Thursday, December 09, 2004

Direct video memory access using directdraw

Good direct draw example accessing video ram

#include
#include

const PHYSICAL_WIDTH = 800;
const PHYSICAL_HEIGHT = 600;

LPDIRECTDRAW lpDDraw;
LPDIRECTDRAWSURFACE lpPrimarySurface;

LRESULT CALLBACK DDrawWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
BOOL DDrawInit(HWND hWnd);
void DDrawDone();
void DrawScreen();

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nCmdShow)
{

WNDCLASS wndClass;
HWND hWnd;
MSG msg;

ZeroMemory(&wndClass, sizeof(wndClass));
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = DDrawWndProc;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.lpszClassName = ;

RegisterClass(&wndClass);

hWnd = CreateWindowEx(
WS_EX_TOPMOST,
wndClass.lpszClassName,
,
WS_POPUP | WS_MAXIMIZE,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
hInstance,
NULL);

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}

LRESULT CALLBACK DDrawWndProc(HWND hWnd,
UINT message, WPARAM wParam,
LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
DDrawInit(hWnd);
SetTimer(hWnd, 1, 50, 0);
return 0;

case WM_TIMER:
DrawScreen();
return 0;

case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
SendMessage(hWnd, WM_CLOSE, 0, 0);
return 0;

case WM_DESTROY:
KillTimer(hWnd, 1);
DDrawDone();
PostQuitMessage(0);
return 0;

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}

BOOL DDrawInit(HWND hWnd)
{
DDSURFACEDESC ddsd;
DDSCAPS ddsc;

if (DirectDrawCreate(NULL, &lpDDraw, NULL) != DD_OK)
return FALSE;

if (lpDDraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN) != DD_OK)
return FALSE;

if (lpDDraw->SetDisplayMode(PHYSICAL_WIDTH,
PHYSICAL_HEIGHT,
8) != DD_OK)
return FALSE;

ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
ddsd.dwFlags = DDSD_CAPS;
if (lpDDraw->CreateSurface(&ddsd, &lpPrimarySurface,
NULL) != DD_OK)
return FALSE;

return TRUE;
}

void DDrawDone()
{
if (lpPrimarySurface != NULL)
lpPrimarySurface->Release();

if (lpDDraw != NULL)
lpDDraw->Release();
}

void DrawScreen()
{
DDSURFACEDESC ddsd;
static int pos;

ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

if (lpPrimarySurface->Lock(NULL, &ddsd,
DDLOCK_WAIT, NULL) == DD_OK)
{
char* buffer = (char*)ddsd.lpSurface;
for (int i = 0; i < PHYSICAL_HEIGHT / 2; i++)
{
memset(buffer + (i * ddsd.lPitch), i + pos,
PHYSICAL_WIDTH);
memset(buffer + ((PHYSICAL_HEIGHT / 2 + i)
* ddsd.lPitch), i - pos,
PHYSICAL_WIDTH);
}

pos++;

lpPrimarySurface->Unlock(ddsd.lpSurface);
}
}


0 Comments:

Post a Comment

<< Home