[win32] Converted winsurf.cpp to C. Fixes and additions for windowed rendering.

This commit is contained in:
koolsmoky
2004-01-11 18:29:29 +00:00
parent a5e24cc268
commit 9110ab17f1
2 changed files with 436 additions and 450 deletions

View File

@@ -0,0 +1,436 @@
/*
** This sets up Windowed rendering
**
** For windowed rendering call grSstWinOpenExt with GR_RESOLUTION_NONE.
*/
#include "3dfx.h"
#include "fxdll.h"
#include "glide.h"
#include "fxglide.h"
#include "fxcmd.h"
#include "gsfc.h"
#include <ddraw.h>
static LPDIRECTDRAW lpDDraw1 = 0;
static LPDIRECTDRAW2 lpDDraw2 = 0;
static LPDIRECTDRAWCLIPPER lpClipper = 0;
static LPDIRECTDRAWSURFACE lpPrimSurf = 0;
static LPDIRECTDRAWSURFACE lpColSurf = 0;
static LPDIRECTDRAWSURFACE lpAuxSurf = 0;
static LPDIRECTDRAWSURFACE lpTexSurf0 = 0;
static LPDIRECTDRAWSURFACE lpTexSurf1 = 0;
static HWND thehWnd = 0;
static DWORD surfWidth = 0;
static DWORD surfHeight = 0;
typedef struct _enumInfoStruct {
GUID guid;
HMONITOR hmon;
} EnumInfo;
static BOOL FAR PASCAL
ddEnumCbEx( GUID FAR *guid, LPSTR desc, LPSTR name, LPVOID ctx, HMONITOR hmon )
{
EnumInfo* pEnumInfo = (EnumInfo*)ctx;
BOOL rv = DDENUMRET_OK;
if(pEnumInfo->hmon == hmon) {
if ( guid ) CopyMemory(&pEnumInfo->guid, guid, sizeof(GUID));
rv = DDENUMRET_CANCEL;
}
return rv;
}
/* This will release the context, and release the surfaces, and destroy the DDRAW objects */
extern void _grReleaseWindowSurface(GrContext_t ctx)
{
GDBG_INFO(80, "_grReleaseWindowSurface\n");
/* Release Context */
grSurfaceReleaseContext(ctx);
GDBG_INFO(80, "Released context!\n");
/* Now release all the surfaces */
if (lpClipper)
{
IDirectDrawSurface2_Release( lpClipper );
lpClipper = 0;
}
if (lpTexSurf1)
{
IDirectDrawSurface2_Release( lpTexSurf1 );
lpTexSurf1 = 0;
}
if (lpTexSurf0)
{
IDirectDrawSurface2_Release( lpTexSurf0 );
lpTexSurf0 = 0;
}
if (lpAuxSurf)
{
IDirectDrawSurface2_Release( lpAuxSurf );
lpAuxSurf = 0;
}
if (lpColSurf)
{
IDirectDrawSurface2_Release( lpColSurf );
lpColSurf = 0;
}
if (lpPrimSurf)
{
IDirectDrawSurface2_Release( lpPrimSurf );
lpPrimSurf = 0;
}
GDBG_INFO(80, "All surfaces released\n");
/* And the DirectDraw objects */
if (lpDDraw2)
{
IDirectDraw2_Release( lpDDraw2 );
lpDDraw2 = NULL;
}
if (lpDDraw1)
{
IDirectDraw_Release( lpDDraw1 );
lpDDraw1 = NULL;
}
GDBG_INFO(80, "Direct Draw released\n");
}
#define GDBG_DDERR(hResult) \
switch ( hResult ) \
{ \
case DDERR_INVALIDOBJECT: \
GDBG_INFO(80, "DERR_INVALIDOBJECT\n"); \
break; \
case DDERR_INVALIDPARAMS: \
GDBG_INFO(80, "DDERR_INVALIDPARAMS\n"); \
break; \
case DDERR_OUTOFVIDEOMEMORY: \
GDBG_INFO(80, "DDERR_OUTOFVIDEOMEMORY\n"); \
break; \
case DDERR_NODIRECTDRAWHW: \
GDBG_INFO(80, "DDERR_NODIRECTDRAWHW\n"); \
break; \
case DDERR_NOCOOPERATIVELEVELSET: \
GDBG_INFO(80, "DDERR_NOCOOPERATIVELEVELSET\n"); \
break; \
case DDERR_INVALIDCAPS: \
GDBG_INFO(80, "DDERR_INVALIDCAPS\n"); \
break; \
case DDERR_INVALIDPIXELFORMAT: \
GDBG_INFO(80, "DDERR_INVALIDPIXELFORMAT\n"); \
break; \
case DDERR_NOALPHAHW: \
GDBG_INFO(80, "DDERR_NOALPHAHW\n"); \
break; \
case DDERR_NOFLIPHW: \
GDBG_INFO(80, "DDERR_NOFLIPHW\n"); \
break; \
case DDERR_NOZBUFFERHW: \
GDBG_INFO(80, "DDERR_NOZBUFFERHW\n"); \
break; \
case DDERR_NOEXCLUSIVEMODE: \
GDBG_INFO(80, "DDERR_NOEXCLUSIVEMODE\n"); \
break; \
case DDERR_OUTOFMEMORY: \
GDBG_INFO(80, "DDERR_OUTOFMEMORY\n"); \
break; \
case DDERR_PRIMARYSURFACEALREADYEXISTS: \
GDBG_INFO(80, "DDERR_PRIMARYSURFACEALREADYEXISTS\n"); \
break; \
case DDERR_NOEMULATION: \
GDBG_INFO(80, "DDERR_NOEMULATION\n"); \
break; \
case DDERR_INCOMPATIBLEPRIMARY: \
GDBG_INFO(80, "DDERR_INCOMPATIBLEPRIMARY\n"); \
break; \
}
/* This will create our DirectDraw surfaces and create the context */
extern GrContext_t _grCreateWindowSurface(FxU32 hWnd,
GrColorFormat_t format,
GrOriginLocation_t origin,
GrPixelFormat_t pixelformat,
int nAuxBuffer)
{
GrContext_t ctx;
GrGC *gc;
RECT clientRect;
LPGUID ddGuid = 0;
HMODULE ddraw = 0;
DDSURFACEDESC ddsd;
HRESULT hResult;
FxI32 bpp = 16;
GDBG_INFO(80, "_grCreateWindowSurface( 0x%x, %d, %d, %d, %d )\n",
hWnd, format, origin, pixelformat, nAuxBuffer);
/* Allocate a context */
ctx = grSurfaceCreateContext(GR_SURFACECONTEXT_WINDOWED);
gc = (GrGC *)ctx;
thehWnd = (HWND) hWnd;
GetClientRect(thehWnd, &clientRect);
surfWidth = clientRect.right - clientRect.left;
surfHeight = clientRect.bottom - clientRect.top;
GDBG_INFO(80, "surfWidth = %d\n", surfWidth);
GDBG_INFO(80, "surfHeight = %d\n", surfHeight);
ddraw = GetModuleHandle( "ddraw.dll" );
if ( ddraw ) {
LPDIRECTDRAWENUMERATEEXA ddEnumEx;
ddEnumEx = (LPDIRECTDRAWENUMERATEEXA)GetProcAddress( ddraw, "DirectDrawEnumerateExA" );
if ( ddEnumEx ) {
EnumInfo enumInfo;
ZeroMemory(&enumInfo, sizeof(enumInfo));
ZeroMemory(&enumInfo.guid, sizeof(GUID));
enumInfo.hmon = (HMONITOR)gc->bInfo->hMon;
ddEnumEx( ddEnumCbEx, &enumInfo, DDENUM_ATTACHEDSECONDARYDEVICES );
ddGuid = &enumInfo.guid;
GDBG_INFO(80, "GUID %d\n", ddGuid);
}
}
/* Create DirectDraw */
if (DirectDrawCreate( ddGuid, &lpDDraw1, NULL ) != DD_OK) {
GDBG_INFO(80, "DDraw Obj Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
GDBG_INFO(80, "DDraw Obj created!\n");
/* Get us a DirectDraw2 interface */
if (IDirectDraw_QueryInterface( lpDDraw1, &IID_IDirectDraw2, (LPVOID*)&lpDDraw2 ) != DD_OK) {
GDBG_INFO(80, "DDraw2 Obj Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
GDBG_INFO(80, "DDraw2 Obj created!\n");
/* Verify screen pixel format */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof( ddsd );
if (IDirectDraw2_GetDisplayMode(lpDDraw2, &ddsd) != DD_OK) {
GDBG_INFO(80, "Couldn't get Display Mode!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
switch (pixelformat) {
case GR_PIXFMT_ARGB_8888:
case GR_PIXFMT_AA_2_ARGB_8888:
case GR_PIXFMT_AA_4_ARGB_8888:
case GR_PIXFMT_AA_8_ARGB_8888:
bpp = 32;
if (IS_NAPALM(gc->bInfo->pciInfo.deviceID)) {
if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32) {
GDBG_INFO(80, "Display is not in 32bpp format!\n");
_grReleaseWindowSurface(ctx);
MessageBox( thehWnd, "Desktop must be set to 32bbp!", "ERROR", MB_OK);
return 0;
}
} else {
GDBG_INFO(80, "Cannot render in 32bpp format!\n");
_grReleaseWindowSurface(ctx);
MessageBox( thehWnd, "Cannot render in 32bpp format!", "ERROR", MB_OK);
return 0;
}
break;
default:
bpp = 16;
if (ddsd.ddpfPixelFormat.dwRGBBitCount < 16) {
GDBG_INFO(80, "Display is not in 16bpp format!\n");
_grReleaseWindowSurface(ctx);
MessageBox( thehWnd, "Desktop must be set to 16bbp!", "ERROR", MB_OK);
return 0;
}
}
/* Set the Coop level to normal */
if (IDirectDraw2_SetCooperativeLevel(lpDDraw2, thehWnd, DDSCL_NORMAL) != DD_OK) {
GDBG_INFO(80, "SetCooperativeLevel Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
/* Move all of the pieces of surface memory on the video card
* to a contiguous block to make the largest chunk of free
* memory available.
*/
/* Works only for DDSCL_EXCLUSIVE.
if (IDirectDraw2_Compact(lpDDraw2) != DD_OK) {
GDBG_INFO(80, "Compact Failed!\n");
}*/
/* Now create us a Primary surface */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hResult = IDirectDraw2_CreateSurface( lpDDraw2, &ddsd, &lpPrimSurf, 0 );
if (hResult != DD_OK) {
GDBG_INFO(80, "Primary Surface Create Failed!\n");
GDBG_DDERR(hResult);
_grReleaseWindowSurface(ctx);
return 0;
}
/* Setup Clipper */
if (IDirectDraw2_CreateClipper( lpDDraw2, 0, &lpClipper, 0 ) != DD_OK) {
GDBG_INFO(80, "Clipper Failted!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
if (IDirectDrawClipper_SetHWnd( lpClipper, 0, thehWnd ) != DD_OK) {
GDBG_INFO(80, "Clipper Failted!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
if (IDirectDrawSurface2_SetClipper( lpPrimSurf, lpClipper ) != DD_OK) {
GDBG_INFO(80, "Clipper Failted!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
/* Setup Color Surface */
if (!lpColSurf) {
GDBG_INFO(80, "Setting up Color Surface\n");
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY;
ddsd.dwWidth = surfWidth;
ddsd.dwHeight = surfHeight;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwRGBBitCount = bpp;
hResult = IDirectDraw2_CreateSurface( lpDDraw2, &ddsd, &lpColSurf, 0 );
if (hResult != DD_OK) {
GDBG_INFO(80, "Colour Surface Create Failed!\n");
GDBG_DDERR(hResult);
_grReleaseWindowSurface(ctx);
return 0;
}
}
/* Setup Aux Surface */
if (nAuxBuffer) {
GDBG_INFO(80, "Setting up Aux Surface\n");
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY;
ddsd.dwWidth = surfWidth;
ddsd.dwHeight = surfHeight;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwRGBBitCount = bpp;
hResult = IDirectDraw2_CreateSurface( lpDDraw2, &ddsd, &lpAuxSurf, 0 );
if (hResult != DD_OK) {
GDBG_INFO(80, "Aux Surface Create Failed!\n");
GDBG_DDERR(hResult);
_grReleaseWindowSurface(ctx);
return 0;
}
}
/* Setup Texture Surface */
GDBG_INFO(80, "Setting up Texture Surface\n");
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY;
/* XXX [koolsmoky] We're screwed if the texture is larger than 1024*1024 (Napalm). */
ddsd.dwWidth = 1024;
ddsd.dwHeight = 1024;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwRGBBitCount = bpp;
hResult = IDirectDraw2_CreateSurface( lpDDraw2, &ddsd, &lpTexSurf0, 0 );
if (hResult != DD_OK) {
GDBG_INFO(80, "Tex Surface0 Create Failed!\n");
GDBG_DDERR(hResult);
_grReleaseWindowSurface(ctx);
return 0;
}
if (gc->num_tmu == 2) {
hResult = IDirectDraw2_CreateSurface( lpDDraw2, &ddsd, &lpTexSurf1, 0 );
if (hResult != DD_OK) {
GDBG_INFO(80, "Tex Surface1 Create Failed!\n");
GDBG_DDERR(hResult);
/* XXX [koolsmoky] Single TMU if we're out of video memory. */
GDBG_INFO(80, "Falling back to single TMU\n");
lpTexSurf1 = 0;
gc->num_tmu = 1;
}
}
/* Select the Context */
grSelectContext(ctx);
/* Set the Render Buffer */
grSurfaceSetRenderingSurface((GrSurface_t*) lpColSurf, FXFALSE);
/* Set the Aux Buffer */
if (nAuxBuffer) grSurfaceSetAuxSurface((GrSurface_t*) lpAuxSurf);
/* Now create the texture buffer0 and 1 */
grSurfaceSetTextureSurface(GR_TMU0, (GrSurface_t*) lpTexSurf0);
if (gc->num_tmu == 2) grSurfaceSetTextureSurface(GR_TMU1, (GrSurface_t*) lpTexSurf1);
/* Set some 'crap' */
gc->grHwnd = hWnd;
gc->grColBuf = gc->state.num_buffers = 2;
gc->grAuxBuf = nAuxBuffer;
gc->grPixelFormat = (int) pixelformat;
gc->chipmask = SST_CHIP_MASK_ALL_CHIPS;
gc->state.color_format = format;
gc->sliCount = 1;
grSstOrigin(origin);
/* Clear the buffers */
grBufferClear( 0x0, 0, 0 );
return ctx;
}
/* This will blit/flip our surfaces */
extern void _grFlipWindowSurface()
{
GDBG_INFO(80, "_grFlipWindowSurface\n");
/* Blit from col to prim */
if (lpPrimSurf && lpColSurf) {
POINT ptClient;
RECT src, dest;
HRESULT hResult;
/* XXX [koolsmoky] Screen will be stretched/shrinked to fit window */
ptClient.x = 0;
ptClient.y = 0;
ClientToScreen(thehWnd, &ptClient);
GetClientRect(thehWnd, &dest);
OffsetRect(&dest, ptClient.x, ptClient.y);
SetRect(&src, 0, 0, surfWidth, surfHeight);
hResult = IDirectDrawSurface_Blt(lpPrimSurf, &dest, lpColSurf, &src, DDBLT_WAIT, NULL);
while(IDirectDrawSurface_GetBltStatus(lpPrimSurf, DDGBS_ISBLTDONE) != DD_OK);
if (hResult != DD_OK) {
GDBG_INFO(80, "Couldn't Blit!\n");
}
}
}

View File

@@ -1,450 +0,0 @@
//
// This sets up Windowed rendering
//
#include <math.h>
extern "C" {
// All this is C Linked
#include <3dfx.h>
#define FX_DLL_DEFINITION
#include <fxdll.h>
#include <glide.h>
#include "fxglide.h"
#include "fxcmd.h"
#include "gsfc.h"
};
/* Begin hacky stuff to enable windowed Glide rendering in Windows */
#include <ddraw.h>
static LPDIRECTDRAW lpDDraw1 = 0;
static LPDIRECTDRAW2 lpDDraw2 = 0;
static LPDIRECTDRAWSURFACE lpPrimSurf = 0;
static LPDIRECTDRAWSURFACE lpColSurf = 0;
static LPDIRECTDRAWSURFACE lpAuxSurf = 0;
static LPDIRECTDRAWSURFACE lpTexSurf0 = 0;
static LPDIRECTDRAWSURFACE lpTexSurf1 = 0;
static HWND thehWnd = 0;
static DWORD surfWidth = 0;
static DWORD surfHeight = 0;
static DWORD screenWidth = 0;
static DWORD screenHeight = 0;
static DWORD bpp = 0;
static BOOL useDDOverlay = FALSE;
static INT WindowPosX = 0;
static INT WindowPosY = 0;
extern "C" void doSplash( void );
extern "C" void _grReleaseWindowSurface(GrContext_t ctx);
#define OVERLAY_COLOUR 0x0D0E0F
/* This will create our DirectDraw surfaces and create the context */
extern "C" GrContext_t _grCreateWindowSurface(FxU32 hWnd,
GrColorFormat_t format,
GrOriginLocation_t origin,
GrPixelFormat_t pixelformat,
int nAuxBuffer)
{
/* Disable this for now */
// return 0;
/* Allocate a context */
GrContext_t ctx = grSurfaceCreateContext(GR_SURFACECONTEXT_WINDOWED);
GrGC *gc = (GrGC *)ctx;
thehWnd = (HWND) hWnd;
screenWidth = GetSystemMetrics(SM_CXSCREEN);
screenHeight = GetSystemMetrics(SM_CYSCREEN);
RECT clientRect;
GetClientRect(thehWnd, &clientRect);
surfWidth = clientRect.right - clientRect.left;
surfHeight = clientRect.bottom - clientRect.top;
switch(pixelformat)
{
case GR_PIXFMT_ARGB_8888:
case GR_PIXFMT_AA_2_ARGB_8888:
case GR_PIXFMT_AA_4_ARGB_8888:
case GR_PIXFMT_AA_8_ARGB_8888:
bpp = 32;
break;
default:
if (0 && _GlideRoot.environment.outputBpp == 32)
{
gc->state.forced32BPP = 16;
bpp = 32;
}
else
bpp = 16;
break;
}
bpp = 16;
/* Now, create DirectDraw */
if ( DirectDrawCreate( NULL, &lpDDraw1, NULL ) != DD_OK)
{
GDBG_INFO(80, "DDraw Obj Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
GDBG_INFO(80, "DDraw Obj created!\n");
/* Get us a DirectDraw2 interface */
if ( lpDDraw1->QueryInterface (IID_IDirectDraw2, (LPVOID*)&lpDDraw2 ) != DD_OK )
{
GDBG_INFO(80, "DDraw2 Obj Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
GDBG_INFO(80, "DDraw2 Obj created!\n");
/* Set the Coop level to normal */
lpDDraw2->SetCooperativeLevel((HWND) hWnd, DDSCL_NORMAL);
/* Now create us a Primary surface */
DDSURFACEDESC ddsd;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY;
if (lpDDraw2->CreateSurface(&ddsd, &lpPrimSurf, NULL) != DD_OK)
{
GDBG_INFO(80, "Primary Surface Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
/* Now create us a Colour surface */
if (useDDOverlay) do
{
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY|DDSCAPS_VIDEOMEMORY;
ddsd.dwWidth = surfWidth;
ddsd.dwHeight = screenHeight;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwRGBBitCount = bpp;
ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
ddsd.ddpfPixelFormat.dwRBitMask = 0xF800;
ddsd.ddpfPixelFormat.dwGBitMask = 0x07E0;
ddsd.ddpfPixelFormat.dwBBitMask = 0x001F;
if (lpDDraw2->CreateSurface(&ddsd, &lpColSurf, NULL) != DD_OK)
{
GDBG_INFO(80, "Overlay Colour Surface Create Failed!\n");
lpColSurf = 0;
break;
}
RECT rectOverlay = {0,0,surfWidth,surfHeight};
RECT rectClient;
DDOVERLAYFX ddofx;
POINT p = {0, 0};
GetClientRect(thehWnd, &rectClient);
ClientToScreen(thehWnd, &p);
rectClient.bottom += p.y;
rectClient.top = p.y;
rectClient.left = p.x;
rectClient.right += p.x;
WindowPosX = p.x;
WindowPosY = p.y;
memset(&ddofx, 0, sizeof(ddofx));
ddofx.dwSize = sizeof(ddofx);
ddofx.dckDestColorkey.dwColorSpaceLowValue = OVERLAY_COLOUR;
ddofx.dckDestColorkey.dwColorSpaceHighValue = OVERLAY_COLOUR;
HRESULT ddrval = lpColSurf->UpdateOverlay(&rectOverlay, lpPrimSurf,
&rectClient,
DDOVER_SHOW|DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE,
&ddofx);
if(ddrval != DD_OK)
{
GDBG_INFO(80, "Unable to update overlay!\n");
lpColSurf->Release();
lpColSurf = 0;
break;
}
/* Now Fill Primary with the col */
DDBLTFX ddbfx;
memset(&ddbfx, 0, sizeof(ddbfx));
ddbfx.dwSize = sizeof(DDBLTFX);
ddbfx.dwFillColor = OVERLAY_COLOUR;
lpPrimSurf->Blt(&rectClient, NULL, &rectClient, DDBLT_COLORFILL|DDBLT_WAIT, &ddbfx);
//lpColSurf->Release();
//lpColSurf = 0;
}
while(0);
if (!lpColSurf)
{
useDDOverlay = FALSE;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM;
ddsd.dwWidth = surfWidth;
ddsd.dwHeight = screenHeight;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwRGBBitCount = bpp;
if (lpDDraw2->CreateSurface(&ddsd, &lpColSurf, NULL) != DD_OK)
{
GDBG_INFO(80, "Colour Surface Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
}
/* Now create us a Aux surface */
if (nAuxBuffer)
{
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM;
ddsd.dwWidth = surfWidth;
ddsd.dwHeight = screenHeight;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwRGBBitCount = bpp;
if (lpDDraw2->CreateSurface(&ddsd, &lpAuxSurf, NULL) != DD_OK)
{
GDBG_INFO(80, "Aux Surface Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
}
/* Now create us a Tex surface */
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM;
ddsd.dwWidth = 2048;
ddsd.dwHeight = 2048;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
ddsd.ddpfPixelFormat.dwRGBBitCount = 16;
if (lpDDraw2->CreateSurface(&ddsd, &lpTexSurf0, NULL) != DD_OK)
{
GDBG_INFO(80, "Tex Surface Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
if (gc->num_tmu == 2)
{
if (lpDDraw2->CreateSurface(&ddsd, &lpTexSurf1, NULL) != DD_OK)
{
GDBG_INFO(80, "Tex Surface Create Failed!\n");
_grReleaseWindowSurface(ctx);
return 0;
}
}
/* Select the Context */
grSelectContext(ctx);
/* Set the Render Buffer */
grSurfaceSetRenderingSurface((GrSurface_t*) lpColSurf, FXFALSE);
/* Set the Aux Buffer */
if (nAuxBuffer) grSurfaceSetAuxSurface((GrSurface_t*) lpAuxSurf);
/* Now create the texture buffer0 and 1 */
grSurfaceSetTextureSurface(GR_TMU0, (GrSurface_t*) lpTexSurf0);
if (gc->num_tmu == 2) grSurfaceSetTextureSurface(GR_TMU1, (GrSurface_t*) lpTexSurf1);
/* Set some 'crap' */
gc->grHwnd = hWnd;
gc->grColBuf = gc->state.num_buffers = 2;
gc->grAuxBuf = nAuxBuffer;
gc->grPixelFormat = (int) pixelformat;
gc->chipmask = SST_CHIP_MASK_ALL_CHIPS;
gc->state.color_format = format;
gc->sliCount = 1;
grSstOrigin(origin);
/* Clear the buffers */
grBufferClear( 0x0, 0, 0 );
return ctx;
}
/* This will blit/flip our surfaces */
extern "C" void _grFlipWindowSurface()
{
// Blit from col to prim
if (lpPrimSurf && lpColSurf)
{
POINT ptClient;
ptClient.x = 0;
ptClient.y = 0;
ClientToScreen(thehWnd, &ptClient);
if (!useDDOverlay)
{
RECT region;
region.bottom = min(surfHeight,screenHeight-ptClient.y);
region.right = min(surfWidth,screenWidth-ptClient.x);
region.top = 0;
region.left = 0;
if (ptClient.y < 0)
{
region.top = -ptClient.y;
ptClient.y = 0;
}
if (ptClient.x < 0)
{
region.left = -ptClient.x;
ptClient.x = 0;
}
if (region.bottom != region.top && region.left != region.right)
lpPrimSurf->BltFast(ptClient.x, ptClient.y, lpColSurf, &region, 0);
}
else
{
/* Need to update the overlay */
if (ptClient.x != WindowPosX || ptClient.y != WindowPosY)
{
WindowPosX = ptClient.x;
WindowPosY = ptClient.y;
RECT region;
RECT rectClient;
region.bottom = min(surfHeight,screenHeight-ptClient.y);
region.right = min(surfWidth,screenWidth-ptClient.x);
region.top = 0;
region.left = 0;
if (ptClient.y < 0)
{
region.top = -ptClient.y;
rectClient.top = 0;
}
else
{
rectClient.top = ptClient.y;
}
if (ptClient.x < 0)
{
region.left = -ptClient.x;
rectClient.left = 0;
}
else
{
rectClient.left = ptClient.x;
}
// Now we need to work out dest width and height
rectClient.right = (region.right-region.left)+rectClient.left;
rectClient.bottom = (region.bottom-region.top)+rectClient.top;
DDOVERLAYFX ddofx;
memset(&ddofx, 0, sizeof(ddofx));
ddofx.dwSize = sizeof(ddofx);
ddofx.dckDestColorkey.dwColorSpaceLowValue = OVERLAY_COLOUR;
ddofx.dckDestColorkey.dwColorSpaceHighValue = OVERLAY_COLOUR;
HRESULT ddrval = lpColSurf->UpdateOverlay(&region, lpPrimSurf,
&rectClient,
DDOVER_SHOW|DDOVER_DDFX|DDOVER_KEYDESTOVERRIDE,
&ddofx);
if(ddrval != DD_OK)
{
GDBG_INFO(80, "Unable to update overlay!\n");
lpColSurf->Release();
lpColSurf = 0;
}
else
{
/* Now Fill Primary with the col */
DDBLTFX ddbfx;
memset(&ddbfx, 0, sizeof(ddbfx));
ddbfx.dwSize = sizeof(DDBLTFX);
ddbfx.dwFillColor = OVERLAY_COLOUR;
lpPrimSurf->Blt(&rectClient, NULL, &rectClient, DDBLT_COLORFILL|DDBLT_WAIT, &ddbfx);
}
}
}
}
}
/* This will release the context, and release the surfaces, and destroy the DDRAW objects */
extern "C" void _grReleaseWindowSurface(GrContext_t ctx)
{
// Release Context
grSurfaceReleaseContext(ctx);
GDBG_INFO(80, "Released context!\n");
// Now release all the surfaces
if (lpTexSurf1)
{
lpTexSurf1->Release();
lpTexSurf1 = 0;
}
if (lpTexSurf0)
{
lpTexSurf0->Release();
lpTexSurf0 = 0;
}
if (lpAuxSurf)
{
lpAuxSurf->Release();
lpAuxSurf = 0;
}
if (lpColSurf)
{
lpColSurf->Release();
lpColSurf = 0;
}
if (lpPrimSurf)
{
lpPrimSurf->Release();
lpPrimSurf = 0;
}
GDBG_INFO(80, "All surfaces released\n");
// And the DirectDraw objects
if (lpDDraw2)
{
lpDDraw2->Release();
lpDDraw2 = NULL;
}
if (lpDDraw1)
{
lpDDraw1->Release();
lpDDraw1 = NULL;
}
GDBG_INFO(80, "Direct Draw released\n");
}