st_stuff.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2000 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION:
  30. * Status bar code.
  31. * Does the face/direction indicator animatin.
  32. * Does palette indicators as well (red pain/berserk, bright pickup)
  33. *
  34. *-----------------------------------------------------------------------------*/
  35. #include "doomdef.h"
  36. #include "doomstat.h"
  37. #include "m_random.h"
  38. #include "i_video.h"
  39. #include "w_wad.h"
  40. #include "st_stuff.h"
  41. #include "st_lib.h"
  42. #include "r_main.h"
  43. #include "am_map.h"
  44. #include "m_cheat.h"
  45. #include "s_sound.h"
  46. #include "sounds.h"
  47. #include "dstrings.h"
  48. #include "r_draw.h"
  49. //
  50. // STATUS BAR DATA
  51. //
  52. // Palette indices.
  53. // For damage/bonus red-/gold-shifts
  54. #define STARTREDPALS 1
  55. #define STARTBONUSPALS 9
  56. #define NUMREDPALS 8
  57. #define NUMBONUSPALS 4
  58. // Radiation suit, green shift.
  59. #define RADIATIONPAL 13
  60. // Location of status bar
  61. #define ST_X 0
  62. #define ST_X2 104
  63. // proff 08/18/98: Changed for high-res
  64. #define ST_FX (ST_X+143)
  65. #define ST_FY (ST_Y+1)
  66. //#define ST_FX 143
  67. //#define ST_FY 169
  68. // Should be set to patch width
  69. // for tall numbers later on
  70. #define ST_TALLNUMWIDTH (tallnum[0]->width)
  71. // Number of status faces.
  72. #define ST_NUMPAINFACES 5
  73. #define ST_NUMSTRAIGHTFACES 3
  74. #define ST_NUMTURNFACES 2
  75. #define ST_NUMSPECIALFACES 3
  76. #define ST_FACESTRIDE \
  77. (ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES)
  78. #define ST_NUMEXTRAFACES 2
  79. #define ST_NUMFACES \
  80. (ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES)
  81. #define ST_TURNOFFSET (ST_NUMSTRAIGHTFACES)
  82. #define ST_OUCHOFFSET (ST_TURNOFFSET + ST_NUMTURNFACES)
  83. #define ST_EVILGRINOFFSET (ST_OUCHOFFSET + 1)
  84. #define ST_RAMPAGEOFFSET (ST_EVILGRINOFFSET + 1)
  85. #define ST_GODFACE (ST_NUMPAINFACES*ST_FACESTRIDE)
  86. #define ST_DEADFACE (ST_GODFACE+1)
  87. // proff 08/18/98: Changed for high-res
  88. #define ST_FACESX (ST_X+143)
  89. #define ST_FACESY (ST_Y)
  90. //#define ST_FACESX 143
  91. //#define ST_FACESY 168
  92. #define ST_EVILGRINCOUNT (2*TICRATE)
  93. #define ST_STRAIGHTFACECOUNT (TICRATE/2)
  94. #define ST_TURNCOUNT (1*TICRATE)
  95. #define ST_OUCHCOUNT (1*TICRATE)
  96. #define ST_RAMPAGEDELAY (2*TICRATE)
  97. #define ST_MUCHPAIN 20
  98. // Location and size of statistics,
  99. // justified according to widget type.
  100. // Problem is, within which space? STbar? Screen?
  101. // Note: this could be read in by a lump.
  102. // Problem is, is the stuff rendered
  103. // into a buffer,
  104. // or into the frame buffer?
  105. // I dunno, why don't you go and find out!!! killough
  106. // AMMO number pos.
  107. #define ST_AMMOWIDTH 3
  108. // proff 08/18/98: Changed for high-res
  109. #define ST_AMMOX (ST_X+44)
  110. #define ST_AMMOY (ST_Y+3)
  111. //#define ST_AMMOX 44
  112. //#define ST_AMMOY 171
  113. // HEALTH number pos.
  114. #define ST_HEALTHWIDTH 3
  115. // proff 08/18/98: Changed for high-res
  116. #define ST_HEALTHX (ST_X+90)
  117. #define ST_HEALTHY (ST_Y+3)
  118. //#define ST_HEALTHX 90
  119. //#define ST_HEALTHY 171
  120. // Weapon pos.
  121. // proff 08/18/98: Changed for high-res
  122. #define ST_ARMSX (ST_X+111)
  123. #define ST_ARMSY (ST_Y+4)
  124. #define ST_ARMSBGX (ST_X+104)
  125. #define ST_ARMSBGY (ST_Y)
  126. //#define ST_ARMSX 111
  127. //#define ST_ARMSY 172
  128. //#define ST_ARMSBGX 104
  129. //#define ST_ARMSBGY 168
  130. #define ST_ARMSXSPACE 12
  131. #define ST_ARMSYSPACE 10
  132. // Frags pos.
  133. // proff 08/18/98: Changed for high-res
  134. #define ST_FRAGSX (ST_X+138)
  135. #define ST_FRAGSY (ST_Y+3)
  136. //#define ST_FRAGSX 138
  137. //#define ST_FRAGSY 171
  138. #define ST_FRAGSWIDTH 2
  139. // ARMOR number pos.
  140. #define ST_ARMORWIDTH 3
  141. // proff 08/18/98: Changed for high-res
  142. #define ST_ARMORX (ST_X+221)
  143. #define ST_ARMORY (ST_Y+3)
  144. //#define ST_ARMORX 221
  145. //#define ST_ARMORY 171
  146. // Key icon positions.
  147. #define ST_KEY0WIDTH 8
  148. #define ST_KEY0HEIGHT 5
  149. // proff 08/18/98: Changed for high-res
  150. #define ST_KEY0X (ST_X+239)
  151. #define ST_KEY0Y (ST_Y+3)
  152. //#define ST_KEY0X 239
  153. //#define ST_KEY0Y 171
  154. #define ST_KEY1WIDTH ST_KEY0WIDTH
  155. // proff 08/18/98: Changed for high-res
  156. #define ST_KEY1X (ST_X+239)
  157. #define ST_KEY1Y (ST_Y+13)
  158. //#define ST_KEY1X 239
  159. //#define ST_KEY1Y 181
  160. #define ST_KEY2WIDTH ST_KEY0WIDTH
  161. // proff 08/18/98: Changed for high-res
  162. #define ST_KEY2X (ST_X+239)
  163. #define ST_KEY2Y (ST_Y+23)
  164. //#define ST_KEY2X 239
  165. //#define ST_KEY2Y 191
  166. // Ammunition counter.
  167. #define ST_AMMO0WIDTH 3
  168. #define ST_AMMO0HEIGHT 6
  169. // proff 08/18/98: Changed for high-res
  170. #define ST_AMMO0X (ST_X+288)
  171. #define ST_AMMO0Y (ST_Y+5)
  172. //#define ST_AMMO0X 288
  173. //#define ST_AMMO0Y 173
  174. #define ST_AMMO1WIDTH ST_AMMO0WIDTH
  175. // proff 08/18/98: Changed for high-res
  176. #define ST_AMMO1X (ST_X+288)
  177. #define ST_AMMO1Y (ST_Y+11)
  178. //#define ST_AMMO1X 288
  179. //#define ST_AMMO1Y 179
  180. #define ST_AMMO2WIDTH ST_AMMO0WIDTH
  181. // proff 08/18/98: Changed for high-res
  182. #define ST_AMMO2X (ST_X+288)
  183. #define ST_AMMO2Y (ST_Y+23)
  184. //#define ST_AMMO2X 288
  185. //#define ST_AMMO2Y 191
  186. #define ST_AMMO3WIDTH ST_AMMO0WIDTH
  187. // proff 08/18/98: Changed for high-res
  188. #define ST_AMMO3X (ST_X+288)
  189. #define ST_AMMO3Y (ST_Y+17)
  190. //#define ST_AMMO3X 288
  191. //#define ST_AMMO3Y 185
  192. // Indicate maximum ammunition.
  193. // Only needed because backpack exists.
  194. #define ST_MAXAMMO0WIDTH 3
  195. #define ST_MAXAMMO0HEIGHT 5
  196. // proff 08/18/98: Changed for high-res
  197. #define ST_MAXAMMO0X (ST_X+314)
  198. #define ST_MAXAMMO0Y (ST_Y+5)
  199. //#define ST_MAXAMMO0X 314
  200. //#define ST_MAXAMMO0Y 173
  201. #define ST_MAXAMMO1WIDTH ST_MAXAMMO0WIDTH
  202. // proff 08/18/98: Changed for high-res
  203. #define ST_MAXAMMO1X (ST_X+314)
  204. #define ST_MAXAMMO1Y (ST_Y+11)
  205. //#define ST_MAXAMMO1X 314
  206. //#define ST_MAXAMMO1Y 179
  207. #define ST_MAXAMMO2WIDTH ST_MAXAMMO0WIDTH
  208. // proff 08/18/98: Changed for high-res
  209. #define ST_MAXAMMO2X (ST_X+314)
  210. #define ST_MAXAMMO2Y (ST_Y+23)
  211. //#define ST_MAXAMMO2X 314
  212. //#define ST_MAXAMMO2Y 191
  213. #define ST_MAXAMMO3WIDTH ST_MAXAMMO0WIDTH
  214. // proff 08/18/98: Changed for high-res
  215. #define ST_MAXAMMO3X (ST_X+314)
  216. #define ST_MAXAMMO3Y (ST_Y+17)
  217. //#define ST_MAXAMMO3X 314
  218. //#define ST_MAXAMMO3Y 185
  219. // killough 2/8/98: weapon info position macros UNUSED, removed here
  220. // main player in game
  221. static player_t *plyr;
  222. // ST_Start() has just been called
  223. static boolean st_firsttime;
  224. // used to execute ST_Init() only once
  225. static int veryfirsttime = 1;
  226. // CPhipps - no longer do direct PLAYPAL handling here
  227. // used for timing
  228. static unsigned int st_clock;
  229. // used for making messages go away
  230. static int st_msgcounter=0;
  231. // used when in chat
  232. static st_chatstateenum_t st_chatstate;
  233. // whether in automap or first-person
  234. static st_stateenum_t st_gamestate;
  235. // whether left-side main status bar is active
  236. static boolean st_statusbaron;
  237. // whether status bar chat is active
  238. static boolean st_chat;
  239. // value of st_chat before message popped up
  240. static boolean st_oldchat;
  241. // whether chat window has the cursor on
  242. static boolean st_cursoron;
  243. // !deathmatch
  244. static boolean st_notdeathmatch;
  245. // !deathmatch && st_statusbaron
  246. static boolean st_armson;
  247. // !deathmatch
  248. static boolean st_fragson;
  249. // 0-9, tall numbers
  250. static patchnum_t tallnum[10];
  251. // tall % sign
  252. static patchnum_t tallpercent;
  253. // 0-9, short, yellow (,different!) numbers
  254. static patchnum_t shortnum[10];
  255. // 3 key-cards, 3 skulls, 3 card/skull combos
  256. // jff 2/24/98 extend number of patches by three skull/card combos
  257. static patchnum_t keys[NUMCARDS+3];
  258. // face status patches
  259. static patchnum_t faces[ST_NUMFACES];
  260. // face background
  261. static patchnum_t faceback; // CPhipps - single background, translated for different players
  262. //e6y: status bar background
  263. /* JDC static */ patchnum_t stbarbg;
  264. // main bar right
  265. static patchnum_t armsbg;
  266. // weapon ownership patches
  267. static patchnum_t arms[6][2];
  268. // ready-weapon widget
  269. static st_number_t w_ready;
  270. //jff 2/16/98 status color change levels
  271. int ammo_red; // ammo percent less than which status is red
  272. int ammo_yellow; // ammo percent less is yellow more green
  273. int health_red; // health amount less than which status is red
  274. int health_yellow; // health amount less than which status is yellow
  275. int health_green; // health amount above is blue, below is green
  276. int armor_red; // armor amount less than which status is red
  277. int armor_yellow; // armor amount less than which status is yellow
  278. int armor_green; // armor amount above is blue, below is green
  279. // in deathmatch only, summary of frags stats
  280. static st_number_t w_frags;
  281. // health widget
  282. static st_percent_t w_health;
  283. // arms background
  284. static st_binicon_t w_armsbg;
  285. // weapon ownership widgets
  286. static st_multicon_t w_arms[6];
  287. // face status widget
  288. static st_multicon_t w_faces;
  289. // keycard widgets
  290. static st_multicon_t w_keyboxes[3];
  291. // armor widget
  292. static st_percent_t w_armor;
  293. // ammo widgets
  294. static st_number_t w_ammo[4];
  295. // max ammo widgets
  296. static st_number_t w_maxammo[4];
  297. // number of frags so far in deathmatch
  298. static int st_fragscount;
  299. // used to use appopriately pained face
  300. static int st_oldhealth = -1;
  301. // used for evil grin
  302. static boolean oldweaponsowned[NUMWEAPONS];
  303. // count until face changes
  304. static int st_facecount = 0;
  305. // current face index, used by w_faces
  306. static int st_faceindex = 0;
  307. // holds key-type for each key box on bar
  308. static int keyboxes[3];
  309. // a random number per tick
  310. static int st_randomnumber;
  311. extern char *mapnames[];
  312. //
  313. // STATUS BAR CODE
  314. //
  315. static void ST_Stop(void);
  316. static void ST_refreshBackground(void)
  317. {
  318. int y=0;
  319. if (st_statusbaron)
  320. {
  321. // proff 05/17/2000: draw to the frontbuffer in OpenGL
  322. if (V_GetMode() == VID_MODEGL)
  323. y=ST_Y;
  324. V_DrawNumPatch(ST_X, y, BG, stbarbg.lumpnum, CR_DEFAULT, VPT_STRETCH);
  325. if (st_armson)
  326. V_DrawNumPatch(ST_ARMSBGX, y, BG, armsbg.lumpnum, CR_DEFAULT, VPT_STRETCH);
  327. // killough 3/7/98: make face background change with displayplayer
  328. if (netgame)
  329. {
  330. V_DrawNumPatch(ST_FX, y, BG, faceback.lumpnum,
  331. displayplayer ? CR_LIMIT+displayplayer : CR_DEFAULT,
  332. displayplayer ? (VPT_TRANS | VPT_STRETCH) : VPT_STRETCH);
  333. }
  334. V_CopyRect(ST_X, y, BG, ST_SCALED_WIDTH, ST_SCALED_HEIGHT, ST_X, ST_SCALED_Y, FG, VPT_NONE);
  335. }
  336. }
  337. // Respond to keyboard input events,
  338. // intercept cheats.
  339. boolean ST_Responder(event_t *ev)
  340. {
  341. // Filter automap on/off.
  342. if (ev->type == ev_keyup && (ev->data1 & 0xffff0000) == AM_MSGHEADER)
  343. {
  344. switch(ev->data1)
  345. {
  346. case AM_MSGENTERED:
  347. st_gamestate = AutomapState;
  348. st_firsttime = true;
  349. break;
  350. case AM_MSGEXITED:
  351. st_gamestate = FirstPersonState;
  352. break;
  353. }
  354. }
  355. else // if a user keypress...
  356. if (ev->type == ev_keydown) // Try cheat responder in m_cheat.c
  357. return M_FindCheats(ev->data1); // killough 4/17/98, 5/2/98
  358. return false;
  359. }
  360. static int ST_calcPainOffset(void)
  361. {
  362. static int lastcalc;
  363. static int oldhealth = -1;
  364. int health = plyr->health > 100 ? 100 : plyr->health;
  365. if (health != oldhealth)
  366. {
  367. lastcalc = ST_FACESTRIDE * (((100 - health) * ST_NUMPAINFACES) / 101);
  368. oldhealth = health;
  369. }
  370. return lastcalc;
  371. }
  372. //
  373. // This is a not-very-pretty routine which handles
  374. // the face states and their timing.
  375. // the precedence of expressions is:
  376. // dead > evil grin > turned head > straight ahead
  377. //
  378. static void ST_updateFaceWidget(void)
  379. {
  380. int i;
  381. angle_t badguyangle;
  382. angle_t diffang;
  383. static int lastattackdown = -1;
  384. static int priority = 0;
  385. boolean doevilgrin;
  386. if (priority < 10)
  387. {
  388. // dead
  389. if (!plyr->health)
  390. {
  391. priority = 9;
  392. st_faceindex = ST_DEADFACE;
  393. st_facecount = 1;
  394. }
  395. }
  396. if (priority < 9)
  397. {
  398. if (plyr->bonuscount)
  399. {
  400. // picking up bonus
  401. doevilgrin = false;
  402. for (i=0;i<NUMWEAPONS;i++)
  403. {
  404. if (oldweaponsowned[i] != plyr->weaponowned[i])
  405. {
  406. doevilgrin = true;
  407. oldweaponsowned[i] = plyr->weaponowned[i];
  408. }
  409. }
  410. if (doevilgrin)
  411. {
  412. // evil grin if just picked up weapon
  413. priority = 8;
  414. st_facecount = ST_EVILGRINCOUNT;
  415. st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET;
  416. }
  417. }
  418. }
  419. if (priority < 8)
  420. {
  421. if (plyr->damagecount && plyr->attacker && plyr->attacker != plyr->mo)
  422. {
  423. // being attacked
  424. priority = 7;
  425. // haleyjd 10/12/03: classic DOOM problem of missing OUCH face
  426. // was due to inversion of this test:
  427. // if(plyr->health - st_oldhealth > ST_MUCHPAIN)
  428. if(st_oldhealth - plyr->health > ST_MUCHPAIN)
  429. {
  430. st_facecount = ST_TURNCOUNT;
  431. st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
  432. }
  433. else
  434. {
  435. badguyangle = R_PointToAngle2(plyr->mo->x,
  436. plyr->mo->y,
  437. plyr->attacker->x,
  438. plyr->attacker->y);
  439. if (badguyangle > plyr->mo->angle)
  440. {
  441. // whether right or left
  442. diffang = badguyangle - plyr->mo->angle;
  443. i = diffang > ANG180;
  444. }
  445. else
  446. {
  447. // whether left or right
  448. diffang = plyr->mo->angle - badguyangle;
  449. i = diffang <= ANG180;
  450. } // confusing, aint it?
  451. st_facecount = ST_TURNCOUNT;
  452. st_faceindex = ST_calcPainOffset();
  453. if (diffang < ANG45)
  454. {
  455. // head-on
  456. st_faceindex += ST_RAMPAGEOFFSET;
  457. }
  458. else if (i)
  459. {
  460. // turn face right
  461. st_faceindex += ST_TURNOFFSET;
  462. }
  463. else
  464. {
  465. // turn face left
  466. st_faceindex += ST_TURNOFFSET+1;
  467. }
  468. }
  469. }
  470. }
  471. if (priority < 7)
  472. {
  473. // getting hurt because of your own damn stupidity
  474. if (plyr->damagecount)
  475. {
  476. // haleyjd 10/12/03: classic DOOM problem of missing OUCH face
  477. // was due to inversion of this test:
  478. // if(plyr->health - st_oldhealth > ST_MUCHPAIN)
  479. if(st_oldhealth - plyr->health > ST_MUCHPAIN)
  480. {
  481. priority = 7;
  482. st_facecount = ST_TURNCOUNT;
  483. st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
  484. }
  485. else
  486. {
  487. priority = 6;
  488. st_facecount = ST_TURNCOUNT;
  489. st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
  490. }
  491. }
  492. }
  493. if (priority < 6)
  494. {
  495. // rapid firing
  496. if (plyr->attackdown)
  497. {
  498. if (lastattackdown==-1)
  499. lastattackdown = ST_RAMPAGEDELAY;
  500. else if (!--lastattackdown)
  501. {
  502. priority = 5;
  503. st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
  504. st_facecount = 1;
  505. lastattackdown = 1;
  506. }
  507. }
  508. else
  509. lastattackdown = -1;
  510. }
  511. if (priority < 5)
  512. {
  513. // invulnerability
  514. if ((plyr->cheats & CF_GODMODE)
  515. || plyr->powers[pw_invulnerability])
  516. {
  517. priority = 4;
  518. st_faceindex = ST_GODFACE;
  519. st_facecount = 1;
  520. }
  521. }
  522. // look left or look right if the facecount has timed out
  523. if (!st_facecount)
  524. {
  525. st_faceindex = ST_calcPainOffset() + (st_randomnumber % 3);
  526. st_facecount = ST_STRAIGHTFACECOUNT;
  527. priority = 0;
  528. }
  529. st_facecount--;
  530. }
  531. int sts_traditional_keys; // killough 2/28/98: traditional status bar keys
  532. static void ST_updateWidgets(void)
  533. {
  534. static int largeammo = 1994; // means "n/a"
  535. int i;
  536. // must redirect the pointer if the ready weapon has changed.
  537. // if (w_ready.data != plyr->readyweapon)
  538. // {
  539. if (weaponinfo[plyr->readyweapon].ammo == am_noammo)
  540. w_ready.num = &largeammo;
  541. else
  542. w_ready.num = &plyr->ammo[weaponinfo[plyr->readyweapon].ammo];
  543. //{
  544. // static int tic=0;
  545. // static int dir=-1;
  546. // if (!(tic&15))
  547. // plyr->ammo[weaponinfo[plyr->readyweapon].ammo]+=dir;
  548. // if (plyr->ammo[weaponinfo[plyr->readyweapon].ammo] == -100)
  549. // dir = 1;
  550. // tic++;
  551. // }
  552. w_ready.data = plyr->readyweapon;
  553. // if (*w_ready.on)
  554. // STlib_updateNum(&w_ready, true);
  555. // refresh weapon change
  556. // }
  557. // update keycard multiple widgets
  558. for (i=0;i<3;i++)
  559. {
  560. keyboxes[i] = plyr->cards[i] ? i : -1;
  561. //jff 2/24/98 select double key
  562. //killough 2/28/98: preserve traditional keys by config option
  563. if (plyr->cards[i+3])
  564. keyboxes[i] = keyboxes[i]==-1 || sts_traditional_keys ? i+3 : i+6;
  565. }
  566. // refresh everything if this is him coming back to life
  567. ST_updateFaceWidget();
  568. // used by the w_armsbg widget
  569. st_notdeathmatch = !deathmatch;
  570. // used by w_arms[] widgets
  571. st_armson = st_statusbaron && !deathmatch;
  572. // used by w_frags widget
  573. st_fragson = deathmatch && st_statusbaron;
  574. st_fragscount = 0;
  575. for (i=0 ; i<MAXPLAYERS ; i++)
  576. {
  577. if (i != displayplayer) // killough 3/7/98
  578. st_fragscount += plyr->frags[i];
  579. else
  580. st_fragscount -= plyr->frags[i];
  581. }
  582. // get rid of chat window if up because of message
  583. if (!--st_msgcounter)
  584. st_chat = st_oldchat;
  585. }
  586. void ST_Ticker(void)
  587. {
  588. st_clock++;
  589. st_randomnumber = M_Random();
  590. ST_updateWidgets();
  591. st_oldhealth = plyr->health;
  592. }
  593. int st_palette = 0;
  594. static void ST_doPaletteStuff(void)
  595. {
  596. int palette;
  597. int cnt = plyr->damagecount;
  598. if (plyr->powers[pw_strength])
  599. {
  600. // slowly fade the berzerk out
  601. int bzc = 12 - (plyr->powers[pw_strength]>>6);
  602. if (bzc > cnt)
  603. cnt = bzc;
  604. }
  605. if (cnt)
  606. {
  607. palette = (cnt+7)>>3;
  608. if (palette >= NUMREDPALS)
  609. palette = NUMREDPALS-1;
  610. /* cph 2006/08/06 - if in the menu, reduce the red tint - navigating to
  611. * load a game can be tricky if the screen is all red */
  612. if (menuactive) palette >>=1;
  613. palette += STARTREDPALS;
  614. }
  615. else
  616. if (plyr->bonuscount)
  617. {
  618. palette = (plyr->bonuscount+7)>>3;
  619. if (palette >= NUMBONUSPALS)
  620. palette = NUMBONUSPALS-1;
  621. palette += STARTBONUSPALS;
  622. }
  623. else
  624. if (plyr->powers[pw_ironfeet] > 4*32 || plyr->powers[pw_ironfeet] & 8)
  625. palette = RADIATIONPAL;
  626. else
  627. palette = 0;
  628. if (palette != st_palette) {
  629. V_SetPalette(st_palette = palette); // CPhipps - use new palette function
  630. // have to redraw the entire status bar when the palette changes
  631. // in truecolor modes - POPE
  632. if (V_GetMode() == VID_MODE15 || V_GetMode() == VID_MODE16 || V_GetMode() == VID_MODE32)
  633. st_firsttime = true;
  634. }
  635. }
  636. static void ST_drawWidgets(boolean refresh)
  637. {
  638. int i;
  639. // used by w_arms[] widgets
  640. st_armson = st_statusbaron && !deathmatch;
  641. // used by w_frags widget
  642. st_fragson = deathmatch && st_statusbaron;
  643. //jff 2/16/98 make color of ammo depend on amount
  644. if (*w_ready.num*100 < ammo_red*plyr->maxammo[weaponinfo[w_ready.data].ammo])
  645. STlib_updateNum(&w_ready, CR_RED, refresh);
  646. else
  647. if (*w_ready.num*100 <
  648. ammo_yellow*plyr->maxammo[weaponinfo[w_ready.data].ammo])
  649. STlib_updateNum(&w_ready, CR_GOLD, refresh);
  650. else
  651. STlib_updateNum(&w_ready, CR_GREEN, refresh);
  652. for (i=0;i<4;i++)
  653. {
  654. STlib_updateNum(&w_ammo[i], CR_DEFAULT, refresh); //jff 2/16/98 no xlation
  655. STlib_updateNum(&w_maxammo[i], CR_DEFAULT, refresh);
  656. }
  657. //jff 2/16/98 make color of health depend on amount
  658. if (*w_health.n.num<health_red)
  659. STlib_updatePercent(&w_health, CR_RED, refresh);
  660. else if (*w_health.n.num<health_yellow)
  661. STlib_updatePercent(&w_health, CR_GOLD, refresh);
  662. else if (*w_health.n.num<=health_green)
  663. STlib_updatePercent(&w_health, CR_GREEN, refresh);
  664. else
  665. STlib_updatePercent(&w_health, CR_BLUE2, refresh); //killough 2/28/98
  666. //jff 2/16/98 make color of armor depend on amount
  667. if (*w_armor.n.num<armor_red)
  668. STlib_updatePercent(&w_armor, CR_RED, refresh);
  669. else if (*w_armor.n.num<armor_yellow)
  670. STlib_updatePercent(&w_armor, CR_GOLD, refresh);
  671. else if (*w_armor.n.num<=armor_green)
  672. STlib_updatePercent(&w_armor, CR_GREEN, refresh);
  673. else
  674. STlib_updatePercent(&w_armor, CR_BLUE2, refresh); //killough 2/28/98
  675. //e6y: moved to ST_refreshBackground() for correct single-pass stretching
  676. //STlib_updateBinIcon(&w_armsbg, refresh);
  677. for (i=0;i<6;i++)
  678. STlib_updateMultIcon(&w_arms[i], refresh);
  679. STlib_updateMultIcon(&w_faces, refresh);
  680. for (i=0;i<3;i++)
  681. STlib_updateMultIcon(&w_keyboxes[i], refresh);
  682. STlib_updateNum(&w_frags, CR_DEFAULT, refresh);
  683. }
  684. static void ST_doRefresh(void)
  685. {
  686. st_firsttime = false;
  687. // draw status bar background to off-screen buff
  688. ST_refreshBackground();
  689. // and refresh all widgets
  690. ST_drawWidgets(true);
  691. }
  692. static void ST_diffDraw(void)
  693. {
  694. // update all widgets
  695. ST_drawWidgets(false);
  696. }
  697. void ST_Drawer(boolean statusbaron, boolean refresh)
  698. {
  699. /* cph - let status bar on be controlled
  700. * completely by the call from D_Display
  701. * proff - really do it
  702. */
  703. st_firsttime = st_firsttime || refresh;
  704. ST_doPaletteStuff(); // Do red-/gold-shifts from damage/items
  705. // JDC: I want the status bar to change when debugging multiplayer
  706. // unfortunately, this doesn't get a lot of the widgets updated
  707. // properly, because they have internal pointers setup based on
  708. // the default displayplayer.
  709. plyr = &players[displayplayer];
  710. if (statusbaron) {
  711. if (st_firsttime || (V_GetMode() == VID_MODEGL))
  712. ST_doRefresh(); /* If just after ST_Start(), refresh all */
  713. else
  714. ST_diffDraw(); /* Otherwise, update as little as possible */
  715. }
  716. }
  717. //
  718. // ST_loadGraphics
  719. //
  720. // CPhipps - Loads graphics needed for status bar if doload is true,
  721. // unloads them otherwise
  722. //
  723. static void ST_loadGraphics(boolean doload)
  724. {
  725. int i, facenum;
  726. char namebuf[9];
  727. // cph - macro that either acquires a pointer and lock for a lump, or
  728. // unlocks it. var is referenced exactly once in either case, so ++ in arg works
  729. // Load the numbers, tall and short
  730. for (i=0;i<10;i++)
  731. {
  732. sprintf(namebuf, "STTNUM%d", i);
  733. R_SetPatchNum(&tallnum[i],namebuf);
  734. sprintf(namebuf, "STYSNUM%d", i);
  735. R_SetPatchNum(&shortnum[i],namebuf);
  736. }
  737. // Load percent key.
  738. R_SetPatchNum(&tallpercent,"STTPRCNT");
  739. // key cards
  740. for (i=0;i<NUMCARDS+3;i++) //jff 2/23/98 show both keys too
  741. {
  742. sprintf(namebuf, "STKEYS%d", i);
  743. R_SetPatchNum(&keys[i], namebuf);
  744. }
  745. //e6y: status bar background
  746. R_SetPatchNum(&stbarbg, "STBAR");
  747. // arms background
  748. R_SetPatchNum(&armsbg, "STARMS");
  749. // arms ownership widgets
  750. for (i=0;i<6;i++)
  751. {
  752. sprintf(namebuf, "STGNUM%d", i+2);
  753. // gray #
  754. R_SetPatchNum(&arms[i][0], namebuf);
  755. // yellow #
  756. arms[i][1] = shortnum[i+2];
  757. }
  758. // face backgrounds for different color players
  759. // killough 3/7/98: add better support for spy mode by loading all
  760. // player face backgrounds and using displayplayer to choose them:
  761. R_SetPatchNum(&faceback, "STFB0");
  762. // face states
  763. facenum = 0;
  764. for (i=0;i<ST_NUMPAINFACES;i++)
  765. {
  766. int j;
  767. for (j=0;j<ST_NUMSTRAIGHTFACES;j++)
  768. {
  769. sprintf(namebuf, "STFST%d%d", i, j);
  770. R_SetPatchNum(&faces[facenum++], namebuf);
  771. }
  772. sprintf(namebuf, "STFTR%d0", i); // turn right
  773. R_SetPatchNum(&faces[facenum++], namebuf);
  774. sprintf(namebuf, "STFTL%d0", i); // turn left
  775. R_SetPatchNum(&faces[facenum++], namebuf);
  776. sprintf(namebuf, "STFOUCH%d", i); // ouch!
  777. R_SetPatchNum(&faces[facenum++], namebuf);
  778. sprintf(namebuf, "STFEVL%d", i); // evil grin ;)
  779. R_SetPatchNum(&faces[facenum++], namebuf);
  780. sprintf(namebuf, "STFKILL%d", i); // pissed off
  781. R_SetPatchNum(&faces[facenum++], namebuf);
  782. }
  783. R_SetPatchNum(&faces[facenum++], "STFGOD0");
  784. R_SetPatchNum(&faces[facenum++], "STFDEAD0");
  785. }
  786. static void ST_loadData(void)
  787. {
  788. ST_loadGraphics(true);
  789. }
  790. static void ST_initData(void)
  791. {
  792. int i;
  793. st_firsttime = true;
  794. plyr = &players[displayplayer]; // killough 3/7/98
  795. st_clock = 0;
  796. st_chatstate = StartChatState;
  797. st_gamestate = FirstPersonState;
  798. st_statusbaron = true;
  799. st_oldchat = st_chat = false;
  800. st_cursoron = false;
  801. st_faceindex = 0;
  802. st_palette = -1;
  803. st_oldhealth = -1;
  804. for (i=0;i<NUMWEAPONS;i++)
  805. oldweaponsowned[i] = plyr->weaponowned[i];
  806. for (i=0;i<3;i++)
  807. keyboxes[i] = -1;
  808. STlib_init();
  809. }
  810. static void ST_createWidgets(void)
  811. {
  812. int i;
  813. // ready weapon ammo
  814. STlib_initNum(&w_ready,
  815. ST_AMMOX,
  816. ST_AMMOY,
  817. tallnum,
  818. &plyr->ammo[weaponinfo[plyr->readyweapon].ammo],
  819. &st_statusbaron,
  820. ST_AMMOWIDTH );
  821. // the last weapon type
  822. w_ready.data = plyr->readyweapon;
  823. // health percentage
  824. STlib_initPercent(&w_health,
  825. ST_HEALTHX,
  826. ST_HEALTHY,
  827. tallnum,
  828. &plyr->health,
  829. &st_statusbaron,
  830. &tallpercent);
  831. // arms background
  832. STlib_initBinIcon(&w_armsbg,
  833. ST_ARMSBGX,
  834. ST_ARMSBGY,
  835. &armsbg,
  836. &st_notdeathmatch,
  837. &st_statusbaron);
  838. // weapons owned
  839. for(i=0;i<6;i++)
  840. {
  841. STlib_initMultIcon(&w_arms[i],
  842. ST_ARMSX+(i%3)*ST_ARMSXSPACE,
  843. ST_ARMSY+(i/3)*ST_ARMSYSPACE,
  844. arms[i], (int *) &plyr->weaponowned[i+1],
  845. &st_armson);
  846. }
  847. // frags sum
  848. STlib_initNum(&w_frags,
  849. ST_FRAGSX,
  850. ST_FRAGSY,
  851. tallnum,
  852. &st_fragscount,
  853. &st_fragson,
  854. ST_FRAGSWIDTH);
  855. // faces
  856. STlib_initMultIcon(&w_faces,
  857. ST_FACESX,
  858. ST_FACESY,
  859. faces,
  860. &st_faceindex,
  861. &st_statusbaron);
  862. // armor percentage - should be colored later
  863. STlib_initPercent(&w_armor,
  864. ST_ARMORX,
  865. ST_ARMORY,
  866. tallnum,
  867. &plyr->armorpoints,
  868. &st_statusbaron, &tallpercent);
  869. // keyboxes 0-2
  870. STlib_initMultIcon(&w_keyboxes[0],
  871. ST_KEY0X,
  872. ST_KEY0Y,
  873. keys,
  874. &keyboxes[0],
  875. &st_statusbaron);
  876. STlib_initMultIcon(&w_keyboxes[1],
  877. ST_KEY1X,
  878. ST_KEY1Y,
  879. keys,
  880. &keyboxes[1],
  881. &st_statusbaron);
  882. STlib_initMultIcon(&w_keyboxes[2],
  883. ST_KEY2X,
  884. ST_KEY2Y,
  885. keys,
  886. &keyboxes[2],
  887. &st_statusbaron);
  888. // ammo count (all four kinds)
  889. STlib_initNum(&w_ammo[0],
  890. ST_AMMO0X,
  891. ST_AMMO0Y,
  892. shortnum,
  893. &plyr->ammo[0],
  894. &st_statusbaron,
  895. ST_AMMO0WIDTH);
  896. STlib_initNum(&w_ammo[1],
  897. ST_AMMO1X,
  898. ST_AMMO1Y,
  899. shortnum,
  900. &plyr->ammo[1],
  901. &st_statusbaron,
  902. ST_AMMO1WIDTH);
  903. STlib_initNum(&w_ammo[2],
  904. ST_AMMO2X,
  905. ST_AMMO2Y,
  906. shortnum,
  907. &plyr->ammo[2],
  908. &st_statusbaron,
  909. ST_AMMO2WIDTH);
  910. STlib_initNum(&w_ammo[3],
  911. ST_AMMO3X,
  912. ST_AMMO3Y,
  913. shortnum,
  914. &plyr->ammo[3],
  915. &st_statusbaron,
  916. ST_AMMO3WIDTH);
  917. // max ammo count (all four kinds)
  918. STlib_initNum(&w_maxammo[0],
  919. ST_MAXAMMO0X,
  920. ST_MAXAMMO0Y,
  921. shortnum,
  922. &plyr->maxammo[0],
  923. &st_statusbaron,
  924. ST_MAXAMMO0WIDTH);
  925. STlib_initNum(&w_maxammo[1],
  926. ST_MAXAMMO1X,
  927. ST_MAXAMMO1Y,
  928. shortnum,
  929. &plyr->maxammo[1],
  930. &st_statusbaron,
  931. ST_MAXAMMO1WIDTH);
  932. STlib_initNum(&w_maxammo[2],
  933. ST_MAXAMMO2X,
  934. ST_MAXAMMO2Y,
  935. shortnum,
  936. &plyr->maxammo[2],
  937. &st_statusbaron,
  938. ST_MAXAMMO2WIDTH);
  939. STlib_initNum(&w_maxammo[3],
  940. ST_MAXAMMO3X,
  941. ST_MAXAMMO3Y,
  942. shortnum,
  943. &plyr->maxammo[3],
  944. &st_statusbaron,
  945. ST_MAXAMMO3WIDTH);
  946. }
  947. static boolean st_stopped = true;
  948. void ST_Start(void)
  949. {
  950. if (!st_stopped)
  951. ST_Stop();
  952. ST_initData();
  953. ST_createWidgets();
  954. st_stopped = false;
  955. }
  956. static void ST_Stop(void)
  957. {
  958. if (st_stopped)
  959. return;
  960. V_SetPalette(0);
  961. st_stopped = true;
  962. }
  963. void ST_Init(void)
  964. {
  965. veryfirsttime = 0;
  966. ST_loadData();
  967. }