1 #include "3dc.h"
2 
3 #include <sys/stat.h>
4 #include <string.h>
5 
6 #include "inline.h"
7 #include "module.h"
8 
9 #include "chnktexi.h"
10 #include "d3d_hud.h"
11 #define UseLocalAssert Yes
12 #include "ourasert.h"
13 #include "hud_layout.h"
14 
15 #undef textprint
16 
17 #define textprintOn Yes
18 
19 #define DHMtextprint Yes
20 	/* define to use Dave Malcolm's replacement textprint routines */
21 
22 
23 /* As specified by Roxby */
24 #define ClearScreenColour 1000
25 
26 /*
27   Experiment to try and fix mystery driver problems
28   Don't set with ForceWindowsPalette on!!!
29   Leave this on!!!
30   On some video cards it seems necessary not only to
31   set palette on vblanking interval, but also AFTER
32   D3D initialisation is complete...
33 */
34 
35 #define ChangePaletteOnVBAlways Yes
36 
37 /*
38 	Turn on or off checking for the validity
39 	of a video mode before switching to it.
40 	Actually causes problems on some systems
41 	because the DirectDraw enumerator fails to
42 	report valid modes (although on other systems
43 	it can report ones that can't be reached, ho
44 	hum), so at least for Chris H. it needs to be
45 	turned off.
46 	NOTE THAT THIS SHOULD HAVE THE SAME SETTING AS
47 	CheckVideoModes at the start of dd_func.cpp, at
48 	least until we make it a system.h value or
49 	something else sensible...
50 */
51 
52 #define CheckVideoModes No
53 
54 
55 /*
56 
57  externs for commonly used global variables and arrays
58 
59 */
60 
61 extern SHAPEHEADER **mainshapelist;
62 extern SHAPEHEADER *testpaletteshapelist[];
63 extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
64 extern int *Global_ShapeNormals;
65 extern int *Global_ShapePoints;
66 extern int *ItemPointers[];
67 extern int ItemData[];
68 extern char projectsubdirectory[];
69 
70 extern int WinLeftX;
71 extern int WinRightX;
72 extern int WinTopY;
73 extern int WinBotY;
74 
75 extern int WindowRequestMode;
76 extern int VideoRequestMode;
77 extern int ZBufferRequestMode;
78 extern int RasterisationRequestMode;
79 extern int SoftwareScanDrawRequestMode;
80 extern int DXMemoryRequestMode;
81 
82 extern int TotalVideoMemory;
83 extern int NumAvailableVideoModes;
84 extern VIDEOMODEINFO AvailableVideoModes[];
85 
86 extern int memoryInitialisationFailure;
87 
88 extern IMAGEHEADER ImageHeaderArray[]; /* Array of Image Headers */
89 
90 /*
91 
92  Global Variables for PC Watcom Functions
93  and Windows 95!
94 
95 */
96 
97 /* Timer */
98    long lastTickCount;
99 
100 	unsigned char *ScreenBuffer    = 0;		/* Ensure initialised to Null */
101 
102 	unsigned char LPTestPalette[1024]; /* to cast to lp*/
103 
104 	int InputMode;
105 
106 	int VideoMode;
107 	int VideoModeType;
108 	int VideoModeTypeScreen;
109 	int WindowMode;
110 	int ScanDrawMode;
111 	int ZBufferMode;
112 	int DXMemoryMode;
113     unsigned char AttemptVideoModeRestart;
114 	VIDEORESTARTMODES VideoRestartMode;
115 
116     PROCESSORTYPES ProcessorType;
117 	BOOL MMXAvailable;
118 
119 	unsigned char *TextureLightingTable = 0;
120 
121 	unsigned char *PaletteRemapTable = 0;
122 
123 	int NumShadingTables    = 0;
124 
125 	int NumPaletteShadingTables              = 0;
126 
127 	int FrameRate;
128 	int NormalFrameTime;
129 	int PrevNormalFrameTime;
130 	extern int CloakingPhase;
131 
132 	/* These two are dummy values to get the DOS platform to compile */
133 
134 	unsigned char KeyCode;
135 	unsigned char KeyASCII;
136 
137 
138 	#if SuppressWarnings
139 	unsigned char *palette_tmp;
140 	static VIEWDESCRIPTORBLOCK* vdb_tmp;
141 	static SCREENDESCRIPTORBLOCK* sdb_tmp;
142 	#endif
143 
144     /* Keyboard */
145 	unsigned char KeyboardInput[MAX_NUMBER_OF_INPUT_KEYS];
146     unsigned char GotAnyKey;
147 
148     /* Input communication with Windows Procedure */
149     /* Print system */
150 
151 #if !DHMtextprint
152     PRINTQUEUEITEM PrintQueue[MaxMessages];
153 	int MessagesStoredThisFrame;
154 #endif
155 
156 	int textprintPosX;
157 	int textprintPosY;
158 	IMAGEHEADER* fontHeader;
159 
160 	/* Added 28/11/97 by DHM: boolean for run-time switching on/off of textprint */
161 	int bEnableTextprint = No;
162 
163 	/* Added 28/1/98 by DHM: as above, but applies specifically to textprintXY */
164 	int bEnableTextprintXY = Yes;
165 
166 	/* Palette */
167 
168 	unsigned char PaletteBuffer[768 + 1];
169 
170 /* Test Palette */
171 
172 unsigned char TestPalette[768];
173 unsigned char TestPalette2[768];
174 
175 
176 
177 
178 /* KJL 11:48:45 28/01/98 - used to scale NormalFrameTime, so the game can be slowed down */
179 int TimeScale=65536;
180 
181 /* KJL 16:00:11 28/01/98 - unscaled frame time */
182 int RealFrameTime;
183 int GlobalFrameCounter;
184 int RouteFinder_CallsThisFrame;
185 
186 /* KJL 15:08:43 29/03/98 - added to give extra flexibility to debugging text */
187 int PrintDebuggingText(const char* t, ...);
188 int ReleasePrintDebuggingText(const char* t, ...);
189 
190 
191 /*
192 
193  IO and Other Functions for the PC
194 
195 */
196 
197 
198 /*
199 
200  Get Shape Data
201 
202  Function returns a pointer to the Shape Header Block
203 
204 */
205 
GetShapeData(int shapenum)206 SHAPEHEADER* GetShapeData(int shapenum)
207 
208 {
209 
210 	if(shapenum>=0 && shapenum< maxshapes)
211 	{
212 		SHAPEHEADER *sptr = mainshapelist[shapenum];
213 		return sptr;
214 	}
215 
216 	return NULL;
217 }
218 
219 
220 /*
221 
222  Platform specific VDB functions for Initialisation and ShowView()
223 
224 */
225 
PlatformSpecificVDBInit(VIEWDESCRIPTORBLOCK * vdb)226 void PlatformSpecificVDBInit(VIEWDESCRIPTORBLOCK *vdb)
227 
228 {
229 	#if SuppressWarnings
230 	vdb_tmp = vdb;
231 	#endif
232 }
233 
234 
PlatformSpecificShowViewEntry(VIEWDESCRIPTORBLOCK * vdb,SCREENDESCRIPTORBLOCK * sdb)235 void PlatformSpecificShowViewEntry(VIEWDESCRIPTORBLOCK *vdb, SCREENDESCRIPTORBLOCK *sdb)
236 
237 {
238 	#if SuppressWarnings
239 	vdb_tmp = vdb;
240 	sdb_tmp = sdb;
241 	#endif
242 }
243 
244 
PlatformSpecificShowViewExit(VIEWDESCRIPTORBLOCK * vdb,SCREENDESCRIPTORBLOCK * sdb)245 void PlatformSpecificShowViewExit(VIEWDESCRIPTORBLOCK *vdb, SCREENDESCRIPTORBLOCK *sdb)
246 
247 {
248 	#if SuppressWarnings
249 	vdb_tmp = vdb;
250 	sdb_tmp = sdb;
251 	#endif
252 }
253 
254 
255 /*
256 
257  Convert UNIX to MS-DOS
258 
259 */
260 
GetDOSFilename(char * fnameptr)261 void GetDOSFilename(char *fnameptr)
262 
263 {
264 
265 	while(*fnameptr) {
266 
267 		if(*fnameptr == 0x2f) *fnameptr = 0x5c;
268 		fnameptr++;
269 
270 	}
271 
272 }
273 
274 /*
275 
276  Compare two filenames.
277 
278  The first filename is assumed to be raw i.e. has no project subdirectory appended.
279  The second is assumed to be ready for use.
280 
281  Make a copy of both strings, prefix the copy of the first with the project subdirectory
282  and convert them to DOS format before the comparison.
283 
284 */
285 
CompareFilenameCH(char * string1,char * string2)286 int CompareFilenameCH(char *string1, char *string2)
287 
288 {
289 
290 	char *srtmp1;
291 	char *srtmp2;
292 	int slen1 = 0;
293 	int slen2 = 0;
294 	int i;
295 	char fname1[ImageNameSize];
296 	char fname2[ImageNameSize];
297 
298 
299 	#if 0
300 	textprint(" Compare "); textprint(string1); textprint("\n");
301 	textprint(" with    "); textprint(string2); textprint("\n");
302 	/*WaitForReturn();*/
303 	#endif
304 
305 
306 	/* Make a copy of string 1, adding the project subdirectory */
307 
308 	srtmp1 = projectsubdirectory;
309 	srtmp2 = fname1;
310 	while(*srtmp1) *srtmp2++ = *srtmp1++;
311 	srtmp1 = string1;
312 	while(*srtmp1) *srtmp2++ = *srtmp1++;
313 	*srtmp2 = 0;
314 
315 	/* Make a copy of string 2 */
316 
317 	srtmp1 = string2;
318 	srtmp2 = fname2;
319 	while(*srtmp1) *srtmp2++ = *srtmp1++;
320 	*srtmp2 = 0;
321 
322 	/* How long are they? */
323 
324 	srtmp1 = fname1;
325 	while(*srtmp1++ != 0)
326 		slen1++;
327 
328 	srtmp2 = fname2;
329 	while(*srtmp2++ != 0)
330 		slen2++;
331 
332 	fname1[slen1] = 0;	/* Term */
333 	fname2[slen2] = 0;
334 
335 	#if 0
336 	textprint("slen1 = %d, ", slen1);
337 	textprint("slen2 = %d\n", slen2);
338 	#endif
339 
340 	#if 0
341 	textprint(" Compare "); textprint(fname1); textprint("\n");
342 	textprint(" with    "); textprint(fname2); textprint("\n");
343 	/*WaitForReturn();*/
344 	#endif
345 
346 
347 	GetDOSFilename(fname1);
348 	GetDOSFilename(fname2);
349 
350 
351 	if(slen1 != slen2) {
352 		/*textprint("not same\n");*/
353 		return No;
354 	}
355 
356 	srtmp1 = fname1;
357 	srtmp2 = fname2;
358 
359 	#if 0
360 	textprint(" Compare "); textprint(srtmp1); textprint("\n");
361 	textprint(" with    "); textprint(srtmp2); textprint("\n");
362 	WaitForReturn();
363 	#endif
364 
365 	for(i = slen1; i!=0; i--) {
366 		if(*srtmp1++ != *srtmp2++) {
367 			/*textprint("not same\n");*/
368 			return No;
369 		}
370 	}
371 
372 	/*textprint("same\n");*/
373 	return Yes;
374 
375 }
376 
377 
378 
379 
380 
381 
382 
383 /*
384 
385  Create an RGB table for "palette"
386 
387  "GetRemappedPaletteColour()" is an access function for this table
388 
389 */
390 
NearestColour(int rs,int gs,int bs,unsigned char * palette)391 int NearestColour(int rs, int gs, int bs, unsigned char *palette)
392 
393 {
394 
395 	int i;
396 	VECTORCH p0;
397 	VECTORCH p1;
398 	int nearest_index;
399 	int nearest_delta;
400 	int d;
401 
402 
403 	p0.vx = rs;
404 	p0.vy = gs;
405 	p0.vz = bs;
406 
407 	nearest_index = 0;
408 	nearest_delta = bigint;
409 
410 	for(i = 0; i < 256; i++) {
411 
412 		p1.vx = palette[0];
413 		p1.vy = palette[1];
414 		p1.vz = palette[2];
415 
416 		d = FandVD_Distance_3d(&p0, &p1);
417 
418 		if(d < nearest_delta) {
419 
420 			nearest_delta = d;
421 			nearest_index = i;
422 
423 		}
424 
425 		palette += 3;
426 
427 	}
428 
429 	return nearest_index;
430 
431 }
432 
433 
434 /*************************************************************************/
435 /*************************************************************************/
436 
437 
438 /*
439 
440  Initialise System and System Variables
441 
442 */
443 
InitialiseSystem()444 void InitialiseSystem()
445 {
446 	BOOL 		rc;
447 	HINSTANCE hInstance = 0;
448 	int nCmdShow = 1;
449 
450     /*
451 		Pick up processor type
452 	*/
453 
454     ProcessorType = ReadProcessorType();
455 
456     if ((ProcessorType == PType_PentiumMMX) ||
457 	   (ProcessorType == PType_Klamath) ||
458 	   (ProcessorType == PType_OffTopOfScale))
459 	  MMXAvailable = TRUE;
460 	else
461 	  MMXAvailable = FALSE;
462 
463     /*
464 		Copy initial requests to current variables,
465 		subject to later modification.
466 	*/
467 
468     VideoMode = VideoRequestMode;
469 	WindowMode = WindowRequestMode;
470 
471     /*
472 		Initialise dubious restart
473 		system for ModeX emulation
474 		and other problems
475 	*/
476 
477     AttemptVideoModeRestart = No;
478 
479     VideoRestartMode = NoRestartRequired;
480 
481     /*
482 		Potentially a whole suite of caps
483 		functions could be sensibly called
484 		from here, to determine available
485 		sound hardware, network links, 3D
486 		hardware acceleration etc
487 	*/
488 
489     /*
490 	  Initialise the basic Direct Draw object,
491 	  find a hardware 3D capable driver if
492 	  possible and appropriate, and
493       determine what display modes, available
494 	  video memory etc exist.
495 	*/
496 
497 #if 0 /* LINUX */
498 	if (InitialiseDirectDrawObject()
499 	    == FALSE)
500 	   /*
501 	     If we cannot get a video mode,
502 	     fail.  No point in a non debugging option
503 	     for this.
504 	   */
505 	   {
506 	    ReleaseDirect3D();
507 	    exit(0x997799);
508 	   }
509 
510     /*
511 		Initialise global to say whether
512 		we think there is an onboard 3D
513 		acceleration card / motherboard
514 		built-in
515 	*/
516 
517     TestInitD3DObject();
518 
519 /*
520 	This is (HOPEFULLY!!) now the right
521 	place to put this call.  Note that it is
522 	not absolutely certain that we can do test
523 	blits from DirectDraw without setting
524 	a cooperative level, however... And note also
525 	that MMX works better with the back buffer in
526 	system memory...
527 */
528     TestMemoryAccess();
529 #endif
530 
531     /* Initialise main window, windows procedure etc */
532 	rc = InitialiseWindowsSystem(hInstance, nCmdShow, WinInitFull);
533 
534     /* Initialise input interface */
535     memset((void*)KeyboardInput, No, MAX_NUMBER_OF_INPUT_KEYS);
536 	GotAnyKey = No;
537 
538 #if 0 /* LINUX */
539 	/* launch Direct Input */
540 	InitialiseDirectInput();
541 	InitialiseDirectKeyboard();
542 	InitialiseDirectMouse();
543 	InitJoysticks();
544 #endif
545 
546     /* Initialise textprint system */
547     textprintPosX = 0;
548 	textprintPosY = 0;
549 	#if debug
550 	InitPrintQueue();
551 	#endif
552 
553 	#if SUPPORT_MMX
554 	SelectMMXOptions();
555 	#endif
556 
557 	{
558 		/* CDF 4/2/97 */
559 		extern void ConstructOneOverSinTable(void);
560 
561 		ConstructOneOverSinTable();
562 	}
563 
564 }
565 
566 
567 /*
568 
569  Exit the system
570 
571 */
572 
ExitSystem(void)573 void ExitSystem(void)
574 {
575 	/* Game specific exit functions */
576 	ExitGame();
577 
578 
579 	// Added by Mark so that Direct Sound exits cleanly
580 	#if SOUND_ON
581 	ExitSoundSystem();	// In ds_func.cpp
582 	#endif
583 
584     /*
585       Shaft DirectDraw and hit Direct3D
586       with a blunt Bill.
587 	  Note that ReleaseDirect3D is currently
588 	  responsible for whacking DirectDraw
589 	  and DirectInput as well; I should probably
590 	  rename it ReleaseDirectX sometime...
591     */
592 
593 	ReleaseDirect3D();
594 
595 	/* Kill windows procedures */
596 	ExitWindowsSystem();
597 }
598 
599 /*
600 	Timer functions are based on Windows timer
601 	giving number of millisecond ticks since Windows
602 	was last booted.  Note this will wrap round after
603    Windows has been up continuously for  approximately
604 	49.7 days.  This is not considered to be too
605 	significant a limitation...
606 */
607 
608 
609 
ResetFrameCounter(void)610 void ResetFrameCounter(void)
611 {
612 	lastTickCount = timeGetTime();
613 
614 	/* KJL 15:03:33 12/16/96 - I'm setting NormalFrameTime too, rather than checking that it's
615 	non-zero everytime I have to divide by it, since it usually is zero on the first frame. */
616 	NormalFrameTime = 65536 >> 4;
617 	PrevNormalFrameTime = NormalFrameTime;
618 
619 	RealFrameTime = NormalFrameTime;
620 	FrameRate = 16;
621 	GlobalFrameCounter=0;
622 	CloakingPhase = 0;
623 
624 
625 	RouteFinder_CallsThisFrame=0;
626 }
FrameCounterHandler(void)627 void FrameCounterHandler(void)
628 {
629 	int newTickCount = timeGetTime();
630 	int fcnt;
631 
632 	fcnt = newTickCount - lastTickCount;
633 	lastTickCount = newTickCount;
634 
635     if (fcnt == 0)
636 	  fcnt = 1; /* for safety */
637 
638 	FrameRate = TimerFrame / fcnt;
639 
640 	PrevNormalFrameTime = NormalFrameTime;
641 	NormalFrameTime = DIV_FIXED(fcnt,TimerFrame);
642 
643 	RealFrameTime = NormalFrameTime;
644 
645 	{
646 		if (TimeScale!=ONE_FIXED)
647 		{
648 			NormalFrameTime = MUL_FIXED(NormalFrameTime,TimeScale);
649 		}
650 
651 	}
652 	/* cap NormalFrameTime if frame rate is really low */
653 	if (NormalFrameTime>16384) NormalFrameTime=16384;
654 	GlobalFrameCounter++;
655 	CloakingPhase += NormalFrameTime>>5;
656 
657 	RouteFinder_CallsThisFrame=0;
658 }
659 
660 /*
661 
662  Wait for Return Key
663 
664  Such a function may not be defined on some platforms
665 
666  On Windows 95 the description of this function has
667  been changed, so that it calls FlushTextprintBuffer
668  and FlipBuffers before going into the actual
669  WaitForReturn code. This is necessary if it is to
670  behave in the same way after a textprint call as it
671  does on the DOS platform.
672 
673 */
674 
WaitForReturn(void)675 void WaitForReturn(void)
676 
677 {
678 	/* Crude but probably serviceable for now */
679 	long SavedTickCount;
680 	SavedTickCount  = lastTickCount;
681 
682 /* Display any lingering text */
683     FlushTextprintBuffer();
684 	FlipBuffers();
685 
686 	while (!(KeyboardInput[KEY_CR]))
687 	   DirectReadKeyboard();
688 
689 	lastTickCount = SavedTickCount;
690 }
691 
692 
693 
694 
695 /*
696 	By copying the globals here we guarantee
697 	that game functions will receive a set of
698 	input values updated at a defined time
699 */
700 
701 
ReadUserInput(void)702 void ReadUserInput(void)
703 {
704 	DirectReadMouse();
705     ReadJoysticks();
706 	DirectReadKeyboard();
707 }
708 
709 /*
710 	At present all keyboard and mouse input is handled
711 	through project specific functionality in win_func,
712 	and all these functions are therefore empty.  Later
713 	we may port to DirectInput, at which point we
714 	may reactivate these.
715 */
716 
717 
718 
ReadKeyboard(void)719 void ReadKeyboard(void)
720 
721 {
722 }
723 
724 
ReadMouse(void)725 void ReadMouse(void)
726 
727 {
728 
729 
730 }
731 
732 
733 
734 /*
735 	Not NECESSARILY the standard functionality,
736 	but it seems good enough to me...
737 */
738 
CursorHome(void)739 void CursorHome(void)
740 
741 {
742 /* Reset positions for textprint system */
743 	textprintPosX = 0;
744 	textprintPosY = 0;
745 }
746 
747 
GetProjectFilename(char * fname,char * image)748 void GetProjectFilename(char *fname, char *image)
749 {
750 
751 	char *src;
752 	char *dst;
753 
754 
755 	src = projectsubdirectory;
756 	dst = fname;
757 
758 	while(*src)
759 		*dst++ = *src++;
760 
761 	src = image;
762 
763 	while(*src)
764 		*dst++ = *src++;
765 
766 	*dst = 0;
767 
768 }
769 
770 
771 /*
772 
773  Attempts to load the image file.
774 
775  Returns a pointer to the image if successful, else zero.
776 
777  Image Header is filled out if successful, else ignore it.
778 
779  NOTE
780 
781  The pointer to the image data is also stored in the image
782  header.
783 
784 */
785 
LoadImageCH(char * fname,IMAGEHEADER * iheader)786 TEXTURE* LoadImageCH(char *fname, IMAGEHEADER *iheader)
787 {
788 	return 0;
789 }
790 
791 
ConvertToDDPalette(unsigned char * src,unsigned char * dst,int length,int flags)792 void ConvertToDDPalette(unsigned char* src, unsigned char* dst, int length, int flags)
793 {
794 	int i;
795 
796 /*
797 	Copy palette, introducing flags and shifting up
798 	to 8 bit triple
799 */
800 
801 	for (i=0; i<length; i++)
802 		{
803 		 *dst++ = (*src++) << 2;
804 		 *dst++ = (*src++) << 2;
805 		 *dst++ = (*src++) << 2;
806 		 *dst++ = flags;
807 		}
808 }
809 
810 /*
811 
812  Platform specific version of "printf()"
813 
814  Not all platforms support, or indeed are ABLE to support printf() in its
815  general form. For this reasons calls to textprint() are made through this
816  function.
817 
818 */
819 
820 /*
821 	If debug or textprintOn are not defined, these
822 	function defintions are collapsed to a simple
823 	return value, which should collapse to no object
824 	code under optimisation.
825 	The whole issue of turning on or off textprint
826 	beyond this point is hereby left to Kevin and
827 	Chris H to fight to the death about...
828 */
829 
830 #if DHMtextprint
831 
832 
833 /*
834 	Dave Malcolm 21/11/96:
835 
836 	I have rewritten the Win95 textprint routines below.
837 
838 	It should now support:
839 		- carriage returns are no longer automatic at the end of lines; there is a #define if you want this behaviour back
840 		- carriage return characters cause a carriage return
841 		- wraparound at the right-hand edge of the screen, with textprint() wrapping to the left-hand edge,
842 		and textprintXY() wrapping back to the X coordinate
843 		- clipping at the bottom edge of the screen
844 		- a warning message if text has been lost due to clipping or buffer overflows etc.
845 		- a y-offset that can be used to scroll up and down the text overlay output from textprint
846 */
847 
848 	/* VERSION SETTINGS: */
849 		#define AutomaticNewLines	No
850 			/* set this to Yes and you will get a \n inserted automatically at the end of each line */
851 			#if AutomaticNewLines
852 				#error Not yet written...
853 			#endif
854 
855 	/* LOW LEVEL ASSERTION SUPPORT */
856 		/*
857 			We cannot use standard assertions in this routine because this routine is called by the standard
858 			assertion routine, and so would run the risk of infinite loops and excitingly obscure bugs.
859 
860 			For this reason we define a special assert macro.
861 		*/
862 
863 #if 1
864 	#define LOWLEVELASSERT(ignore)
865 #else
866 		#if debug
867 
868 			#define LOWLEVELASSERT(x) \
869 			     (void)									\
870 			     (										\
871 			     	(x) 								\
872 			     	? 1 : (ReleaseDirect3D(),exit(GlobalAssertCode),0)	\
873 			     )
874 
875 		#else
876 			/* Assertions are disabled at compile-time: */
877 			#define LOWLEVELASSERT(ignore)
878 
879 		#endif
880 #endif
881 
882 
883 	/*
884 		We extract arguments into a buffer, with a dodgy hack to increase it in size to give more defence
885 		against buffer overflows; there seems to be no easy & robust way to give vsprintf() a buffer size...
886 
887 		This buffer is reset once per string per frame
888 	*/
889 	#define PARANOIA_BYTES	(1024)
890 	#define TEXTPRINT_BUFFER_SIZE	(MaxMsgChars+PARANOIA_BYTES+1)
891 	static char TextprintBuffer[TEXTPRINT_BUFFER_SIZE]="";
892 
893 	/*
894 
895 	The PRINTQUEUEITEM structure from PLATFORM.H is not used by my system; instead of queueing strings to be
896 	displayed we do it on a character by character basis, with a limit on the total number of chars per frame.
897 
898 	This limit is set to be (MaxMsgChars*MaxMessages), which gives the same power and more flexibility than the
899 	old system.
900 
901 	When the queue is full, additional characters get ignored.
902 
903 	This is queue is reset once per frame.
904 
905 	*/
906 
907 	typedef struct daveprintchar {
908 		char CharToPrint;
909 		int x,y;
910 	} DAVEPRINTCHAR;
911 
912 	#define DHM_PRINT_QUEUE_SIZE (MaxMsgChars*MaxMessages)
913 
914 	static DAVEPRINTCHAR DHM_PrintQueue[DHM_PRINT_QUEUE_SIZE];
915 	static int DHM_NumCharsInQueue=0;
916 
917 	static int fTextLost=No;
918 	static char TextLostMessage[]="textprint warning:TEXT LOST";
919 	#define TEXT_LOST_X	(50)
920 	#define TEXT_LOST_Y	(20)
921 
922 	volatile int textprint_Y_offset=0;
923 
924 
925 /* Dave's version of initialising the print queue */
InitPrintQueue(void)926 void InitPrintQueue(void)
927 {
928 	DHM_NumCharsInQueue=0;
929 	fTextLost=No;
930 }
931 
932 /*
933 
934 	Old systems comment:
935 		Write all messages in buffer to screen
936 		(to be called at end of frame, after surface
937 		/ execute buffer unlock in DrawItemListContents,
938 		so that text appears at the front of the back
939 		buffer immediately before the flip).
940 
941 	This is Dave's version of the same:
942 */
943 
FlushTextprintBuffer(void)944 void FlushTextprintBuffer(void)
945 
946 {
947 	/* PRECONDITION: */
948 	{
949 		LOWLEVELASSERT(DHM_NumCharsInQueue<DHM_PRINT_QUEUE_SIZE);
950 	}
951 
952 	/* CODE: */
953 	{
954 		{
955 			int i;
956 			DAVEPRINTCHAR* pDPR=&DHM_PrintQueue[0];
957 
958 			for (i=0; i<DHM_NumCharsInQueue; i++)
959 			{
960 			#if 0
961 				BlitWin95Char
962 				(
963 					pDPR->x,
964 					pDPR->y,
965 					pDPR->CharToPrint
966 				);
967 			#else
968 				D3D_BlitWhiteChar
969 				(
970 					pDPR->x,
971 					pDPR->y,
972 					pDPR->CharToPrint
973 				);
974 			#endif
975 				pDPR++;
976 			}
977 
978 			if (fTextLost)
979 			{
980 				/* Display error message in case test has been lost due to clipping of Y edge, or buffer overflow */
981 				int i;
982 				int NumChars=strlen(TextLostMessage);
983 
984 				for (i=0;i<NumChars;i++)
985 				{
986 	   //			   	BlitWin95Char(TEXT_LOST_X+(i*CharWidth),TEXT_LOST_Y,TextLostMessage[i]);
987 				}
988 
989 				fTextLost=No;
990 			}
991 		}
992 		DHM_NumCharsInQueue=0;
993 
994 	}
995 }
996 
LastDisplayableXForChars(void)997 static int LastDisplayableXForChars(void)
998 {
999 	return ScreenDescriptorBlock.SDB_Width-CharWidth;
1000 }
1001 
LastDisplayableYForChars(void)1002 static int LastDisplayableYForChars(void)
1003 {
1004 	return ScreenDescriptorBlock.SDB_Height-CharHeight;
1005 }
1006 
1007 
DHM_AddToQueue(int x,int y,char Ch)1008 static void DHM_AddToQueue(int x,int y, char Ch)
1009 {
1010 
1011 	if
1012 	(
1013 		(y>=0)
1014 		&&
1015 		(y<=LastDisplayableYForChars())
1016 	)
1017 	{
1018 		if (DHM_NumCharsInQueue<DHM_PRINT_QUEUE_SIZE)
1019 		{
1020 			DAVEPRINTCHAR* pDPR=&DHM_PrintQueue[DHM_NumCharsInQueue++];
1021 			/* We insert into the queue at this position, updating the length of the queue */
1022 
1023 			pDPR->x=x;
1024 			pDPR->y=y;
1025 			pDPR->CharToPrint=Ch;
1026 		}
1027 		else
1028 		{
1029 			/* Otherwise the queue if full, we will have to ignore this char; set an error flag so we get a message*/
1030 			fTextLost=Yes;
1031 		}
1032 	}
1033 	else
1034 	{
1035 		/* Otherwise the text is off the top or bottom of the screen; set an error flag to get a message up*/
1036 		fTextLost=Yes;
1037 	}
1038 }
1039 
DHM_MoveBufferToQueue(int * pPosX,int * pPosY,int fZeroLeftMargin)1040 static int DHM_MoveBufferToQueue(int* pPosX,int* pPosY,int fZeroLeftMargin)
1041 {
1042 	/*
1043 	Function takes two integers by reference (using pointers), and outputs whatever is in
1044 	the string buffer into the character queue, so that code can be shared by textprint() and textprintXY()
1045 
1046 	Returns "number of lines": any carriage returns or word wraps
1047 	*/
1048 
1049 	/* PRECONDITION */
1050 	{
1051 		LOWLEVELASSERT(pPosX);
1052 		LOWLEVELASSERT(pPosY);
1053 	}
1054 
1055 	/* CODE */
1056 	{
1057 		int NumLines=0;
1058 
1059 		int LeftMarginX;
1060 
1061 		if (fZeroLeftMargin)
1062 		{
1063 			LeftMarginX=0;
1064 		}
1065 		else
1066 		{
1067 			LeftMarginX=*pPosX;
1068 		}
1069 
1070 
1071 
1072 		/* Iterate through the string in the buffer, adding the individual characters to the queue */
1073 		{
1074 			char* pCh=&TextprintBuffer[0];
1075 			int SafetyCount=0;
1076 
1077 			while
1078 			(
1079 				((*pCh)!='\0')
1080 				&&
1081 				((SafetyCount++)<MaxMsgChars)
1082 			)
1083 			{
1084 				switch (*pCh)
1085 				{
1086 					case '\n':
1087 						{
1088 							/* Wrap around to next line.,. */
1089 							(*pPosY)+=HUD_FONT_HEIGHT;
1090 							(*pPosX)=LeftMarginX;
1091 							NumLines++;
1092 
1093 						}
1094 						break;
1095 					default:
1096 						{
1097 							/* It is a standard character or a space */
1098 							DHM_AddToQueue(*pPosX,(*pPosY)+textprint_Y_offset, *pCh);
1099 
1100 							(*pPosX)+=AAFontWidths[(unsigned char)*pCh];//CharWidthInPixels(*pCh);
1101 
1102 							if ((*pPosX)>LastDisplayableXForChars())
1103 							{
1104 								/* Wrap around to next line.,. */
1105 								(*pPosY)+=HUD_FONT_HEIGHT;
1106 								(*pPosX)=LeftMarginX;
1107 								NumLines++;
1108 							}
1109 						}
1110 				}
1111 
1112 				/* ...and on to the next character*/
1113 				pCh++;
1114 			}
1115 		}
1116 
1117 		/* Clear the string buffer */
1118 		{
1119 			TextprintBuffer[0]='\0';
1120 		}
1121 
1122 		return NumLines;
1123 	}
1124 
1125 }
1126 
1127 
textprint(const char * t,...)1128 int textprint(const char* t, ...)
1129 {
1130 	#if (debug && textprintOn)
1131 	if
1132 	(
1133 		bEnableTextprint
1134 	)
1135 	{
1136 		/*
1137 		Get message string from arguments into buffer...
1138 		*/
1139 		{
1140 			va_list ap;
1141 
1142 			va_start(ap, t);
1143 			vsprintf(&TextprintBuffer[0], t, ap);
1144 			va_end(ap);
1145 		}
1146 
1147 		/*
1148 		Attempt to trap buffer overflows...
1149 		*/
1150 		{
1151 			LOWLEVELASSERT(strlen(TextprintBuffer)<TextprintBuffer);
1152 		}
1153 
1154 		return DHM_MoveBufferToQueue(&textprintPosX,&textprintPosY,Yes);
1155 
1156 
1157 	}
1158 	else
1159 	{
1160 		// Run-time disabling of textprint()
1161 		return 0;
1162 	}
1163 	#else
1164 		/* Do nothing; hope the function call gets optimised away */
1165 		return 0;
1166 	#endif
1167 }
PrintDebuggingText(const char * t,...)1168 int PrintDebuggingText(const char* t, ...)
1169 {
1170 	/*
1171 	Get message string from arguments into buffer...
1172 	*/
1173 	{
1174 		va_list ap;
1175 
1176 		va_start(ap, t);
1177 		vsprintf(&TextprintBuffer[0], t, ap);
1178 		va_end(ap);
1179 	}
1180 
1181 	/*
1182 	Attempt to trap buffer overflows...
1183 	*/
1184 	{
1185 		LOWLEVELASSERT(strlen(TextprintBuffer)<TextprintBuffer);
1186 	}
1187 
1188 	return DHM_MoveBufferToQueue(&textprintPosX,&textprintPosY,Yes);
1189 }
ReleasePrintDebuggingText(const char * t,...)1190 int ReleasePrintDebuggingText(const char* t, ...)
1191 {
1192 	/*
1193 	Get message string from arguments into buffer...
1194 	*/
1195 	{
1196 		va_list ap;
1197 
1198 		va_start(ap, t);
1199 		vsprintf(&TextprintBuffer[0], t, ap);
1200 		va_end(ap);
1201 	}
1202 
1203 	/*
1204 	Attempt to trap buffer overflows...
1205 	*/
1206 	{
1207 		LOWLEVELASSERT(strlen(TextprintBuffer)<TextprintBuffer);
1208 	}
1209 
1210 	return DHM_MoveBufferToQueue(&textprintPosX,&textprintPosY,Yes);
1211 }
1212 
1213 
textprintXY(int x,int y,const char * t,...)1214 int textprintXY(int x, int y, const char* t, ...)
1215 
1216 {
1217 	#if (debug && textprintOn)
1218 	if
1219 	(
1220 		bEnableTextprintXY
1221 	)
1222 	{
1223 		/*
1224 		Get message string from arguments into buffer...
1225 		*/
1226 		{
1227 			va_list ap;
1228 
1229 			va_start(ap, t);
1230 			vsprintf(&TextprintBuffer[0], t, ap);
1231 			va_end(ap);
1232 		}
1233 
1234 		/*
1235 		Attempt to trap buffer overflows...
1236 		*/
1237 		{
1238 			LOWLEVELASSERT(strlen(TextprintBuffer)<TextprintBuffer);
1239 		}
1240 
1241 		{
1242 			int localX=x;
1243 			int localY=y;
1244 
1245 			return DHM_MoveBufferToQueue(&localX,&localY,No);
1246 		}
1247 
1248 
1249 	}
1250 	else
1251 	{
1252 		// Run-time disabling of textprint()
1253 		return 0;
1254 	}
1255 	#else
1256 	{
1257 		/* Do nothing; hope the function call gets optimised away */
1258 
1259 		return 0;
1260 	}
1261 	#endif
1262 }
1263 
1264 
1265 
1266 	/*
1267 	 *
1268 	 *
1269 
1270 	End of Dave Malcolm's text routines; old version is below
1271 
1272 	 *
1273 	 *
1274 	 */
1275 #else
1276 
1277 /*
1278 	NOTE!!!! All this software is intended for debugging
1279 	only.  It emulates the print interface in any video
1280 	mode supported by the engine, but there are limits -
1281 	messages will pile up at the bottom of the screen
1282 	and overwrite each other, all messages will appear at the
1283 	fron in the main screen (NOT clipped to the VDB), messages
1284 	will not wrap round if they are longer than a screen line
1285 	unless \n is inserted in the print string, and the text colour
1286 	is not guaranteed to be white in paletted modes.
1287 	So there.
1288 */
1289 
1290 
1291 /*
1292 	IMPORTANT!!!!
1293 	Messages longer than MaxMsgChars are liable
1294 	to CRASH this routine.  I haven't bothered
1295 	to do anything about this on the grounds that
1296 	we can't tell how long the message is until after
1297 	the vsprintf call, and the crash is likely to
1298 	occur in vsprintf itself as it overflows the
1299 	buffer.
1300 */
1301 
1302 /*
1303 	!!!!! FIXME??
1304 	textprints don't seem to appear
1305 	in SubWindow mode --- possibly
1306 	because the colours in the font
1307 	are going to system font colours which
1308 	are invisible???
1309 */
1310 
1311 #if (debug && textprintOn)
1312 
textprint(const char * t,...)1313 int textprint(const char* t, ...)
1314 
1315 {
1316 	int i,j;
1317 	va_list ap;
1318 	char message[MaxMsgChars];
1319 	char outmsg[MaxMsgChars];
1320 	int numlines;
1321 	int CharCount;
1322 	int XPos=0;
1323 
1324 	va_start(ap, t);
1325 
1326 	vsprintf(&message[0], t, ap);
1327 
1328 	va_end(ap);
1329 
1330     i = 0;
1331 	j = 0;
1332 	numlines = 0;
1333 	CharCount = strlen(&message[0]);
1334 
1335     /* Read through message buffer until we reach the terminator */
1336     while ((i < CharCount) && (message[i] != '\0'))
1337   	{
1338     	outmsg[j++] = message[i];
1339 		XPos+=CharWidth;
1340         /* newline within string */
1341         if ((message[i] == '\n')||(XPos>ScreenDescriptorBlock.SDB_Width))
1342 	      {
1343 	       /* Display string and reset to start of next line */
1344 	       WriteStringToTextBuffer(textprintPosX, textprintPosY,
1345 	              &outmsg[0]);
1346 		   textprintPosX = 0;
1347 		   textprintPosY += HUD_FONT_HEIGHT;
1348 		   XPos=0;
1349 		   /* Messages can pile up at bottom of screen */
1350 		   if (textprintPosY > ScreenDescriptorBlock.SDB_Height)
1351 		     textprintPosY = ScreenDescriptorBlock.SDB_Height;
1352 		   /* Clear output string and reset variables */
1353 		   {
1354 			int k;
1355 		    for (k=0; k<(j+1); k++)
1356 			  outmsg[k] = 0;
1357 		   }
1358 		   j = 0;
1359 		   /* Record number of lines output */
1360 		   numlines++;
1361 		  }
1362 		 i++;
1363        }
1364 
1365 	/* Flush any remaining characters */
1366 	WriteStringToTextBuffer(textprintPosX, textprintPosY,
1367 	     &outmsg[0]);
1368     textprintPosX = 0;
1369 	textprintPosY += HUD_FONT_HEIGHT;
1370 	/* Messages can pile up at bottom of screen */
1371 	if (textprintPosY > ScreenDescriptorBlock.SDB_Height)
1372 	  textprintPosY = ScreenDescriptorBlock.SDB_Height;
1373 	numlines++;
1374 
1375 	return numlines;
1376 }
1377 
1378 /*
1379 	Textprint to defined location on screen
1380 	(in screen coordinates for current video
1381 	mode).
1382 	NOTE!!! Newlines within strings sent to this
1383 	function will be IGNORED.
1384 */
1385 
textprintXY(int x,int y,const char * t,...)1386 int textprintXY(int x, int y, const char* t, ...)
1387 
1388 {
1389 	va_list ap;
1390 	char message[MaxMsgChars];
1391 
1392 	va_start(ap, t);
1393 
1394 	vsprintf(&message[0], t, ap);
1395 
1396 	va_end(ap);
1397 
1398 	WriteStringToTextBuffer(x, y, &message[0]);
1399 
1400 	return 1; /* for one line */
1401 }
1402 
1403 #else
1404 
textprint(const char * t,...)1405 int textprint(const char* t, ...)
1406 
1407 {
1408 	return 0;
1409 }
1410 
textprintXY(int x,int y,const char * t,...)1411 int textprintXY(int x, int y, const char* t, ...)
1412 
1413 {
1414 	return 0;
1415 }
1416 
1417 #endif
1418 
1419 
1420 /*
1421 	Add string to text buffer
1422 */
1423 
WriteStringToTextBuffer(int x,int y,unsigned char * buffer)1424 void WriteStringToTextBuffer(int x, int y, unsigned char *buffer)
1425 
1426 {
1427 	if (MessagesStoredThisFrame < MaxMessages)
1428 	  {
1429 	   strcpy(PrintQueue[MessagesStoredThisFrame].text, buffer);
1430 
1431        PrintQueue[MessagesStoredThisFrame].text_length = strlen(buffer);
1432 	   PrintQueue[MessagesStoredThisFrame].x = x;
1433 	   PrintQueue[MessagesStoredThisFrame].y = y;
1434 
1435 	   MessagesStoredThisFrame++;
1436 	  }
1437 }
1438 
1439 
1440 /*
1441 	Display string of chracters, starting at passed pointer,
1442 	at location on screen starting with x and y.
1443 
1444 	Patched by Dave Malcolm 20/11/96 so that text wraps around when it reaches the right hand edge of the screen, in
1445 	this routine, at least...
1446 */
1447 
1448 
DisplayWin95String(int x,int y,unsigned char * buffer)1449 void DisplayWin95String(int x, int y, unsigned char *buffer)
1450 
1451 {
1452 	int InitialX=x;
1453 	int stlen;
1454 	unsigned char ch;
1455 
1456 	stlen = strlen(buffer);
1457 
1458     do
1459 	  {
1460        ch = (unsigned char) *buffer;
1461 	   BlitWin95Char(x, y, ch);
1462 	   x += CharWidth;
1463 	   if (x > (ScreenDescriptorBlock.SDB_Width
1464 	       - CharWidth))
1465 		{
1466 			#if 1
1467 				/* Wrap to new line, based on coordinates for display...*/
1468 				x=InitialX;
1469 				y+=HUD_FONT_HEIGHT;
1470 			#else
1471 			   	/* Characters will pile up at screen edge */
1472 				x = (ScreenDescriptorBlock.SDB_Width - CharWidth);
1473 			#endif
1474 		}
1475 
1476 	   buffer++;
1477 	   stlen--;
1478 	  }
1479 	while ((ch != '\n') && (ch != '\0') &&
1480 	      (stlen > 0));
1481 }
1482 
1483 /*
1484 	Write all messages in buffer to screen
1485 	(to be called at end of frame, after surface
1486 	/ execute buffer unlock in DrawItemListContents,
1487 	so that text appears at the front of the back
1488 	buffer immediately before the flip).
1489 */
1490 
FlushTextprintBuffer(void)1491 void FlushTextprintBuffer(void)
1492 
1493 {
1494 	int i;
1495 
1496     for (i=0; i<MessagesStoredThisFrame; i++)
1497 	  {
1498 	   if (PrintQueue[i].text_length)
1499 	     DisplayWin95String(PrintQueue[i].x,
1500 	        PrintQueue[i].y, PrintQueue[i].text);
1501 
1502        /*
1503          More mystery code from Roxby --- an extra safety
1504 		 check for printing?? Or a hangover from a linked
1505 		 list version of the data structure???
1506 	   */
1507        PrintQueue[i].text_length = 0;
1508 	  }
1509 
1510     MessagesStoredThisFrame = 0;
1511 }
1512 
1513 /* Initialise print queue */
1514 
InitPrintQueue(void)1515 void InitPrintQueue(void)
1516 
1517 {
1518 	int i;
1519 
1520     /* Mystery code from Roxby here... */
1521     for (i=0; i < MaxMessages; i++)
1522 	   PrintQueue[i].text_length = 0;
1523 
1524     MessagesStoredThisFrame = 0;
1525 }
1526 
1527 #endif
1528 	/*end of old version of text routines */
1529 
1530 /*
1531 	Load main, 8 bit paletted, font
1532 	(assumed to be on hard drive at present)
1533 	and create hi and true colour mode fonts
1534 	from it. Note that for this system to work
1535 	properly all bits on must be white or similar
1536 	in 8 bit mode 222 and Raw256 palettes as well
1537 	as mode 8T.
1538 */
1539 
1540 /*
1541 	MUST be called after GenerateDirectDrawSurface,
1542 	i.e. AFTER SetVideoMode.
1543 	AND ONLY ONCE!!!!
1544 */
1545 
1546 
1547 
1548 /*
1549 	This function is intended to allow YOU,
1550 	the user, to obtain your heart's fondest desires
1551 	by one simple call.  Money? Love? A better job?
1552 	It's all here, you have only to ask...
1553 	No, I was lying actually.
1554 	In fact, this should allow you to change
1555 	display modes cleanly.  Pass your request modes
1556 	(as normally set up in system.c).  For all entries
1557 	which you do not want to change, simply pass
1558 	the current global value (e.g. ZBufferRequestMode
1559 	in the NewZBufferMode entry).
1560 
1561     Note that the function must always be passed the
1562 	HINSTANCE and nCmdShow from winmain.
1563 */
1564 
1565 /*
1566 	Note that this function will NOT
1567 	reinitialise the DirectDraw object
1568 	or switch to or from a hardware DD
1569 	device, but it will release and rebuild
1570 	all the Direct3D objects.
1571 */
1572 
1573 /*
1574 	Note that you MUST be in the right
1575 	directory for a texture reload before you
1576 	call this, and normal operations CAN change
1577 	the directory...
1578 */
1579 
1580 /*
1581 	NOTE!!! If you start in DirectDraw mode
1582 	and go to Direct3D mode, this function
1583 	CANNOT POSSIBLY WORK WITHOUT A FULL SHAPE
1584 	RELOAD, since the shape data is overwritten
1585 	during DirectDraw initialisation!!!!
1586 
1587     NOTE ALSO: TEXTURE RELOAD MAY BE DODGY
1588 	WITHOUT A SHAPE RELOAD!!!
1589 */
1590 
ChangeDisplayModes(HINSTANCE hInst,int nCmd,int NewVideoMode,int NewWindowMode,int NewZBufferMode,int NewRasterisationMode,int NewSoftwareScanDrawMode,int NewDXMemoryMode)1591 int ChangeDisplayModes(HINSTANCE hInst, int nCmd,
1592      int NewVideoMode, int NewWindowMode,
1593      int NewZBufferMode, int NewRasterisationMode,
1594      int NewSoftwareScanDrawMode, int NewDXMemoryMode)
1595 {
1596     BOOL rc;
1597 	BOOL ChangeWindow = No;
1598 
1599 /*
1600 	Shut down DirectX objects and destroy
1601 	the current window, if necessary.
1602 */
1603 
1604     if (NewWindowMode != WindowMode)
1605 	  ChangeWindow = Yes;
1606 
1607     DeallocateAllImages();
1608 
1609     ReleaseDirect3DNotDD();
1610 
1611     finiObjectsExceptDD();
1612 
1613 
1614     if (ChangeWindow)
1615       ExitWindowsSystem();
1616 
1617 /* Test!! */
1618 
1619 /*
1620 	Set the request modes and actual modes
1621 	according to the passed values.
1622 */
1623 
1624     VideoRequestMode = NewVideoMode;
1625     WindowRequestMode = NewWindowMode;
1626 	ZBufferRequestMode = NewZBufferMode;
1627 	RasterisationRequestMode = NewRasterisationMode;
1628 	SoftwareScanDrawRequestMode = NewSoftwareScanDrawMode;
1629 	DXMemoryRequestMode = NewDXMemoryMode;
1630 
1631     VideoMode = VideoRequestMode;
1632 	WindowMode = WindowRequestMode;
1633 
1634 	/* this may reconstruct the dd object depending
1635 	   on the rasterisation request mode and whether
1636 	   a hardware dd driver is selected or could be
1637 	   available */
1638 	ChangeDirectDrawObject();
1639 
1640     /*
1641 	  Check that our new video mode exists,
1642 	  and pick a valid option if it doesn't and
1643 	  we can find one.
1644 	*/
1645 
1646     #if CheckVideoModes
1647 	if (WindowMode == WindowModeFullScreen)
1648 	  {
1649 	   if (!(CheckForVideoModes(VideoMode)))
1650 	     {
1651 	      VideoMode = VideoMode_DX_640x480x8;
1652 	      if (!(CheckForVideoModes(VideoMode)))
1653 	        {
1654 		     VideoMode = VideoMode_DX_640x480x15;
1655 		     if (!(CheckForVideoModes(VideoMode)))
1656 		       {
1657 			    ReleaseDirect3D(); // for safety
1658 			    return FALSE;
1659 			   }
1660 		    }
1661 	     }
1662 	  }
1663 	#endif
1664 
1665 /*
1666 	Recreate the window, allowing
1667 	for possible change in WindowMode.
1668 */
1669 
1670     if (ChangeWindow)
1671 	  {
1672 	   rc = InitialiseWindowsSystem(hInst, nCmd,
1673 	      WinInitChange);
1674 
1675        if (rc == FALSE)
1676 	     return rc;
1677 	  }
1678 
1679 /*
1680 	Set the video mode again.  This
1681 	will handle all changes to DirectDraw
1682 	objects, all Direct3D initialisation,
1683 	and other request modes such as
1684 	zbuffering.
1685 */
1686 
1687     /*
1688 		Err... shutting down and restarting
1689 		on a hardware driver appears to
1690 		screw up file handling somehow...
1691 		umm... but not for Microsoft demos,
1692 		obviously...
1693 		FIXME!!!
1694 	*/
1695 
1696 /*
1697     SetVideoMode[VideoMode]();
1698 */
1699 
1700 /*
1701 	Lose all the textures and reload the
1702 	debugging font
1703 */
1704 
1705     InitialiseTextures();
1706 
1707 
1708 /*
1709 	Well, we HOPE it's okay...
1710 */
1711 
1712     return TRUE;
1713 }
1714 
1715 
1716 /*
1717 	Reverse of ConvertToDDPalette, introduced
1718 	to maintain internal interfaces only...
1719 */
1720 
ConvertDDToInternalPalette(unsigned char * src,unsigned char * dst,int length)1721 void ConvertDDToInternalPalette(unsigned char* src, unsigned char* dst, int length)
1722 {
1723 	int i;
1724 
1725 /*
1726 	Copy palette, shifting down
1727 	to 5 bit triple
1728 */
1729 
1730 	for (i=0; i<length; i++)
1731 		{
1732 		 *dst++ = (*src++) >> 2;
1733 		 *dst++ = (*src++) >> 2;
1734 		 *dst++ = (*src++) >> 2;
1735 		}
1736 }
1737