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