summaryrefslogtreecommitdiff
path: root/3dc/win95/DD_FUNC.CPP
diff options
context:
space:
mode:
authorSteven Fuller <relnev@icculus.org>2001-07-01 00:55:22 +0000
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-20 02:09:04 +0200
commit2186d5f3f95cd74a070a490d899291648d58667a (patch)
tree55241a1afa3e1a22e0b6593a8dead0b703800f44 /3dc/win95/DD_FUNC.CPP
parent218ca90543758a20ac326e444ca0643174ca7384 (diff)
Initial revision
Diffstat (limited to '3dc/win95/DD_FUNC.CPP')
-rw-r--r--3dc/win95/DD_FUNC.CPP2260
1 files changed, 0 insertions, 2260 deletions
diff --git a/3dc/win95/DD_FUNC.CPP b/3dc/win95/DD_FUNC.CPP
deleted file mode 100644
index 3be2188..0000000
--- a/3dc/win95/DD_FUNC.CPP
+++ /dev/null
@@ -1,2260 +0,0 @@
-extern "C" {
-
-#include "3dc.h"
-#include "vramtime.h"
-#include "dxlog.h"
-#include "inline.h"
-#include "scrshot.hpp"
-#include "awTexLd.h" // to set the surface format for Aw gfx dd surface loads
-
-#define UseLocalAssert No
-#include "ourasert.h"
-
-
-// for 640x480x8 experiment
-#define InterlaceExperiment No
-
-
-// In as separate define to debug because we
-// might want to leave it even in a published
-// game.
-#define AllowReboot Yes
-
-// In as #define since there is no
-// obvious good behaviour on failure
-#define CheckForModeXInSubWindow No
-
-// Temporary hack!
-#define NoPalette No
-extern void TimeStampedMessage(char *s);
-
-// Nasty hack to try and fix non-appearance of font
-// on some machines, probably due to there not being
-// enough video memory for the font and BltFast
-// not working outside display memory.
-// According to Roxby, source colour keying won't work
-// on Blt in the Beta 3, so expect a grotty font with this on.
-// PS Source colour keying works, but the font
-// still doesn't appear on my machine in SubWindow
-// mode... Ho hum...
-#define NoBltFastOnFont No
-
-
-// Check to see if video mode is valid
-// and rewrite it if it isn't reported
-
-#define CheckVideoMode No
-
-/*
- Globals
-*/
-
-LPDIRECTDRAW lpDD; // DirectDraw object
-LPDIRECTDRAWSURFACE lpDDSPrimary; // DirectDraw primary surface
-LPDIRECTDRAWSURFACE lpDDSBack; // DirectDraw back surface
-LPDIRECTDRAWSURFACE lpDDSHiddenBack; // for system memory rendering target, stable configuration
-LPDIRECTDRAWPALETTE lpDDPal[MaxPalettes]; // DirectDraw palette
-#if debug || PreBeta
-LPDIRECTDRAWSURFACE lpDDDbgFont; // Debugging font, specific to current video mode
-#endif
-// For SubWindow mode
-LPDIRECTDRAWCLIPPER lpDDClipper;
-// DirectDraw gdi surface
-LPDIRECTDRAWSURFACE lpDDGDI;
-int VideoModeColourDepth;
-long BackBufferPitch;
-// To describe available video hardware
-int TotalVideoMemory;
-int NumAvailableVideoModes;
-VIDEOMODEINFO AvailableVideoModes[MaxAvailableVideoModes];
-// Must be kept up to date with jump table!!!!
-VIDEOMODEINFO EngineVideoModes[] = {
- // Mode 320x200x8
- 320, // width
- 200, // height
- 8, // colour depth (bits per pixel)
- // Mode 320x200x8T
- 320, // width
- 200, // height
- 8, // colour depth (bits per pixel)
- // Mode 320x200x15
- 320, // width
- 200, // height
- 16, // colour depth (bits per pixel)
- // Mode 320x240x8
- 320, // width
- 240, // height
- 8, // colour depth (bits per pixel)
- // Mode 640x480x8
- 640, // width
- 480, // height
- 8, // colour depth (bits per pixel)
- // Mode 640x480x8T
- 640, // width
- 480, // height
- 8, // colour depth (bits per pixel)
- // Mode 640x480x15
- 640, // width
- 480, // height
- 16, // colour depth (bits per pixel)
- // Mode 640x480x24
- 640, // width
- 480, // height
- 24 // colour depth (bits per pixel)
- };
-
-// Flag for backdrop composition
-
-// for 640x480x8 experiment
-#if InterlaceExperiment
-int oddDraw;
-#endif
-
-
-// Surface for Backdrop composition
-LPDIRECTDRAWSURFACE lpDDBackdrop;
-// Pointer into Backdrop DD surface
-unsigned char* BackScreenBuffer;
-// Pitch on auxilliary backdrop surface
-static long BackScreenPitch;
-DDPIXELFORMAT DisplayPixelFormat;
-
-// For locking against other processes, e.g.
-// mouse pointer display
-unsigned char GlobalFlipLock = No;
-
-/* Externs */
-
-extern int VideoMode;
-extern int VideoModeTypeScreen;
-extern int VideoModeType;
-extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
-extern unsigned char *ScreenBuffer;
-extern HWND hWndMain;
-extern unsigned char LPTestPalette[];
-extern unsigned char TestPalette[];
-extern int WindowMode;
-extern WINSCALEXY TopLeftSubWindow;
-extern WINSCALEXY ExtentXYSubWindow;
-extern int WinWidth;
-extern int WinHeight;
-extern int WinLeftX;
-extern int WinTopY;
-extern int WinRightX;
-extern int WinBotY;
-extern int DXMemoryMode;
-extern int RasterisationRequestMode;
-extern int DXMemoryRequestMode;
-extern int WindowRequestMode;
-extern int VideoRequestMode;
-extern int ZBufferRequestMode;
-extern int SoftwareScanDrawRequestMode;
-extern unsigned char AttemptVideoModeRestart;
-extern VIDEORESTARTMODES VideoRestartMode;
-extern BOOL MMXAvailable;
-extern BOOL D3DHardwareAvailable;
-extern int cosine[];
-extern int sine[];
-
-BOOL really_32_bit = 0;
-
-void GenerateDirectDrawSurface()
-
-{
-
- DDCAPS ddcaps;
- HRESULT ddrval;
- DDSURFACEDESC ddsd;
- DDSCAPS ddscaps;
- unsigned char Mode8T;
-
- // Check for combination of a MODEX type mode
- // and SubWindowing
-
- #if AllowReboot
- // THIS MAY NOT WORK!!!
- if (WindowMode == WindowModeSubWindow)
- ddrval = lpDD->SetCooperativeLevel(hWndMain,
- DDSCL_NORMAL);
- else
- ddrval = lpDD->SetCooperativeLevel(hWndMain,
- DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT );
-
- LOGDXERR(ddrval);
- #else
- // More stable even if crashes cannot be booted
- // out of?
- if (WindowMode == WindowModeSubWindow)
- ddrval = lpDD->SetCooperativeLevel(hWndMain,
- DDSCL_NORMAL);
- else
- ddrval = lpDD->SetCooperativeLevel(hWndMain,
- DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX);
- LOGDXERR(ddrval);
- #endif
-
- TimeStampedMessage("Allow reboot thingy");
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x2);
- }
- #else
- return;
- #endif
-
- switch (ScreenDescriptorBlock.SDB_ScreenDepth)
- {
- case VideoModeType_8:
- VideoModeColourDepth = 8;
- Mode8T = No;
- break;
- case VideoModeType_15:
- VideoModeColourDepth = 16;
- Mode8T = No;
- break;
- case VideoModeType_24:
- if (really_32_bit)
- VideoModeColourDepth = 32;
- else
- VideoModeColourDepth = 24;
- Mode8T = No;
- break;
- case VideoModeType_8T:
- VideoModeColourDepth = 8;
- Mode8T = Yes;
- break;
- default:
- VideoModeColourDepth = 16; // default is 16 bit colour
- break;
- }
-
- // Note that SetDisplayMode is now technically part
- // of the DirectDraw2 COM interface, not DirectDraw.
- // However, as long as we do not wish to change
- // monitor refresh rates we do not need to use the
- // DirectDraw2 version or set up a separate secondary
- // DD interface object, which be just plain fiddly.
-
- // MAY NOT WORK LIKE THIS IN SUBWINDOW MODE!!!!
- if (WindowMode == WindowModeFullScreen)
- {
- ddrval = lpDD->SetDisplayMode(ScreenDescriptorBlock.SDB_Width,
- ScreenDescriptorBlock.SDB_Height, VideoModeColourDepth);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- {
- if ((ddrval == DDERR_INVALIDMODE) ||
- (ddrval == DDERR_GENERIC) ||
- (ddrval == DDERR_INVALIDPIXELFORMAT))
- {
- AttemptVideoModeRestart = Yes;
- VideoRestartMode = RestartDisplayModeNotAvailable;
- }
- return;
- }
- #endif
- }
- TimeStampedMessage("after SetDisplayMode");
-
- // Create primary surface and back buffer
- // IMPORTANT!!! Currently no support for triple
- // buffering in SubWindow mode!!!
-
- if (WindowMode == WindowModeSubWindow)
- {
- // Create primary
- memset(&ddsd,0,sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
- ddsd.dwFlags = DDSD_CAPS;
-
- // Request a 3D capable device so that
- // Direct3D accesses will work
- // note primary must be in video memory
- ddsd.ddsCaps.dwCaps = (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE);
-
- ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x41);
- }
- #else
- return;
- #endif
-
- // Create back buffer
- memset(&ddsd,0,sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
- ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
- ddsd.dwHeight = ScreenDescriptorBlock.SDB_Height;
- ddsd.dwWidth = ScreenDescriptorBlock.SDB_Width;
-
- // Request a 3D capable device so that
- // Direct3D accesses will work
- if (DXMemoryMode == SystemMemoryPreferred)
- ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY | DDSCAPS_3DDEVICE);
- else // video memory if possible
- ddsd.ddsCaps.dwCaps= (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE);
-
- ddrval = lpDD->CreateSurface(&ddsd, &lpDDSBack, NULL);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x5);
- }
- #else
- return;
- #endif
-
- // Create clipper objects
- ddrval = lpDD->CreateClipper(0, &lpDDClipper, NULL);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x55);
- }
- #else
- return;
- #endif
-
- ddrval = lpDDClipper->SetHWnd(0, hWndMain);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x51);
- }
- #else
- return;
- #endif
-
- ddrval = lpDDSPrimary->SetClipper(lpDDClipper);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x52);
- }
- #else
- return;
- #endif
- }
- else // default to FullScreen...
- {
- TimeStampedMessage("after 'default to FullScreen'");
- if (DXMemoryMode == VideoMemoryPreferred)
- {
- ddcaps.dwSize = sizeof (ddcaps);
- memset (&ddsd, 0, sizeof (ddsd));
- ddsd.dwSize = sizeof (ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
-
- // Request a 3D capable device so that
- // Direct3D accesses will work
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- DDSCAPS_FLIP |
- DDSCAPS_COMPLEX |
- DDSCAPS_3DDEVICE;
-
- ddsd.dwBackBufferCount = 1;
-
- ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
- LOGDXERR(ddrval);
- TimeStampedMessage("after vm CreateSurface");
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x41);
- }
- #else
- {
- // For dubious modex emulation
- // problem fix and dubious driver
- // cannot change to different bit depths
- // fix.
- // Note that this must be kept up to date!!!!
- if ((ddrval == DDERR_OUTOFVIDEOMEMORY) &&
- ((VideoMode == VideoMode_DX_320x200x8) ||
- (VideoMode == VideoMode_DX_320x200x8T) ||
- (VideoMode == VideoMode_DX_320x240x8) ||
- (VideoMode == VideoMode_DX_320x200x15)))
- {
- AttemptVideoModeRestart = Yes;
- VideoRestartMode = RestartOutOfVidMemForPrimary;
- }
- else if ((ddrval == DDERR_INVALIDMODE) ||
- (ddrval == DDERR_GENERIC) ||
- (ddrval == DDERR_INVALIDPIXELFORMAT))
- {
- AttemptVideoModeRestart = Yes;
- VideoRestartMode = RestartDisplayModeNotAvailable;
- }
-
- return;
- }
- #endif
-
- // get a pointer to the back buffer
- // DO I NEED TO SET A SIZE FIELD HERE??
- // SEEMS I _CAN'T_, ANYWAY...
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
-
- ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps,&lpDDSBack);
- LOGDXERR(ddrval);
- TimeStampedMessage("after vm GetAttachedSurface");
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x5);
- }
- #else
- return;
- #endif
- }
- // assume we want a system memory
- // rendering target, e.g. for MMX
- else
- {
- DDPIXELFORMAT TempPixelFormat;
-
- // Make primary, with back buffer in video memory
- ddcaps.dwSize = sizeof (ddcaps);
- memset (&ddsd, 0, sizeof (ddsd));
- ddsd.dwSize = sizeof (ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
-
- // Request a 3D capable device so that
- // Direct3D accesses will work
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- DDSCAPS_FLIP |
- DDSCAPS_COMPLEX |
- DDSCAPS_3DDEVICE;
-
- ddsd.dwBackBufferCount = 1;
-
- ddrval = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
- LOGDXERR(ddrval);
- TimeStampedMessage("after vm CreateSurface");
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- {
- return;
- }
- #endif
-
- // get a pointer to the back buffer
- // Note that in this configuration the back
- // buffer is hidden from the rendering system,
- // since other configurations do not seem to be
- // stable in ModeX emulation modes
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
-
- ddrval = lpDDSPrimary->GetAttachedSurface(
- &ddscaps,
- &lpDDSHiddenBack);
- LOGDXERR(ddrval);
- TimeStampedMessage("after vm GetAttachedSurface");
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- return;
- #endif
-
- // Save pixel format of primary
- memcpy(&TempPixelFormat, &ddsd.ddpfPixelFormat,
- sizeof(DDPIXELFORMAT));
- TimeStampedMessage("after memcpy 1");
-
- // Create rendering target
- memset(&ddsd,0,sizeof(DDSURFACEDESC));
- ddsd.dwSize = sizeof(DDSURFACEDESC);
- ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
- ddsd.dwHeight = ScreenDescriptorBlock.SDB_Height;
- ddsd.dwWidth = ScreenDescriptorBlock.SDB_Width;
-
- // Ensure rendering target has same format as primary
- memcpy(&ddsd.ddpfPixelFormat, &TempPixelFormat,
- sizeof(DDPIXELFORMAT));
- TimeStampedMessage("after memcpy 2");
-
- // Request a 3D capable device so that
- // Direct3D accesses will work
- ddsd.ddsCaps.dwCaps = (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY | DDSCAPS_3DDEVICE);
-
- ddrval = lpDD->CreateSurface(&ddsd, &lpDDSBack, NULL);
- TimeStampedMessage("after CreateSurface");
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- return;
- #endif
- }
- }
-
- // Set the Colour Palette (paletted modes only)
- #if NoPalette
- #else
- if (VideoModeColourDepth == 8)
- {
-
- TimeStampedMessage("SHOULD NEVER GET HERE");
-
- if (WindowMode == WindowModeSubWindow)
- // Use system palette in a SubWindow case
- {
- // Standard windows RGB + flags palette
- // structure prototyped in various versions
- // (Though not, apparently, others) of objbase.h
- PALETTEENTRY SystemPalette[256];
- // Get system palette via GDI device context
- HDC hdc = GetDC(NULL);
- GetSystemPaletteEntries(hdc, 0, (1 << 8), SystemPalette);
- // Restrict system to two palette entries only.
- SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
- ReleaseDC(NULL, hdc);
-
- // Flag system palette entries
- // Will this work?
- // I sure hope so...
- {
- int i;
- // Take all but 20 basic entries for our
- // greedy little sod of a game window
- for (i=0; i<1; i++)
- SystemPalette[i].peFlags = PC_EXPLICIT;
- for (i=1; i<(256-1); i++)
- {
- SystemPalette[i].peRed = LPTestPalette[i*4];
- SystemPalette[i].peGreen = LPTestPalette[(i*4)+1];
- SystemPalette[i].peBlue = LPTestPalette[(i*4)+2];
- SystemPalette[i].peFlags = PC_RESERVED;
- }
- for (i=(256-1); i<256; i++)
- SystemPalette[i].peFlags = PC_EXPLICIT;
- }
-
- // Create the palette within DirectDraw, using
- // DD palette initialisation rather than ours
- ddrval = lpDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256,
- SystemPalette, &lpDDPal[0], NULL);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x7);
- }
- #else
- return;
- #endif
-
- // Set palette on both buffers
- ddrval = lpDDSBack->SetPalette(lpDDPal[0]);
- LOGDXERR(ddrval);
- ddrval = lpDDSPrimary->SetPalette(lpDDPal[0]);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- return;
- #endif
- // Save palette in internal format for
- // use later
- // Out because it causes problems with
- // window mode swapping.
- // ConvertDDToInternalPalette((unsigned char*) SystemPalette, TestPalette, 256);
- }
- else // default to FullScreen
- {
- if ((ScreenDescriptorBlock.SDB_Flags
- & SDB_Flag_Raw256) || (Mode8T))// full 256 colours
- ddrval = lpDD->CreatePalette((DDPCAPS_8BIT | DDPCAPS_ALLOW256),
- (LPPALETTEENTRY)(LPTestPalette),
- &lpDDPal[0],
- NULL);
- else // default is 222
- ddrval = lpDD->CreatePalette((DDPCAPS_8BIT),
- (LPPALETTEENTRY)(LPTestPalette),
- &lpDDPal[0],
- NULL);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x7);
- }
- #else
- return;
- #endif
-
- ddrval = lpDDSPrimary->SetPalette(lpDDPal[0]);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x8);
- }
- #else
- return;
- #endif
-
-// Set palette on BOTH buffers to work around
-// bug in Direct3D initialisation!!!
- ddrval = lpDDSBack->SetPalette(lpDDPal[0]);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(0x8);
- }
- #else
- return;
- #endif
- }
- }
- #endif // for NoPalette
-
- // Get the surface desc for AW DDSurface loads
-
- memset(&ddsd,0,sizeof ddsd);
- ddsd.dwSize = sizeof ddsd;
- ddrval = lpDDSPrimary->GetSurfaceDesc(&ddsd);
- LOGDXERR(ddrval);
- GLOBALASSERT(DD_OK==ddrval);
- TimeStampedMessage("after memset");
- AwSetSurfaceFormat(&ddsd);
- TimeStampedMessage("after AwSetSurfaceFormat");
-
- // Do an initial lock and unlock on the back buffer
- // to pull out vital information such as the
- // surface description
- LockSurfaceAndGetBufferPointer();
- UnlockSurface();
- TimeStampedMessage("after Lock & Unlock");
-
-}
-
-// Lock back buffer and get screen pointer
-
-void LockSurfaceAndGetBufferPointer()
-{
- DDSURFACEDESC ddsdback;
- HRESULT ddrval;
- int count = 0;
-
- #if optimiseblit
- while (lpDDSBack->GetBltStatus(DDGBS_ISBLTDONE) != DD_OK);
- #endif
-
- memset(&ddsdback, 0, sizeof(ddsdback));
- ddsdback.dwSize = sizeof(ddsdback);
-
- // DDLOCK_WAIT is another safety option that
- // should in theory be removable by using
- // the GetBltStatus call above.
- // Or of course the while loop...
- while ((ddrval = lpDDSBack->Lock(NULL, &ddsdback, DDLOCK_WAIT, NULL)) == DDERR_WASSTILLDRAWING)
- {
- count++;
- if (count>1) // was 10000, for test purposes ONLY!!!
- {
- LOGDXERR(ddrval);
- ReleaseDirect3D();
- exit(0x2001);
- }
- }
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- return;
- #endif
- }
-
- /* ddsdback now contains my lpSurface)*/
-
- ScreenBuffer = (unsigned char *)ddsdback.lpSurface;
- BackBufferPitch = ddsdback.lPitch;
-
- // Get pixel format description of
- // rendering target
- memcpy(&DisplayPixelFormat, &ddsdback.ddpfPixelFormat,
- sizeof(DDPIXELFORMAT));
-}
-
-void UnlockSurface(void)
-{
- HRESULT ddrval;
-
- ddrval = lpDDSBack->Unlock((LPVOID)ScreenBuffer);
- LOGDXERR(ddrval);
-
- #if debug
- if (ddrval != DD_OK)
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #endif
-}
-
-void FlipBuffers(void)
-{
- HRESULT ddrval;
-
- // for locking against other draw processes,
- // e.g. mouse pointer
- GlobalFlipLock = Yes;
-
- // IMPORTANT!!! OptimiseFlip, Blit are
- // not supported in SubWindow mode!!!
-
- if (WindowMode == WindowModeSubWindow)
- {
- RECT dest;
-
- // For SubWindow mode, we cannot flip, but
- // must instead do a (stretched, in principle)
- // blit to the front buffer to combine with GDI
- // surfaces.
- // The whole back buffer should be taken.
- dest.left = WinLeftX;
- dest.top = WinTopY;
- dest.right = WinRightX;
- dest.bottom = WinBotY;
- ddrval = lpDDSPrimary->Blt(&dest, lpDDSBack,
- NULL, DDBLT_WAIT, NULL);
- }
- else // default to FullScreen
- {
- // we hope to flip, and flip to hope
- // we are the tumbling jongleurs...
- if (DXMemoryMode == VideoMemoryPreferred)
- {
- #if optimiseflip
- while (lpDDSBack->GetFlipStatus(DDGFS_ISFLIPDONE) == DDERR_WASSTILLDRAWING)
- ProcessProjectWhileWaitingToBeFlippable();
- #endif
-
- // we are going to flip with DDFLIP_WAIT on
- // even if optimiseflip is set.
- // IT'S THE ONLY WAY TO BE SURE.
- ddrval = lpDDSPrimary->Flip(NULL, DDFLIP_WAIT);
-
- while(1)
- {
- if (ddrval == DD_OK)
- break;
- if (ddrval == DDERR_SURFACELOST)
- {
- ddrval = lpDDSPrimary->Restore();
- if (ddrval != DD_OK)
- break;
- }
- if (ddrval != DDERR_WASSTILLDRAWING)
- break;
- }
- }
- else // assume system memory rendering target
- {
- // Take rendering target to back buffer
- // Rendering target should map fully onto back buffer
- ddrval = lpDDSHiddenBack->Blt(NULL, lpDDSBack,
- NULL, DDBLT_WAIT, NULL);
-
- // And now do a standard flip
- #if optimiseflip
- while (lpDDSBack->GetFlipStatus(DDGFS_ISFLIPDONE) == DDERR_WASSTILLDRAWING)
- ProcessProjectWhileWaitingToBeFlippable();
- #endif
-
- // we are going to flip with DDFLIP_WAIT on
- // even if optimiseflip is set.
- // IT'S THE ONLY WAY TO BE SURE.
- ddrval = lpDDSPrimary->Flip(NULL, DDFLIP_WAIT);
-
- while(1)
- {
- if (ddrval == DD_OK)
- break;
- if (ddrval == DDERR_SURFACELOST)
- {
- ddrval = lpDDSPrimary->Restore();
- if (ddrval != DD_OK)
- break;
- }
- if (ddrval != DDERR_WASSTILLDRAWING)
- break;
- }
- }
- }
-
- GlobalFlipLock = No;
-
- ProjectSpecificBufferFlipPostProcessing();
-
- HandleScreenShot();
-
- #if InterlaceExperiment
- oddDraw ^= 1;
- #endif
-}
-
-void InGameFlipBuffers(void)
-{
- FlipBuffers();
- return;
- HRESULT ddrval;
-
- // for locking against other draw processes,
- // e.g. mouse pointer
- GlobalFlipLock = Yes;
-
- // IMPORTANT!!! OptimiseFlip, Blit are
- // not supported in SubWindow mode!!!
-
- if (WindowMode == WindowModeSubWindow)
- {
- RECT dest;
-
- // For SubWindow mode, we cannot flip, but
- // must instead do a (stretched, in principle)
- // blit to the front buffer to combine with GDI
- // surfaces.
- // The whole back buffer should be taken.
- dest.left = WinLeftX;
- dest.top = WinTopY;
- dest.right = WinRightX;
- dest.bottom = WinBotY;
- ddrval = lpDDSPrimary->Blt(&dest, lpDDSBack,
- NULL, DDBLT_WAIT, NULL);
- }
- else // default to FullScreen
- {
- // we hope to flip, and flip to hope
- // we are the tumbling jongleurs...
- if (DXMemoryMode == VideoMemoryPreferred)
- {
- #if optimiseflip
- while (lpDDSBack->GetFlipStatus(DDGFS_ISFLIPDONE) == DDERR_WASSTILLDRAWING)
- ProcessProjectWhileWaitingToBeFlippable();
- #endif
-
- // we are going to flip with DDFLIP_WAIT on
- // even if optimiseflip is set.
- // IT'S THE ONLY WAY TO BE SURE.
- ddrval = lpDDSPrimary->Flip(NULL, 0);
-
- while(0)
- {
- if (ddrval == DD_OK)
- break;
- if (ddrval == DDERR_SURFACELOST)
- {
- ddrval = lpDDSPrimary->Restore();
- if (ddrval != DD_OK)
- break;
- }
- if (ddrval != DDERR_WASSTILLDRAWING)
- break;
- }
- }
- else // assume system memory rendering target
- {
- LOCALASSERT(0);
- // Take rendering target to back buffer
- // Rendering target should map fully onto back buffer
- ddrval = lpDDSHiddenBack->Blt(NULL, lpDDSBack,
- NULL, DDBLT_WAIT, NULL);
-
- // And now do a standard flip
- #if optimiseflip
- while (lpDDSBack->GetFlipStatus(DDGFS_ISFLIPDONE) == DDERR_WASSTILLDRAWING)
- ProcessProjectWhileWaitingToBeFlippable();
- #endif
-
- // we are going to flip with DDFLIP_WAIT on
- // even if optimiseflip is set.
- // IT'S THE ONLY WAY TO BE SURE.
- ddrval = lpDDSPrimary->Flip(NULL, DDFLIP_WAIT);
-
- while(1)
- {
- if (ddrval == DD_OK)
- break;
- if (ddrval == DDERR_SURFACELOST)
- {
- ddrval = lpDDSPrimary->Restore();
- if (ddrval != DD_OK)
- break;
- }
- if (ddrval != DDERR_WASSTILLDRAWING)
- break;
- }
- }
- }
-
- GlobalFlipLock = No;
-
- ProjectSpecificBufferFlipPostProcessing();
-
- HandleScreenShot();
-
- #if InterlaceExperiment
- oddDraw ^= 1;
- #endif
-}
-
-// As of 29/4/96, slightly later in the day,
-// it now deallocates NOTHING explcitly, but
-// just calls Release on the entire DD object,
-// which seems a better approach. Ho hum.
-
-// This function is now OBSOLETE (25 / 7 / 96)
-// CALL RELEASEDIRECT3D INSTEAD!!!
-
-void finiObjects(void)
-{
- if (lpDD != NULL)
- {
- lpDD->Release();
- lpDD = NULL;
- }
-}
-
-// Release ONE direct draw surface, to be used
-// when replacing images via imageheader array,
-// e.g. in LoadBackdrop.
-
-void ReleaseDDSurface(void* DDSurface)
-
-{
- LPDIRECTDRAWSURFACE lpSurface;
-
- WaitForVRamReady(VWS_DDRELEASE);
-
- lpSurface = (LPDIRECTDRAWSURFACE) DDSurface;
-
- if (lpSurface != NULL)
- {
- lpSurface->Release();
- lpSurface = NULL;
- }
-}
-
-
-// Blt member is used rather BltFast because BltFast does not
-// allow a colour fill
-
-void ColourFillBackBuffer(int FillColour)
-
-{
- HRESULT ddrval;
- DDBLTFX ddbltfx;
-
- memset(&ddbltfx, 0, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwFillColor = FillColour;
-
- /* lets blt a color to the surface*/
- #if optimiseblit
- while (lpDDSBack->GetBltStatus(DDGBS_CANBLT) != DD_OK);
- #endif
-
- #if optimiseblit
- ddrval = lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_ASYNC, &ddbltfx);
-
- if (ddrval == DDERR_WASSTILLDRAWING)
- ddrval = lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT,
- &ddbltfx);
- #else
- ddrval = lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
- #endif
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- return;
- #endif
- }
-}
-
-// Blt member is used rather BltFast because BltFast does not
-// allow a colour fill
-
-void ColourFillBackBufferQuad(int FillColour, int LeftX,
- int TopY, int RightX, int BotY)
-
-{
- HRESULT ddrval;
- DDBLTFX ddbltfx;
- RECT destRect;
-
- destRect.left = LeftX;
- destRect.top = TopY;
- destRect.right = RightX;
- destRect.bottom = BotY;
-
- memset(&ddbltfx, 0, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwFillColor = FillColour;
-
- /* lets blt a color to the surface*/
- #if optimiseblit
- while (lpDDSBack->GetBltStatus(DDGBS_CANBLT) != DD_OK);
- #endif
-
- #if optimiseblit
- ddrval = lpDDSBack->Blt(&destRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_ASYNC, &ddbltfx);
-
- if (ddrval == DDERR_WASSTILLDRAWING)
- ddrval = lpDDSBack->Blt(&destRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
- #else
- ddrval = lpDDSBack->Blt(&destRect, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
- #endif
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- return;
- #endif
- }
-}
-
-// Note Blt is used rather than BltFast because BltFast will
-// always attempt to invoke an asynchronous blit and this appears
-// to be unstable at present (cf. problems with optimiseblit)
-// CHECK THIS -- WITH DDBLTFASTWAIT???
-// COMMENT ABOVE NOW OBSOLETE...
-
-void BlitToBackBuffer(void* lpBackground, RECT* destRectPtr, RECT* srcRectPtr)
-
-{
- HRESULT ddrval;
-
- #if optimiseblit
- while (lpDDSBack->GetBltStatus(DDGBS_CANBLT) != DD_OK);
- #endif
-
- #if optimiseblit
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_ASYNC, NULL);
-
- if (ddrval == DDERR_WASSTILLDRAWING)
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_WAIT, NULL);
- #else
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_WAIT, NULL);
- #endif
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- return;
- #endif
- }
-}
-
-// Note Blt is used rather than BltFast because BltFast does not
-// support DDBLTFX and therefore cannot be used to attempt to
-// prevent tearing
-
-void BlitToBackBufferWithoutTearing(void* lpBackground, RECT* destRectPtr, RECT* srcRectPtr)
-
-{
- HRESULT ddrval;
- DDBLTFX ddbltfx;
-
- memset(&ddbltfx, 0, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
-
- #if optimiseblit
- while (lpDDSBack->GetBltStatus(DDGBS_CANBLT) != DD_OK);
- #endif
-
- #if optimiseblit
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_ASYNC | DDBLT_DDFX, &ddbltfx);
-
- if (ddrval == DDERR_WASSTILLDRAWING)
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_WAIT | DDBLT_DDFX, &ddbltfx);
- #else
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_WAIT | DDBLT_DDFX, &ddbltfx);
- #endif
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- return;
- #endif
- }
-}
-
-#if 0
-
-// Note Blt is used rather than BltFast because BltFast does
-// not support the DDBLTFX structure and therefore cannot accept
-// a rotated blit
-
-void RotatedBlitToBackBuffer(void* lpBackground, RECT* destRectPtr, RECT* srcRectPtr, int RollZ)
-
-{
- HRESULT ddrval;
- DDBLTFX ddbltfx;
-
- memset(&ddbltfx, 0, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwRotationAngle = RollZ;
-
- #if optimiseblit
- while (lpDDSBack->GetBltStatus(DDGBS_CANBLT) != DD_OK);
- #endif
-
- #if optimiseblit
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_ASYNC | DDBLT_ROTATIONANGLE, &ddbltfx);
-
- if (ddrval == DDERR_WASSTILLDRAWING)
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_WAIT | DDBLT_ROTATIONANGLE, &ddbltfx);
- #else
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_WAIT | DDBLT_ROTATIONANGLE, &ddbltfx);
- #endif
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- return;
- #endif
- }
-}
-
-// Note Blt is used rather than BltFast because BltFast does not
-// support DDBLTFX and therefore cannot be used to attempt to
-// prevent tearing
-
-void RotatedBlitToBackBufferWithoutTearing(void* lpBackground, RECT* destRectPtr, RECT* srcRectPtr, int RollZ)
-
-{
- HRESULT ddrval;
- DDBLTFX ddbltfx;
-
- memset(&ddbltfx, 0, sizeof(ddbltfx));
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
- ddbltfx.dwRotationAngle = RollZ;
-
- #if optimiseblit
- while (lpDDSBack->GetBltStatus(DDGBS_CANBLT) != DD_OK);
- #endif
-
- #if optimiseblit
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_ASYNC | DDBLT_DDFX | DDBLT_ROTATIONANGLE, &ddbltfx);
-
- if (ddrval == DDERR_WASSTILLDRAWING)
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_WAIT | DDBLT_DDFX | DDBLT_ROTATIONANGLE, &ddbltfx);
- #else
- ddrval = lpDDSBack->Blt(destRectPtr, (LPDIRECTDRAWSURFACE) lpBackground,
- srcRectPtr, DDBLT_WAIT | DDBLT_DDFX | DDBLT_ROTATIONANGLE, &ddbltfx);
- #endif
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- return;
- #endif
- }
-}
-
-#endif
-
-
-// Note x, y are assumed to be TOP LEFT of character
-// BltFast is used here, partially as an experiment (ahem...)
-
-// THIS FUNCTION ASSUMES A VERTICAL FONT BRUSH!!!
-
-// FIXME!!! This function does not always seem to
-// produce visible text in SubWindow mode; i.e.
-// as of 29/4/96 it works on Roxby's and fails on
-// mine. I suspect this is because we are using
-// BltFast, which 'works only on display memory',
-// and there isn't enough video RAM on my card
-// to put the debug font in video memory in SubWindow
-// mode. Or something.
-// At present I have done nothing about this, since Roxby
-// claims that as of Beta 3 he can't get source colour
-// keying working on the blitter without using BltFast, and
-// we need source colour keying to get the font to
-// look right.
-// Will have to be looked at at some stage, 'tho.
-
-#if debug || PreBeta
-void BlitWin95Char(int x, int y, unsigned char toprint)
-
-{
- static int bltwin95char_ok=1;
- if (!bltwin95char_ok) return;
-
- int FontIndex;
- RECT source;
- HRESULT ddrval;
- #if NoBltFastOnFont
- RECT destination;
- #endif
-
- // Check for data out of range for font
- if ((toprint < FontStart) || (toprint > FontEnd))
- return;
-
- // Check for character being on screen
- if ((x < ScreenDescriptorBlock.SDB_ClipLeft) ||
- ((x + CharWidth) > ScreenDescriptorBlock.SDB_ClipRight) ||
- (y < ScreenDescriptorBlock.SDB_ClipUp) ||
- ((y + CharHeight) > ScreenDescriptorBlock.SDB_ClipDown))
- return;
-
- // Generate font index and source rectangle
- // Assumes vertical brush
- FontIndex = (toprint - FontStart);
-
- source.left = 0;
- source.top = (FontIndex * CharHeight);
- source.right = CharWidth;
- source.bottom = ((FontIndex + 1) * CharHeight);
-
- // Do blit
- #if NoBltFastOnFont
- destination.left = x;
- destination.top = y;
- destination.right = (x+CharWidth);
- destination.bottom = (y+CharHeight);
- ddrval = lpDDSBack->Blt(&destination, lpDDDbgFont,
- &source, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
- #else
- ddrval = lpDDSBack->BltFast(x, y,
- lpDDDbgFont, &source,
- DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
- #endif
-
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- #if debug && 0
- {
- ReleaseDirect3D();
- exit(0x11);
- }
- #else
- bltwin95char_ok = 0;
- return;
- #endif
-}
-
-#else
-void BlitWin95Char(int x, int y, unsigned char toprint)
-{
-}
-#endif
-
-// IMPORTANT!!! FIXME!!!!
-
-// This function has been hacked to FORCE images into
-// system memory due to what appears to be a bug in
-// DirectDraw's defaulting to system memory...
-
-// Has HOPEFULLY now been fixed to deal with non 8 bit
-// images... but I wouldn't count on it...
-
-// If SysMem is TRUE, the image should go into system memory. If it is
-// FALSE, we will try for video memory. And may God walk at our side in
-// the valley of the shadow.
-
-
-
-// This callback enumerates all the DirectDraw
-// devices present on a system searching for one
-// with hardware 3D support available. If such
-// a device is present, it will always be selected.
-// Otherwise, no valid device will be returned.
-
-static BOOL bHardwareDDObj = FALSE;
-static BOOL bNoHardwareDD = FALSE;
-
-
-BOOL FAR PASCAL EnumDDObjectsCallback(GUID FAR* lpGUID, LPSTR lpDriverDesc,
- LPSTR lpDriverName, LPVOID lpContext)
-{
- LPDIRECTDRAW lpDDTest;
- DDCAPS DriverCaps, HELCaps;
- HRESULT ddrval;
-
- /*
- A NULL GUID* indicates the DirectDraw HEL which we are not interested
- in at the moment, because we are cruel and heartless and really
- really nasty people, after all.
- */
-
- if (lpGUID)
- {
- // Create the DirectDraw device using this driver. If it fails,
- // just move on to the next driver.
-
- ddrval = DirectDrawCreate(lpGUID, &lpDDTest, NULL);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- return DDENUMRET_OK;
-
- // Get the capabilities of this DirectDraw driver. If it fails,
- // just move on to the next driver.
-
- memset(&DriverCaps, 0, sizeof(DDCAPS));
- DriverCaps.dwSize = sizeof(DDCAPS);
- memset(&HELCaps, 0, sizeof(DDCAPS));
- HELCaps.dwSize = sizeof(DDCAPS);
-
- ddrval = lpDDTest->GetCaps(&DriverCaps, &HELCaps);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- lpDDTest->Release();
- return DDENUMRET_OK;
- }
-
- // JH - changed so that debugging in a window works if you've got two cards or something
- if (DriverCaps.dwCaps & DDCAPS_3D && WindowRequestMode != WindowModeSubWindow)
- {
- // We have found a 3d hardware device. Return the DD object
- // and stop enumeration.
- // This assumes that 3d capable DD hardware
- // drivers cannot operate in a window.
- // True? CHECKME!!!
- WindowMode = WindowModeFullScreen;
- *(LPDIRECTDRAW*)lpContext = lpDDTest;
- return DDENUMRET_CANCEL;
- }
- lpDDTest->Release();
- }
- return DDENUMRET_OK;
-}
-
-
-// Set up the DirectDraw object for the
-// system. Using this we can determine the
-// system capabilities. The DirectDraw object
-// in question should never be released until
-// ExitSystem, even if window or video modes
-// are changed. Note that as well as checking
-// for valid video modes etc, this function will
-// also search for hardware DirectDraw objects
-// and use one if appropriate.
-
-// Note that GenerateDirectDrawSurface and
-// SetVideoMode now just set a video mode,
-// rather than (as previously) initialising the
-// DirectDraw model.
-
-// This function should be called
-// during InitialiseSystem, so that we can
-// be sure that SetVideoMode (called later)
-// will be setting a valid mode. The function
-// must be called after InitialVideoMode (which
-// sets the mode it validates) and before
-// InitialiseWindowsSystem, since in the
-// current version that needs to know the
-// WindowMode, not the VideoMode. Note that
-// InitialiseWindowsSystem itself must be called
-// after InitialVideoMode (it is currently
-// called at the start of InitialiseSystem).
-
-DDCAPS direct_draw_caps;
-
-BOOL InitialiseDirectDrawObject(void)
-
-{
- HRESULT ddrval;
- LPDIRECTDRAW lpDDHardware = NULL;
-
- // Set up DirectDraw object.
-
- // If we are not in emulation only mode,
- // search for a hardware 3D capable DirectDraw
- // driver and use it. If this fails, or if we
- // are in emulation, go straight for the HEL.
- if (RasterisationRequestMode != RequestSoftwareRasterisation)
- {
- ddrval = DirectDrawEnumerate(EnumDDObjectsCallback, &lpDDHardware);
- LOGDXERR(ddrval);
- if (ddrval != DD_OK)
- {
- #if debug
- ReleaseDirect3D();
- exit(ddrval);
- #else
- return FALSE;
- #endif
- }
- }
-
- // If we don't have a hardware driver, either
- // because there wasn't one or because we are in
- // HEL... then make one.
-
- if (!lpDDHardware)
- {
- if (RasterisationRequestMode != RequestSoftwareRasterisation)
- bNoHardwareDD = TRUE;
- bHardwareDDObj = FALSE;
- ddrval = DirectDrawCreate(NULL, &lpDD, NULL);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- {
- ReleaseDirect3D(); // for safety
- return FALSE;
- }
- #endif
- }
- else
- {
- bHardwareDDObj = TRUE;
- lpDD = lpDDHardware;
- }
-
- AwSetDDObject(lpDD);
-
- // Get caps for hardware DD driver/HEL layer
- memset(&direct_draw_caps, 0, sizeof(direct_draw_caps));
- direct_draw_caps.dwSize = sizeof(direct_draw_caps);
- ddrval = lpDD->GetCaps(&direct_draw_caps, NULL);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- {
- ReleaseDirect3D(); // for safety
- return FALSE;
- }
- #endif
-
- // Put statistics into globals
- TotalVideoMemory = (int) (direct_draw_caps.dwVidMemTotal);
- // At some stage, we should set up a proper
- // structure here with the general system
- // capabilities in it.
- // Notably, we may need to check DD surface
- // alignment values and the stride.
-
- // NOTE THAT AS GARRY HAS POINTED OUT, TOTAL
- // FREE VIDMEM CAN CHANGE AFTER SETTING THE
- // VIDEO MODE OR COOPERATIVE LEVEL, SO WE
- // SHOULD REALLY BE RUNNING THIS GETCAPS MEMBER
- // ON THE DDOBJECT AGAIN AFTER GENERATESURFACE, OR
- // POSSIBLY WHENEVER THE USER WANTS.
- // ***FIXME!!!***
-
- // Run the display modes enumerator
- // Note that NULL in the second entry
- // means enumerate all available display
- // modes on the driver.
- NumAvailableVideoModes = 0;
- ddrval = lpDD->EnumDisplayModes(0, NULL, 0, EnumDisplayModesCallback);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- {
- ReleaseDirect3D(); // for safety
- return FALSE;
- }
- #endif
-
- // Check that the video mode asked
- // for (initially at least in
- // InitialVideoMode) is actually
- // available. If it is not, attempt to
- // default to 640x480x8 and 640x480x15
- // (liable to be the most common modes)
- // and if that fails, exit altogether
- // with a failure code.
-
- // Note!!! This only matters in FullScreen
- // mode. In SubWindow mode we must use the
- // Windows display mode anyway. Obviously
- // initialisation of the video mode will fail
- // in SubWindow mode if the colour depth of
- // the Windows display is different to the
- // VideoMode colour depth, but I have not bothered
- // to check for this since SubWindow mode is
- // only intended for debugging and the failure
- // case exits with an appropriate DirectDraw
- // error anyway.
- #if CheckVideoMode
- if (WindowMode == WindowModeFullScreen)
- {
- if (!(CheckForVideoModes(VideoMode)))
- {
- VideoMode = VideoMode_DX_640x480x8;
- if (!(CheckForVideoModes(VideoMode)))
- {
- VideoMode = VideoMode_DX_640x480x15;
- if (!(CheckForVideoModes(VideoMode)))
- {
- ReleaseDirect3D(); // for safety
- return FALSE;
- }
- }
- }
- }
- #endif // for CheckVideoMode
-
- return TRUE; // Successful completion
-}
-
-
-// return TRUE on success
-
-static BOOL ReallyChangeDDObj(void)
-{
- finiObjects();
-
- if (InitialiseDirectDrawObject()
- == FALSE)
- /*
- If we cannot get a video mode,
- fail. No point in a non debugging option
- for this.
- */
- {
- #if debug
- ReleaseDirect3D();
- exit(0x997798);
- #else
- return FALSE;
- #endif
- }
-
- /*
- Initialise global to say whether
- we think there is an onboard 3D
- acceleration card / motherboard
- built-in
- */
- #if 0
- TestInitD3DObject();
-
-/*
- This is (HOPEFULLY!!) now the right
- place to put this call. Note that it is
- not absolutely certain that we can do test
- blits from DirectDraw without setting
- a cooperative level, however... And note also
- that MMX works better with the back buffer in
- system memory...
-*/
- TestMemoryAccess();
- #endif
- return TRUE;
-}
-
-int SelectDirectDrawObject(LPGUID pGUID)
-{
- HRESULT ddrval;
- LPDIRECTDRAW lpDDHardware = NULL;
-
- // Set up DirectDraw object.
- bNoHardwareDD = TRUE;
- bHardwareDDObj = FALSE;
- ddrval = DirectDrawCreate(pGUID, &lpDD, NULL);
-
- AwSetDDObject(lpDD);
-
- // Get caps for hardware DD driver/HEL layer
- memset(&direct_draw_caps, 0, sizeof(direct_draw_caps));
- direct_draw_caps.dwSize = sizeof(direct_draw_caps);
- ddrval = lpDD->GetCaps(&direct_draw_caps, NULL);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- {
- ReleaseDirect3D(); // for safety
- return FALSE;
- }
- #endif
-
- // Put statistics into globals
- TotalVideoMemory = (int) (direct_draw_caps.dwVidMemTotal);
- // At some stage, we should set up a proper
- // structure here with the general system
- // capabilities in it.
- // Notably, we may need to check DD surface
- // alignment values and the stride.
-
- // NOTE THAT AS GARRY HAS POINTED OUT, TOTAL
- // FREE VIDMEM CAN CHANGE AFTER SETTING THE
- // VIDEO MODE OR COOPERATIVE LEVEL, SO WE
- // SHOULD REALLY BE RUNNING THIS GETCAPS MEMBER
- // ON THE DDOBJECT AGAIN AFTER GENERATESURFACE, OR
- // POSSIBLY WHENEVER THE USER WANTS.
- // ***FIXME!!!***
-
- // Run the display modes enumerator
- // Note that NULL in the second entry
- // means enumerate all available display
- // modes on the driver.
- NumAvailableVideoModes = 0;
- ddrval = lpDD->EnumDisplayModes(0, NULL, 0, EnumDisplayModesCallback);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- {
- ReleaseDirect3D(); // for safety
- return FALSE;
- }
- #endif
-
- // Check that the video mode asked
- // for (initially at least in
- // InitialVideoMode) is actually
- // available. If it is not, attempt to
- // default to 640x480x8 and 640x480x15
- // (liable to be the most common modes)
- // and if that fails, exit altogether
- // with a failure code.
-
- // Note!!! This only matters in FullScreen
- // mode. In SubWindow mode we must use the
- // Windows display mode anyway. Obviously
- // initialisation of the video mode will fail
- // in SubWindow mode if the colour depth of
- // the Windows display is different to the
- // VideoMode colour depth, but I have not bothered
- // to check for this since SubWindow mode is
- // only intended for debugging and the failure
- // case exits with an appropriate DirectDraw
- // error anyway.
- #if CheckVideoMode
- if (WindowMode == WindowModeFullScreen)
- {
- if (!(CheckForVideoModes(VideoMode)))
- {
- VideoMode = VideoMode_DX_640x480x8;
- if (!(CheckForVideoModes(VideoMode)))
- {
- VideoMode = VideoMode_DX_640x480x15;
- if (!(CheckForVideoModes(VideoMode)))
- {
- ReleaseDirect3D(); // for safety
- return FALSE;
- }
- }
- }
- }
- #endif // for CheckVideoMode
-
- return TRUE; // Successful completion
-}
-
-
-
-BOOL ChangeDirectDrawObject(void)
-{
- if (RequestSoftwareRasterisation==RasterisationRequestMode)
- {
- // software modes required
- if (bHardwareDDObj)
- {
- // but was previously hardware DD
- return ReallyChangeDDObj();
- }
- }
- else
- {
- // hardware modes requested if available
- if (!bHardwareDDObj && !bNoHardwareDD)
- {
- // but was previously software DD and
- // we haven't established that hardware isn't available
- return ReallyChangeDDObj();
- }
- }
-
- return TRUE;
-}
-
-
-
-BOOL CheckForVideoModes(int TestVideoMode)
-
-{
- int i=0;
- BOOL EarlyExit = FALSE;
-
- do
- {
- if ((EngineVideoModes[TestVideoMode].Width
- == AvailableVideoModes[i].Width) &&
- (EngineVideoModes[TestVideoMode].Height
- == AvailableVideoModes[i].Height) &&
- (EngineVideoModes[TestVideoMode].ColourDepth
- == AvailableVideoModes[i].ColourDepth))
- EarlyExit = TRUE;
- else
- i++;
- }
- while ((i < NumAvailableVideoModes) &&
- (!EarlyExit));
-
- return(EarlyExit);
-}
-
-HRESULT CALLBACK EnumDisplayModesCallback(LPDDSURFACEDESC pddsd, LPVOID Context)
-{
- AvailableVideoModes[NumAvailableVideoModes].Width = pddsd->dwWidth;
- AvailableVideoModes[NumAvailableVideoModes].Height = pddsd->dwHeight;
- AvailableVideoModes[NumAvailableVideoModes].ColourDepth = pddsd->ddpfPixelFormat.dwRGBBitCount;
- NumAvailableVideoModes++;
-
- if (NumAvailableVideoModes < MaxAvailableVideoModes)
- return DDENUMRET_OK;
- else
- return DDENUMRET_CANCEL;
-}
-
-// Deallocate all objects except the basic
-// DirectDraw objects, which we want to do
-// before shifting display modes or window
-// mode. Note that ExitWindowsSystem must be
-// called separately. Note also that ExitSystem
-// should be called for a full system shutdown.
-
-// FIXME!!! BACKDROPS?!?!? -- done in
-// DeallocateAllImages (called from ReleaseDirect3D
-// and ReleaseDirect3DNotDD)
-
-// Note that getting the right sequence for releases
-// here is CRUCIAL. Note also that the font surface
-// is NOT explicitly deallocated; hopefully it will just
-// go when we kill the primary (as an offscreen surface).
-// Could this cause problems for DeallocateAllImages??
-// Um, err, I sure hope not...
-
-
-void finiObjectsExceptDD(void)
-{
- if (WindowMode == WindowModeSubWindow)
- {
- if (lpDDClipper != NULL)
- {
- lpDDClipper->Release();
- lpDDClipper = NULL;
- }
- }
-
- if (lpDDPal[0] != NULL) // should be killed neway???
- {
- lpDDPal[0]->Release();
- lpDDPal[0] = NULL;
- }
-
- if (lpDDSBack != NULL)
- {
- lpDDSBack->Release();
- lpDDSBack = NULL;
- }
-
- if (lpDDSPrimary != NULL)
- {
- lpDDSPrimary->Release();
- lpDDSPrimary = NULL;
- }
-}
-
-
-// This will hopefully allow us to change
-// the palette at runtime, assuming that
-// we are in a palettised mode. It will
-// wait for vertical blank to make it work
-// on all video cards (I hope). Note that
-// the palette should be passed in engine
-// internal format, i.e. 6 bits, and will be
-// converted to the DirectDraw format internally.
-
-// Note we assume entry 0 in the lpDDPal array!!!
-
-// Note for 222 mode we set the FIRST 64 entries!!!
-// Not certain that's right, actually...
-
-int ChangePalette (unsigned char* NewPalette)
-
-{
- unsigned char DDPalette[1024]; // 256 colours, 4 bytes each
- int NumEntries;
-
- // Check for palettised mode
- // Note we must use VideoModeTypeScreen
- // due to nature of Direct3D ramp driver
- // interface.
-
- if ((VideoModeTypeScreen != VideoModeType_8) &&
- (VideoModeTypeScreen != VideoModeType_8T))
- return No;
-
- // Check for FullScreen mode
- // if (WindowMode != WindowModeFullScreen)
- // return No;
-
- // Set up number of entries to change
- if (ScreenDescriptorBlock.SDB_Flags & SDB_Flag_222)
- NumEntries = 256; // actually, this seems to be right...
- else if ((ScreenDescriptorBlock.SDB_Flags & SDB_Flag_Raw256)
- || (VideoModeTypeScreen == VideoModeType_8T))
- NumEntries = 256;
- else
- return No; // undefined behaviour
-
- // Convert to DirectDraw 4 bytes, 8 bit format
- // with all flag entries set to zero
-
- ConvertToDDPalette(NewPalette, DDPalette, NumEntries, 0);
-
- // Wait for beginning of next vertical
- // blanking interval
- lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
-
- // Set all entries in palette to new values
- lpDDPal[0]->SetEntries(0,0,NumEntries,(LPPALETTEENTRY)
- DDPalette);
-
- return Yes;
-}
-
-// At some stage it may be worth expanding this function
-// to get more than video memory, or replacing it
-// with one that uses GetCaps to fill out a general
-// structure.
-
-int GetAvailableVideoMemory(void)
-{
- DDCAPS ddcaps;
- HRESULT ddrval;
-
- // Get caps for DirectDraw object
- memset(&ddcaps, 0, sizeof(ddcaps));
- ddcaps.dwSize = sizeof(ddcaps);
- ddrval = lpDD->GetCaps(&ddcaps, NULL);
- LOGDXERR(ddrval);
-
- if (ddrval != DD_OK)
- #if debug
- {
- ReleaseDirect3D();
- exit(ddrval);
- }
- #else
- return -1;
- #endif
-
- return (int) (ddcaps.dwVidMemFree);
-}
-
-/*
- This is designed to allow for ModeX
- emulation failures where the system
- boots up in a low memory cost mode
- which actually takes up much more than
- a high cost mode because GDI cannot be
- evicted. Note that the VideoMode reset
- done here is in any case a last ditch
- measure, since the higher res version will
- be much slower as well as (normally) more
- costly in terms of memory.
-
- It will also now do start errors due to the
- driver not being able to change to a mode of
- a different colour depth, and this not being reported
- by the DirectDraw object's enum display modes
- callback. Hopefully.
-
- NOTE THAT THIS MUST BE CALLED FROM YOUR WINMAIN
- AFTER SETVIDEOMODE IF IT IS TO WORK.
-
- NOTE ALSO THAT THE ACTIVATION CODE FOR THIS IS
- IN GENERATEDIRECTDRAWSURFACE AND WILL NOT BE TURNED
- ON UNLESS -->DEBUG<-- IS -->OFF<--.
-*/
-
-void HandleVideoModeRestarts(HINSTANCE hInstance, int nCmdShow)
-{
- if (AttemptVideoModeRestart)
- {
- switch (VideoRestartMode)
- {
- case RestartDisplayModeNotAvailable:
- {
- // Rewrite mode as equivalent resolution,
- // different bit depth, before trying again.
- // Note this must be kept up to date!!!
- switch (VideoMode)
- {
- case VideoMode_DX_320x200x8:
- {
- ReleaseDirect3D();
- exit(0xfedd);
- }
- VideoMode = VideoMode_DX_320x200x15;
- break;
-
- case VideoMode_DX_320x200x8T:
- VideoMode = VideoMode_DX_320x200x15;
- break;
-
- case VideoMode_DX_320x200x15:
- VideoMode = VideoMode_DX_320x200x8T;
- break;
-
- case VideoMode_DX_320x240x8:
- VideoMode = VideoMode_DX_320x200x15;
- break;
-
- case VideoMode_DX_640x480x8:
- VideoMode = VideoMode_DX_640x480x15;
- break;
-
- case VideoMode_DX_640x480x8T:
- VideoMode = VideoMode_DX_640x480x15;
- break;
-
- case VideoMode_DX_640x480x15:
- VideoMode = VideoMode_DX_640x480x8T;
- break;
-
- case VideoMode_DX_640x480x24:
- VideoMode = VideoMode_DX_640x480x15;
- break;
-
- default: // hmm...
- break;
- }
-
- // Clear variables
- AttemptVideoModeRestart = No;
- VideoRestartMode = NoRestartRequired;
-
- ChangeDisplayModes(hInstance, nCmdShow,
- VideoMode, WindowRequestMode,
- ZBufferRequestMode, RasterisationRequestMode,
- SoftwareScanDrawRequestMode, DXMemoryRequestMode);
- }
- break;
-
- case RestartOutOfVidMemForPrimary:
- {
- // Guess mode reset
- // Note this must be kept up to date!!!
- if ((VideoMode == VideoMode_DX_320x200x8) ||
- (VideoMode == VideoMode_DX_320x200x8T) ||
- (VideoMode == VideoMode_DX_320x240x8))
- VideoMode = VideoMode_DX_640x480x8;
- else if (VideoMode == VideoMode_DX_320x200x15)
- VideoMode = VideoMode_DX_640x480x15;
-
- // Clear variables
- AttemptVideoModeRestart = No;
- VideoRestartMode = NoRestartRequired;
-
- ChangeDisplayModes(hInstance, nCmdShow,
- VideoMode, WindowRequestMode,
- ZBufferRequestMode, RasterisationRequestMode,
- SoftwareScanDrawRequestMode, DXMemoryRequestMode);
- }
- break;
-
- default: // err...
- break;
- }
- }
-}
-
-
-// Take a 24 bit RGB colour and return it in the
-// correct format for the current primary surface
-// We will assume that the primary is NOT in a
-// palettised mode, since the mapping if we have
-// already set a palette is undefined.
-
-int GetSingleColourForPrimary(int Colour)
-
-{
- unsigned long m;
- int s;
- int red_shift, red_scale;
- int green_shift, green_scale;
- int blue_shift, blue_scale;
- int RetVal = 0;
- int r, g ,b;
-
- // Fail for palettised modes
- if ((VideoModeTypeScreen == VideoModeType_8)
- || (VideoModeTypeScreen == VideoModeType_8T))
- return -1;
-
- // Extra! check for palettised modes
- if ((DisplayPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
- || (DisplayPixelFormat.dwFlags & DDPF_PALETTEINDEXED4))
- return -1;
-
- // Determine r, g, b masks and scale
- for (s = 0, m = DisplayPixelFormat.dwRBitMask;
- !(m & 1); s++, m >>= 1);
-
- red_shift = s;
- red_scale = 255 / (DisplayPixelFormat.dwRBitMask >> s);
-
- for (s = 0, m = DisplayPixelFormat.dwGBitMask;
- !(m & 1); s++, m >>= 1);
-
- green_shift = s;
- green_scale = 255 / (DisplayPixelFormat.dwGBitMask >> s);
-
- for (s = 0, m = DisplayPixelFormat.dwBBitMask;
- !(m & 1); s++, m >>= 1);
-
- blue_shift = s;
- blue_scale = 255 / (DisplayPixelFormat.dwBBitMask >> s);
-
- // Extract r,g,b components from input colour
- r = (Colour >> 16) & 0xff;
- g = (Colour >> 8) & 0xff;
- b = Colour & 0xff;
-
- // Scale and shift each value
- r /= red_scale;
- g /= green_scale;
- b /= blue_scale;
- RetVal = (r << red_shift) | (g << green_shift)
- | (b << blue_shift);
-
- return(RetVal);
-}
-
-#if triplebuffer
-// NOTE TRIPLE BUFFERING SUPPORT HAS BEEN -->REMOVED<--
-// ON THE GROUNDS THAT THE SECOND BACK BUFFER TAKES UP
-// EXTRA MEMORY AND IT'S NOT GOING TO GO ANY FASTER
-// ANYWAY UNLESS YOUR VIDEO CARD FLIPS IN HARDWARE AND
-// TAKES MORE THAN ABOUT 10 MILLISECONDS TO DO IT.
-// WHICH I CERTAINLY HOPE ISN'T TRUE...
-
-// NOTE ALSO: THIS FUNCTION DOESN'T WORK! (DESPITE
-// THE DOCUMENTATION). YOU NEED TO USE GETATTACHEDSURFACE
-// TWICE INSTEAD. SEE ARSEWIPE CODE FOR A WORKING
-// EXAMPLE (NOTE THAT TRIPLE BUFFERING CAN BE OPTIMAL
-// IN ARSEWIPE BECAUSE IT'S 2D, AND THE TIME TO THE NEXT
-// SURFACE LOCK IN A RENDERING CYCLE CAN THUS BE MUCH LESS
-// THAN IN 3DC).
-
-// defines this function as FAR PASCAL, i.e.
-// using Windows standard parameter passing convention,
-// which will be neecessary for all callbacks
-
-HRESULT WINAPI InitTripleBuffers(LPDIRECTDRAWSURFACE lpdd,
- LPDDSURFACEDESC lpsd, LPVOID lpc)
-{
- if ((lpsd->ddsCaps.dwCaps & DDSCAPS_FLIP) &&
- (!(lpsd->ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER))
- && (BackBufferEnum < MaxBackBuffers))
- lpDDSBack[BackBufferEnum++] = lpdd;
-
- if (BackBufferEnum == MaxBackBuffers)
- return(DDENUMRET_CANCEL);
- else
- return(DDENUMRET_OK);
-}
-#endif
-
-
-
-/* new versions of these functions, provided by neil */
-static GDIObjectReferenceCount = 0;
-BOOL GetGDISurface(void)
-{
- HRESULT hr = DD_OK;
-
- if(WindowMode == WindowModeSubWindow) return TRUE;
-
- if(!lpDDGDI)
- {
- hr = lpDD->GetGDISurface(&lpDDGDI);
- if(hr != DD_OK)
- {
- ReleaseDirect3D();
- exit(hr);
- }
- }
-
- // flip the buffer to the GDI surface
- hr = lpDD->FlipToGDISurface();
- if(hr != DD_OK)
- {
- ReleaseDirect3D();
- exit(hr);
- }
-
- GDIObjectReferenceCount++;
-
- // release windows palette entries -
- // whenever we flip to the GDI surface,
- // we will want the full palette.
-
- if (VideoModeColourDepth == 8)
- {
- HDC hdc = GetDC(NULL);
- SetSystemPaletteUse(hdc, SYSPAL_STATIC);
- ReleaseDC(NULL, hdc);
- }
-
- return TRUE;
-}
-
-
-BOOL LeaveGDISurface(void)
-{
- HRESULT hr = DD_OK;
-
- if(WindowMode == WindowModeSubWindow) return TRUE;
-
- if (GDIObjectReferenceCount <= 1)
- {
- ReleaseDDSurface(lpDDGDI);
- }
-
- // recapture system static palette
- // entries (see note above in
- // GetGDISurface... )
-
- if (VideoModeColourDepth == 8)
- {
- HDC hdc = GetDC(NULL);
- SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC);
- ReleaseDC(NULL, hdc);
- }
-
- return TRUE;
-}
-
-/************ for extern "C"*****************/
-
-};
-