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