summaryrefslogtreecommitdiff
path: root/src/heretic/sb_bar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/heretic/sb_bar.c')
-rw-r--r--src/heretic/sb_bar.c1456
1 files changed, 1456 insertions, 0 deletions
diff --git a/src/heretic/sb_bar.c b/src/heretic/sb_bar.c
new file mode 100644
index 00000000..0f23fcf5
--- /dev/null
+++ b/src/heretic/sb_bar.c
@@ -0,0 +1,1456 @@
+
+// SB_bar.c
+
+#include "DoomDef.h"
+#include "P_local.h"
+#include "soundst.h"
+
+// Macros
+
+#define CHEAT_ENCRYPT(a) \
+ ((((a)&1)<<5)+ \
+ (((a)&2)<<1)+ \
+ (((a)&4)<<4)+ \
+ (((a)&8)>>3)+ \
+ (((a)&16)>>3)+ \
+ (((a)&32)<<2)+ \
+ (((a)&64)>>2)+ \
+ (((a)&128)>>4))
+
+// Types
+
+typedef struct Cheat_s
+{
+ void (*func)(player_t *player, struct Cheat_s *cheat);
+ byte *sequence;
+ byte *pos;
+ int args[2];
+ int currentArg;
+} Cheat_t;
+
+// Private Functions
+
+static void DrawSoundInfo(void);
+static void ShadeLine(int x, int y, int height, int shade);
+static void ShadeChain(void);
+static void DrINumber(signed int val, int x, int y);
+static void DrBNumber(signed int val, int x, int y);
+static void DrawCommonBar(void);
+static void DrawMainBar(void);
+static void DrawInventoryBar(void);
+static void DrawFullScreenStuff(void);
+static boolean HandleCheats(byte key);
+static boolean CheatAddKey(Cheat_t *cheat, byte key, boolean *eat);
+static void CheatGodFunc(player_t *player, Cheat_t *cheat);
+static void CheatNoClipFunc(player_t *player, Cheat_t *cheat);
+static void CheatWeaponsFunc(player_t *player, Cheat_t *cheat);
+static void CheatPowerFunc(player_t *player, Cheat_t *cheat);
+static void CheatHealthFunc(player_t *player, Cheat_t *cheat);
+static void CheatKeysFunc(player_t *player, Cheat_t *cheat);
+static void CheatSoundFunc(player_t *player, Cheat_t *cheat);
+static void CheatTickerFunc(player_t *player, Cheat_t *cheat);
+static void CheatArtifact1Func(player_t *player, Cheat_t *cheat);
+static void CheatArtifact2Func(player_t *player, Cheat_t *cheat);
+static void CheatArtifact3Func(player_t *player, Cheat_t *cheat);
+static void CheatWarpFunc(player_t *player, Cheat_t *cheat);
+static void CheatChickenFunc(player_t *player, Cheat_t *cheat);
+static void CheatMassacreFunc(player_t *player, Cheat_t *cheat);
+static void CheatIDKFAFunc(player_t *player, Cheat_t *cheat);
+static void CheatIDDQDFunc(player_t *player, Cheat_t *cheat);
+
+// Public Data
+
+boolean DebugSound; // debug flag for displaying sound info
+
+boolean inventory;
+int curpos;
+int inv_ptr;
+int ArtifactFlash;
+
+// Private Data
+
+static int HealthMarker;
+static int ChainWiggle;
+static player_t *CPlayer;
+int playpalette;
+
+patch_t *PatchLTFACE;
+patch_t *PatchRTFACE;
+patch_t *PatchBARBACK;
+patch_t *PatchCHAIN;
+patch_t *PatchSTATBAR;
+patch_t *PatchLIFEGEM;
+//patch_t *PatchEMPWEAP;
+//patch_t *PatchLIL4BOX;
+patch_t *PatchLTFCTOP;
+patch_t *PatchRTFCTOP;
+//patch_t *PatchARMORBOX;
+//patch_t *PatchARTIBOX;
+patch_t *PatchSELECTBOX;
+//patch_t *PatchKILLSPIC;
+//patch_t *PatchMANAPIC;
+//patch_t *PatchPOWERICN;
+patch_t *PatchINVLFGEM1;
+patch_t *PatchINVLFGEM2;
+patch_t *PatchINVRTGEM1;
+patch_t *PatchINVRTGEM2;
+patch_t *PatchINumbers[10];
+patch_t *PatchNEGATIVE;
+patch_t *PatchSmNumbers[10];
+patch_t *PatchBLACKSQ;
+patch_t *PatchINVBAR;
+patch_t *PatchARMCLEAR;
+patch_t *PatchCHAINBACK;
+//byte *ShadeTables;
+extern byte *screen;
+int FontBNumBase;
+int spinbooklump;
+int spinflylump;
+
+static byte CheatLookup[256];
+
+// Toggle god mode
+static byte CheatGodSeq[] =
+{
+ CHEAT_ENCRYPT('q'),
+ CHEAT_ENCRYPT('u'),
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('c'),
+ CHEAT_ENCRYPT('k'),
+ CHEAT_ENCRYPT('e'),
+ CHEAT_ENCRYPT('n'),
+ 0xff
+};
+
+// Toggle no clipping mode
+static byte CheatNoClipSeq[] =
+{
+ CHEAT_ENCRYPT('k'),
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('t'),
+ CHEAT_ENCRYPT('t'),
+ CHEAT_ENCRYPT('y'),
+ 0xff
+};
+
+// Get all weapons and ammo
+static byte CheatWeaponsSeq[] =
+{
+ CHEAT_ENCRYPT('r'),
+ CHEAT_ENCRYPT('a'),
+ CHEAT_ENCRYPT('m'),
+ CHEAT_ENCRYPT('b'),
+ CHEAT_ENCRYPT('o'),
+ 0xff
+};
+
+// Toggle tome of power
+static byte CheatPowerSeq[] =
+{
+ CHEAT_ENCRYPT('s'),
+ CHEAT_ENCRYPT('h'),
+ CHEAT_ENCRYPT('a'),
+ CHEAT_ENCRYPT('z'),
+ CHEAT_ENCRYPT('a'),
+ CHEAT_ENCRYPT('m'),
+ 0xff, 0
+};
+
+// Get full health
+static byte CheatHealthSeq[] =
+{
+ CHEAT_ENCRYPT('p'),
+ CHEAT_ENCRYPT('o'),
+ CHEAT_ENCRYPT('n'),
+ CHEAT_ENCRYPT('c'),
+ CHEAT_ENCRYPT('e'),
+ 0xff
+};
+
+// Get all keys
+static byte CheatKeysSeq[] =
+{
+ CHEAT_ENCRYPT('s'),
+ CHEAT_ENCRYPT('k'),
+ CHEAT_ENCRYPT('e'),
+ CHEAT_ENCRYPT('l'),
+ 0xff, 0
+};
+
+// Toggle sound debug info
+static byte CheatSoundSeq[] =
+{
+ CHEAT_ENCRYPT('n'),
+ CHEAT_ENCRYPT('o'),
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('s'),
+ CHEAT_ENCRYPT('e'),
+ 0xff
+};
+
+// Toggle ticker
+static byte CheatTickerSeq[] =
+{
+ CHEAT_ENCRYPT('t'),
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('c'),
+ CHEAT_ENCRYPT('k'),
+ CHEAT_ENCRYPT('e'),
+ CHEAT_ENCRYPT('r'),
+ 0xff, 0
+};
+
+// Get an artifact 1st stage (ask for type)
+static byte CheatArtifact1Seq[] =
+{
+ CHEAT_ENCRYPT('g'),
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('m'),
+ CHEAT_ENCRYPT('m'),
+ CHEAT_ENCRYPT('e'),
+ 0xff
+};
+
+// Get an artifact 2nd stage (ask for count)
+static byte CheatArtifact2Seq[] =
+{
+ CHEAT_ENCRYPT('g'),
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('m'),
+ CHEAT_ENCRYPT('m'),
+ CHEAT_ENCRYPT('e'),
+ 0, 0xff, 0
+};
+
+// Get an artifact final stage
+static byte CheatArtifact3Seq[] =
+{
+ CHEAT_ENCRYPT('g'),
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('m'),
+ CHEAT_ENCRYPT('m'),
+ CHEAT_ENCRYPT('e'),
+ 0, 0, 0xff
+};
+
+// Warp to new level
+static byte CheatWarpSeq[] =
+{
+ CHEAT_ENCRYPT('e'),
+ CHEAT_ENCRYPT('n'),
+ CHEAT_ENCRYPT('g'),
+ CHEAT_ENCRYPT('a'),
+ CHEAT_ENCRYPT('g'),
+ CHEAT_ENCRYPT('e'),
+ 0, 0, 0xff, 0
+};
+
+// Save a screenshot
+static byte CheatChickenSeq[] =
+{
+ CHEAT_ENCRYPT('c'),
+ CHEAT_ENCRYPT('o'),
+ CHEAT_ENCRYPT('c'),
+ CHEAT_ENCRYPT('k'),
+ CHEAT_ENCRYPT('a'),
+ CHEAT_ENCRYPT('d'),
+ CHEAT_ENCRYPT('o'),
+ CHEAT_ENCRYPT('o'),
+ CHEAT_ENCRYPT('d'),
+ CHEAT_ENCRYPT('l'),
+ CHEAT_ENCRYPT('e'),
+ CHEAT_ENCRYPT('d'),
+ CHEAT_ENCRYPT('o'),
+ CHEAT_ENCRYPT('o'),
+ 0xff, 0
+};
+
+// Kill all monsters
+static byte CheatMassacreSeq[] =
+{
+ CHEAT_ENCRYPT('m'),
+ CHEAT_ENCRYPT('a'),
+ CHEAT_ENCRYPT('s'),
+ CHEAT_ENCRYPT('s'),
+ CHEAT_ENCRYPT('a'),
+ CHEAT_ENCRYPT('c'),
+ CHEAT_ENCRYPT('r'),
+ CHEAT_ENCRYPT('e'),
+ 0xff, 0
+};
+
+static byte CheatIDKFASeq[] =
+{
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('d'),
+ CHEAT_ENCRYPT('k'),
+ CHEAT_ENCRYPT('f'),
+ CHEAT_ENCRYPT('a'),
+ 0xff, 0
+};
+
+static byte CheatIDDQDSeq[] =
+{
+ CHEAT_ENCRYPT('i'),
+ CHEAT_ENCRYPT('d'),
+ CHEAT_ENCRYPT('d'),
+ CHEAT_ENCRYPT('q'),
+ CHEAT_ENCRYPT('d'),
+ 0xff, 0
+};
+
+static Cheat_t Cheats[] =
+{
+ { CheatGodFunc, CheatGodSeq, NULL, 0, 0, 0 },
+ { CheatNoClipFunc, CheatNoClipSeq, NULL, 0, 0, 0 },
+ { CheatWeaponsFunc, CheatWeaponsSeq, NULL, 0, 0, 0 },
+ { CheatPowerFunc, CheatPowerSeq, NULL, 0, 0, 0 },
+ { CheatHealthFunc, CheatHealthSeq, NULL, 0, 0, 0 },
+ { CheatKeysFunc, CheatKeysSeq, NULL, 0, 0, 0 },
+ { CheatSoundFunc, CheatSoundSeq, NULL, 0, 0, 0 },
+ { CheatTickerFunc, CheatTickerSeq, NULL, 0, 0, 0 },
+ { CheatArtifact1Func, CheatArtifact1Seq, NULL, 0, 0, 0 },
+ { CheatArtifact2Func, CheatArtifact2Seq, NULL, 0, 0, 0 },
+ { CheatArtifact3Func, CheatArtifact3Seq, NULL, 0, 0, 0 },
+ { CheatWarpFunc, CheatWarpSeq, NULL, 0, 0, 0 },
+ { CheatChickenFunc, CheatChickenSeq, NULL, 0, 0, 0 },
+ { CheatMassacreFunc, CheatMassacreSeq, NULL, 0, 0, 0 },
+ { CheatIDKFAFunc, CheatIDKFASeq, NULL, 0, 0, 0 },
+ { CheatIDDQDFunc, CheatIDDQDSeq, NULL, 0, 0, 0 },
+ { NULL, NULL, NULL, 0, 0, 0 } // Terminator
+};
+
+//---------------------------------------------------------------------------
+//
+// PROC SB_Init
+//
+//---------------------------------------------------------------------------
+
+void SB_Init(void)
+{
+ int i;
+ int startLump;
+
+ PatchLTFACE = W_CacheLumpName("LTFACE", PU_STATIC);
+ PatchRTFACE = W_CacheLumpName("RTFACE", PU_STATIC);
+ PatchBARBACK = W_CacheLumpName("BARBACK", PU_STATIC);
+ PatchINVBAR = W_CacheLumpName("INVBAR", PU_STATIC);
+ PatchCHAIN = W_CacheLumpName("CHAIN", PU_STATIC);
+ if(deathmatch)
+ {
+ PatchSTATBAR = W_CacheLumpName("STATBAR", PU_STATIC);
+ }
+ else
+ {
+ PatchSTATBAR = W_CacheLumpName("LIFEBAR", PU_STATIC);
+ }
+ if(!netgame)
+ { // single player game uses red life gem
+ PatchLIFEGEM = W_CacheLumpName("LIFEGEM2", PU_STATIC);
+ }
+ else
+ {
+ PatchLIFEGEM = W_CacheLumpNum(W_GetNumForName("LIFEGEM0")
+ + consoleplayer, PU_STATIC);
+ }
+ PatchLTFCTOP = W_CacheLumpName("LTFCTOP", PU_STATIC);
+ PatchRTFCTOP = W_CacheLumpName("RTFCTOP", PU_STATIC);
+ PatchSELECTBOX = W_CacheLumpName("SELECTBOX", PU_STATIC);
+ PatchINVLFGEM1 = W_CacheLumpName("INVGEML1", PU_STATIC);
+ PatchINVLFGEM2 = W_CacheLumpName("INVGEML2", PU_STATIC);
+ PatchINVRTGEM1 = W_CacheLumpName("INVGEMR1", PU_STATIC);
+ PatchINVRTGEM2 = W_CacheLumpName("INVGEMR2", PU_STATIC);
+ PatchBLACKSQ = W_CacheLumpName("BLACKSQ", PU_STATIC);
+ PatchARMCLEAR = W_CacheLumpName("ARMCLEAR", PU_STATIC);
+ PatchCHAINBACK = W_CacheLumpName("CHAINBACK", PU_STATIC);
+ startLump = W_GetNumForName("IN0");
+ for(i = 0; i < 10; i++)
+ {
+ PatchINumbers[i] = W_CacheLumpNum(startLump+i, PU_STATIC);
+ }
+ PatchNEGATIVE = W_CacheLumpName("NEGNUM", PU_STATIC);
+ FontBNumBase = W_GetNumForName("FONTB16");
+ startLump = W_GetNumForName("SMALLIN0");
+ for(i = 0; i < 10; i++)
+ {
+ PatchSmNumbers[i] = W_CacheLumpNum(startLump+i, PU_STATIC);
+ }
+ playpalette = W_GetNumForName("PLAYPAL");
+ spinbooklump = W_GetNumForName("SPINBK0");
+ spinflylump = W_GetNumForName("SPFLY0");
+ for(i = 0; i < 256; i++)
+ {
+ CheatLookup[i] = CHEAT_ENCRYPT(i);
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC SB_Ticker
+//
+//---------------------------------------------------------------------------
+
+void SB_Ticker(void)
+{
+ int delta;
+ int curHealth;
+
+ if(leveltime&1)
+ {
+ ChainWiggle = P_Random()&1;
+ }
+ curHealth = players[consoleplayer].mo->health;
+ if(curHealth < 0)
+ {
+ curHealth = 0;
+ }
+ if(curHealth < HealthMarker)
+ {
+ delta = (HealthMarker-curHealth)>>2;
+ if(delta < 1)
+ {
+ delta = 1;
+ }
+ else if(delta > 8)
+ {
+ delta = 8;
+ }
+ HealthMarker -= delta;
+ }
+ else if(curHealth > HealthMarker)
+ {
+ delta = (curHealth-HealthMarker)>>2;
+ if(delta < 1)
+ {
+ delta = 1;
+ }
+ else if(delta > 8)
+ {
+ delta = 8;
+ }
+ HealthMarker += delta;
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrINumber
+//
+// Draws a three digit number.
+//
+//---------------------------------------------------------------------------
+
+static void DrINumber(signed int val, int x, int y)
+{
+ patch_t *patch;
+ int oldval;
+
+ oldval = val;
+ if(val < 0)
+ {
+ if(val < -9)
+ {
+ V_DrawPatch(x+1, y+1, W_CacheLumpName("LAME", PU_CACHE));
+ }
+ else
+ {
+ val = -val;
+ V_DrawPatch(x+18, y, PatchINumbers[val]);
+ V_DrawPatch(x+9, y, PatchNEGATIVE);
+ }
+ return;
+ }
+ if(val > 99)
+ {
+ patch = PatchINumbers[val/100];
+ V_DrawPatch(x, y, patch);
+ }
+ val = val%100;
+ if(val > 9 || oldval > 99)
+ {
+ patch = PatchINumbers[val/10];
+ V_DrawPatch(x+9, y, patch);
+ }
+ val = val%10;
+ patch = PatchINumbers[val];
+ V_DrawPatch(x+18, y, patch);
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrBNumber
+//
+// Draws a three digit number using FontB
+//
+//---------------------------------------------------------------------------
+
+static void DrBNumber(signed int val, int x, int y)
+{
+ patch_t *patch;
+ int xpos;
+ int oldval;
+
+ oldval = val;
+ xpos = x;
+ if(val < 0)
+ {
+ val = 0;
+ }
+ if(val > 99)
+ {
+ patch = W_CacheLumpNum(FontBNumBase+val/100, PU_CACHE);
+ V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
+ }
+ val = val%100;
+ xpos += 12;
+ if(val > 9 || oldval > 99)
+ {
+ patch = W_CacheLumpNum(FontBNumBase+val/10, PU_CACHE);
+ V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
+ }
+ val = val%10;
+ xpos += 12;
+ patch = W_CacheLumpNum(FontBNumBase+val, PU_CACHE);
+ V_DrawShadowedPatch(xpos+6-patch->width/2, y, patch);
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrSmallNumber
+//
+// Draws a small two digit number.
+//
+//---------------------------------------------------------------------------
+
+static void DrSmallNumber(int val, int x, int y)
+{
+ patch_t *patch;
+
+ if(val == 1)
+ {
+ return;
+ }
+ if(val > 9)
+ {
+ patch = PatchSmNumbers[val/10];
+ V_DrawPatch(x, y, patch);
+ }
+ val = val%10;
+ patch = PatchSmNumbers[val];
+ V_DrawPatch(x+4, y, patch);
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC ShadeLine
+//
+//---------------------------------------------------------------------------
+
+static void ShadeLine(int x, int y, int height, int shade)
+{
+ byte *dest;
+ byte *shades;
+
+ shades = colormaps+9*256+shade*2*256;
+ dest = screen+y*SCREENWIDTH+x;
+ while(height--)
+ {
+ *(dest) = *(shades+*dest);
+ dest += SCREENWIDTH;
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC ShadeChain
+//
+//---------------------------------------------------------------------------
+
+static void ShadeChain(void)
+{
+ int i;
+
+ for(i = 0; i < 16; i++)
+ {
+ ShadeLine(277+i, 190, 10, i/2);
+ ShadeLine(19+i, 190, 10, 7-(i/2));
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrawSoundInfo
+//
+// Displays sound debugging information.
+//
+//---------------------------------------------------------------------------
+
+static void DrawSoundInfo(void)
+{
+ int i;
+ SoundInfo_t s;
+ ChanInfo_t *c;
+ char text[32];
+ int x;
+ int y;
+ int xPos[7] = {1, 75, 112, 156, 200, 230, 260};
+
+ if(leveltime&16)
+ {
+ MN_DrTextA("*** SOUND DEBUG INFO ***", xPos[0], 20);
+ }
+ S_GetChannelInfo(&s);
+ if(s.channelCount == 0)
+ {
+ return;
+ }
+ x = 0;
+ MN_DrTextA("NAME", xPos[x++], 30);
+ MN_DrTextA("MO.T", xPos[x++], 30);
+ MN_DrTextA("MO.X", xPos[x++], 30);
+ MN_DrTextA("MO.Y", xPos[x++], 30);
+ MN_DrTextA("ID", xPos[x++], 30);
+ MN_DrTextA("PRI", xPos[x++], 30);
+ MN_DrTextA("DIST", xPos[x++], 30);
+ for(i = 0; i < s.channelCount; i++)
+ {
+ c = &s.chan[i];
+ x = 0;
+ y = 40+i*10;
+ if(c->mo == NULL)
+ { // Channel is unused
+ MN_DrTextA("------", xPos[0], y);
+ continue;
+ }
+ sprintf(text, "%s", c->name);
+ M_ForceUppercase(text);
+ MN_DrTextA(text, xPos[x++], y);
+ sprintf(text, "%d", c->mo->type);
+ MN_DrTextA(text, xPos[x++], y);
+ sprintf(text, "%d", c->mo->x>>FRACBITS);
+ MN_DrTextA(text, xPos[x++], y);
+ sprintf(text, "%d", c->mo->y>>FRACBITS);
+ MN_DrTextA(text, xPos[x++], y);
+ sprintf(text, "%d", c->id);
+ MN_DrTextA(text, xPos[x++], y);
+ sprintf(text, "%d", c->priority);
+ MN_DrTextA(text, xPos[x++], y);
+ sprintf(text, "%d", c->distance);
+ MN_DrTextA(text, xPos[x++], y);
+ }
+ UpdateState |= I_FULLSCRN;
+ BorderNeedRefresh = true;
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC SB_Drawer
+//
+//---------------------------------------------------------------------------
+
+char patcharti[][10] =
+{
+ {"ARTIBOX"}, // none
+ {"ARTIINVU"}, // invulnerability
+ {"ARTIINVS"}, // invisibility
+ {"ARTIPTN2"}, // health
+ {"ARTISPHL"}, // superhealth
+ {"ARTIPWBK"}, // tomeofpower
+ {"ARTITRCH"}, // torch
+ {"ARTIFBMB"}, // firebomb
+ {"ARTIEGGC"}, // egg
+ {"ARTISOAR"}, // fly
+ {"ARTIATLP"} // teleport
+};
+
+char ammopic[][10] =
+{
+ {"INAMGLD"},
+ {"INAMBOW"},
+ {"INAMBST"},
+ {"INAMRAM"},
+ {"INAMPNX"},
+ {"INAMLOB"}
+};
+
+int SB_state = -1;
+static int oldarti = 0;
+static int oldartiCount = 0;
+static int oldfrags = -9999;
+static int oldammo = -1;
+static int oldarmor = -1;
+static int oldweapon = -1;
+static int oldhealth = -1;
+static int oldlife = -1;
+static int oldkeys = -1;
+
+int playerkeys = 0;
+
+extern boolean automapactive;
+
+void SB_Drawer(void)
+{
+ int frame;
+ static boolean hitCenterFrame;
+
+ // Sound info debug stuff
+ if(DebugSound == true)
+ {
+ DrawSoundInfo();
+ }
+ CPlayer = &players[consoleplayer];
+ if(viewheight == SCREENHEIGHT && !automapactive)
+ {
+ DrawFullScreenStuff();
+ SB_state = -1;
+ }
+ else
+ {
+ if(SB_state == -1)
+ {
+ V_DrawPatch(0, 158, PatchBARBACK);
+ if(players[consoleplayer].cheats&CF_GODMODE)
+ {
+ V_DrawPatch(16, 167, W_CacheLumpName("GOD1", PU_CACHE));
+ V_DrawPatch(287, 167, W_CacheLumpName("GOD2", PU_CACHE));
+ }
+ oldhealth = -1;
+ }
+ DrawCommonBar();
+ if(!inventory)
+ {
+ if(SB_state != 0)
+ {
+ // Main interface
+ V_DrawPatch(34, 160, PatchSTATBAR);
+ oldarti = 0;
+ oldammo = -1;
+ oldarmor = -1;
+ oldweapon = -1;
+ oldfrags = -9999; //can't use -1, 'cuz of negative frags
+ oldlife = -1;
+ oldkeys = -1;
+ }
+ DrawMainBar();
+ SB_state = 0;
+ }
+ else
+ {
+ if(SB_state != 1)
+ {
+ V_DrawPatch(34, 160, PatchINVBAR);
+ }
+ DrawInventoryBar();
+ SB_state = 1;
+ }
+ }
+ SB_PaletteFlash();
+
+ // Flight icons
+ if(CPlayer->powers[pw_flight])
+ {
+ if(CPlayer->powers[pw_flight] > BLINKTHRESHOLD
+ || !(CPlayer->powers[pw_flight]&16))
+ {
+ frame = (leveltime/3)&15;
+ if(CPlayer->mo->flags2&MF2_FLY)
+ {
+ if(hitCenterFrame && (frame != 15 && frame != 0))
+ {
+ V_DrawPatch(20, 17, W_CacheLumpNum(spinflylump+15,
+ PU_CACHE));
+ }
+ else
+ {
+ V_DrawPatch(20, 17, W_CacheLumpNum(spinflylump+frame,
+ PU_CACHE));
+ hitCenterFrame = false;
+ }
+ }
+ else
+ {
+ if(!hitCenterFrame && (frame != 15 && frame != 0))
+ {
+ V_DrawPatch(20, 17, W_CacheLumpNum(spinflylump+frame,
+ PU_CACHE));
+ hitCenterFrame = false;
+ }
+ else
+ {
+ V_DrawPatch(20, 17, W_CacheLumpNum(spinflylump+15,
+ PU_CACHE));
+ hitCenterFrame = true;
+ }
+ }
+ BorderTopRefresh = true;
+ UpdateState |= I_MESSAGES;
+ }
+ else
+ {
+ BorderTopRefresh = true;
+ UpdateState |= I_MESSAGES;
+ }
+ }
+
+ if(CPlayer->powers[pw_weaponlevel2] && !CPlayer->chickenTics)
+ {
+ if(CPlayer->powers[pw_weaponlevel2] > BLINKTHRESHOLD
+ || !(CPlayer->powers[pw_weaponlevel2]&16))
+ {
+ frame = (leveltime/3)&15;
+ V_DrawPatch(300, 17, W_CacheLumpNum(spinbooklump+frame, PU_CACHE));
+ BorderTopRefresh = true;
+ UpdateState |= I_MESSAGES;
+ }
+ else
+ {
+ BorderTopRefresh = true;
+ UpdateState |= I_MESSAGES;
+ }
+ }
+/*
+ if(CPlayer->powers[pw_weaponlevel2] > BLINKTHRESHOLD
+ || (CPlayer->powers[pw_weaponlevel2]&8))
+ {
+ V_DrawPatch(291, 0, W_CacheLumpName("ARTIPWBK", PU_CACHE));
+ }
+ else
+ {
+ BorderTopRefresh = true;
+ }
+ }
+*/
+}
+
+// sets the new palette based upon current values of player->damagecount
+// and player->bonuscount
+void SB_PaletteFlash(void)
+{
+ static int sb_palette = 0;
+ int palette;
+ byte *pal;
+
+ CPlayer = &players[consoleplayer];
+
+ if(CPlayer->damagecount)
+ {
+ palette = (CPlayer->damagecount+7)>>3;
+ if(palette >= NUMREDPALS)
+ {
+ palette = NUMREDPALS-1;
+ }
+ palette += STARTREDPALS;
+ }
+ else if(CPlayer->bonuscount)
+ {
+ palette = (CPlayer->bonuscount+7)>>3;
+ if(palette >= NUMBONUSPALS)
+ {
+ palette = NUMBONUSPALS-1;
+ }
+ palette += STARTBONUSPALS;
+ }
+ else
+ {
+ palette = 0;
+ }
+ if(palette != sb_palette)
+ {
+ sb_palette = palette;
+ pal = (byte *)W_CacheLumpNum(playpalette, PU_CACHE)+palette*768;
+ I_SetPalette(pal);
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrawCommonBar
+//
+//---------------------------------------------------------------------------
+
+void DrawCommonBar(void)
+{
+ int chainY;
+ int healthPos;
+
+ V_DrawPatch(0, 148, PatchLTFCTOP);
+ V_DrawPatch(290, 148, PatchRTFCTOP);
+
+ if(oldhealth != HealthMarker)
+ {
+ oldhealth = HealthMarker;
+ healthPos = HealthMarker;
+ if(healthPos < 0)
+ {
+ healthPos = 0;
+ }
+ if(healthPos > 100)
+ {
+ healthPos = 100;
+ }
+ healthPos = (healthPos*256)/100;
+ chainY = (HealthMarker == CPlayer->mo->health) ? 191 : 191+ChainWiggle;
+ V_DrawPatch(0, 190, PatchCHAINBACK);
+ V_DrawPatch(2+(healthPos%17), chainY, PatchCHAIN);
+ V_DrawPatch(17+healthPos, chainY, PatchLIFEGEM);
+ V_DrawPatch(0, 190, PatchLTFACE);
+ V_DrawPatch(276, 190, PatchRTFACE);
+ ShadeChain();
+ UpdateState |= I_STATBAR;
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrawMainBar
+//
+//---------------------------------------------------------------------------
+
+void DrawMainBar(void)
+{
+ int i;
+ int temp;
+
+ // Ready artifact
+ if(ArtifactFlash)
+ {
+ V_DrawPatch(180, 161, PatchBLACKSQ);
+ V_DrawPatch(182, 161, W_CacheLumpNum(W_GetNumForName("useartia")
+ + ArtifactFlash - 1, PU_CACHE));
+ ArtifactFlash--;
+ oldarti = -1; // so that the correct artifact fills in after the flash
+ UpdateState |= I_STATBAR;
+ }
+ else if(oldarti != CPlayer->readyArtifact
+ || oldartiCount != CPlayer->inventory[inv_ptr].count)
+ {
+ V_DrawPatch(180, 161, PatchBLACKSQ);
+ if(CPlayer->readyArtifact > 0)
+ {
+ V_DrawPatch(179,160, W_CacheLumpName(patcharti[CPlayer->readyArtifact],
+ PU_CACHE));
+ DrSmallNumber(CPlayer->inventory[inv_ptr].count, 201, 182);
+ }
+ oldarti = CPlayer->readyArtifact;
+ oldartiCount = CPlayer->inventory[inv_ptr].count;
+ UpdateState |= I_STATBAR;
+ }
+
+ // Frags
+ if(deathmatch)
+ {
+ temp = 0;
+ for(i = 0; i < MAXPLAYERS; i++)
+ {
+ temp += CPlayer->frags[i];
+ }
+ if(temp != oldfrags)
+ {
+ V_DrawPatch(57, 171, PatchARMCLEAR);
+ DrINumber(temp, 61, 170);
+ oldfrags = temp;
+ UpdateState |= I_STATBAR;
+ }
+ }
+ else
+ {
+ temp = HealthMarker;
+ if(temp < 0)
+ {
+ temp = 0;
+ }
+ else if(temp > 100)
+ {
+ temp = 100;
+ }
+ if(oldlife != temp)
+ {
+ oldlife = temp;
+ V_DrawPatch(57, 171, PatchARMCLEAR);
+ DrINumber(temp, 61, 170);
+ UpdateState |= I_STATBAR;
+ }
+ }
+
+ // Keys
+ if(oldkeys != playerkeys)
+ {
+ if(CPlayer->keys[key_yellow])
+ {
+ V_DrawPatch(153, 164, W_CacheLumpName("ykeyicon", PU_CACHE));
+ }
+ if(CPlayer->keys[key_green])
+ {
+ V_DrawPatch(153, 172, W_CacheLumpName("gkeyicon", PU_CACHE));
+ }
+ if(CPlayer->keys[key_blue])
+ {
+ V_DrawPatch(153, 180, W_CacheLumpName("bkeyicon", PU_CACHE));
+ }
+ oldkeys = playerkeys;
+ UpdateState |= I_STATBAR;
+ }
+ // Ammo
+ temp = CPlayer->ammo[wpnlev1info[CPlayer->readyweapon].ammo];
+ if(oldammo != temp || oldweapon != CPlayer->readyweapon)
+ {
+ V_DrawPatch(108, 161, PatchBLACKSQ);
+ if(temp && CPlayer->readyweapon > 0 && CPlayer->readyweapon < 7)
+ {
+ DrINumber(temp, 109, 162);
+ V_DrawPatch(111, 172, W_CacheLumpName(
+ ammopic[CPlayer->readyweapon-1], PU_CACHE));
+ }
+ oldammo = temp;
+ oldweapon = CPlayer->readyweapon;
+ UpdateState |= I_STATBAR;
+ }
+
+ // Armor
+ if(oldarmor != CPlayer->armorpoints)
+ {
+ V_DrawPatch(224, 171, PatchARMCLEAR);
+ DrINumber(CPlayer->armorpoints, 228, 170);
+ oldarmor = CPlayer->armorpoints;
+ UpdateState |= I_STATBAR;
+ }
+}
+
+//---------------------------------------------------------------------------
+//
+// PROC DrawInventoryBar
+//
+//---------------------------------------------------------------------------
+
+void DrawInventoryBar(void)
+{
+ int i;
+ int x;
+
+ x = inv_ptr-curpos;
+ UpdateState |= I_STATBAR;
+ V_DrawPatch(34, 160, PatchINVBAR);
+ for(i = 0; i < 7; i++)
+ {
+ //V_DrawPatch(50+i*31, 160, W_CacheLumpName("ARTIBOX", PU_CACHE));
+ if(CPlayer->inventorySlotNum > x+i
+ && CPlayer->inventory[x+i].type != arti_none)
+ {
+ V_DrawPatch(50+i*31, 160, W_CacheLumpName(
+ patcharti[CPlayer->inventory[x+i].type], PU_CACHE));
+ DrSmallNumber(CPlayer->inventory[x+i].count, 69+i*31, 182);
+ }
+ }
+ V_DrawPatch(50+curpos*31, 189, PatchSELECTBOX);
+ if(x != 0)
+ {
+ V_DrawPatch(38, 159,!(leveltime&4) ? PatchINVLFGEM1 :
+ PatchINVLFGEM2);
+ }
+ if(CPlayer->inventorySlotNum-x > 7)
+ {
+ V_DrawPatch(269, 159,!(leveltime&4) ?
+ PatchINVRTGEM1 : PatchINVRTGEM2);
+ }
+}
+
+void DrawFullScreenStuff(void)
+{
+ int i;
+ int x;
+ int temp;
+
+ UpdateState |= I_FULLSCRN;
+ if(CPlayer->mo->health > 0)
+ {
+ DrBNumber(CPlayer->mo->health, 5, 180);
+ }
+ else
+ {
+ DrBNumber(0, 5, 180);
+ }
+ if(deathmatch)
+ {
+ temp = 0;
+ for(i=0; i<MAXPLAYERS; i++)
+ {
+ if(playeringame[i])
+ {
+ temp += CPlayer->frags[i];
+ }
+ }
+ DrINumber(temp, 45, 185);
+ }
+ if(!inventory)
+ {
+ if(CPlayer->readyArtifact > 0)
+ {
+ V_DrawFuzzPatch(286, 170, W_CacheLumpName("ARTIBOX",
+ PU_CACHE));
+ V_DrawPatch(286, 170,
+ W_CacheLumpName(patcharti[CPlayer->readyArtifact], PU_CACHE));
+ DrSmallNumber(CPlayer->inventory[inv_ptr].count, 307, 192);
+ }
+ }
+ else
+ {
+ x = inv_ptr-curpos;
+ for(i = 0; i < 7; i++)
+ {
+ V_DrawFuzzPatch(50+i*31, 168, W_CacheLumpName("ARTIBOX",
+ PU_CACHE));
+ if(CPlayer->inventorySlotNum > x+i
+ && CPlayer->inventory[x+i].type != arti_none)
+ {
+ V_DrawPatch(50+i*31, 168, W_CacheLumpName(
+ patcharti[CPlayer->inventory[x+i].type], PU_CACHE));
+ DrSmallNumber(CPlayer->inventory[x+i].count, 69+i*31, 190);
+ }
+ }
+ V_DrawPatch(50+curpos*31, 197, PatchSELECTBOX);
+ if(x != 0)
+ {
+ V_DrawPatch(38, 167, !(leveltime&4) ? PatchINVLFGEM1 :
+ PatchINVLFGEM2);
+ }
+ if(CPlayer->inventorySlotNum-x > 7)
+ {
+ V_DrawPatch(269, 167, !(leveltime&4) ?
+ PatchINVRTGEM1 : PatchINVRTGEM2);
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+//
+// FUNC SB_Responder
+//
+//--------------------------------------------------------------------------
+
+boolean SB_Responder(event_t *event)
+{
+ if(event->type == ev_keydown)
+ {
+ if(HandleCheats(event->data1))
+ { // Need to eat the key
+ return(true);
+ }
+ }
+ return(false);
+}
+
+//--------------------------------------------------------------------------
+//
+// FUNC HandleCheats
+//
+// Returns true if the caller should eat the key.
+//
+//--------------------------------------------------------------------------
+
+static boolean HandleCheats(byte key)
+{
+ int i;
+ boolean eat;
+
+ if(netgame || gameskill == sk_nightmare)
+ { // Can't cheat in a net-game, or in nightmare mode
+ return(false);
+ }
+ if(players[consoleplayer].health <= 0)
+ { // Dead players can't cheat
+ return(false);
+ }
+ eat = false;
+ for(i = 0; Cheats[i].func != NULL; i++)
+ {
+ if(CheatAddKey(&Cheats[i], key, &eat))
+ {
+ Cheats[i].func(&players[consoleplayer], &Cheats[i]);
+ S_StartSound(NULL, sfx_dorcls);
+ }
+ }
+ return(eat);
+}
+
+//--------------------------------------------------------------------------
+//
+// FUNC CheatAddkey
+//
+// Returns true if the added key completed the cheat, false otherwise.
+//
+//--------------------------------------------------------------------------
+
+static boolean CheatAddKey(Cheat_t *cheat, byte key, boolean *eat)
+{
+ if(!cheat->pos)
+ {
+ cheat->pos = cheat->sequence;
+ cheat->currentArg = 0;
+ }
+ if(*cheat->pos == 0)
+ {
+ *eat = true;
+ cheat->args[cheat->currentArg++] = key;
+ cheat->pos++;
+ }
+ else if(CheatLookup[key] == *cheat->pos)
+ {
+ cheat->pos++;
+ }
+ else
+ {
+ cheat->pos = cheat->sequence;
+ cheat->currentArg = 0;
+ }
+ if(*cheat->pos == 0xff)
+ {
+ cheat->pos = cheat->sequence;
+ cheat->currentArg = 0;
+ return(true);
+ }
+ return(false);
+}
+
+//--------------------------------------------------------------------------
+//
+// CHEAT FUNCTIONS
+//
+//--------------------------------------------------------------------------
+
+static void CheatGodFunc(player_t *player, Cheat_t *cheat)
+{
+ player->cheats ^= CF_GODMODE;
+ if(player->cheats&CF_GODMODE)
+ {
+ P_SetMessage(player, TXT_CHEATGODON, false);
+ }
+ else
+ {
+ P_SetMessage(player, TXT_CHEATGODOFF, false);
+ }
+ SB_state = -1;
+}
+
+static void CheatNoClipFunc(player_t *player, Cheat_t *cheat)
+{
+ player->cheats ^= CF_NOCLIP;
+ if(player->cheats&CF_NOCLIP)
+ {
+ P_SetMessage(player, TXT_CHEATNOCLIPON, false);
+ }
+ else
+ {
+ P_SetMessage(player, TXT_CHEATNOCLIPOFF, false);
+ }
+}
+
+static void CheatWeaponsFunc(player_t *player, Cheat_t *cheat)
+{
+ int i;
+ //extern boolean *WeaponInShareware;
+
+ player->armorpoints = 200;
+ player->armortype = 2;
+ if(!player->backpack)
+ {
+ for(i = 0; i < NUMAMMO; i++)
+ {
+ player->maxammo[i] *= 2;
+ }
+ player->backpack = true;
+ }
+ for(i = 0; i < NUMWEAPONS-1; i++)
+ {
+ player->weaponowned[i] = true;
+ }
+ if(shareware)
+ {
+ player->weaponowned[wp_skullrod] = false;
+ player->weaponowned[wp_phoenixrod] = false;
+ player->weaponowned[wp_mace] = false;
+ }
+ for(i = 0; i < NUMAMMO; i++)
+ {
+ player->ammo[i] = player->maxammo[i];
+ }
+ P_SetMessage(player, TXT_CHEATWEAPONS, false);
+}
+
+static void CheatPowerFunc(player_t *player, Cheat_t *cheat)
+{
+ if(player->powers[pw_weaponlevel2])
+ {
+ player->powers[pw_weaponlevel2] = 0;
+ P_SetMessage(player, TXT_CHEATPOWEROFF, false);
+ }
+ else
+ {
+ P_UseArtifact(player, arti_tomeofpower);
+ P_SetMessage(player, TXT_CHEATPOWERON, false);
+ }
+}
+
+static void CheatHealthFunc(player_t *player, Cheat_t *cheat)
+{
+ if(player->chickenTics)
+ {
+ player->health = player->mo->health = MAXCHICKENHEALTH;
+ }
+ else
+ {
+ player->health = player->mo->health = MAXHEALTH;
+ }
+ P_SetMessage(player, TXT_CHEATHEALTH, false);
+}
+
+static void CheatKeysFunc(player_t *player, Cheat_t *cheat)
+{
+ extern int playerkeys;
+
+ player->keys[key_yellow] = true;
+ player->keys[key_green] = true;
+ player->keys[key_blue] = true;
+ playerkeys = 7; // Key refresh flags
+ P_SetMessage(player, TXT_CHEATKEYS, false);
+}
+
+static void CheatSoundFunc(player_t *player, Cheat_t *cheat)
+{
+ DebugSound = !DebugSound;
+ if(DebugSound)
+ {
+ P_SetMessage(player, TXT_CHEATSOUNDON, false);
+ }
+ else
+ {
+ P_SetMessage(player, TXT_CHEATSOUNDOFF, false);
+ }
+}
+
+static void CheatTickerFunc(player_t *player, Cheat_t *cheat)
+{
+ extern int DisplayTicker;
+
+ DisplayTicker = !DisplayTicker;
+ if(DisplayTicker)
+ {
+ P_SetMessage(player, TXT_CHEATTICKERON, false);
+ }
+ else
+ {
+ P_SetMessage(player, TXT_CHEATTICKEROFF, false);
+ }
+}
+
+static void CheatArtifact1Func(player_t *player, Cheat_t *cheat)
+{
+ P_SetMessage(player, TXT_CHEATARTIFACTS1, false);
+}
+
+static void CheatArtifact2Func(player_t *player, Cheat_t *cheat)
+{
+ P_SetMessage(player, TXT_CHEATARTIFACTS2, false);
+}
+
+static void CheatArtifact3Func(player_t *player, Cheat_t *cheat)
+{
+ int i;
+ int j;
+ artitype_t type;
+ int count;
+
+ type = cheat->args[0]-'a'+1;
+ count = cheat->args[1]-'0';
+ if(type == 26 && count == 0)
+ { // All artifacts
+ for(i = arti_none+1; i < NUMARTIFACTS; i++)
+ {
+ if(shareware && (i == arti_superhealth
+ || i == arti_teleport))
+ {
+ continue;
+ }
+ for(j = 0; j < 16; j++)
+ {
+ P_GiveArtifact(player, i, NULL);
+ }
+ }
+ P_SetMessage(player, TXT_CHEATARTIFACTS3, false);
+ }
+ else if(type > arti_none && type < NUMARTIFACTS
+ && count > 0 && count < 10)
+ {
+ if(shareware && (type == arti_superhealth || type == arti_teleport))
+ {
+ P_SetMessage(player, TXT_CHEATARTIFACTSFAIL, false);
+ return;
+ }
+ for(i = 0; i < count; i++)
+ {
+ P_GiveArtifact(player, type, NULL);
+ }
+ P_SetMessage(player, TXT_CHEATARTIFACTS3, false);
+ }
+ else
+ { // Bad input
+ P_SetMessage(player, TXT_CHEATARTIFACTSFAIL, false);
+ }
+}
+
+static void CheatWarpFunc(player_t *player, Cheat_t *cheat)
+{
+ int episode;
+ int map;
+
+ episode = cheat->args[0]-'0';
+ map = cheat->args[1]-'0';
+ if(M_ValidEpisodeMap(episode, map))
+ {
+ G_DeferedInitNew(gameskill, episode, map);
+ P_SetMessage(player, TXT_CHEATWARP, false);
+ }
+}
+
+static void CheatChickenFunc(player_t *player, Cheat_t *cheat)
+{
+ extern boolean P_UndoPlayerChicken(player_t *player);
+
+ if(player->chickenTics)
+ {
+ if(P_UndoPlayerChicken(player))
+ {
+ P_SetMessage(player, TXT_CHEATCHICKENOFF, false);
+ }
+ }
+ else if(P_ChickenMorphPlayer(player))
+ {
+ P_SetMessage(player, TXT_CHEATCHICKENON, false);
+ }
+}
+
+static void CheatMassacreFunc(player_t *player, Cheat_t *cheat)
+{
+ P_Massacre();
+ P_SetMessage(player, TXT_CHEATMASSACRE, false);
+}
+
+static void CheatIDKFAFunc(player_t *player, Cheat_t *cheat)
+{
+ int i;
+ if(player->chickenTics)
+ {
+ return;
+ }
+ for(i = 1; i < 8; i++)
+ {
+ player->weaponowned[i] = false;
+ }
+ player->pendingweapon = wp_staff;
+ P_SetMessage(player, TXT_CHEATIDKFA, true);
+}
+
+static void CheatIDDQDFunc(player_t *player, Cheat_t *cheat)
+{
+ P_DamageMobj(player->mo, NULL, player->mo, 10000);
+ P_SetMessage(player, TXT_CHEATIDDQD, true);
+}