]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - sbar.c
csqc patch from [515], seems to work with [515]'s dpcsqc test mod, needs a lot of...
[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 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"};
103 cvar_t  showtime = {CVAR_SAVE, "showtime", "0"};
104 cvar_t  showtime_format = {CVAR_SAVE, "showtime_format", "%H:%M:%S"};
105 cvar_t  showdate = {CVAR_SAVE, "showdate", "0"};
106 cvar_t  showdate_format = {CVAR_SAVE, "showdate_format", "%Y-%m-%d"};
107 cvar_t  sbar_alpha_bg = {CVAR_SAVE, "sbar_alpha_bg", "0.4"};
108 cvar_t  sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1"};
109
110 cvar_t  cl_deathscoreboard = {0, "cl_deathscoreboard", "1"};
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);
351         Cmd_AddCommand ("-showscores", Sbar_DontShowScores);
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)
553                         {
554                                 color = cl.scores[fragsort[i]].colors;
555                                 teamlines++;
556                                 strcpy(teams[teamlines-1].name, "Total Team Score");
557                                 teams[teamlines-1].frags = 0;
558                                 teams[teamlines-1].colors = cl.scores[fragsort[i]].colors;
559                         }
560
561                         if (cl.scores[fragsort[i]].frags != -666)
562                         {
563                                 // do not add spedcators
564                                 // (ugly hack for nexuiz)
565                                 teams[teamlines-1].frags += cl.scores[fragsort[i]].frags;
566                         }
567                 }
568
569                 // now sort teams by scores.
570                 for (i=0 ; i<teamlines ; i++)
571                         teamsort[i] = i;
572                 for (i=0 ; i<teamlines ; i++)
573                 {
574                         for (j=0 ; j<teamlines-1-i ; j++)
575                         {
576                                 if (teams[teamsort[j]].frags < teams[teamsort[j+1]].frags)
577                                 {
578                                         k = teamsort[j];
579                                         teamsort[j] = teamsort[j+1];
580                                         teamsort[j+1] = k;
581                                 }
582                         }
583                 }
584         }
585 }
586
587 /*
588 ===============
589 Sbar_SoloScoreboard
590 ===============
591 */
592 void Sbar_SoloScoreboard (void)
593 {
594         char    str[80];
595         int             minutes, seconds, tens, units;
596         int             l;
597
598         if (gamemode != GAME_NEXUIZ) {
599                 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
600                 Sbar_DrawString (8, 4, str);
601
602                 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
603                 Sbar_DrawString (8, 12, str);
604         }
605
606 // time
607         minutes = cl.time / 60;
608         seconds = cl.time - 60*minutes;
609         tens = seconds / 10;
610         units = seconds - 10*tens;
611         sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
612         Sbar_DrawString (184, 4, str);
613
614 // draw level name
615         if (gamemode == GAME_NEXUIZ) {
616                 l = (int) strlen (cl.worldmodel->name);
617                 Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
618         } else {
619                 l = (int) strlen (cl.levelname);
620                 Sbar_DrawString (232 - l*4, 12, cl.levelname);
621         }
622 }
623
624 /*
625 ===============
626 Sbar_DrawScoreboard
627 ===============
628 */
629 void Sbar_DrawScoreboard (void)
630 {
631         Sbar_SoloScoreboard ();
632         if (cl.gametype == GAME_DEATHMATCH)
633                 Sbar_DeathmatchOverlay ();
634 }
635
636 //=============================================================================
637
638 // AK to make DrawInventory smaller
639 static void Sbar_DrawWeapon(int nr, float fade, int active)
640 {
641         // width = 300, height = 100
642         const int w_width = 300, w_height = 100, w_space = 10;
643         const float w_scale = 0.4;
644
645         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);
646         //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);
647
648         if (active)
649                 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);
650 }
651
652 /*
653 ===============
654 Sbar_DrawInventory
655 ===============
656 */
657 void Sbar_DrawInventory (void)
658 {
659         int i;
660         char num[6];
661         float time;
662         int flashon;
663
664         if (gamemode == GAME_ROGUE)
665         {
666                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
667                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], sbar_alpha_bg.value);
668                 else
669                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], sbar_alpha_bg.value);
670         }
671         else
672                 Sbar_DrawAlphaPic (0, -24, sb_ibar, sbar_alpha_bg.value);
673
674         // weapons
675         for (i=0 ; i<7 ; i++)
676         {
677                 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
678                 {
679                         time = cl.item_gettime[i];
680                         flashon = (int)((cl.time - time)*10);
681                         if (flashon >= 10)
682                         {
683                                 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i)  )
684                                         flashon = 1;
685                                 else
686                                         flashon = 0;
687                         }
688                         else
689                                 flashon = (flashon%5) + 2;
690
691                         Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
692                 }
693         }
694
695         // MED 01/04/97
696         // hipnotic weapons
697         if (gamemode == GAME_HIPNOTIC)
698         {
699                 int grenadeflashing=0;
700                 for (i=0 ; i<4 ; i++)
701                 {
702                         if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
703                         {
704                                 time = cl.item_gettime[hipweapons[i]];
705                                 flashon = (int)((cl.time - time)*10);
706                                 if (flashon >= 10)
707                                 {
708                                         if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i])  )
709                                                 flashon = 1;
710                                         else
711                                                 flashon = 0;
712                                 }
713                                 else
714                                         flashon = (flashon%5) + 2;
715
716                                 // check grenade launcher
717                                 if (i==2)
718                                 {
719                                         if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
720                                         {
721                                                 if (flashon)
722                                                 {
723                                                         grenadeflashing = 1;
724                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
725                                                 }
726                                         }
727                                 }
728                                 else if (i==3)
729                                 {
730                                         if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
731                                         {
732                                                 if (!grenadeflashing)
733                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
734                                         }
735                                         else
736                                                 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
737                                 }
738                                 else
739                                         Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
740                         }
741                 }
742         }
743
744         if (gamemode == GAME_ROGUE)
745         {
746                 // check for powered up weapon.
747                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
748                         for (i=0;i<5;i++)
749                                 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
750                                         Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
751         }
752
753         // ammo counts
754         for (i=0 ; i<4 ; i++)
755         {
756                 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
757                 if (num[0] != ' ')
758                         Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
759                 if (num[1] != ' ')
760                         Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
761                 if (num[2] != ' ')
762                         Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
763         }
764
765         // items
766         for (i=0 ; i<6 ; i++)
767                 if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
768                 {
769                         //MED 01/04/97 changed keys
770                         if (gamemode != GAME_HIPNOTIC || (i>1))
771                                 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
772                 }
773
774         //MED 01/04/97 added hipnotic items
775         // hipnotic items
776         if (gamemode == GAME_HIPNOTIC)
777         {
778                 for (i=0 ; i<2 ; i++)
779                         if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
780                                 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
781         }
782
783         if (gamemode == GAME_ROGUE)
784         {
785                 // new rogue items
786                 for (i=0 ; i<2 ; i++)
787                         if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
788                                 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
789         }
790         else
791         {
792                 // sigils
793                 for (i=0 ; i<4 ; i++)
794                         if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
795                                 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
796         }
797 }
798
799 //=============================================================================
800
801 /*
802 ===============
803 Sbar_DrawFrags
804 ===============
805 */
806 void Sbar_DrawFrags (void)
807 {
808         int i, k, l, x, f;
809         char num[12];
810         scoreboard_t *s;
811         unsigned char *c;
812
813         Sbar_SortFrags ();
814
815         // draw the text
816         l = min(scoreboardlines, 4);
817
818         x = 23 * 8;
819
820         for (i = 0;i < l;i++)
821         {
822                 k = fragsort[i];
823                 s = &cl.scores[k];
824
825                 // draw background
826                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
827                 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);
828                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
829                 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);
830
831                 // draw number
832                 f = s->frags;
833                 sprintf (num, "%3i",f);
834
835                 if (k == cl.viewentity - 1)
836                 {
837                         Sbar_DrawCharacter ( x      + 2, -24, 16);
838                         Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
839                 }
840                 Sbar_DrawCharacter (x +  8, -24, num[0]);
841                 Sbar_DrawCharacter (x + 16, -24, num[1]);
842                 Sbar_DrawCharacter (x + 24, -24, num[2]);
843                 x += 32;
844         }
845 }
846
847 //=============================================================================
848
849
850 /*
851 ===============
852 Sbar_DrawFace
853 ===============
854 */
855 void Sbar_DrawFace (void)
856 {
857         int f;
858
859 // PGM 01/19/97 - team color drawing
860 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
861         if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
862         {
863                 char num[12];
864                 scoreboard_t *s;
865                 unsigned char *c;
866
867                 s = &cl.scores[cl.viewentity - 1];
868                 // draw background
869                 Sbar_DrawPic (112, 0, rsb_teambord);
870                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
871                 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);
872                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
873                 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);
874
875                 // draw number
876                 f = s->frags;
877                 sprintf (num, "%3i",f);
878
879                 if ((s->colors & 0xf0)==0)
880                 {
881                         if (num[0] != ' ')
882                                 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
883                         if (num[1] != ' ')
884                                 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
885                         if (num[2] != ' ')
886                                 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
887                 }
888                 else
889                 {
890                         Sbar_DrawCharacter ( 109, 3, num[0]);
891                         Sbar_DrawCharacter ( 116, 3, num[1]);
892                         Sbar_DrawCharacter ( 123, 3, num[2]);
893                 }
894
895                 return;
896         }
897 // PGM 01/19/97 - team color drawing
898
899         if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
900                 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
901         else if (cl.stats[STAT_ITEMS] & IT_QUAD)
902                 Sbar_DrawPic (112, 0, sb_face_quad );
903         else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
904                 Sbar_DrawPic (112, 0, sb_face_invis );
905         else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
906                 Sbar_DrawPic (112, 0, sb_face_invuln);
907         else
908         {
909                 f = cl.stats[STAT_HEALTH] / 20;
910                 f = bound(0, f, 4);
911                 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
912         }
913 }
914
915 void Sbar_ShowFPS(void)
916 {
917         float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
918         char fpsstring[32];
919         char timestring[32];
920         char datestring[32];
921         qboolean red = false;
922         fpsstring[0] = 0;
923         timestring[0] = 0;
924         datestring[0] = 0;
925         if (showfps.integer)
926         {
927                 float calc;
928                 if (showfps.integer > 1)
929                 {
930                         static double currtime, frametimes[32];
931                         double newtime, total;
932                         int count, i;
933                         static int framecycle = 0;
934
935                         newtime = Sys_DoubleTime();
936                         frametimes[framecycle] = newtime - currtime;
937                         total = 0;
938                         count = 0;
939                         while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31])
940                         {
941                                 total += frametimes[i];
942                                 count++;
943                         }
944                         framecycle++;
945                         framecycle &= 31;
946                         if (showfps.integer == 2)
947                                 calc = (((double)count / total) + 0.5);
948                         else // showfps 3, rapid update
949                                 calc = ((1.0 / (newtime - currtime)) + 0.5);
950                         currtime = newtime;
951                 }
952                 else
953                 {
954                         static double nexttime = 0, lasttime = 0;
955                         static float framerate = 0;
956                         static int framecount = 0;
957                         double newtime;
958                         newtime = Sys_DoubleTime();
959                         if (newtime >= nexttime)
960                         {
961                                 framerate = ((float)framecount / (newtime - lasttime) + 0.5);
962                                 lasttime = newtime;
963                                 nexttime = max(nexttime + 1, lasttime - 1);
964                                 framecount = 0;
965                         }
966                         framecount++;
967                         calc = framerate;
968                 }
969
970                 if ((red = (calc < 1.0f)))
971                         dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
972                 else
973                         dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
974         }
975         if (showtime.integer)
976                 strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
977         if (showdate.integer)
978                 strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
979         if (fpsstring[0] || timestring[0])
980         {
981                 fps_scalex = 12;
982                 fps_scaley = 12;
983                 fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
984                 //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
985                 //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
986                 fps_y = vid_conheight.integer - fps_height;
987                 if (fpsstring[0])
988                 {
989                         fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
990                         DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
991                         if (red)
992                                 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0);
993                         else
994                                 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
995                         fps_y += fps_scaley;
996                 }
997                 if (timestring[0])
998                 {
999                         fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
1000                         DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
1001                         DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
1002                         fps_y += fps_scaley;
1003                 }
1004                 if (datestring[0])
1005                 {
1006                         fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
1007                         DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
1008                         DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
1009                         fps_y += fps_scaley;
1010                 }
1011         }
1012 }
1013
1014 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)
1015 {
1016         float r[5];
1017         c2 = bound(0, c2, 1);
1018         c1 = bound(0, c1, 1 - c2);
1019         r[0] = 0;
1020         r[1] = rangey + rangeheight * (c2 + c1);
1021         r[2] = rangey + rangeheight * (c2);
1022         r[3] = rangey;
1023         r[4] = height;
1024         if (r[1] > r[0])
1025                 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);
1026         if (r[2] > r[1])
1027                 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);
1028         if (r[3] > r[2])
1029                 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);
1030         if (r[4] > r[3])
1031                 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);
1032 }
1033
1034 /*
1035 ===============
1036 Sbar_Draw
1037 ===============
1038 */
1039 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
1040 extern cvar_t v_kicktime;
1041 void Sbar_Draw (void)
1042 {
1043         if(cl.csqc_vidvars.drawenginesbar)      //[515]: csqc drawsbar
1044         {
1045                 if (cl.intermission == 1)
1046                 {
1047                         Sbar_IntermissionOverlay();
1048                         return;
1049                 }
1050                 else if (cl.intermission == 2)
1051                 {
1052                         Sbar_FinaleOverlay();
1053                         return;
1054                 }
1055
1056                 if (gamemode == GAME_NETHERWORLD)
1057                 {
1058                 }
1059                 else if (gamemode == GAME_SOM)
1060                 {
1061                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1062                                 Sbar_DrawScoreboard ();
1063                         else if (sb_lines)
1064                         {
1065                                 // this is the top left of the sbar area
1066                                 sbar_x = 0;
1067                                 sbar_y = vid_conheight.integer - 24*3;
1068
1069                                 // armor
1070                                 if (cl.stats[STAT_ARMOR])
1071                                 {
1072                                         if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1073                                                 Sbar_DrawPic(0, 0, somsb_armor[2]);
1074                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1075                                                 Sbar_DrawPic(0, 0, somsb_armor[1]);
1076                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1077                                                 Sbar_DrawPic(0, 0, somsb_armor[0]);
1078                                         Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1079                                 }
1080
1081                                 // health
1082                                 Sbar_DrawPic(0, 24, somsb_health);
1083                                 Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1084
1085                                 // ammo icon
1086                                 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1087                                         Sbar_DrawPic(0, 48, somsb_ammo[0]);
1088                                 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1089                                         Sbar_DrawPic(0, 48, somsb_ammo[1]);
1090                                 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1091                                         Sbar_DrawPic(0, 48, somsb_ammo[2]);
1092                                 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1093                                         Sbar_DrawPic(0, 48, somsb_ammo[3]);
1094                                 Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
1095                                 if (cl.stats[STAT_SHELLS])
1096                                         Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
1097                         }
1098                 }
1099                 else if (gamemode == GAME_NEXUIZ)
1100                 {
1101                         sbar_y = vid_conheight.integer - 47;
1102                         sbar_x = (vid_conwidth.integer - 640)/2;
1103
1104                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1105                         {
1106                                 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1107                                 Sbar_DrawScoreboard ();
1108                         }
1109                         else if (sb_lines)
1110                         {
1111                                 int i;
1112                                 double time;
1113                                 float fade;
1114
1115                                 // we have a max time 2s (min time = 0)
1116                                 if ((time = cl.time - cl.weapontime) < 2)
1117                                 {
1118                                         fade = (1.0 - 0.5 * time);
1119                                         fade *= fade;
1120                                         for (i = 0; i < 8;i++)
1121                                                 if (cl.stats[STAT_ITEMS] & (1 << i))
1122                                                         Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1123
1124                                         if((cl.stats[STAT_ITEMS] & (1<<12)))
1125                                                 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1126                                 }
1127
1128                                 //if (!cl.islocalgame)
1129                                 //      Sbar_DrawFrags ();
1130
1131                                 if (sb_lines > 24)
1132                                         Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_fg.value);
1133                                 else
1134                                         Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
1135
1136                                 // special items
1137                                 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1138                                 {
1139                                         // Nexuiz has no anum pics
1140                                         //Sbar_DrawNum (36, 0, 666, 3, 1);
1141                                         // Nexuiz has no disc pic
1142                                         //Sbar_DrawPic (0, 0, sb_disc);
1143                                 }
1144
1145                                 // armor
1146                                 Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
1147
1148                                 // health
1149                                 if(cl.stats[STAT_HEALTH] > 100)
1150                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
1151                                 else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
1152                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1153                                 else
1154                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1155
1156                                 // AK dont draw ammo for the laser
1157                                 if(cl.stats[STAT_ACTIVEWEAPON] != 12)
1158                                 {
1159                                         if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1160                                                 Sbar_DrawPic (519, 0, sb_ammo[0]);
1161                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1162                                                 Sbar_DrawPic (519, 0, sb_ammo[1]);
1163                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1164                                                 Sbar_DrawPic (519, 0, sb_ammo[2]);
1165                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1166                                                 Sbar_DrawPic (519, 0, sb_ammo[3]);
1167
1168                                         if(cl.stats[STAT_AMMO] <= 10)
1169                                                 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
1170                                         else
1171                                                 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
1172
1173                                 }
1174
1175                                 if (sb_lines > 24)
1176                                         DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay->name,0,0,1,1,1,1,DRAWFLAG_MODULATE);
1177                         }
1178
1179                         //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1180                         //      Sbar_MiniDeathmatchOverlay (0, 17);
1181                 }
1182                 else if (gamemode == GAME_ZYMOTIC)
1183                 {
1184         #if 1
1185                         float scale = 64.0f / 256.0f;
1186                         float kickoffset[3];
1187                         VectorClear(kickoffset);
1188                         if (v_dmg_time > 0)
1189                         {
1190                                 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1191                                 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1192                         }
1193                         sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1194                         sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1195                         // left1 16, 48 : 126 -66
1196                         // left2 16, 128 : 196 -66
1197                         // right 176, 48 : 196 -136
1198                         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);
1199                         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);
1200                         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);
1201                         DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1202         #else
1203                         float scale = 128.0f / 256.0f;
1204                         float healthstart, healthheight, healthstarttc, healthendtc;
1205                         float shieldstart, shieldheight, shieldstarttc, shieldendtc;
1206                         float ammostart, ammoheight, ammostarttc, ammoendtc;
1207                         float clipstart, clipheight, clipstarttc, clipendtc;
1208                         float kickoffset[3], offset;
1209                         VectorClear(kickoffset);
1210                         if (v_dmg_time > 0)
1211                         {
1212                                 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1213                                 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1214                         }
1215                         sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1216                         sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1217                         offset = 0; // TODO: offset should be controlled by recoil (question: how to detect firing?)
1218                         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);
1219                         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);
1220                         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);
1221                         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);
1222                         healthheight = cl.stats[STAT_HEALTH] * (152.0f / 300.0f);
1223                         shieldheight = cl.stats[STAT_ARMOR] * (152.0f / 300.0f);
1224                         healthstart = 204 - healthheight;
1225                         shieldstart = healthstart - shieldheight;
1226                         healthstarttc = healthstart * (1.0f / 256.0f);
1227                         healthendtc = (healthstart + healthheight) * (1.0f / 256.0f);
1228                         shieldstarttc = shieldstart * (1.0f / 256.0f);
1229                         shieldendtc = (shieldstart + shieldheight) * (1.0f / 256.0f);
1230                         ammoheight = cl.stats[STAT_SHELLS] * (62.0f / 200.0f);
1231                         ammostart = 114 - ammoheight;
1232                         ammostarttc = ammostart * (1.0f / 256.0f);
1233                         ammoendtc = (ammostart + ammoheight) * (1.0f / 256.0f);
1234                         clipheight = cl.stats[STAT_AMMO] * (122.0f / 200.0f);
1235                         clipstart = 190 - clipheight;
1236                         clipstarttc = clipstart * (1.0f / 256.0f);
1237                         clipendtc = (clipstart + clipheight) * (1.0f / 256.0f);
1238                         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);
1239                         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);
1240                         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);
1241                         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);
1242                         DrawQ_Pic(sbar_x + 0 * scale, sbar_y + 0 * scale, zymsb_crosshair_background->name, 256 * scale, 256 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1243                         DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1244         #endif
1245                 }
1246                 else // Quake and others
1247                 {
1248                         sbar_y = vid_conheight.integer - SBAR_HEIGHT;
1249                         if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
1250                                 sbar_x = 0;
1251                         else
1252                                 sbar_x = (vid_conwidth.integer - 320)/2;
1253
1254                         if (sb_lines > 24)
1255                         {
1256                                 if (gamemode != GAME_GOODVSBAD2)
1257                                         Sbar_DrawInventory ();
1258                                 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1259                                         Sbar_DrawFrags ();
1260                         }
1261
1262                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1263                         {
1264                                 if (gamemode != GAME_GOODVSBAD2)
1265                                         Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1266                                 Sbar_DrawScoreboard ();
1267                         }
1268                         else if (sb_lines)
1269                         {
1270                                 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_bg.value);
1271
1272                                 // keys (hipnotic only)
1273                                 //MED 01/04/97 moved keys here so they would not be overwritten
1274                                 if (gamemode == GAME_HIPNOTIC)
1275                                 {
1276                                         if (cl.stats[STAT_ITEMS] & IT_KEY1)
1277                                                 Sbar_DrawPic (209, 3, sb_items[0]);
1278                                         if (cl.stats[STAT_ITEMS] & IT_KEY2)
1279                                                 Sbar_DrawPic (209, 12, sb_items[1]);
1280                                 }
1281                                 // armor
1282                                 if (gamemode != GAME_GOODVSBAD2)
1283                                 {
1284                                         if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1285                                         {
1286                                                 Sbar_DrawNum (24, 0, 666, 3, 1);
1287                                                 Sbar_DrawPic (0, 0, sb_disc);
1288                                         }
1289                                         else
1290                                         {
1291                                                 if (gamemode == GAME_ROGUE)
1292                                                 {
1293                                                         Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1294                                                         if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
1295                                                                 Sbar_DrawPic (0, 0, sb_armor[2]);
1296                                                         else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
1297                                                                 Sbar_DrawPic (0, 0, sb_armor[1]);
1298                                                         else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
1299                                                                 Sbar_DrawPic (0, 0, sb_armor[0]);
1300                                                 }
1301                                                 else
1302                                                 {
1303                                                         Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1304                                                         if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1305                                                                 Sbar_DrawPic (0, 0, sb_armor[2]);
1306                                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1307                                                                 Sbar_DrawPic (0, 0, sb_armor[1]);
1308                                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1309                                                                 Sbar_DrawPic (0, 0, sb_armor[0]);
1310                                                 }
1311                                         }
1312                                 }
1313
1314                                 // face
1315                                 Sbar_DrawFace ();
1316
1317                                 // health
1318                                 Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1319
1320                                 // ammo icon
1321                                 if (gamemode == GAME_ROGUE)
1322                                 {
1323                                         if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
1324                                                 Sbar_DrawPic (224, 0, sb_ammo[0]);
1325                                         else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
1326                                                 Sbar_DrawPic (224, 0, sb_ammo[1]);
1327                                         else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
1328                                                 Sbar_DrawPic (224, 0, sb_ammo[2]);
1329                                         else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
1330                                                 Sbar_DrawPic (224, 0, sb_ammo[3]);
1331                                         else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
1332                                                 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1333                                         else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
1334                                                 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1335                                         else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
1336                                                 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1337                                 }
1338                                 else
1339                                 {
1340                                         if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1341                                                 Sbar_DrawPic (224, 0, sb_ammo[0]);
1342                                         else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1343                                                 Sbar_DrawPic (224, 0, sb_ammo[1]);
1344                                         else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1345                                                 Sbar_DrawPic (224, 0, sb_ammo[2]);
1346                                         else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1347                                                 Sbar_DrawPic (224, 0, sb_ammo[3]);
1348                                 }
1349
1350                                 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1351
1352                         }
1353
1354                         if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1355                         {
1356                                 if (gamemode == GAME_TRANSFUSION)
1357                                         Sbar_MiniDeathmatchOverlay (0, 0);
1358                                 else
1359                                         Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
1360                         }
1361                 }
1362         }
1363
1364         Sbar_ShowFPS();
1365
1366         if(cl.csqc_vidvars.drawcrosshair)
1367                 R_Draw2DCrosshair();
1368
1369         if (cl_prydoncursor.integer)
1370                 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);
1371 }
1372
1373 //=============================================================================
1374
1375 /*
1376 ==================
1377 Sbar_DeathmatchOverlay
1378
1379 ==================
1380 */
1381 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1382 {
1383         unsigned char *c;
1384         // draw colors behind score
1385         c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1386         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);
1387         c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1388         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);
1389         // print the text
1390         //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);
1391         // FIXME: use a constant for this color tag instead
1392         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 );
1393         return 8;
1394 }
1395
1396 void Sbar_DeathmatchOverlay (void)
1397 {
1398         int i, x, y;
1399         cachepic_t *pic;
1400
1401         pic = Draw_CachePic ("gfx/ranking", true);
1402         DrawQ_Pic ((vid_conwidth.integer - pic->width)/2, 8, "gfx/ranking", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1403
1404         // scores
1405         Sbar_SortFrags ();
1406         // draw the text
1407         x = (vid_conwidth.integer - (6 + 15) * 8) / 2;
1408         y = 40;
1409
1410         if (Sbar_IsTeammatch ())
1411         {
1412                 // show team scores first
1413                 for (i = 0;i < teamlines && y < vid_conheight.integer;i++)
1414                         y += Sbar_PrintScoreboardItem((teams + teamsort[i]), x, y);
1415                 y += 5;
1416         }
1417
1418         for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
1419                 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1420 }
1421
1422 /*
1423 ==================
1424 Sbar_DeathmatchOverlay
1425
1426 ==================
1427 */
1428 void Sbar_MiniDeathmatchOverlay (int x, int y)
1429 {
1430         int i, numlines;
1431
1432         // decide where to print
1433         if (gamemode == GAME_TRANSFUSION)
1434                 numlines = (vid_conwidth.integer - x + 127) / 128;
1435         else
1436                 numlines = (vid_conheight.integer - y + 7) / 8;
1437
1438         // give up if there isn't room
1439         if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
1440                 return;
1441
1442         // scores
1443         Sbar_SortFrags ();
1444
1445         //find us
1446         for (i = 0; i < scoreboardlines; i++)
1447                 if (fragsort[i] == cl.playerentity - 1)
1448                         break;
1449
1450         // figure out start
1451         i -= numlines/2;
1452         i = min(i, scoreboardlines - numlines);
1453         i = max(i, 0);
1454
1455         if (gamemode == GAME_TRANSFUSION)
1456         {
1457                 for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
1458                         x += 128 + Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1459         }
1460         else
1461         {
1462                 for (;i < scoreboardlines && y < vid_conheight.integer;i++)
1463                         y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1464         }
1465 }
1466
1467 /*
1468 ==================
1469 Sbar_IntermissionOverlay
1470
1471 ==================
1472 */
1473 void Sbar_IntermissionOverlay (void)
1474 {
1475         int             dig;
1476         int             num;
1477
1478         if (cl.gametype == GAME_DEATHMATCH)
1479         {
1480                 Sbar_DeathmatchOverlay ();
1481                 return;
1482         }
1483
1484         sbar_x = (vid_conwidth.integer - 320) >> 1;
1485         sbar_y = (vid_conheight.integer - 200) >> 1;
1486
1487         DrawQ_Pic (sbar_x + 64, sbar_y + 24, "gfx/complete", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1488         DrawQ_Pic (sbar_x + 0, sbar_y + 56, "gfx/inter", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1489
1490 // time
1491         dig = cl.completed_time/60;
1492         Sbar_DrawNum (160, 64, dig, 3, 0);
1493         num = cl.completed_time - dig*60;
1494         if (gamemode != GAME_NEXUIZ)
1495                 Sbar_DrawPic (234,64,sb_colon);
1496         Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1497         Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1498
1499         Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1500         if (gamemode != GAME_NEXUIZ)
1501                 Sbar_DrawPic (232, 104, sb_slash);
1502         Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1503
1504         Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1505         if (gamemode != GAME_NEXUIZ)
1506                 Sbar_DrawPic (232, 144, sb_slash);
1507         Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1508
1509 }
1510
1511
1512 /*
1513 ==================
1514 Sbar_FinaleOverlay
1515
1516 ==================
1517 */
1518 void Sbar_FinaleOverlay (void)
1519 {
1520         cachepic_t      *pic;
1521
1522         pic = Draw_CachePic ("gfx/finale", true);
1523         DrawQ_Pic((vid_conwidth.integer - pic->width)/2, 16, "gfx/finale", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1524 }
1525