1 
2 //**************************************************************************
3 //**
4 //** sb_bar.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile: sb_bar.c,v $
7 //** $Revision: 1.94 $
8 //** $Date: 95/12/31 21:10:08 $
9 //** $Author: bgokey $
10 //**
11 //**************************************************************************
12 
13 // HEADER FILES ------------------------------------------------------------
14 
15 #include "h2def.h"
16 #include "p_local.h"
17 #include "soundst.h"
18 
19 #ifdef __WATCOMC__
20 #include "i_sound.h" // For CD stuff
21 #endif
22 
23 // MACROS ------------------------------------------------------------------
24 
25 #define CHEAT_ENCRYPT(a) \
26 	((((a)&1)<<2)+ \
27 	(((a)&2)>>1)+ \
28 	(((a)&4)<<5)+ \
29 	(((a)&8)<<2)+ \
30 	(((a)&16)>>3)+ \
31 	(((a)&32)<<1)+ \
32 	(((a)&64)>>3)+ \
33 	(((a)&128)>>3))
34 
35 // TYPES -------------------------------------------------------------------
36 
37 typedef struct Cheat_s
38 {
39 	void (*func)(player_t *player, struct Cheat_s *cheat);
40 	byte *sequence;
41 	byte *pos;
42 	int args[2];
43 	int currentArg;
44 } Cheat_t;
45 
46 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
47 
48 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
49 
50 void SB_PaletteFlash(boolean forceChange);
51 
52 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
53 
54 static void DrawSoundInfo(void);
55 static void DrINumber(signed int val, int x, int y);
56 static void DrRedINumber(signed int val, int x, int y);
57 static void DrBNumber(signed int val, int x, int y);
58 static void DrawCommonBar(void);
59 static void DrawMainBar(void);
60 static void DrawInventoryBar(void);
61 static void DrawKeyBar(void);
62 static void DrawWeaponPieces(void);
63 static void DrawFullScreenStuff(void);
64 static void DrawAnimatedIcons(void);
65 static boolean HandleCheats(byte key);
66 static boolean CheatAddKey(Cheat_t *cheat, byte key, boolean *eat);
67 static void CheatGodFunc(player_t *player, Cheat_t *cheat);
68 static void CheatNoClipFunc(player_t *player, Cheat_t *cheat);
69 static void CheatFunnyPiggyFunc1(player_t *player, Cheat_t *cheat);
70 static void CheatFunnyPiggyFunc2(player_t *player, Cheat_t *cheat);
71 static void CheatWeaponsFunc(player_t *player, Cheat_t *cheat);
72 static void CheatHealthFunc(player_t *player, Cheat_t *cheat);
73 static void CheatKeysFunc(player_t *player, Cheat_t *cheat);
74 static void CheatSoundFunc(player_t *player, Cheat_t *cheat);
75 static void CheatTickerFunc(player_t *player, Cheat_t *cheat);
76 static void CheatArtifactAllFunc(player_t *player, Cheat_t *cheat);
77 static void CheatPuzzleFunc(player_t *player, Cheat_t *cheat);
78 static void CheatWarpFunc(player_t *player, Cheat_t *cheat);
79 static void CheatPigFunc(player_t *player, Cheat_t *cheat);
80 static void CheatMassacreFunc(player_t *player, Cheat_t *cheat);
81 static void CheatIDKFAFunc(player_t *player, Cheat_t *cheat);
82 static void CheatQuickenFunc(player_t *player, Cheat_t *cheat);
83 static void CheatClassFunc1(player_t *player, Cheat_t *cheat);
84 static void CheatClassFunc2(player_t *player, Cheat_t *cheat);
85 static void CheatInitFunc(player_t *player, Cheat_t *cheat);
86 static void CheatInitFunc(player_t *player, Cheat_t *cheat);
87 static void CheatVersionFunc(player_t *player, Cheat_t *cheat);
88 static void CheatDebugFunc(player_t *player, Cheat_t *cheat);
89 static void CheatScriptFunc1(player_t *player, Cheat_t *cheat);
90 static void CheatScriptFunc2(player_t *player, Cheat_t *cheat);
91 static void CheatScriptFunc3(player_t *player, Cheat_t *cheat);
92 static void CheatRevealFunc(player_t *player, Cheat_t *cheat);
93 static void CheatTrackFunc1(player_t *player, Cheat_t *cheat);
94 static void CheatTrackFunc2(player_t *player, Cheat_t *cheat);
95 
96 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
97 
98 extern byte *screen;
99 extern int ArmorIncrement[NUMCLASSES][NUMARMOR];
100 extern int AutoArmorSave[NUMCLASSES];
101 
102 #ifdef __WATCOMC__
103 extern boolean i_CDMusic;
104 extern int i_CDMusicLength;
105 extern int i_CDTrack;
106 extern int i_CDCurrentTrack;
107 extern int oldTic;
108 #endif
109 
110 // PUBLIC DATA DECLARATIONS ------------------------------------------------
111 
112 boolean DebugSound; // Debug flag for displaying sound info
113 boolean inventory;
114 int curpos;
115 int inv_ptr;
116 int ArtifactFlash;
117 
118 #ifndef __WATCOMC__
119 boolean i_CDMusic; // in Watcom, defined in i_ibm
120 #endif
121 
122 // PRIVATE DATA DEFINITIONS ------------------------------------------------
123 
124 static byte CheatLookup[256];
125 static int HealthMarker;
126 //static int ChainWiggle;
127 static player_t *CPlayer;
128 static int SpinFlylump;
129 static int SpinMinotaurLump;
130 static int SpinSpeedLump;
131 static int SpinDefenseLump;
132 
133 static int FontBNumBase;
134 static int PlayPalette;
135 
136 static patch_t *PatchH2BAR;
137 static patch_t *PatchH2TOP;
138 static patch_t *PatchLFEDGE;
139 static patch_t *PatchRTEDGE;
140 static patch_t *PatchARMCLEAR;
141 static patch_t *PatchARTICLEAR;
142 static patch_t *PatchMANACLEAR;
143 static patch_t *PatchKILLS;
144 static patch_t *PatchMANAVIAL1;
145 static patch_t *PatchMANAVIAL2;
146 static patch_t *PatchMANAVIALDIM1;
147 static patch_t *PatchMANAVIALDIM2;
148 static patch_t *PatchMANADIM1;
149 static patch_t *PatchMANADIM2;
150 static patch_t *PatchMANABRIGHT1;
151 static patch_t *PatchMANABRIGHT2;
152 static patch_t *PatchCHAIN;
153 static patch_t *PatchSTATBAR;
154 static patch_t *PatchKEYBAR;
155 static patch_t *PatchLIFEGEM;
156 static patch_t *PatchSELECTBOX;
157 static patch_t *PatchINumbers[10];
158 static patch_t *PatchNEGATIVE;
159 static patch_t *PatchSmNumbers[10];
160 static patch_t *PatchINVBAR;
161 static patch_t *PatchWEAPONSLOT;
162 static patch_t *PatchWEAPONFULL;
163 static patch_t *PatchPIECE1;
164 static patch_t *PatchPIECE2;
165 static patch_t *PatchPIECE3;
166 static patch_t *PatchINVLFGEM1;
167 static patch_t *PatchINVLFGEM2;
168 static patch_t *PatchINVRTGEM1;
169 static patch_t *PatchINVRTGEM2;
170 static byte CheatGodSeq[]={74,206,202,108,233,255,0};
171 static byte CheatNoClipSeq[]={79,233,237,237,74,204,75,255,0};
172 static byte CheatFunnyPiggySeq1[]={237,232,205,76,255,0};
173 static byte CheatFunnyPiggySeq2[]={67,102,195,255,0};
174 static byte CheatWeaponsSeq[]={109,76,75,204,232,108,233,255,0};
175 static byte CheatHealthSeq[]={109,108,75,204,204,203,76,255,0};
176 static byte CheatKeysSeq[]={107,76,203,79,109,232,76,200,255,0};
177 static byte CheatSoundSeq[]={233,237,108,79,204,255,0};
178 static byte CheatTickerSeq[]={202,108,77,109,204,75,255,0};
179 static byte CheatArtifactAllSeq[]={77,104,206,236,76,109,255,0};
180 static byte CheatPuzzleSeq[]={107,233,76,108,109,76,107,76,107,233,76,108,109,76,255,0};
181 static byte CheatWarpSeq[]={108,200,108,64,233,76,0,0,255,0};
182 static byte CheatPigSeq[]={74,75,204,202,202,110,64,204,110,204,79,255,0};
183 static byte CheatMassacreSeq[]={108,64,232,237,203,204,64,110,237,206,255,0};
184 static byte CheatIDKFASeq[]={233,75,76,255,0};
185 static byte CheatQuickenSeq[]={79,76,202,76,233,255,0};
186 static byte CheatClass1Seq[]={202,75,76,233,79,236,206,202,76,202,108,237,233,0,255,0};
187 static byte CheatClass2Seq[]={202,75,76,233,79,236,206,202,76,202,108,237,233,0,0xff,0};
188 static byte CheatInitSeq[]={79,202,76,75,202,255,0};
189 static byte CheatVersionSeq[]={203,204,75,255,0};
190 static byte CheatDebugSeq[]={77,237,237,75,200,79,255,0};
191 static byte CheatScriptSeq1[]={200,237,108,202,0,0,255,0};
192 static byte CheatScriptSeq2[]={200,237,108,202,0,255,0};
193 static byte CheatScriptSeq3[]={200,237,108,202,0,0,255,0};
194 static byte CheatRevealSeq[]={79,104,237,207,236,204,255,0};
195 static byte CheatTrackSeq1[]={72,255,0};
196 static byte CheatTrackSeq2[]={72,0,0,255,0};
197 static Cheat_t Cheats[] =
198 {
199   	{ CheatTrackFunc1, CheatTrackSeq1, NULL, {0, 0}, 0 },
200 	{ CheatTrackFunc2, CheatTrackSeq2, NULL, {0, 0}, 0 },
201 	{ CheatGodFunc, CheatGodSeq, NULL, 0, 0, 0 },
202 	{ CheatFunnyPiggyFunc1, CheatFunnyPiggySeq1, NULL, 0, 0, 0 },
203 	{ CheatFunnyPiggyFunc2, CheatFunnyPiggySeq2, NULL, 0, 0, 0 },
204 	{ CheatNoClipFunc, CheatNoClipSeq, NULL, 0, 0, 0 },
205 	{ CheatWeaponsFunc, CheatWeaponsSeq, NULL, 0, 0, 0 },
206 	{ CheatHealthFunc, CheatHealthSeq, NULL, 0, 0, 0 },
207 	{ CheatKeysFunc, CheatKeysSeq, NULL, 0, 0, 0 },
208 	{ CheatSoundFunc, CheatSoundSeq, NULL, 0, 0, 0 },
209 	{ CheatTickerFunc, CheatTickerSeq, NULL, 0, 0, 0 },
210 	{ CheatArtifactAllFunc, CheatArtifactAllSeq, NULL, 0, 0, 0 },
211 	{ CheatPuzzleFunc, CheatPuzzleSeq, NULL, 0, 0, 0 },
212 	{ CheatWarpFunc, CheatWarpSeq, NULL, 0, 0, 0 },
213 	{ CheatPigFunc, CheatPigSeq, NULL, 0, 0, 0 },
214 	{ CheatMassacreFunc, CheatMassacreSeq, NULL, 0, 0, 0 },
215 	{ CheatIDKFAFunc, CheatIDKFASeq, NULL, 0, 0, 0 },
216 	{ CheatQuickenFunc, CheatQuickenSeq, NULL, 0, 0, 0 },
217 	{ CheatClassFunc1, CheatClass1Seq, NULL, 0, 0, 0 },
218 	{ CheatClassFunc2, CheatClass2Seq, NULL, 0, 0, 0 },
219 	{ CheatInitFunc, CheatInitSeq, NULL, 0, 0, 0 },
220 	{ CheatVersionFunc, CheatVersionSeq, NULL, 0, 0, 0 },
221 	{ CheatDebugFunc, CheatDebugSeq, NULL, 0, 0, 0 },
222 	{ CheatScriptFunc1, CheatScriptSeq1, NULL, 0, 0, 0 },
223 	{ CheatScriptFunc2, CheatScriptSeq2, NULL, 0, 0, 0 },
224 	{ CheatScriptFunc3, CheatScriptSeq3, NULL, 0, 0, 0 },
225 	{ CheatRevealFunc, CheatRevealSeq, NULL, 0, 0, 0 },
226 	{ NULL, NULL, NULL, 0, 0, 0 } // Terminator
227 
228 };
229 
230 // CODE --------------------------------------------------------------------
231 
232 //==========================================================================
233 //
234 // SB_Init
235 //
236 //==========================================================================
237 
SB_Init(void)238 void SB_Init(void)
239 {
240 	int i;
241 	int startLump;
242 
243 	PatchH2BAR = W_CacheLumpName("H2BAR", PU_STATIC);
244 	PatchH2TOP = W_CacheLumpName("H2TOP", PU_STATIC);
245 	PatchINVBAR = W_CacheLumpName("INVBAR", PU_STATIC);
246 	PatchLFEDGE	= W_CacheLumpName("LFEDGE", PU_STATIC);
247 	PatchRTEDGE	= W_CacheLumpName("RTEDGE", PU_STATIC);
248 	PatchSTATBAR = W_CacheLumpName("STATBAR", PU_STATIC);
249 	PatchKEYBAR = W_CacheLumpName("KEYBAR", PU_STATIC);
250 	PatchSELECTBOX = W_CacheLumpName("SELECTBOX", PU_STATIC);
251 	PatchARTICLEAR = W_CacheLumpName("ARTICLS", PU_STATIC);
252 	PatchARMCLEAR = W_CacheLumpName("ARMCLS", PU_STATIC);
253 	PatchMANACLEAR = W_CacheLumpName("MANACLS", PU_STATIC);
254 	PatchMANAVIAL1 = W_CacheLumpName("MANAVL1", PU_STATIC);
255 	PatchMANAVIAL2 = W_CacheLumpName("MANAVL2", PU_STATIC);
256 	PatchMANAVIALDIM1 = W_CacheLumpName("MANAVL1D", PU_STATIC);
257 	PatchMANAVIALDIM2 = W_CacheLumpName("MANAVL2D", PU_STATIC);
258 	PatchMANADIM1 = W_CacheLumpName("MANADIM1", PU_STATIC);
259 	PatchMANADIM2 = W_CacheLumpName("MANADIM2", PU_STATIC);
260 	PatchMANABRIGHT1 = W_CacheLumpName("MANABRT1", PU_STATIC);
261 	PatchMANABRIGHT2 = W_CacheLumpName("MANABRT2", PU_STATIC);
262 	PatchINVLFGEM1 = W_CacheLumpName("invgeml1", PU_STATIC);
263 	PatchINVLFGEM2 = W_CacheLumpName("invgeml2", PU_STATIC);
264 	PatchINVRTGEM1 = W_CacheLumpName("invgemr1", PU_STATIC);
265 	PatchINVRTGEM2 = W_CacheLumpName("invgemr2", PU_STATIC);
266 
267 //	PatchCHAINBACK = W_CacheLumpName("CHAINBACK", PU_STATIC);
268 	startLump = W_GetNumForName("IN0");
269 	for(i = 0; i < 10; i++)
270 	{
271 		PatchINumbers[i] = W_CacheLumpNum(startLump+i, PU_STATIC);
272 	}
273 	PatchNEGATIVE = W_CacheLumpName("NEGNUM", PU_STATIC);
274 	FontBNumBase = W_GetNumForName("FONTB16");
275 	startLump = W_GetNumForName("SMALLIN0");
276 	for(i = 0; i < 10; i++)
277 	{
278 		PatchSmNumbers[i] = W_CacheLumpNum(startLump+i, PU_STATIC);
279 	}
280 	PlayPalette = W_GetNumForName("PLAYPAL");
281 	SpinFlylump = W_GetNumForName("SPFLY0");
282 	SpinMinotaurLump = W_GetNumForName("SPMINO0");
283 	SpinSpeedLump = W_GetNumForName("SPBOOT0");
284 	SpinDefenseLump = W_GetNumForName("SPSHLD0");
285 
286 	for(i = 0; i < 256; i++)
287 	{
288 		CheatLookup[i] = CHEAT_ENCRYPT(i);
289 	}
290 
291 	if(deathmatch)
292 	{
293 		PatchKILLS = W_CacheLumpName("KILLS", PU_STATIC);
294 	}
295 	SB_SetClassData();
296 }
297 
298 //==========================================================================
299 //
300 // SB_SetClassData
301 //
302 //==========================================================================
303 
SB_SetClassData(void)304 void SB_SetClassData(void)
305 {
306 	int class;
307 
308 	class = PlayerClass[consoleplayer]; // original player class (not pig)
309 	PatchWEAPONSLOT = W_CacheLumpNum(W_GetNumForName("wpslot0")
310 		+class, PU_STATIC);
311 	PatchWEAPONFULL = W_CacheLumpNum(W_GetNumForName("wpfull0")
312 		+class, PU_STATIC);
313 	PatchPIECE1	= W_CacheLumpNum(W_GetNumForName("wpiecef1")
314 		+class, PU_STATIC);
315 	PatchPIECE2	= W_CacheLumpNum(W_GetNumForName("wpiecef2")
316 		+class, PU_STATIC);
317 	PatchPIECE3	= W_CacheLumpNum(W_GetNumForName("wpiecef3")
318 		+class, PU_STATIC);
319 	PatchCHAIN = W_CacheLumpNum(W_GetNumForName("chain")
320 		+class, PU_STATIC);
321 	if(!netgame)
322 	{ // single player game uses red life gem (the second gem)
323 		PatchLIFEGEM = W_CacheLumpNum(W_GetNumForName("lifegem")
324 			+MAXPLAYERS*class+1, PU_STATIC);
325 	}
326 	else
327 	{
328 		PatchLIFEGEM = W_CacheLumpNum(W_GetNumForName("lifegem")
329 			+MAXPLAYERS*class+consoleplayer, PU_STATIC);
330 	}
331 	SB_state = -1;
332 	UpdateState |= I_FULLSCRN;
333 }
334 
335 //==========================================================================
336 //
337 // SB_Ticker
338 //
339 //==========================================================================
340 
SB_Ticker(void)341 void SB_Ticker(void)
342 {
343 	int delta;
344 	int curHealth;
345 
346 	curHealth = players[consoleplayer].mo->health;
347 	if(curHealth < 0)
348 	{
349 		curHealth = 0;
350 	}
351 	if(curHealth < HealthMarker)
352 	{
353 		delta = (HealthMarker-curHealth)>>2;
354 		if(delta < 1)
355 		{
356 			delta = 1;
357 		}
358 		else if(delta > 6)
359 		{
360 			delta = 6;
361 		}
362 		HealthMarker -= delta;
363 	}
364 	else if(curHealth > HealthMarker)
365 	{
366 		delta = (curHealth-HealthMarker)>>2;
367 		if(delta < 1)
368 		{
369 			delta = 1;
370 		}
371 		else if(delta > 6)
372 		{
373 			delta = 6;
374 		}
375 		HealthMarker += delta;
376 	}
377 }
378 
379 //==========================================================================
380 //
381 // DrINumber
382 //
383 // Draws a three digit number.
384 //
385 //==========================================================================
386 
DrINumber(signed int val,int x,int y)387 static void DrINumber(signed int val, int x, int y)
388 {
389 	patch_t *patch;
390 	int oldval;
391 
392 	oldval = val;
393 	if(val < 0)
394 	{
395 		val = -val;
396 		if(val > 99)
397 		{
398 			val = 99;
399 		}
400 		if(val > 9)
401 		{
402 			patch = PatchINumbers[val/10];
403 			V_DrawPatch(x+8, y, patch);
404 			V_DrawPatch(x, y, PatchNEGATIVE);
405 		}
406 		else
407 		{
408 			V_DrawPatch(x+8, y, PatchNEGATIVE);
409 		}
410 		val = val%10;
411 		patch = PatchINumbers[val];
412 		V_DrawPatch(x+16, y, patch);
413 		return;
414 	}
415 	if(val > 99)
416 	{
417 		patch = PatchINumbers[val/100];
418 		V_DrawPatch(x, y, patch);
419 	}
420 	val = val%100;
421 	if(val > 9 || oldval > 99)
422 	{
423 		patch = PatchINumbers[val/10];
424 		V_DrawPatch(x+8, y, patch);
425 	}
426 	val = val%10;
427 	patch = PatchINumbers[val];
428 	V_DrawPatch(x+16, y, patch);
429 }
430 
431 //==========================================================================
432 //
433 // DrRedINumber
434 //
435 // Draws a three digit number using the red font
436 //
437 //==========================================================================
438 
DrRedINumber(signed int val,int x,int y)439 static void DrRedINumber(signed int val, int x, int y)
440 {
441 	patch_t *patch;
442 	int oldval;
443 
444 	oldval = val;
445 	if(val < 0)
446 	{
447 		val = 0;
448 	}
449 	if(val > 99)
450 	{
451 		patch = W_CacheLumpNum(W_GetNumForName("inred0")+val/100, PU_CACHE);
452 		V_DrawPatch(x, y, patch);
453 	}
454 	val = val%100;
455 	if(val > 9 || oldval > 99)
456 	{
457 		patch = W_CacheLumpNum(W_GetNumForName("inred0")+val/10, PU_CACHE);
458 		V_DrawPatch(x+8, y, patch);
459 	}
460 	val = val%10;
461 	patch = W_CacheLumpNum(W_GetNumForName("inred0")+val, PU_CACHE);
462 	V_DrawPatch(x+16, y, patch);
463 }
464 
465 //==========================================================================
466 //
467 // DrBNumber
468 //
469 // Draws a three digit number using FontB
470 //
471 //==========================================================================
472 
DrBNumber(signed int val,int x,int y)473 static void DrBNumber(signed int val, int x, int y)
474 {
475 	patch_t *patch;
476 	int xpos;
477 	int oldval;
478 
479 	oldval = val;
480 	xpos = x;
481 	if(val < 0)
482 	{
483 		val = 0;
484 	}
485 	if(val > 99)
486 	{
487 #if 0
488 	    if (use_gl)
489 	      OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val/100);
490 	    else
491 #endif
492 	    {
493 		patch = W_CacheLumpNum(FontBNumBase+val/100, PU_CACHE);
494 		V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
495 	    }
496 	}
497 	val = val%100;
498 	xpos += 12;
499 	if(val > 9 || oldval > 99)
500 	{
501 #if 0
502 	    if (use_gl)
503 	      OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val/10);
504 	    else
505 #endif
506 	    {
507 		patch = W_CacheLumpNum(FontBNumBase+val/10, PU_CACHE);
508 		V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
509 	    }
510 	}
511 	val = val%10;
512 	xpos += 12;
513 #if 0
514 	if (use_gl)
515 	  OGL_DrawShadowedPatch(xpos+6-patch->width/2, y, FontBNumBase+val);
516 	else
517 #endif
518 	{
519 	 patch = W_CacheLumpNum(FontBNumBase+val, PU_CACHE);
520 	 V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
521 	}
522 }
523 
524 //==========================================================================
525 //
526 // DrSmallNumber
527 //
528 // Draws a small two digit number.
529 //
530 //==========================================================================
531 
DrSmallNumber(int val,int x,int y)532 static void DrSmallNumber(int val, int x, int y)
533 {
534 	patch_t *patch;
535 
536 	if(val <= 0)
537 	{
538 		return;
539 	}
540 	if(val > 999)
541 	{
542 		val %= 1000;
543 	}
544 	if(val > 99)
545 	{
546 		patch = PatchSmNumbers[val/100];
547 		V_DrawPatch(x, y, patch);
548 		patch = PatchSmNumbers[(val%100)/10];
549 		V_DrawPatch(x+4, y, patch);
550 	}
551 	else if(val > 9)
552 	{
553 		patch = PatchSmNumbers[val/10];
554 		V_DrawPatch(x+4, y, patch);
555 	}
556 	val %= 10;
557 	patch = PatchSmNumbers[val];
558 	V_DrawPatch(x+8, y, patch);
559 }
560 
561 /*
562 //==========================================================================
563 //
564 // ShadeLine
565 //
566 //==========================================================================
567 
568 static void ShadeLine(int x, int y, int height, int shade)
569 {
570 	byte *dest;
571 	byte *shades;
572 
573 	shades = colormaps+9*256+shade*2*256;
574 	dest = screen+y*SCREENWIDTH+x;
575 	while(height--)
576 	{
577 		*(dest) = *(shades+*dest);
578 		dest += SCREENWIDTH;
579 	}
580 }
581 
582 //==========================================================================
583 //
584 // ShadeChain
585 //
586 //==========================================================================
587 
588 static void ShadeChain(void)
589 {
590 	int i;
591 
592 	for(i = 0; i < 16; i++)
593 	{
594 		ShadeLine(277+i, 190, 10, i/2);
595 		ShadeLine(19+i, 190, 10, 7-(i/2));
596 	}
597 }
598 */
599 
600 //==========================================================================
601 //
602 // DrawSoundInfo
603 //
604 // Displays sound debugging information.
605 //
606 //==========================================================================
607 
DrawSoundInfo(void)608 static void DrawSoundInfo(void)
609 {
610 	int i;
611 	SoundInfo_t s;
612 	ChanInfo_t *c;
613 	char text[32];
614 	int x;
615 	int y;
616 	int xPos[7] = {1, 75, 112, 156, 200, 230, 260};
617 
618 	if(leveltime&16)
619 	{
620 		MN_DrTextA("*** SOUND DEBUG INFO ***", xPos[0], 20);
621 	}
622 	S_GetChannelInfo(&s);
623 	if(s.channelCount == 0)
624 	{
625 		return;
626 	}
627 	x = 0;
628 	MN_DrTextA("NAME", xPos[x++], 30);
629 	MN_DrTextA("MO.T", xPos[x++], 30);
630 	MN_DrTextA("MO.X", xPos[x++], 30);
631 	MN_DrTextA("MO.Y", xPos[x++], 30);
632 	MN_DrTextA("ID", xPos[x++], 30);
633 	MN_DrTextA("PRI", xPos[x++], 30);
634 	MN_DrTextA("DIST", xPos[x++], 30);
635 	for(i = 0; i < s.channelCount; i++)
636 	{
637 		c = &s.chan[i];
638 		x = 0;
639 		y = 40+i*10;
640 		if(c->mo == NULL)
641 		{ // Channel is unused
642 			MN_DrTextA("------", xPos[0], y);
643 			continue;
644 		}
645 		sprintf(text, "%s", c->name);
646 		M_ForceUppercase(text);
647 		MN_DrTextA(text, xPos[x++], y);
648 		sprintf(text, "%d", c->mo->type);
649 		MN_DrTextA(text, xPos[x++], y);
650 		sprintf(text, "%d", c->mo->x>>FRACBITS);
651 		MN_DrTextA(text, xPos[x++], y);
652 		sprintf(text, "%d", c->mo->y>>FRACBITS);
653 		MN_DrTextA(text, xPos[x++], y);
654 		sprintf(text, "%d", (int)c->id); /* XXX stripping long */
655 		MN_DrTextA(text, xPos[x++], y);
656 		sprintf(text, "%d", c->priority);
657 		MN_DrTextA(text, xPos[x++], y);
658 		sprintf(text, "%d", c->distance);
659 		MN_DrTextA(text, xPos[x++], y);
660 	}
661 	UpdateState |= I_FULLSCRN;
662 	BorderNeedRefresh = true;
663 }
664 
665 //==========================================================================
666 //
667 // SB_Drawer
668 //
669 //==========================================================================
670 
671 char patcharti[][10] =
672 {
673 	{ "ARTIBOX" },    	// none
674 	{ "ARTIINVU" },   	// invulnerability
675 	{ "ARTIPTN2" },   	// health
676 	{ "ARTISPHL" },   	// superhealth
677 	{ "ARTIHRAD" },		// healing radius
678 	{ "ARTISUMN" },   	// summon maulator
679 	{ "ARTITRCH" },   	// torch
680 	{ "ARTIPORK" },   	// egg
681 	{ "ARTISOAR" },   	// fly
682 	{ "ARTIBLST" },		// blast radius
683 	{ "ARTIPSBG" },		// poison bag
684 	{ "ARTITELO" },		// teleport other
685 	{ "ARTISPED" },  	// speed
686 	{ "ARTIBMAN" },		// boost mana
687 	{ "ARTIBRAC" },		// boost armor
688 	{ "ARTIATLP" },   	// teleport
689 	{ "ARTISKLL" },		// arti_puzzskull
690 	{ "ARTIBGEM" },		// arti_puzzgembig
691 	{ "ARTIGEMR" },		// arti_puzzgemred
692 	{ "ARTIGEMG" },		// arti_puzzgemgreen1
693 	{ "ARTIGMG2" },		// arti_puzzgemgreen2
694 	{ "ARTIGEMB" },		// arti_puzzgemblue1
695 	{ "ARTIGMB2" },		// arti_puzzgemblue2
696 	{ "ARTIBOK1" },		// arti_puzzbook1
697 	{ "ARTIBOK2" },		// arti_puzzbook2
698 	{ "ARTISKL2" },		// arti_puzzskull2
699 	{ "ARTIFWEP" },		// arti_puzzfweapon
700 	{ "ARTICWEP" },		// arti_puzzcweapon
701 	{ "ARTIMWEP" },		// arti_puzzmweapon
702 	{ "ARTIGEAR" },		// arti_puzzgear1
703 	{ "ARTIGER2" },		// arti_puzzgear2
704 	{ "ARTIGER3" },		// arti_puzzgear3
705 	{ "ARTIGER4" },		// arti_puzzgear4
706 };
707 
708 int SB_state = -1;
709 static int oldarti = 0;
710 static int oldartiCount = 0;
711 static int oldfrags = -9999;
712 static int oldmana1 = -1;
713 static int oldmana2 = -1;
714 static int oldarmor = -1;
715 static int oldhealth = -1;
716 static int oldlife = -1;
717 static int oldpieces = -1;
718 static int oldweapon = -1;
719 static int oldkeys = -1;
720 
721 extern boolean automapactive;
722 
SB_Drawer(void)723 void SB_Drawer(void)
724 {
725 	// Sound info debug stuff
726 	if(DebugSound == true)
727 	{
728 		DrawSoundInfo();
729 	}
730 	CPlayer = &players[consoleplayer];
731 	if(viewheight == SCREENHEIGHT && !automapactive)
732 	{
733 		DrawFullScreenStuff();
734 		SB_state = -1;
735 	}
736 	else
737 	{
738 		if(SB_state == -1)
739 		{
740 			V_DrawPatch(0, 134, PatchH2BAR);
741 			oldhealth = -1;
742 		}
743 		DrawCommonBar();
744 		if(!inventory)
745 		{
746 			if(SB_state != 0)
747 			{
748 				// Main interface
749 				if(!automapactive)
750 				{
751 					V_DrawPatch(38, 162, PatchSTATBAR);
752 				}
753 				else
754 				{
755 					V_DrawPatch(38, 162, PatchKEYBAR);
756 				}
757 				oldarti = 0;
758 				oldmana1 = -1;
759 				oldmana2 = -1;
760 				oldarmor = -1;
761 				oldpieces = -1;
762 				oldfrags = -9999; //can't use -1, 'cuz of negative frags
763 				oldlife = -1;
764 				oldweapon = -1;
765 				oldkeys = -1;
766 			}
767 			if(!automapactive)
768 			{
769 				DrawMainBar();
770 			}
771 			else
772 			{
773 				DrawKeyBar();
774 			}
775 			SB_state = 0;
776 		}
777 		else
778 		{
779 			DrawInventoryBar();
780 			SB_state = 1;
781 		}
782 	}
783 	SB_PaletteFlash(false);
784 	DrawAnimatedIcons();
785 }
786 
787 //==========================================================================
788 //
789 // DrawAnimatedIcons
790 //
791 //==========================================================================
792 
DrawAnimatedIcons(void)793 static void DrawAnimatedIcons(void)
794 {
795 	int frame;
796 	static boolean hitCenterFrame;
797 
798 	// Wings of wrath
799 	if(CPlayer->powers[pw_flight])
800 	{
801 		if(CPlayer->powers[pw_flight] > BLINKTHRESHOLD
802 			|| !(CPlayer->powers[pw_flight]&16))
803 		{
804 			frame = (leveltime/3)&15;
805 			if(CPlayer->mo->flags2&MF2_FLY)
806 			{
807 				if(hitCenterFrame && (frame != 15 && frame != 0))
808 				{
809 					V_DrawPatch(20, 19, W_CacheLumpNum(SpinFlylump+15,
810 						PU_CACHE));
811 				}
812 				else
813 				{
814 					V_DrawPatch(20, 19, W_CacheLumpNum(SpinFlylump+frame,
815 						PU_CACHE));
816 					hitCenterFrame = false;
817 				}
818 			}
819 			else
820 			{
821 				if(!hitCenterFrame && (frame != 15 && frame != 0))
822 				{
823 					V_DrawPatch(20, 19, W_CacheLumpNum(SpinFlylump+frame,
824 						PU_CACHE));
825 					hitCenterFrame = false;
826 				}
827 				else
828 				{
829 					V_DrawPatch(20, 19, W_CacheLumpNum(SpinFlylump+15,
830 						PU_CACHE));
831 					hitCenterFrame = true;
832 				}
833 			}
834 		}
835 		BorderTopRefresh = true;
836 		UpdateState |= I_MESSAGES;
837 	}
838 
839 	// Speed Boots
840 	if(CPlayer->powers[pw_speed])
841 	{
842 		if(CPlayer->powers[pw_speed] > BLINKTHRESHOLD
843 			|| !(CPlayer->powers[pw_speed]&16))
844 		{
845 			frame = (leveltime/3)&15;
846 			V_DrawPatch(60, 19, W_CacheLumpNum(SpinSpeedLump+frame,
847 				PU_CACHE));
848 		}
849 		BorderTopRefresh = true;
850 		UpdateState |= I_MESSAGES;
851 	}
852 
853 	// Defensive power
854 	if(CPlayer->powers[pw_invulnerability])
855 	{
856 		if(CPlayer->powers[pw_invulnerability] > BLINKTHRESHOLD
857 			|| !(CPlayer->powers[pw_invulnerability]&16))
858 		{
859 			frame = (leveltime/3)&15;
860 			V_DrawPatch(260, 19, W_CacheLumpNum(SpinDefenseLump+frame,
861 				PU_CACHE));
862 		}
863 		BorderTopRefresh = true;
864 		UpdateState |= I_MESSAGES;
865 	}
866 
867 	// Minotaur Active
868 	if(CPlayer->powers[pw_minotaur])
869 	{
870 		if(CPlayer->powers[pw_minotaur] > BLINKTHRESHOLD
871 			|| !(CPlayer->powers[pw_minotaur]&16))
872 		{
873 			frame = (leveltime/3)&15;
874 			V_DrawPatch(300, 19, W_CacheLumpNum(SpinMinotaurLump+frame,
875 				PU_CACHE));
876 		}
877 		BorderTopRefresh = true;
878 		UpdateState |= I_MESSAGES;
879 	}
880 }
881 
882 //==========================================================================
883 //
884 // SB_PaletteFlash
885 //
886 // Sets the new palette based upon the current values of
887 // consoleplayer->damagecount and consoleplayer->bonuscount.
888 //
889 //==========================================================================
890 
SB_PaletteFlash(boolean forceChange)891 void SB_PaletteFlash(boolean forceChange)
892 {
893 	static int sb_palette = 0;
894 	int palette;
895 	byte *pal;
896 
897 	if(forceChange)
898 	{
899 		sb_palette = -1;
900 	}
901 	if(gamestate == GS_LEVEL)
902 	{
903 		CPlayer = &players[consoleplayer];
904 		if(CPlayer->poisoncount)
905 		{
906 			palette = 0;
907 			palette = (CPlayer->poisoncount+7)>>3;
908 			if(palette >= NUMPOISONPALS)
909 			{
910 				palette = NUMPOISONPALS-1;
911 			}
912 			palette += STARTPOISONPALS;
913 		}
914 		else if(CPlayer->damagecount)
915 		{
916 			palette = (CPlayer->damagecount+7)>>3;
917 			if(palette >= NUMREDPALS)
918 			{
919 				palette = NUMREDPALS-1;
920 			}
921 			palette += STARTREDPALS;
922 		}
923 		else if(CPlayer->bonuscount)
924 		{
925 			palette = (CPlayer->bonuscount+7)>>3;
926 			if(palette >= NUMBONUSPALS)
927 			{
928 				palette = NUMBONUSPALS-1;
929 			}
930 			palette += STARTBONUSPALS;
931 		}
932 		else if(CPlayer->mo->flags2&MF2_ICEDAMAGE)
933 		{ // Frozen player
934 			palette = STARTICEPAL;
935 		}
936 		else
937 		{
938 			palette = 0;
939 		}
940 	}
941 	else
942 	{
943 		palette = 0;
944 	}
945 	if(palette != sb_palette)
946 	{
947 		sb_palette = palette;
948 		pal = (byte *)W_CacheLumpNum(PlayPalette, PU_CACHE)+palette*768;
949 		I_SetPalette(pal);
950 	}
951 }
952 
953 //==========================================================================
954 //
955 // DrawCommonBar
956 //
957 //==========================================================================
958 
DrawCommonBar(void)959 void DrawCommonBar(void)
960 {
961 	int healthPos;
962 
963 	V_DrawPatch(0, 134, PatchH2TOP);
964 
965 	if(oldhealth != HealthMarker)
966 	{
967 		oldhealth = HealthMarker;
968 		healthPos = HealthMarker;
969 		if(healthPos < 0)
970 		{
971 			healthPos = 0;
972 		}
973 		if(healthPos > 100)
974 		{
975 			healthPos = 100;
976 		}
977 		V_DrawPatch(28+(((healthPos*196)/100)%9), 193, PatchCHAIN);
978 		V_DrawPatch(7+((healthPos*11)/5), 193, PatchLIFEGEM);
979 		V_DrawPatch(0, 193, PatchLFEDGE);
980 		V_DrawPatch(277, 193, PatchRTEDGE);
981 //		ShadeChain();
982 		UpdateState |= I_STATBAR;
983 	}
984 }
985 
986 //==========================================================================
987 //
988 // DrawMainBar
989 //
990 //==========================================================================
991 
DrawMainBar(void)992 void DrawMainBar(void)
993 {
994 	int i;
995 	int temp;
996 	patch_t *manaPatch1, *manaPatch2;
997 	patch_t *manaVialPatch1, *manaVialPatch2;
998 
999 	manaPatch1 = NULL;
1000 	manaPatch2 = NULL;
1001 	manaVialPatch1 = NULL;
1002 	manaVialPatch2 = NULL;
1003 
1004 	// Ready artifact
1005 	if(ArtifactFlash)
1006 	{
1007 		V_DrawPatch(144, 160, PatchARTICLEAR);
1008 		V_DrawPatch(148, 164, W_CacheLumpNum(W_GetNumForName("useartia")
1009 			+ ArtifactFlash - 1, PU_CACHE));
1010 		ArtifactFlash--;
1011 		oldarti = -1; // so that the correct artifact fills in after the flash
1012 		UpdateState |= I_STATBAR;
1013 	}
1014 	else if(oldarti != CPlayer->readyArtifact
1015 		|| oldartiCount != CPlayer->inventory[inv_ptr].count)
1016 	{
1017 		V_DrawPatch(144, 160, PatchARTICLEAR);
1018 		if(CPlayer->readyArtifact > 0)
1019 		{
1020 			V_DrawPatch(143, 163,
1021 				W_CacheLumpName(patcharti[CPlayer->readyArtifact], PU_CACHE));
1022 			if(CPlayer->inventory[inv_ptr].count > 1)
1023 			{
1024 				DrSmallNumber(CPlayer->inventory[inv_ptr].count, 162, 184);
1025 			}
1026 		}
1027 		oldarti = CPlayer->readyArtifact;
1028 		oldartiCount = CPlayer->inventory[inv_ptr].count;
1029 		UpdateState |= I_STATBAR;
1030 	}
1031 
1032 	// Frags
1033 	if(deathmatch)
1034 	{
1035 		temp = 0;
1036 		for(i = 0; i < MAXPLAYERS; i++)
1037 		{
1038 			temp += CPlayer->frags[i];
1039 		}
1040 		if(temp != oldfrags)
1041 		{
1042 			V_DrawPatch(38, 162, PatchKILLS);
1043 			DrINumber(temp, 40, 176);
1044 			oldfrags = temp;
1045 			UpdateState |= I_STATBAR;
1046 		}
1047 	}
1048 	else
1049 	{
1050 		temp = HealthMarker;
1051 		if(temp < 0)
1052 		{
1053 			temp = 0;
1054 		}
1055 		else if(temp > 100)
1056 		{
1057 			temp = 100;
1058 		}
1059 		if(oldlife != temp)
1060 		{
1061 			oldlife = temp;
1062 			V_DrawPatch(41, 178, PatchARMCLEAR);
1063 			if(temp >= 25)
1064 			{
1065 				DrINumber(temp, 40, 176);
1066 			}
1067 			else
1068 			{
1069 				DrRedINumber(temp, 40, 176);
1070 			}
1071 			UpdateState |= I_STATBAR;
1072 		}
1073 	}
1074 	// Mana
1075 	temp = CPlayer->mana[0];
1076 	if(oldmana1 != temp)
1077 	{
1078 		V_DrawPatch(77, 178, PatchMANACLEAR);
1079 		DrSmallNumber(temp, 79, 181);
1080 		manaVialPatch1 = (patch_t *)1; // force a vial update
1081 		if(temp == 0)
1082 		{ // Draw Dim Mana icon
1083 			manaPatch1 = PatchMANADIM1;
1084 		}
1085 		else if(oldmana1 == 0)
1086 		{
1087 			manaPatch1 = PatchMANABRIGHT1;
1088 		}
1089 		oldmana1 = temp;
1090 		UpdateState |= I_STATBAR;
1091 	}
1092 	temp = CPlayer->mana[1];
1093 	if(oldmana2 != temp)
1094 	{
1095 		V_DrawPatch(109, 178, PatchMANACLEAR);
1096 		DrSmallNumber(temp, 111, 181);
1097 		manaVialPatch1 = (patch_t *)1; // force a vial update
1098 		if(temp == 0)
1099 		{ // Draw Dim Mana icon
1100 			manaPatch2 = PatchMANADIM2;
1101 		}
1102 		else if(oldmana2 == 0)
1103 		{
1104 			manaPatch2 = PatchMANABRIGHT2;
1105 		}
1106 		oldmana2 = temp;
1107 		UpdateState |= I_STATBAR;
1108 	}
1109 	if(oldweapon != CPlayer->readyweapon || manaPatch1 || manaPatch2
1110 		|| manaVialPatch1)
1111 	{ // Update mana graphics based upon mana count/weapon type
1112 		if(CPlayer->readyweapon == WP_FIRST)
1113 		{
1114 			manaPatch1 = PatchMANADIM1;
1115 			manaPatch2 = PatchMANADIM2;
1116 			manaVialPatch1 = PatchMANAVIALDIM1;
1117 			manaVialPatch2 = PatchMANAVIALDIM2;
1118 		}
1119 		else if(CPlayer->readyweapon == WP_SECOND)
1120 		{
1121 			if(!manaPatch1)
1122 			{
1123 				manaPatch1 = PatchMANABRIGHT1;
1124 			}
1125 			manaVialPatch1 = PatchMANAVIAL1;
1126 			manaPatch2 = PatchMANADIM2;
1127 			manaVialPatch2 = PatchMANAVIALDIM2;
1128 		}
1129 		else if(CPlayer->readyweapon == WP_THIRD)
1130 		{
1131 			manaPatch1 = PatchMANADIM1;
1132 			manaVialPatch1 = PatchMANAVIALDIM1;
1133 			if(!manaPatch2)
1134 			{
1135 				manaPatch2 = PatchMANABRIGHT2;
1136 			}
1137 			manaVialPatch2 = PatchMANAVIAL2;
1138 		}
1139 		else
1140 		{
1141 			manaVialPatch1 = PatchMANAVIAL1;
1142 			manaVialPatch2 = PatchMANAVIAL2;
1143 			if(!manaPatch1)
1144 			{
1145 				manaPatch1 = PatchMANABRIGHT1;
1146 			}
1147 			if(!manaPatch2)
1148 			{
1149 				manaPatch2 = PatchMANABRIGHT2;
1150 			}
1151 		}
1152 		V_DrawPatch(77, 164, manaPatch1);
1153 		V_DrawPatch(110, 164, manaPatch2);
1154 		V_DrawPatch(94, 164, manaVialPatch1);
1155 		for(i = 165; i < 187-(22*CPlayer->mana[0])/MAX_MANA; i++)
1156 		{
1157 			screen[i*SCREENWIDTH+95] = 0;
1158 			screen[i*SCREENWIDTH+96] = 0;
1159 			screen[i*SCREENWIDTH+97] = 0;
1160 		}
1161 		V_DrawPatch(102, 164, manaVialPatch2);
1162 		for(i = 165; i < 187-(22*CPlayer->mana[1])/MAX_MANA; i++)
1163 		{
1164 			screen[i*SCREENWIDTH+103] = 0;
1165 			screen[i*SCREENWIDTH+104] = 0;
1166 			screen[i*SCREENWIDTH+105] = 0;
1167 		}
1168 		oldweapon = CPlayer->readyweapon;
1169 		UpdateState |= I_STATBAR;
1170 	}
1171 	// Armor
1172 	temp = AutoArmorSave[CPlayer->class]
1173 		+CPlayer->armorpoints[ARMOR_ARMOR]+CPlayer->armorpoints[ARMOR_SHIELD]
1174 		+CPlayer->armorpoints[ARMOR_HELMET]+CPlayer->armorpoints[ARMOR_AMULET];
1175 	if(oldarmor != temp)
1176 	{
1177 		oldarmor = temp;
1178 		V_DrawPatch(255, 178, PatchARMCLEAR);
1179 		DrINumber(FixedDiv(temp, 5*FRACUNIT)>>FRACBITS, 250, 176);
1180 		UpdateState |= I_STATBAR;
1181 	}
1182 	// Weapon Pieces
1183 	if(oldpieces != CPlayer->pieces)
1184 	{
1185 		DrawWeaponPieces();
1186 		oldpieces = CPlayer->pieces;
1187 		UpdateState |= I_STATBAR;
1188 	}
1189 }
1190 
1191 //==========================================================================
1192 //
1193 // DrawInventoryBar
1194 //
1195 //==========================================================================
1196 
DrawInventoryBar(void)1197 void DrawInventoryBar(void)
1198 {
1199 	int i;
1200 	int x;
1201 
1202 	x = inv_ptr-curpos;
1203 	UpdateState |= I_STATBAR;
1204 	V_DrawPatch(38, 162, PatchINVBAR);
1205 	for(i = 0; i < 7; i++)
1206 	{
1207 		//V_DrawPatch(50+i*31, 160, W_CacheLumpName("ARTIBOX", PU_CACHE));
1208 		if(CPlayer->inventorySlotNum > x+i
1209 			&& CPlayer->inventory[x+i].type != arti_none)
1210 		{
1211 			V_DrawPatch(50+i*31, 163, W_CacheLumpName(
1212 				patcharti[CPlayer->inventory[x+i].type], PU_CACHE));
1213 			if(CPlayer->inventory[x+i].count > 1)
1214 			{
1215 				DrSmallNumber(CPlayer->inventory[x+i].count, 68+i*31, 185);
1216 			}
1217 		}
1218 	}
1219 	V_DrawPatch(50+curpos*31, 163, PatchSELECTBOX);
1220 	if(x != 0)
1221 	{
1222 		V_DrawPatch(42, 163, !(leveltime&4) ? PatchINVLFGEM1 :
1223 			PatchINVLFGEM2);
1224 	}
1225 	if(CPlayer->inventorySlotNum-x > 7)
1226 	{
1227 		V_DrawPatch(269, 163, !(leveltime&4) ? PatchINVRTGEM1 :
1228 			PatchINVRTGEM2);
1229 	}
1230 }
1231 
1232 //==========================================================================
1233 //
1234 // DrawKeyBar
1235 //
1236 //==========================================================================
1237 
DrawKeyBar(void)1238 void DrawKeyBar(void)
1239 {
1240 	int i;
1241 	int xPosition;
1242 	int temp;
1243 
1244 	if(oldkeys != CPlayer->keys)
1245 	{
1246 		xPosition = 46;
1247 		for(i = 0; i < NUMKEYS && xPosition <= 126; i++)
1248 		{
1249 			if(CPlayer->keys&(1<<i))
1250 			{
1251 				V_DrawPatch(xPosition, 164,
1252 					W_CacheLumpNum(W_GetNumForName("keyslot1")+i, PU_CACHE));
1253 				xPosition += 20;
1254 			}
1255 		}
1256 		oldkeys = CPlayer->keys;
1257 		UpdateState |= I_STATBAR;
1258 	}
1259 	temp = AutoArmorSave[CPlayer->class]
1260 		+CPlayer->armorpoints[ARMOR_ARMOR]+CPlayer->armorpoints[ARMOR_SHIELD]
1261 		+CPlayer->armorpoints[ARMOR_HELMET]+CPlayer->armorpoints[ARMOR_AMULET];
1262 	if(oldarmor != temp)
1263 	{
1264 		for(i = 0; i < NUMARMOR; i++)
1265 		{
1266 			if(!CPlayer->armorpoints[i])
1267 			{
1268 				continue;
1269 			}
1270 			if(CPlayer->armorpoints[i] <=
1271 				(ArmorIncrement[CPlayer->class][i]>>2))
1272 			{
1273 				V_DrawFuzzPatch(150+31*i, 164,
1274 					W_CacheLumpNum(W_GetNumForName("armslot1")+i, PU_CACHE));
1275 			}
1276 			else if(CPlayer->armorpoints[i] <=
1277 				(ArmorIncrement[CPlayer->class][i]>>1))
1278 			{
1279 				V_DrawAltFuzzPatch(150+31*i, 164,
1280 					W_CacheLumpNum(W_GetNumForName("armslot1")+i, PU_CACHE));
1281 			}
1282 			else
1283 			{
1284 				V_DrawPatch(150+31*i, 164,
1285 					W_CacheLumpNum(W_GetNumForName("armslot1")+i, PU_CACHE));
1286 			}
1287 		}
1288 		oldarmor = temp;
1289 		UpdateState |= I_STATBAR;
1290 	}
1291 }
1292 
1293 //==========================================================================
1294 //
1295 // DrawWeaponPieces
1296 //
1297 //==========================================================================
1298 
1299 static int PieceX[NUMCLASSES][3] =
1300 {
1301 	{ 190, 225, 234 },
1302 	{ 190, 212, 225 },
1303 	{ 190, 205, 224 },
1304 	{ 0, 0, 0 }			// Pig is never used
1305 };
1306 
DrawWeaponPieces(void)1307 static void DrawWeaponPieces(void)
1308 {
1309 	if(CPlayer->pieces == 7)
1310 	{
1311 		V_DrawPatch(190, 162, PatchWEAPONFULL);
1312 		return;
1313 	}
1314 	V_DrawPatch(190, 162, PatchWEAPONSLOT);
1315 	if(CPlayer->pieces&WPIECE1)
1316 	{
1317 		V_DrawPatch(PieceX[PlayerClass[consoleplayer]][0], 162, PatchPIECE1);
1318 	}
1319 	if(CPlayer->pieces&WPIECE2)
1320 	{
1321 		V_DrawPatch(PieceX[PlayerClass[consoleplayer]][1], 162, PatchPIECE2);
1322 	}
1323 	if(CPlayer->pieces&WPIECE3)
1324 	{
1325 		V_DrawPatch(PieceX[PlayerClass[consoleplayer]][2], 162, PatchPIECE3);
1326 	}
1327 }
1328 
1329 //==========================================================================
1330 //
1331 // DrawFullScreenStuff
1332 //
1333 //==========================================================================
1334 
DrawFullScreenStuff(void)1335 void DrawFullScreenStuff(void)
1336 {
1337 	int i;
1338 	int x;
1339 	int temp;
1340 
1341 	UpdateState |= I_FULLSCRN;
1342 	if(CPlayer->mo->health > 0)
1343 	{
1344 		DrBNumber(CPlayer->mo->health, 5, 180);
1345 	}
1346 	else
1347 	{
1348 		DrBNumber(0, 5, 180);
1349 	}
1350 	if(deathmatch)
1351 	{
1352 		temp = 0;
1353 		for(i=0; i<MAXPLAYERS; i++)
1354 		{
1355 			if(playeringame[i])
1356 			{
1357 				temp += CPlayer->frags[i];
1358 			}
1359 		}
1360 		DrINumber(temp, 45, 185);
1361 	}
1362 	if(!inventory)
1363 	{
1364 		if(CPlayer->readyArtifact > 0)
1365 		{
1366 			V_DrawFuzzPatch(286, 170, W_CacheLumpName("ARTIBOX",
1367 				PU_CACHE));
1368 			V_DrawPatch(284, 169,
1369 				W_CacheLumpName(patcharti[CPlayer->readyArtifact], PU_CACHE));
1370 			if(CPlayer->inventory[inv_ptr].count > 1)
1371 			{
1372 				DrSmallNumber(CPlayer->inventory[inv_ptr].count, 302, 192);
1373 			}
1374 		}
1375 	}
1376 	else
1377 	{
1378 		x = inv_ptr-curpos;
1379 		for(i = 0; i < 7; i++)
1380 		{
1381 			V_DrawFuzzPatch(50+i*31, 168, W_CacheLumpName("ARTIBOX",
1382 				PU_CACHE));
1383 			if(CPlayer->inventorySlotNum > x+i
1384 				&& CPlayer->inventory[x+i].type != arti_none)
1385 			{
1386 				V_DrawPatch(49+i*31, 167, W_CacheLumpName(
1387 					patcharti[CPlayer->inventory[x+i].type], PU_CACHE));
1388 				if(CPlayer->inventory[x+i].count > 1)
1389 				{
1390 					DrSmallNumber(CPlayer->inventory[x+i].count, 66+i*31,
1391  						188);
1392 				}
1393 			}
1394 		}
1395 		V_DrawPatch(50+curpos*31, 167, PatchSELECTBOX);
1396 		if(x != 0)
1397 		{
1398 			V_DrawPatch(40, 167, !(leveltime&4) ? PatchINVLFGEM1 :
1399 				PatchINVLFGEM2);
1400 		}
1401 		if(CPlayer->inventorySlotNum-x > 7)
1402 		{
1403 			V_DrawPatch(268, 167, !(leveltime&4) ?
1404 				PatchINVRTGEM1 : PatchINVRTGEM2);
1405 		}
1406 	}
1407 }
1408 
1409 
1410 //==========================================================================
1411 //
1412 // Draw_TeleportIcon
1413 //
1414 //==========================================================================
Draw_TeleportIcon(void)1415 void Draw_TeleportIcon(void)
1416 {
1417 	patch_t *patch;
1418 	patch = W_CacheLumpNum(W_GetNumForName("teleicon"), PU_CACHE);
1419 	V_DrawPatch(100, 68, patch);
1420 	UpdateState |= I_FULLSCRN;
1421 	I_UpdateNoBlit();
1422 	I_FinishUpdate(); /* XXX */
1423 	UpdateState |= I_FULLSCRN;
1424 }
1425 
1426 //==========================================================================
1427 //
1428 // Draw_SaveIcon
1429 //
1430 //==========================================================================
Draw_SaveIcon(void)1431 void Draw_SaveIcon(void)
1432 {
1433 	patch_t *patch;
1434 	patch = W_CacheLumpNum(W_GetNumForName("saveicon"), PU_CACHE);
1435 	V_DrawPatch(100, 68, patch);
1436 	UpdateState |= I_FULLSCRN;
1437 	I_UpdateNoBlit();
1438 	I_FinishUpdate(); /* XXX */
1439 	UpdateState |= I_FULLSCRN;
1440 }
1441 
1442 //==========================================================================
1443 //
1444 // Draw_LoadIcon
1445 //
1446 //==========================================================================
Draw_LoadIcon(void)1447 void Draw_LoadIcon(void)
1448 {
1449 	patch_t *patch;
1450 	patch = W_CacheLumpNum(W_GetNumForName("loadicon"), PU_CACHE);
1451 	V_DrawPatch(100, 68, patch);
1452 	UpdateState |= I_FULLSCRN;
1453 	I_UpdateNoBlit();
1454 	I_FinishUpdate(); /* XXX */
1455 	UpdateState |= I_FULLSCRN;
1456 }
1457 
1458 
1459 
1460 //==========================================================================
1461 //
1462 // SB_Responder
1463 //
1464 //==========================================================================
1465 
SB_Responder(event_t * event)1466 boolean SB_Responder(event_t *event)
1467 {
1468 	if(event->type == ev_keydown)
1469 	{
1470 		if(HandleCheats(event->data1))
1471 		{ // Need to eat the key
1472 			return(true);
1473 		}
1474 	}
1475 	return(false);
1476 }
1477 
1478 //==========================================================================
1479 //
1480 // HandleCheats
1481 //
1482 // Returns true if the caller should eat the key.
1483 //
1484 //==========================================================================
1485 
HandleCheats(byte key)1486 static boolean HandleCheats(byte key)
1487 {
1488 	int i;
1489 	boolean eat;
1490 
1491 	if(gameskill == sk_nightmare)
1492 	{ // Can't cheat in nightmare mode
1493 		return(false);
1494 	}
1495 	else if(netgame)
1496 	{ // change CD track is the only cheat available in deathmatch
1497 		eat = false;
1498 		if(i_CDMusic)
1499 		{
1500 			if(CheatAddKey(&Cheats[0], key, &eat))
1501 			{
1502 				Cheats[0].func(&players[consoleplayer], &Cheats[0]);
1503 				S_StartSound(NULL, SFX_PLATFORM_STOP);
1504 			}
1505 			if(CheatAddKey(&Cheats[1], key, &eat))
1506 			{
1507 				Cheats[1].func(&players[consoleplayer], &Cheats[1]);
1508 				S_StartSound(NULL, SFX_PLATFORM_STOP);
1509 			}
1510 		}
1511 		return eat;
1512 	}
1513 	if(players[consoleplayer].health <= 0)
1514 	{ // Dead players can't cheat
1515 		return(false);
1516 	}
1517 	eat = false;
1518 	for(i = 0; Cheats[i].func != NULL; i++)
1519 	{
1520 		if(CheatAddKey(&Cheats[i], key, &eat))
1521 		{
1522 			Cheats[i].func(&players[consoleplayer], &Cheats[i]);
1523 			S_StartSound(NULL, SFX_PLATFORM_STOP);
1524 		}
1525 	}
1526 	return(eat);
1527 }
1528 
1529 //==========================================================================
1530 //
1531 // CheatAddkey
1532 //
1533 // Returns true if the added key completed the cheat, false otherwise.
1534 //
1535 //==========================================================================
1536 
CheatAddKey(Cheat_t * cheat,byte key,boolean * eat)1537 static boolean CheatAddKey(Cheat_t *cheat, byte key, boolean *eat)
1538 {
1539 	if(!cheat->pos)
1540 	{
1541 		cheat->pos = cheat->sequence;
1542 		cheat->currentArg = 0;
1543 	}
1544 	if(*cheat->pos == 0)
1545 	{
1546 		*eat = true;
1547 		cheat->args[cheat->currentArg++] = key;
1548 		cheat->pos++;
1549 	}
1550 	else if(CheatLookup[key] == *cheat->pos)
1551 	{
1552 		cheat->pos++;
1553 	}
1554 	else
1555 	{
1556 		cheat->pos = cheat->sequence;
1557 		cheat->currentArg = 0;
1558 	}
1559 	if(*cheat->pos == 0xff)
1560 	{
1561 		cheat->pos = cheat->sequence;
1562 		cheat->currentArg = 0;
1563 		return(true);
1564 	}
1565 	return(false);
1566 }
1567 
1568 //==========================================================================
1569 //
1570 // CHEAT FUNCTIONS
1571 //
1572 //==========================================================================
1573 
CheatGodFunc(player_t * player,Cheat_t * cheat)1574 static void CheatGodFunc(player_t *player, Cheat_t *cheat)
1575 {
1576 	if (player->cheats & CF_FUNNYPIGGY) return;
1577 	player->cheats ^= CF_GODMODE;
1578 	if(player->cheats&CF_GODMODE)
1579 	{
1580 		P_SetMessage(player, TXT_CHEATGODON, true);
1581 	}
1582 	else
1583 	{
1584 		P_SetMessage(player, TXT_CHEATGODOFF, true);
1585 	}
1586 	SB_state = -1;
1587 }
1588 
CheatFunnyPiggyFunc1(player_t * player,Cheat_t * cheat)1589 static void CheatFunnyPiggyFunc1(player_t *player, Cheat_t *cheat)
1590 {
1591 	if(!(player->cheats&CF_FUNNYPIGGY))
1592 	{
1593 		player->cheats |= (CF_FUNNYPIGGY | CF_GODMODE);
1594 		P_MorphPlayer(player);
1595 	}
1596 	SB_state = -1;
1597 	P_SetMessage(player, TXT_CHEATFUNNYPIGGYON, true);
1598 }
1599 
CheatFunnyPiggyFunc2(player_t * player,Cheat_t * cheat)1600 static void CheatFunnyPiggyFunc2(player_t *player, Cheat_t *cheat)
1601 {
1602 	extern boolean P_UndoPlayerMorph(player_t *player);
1603 
1604 	if(player->cheats&CF_FUNNYPIGGY)
1605 	{
1606 		player->cheats &= ~(CF_FUNNYPIGGY | CF_GODMODE);
1607 		P_SetMessage(player, TXT_CHEATFUNNYPIGGYOFF, true);
1608 		P_UndoPlayerMorph(player);
1609 	}
1610 	SB_state = -1;
1611 }
1612 
CheatNoClipFunc(player_t * player,Cheat_t * cheat)1613 static void CheatNoClipFunc(player_t *player, Cheat_t *cheat)
1614 {
1615 	player->cheats ^= CF_NOCLIP;
1616 	if(player->cheats&CF_NOCLIP)
1617 	{
1618 		P_SetMessage(player, TXT_CHEATNOCLIPON, true);
1619 	}
1620 	else
1621 	{
1622 		P_SetMessage(player, TXT_CHEATNOCLIPOFF, true);
1623 	}
1624 }
1625 
CheatWeaponsFunc(player_t * player,Cheat_t * cheat)1626 static void CheatWeaponsFunc(player_t *player, Cheat_t *cheat)
1627 {
1628 	int i;
1629 	//extern boolean *WeaponInShareware;
1630 
1631 	for(i = 0; i < NUMARMOR; i++)
1632 	{
1633 		player->armorpoints[i] = ArmorIncrement[player->class][i];
1634 	}
1635 	for(i = 0; i < NUMWEAPONS; i++)
1636 	{
1637 		player->weaponowned[i] = true;
1638 	}
1639 	for(i = 0; i < NUMMANA; i++)
1640 	{
1641 		player->mana[i] = MAX_MANA;
1642 	}
1643 	P_SetMessage(player, TXT_CHEATWEAPONS, true);
1644 }
1645 
CheatHealthFunc(player_t * player,Cheat_t * cheat)1646 static void CheatHealthFunc(player_t *player, Cheat_t *cheat)
1647 {
1648 	if(player->morphTics)
1649 	{
1650 		player->health = player->mo->health = MAXMORPHHEALTH;
1651 	}
1652 	else
1653 	{
1654 		player->health = player->mo->health = MAXHEALTH;
1655 	}
1656 	P_SetMessage(player, TXT_CHEATHEALTH, true);
1657 }
1658 
CheatKeysFunc(player_t * player,Cheat_t * cheat)1659 static void CheatKeysFunc(player_t *player, Cheat_t *cheat)
1660 {
1661 	player->keys = 2047;
1662 	P_SetMessage(player, TXT_CHEATKEYS, true);
1663 }
1664 
CheatSoundFunc(player_t * player,Cheat_t * cheat)1665 static void CheatSoundFunc(player_t *player, Cheat_t *cheat)
1666 {
1667 	DebugSound = !DebugSound;
1668 	if(DebugSound)
1669 	{
1670 		P_SetMessage(player, TXT_CHEATSOUNDON, true);
1671 	}
1672 	else
1673 	{
1674 		P_SetMessage(player, TXT_CHEATSOUNDOFF, true);
1675 	}
1676 }
1677 
CheatTickerFunc(player_t * player,Cheat_t * cheat)1678 static void CheatTickerFunc(player_t *player, Cheat_t *cheat)
1679 {
1680 	extern int DisplayTicker;
1681 
1682 	DisplayTicker = !DisplayTicker;
1683 	if(DisplayTicker)
1684 	{
1685 		P_SetMessage(player, TXT_CHEATTICKERON, true);
1686 	}
1687 	else
1688 	{
1689 		P_SetMessage(player, TXT_CHEATTICKEROFF, true);
1690 	}
1691 }
1692 
CheatArtifactAllFunc(player_t * player,Cheat_t * cheat)1693 static void CheatArtifactAllFunc(player_t *player, Cheat_t *cheat)
1694 {
1695 	int i;
1696 	int j;
1697 
1698 	for(i = arti_none+1; i < arti_firstpuzzitem; i++)
1699 	{
1700 		for(j = 0; j < 25; j++)
1701 		{
1702 			P_GiveArtifact(player, i, NULL);
1703 		}
1704 	}
1705 	P_SetMessage(player, TXT_CHEATARTIFACTS3, true);
1706 }
1707 
CheatPuzzleFunc(player_t * player,Cheat_t * cheat)1708 static void CheatPuzzleFunc(player_t *player, Cheat_t *cheat)
1709 {
1710 	int i;
1711 
1712 	for(i = arti_firstpuzzitem; i < NUMARTIFACTS; i++)
1713 	{
1714 		P_GiveArtifact(player, i, NULL);
1715 	}
1716 	P_SetMessage(player, TXT_CHEATARTIFACTS3, true);
1717 }
1718 
CheatInitFunc(player_t * player,Cheat_t * cheat)1719 static void CheatInitFunc(player_t *player, Cheat_t *cheat)
1720 {
1721 	G_DeferedInitNew(gameskill, gameepisode, gamemap);
1722 	P_SetMessage(player, TXT_CHEATWARP, true);
1723 }
1724 
CheatWarpFunc(player_t * player,Cheat_t * cheat)1725 static void CheatWarpFunc(player_t *player, Cheat_t *cheat)
1726 {
1727 	int tens;
1728 	int ones;
1729 	int map;
1730 	char mapName[9];
1731 	char auxName[128];
1732 	FILE *fp;
1733 
1734 	tens = cheat->args[0]-'0';
1735 	ones = cheat->args[1]-'0';
1736 	if(tens < 0 || tens > 9 || ones < 0 || ones > 9)
1737 	{ // Bad map
1738 		P_SetMessage(player, TXT_CHEATBADINPUT, true);
1739 		return;
1740 	}
1741 	map = P_TranslateMap((cheat->args[0]-'0')*10+cheat->args[1]-'0');
1742 	if(map == -1)
1743 	{ // Not found
1744 		P_SetMessage(player, TXT_CHEATNOMAP, true);
1745 		return;
1746 	}
1747 	if(map == gamemap)
1748 	{ // Don't try to teleport to current map
1749 		P_SetMessage(player, TXT_CHEATBADINPUT, true);
1750 		return;
1751 	}
1752 	if(DevMaps)
1753 	{ // Search map development directory
1754 		sprintf(auxName, "%sMAP%02d.WAD", DevMapsDir, map);
1755 		fp = fopen(auxName, "rb");
1756 		if(fp)
1757 		{
1758 			fclose(fp);
1759 		}
1760 		else
1761 		{ // Can't find
1762 			P_SetMessage(player, TXT_CHEATNOMAP, true);
1763 			return;
1764 		}
1765 	}
1766 	else
1767 	{ // Search primary lumps
1768 		sprintf(mapName, "MAP%02d", map);
1769 		if(W_CheckNumForName(mapName) == -1)
1770 		{ // Can't find
1771 			P_SetMessage(player, TXT_CHEATNOMAP, true);
1772 			return;
1773 		}
1774 	}
1775 	P_SetMessage(player, TXT_CHEATWARP, true);
1776 	G_TeleportNewMap(map, 0);
1777 }
1778 
CheatPigFunc(player_t * player,Cheat_t * cheat)1779 static void CheatPigFunc(player_t *player, Cheat_t *cheat)
1780 {
1781 	extern boolean P_UndoPlayerMorph(player_t *player);
1782 
1783 	if(player->morphTics)
1784 	{
1785 		P_UndoPlayerMorph(player);
1786 	}
1787 	else
1788 	{
1789 	 	P_MorphPlayer(player);
1790 	}
1791 	P_SetMessage(player, "SQUEAL!!", true);
1792 }
1793 
1794 
CheatMassacreFunc(player_t * player,Cheat_t * cheat)1795 static void CheatMassacreFunc(player_t *player, Cheat_t *cheat)
1796 {
1797 	int count;
1798 	char buffer[80];
1799 
1800 	count = P_Massacre();
1801 	sprintf(buffer, "%d MONSTERS KILLED\n", count);
1802 	P_SetMessage(player, buffer, true);
1803 }
1804 
CheatIDKFAFunc(player_t * player,Cheat_t * cheat)1805 static void CheatIDKFAFunc(player_t *player, Cheat_t *cheat)
1806 {
1807 	int i;
1808 	if(player->morphTics)
1809 	{
1810 		return;
1811 	}
1812 	for(i = 1; i < 8; i++)
1813 	{
1814 		player->weaponowned[i] = false;
1815 	}
1816 	player->pendingweapon = WP_FIRST;
1817 	P_SetMessage(player, TXT_CHEATIDKFA, true);
1818 }
1819 
CheatQuickenFunc(player_t * player,Cheat_t * cheat)1820 static void CheatQuickenFunc(player_t *player, Cheat_t *cheat)
1821 {
1822 	P_SetMessage(player, "NO ROOM FOR CHEATER IN OUR WORLD!", true);
1823 	P_DamageMobj(player->mo, NULL, player->mo, 10000);
1824 }
1825 
1826 
CheatClassFunc1(player_t * player,Cheat_t * cheat)1827 static void CheatClassFunc1(player_t *player, Cheat_t *cheat)
1828 {
1829 	P_SetMessage(player, "ENTER NEW PLAYER CLASS (0 - 2)", true);
1830 }
1831 
CheatClassFunc2(player_t * player,Cheat_t * cheat)1832 static void CheatClassFunc2(player_t *player, Cheat_t *cheat)
1833 {
1834 	int i;
1835 	int class;
1836 
1837 	if(player->morphTics)
1838 	{ // don't change class if the player is morphed
1839 		return;
1840 	}
1841 	class = cheat->args[0]-'0';
1842 	if(class > 2 || class < 0)
1843 	{
1844 		P_SetMessage(player, "INVALID PLAYER CLASS", true);
1845 		return;
1846 	}
1847 	player->class = class;
1848 	for(i = 0; i < NUMARMOR; i++)
1849 	{
1850 		player->armorpoints[i] = 0;
1851 	}
1852 	PlayerClass[consoleplayer] = class;
1853 	P_PostMorphWeapon(player, WP_FIRST);
1854 	SB_SetClassData();
1855 	SB_state = -1;
1856 	UpdateState |= I_FULLSCRN;
1857 }
1858 
CheatVersionFunc(player_t * player,Cheat_t * cheat)1859 static void CheatVersionFunc(player_t *player, Cheat_t *cheat)
1860 {
1861 	P_SetMessage(player, VERSIONTEXT, true);
1862 }
1863 
CheatDebugFunc(player_t * player,Cheat_t * cheat)1864 static void CheatDebugFunc(player_t *player, Cheat_t *cheat)
1865 {
1866 	char textBuffer[50];
1867 	sprintf(textBuffer, "MAP %d (%d)  X:%5d  Y:%5d  Z:%5d",
1868 				P_GetMapWarpTrans(gamemap),
1869 				gamemap,
1870 				player->mo->x >> FRACBITS,
1871 				player->mo->y >> FRACBITS,
1872 				player->mo->z >> FRACBITS);
1873 	P_SetMessage(player, textBuffer, true);
1874 }
1875 
CheatScriptFunc1(player_t * player,Cheat_t * cheat)1876 static void CheatScriptFunc1(player_t *player, Cheat_t *cheat)
1877 {
1878 	P_SetMessage(player, "RUN WHICH SCRIPT(01-99)?", true);
1879 }
1880 
CheatScriptFunc2(player_t * player,Cheat_t * cheat)1881 static void CheatScriptFunc2(player_t *player, Cheat_t *cheat)
1882 {
1883 	P_SetMessage(player, "RUN WHICH SCRIPT(01-99)?", true);
1884 }
1885 
CheatScriptFunc3(player_t * player,Cheat_t * cheat)1886 static void CheatScriptFunc3(player_t *player, Cheat_t *cheat)
1887 {
1888 	int script;
1889 	byte args[3];
1890 	int tens, ones;
1891 	char textBuffer[40];
1892 
1893 	tens = cheat->args[0]-'0';
1894 	ones = cheat->args[1]-'0';
1895 	script = tens*10 + ones;
1896 	if (script < 1) return;
1897 	if (script > 99) return;
1898 	args[0]=args[1]=args[2]=0;
1899 
1900 	if(P_StartACS(script, 0, args, player->mo, NULL, 0))
1901 	{
1902 		sprintf(textBuffer, "RUNNING SCRIPT %.2d", script);
1903 		P_SetMessage(player, textBuffer, true);
1904 	}
1905 }
1906 
1907 extern int cheating;
1908 
CheatRevealFunc(player_t * player,Cheat_t * cheat)1909 static void CheatRevealFunc(player_t *player, Cheat_t *cheat)
1910 {
1911 	cheating = (cheating+1) % 3;
1912 }
1913 
1914 //===========================================================================
1915 //
1916 // CheatTrackFunc1
1917 //
1918 //===========================================================================
1919 
CheatTrackFunc1(player_t * player,Cheat_t * cheat)1920 static void CheatTrackFunc1(player_t *player, Cheat_t *cheat)
1921 {
1922 #ifdef __WATCOMC__
1923 	char buffer[80];
1924 
1925 	if(!i_CDMusic)
1926 	{
1927 		return;
1928 	}
1929 	if(I_CDMusInit() == -1)
1930 	{
1931 		P_SetMessage(player, "ERROR INITIALIZING CD", true);
1932 	}
1933 	sprintf(buffer, "ENTER DESIRED CD TRACK (%.2d - %.2d):\n",
1934 		I_CDMusFirstTrack(), I_CDMusLastTrack());
1935 	P_SetMessage(player, buffer, true);
1936 #endif
1937 }
1938 
1939 //===========================================================================
1940 //
1941 // CheatTrackFunc2
1942 //
1943 //===========================================================================
1944 
CheatTrackFunc2(player_t * player,Cheat_t * cheat)1945 static void CheatTrackFunc2(player_t *player, Cheat_t *cheat)
1946 {
1947 #ifdef __WATCOMC__
1948 	char buffer[80];
1949 	int track;
1950 
1951 	if(!i_CDMusic)
1952 	{
1953 		return;
1954 	}
1955 	track = (cheat->args[0]-'0')*10+(cheat->args[1]-'0');
1956 	if(track < I_CDMusFirstTrack() || track > I_CDMusLastTrack())
1957 	{
1958 		P_SetMessage(player, "INVALID TRACK NUMBER\n", true);
1959 		return;
1960 	}
1961 	if(track == i_CDCurrentTrack)
1962 	{
1963 		return;
1964 	}
1965 	if(I_CDMusPlay(track))
1966 	{
1967 		sprintf(buffer, "ERROR WHILE TRYING TO PLAY CD TRACK: %.2d\n", track);
1968 		P_SetMessage(player, buffer, true);
1969 	}
1970 	else
1971 	{ // No error encountered while attempting to play the track
1972 		sprintf(buffer, "PLAYING TRACK: %.2d\n", track);
1973 		P_SetMessage(player, buffer, true);
1974 		i_CDMusicLength = 35*I_CDMusTrackLength(track);
1975 		oldTic = gametic;
1976 		i_CDTrack = track;
1977 		i_CDCurrentTrack = track;
1978 	}
1979 #endif
1980 }
1981