-
DirectX7 Troubles
I'm trying to make a checkers game in DirectX, but everytime I quit the app, I get an access violation error(can't read a part of the memory)
Here's all the code:
Code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#define INITGUID
#include <ddraw.h>
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
// initializes a direct draw struct
#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
#define SAFE_RELEASE(x) {if(x) {x->Release(); x = NULL;}}
// GLOBALS ////////////////////////////////////////////////
HWND g_hWnd = NULL; // globally track main window
HINSTANCE g_hInstance = NULL; // globally track hinstance
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_COLORS 16
#define CLASS_NAME "Checkers"
#define WINDOW_NAME "Checkers"
//LPDIRECTDRAW lpDD = NULL; // dd object
LPDIRECTDRAW7 lpDD7 = NULL; // dd4 object
LPDIRECTDRAWSURFACE7 lpDDSPrimary = NULL; // dd primary surface
LPDIRECTDRAWSURFACE7 lpDDSBack = NULL; // dd back surface
LPDIRECTDRAWSURFACE7 lpDDSTile[8][8];
LPDIRECTDRAWPALETTE lpDDPal = NULL; // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER lpDDClipper = NULL; // dd clipper
PALETTEENTRY palette[256]; // color palette
DDSURFACEDESC2 DDSD; // a direct draw surface description struct
DDSCAPS2 DDSCaps; // a direct draw surface capabilities struct
HBITMAP hbRedTile, hbBlackTile, hbRedPiece, hbBlackPiece;
LPDIRECTDRAWSURFACE7 bitmap_surface(int nResId)
{
HDC hdc;
HBITMAP bit;
LPDIRECTDRAWSURFACE7 surf;
bit = LoadBitmap(g_hInstance, MAKEINTRESOURCE(nResId));
if(!bit)
return NULL;
BITMAP bitmap;
GetObject(bit, sizeof(BITMAP), &bitmap);
int surf_w = bitmap.bmWidth;
int surf_h = bitmap.bmHeight;
HRESULT hRes;
DDSURFACEDESC2 DDSD2;
ZeroMemory(&DDSD2, sizeof(DDSD2));
DDSD2.dwSize = sizeof(DDSURFACEDESC2);
DDSD2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
DDSD2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
DDSD2.dwWidth = surf_w;
DDSD2.dwHeight = surf_h;
hRes = lpDD7->CreateSurface(&DDSD2, &surf, NULL);
if(hRes != DD_OK) {
DeleteObject(bit);
return NULL;
}
else {
surf->GetDC(&hdc);
HDC bit_dc = CreateCompatibleDC(hdc);
SelectObject(bit_dc, bit);
BitBlt(hdc, 0, 0, surf_w, surf_h, bit_dc, 0, 0, SRCCOPY);
surf->ReleaseDC(hdc);
DeleteDC(bit_dc);
}
DeleteObject(bit);
return(surf);
}
void LoadImages()
{
int x, y;
for(x = 0; x < 8; x++)
{
for(y = 0; y < 8; y++)
{
if(((x % 2) == 1) && ((y % 2) == 1))
{
lpDDSTile[x][y] = bitmap_surface(IDB_BLACKTILE);
} else {
lpDDSTile[x][y] = bitmap_surface(IDB_REDTILE);
}
}
}
}
void DrawBoard()
{
//80x60
int x, y;
int xpos = 0, ypos = 0;
for(x = 0; x < 8; x++)
{
for(y = 0; y < 8; y++)
{
lpDDSBack->BltFast(xpos,ypos, lpDDSTile[x][y], NULL, DDBLTFAST_WAIT);
ypos += 60;
}
xpos += 80;
}
}
int InitGame()
{
if (FAILED(DirectDrawCreateEx(NULL, (LPVOID*)&lpDD7, IID_IDirectDraw7, NULL)))
{
return(0);
}
if(!(lpDD7->SetCooperativeLevel(g_hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE))) MessageBox(NULL, "SetCooperativeLevel", "", MB_OK);
if(!(lpDD7->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_COLORS, 0, 0))) MessageBox(NULL, "SetDisplayMode", "", MB_OK);
ZeroMemory(&DDSD, sizeof(DDSURFACEDESC2));
DDSD.dwSize = sizeof(DDSURFACEDESC2);
DDSD.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
DDSD.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
DDSD.dwBackBufferCount = 1;
if(!(lpDD7->CreateSurface(&DDSD, &lpDDSPrimary, NULL))) MessageBox(NULL, "CreateSurface", "", MB_OK);
DDSCaps.dwCaps = DDSCAPS_BACKBUFFER;
HRESULT hRes = lpDDSPrimary->GetAttachedSurface(&DDSCaps, &lpDDSBack);
if(hRes != DD_OK) return(0);
return(1);
}
int EndGame()
{
SAFE_RELEASE(lpDDSPrimary);
SAFE_RELEASE(lpDDSBack);
SAFE_RELEASE(lpDD7);
int x, y;
for(x = 0; x < 8; x++)
{
for(y = 0; y < 8; y++)
{
SAFE_RELEASE(lpDDSTile[x][y]);
}
}
return(1);
}
int GameMain()
{
if (KEYDOWN(VK_ESCAPE))
SendMessage(g_hWnd,WM_CLOSE,0,0);
return(1);
}
Code:
#include "checkers.h"
LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;
WNDCLASSEX winclass;
HWND hWnd;
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WinProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hInstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = CLASS_NAME;
if(!RegisterClassEx(&winclass))
return(0);
if(!(hWnd = CreateWindowEx(NULL, CLASS_NAME, WINDOW_NAME, WS_POPUP | WS_VISIBLE, 0,0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL)))
return(0);
g_hWnd = hWnd;
g_hInstance = hInstance;
InitGame();
while(true)
{
if(PeekMessage(&msg, NULL, 0,0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GameMain();
}
EndGame();
return(msg.wParam);
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
//InitGame();
//MessageBox(NULL, "test", "test", MB_OK);
return 0;
//case WM_PAINT:
//DrawBoard();
//return 0;
//case WM_SIZE:
return 0;
case WM_LBUTTONDBLCLK:
EndGame();
PostQuitMessage(0);
return(0);
//case WM_LBUTTONDOWN:
// return(0);
case WM_DESTROY:
//EndGame();
PostQuitMessage(0);
return 0;
//
// Process other messages.
//
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
I think the problem is occuring in InitGame, because when it only contained the first 6 lines, it didn't do this.
Thanks,
-Dennis