]> icculus.org git repositories - divverent/darkplaces.git/blob - sbar.c
added a bunch more COLLISIONPARANOID code trying to track down a physics bug with...
[divverent/darkplaces.git] / sbar.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 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 typedef struct
25 {
26         char name[32];
27 }
28 sbarpic_t;
29
30 static sbarpic_t sbarpics[256];
31 static int numsbarpics;
32
33 static sbarpic_t *Sbar_NewPic(const char *name)
34 {
35         strcpy(sbarpics[numsbarpics].name, name);
36         // precache it
37         // FIXME: precache on every renderer restart (or move this to client)
38         Draw_CachePic(sbarpics[numsbarpics].name);
39         return sbarpics + (numsbarpics++);
40 }
41
42 sbarpic_t *sb_disc;
43
44 #define STAT_MINUS 10 // num frame for '-' stats digit
45 sbarpic_t *sb_nums[2][11];
46 sbarpic_t *sb_colon, *sb_slash;
47 sbarpic_t *sb_ibar;
48 sbarpic_t *sb_sbar;
49 sbarpic_t *sb_scorebar;
50 // AK only used by NEX(and only if everybody agrees)
51 sbarpic_t *sb_sbar_overlay;
52
53 // AK changed the bound to 9
54 sbarpic_t *sb_weapons[7][9]; // 0 is active, 1 is owned, 2-5 are flashes
55 sbarpic_t *sb_ammo[4];
56 sbarpic_t *sb_sigil[4];
57 sbarpic_t *sb_armor[3];
58 sbarpic_t *sb_items[32];
59
60 // 0-4 are based on health (in 20 increments)
61 // 0 is static, 1 is temporary animation
62 sbarpic_t *sb_faces[5][2];
63
64 sbarpic_t *sb_face_invis;
65 sbarpic_t *sb_face_quad;
66 sbarpic_t *sb_face_invuln;
67 sbarpic_t *sb_face_invis_invuln;
68
69 qboolean sb_showscores;
70
71 int sb_lines;                   // scan lines to draw
72
73 sbarpic_t *rsb_invbar[2];
74 sbarpic_t *rsb_weapons[5];
75 sbarpic_t *rsb_items[2];
76 sbarpic_t *rsb_ammo[3];
77 sbarpic_t *rsb_teambord;                // PGM 01/19/97 - team color border
78
79 //MED 01/04/97 added two more weapons + 3 alternates for grenade launcher
80 sbarpic_t *hsb_weapons[7][5];   // 0 is active, 1 is owned, 2-5 are flashes
81 //MED 01/04/97 added array to simplify weapon parsing
82 int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT};
83 //MED 01/04/97 added hipnotic items array
84 sbarpic_t *hsb_items[2];
85
86 cvar_t  showfps = {CVAR_SAVE, "showfps", "0"};
87 cvar_t  sbar_alpha = {CVAR_SAVE, "sbar_alpha", "1"};
88
89 void Sbar_MiniDeathmatchOverlay (void);
90 void Sbar_DeathmatchOverlay (void);
91 void Sbar_IntermissionOverlay (void);
92 void Sbar_FinaleOverlay (void);
93
94
95 /*
96 ===============
97 Sbar_ShowScores
98
99 Tab key down
100 ===============
101 */
102 void Sbar_ShowScores (void)
103 {
104         if (sb_showscores)
105                 return;
106         sb_showscores = true;
107 }
108
109 /*
110 ===============
111 Sbar_DontShowScores
112
113 Tab key up
114 ===============
115 */
116 void Sbar_DontShowScores (void)
117 {
118         sb_showscores = false;
119 }
120
121 void sbar_start(void)
122 {
123         int i;
124
125         numsbarpics = 0;
126
127         sb_disc = Sbar_NewPic("gfx/disc");
128
129         for (i = 0;i < 10;i++)
130         {
131                 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
132                 sb_nums[1][i] = Sbar_NewPic (va("gfx/anum_%i",i));
133         }
134
135         sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
136         sb_nums[1][10] = Sbar_NewPic ("gfx/anum_minus");
137
138         sb_colon = Sbar_NewPic ("gfx/num_colon");
139         sb_slash = Sbar_NewPic ("gfx/num_slash");
140
141         //AK NX uses its own hud
142         if(gamemode == GAME_NEXUIZ)
143         {
144                 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
145                 sb_ammo[1] = Sbar_NewPic ("gfx/sb_bullets");
146                 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
147                 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
148
149                 sb_items[2] = Sbar_NewPic ("gfx/sb_slowmo");
150                 sb_items[3] = Sbar_NewPic ("gfx/sb_invinc");
151                 sb_items[4] = Sbar_NewPic ("gfx/sb_energy");
152                 sb_items[5] = Sbar_NewPic ("gfx/sb_str");
153
154                 sb_sbar = Sbar_NewPic("gfx/sbar");
155                 sb_sbar_overlay = Sbar_NewPic("gfx/sbar_overlay");
156
157                 for(i = 0; i < 9;i++)
158                         sb_weapons[0][i] = Sbar_NewPic(va("gfx/inv_weapon%i",i));
159
160                 return;
161         }
162
163         sb_weapons[0][0] = Sbar_NewPic ("gfx/inv_shotgun");
164         sb_weapons[0][1] = Sbar_NewPic ("gfx/inv_sshotgun");
165         sb_weapons[0][2] = Sbar_NewPic ("gfx/inv_nailgun");
166         sb_weapons[0][3] = Sbar_NewPic ("gfx/inv_snailgun");
167         sb_weapons[0][4] = Sbar_NewPic ("gfx/inv_rlaunch");
168         sb_weapons[0][5] = Sbar_NewPic ("gfx/inv_srlaunch");
169         sb_weapons[0][6] = Sbar_NewPic ("gfx/inv_lightng");
170
171         sb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_shotgun");
172         sb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_sshotgun");
173         sb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_nailgun");
174         sb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_snailgun");
175         sb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_rlaunch");
176         sb_weapons[1][5] = Sbar_NewPic ("gfx/inv2_srlaunch");
177         sb_weapons[1][6] = Sbar_NewPic ("gfx/inv2_lightng");
178
179         for (i = 0;i < 5;i++)
180         {
181                 sb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_shotgun",i+1));
182                 sb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_sshotgun",i+1));
183                 sb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_nailgun",i+1));
184                 sb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_snailgun",i+1));
185                 sb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_rlaunch",i+1));
186                 sb_weapons[2+i][5] = Sbar_NewPic (va("gfx/inva%i_srlaunch",i+1));
187                 sb_weapons[2+i][6] = Sbar_NewPic (va("gfx/inva%i_lightng",i+1));
188         }
189
190         sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
191         sb_ammo[1] = Sbar_NewPic ("gfx/sb_nails");
192         sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
193         sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
194
195         sb_armor[0] = Sbar_NewPic ("gfx/sb_armor1");
196         sb_armor[1] = Sbar_NewPic ("gfx/sb_armor2");
197         sb_armor[2] = Sbar_NewPic ("gfx/sb_armor3");
198
199         sb_items[0] = Sbar_NewPic ("gfx/sb_key1");
200         sb_items[1] = Sbar_NewPic ("gfx/sb_key2");
201         sb_items[2] = Sbar_NewPic ("gfx/sb_invis");
202         sb_items[3] = Sbar_NewPic ("gfx/sb_invuln");
203         sb_items[4] = Sbar_NewPic ("gfx/sb_suit");
204         sb_items[5] = Sbar_NewPic ("gfx/sb_quad");
205
206         sb_sigil[0] = Sbar_NewPic ("gfx/sb_sigil1");
207         sb_sigil[1] = Sbar_NewPic ("gfx/sb_sigil2");
208         sb_sigil[2] = Sbar_NewPic ("gfx/sb_sigil3");
209         sb_sigil[3] = Sbar_NewPic ("gfx/sb_sigil4");
210
211         sb_faces[4][0] = Sbar_NewPic ("gfx/face1");
212         sb_faces[4][1] = Sbar_NewPic ("gfx/face_p1");
213         sb_faces[3][0] = Sbar_NewPic ("gfx/face2");
214         sb_faces[3][1] = Sbar_NewPic ("gfx/face_p2");
215         sb_faces[2][0] = Sbar_NewPic ("gfx/face3");
216         sb_faces[2][1] = Sbar_NewPic ("gfx/face_p3");
217         sb_faces[1][0] = Sbar_NewPic ("gfx/face4");
218         sb_faces[1][1] = Sbar_NewPic ("gfx/face_p4");
219         sb_faces[0][0] = Sbar_NewPic ("gfx/face5");
220         sb_faces[0][1] = Sbar_NewPic ("gfx/face_p5");
221
222         sb_face_invis = Sbar_NewPic ("gfx/face_invis");
223         sb_face_invuln = Sbar_NewPic ("gfx/face_invul2");
224         sb_face_invis_invuln = Sbar_NewPic ("gfx/face_inv2");
225         sb_face_quad = Sbar_NewPic ("gfx/face_quad");
226
227         sb_sbar = Sbar_NewPic ("gfx/sbar");
228         sb_ibar = Sbar_NewPic ("gfx/ibar");
229         sb_scorebar = Sbar_NewPic ("gfx/scorebar");
230
231 //MED 01/04/97 added new hipnotic weapons
232         if (gamemode == GAME_HIPNOTIC)
233         {
234                 hsb_weapons[0][0] = Sbar_NewPic ("gfx/inv_laser");
235                 hsb_weapons[0][1] = Sbar_NewPic ("gfx/inv_mjolnir");
236                 hsb_weapons[0][2] = Sbar_NewPic ("gfx/inv_gren_prox");
237                 hsb_weapons[0][3] = Sbar_NewPic ("gfx/inv_prox_gren");
238                 hsb_weapons[0][4] = Sbar_NewPic ("gfx/inv_prox");
239
240                 hsb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_laser");
241                 hsb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_mjolnir");
242                 hsb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_gren_prox");
243                 hsb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_prox_gren");
244                 hsb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_prox");
245
246                 for (i = 0;i < 5;i++)
247                 {
248                         hsb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_laser",i+1));
249                         hsb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_mjolnir",i+1));
250                         hsb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_gren_prox",i+1));
251                         hsb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_prox_gren",i+1));
252                         hsb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_prox",i+1));
253                 }
254
255                 hsb_items[0] = Sbar_NewPic ("gfx/sb_wsuit");
256                 hsb_items[1] = Sbar_NewPic ("gfx/sb_eshld");
257         }
258         else if (gamemode == GAME_ROGUE)
259         {
260                 rsb_invbar[0] = Sbar_NewPic ("gfx/r_invbar1");
261                 rsb_invbar[1] = Sbar_NewPic ("gfx/r_invbar2");
262
263                 rsb_weapons[0] = Sbar_NewPic ("gfx/r_lava");
264                 rsb_weapons[1] = Sbar_NewPic ("gfx/r_superlava");
265                 rsb_weapons[2] = Sbar_NewPic ("gfx/r_gren");
266                 rsb_weapons[3] = Sbar_NewPic ("gfx/r_multirock");
267                 rsb_weapons[4] = Sbar_NewPic ("gfx/r_plasma");
268
269                 rsb_items[0] = Sbar_NewPic ("gfx/r_shield1");
270                 rsb_items[1] = Sbar_NewPic ("gfx/r_agrav1");
271
272 // PGM 01/19/97 - team color border
273                 rsb_teambord = Sbar_NewPic ("gfx/r_teambord");
274 // PGM 01/19/97 - team color border
275
276                 rsb_ammo[0] = Sbar_NewPic ("gfx/r_ammolava");
277                 rsb_ammo[1] = Sbar_NewPic ("gfx/r_ammomulti");
278                 rsb_ammo[2] = Sbar_NewPic ("gfx/r_ammoplasma");
279         }
280 }
281
282 void sbar_shutdown(void)
283 {
284 }
285
286 void sbar_newmap(void)
287 {
288 }
289
290 void Sbar_Init (void)
291 {
292         Cmd_AddCommand ("+showscores", Sbar_ShowScores);
293         Cmd_AddCommand ("-showscores", Sbar_DontShowScores);
294         Cvar_RegisterVariable (&showfps);
295         Cvar_RegisterVariable (&sbar_alpha);
296
297         R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
298 }
299
300
301 //=============================================================================
302
303 // drawing routines are relative to the status bar location
304
305 int sbar_x, sbar_y;
306
307 /*
308 =============
309 Sbar_DrawPic
310 =============
311 */
312 void Sbar_DrawPic (int x, int y, sbarpic_t *sbarpic)
313 {
314         DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, sbar_alpha.value, 0);
315 }
316
317 void Sbar_DrawAlphaPic (int x, int y, sbarpic_t *sbarpic, float alpha)
318 {
319         DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, alpha * sbar_alpha.value, 0);
320 }
321
322 /*
323 ================
324 Sbar_DrawCharacter
325
326 Draws one solid graphics character
327 ================
328 */
329 void Sbar_DrawCharacter (int x, int y, int num)
330 {
331         DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha.value, 0);
332 }
333
334 /*
335 ================
336 Sbar_DrawString
337 ================
338 */
339 void Sbar_DrawString (int x, int y, char *str)
340 {
341         DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha.value, 0);
342 }
343
344 /*
345 =============
346 Sbar_DrawNum
347 =============
348 */
349 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
350 {
351         char str[32], *ptr;
352         int l, frame;
353
354         l = sprintf(str, "%i", num);
355         ptr = str;
356         if (l > digits)
357                 ptr += (l-digits);
358         if (l < digits)
359                 x += (digits-l)*24;
360
361         while (*ptr)
362         {
363                 if (*ptr == '-')
364                         frame = STAT_MINUS;
365                 else
366                         frame = *ptr -'0';
367
368                 Sbar_DrawPic (x, y, sb_nums[color][frame]);
369                 x += 24;
370
371                 ptr++;
372         }
373 }
374
375 /*
376 =============
377 Sbar_DrawXNum
378 =============
379 */
380
381 void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
382 {
383         char str[32], *ptr;
384         int l, frame;
385
386         l = sprintf(str, "%i", num);
387         ptr = str;
388         if (l > digits)
389                 ptr += (l-digits);
390         if (l < digits)
391                 x += (digits-l) * lettersize;
392
393         while (*ptr)
394         {
395                 if (*ptr == '-')
396                         frame = STAT_MINUS;
397                 else
398                         frame = *ptr -'0';
399
400                 DrawQ_Pic (sbar_x + x, sbar_y + y, sb_nums[0][frame]->name,lettersize,lettersize,r,g,b,a * sbar_alpha.value,flags);
401                 x += lettersize;
402
403                 ptr++;
404         }
405 }
406
407 //=============================================================================
408
409
410 /*
411 ===============
412 Sbar_SortFrags
413 ===============
414 */
415 static int fragsort[MAX_SCOREBOARD];
416 static int scoreboardlines;
417 void Sbar_SortFrags (void)
418 {
419         int             i, j, k;
420
421 // sort by frags
422         scoreboardlines = 0;
423         for (i=0 ; i<cl.maxclients ; i++)
424         {
425                 if (cl.scores[i].name[0])
426                 {
427                         fragsort[scoreboardlines] = i;
428                         scoreboardlines++;
429                 }
430         }
431
432         for (i=0 ; i<scoreboardlines ; i++)
433                 for (j=0 ; j<scoreboardlines-1-i ; j++)
434                         if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
435                         {
436                                 k = fragsort[j];
437                                 fragsort[j] = fragsort[j+1];
438                                 fragsort[j+1] = k;
439                         }
440 }
441
442 /*
443 ===============
444 Sbar_SoloScoreboard
445 ===============
446 */
447 void Sbar_SoloScoreboard (void)
448 {
449         char    str[80];
450         int             minutes, seconds, tens, units;
451         int             l;
452
453         sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
454         Sbar_DrawString (8, 4, str);
455
456         sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
457         Sbar_DrawString (8, 12, str);
458
459 // time
460         minutes = cl.time / 60;
461         seconds = cl.time - 60*minutes;
462         tens = seconds / 10;
463         units = seconds - 10*tens;
464         sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
465         Sbar_DrawString (184, 4, str);
466
467 // draw level name
468         l = strlen (cl.levelname);
469         Sbar_DrawString (232 - l*4, 12, cl.levelname);
470 }
471
472 /*
473 ===============
474 Sbar_DrawScoreboard
475 ===============
476 */
477 void Sbar_DrawScoreboard (void)
478 {
479         Sbar_SoloScoreboard ();
480         if (cl.gametype == GAME_DEATHMATCH)
481                 Sbar_DeathmatchOverlay ();
482 }
483
484 //=============================================================================
485
486 // AK to make DrawInventory smaller
487 static void Sbar_DrawWeapon(int nr, float fade, int active)
488 {
489         // width = 300, height = 100
490         const int w_width = 300, w_height = 100, w_space = 10, font_size = 10;
491         const float w_scale = 0.4;
492
493         DrawQ_Pic(vid.conwidth - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, sb_weapons[0][nr]->name, w_width * w_scale, w_height * w_scale, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 1, fade * sbar_alpha.value, DRAWFLAG_ADDITIVE);
494         DrawQ_String(vid.conwidth - (w_space + font_size ), (w_height + w_space) * w_scale * nr + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 0, 0, fade, 0);
495
496         if (active)
497                 DrawQ_Fill(vid.conwidth - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, w_width * w_scale, w_height * w_scale, 0.3, 0.3, 0.3, fade * sbar_alpha.value, DRAWFLAG_ADDITIVE);
498 }
499
500 /*
501 ===============
502 Sbar_DrawInventory
503 ===============
504 */
505 void Sbar_DrawInventory (void)
506 {
507         int i;
508         char num[6];
509         float time;
510         int flashon;
511         // AK 2003
512         float fade;
513
514         if(gamemode == GAME_NEXUIZ)
515         {
516                 num[0] = cl.stats[STAT_ACTIVEWEAPON];
517                 // we have a max time 2s (min time = 0)
518                 if ((time = cl.time - cl.weapontime) > 2)
519                         return;
520
521                 fade = (1.0 - 0.5 * time);
522                 fade *= fade;
523                 for (i = 0; i < 8;i++)
524                 {
525                         if (!(cl.items & (1 << i)))
526                                 continue;
527                         Sbar_DrawWeapon(i + 1, fade, (i == num[0]));
528                 }
529
530                 if(!(cl.items & (1<<12)))
531                         return;
532                 Sbar_DrawWeapon(0, fade, (num[0] == 12));
533                 return;
534         }
535
536         if (gamemode == GAME_ROGUE)
537         {
538                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
539                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], 0.4);
540                 else
541                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], 0.4);
542         }
543         else
544                 Sbar_DrawAlphaPic (0, -24, sb_ibar, 0.4);
545
546         // weapons
547         for (i=0 ; i<7 ; i++)
548         {
549                 if (cl.items & (IT_SHOTGUN<<i) )
550                 {
551                         time = cl.item_gettime[i];
552                         flashon = (int)((cl.time - time)*10);
553                         if (flashon >= 10)
554                         {
555                                 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i)  )
556                                         flashon = 1;
557                                 else
558                                         flashon = 0;
559                         }
560                         else
561                                 flashon = (flashon%5) + 2;
562
563                         Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], 0.4);
564                 }
565         }
566
567         // MED 01/04/97
568         // hipnotic weapons
569         if (gamemode == GAME_HIPNOTIC)
570         {
571                 int grenadeflashing=0;
572                 for (i=0 ; i<4 ; i++)
573                 {
574                         if (cl.items & (1<<hipweapons[i]) )
575                         {
576                                 time = cl.item_gettime[hipweapons[i]];
577                                 flashon = (int)((cl.time - time)*10);
578                                 if (flashon >= 10)
579                                 {
580                                         if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i])  )
581                                                 flashon = 1;
582                                         else
583                                                 flashon = 0;
584                                 }
585                                 else
586                                         flashon = (flashon%5) + 2;
587
588                                 // check grenade launcher
589                                 if (i==2)
590                                 {
591                                         if (cl.items & HIT_PROXIMITY_GUN)
592                                         {
593                                                 if (flashon)
594                                                 {
595                                                         grenadeflashing = 1;
596                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
597                                                 }
598                                         }
599                                 }
600                                 else if (i==3)
601                                 {
602                                         if (cl.items & (IT_SHOTGUN<<4))
603                                         {
604                                                 if (!grenadeflashing)
605                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
606                                         }
607                                         else
608                                                 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
609                                 }
610                                 else
611                                         Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
612                         }
613                 }
614         }
615
616         if (gamemode == GAME_ROGUE)
617         {
618                 // check for powered up weapon.
619                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
620                         for (i=0;i<5;i++)
621                                 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
622                                         Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
623         }
624
625         // ammo counts
626         for (i=0 ; i<4 ; i++)
627         {
628                 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
629                 if (num[0] != ' ')
630                         Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
631                 if (num[1] != ' ')
632                         Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
633                 if (num[2] != ' ')
634                         Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
635         }
636
637         // items
638         for (i=0 ; i<6 ; i++)
639                 if (cl.items & (1<<(17+i)))
640                 {
641                         //MED 01/04/97 changed keys
642                         if (gamemode != GAME_HIPNOTIC || (i>1))
643                                 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
644                 }
645
646         //MED 01/04/97 added hipnotic items
647         // hipnotic items
648         if (gamemode == GAME_HIPNOTIC)
649         {
650                 for (i=0 ; i<2 ; i++)
651                         if (cl.items & (1<<(24+i)))
652                                 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
653         }
654
655         if (gamemode == GAME_ROGUE)
656         {
657                 // new rogue items
658                 for (i=0 ; i<2 ; i++)
659                         if (cl.items & (1<<(29+i)))
660                                 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
661         }
662         else
663         {
664                 // sigils
665                 for (i=0 ; i<4 ; i++)
666                         if (cl.items & (1<<(28+i)))
667                                 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
668         }
669 }
670
671 //=============================================================================
672
673 /*
674 ===============
675 Sbar_DrawFrags
676 ===============
677 */
678 void Sbar_DrawFrags (void)
679 {
680         int i, k, l, x, f;
681         char num[12];
682         scoreboard_t *s;
683         qbyte *c;
684
685         Sbar_SortFrags ();
686
687         // draw the text
688         l = scoreboardlines <= 4 ? scoreboardlines : 4;
689
690         x = 23 * 8;
691
692         for (i = 0;i < l;i++)
693         {
694                 k = fragsort[i];
695                 s = &cl.scores[k];
696                 if (!s->name[0])
697                         continue;
698
699                 // draw background
700                 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
701                 DrawQ_Fill (sbar_x + x + 10, sbar_y     - 23, 28, 4, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha.value, 0);
702                 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
703                 DrawQ_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 28, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha.value, 0);
704
705                 // draw number
706                 f = s->frags;
707                 sprintf (num, "%3i",f);
708
709                 Sbar_DrawCharacter (x +  8, -24, num[0]);
710                 Sbar_DrawCharacter (x + 16, -24, num[1]);
711                 Sbar_DrawCharacter (x + 24, -24, num[2]);
712
713                 if (k == cl.viewentity - 1)
714                 {
715                         Sbar_DrawCharacter ( x      + 2, -24, 16);
716                         Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
717                 }
718                 x += 32;
719         }
720 }
721
722 //=============================================================================
723
724
725 /*
726 ===============
727 Sbar_DrawFace
728 ===============
729 */
730 void Sbar_DrawFace (void)
731 {
732         int f;
733
734 // PGM 01/19/97 - team color drawing
735 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
736         if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
737         {
738                 char num[12];
739                 scoreboard_t *s;
740                 qbyte *c;
741
742                 s = &cl.scores[cl.viewentity - 1];
743                 // draw background
744                 Sbar_DrawPic (112, 0, rsb_teambord);
745                 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
746                 DrawQ_Fill (sbar_x + 113, vid.conheight-SBAR_HEIGHT+3, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha.value, 0);
747                 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
748                 DrawQ_Fill (sbar_x + 113, vid.conheight-SBAR_HEIGHT+12, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha.value, 0);
749
750                 // draw number
751                 f = s->frags;
752                 sprintf (num, "%3i",f);
753
754                 if ((s->colors & 0xf0)==0)
755                 {
756                         if (num[0] != ' ')
757                                 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
758                         if (num[1] != ' ')
759                                 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
760                         if (num[2] != ' ')
761                                 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
762                 }
763                 else
764                 {
765                         Sbar_DrawCharacter ( 109, 3, num[0]);
766                         Sbar_DrawCharacter ( 116, 3, num[1]);
767                         Sbar_DrawCharacter ( 123, 3, num[2]);
768                 }
769
770                 return;
771         }
772 // PGM 01/19/97 - team color drawing
773
774         if ( (cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
775                 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
776         else if (cl.items & IT_QUAD)
777                 Sbar_DrawPic (112, 0, sb_face_quad );
778         else if (cl.items & IT_INVISIBILITY)
779                 Sbar_DrawPic (112, 0, sb_face_invis );
780         else if (cl.items & IT_INVULNERABILITY)
781                 Sbar_DrawPic (112, 0, sb_face_invuln);
782         else
783         {
784                 f = cl.stats[STAT_HEALTH] / 20;
785                 f = bound(0, f, 4);
786                 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
787         }
788 }
789
790 void Sbar_ShowFPS(void)
791 {
792         if (showfps.integer)
793         {
794                 int calc;
795                 char temp[32];
796                 float fps_x, fps_y, fps_scalex, fps_scaley;
797                 if (showfps.integer > 1)
798                 {
799                         static double currtime, frametimes[32];
800                         double newtime, total;
801                         int count, i;
802                         static int framecycle = 0;
803
804                         newtime = Sys_DoubleTime();
805                         frametimes[framecycle] = newtime - currtime;
806                         total = 0;
807                         count = 0;
808                         while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31])
809                         {
810                                 total += frametimes[i];
811                                 count++;
812                         }
813                         framecycle++;
814                         framecycle &= 31;
815                         if (showfps.integer == 2)
816                                 calc = (int) (((double) count / total) + 0.5);
817                         else // showfps 3, rapid update
818                                 calc = (int) ((1.0 / (newtime - currtime)) + 0.5);
819                         currtime = newtime;
820                 }
821                 else
822                 {
823                         static double nexttime = 0, lasttime = 0;
824                         static int framerate = 0, framecount = 0;
825                         double newtime;
826                         newtime = Sys_DoubleTime();
827                         if (newtime < nexttime)
828                                 framecount++;
829                         else
830                         {
831                                 framerate = (int) (framecount / (newtime - lasttime) + 0.5);
832                                 lasttime = newtime;
833                                 nexttime = lasttime + 0.2;
834                                 framecount = 1;
835                         }
836                         calc = framerate;
837                 }
838                 sprintf(temp, "%4i", calc);
839                 fps_scalex = 12;
840                 fps_scaley = 12;
841                 fps_x = vid.conwidth - (fps_scalex * strlen(temp));
842                 fps_y = vid.conheight - sb_lines/* - 8*/; // yes this might draw over the sbar
843                 if (fps_y > vid.conheight - fps_scaley)
844                         fps_y = vid.conheight - fps_scaley;
845                 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(temp), fps_scaley, 0, 0, 0, 0.5 * sbar_alpha.value, 0);
846                 DrawQ_String(fps_x, fps_y, temp, 0, fps_scalex, fps_scaley, 1, 1, 1, 1 * sbar_alpha.value, 0);
847         }
848 }
849
850 /*
851 ===============
852 Sbar_Draw
853 ===============
854 */
855 void Sbar_Draw (void)
856 {
857         if (scr_con_current == vid.conheight)
858                 return;         // console is full screen
859
860         if (cl.intermission == 1)
861         {
862                 Sbar_IntermissionOverlay();
863                 return;
864         }
865         else if (cl.intermission == 2)
866         {
867                 Sbar_FinaleOverlay();
868                 return;
869         }
870
871         if (gamemode == GAME_NEXUIZ)
872         {
873                 sbar_y = vid.conheight - 47;
874                 sbar_x = (vid.conwidth - 640)/2;
875
876                 if (sb_lines)
877                 {
878                         Sbar_DrawInventory();
879                         if (!cl.islocalgame)
880                                 Sbar_DrawFrags ();
881                 }
882
883                 if (sb_showscores || cl.stats[STAT_HEALTH] <= 0)
884                 {
885                         Sbar_DrawAlphaPic (0, 0, sb_scorebar, 0.4);
886                         Sbar_DrawScoreboard ();
887                 }
888                 else if (sb_lines)
889                 {
890                         Sbar_DrawPic (0, 0, sb_sbar);
891
892                         // special items
893                         if (cl.items & IT_INVULNERABILITY)
894                         {
895                                 Sbar_DrawNum (36, 0, 666, 3, 1);
896                                 Sbar_DrawPic (0, 0, sb_disc);
897                         }
898
899                         // armor
900                         Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
901
902                         // health
903                         if(cl.stats[STAT_HEALTH] > 100)
904                                 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
905                         else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
906                                 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
907                         else
908                                 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
909
910                         // AK dont draw ammo for the laser
911                         if(cl.stats[STAT_ACTIVEWEAPON] != 12)
912                         {
913                                 if (cl.items & NEX_IT_SHELLS)
914                                         Sbar_DrawPic (519, 0, sb_ammo[0]);
915                                 else if (cl.items & NEX_IT_BULLETS)
916                                         Sbar_DrawPic (519, 0, sb_ammo[1]);
917                                 else if (cl.items & NEX_IT_ROCKETS)
918                                         Sbar_DrawPic (519, 0, sb_ammo[2]);
919                                 else if (cl.items & NEX_IT_CELLS)
920                                         Sbar_DrawPic (519, 0, sb_ammo[3]);
921
922                                 if(cl.stats[STAT_AMMO] <= 10)
923                                         Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
924                                 else
925                                         Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
926
927                         }
928
929                         DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay->name,0,0,1,1,1,1,DRAWFLAG_MODULATE);
930                 }
931         }
932         else
933         {
934                 sbar_y = vid.conheight - SBAR_HEIGHT;
935                 if (cl.gametype == GAME_DEATHMATCH)
936                         sbar_x = 0;
937                 else
938                         sbar_x = (vid.conwidth - 320)/2;
939
940                 if (sb_lines > 24)
941                 {
942                         if (gamemode != GAME_GOODVSBAD2)
943                                 Sbar_DrawInventory ();
944                         if (!cl.islocalgame)
945                                 Sbar_DrawFrags ();
946                 }
947
948                 if (sb_showscores || cl.stats[STAT_HEALTH] <= 0)
949                 {
950                         if (gamemode != GAME_GOODVSBAD2)
951                                 Sbar_DrawAlphaPic (0, 0, sb_scorebar, 0.4);
952                         Sbar_DrawScoreboard ();
953                 }
954                 else if (sb_lines)
955                 {
956                         Sbar_DrawAlphaPic (0, 0, sb_sbar, 0.4);
957
958                         // keys (hipnotic only)
959                         //MED 01/04/97 moved keys here so they would not be overwritten
960                         if (gamemode == GAME_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 (gamemode != GAME_GOODVSBAD2)
969                         {
970                                 if (cl.items & IT_INVULNERABILITY)
971                                 {
972                                         Sbar_DrawNum (24, 0, 666, 3, 1);
973                                         Sbar_DrawPic (0, 0, sb_disc);
974                                 }
975                                 else
976                                 {
977                                         if (gamemode == GAME_ROGUE)
978                                         {
979                                                 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
980                                                 if (cl.items & RIT_ARMOR3)
981                                                         Sbar_DrawPic (0, 0, sb_armor[2]);
982                                                 else if (cl.items & RIT_ARMOR2)
983                                                         Sbar_DrawPic (0, 0, sb_armor[1]);
984                                                 else if (cl.items & RIT_ARMOR1)
985                                                         Sbar_DrawPic (0, 0, sb_armor[0]);
986                                         }
987                                         else
988                                         {
989                                                 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, 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
1000                         // face
1001                         Sbar_DrawFace ();
1002
1003                         // health
1004                         Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1005
1006                         // ammo icon
1007                         if (gamemode == GAME_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, cl.stats[STAT_AMMO] <= 10);
1037
1038                 }
1039         }
1040
1041         if (vid.conwidth > 320 && cl.gametype == GAME_DEATHMATCH)
1042                 Sbar_MiniDeathmatchOverlay ();
1043
1044         Sbar_ShowFPS();
1045
1046         R_Draw2DCrosshair();
1047 }
1048
1049 //=============================================================================
1050
1051 /*
1052 ==================
1053 Sbar_DeathmatchOverlay
1054
1055 ==================
1056 */
1057 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1058 {
1059         qbyte *c;
1060         if (s->name[0] || s->frags || s->colors || (s - cl.scores) == cl.playerentity - 1)
1061         {
1062                 // draw colors behind score
1063                 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
1064                 DrawQ_Fill(x + 8, y+1, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha.value, 0);
1065                 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
1066                 DrawQ_Fill(x + 8, y+4, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha.value, 0);
1067                 // print the text
1068                 DrawQ_String(x, y, va("%c%4i %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha.value, 0);
1069                 return 8;
1070         }
1071         else
1072                 return 0;
1073 }
1074
1075 void Sbar_DeathmatchOverlay (void)
1076 {
1077         int i, x, y;
1078         cachepic_t *pic;
1079
1080         pic = Draw_CachePic ("gfx/ranking.lmp");
1081         DrawQ_Pic ((vid.conwidth - pic->width)/2, 8, "gfx/ranking.lmp", 0, 0, 1, 1, 1, 1 * sbar_alpha.value, 0);
1082
1083         // scores
1084         Sbar_SortFrags ();
1085         // draw the text
1086         x = (vid.conwidth - (6 + 15) * 8) / 2;
1087         y = 40;
1088         for (i = 0;i < scoreboardlines && y < vid.conheight;i++)
1089                 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1090 }
1091
1092 /*
1093 ==================
1094 Sbar_DeathmatchOverlay
1095
1096 ==================
1097 */
1098 void Sbar_MiniDeathmatchOverlay (void)
1099 {
1100         int i, x, y, numlines;
1101
1102         // decide where to print
1103         // AK Nex wants its scores on the upper left
1104         if(gamemode == GAME_NEXUIZ)
1105         {
1106                 x = 0;
1107                 y = 0;
1108         }
1109         else
1110         {
1111                 x = 324;
1112                 y = vid.conheight - sb_lines;
1113         }
1114
1115         numlines = (vid.conheight - y) / 8;
1116         // give up if there isn't room
1117         if (x + (6 + 15) * 8 > vid.conwidth || numlines < 1)
1118                 return;
1119
1120         // scores
1121         Sbar_SortFrags ();
1122
1123         //find us
1124         for (i = 0; i < scoreboardlines; i++)
1125                 if (fragsort[i] == cl.playerentity - 1)
1126                         break;
1127
1128         if (i == scoreboardlines) // we're not there
1129                 i = 0;
1130         else // figure out start
1131         {
1132                 i -= numlines/2;
1133                 i = bound(0, i, scoreboardlines - numlines);
1134         }
1135
1136         for (;i < scoreboardlines && y < vid.conheight;i++)
1137                 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1138 }
1139
1140 /*
1141 ==================
1142 Sbar_IntermissionOverlay
1143
1144 ==================
1145 */
1146 void Sbar_IntermissionOverlay (void)
1147 {
1148         int             dig;
1149         int             num;
1150
1151         if (cl.gametype == GAME_DEATHMATCH)
1152         {
1153                 Sbar_DeathmatchOverlay ();
1154                 return;
1155         }
1156
1157         sbar_x = (vid.conwidth - 320) >> 1;
1158         sbar_y = (vid.conheight - 200) >> 1;
1159
1160         DrawQ_Pic (sbar_x + 64, sbar_y + 24, "gfx/complete.lmp", 0, 0, 1, 1, 1, 1 * sbar_alpha.value, 0);
1161         DrawQ_Pic (sbar_x + 0, sbar_y + 56, "gfx/inter.lmp", 0, 0, 1, 1, 1, 1 * sbar_alpha.value, 0);
1162
1163 // time
1164         dig = cl.completed_time/60;
1165         Sbar_DrawNum (160, 64, dig, 3, 0);
1166         num = cl.completed_time - dig*60;
1167         Sbar_DrawPic (234,64,sb_colon);
1168         Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1169         Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1170
1171         Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1172         Sbar_DrawPic (232, 104, sb_slash);
1173         Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1174
1175         Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1176         Sbar_DrawPic (232, 144, sb_slash);
1177         Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1178
1179 }
1180
1181
1182 /*
1183 ==================
1184 Sbar_FinaleOverlay
1185
1186 ==================
1187 */
1188 void Sbar_FinaleOverlay (void)
1189 {
1190         cachepic_t      *pic;
1191
1192         pic = Draw_CachePic ("gfx/finale.lmp");
1193         DrawQ_Pic((vid.conwidth - pic->width)/2, 16, "gfx/finale.lmp", 0, 0, 1, 1, 1, 1 * sbar_alpha.value, 0);
1194 }
1195