/* Direct Draw Surface Routines */
#include <stdio.h>

#include "windows.h"
#include "ddraw.h"
#include "ddmem.h"

#include "sgl.h"
#include "textower.h"

/* Local defs */
#define REPORT_DEVICE_CAPS			0
#define REPORT_ALL_ERRORS			1
#define DIALOG_ERRORS				1

#define NAME "TexTower"
#define TITLE "Tower5 : Rendering on-screen"


/* local typedefs */
typedef LPBYTE			LPMEM;
typedef LPMEM FAR *		LPMEMADDRESS;

/* publics */
LPDIRECTDRAW			pDDObject=0;
LPDIRECTDRAWSURFACE		pFrontBuffer=0;
LPMEM					pFrontBufferMemory=0;
DWORD					dwBufferStride=0;

WORD					wBitsPerPixel=0;
WORD					wWidth=0;
WORD					wHeight=0;

DDCAPS					DDDriverCaps;
DDCAPS					DDHELCaps;
DDSCAPS					DDSurfaceCaps;
BOOL					bDisplayCapsValid=0;

HRESULT					hresult=0;
DWORD					hresultSeverity=0;
DWORD					hresultFacility=0;
DWORD					hresultCode=0;

BOOL					bRet;

CALLBACK_SURFACE_PARAMS	CallbackSurfaceInfo;
DDSURFACEDESC			PrimarySurfaceInfo;

/*  Macros */
#define TEXT_ERR(x) case x : ErrorText = #x ; break;
#define ReportCaps(x) if (DDDriverCaps.dwCaps & x) OutputDebugString( #x "\n");
#define ReportDDSCaps(x) if (dwCaps & x) OutputDebugString( #x "\n");


/* Local protos */
int GetDDrawServices();
int FreeDDrawServices();
int DDCreateObject(HWND hWnd);
void ReportDDrawError (HRESULT err);
int DDCreatePrimarySurface();
WORD GetPhysicalColour(BYTE bRed, BYTE bGreen, BYTE bBlue);


int DDColourFill(BYTE bRed, BYTE bGreen, BYTE bBlue, LPDIRECTDRAWSURFACE pSurface);

int DDLock (LPDIRECTDRAWSURFACE pSurface, LPMEMADDRESS pMemAddress, LPDWORD pStride);
int DDUnlock(LPDIRECTDRAWSURFACE pSurface);
int DDWaitForVSync();
int DDInVerticalBlank(LPBOOL pbIsInVB);
int DDGetDisplayCaps();
void ReportSurfaceCaps(DWORD dwCaps);

HINSTANCE hInstDD=0;

typedef HRESULT (WINAPI *DDCREATE) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *);
DDCREATE FnDirectDrawCreate = 0;


/*** Init ***/
int GetDDrawServices()
{
	if (!hInstDD)
	{
		hInstDD = LoadLibrary("ddraw.dll");
	}
	
	if (!hInstDD)
	{
		MessageBox (NULL, "Error - direct draw drivers not available", NAME, MB_OK|MB_ICONHAND|MB_SYSTEMMODAL);
		return DD_FAIL;
	}
	
	if (!FnDirectDrawCreate)
	{
		FnDirectDrawCreate = (DDCREATE)GetProcAddress(hInstDD,"DirectDrawCreate");
	}
	
	if (!FnDirectDrawCreate)
	{
		MessageBox (NULL, "Error - direct draw cannot be initialised", NAME, MB_OK|MB_ICONHAND|MB_SYSTEMMODAL);
		return DD_FAIL;
	}
	
	return DD_OK;

}/*GetDDrawServices*/


int FreeDDrawServices()
{
	BOOL bOK;
	
	if (hInstDD)
	{
		bOK = FreeLibrary(hInstDD);
	}
	
	if (!bOK)
	{
		return DD_FAIL;
	}
	
	FnDirectDrawCreate = (DDCREATE)0;

	return DD_OK;

}/*FreeDDrawServices*/


/***** SGL Services ***/

int DDrawInit(HWND hWnd)
{
	int	nRet;

	WritePrivateProfileString("LastError","Error","None","sglhw.ini");
	
	if (!hInstDD)
	{
		nRet = GetDDrawServices();
	
		if (nRet)
		{
			return nRet;
		}
	}

	DDGetDisplayCaps();
	
	/* Direct draw initialisation */
	nRet = DDCreateObject(hWnd);
	
	if (nRet)
	{
		return nRet;
	}
	
	nRet = DDCreatePrimarySurface();

	if (nRet)
	{
		return nRet;
	}
	
	/* Validate lock */
	nRet = DDLock (pFrontBuffer, &pFrontBufferMemory, &dwBufferStride);

	if (nRet)
	{
		return nRet;
	}
	
	DDUnlock(pFrontBuffer);
	
	return DD_OK;

}/*DDrawInit*/

void DDUnlockFrontBuffer()
{
	DDUnlock(pFrontBuffer);
}

int DDGetWindowInfo (HWND hWnd, LPWORD *pMem, LPWORD pStride)
{
	LPPOINT lpPoint;
	RECT rcWindow;
	int StartLine;
	int StartOffset;
	int nRet;
	
	nRet = DDLock (pFrontBuffer, &pFrontBufferMemory, &dwBufferStride);
	
	if (nRet)
	{
		return nRet;
	}
	
	/* DDUnlock(pFrontBuffer); */
	
	/* Get Client Rect and calculate start address of window */
	GetClientRect (hWnd, &rcWindow);
	
	/* Convert to screen coord's */
	lpPoint = (LPPOINT)&rcWindow;
	ClientToScreen (hWnd, lpPoint);
	
	/* Calculate start address of window client area */
	StartLine = rcWindow.top;
	StartOffset = rcWindow.left;
	
	StartLine *= dwBufferStride;
	StartOffset *= 2; /* 16bpp */
	 
	pFrontBufferMemory+= StartLine;
	pFrontBufferMemory+= StartOffset;
	(DWORD)pFrontBufferMemory &= (DWORD)0xFFFFFFFCL; /* Dword align */

	*pMem = (LPWORD)pFrontBufferMemory;
	*pStride = (WORD)dwBufferStride;
	
	return 0;

}/*DDGetWindowInfo*/


int DDGetDisplayCaps()
{
	int nRet;
	BOOL bNewObj=FALSE;
	
	if (!hInstDD)
	{
		nRet = GetDDrawServices();
		
		if (nRet)
		{
			return nRet;
		}
	}
	
	if (!pDDObject)
	{
		hresult = FnDirectDrawCreate(NULL, (LPDIRECTDRAW FAR *)&pDDObject, NULL);
		
		if (hresult != DD_OK)
		{
			pDDObject = NULL;
			ReportDDrawError(hresult);
			return DD_FAIL;
		}
		
		bNewObj=TRUE;
	}
	
	ZeroMemory(&DDDriverCaps, sizeof(DDDriverCaps));
	DDDriverCaps.dwSize = sizeof(DDDriverCaps);
	
	ZeroMemory(&DDHELCaps, sizeof(DDHELCaps));
	DDHELCaps.dwSize = sizeof(DDHELCaps);
	
	hresult = IDirectDraw_GetCaps(pDDObject, &DDDriverCaps, &DDHELCaps);
	
	if (bNewObj)
	{
		IDirectDraw_Release(pDDObject);
		pDDObject = NULL;
	}
	
	if (hresult != DD_OK)
	{
		ReportDDrawError(hresult);
		return DD_FAIL;
	}
	
	bDisplayCapsValid = TRUE;
	
#if REPORT_DEVICE_CAPS

	if (bNewObj)
	{
	//	OutputDebugString("*** driver caps ***\n");
		ReportCaps(DDCAPS_3D)
		ReportCaps(DDCAPS_ALIGNBOUNDARYDEST)
		ReportCaps(DDCAPS_ALIGNSIZEDEST)
		ReportCaps(DDCAPS_ALIGNBOUNDARYSRC)
		ReportCaps(DDCAPS_ALIGNSIZESRC)
		ReportCaps(DDCAPS_ALIGNSTRIDE)
		ReportCaps(DDCAPS_BANKSWITCHED)
		ReportCaps(DDCAPS_BLT)
		ReportCaps(DDCAPS_BLTCOLORFILL)
		ReportCaps(DDCAPS_BLTQUEUE)
		ReportCaps(DDCAPS_BLTFOURCC)
		ReportCaps(DDCAPS_BLTSTRETCH)
		ReportCaps(DDCAPS_GDI)
		ReportCaps(DDCAPS_OVERLAY)
		ReportCaps(DDCAPS_OVERLAYCANTCLIP)
		ReportCaps(DDCAPS_OVERLAYFOURCC)
		ReportCaps(DDCAPS_OVERLAYSTRETCH)
		ReportCaps(DDCAPS_PALETTE)
		ReportCaps(DDCAPS_READSCANLINE)
		ReportCaps(DDCAPS_STEREOVIEW)
		ReportCaps(DDCAPS_VBI)
		ReportCaps(DDCAPS_ZBLTS)
		ReportCaps(DDCAPS_ZOVERLAYS)
		ReportCaps(DDCAPS_COLORKEY)
		ReportCaps(DDCAPS_ALPHA)
		ReportCaps(DDCAPS_NOHARDWARE)
	}
#endif

	return DD_OK;

}/*DDGetDisplayCaps*/


int DDCreateObject(HWND hWnd)
{
	
	if (!IsWindow(hWnd))
	{
		return DD_FAIL;
	}
	
	if (!pDDObject)
	{
		hresult = FnDirectDrawCreate(NULL, (LPDIRECTDRAW FAR *)&pDDObject, NULL);
		
		if (hresult != DD_OK)
		{
			pDDObject = NULL;
			ReportDDrawError(hresult);
			return DD_FAIL;
		}
	}
	
	if (hresult != DD_OK)
	{
		pDDObject = 0;
		ReportDDrawError(hresult);
		return DD_FAIL;
	}
	
	/* set cpooperative level */
	hresult = IDirectDraw_SetCooperativeLevel (pDDObject, hWnd, DDSCL_NORMAL);

	if (hresult != DD_OK)
	{
	 	ReportDDrawError(hresult);
		return DD_FAIL;
	}

	return DD_OK;

}/*DDCreateObject*/



int DDCreatePrimarySurface()
{
	
	ZeroMemory(&PrimarySurfaceInfo, sizeof(PrimarySurfaceInfo));
	PrimarySurfaceInfo.dwSize = sizeof(PrimarySurfaceInfo);
	PrimarySurfaceInfo.dwFlags = DDSD_CAPS;
	PrimarySurfaceInfo.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
	
	hresult = IDirectDraw_CreateSurface(pDDObject, &PrimarySurfaceInfo, &pFrontBuffer, NULL);
	
	if (hresult != DD_OK)
	{
		ReportDDrawError(hresult);
		return DD_FAIL;
	}

    return DD_OK;

}/*DDCreatePrimarySurface*/


/* Returns a physical colour in 16 bit graphics buffer fromat. */
/* Note : MS don't support 24 or 32 bit in ddraw flipping modes, so we won't either */
WORD GetPhysicalColour(BYTE bRed, BYTE bGreen, BYTE bBlue)
{
	WORD wColor;
	
	/* 16 bit mode : rrrr rggg gggb bbbb */
	bRed>>=3;
	bGreen>>=2;
	bBlue>>=3;

	wColor = 0;
	wColor |= ((WORD)bRed<<11);
	wColor |= ((WORD)bGreen<<5);
	wColor |= (WORD)bBlue;

	return wColor;

}/*GetPhysicalColour*/



void ReportSurfaceCaps(DWORD dwCaps)
{
//	OutputDebugString("*** surface caps ***\n");
	ReportDDSCaps(DDSCAPS_3D)
	ReportDDSCaps(DDSCAPS_ALPHA)
	ReportDDSCaps(DDSCAPS_BACKBUFFER)
	ReportDDSCaps(DDSCAPS_COMPLEX)
	ReportDDSCaps(DDSCAPS_FLIP)
	ReportDDSCaps(DDSCAPS_FRONTBUFFER)
	ReportDDSCaps(DDSCAPS_OFFSCREENPLAIN)
	ReportDDSCaps(DDSCAPS_OVERLAY)
	ReportDDSCaps(DDSCAPS_PALETTE)
	ReportDDSCaps(DDSCAPS_PRIMARYSURFACE)
	ReportDDSCaps(DDSCAPS_PRIMARYSURFACELEFT)
	ReportDDSCaps(DDSCAPS_SYSTEMMEMORY)
	/* ReportDDSCaps(DDSCAPS_TEXTUREMAP) */
	ReportDDSCaps(DDSCAPS_VIDEOMEMORY)
	ReportDDSCaps(DDSCAPS_VISIBLE)
	ReportDDSCaps(DDSCAPS_WRITEONLY)
	ReportDDSCaps(DDSCAPS_ZBUFFER)
	ReportDDSCaps(DDSCAPS_OWNDC)
	ReportDDSCaps(DDSCAPS_LIVEVIDEO)
	ReportDDSCaps(DDSCAPS_HWCODEC)
	ReportDDSCaps(DDSCAPS_MODEX)

}/*ReportSurfaceCaps*/


int DDLock (LPDIRECTDRAWSURFACE pSurface, LPMEMADDRESS pMemAddress, LPDWORD pStride)
{
	DDSURFACEDESC SurfaceInfo;

	/* Lock buffer and get address and stride */
	ZeroMemory(&SurfaceInfo, sizeof(SurfaceInfo));
	SurfaceInfo.dwSize = sizeof(SurfaceInfo);
	SurfaceInfo.dwFlags = DDLOCK_SURFACEMEMORYPTR;	/* Request valid memory pointer */

	hresult = IDirectDrawSurface_Lock (	pSurface,		/* Direct Draw surface */
										NULL,			/* Rectangle NULL=all */
										&SurfaceInfo,	/* Descriptor structure */
										DDLOCK_WAIT,	/* Flags */
										NULL);			/* Event */
	/* Test for SURFACE LOST */
	if (hresult == DDERR_SURFACELOST)
	{
		hresult = IDirectDrawSurface_Restore (pSurface);
		
		if (hresult != DD_OK)
		{
			ReportDDrawError(hresult);
			return FALSE;
		}
		
		hresult = IDirectDrawSurface_Lock (	pSurface,	/* Direct Draw surface */
										NULL,			/* Rectangle NULL=all */
										&SurfaceInfo,	/* Descriptor structure */
										DDLOCK_WAIT,	/* Flags */
										NULL);			/* Event */
	}

	if (hresult != DD_OK)
	{
		ReportDDrawError(hresult);
		return DD_FAIL;
	}

	*pMemAddress = (LPMEM)SurfaceInfo.lpSurface;
	*pStride = (DWORD)SurfaceInfo.lPitch;

	return DD_OK;

}/*DDLock*/


int DDUnlock(LPDIRECTDRAWSURFACE pSurface)
{
	/* Unlock */
	hresult = IDirectDrawSurface_Unlock (	pSurface,	/* Direct Draw Surface */
											NULL);		/* Pointer returned by lock if rqd. */
														/* NULL=all */
	if (hresult != DD_OK)
	{
		ReportDDrawError(hresult);
		return DD_FAIL;
	}

	return DD_OK;

}/*DDUnlock*/


int DDWaitForVSync()
{
	BOOL bIsInVB;
	int nTries=0;

	hresult = IDirectDraw_GetVerticalBlankStatus (pDDObject, &bIsInVB);

	if (hresult != DD_OK)
	{
		ReportDDrawError(hresult);
		return DD_FAIL;
	}

	if (bIsInVB)
	{
		hresult = IDirectDraw_WaitForVerticalBlank(pDDObject, DDWAITVB_BLOCKEND, (HANDLE) 0);
	}
	else
	{
		hresult = IDirectDraw_WaitForVerticalBlank(pDDObject, DDWAITVB_BLOCKBEGIN, (HANDLE) 0);
	}

	/* VSync has occurred */

	if (hresult != DD_OK)
	{
		ReportDDrawError(hresult);
		return DD_FAIL;
	}

	return DD_OK;

}/*DDWaitForVSync*/


int DDInVerticalBlank(LPBOOL pbIsInVB)
{

	hresult = IDirectDraw_GetVerticalBlankStatus (pDDObject, pbIsInVB);

    if (hresult != DD_OK)
	{
		ReportDDrawError(hresult);
		return DD_FAIL;
	}

	return DD_OK;

}/*DDInVerticalBlank*/


void DDEnd()
{
	/* Allow rendering to end with 100mS delay */
	Sleep(100);
	
	if (pFrontBuffer)
	{
		DDWaitForVSync();
		
		hresult = IDirectDrawSurface_Release(pFrontBuffer);

		if (hresult != DD_OK)
		{
			ReportDDrawError(hresult);
		}
		
		DDWaitForVSync();
		pFrontBuffer = NULL;
	}
	
	DDWaitForVSync();
	
	if (pDDObject)
	{
		hresult = IDirectDraw_Release(pDDObject);
		
		if (hresult != DD_OK)
		{
			ReportDDrawError(hresult);
		}

		pDDObject = NULL;
	}
	
	FreeDDrawServices();
	
}/*DDEnd*/


/* Surface must be unlocked for this to work */
int DDColourFill(BYTE bRed, BYTE bGreen, BYTE bBlue, LPDIRECTDRAWSURFACE pSurface)
{
	DDBLTFX BltInfo;
	WORD wFillColor;
	
	wFillColor = GetPhysicalColour(bRed, bGreen, bBlue);

	#if WRITE_DIRECT

		/* Fill the surface by writing directly to surface memory */
		error = DDWriteDirect(wFillColor, pSurface);

	#else

		ZeroMemory(&BltInfo, sizeof(BltInfo));
		BltInfo.dwSize = sizeof(BltInfo);
		BltInfo.dwFillColor = (WORD)wFillColor; /* physical colour */
	
		hresult = IDirectDrawSurface_Blt
						(	pSurface,						/* Direct Draw destination surface */
							NULL,							/* Dest rect */
							NULL,							/* Direct Draw source surface */
							NULL,							/* Source Rect */
							DDBLT_COLORFILL | DDBLT_WAIT,	/* Flags */
							&BltInfo);						/* Blt info structure */
	
		if (hresult != DD_OK)
		{
			ReportDDrawError(hresult);
			return DD_FAIL;
		}

	#endif
	
	return DD_OK;

}/*DDColourFill*/


int DDWriteDirect(WORD wFillColor, LPDIRECTDRAWSURFACE pSurface)
{
	LPMEM MemAddress;
	DWORD dwStride;
	int x,y;
	short * p;
	DWORD dwLineAddr;
	DWORD dwPixelAddr;
	int nRet;

	/* Fill the surface by writing directly to surface memory */
	
	nRet =  DDLock (pSurface, &MemAddress, &dwStride);

	if (nRet)
	{
		return nRet;
	}

	dwLineAddr = (DWORD)MemAddress;
	
	for (y=0; y<480; y++)
	{
		dwPixelAddr = dwLineAddr;
		
		for (x=0; x<640; x++)
		{
			p = (short*) dwPixelAddr;
			*p = (short)wFillColor;
			
			dwPixelAddr += 2;
		}
		dwLineAddr += dwStride;
	}
	
	nRet =  DDUnlock (pSurface);

	return nRet;
}

void ReportDDrawError(HRESULT err)
{
	char ErrorStr[128];
	char ErrorStr2[128];
	char * ErrorText;

	/* HRESULT code fields are defined in winerror.h */
	hresultSeverity = HRESULT_SEVERITY(err);
	hresultFacility = HRESULT_FACILITY(err);
	hresultCode = HRESULT_CODE(err);

	if (hresultSeverity == SEVERITY_SUCCESS)
	{
		/* No error */
		return;
	}

#ifdef REPORT_ALL_ERRORS

	/* Test for Direct Draw error codes in ddraw.h */
	switch (err)
	{
		/* Macro : #define TEXT_ERR(x) case x : ErrorText = #x; break; */
		
		TEXT_ERR(DDERR_CANNOTATTACHSURFACE)
		TEXT_ERR(DDERR_CANNOTDETACHSURFACE)
		TEXT_ERR(DDERR_CURRENTLYNOTAVAIL)
		TEXT_ERR(DDERR_EXCEPTION)
		TEXT_ERR(DDERR_GENERIC)
		TEXT_ERR(DDERR_HEIGHTALIGN)
		TEXT_ERR(DDERR_INCOMPATIBLEPRIMARY)
		TEXT_ERR(DDERR_INVALIDPARAMS)
		TEXT_ERR(DDERR_INVALIDPIXELFORMAT)
		TEXT_ERR(DDERR_INVALIDRECT)
		TEXT_ERR(DDERR_LOCKEDSURFACES)
		TEXT_ERR(DDERR_NO3D)
		TEXT_ERR(DDERR_NOALPHAHW)
		TEXT_ERR(DDERR_NOCLIPLIST)
		TEXT_ERR(DDERR_NOCOLORCONVHW)
		TEXT_ERR(DDERR_NOCOOPERATIVELEVELSET)
		TEXT_ERR(DDERR_NOCOLORKEY)
		TEXT_ERR(DDERR_NOCOLORKEYHW)
		TEXT_ERR(DDERR_NODIRECTDRAWSUPPORT)
		TEXT_ERR(DDERR_NOEXCLUSIVEMODE)
		TEXT_ERR(DDERR_NOFLIPHW)
		TEXT_ERR(DDERR_NOGDI)
		TEXT_ERR(DDERR_NOMIRRORHW)
		TEXT_ERR(DDERR_NOTFOUND)
		TEXT_ERR(DDERR_NOOVERLAYHW)
		TEXT_ERR(DDERR_NORASTEROPHW)
		TEXT_ERR(DDERR_NOSTRETCHHW)
		TEXT_ERR(DDERR_NOT4BITCOLOR)
		TEXT_ERR(DDERR_NOT4BITCOLORINDEX)
		TEXT_ERR(DDERR_NOT8BITCOLOR)
		TEXT_ERR(DDERR_NOTEXTUREHW)
		TEXT_ERR(DDERR_NOVSYNCHW)
		TEXT_ERR(DDERR_NOZBUFFERHW)
		TEXT_ERR(DDERR_NOZOVERLAYHW)
		TEXT_ERR(DDERR_OUTOFCAPS)
		TEXT_ERR(DDERR_OUTOFMEMORY)
		TEXT_ERR(DDERR_OVERLAYCANTCLIP)
		TEXT_ERR(DDERR_OVERLAYCOLORKEYONLYONEACTIVE)
		TEXT_ERR(DDERR_PALETTEBUSY)
		TEXT_ERR(DDERR_COLORKEYNOTSET)
		TEXT_ERR(DDERR_SURFACEALREADYATTACHED)
		TEXT_ERR(DDERR_SURFACEALREADYDEPENDENT)
		TEXT_ERR(DDERR_SURFACEBUSY)
		TEXT_ERR(DDERR_SURFACEISOBSCURED)
		TEXT_ERR(DDERR_SURFACELOST)
		TEXT_ERR(DDERR_SURFACENOTATTACHED)
		TEXT_ERR(DDERR_TOOBIGHEIGHT)
		TEXT_ERR(DDERR_TOOBIGSIZE)
		TEXT_ERR(DDERR_TOOBIGWIDTH)
		TEXT_ERR(DDERR_UNSUPPORTED)
		TEXT_ERR(DDERR_UNSUPPORTEDMASK)
		TEXT_ERR(DDERR_VERTICALBLANKINPROGRESS)
		TEXT_ERR(DDERR_WASSTILLDRAWING)
		TEXT_ERR(DDERR_XALIGN)
		TEXT_ERR(DDERR_INVALIDDIRECTDRAWGUID)
		TEXT_ERR(DDERR_DIRECTDRAWALREADYCREATED)
		TEXT_ERR(DDERR_NODIRECTDRAWHW)
		TEXT_ERR(DDERR_PRIMARYSURFACEALREADYEXISTS)
		TEXT_ERR(DDERR_NOEMULATION)
		TEXT_ERR(DDERR_REGIONTOOSMALL)
		TEXT_ERR(DDERR_CLIPPERISUSINGHWND)
		TEXT_ERR(DDERR_NOCLIPPERATTACHED)
		TEXT_ERR(DDERR_NOHWND)
		TEXT_ERR(DDERR_HWNDSUBCLASSED)
		TEXT_ERR(DDERR_HWNDALREADYSET)
		TEXT_ERR(DDERR_NOPALETTEATTACHED)
		TEXT_ERR(DDERR_NOPALETTEHW)
		TEXT_ERR(DDERR_BLTFASTCANTCLIP)
		TEXT_ERR(DDERR_NOBLTHW)
		TEXT_ERR(DDERR_NODDROPSHW)
		TEXT_ERR(DDERR_OVERLAYNOTVISIBLE)
		TEXT_ERR(DDERR_NOOVERLAYDEST)
		TEXT_ERR(DDERR_INVALIDPOSITION)
		TEXT_ERR(DDERR_NOTAOVERLAYSURFACE)
		TEXT_ERR(DDERR_EXCLUSIVEMODEALREADYSET)
		TEXT_ERR(DDERR_NOTFLIPPABLE)
		TEXT_ERR(DDERR_CANTDUPLICATE)
		TEXT_ERR(DDERR_NOTLOCKED)
		TEXT_ERR(DDERR_CANTCREATEDC)
		TEXT_ERR(DDERR_NODC)
		TEXT_ERR(DDERR_WRONGMODE)
		TEXT_ERR(DDERR_IMPLICITLYCREATED)
		TEXT_ERR(DDERR_NOTPALETTIZED)
		TEXT_ERR(DDERR_UNSUPPORTEDMODE)
		TEXT_ERR(E_UNEXPECTED)
		TEXT_ERR(E_NOINTERFACE)
		TEXT_ERR(E_POINTER)
		TEXT_ERR(E_HANDLE)
		TEXT_ERR(E_ABORT)
		TEXT_ERR(E_ACCESSDENIED)

		default :
		{
			sprintf(ErrorStr2,"Error not recognised : 0x%08Xl\n",err);
			ErrorText = ErrorStr2;
		}
	}

	strcpy(ErrorStr,"Direct Draw Error : ");
	strcat(ErrorStr,ErrorText);
	strcat(ErrorStr,"\n");
	#if DEBUG
//	OutputDebugString(ErrorStr);
	#endif
	
	#if DIALOG_ERRORS
		MessageBox (NULL, ErrorStr, NAME, MB_OK|MB_ICONHAND|MB_SYSTEMMODAL);
	#endif

	WritePrivateProfileString("LastError","Error",ErrorStr,"sglhw.ini");

#endif

}/*ReportDDrawError*/

/* ddmem.c */

