#include <windows.h>
#include <ddraw.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
///////////
//定数定義//
///////////
#define DISPXSIZE 320 // 画面横サイズ
#define DISPYSIZE 240 // 画面縦サイズ
#define SPRITEXSIZE 320 // スプライト横サイズ
#define SPRITEYSIZE 240 // スプライト縦サイズ
///////////
//変数定義//
///////////
HWND hWND; // ウインドウハンドル
HINSTANCE hINSTANCE; // ウインドウインスタンス
char lpszAppName[] = "DDsimple"; // アプリケーション名
int spx,spy; // スプライトの座標
//////////////////////
// DirectDraw構造体 //
//////////////////////
LPDIRECTDRAW lpDD = NULL; // DirectDrawオブジェクト
LPDIRECTDRAWSURFACE lpFRONTSURFACE = NULL; // プライマリサーフェス
LPDIRECTDRAWSURFACE lpBACKSURFACE = NULL; // バックサーフェス
LPDIRECTDRAWSURFACE lpSPRITE = NULL; // スプライトサーフェス
LPDIRECTDRAWPALETTE lpPALETTE = NULL; // パレット
PALETTEENTRY pePAL[256]; // パレット構造体
/*===============
関数定義
================*/
BOOL InitDDraw(HWND hwnd, int x, int y, int sx, int sy);
void ReleaseDDraw(void);
BOOL SetDDrawSprite(LPCSTR Resource , int sx , int sy);
void DrawDDrawSprite(int x, int y, RECT* rect);
void DrawDDrawSpriteClip(int x, int y, RECT* rect);
//void ResumeDDraw(void);
HRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg){
case WM_KEYDOWN: // キーが押された
switch(wParam){
case VK_ESCAPE: // 終了処理
DestroyWindow(hWnd);
break;
case VK_LEFT: // 左移動
spx -= 8;break;
case VK_RIGHT: // 右移動
spx += 8;break;
case VK_UP: // 上移動
spy -= 8;break;
case VK_DOWN: // 下移動
spy += 8;break;
}
return(TRUE);
case WM_ACTIVATEAPP:// 制御がこのアプリケーションに移った
if((wParam) && (lpDD != NULL))
// lpDDがNULLの時はResumeしてはいけない
{
//ResumeDDraw(); // DirectDrawの再構築
return(TRUE);
}
break;
case WM_CLOSE: // ウインドウが閉じられた
DestroyWindow(hWnd);
return(TRUE);
case WM_DESTROY: // ウインドウが破壊された
ReleaseDDraw();
PostQuitMessage(0);
return(TRUE);
}
return(DefWindowProc(hWnd, iMsg, wParam, lParam));
}
int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wndclass;
MSG msg;
hINSTANCE = hInstance;
////////////////////////////////////////
// おきまりのウインドウクラス生成処理 //
////////////////////////////////////////
// ウインドウクラスの生成
wndclass.style = NULL;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hINSTANCE;
wndclass.hIcon = LoadIcon(NULL,"ICON");
wndclass.hCursor = NULL;
wndclass.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = lpszAppName;
RegisterClass(&wndclass);
// ウインドウの生成
hWND = CreateWindow(lpszAppName, lpszAppName,
WS_POPUP|WS_VISIBLE|WS_SYSMENU,
0, 0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL, NULL, hINSTANCE, NULL );
////////////////////////
// 本格的な初期化処理 //
////////////////////////
// DirectDrawとその他初期化
if(InitDDraw(hWND, DISPXSIZE, DISPYSIZE, SPRITEXSIZE , SPRITEYSIZE) != TRUE)
{
MessageBox(hWND,"Can't create DirectDraw Object",
"error",MB_APPLMODAL);
DestroyWindow(hWND);
}
else
{
for(;;){ // メインループ
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
PostQuitMessage(msg.wParam);
return 0;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// 画面クリア
DDBLTFX ddbltfx;
ZeroMemory(&ddbltfx, sizeof(DDBLTFX));
ddbltfx.dwSize = sizeof(DDBLTFX);
lpBACKSURFACE->Blt(NULL, NULL, NULL,DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx);
}
}
return(FALSE);
}
BOOL InitDDraw(HWND hwnd, int x, int y, int sx, int sy)
{
DDSURFACEDESC ddsd; // DirectDrawサーフェスの属性情報を格納する
DDSCAPS ddscaps; // DirectDrawサーフェスの能力情報を格納する
// DirectDrawオブジェクトを生成
if( DirectDrawCreate( NULL , &lpDD , NULL ) != DD_OK )return FALSE;//失敗
// DirectDraw協調レベルを設定
lpDD->SetCooperativeLevel( hwnd , DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN |
DDSCL_ALLOWMODEX);
// DDSCL_EXCLUSIVE 排他モード(占有モード)
// DDSCL_FULLSCREEN フルスクリーンモード
// DDSCL_ALLOWMODEX ModeXモード
lpDD->SetDisplayMode(x, y, 8); // 256色
// プラリマリサーフェスの初期化
ZeroMemory(&ddsd, sizeof( ddsd ) );// ゼロクリア
ddsd.dwSize = sizeof( ddsd ); // サイズ格納
ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT; // 有効データ指定フラグ設定
// DDSD_CAPS ddsCapsを有効化
// DDSD_BACKBUFFERCOUNT dwBackBufferCountを有効化
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;
// DDSCAPS_PRIMARYSURFACE プライマリサーフェスであることを明示
// DDSCAPS_FLIP フリップを可能にする
// DDSCAPS_COMPLEX 複合サーフェスの使用を指定
ddsd.dwBackBufferCount = 1;
// バックバッファの数を指定(この場合、バックサーフェスのみな
// ので1を指定している。
lpDD->CreateSurface( &ddsd , &lpFRONTSURFACE , NULL);
//ddsdの設定に基づいてサーフェスを作成。サーフェスオブジェクト
//はlpFRONTSURFACEから参照可能
// バックサーフェスの初期化
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
//DDCAPS_BACKBUFFER バックバッファであることを指定
lpFRONTSURFACE->GetAttachedSurface( &ddscaps , &lpBACKSURFACE);
// ddscapsの指定に基づいてアタッチドサーフェス(バックサーフェス)
// を生成。オブジェクトはlpBACKSURFACEから参照可能。
// パレットの生成
lpDD->CreatePalette( DDPCAPS_8BIT , pePAL , &lpPALETTE , NULL);
// 8ビット(256色)
lpFRONTSURFACE->SetPalette( lpPALETTE );
// フロントサーフェスにパレットを設定
// スプライトサーフェスの生成
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH|DDSD_HEIGHT;
// DDSD_CAPS ddsCapsを有効化
// DDSD_WIDTH dwWidthを有効化
// DDSD_HEIGHT dwHeightを有効化
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
// DDSCAPS_OFFSCREENPLAIN 非表示画面属性を設定
ddsd.dwWidth = sx; // スプライトサーフェス横幅
ddsd.dwHeight = sy; // スプライトサーフェス縦幅
lpDD->CreateSurface( &ddsd , &lpSPRITE , NULL);// スプライトサーフェス生成
return(TRUE);//成功
}
#if 0
////////////////////////////////////////////////////////////////////
DirectDrawの終了処理(){}
void ReleaseDDraw(void)
各々のDirectDraw資源を開放する
////////////////////////////////////////////////////////////////////
#endif
void ReleaseDDraw(void)
{
if( lpSPRITE != NULL) lpSPRITE->Release();
if( lpPALETTE != NULL) lpPALETTE->Release();
if( lpFRONTSURFACE != NULL) lpFRONTSURFACE->Release();
if( lpDD != NULL) lpDD->Release();
}