summaryrefslogtreecommitdiff
path: root/3dc/win95/d3_func.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3dc/win95/d3_func.cpp')
-rw-r--r--3dc/win95/d3_func.cpp949
1 files changed, 949 insertions, 0 deletions
diff --git a/3dc/win95/d3_func.cpp b/3dc/win95/d3_func.cpp
new file mode 100644
index 0000000..923e7f2
--- /dev/null
+++ b/3dc/win95/d3_func.cpp
@@ -0,0 +1,949 @@
+
+// Interface functions (written in C++) for
+// Direct3D immediate mode system
+
+// Must link to C code in main engine system
+
+extern "C" {
+
+// Mysterious definition required by objbase.h
+// (included via one of the include files below)
+// to start definition of obscure unique in the
+// universe IDs required by Direct3D before it
+// will deign to cough up with anything useful...
+
+#define INITGUID
+
+#include "3dc.h"
+
+#include "awTexLd.h"
+
+#include "dxlog.h"
+#include "module.h"
+#include "inline.h"
+
+#include "d3_func.h"
+#include "d3dmacs.h"
+
+#include "string.h"
+
+#include "kshape.h"
+#include "eax.h"
+#include "vmanpset.h"
+
+extern "C++" {
+#include "chnktexi.h"
+#include "chnkload.hpp" // c++ header which ignores class definitions/member functions if __cplusplus is not defined ?
+#include "r2base.h"
+}
+
+#define UseLocalAssert No
+#include "ourasert.h"
+
+
+
+// FIXME!!! Structures in d3d structure
+// never have any size field set!!!
+// This is how it's done in Microsoft's
+// demo code --- but ARE THEY LYING???
+
+// As far as I know the execute buffer should always be in
+// system memory on any configuration, but this may
+// eventually have to be changed to something that reacts
+// to the caps bit in the driver, once drivers have reached
+// the point where we can safely assume that such bits will be valid.
+#define ForceExecuteBufferIntoSystemMemory Yes
+
+// To define TBLEND mode --- at present
+// it must be on for ramp textures and
+// off for evrything else...
+#define ForceTBlendCopy No
+
+// Set to Yes for debugging, to No for normal
+// operations (i.e. if we need a palettised
+// file for an accelerator, load it from
+// pre-palettised data, using code not yet
+// written as of 27 / 8/ 96)
+#define QuantiseOnLoad Yes
+
+// Set to Yes to make default texture filter bilinear averaging rather
+// than nearest
+BOOL BilinearTextureFilter = 1;
+
+extern LPDIRECTDRAW lpDD;
+
+#if 0//
+// Externs
+
+extern int VideoMode;
+extern int DXMemoryMode;
+extern int ZBufferRequestMode;
+extern int RasterisationRequestMode;
+extern int SoftwareScanDrawRequestMode;
+extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
+extern VIEWDESCRIPTORBLOCK* Global_VDB_Ptr;
+extern IMAGEHEADER ImageHeaderArray[];
+extern BOOL MMXAvailable;
+
+
+//Globals
+
+int D3DDriverMode;
+
+
+
+static unsigned char DefaultD3DTextureFilterMin;
+static unsigned char DefaultD3DTextureFilterMax;
+
+
+#if SuppressWarnings
+static int* itemptr_tmp;
+
+#ifdef __WATCOMC__
+#pragma warning 389 5
+#pragma message("Note: Disabled Warning W389 'Integral value may be truncated...'")
+#endif
+
+#endif
+
+
+#endif //
+HRESULT LastError;
+int ExBufSize;
+
+LPDIRECT3DEXECUTEBUFFER lpD3DExecCmdBuf;
+LPDIRECTDRAWSURFACE lpZBuffer;
+extern LPDIRECTDRAWSURFACE lpDDSBack;
+extern LPDIRECTDRAWSURFACE lpDDSPrimary;
+extern LPDIRECTDRAWPALETTE lpDDPal[]; // DirectDraw palette
+
+D3DINFO d3d;
+BOOL D3DHardwareAvailable;
+
+int StartDriver;
+int StartFormat;
+
+
+static int devZBufDepth;
+
+
+extern int WindowMode;
+extern int ZBufferMode;
+extern int ScanDrawMode;
+extern int VideoModeColourDepth;
+
+extern enum TexFmt { D3TF_4BIT, D3TF_8BIT, D3TF_16BIT, D3TF_32BIT, D3TF_MAX } d3d_desired_tex_fmt;
+
+// Callback function to enumerate devices present
+// on system (required so that device interface GUID
+// can be retrieved if for no other reason). Device
+// information is copied into instance of structure
+// defined in d3_func.h
+
+HRESULT WINAPI DeviceEnumerator(LPGUID lpGuid,
+ LPSTR lpDeviceDescription, LPSTR lpDeviceName,
+ LPD3DDEVICEDESC lpHWDesc, LPD3DDEVICEDESC lpHELDesc, LPVOID lpContext)
+{
+ int *lpStartDriver = (int *)lpContext;
+
+ /*
+ Record the D3D driver's description
+ of itself.
+ */
+
+ memcpy(&d3d.Driver[d3d.NumDrivers].Guid, lpGuid, sizeof(GUID));
+ strcpy(d3d.Driver[d3d.NumDrivers].About, lpDeviceDescription);
+ strcpy(d3d.Driver[d3d.NumDrivers].Name, lpDeviceName);
+
+ /*
+ Is this a hardware device or software emulation? Checking the color
+ model for a valid model works.
+ */
+
+ if (lpHWDesc->dcmColorModel)
+ {
+ D3DHardwareAvailable = Yes;
+ d3d.Driver[d3d.NumDrivers].Hardware = Yes;
+ memcpy(&d3d.Driver[d3d.NumDrivers].Desc, lpHWDesc,
+ sizeof(D3DDEVICEDESC));
+ }
+ else
+ {
+ d3d.Driver[d3d.NumDrivers].Hardware = No;
+ memcpy(&d3d.Driver[d3d.NumDrivers].Desc, lpHELDesc,
+ sizeof(D3DDEVICEDESC));
+ }
+
+ /*
+ Does this driver do texture mapping?
+ */
+
+ d3d.Driver[d3d.NumDrivers].Textures =
+ (d3d.Driver[d3d.NumDrivers].Desc.dpcTriCaps.dwTextureCaps &
+ D3DPTEXTURECAPS_PERSPECTIVE) ? TRUE : FALSE;
+
+ /*
+ Can this driver use a z-buffer?
+ */
+
+ d3d.Driver[d3d.NumDrivers].ZBuffer =
+ d3d.Driver[d3d.NumDrivers].Desc.dwDeviceZBufferBitDepth & (DDBD_16 | DDBD_24 | DDBD_32)
+ ? TRUE : FALSE;
+
+// The driver description is recorded here,
+// and some basic things like ZBuffering
+// availability are noted separately. Other
+// things such as hardware acceleration for
+// translucency could potentially be noted here
+// for use in the Write functions to decide
+// whether e.g. iflag_transparent should be
+// treated as valid. Obviously this will
+// require modification of the D3DDRIVERINFO
+// structure in d3_func.h
+
+ *lpStartDriver = d3d.NumDrivers;
+
+ d3d.NumDrivers++;
+ if (d3d.NumDrivers == MAX_D3D_DRIVERS)
+ return (D3DENUMRET_CANCEL);
+ else
+ return (D3DENUMRET_OK);
+}
+
+// This function is called from
+// InitialiseDirect3DImmediateMode, to
+// insert and execute opcodes which cannot
+// be run during a "real" scene because of
+// some obscure feature of Direct3D.
+
+
+
+// Initialise Direct3D immediate mode system
+
+BOOL InitialiseDirect3DImmediateMode(void)
+{
+ BOOL RetVal;
+// to tell device enum function that it has not been called before
+ StartDriver = -1;
+// to tell texture enum function that it has not been called before
+ StartFormat = -1;
+
+// default is no hardware
+// note that we are still resetting
+// this here just in case the test from
+// InitialiseSystem failed and things aren't
+// what we thought...
+ D3DHardwareAvailable = No;
+
+// Zero d3d structure
+ memset(&d3d, 0, sizeof(D3DINFO));
+
+// Set up Direct3D interface object
+
+ LastError = lpDD->QueryInterface(IID_IDirect3D, (LPVOID*) &d3d.lpD3D);
+ LOGDXERR(LastError);
+
+ if (LastError != DD_OK)
+ return FALSE;
+// Use callback function to enumerate available devices on system
+// and acquire device GUIDs etc
+// note that we are still resetting
+// this here just in case the test from
+// InitialiseSystem failed and things aren't
+// what we thought...
+ LastError = d3d.lpD3D->EnumDevices(DeviceEnumerator, (LPVOID)&StartDriver);
+ LOGDXERR(LastError);
+
+ if (LastError != D3D_OK)
+ return FALSE;
+
+// Must be run as soon as possible in the
+// initialisation sequence, but after the
+// device enumeration (and obviously after
+// DirectDraw object and surface initialisation).
+ SelectD3DDriverAndDrawMode();
+ d3d.ThisDriver = d3d.Driver[d3d.CurrentDriver].Desc;
+
+// Test!!! Release D3D object if we don't need it and do an
+// early exit. Will this fix the banding problem on some
+// accelerators in palettised modes??
+// Evidently not. Still, probably a good thing to do...
+// But!!! The whole banding problem appears to be a
+// modeX emulation problem on some 3D accelerator cards...
+ #if 1
+ if (ScanDrawMode == ScanDrawDirectDraw)
+ {
+ ReleaseDirect3DNotDDOrImages();
+ return TRUE;
+ }
+ #endif
+
+
+// Note that this must be done BEFORE the D3D device object is created
+ #if SupportZBuffering
+ if (ZBufferMode != ZBufferOff)
+ {
+ RetVal = CreateD3DZBuffer();
+ if (RetVal == FALSE) return FALSE;
+ }
+ #endif
+
+// Set up Direct3D device object (must be linked to back buffer)
+ LastError = lpDDSBack->QueryInterface(d3d.Driver[d3d.CurrentDriver].Guid,
+ (LPVOID*)&d3d.lpD3DDevice);
+ LOGDXERR(LastError);
+
+ if (LastError != DD_OK)
+ return FALSE;
+
+ AW_TL_ERC awErr = AwSetD3DDevice(d3d.lpD3DDevice);
+ GLOBALASSERT(AW_TLE_OK==awErr);
+// Enumerate texture formats and pick one
+// (palettised if possible).
+ d3d.NumTextureFormats = 0;
+
+ d3d_desired_tex_fmt=D3TF_8BIT;
+
+ LastError = d3d.lpD3DDevice->EnumTextureFormats
+ (TextureFormatsEnumerator,
+ (LPVOID)&StartFormat);
+ LOGDXERR(LastError);
+
+ if (LastError != D3D_OK)
+ #if debug
+ {
+ ReleaseDirect3D();
+ exit(LastError);
+ }
+ #else
+ return FALSE;
+ #endif
+
+ d3d.CurrentTextureFormat = StartFormat;
+
+ // NEW NEW NEW
+ // Note: we are NOT restricted to only one texture format
+ awErr = AwSetTextureFormat(&d3d.TextureFormat[StartFormat].ddsd);
+ GLOBALASSERT(AW_TLE_OK==awErr);
+
+// Create viewport
+ LastError = d3d.lpD3D->CreateViewport(&d3d.lpD3DViewport, NULL);
+ LOGDXERR(LastError);
+
+ if (LastError != D3D_OK)
+ return FALSE;
+
+// Add viewport to desired device
+ LastError = d3d.lpD3DDevice->AddViewport(d3d.lpD3DViewport);
+ LOGDXERR(LastError);
+
+ if (LastError != D3D_OK)
+ return FALSE;
+
+// Set up viewport data
+
+// Note that the viewport is always set to the
+// SDB limits because internal clipping is handled
+// within the main engine code using the VDB
+// system.
+
+ {
+ // Configure viewport here
+ D3DVIEWPORT viewPort;
+ memset(&viewPort, 0, sizeof(D3DVIEWPORT));
+ viewPort.dwSize = sizeof(D3DVIEWPORT);
+ viewPort.dwX = 0; // origins x and y
+ viewPort.dwY = 0;
+ viewPort.dwWidth = ScreenDescriptorBlock.SDB_Width;
+ viewPort.dwHeight = ScreenDescriptorBlock.SDB_Height;
+ viewPort.dvScaleX = D3DVAL((float)viewPort.dwWidth / 2.0); // ????was 2.0
+ viewPort.dvScaleY = D3DVAL((float)viewPort.dwHeight / 2.0); // ????was 2.0
+ viewPort.dvMaxX = D3DVAL(D3DDivide(D3DVAL(viewPort.dwWidth),
+ D3DVAL(2 * viewPort.dvScaleX))); // ????
+ viewPort.dvMaxY = D3DVAL(D3DDivide(D3DVAL(viewPort.dwHeight),
+ D3DVAL(2 * viewPort.dvScaleY))); // ????
+
+ // And actually set viewport
+ LastError = d3d.lpD3DViewport->SetViewport(&viewPort);
+ LOGDXERR(LastError);
+
+ if (LastError != D3D_OK)
+ return FALSE;
+ }
+
+// At present we will not set a background material for the
+// viewport, staying instead with the blit code in backdrop.c
+
+// Also, we are not currently adding default lights to the
+// viewport, since the engine lighting system is completely
+// disconnected from the immediate mode lighting module.
+
+// Create execute buffer
+
+ {
+ // Locals for execute buffer
+ D3DEXECUTEBUFFERDESC d3dexDesc;
+
+ // Set up structure to initialise buffer
+ // Note some instructions (e.g. lines) may be smaller than a
+ // triangle, but none can be larger
+ ExBufSize = ((sizeof(D3DINSTRUCTION) + sizeof(D3DTRIANGLE))
+ * MaxD3DInstructions)
+ + (sizeof(D3DTLVERTEX) * MaxD3DVertices);
+ memset(&d3dexDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
+ d3dexDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
+ d3dexDesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
+ d3dexDesc.dwBufferSize = ExBufSize;
+ #if ForceExecuteBufferIntoSystemMemory
+ d3dexDesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
+ #else
+ d3dexDesc.dwCaps = D3DDEBCAPS_MEM; // untested!!!
+ #endif
+
+ // Create buffer
+ LastError = d3d.lpD3DDevice->CreateExecuteBuffer
+ (&d3dexDesc, &lpD3DExecCmdBuf, NULL);
+ LOGDXERR(LastError);
+
+ if (LastError != D3D_OK)
+ return FALSE;
+ }
+
+ // Temporary patch here because the defaults function
+ // buggers palette setting in ScanDrawDirectDraw
+ // for some really obscure reason...
+
+ if (ScanDrawMode != ScanDrawDirectDraw)
+ SetExecuteBufferDefaults();
+
+
+ return TRUE;
+}
+
+#if 1
+
+// Note that error conditions have been removed
+// on the grounds that an early exit will prevent
+// EndScene being run if this function is used,
+// which screws up all subsequent buffers
+
+BOOL RenderD3DScene(void)
+
+{
+ // Begin scene
+ // My theory is that the functionality of this
+ // thing must invoke a DirectDraw surface lock
+ // on the back buffer without telling you. However,
+ // we shall see...
+
+ LastError = d3d.lpD3DDevice->BeginScene();
+ LOGDXERR(LastError);
+
+ // if (LastError != D3D_OK)
+ // return FALSE;
+
+ // Execute buffer
+ LastError = d3d.lpD3DDevice->Execute(lpD3DExecCmdBuf,
+ d3d.lpD3DViewport, D3DEXECUTE_UNCLIPPED);
+ LOGDXERR(LastError);
+
+ // if (LastError != D3D_OK)
+ // return FALSE;
+
+ // End scene
+ LastError = d3d.lpD3DDevice->EndScene();
+ LOGDXERR(LastError);
+
+ // if (LastError != D3D_OK)
+ // return FALSE;
+
+
+
+ return TRUE;
+}
+
+#else
+
+int Time1, Time2, Time3, Time4;
+
+BOOL RenderD3DScene(void)
+
+{
+
+ // Begin scene
+ // My theory is that the functionality of this
+ // thing must invoke a DirectDraw surface lock
+ // on the back buffer without telling you. However,
+ // we shall see...
+
+ Time1 = GetWindowsTickCount();
+
+ LastError = d3d.lpD3DDevice->BeginScene();
+ LOGDXERR(LastError);
+
+ if (LastError != D3D_OK)
+ return FALSE;
+
+ Time2 = GetWindowsTickCount();
+
+ // Execute buffer
+ #if 1
+ LastError = d3d.lpD3DDevice->Execute(lpD3DExecCmdBuf,
+ d3d.lpD3DViewport, D3DEXECUTE_UNCLIPPED);
+ LOGDXERR(LastError);
+ #else
+ LastError = d3d.lpD3DDevice->Execute(lpD3DExecCmdBuf,
+ d3d.lpD3DViewport, D3DEXECUTE_CLIPPED);
+ LOGDXERR(LastError);
+ #endif
+
+ if (LastError != D3D_OK)
+ return FALSE;
+
+ Time3 = GetWindowsTickCount();
+
+ // End scene
+ LastError = d3d.lpD3DDevice->EndScene();
+ LOGDXERR(LastError);
+
+ if (LastError != D3D_OK)
+ return FALSE;
+
+ Time4 = GetWindowsTickCount();
+
+
+
+ return TRUE;
+
+#endif
+
+
+// With a bit of luck this should automatically
+// release all the Direct3D and DirectDraw
+// objects using their own functionality.
+// A separate call to finiObjects
+// is not required.
+// NOTE!!! This depends on Microsoft macros
+// in d3dmacs.h, which is in the win95 directory
+// and must be upgraded from sdk upgrades!!!
+
+void ReleaseDirect3D(void)
+
+{
+ DeallocateAllImages();
+ RELEASE(d3d.lpD3DViewport);
+ RELEASE(d3d.lpD3DDevice);
+ #if SupportZBuffering
+ RELEASE(lpZBuffer);
+ #endif
+ RELEASE(lpDDPal[0]);
+ RELEASE(lpDDSBack);
+ RELEASE(lpDDSPrimary);
+ RELEASE(d3d.lpD3D);
+ RELEASE(lpDD);
+
+ /* release Direct Input stuff */
+ ReleaseDirectKeyboard();
+ ReleaseDirectMouse();
+ ReleaseDirectInput();
+
+ // Reset windows palette entry allocation
+ if ((VideoModeColourDepth == 8) && (WindowMode == WindowModeSubWindow))
+ {
+ HDC hdc = GetDC(NULL);
+ SetSystemPaletteUse(hdc, SYSPAL_STATIC);
+ ReleaseDC(NULL, hdc);
+ }
+}
+
+// Release all Direct3D objects
+// but not DirectDraw
+
+void ReleaseDirect3DNotDDOrImages(void)
+
+{
+ RELEASE(d3d.lpD3DViewport);
+ RELEASE(d3d.lpD3DDevice);
+ #if SupportZBuffering
+ RELEASE(lpZBuffer);
+ #endif
+ RELEASE(d3d.lpD3D);
+}
+
+void ReleaseDirect3DNotDD(void)
+
+{
+ DeallocateAllImages();
+ RELEASE(d3d.lpD3DViewport);
+ RELEASE(d3d.lpD3DDevice);
+ #if SupportZBuffering
+ RELEASE(lpZBuffer);
+ #endif
+ RELEASE(d3d.lpD3D);
+}
+
+
+// NOTE!!! These functions depend on Microsoft macros
+// in d3dmacs.h, which is in the win95 directory
+// and must be upgraded from sdk upgrades!!!
+
+
+// ALSO NOTE!!! All this stuff involves heavy
+// use of floating point assembler in software
+// emulation, probably hand parallelised between
+// the FPU and the processor or something bizarre,
+// implying that this stuff SHOULD NOT be used
+// one anything below a Pentium.
+
+// AND AGAIN!!! Due to the nature of the item
+// format, the rasterisation module MUST RECEIVE
+// repeated vertices in the data area. Tough shit,
+// Microsoft, that's what I say...
+
+void WritePolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+void WriteGouraudPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+void Write2dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+void WriteGouraud2dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+
+void Write3dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+ }
+
+void WriteGouraud3dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+#if SupportZBuffering
+
+// To make effective use of 16 bit z buffers (common
+// on hardware accelerators) we must have a z coordinate
+// which has been transformed into screen space in such a
+// way that linearity and planearity are preserved, i.e. as
+// if we had done a homogeneous transformation. For the case
+// in which the far clipping plane is much further away than the
+// near one (effectively true for 3dc, especially as there is
+// no far clipping plane as such), the appropriate transformation
+// can be reduced to zScreen = (ZWorld - ZNear) / ZWorld. This
+// calculation is therefore (unfortunately) done for each vertex
+// for z buffered items, taking ZNear to be the current
+// VDB_ClipZ * GlobalScale.
+
+
+void WriteZBPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+void WriteZBGouraudPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+void WriteZB2dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+
+void WriteZBGouraud2dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+void WriteZB3dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+void WriteZBGouraud3dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+#endif
+
+
+
+void WriteBackdrop2dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+// Same as ordinary 2d textured draw at present, but may e.g.
+// require different texture wrapping behaviour or
+// w values.
+
+void WriteBackdrop3dTexturedPolygonToExecuteBuffer(int* itemptr)
+
+{
+}
+
+
+// Note that this is all dead crap and deeply unoptimised
+// But then... a) it's really only a test and
+// b) it's for the tools group anyway...
+
+
+void DirectWriteD3DLine(VECTOR2D* LineStart, VECTOR2D* LineEnd, int LineColour)
+
+{
+
+}
+
+
+// reload D3D image -- assumes a base pointer points to the image loaded
+// from disc, in a suitable format
+
+void ReloadImageIntoD3DImmediateSurface(IMAGEHEADER* iheader)
+{
+
+ void *reloadedTexturePtr = ReloadImageIntoD3DTexture(iheader);
+ LOCALASSERT(reloadedTexturePtr != NULL);
+
+ int gotTextureHandle = GetTextureHandle(iheader);
+ LOCALASSERT(gotTextureHandle == TRUE);
+}
+
+void* ReloadImageIntoD3DTexture(IMAGEHEADER* iheader)
+{
+ // NOTE FIXME BUG HACK
+ // what if the image was a DD surface ??
+
+ if (iheader->hBackup)
+ {
+ iheader->D3DTexture = AwCreateTexture("rf",AW_TLF_PREVSRC|AW_TLF_COMPRESS);
+ return iheader->D3DTexture;
+ }
+ else return NULL;
+}
+
+int GetTextureHandle(IMAGEHEADER *imageHeaderPtr)
+{
+ LPDIRECT3DTEXTURE Texture = (LPDIRECT3DTEXTURE) imageHeaderPtr->D3DTexture;
+
+ LastError = Texture->GetHandle(d3d.lpD3DDevice, (D3DTEXTUREHANDLE*)&(imageHeaderPtr->D3DHandle));
+
+ if (LastError != D3D_OK) return FALSE;
+
+ return TRUE;
+}
+
+
+
+void ReleaseD3DTexture(void* D3DTexture)
+
+{
+ LPDIRECT3DTEXTURE lpTexture;
+
+ lpTexture = (LPDIRECT3DTEXTURE) D3DTexture;
+ RELEASE(lpTexture);
+}
+
+
+#if SupportZBuffering
+
+BOOL CreateD3DZBuffer(void)
+
+{
+ DDSURFACEDESC ddsd;
+
+ // For safety, kill any existing z buffer
+ #if SupportZBuffering
+ RELEASE(lpZBuffer);
+ #endif
+
+
+ // If we do not have z buffering support
+ // on this driver, give up now
+ if (!(d3d.Driver[d3d.CurrentDriver].ZBuffer))
+ return FALSE;
+
+ memset(&ddsd,0,sizeof(DDSURFACEDESC));
+ ddsd.dwSize = sizeof(DDSURFACEDESC);
+ ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH);
+ ddsd.dwHeight = ScreenDescriptorBlock.SDB_Height;
+ ddsd.dwWidth = ScreenDescriptorBlock.SDB_Width;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
+
+ // If we are on a hardware driver, then the z buffer
+ // MUST be in video memory. Otherwise, it MUST be
+ // in system memory. I think.
+
+ if (d3d.Driver[d3d.CurrentDriver].Hardware)
+ ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
+ else
+ ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
+
+ // Get the Z buffer bit depth from this driver's
+ // D3D device description and add it to the description
+ // of the surface we want to create
+
+ devZBufDepth = d3d.Driver[d3d.CurrentDriver].Desc.dwDeviceZBufferBitDepth;
+
+ if (devZBufDepth & DDBD_32)
+ ddsd.dwZBufferBitDepth = 32;
+ else if (devZBufDepth & DDBD_24)
+ ddsd.dwZBufferBitDepth = 24;
+ else if (devZBufDepth & DDBD_16)
+ ddsd.dwZBufferBitDepth = 16;
+ else if (devZBufDepth & DDBD_8)
+ ddsd.dwZBufferBitDepth = 8;
+ else
+ {
+ #if debug
+ ReleaseDirect3D();
+ exit(0x511621);
+ #else
+ return FALSE;
+ #endif
+ }
+
+ // Eight-bit z buffer? Fuck off.
+ if (ddsd.dwZBufferBitDepth == 8)
+ return FALSE;
+
+ // Now we must actually make the z buffer
+
+ LastError = lpDD->CreateSurface(&ddsd,&lpZBuffer, NULL);
+
+ if (LastError != DD_OK)
+ {
+ RELEASE(lpZBuffer);
+ return FALSE;
+ }
+
+ LastError = lpDDSBack->AddAttachedSurface(lpZBuffer);
+
+ if (LastError != DD_OK)
+ {
+ RELEASE(lpZBuffer);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#define ZFlushVal 0xffffffff
+
+// At present we are using my z flush function, with the
+// (undocumented) addition of a fill colour for the
+// actual depth fill, since it seems to work and at least
+// I know what it does. If it starts failing we'll probably
+// have to go back to invoking the viewport clear through
+// Direct3D.
+
+void FlushD3DZBuffer(void)
+
+{
+
+ DDBLTFX ddbltfx;
+
+ memset(&ddbltfx, 0, sizeof(ddbltfx));
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillDepth = devZBufDepth;
+ ddbltfx.dwFillColor = ZFlushVal;
+
+ /* lets blt a color to the surface*/
+ LastError = lpZBuffer->Blt(NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &ddbltfx);
+
+}
+void SecondFlushD3DZBuffer(void)
+{
+ #if 1
+ {
+ WriteEndCodeToExecuteBuffer();
+ UnlockExecuteBufferAndPrepareForUse();
+ ExecuteBuffer();
+ LockExecuteBuffer();
+ }
+
+ DDBLTFX ddbltfx;
+
+ memset(&ddbltfx, 0, sizeof(ddbltfx));
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillDepth = devZBufDepth;
+ ddbltfx.dwFillColor = ZFlushVal;
+
+ /* lets blt a color to the surface*/
+ LastError = lpZBuffer->Blt(NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &ddbltfx);
+ #else
+ extern void ClearZBufferWithPolygon(void);
+ ClearZBufferWithPolygon();
+ #endif
+}
+
+
+#endif
+void FlushZB(void)
+{
+ HRESULT hRes;
+ D3DRECT d3dRect;
+
+
+ d3dRect.lX1 = 0;
+ d3dRect.lX2 = 640;
+ d3dRect.lY1 = 0;
+ d3dRect.lY2 = 480;
+ hRes = d3d.lpD3DViewport->Clear(1, &d3dRect, D3DCLEAR_ZBUFFER);
+
+
+}
+
+
+
+// For extern "C"
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \ No newline at end of file