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