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