Move c/h files implementing/defining standard library stuff into a new libc directory...
[kugel-rb.git] / apps / plugins / doom / st_stuff.c
blobfeae89a802488b5862060dccd8760a625439cbab
1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
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
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA.
27 * DESCRIPTION:
28 * Status bar code.
29 * Does the face/direction indicator animatin.
30 * Does palette indicators as well (red pain/berserk, bright pickup)
32 *-----------------------------------------------------------------------------*/
34 #include "doomdef.h"
35 #include "doomstat.h"
36 #include "m_random.h"
37 #include "i_video.h"
38 #include "w_wad.h"
39 #include "st_stuff.h"
40 #include "st_lib.h"
41 #include "r_main.h"
42 #include "am_map.h"
43 #include "m_cheat.h"
44 #include "s_sound.h"
45 #include "sounds.h"
46 #include "dstrings.h"
47 #include "r_draw.h"
50 // STATUS BAR DATA
53 // Palette indices.
54 // For damage/bonus red-/gold-shifts
55 #define STARTREDPALS 1
56 #define STARTBONUSPALS 9
57 #define NUMREDPALS 8
58 #define NUMBONUSPALS 4
59 // Radiation suit, green shift.
60 #define RADIATIONPAL 13
62 // Location of status bar
63 #define ST_X 0
64 #define ST_X2 104
66 // proff 08/18/98: Changed for high-res
67 #define ST_FX (ST_X+143)
68 #define ST_FY (ST_Y+1)
69 //#define ST_FX 143
70 //#define ST_FY 169
72 // Should be set to patch width
73 // for tall numbers later on
74 #define ST_TALLNUMWIDTH (tallnum[0]->width)
76 // Number of status faces.
77 #define ST_NUMPAINFACES 5
78 #define ST_NUMSTRAIGHTFACES 3
79 #define ST_NUMTURNFACES 2
80 #define ST_NUMSPECIALFACES 3
82 #define ST_FACESTRIDE \
83 (ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES)
85 #define ST_NUMEXTRAFACES 2
87 #define ST_NUMFACES \
88 (ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES)
90 #define ST_TURNOFFSET (ST_NUMSTRAIGHTFACES)
91 #define ST_OUCHOFFSET (ST_TURNOFFSET + ST_NUMTURNFACES)
92 #define ST_EVILGRINOFFSET (ST_OUCHOFFSET + 1)
93 #define ST_RAMPAGEOFFSET (ST_EVILGRINOFFSET + 1)
94 #define ST_GODFACE (ST_NUMPAINFACES*ST_FACESTRIDE)
95 #define ST_DEADFACE (ST_GODFACE+1)
97 // proff 08/18/98: Changed for high-res
98 #define ST_FACESX (ST_X+143)
99 #define ST_FACESY (ST_Y)
100 //#define ST_FACESX 143
101 //#define ST_FACESY 168
103 #define ST_EVILGRINCOUNT (2*TICRATE)
104 #define ST_STRAIGHTFACECOUNT (TICRATE/2)
105 #define ST_TURNCOUNT (1*TICRATE)
106 #define ST_OUCHCOUNT (1*TICRATE)
107 #define ST_RAMPAGEDELAY (2*TICRATE)
109 #define ST_MUCHPAIN 20
111 // Location and size of statistics,
112 // justified according to widget type.
113 // Problem is, within which space? STbar? Screen?
114 // Note: this could be read in by a lump.
115 // Problem is, is the stuff rendered
116 // into a buffer,
117 // or into the frame buffer?
118 // I dunno, why don't you go and find out!!! killough
120 // AMMO number pos.
121 #define ST_AMMOWIDTH 3
122 // proff 08/18/98: Changed for high-res
123 #define ST_AMMOX (ST_X+44)
124 #define ST_AMMOY (ST_Y+3)
125 //#define ST_AMMOX 44
126 //#define ST_AMMOY 171
128 // HEALTH number pos.
129 #define ST_HEALTHWIDTH 3
130 // proff 08/18/98: Changed for high-res
131 #define ST_HEALTHX (ST_X+90)
132 #define ST_HEALTHY (ST_Y+3)
133 //#define ST_HEALTHX 90
134 //#define ST_HEALTHY 171
136 // Weapon pos.
137 // proff 08/18/98: Changed for high-res
138 #define ST_ARMSX (ST_X+111)
139 #define ST_ARMSY (ST_Y+4)
140 #define ST_ARMSBGX (ST_X+104)
141 #define ST_ARMSBGY (ST_Y)
142 //#define ST_ARMSX 111
143 //#define ST_ARMSY 172
144 //#define ST_ARMSBGX 104
145 //#define ST_ARMSBGY 168
146 #define ST_ARMSXSPACE 12
147 #define ST_ARMSYSPACE 10
149 // Frags pos.
150 // proff 08/18/98: Changed for high-res
151 #define ST_FRAGSX (ST_X+138)
152 #define ST_FRAGSY (ST_Y+3)
153 //#define ST_FRAGSX 138
154 //#define ST_FRAGSY 171
155 #define ST_FRAGSWIDTH 2
157 // ARMOR number pos.
158 #define ST_ARMORWIDTH 3
159 // proff 08/18/98: Changed for high-res
160 #define ST_ARMORX (ST_X+221)
161 #define ST_ARMORY (ST_Y+3)
162 //#define ST_ARMORX 221
163 //#define ST_ARMORY 171
165 // Key icon positions.
166 #define ST_KEY0WIDTH 8
167 #define ST_KEY0HEIGHT 5
168 // proff 08/18/98: Changed for high-res
169 #define ST_KEY0X (ST_X+239)
170 #define ST_KEY0Y (ST_Y+3)
171 //#define ST_KEY0X 239
172 //#define ST_KEY0Y 171
173 #define ST_KEY1WIDTH ST_KEY0WIDTH
174 // proff 08/18/98: Changed for high-res
175 #define ST_KEY1X (ST_X+239)
176 #define ST_KEY1Y (ST_Y+13)
177 //#define ST_KEY1X 239
178 //#define ST_KEY1Y 181
179 #define ST_KEY2WIDTH ST_KEY0WIDTH
180 // proff 08/18/98: Changed for high-res
181 #define ST_KEY2X (ST_X+239)
182 #define ST_KEY2Y (ST_Y+23)
183 //#define ST_KEY2X 239
184 //#define ST_KEY2Y 191
186 // Ammunition counter.
187 #define ST_AMMO0WIDTH 3
188 #define ST_AMMO0HEIGHT 6
189 // proff 08/18/98: Changed for high-res
190 #define ST_AMMO0X (ST_X+288)
191 #define ST_AMMO0Y (ST_Y+5)
192 //#define ST_AMMO0X 288
193 //#define ST_AMMO0Y 173
194 #define ST_AMMO1WIDTH ST_AMMO0WIDTH
195 // proff 08/18/98: Changed for high-res
196 #define ST_AMMO1X (ST_X+288)
197 #define ST_AMMO1Y (ST_Y+11)
198 //#define ST_AMMO1X 288
199 //#define ST_AMMO1Y 179
200 #define ST_AMMO2WIDTH ST_AMMO0WIDTH
201 // proff 08/18/98: Changed for high-res
202 #define ST_AMMO2X (ST_X+288)
203 #define ST_AMMO2Y (ST_Y+23)
204 //#define ST_AMMO2X 288
205 //#define ST_AMMO2Y 191
206 #define ST_AMMO3WIDTH ST_AMMO0WIDTH
207 // proff 08/18/98: Changed for high-res
208 #define ST_AMMO3X (ST_X+288)
209 #define ST_AMMO3Y (ST_Y+17)
210 //#define ST_AMMO3X 288
211 //#define ST_AMMO3Y 185
213 // Indicate maximum ammunition.
214 // Only needed because backpack exists.
215 #define ST_MAXAMMO0WIDTH 3
216 #define ST_MAXAMMO0HEIGHT 5
217 // proff 08/18/98: Changed for high-res
218 #define ST_MAXAMMO0X (ST_X+314)
219 #define ST_MAXAMMO0Y (ST_Y+5)
220 //#define ST_MAXAMMO0X 314
221 //#define ST_MAXAMMO0Y 173
222 #define ST_MAXAMMO1WIDTH ST_MAXAMMO0WIDTH
223 // proff 08/18/98: Changed for high-res
224 #define ST_MAXAMMO1X (ST_X+314)
225 #define ST_MAXAMMO1Y (ST_Y+11)
226 //#define ST_MAXAMMO1X 314
227 //#define ST_MAXAMMO1Y 179
228 #define ST_MAXAMMO2WIDTH ST_MAXAMMO0WIDTH
229 // proff 08/18/98: Changed for high-res
230 #define ST_MAXAMMO2X (ST_X+314)
231 #define ST_MAXAMMO2Y (ST_Y+23)
232 //#define ST_MAXAMMO2X 314
233 //#define ST_MAXAMMO2Y 191
234 #define ST_MAXAMMO3WIDTH ST_MAXAMMO0WIDTH
235 // proff 08/18/98: Changed for high-res
236 #define ST_MAXAMMO3X (ST_X+314)
237 #define ST_MAXAMMO3Y (ST_Y+17)
238 //#define ST_MAXAMMO3X 314
239 //#define ST_MAXAMMO3Y 185
241 // killough 2/8/98: weapon info position macros UNUSED, removed here
243 // main player in game
244 static player_t *plyr;
246 // ST_Start() has just been called
247 static boolean st_firsttime;
249 // used to execute ST_Init() only once
250 static int veryfirsttime = 1;
252 // CPhipps - no longer do direct PLAYPAL handling here
254 // used for timing
255 static unsigned int st_clock;
257 // used for making messages go away
258 static int st_msgcounter=0;
260 // used when in chat
261 static st_chatstateenum_t st_chatstate;
263 // whether in automap or first-person
264 static st_stateenum_t st_gamestate;
266 // whether left-side main status bar is active
267 static boolean st_statusbaron;
269 // whether status bar chat is active
270 static boolean st_chat;
272 // value of st_chat before message popped up
273 static boolean st_oldchat;
275 // whether chat window has the cursor on
276 static boolean st_cursoron;
278 // !deathmatch
279 static boolean st_notdeathmatch;
281 // !deathmatch && st_statusbaron
282 static boolean st_armson;
284 // !deathmatch
285 static boolean st_fragson;
287 // main bar left
288 // CPhipps - convert to a bitmap
289 static byte *sbar;
290 static unsigned short sbar_width, sbar_height;
292 // 0-9, tall numbers
293 static patchnum_t tallnum[10];
295 // tall % sign
296 static patchnum_t tallpercent;
298 // 0-9, short, yellow (,different!) numbers
299 static patchnum_t shortnum[10];
301 // 3 key-cards, 3 skulls, 3 card/skull combos
302 // jff 2/24/98 extend number of patches by three skull/card combos
303 static patchnum_t keys[NUMCARDS+3];
305 // face status patches
306 static patchnum_t faces[ST_NUMFACES];
308 // face background
309 static patchnum_t faceback; // CPhipps - single background, translated for different players
311 // main bar right
312 static patchnum_t armsbg;
314 // weapon ownership patches
315 static patchnum_t arms[6][2];
317 // ready-weapon widget
318 static st_number_t w_ready;
320 //jff 2/16/98 status color change levels
321 int ammo_red; // ammo percent less than which status is red
322 int ammo_yellow; // ammo percent less is yellow more green
323 int health_red; // health amount less than which status is red
324 int health_yellow; // health amount less than which status is yellow
325 int health_green; // health amount above is blue, below is green
326 int armor_red; // armor amount less than which status is red
327 int armor_yellow; // armor amount less than which status is yellow
328 int armor_green; // armor amount above is blue, below is green
330 // in deathmatch only, summary of frags stats
331 static st_number_t w_frags;
333 // health widget
334 static st_percent_t w_health;
336 // arms background
337 static st_binicon_t w_armsbg;
339 // weapon ownership widgets
340 static st_multicon_t w_arms[6];
342 // face status widget
343 static st_multicon_t w_faces;
345 // keycard widgets
346 static st_multicon_t w_keyboxes[3];
348 // armor widget
349 static st_percent_t w_armor;
351 // ammo widgets
352 static st_number_t w_ammo[4];
354 // max ammo widgets
355 static st_number_t w_maxammo[4];
357 // number of frags so far in deathmatch
358 static int st_fragscount;
360 // used to use appopriately pained face
361 static int st_oldhealth = -1;
363 // used for evil grin
364 static boolean oldweaponsowned[NUMWEAPONS];
366 // count until face changes
367 static int st_facecount = 0;
369 // current face index, used by w_faces
370 static int st_faceindex = 0;
372 // holds key-type for each key box on bar
373 static int keyboxes[3];
375 // a random number per tick
376 static int st_randomnumber;
378 extern char *mapnames[];
382 // STATUS BAR CODE
384 void ST_Stop(void);
386 void ST_refreshBackground(void)
388 int y=0;
389 int screen=BG;
391 if (st_statusbaron)
393 V_DrawNamePatch(ST_X, y, screen, "STBAR", CR_DEFAULT, VPT_STRETCH);
395 // killough 3/7/98: make face background change with displayplayer
396 if (netgame)
398 V_DrawNumPatch(ST_FX, y, BG, faceback.lumpnum,
399 displayplayer ? CR_LIMIT+displayplayer : CR_DEFAULT,
400 displayplayer ? (VPT_TRANS | VPT_STRETCH) : VPT_STRETCH);
403 V_CopyRect(ST_X, y, screen, ST_SCALED_WIDTH, ST_SCALED_HEIGHT, ST_X, ST_SCALED_Y, FG, VPT_NONE);
408 // Respond to keyboard input events,
409 // intercept cheats.
410 boolean ST_Responder(event_t *ev)
412 // Filter automap on/off.
413 if (ev->type == ev_keyup && (ev->data1 & 0xffff0000) == AM_MSGHEADER)
415 switch(ev->data1)
417 case AM_MSGENTERED:
418 st_gamestate = AutomapState;
419 st_firsttime = true;
420 break;
422 case AM_MSGEXITED:
423 st_gamestate = FirstPersonState;
424 break;
427 // else // if a user keypress...
428 // if (ev->type == ev_keydown) // Try cheat responder in m_cheat.c
429 // return M_FindCheats(ev->data1); // killough 4/17/98, 5/2/98
430 return false;
433 int ST_calcPainOffset(void)
435 static int lastcalc;
436 static int oldhealth = -1;
437 int health = plyr->health > 100 ? 100 : plyr->health;
439 if (health != oldhealth)
441 lastcalc = ST_FACESTRIDE * (((100 - health) * ST_NUMPAINFACES) / 101);
442 oldhealth = health;
444 return lastcalc;
449 // This is a not-very-pretty routine which handles
450 // the face states and their timing.
451 // the precedence of expressions is:
452 // dead > evil grin > turned head > straight ahead
455 void ST_updateFaceWidget(void)
457 int i;
458 angle_t badguyangle;
459 angle_t diffang;
460 static int lastattackdown = -1;
461 static int priority = 0;
462 boolean doevilgrin;
464 if (priority < 10)
466 // dead
467 if (!plyr->health)
469 priority = 9;
470 st_faceindex = ST_DEADFACE;
471 st_facecount = 1;
475 if (priority < 9)
477 if (plyr->bonuscount)
479 // picking up bonus
480 doevilgrin = false;
482 for (i=0;i<NUMWEAPONS;i++)
484 if (oldweaponsowned[i] != plyr->weaponowned[i])
486 doevilgrin = true;
487 oldweaponsowned[i] = plyr->weaponowned[i];
490 if (doevilgrin)
492 // evil grin if just picked up weapon
493 priority = 8;
494 st_facecount = ST_EVILGRINCOUNT;
495 st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET;
501 if (priority < 8)
503 if (plyr->damagecount && plyr->attacker && plyr->attacker != plyr->mo)
505 // being attacked
506 priority = 7;
508 if (plyr->health - st_oldhealth > ST_MUCHPAIN)
510 st_facecount = ST_TURNCOUNT;
511 st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
513 else
515 badguyangle = R_PointToAngle2(plyr->mo->x,
516 plyr->mo->y,
517 plyr->attacker->x,
518 plyr->attacker->y);
520 if (badguyangle > plyr->mo->angle)
522 // whether right or left
523 diffang = badguyangle - plyr->mo->angle;
524 i = diffang > ANG180;
526 else
528 // whether left or right
529 diffang = plyr->mo->angle - badguyangle;
530 i = diffang <= ANG180;
531 } // confusing, aint it?
534 st_facecount = ST_TURNCOUNT;
535 st_faceindex = ST_calcPainOffset();
537 if (diffang < ANG45)
539 // head-on
540 st_faceindex += ST_RAMPAGEOFFSET;
542 else if (i)
544 // turn face right
545 st_faceindex += ST_TURNOFFSET;
547 else
549 // turn face left
550 st_faceindex += ST_TURNOFFSET+1;
556 if (priority < 7)
558 // getting hurt because of your own damn stupidity
559 if (plyr->damagecount)
561 if (plyr->health - st_oldhealth > ST_MUCHPAIN)
563 priority = 7;
564 st_facecount = ST_TURNCOUNT;
565 st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
567 else
569 priority = 6;
570 st_facecount = ST_TURNCOUNT;
571 st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
578 if (priority < 6)
580 // rapid firing
581 if (plyr->attackdown)
583 if (lastattackdown==-1)
584 lastattackdown = ST_RAMPAGEDELAY;
585 else if (!--lastattackdown)
587 priority = 5;
588 st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
589 st_facecount = 1;
590 lastattackdown = 1;
593 else
594 lastattackdown = -1;
598 if (priority < 5)
600 // invulnerability
601 if ((plyr->cheats & CF_GODMODE)
602 || plyr->powers[pw_invulnerability])
604 priority = 4;
606 st_faceindex = ST_GODFACE;
607 st_facecount = 1;
613 // look left or look right if the facecount has timed out
614 if (!st_facecount)
616 st_faceindex = ST_calcPainOffset() + (st_randomnumber % 3);
617 st_facecount = ST_STRAIGHTFACECOUNT;
618 priority = 0;
621 st_facecount--;
625 int sts_traditional_keys; // killough 2/28/98: traditional status bar keys
627 void ST_updateWidgets(void)
629 static int largeammo = 1994; // means "n/a"
630 int i;
632 // must redirect the pointer if the ready weapon has changed.
633 // if (w_ready.data != plyr->readyweapon)
634 // {
635 if (weaponinfo[plyr->readyweapon].ammo == am_noammo)
636 w_ready.num = &largeammo;
637 else
638 w_ready.num = &plyr->ammo[weaponinfo[plyr->readyweapon].ammo];
640 // static int tic=0;
641 // static int dir=-1;
642 // if (!(tic&15))
643 // plyr->ammo[weaponinfo[plyr->readyweapon].ammo]+=dir;
644 // if (plyr->ammo[weaponinfo[plyr->readyweapon].ammo] == -100)
645 // dir = 1;
646 // tic++;
647 // }
648 w_ready.data = plyr->readyweapon;
650 // if (*w_ready.on)
651 // STlib_updateNum(&w_ready, true);
652 // refresh weapon change
653 // }
655 // update keycard multiple widgets
656 for (i=0;i<3;i++)
658 keyboxes[i] = plyr->cards[i] ? i : -1;
660 //jff 2/24/98 select double key
661 //killough 2/28/98: preserve traditional keys by config option
663 if (plyr->cards[i+3])
664 keyboxes[i] = keyboxes[i]==-1 || sts_traditional_keys ? i+3 : i+6;
667 // refresh everything if this is him coming back to life
668 ST_updateFaceWidget();
670 // used by the w_armsbg widget
671 st_notdeathmatch = !deathmatch;
673 // used by w_arms[] widgets
674 st_armson = st_statusbaron && !deathmatch;
676 // used by w_frags widget
677 st_fragson = deathmatch && st_statusbaron;
678 st_fragscount = 0;
680 for (i=0 ; i<MAXPLAYERS ; i++)
682 if (i != displayplayer) // killough 3/7/98
683 st_fragscount += plyr->frags[i];
684 else
685 st_fragscount -= plyr->frags[i];
688 // get rid of chat window if up because of message
689 if (!--st_msgcounter)
690 st_chat = st_oldchat;
694 void ST_Ticker (void)
696 st_clock++;
697 st_randomnumber = M_Random();
698 ST_updateWidgets();
699 st_oldhealth = plyr->health;
702 static int st_palette = 0;
704 void ST_doPaletteStuff(void)
706 int palette;
707 int cnt = plyr->damagecount;
709 if (plyr->powers[pw_strength])
711 // slowly fade the berzerk out
712 int bzc = 12 - (plyr->powers[pw_strength]>>6);
713 if (bzc > cnt)
714 cnt = bzc;
717 if (cnt)
719 palette = (cnt+7)>>3;
720 if (palette >= NUMREDPALS)
721 palette = NUMREDPALS-1;
722 palette += STARTREDPALS;
724 else
725 if (plyr->bonuscount)
727 palette = (plyr->bonuscount+7)>>3;
728 if (palette >= NUMBONUSPALS)
729 palette = NUMBONUSPALS-1;
730 palette += STARTBONUSPALS;
732 else
733 if (plyr->powers[pw_ironfeet] > 4*32 || plyr->powers[pw_ironfeet] & 8)
734 palette = RADIATIONPAL;
735 else
736 palette = 0;
738 if (palette != st_palette)
739 V_SetPalette(st_palette = palette); // CPhipps - use new palette function
742 void ST_drawWidgets(boolean refresh)
744 int i;
746 // used by w_arms[] widgets
747 st_armson = st_statusbaron && !deathmatch;
749 // used by w_frags widget
750 st_fragson = deathmatch && st_statusbaron;
752 //jff 2/16/98 make color of ammo depend on amount
753 if (*w_ready.num*100 < ammo_red*plyr->maxammo[weaponinfo[w_ready.data].ammo])
754 STlib_updateNum(&w_ready, CR_RED, refresh);
755 else
756 if (*w_ready.num*100 <
757 ammo_yellow*plyr->maxammo[weaponinfo[w_ready.data].ammo])
758 STlib_updateNum(&w_ready, CR_GOLD, refresh);
759 else
760 STlib_updateNum(&w_ready, CR_GREEN, refresh);
762 for (i=0;i<4;i++)
764 STlib_updateNum(&w_ammo[i], CR_DEFAULT, refresh);
765 STlib_updateNum(&w_maxammo[i], CR_DEFAULT, refresh);
768 //jff 2/16/98 make color of health depend on amount
769 if (*w_health.n.num<health_red)
770 STlib_updatePercent(&w_health, CR_RED, refresh);
771 else if (*w_health.n.num<health_yellow)
772 STlib_updatePercent(&w_health, CR_GOLD, refresh);
773 else if (*w_health.n.num<=health_green)
774 STlib_updatePercent(&w_health, CR_GREEN, refresh);
775 else
776 STlib_updatePercent(&w_health, CR_BLUE2, refresh); //killough 2/28/98
778 //jff 2/16/98 make color of armor depend on amount
779 if (*w_armor.n.num<armor_red)
780 STlib_updatePercent(&w_armor, CR_RED, refresh);
781 else if (*w_armor.n.num<armor_yellow)
782 STlib_updatePercent(&w_armor, CR_GOLD, refresh);
783 else if (*w_armor.n.num<=armor_green)
784 STlib_updatePercent(&w_armor, CR_GREEN, refresh);
785 else
786 STlib_updatePercent(&w_armor, CR_BLUE2, refresh); //killough 2/28/98
788 STlib_updateBinIcon(&w_armsbg, refresh);
790 for (i=0;i<6;i++)
791 STlib_updateMultIcon(&w_arms[i], refresh);
793 STlib_updateMultIcon(&w_faces, refresh);
795 for (i=0;i<3;i++)
796 STlib_updateMultIcon(&w_keyboxes[i], refresh);
798 STlib_updateNum(&w_frags, CR_DEFAULT, refresh);
802 void ST_doRefresh(void)
805 st_firsttime = false;
807 // draw status bar background to off-screen buff
808 ST_refreshBackground();
810 // and refresh all widgets
811 ST_drawWidgets(true);
815 void ST_diffDraw(void)
817 // update all widgets
818 ST_drawWidgets(false);
821 void ST_Drawer(boolean st_statusbaron, boolean refresh)
823 /* cph - let status bar on be controlled
824 * completely by the call from D_Display
825 * proff - really do it
827 st_firsttime = st_firsttime || refresh;
829 ST_doPaletteStuff(); // Do red-/gold-shifts from damage/items
831 if (st_statusbaron) {
832 if (st_firsttime)
833 ST_doRefresh(); /* If just after ST_Start(), refresh all */
834 else
835 ST_diffDraw(); /* Otherwise, update as little as possible */
840 // ST_loadGraphics
842 // CPhipps - Loads graphics needed for status bar if doload is true,
843 // unloads them otherwise
845 static void ST_loadGraphics(boolean doload)
848 int i,facenum;
850 char namebuf[9];
851 // cph - macro that either acquires a pointer and lock for a lump, or
852 // unlocks it. var is referenced exactly once in either case, so ++ in arg works
854 #define LOADORFREE(var,name) \
855 if (!doload) { W_UnlockLumpName(name); var = NULL; } \
856 else var = (const patch_t*)W_CacheLumpName(name)
859 // Load the numbers, tall and short
860 for (i=0;i<10;i++)
862 snprintf(namebuf, sizeof(namebuf),"STTNUM%d", i);
863 R_SetPatchNum(&tallnum[i],namebuf);
865 snprintf(namebuf, sizeof(namebuf),"STYSNUM%d", i);
866 R_SetPatchNum(&shortnum[i],namebuf);
869 // Load percent key.
870 R_SetPatchNum(&tallpercent,"STTPRCNT");
872 // key cards
873 for (i=0;i<NUMCARDS+3;i++) //jff 2/23/98 show both keys too
875 snprintf(namebuf, sizeof(namebuf), "STKEYS%d", i);
876 R_SetPatchNum(&keys[i], namebuf);
879 // arms background
880 R_SetPatchNum(&armsbg, "STARMS");
882 // arms ownership widgets
883 for (i=0;i<6;i++)
885 snprintf(namebuf, sizeof(namebuf),"STGNUM%d", i+2);
886 // gray #
887 R_SetPatchNum(&arms[i][0], namebuf);
889 // yellow #
890 arms[i][1] = shortnum[i+2];
893 // face backgrounds for different color players
894 // killough 3/7/98: add better support for spy mode by loading all
895 // player face backgrounds and using displayplayer to choose them:
896 R_SetPatchNum(&faceback, "STFB0");
898 // status bar background bits
899 if (doload)
900 sbar = V_PatchToBlock("STBAR", CR_DEFAULT, VPT_NONE,
901 &sbar_width, &sbar_height);
902 else {
903 free(sbar); sbar=NULL;
906 // face states
907 facenum = 0;
908 for (i=0;i<ST_NUMPAINFACES;i++)
910 int j;
911 for (j=0;j<ST_NUMSTRAIGHTFACES;j++)
913 snprintf(namebuf, sizeof(namebuf), "STFST%d%d", i, j);
914 R_SetPatchNum(&faces[facenum++], namebuf);
916 snprintf(namebuf, sizeof(namebuf), "STFTR%d0", i); // turn right
917 R_SetPatchNum(&faces[facenum++], namebuf);
918 snprintf(namebuf, sizeof(namebuf), "STFTL%d0", i); // turn left
919 R_SetPatchNum(&faces[facenum++], namebuf);
920 snprintf(namebuf, sizeof(namebuf), "STFOUCH%d", i); // ouch!
921 R_SetPatchNum(&faces[facenum++], namebuf);
922 snprintf(namebuf, sizeof(namebuf), "STFEVL%d", i); // evil grin ;)
923 R_SetPatchNum(&faces[facenum++], namebuf);
924 snprintf(namebuf, sizeof(namebuf), "STFKILL%d", i); // pissed off
925 R_SetPatchNum(&faces[facenum++], namebuf);
927 R_SetPatchNum(&faces[facenum++], "STFGOD0");
928 R_SetPatchNum(&faces[facenum++], "STFDEAD0");
931 void ST_loadData(void)
933 ST_loadGraphics(true);
936 void ST_unloadData(void)
938 ST_loadGraphics(false);
941 void ST_initData(void)
943 int i;
945 st_firsttime = true;
946 plyr = &players[displayplayer]; // killough 3/7/98
948 st_clock = 0;
949 st_chatstate = StartChatState;
950 st_gamestate = FirstPersonState;
952 st_statusbaron = true;
953 st_oldchat = st_chat = false;
954 st_cursoron = false;
956 st_faceindex = 0;
957 st_palette = -1;
959 st_oldhealth = -1;
961 for (i=0;i<NUMWEAPONS;i++)
962 oldweaponsowned[i] = plyr->weaponowned[i];
964 for (i=0;i<3;i++)
965 keyboxes[i] = -1;
967 STlib_init();
970 void ST_createWidgets(void)
972 int i;
974 // ready weapon ammo
975 STlib_initNum(&w_ready,
976 ST_AMMOX,
977 ST_AMMOY,
978 tallnum,
979 &plyr->ammo[weaponinfo[plyr->readyweapon].ammo],
980 &st_statusbaron,
981 ST_AMMOWIDTH );
983 // the last weapon type
984 w_ready.data = plyr->readyweapon;
986 // health percentage
987 STlib_initPercent(&w_health,
988 ST_HEALTHX,
989 ST_HEALTHY,
990 tallnum,
991 &plyr->health,
992 &st_statusbaron,
993 &tallpercent);
995 // arms background
996 STlib_initBinIcon(&w_armsbg,
997 ST_ARMSBGX,
998 ST_ARMSBGY,
999 &armsbg,
1000 &st_notdeathmatch,
1001 &st_statusbaron);
1003 // weapons owned
1004 for(i=0;i<6;i++)
1006 STlib_initMultIcon(&w_arms[i],
1007 ST_ARMSX+(i%3)*ST_ARMSXSPACE,
1008 ST_ARMSY+(i/3)*ST_ARMSYSPACE,
1009 arms[i], (int *) &plyr->weaponowned[i+1],
1010 &st_armson);
1013 // frags sum
1014 STlib_initNum(&w_frags,
1015 ST_FRAGSX,
1016 ST_FRAGSY,
1017 tallnum,
1018 &st_fragscount,
1019 &st_fragson,
1020 ST_FRAGSWIDTH);
1022 // faces
1023 STlib_initMultIcon(&w_faces,
1024 ST_FACESX,
1025 ST_FACESY,
1026 faces,
1027 &st_faceindex,
1028 &st_statusbaron);
1030 // armor percentage - should be colored later
1031 STlib_initPercent(&w_armor,
1032 ST_ARMORX,
1033 ST_ARMORY,
1034 tallnum,
1035 &plyr->armorpoints,
1036 &st_statusbaron, &tallpercent);
1038 // keyboxes 0-2
1039 STlib_initMultIcon(&w_keyboxes[0],
1040 ST_KEY0X,
1041 ST_KEY0Y,
1042 keys,
1043 &keyboxes[0],
1044 &st_statusbaron);
1046 STlib_initMultIcon(&w_keyboxes[1],
1047 ST_KEY1X,
1048 ST_KEY1Y,
1049 keys,
1050 &keyboxes[1],
1051 &st_statusbaron);
1053 STlib_initMultIcon(&w_keyboxes[2],
1054 ST_KEY2X,
1055 ST_KEY2Y,
1056 keys,
1057 &keyboxes[2],
1058 &st_statusbaron);
1060 // ammo count (all four kinds)
1061 STlib_initNum(&w_ammo[0],
1062 ST_AMMO0X,
1063 ST_AMMO0Y,
1064 shortnum,
1065 &plyr->ammo[0],
1066 &st_statusbaron,
1067 ST_AMMO0WIDTH);
1069 STlib_initNum(&w_ammo[1],
1070 ST_AMMO1X,
1071 ST_AMMO1Y,
1072 shortnum,
1073 &plyr->ammo[1],
1074 &st_statusbaron,
1075 ST_AMMO1WIDTH);
1077 STlib_initNum(&w_ammo[2],
1078 ST_AMMO2X,
1079 ST_AMMO2Y,
1080 shortnum,
1081 &plyr->ammo[2],
1082 &st_statusbaron,
1083 ST_AMMO2WIDTH);
1085 STlib_initNum(&w_ammo[3],
1086 ST_AMMO3X,
1087 ST_AMMO3Y,
1088 shortnum,
1089 &plyr->ammo[3],
1090 &st_statusbaron,
1091 ST_AMMO3WIDTH);
1093 // max ammo count (all four kinds)
1094 STlib_initNum(&w_maxammo[0],
1095 ST_MAXAMMO0X,
1096 ST_MAXAMMO0Y,
1097 shortnum,
1098 &plyr->maxammo[0],
1099 &st_statusbaron,
1100 ST_MAXAMMO0WIDTH);
1102 STlib_initNum(&w_maxammo[1],
1103 ST_MAXAMMO1X,
1104 ST_MAXAMMO1Y,
1105 shortnum,
1106 &plyr->maxammo[1],
1107 &st_statusbaron,
1108 ST_MAXAMMO1WIDTH);
1110 STlib_initNum(&w_maxammo[2],
1111 ST_MAXAMMO2X,
1112 ST_MAXAMMO2Y,
1113 shortnum,
1114 &plyr->maxammo[2],
1115 &st_statusbaron,
1116 ST_MAXAMMO2WIDTH);
1118 STlib_initNum(&w_maxammo[3],
1119 ST_MAXAMMO3X,
1120 ST_MAXAMMO3Y,
1121 shortnum,
1122 &plyr->maxammo[3],
1123 &st_statusbaron,
1124 ST_MAXAMMO3WIDTH);
1127 static boolean st_stopped = true;
1129 void ST_Start(void)
1131 if (!st_stopped)
1132 ST_Stop();
1133 ST_initData();
1134 ST_createWidgets();
1135 st_stopped = false;
1138 void ST_Stop(void)
1140 if (st_stopped)
1141 return;
1142 V_SetPalette(0);
1143 st_stopped = true;
1146 void ST_Init(void)
1148 veryfirsttime = 0;
1149 ST_loadData();
1150 // proff 08/18/98: Changed for high-res
1151 d_screens[4] = Z_Malloc(SCREENWIDTH*(ST_SCALED_HEIGHT+1), PU_STATIC, 0);
1152 // d_screens[4] = Z_Malloc(ST_WIDTH*ST_HEIGHT, PU_STATIC, 0);