#include "stdhdr.h"
#include "Debug.h"
#include "Draw.h"
#include "ddutil.h"
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "ddraw.lib")
IDirectDraw7 *g_pDD;
IDirectDrawSurface7 *g_lpPrimary, *g_lpBackBuffer;
static int g_cxScreen, g_cyScreen, g_nBPP;
BOOL InitDirectDraw(int cxScreen, int cyScreen, int nBPP)
{
HRESULT h;
h = DirectDrawCreateEx(NULL, (void **)&g_pDD, IID_IDirectDraw7, NULL);
if (FAILED(h))
{
DISPLAYERRORCODE(h, "DirectDraw could not be initialised. Check for low memory or low system resources.");
return FALSE;
}
ShowWindow(hWndMain, SW_SHOW);
g_pDD->SetCooperativeLevel(hWndMain,
DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
if (FAILED(h))
{
ExitDirectDraw();
DISPLAYERRORCODE(h, "DirectDraw could not be initialised. Check for low memory or low system resources.");
return FALSE;
}
g_cxScreen = cxScreen;
g_cyScreen = cyScreen;
g_nBPP = nBPP;
h = g_pDD->SetDisplayMode(g_cxScreen, g_cyScreen, g_nBPP, 0, 0);
if (FAILED(h))
{
ExitDirectDraw();
DISPLAYERRORCODE(h, "This graphics card does not support the required video mode.");
return FALSE;
}
DDSURFACEDESC2 ddsd;
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 = 2;
h = g_pDD->CreateSurface(&ddsd, &g_lpPrimary, NULL);
if (FAILED(h))
{
ExitDirectDraw();
DISPLAYERRORCODE(h, "This graphics card does not have enough video memory.");
return FALSE;
}
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
g_lpPrimary->GetAttachedSurface(&ddsd.ddsCaps, &g_lpBackBuffer);
return TRUE;
}
IDirectDrawSurface7 *LoadSurface(LPCTSTR lpFilename)
{
return DDLoadBitmap(g_pDD, lpFilename, 0, 0);
}
void ExitDirectDraw()
{
g_lpPrimary->Release();
g_lpPrimary = NULL;
g_pDD->Release();
g_pDD = NULL;
}
BOOL BackBlt(int x, int y, IDirectDrawSurface7 *lpSurf, LPCRECT pRect, DWORD dwFlags)
{
HRESULT h;
RECT rc = *pRect;
if ((x > g_cxScreen) || (y > g_cyScreen))
return TRUE;
if (x < 0)
{ rc.left -= x;
x = 0;
}
if (y < 0)
{ rc.top -= y;
y = 0;
}
if (rc.left < 0)
rc.left = 0;
if (rc.top < 0)
rc.top = 0;
if ((x + rc.right - rc.left) > g_cxScreen)
rc.right -= (x + rc.right - rc.left) - g_cxScreen;
if ((y + rc.bottom - rc.top) > g_cyScreen)
rc.bottom -= (y + rc.bottom - rc.top) - g_cyScreen;
if ((rc.right <= rc.left) || (rc.bottom <= rc.top))
return TRUE;
h = g_lpBackBuffer->BltFast(x, y, lpSurf, &rc, dwFlags | DDBLTFAST_WAIT);
if (h == DDERR_SURFACELOST)
{
g_pDD->RestoreAllSurfaces();
ReloadAllSurfaces();
h = g_lpBackBuffer->BltFast(x, y, lpSurf, &rc, dwFlags | DDBLTFAST_WAIT);
}
if (h != DD_OK)
return FALSE;
return TRUE;
}
BOOL ClearScreen(DWORD dwColour)
{
DDBLTFX ddfx;
HRESULT h;
ddfx.dwSize = sizeof(ddfx);
ddfx.dwFillColor = dwColour;
h = g_lpBackBuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddfx);
if (h == DDERR_SURFACELOST)
{
g_pDD->RestoreAllSurfaces();
ReloadAllSurfaces();
h = g_lpBackBuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddfx);
}
if (h != DD_OK)
return FALSE;
return TRUE;
}