/*   バックバッファのフリップ 1999/ 2/11 宍戸 輝光 */ #include #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); void draw(void); LPDIRECTDRAW lpDD=NULL; LPDIRECTDRAWSURFACE lpDDSPrimary=NULL,lpDDSBack=NULL; DDSURFACEDESC ddsd; DDSCAPS ddscaps; LPDIRECTDRAWPALETTE lpDPalette; DWORD dwHeight=0,dwDHeight=1,dwDPl=1; BYTE bPl=128; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASSEX wndclass ; PALETTEENTRY pePal[256]; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; wndclass.hIconSm = NULL; RegisterClassEx (&wndclass); HWND hwnd=CreateWindowEx(WS_EX_TOPMOST,"CWindow",NULL, WS_POPUP,0,0,640,480,NULL,NULL,hInstance,NULL); ShowWindow (hwnd,iCmdShow); // ウインドウを表示 UpdateWindow (hwnd); DirectDrawCreate(NULL,&lpDD,NULL); // DirectDrawオブジェクト作成 lpDD->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); lpDD->SetDisplayMode(640,480,8); // 画面を640*480/8Bit モードに設定 FillMemory(&ddsd,0,sizeof(ddsd)); // プライマリサーフェイス作成 ddsd.dwSize=sizeof(ddsd); ddsd.dwFlags=DDSD_CAPS| DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE| DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; lpDD->CreateSurface(&ddsd,&lpDDSPrimary,NULL); // バックバッファ取得 ddscaps.dwCaps = DDSCAPS_BACKBUFFER; lpDDSPrimary->GetAttachedSurface(&ddscaps,&lpDDSBack); for (int i=0;i<256;i++) { // パレット作成 pePal[i].peRed=i; pePal[i].peGreen=i; pePal[i].peBlue=i; pePal[i].peFlags=NULL; } lpDD->CreatePalette(DDPCAPS_8BIT,pePal,&lpDPalette,NULL); lpDPalette->SetEntries(0,0,256,pePal); lpDDSPrimary->SetPalette(lpDPalette); // パレット設定 while (1) { /* メインループ */ if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) { if (!GetMessage (&msg,NULL,0,0)) // メッセージ処理 return msg.wParam ; TranslateMessage(&msg); DispatchMessage(&msg); } else draw(); // 描画処理 } } void draw(void) { // バックバッファに描画、フリップ lpDDSBack->Lock(NULL,&ddsd,DDLOCK_WAIT,NULL); BYTE* lpBuf=(BYTE*)ddsd.lpSurface; FillMemory(lpBuf,640*480,0); FillMemory(lpBuf,640*dwHeight,bPl); lpDDSBack->Unlock(NULL); lpDDSPrimary->Flip(NULL, DDFLIP_WAIT); if (dwHeight==479) dwDHeight=-1; else if (dwHeight==0) dwDHeight=1; dwHeight+=dwDHeight; if (bPl==255) dwDPl=-1; else if (bPl==64) dwDPl=1; if (dwHeight % 2==0) // 2周期に一度色変更 bPl+=dwDPl; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_KEYDOWN: if (wParam==VK_ESCAPE) // エスケープキーが押されたら終了 PostMessage(hwnd,WM_CLOSE,0,0); break; case WM_DESTROY : // 終了処理 lpDD->RestoreDisplayMode(); // 画面モードを元に戻す if (lpDDSBack) // バックバッファ解放 lpDDSBack->Release(); if (lpDDSPrimary) // サーフェイス解放 lpDDSPrimary->Release(); if (lpDD) // DirectDrawオブジェクト解放 lpDD->Release(); PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }