summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/sbar.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2018-02-11 15:34:30 -0500
committerFranklin Wei <git@fwei.tk>2019-07-19 22:37:40 -0400
commit5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4 (patch)
tree84406e21639529a185556a33e5de7f43cffc277b /apps/plugins/sdl/progs/quake/sbar.c
parentb70fecf21ddc21877ec1ae7888d9c18a979e37ad (diff)
downloadrockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.tar.gz
rockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.zip
Quake!
This ports id Software's Quake to run on the SDL plugin runtime. The source code originated from id under the GPLv2 license. I used https://github.com/ahefner/sdlquake as the base of my port. Performance is, unsurprisingly, not on par with what you're probably used to on PC. I average about 10FPS on ipod6g, but it's still playable. Sound works well enough, but in-game music is not supported. I've written ARM assembly routines for the inner sound loop. Make sure you turn the "brightness" all the way down, or colors will look funky. To run, extract Quake's data files to /.rockbox/quake. Have fun! Change-Id: I4285036e967d7f0722802d43cf2096c808ca5799
Diffstat (limited to 'apps/plugins/sdl/progs/quake/sbar.c')
-rw-r--r--apps/plugins/sdl/progs/quake/sbar.c1323
1 files changed, 1323 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/sbar.c b/apps/plugins/sdl/progs/quake/sbar.c
new file mode 100644
index 0000000000..be9ec9cd75
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/sbar.c
@@ -0,0 +1,1323 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20// sbar.c -- status bar code
21
22#include "quakedef.h"
23
24
25int sb_updates; // if >= vid.numpages, no update needed
26
27#define STAT_MINUS 10 // num frame for '-' stats digit
28qpic_t *sb_nums[2][11];
29qpic_t *sb_colon, *sb_slash;
30qpic_t *sb_ibar;
31qpic_t *sb_sbar;
32qpic_t *sb_scorebar;
33
34qpic_t *sb_weapons[7][8]; // 0 is active, 1 is owned, 2-5 are flashes
35qpic_t *sb_ammo[4];
36qpic_t *sb_sigil[4];
37qpic_t *sb_armor[3];
38qpic_t *sb_items[32];
39
40qpic_t *sb_faces[7][2]; // 0 is gibbed, 1 is dead, 2-6 are alive
41 // 0 is static, 1 is temporary animation
42qpic_t *sb_face_invis;
43qpic_t *sb_face_quad;
44qpic_t *sb_face_invuln;
45qpic_t *sb_face_invis_invuln;
46
47qboolean sb_showscores;
48
49int sb_lines; // scan lines to draw
50
51qpic_t *rsb_invbar[2];
52qpic_t *rsb_weapons[5];
53qpic_t *rsb_items[2];
54qpic_t *rsb_ammo[3];
55qpic_t *rsb_teambord; // PGM 01/19/97 - team color border
56
57//MED 01/04/97 added two more weapons + 3 alternates for grenade launcher
58qpic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes
59//MED 01/04/97 added array to simplify weapon parsing
60int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT};
61//MED 01/04/97 added hipnotic items array
62qpic_t *hsb_items[2];
63
64void Sbar_MiniDeathmatchOverlay (void);
65void Sbar_DeathmatchOverlay (void);
66void M_DrawPic (int x, int y, qpic_t *pic);
67
68/*
69===============
70Sbar_ShowScores
71
72Tab key down
73===============
74*/
75void Sbar_ShowScores (void)
76{
77 if (sb_showscores)
78 return;
79 sb_showscores = true;
80 sb_updates = 0;
81}
82
83/*
84===============
85Sbar_DontShowScores
86
87Tab key up
88===============
89*/
90void Sbar_DontShowScores (void)
91{
92 sb_showscores = false;
93 sb_updates = 0;
94}
95
96/*
97===============
98Sbar_Changed
99===============
100*/
101void Sbar_Changed (void)
102{
103 sb_updates = 0; // update next frame
104}
105
106/*
107===============
108Sbar_Init
109===============
110*/
111void Sbar_Init (void)
112{
113 int i;
114
115 for (i=0 ; i<10 ; i++)
116 {
117 sb_nums[0][i] = Draw_PicFromWad (va("num_%i",i));
118 sb_nums[1][i] = Draw_PicFromWad (va("anum_%i",i));
119 }
120
121 sb_nums[0][10] = Draw_PicFromWad ("num_minus");
122 sb_nums[1][10] = Draw_PicFromWad ("anum_minus");
123
124 sb_colon = Draw_PicFromWad ("num_colon");
125 sb_slash = Draw_PicFromWad ("num_slash");
126
127 sb_weapons[0][0] = Draw_PicFromWad ("inv_shotgun");
128 sb_weapons[0][1] = Draw_PicFromWad ("inv_sshotgun");
129 sb_weapons[0][2] = Draw_PicFromWad ("inv_nailgun");
130 sb_weapons[0][3] = Draw_PicFromWad ("inv_snailgun");
131 sb_weapons[0][4] = Draw_PicFromWad ("inv_rlaunch");
132 sb_weapons[0][5] = Draw_PicFromWad ("inv_srlaunch");
133 sb_weapons[0][6] = Draw_PicFromWad ("inv_lightng");
134
135 sb_weapons[1][0] = Draw_PicFromWad ("inv2_shotgun");
136 sb_weapons[1][1] = Draw_PicFromWad ("inv2_sshotgun");
137 sb_weapons[1][2] = Draw_PicFromWad ("inv2_nailgun");
138 sb_weapons[1][3] = Draw_PicFromWad ("inv2_snailgun");
139 sb_weapons[1][4] = Draw_PicFromWad ("inv2_rlaunch");
140 sb_weapons[1][5] = Draw_PicFromWad ("inv2_srlaunch");
141 sb_weapons[1][6] = Draw_PicFromWad ("inv2_lightng");
142
143 for (i=0 ; i<5 ; i++)
144 {
145 sb_weapons[2+i][0] = Draw_PicFromWad (va("inva%i_shotgun",i+1));
146 sb_weapons[2+i][1] = Draw_PicFromWad (va("inva%i_sshotgun",i+1));
147 sb_weapons[2+i][2] = Draw_PicFromWad (va("inva%i_nailgun",i+1));
148 sb_weapons[2+i][3] = Draw_PicFromWad (va("inva%i_snailgun",i+1));
149 sb_weapons[2+i][4] = Draw_PicFromWad (va("inva%i_rlaunch",i+1));
150 sb_weapons[2+i][5] = Draw_PicFromWad (va("inva%i_srlaunch",i+1));
151 sb_weapons[2+i][6] = Draw_PicFromWad (va("inva%i_lightng",i+1));
152 }
153
154 sb_ammo[0] = Draw_PicFromWad ("sb_shells");
155 sb_ammo[1] = Draw_PicFromWad ("sb_nails");
156 sb_ammo[2] = Draw_PicFromWad ("sb_rocket");
157 sb_ammo[3] = Draw_PicFromWad ("sb_cells");
158
159 sb_armor[0] = Draw_PicFromWad ("sb_armor1");
160 sb_armor[1] = Draw_PicFromWad ("sb_armor2");
161 sb_armor[2] = Draw_PicFromWad ("sb_armor3");
162
163 sb_items[0] = Draw_PicFromWad ("sb_key1");
164 sb_items[1] = Draw_PicFromWad ("sb_key2");
165 sb_items[2] = Draw_PicFromWad ("sb_invis");
166 sb_items[3] = Draw_PicFromWad ("sb_invuln");
167 sb_items[4] = Draw_PicFromWad ("sb_suit");
168 sb_items[5] = Draw_PicFromWad ("sb_quad");
169
170 sb_sigil[0] = Draw_PicFromWad ("sb_sigil1");
171 sb_sigil[1] = Draw_PicFromWad ("sb_sigil2");
172 sb_sigil[2] = Draw_PicFromWad ("sb_sigil3");
173 sb_sigil[3] = Draw_PicFromWad ("sb_sigil4");
174
175 sb_faces[4][0] = Draw_PicFromWad ("face1");
176 sb_faces[4][1] = Draw_PicFromWad ("face_p1");
177 sb_faces[3][0] = Draw_PicFromWad ("face2");
178 sb_faces[3][1] = Draw_PicFromWad ("face_p2");
179 sb_faces[2][0] = Draw_PicFromWad ("face3");
180 sb_faces[2][1] = Draw_PicFromWad ("face_p3");
181 sb_faces[1][0] = Draw_PicFromWad ("face4");
182 sb_faces[1][1] = Draw_PicFromWad ("face_p4");
183 sb_faces[0][0] = Draw_PicFromWad ("face5");
184 sb_faces[0][1] = Draw_PicFromWad ("face_p5");
185
186 sb_face_invis = Draw_PicFromWad ("face_invis");
187 sb_face_invuln = Draw_PicFromWad ("face_invul2");
188 sb_face_invis_invuln = Draw_PicFromWad ("face_inv2");
189 sb_face_quad = Draw_PicFromWad ("face_quad");
190
191 Cmd_AddCommand ("+showscores", Sbar_ShowScores);
192 Cmd_AddCommand ("-showscores", Sbar_DontShowScores);
193
194 sb_sbar = Draw_PicFromWad ("sbar");
195 sb_ibar = Draw_PicFromWad ("ibar");
196 sb_scorebar = Draw_PicFromWad ("scorebar");
197
198//MED 01/04/97 added new hipnotic weapons
199 if (hipnotic)
200 {
201 hsb_weapons[0][0] = Draw_PicFromWad ("inv_laser");
202 hsb_weapons[0][1] = Draw_PicFromWad ("inv_mjolnir");
203 hsb_weapons[0][2] = Draw_PicFromWad ("inv_gren_prox");
204 hsb_weapons[0][3] = Draw_PicFromWad ("inv_prox_gren");
205 hsb_weapons[0][4] = Draw_PicFromWad ("inv_prox");
206
207 hsb_weapons[1][0] = Draw_PicFromWad ("inv2_laser");
208 hsb_weapons[1][1] = Draw_PicFromWad ("inv2_mjolnir");
209 hsb_weapons[1][2] = Draw_PicFromWad ("inv2_gren_prox");
210 hsb_weapons[1][3] = Draw_PicFromWad ("inv2_prox_gren");
211 hsb_weapons[1][4] = Draw_PicFromWad ("inv2_prox");
212
213 for (i=0 ; i<5 ; i++)
214 {
215 hsb_weapons[2+i][0] = Draw_PicFromWad (va("inva%i_laser",i+1));
216 hsb_weapons[2+i][1] = Draw_PicFromWad (va("inva%i_mjolnir",i+1));
217 hsb_weapons[2+i][2] = Draw_PicFromWad (va("inva%i_gren_prox",i+1));
218 hsb_weapons[2+i][3] = Draw_PicFromWad (va("inva%i_prox_gren",i+1));
219 hsb_weapons[2+i][4] = Draw_PicFromWad (va("inva%i_prox",i+1));
220 }
221
222 hsb_items[0] = Draw_PicFromWad ("sb_wsuit");
223 hsb_items[1] = Draw_PicFromWad ("sb_eshld");
224 }
225
226 if (rogue)
227 {
228 rsb_invbar[0] = Draw_PicFromWad ("r_invbar1");
229 rsb_invbar[1] = Draw_PicFromWad ("r_invbar2");
230
231 rsb_weapons[0] = Draw_PicFromWad ("r_lava");
232 rsb_weapons[1] = Draw_PicFromWad ("r_superlava");
233 rsb_weapons[2] = Draw_PicFromWad ("r_gren");
234 rsb_weapons[3] = Draw_PicFromWad ("r_multirock");
235 rsb_weapons[4] = Draw_PicFromWad ("r_plasma");
236
237 rsb_items[0] = Draw_PicFromWad ("r_shield1");
238 rsb_items[1] = Draw_PicFromWad ("r_agrav1");
239
240// PGM 01/19/97 - team color border
241 rsb_teambord = Draw_PicFromWad ("r_teambord");
242// PGM 01/19/97 - team color border
243
244 rsb_ammo[0] = Draw_PicFromWad ("r_ammolava");
245 rsb_ammo[1] = Draw_PicFromWad ("r_ammomulti");
246 rsb_ammo[2] = Draw_PicFromWad ("r_ammoplasma");
247 }
248}
249
250
251//=============================================================================
252
253// drawing routines are relative to the status bar location
254
255/*
256=============
257Sbar_DrawPic
258=============
259*/
260void Sbar_DrawPic (int x, int y, qpic_t *pic)
261{
262 if (cl.gametype == GAME_DEATHMATCH)
263 Draw_Pic (x /* + ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic);
264 else
265 Draw_Pic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic);
266}
267
268/*
269=============
270Sbar_DrawTransPic
271=============
272*/
273void Sbar_DrawTransPic (int x, int y, qpic_t *pic)
274{
275 if (cl.gametype == GAME_DEATHMATCH)
276 Draw_TransPic (x /*+ ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic);
277 else
278 Draw_TransPic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic);
279}
280
281/*
282================
283Sbar_DrawCharacter
284
285Draws one solid graphics character
286================
287*/
288void Sbar_DrawCharacter (int x, int y, int num)
289{
290 if (cl.gametype == GAME_DEATHMATCH)
291 Draw_Character ( x /*+ ((vid.width - 320)>>1) */ + 4 , y + vid.height-SBAR_HEIGHT, num);
292 else
293 Draw_Character ( x + ((vid.width - 320)>>1) + 4 , y + vid.height-SBAR_HEIGHT, num);
294}
295
296/*
297================
298Sbar_DrawString
299================
300*/
301void Sbar_DrawString (int x, int y, char *str)
302{
303 if (cl.gametype == GAME_DEATHMATCH)
304 Draw_String (x /*+ ((vid.width - 320)>>1)*/, y+ vid.height-SBAR_HEIGHT, str);
305 else
306 Draw_String (x + ((vid.width - 320)>>1), y+ vid.height-SBAR_HEIGHT, str);
307}
308
309/*
310=============
311Sbar_itoa
312=============
313*/
314int Sbar_itoa (int num, char *buf)
315{
316 char *str;
317 int pow10;
318 int dig;
319
320 str = buf;
321
322 if (num < 0)
323 {
324 *str++ = '-';
325 num = -num;
326 }
327
328 for (pow10 = 10 ; num >= pow10 ; pow10 *= 10)
329 ;
330
331 do
332 {
333 pow10 /= 10;
334 dig = num/pow10;
335 *str++ = '0'+dig;
336 num -= dig*pow10;
337 } while (pow10 != 1);
338
339 *str = 0;
340
341 return str-buf;
342}
343
344
345/*
346=============
347Sbar_DrawNum
348=============
349*/
350void Sbar_DrawNum (int x, int y, int num, int digits, int color)
351{
352 char str[12];
353 char *ptr;
354 int l, frame;
355
356 l = Sbar_itoa (num, str);
357 ptr = str;
358 if (l > digits)
359 ptr += (l-digits);
360 if (l < digits)
361 x += (digits-l)*24;
362
363 while (*ptr)
364 {
365 if (*ptr == '-')
366 frame = STAT_MINUS;
367 else
368 frame = *ptr -'0';
369
370 Sbar_DrawTransPic (x,y,sb_nums[color][frame]);
371 x += 24;
372 ptr++;
373 }
374}
375
376//=============================================================================
377
378int fragsort[MAX_SCOREBOARD];
379
380char scoreboardtext[MAX_SCOREBOARD][20];
381int scoreboardtop[MAX_SCOREBOARD];
382int scoreboardbottom[MAX_SCOREBOARD];
383int scoreboardcount[MAX_SCOREBOARD];
384int scoreboardlines;
385
386/*
387===============
388Sbar_SortFrags
389===============
390*/
391void Sbar_SortFrags (void)
392{
393 int i, j, k;
394
395// sort by frags
396 scoreboardlines = 0;
397 for (i=0 ; i<cl.maxclients ; i++)
398 {
399 if (cl.scores[i].name[0])
400 {
401 fragsort[scoreboardlines] = i;
402 scoreboardlines++;
403 }
404 }
405
406 for (i=0 ; i<scoreboardlines ; i++)
407 for (j=0 ; j<scoreboardlines-1-i ; j++)
408 if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
409 {
410 k = fragsort[j];
411 fragsort[j] = fragsort[j+1];
412 fragsort[j+1] = k;
413 }
414}
415
416int Sbar_ColorForMap (int m)
417{
418 return m < 128 ? m + 8 : m + 8;
419}
420
421/*
422===============
423Sbar_UpdateScoreboard
424===============
425*/
426void Sbar_UpdateScoreboard (void)
427{
428 int i, k;
429 int top, bottom;
430 scoreboard_t *s;
431
432 Sbar_SortFrags ();
433
434// draw the text
435 memset (scoreboardtext, 0, sizeof(scoreboardtext));
436
437 for (i=0 ; i<scoreboardlines; i++)
438 {
439 k = fragsort[i];
440 s = &cl.scores[k];
441 sprintf (&scoreboardtext[i][1], "%3i %s", s->frags, s->name);
442
443 top = s->colors & 0xf0;
444 bottom = (s->colors & 15) <<4;
445 scoreboardtop[i] = Sbar_ColorForMap (top);
446 scoreboardbottom[i] = Sbar_ColorForMap (bottom);
447 }
448}
449
450
451
452/*
453===============
454Sbar_SoloScoreboard
455===============
456*/
457void Sbar_SoloScoreboard (void)
458{
459 char str[80];
460 int minutes, seconds, tens, units;
461 int l;
462
463 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
464 Sbar_DrawString (8, 4, str);
465
466 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
467 Sbar_DrawString (8, 12, str);
468
469// time
470 minutes = cl.time / 60;
471 seconds = cl.time - 60*minutes;
472 tens = seconds / 10;
473 units = seconds - 10*tens;
474 sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
475 Sbar_DrawString (184, 4, str);
476
477// draw level name
478 l = strlen (cl.levelname);
479 Sbar_DrawString (232 - l*4, 12, cl.levelname);
480}
481
482/*
483===============
484Sbar_DrawScoreboard
485===============
486*/
487void Sbar_DrawScoreboard (void)
488{
489 Sbar_SoloScoreboard ();
490 if (cl.gametype == GAME_DEATHMATCH)
491 Sbar_DeathmatchOverlay ();
492#if 0
493 int i, j, c;
494 int x, y;
495 int l;
496 int top, bottom;
497 scoreboard_t *s;
498
499 if (cl.gametype != GAME_DEATHMATCH)
500 {
501 Sbar_SoloScoreboard ();
502 return;
503 }
504
505 Sbar_UpdateScoreboard ();
506
507 l = scoreboardlines <= 6 ? scoreboardlines : 6;
508
509 for (i=0 ; i<l ; i++)
510 {
511 x = 20*(i&1);
512 y = i/2 * 8;
513
514 s = &cl.scores[fragsort[i]];
515 if (!s->name[0])
516 continue;
517
518 // draw background
519 top = s->colors & 0xf0;
520 bottom = (s->colors & 15)<<4;
521 top = Sbar_ColorForMap (top);
522 bottom = Sbar_ColorForMap (bottom);
523
524 Draw_Fill ( x*8+10 + ((vid.width - 320)>>1), y + vid.height - SBAR_HEIGHT, 28, 4, top);
525 Draw_Fill ( x*8+10 + ((vid.width - 320)>>1), y+4 + vid.height - SBAR_HEIGHT, 28, 4, bottom);
526
527 // draw text
528 for (j=0 ; j<20 ; j++)
529 {
530 c = scoreboardtext[i][j];
531 if (c == 0 || c == ' ')
532 continue;
533 Sbar_DrawCharacter ( (x+j)*8, y, c);
534 }
535 }
536#endif
537}
538
539//=============================================================================
540
541/*
542===============
543Sbar_DrawInventory
544===============
545*/
546void Sbar_DrawInventory (void)
547{
548 int i;
549 char num[6];
550 float time;
551 int flashon;
552
553 if (rogue)
554 {
555 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
556 Sbar_DrawPic (0, -24, rsb_invbar[0]);
557 else
558 Sbar_DrawPic (0, -24, rsb_invbar[1]);
559 }
560 else
561 {
562 Sbar_DrawPic (0, -24, sb_ibar);
563 }
564
565// weapons
566 for (i=0 ; i<7 ; i++)
567 {
568 if (cl.items & (IT_SHOTGUN<<i) )
569 {
570 time = cl.item_gettime[i];
571 flashon = (int)((cl.time - time)*10);
572 if (flashon >= 10)
573 {
574 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
575 flashon = 1;
576 else
577 flashon = 0;
578 }
579 else
580 flashon = (flashon%5) + 2;
581
582 Sbar_DrawPic (i*24, -16, sb_weapons[flashon][i]);
583
584 if (flashon > 1)
585 sb_updates = 0; // force update to remove flash
586 }
587 }
588
589// MED 01/04/97
590// hipnotic weapons
591 if (hipnotic)
592 {
593 int grenadeflashing=0;
594 for (i=0 ; i<4 ; i++)
595 {
596 if (cl.items & (1<<hipweapons[i]) )
597 {
598 time = cl.item_gettime[hipweapons[i]];
599 flashon = (int)((cl.time - time)*10);
600 if (flashon >= 10)
601 {
602 if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i]) )
603 flashon = 1;
604 else
605 flashon = 0;
606 }
607 else
608 flashon = (flashon%5) + 2;
609
610 // check grenade launcher
611 if (i==2)
612 {
613 if (cl.items & HIT_PROXIMITY_GUN)
614 {
615 if (flashon)
616 {
617 grenadeflashing = 1;
618 Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
619 }
620 }
621 }
622 else if (i==3)
623 {
624 if (cl.items & (IT_SHOTGUN<<4))
625 {
626 if (flashon && !grenadeflashing)
627 {
628 Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
629 }
630 else if (!grenadeflashing)
631 {
632 Sbar_DrawPic (96, -16, hsb_weapons[0][3]);
633 }
634 }
635 else
636 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
637 }
638 else
639 Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
640 if (flashon > 1)
641 sb_updates = 0; // force update to remove flash
642 }
643 }
644 }
645
646 if (rogue)
647 {
648 // check for powered up weapon.
649 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
650 {
651 for (i=0;i<5;i++)
652 {
653 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
654 {
655 Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
656 }
657 }
658 }
659 }
660
661// ammo counts
662 for (i=0 ; i<4 ; i++)
663 {
664 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
665 if (num[0] != ' ')
666 Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
667 if (num[1] != ' ')
668 Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
669 if (num[2] != ' ')
670 Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
671 }
672
673 flashon = 0;
674 // items
675 for (i=0 ; i<6 ; i++)
676 if (cl.items & (1<<(17+i)))
677 {
678 time = cl.item_gettime[17+i];
679 if (time && time > cl.time - 2 && flashon )
680 { // flash frame
681 sb_updates = 0;
682 }
683 else
684 {
685 //MED 01/04/97 changed keys
686 if (!hipnotic || (i>1))
687 {
688 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
689 }
690 }
691 if (time && time > cl.time - 2)
692 sb_updates = 0;
693 }
694 //MED 01/04/97 added hipnotic items
695 // hipnotic items
696 if (hipnotic)
697 {
698 for (i=0 ; i<2 ; i++)
699 if (cl.items & (1<<(24+i)))
700 {
701 time = cl.item_gettime[24+i];
702 if (time && time > cl.time - 2 && flashon )
703 { // flash frame
704 sb_updates = 0;
705 }
706 else
707 {
708 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
709 }
710 if (time && time > cl.time - 2)
711 sb_updates = 0;
712 }
713 }
714
715 if (rogue)
716 {
717 // new rogue items
718 for (i=0 ; i<2 ; i++)
719 {
720 if (cl.items & (1<<(29+i)))
721 {
722 time = cl.item_gettime[29+i];
723
724 if (time && time > cl.time - 2 && flashon )
725 { // flash frame
726 sb_updates = 0;
727 }
728 else
729 {
730 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
731 }
732
733 if (time && time > cl.time - 2)
734 sb_updates = 0;
735 }
736 }
737 }
738 else
739 {
740 // sigils
741 for (i=0 ; i<4 ; i++)
742 {
743 if (cl.items & (1<<(28+i)))
744 {
745 time = cl.item_gettime[28+i];
746 if (time && time > cl.time - 2 && flashon )
747 { // flash frame
748 sb_updates = 0;
749 }
750 else
751 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
752 if (time && time > cl.time - 2)
753 sb_updates = 0;
754 }
755 }
756 }
757}
758
759//=============================================================================
760
761/*
762===============
763Sbar_DrawFrags
764===============
765*/
766void Sbar_DrawFrags (void)
767{
768 int i, k, l;
769 int top, bottom;
770 int x, y, f;
771 int xofs;
772 char num[12];
773 scoreboard_t *s;
774
775 Sbar_SortFrags ();
776
777// draw the text
778 l = scoreboardlines <= 4 ? scoreboardlines : 4;
779
780 x = 23;
781 if (cl.gametype == GAME_DEATHMATCH)
782 xofs = 0;
783 else
784 xofs = (vid.width - 320)>>1;
785 y = vid.height - SBAR_HEIGHT - 23;
786
787 for (i=0 ; i<l ; i++)
788 {
789 k = fragsort[i];
790 s = &cl.scores[k];
791 if (!s->name[0])
792 continue;
793
794 // draw background
795 top = s->colors & 0xf0;
796 bottom = (s->colors & 15)<<4;
797 top = Sbar_ColorForMap (top);
798 bottom = Sbar_ColorForMap (bottom);
799
800 Draw_Fill (xofs + x*8 + 10, y, 28, 4, top);
801 Draw_Fill (xofs + x*8 + 10, y+4, 28, 3, bottom);
802
803 // draw number
804 f = s->frags;
805 sprintf (num, "%3i",f);
806
807 Sbar_DrawCharacter ( (x+1)*8 , -24, num[0]);
808 Sbar_DrawCharacter ( (x+2)*8 , -24, num[1]);
809 Sbar_DrawCharacter ( (x+3)*8 , -24, num[2]);
810
811 if (k == cl.viewentity - 1)
812 {
813 Sbar_DrawCharacter (x*8+2, -24, 16);
814 Sbar_DrawCharacter ( (x+4)*8-4, -24, 17);
815 }
816 x+=4;
817 }
818}
819
820//=============================================================================
821
822
823/*
824===============
825Sbar_DrawFace
826===============
827*/
828void Sbar_DrawFace (void)
829{
830 int f, anim;
831
832// PGM 01/19/97 - team color drawing
833// PGM 03/02/97 - fixed so color swatch only appears in CTF modes
834 if (rogue &&
835 (cl.maxclients != 1) &&
836 (teamplay.value>3) &&
837 (teamplay.value<7))
838 {
839 int top, bottom;
840 int xofs;
841 char num[12];
842 scoreboard_t *s;
843
844 s = &cl.scores[cl.viewentity - 1];
845 // draw background
846 top = s->colors & 0xf0;
847 bottom = (s->colors & 15)<<4;
848 top = Sbar_ColorForMap (top);
849 bottom = Sbar_ColorForMap (bottom);
850
851 if (cl.gametype == GAME_DEATHMATCH)
852 xofs = 113;
853 else
854 xofs = ((vid.width - 320)>>1) + 113;
855
856 Sbar_DrawPic (112, 0, rsb_teambord);
857 Draw_Fill (xofs, vid.height-SBAR_HEIGHT+3, 22, 9, top);
858 Draw_Fill (xofs, vid.height-SBAR_HEIGHT+12, 22, 9, bottom);
859
860 // draw number
861 f = s->frags;
862 sprintf (num, "%3i",f);
863
864 if (top==8)
865 {
866 if (num[0] != ' ')
867 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
868 if (num[1] != ' ')
869 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
870 if (num[2] != ' ')
871 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
872 }
873 else
874 {
875 Sbar_DrawCharacter ( 109, 3, num[0]);
876 Sbar_DrawCharacter ( 116, 3, num[1]);
877 Sbar_DrawCharacter ( 123, 3, num[2]);
878 }
879
880 return;
881 }
882// PGM 01/19/97 - team color drawing
883
884 if ( (cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY) )
885 == (IT_INVISIBILITY | IT_INVULNERABILITY) )
886 {
887 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
888 return;
889 }
890 if (cl.items & IT_QUAD)
891 {
892 Sbar_DrawPic (112, 0, sb_face_quad );
893 return;
894 }
895 if (cl.items & IT_INVISIBILITY)
896 {
897 Sbar_DrawPic (112, 0, sb_face_invis );
898 return;
899 }
900 if (cl.items & IT_INVULNERABILITY)
901 {
902 Sbar_DrawPic (112, 0, sb_face_invuln);
903 return;
904 }
905
906 if (cl.stats[STAT_HEALTH] >= 100)
907 f = 4;
908 else
909 f = cl.stats[STAT_HEALTH] / 20;
910
911 if (cl.time <= cl.faceanimtime)
912 {
913 anim = 1;
914 sb_updates = 0; // make sure the anim gets drawn over
915 }
916 else
917 anim = 0;
918 Sbar_DrawPic (112, 0, sb_faces[f][anim]);
919}
920
921/*
922===============
923Sbar_Draw
924===============
925*/
926void Sbar_Draw (void)
927{
928 if (scr_con_current == vid.height)
929 return; // console is full screen
930
931 if (sb_updates >= vid.numpages)
932 return;
933
934 scr_copyeverything = 1;
935
936 sb_updates++;
937
938 if (sb_lines && vid.width > 320)
939 Draw_TileClear (0, vid.height - sb_lines, vid.width, sb_lines);
940
941 if (sb_lines > 24)
942 {
943 Sbar_DrawInventory ();
944 if (cl.maxclients != 1)
945 Sbar_DrawFrags ();
946 }
947
948 if (sb_showscores || cl.stats[STAT_HEALTH] <= 0)
949 {
950 Sbar_DrawPic (0, 0, sb_scorebar);
951 Sbar_DrawScoreboard ();
952 sb_updates = 0;
953 }
954 else if (sb_lines)
955 {
956 Sbar_DrawPic (0, 0, sb_sbar);
957
958 // keys (hipnotic only)
959 //MED 01/04/97 moved keys here so they would not be overwritten
960 if (hipnotic)
961 {
962 if (cl.items & IT_KEY1)
963 Sbar_DrawPic (209, 3, sb_items[0]);
964 if (cl.items & IT_KEY2)
965 Sbar_DrawPic (209, 12, sb_items[1]);
966 }
967 // armor
968 if (cl.items & IT_INVULNERABILITY)
969 {
970 Sbar_DrawNum (24, 0, 666, 3, 1);
971 Sbar_DrawPic (0, 0, draw_disc);
972 }
973 else
974 {
975 if (rogue)
976 {
977 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3,
978 cl.stats[STAT_ARMOR] <= 25);
979 if (cl.items & RIT_ARMOR3)
980 Sbar_DrawPic (0, 0, sb_armor[2]);
981 else if (cl.items & RIT_ARMOR2)
982 Sbar_DrawPic (0, 0, sb_armor[1]);
983 else if (cl.items & RIT_ARMOR1)
984 Sbar_DrawPic (0, 0, sb_armor[0]);
985 }
986 else
987 {
988 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3
989 , cl.stats[STAT_ARMOR] <= 25);
990 if (cl.items & IT_ARMOR3)
991 Sbar_DrawPic (0, 0, sb_armor[2]);
992 else if (cl.items & IT_ARMOR2)
993 Sbar_DrawPic (0, 0, sb_armor[1]);
994 else if (cl.items & IT_ARMOR1)
995 Sbar_DrawPic (0, 0, sb_armor[0]);
996 }
997 }
998
999 // face
1000 Sbar_DrawFace ();
1001
1002 // health
1003 Sbar_DrawNum (136, 0, cl.stats[STAT_HEALTH], 3
1004 , cl.stats[STAT_HEALTH] <= 25);
1005
1006 // ammo icon
1007 if (rogue)
1008 {
1009 if (cl.items & RIT_SHELLS)
1010 Sbar_DrawPic (224, 0, sb_ammo[0]);
1011 else if (cl.items & RIT_NAILS)
1012 Sbar_DrawPic (224, 0, sb_ammo[1]);
1013 else if (cl.items & RIT_ROCKETS)
1014 Sbar_DrawPic (224, 0, sb_ammo[2]);
1015 else if (cl.items & RIT_CELLS)
1016 Sbar_DrawPic (224, 0, sb_ammo[3]);
1017 else if (cl.items & RIT_LAVA_NAILS)
1018 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1019 else if (cl.items & RIT_PLASMA_AMMO)
1020 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1021 else if (cl.items & RIT_MULTI_ROCKETS)
1022 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1023 }
1024 else
1025 {
1026 if (cl.items & IT_SHELLS)
1027 Sbar_DrawPic (224, 0, sb_ammo[0]);
1028 else if (cl.items & IT_NAILS)
1029 Sbar_DrawPic (224, 0, sb_ammo[1]);
1030 else if (cl.items & IT_ROCKETS)
1031 Sbar_DrawPic (224, 0, sb_ammo[2]);
1032 else if (cl.items & IT_CELLS)
1033 Sbar_DrawPic (224, 0, sb_ammo[3]);
1034 }
1035
1036 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3,
1037 cl.stats[STAT_AMMO] <= 10);
1038 }
1039
1040 if (vid.width > 320) {
1041 if (cl.gametype == GAME_DEATHMATCH)
1042 Sbar_MiniDeathmatchOverlay ();
1043 }
1044}
1045
1046//=============================================================================
1047
1048/*
1049==================
1050Sbar_IntermissionNumber
1051
1052==================
1053*/
1054void Sbar_IntermissionNumber (int x, int y, int num, int digits, int color)
1055{
1056 char str[12];
1057 char *ptr;
1058 int l, frame;
1059
1060 l = Sbar_itoa (num, str);
1061 ptr = str;
1062 if (l > digits)
1063 ptr += (l-digits);
1064 if (l < digits)
1065 x += (digits-l)*24;
1066
1067 while (*ptr)
1068 {
1069 if (*ptr == '-')
1070 frame = STAT_MINUS;
1071 else
1072 frame = *ptr -'0';
1073
1074 Draw_TransPic (x,y,sb_nums[color][frame]);
1075 x += 24;
1076 ptr++;
1077 }
1078}
1079
1080/*
1081==================
1082Sbar_DeathmatchOverlay
1083
1084==================
1085*/
1086void Sbar_DeathmatchOverlay (void)
1087{
1088 qpic_t *pic;
1089 int i, k, l;
1090 int top, bottom;
1091 int x, y, f;
1092 char num[12];
1093 scoreboard_t *s;
1094
1095 scr_copyeverything = 1;
1096 scr_fullupdate = 0;
1097
1098 pic = Draw_CachePic ("gfx/ranking.lmp");
1099 M_DrawPic ((320-pic->width)/2, 8, pic);
1100
1101// scores
1102 Sbar_SortFrags ();
1103
1104// draw the text
1105 l = scoreboardlines;
1106
1107 x = 80 + ((vid.width - 320)>>1);
1108 y = 40;
1109 for (i=0 ; i<l ; i++)
1110 {
1111 k = fragsort[i];
1112 s = &cl.scores[k];
1113 if (!s->name[0])
1114 continue;
1115
1116 // draw background
1117 top = s->colors & 0xf0;
1118 bottom = (s->colors & 15)<<4;
1119 top = Sbar_ColorForMap (top);
1120 bottom = Sbar_ColorForMap (bottom);
1121
1122 Draw_Fill ( x, y, 40, 4, top);
1123 Draw_Fill ( x, y+4, 40, 4, bottom);
1124
1125 // draw number
1126 f = s->frags;
1127 sprintf (num, "%3i",f);
1128
1129 Draw_Character ( x+8 , y, num[0]);
1130 Draw_Character ( x+16 , y, num[1]);
1131 Draw_Character ( x+24 , y, num[2]);
1132
1133 if (k == cl.viewentity - 1)
1134 Draw_Character ( x - 8, y, 12);
1135
1136#if 0
1137{
1138 int total;
1139 int n, minutes, tens, units;
1140
1141 // draw time
1142 total = cl.completed_time - s->entertime;
1143 minutes = (int)total/60;
1144 n = total - minutes*60;
1145 tens = n/10;
1146 units = n%10;
1147
1148 sprintf (num, "%3i:%i%i", minutes, tens, units);
1149
1150 Draw_String ( x+48 , y, num);
1151}
1152#endif
1153
1154 // draw name
1155 Draw_String (x+64, y, s->name);
1156
1157 y += 10;
1158 }
1159}
1160
1161/*
1162==================
1163Sbar_DeathmatchOverlay
1164
1165==================
1166*/
1167void Sbar_MiniDeathmatchOverlay (void)
1168{
1169 qpic_t *pic;
1170 int i, k, l;
1171 int top, bottom;
1172 int x, y, f;
1173 char num[12];
1174 scoreboard_t *s;
1175 int numlines;
1176
1177 if (vid.width < 512 || !sb_lines)
1178 return;
1179
1180 scr_copyeverything = 1;
1181 scr_fullupdate = 0;
1182
1183// scores
1184 Sbar_SortFrags ();
1185
1186// draw the text
1187 l = scoreboardlines;
1188 y = vid.height - sb_lines;
1189 numlines = sb_lines/8;
1190 if (numlines < 3)
1191 return;
1192
1193 //find us
1194 for (i = 0; i < scoreboardlines; i++)
1195 if (fragsort[i] == cl.viewentity - 1)
1196 break;
1197
1198 if (i == scoreboardlines) // we're not there
1199 i = 0;
1200 else // figure out start
1201 i = i - numlines/2;
1202
1203 if (i > scoreboardlines - numlines)
1204 i = scoreboardlines - numlines;
1205 if (i < 0)
1206 i = 0;
1207
1208 x = 324;
1209 for (/* */; i < scoreboardlines && y < vid.height - 8 ; i++)
1210 {
1211 k = fragsort[i];
1212 s = &cl.scores[k];
1213 if (!s->name[0])
1214 continue;
1215
1216 // draw background
1217 top = s->colors & 0xf0;
1218 bottom = (s->colors & 15)<<4;
1219 top = Sbar_ColorForMap (top);
1220 bottom = Sbar_ColorForMap (bottom);
1221
1222 Draw_Fill ( x, y+1, 40, 3, top);
1223 Draw_Fill ( x, y+4, 40, 4, bottom);
1224
1225 // draw number
1226 f = s->frags;
1227 sprintf (num, "%3i",f);
1228
1229 Draw_Character ( x+8 , y, num[0]);
1230 Draw_Character ( x+16 , y, num[1]);
1231 Draw_Character ( x+24 , y, num[2]);
1232
1233 if (k == cl.viewentity - 1) {
1234 Draw_Character ( x, y, 16);
1235 Draw_Character ( x + 32, y, 17);
1236 }
1237
1238#if 0
1239{
1240 int total;
1241 int n, minutes, tens, units;
1242
1243 // draw time
1244 total = cl.completed_time - s->entertime;
1245 minutes = (int)total/60;
1246 n = total - minutes*60;
1247 tens = n/10;
1248 units = n%10;
1249
1250 sprintf (num, "%3i:%i%i", minutes, tens, units);
1251
1252 Draw_String ( x+48 , y, num);
1253}
1254#endif
1255
1256 // draw name
1257 Draw_String (x+48, y, s->name);
1258
1259 y += 8;
1260 }
1261}
1262
1263/*
1264==================
1265Sbar_IntermissionOverlay
1266
1267==================
1268*/
1269void Sbar_IntermissionOverlay (void)
1270{
1271 qpic_t *pic;
1272 int dig;
1273 int num;
1274
1275 scr_copyeverything = 1;
1276 scr_fullupdate = 0;
1277
1278 if (cl.gametype == GAME_DEATHMATCH)
1279 {
1280 Sbar_DeathmatchOverlay ();
1281 return;
1282 }
1283
1284 pic = Draw_CachePic ("gfx/complete.lmp");
1285 Draw_Pic (64, 24, pic);
1286
1287 pic = Draw_CachePic ("gfx/inter.lmp");
1288 Draw_TransPic (0, 56, pic);
1289
1290// time
1291 dig = cl.completed_time/60;
1292 Sbar_IntermissionNumber (160, 64, dig, 3, 0);
1293 num = cl.completed_time - dig*60;
1294 Draw_TransPic (234,64,sb_colon);
1295 Draw_TransPic (246,64,sb_nums[0][num/10]);
1296 Draw_TransPic (266,64,sb_nums[0][num%10]);
1297
1298 Sbar_IntermissionNumber (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1299 Draw_TransPic (232,104,sb_slash);
1300 Sbar_IntermissionNumber (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1301
1302 Sbar_IntermissionNumber (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1303 Draw_TransPic (232,144,sb_slash);
1304 Sbar_IntermissionNumber (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1305
1306}
1307
1308
1309/*
1310==================
1311Sbar_FinaleOverlay
1312
1313==================
1314*/
1315void Sbar_FinaleOverlay (void)
1316{
1317 qpic_t *pic;
1318
1319 scr_copyeverything = 1;
1320
1321 pic = Draw_CachePic ("gfx/finale.lmp");
1322 Draw_TransPic ( (vid.width-pic->width)/2, 16, pic);
1323}