DirectDraw
Visual C++ 2005 Express Edition
Windows Server 2003 SP1 Platform SDK
DirectX 9.0 SDK Update (October 2004)
Windowsアプリケーション
DirectDrawによるビデオメモリアクセス
DirectDraw.cpp
// マルチバイト文字セット // ddraw.lib #include
#include
#include
static LPDIRECTDRAW g_pDD = NULL; static LPDIRECTDRAWSURFACE g_pDDSPrimary = NULL; static LPDIRECTDRAWPALETTE g_pDDPalette = NULL; void Trace(const char *pcFormat, ...); LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int Draw(void); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char acClassName[] = "DirectDraw"; WNDCLASSEX wcex; HWND hWnd; MSG msg; DDSURFACEDESC ddsd; PALETTEENTRY pePal[256]; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wcex.lpszMenuName = NULL; wcex.lpszClassName = acClassName; wcex.hIconSm = NULL; RegisterClassEx(&wcex); hWnd = CreateWindowEx( WS_EX_TOPMOST, // ExStyle acClassName, NULL, // WindowName WS_POPUP, 0, // x 0, // y 640, // Width 480, // Height NULL, // WndParent NULL, // Menu hInstance, NULL); // Param if (hWnd == NULL) { return 0; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // DirectDrawオブジェクト if (DirectDrawCreate(NULL, &g_pDD, NULL) != DD_OK) { return 0; } g_pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); g_pDD->SetDisplayMode(640, 480, 8); // プライマリサーフェイス ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL) != DD_OK) { return 0; } // パレット for (int i = 1; i < 255; i++) { pePal[i].peRed = i * 2 / 3 + 32; pePal[i].peGreen = i / 2 + 16; pePal[i].peBlue = i; pePal[i].peFlags = NULL; } g_pDD->CreatePalette(DDPCAPS_8BIT, pePal, &g_pDDPalette, NULL); g_pDDPalette->SetEntries(0, 0, 256, pePal); g_pDDSPrimary->SetPalette(g_pDDPalette); while (1) { if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (! GetMessage(&msg, NULL, 0, 0)) { break; } TranslateMessage(&msg); DispatchMessage(&msg); } else { if (Draw() != 0) { PostMessage(hWnd, WM_CLOSE, 0, 0); } } } return (int)msg.wParam; } void Trace(const char *pcFormat, ...) { va_list args; char acBuf[512]; int iRet; va_start(args, pcFormat); iRet = vsprintf_s(acBuf, sizeof(acBuf), pcFormat, args); if (0 < iRet) { OutputDebugString(acBuf); } va_end(args); } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_KEYDOWN: if (wParam == VK_ESCAPE) { PostMessage(hWnd, WM_CLOSE, 0, 0); } break; case WM_DESTROY: g_pDD->RestoreDisplayMode(); if (g_pDDSPrimary != NULL) { g_pDDSPrimary->Release(); } if (g_pDD != NULL) { g_pDD->Release(); } PostQuitMessage(0); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } int Draw(void) { DDSURFACEDESC ddsd; BYTE *pbVideoMemory; int iRetVal; ddsd.dwSize = sizeof(DDSURFACEDESC); if (g_pDDSPrimary->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL) != DD_OK) { return -1; } pbVideoMemory = (BYTE *)ddsd.lpSurface; iRetVal = 0; if (g_pDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL) != DD_OK) { iRetVal = -1; } pbVideoMemory[rand() % 640 + (rand() % 480) * 640] = rand() % 256; g_pDDSPrimary->Unlock(NULL); return iRetVal; }