fix the minutes display on the QW scoreboard
[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 sbarpic_s
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 sbarpic_t *zymsb_crosshair_center;
93 sbarpic_t *zymsb_crosshair_line;
94 sbarpic_t *zymsb_crosshair_health;
95 sbarpic_t *zymsb_crosshair_ammo;
96 sbarpic_t *zymsb_crosshair_clip;
97 sbarpic_t *zymsb_crosshair_background;
98 sbarpic_t *zymsb_crosshair_left1;
99 sbarpic_t *zymsb_crosshair_left2;
100 sbarpic_t *zymsb_crosshair_right;
101
102 cvar_t showfps = {CVAR_SAVE, "showfps", "0", "shows your rendered fps (frames per second)"};
103 cvar_t showtime = {CVAR_SAVE, "showtime", "0", "shows current time of day (useful on screenshots)"};
104 cvar_t showtime_format = {CVAR_SAVE, "showtime_format", "%H:%M:%S", "format string for time of day"};
105 cvar_t showdate = {CVAR_SAVE, "showdate", "0", "shows current date (useful on screenshots)"};
106 cvar_t showdate_format = {CVAR_SAVE, "showdate_format", "%Y-%m-%d", "format string for date"};
107 cvar_t sbar_alpha_bg = {CVAR_SAVE, "sbar_alpha_bg", "0.4", "opacity value of the statusbar background image"};
108 cvar_t sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1", "opacity value of the statusbar weapon/item icons and numbers"};
109
110 cvar_t cl_deathscoreboard = {0, "cl_deathscoreboard", "1", "shows scoreboard (+showscores) while dead"};
111
112 void Sbar_MiniDeathmatchOverlay (int x, int y);
113 void Sbar_DeathmatchOverlay (void);
114 void Sbar_IntermissionOverlay (void);
115 void Sbar_FinaleOverlay (void);
116
117
118 /*
119 ===============
120 Sbar_ShowScores
121
122 Tab key down
123 ===============
124 */
125 void Sbar_ShowScores (void)
126 {
127         if (sb_showscores)
128                 return;
129         sb_showscores = true;
130 }
131
132 /*
133 ===============
134 Sbar_DontShowScores
135
136 Tab key up
137 ===============
138 */
139 void Sbar_DontShowScores (void)
140 {
141         sb_showscores = false;
142 }
143
144 void sbar_start(void)
145 {
146         int i;
147
148         numsbarpics = 0;
149
150         if (gamemode == GAME_NETHERWORLD)
151         {
152         }
153         else if (gamemode == GAME_SOM)
154         {
155                 sb_disc = Sbar_NewPic("gfx/disc");
156
157                 for (i = 0;i < 10;i++)
158                         sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
159
160                 somsb_health = Sbar_NewPic("gfx/hud_health");
161                 somsb_ammo[0] = Sbar_NewPic("gfx/sb_shells");
162                 somsb_ammo[1] = Sbar_NewPic("gfx/sb_nails");
163                 somsb_ammo[2] = Sbar_NewPic("gfx/sb_rocket");
164                 somsb_ammo[3] = Sbar_NewPic("gfx/sb_cells");
165                 somsb_armor[0] = Sbar_NewPic("gfx/sb_armor1");
166                 somsb_armor[1] = Sbar_NewPic("gfx/sb_armor2");
167                 somsb_armor[2] = Sbar_NewPic("gfx/sb_armor3");
168         }
169         else if (gamemode == GAME_NEXUIZ)
170         {
171                 for (i = 0;i < 10;i++)
172                         sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
173                 sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
174
175                 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
176                 sb_ammo[1] = Sbar_NewPic ("gfx/sb_bullets");
177                 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
178                 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
179
180                 sb_items[2] = Sbar_NewPic ("gfx/sb_slowmo");
181                 sb_items[3] = Sbar_NewPic ("gfx/sb_invinc");
182                 sb_items[4] = Sbar_NewPic ("gfx/sb_energy");
183                 sb_items[5] = Sbar_NewPic ("gfx/sb_str");
184
185                 sb_sbar = Sbar_NewPic("gfx/sbar");
186                 sb_sbar_minimal = Sbar_NewPic("gfx/sbar_minimal");
187                 sb_sbar_overlay = Sbar_NewPic("gfx/sbar_overlay");
188
189                 for(i = 0; i < 9;i++)
190                         sb_weapons[0][i] = Sbar_NewPic(va("gfx/inv_weapon%i",i));
191         }
192         else if (gamemode == GAME_ZYMOTIC)
193         {
194                 zymsb_crosshair_center = Sbar_NewPic ("gfx/hud/crosshair_center");
195                 zymsb_crosshair_line = Sbar_NewPic ("gfx/hud/crosshair_line");
196                 zymsb_crosshair_health = Sbar_NewPic ("gfx/hud/crosshair_health");
197                 zymsb_crosshair_clip = Sbar_NewPic ("gfx/hud/crosshair_clip");
198                 zymsb_crosshair_ammo = Sbar_NewPic ("gfx/hud/crosshair_ammo");
199                 zymsb_crosshair_background = Sbar_NewPic ("gfx/hud/crosshair_background");
200                 zymsb_crosshair_left1 = Sbar_NewPic ("gfx/hud/crosshair_left1");
201                 zymsb_crosshair_left2 = Sbar_NewPic ("gfx/hud/crosshair_left2");
202                 zymsb_crosshair_right = Sbar_NewPic ("gfx/hud/crosshair_right");
203         }
204         else
205         {
206                 sb_disc = Sbar_NewPic("gfx/disc");
207
208                 for (i = 0;i < 10;i++)
209                 {
210                         sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
211                         sb_nums[1][i] = Sbar_NewPic (va("gfx/anum_%i",i));
212                 }
213
214                 sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
215                 sb_nums[1][10] = Sbar_NewPic ("gfx/anum_minus");
216
217                 sb_colon = Sbar_NewPic ("gfx/num_colon");
218                 sb_slash = Sbar_NewPic ("gfx/num_slash");
219
220                 sb_weapons[0][0] = Sbar_NewPic ("gfx/inv_shotgun");
221                 sb_weapons[0][1] = Sbar_NewPic ("gfx/inv_sshotgun");
222                 sb_weapons[0][2] = Sbar_NewPic ("gfx/inv_nailgun");
223                 sb_weapons[0][3] = Sbar_NewPic ("gfx/inv_snailgun");
224                 sb_weapons[0][4] = Sbar_NewPic ("gfx/inv_rlaunch");
225                 sb_weapons[0][5] = Sbar_NewPic ("gfx/inv_srlaunch");
226                 sb_weapons[0][6] = Sbar_NewPic ("gfx/inv_lightng");
227
228                 sb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_shotgun");
229                 sb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_sshotgun");
230                 sb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_nailgun");
231                 sb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_snailgun");
232                 sb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_rlaunch");
233                 sb_weapons[1][5] = Sbar_NewPic ("gfx/inv2_srlaunch");
234                 sb_weapons[1][6] = Sbar_NewPic ("gfx/inv2_lightng");
235
236                 for (i = 0;i < 5;i++)
237                 {
238                         sb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_shotgun",i+1));
239                         sb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_sshotgun",i+1));
240                         sb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_nailgun",i+1));
241                         sb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_snailgun",i+1));
242                         sb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_rlaunch",i+1));
243                         sb_weapons[2+i][5] = Sbar_NewPic (va("gfx/inva%i_srlaunch",i+1));
244                         sb_weapons[2+i][6] = Sbar_NewPic (va("gfx/inva%i_lightng",i+1));
245                 }
246
247                 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
248                 sb_ammo[1] = Sbar_NewPic ("gfx/sb_nails");
249                 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
250                 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
251
252                 sb_armor[0] = Sbar_NewPic ("gfx/sb_armor1");
253                 sb_armor[1] = Sbar_NewPic ("gfx/sb_armor2");
254                 sb_armor[2] = Sbar_NewPic ("gfx/sb_armor3");
255
256                 sb_items[0] = Sbar_NewPic ("gfx/sb_key1");
257                 sb_items[1] = Sbar_NewPic ("gfx/sb_key2");
258                 sb_items[2] = Sbar_NewPic ("gfx/sb_invis");
259                 sb_items[3] = Sbar_NewPic ("gfx/sb_invuln");
260                 sb_items[4] = Sbar_NewPic ("gfx/sb_suit");
261                 sb_items[5] = Sbar_NewPic ("gfx/sb_quad");
262
263                 sb_sigil[0] = Sbar_NewPic ("gfx/sb_sigil1");
264                 sb_sigil[1] = Sbar_NewPic ("gfx/sb_sigil2");
265                 sb_sigil[2] = Sbar_NewPic ("gfx/sb_sigil3");
266                 sb_sigil[3] = Sbar_NewPic ("gfx/sb_sigil4");
267
268                 sb_faces[4][0] = Sbar_NewPic ("gfx/face1");
269                 sb_faces[4][1] = Sbar_NewPic ("gfx/face_p1");
270                 sb_faces[3][0] = Sbar_NewPic ("gfx/face2");
271                 sb_faces[3][1] = Sbar_NewPic ("gfx/face_p2");
272                 sb_faces[2][0] = Sbar_NewPic ("gfx/face3");
273                 sb_faces[2][1] = Sbar_NewPic ("gfx/face_p3");
274                 sb_faces[1][0] = Sbar_NewPic ("gfx/face4");
275                 sb_faces[1][1] = Sbar_NewPic ("gfx/face_p4");
276                 sb_faces[0][0] = Sbar_NewPic ("gfx/face5");
277                 sb_faces[0][1] = Sbar_NewPic ("gfx/face_p5");
278
279                 sb_face_invis = Sbar_NewPic ("gfx/face_invis");
280                 sb_face_invuln = Sbar_NewPic ("gfx/face_invul2");
281                 sb_face_invis_invuln = Sbar_NewPic ("gfx/face_inv2");
282                 sb_face_quad = Sbar_NewPic ("gfx/face_quad");
283
284                 sb_sbar = Sbar_NewPic ("gfx/sbar");
285                 sb_ibar = Sbar_NewPic ("gfx/ibar");
286                 sb_scorebar = Sbar_NewPic ("gfx/scorebar");
287
288         //MED 01/04/97 added new hipnotic weapons
289                 if (gamemode == GAME_HIPNOTIC)
290                 {
291                         hsb_weapons[0][0] = Sbar_NewPic ("gfx/inv_laser");
292                         hsb_weapons[0][1] = Sbar_NewPic ("gfx/inv_mjolnir");
293                         hsb_weapons[0][2] = Sbar_NewPic ("gfx/inv_gren_prox");
294                         hsb_weapons[0][3] = Sbar_NewPic ("gfx/inv_prox_gren");
295                         hsb_weapons[0][4] = Sbar_NewPic ("gfx/inv_prox");
296
297                         hsb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_laser");
298                         hsb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_mjolnir");
299                         hsb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_gren_prox");
300                         hsb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_prox_gren");
301                         hsb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_prox");
302
303                         for (i = 0;i < 5;i++)
304                         {
305                                 hsb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_laser",i+1));
306                                 hsb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_mjolnir",i+1));
307                                 hsb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_gren_prox",i+1));
308                                 hsb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_prox_gren",i+1));
309                                 hsb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_prox",i+1));
310                         }
311
312                         hsb_items[0] = Sbar_NewPic ("gfx/sb_wsuit");
313                         hsb_items[1] = Sbar_NewPic ("gfx/sb_eshld");
314                 }
315                 else if (gamemode == GAME_ROGUE)
316                 {
317                         rsb_invbar[0] = Sbar_NewPic ("gfx/r_invbar1");
318                         rsb_invbar[1] = Sbar_NewPic ("gfx/r_invbar2");
319
320                         rsb_weapons[0] = Sbar_NewPic ("gfx/r_lava");
321                         rsb_weapons[1] = Sbar_NewPic ("gfx/r_superlava");
322                         rsb_weapons[2] = Sbar_NewPic ("gfx/r_gren");
323                         rsb_weapons[3] = Sbar_NewPic ("gfx/r_multirock");
324                         rsb_weapons[4] = Sbar_NewPic ("gfx/r_plasma");
325
326                         rsb_items[0] = Sbar_NewPic ("gfx/r_shield1");
327                         rsb_items[1] = Sbar_NewPic ("gfx/r_agrav1");
328
329         // PGM 01/19/97 - team color border
330                         rsb_teambord = Sbar_NewPic ("gfx/r_teambord");
331         // PGM 01/19/97 - team color border
332
333                         rsb_ammo[0] = Sbar_NewPic ("gfx/r_ammolava");
334                         rsb_ammo[1] = Sbar_NewPic ("gfx/r_ammomulti");
335                         rsb_ammo[2] = Sbar_NewPic ("gfx/r_ammoplasma");
336                 }
337         }
338 }
339
340 void sbar_shutdown(void)
341 {
342 }
343
344 void sbar_newmap(void)
345 {
346 }
347
348 void Sbar_Init (void)
349 {
350         Cmd_AddCommand ("+showscores", Sbar_ShowScores, "show scoreboard");
351         Cmd_AddCommand ("-showscores", Sbar_DontShowScores, "hide scoreboard");
352         Cvar_RegisterVariable (&showfps);
353         Cvar_RegisterVariable (&showtime);
354         Cvar_RegisterVariable (&showtime_format);
355         Cvar_RegisterVariable (&showdate);
356         Cvar_RegisterVariable (&showdate_format);
357         Cvar_RegisterVariable (&sbar_alpha_bg);
358         Cvar_RegisterVariable (&sbar_alpha_fg);
359         Cvar_RegisterVariable (&cl_deathscoreboard);
360
361         R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
362 }
363
364
365 //=============================================================================
366
367 // drawing routines are relative to the status bar location
368
369 int sbar_x, sbar_y;
370
371 /*
372 =============
373 Sbar_DrawPic
374 =============
375 */
376 void Sbar_DrawPic (int x, int y, sbarpic_t *sbarpic)
377 {
378         DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
379 }
380
381 void Sbar_DrawAlphaPic (int x, int y, sbarpic_t *sbarpic, float alpha)
382 {
383         DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, alpha, 0);
384 }
385
386 /*
387 ================
388 Sbar_DrawCharacter
389
390 Draws one solid graphics character
391 ================
392 */
393 void Sbar_DrawCharacter (int x, int y, int num)
394 {
395         DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
396 }
397
398 /*
399 ================
400 Sbar_DrawString
401 ================
402 */
403 void Sbar_DrawString (int x, int y, char *str)
404 {
405         DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
406 }
407
408 /*
409 =============
410 Sbar_DrawNum
411 =============
412 */
413 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
414 {
415         char str[32], *ptr;
416         int l, frame;
417
418         l = sprintf(str, "%i", num);
419         ptr = str;
420         if (l > digits)
421                 ptr += (l-digits);
422         if (l < digits)
423                 x += (digits-l)*24;
424
425         while (*ptr)
426         {
427                 if (*ptr == '-')
428                         frame = STAT_MINUS;
429                 else
430                         frame = *ptr -'0';
431
432                 Sbar_DrawPic (x, y, sb_nums[color][frame]);
433                 x += 24;
434
435                 ptr++;
436         }
437 }
438
439 /*
440 =============
441 Sbar_DrawXNum
442 =============
443 */
444
445 void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
446 {
447         char str[32], *ptr;
448         int l, frame;
449
450         l = sprintf(str, "%i", num);
451         ptr = str;
452         if (l > digits)
453                 ptr += (l-digits);
454         if (l < digits)
455                 x += (digits-l) * lettersize;
456
457         while (*ptr)
458         {
459                 if (*ptr == '-')
460                         frame = STAT_MINUS;
461                 else
462                         frame = *ptr -'0';
463
464                 DrawQ_Pic (sbar_x + x, sbar_y + y, sb_nums[0][frame]->name,lettersize,lettersize,r,g,b,a * sbar_alpha_fg.value,flags);
465                 x += lettersize;
466
467                 ptr++;
468         }
469 }
470
471 //=============================================================================
472
473
474 int Sbar_IsTeammatch()
475 {
476         // currently only nexuiz uses the team score board
477         return ((gamemode == GAME_NEXUIZ)
478                 && (teamplay.integer > 0));
479 }
480
481 /*
482 ===============
483 Sbar_SortFrags
484 ===============
485 */
486 static int fragsort[MAX_SCOREBOARD];
487 static int scoreboardlines;
488
489 //[515]: Sbar_GetPlayer for csqc "getplayerkey" func
490 int Sbar_GetPlayer (int index)
491 {
492         if(index < 0)
493         {
494                 index = -1-index;
495                 if(index >= scoreboardlines)
496                         return -1;
497                 index = fragsort[index];
498         }
499         if(index >= scoreboardlines)
500                 return -1;
501         return index;
502 }
503
504 static scoreboard_t teams[MAX_SCOREBOARD];
505 static int teamsort[MAX_SCOREBOARD];
506 static int teamlines;
507 void Sbar_SortFrags (void)
508 {
509         int i, j, k, color;
510
511         // sort by frags
512         scoreboardlines = 0;
513         for (i=0 ; i<cl.maxclients ; i++)
514         {
515                 if (cl.scores[i].name[0])
516                 {
517                         fragsort[scoreboardlines] = i;
518                         scoreboardlines++;
519                 }
520         }
521
522         for (i=0 ; i<scoreboardlines ; i++)
523                 for (j=0 ; j<scoreboardlines-1-i ; j++)
524                         if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
525                         {
526                                 k = fragsort[j];
527                                 fragsort[j] = fragsort[j+1];
528                                 fragsort[j+1] = k;
529                         }
530
531         teamlines = 0;
532         if (Sbar_IsTeammatch ())
533         {
534                 // now sort players by teams.
535                 for (i=0 ; i<scoreboardlines ; i++)
536                 {
537                         for (j=0 ; j<scoreboardlines-1-i ; j++)
538                         {
539                                 if (cl.scores[fragsort[j]].colors < cl.scores[fragsort[j+1]].colors)
540                                 {
541                                         k = fragsort[j];
542                                         fragsort[j] = fragsort[j+1];
543                                         fragsort[j+1] = k;
544                                 }
545                         }
546                 }
547
548                 // calculate team scores
549                 color = -1;
550                 for (i=0 ; i<scoreboardlines ; i++)
551                 {
552                         if (color != (cl.scores[fragsort[i]].colors & 15))
553                         {
554                                 color = cl.scores[fragsort[i]].colors & 15;
555                                 teamlines++;
556
557                                 if (color == 4)
558                                         strcpy(teams[teamlines-1].name, "^1Red Team");
559                                 else if (color == 13)
560                                         strcpy(teams[teamlines-1].name, "^4Blue Team");
561                                 else if (color == 9)
562                                         strcpy(teams[teamlines-1].name, "^6Pink Team");
563                                 else if (color == 12)
564                                         strcpy(teams[teamlines-1].name, "^3Yellow Team");
565                                 else
566                                         strcpy(teams[teamlines-1].name, "Total Team Score");
567
568                                 teams[teamlines-1].frags = 0;
569                                 teams[teamlines-1].colors = color + 16 * color;
570                         }
571
572                         if (cl.scores[fragsort[i]].frags != -666)
573                         {
574                                 // do not add spedcators
575                                 // (ugly hack for nexuiz)
576                                 teams[teamlines-1].frags += cl.scores[fragsort[i]].frags;
577                         }
578                 }
579
580                 // now sort teams by scores.
581                 for (i=0 ; i<teamlines ; i++)
582                         teamsort[i] = i;
583                 for (i=0 ; i<teamlines ; i++)
584                 {
585                         for (j=0 ; j<teamlines-1-i ; j++)
586                         {
587                                 if (teams[teamsort[j]].frags < teams[teamsort[j+1]].frags)
588                                 {
589                                         k = teamsort[j];
590                                         teamsort[j] = teamsort[j+1];
591                                         teamsort[j+1] = k;
592                                 }
593                         }
594                 }
595         }
596 }
597
598 /*
599 ===============
600 Sbar_SoloScoreboard
601 ===============
602 */
603 void Sbar_SoloScoreboard (void)
604 {
605         char    str[80];
606         int             minutes, seconds, tens, units;
607         int             l;
608
609         if (gamemode != GAME_NEXUIZ) {
610                 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
611                 Sbar_DrawString (8, 4, str);
612
613                 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
614                 Sbar_DrawString (8, 12, str);
615         }
616
617 // time
618         minutes = cl.time / 60;
619         seconds = cl.time - 60*minutes;
620         tens = seconds / 10;
621         units = seconds - 10*tens;
622         sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
623         Sbar_DrawString (184, 4, str);
624
625 // draw level name
626         if (gamemode == GAME_NEXUIZ) {
627                 l = (int) strlen (cl.worldmodel->name);
628                 Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
629         } else {
630                 l = (int) strlen (cl.levelname);
631                 Sbar_DrawString (232 - l*4, 12, cl.levelname);
632         }
633 }
634
635 /*
636 ===============
637 Sbar_DrawScoreboard
638 ===============
639 */
640 void Sbar_DrawScoreboard (void)
641 {
642         Sbar_SoloScoreboard ();
643         if (cl.gametype == GAME_DEATHMATCH)
644                 Sbar_DeathmatchOverlay ();
645 }
646
647 //=============================================================================
648
649 // AK to make DrawInventory smaller
650 static void Sbar_DrawWeapon(int nr, float fade, int active)
651 {
652         // width = 300, height = 100
653         const int w_width = 300, w_height = 100, w_space = 10;
654         const float w_scale = 0.4;
655
656         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);
657         //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);
658
659         if (active)
660                 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);
661 }
662
663 /*
664 ===============
665 Sbar_DrawInventory
666 ===============
667 */
668 void Sbar_DrawInventory (void)
669 {
670         int i;
671         char num[6];
672         float time;
673         int flashon;
674
675         if (gamemode == GAME_ROGUE)
676         {
677                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
678                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], sbar_alpha_bg.value);
679                 else
680                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], sbar_alpha_bg.value);
681         }
682         else
683                 Sbar_DrawAlphaPic (0, -24, sb_ibar, sbar_alpha_bg.value);
684
685         // weapons
686         for (i=0 ; i<7 ; i++)
687         {
688                 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
689                 {
690                         time = cl.item_gettime[i];
691                         flashon = (int)((cl.time - time)*10);
692                         if (flashon >= 10)
693                         {
694                                 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i)  )
695                                         flashon = 1;
696                                 else
697                                         flashon = 0;
698                         }
699                         else
700                                 flashon = (flashon%5) + 2;
701
702                         Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
703                 }
704         }
705
706         // MED 01/04/97
707         // hipnotic weapons
708         if (gamemode == GAME_HIPNOTIC)
709         {
710                 int grenadeflashing=0;
711                 for (i=0 ; i<4 ; i++)
712                 {
713                         if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
714                         {
715                                 time = cl.item_gettime[hipweapons[i]];
716                                 flashon = (int)((cl.time - time)*10);
717                                 if (flashon >= 10)
718                                 {
719                                         if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i])  )
720                                                 flashon = 1;
721                                         else
722                                                 flashon = 0;
723                                 }
724                                 else
725                                         flashon = (flashon%5) + 2;
726
727                                 // check grenade launcher
728                                 if (i==2)
729                                 {
730                                         if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
731                                         {
732                                                 if (flashon)
733                                                 {
734                                                         grenadeflashing = 1;
735                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
736                                                 }
737                                         }
738                                 }
739                                 else if (i==3)
740                                 {
741                                         if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
742                                         {
743                                                 if (!grenadeflashing)
744                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
745                                         }
746                                         else
747                                                 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
748                                 }
749                                 else
750                                         Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
751                         }
752                 }
753         }
754
755         if (gamemode == GAME_ROGUE)
756         {
757                 // check for powered up weapon.
758                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
759                         for (i=0;i<5;i++)
760                                 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
761                                         Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
762         }
763
764         // ammo counts
765         for (i=0 ; i<4 ; i++)
766         {
767                 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
768                 if (num[0] != ' ')
769                         Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
770                 if (num[1] != ' ')
771                         Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
772                 if (num[2] != ' ')
773                         Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
774         }
775
776         // items
777         for (i=0 ; i<6 ; i++)
778                 if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
779                 {
780                         //MED 01/04/97 changed keys
781                         if (gamemode != GAME_HIPNOTIC || (i>1))
782                                 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
783                 }
784
785         //MED 01/04/97 added hipnotic items
786         // hipnotic items
787         if (gamemode == GAME_HIPNOTIC)
788         {
789                 for (i=0 ; i<2 ; i++)
790                         if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
791                                 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
792         }
793
794         if (gamemode == GAME_ROGUE)
795         {
796                 // new rogue items
797                 for (i=0 ; i<2 ; i++)
798                         if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
799                                 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
800         }
801         else
802         {
803                 // sigils
804                 for (i=0 ; i<4 ; i++)
805                         if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
806                                 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
807         }
808 }
809
810 //=============================================================================
811
812 /*
813 ===============
814 Sbar_DrawFrags
815 ===============
816 */
817 void Sbar_DrawFrags (void)
818 {
819         int i, k, l, x, f;
820         char num[12];
821         scoreboard_t *s;
822         unsigned char *c;
823
824         Sbar_SortFrags ();
825
826         // draw the text
827         l = min(scoreboardlines, 4);
828
829         x = 23 * 8;
830
831         for (i = 0;i < l;i++)
832         {
833                 k = fragsort[i];
834                 s = &cl.scores[k];
835
836                 // draw background
837                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
838                 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);
839                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
840                 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);
841
842                 // draw number
843                 f = s->frags;
844                 sprintf (num, "%3i",f);
845
846                 if (k == cl.viewentity - 1)
847                 {
848                         Sbar_DrawCharacter ( x      + 2, -24, 16);
849                         Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
850                 }
851                 Sbar_DrawCharacter (x +  8, -24, num[0]);
852                 Sbar_DrawCharacter (x + 16, -24, num[1]);
853                 Sbar_DrawCharacter (x + 24, -24, num[2]);
854                 x += 32;
855         }
856 }
857
858 //=============================================================================
859
860
861 /*
862 ===============
863 Sbar_DrawFace
864 ===============
865 */
866 void Sbar_DrawFace (void)
867 {
868         int f;
869
870 // PGM 01/19/97 - team color drawing
871 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
872         if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
873         {
874                 char num[12];
875                 scoreboard_t *s;
876                 unsigned char *c;
877
878                 s = &cl.scores[cl.viewentity - 1];
879                 // draw background
880                 Sbar_DrawPic (112, 0, rsb_teambord);
881                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
882                 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);
883                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
884                 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);
885
886                 // draw number
887                 f = s->frags;
888                 sprintf (num, "%3i",f);
889
890                 if ((s->colors & 0xf0)==0)
891                 {
892                         if (num[0] != ' ')
893                                 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
894                         if (num[1] != ' ')
895                                 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
896                         if (num[2] != ' ')
897                                 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
898                 }
899                 else
900                 {
901                         Sbar_DrawCharacter ( 109, 3, num[0]);
902                         Sbar_DrawCharacter ( 116, 3, num[1]);
903                         Sbar_DrawCharacter ( 123, 3, num[2]);
904                 }
905
906                 return;
907         }
908 // PGM 01/19/97 - team color drawing
909
910         if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
911                 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
912         else if (cl.stats[STAT_ITEMS] & IT_QUAD)
913                 Sbar_DrawPic (112, 0, sb_face_quad );
914         else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
915                 Sbar_DrawPic (112, 0, sb_face_invis );
916         else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
917                 Sbar_DrawPic (112, 0, sb_face_invuln);
918         else
919         {
920                 f = cl.stats[STAT_HEALTH] / 20;
921                 f = bound(0, f, 4);
922                 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
923         }
924 }
925
926 void Sbar_ShowFPS(void)
927 {
928         float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
929         char fpsstring[32];
930         char timestring[32];
931         char datestring[32];
932         qboolean red = false;
933         fpsstring[0] = 0;
934         timestring[0] = 0;
935         datestring[0] = 0;
936         if (showfps.integer)
937         {
938                 float calc;
939                 if (showfps.integer > 1)
940                 {
941                         static double currtime, frametimes[32];
942                         double newtime, total;
943                         int count, i;
944                         static int framecycle = 0;
945
946                         newtime = Sys_DoubleTime();
947                         frametimes[framecycle] = newtime - currtime;
948                         total = 0;
949                         count = 0;
950                         while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31])
951                         {
952                                 total += frametimes[i];
953                                 count++;
954                         }
955                         framecycle++;
956                         framecycle &= 31;
957                         if (showfps.integer == 2)
958                                 calc = (((double)count / total) + 0.5);
959                         else // showfps 3, rapid update
960                                 calc = ((1.0 / (newtime - currtime)) + 0.5);
961                         currtime = newtime;
962                 }
963                 else
964                 {
965                         static double nexttime = 0, lasttime = 0;
966                         static float framerate = 0;
967                         static int framecount = 0;
968                         double newtime;
969                         newtime = Sys_DoubleTime();
970                         if (newtime >= nexttime)
971                         {
972                                 framerate = ((float)framecount / (newtime - lasttime) + 0.5);
973                                 lasttime = newtime;
974                                 nexttime = max(nexttime + 1, lasttime - 1);
975                                 framecount = 0;
976                         }
977                         framecount++;
978                         calc = framerate;
979                 }
980
981                 if ((red = (calc < 1.0f)))
982                         dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
983                 else
984                         dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
985         }
986         if (showtime.integer)
987                 strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
988         if (showdate.integer)
989                 strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
990         if (fpsstring[0] || timestring[0])
991         {
992                 fps_scalex = 12;
993                 fps_scaley = 12;
994                 fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
995                 //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
996                 //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
997                 fps_y = vid_conheight.integer - fps_height;
998                 if (fpsstring[0])
999                 {
1000                         fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
1001                         DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
1002                         if (red)
1003                                 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0);
1004                         else
1005                                 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
1006                         fps_y += fps_scaley;
1007                 }
1008                 if (timestring[0])
1009                 {
1010                         fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
1011                         DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
1012                         DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
1013                         fps_y += fps_scaley;
1014                 }
1015                 if (datestring[0])
1016                 {
1017                         fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
1018                         DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
1019                         DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
1020                         fps_y += fps_scaley;
1021                 }
1022         }
1023 }
1024
1025 void Sbar_DrawGauge(float x, float y, const char *picname, float width, float height, float rangey, float rangeheight, float c1, float c2, float c1r, float c1g, float c1b, float c1a, float c2r, float c2g, float c2b, float c2a, float c3r, float c3g, float c3b, float c3a, int drawflags)
1026 {
1027         float r[5];
1028         c2 = bound(0, c2, 1);
1029         c1 = bound(0, c1, 1 - c2);
1030         r[0] = 0;
1031         r[1] = rangey + rangeheight * (c2 + c1);
1032         r[2] = rangey + rangeheight * (c2);
1033         r[3] = rangey;
1034         r[4] = height;
1035         if (r[1] > r[0])
1036                 DrawQ_SuperPic(x, y + r[0], picname, width, (r[1] - r[0]), 0,(r[0] / height), c3r,c3g,c3b,c3a, 1,(r[0] / height), c3r,c3g,c3b,c3a, 0,(r[1] / height), c3r,c3g,c3b,c3a, 1,(r[1] / height), c3r,c3g,c3b,c3a, drawflags);
1037         if (r[2] > r[1])
1038                 DrawQ_SuperPic(x, y + r[1], picname, width, (r[2] - r[1]), 0,(r[1] / height), c1r,c1g,c1b,c1a, 1,(r[1] / height), c1r,c1g,c1b,c1a, 0,(r[2] / height), c1r,c1g,c1b,c1a, 1,(r[2] / height), c1r,c1g,c1b,c1a, drawflags);
1039         if (r[3] > r[2])
1040                 DrawQ_SuperPic(x, y + r[2], picname, width, (r[3] - r[2]), 0,(r[2] / height), c2r,c2g,c2b,c2a, 1,(r[2] / height), c2r,c2g,c2b,c2a, 0,(r[3] / height), c2r,c2g,c2b,c2a, 1,(r[3] / height), c2r,c2g,c2b,c2a, drawflags);
1041         if (r[4] > r[3])
1042                 DrawQ_SuperPic(x, y + r[3], picname, width, (r[4] - r[3]), 0,(r[3] / height), c3r,c3g,c3b,c3a, 1,(r[3] / height), c3r,c3g,c3b,c3a, 0,(r[4] / height), c3r,c3g,c3b,c3a, 1,(r[4] / height), c3r,c3g,c3b,c3a, drawflags);
1043 }
1044
1045 /*
1046 ===============
1047 Sbar_Draw
1048 ===============
1049 */
1050 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
1051 extern cvar_t v_kicktime;
1052 void Sbar_Draw (void)
1053 {
1054         if(cl.csqc_vidvars.drawenginesbar)      //[515]: csqc drawsbar
1055         {
1056                 if (cl.intermission == 1)
1057                 {
1058                         Sbar_IntermissionOverlay();
1059                         return;
1060                 }
1061                 else if (cl.intermission == 2)
1062                 {
1063                         Sbar_FinaleOverlay();
1064                         return;
1065                 }
1066
1067                 if (gamemode == GAME_NETHERWORLD)
1068                 {
1069                 }
1070                 else if (gamemode == GAME_SOM)
1071                 {
1072                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1073                                 Sbar_DrawScoreboard ();
1074                         else if (sb_lines)
1075                         {
1076                                 // this is the top left of the sbar area
1077                                 sbar_x = 0;
1078                                 sbar_y = vid_conheight.integer - 24*3;
1079
1080                                 // armor
1081                                 if (cl.stats[STAT_ARMOR])
1082                                 {
1083                                         if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1084                                                 Sbar_DrawPic(0, 0, somsb_armor[2]);
1085                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1086                                                 Sbar_DrawPic(0, 0, somsb_armor[1]);
1087                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1088                                                 Sbar_DrawPic(0, 0, somsb_armor[0]);
1089                                         Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1090                                 }
1091
1092                                 // health
1093                                 Sbar_DrawPic(0, 24, somsb_health);
1094                                 Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1095
1096                                 // ammo icon
1097                                 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1098                                         Sbar_DrawPic(0, 48, somsb_ammo[0]);
1099                                 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1100                                         Sbar_DrawPic(0, 48, somsb_ammo[1]);
1101                                 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1102                                         Sbar_DrawPic(0, 48, somsb_ammo[2]);
1103                                 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1104                                         Sbar_DrawPic(0, 48, somsb_ammo[3]);
1105                                 Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
1106                                 if (cl.stats[STAT_SHELLS])
1107                                         Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
1108                         }
1109                 }
1110                 else if (gamemode == GAME_NEXUIZ)
1111                 {
1112                         sbar_y = vid_conheight.integer - 47;
1113                         sbar_x = (vid_conwidth.integer - 640)/2;
1114
1115                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1116                         {
1117                                 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1118                                 Sbar_DrawScoreboard ();
1119                         }
1120                         else if (sb_lines)
1121                         {
1122                                 int i;
1123                                 double time;
1124                                 float fade;
1125
1126                                 // we have a max time 2s (min time = 0)
1127                                 if ((time = cl.time - cl.weapontime) < 2)
1128                                 {
1129                                         fade = (1.0 - 0.5 * time);
1130                                         fade *= fade;
1131                                         for (i = 0; i < 8;i++)
1132                                                 if (cl.stats[STAT_ITEMS] & (1 << i))
1133                                                         Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1134
1135                                         if((cl.stats[STAT_ITEMS] & (1<<12)))
1136                                                 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1137                                 }
1138
1139                                 //if (!cl.islocalgame)
1140                                 //      Sbar_DrawFrags ();
1141
1142                                 if (sb_lines > 24)
1143                                         Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_fg.value);
1144                                 else
1145                                         Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
1146
1147                                 // special items
1148                                 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1149                                 {
1150                                         // Nexuiz has no anum pics
1151                                         //Sbar_DrawNum (36, 0, 666, 3, 1);
1152                                         // Nexuiz has no disc pic
1153                                         //Sbar_DrawPic (0, 0, sb_disc);
1154                                 }
1155
1156                                 // armor
1157                                 Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
1158
1159                                 // health
1160                                 if(cl.stats[STAT_HEALTH] > 100)
1161                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
1162                                 else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
1163                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1164                                 else
1165                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1166
1167                                 // AK dont draw ammo for the laser
1168                                 if(cl.stats[STAT_ACTIVEWEAPON] != 12)
1169                                 {
1170                                         if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1171                                                 Sbar_DrawPic (519, 0, sb_ammo[0]);
1172                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1173                                                 Sbar_DrawPic (519, 0, sb_ammo[1]);
1174                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1175                                                 Sbar_DrawPic (519, 0, sb_ammo[2]);
1176                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1177                                                 Sbar_DrawPic (519, 0, sb_ammo[3]);
1178
1179                                         if(cl.stats[STAT_AMMO] <= 10)
1180                                                 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
1181                                         else
1182                                                 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
1183
1184                                 }
1185
1186                                 if (sb_lines > 24)
1187                                         DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay->name,0,0,1,1,1,1,DRAWFLAG_MODULATE);
1188                         }
1189
1190                         //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1191                         //      Sbar_MiniDeathmatchOverlay (0, 17);
1192                 }
1193                 else if (gamemode == GAME_ZYMOTIC)
1194                 {
1195         #if 1
1196                         float scale = 64.0f / 256.0f;
1197                         float kickoffset[3];
1198                         VectorClear(kickoffset);
1199                         if (v_dmg_time > 0)
1200                         {
1201                                 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1202                                 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1203                         }
1204                         sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1205                         sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1206                         // left1 16, 48 : 126 -66
1207                         // left2 16, 128 : 196 -66
1208                         // right 176, 48 : 196 -136
1209                         Sbar_DrawGauge(sbar_x +  16 * scale, sbar_y +  48 * scale, zymsb_crosshair_left1->name, 64*scale,  80*scale, 78*scale,  -66*scale, cl.stats[STAT_AMMO]  * (1.0 / 200.0), cl.stats[STAT_SHELLS]  * (1.0 / 200.0), 0.8f,0.8f,0.0f,1.0f, 0.8f,0.5f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1210                         Sbar_DrawGauge(sbar_x +  16 * scale, sbar_y + 128 * scale, zymsb_crosshair_left2->name, 64*scale,  80*scale, 68*scale,  -66*scale, cl.stats[STAT_NAILS] * (1.0 / 200.0), cl.stats[STAT_ROCKETS] * (1.0 / 200.0), 0.8f,0.8f,0.0f,1.0f, 0.8f,0.5f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1211                         Sbar_DrawGauge(sbar_x + 176 * scale, sbar_y +  48 * scale, zymsb_crosshair_right->name, 64*scale, 160*scale, 148*scale, -136*scale, cl.stats[STAT_ARMOR]  * (1.0 / 300.0), cl.stats[STAT_HEALTH]  * (1.0 / 300.0), 0.0f,0.5f,1.0f,1.0f, 1.0f,0.0f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1212                         DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1213         #else
1214                         float scale = 128.0f / 256.0f;
1215                         float healthstart, healthheight, healthstarttc, healthendtc;
1216                         float shieldstart, shieldheight, shieldstarttc, shieldendtc;
1217                         float ammostart, ammoheight, ammostarttc, ammoendtc;
1218                         float clipstart, clipheight, clipstarttc, clipendtc;
1219                         float kickoffset[3], offset;
1220                         VectorClear(kickoffset);
1221                         if (v_dmg_time > 0)
1222                         {
1223                                 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1224                                 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1225                         }
1226                         sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1227                         sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1228                         offset = 0; // TODO: offset should be controlled by recoil (question: how to detect firing?)
1229                         DrawQ_SuperPic(sbar_x +  120           * scale, sbar_y + ( 88 - offset) * scale, zymsb_crosshair_line->name, 16 * scale, 36 * scale, 0,0, 1,1,1,1, 1,0, 1,1,1,1, 0,1, 1,1,1,1, 1,1, 1,1,1,1, 0);
1230                         DrawQ_SuperPic(sbar_x + (132 + offset) * scale, sbar_y + 120            * scale, zymsb_crosshair_line->name, 36 * scale, 16 * scale, 0,1, 1,1,1,1, 0,0, 1,1,1,1, 1,1, 1,1,1,1, 1,0, 1,1,1,1, 0);
1231                         DrawQ_SuperPic(sbar_x +  120           * scale, sbar_y + (132 + offset) * scale, zymsb_crosshair_line->name, 16 * scale, 36 * scale, 1,1, 1,1,1,1, 0,1, 1,1,1,1, 1,0, 1,1,1,1, 0,0, 1,1,1,1, 0);
1232                         DrawQ_SuperPic(sbar_x + ( 88 - offset) * scale, sbar_y + 120            * scale, zymsb_crosshair_line->name, 36 * scale, 16 * scale, 1,0, 1,1,1,1, 1,1, 1,1,1,1, 0,0, 1,1,1,1, 0,1, 1,1,1,1, 0);
1233                         healthheight = cl.stats[STAT_HEALTH] * (152.0f / 300.0f);
1234                         shieldheight = cl.stats[STAT_ARMOR] * (152.0f / 300.0f);
1235                         healthstart = 204 - healthheight;
1236                         shieldstart = healthstart - shieldheight;
1237                         healthstarttc = healthstart * (1.0f / 256.0f);
1238                         healthendtc = (healthstart + healthheight) * (1.0f / 256.0f);
1239                         shieldstarttc = shieldstart * (1.0f / 256.0f);
1240                         shieldendtc = (shieldstart + shieldheight) * (1.0f / 256.0f);
1241                         ammoheight = cl.stats[STAT_SHELLS] * (62.0f / 200.0f);
1242                         ammostart = 114 - ammoheight;
1243                         ammostarttc = ammostart * (1.0f / 256.0f);
1244                         ammoendtc = (ammostart + ammoheight) * (1.0f / 256.0f);
1245                         clipheight = cl.stats[STAT_AMMO] * (122.0f / 200.0f);
1246                         clipstart = 190 - clipheight;
1247                         clipstarttc = clipstart * (1.0f / 256.0f);
1248                         clipendtc = (clipstart + clipheight) * (1.0f / 256.0f);
1249                         if (healthheight > 0) DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + healthstart * scale, zymsb_crosshair_health->name, 256 * scale, healthheight * scale, 0,healthstarttc, 1.0f,0.0f,0.0f,1.0f, 1,healthstarttc, 1.0f,0.0f,0.0f,1.0f, 0,healthendtc, 1.0f,0.0f,0.0f,1.0f, 1,healthendtc, 1.0f,0.0f,0.0f,1.0f, DRAWFLAG_NORMAL);
1250                         if (shieldheight > 0) DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + shieldstart * scale, zymsb_crosshair_health->name, 256 * scale, shieldheight * scale, 0,shieldstarttc, 0.0f,0.5f,1.0f,1.0f, 1,shieldstarttc, 0.0f,0.5f,1.0f,1.0f, 0,shieldendtc, 0.0f,0.5f,1.0f,1.0f, 1,shieldendtc, 0.0f,0.5f,1.0f,1.0f, DRAWFLAG_NORMAL);
1251                         if (ammoheight > 0)   DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + ammostart   * scale, zymsb_crosshair_ammo->name,   256 * scale, ammoheight   * scale, 0,ammostarttc,   0.8f,0.8f,0.0f,1.0f, 1,ammostarttc,   0.8f,0.8f,0.0f,1.0f, 0,ammoendtc,   0.8f,0.8f,0.0f,1.0f, 1,ammoendtc,   0.8f,0.8f,0.0f,1.0f, DRAWFLAG_NORMAL);
1252                         if (clipheight > 0)   DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + clipstart   * scale, zymsb_crosshair_clip->name,   256 * scale, clipheight   * scale, 0,clipstarttc,   1.0f,1.0f,0.0f,1.0f, 1,clipstarttc,   1.0f,1.0f,0.0f,1.0f, 0,clipendtc,   1.0f,1.0f,0.0f,1.0f, 1,clipendtc,   1.0f,1.0f,0.0f,1.0f, DRAWFLAG_NORMAL);
1253                         DrawQ_Pic(sbar_x + 0 * scale, sbar_y + 0 * scale, zymsb_crosshair_background->name, 256 * scale, 256 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1254                         DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1255         #endif
1256                 }
1257                 else // Quake and others
1258                 {
1259                         sbar_y = vid_conheight.integer - SBAR_HEIGHT;
1260                         if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
1261                                 sbar_x = 0;
1262                         else
1263                                 sbar_x = (vid_conwidth.integer - 320)/2;
1264
1265                         if (sb_lines > 24)
1266                         {
1267                                 if (gamemode != GAME_GOODVSBAD2)
1268                                         Sbar_DrawInventory ();
1269                                 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1270                                         Sbar_DrawFrags ();
1271                         }
1272
1273                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1274                         {
1275                                 if (gamemode != GAME_GOODVSBAD2)
1276                                         Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1277                                 Sbar_DrawScoreboard ();
1278                         }
1279                         else if (sb_lines)
1280                         {
1281                                 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_bg.value);
1282
1283                                 // keys (hipnotic only)
1284                                 //MED 01/04/97 moved keys here so they would not be overwritten
1285                                 if (gamemode == GAME_HIPNOTIC)
1286                                 {
1287                                         if (cl.stats[STAT_ITEMS] & IT_KEY1)
1288                                                 Sbar_DrawPic (209, 3, sb_items[0]);
1289                                         if (cl.stats[STAT_ITEMS] & IT_KEY2)
1290                                                 Sbar_DrawPic (209, 12, sb_items[1]);
1291                                 }
1292                                 // armor
1293                                 if (gamemode != GAME_GOODVSBAD2)
1294                                 {
1295                                         if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1296                                         {
1297                                                 Sbar_DrawNum (24, 0, 666, 3, 1);
1298                                                 Sbar_DrawPic (0, 0, sb_disc);
1299                                         }
1300                                         else
1301                                         {
1302                                                 if (gamemode == GAME_ROGUE)
1303                                                 {
1304                                                         Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1305                                                         if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
1306                                                                 Sbar_DrawPic (0, 0, sb_armor[2]);
1307                                                         else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
1308                                                                 Sbar_DrawPic (0, 0, sb_armor[1]);
1309                                                         else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
1310                                                                 Sbar_DrawPic (0, 0, sb_armor[0]);
1311                                                 }
1312                                                 else
1313                                                 {
1314                                                         Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1315                                                         if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1316                                                                 Sbar_DrawPic (0, 0, sb_armor[2]);
1317                                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1318                                                                 Sbar_DrawPic (0, 0, sb_armor[1]);
1319                                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1320                                                                 Sbar_DrawPic (0, 0, sb_armor[0]);
1321                                                 }
1322                                         }
1323                                 }
1324
1325                                 // face
1326                                 Sbar_DrawFace ();
1327
1328                                 // health
1329                                 Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1330
1331                                 // ammo icon
1332                                 if (gamemode == GAME_ROGUE)
1333                                 {
1334                                         if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
1335                                                 Sbar_DrawPic (224, 0, sb_ammo[0]);
1336                                         else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
1337                                                 Sbar_DrawPic (224, 0, sb_ammo[1]);
1338                                         else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
1339                                                 Sbar_DrawPic (224, 0, sb_ammo[2]);
1340                                         else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
1341                                                 Sbar_DrawPic (224, 0, sb_ammo[3]);
1342                                         else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
1343                                                 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1344                                         else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
1345                                                 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1346                                         else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
1347                                                 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1348                                 }
1349                                 else
1350                                 {
1351                                         if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1352                                                 Sbar_DrawPic (224, 0, sb_ammo[0]);
1353                                         else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1354                                                 Sbar_DrawPic (224, 0, sb_ammo[1]);
1355                                         else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1356                                                 Sbar_DrawPic (224, 0, sb_ammo[2]);
1357                                         else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1358                                                 Sbar_DrawPic (224, 0, sb_ammo[3]);
1359                                 }
1360
1361                                 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1362
1363                         }
1364
1365                         if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1366                         {
1367                                 if (gamemode == GAME_TRANSFUSION)
1368                                         Sbar_MiniDeathmatchOverlay (0, 0);
1369                                 else
1370                                         Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
1371                         }
1372                 }
1373         }
1374
1375         Sbar_ShowFPS();
1376
1377         if(cl.csqc_vidvars.drawcrosshair)
1378                 R_Draw2DCrosshair();
1379
1380         if (cl_prydoncursor.integer)
1381                 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);
1382 }
1383
1384 //=============================================================================
1385
1386 /*
1387 ==================
1388 Sbar_DeathmatchOverlay
1389
1390 ==================
1391 */
1392 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1393 {
1394         int minutes;
1395         unsigned char *c;
1396         if (cls.protocol == PROTOCOL_QUAKEWORLD)
1397         {
1398                 minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : realtime - s->qw_entertime) / 60.0);
1399                 // draw colors behind score
1400                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1401                 DrawQ_Fill(x + 14*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);
1402                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1403                 DrawQ_Fill(x + 14*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);
1404                 // print the text
1405                 //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);
1406                 DrawQ_ColoredString(x, y, va("%c%4i %2i %4i %4i %-4s %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
1407         }
1408         else
1409         {
1410                 // draw colors behind score
1411                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1412                 DrawQ_Fill(x + 1*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);
1413                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1414                 DrawQ_Fill(x + 1*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);
1415                 // print the text
1416                 //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);
1417                 DrawQ_ColoredString(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, NULL );
1418         }
1419         return 8;
1420 }
1421
1422 void Sbar_DeathmatchOverlay (void)
1423 {
1424         int i, x, y;
1425         cachepic_t *pic;
1426
1427         // request new ping times every two second
1428         if (cl.last_ping_request < realtime - 2)
1429         {
1430                 cl.last_ping_request = realtime;
1431                 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1432                 {
1433                         MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
1434                         MSG_WriteString(&cls.netcon->message, "pings");
1435                 }
1436         }
1437
1438         pic = Draw_CachePic ("gfx/ranking", true);
1439         DrawQ_Pic ((vid_conwidth.integer - pic->width)/2, 8, "gfx/ranking", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1440
1441         // scores
1442         Sbar_SortFrags ();
1443         // draw the text
1444         if (cls.protocol == PROTOCOL_QUAKEWORLD)
1445                 x = (vid_conwidth.integer - (6 + 17 + 15) * 8) / 2;
1446         else
1447                 x = (vid_conwidth.integer - (6 + 15) * 8) / 2;
1448         y = 40;
1449
1450         if (Sbar_IsTeammatch ())
1451         {
1452                 // show team scores first
1453                 for (i = 0;i < teamlines && y < vid_conheight.integer;i++)
1454                         y += Sbar_PrintScoreboardItem((teams + teamsort[i]), x, y);
1455                 y += 5;
1456         }
1457
1458         for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
1459                 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1460 }
1461
1462 /*
1463 ==================
1464 Sbar_DeathmatchOverlay
1465
1466 ==================
1467 */
1468 void Sbar_MiniDeathmatchOverlay (int x, int y)
1469 {
1470         int i, numlines;
1471
1472         // decide where to print
1473         if (gamemode == GAME_TRANSFUSION)
1474                 numlines = (vid_conwidth.integer - x + 127) / 128;
1475         else
1476                 numlines = (vid_conheight.integer - y + 7) / 8;
1477
1478         // give up if there isn't room
1479         if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
1480                 return;
1481
1482         // scores
1483         Sbar_SortFrags ();
1484
1485         //find us
1486         for (i = 0; i < scoreboardlines; i++)
1487                 if (fragsort[i] == cl.playerentity - 1)
1488                         break;
1489
1490         // figure out start
1491         i -= numlines/2;
1492         i = min(i, scoreboardlines - numlines);
1493         i = max(i, 0);
1494
1495         if (gamemode == GAME_TRANSFUSION)
1496         {
1497                 for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
1498                         x += 128 + Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1499         }
1500         else
1501         {
1502                 for (;i < scoreboardlines && y < vid_conheight.integer;i++)
1503                         y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1504         }
1505 }
1506
1507 /*
1508 ==================
1509 Sbar_IntermissionOverlay
1510
1511 ==================
1512 */
1513 void Sbar_IntermissionOverlay (void)
1514 {
1515         int             dig;
1516         int             num;
1517
1518         if (cl.gametype == GAME_DEATHMATCH)
1519         {
1520                 Sbar_DeathmatchOverlay ();
1521                 return;
1522         }
1523
1524         sbar_x = (vid_conwidth.integer - 320) >> 1;
1525         sbar_y = (vid_conheight.integer - 200) >> 1;
1526
1527         DrawQ_Pic (sbar_x + 64, sbar_y + 24, "gfx/complete", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1528         DrawQ_Pic (sbar_x + 0, sbar_y + 56, "gfx/inter", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1529
1530 // time
1531         dig = cl.completed_time/60;
1532         Sbar_DrawNum (160, 64, dig, 3, 0);
1533         num = cl.completed_time - dig*60;
1534         if (gamemode != GAME_NEXUIZ)
1535                 Sbar_DrawPic (234,64,sb_colon);
1536         Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1537         Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1538
1539         Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1540         if (gamemode != GAME_NEXUIZ)
1541                 Sbar_DrawPic (232, 104, sb_slash);
1542         Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1543
1544         Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1545         if (gamemode != GAME_NEXUIZ)
1546                 Sbar_DrawPic (232, 144, sb_slash);
1547         Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1548
1549 }
1550
1551
1552 /*
1553 ==================
1554 Sbar_FinaleOverlay
1555
1556 ==================
1557 */
1558 void Sbar_FinaleOverlay (void)
1559 {
1560         cachepic_t      *pic;
1561
1562         pic = Draw_CachePic ("gfx/finale", true);
1563         DrawQ_Pic((vid_conwidth.integer - pic->width)/2, 16, "gfx/finale", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1564 }
1565