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