Hey guys! I'm currently learning DirectX (DirectDraw to be specific), in order to recode my game (you can check out the GDI version in my sig). But this simple prog keeps giving me an illegal operation whenever I close it! No idea what's wrong, except that my init/shutdown code was working fine before... Well, this is the relevant code:
Anyone have any quick pointers?PHP Code:#include <ddraw.h>
#include "main.h" //function prototypes
#define WINDOW_CAPTION "DirectX Pixelz"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define WINDOW_POS_X 0
#define WINDOW_POS_Y 0
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
HWND hWnd;
bool done;
LPDIRECTDRAW ddraw;
LPDIRECTDRAWSURFACE surfacePrimary, surfaceSecondary;
unsigned char* videoBuffer;
DDSURFACEDESC desc = {0};
DDSCAPS ddscaps;
int x, y;
void registerWindowClass()
{
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(wc);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "WndClass";
RegisterClassEx(&wc);
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmd, int showCmd)
{
srand((unsigned int)GetTickCount());
registerWindowClass();
hWnd = CreateWindowEx(0, "WndClass", WINDOW_CAPTION, WS_POPUP, WINDOW_POS_X, WINDOW_POS_Y, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInst, NULL);
ShowWindow(hWnd, SW_SHOW);
if(!gameInit())
return 1;
MSG msg;
while(!done)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
gameMain();
}
gameShutdown();
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
done = true;
DestroyWindow(hWnd);
return 0;
case WM_KEYDOWN:
switch((int)wParam)
{
case 'Q':
done = true;
DestroyWindow(hWnd);
break;
}
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
bool gameInit()
{
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
desc.dwBackBufferCount = 1;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP | DDSCAPS_COMPLEX;
if(DirectDrawCreate(NULL, &ddraw, NULL) != DD_OK)
return false;
if(ddraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_ALLOWREBOOT) != DD_OK)
return false;
if(ddraw->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, 8) != DD_OK)
return false;
if(ddraw->CreateSurface(&desc, &surfacePrimary, NULL) != DD_OK)
return false;
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if(surfacePrimary->GetAttachedSurface(&ddscaps, &surfaceSecondary) != DD_OK)
return false;
return true;
}
void gameMain()
{
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
surfaceSecondary->Lock(NULL, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
videoBuffer = (unsigned char*)desc.lpSurface;
if(desc.lPitch == SCREEN_WIDTH)
memset(videoBuffer,0,SCREEN_WIDTH*SCREEN_HEIGHT);
else
{
unsigned char* asdf = videoBuffer;
for(int i = 0; i < SCREEN_HEIGHT; ++i)
{
memset(asdf, 0, SCREEN_WIDTH);
asdf += desc.lPitch;
}
}
for(int i = 0; i < 1000; ++i)
{
x = rand() % SCREEN_WIDTH;
y = rand() % SCREEN_HEIGHT;
videoBuffer[x + (y * (desc.lPitch))] = rand() % 256;
}
surfaceSecondary->Unlock(videoBuffer);
while(surfacePrimary->Flip(NULL, DDFLIP_WAIT) != DD_OK && (!done));
}
void gameShutdown()
{
if(surfaceSecondary != NULL)
surfaceSecondary->Release();
if(surfacePrimary != NULL)
surfacePrimary->Release();
if(ddraw != NULL)
ddraw->Release();
}



LinkBack URL
About LinkBacks



Well, I guess it doesn't surprise me even though I took the releasing stuff right out of a book... the book I'm using has a typo/bug every couple of pages
I guess I'll try taking out the backbuffer-releasing lines though 
". Is it faster than "while(true)" or neater or something?