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