summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/st_stuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/doom/st_stuff.c')
-rw-r--r--apps/plugins/doom/st_stuff.c1153
1 files changed, 1153 insertions, 0 deletions
diff --git a/apps/plugins/doom/st_stuff.c b/apps/plugins/doom/st_stuff.c
new file mode 100644
index 0000000000..5d9244d951
--- /dev/null
+++ b/apps/plugins/doom/st_stuff.c
@@ -0,0 +1,1153 @@
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 *
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.
16 *
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.
21 *
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.
26 *
27 * DESCRIPTION:
28 * Status bar code.
29 * Does the face/direction indicator animatin.
30 * Does palette indicators as well (red pain/berserk, bright pickup)
31 *
32 *-----------------------------------------------------------------------------*/
33
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"
48
49//
50// STATUS BAR DATA
51//
52
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
61
62// Location of status bar
63#define ST_X 0
64#define ST_X2 104
65
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
71
72// Should be set to patch width
73// for tall numbers later on
74#define ST_TALLNUMWIDTH (tallnum[0]->width)
75
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
81
82#define ST_FACESTRIDE \
83 (ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES)
84
85#define ST_NUMEXTRAFACES 2
86
87#define ST_NUMFACES \
88 (ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES)
89
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)
96
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
102
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)
108
109#define ST_MUCHPAIN 20
110
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
119
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
127
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
135
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
148
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
156
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
164
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
185
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
212
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
240
241// killough 2/8/98: weapon info position macros UNUSED, removed here
242
243// main player in game
244static player_t *plyr;
245
246// ST_Start() has just been called
247static boolean st_firsttime;
248
249// used to execute ST_Init() only once
250static int veryfirsttime = 1;
251
252// CPhipps - no longer do direct PLAYPAL handling here
253
254// used for timing
255static unsigned int st_clock;
256
257// used for making messages go away
258static int st_msgcounter=0;
259
260// used when in chat
261static st_chatstateenum_t st_chatstate;
262
263// whether in automap or first-person
264static st_stateenum_t st_gamestate;
265
266// whether left-side main status bar is active
267static boolean st_statusbaron;
268
269// whether status bar chat is active
270static boolean st_chat;
271
272// value of st_chat before message popped up
273static boolean st_oldchat;
274
275// whether chat window has the cursor on
276static boolean st_cursoron;
277
278// !deathmatch
279static boolean st_notdeathmatch;
280
281// !deathmatch && st_statusbaron
282static boolean st_armson;
283
284// !deathmatch
285static boolean st_fragson;
286
287// main bar left
288// CPhipps - convert to a bitmap
289static byte *sbar;
290static unsigned short sbar_width, sbar_height;
291
292// 0-9, tall numbers
293static patchnum_t tallnum[10];
294
295// tall % sign
296static patchnum_t tallpercent;
297
298// 0-9, short, yellow (,different!) numbers
299static patchnum_t shortnum[10];
300
301// 3 key-cards, 3 skulls, 3 card/skull combos
302// jff 2/24/98 extend number of patches by three skull/card combos
303static patchnum_t keys[NUMCARDS+3];
304
305// face status patches
306static patchnum_t faces[ST_NUMFACES];
307
308// face background
309static patchnum_t faceback; // CPhipps - single background, translated for different players
310
311// main bar right
312static patchnum_t armsbg;
313
314// weapon ownership patches
315static patchnum_t arms[6][2];
316
317// ready-weapon widget
318static st_number_t w_ready;
319
320//jff 2/16/98 status color change levels
321int ammo_red; // ammo percent less than which status is red
322int ammo_yellow; // ammo percent less is yellow more green
323int health_red; // health amount less than which status is red
324int health_yellow; // health amount less than which status is yellow
325int health_green; // health amount above is blue, below is green
326int armor_red; // armor amount less than which status is red
327int armor_yellow; // armor amount less than which status is yellow
328int armor_green; // armor amount above is blue, below is green
329
330// in deathmatch only, summary of frags stats
331static st_number_t w_frags;
332
333// health widget
334static st_percent_t w_health;
335
336// arms background
337static st_binicon_t w_armsbg;
338
339// weapon ownership widgets
340static st_multicon_t w_arms[6];
341
342// face status widget
343static st_multicon_t w_faces;
344
345// keycard widgets
346static st_multicon_t w_keyboxes[3];
347
348// armor widget
349static st_percent_t w_armor;
350
351// ammo widgets
352static st_number_t w_ammo[4];
353
354// max ammo widgets
355static st_number_t w_maxammo[4];
356
357// number of frags so far in deathmatch
358static int st_fragscount;
359
360// used to use appopriately pained face
361static int st_oldhealth = -1;
362
363// used for evil grin
364static boolean oldweaponsowned[NUMWEAPONS];
365
366// count until face changes
367static int st_facecount = 0;
368
369// current face index, used by w_faces
370static int st_faceindex = 0;
371
372// holds key-type for each key box on bar
373static int keyboxes[3];
374
375// a random number per tick
376static int st_randomnumber;
377
378extern char *mapnames[];
379
380
381//
382// STATUS BAR CODE
383//
384void ST_Stop(void);
385
386void ST_refreshBackground(void)
387{
388 int y=0;
389 int screen=BG;
390
391 if (st_statusbaron)
392 {
393 V_DrawNamePatch(ST_X, y, screen, "STBAR", CR_DEFAULT, VPT_STRETCH);
394
395 // killough 3/7/98: make face background change with displayplayer
396 if (netgame)
397 {
398 V_DrawNumPatch(ST_FX, y, BG, faceback.lumpnum,
399 displayplayer ? CR_LIMIT+displayplayer : CR_DEFAULT,
400 displayplayer ? (VPT_TRANS | VPT_STRETCH) : VPT_STRETCH);
401 }
402
403 V_CopyRect(ST_X, y, screen, ST_SCALED_WIDTH, ST_SCALED_HEIGHT, ST_X, ST_SCALED_Y, FG, VPT_NONE);
404 }
405}
406
407
408// Respond to keyboard input events,
409// intercept cheats.
410boolean ST_Responder(event_t *ev)
411{
412 // Filter automap on/off.
413 if (ev->type == ev_keyup && (ev->data1 & 0xffff0000) == AM_MSGHEADER)
414 {
415 switch(ev->data1)
416 {
417 case AM_MSGENTERED:
418 st_gamestate = AutomapState;
419 st_firsttime = true;
420 break;
421
422 case AM_MSGEXITED:
423 st_gamestate = FirstPersonState;
424 break;
425 }
426 }
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;
431}
432
433int ST_calcPainOffset(void)
434{
435 static int lastcalc;
436 static int oldhealth = -1;
437 int health = plyr->health > 100 ? 100 : plyr->health;
438
439 if (health != oldhealth)
440 {
441 lastcalc = ST_FACESTRIDE * (((100 - health) * ST_NUMPAINFACES) / 101);
442 oldhealth = health;
443 }
444 return lastcalc;
445}
446
447
448//
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
453//
454
455void ST_updateFaceWidget(void)
456{
457 int i;
458 angle_t badguyangle;
459 angle_t diffang;
460 static int lastattackdown = -1;
461 static int priority = 0;
462 boolean doevilgrin;
463
464 if (priority < 10)
465 {
466 // dead
467 if (!plyr->health)
468 {
469 priority = 9;
470 st_faceindex = ST_DEADFACE;
471 st_facecount = 1;
472 }
473 }
474
475 if (priority < 9)
476 {
477 if (plyr->bonuscount)
478 {
479 // picking up bonus
480 doevilgrin = false;
481
482 for (i=0;i<NUMWEAPONS;i++)
483 {
484 if (oldweaponsowned[i] != plyr->weaponowned[i])
485 {
486 doevilgrin = true;
487 oldweaponsowned[i] = plyr->weaponowned[i];
488 }
489 }
490 if (doevilgrin)
491 {
492 // evil grin if just picked up weapon
493 priority = 8;
494 st_facecount = ST_EVILGRINCOUNT;
495 st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET;
496 }
497 }
498
499 }
500
501 if (priority < 8)
502 {
503 if (plyr->damagecount && plyr->attacker && plyr->attacker != plyr->mo)
504 {
505 // being attacked
506 priority = 7;
507
508 if (plyr->health - st_oldhealth > ST_MUCHPAIN)
509 {
510 st_facecount = ST_TURNCOUNT;
511 st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
512 }
513 else
514 {
515 badguyangle = R_PointToAngle2(plyr->mo->x,
516 plyr->mo->y,
517 plyr->attacker->x,
518 plyr->attacker->y);
519
520 if (badguyangle > plyr->mo->angle)
521 {
522 // whether right or left
523 diffang = badguyangle - plyr->mo->angle;
524 i = diffang > ANG180;
525 }
526 else
527 {
528 // whether left or right
529 diffang = plyr->mo->angle - badguyangle;
530 i = diffang <= ANG180;
531 } // confusing, aint it?
532
533
534 st_facecount = ST_TURNCOUNT;
535 st_faceindex = ST_calcPainOffset();
536
537 if (diffang < ANG45)
538 {
539 // head-on
540 st_faceindex += ST_RAMPAGEOFFSET;
541 }
542 else if (i)
543 {
544 // turn face right
545 st_faceindex += ST_TURNOFFSET;
546 }
547 else
548 {
549 // turn face left
550 st_faceindex += ST_TURNOFFSET+1;
551 }
552 }
553 }
554 }
555
556 if (priority < 7)
557 {
558 // getting hurt because of your own damn stupidity
559 if (plyr->damagecount)
560 {
561 if (plyr->health - st_oldhealth > ST_MUCHPAIN)
562 {
563 priority = 7;
564 st_facecount = ST_TURNCOUNT;
565 st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
566 }
567 else
568 {
569 priority = 6;
570 st_facecount = ST_TURNCOUNT;
571 st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
572 }
573
574 }
575
576 }
577
578 if (priority < 6)
579 {
580 // rapid firing
581 if (plyr->attackdown)
582 {
583 if (lastattackdown==-1)
584 lastattackdown = ST_RAMPAGEDELAY;
585 else if (!--lastattackdown)
586 {
587 priority = 5;
588 st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
589 st_facecount = 1;
590 lastattackdown = 1;
591 }
592 }
593 else
594 lastattackdown = -1;
595
596 }
597
598 if (priority < 5)
599 {
600 // invulnerability
601 if ((plyr->cheats & CF_GODMODE)
602 || plyr->powers[pw_invulnerability])
603 {
604 priority = 4;
605
606 st_faceindex = ST_GODFACE;
607 st_facecount = 1;
608
609 }
610
611 }
612
613 // look left or look right if the facecount has timed out
614 if (!st_facecount)
615 {
616 st_faceindex = ST_calcPainOffset() + (st_randomnumber % 3);
617 st_facecount = ST_STRAIGHTFACECOUNT;
618 priority = 0;
619 }
620
621 st_facecount--;
622
623}
624
625int sts_traditional_keys; // killough 2/28/98: traditional status bar keys
626
627void ST_updateWidgets(void)
628{
629 static int largeammo = 1994; // means "n/a"
630 int i;
631
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];
639 //{
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;
649
650 // if (*w_ready.on)
651 // STlib_updateNum(&w_ready, true);
652 // refresh weapon change
653 // }
654
655 // update keycard multiple widgets
656 for (i=0;i<3;i++)
657 {
658 keyboxes[i] = plyr->cards[i] ? i : -1;
659
660 //jff 2/24/98 select double key
661 //killough 2/28/98: preserve traditional keys by config option
662
663 if (plyr->cards[i+3])
664 keyboxes[i] = keyboxes[i]==-1 || sts_traditional_keys ? i+3 : i+6;
665 }
666
667 // refresh everything if this is him coming back to life
668 ST_updateFaceWidget();
669
670 // used by the w_armsbg widget
671 st_notdeathmatch = !deathmatch;
672
673 // used by w_arms[] widgets
674 st_armson = st_statusbaron && !deathmatch;
675
676 // used by w_frags widget
677 st_fragson = deathmatch && st_statusbaron;
678 st_fragscount = 0;
679
680 for (i=0 ; i<MAXPLAYERS ; i++)
681 {
682 if (i != displayplayer) // killough 3/7/98
683 st_fragscount += plyr->frags[i];
684 else
685 st_fragscount -= plyr->frags[i];
686 }
687
688 // get rid of chat window if up because of message
689 if (!--st_msgcounter)
690 st_chat = st_oldchat;
691
692}
693
694void ST_Ticker (void)
695{
696 st_clock++;
697 st_randomnumber = M_Random();
698 ST_updateWidgets();
699 st_oldhealth = plyr->health;
700}
701
702static int st_palette = 0;
703
704void ST_doPaletteStuff(void)
705{
706 int palette;
707 int cnt = plyr->damagecount;
708
709 if (plyr->powers[pw_strength])
710 {
711 // slowly fade the berzerk out
712 int bzc = 12 - (plyr->powers[pw_strength]>>6);
713 if (bzc > cnt)
714 cnt = bzc;
715 }
716
717 if (cnt)
718 {
719 palette = (cnt+7)>>3;
720 if (palette >= NUMREDPALS)
721 palette = NUMREDPALS-1;
722 palette += STARTREDPALS;
723 }
724 else
725 if (plyr->bonuscount)
726 {
727 palette = (plyr->bonuscount+7)>>3;
728 if (palette >= NUMBONUSPALS)
729 palette = NUMBONUSPALS-1;
730 palette += STARTBONUSPALS;
731 }
732 else
733 if (plyr->powers[pw_ironfeet] > 4*32 || plyr->powers[pw_ironfeet] & 8)
734 palette = RADIATIONPAL;
735 else
736 palette = 0;
737
738 if (palette != st_palette)
739 V_SetPalette(st_palette = palette); // CPhipps - use new palette function
740}
741
742void ST_drawWidgets(boolean refresh)
743{
744 int i;
745
746 // used by w_arms[] widgets
747 st_armson = st_statusbaron && !deathmatch;
748
749 // used by w_frags widget
750 st_fragson = deathmatch && st_statusbaron;
751
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);
761
762 for (i=0;i<4;i++)
763 {
764 STlib_updateNum(&w_ammo[i], CR_DEFAULT, refresh);
765 STlib_updateNum(&w_maxammo[i], CR_DEFAULT, refresh);
766 }
767
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
777
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
787
788 STlib_updateBinIcon(&w_armsbg, refresh);
789
790 for (i=0;i<6;i++)
791 STlib_updateMultIcon(&w_arms[i], refresh);
792
793 STlib_updateMultIcon(&w_faces, refresh);
794
795 for (i=0;i<3;i++)
796 STlib_updateMultIcon(&w_keyboxes[i], refresh);
797
798 STlib_updateNum(&w_frags, CR_DEFAULT, refresh);
799
800}
801
802void ST_doRefresh(void)
803{
804
805 st_firsttime = false;
806
807 // draw status bar background to off-screen buff
808 ST_refreshBackground();
809
810 // and refresh all widgets
811 ST_drawWidgets(true);
812
813}
814
815void ST_diffDraw(void)
816{
817 // update all widgets
818 ST_drawWidgets(false);
819}
820
821void ST_Drawer(boolean st_statusbaron, boolean refresh)
822{
823 /* cph - let status bar on be controlled
824 * completely by the call from D_Display
825 * proff - really do it
826 */
827 st_firsttime = st_firsttime || refresh;
828
829 ST_doPaletteStuff(); // Do red-/gold-shifts from damage/items
830
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 */
836 }
837}
838
839//
840// ST_loadGraphics
841//
842// CPhipps - Loads graphics needed for status bar if doload is true,
843// unloads them otherwise
844//
845static void ST_loadGraphics(boolean doload)
846{
847
848 int i,facenum;
849
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
853 /*
854 #define LOADORFREE(var,name) \
855 if (!doload) { W_UnlockLumpName(name); var = NULL; } \
856 else var = (const patch_t*)W_CacheLumpName(name)
857 */
858
859 // Load the numbers, tall and short
860 for (i=0;i<10;i++)
861 {
862 snprintf(namebuf, sizeof(namebuf),"STTNUM%d", i);
863 R_SetPatchNum(&tallnum[i],namebuf);
864
865 snprintf(namebuf, sizeof(namebuf),"STYSNUM%d", i);
866 R_SetPatchNum(&shortnum[i],namebuf);
867 }
868
869 // Load percent key.
870 R_SetPatchNum(&tallpercent,"STTPRCNT");
871
872 // key cards
873 for (i=0;i<NUMCARDS+3;i++) //jff 2/23/98 show both keys too
874 {
875 snprintf(namebuf, sizeof(namebuf), "STKEYS%d", i);
876 R_SetPatchNum(&keys[i], namebuf);
877 }
878
879 // arms background
880 R_SetPatchNum(&armsbg, "STARMS");
881
882 // arms ownership widgets
883 for (i=0;i<6;i++)
884 {
885 snprintf(namebuf, sizeof(namebuf),"STGNUM%d", i+2);
886 // gray #
887 R_SetPatchNum(&arms[i][0], namebuf);
888
889 // yellow #
890 arms[i][1] = shortnum[i+2];
891 }
892
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");
897
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;
904 }
905
906 // face states
907 facenum = 0;
908 for (i=0;i<ST_NUMPAINFACES;i++)
909 {
910 int j;
911 for (j=0;j<ST_NUMSTRAIGHTFACES;j++)
912 {
913 snprintf(namebuf, sizeof(namebuf), "STFST%d%d", i, j);
914 R_SetPatchNum(&faces[facenum++], namebuf);
915 }
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);
926 }
927 R_SetPatchNum(&faces[facenum++], "STFGOD0");
928 R_SetPatchNum(&faces[facenum++], "STFDEAD0");
929}
930
931void ST_loadData(void)
932{
933 ST_loadGraphics(true);
934}
935
936void ST_unloadData(void)
937{
938 ST_loadGraphics(false);
939}
940
941void ST_initData(void)
942{
943 int i;
944
945 st_firsttime = true;
946 plyr = &players[displayplayer]; // killough 3/7/98
947
948 st_clock = 0;
949 st_chatstate = StartChatState;
950 st_gamestate = FirstPersonState;
951
952 st_statusbaron = true;
953 st_oldchat = st_chat = false;
954 st_cursoron = false;
955
956 st_faceindex = 0;
957 st_palette = -1;
958
959 st_oldhealth = -1;
960
961 for (i=0;i<NUMWEAPONS;i++)
962 oldweaponsowned[i] = plyr->weaponowned[i];
963
964 for (i=0;i<3;i++)
965 keyboxes[i] = -1;
966
967 STlib_init();
968}
969
970void ST_createWidgets(void)
971{
972 int i;
973
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 );
982
983 // the last weapon type
984 w_ready.data = plyr->readyweapon;
985
986 // health percentage
987 STlib_initPercent(&w_health,
988 ST_HEALTHX,
989 ST_HEALTHY,
990 tallnum,
991 &plyr->health,
992 &st_statusbaron,
993 &tallpercent);
994
995 // arms background
996 STlib_initBinIcon(&w_armsbg,
997 ST_ARMSBGX,
998 ST_ARMSBGY,
999 &armsbg,
1000 &st_notdeathmatch,
1001 &st_statusbaron);
1002
1003 // weapons owned
1004 for(i=0;i<6;i++)
1005 {
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);
1011 }
1012
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);
1021
1022 // faces
1023 STlib_initMultIcon(&w_faces,
1024 ST_FACESX,
1025 ST_FACESY,
1026 faces,
1027 &st_faceindex,
1028 &st_statusbaron);
1029
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);
1037
1038 // keyboxes 0-2
1039 STlib_initMultIcon(&w_keyboxes[0],
1040 ST_KEY0X,
1041 ST_KEY0Y,
1042 keys,
1043 &keyboxes[0],
1044 &st_statusbaron);
1045
1046 STlib_initMultIcon(&w_keyboxes[1],
1047 ST_KEY1X,
1048 ST_KEY1Y,
1049 keys,
1050 &keyboxes[1],
1051 &st_statusbaron);
1052
1053 STlib_initMultIcon(&w_keyboxes[2],
1054 ST_KEY2X,
1055 ST_KEY2Y,
1056 keys,
1057 &keyboxes[2],
1058 &st_statusbaron);
1059
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);
1068
1069 STlib_initNum(&w_ammo[1],
1070 ST_AMMO1X,
1071 ST_AMMO1Y,
1072 shortnum,
1073 &plyr->ammo[1],
1074 &st_statusbaron,
1075 ST_AMMO1WIDTH);
1076
1077 STlib_initNum(&w_ammo[2],
1078 ST_AMMO2X,
1079 ST_AMMO2Y,
1080 shortnum,
1081 &plyr->ammo[2],
1082 &st_statusbaron,
1083 ST_AMMO2WIDTH);
1084
1085 STlib_initNum(&w_ammo[3],
1086 ST_AMMO3X,
1087 ST_AMMO3Y,
1088 shortnum,
1089 &plyr->ammo[3],
1090 &st_statusbaron,
1091 ST_AMMO3WIDTH);
1092
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);
1101
1102 STlib_initNum(&w_maxammo[1],
1103 ST_MAXAMMO1X,
1104 ST_MAXAMMO1Y,
1105 shortnum,
1106 &plyr->maxammo[1],
1107 &st_statusbaron,
1108 ST_MAXAMMO1WIDTH);
1109
1110 STlib_initNum(&w_maxammo[2],
1111 ST_MAXAMMO2X,
1112 ST_MAXAMMO2Y,
1113 shortnum,
1114 &plyr->maxammo[2],
1115 &st_statusbaron,
1116 ST_MAXAMMO2WIDTH);
1117
1118 STlib_initNum(&w_maxammo[3],
1119 ST_MAXAMMO3X,
1120 ST_MAXAMMO3Y,
1121 shortnum,
1122 &plyr->maxammo[3],
1123 &st_statusbaron,
1124 ST_MAXAMMO3WIDTH);
1125}
1126
1127static boolean st_stopped = true;
1128
1129void ST_Start(void)
1130{
1131 if (!st_stopped)
1132 ST_Stop();
1133 ST_initData();
1134 ST_createWidgets();
1135 st_stopped = false;
1136}
1137
1138void ST_Stop(void)
1139{
1140 if (st_stopped)
1141 return;
1142 V_SetPalette(0);
1143 st_stopped = true;
1144}
1145
1146void ST_Init(void)
1147{
1148 veryfirsttime = 0;
1149 ST_loadData();
1150 // proff 08/18/98: Changed for high-res
1151 screens[4] = Z_Malloc(SCREENWIDTH*(ST_SCALED_HEIGHT+1), PU_STATIC, 0);
1152 // screens[4] = Z_Malloc(ST_WIDTH*ST_HEIGHT, PU_STATIC, 0);
1153}