#define _CRT_SECURE_NO_DEPRECATE 1
//必要なライブラリファイルのロード
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
//必要なヘッダーファイルのインクルード
#define STRICT
#include <windows.h>
#include <d3dx9.h>
#include "GPLib.h"
#include "MyLib.h"
//シンボル定義及びマクロ
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define SAFE_RELEASE(p)   { if(p) { (p)->Release(); (p)=NULL; } }
//円周率
#define PI 3.1415926535f
//ブロックサイズ
#define B_SIZE 32
//フレームサイズ
#define FRAME_W 10
#define FRAME_H 14
#define MAX_CONNECT_BLOCK (100)
// 消去に必要な連続の数
#define ERASE_MIN (4)
#define SCORE_PX 5  
#define SCORE_PY 4
#define SCORE_W 8
#define SCORE_H 2
#define NUMBER_W 24
#define NUMBER_H 24
//ピースサイズ
#define PIECE_W 2
#define PIECE_H 1
//移動方向
#define LEFT_P 1<<0
#define RIGHT_P 1<<1
#define DOWN_P 1<<2
//ブロックの種類
#define NONE_D  0
#define WHITE_B  1
#define BLUE_B   2
#define RED_B  3
#define WALL1_B   4

// モード
#define MODE_OPENING  0
#define MODE_GAME_PREPARE 1
#define MODE_GAME   2
#define MODE_ENDING   3
//操作PIECE
struct SPIECE
{
 INT  iX,iY;//フィールド内のピース左上の位置
 DWORD dwKind;//ピースの種類
 INT  iBlock[PIECE_W][PIECE_H];//ピースの形状
};
//配置BLOCK
struct SBLOCK
{
 DWORD dwKind;//ブロックの種類
};
//関数プロトタイプの宣言
VOID Draw();
VOID FreeDx();
VOID Initialize();
BOOL ChangePiece();
INT DeleteLine( );
void Count(int, int);
BOOL MovePiece( INT );
VOID CreatePiece( );
VOID NextPiece( );
VOID CopyPiece( );
INT DeleteBall( );
VOID ShiftBall();
VOID DrawGameOverEffect();
BOOL RotationPiece();
INT GetLeft( SPIECE );
INT GetRight( SPIECE );
INT GetDown( SPIECE );
//グローバルなインスタンスを宣言
LPDIRECT3D9   lpD3d = NULL;
LPDIRECT3DDEVICE9 lpDev = NULL;
LPDIRECT3DTEXTURE9 lpTex = NULL;
LPDIRECT3DTEXTURE9 lpTex2 = NULL;
LPDIRECT3DTEXTURE9 lpTex3 = NULL;
LPDIRECT3DTEXTURE9 lpTex4 = NULL;
LPDIRECT3DTEXTURE9 lpTitleTex = NULL;
LPDIRECT3DTEXTURE9 lpEndingTex = NULL;

HWND    hWndApp;
LPD3DXFONT   lpFont = NULL;

INT  iMode;
//キーボード情報
BYTE bSaveKey[256];
//操作ピース情報
SPIECE sPiece;
//予告ピース情報
SPIECE sNextPiece;
//配置ブロック情報
SBLOCK sBlock[FRAME_W][FRAME_H];
//削除中かどうかの判断フラグ&削除ライン数
INT  iDel;
// ゲームオーバーフラグ
INT  fGameOver;

INT  Score;
INT  HighScore;
// つながったブロックの値
int nConnects;
// つながったブロックの座標
int nX[MAX_CONNECT_BLOCK];
int nY[MAX_CONNECT_BLOCK];
// ブロッククリア
void clear();
// ブロック表示
void show();
// ブロックの消去
void delBlock();
// 連続しているブロックのカウント
void Count(int x,int y);
// Name:Draw()
// Desc:描画
VOID Opening()
{
 BYTE bKey[256];
 //キー情報を取得
 GetKeyboardState( bKey );
 lpDev->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(128,128,128), 1.0f, 0 );
 // 描画開始 
 if( SUCCEEDED( lpDev->BeginScene() ) ){
 
  // タイトルの描画
  DrawSprite(
   lpDev,lpTitleTex,
   0, 0,
   WINDOW_WIDTH, WINDOW_HEIGHT,
   WINDOW_WIDTH/2, WINDOW_HEIGHT/2,
   1, 1,
   0, 0,
   0, 0xffffffff);
  // 描画終了
  lpDev->EndScene();
 }
 //
 lpDev->Present( NULL, NULL, NULL, NULL );
 // スペースキーを押されたらモードチェンジ
 if( bKey[VK_SPACE]&0x80 && !(bSaveKey[VK_SPACE]&0x80))
 {
  // ゲーム準備モード
  iMode = MODE_GAME_PREPARE;
 }
 // キーボードのコピー
 memcpy( bSaveKey, bKey, sizeof(BYTE)*256 );
}
// Name:GamePrepare()// Desc:ゲームの準備
VOID GamePrepare()
{
 int i,j;
 // スコアを0にする
 Score = 0;
 //2次元配列の初期化
 for( i=0 ; i<FRAME_W ; i++)
  for( j=0 ; j<FRAME_H ; j++ )
   sBlock[i][j].dwKind = NONE_D;
 //ピースの生成
 CreatePiece();
 NextPiece();
 iDel = 0;
 // ゲームオーバーフラグをリセット
 fGameOver = 0;
 // セーブキーのクリア
 ZeroMemory( bSaveKey, sizeof(BYTE)*256);
 // ゲーム準備モード
 iMode = MODE_GAME;
 // オートリピートカウントを0にする
}
// Name:Ending()// Desc:オープニング
VOID Ending()
{
 BYTE bKey[256];
 //キー情報を取得
 GetKeyboardState( bKey );
 lpDev->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(128,128,128), 1.0f, 0 );
 // 描画開始
 if( SUCCEEDED( lpDev->BeginScene() ) ){
  // タイトルの描画
  DrawSprite(
   lpDev,lpEndingTex,
   0, 0,
   WINDOW_WIDTH, WINDOW_HEIGHT,
   WINDOW_WIDTH/2, WINDOW_HEIGHT/2,
   1, 1,
   0, 0,
   0, 0xffffffff);
  // 描画終了
  lpDev->EndScene();
 }
 lpDev->Present( NULL, NULL, NULL, NULL );
 // スペースキーを押されたらモードチェンジ
 if( bKey[VK_SPACE]&0x80 && !(bSaveKey[VK_SPACE]&0x80))
 {
  // オープニングモード
  iMode = MODE_OPENING;
  // キーボードのクリア
  ZeroMemory( bSaveKey, sizeof(BYTE)*256);
 }
 // キーボードのコピー
 memcpy( bSaveKey, bKey, sizeof(BYTE)*256 );
}