1 
2 // Interface  functions (written in C++) for
3 // Direct3D immediate mode system
4 
5 // Must link to C code in main engine system
6 
7 extern "C" {
8 
9 // Mysterious definition required by objbase.h
10 // (included via one of the include files below)
11 // to start definition of obscure unique in the
12 // universe IDs required  by Direct3D before it
13 // will deign to cough up with anything useful...
14 
15 #define INITGUID
16 
17 #include "3dc.h"
18 
19 #include "awTexLd.h"
20 
21 #include "dxlog.h"
22 #include "module.h"
23 #include "inline.h"
24 
25 #include "d3_func.h"
26 #include "d3dmacs.h"
27 
28 #include "string.h"
29 
30 #include "kshape.h"
31 #include "eax.h"
32 #include "vmanpset.h"
33 
34 extern "C++" {
35 #include "chnktexi.h"
36 #include "chnkload.hpp" // c++ header which ignores class definitions/member functions if __cplusplus is not defined ?
37 #include "r2base.h"
38 }
39 
40 #define UseLocalAssert No
41 #include "ourasert.h"
42 
43 
44 
45 // FIXME!!! Structures in d3d structure
46 // never have any size field set!!!
47 // This is how it's done in Microsoft's
48 // demo code --- but ARE THEY LYING???
49 
50 // As far as I know the execute buffer should always be in
51 // system memory on any configuration, but this may
52 // eventually have to be changed to something that reacts
53 // to the caps bit in the driver, once drivers have reached
54 // the point where we can safely assume that such bits will be valid.
55 #define ForceExecuteBufferIntoSystemMemory Yes
56 
57 // To define TBLEND mode --- at present
58 // it must be on for ramp textures and
59 // off for evrything else...
60 #define ForceTBlendCopy No
61 
62 // Set to Yes for debugging, to No for normal
63 // operations (i.e. if we need a palettised
64 // file for an accelerator, load it from
65 // pre-palettised data, using code not yet
66 // written as of 27 / 8/ 96)
67 #define QuantiseOnLoad Yes
68 
69 // Set to Yes to make default texture filter bilinear averaging rather
70 // than nearest
71 BOOL BilinearTextureFilter = 1;
72 
73 extern LPDIRECTDRAW lpDD;
74 
75 #if 0//
76 // Externs
77 
78 extern int VideoMode;
79 extern int DXMemoryMode;
80 extern int ZBufferRequestMode;
81 extern int RasterisationRequestMode;
82 extern int SoftwareScanDrawRequestMode;
83 extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
84 extern VIEWDESCRIPTORBLOCK* Global_VDB_Ptr;
85 extern IMAGEHEADER ImageHeaderArray[];
86 extern BOOL MMXAvailable;
87 
88 
89 //Globals
90 
91 int D3DDriverMode;
92 
93 
94 
95 static unsigned char DefaultD3DTextureFilterMin;
96 static unsigned char DefaultD3DTextureFilterMax;
97 
98 
99 #if SuppressWarnings
100 static int* itemptr_tmp;
101 #endif
102 
103 
104 #endif //
105 HRESULT LastError;
106 int ExBufSize;
107 
108 LPDIRECT3DEXECUTEBUFFER lpD3DExecCmdBuf;
109 LPDIRECTDRAWSURFACE lpZBuffer;
110 extern LPDIRECTDRAWSURFACE lpDDSBack;
111 extern LPDIRECTDRAWSURFACE lpDDSPrimary;
112 extern LPDIRECTDRAWPALETTE lpDDPal[]; // DirectDraw palette
113 
114 D3DINFO d3d;
115 BOOL D3DHardwareAvailable;
116 
117 int StartDriver;
118 int StartFormat;
119 
120 
121 static int devZBufDepth;
122 
123 
124 extern int WindowMode;
125 extern int ZBufferMode;
126 extern int ScanDrawMode;
127 extern int VideoModeColourDepth;
128 
129 extern enum TexFmt { D3TF_4BIT, D3TF_8BIT, D3TF_16BIT, D3TF_32BIT, D3TF_MAX } d3d_desired_tex_fmt;
130 
131 // Callback function to enumerate devices present
132 // on system (required so that device interface GUID
133 // can be retrieved if for no other reason).  Device
134 // information is copied into instance of structure
135 // defined in d3_func.h
136 
DeviceEnumerator(LPGUID lpGuid,LPSTR lpDeviceDescription,LPSTR lpDeviceName,LPD3DDEVICEDESC lpHWDesc,LPD3DDEVICEDESC lpHELDesc,LPVOID lpContext)137 HRESULT WINAPI DeviceEnumerator(LPGUID lpGuid,
138         LPSTR lpDeviceDescription, LPSTR lpDeviceName,
139         LPD3DDEVICEDESC lpHWDesc, LPD3DDEVICEDESC lpHELDesc, LPVOID lpContext)
140 {
141     int *lpStartDriver = (int *)lpContext;
142 
143     /*
144       Record the D3D driver's description
145 	  of itself.
146     */
147 
148     memcpy(&d3d.Driver[d3d.NumDrivers].Guid, lpGuid, sizeof(GUID));
149     strcpy(d3d.Driver[d3d.NumDrivers].About, lpDeviceDescription);
150     strcpy(d3d.Driver[d3d.NumDrivers].Name, lpDeviceName);
151 
152     /*
153       Is this a hardware device or software emulation?  Checking the color
154       model for a valid model works.
155     */
156 
157     if (lpHWDesc->dcmColorModel)
158 	  {
159 	   D3DHardwareAvailable = Yes;
160        d3d.Driver[d3d.NumDrivers].Hardware = Yes;
161        memcpy(&d3d.Driver[d3d.NumDrivers].Desc, lpHWDesc,
162                sizeof(D3DDEVICEDESC));
163       }
164     else
165       {
166        d3d.Driver[d3d.NumDrivers].Hardware = No;
167        memcpy(&d3d.Driver[d3d.NumDrivers].Desc, lpHELDesc,
168                sizeof(D3DDEVICEDESC));
169       }
170 
171     /*
172       Does this driver do texture mapping?
173     */
174 
175     d3d.Driver[d3d.NumDrivers].Textures =
176         (d3d.Driver[d3d.NumDrivers].Desc.dpcTriCaps.dwTextureCaps &
177          D3DPTEXTURECAPS_PERSPECTIVE) ? TRUE : FALSE;
178 
179     /*
180       Can this driver use a z-buffer?
181     */
182 
183     d3d.Driver[d3d.NumDrivers].ZBuffer =
184         d3d.Driver[d3d.NumDrivers].Desc.dwDeviceZBufferBitDepth & (DDBD_16 | DDBD_24 | DDBD_32)
185                 ? TRUE : FALSE;
186 
187 // The driver description is recorded here,
188 // and some basic things like ZBuffering
189 // availability are noted separately.  Other
190 // things such as hardware acceleration for
191 // translucency could potentially be noted here
192 // for use in the Write functions to decide
193 // whether e.g. iflag_transparent should be
194 // treated as valid.  Obviously this will
195 // require modification of the D3DDRIVERINFO
196 // structure in d3_func.h
197 
198     *lpStartDriver = d3d.NumDrivers;
199 
200     d3d.NumDrivers++;
201     if (d3d.NumDrivers == MAX_D3D_DRIVERS)
202       return (D3DENUMRET_CANCEL);
203 	else
204       return (D3DENUMRET_OK);
205 }
206 
207 // This function is called from
208 // InitialiseDirect3DImmediateMode, to
209 // insert and execute opcodes which cannot
210 // be run during a "real" scene because of
211 // some obscure feature of Direct3D.
212 
213 
214 
215 // Initialise Direct3D immediate mode system
216 
InitialiseDirect3DImmediateMode(void)217 BOOL InitialiseDirect3DImmediateMode(void)
218 {
219     BOOL RetVal;
220 // to tell device enum function that it has not been called before
221 	StartDriver = -1;
222 // to tell texture enum function that it has not been called before
223     StartFormat = -1;
224 
225 // default is no hardware
226 // note that we are still resetting
227 // this here just in case the test from
228 // InitialiseSystem failed and things aren't
229 // what we thought...
230 	D3DHardwareAvailable = No;
231 
232 // Zero d3d structure
233     memset(&d3d, 0, sizeof(D3DINFO));
234 
235 //  Set up Direct3D interface object
236 
237 	LastError = lpDD->QueryInterface(IID_IDirect3D, (LPVOID*) &d3d.lpD3D);
238 	LOGDXERR(LastError);
239 
240     if (LastError != DD_OK)
241 	  return FALSE;
242 // Use callback function to enumerate available devices on system
243 // and acquire device GUIDs etc
244 // note that we are still resetting
245 // this here just in case the test from
246 // InitialiseSystem failed and things aren't
247 // what we thought...
248     LastError = d3d.lpD3D->EnumDevices(DeviceEnumerator, (LPVOID)&StartDriver);
249 	LOGDXERR(LastError);
250 
251     if (LastError != D3D_OK)
252       return FALSE;
253 
254 // Must be run as soon as possible in the
255 // initialisation sequence, but after the
256 // device enumeration (and obviously after
257 // DirectDraw object and surface initialisation).
258     SelectD3DDriverAndDrawMode();
259 	d3d.ThisDriver = d3d.Driver[d3d.CurrentDriver].Desc;
260 
261 // Test!!! Release D3D object if we don't need it and do an
262 // early exit.  Will this fix the banding problem on some
263 // accelerators in palettised modes??
264 // Evidently not.  Still, probably a good thing to do...
265 // But!!! The whole banding problem appears to be a
266 // modeX emulation problem on some 3D accelerator cards...
267    #if 1
268    if (ScanDrawMode == ScanDrawDirectDraw)
269      {
270 	  ReleaseDirect3DNotDDOrImages();
271 	  return TRUE;
272 	 }
273    #endif
274 
275 
276 //  Note that this must be done BEFORE the D3D device object is created
277     #if SupportZBuffering
278     if (ZBufferMode != ZBufferOff)
279 	{
280     	RetVal = CreateD3DZBuffer();
281 		if (RetVal == FALSE) return FALSE;
282 	}
283 	#endif
284 
285 //  Set up Direct3D device object (must be linked to back buffer)
286     LastError = lpDDSBack->QueryInterface(d3d.Driver[d3d.CurrentDriver].Guid,
287                (LPVOID*)&d3d.lpD3DDevice);
288 	LOGDXERR(LastError);
289 
290     if (LastError != DD_OK)
291       return FALSE;
292 
293 	AW_TL_ERC awErr = AwSetD3DDevice(d3d.lpD3DDevice);
294     GLOBALASSERT(AW_TLE_OK==awErr);
295 // Enumerate texture formats and pick one
296 // (palettised if possible).
297     d3d.NumTextureFormats = 0;
298 
299 	d3d_desired_tex_fmt=D3TF_8BIT;
300 
301     LastError = d3d.lpD3DDevice->EnumTextureFormats
302               (TextureFormatsEnumerator,
303               (LPVOID)&StartFormat);
304 	LOGDXERR(LastError);
305 
306     if (LastError != D3D_OK)
307     #if debug
308       {
309 	   ReleaseDirect3D();
310 	   exit(LastError);
311 	  }
312     #else
313       return FALSE;
314     #endif
315 
316     d3d.CurrentTextureFormat = StartFormat;
317 
318     // NEW NEW NEW
319     // Note: we are NOT restricted to only one texture format
320     awErr = AwSetTextureFormat(&d3d.TextureFormat[StartFormat].ddsd);
321     GLOBALASSERT(AW_TLE_OK==awErr);
322 
323 // Create viewport
324 	LastError = d3d.lpD3D->CreateViewport(&d3d.lpD3DViewport, NULL);
325 	LOGDXERR(LastError);
326 
327    if (LastError != D3D_OK)
328      return FALSE;
329 
330 // Add viewport to desired device
331    LastError = d3d.lpD3DDevice->AddViewport(d3d.lpD3DViewport);
332 	LOGDXERR(LastError);
333 
334    if (LastError != D3D_OK)
335      return FALSE;
336 
337 // Set up viewport data
338 
339 // Note that the viewport is always set to the
340 // SDB limits because internal clipping is handled
341 // within the main engine code using the VDB
342 // system.
343 
344    {
345     // Configure viewport here
346     D3DVIEWPORT viewPort;
347 	memset(&viewPort, 0, sizeof(D3DVIEWPORT));
348 	viewPort.dwSize = sizeof(D3DVIEWPORT);
349 	viewPort.dwX = 0; // origins x and y
350 	viewPort.dwY = 0;
351 	viewPort.dwWidth = ScreenDescriptorBlock.SDB_Width;
352 	viewPort.dwHeight = ScreenDescriptorBlock.SDB_Height;
353 	viewPort.dvScaleX = D3DVAL((float)viewPort.dwWidth / 2.0); // ????was 2.0
354 	viewPort.dvScaleY = D3DVAL((float)viewPort.dwHeight  / 2.0); // ????was 2.0
355     viewPort.dvMaxX = D3DVAL(D3DDivide(D3DVAL(viewPort.dwWidth),
356                   D3DVAL(2 * viewPort.dvScaleX))); // ????
357     viewPort.dvMaxY = D3DVAL(D3DDivide(D3DVAL(viewPort.dwHeight),
358                   D3DVAL(2 * viewPort.dvScaleY))); // ????
359 
360     // And actually set viewport
361     LastError = d3d.lpD3DViewport->SetViewport(&viewPort);
362 	LOGDXERR(LastError);
363 
364     if (LastError != D3D_OK)
365 	  return FALSE;
366    }
367 
368 // At present we will not set a background material for the
369 // viewport, staying instead with the blit code in backdrop.c
370 
371 // Also, we are not currently adding default lights to the
372 // viewport, since the engine lighting system is completely
373 // disconnected from the immediate mode lighting module.
374 
375 // Create execute buffer
376 
377   {
378    // Locals for execute buffer
379    D3DEXECUTEBUFFERDESC d3dexDesc;
380 
381    // Set up structure to initialise buffer
382    // Note some instructions (e.g. lines) may be smaller than a
383    // triangle, but none can be larger
384    ExBufSize = ((sizeof(D3DINSTRUCTION) + sizeof(D3DTRIANGLE))
385                 * MaxD3DInstructions)
386 			    + (sizeof(D3DTLVERTEX) * MaxD3DVertices);
387    memset(&d3dexDesc, 0, sizeof(D3DEXECUTEBUFFERDESC));
388    d3dexDesc.dwSize = sizeof(D3DEXECUTEBUFFERDESC);
389    d3dexDesc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
390    d3dexDesc.dwBufferSize = ExBufSize;
391    #if ForceExecuteBufferIntoSystemMemory
392    d3dexDesc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY;
393    #else
394    d3dexDesc.dwCaps = D3DDEBCAPS_MEM; // untested!!!
395    #endif
396 
397    // Create buffer
398    LastError = d3d.lpD3DDevice->CreateExecuteBuffer
399             (&d3dexDesc, &lpD3DExecCmdBuf, NULL);
400 	LOGDXERR(LastError);
401 
402    if (LastError != D3D_OK)
403      return FALSE;
404   }
405 
406   // Temporary patch here because the defaults function
407   // buggers palette setting in ScanDrawDirectDraw
408   // for some really obscure reason...
409 
410   if (ScanDrawMode != ScanDrawDirectDraw)
411     SetExecuteBufferDefaults();
412 
413 
414   return TRUE;
415 }
416 
417 #if 1
418 
419 // Note that error conditions have been removed
420 // on the grounds that an early exit will prevent
421 // EndScene being run if this function is used,
422 // which screws up all subsequent buffers
423 
RenderD3DScene(void)424 BOOL RenderD3DScene(void)
425 
426 {
427     // Begin scene
428 	// My theory is that the functionality of this
429 	// thing must invoke a DirectDraw surface lock
430 	// on the back buffer without telling you.  However,
431 	// we shall see...
432 
433 	LastError = d3d.lpD3DDevice->BeginScene();
434 	LOGDXERR(LastError);
435 
436 	// if (LastError != D3D_OK)
437 	//  return FALSE;
438 
439 	// Execute buffer
440 	LastError = d3d.lpD3DDevice->Execute(lpD3DExecCmdBuf,
441 	          d3d.lpD3DViewport, D3DEXECUTE_UNCLIPPED);
442 	LOGDXERR(LastError);
443 
444 	// if (LastError != D3D_OK)
445 	//  return FALSE;
446 
447 	// End scene
448     LastError = d3d.lpD3DDevice->EndScene();
449 	LOGDXERR(LastError);
450 
451 	// if (LastError != D3D_OK)
452 	//  return FALSE;
453 
454 
455 
456 	return TRUE;
457 }
458 
459 #else
460 
461 int Time1, Time2, Time3, Time4;
462 
RenderD3DScene(void)463 BOOL RenderD3DScene(void)
464 
465 {
466 
467     // Begin scene
468 	// My theory is that the functionality of this
469 	// thing must invoke a DirectDraw surface lock
470 	// on the back buffer without telling you.  However,
471 	// we shall see...
472 
473     Time1 = GetWindowsTickCount();
474 
475 	LastError = d3d.lpD3DDevice->BeginScene();
476 	LOGDXERR(LastError);
477 
478 	if (LastError != D3D_OK)
479 	  return FALSE;
480 
481     Time2 = GetWindowsTickCount();
482 
483 	// Execute buffer
484 	#if 1
485 	LastError = d3d.lpD3DDevice->Execute(lpD3DExecCmdBuf,
486 	          d3d.lpD3DViewport, D3DEXECUTE_UNCLIPPED);
487 	LOGDXERR(LastError);
488 	#else
489 	LastError = d3d.lpD3DDevice->Execute(lpD3DExecCmdBuf,
490 	          d3d.lpD3DViewport, D3DEXECUTE_CLIPPED);
491 	LOGDXERR(LastError);
492 	#endif
493 
494 	if (LastError != D3D_OK)
495 	  return FALSE;
496 
497     Time3 = GetWindowsTickCount();
498 
499 	// End scene
500     LastError = d3d.lpD3DDevice->EndScene();
501 	LOGDXERR(LastError);
502 
503 	if (LastError != D3D_OK)
504 	  return FALSE;
505 
506     Time4 = GetWindowsTickCount();
507 
508 
509 
510 	return TRUE;
511 
512 #endif
513 
514 
515 // With a bit of luck this should automatically
516 // release all the Direct3D and  DirectDraw
517 // objects using their own functionality.
518 // A separate call to finiObjects
519 // is not required.
520 // NOTE!!! This depends on Microsoft macros
521 // in d3dmacs.h, which is in the win95 directory
522 // and must be upgraded from sdk upgrades!!!
523 
524 void ReleaseDirect3D(void)
525 
526 {
527     DeallocateAllImages();
528     RELEASE(d3d.lpD3DViewport);
529     RELEASE(d3d.lpD3DDevice);
530 	#if SupportZBuffering
531     RELEASE(lpZBuffer);
532 	#endif
533     RELEASE(lpDDPal[0]);
534     RELEASE(lpDDSBack);
535     RELEASE(lpDDSPrimary);
536     RELEASE(d3d.lpD3D);
537     RELEASE(lpDD);
538 
539 	/* release Direct Input stuff */
540 	ReleaseDirectKeyboard();
541 	ReleaseDirectMouse();
542 	ReleaseDirectInput();
543 
544 	// Reset windows palette entry allocation
545 	if ((VideoModeColourDepth == 8) && (WindowMode == WindowModeSubWindow))
546 	  {
547 	   HDC hdc = GetDC(NULL);
548 	   SetSystemPaletteUse(hdc, SYSPAL_STATIC);
549        ReleaseDC(NULL, hdc);
550 	  }
551 }
552 
553 // Release all Direct3D objects
554 // but not DirectDraw
555 
556 void ReleaseDirect3DNotDDOrImages(void)
557 
558 {
559     RELEASE(d3d.lpD3DViewport);
560     RELEASE(d3d.lpD3DDevice);
561 	#if SupportZBuffering
562     RELEASE(lpZBuffer);
563 	#endif
564     RELEASE(d3d.lpD3D);
565 }
566 
567 void ReleaseDirect3DNotDD(void)
568 
569 {
570     DeallocateAllImages();
571     RELEASE(d3d.lpD3DViewport);
572     RELEASE(d3d.lpD3DDevice);
573 	#if SupportZBuffering
574     RELEASE(lpZBuffer);
575 	#endif
576     RELEASE(d3d.lpD3D);
577 }
578 
579 
580 // NOTE!!! These functions depend on Microsoft macros
581 // in d3dmacs.h, which is in the win95 directory
582 // and must be upgraded from sdk upgrades!!!
583 
584 
585 // ALSO NOTE!!!  All this stuff involves heavy
586 // use of floating point assembler in software
587 // emulation, probably hand parallelised between
588 // the FPU and the processor or something bizarre,
589 // implying that this stuff SHOULD NOT be used
590 // one anything below a Pentium.
591 
592 // AND AGAIN!!! Due to the nature of the item
593 // format, the  rasterisation module MUST RECEIVE
594 // repeated vertices in the data area.  Tough shit,
595 // Microsoft, that's what I say...
596 
597 void WritePolygonToExecuteBuffer(int* itemptr)
598 
599 {
600 }
601 
602 void WriteGouraudPolygonToExecuteBuffer(int* itemptr)
603 
604 {
605 }
606 
607 void Write2dTexturedPolygonToExecuteBuffer(int* itemptr)
608 
609 {
610 }
611 
612 void WriteGouraud2dTexturedPolygonToExecuteBuffer(int* itemptr)
613 
614 {
615 }
616 
617 
618 void Write3dTexturedPolygonToExecuteBuffer(int* itemptr)
619 
620 {
621  }
622 
623 void WriteGouraud3dTexturedPolygonToExecuteBuffer(int* itemptr)
624 
625 {
626 }
627 
628 #if SupportZBuffering
629 
630 // To make effective use of 16 bit z buffers (common
631 // on hardware accelerators) we must have a z coordinate
632 // which has been transformed into screen space in such a
633 // way that linearity and planearity are preserved, i.e. as
634 // if we had done a homogeneous transformation.  For the case
635 // in which the far clipping plane is much further away than the
636 // near one (effectively true for 3dc, especially as there is
637 // no far clipping plane as such), the appropriate transformation
638 // can be reduced to zScreen = (ZWorld - ZNear) / ZWorld.  This
639 // calculation is therefore (unfortunately) done for each vertex
640 // for z buffered items, taking ZNear to be the current
641 // VDB_ClipZ * GlobalScale.
642 
643 
644 void WriteZBPolygonToExecuteBuffer(int* itemptr)
645 
646 {
647 }
648 
649 void WriteZBGouraudPolygonToExecuteBuffer(int* itemptr)
650 
651 {
652 }
653 
654 void WriteZB2dTexturedPolygonToExecuteBuffer(int* itemptr)
655 
656 {
657 }
658 
659 
660 void WriteZBGouraud2dTexturedPolygonToExecuteBuffer(int* itemptr)
661 
662 {
663 }
664 
665 void WriteZB3dTexturedPolygonToExecuteBuffer(int* itemptr)
666 
667 {
668 }
669 
670 void WriteZBGouraud3dTexturedPolygonToExecuteBuffer(int* itemptr)
671 
672 {
673 }
674 
675 #endif
676 
677 
678 
679 void WriteBackdrop2dTexturedPolygonToExecuteBuffer(int* itemptr)
680 
681 {
682 }
683 
684 // Same as ordinary 2d textured draw at present, but may e.g.
685 // require different texture wrapping behaviour or
686 // w values.
687 
688 void WriteBackdrop3dTexturedPolygonToExecuteBuffer(int* itemptr)
689 
690 {
691 }
692 
693 
694 // Note that this is all dead crap and deeply unoptimised
695 // But then... a) it's really only a test and
696 // b) it's for the tools group anyway...
697 
698 
699 void DirectWriteD3DLine(VECTOR2D* LineStart, VECTOR2D* LineEnd, int LineColour)
700 
701 {
702 
703 }
704 
705 
706 // reload D3D image -- assumes a base pointer points to the image loaded
707 // from disc, in a suitable format
708 
709 void ReloadImageIntoD3DImmediateSurface(IMAGEHEADER* iheader)
710 {
711 
712     void *reloadedTexturePtr = ReloadImageIntoD3DTexture(iheader);
713 	LOCALASSERT(reloadedTexturePtr != NULL);
714 
715 	int gotTextureHandle = GetTextureHandle(iheader);
716 	LOCALASSERT(gotTextureHandle == TRUE);
717 }
718 
719 void* ReloadImageIntoD3DTexture(IMAGEHEADER* iheader)
720 {
721 	// NOTE FIXME BUG HACK
722 	// what if the image was a DD surface ??
723 
724 	if (iheader->hBackup)
725 	{
726 		iheader->D3DTexture = AwCreateTexture("rf",AW_TLF_PREVSRC|AW_TLF_COMPRESS);
727 		return iheader->D3DTexture;
728 	}
729 	else return NULL;
730 }
731 
732 int GetTextureHandle(IMAGEHEADER *imageHeaderPtr)
733 {
734  	LPDIRECT3DTEXTURE Texture = (LPDIRECT3DTEXTURE) imageHeaderPtr->D3DTexture;
735 
736 	LastError = Texture->GetHandle(d3d.lpD3DDevice, (D3DTEXTUREHANDLE*)&(imageHeaderPtr->D3DHandle));
737 
738 	if (LastError != D3D_OK) return FALSE;
739 
740 	return TRUE;
741 }
742 
743 
744 
745 void ReleaseD3DTexture(void* D3DTexture)
746 
747 {
748 	LPDIRECT3DTEXTURE lpTexture;
749 
750     lpTexture = (LPDIRECT3DTEXTURE) D3DTexture;
751 	RELEASE(lpTexture);
752 }
753 
754 
755 #if SupportZBuffering
756 
757 BOOL CreateD3DZBuffer(void)
758 
759 {
760     DDSURFACEDESC ddsd;
761 
762     // For safety, kill any existing z buffer
763 	#if SupportZBuffering
764 	RELEASE(lpZBuffer);
765 	#endif
766 
767 
768 	// If we do not have z buffering support
769 	// on this driver, give up now
770 	if (!(d3d.Driver[d3d.CurrentDriver].ZBuffer))
771 	  return FALSE;
772 
773     memset(&ddsd,0,sizeof(DDSURFACEDESC));
774     ddsd.dwSize = sizeof(DDSURFACEDESC);
775     ddsd.dwFlags = (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH);
776     ddsd.dwHeight = ScreenDescriptorBlock.SDB_Height;
777     ddsd.dwWidth = ScreenDescriptorBlock.SDB_Width;
778     ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
779 
780 	// If we are on a hardware driver, then the z buffer
781 	// MUST be in video memory.  Otherwise, it MUST be
782 	// in system memory.  I think.
783 
784     if (d3d.Driver[d3d.CurrentDriver].Hardware)
785         ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
786     else
787         ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
788 
789     // Get the Z buffer bit depth from this driver's
790     // D3D device description and add it to the description
791 	// of the surface we want to create
792 
793     devZBufDepth = d3d.Driver[d3d.CurrentDriver].Desc.dwDeviceZBufferBitDepth;
794 
795     if (devZBufDepth & DDBD_32)
796         ddsd.dwZBufferBitDepth = 32;
797     else if (devZBufDepth & DDBD_24)
798         ddsd.dwZBufferBitDepth = 24;
799     else if (devZBufDepth & DDBD_16)
800         ddsd.dwZBufferBitDepth = 16;
801     else if (devZBufDepth & DDBD_8)
802         ddsd.dwZBufferBitDepth = 8;
803     else
804 	  {
805 	   #if debug
806 	   ReleaseDirect3D();
807 	   exit(0x511621);
808 	   #else
809 	   return FALSE;
810 	   #endif
811 	  }
812 
813     // Eight-bit z buffer? Fuck off.
814 	if (ddsd.dwZBufferBitDepth == 8)
815 	  return FALSE;
816 
817     // Now we must actually make the z buffer
818 
819     LastError = lpDD->CreateSurface(&ddsd,&lpZBuffer, NULL);
820 
821     if (LastError != DD_OK)
822 	{
823 	   RELEASE(lpZBuffer);
824 	   return FALSE;
825 	}
826 
827     LastError = lpDDSBack->AddAttachedSurface(lpZBuffer);
828 
829     if (LastError != DD_OK)
830 	{
831 	   RELEASE(lpZBuffer);
832 	   return FALSE;
833 	}
834 
835 	return TRUE;
836 }
837 
838 #define ZFlushVal 0xffffffff
839 
840 // At present we are using my z flush function, with the
841 // (undocumented) addition of a fill colour for the
842 // actual depth fill, since it seems to work and at least
843 // I know what it does.  If it starts failing we'll probably
844 // have to go back to invoking the viewport clear through
845 // Direct3D.
846 
847 void FlushD3DZBuffer(void)
848 
849 {
850 
851 	DDBLTFX ddbltfx;
852 
853     memset(&ddbltfx, 0, sizeof(ddbltfx));
854 	ddbltfx.dwSize = sizeof(ddbltfx);
855 	ddbltfx.dwFillDepth	= devZBufDepth;
856 	ddbltfx.dwFillColor	= ZFlushVal;
857 
858 	/* lets blt a color to the surface*/
859 	LastError = lpZBuffer->Blt(NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &ddbltfx);
860 
861 }
862 void SecondFlushD3DZBuffer(void)
863 {
864 	#if 1
865 	{
866 	   WriteEndCodeToExecuteBuffer();
867   	   UnlockExecuteBufferAndPrepareForUse();
868 	   ExecuteBuffer();
869   	   LockExecuteBuffer();
870 	}
871 
872 	DDBLTFX ddbltfx;
873 
874     memset(&ddbltfx, 0, sizeof(ddbltfx));
875 	ddbltfx.dwSize = sizeof(ddbltfx);
876 	ddbltfx.dwFillDepth	= devZBufDepth;
877 	ddbltfx.dwFillColor	= ZFlushVal;
878 
879 	/* lets blt a color to the surface*/
880 	LastError = lpZBuffer->Blt(NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &ddbltfx);
881 	#else
882 	extern void ClearZBufferWithPolygon(void);
883 	ClearZBufferWithPolygon();
884 	#endif
885 }
886 
887 
888 #endif
889 void FlushZB(void)
890 {
891     HRESULT hRes;
892     D3DRECT d3dRect;
893 
894 
895     d3dRect.lX1 = 0;
896     d3dRect.lX2 = 640;
897     d3dRect.lY1 = 0;
898     d3dRect.lY2 = 480;
899     hRes = d3d.lpD3DViewport->Clear(1, &d3dRect, D3DCLEAR_ZBUFFER);
900 
901 
902 }
903 
904 // For extern "C"
905 
906 };
907