[win32] Converted winsurf.cpp to C. Fixes and additions for windowed rendering.
This commit is contained in:
436
glide3x/h5/glide3/src/winsurf.c
Normal file
436
glide3x/h5/glide3/src/winsurf.c
Normal 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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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, ®ion, 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(®ion, 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");
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user