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