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