Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // Emacs style mode select   -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //      Status bar code.
  21. //      Does the face/direction indicator animatin.
  22. //      Does palette indicators as well (red pain/berserk, bright pickup)
  23. //
  24. //-----------------------------------------------------------------------------
  25.  
  26. static const char
  27. rcsid[] = "$Id: st_stuff.c,v 1.6 1997/02/03 22:45:13 b1 Exp $";
  28.  
  29.  
  30. #include <stdio.h>
  31.  
  32. #include "i_system.h"
  33. #include "i_video.h"
  34. #include "z_zone.h"
  35. #include "m_random.h"
  36. #include "w_wad.h"
  37.  
  38. #include "doomdef.h"
  39.  
  40. #include "g_game.h"
  41.  
  42. #include "st_stuff.h"
  43. #include "st_lib.h"
  44. #include "r_local.h"
  45.  
  46. #include "p_local.h"
  47. #include "p_inter.h"
  48.  
  49. #include "am_map.h"
  50. #include "m_cheat.h"
  51.  
  52. #include "s_sound.h"
  53.  
  54. // Needs access to LFB.
  55. #include "v_video.h"
  56.  
  57. // State.
  58. #include "doomstat.h"
  59.  
  60. // Data.
  61. #include "dstrings.h"
  62. #include "sounds.h"
  63.  
  64. //
  65. // STATUS BAR DATA
  66. //
  67.  
  68.  
  69. // Palette indices.
  70. // For damage/bonus red-/gold-shifts
  71. #define STARTREDPALS            1
  72. #define STARTBONUSPALS          9
  73. #define NUMREDPALS                      8
  74. #define NUMBONUSPALS            4
  75. // Radiation suit, green shift.
  76. #define RADIATIONPAL            13
  77.  
  78. // N/256*100% probability
  79. //  that the normal face state will change
  80. #define ST_FACEPROBABILITY              96
  81.  
  82. // For Responder
  83. #define ST_TOGGLECHAT           KEY_ENTER
  84.  
  85. // Location of status bar
  86. #define ST_X                            0
  87. #define ST_X2                           104
  88.  
  89. #define ST_FX                   143
  90. #define ST_FY                   169
  91.  
  92. // Should be set to patch width
  93. //  for tall numbers later on
  94. #define ST_TALLNUMWIDTH         (tallnum[0]->width)
  95.  
  96. // Number of status faces.
  97. #define ST_NUMPAINFACES         5
  98. #define ST_NUMSTRAIGHTFACES     3
  99. #define ST_NUMTURNFACES         2
  100. #define ST_NUMSPECIALFACES              3
  101.  
  102. #define ST_FACESTRIDE \
  103.           (ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES)
  104.  
  105. #define ST_NUMEXTRAFACES                2
  106.  
  107. #define ST_NUMFACES \
  108.           (ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES)
  109.  
  110. #define ST_TURNOFFSET           (ST_NUMSTRAIGHTFACES)
  111. #define ST_OUCHOFFSET           (ST_TURNOFFSET + ST_NUMTURNFACES)
  112. #define ST_EVILGRINOFFSET               (ST_OUCHOFFSET + 1)
  113. #define ST_RAMPAGEOFFSET                (ST_EVILGRINOFFSET + 1)
  114. #define ST_GODFACE                      (ST_NUMPAINFACES*ST_FACESTRIDE)
  115. #define ST_DEADFACE                     (ST_GODFACE+1)
  116.  
  117. #define ST_FACESX                       143
  118. #define ST_FACESY                       168
  119.  
  120. #define ST_EVILGRINCOUNT                (2*TICRATE)
  121. #define ST_STRAIGHTFACECOUNT    (TICRATE/2)
  122. #define ST_TURNCOUNT            (1*TICRATE)
  123. #define ST_OUCHCOUNT            (1*TICRATE)
  124. #define ST_RAMPAGEDELAY         (2*TICRATE)
  125.  
  126. #define ST_MUCHPAIN                     20
  127.  
  128.  
  129. // Location and size of statistics,
  130. //  justified according to widget type.
  131. // Problem is, within which space? STbar? Screen?
  132. // Note: this could be read in by a lump.
  133. //       Problem is, is the stuff rendered
  134. //       into a buffer,
  135. //       or into the frame buffer?
  136.  
  137. // AMMO number pos.
  138. #define ST_AMMOWIDTH            3      
  139. #define ST_AMMOX                        44
  140. #define ST_AMMOY                        171
  141.  
  142. // HEALTH number pos.
  143. #define ST_HEALTHWIDTH          3      
  144. #define ST_HEALTHX                      90
  145. #define ST_HEALTHY                      171
  146.  
  147. // Weapon pos.
  148. #define ST_ARMSX                        111
  149. #define ST_ARMSY                        172
  150. #define ST_ARMSBGX                      104
  151. #define ST_ARMSBGY                      168
  152. #define ST_ARMSXSPACE           12
  153. #define ST_ARMSYSPACE           10
  154.  
  155. // Frags pos.
  156. #define ST_FRAGSX                       138
  157. #define ST_FRAGSY                       171    
  158. #define ST_FRAGSWIDTH           2
  159.  
  160. // ARMOR number pos.
  161. #define ST_ARMORWIDTH           3
  162. #define ST_ARMORX                       221
  163. #define ST_ARMORY                       171
  164.  
  165. // Key icon positions.
  166. #define ST_KEY0WIDTH            8
  167. #define ST_KEY0HEIGHT           5
  168. #define ST_KEY0X                        239
  169. #define ST_KEY0Y                        171
  170. #define ST_KEY1WIDTH            ST_KEY0WIDTH
  171. #define ST_KEY1X                        239
  172. #define ST_KEY1Y                        181
  173. #define ST_KEY2WIDTH            ST_KEY0WIDTH
  174. #define ST_KEY2X                        239
  175. #define ST_KEY2Y                        191
  176.  
  177. // Ammunition counter.
  178. #define ST_AMMO0WIDTH           3
  179. #define ST_AMMO0HEIGHT          6
  180. #define ST_AMMO0X                       288
  181. #define ST_AMMO0Y                       173
  182. #define ST_AMMO1WIDTH           ST_AMMO0WIDTH
  183. #define ST_AMMO1X                       288
  184. #define ST_AMMO1Y                       179
  185. #define ST_AMMO2WIDTH           ST_AMMO0WIDTH
  186. #define ST_AMMO2X                       288
  187. #define ST_AMMO2Y                       191
  188. #define ST_AMMO3WIDTH           ST_AMMO0WIDTH
  189. #define ST_AMMO3X                       288
  190. #define ST_AMMO3Y                       185
  191.  
  192. // Indicate maximum ammunition.
  193. // Only needed because backpack exists.
  194. #define ST_MAXAMMO0WIDTH                3
  195. #define ST_MAXAMMO0HEIGHT               5
  196. #define ST_MAXAMMO0X            314
  197. #define ST_MAXAMMO0Y            173
  198. #define ST_MAXAMMO1WIDTH                ST_MAXAMMO0WIDTH
  199. #define ST_MAXAMMO1X            314
  200. #define ST_MAXAMMO1Y            179
  201. #define ST_MAXAMMO2WIDTH                ST_MAXAMMO0WIDTH
  202. #define ST_MAXAMMO2X            314
  203. #define ST_MAXAMMO2Y            191
  204. #define ST_MAXAMMO3WIDTH                ST_MAXAMMO0WIDTH
  205. #define ST_MAXAMMO3X            314
  206. #define ST_MAXAMMO3Y            185
  207.  
  208. // pistol
  209. #define ST_WEAPON0X                     110
  210. #define ST_WEAPON0Y                     172
  211.  
  212. // shotgun
  213. #define ST_WEAPON1X                     122
  214. #define ST_WEAPON1Y                     172
  215.  
  216. // chain gun
  217. #define ST_WEAPON2X                     134
  218. #define ST_WEAPON2Y                     172
  219.  
  220. // missile launcher
  221. #define ST_WEAPON3X                     110
  222. #define ST_WEAPON3Y                     181
  223.  
  224. // plasma gun
  225. #define ST_WEAPON4X                     122
  226. #define ST_WEAPON4Y                     181
  227.  
  228.  // bfg
  229. #define ST_WEAPON5X                     134
  230. #define ST_WEAPON5Y                     181
  231.  
  232. // WPNS title
  233. #define ST_WPNSX                        109
  234. #define ST_WPNSY                        191
  235.  
  236.  // DETH title
  237. #define ST_DETHX                        109
  238. #define ST_DETHY                        191
  239.  
  240. //Incoming messages window location
  241. //UNUSED
  242. // #define ST_MSGTEXTX     (viewwindowx)
  243. // #define ST_MSGTEXTY     (viewwindowy+viewheight-18)
  244. #define ST_MSGTEXTX                     0
  245. #define ST_MSGTEXTY                     0
  246. // Dimensions given in characters.
  247. #define ST_MSGWIDTH                     52
  248. // Or shall I say, in lines?
  249. #define ST_MSGHEIGHT            1
  250.  
  251. #define ST_OUTTEXTX                     0
  252. #define ST_OUTTEXTY                     6
  253.  
  254. // Width, in characters again.
  255. #define ST_OUTWIDTH                     52
  256.  // Height, in lines.
  257. #define ST_OUTHEIGHT            1
  258.  
  259. #define ST_MAPWIDTH     \
  260.     (strlen(mapnames[(gameepisode-1)*9+(gamemap-1)]))
  261.  
  262. #define ST_MAPTITLEX \
  263.     (SCREENWIDTH - ST_MAPWIDTH * ST_CHATFONTWIDTH)
  264.  
  265. #define ST_MAPTITLEY            0
  266. #define ST_MAPHEIGHT            1
  267.  
  268.            
  269. // main player in game
  270. static player_t*        plyr;
  271.  
  272. // ST_Start() has just been called
  273. static boolean          st_firsttime;
  274.  
  275. // used to execute ST_Init() only once
  276. static int              veryfirsttime = 1;
  277.  
  278. // lump number for PLAYPAL
  279. static int              lu_palette;
  280.  
  281. // used for timing
  282. static unsigned int     st_clock;
  283.  
  284. // used for making messages go away
  285. static int              st_msgcounter=0;
  286.  
  287. // used when in chat
  288. static st_chatstateenum_t       st_chatstate;
  289.  
  290. // whether in automap or first-person
  291. static st_stateenum_t   st_gamestate;
  292.  
  293. // whether left-side main status bar is active
  294. static boolean          st_statusbaron;
  295.  
  296. // whether status bar chat is active
  297. static boolean          st_chat;
  298.  
  299. // value of st_chat before message popped up
  300. static boolean          st_oldchat;
  301.  
  302. // whether chat window has the cursor on
  303. static boolean          st_cursoron;
  304.  
  305. // !deathmatch
  306. static boolean          st_notdeathmatch;
  307.  
  308. // !deathmatch && st_statusbaron
  309. static boolean          st_armson;
  310.  
  311. // !deathmatch
  312. static boolean          st_fragson;
  313.  
  314. // main bar left
  315. static patch_t*         sbar;
  316.  
  317. // 0-9, tall numbers
  318. static patch_t*         tallnum[10];
  319.  
  320. // tall % sign
  321. static patch_t*         tallpercent;
  322.  
  323. // 0-9, short, yellow (,different!) numbers
  324. static patch_t*         shortnum[10];
  325.  
  326. // 3 key-cards, 3 skulls
  327. static patch_t*         keys[NUMCARDS];
  328.  
  329. // face status patches
  330. static patch_t*         faces[ST_NUMFACES];
  331.  
  332. // face background
  333. static patch_t*         faceback;
  334.  
  335.  // main bar right
  336. static patch_t*         armsbg;
  337.  
  338. // weapon ownership patches
  339. static patch_t*         arms[6][2];
  340.  
  341. // ready-weapon widget
  342. static st_number_t      w_ready;
  343.  
  344.  // in deathmatch only, summary of frags stats
  345. static st_number_t      w_frags;
  346.  
  347. // health widget
  348. static st_percent_t     w_health;
  349.  
  350. // arms background
  351. static st_binicon_t     w_armsbg;
  352.  
  353.  
  354. // weapon ownership widgets
  355. static st_multicon_t    w_arms[6];
  356.  
  357. // face status widget
  358. static st_multicon_t    w_faces;
  359.  
  360. // keycard widgets
  361. static st_multicon_t    w_keyboxes[3];
  362.  
  363. // armor widget
  364. static st_percent_t     w_armor;
  365.  
  366. // ammo widgets
  367. static st_number_t      w_ammo[4];
  368.  
  369. // max ammo widgets
  370. static st_number_t      w_maxammo[4];
  371.  
  372.  
  373.  
  374.  // number of frags so far in deathmatch
  375. static int      st_fragscount;
  376.  
  377. // used to use appopriately pained face
  378. static int      st_oldhealth = -1;
  379.  
  380. // used for evil grin
  381. static boolean  oldweaponsowned[NUMWEAPONS];
  382.  
  383.  // count until face changes
  384. static int      st_facecount = 0;
  385.  
  386. // current face index, used by w_faces
  387. static int      st_faceindex = 0;
  388.  
  389. // holds key-type for each key box on bar
  390. static int      keyboxes[3];
  391.  
  392. // a random number per tick
  393. static int      st_randomnumber;  
  394.  
  395.  
  396.  
  397. // Massive bunches of cheat shit
  398. //  to keep it from being easy to figure them out.
  399. // Yeah, right...
  400. unsigned char   cheat_mus_seq[] =
  401. {
  402.     0xb2, 0x26, 0xb6, 0xae, 0xea, 1, 0, 0, 0xff
  403. };
  404.  
  405. unsigned char   cheat_choppers_seq[] =
  406. {
  407.     0xb2, 0x26, 0xe2, 0x32, 0xf6, 0x2a, 0x2a, 0xa6, 0x6a, 0xea, 0xff // id...
  408. };
  409.  
  410. unsigned char   cheat_god_seq[] =
  411. {
  412.     0xb2, 0x26, 0x26, 0xaa, 0x26, 0xff  // iddqd
  413. };
  414.  
  415. unsigned char   cheat_ammo_seq[] =
  416. {
  417.     0xb2, 0x26, 0xf2, 0x66, 0xa2, 0xff  // idkfa
  418. };
  419.  
  420. unsigned char   cheat_ammonokey_seq[] =
  421. {
  422.     0xb2, 0x26, 0x66, 0xa2, 0xff        // idfa
  423. };
  424.  
  425.  
  426. // Smashing Pumpkins Into Samml Piles Of Putried Debris.
  427. unsigned char   cheat_noclip_seq[] =
  428. {
  429.     0xb2, 0x26, 0xea, 0x2a, 0xb2,       // idspispopd
  430.     0xea, 0x2a, 0xf6, 0x2a, 0x26, 0xff
  431. };
  432.  
  433. //
  434. unsigned char   cheat_commercial_noclip_seq[] =
  435. {
  436.     0xb2, 0x26, 0xe2, 0x36, 0xb2, 0x2a, 0xff    // idclip
  437. };
  438.  
  439.  
  440.  
  441. unsigned char   cheat_powerup_seq[7][10] =
  442. {
  443.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0x6e, 0xff },     // beholdv
  444.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0xea, 0xff },     // beholds
  445.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0xb2, 0xff },     // beholdi
  446.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0x6a, 0xff },     // beholdr
  447.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0xa2, 0xff },     // beholda
  448.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0x36, 0xff },     // beholdl
  449.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0xff }            // behold
  450. };
  451.  
  452.  
  453. unsigned char   cheat_clev_seq[] =
  454. {
  455.     0xb2, 0x26,  0xe2, 0x36, 0xa6, 0x6e, 1, 0, 0, 0xff  // idclev
  456. };
  457.  
  458.  
  459. // my position cheat
  460. unsigned char   cheat_mypos_seq[] =
  461. {
  462.     0xb2, 0x26, 0xb6, 0xba, 0x2a, 0xf6, 0xea, 0xff      // idmypos
  463. };
  464.  
  465.  
  466. // Now what?
  467. cheatseq_t      cheat_mus = { cheat_mus_seq, 0 };
  468. cheatseq_t      cheat_god = { cheat_god_seq, 0 };
  469. cheatseq_t      cheat_ammo = { cheat_ammo_seq, 0 };
  470. cheatseq_t      cheat_ammonokey = { cheat_ammonokey_seq, 0 };
  471. cheatseq_t      cheat_noclip = { cheat_noclip_seq, 0 };
  472. cheatseq_t      cheat_commercial_noclip = { cheat_commercial_noclip_seq, 0 };
  473.  
  474. cheatseq_t      cheat_powerup[7] =
  475. {
  476.     { cheat_powerup_seq[0], 0 },
  477.     { cheat_powerup_seq[1], 0 },
  478.     { cheat_powerup_seq[2], 0 },
  479.     { cheat_powerup_seq[3], 0 },
  480.     { cheat_powerup_seq[4], 0 },
  481.     { cheat_powerup_seq[5], 0 },
  482.     { cheat_powerup_seq[6], 0 }
  483. };
  484.  
  485. cheatseq_t      cheat_choppers = { cheat_choppers_seq, 0 };
  486. cheatseq_t      cheat_clev = { cheat_clev_seq, 0 };
  487. cheatseq_t      cheat_mypos = { cheat_mypos_seq, 0 };
  488.  
  489.  
  490. //
  491. extern char*    mapnames[];
  492.  
  493.  
  494. //
  495. // STATUS BAR CODE
  496. //
  497. void ST_Stop(void);
  498.  
  499. void ST_refreshBackground(void)
  500. {
  501.  
  502.     if (st_statusbaron)
  503.     {
  504.         V_DrawPatch(ST_X, 0, BG, sbar);
  505.  
  506.         if (netgame)
  507.             V_DrawPatch(ST_FX, 0, BG, faceback);
  508.  
  509.         V_CopyRect(ST_X, 0, BG, ST_WIDTH, ST_HEIGHT, ST_X, ST_Y, FG);
  510.     }
  511.  
  512. }
  513.  
  514.  
  515. // Respond to keyboard input events,
  516. //  intercept cheats.
  517. boolean
  518. ST_Responder (event_t* ev)
  519. {
  520.   int           i;
  521.    
  522.   // Filter automap on/off.
  523.   if (ev->type == ev_keyup
  524.       && ((ev->data1 & 0xffff0000) == AM_MSGHEADER))
  525.   {
  526.     switch(ev->data1)
  527.     {
  528.       case AM_MSGENTERED:
  529.         st_gamestate = AutomapState;
  530.         st_firsttime = true;
  531.         break;
  532.        
  533.       case AM_MSGEXITED:
  534.         //      fprintf(stderr, "AM exited\n");
  535.         st_gamestate = FirstPersonState;
  536.         break;
  537.     }
  538.   }
  539.  
  540.   // if a user keypress...
  541.   else if (ev->type == ev_keydown)
  542.   {
  543.     if (!netgame)
  544.     {
  545.       // b. - enabled for more debug fun.
  546.       // if (gameskill != sk_nightmare) {
  547.      
  548.       // 'dqd' cheat for toggleable god mode
  549.       if (cht_CheckCheat(&cheat_god, ev->data1))
  550.       {
  551.         plyr->cheats ^= CF_GODMODE;
  552.         if (plyr->cheats & CF_GODMODE)
  553.         {
  554.           if (plyr->mo)
  555.             plyr->mo->health = 100;
  556.          
  557.           plyr->health = 100;
  558.           plyr->message = STSTR_DQDON;
  559.         }
  560.         else
  561.           plyr->message = STSTR_DQDOFF;
  562.       }
  563.       // 'fa' cheat for killer fucking arsenal
  564.       else if (cht_CheckCheat(&cheat_ammonokey, ev->data1))
  565.       {
  566.         plyr->armorpoints = 200;
  567.         plyr->armortype = 2;
  568.        
  569.         for (i=0;i<NUMWEAPONS;i++)
  570.           plyr->weaponowned[i] = true;
  571.        
  572.         for (i=0;i<NUMAMMO;i++)
  573.           plyr->ammo[i] = plyr->maxammo[i];
  574.        
  575.         plyr->message = STSTR_FAADDED;
  576.       }
  577.       // 'kfa' cheat for key full ammo
  578.       else if (cht_CheckCheat(&cheat_ammo, ev->data1))
  579.       {
  580.         plyr->armorpoints = 200;
  581.         plyr->armortype = 2;
  582.        
  583.         for (i=0;i<NUMWEAPONS;i++)
  584.           plyr->weaponowned[i] = true;
  585.        
  586.         for (i=0;i<NUMAMMO;i++)
  587.           plyr->ammo[i] = plyr->maxammo[i];
  588.        
  589.         for (i=0;i<NUMCARDS;i++)
  590.           plyr->cards[i] = true;
  591.        
  592.         plyr->message = STSTR_KFAADDED;
  593.       }
  594.       // 'mus' cheat for changing music
  595.       else if (cht_CheckCheat(&cheat_mus, ev->data1))
  596.       {
  597.        
  598.         char    buf[3];
  599.         int             musnum;
  600.        
  601.         plyr->message = STSTR_MUS;
  602.         cht_GetParam(&cheat_mus, buf);
  603.        
  604.         if (gamemode == commercial)
  605.         {
  606.           musnum = mus_runnin + (buf[0]-'0')*10 + buf[1]-'0' - 1;
  607.          
  608.           if (((buf[0]-'0')*10 + buf[1]-'0') > 35)
  609.             plyr->message = STSTR_NOMUS;
  610.           else
  611.             S_ChangeMusic(musnum, 1);
  612.         }
  613.         else
  614.         {
  615.           musnum = mus_e1m1 + (buf[0]-'1')*9 + (buf[1]-'1');
  616.          
  617.           if (((buf[0]-'1')*9 + buf[1]-'1') > 31)
  618.             plyr->message = STSTR_NOMUS;
  619.           else
  620.             S_ChangeMusic(musnum, 1);
  621.         }
  622.       }
  623.       // Simplified, accepting both "noclip" and "idspispopd".
  624.       // no clipping mode cheat
  625.       else if ( cht_CheckCheat(&cheat_noclip, ev->data1)
  626.                 || cht_CheckCheat(&cheat_commercial_noclip,ev->data1) )
  627.       {
  628.         plyr->cheats ^= CF_NOCLIP;
  629.        
  630.         if (plyr->cheats & CF_NOCLIP)
  631.           plyr->message = STSTR_NCON;
  632.         else
  633.           plyr->message = STSTR_NCOFF;
  634.       }
  635.       // 'behold?' power-up cheats
  636.       for (i=0;i<6;i++)
  637.       {
  638.         if (cht_CheckCheat(&cheat_powerup[i], ev->data1))
  639.         {
  640.           if (!plyr->powers[i])
  641.             P_GivePower( plyr, i);
  642.           else if (i!=pw_strength)
  643.             plyr->powers[i] = 1;
  644.           else
  645.             plyr->powers[i] = 0;
  646.          
  647.           plyr->message = STSTR_BEHOLDX;
  648.         }
  649.       }
  650.      
  651.       // 'behold' power-up menu
  652.       if (cht_CheckCheat(&cheat_powerup[6], ev->data1))
  653.       {
  654.         plyr->message = STSTR_BEHOLD;
  655.       }
  656.       // 'choppers' invulnerability & chainsaw
  657.       else if (cht_CheckCheat(&cheat_choppers, ev->data1))
  658.       {
  659.         plyr->weaponowned[wp_chainsaw] = true;
  660.         plyr->powers[pw_invulnerability] = true;
  661.         plyr->message = STSTR_CHOPPERS;
  662.       }
  663.       // 'mypos' for player position
  664.       else if (cht_CheckCheat(&cheat_mypos, ev->data1))
  665.       {
  666.         static char     buf[ST_MSGWIDTH];
  667.         sprintf(buf, "ang=0x%x;x,y=(0x%x,0x%x)",
  668.                 players[consoleplayer].mo->angle,
  669.                 players[consoleplayer].mo->x,
  670.                 players[consoleplayer].mo->y);
  671.         plyr->message = buf;
  672.       }
  673.     }
  674.    
  675.     // 'clev' change-level cheat
  676.     if (cht_CheckCheat(&cheat_clev, ev->data1))
  677.     {
  678.       char              buf[3];
  679.       int               epsd;
  680.       int               map;
  681.      
  682.       cht_GetParam(&cheat_clev, buf);
  683.      
  684.       if (gamemode == commercial)
  685.       {
  686.         epsd = 0;
  687.         map = (buf[0] - '0')*10 + buf[1] - '0';
  688.       }
  689.       else
  690.       {
  691.         epsd = buf[0] - '0';
  692.         map = buf[1] - '0';
  693.       }
  694.  
  695.       // Catch invalid maps.
  696.       if (epsd < 1)
  697.         return false;
  698.  
  699.       if (map < 1)
  700.         return false;
  701.      
  702.       // Ohmygod - this is not going to work.
  703.       if ((gamemode == retail)
  704.           && ((epsd > 4) || (map > 9)))
  705.         return false;
  706.  
  707.       if ((gamemode == registered)
  708.           && ((epsd > 3) || (map > 9)))
  709.         return false;
  710.  
  711.       if ((gamemode == shareware)
  712.           && ((epsd > 1) || (map > 9)))
  713.         return false;
  714.  
  715.       if ((gamemode == commercial)
  716.         && (( epsd > 1) || (map > 34)))
  717.         return false;
  718.  
  719.       // So be it.
  720.       plyr->message = STSTR_CLEV;
  721.       G_DeferedInitNew(gameskill, epsd, map);
  722.     }    
  723.   }
  724.   return false;
  725. }
  726.  
  727.  
  728.  
  729. int ST_calcPainOffset(void)
  730. {
  731.     int         health;
  732.     static int  lastcalc;
  733.     static int  oldhealth = -1;
  734.    
  735.     health = plyr->health > 100 ? 100 : plyr->health;
  736.  
  737.     if (health != oldhealth)
  738.     {
  739.         lastcalc = ST_FACESTRIDE * (((100 - health) * ST_NUMPAINFACES) / 101);
  740.         oldhealth = health;
  741.     }
  742.     return lastcalc;
  743. }
  744.  
  745.  
  746. //
  747. // This is a not-very-pretty routine which handles
  748. //  the face states and their timing.
  749. // the precedence of expressions is:
  750. //  dead > evil grin > turned head > straight ahead
  751. //
  752. void ST_updateFaceWidget(void)
  753. {
  754.     int         i;
  755.     angle_t     badguyangle;
  756.     angle_t     diffang;
  757.     static int  lastattackdown = -1;
  758.     static int  priority = 0;
  759.     boolean     doevilgrin;
  760.  
  761.     if (priority < 10)
  762.     {
  763.         // dead
  764.         if (!plyr->health)
  765.         {
  766.             priority = 9;
  767.             st_faceindex = ST_DEADFACE;
  768.             st_facecount = 1;
  769.         }
  770.     }
  771.  
  772.     if (priority < 9)
  773.     {
  774.         if (plyr->bonuscount)
  775.         {
  776.             // picking up bonus
  777.             doevilgrin = false;
  778.  
  779.             for (i=0;i<NUMWEAPONS;i++)
  780.             {
  781.                 if (oldweaponsowned[i] != plyr->weaponowned[i])
  782.                 {
  783.                     doevilgrin = true;
  784.                     oldweaponsowned[i] = plyr->weaponowned[i];
  785.                 }
  786.             }
  787.             if (doevilgrin)
  788.             {
  789.                 // evil grin if just picked up weapon
  790.                 priority = 8;
  791.                 st_facecount = ST_EVILGRINCOUNT;
  792.                 st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET;
  793.             }
  794.         }
  795.  
  796.     }
  797.  
  798.     if (priority < 8)
  799.     {
  800.         if (plyr->damagecount
  801.             && plyr->attacker
  802.             && plyr->attacker != plyr->mo)
  803.         {
  804.             // being attacked
  805.             priority = 7;
  806.            
  807.             if (plyr->health - st_oldhealth > ST_MUCHPAIN)
  808.             {
  809.                 st_facecount = ST_TURNCOUNT;
  810.                 st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
  811.             }
  812.             else
  813.             {
  814.                 badguyangle = R_PointToAngle2(plyr->mo->x,
  815.                                               plyr->mo->y,
  816.                                               plyr->attacker->x,
  817.                                               plyr->attacker->y);
  818.                
  819.                 if (badguyangle > plyr->mo->angle)
  820.                 {
  821.                     // whether right or left
  822.                     diffang = badguyangle - plyr->mo->angle;
  823.                     i = diffang > ANG180;
  824.                 }
  825.                 else
  826.                 {
  827.                     // whether left or right
  828.                     diffang = plyr->mo->angle - badguyangle;
  829.                     i = diffang <= ANG180;
  830.                 } // confusing, aint it?
  831.  
  832.                
  833.                 st_facecount = ST_TURNCOUNT;
  834.                 st_faceindex = ST_calcPainOffset();
  835.                
  836.                 if (diffang < ANG45)
  837.                 {
  838.                     // head-on    
  839.                     st_faceindex += ST_RAMPAGEOFFSET;
  840.                 }
  841.                 else if (i)
  842.                 {
  843.                     // turn face right
  844.                     st_faceindex += ST_TURNOFFSET;
  845.                 }
  846.                 else
  847.                 {
  848.                     // turn face left
  849.                     st_faceindex += ST_TURNOFFSET+1;
  850.                 }
  851.             }
  852.         }
  853.     }
  854.  
  855.     if (priority < 7)
  856.     {
  857.         // getting hurt because of your own damn stupidity
  858.         if (plyr->damagecount)
  859.         {
  860.             if (plyr->health - st_oldhealth > ST_MUCHPAIN)
  861.             {
  862.                 priority = 7;
  863.                 st_facecount = ST_TURNCOUNT;
  864.                 st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
  865.             }
  866.             else
  867.             {
  868.                 priority = 6;
  869.                 st_facecount = ST_TURNCOUNT;
  870.                 st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
  871.             }
  872.  
  873.         }
  874.  
  875.     }
  876.  
  877.     if (priority < 6)
  878.     {
  879.         // rapid firing
  880.         if (plyr->attackdown)
  881.         {
  882.             if (lastattackdown==-1)
  883.                 lastattackdown = ST_RAMPAGEDELAY;
  884.             else if (!--lastattackdown)
  885.             {
  886.                 priority = 5;
  887.                 st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
  888.                 st_facecount = 1;
  889.                 lastattackdown = 1;
  890.             }
  891.         }
  892.         else
  893.             lastattackdown = -1;
  894.  
  895.     }
  896.  
  897.     if (priority < 5)
  898.     {
  899.         // invulnerability
  900.         if ((plyr->cheats & CF_GODMODE)
  901.             || plyr->powers[pw_invulnerability])
  902.         {
  903.             priority = 4;
  904.  
  905.             st_faceindex = ST_GODFACE;
  906.             st_facecount = 1;
  907.  
  908.         }
  909.  
  910.     }
  911.  
  912.     // look left or look right if the facecount has timed out
  913.     if (!st_facecount)
  914.     {
  915.         st_faceindex = ST_calcPainOffset() + (st_randomnumber % 3);
  916.         st_facecount = ST_STRAIGHTFACECOUNT;
  917.         priority = 0;
  918.     }
  919.  
  920.     st_facecount--;
  921.  
  922. }
  923.  
  924. void ST_updateWidgets(void)
  925. {
  926.     static int  largeammo = 1994; // means "n/a"
  927.     int         i;
  928.  
  929.     // must redirect the pointer if the ready weapon has changed.
  930.     //  if (w_ready.data != plyr->readyweapon)
  931.     //  {
  932.     if (weaponinfo[plyr->readyweapon].ammo == am_noammo)
  933.         w_ready.num = &largeammo;
  934.     else
  935.         w_ready.num = &plyr->ammo[weaponinfo[plyr->readyweapon].ammo];
  936.     //{
  937.     // static int tic=0;
  938.     // static int dir=-1;
  939.     // if (!(tic&15))
  940.     //   plyr->ammo[weaponinfo[plyr->readyweapon].ammo]+=dir;
  941.     // if (plyr->ammo[weaponinfo[plyr->readyweapon].ammo] == -100)
  942.     //   dir = 1;
  943.     // tic++;
  944.     // }
  945.     w_ready.data = plyr->readyweapon;
  946.  
  947.     // if (*w_ready.on)
  948.     //  STlib_updateNum(&w_ready, true);
  949.     // refresh weapon change
  950.     //  }
  951.  
  952.     // update keycard multiple widgets
  953.     for (i=0;i<3;i++)
  954.     {
  955.         keyboxes[i] = plyr->cards[i] ? i : -1;
  956.  
  957.         if (plyr->cards[i+3])
  958.             keyboxes[i] = i+3;
  959.     }
  960.  
  961.     // refresh everything if this is him coming back to life
  962.     ST_updateFaceWidget();
  963.  
  964.     // used by the w_armsbg widget
  965.     st_notdeathmatch = !deathmatch;
  966.    
  967.     // used by w_arms[] widgets
  968.     st_armson = st_statusbaron && !deathmatch;
  969.  
  970.     // used by w_frags widget
  971.     st_fragson = deathmatch && st_statusbaron;
  972.     st_fragscount = 0;
  973.  
  974.     for (i=0 ; i<MAXPLAYERS ; i++)
  975.     {
  976.         if (i != consoleplayer)
  977.             st_fragscount += plyr->frags[i];
  978.         else
  979.             st_fragscount -= plyr->frags[i];
  980.     }
  981.  
  982.     // get rid of chat window if up because of message
  983.     if (!--st_msgcounter)
  984.         st_chat = st_oldchat;
  985.  
  986. }
  987.  
  988. void ST_Ticker (void)
  989. {
  990.  
  991.     st_clock++;
  992.     st_randomnumber = M_Random();
  993.     ST_updateWidgets();
  994.     st_oldhealth = plyr->health;
  995.  
  996. }
  997.  
  998. static int st_palette = 0;
  999.  
  1000. void ST_doPaletteStuff(void)
  1001. {
  1002.  
  1003.     int         palette;
  1004.     byte*       pal;
  1005.     int         cnt;
  1006.     int         bzc;
  1007.  
  1008.     cnt = plyr->damagecount;
  1009.  
  1010.     if (plyr->powers[pw_strength])
  1011.     {
  1012.         // slowly fade the berzerk out
  1013.         bzc = 12 - (plyr->powers[pw_strength]>>6);
  1014.  
  1015.         if (bzc > cnt)
  1016.             cnt = bzc;
  1017.     }
  1018.        
  1019.     if (cnt)
  1020.     {
  1021.         palette = (cnt+7)>>3;
  1022.        
  1023.         if (palette >= NUMREDPALS)
  1024.             palette = NUMREDPALS-1;
  1025.  
  1026.         palette += STARTREDPALS;
  1027.     }
  1028.  
  1029.     else if (plyr->bonuscount)
  1030.     {
  1031.         palette = (plyr->bonuscount+7)>>3;
  1032.  
  1033.         if (palette >= NUMBONUSPALS)
  1034.             palette = NUMBONUSPALS-1;
  1035.  
  1036.         palette += STARTBONUSPALS;
  1037.     }
  1038.  
  1039.     else if ( plyr->powers[pw_ironfeet] > 4*32
  1040.               || plyr->powers[pw_ironfeet]&8)
  1041.         palette = RADIATIONPAL;
  1042.     else
  1043.         palette = 0;
  1044.  
  1045.     if (palette != st_palette)
  1046.     {
  1047.         st_palette = palette;
  1048.         pal = (byte *) W_CacheLumpNum (lu_palette, PU_CACHE)+palette*768;
  1049.         I_SetPalette (pal);
  1050.     }
  1051.  
  1052. }
  1053.  
  1054. void ST_drawWidgets(boolean refresh)
  1055. {
  1056.     int         i;
  1057.  
  1058.     // used by w_arms[] widgets
  1059.     st_armson = st_statusbaron && !deathmatch;
  1060.  
  1061.     // used by w_frags widget
  1062.     st_fragson = deathmatch && st_statusbaron;
  1063.  
  1064.     STlib_updateNum(&w_ready, refresh);
  1065.  
  1066.     for (i=0;i<4;i++)
  1067.     {
  1068.         STlib_updateNum(&w_ammo[i], refresh);
  1069.         STlib_updateNum(&w_maxammo[i], refresh);
  1070.     }
  1071.  
  1072.     STlib_updatePercent(&w_health, refresh);
  1073.     STlib_updatePercent(&w_armor, refresh);
  1074.  
  1075.     STlib_updateBinIcon(&w_armsbg, refresh);
  1076.  
  1077.     for (i=0;i<6;i++)
  1078.         STlib_updateMultIcon(&w_arms[i], refresh);
  1079.  
  1080.     STlib_updateMultIcon(&w_faces, refresh);
  1081.  
  1082.     for (i=0;i<3;i++)
  1083.         STlib_updateMultIcon(&w_keyboxes[i], refresh);
  1084.  
  1085.     STlib_updateNum(&w_frags, refresh);
  1086.  
  1087. }
  1088.  
  1089. void ST_doRefresh(void)
  1090. {
  1091.  
  1092.     st_firsttime = false;
  1093.  
  1094.     // draw status bar background to off-screen buff
  1095.     ST_refreshBackground();
  1096.  
  1097.     // and refresh all widgets
  1098.     ST_drawWidgets(true);
  1099.  
  1100. }
  1101.  
  1102. void ST_diffDraw(void)
  1103. {
  1104.     // update all widgets
  1105.     ST_drawWidgets(false);
  1106. }
  1107.  
  1108. void ST_Drawer (boolean fullscreen, boolean refresh)
  1109. {
  1110.  
  1111.     st_statusbaron = (!fullscreen) || automapactive;
  1112.     st_firsttime = st_firsttime || refresh;
  1113.  
  1114.     // Do red-/gold-shifts from damage/items
  1115.     ST_doPaletteStuff();
  1116.  
  1117.     // If just after ST_Start(), refresh all
  1118.     if (st_firsttime) ST_doRefresh();
  1119.     // Otherwise, update as little as possible
  1120.     else ST_diffDraw();
  1121.  
  1122. }
  1123.  
  1124. void ST_loadGraphics(void)
  1125. {
  1126.  
  1127.     int         i;
  1128.     int         j;
  1129.     int         facenum;
  1130.    
  1131.     char        namebuf[9];
  1132.  
  1133.     // Load the numbers, tall and short
  1134.     for (i=0;i<10;i++)
  1135.     {
  1136.         sprintf(namebuf, "STTNUM%d", i);
  1137.         tallnum[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1138.  
  1139.         sprintf(namebuf, "STYSNUM%d", i);
  1140.         shortnum[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1141.     }
  1142.  
  1143.     // Load percent key.
  1144.     //Note: why not load STMINUS here, too?
  1145.     tallpercent = (patch_t *) W_CacheLumpName("STTPRCNT", PU_STATIC);
  1146.  
  1147.     // key cards
  1148.     for (i=0;i<NUMCARDS;i++)
  1149.     {
  1150.         sprintf(namebuf, "STKEYS%d", i);
  1151.         keys[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1152.     }
  1153.  
  1154.     // arms background
  1155.     armsbg = (patch_t *) W_CacheLumpName("STARMS", PU_STATIC);
  1156.  
  1157.     // arms ownership widgets
  1158.     for (i=0;i<6;i++)
  1159.     {
  1160.         sprintf(namebuf, "STGNUM%d", i+2);
  1161.  
  1162.         // gray #
  1163.         arms[i][0] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1164.  
  1165.         // yellow #
  1166.         arms[i][1] = shortnum[i+2];
  1167.     }
  1168.  
  1169.     // face backgrounds for different color players
  1170.     sprintf(namebuf, "STFB%d", consoleplayer);
  1171.     faceback = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1172.  
  1173.     // status bar background bits
  1174.     sbar = (patch_t *) W_CacheLumpName("STBAR", PU_STATIC);
  1175.  
  1176.     // face states
  1177.     facenum = 0;
  1178.     for (i=0;i<ST_NUMPAINFACES;i++)
  1179.     {
  1180.         for (j=0;j<ST_NUMSTRAIGHTFACES;j++)
  1181.         {
  1182.             sprintf(namebuf, "STFST%d%d", i, j);
  1183.             faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1184.         }
  1185.         sprintf(namebuf, "STFTR%d0", i);        // turn right
  1186.         faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1187.         sprintf(namebuf, "STFTL%d0", i);        // turn left
  1188.         faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1189.         sprintf(namebuf, "STFOUCH%d", i);       // ouch!
  1190.         faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1191.         sprintf(namebuf, "STFEVL%d", i);        // evil grin ;)
  1192.         faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1193.         sprintf(namebuf, "STFKILL%d", i);       // pissed off
  1194.         faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1195.     }
  1196.     faces[facenum++] = W_CacheLumpName("STFGOD0", PU_STATIC);
  1197.     faces[facenum++] = W_CacheLumpName("STFDEAD0", PU_STATIC);
  1198.  
  1199. }
  1200.  
  1201. void ST_loadData(void)
  1202. {
  1203.     lu_palette = W_GetNumForName ("PLAYPAL");
  1204.     ST_loadGraphics();
  1205. }
  1206.  
  1207. void ST_unloadGraphics(void)
  1208. {
  1209.  
  1210.     int i;
  1211.  
  1212.     // unload the numbers, tall and short
  1213.     for (i=0;i<10;i++)
  1214.     {
  1215.         Z_ChangeTag(tallnum[i], PU_CACHE);
  1216.         Z_ChangeTag(shortnum[i], PU_CACHE);
  1217.     }
  1218.     // unload tall percent
  1219.     Z_ChangeTag(tallpercent, PU_CACHE);
  1220.  
  1221.     // unload arms background
  1222.     Z_ChangeTag(armsbg, PU_CACHE);
  1223.  
  1224.     // unload gray #'s
  1225.     for (i=0;i<6;i++)
  1226.         Z_ChangeTag(arms[i][0], PU_CACHE);
  1227.    
  1228.     // unload the key cards
  1229.     for (i=0;i<NUMCARDS;i++)
  1230.         Z_ChangeTag(keys[i], PU_CACHE);
  1231.  
  1232.     Z_ChangeTag(sbar, PU_CACHE);
  1233.     Z_ChangeTag(faceback, PU_CACHE);
  1234.  
  1235.     for (i=0;i<ST_NUMFACES;i++)
  1236.         Z_ChangeTag(faces[i], PU_CACHE);
  1237.  
  1238.     // Note: nobody ain't seen no unloading
  1239.     //   of stminus yet. Dude.
  1240.    
  1241.  
  1242. }
  1243.  
  1244. void ST_unloadData(void)
  1245. {
  1246.     ST_unloadGraphics();
  1247. }
  1248.  
  1249. void ST_initData(void)
  1250. {
  1251.  
  1252.     int         i;
  1253.  
  1254.     st_firsttime = true;
  1255.     plyr = &players[consoleplayer];
  1256.  
  1257.     st_clock = 0;
  1258.     st_chatstate = StartChatState;
  1259.     st_gamestate = FirstPersonState;
  1260.  
  1261.     st_statusbaron = true;
  1262.     st_oldchat = st_chat = false;
  1263.     st_cursoron = false;
  1264.  
  1265.     st_faceindex = 0;
  1266.     st_palette = -1;
  1267.  
  1268.     st_oldhealth = -1;
  1269.  
  1270.     for (i=0;i<NUMWEAPONS;i++)
  1271.         oldweaponsowned[i] = plyr->weaponowned[i];
  1272.  
  1273.     for (i=0;i<3;i++)
  1274.         keyboxes[i] = -1;
  1275.  
  1276.     STlib_init();
  1277.  
  1278. }
  1279.  
  1280.  
  1281.  
  1282. void ST_createWidgets(void)
  1283. {
  1284.  
  1285.     int i;
  1286.  
  1287.     // ready weapon ammo
  1288.     STlib_initNum(&w_ready,
  1289.                   ST_AMMOX,
  1290.                   ST_AMMOY,
  1291.                   tallnum,
  1292.                   &plyr->ammo[weaponinfo[plyr->readyweapon].ammo],
  1293.                   &st_statusbaron,
  1294.                   ST_AMMOWIDTH );
  1295.  
  1296.     // the last weapon type
  1297.     w_ready.data = plyr->readyweapon;
  1298.  
  1299.     // health percentage
  1300.     STlib_initPercent(&w_health,
  1301.                       ST_HEALTHX,
  1302.                       ST_HEALTHY,
  1303.                       tallnum,
  1304.                       &plyr->health,
  1305.                       &st_statusbaron,
  1306.                       tallpercent);
  1307.  
  1308.     // arms background
  1309.     STlib_initBinIcon(&w_armsbg,
  1310.                       ST_ARMSBGX,
  1311.                       ST_ARMSBGY,
  1312.                       armsbg,
  1313.                       &st_notdeathmatch,
  1314.                       &st_statusbaron);
  1315.  
  1316.     // weapons owned
  1317.     for(i=0;i<6;i++)
  1318.     {
  1319.         STlib_initMultIcon(&w_arms[i],
  1320.                            ST_ARMSX+(i%3)*ST_ARMSXSPACE,
  1321.                            ST_ARMSY+(i/3)*ST_ARMSYSPACE,
  1322.                            arms[i], (int *) &plyr->weaponowned[i+1],
  1323.                            &st_armson);
  1324.     }
  1325.  
  1326.     // frags sum
  1327.     STlib_initNum(&w_frags,
  1328.                   ST_FRAGSX,
  1329.                   ST_FRAGSY,
  1330.                   tallnum,
  1331.                   &st_fragscount,
  1332.                   &st_fragson,
  1333.                   ST_FRAGSWIDTH);
  1334.  
  1335.     // faces
  1336.     STlib_initMultIcon(&w_faces,
  1337.                        ST_FACESX,
  1338.                        ST_FACESY,
  1339.                        faces,
  1340.                        &st_faceindex,
  1341.                        &st_statusbaron);
  1342.  
  1343.     // armor percentage - should be colored later
  1344.     STlib_initPercent(&w_armor,
  1345.                       ST_ARMORX,
  1346.                       ST_ARMORY,
  1347.                       tallnum,
  1348.                       &plyr->armorpoints,
  1349.                       &st_statusbaron, tallpercent);
  1350.  
  1351.     // keyboxes 0-2
  1352.     STlib_initMultIcon(&w_keyboxes[0],
  1353.                        ST_KEY0X,
  1354.                        ST_KEY0Y,
  1355.                        keys,
  1356.                        &keyboxes[0],
  1357.                        &st_statusbaron);
  1358.    
  1359.     STlib_initMultIcon(&w_keyboxes[1],
  1360.                        ST_KEY1X,
  1361.                        ST_KEY1Y,
  1362.                        keys,
  1363.                        &keyboxes[1],
  1364.                        &st_statusbaron);
  1365.  
  1366.     STlib_initMultIcon(&w_keyboxes[2],
  1367.                        ST_KEY2X,
  1368.                        ST_KEY2Y,
  1369.                        keys,
  1370.                        &keyboxes[2],
  1371.                        &st_statusbaron);
  1372.  
  1373.     // ammo count (all four kinds)
  1374.     STlib_initNum(&w_ammo[0],
  1375.                   ST_AMMO0X,
  1376.                   ST_AMMO0Y,
  1377.                   shortnum,
  1378.                   &plyr->ammo[0],
  1379.                   &st_statusbaron,
  1380.                   ST_AMMO0WIDTH);
  1381.  
  1382.     STlib_initNum(&w_ammo[1],
  1383.                   ST_AMMO1X,
  1384.                   ST_AMMO1Y,
  1385.                   shortnum,
  1386.                   &plyr->ammo[1],
  1387.                   &st_statusbaron,
  1388.                   ST_AMMO1WIDTH);
  1389.  
  1390.     STlib_initNum(&w_ammo[2],
  1391.                   ST_AMMO2X,
  1392.                   ST_AMMO2Y,
  1393.                   shortnum,
  1394.                   &plyr->ammo[2],
  1395.                   &st_statusbaron,
  1396.                   ST_AMMO2WIDTH);
  1397.    
  1398.     STlib_initNum(&w_ammo[3],
  1399.                   ST_AMMO3X,
  1400.                   ST_AMMO3Y,
  1401.                   shortnum,
  1402.                   &plyr->ammo[3],
  1403.                   &st_statusbaron,
  1404.                   ST_AMMO3WIDTH);
  1405.  
  1406.     // max ammo count (all four kinds)
  1407.     STlib_initNum(&w_maxammo[0],
  1408.                   ST_MAXAMMO0X,
  1409.                   ST_MAXAMMO0Y,
  1410.                   shortnum,
  1411.                   &plyr->maxammo[0],
  1412.                   &st_statusbaron,
  1413.                   ST_MAXAMMO0WIDTH);
  1414.  
  1415.     STlib_initNum(&w_maxammo[1],
  1416.                   ST_MAXAMMO1X,
  1417.                   ST_MAXAMMO1Y,
  1418.                   shortnum,
  1419.                   &plyr->maxammo[1],
  1420.                   &st_statusbaron,
  1421.                   ST_MAXAMMO1WIDTH);
  1422.  
  1423.     STlib_initNum(&w_maxammo[2],
  1424.                   ST_MAXAMMO2X,
  1425.                   ST_MAXAMMO2Y,
  1426.                   shortnum,
  1427.                   &plyr->maxammo[2],
  1428.                   &st_statusbaron,
  1429.                   ST_MAXAMMO2WIDTH);
  1430.    
  1431.     STlib_initNum(&w_maxammo[3],
  1432.                   ST_MAXAMMO3X,
  1433.                   ST_MAXAMMO3Y,
  1434.                   shortnum,
  1435.                   &plyr->maxammo[3],
  1436.                   &st_statusbaron,
  1437.                   ST_MAXAMMO3WIDTH);
  1438.  
  1439. }
  1440.  
  1441. static boolean  st_stopped = true;
  1442.  
  1443.  
  1444. void ST_Start (void)
  1445. {
  1446.  
  1447.     if (!st_stopped)
  1448.         ST_Stop();
  1449.  
  1450.     ST_initData();
  1451.     ST_createWidgets();
  1452.     st_stopped = false;
  1453.  
  1454. }
  1455.  
  1456. void ST_Stop (void)
  1457. {
  1458.     if (st_stopped)
  1459.         return;
  1460.  
  1461.     I_SetPalette (W_CacheLumpNum (lu_palette, PU_CACHE));
  1462.  
  1463.     st_stopped = true;
  1464. }
  1465.  
  1466. void ST_Init (void)
  1467. {
  1468.     veryfirsttime = 0;
  1469.     ST_loadData();
  1470.     screens[4] = (byte *) Z_Malloc(ST_WIDTH*ST_HEIGHT, PU_STATIC, 0);
  1471. }
  1472.