I've managed to make some minor improvements to the DirectDraw function DD_SetupDirectDraw. I am using the Summer 2003 release of the DirectX 9.0 SDK. This release supports the interface IDirectDraw7, which makes some improvements over IDirectDraw.
Here is the old code. It makes redundant calls to
QueryInterface and
SetCooperativeLevel. A slightly better way to do this involves obtaining a pointer to IDirectDraw7 using
DirectDrawCreateEx. I also added a the ability to use Ctrl-Alt-Del to break out of the game:
// Old Code
BOOL DD_SetupDirectDraw(HWND hwnd )
{
HRESULT hresult;
static DDSURFACEDESC2 ddsd;
static DDSCAPS2 ddscaps;
ShowCursor(FALSE);
hresult = DirectDrawCreate( NULL, &lpDD, NULL );
if (hresult != DD_OK)
ErrorBox("DirectDrawCreate Error",hresult);
hresult = lpDD->SetCooperativeLevel(hwnd, DDSCL_NORMAL);
if (hresult != DD_OK)
ErrorBox("GetCaps Error",hresult);
hresult = lpDD->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpDD7);
if (hresult != DD_OK)
ErrorBox("QueryInterface Error",hresult);
hresult = lpDD7->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX);
if (hresult != DD_OK)
ErrorBox("SetCooperativeLevel Error",hresult);
hresult = lpDD7->SetDisplayMode(iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT, 8, 0, DDSDM_STANDARDVGAMODE);
if (hresult != DD_OK)
ErrorBox("SetDisplayMode Error",hresult);
memset(&ddsd, sizeof(DDSURFACEDESC2), 0);
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
hresult = lpDD7->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
if (hresult != DD_OK)
ErrorBox("CreateSurface Error",hresult);
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hresult = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
if (hresult != DD_OK)
ErrorBox("GetAttachedSurface Error",hresult);
lpDDSPrimary->GetCaps(&ddscaps);
ddsd.dwSize = sizeof(ddsd);
lpDDSBack->GetSurfaceDesc(&ddsd);
return TRUE;
}Here's the new code. Remember, this is still very archaic. I am digging through the WinROTT video routines to decipher what is really happening. The more I learn, the more my hat is off to the original WinROTT developers for getting the game to operate properly at all.
// New Code
// ----------- NEW GLOBALS
LPDIRECTDRAW7 lpDD7; // DirectDraw Interface
LPDIRECTDRAWSURFACE7 lpDDSPrimary; // DirectDraw Surface
LPDIRECTDRAWSURFACE7 lpDDSBack; // DirectDraw Backbuffer Surface
BOOL DD_SetupDirectDraw(HWND hwnd )
{
HRESULT hresult;
static DDSURFACEDESC2 ddsd;
static DDSCAPS2 ddscaps;
ShowCursor(FALSE);
hresult = DirectDrawCreateEx( NULL, (LPVOID *)&lpDD7, IID_IDirectDraw7, NULL );
if (hresult != DD_OK)
ErrorBox(_T("DirectDrawCreate Error"),hresult);
hresult = lpDD7->SetCooperativeLevel(hwnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX);
if (hresult != DD_OK)
ErrorBox(_T("SetCooperativeLevel Error"),hresult);
hresult = lpDD7->SetDisplayMode(iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT, 8, 0, DDSDM_STANDARDVGAMODE);
if (hresult != DD_OK)
ErrorBox(_T("SetDisplayMode Error"),hresult);
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY;;
ddsd.dwBackBufferCount = 1;
hresult = lpDD7->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
if (hresult != DD_OK)
ErrorBox(_T("CreateSurface Error"),hresult);
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hresult = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
if (hresult != DD_OK)
ErrorBox(_T("GetAttachedSurface Error"),hresult);
lpDDSPrimary->GetCaps(&ddscaps);
ddsd.dwSize = sizeof(ddsd);
lpDDSBack->GetSurfaceDesc(&ddsd);
return TRUE;
}
If you have any questions, please don't hesitate to ask.
Sources:
Game Programming Genesis Part IV : Introduction to DirectXwww.gamedev.net is an important resource for all things graphical.