2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // sbar.c -- status bar code
26 #define STAT_MINUS 10 // num frame for '-' stats digit
27 cachepic_t *sb_nums[2][11];
28 cachepic_t *sb_colon, *sb_slash;
31 cachepic_t *sb_scorebar;
32 // AK only used by NEX
33 cachepic_t *sb_sbar_minimal;
34 cachepic_t *sb_sbar_overlay;
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];
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 cachepic_t *sb_health; // GAME_NEXUIZ
48 cachepic_t *sb_face_invis;
49 cachepic_t *sb_face_quad;
50 cachepic_t *sb_face_invuln;
51 cachepic_t *sb_face_invis_invuln;
53 qboolean sb_showscores;
55 int sb_lines; // scan lines to draw
57 cachepic_t *rsb_invbar[2];
58 cachepic_t *rsb_weapons[5];
59 cachepic_t *rsb_items[2];
60 cachepic_t *rsb_ammo[3];
61 cachepic_t *rsb_teambord; // PGM 01/19/97 - team color border
63 //MED 01/04/97 added two more weapons + 3 alternates for grenade launcher
64 cachepic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes
65 //MED 01/04/97 added array to simplify weapon parsing
66 int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT};
67 //MED 01/04/97 added hipnotic items array
68 cachepic_t *hsb_items[2];
71 cachepic_t *somsb_health;
72 cachepic_t *somsb_ammo[4];
73 cachepic_t *somsb_armor[3];
75 cachepic_t *zymsb_crosshair_center;
76 cachepic_t *zymsb_crosshair_line;
77 cachepic_t *zymsb_crosshair_health;
78 cachepic_t *zymsb_crosshair_ammo;
79 cachepic_t *zymsb_crosshair_clip;
80 cachepic_t *zymsb_crosshair_background;
81 cachepic_t *zymsb_crosshair_left1;
82 cachepic_t *zymsb_crosshair_left2;
83 cachepic_t *zymsb_crosshair_right;
85 cachepic_t *sb_ranking;
86 cachepic_t *sb_complete;
88 cachepic_t *sb_finale;
90 cvar_t showfps = {CVAR_SAVE, "showfps", "0", "shows your rendered fps (frames per second)"};
91 cvar_t showtime = {CVAR_SAVE, "showtime", "0", "shows current time of day (useful on screenshots)"};
92 cvar_t showtime_format = {CVAR_SAVE, "showtime_format", "%H:%M:%S", "format string for time of day"};
93 cvar_t showdate = {CVAR_SAVE, "showdate", "0", "shows current date (useful on screenshots)"};
94 cvar_t showdate_format = {CVAR_SAVE, "showdate_format", "%Y-%m-%d", "format string for date"};
95 cvar_t sbar_alpha_bg = {CVAR_SAVE, "sbar_alpha_bg", "0.4", "opacity value of the statusbar background image"};
96 cvar_t sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1", "opacity value of the statusbar weapon/item icons and numbers"};
97 cvar_t sbar_hudselector = {CVAR_SAVE, "sbar_hudselector", "0", "selects which of the builtin hud layouts to use (meaning is somewhat dependent on gamemode, so nexuiz has a very different set of hud layouts than quake for example)"};
99 cvar_t cl_deathscoreboard = {0, "cl_deathscoreboard", "1", "shows scoreboard (+showscores) while dead"};
101 cvar_t crosshair_color_red = {CVAR_SAVE, "crosshair_color_red", "1", "customizable crosshair color"};
102 cvar_t crosshair_color_green = {CVAR_SAVE, "crosshair_color_green", "0", "customizable crosshair color"};
103 cvar_t crosshair_color_blue = {CVAR_SAVE, "crosshair_color_blue", "0", "customizable crosshair color"};
104 cvar_t crosshair_color_alpha = {CVAR_SAVE, "crosshair_color_alpha", "1", "how opaque the crosshair should be"};
105 cvar_t crosshair_size = {CVAR_SAVE, "crosshair_size", "1", "adjusts size of the crosshair on the screen"};
107 void Sbar_MiniDeathmatchOverlay (int x, int y);
108 void Sbar_DeathmatchOverlay (void);
109 void Sbar_IntermissionOverlay (void);
110 void Sbar_FinaleOverlay (void);
120 void Sbar_ShowScores (void)
124 sb_showscores = true;
134 void Sbar_DontShowScores (void)
136 sb_showscores = false;
139 void sbar_start(void)
143 if (gamemode == GAME_NETHERWORLD)
146 else if (gamemode == GAME_SOM)
148 sb_disc = Draw_CachePic("gfx/disc", true);
150 for (i = 0;i < 10;i++)
151 sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
153 somsb_health = Draw_CachePic("gfx/hud_health", true);
154 somsb_ammo[0] = Draw_CachePic("gfx/sb_shells", true);
155 somsb_ammo[1] = Draw_CachePic("gfx/sb_nails", true);
156 somsb_ammo[2] = Draw_CachePic("gfx/sb_rocket", true);
157 somsb_ammo[3] = Draw_CachePic("gfx/sb_cells", true);
158 somsb_armor[0] = Draw_CachePic("gfx/sb_armor1", true);
159 somsb_armor[1] = Draw_CachePic("gfx/sb_armor2", true);
160 somsb_armor[2] = Draw_CachePic("gfx/sb_armor3", true);
162 else if (gamemode == GAME_NEXUIZ)
164 for (i = 0;i < 10;i++)
165 sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
166 sb_nums[0][10] = Draw_CachePic ("gfx/num_minus", true);
168 sb_ammo[0] = Draw_CachePic ("gfx/sb_shells", true);
169 sb_ammo[1] = Draw_CachePic ("gfx/sb_bullets", true);
170 sb_ammo[2] = Draw_CachePic ("gfx/sb_rocket", true);
171 sb_ammo[3] = Draw_CachePic ("gfx/sb_cells", true);
173 sb_armor[0] = Draw_CachePic ("gfx/sb_armor", true);
177 sb_health = Draw_CachePic ("gfx/sb_health", true);
179 sb_items[2] = Draw_CachePic ("gfx/sb_slowmo", true);
180 sb_items[3] = Draw_CachePic ("gfx/sb_invinc", true);
181 sb_items[4] = Draw_CachePic ("gfx/sb_energy", true);
182 sb_items[5] = Draw_CachePic ("gfx/sb_str", true);
184 sb_items[11] = Draw_CachePic ("gfx/sb_flag_red_taken", true);
185 sb_items[12] = Draw_CachePic ("gfx/sb_flag_red_lost", true);
186 sb_items[13] = Draw_CachePic ("gfx/sb_flag_red_carrying", true);
187 sb_items[14] = Draw_CachePic ("gfx/sb_key_carrying", true);
188 sb_items[15] = Draw_CachePic ("gfx/sb_flag_blue_taken", true);
189 sb_items[16] = Draw_CachePic ("gfx/sb_flag_blue_lost", true);
190 sb_items[17] = Draw_CachePic ("gfx/sb_flag_blue_carrying", true);
192 sb_sbar = Draw_CachePic("gfx/sbar", true);
193 sb_sbar_minimal = Draw_CachePic("gfx/sbar_minimal", true);
194 sb_sbar_overlay = Draw_CachePic("gfx/sbar_overlay", true);
196 for(i = 0; i < 9;i++)
197 sb_weapons[0][i] = Draw_CachePic(va("gfx/inv_weapon%i",i), true);
199 else if (gamemode == GAME_ZYMOTIC)
201 zymsb_crosshair_center = Draw_CachePic ("gfx/hud/crosshair_center", true);
202 zymsb_crosshair_line = Draw_CachePic ("gfx/hud/crosshair_line", true);
203 zymsb_crosshair_health = Draw_CachePic ("gfx/hud/crosshair_health", true);
204 zymsb_crosshair_clip = Draw_CachePic ("gfx/hud/crosshair_clip", true);
205 zymsb_crosshair_ammo = Draw_CachePic ("gfx/hud/crosshair_ammo", true);
206 zymsb_crosshair_background = Draw_CachePic ("gfx/hud/crosshair_background", true);
207 zymsb_crosshair_left1 = Draw_CachePic ("gfx/hud/crosshair_left1", true);
208 zymsb_crosshair_left2 = Draw_CachePic ("gfx/hud/crosshair_left2", true);
209 zymsb_crosshair_right = Draw_CachePic ("gfx/hud/crosshair_right", true);
213 sb_disc = Draw_CachePic("gfx/disc", true);
215 for (i = 0;i < 10;i++)
217 sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
218 sb_nums[1][i] = Draw_CachePic (va("gfx/anum_%i",i), true);
221 sb_nums[0][10] = Draw_CachePic ("gfx/num_minus", true);
222 sb_nums[1][10] = Draw_CachePic ("gfx/anum_minus", true);
224 sb_colon = Draw_CachePic ("gfx/num_colon", true);
225 sb_slash = Draw_CachePic ("gfx/num_slash", true);
227 sb_weapons[0][0] = Draw_CachePic ("gfx/inv_shotgun", true);
228 sb_weapons[0][1] = Draw_CachePic ("gfx/inv_sshotgun", true);
229 sb_weapons[0][2] = Draw_CachePic ("gfx/inv_nailgun", true);
230 sb_weapons[0][3] = Draw_CachePic ("gfx/inv_snailgun", true);
231 sb_weapons[0][4] = Draw_CachePic ("gfx/inv_rlaunch", true);
232 sb_weapons[0][5] = Draw_CachePic ("gfx/inv_srlaunch", true);
233 sb_weapons[0][6] = Draw_CachePic ("gfx/inv_lightng", true);
235 sb_weapons[1][0] = Draw_CachePic ("gfx/inv2_shotgun", true);
236 sb_weapons[1][1] = Draw_CachePic ("gfx/inv2_sshotgun", true);
237 sb_weapons[1][2] = Draw_CachePic ("gfx/inv2_nailgun", true);
238 sb_weapons[1][3] = Draw_CachePic ("gfx/inv2_snailgun", true);
239 sb_weapons[1][4] = Draw_CachePic ("gfx/inv2_rlaunch", true);
240 sb_weapons[1][5] = Draw_CachePic ("gfx/inv2_srlaunch", true);
241 sb_weapons[1][6] = Draw_CachePic ("gfx/inv2_lightng", true);
243 for (i = 0;i < 5;i++)
245 sb_weapons[2+i][0] = Draw_CachePic (va("gfx/inva%i_shotgun",i+1), true);
246 sb_weapons[2+i][1] = Draw_CachePic (va("gfx/inva%i_sshotgun",i+1), true);
247 sb_weapons[2+i][2] = Draw_CachePic (va("gfx/inva%i_nailgun",i+1), true);
248 sb_weapons[2+i][3] = Draw_CachePic (va("gfx/inva%i_snailgun",i+1), true);
249 sb_weapons[2+i][4] = Draw_CachePic (va("gfx/inva%i_rlaunch",i+1), true);
250 sb_weapons[2+i][5] = Draw_CachePic (va("gfx/inva%i_srlaunch",i+1), true);
251 sb_weapons[2+i][6] = Draw_CachePic (va("gfx/inva%i_lightng",i+1), true);
254 sb_ammo[0] = Draw_CachePic ("gfx/sb_shells", true);
255 sb_ammo[1] = Draw_CachePic ("gfx/sb_nails", true);
256 sb_ammo[2] = Draw_CachePic ("gfx/sb_rocket", true);
257 sb_ammo[3] = Draw_CachePic ("gfx/sb_cells", true);
259 sb_armor[0] = Draw_CachePic ("gfx/sb_armor1", true);
260 sb_armor[1] = Draw_CachePic ("gfx/sb_armor2", true);
261 sb_armor[2] = Draw_CachePic ("gfx/sb_armor3", true);
263 sb_items[0] = Draw_CachePic ("gfx/sb_key1", true);
264 sb_items[1] = Draw_CachePic ("gfx/sb_key2", true);
265 sb_items[2] = Draw_CachePic ("gfx/sb_invis", true);
266 sb_items[3] = Draw_CachePic ("gfx/sb_invuln", true);
267 sb_items[4] = Draw_CachePic ("gfx/sb_suit", true);
268 sb_items[5] = Draw_CachePic ("gfx/sb_quad", true);
270 sb_sigil[0] = Draw_CachePic ("gfx/sb_sigil1", true);
271 sb_sigil[1] = Draw_CachePic ("gfx/sb_sigil2", true);
272 sb_sigil[2] = Draw_CachePic ("gfx/sb_sigil3", true);
273 sb_sigil[3] = Draw_CachePic ("gfx/sb_sigil4", true);
275 sb_faces[4][0] = Draw_CachePic ("gfx/face1", true);
276 sb_faces[4][1] = Draw_CachePic ("gfx/face_p1", true);
277 sb_faces[3][0] = Draw_CachePic ("gfx/face2", true);
278 sb_faces[3][1] = Draw_CachePic ("gfx/face_p2", true);
279 sb_faces[2][0] = Draw_CachePic ("gfx/face3", true);
280 sb_faces[2][1] = Draw_CachePic ("gfx/face_p3", true);
281 sb_faces[1][0] = Draw_CachePic ("gfx/face4", true);
282 sb_faces[1][1] = Draw_CachePic ("gfx/face_p4", true);
283 sb_faces[0][0] = Draw_CachePic ("gfx/face5", true);
284 sb_faces[0][1] = Draw_CachePic ("gfx/face_p5", true);
286 sb_face_invis = Draw_CachePic ("gfx/face_invis", true);
287 sb_face_invuln = Draw_CachePic ("gfx/face_invul2", true);
288 sb_face_invis_invuln = Draw_CachePic ("gfx/face_inv2", true);
289 sb_face_quad = Draw_CachePic ("gfx/face_quad", true);
291 sb_sbar = Draw_CachePic ("gfx/sbar", true);
292 sb_ibar = Draw_CachePic ("gfx/ibar", true);
293 sb_scorebar = Draw_CachePic ("gfx/scorebar", true);
295 //MED 01/04/97 added new hipnotic weapons
296 if (gamemode == GAME_HIPNOTIC)
298 hsb_weapons[0][0] = Draw_CachePic ("gfx/inv_laser", true);
299 hsb_weapons[0][1] = Draw_CachePic ("gfx/inv_mjolnir", true);
300 hsb_weapons[0][2] = Draw_CachePic ("gfx/inv_gren_prox", true);
301 hsb_weapons[0][3] = Draw_CachePic ("gfx/inv_prox_gren", true);
302 hsb_weapons[0][4] = Draw_CachePic ("gfx/inv_prox", true);
304 hsb_weapons[1][0] = Draw_CachePic ("gfx/inv2_laser", true);
305 hsb_weapons[1][1] = Draw_CachePic ("gfx/inv2_mjolnir", true);
306 hsb_weapons[1][2] = Draw_CachePic ("gfx/inv2_gren_prox", true);
307 hsb_weapons[1][3] = Draw_CachePic ("gfx/inv2_prox_gren", true);
308 hsb_weapons[1][4] = Draw_CachePic ("gfx/inv2_prox", true);
310 for (i = 0;i < 5;i++)
312 hsb_weapons[2+i][0] = Draw_CachePic (va("gfx/inva%i_laser",i+1), true);
313 hsb_weapons[2+i][1] = Draw_CachePic (va("gfx/inva%i_mjolnir",i+1), true);
314 hsb_weapons[2+i][2] = Draw_CachePic (va("gfx/inva%i_gren_prox",i+1), true);
315 hsb_weapons[2+i][3] = Draw_CachePic (va("gfx/inva%i_prox_gren",i+1), true);
316 hsb_weapons[2+i][4] = Draw_CachePic (va("gfx/inva%i_prox",i+1), true);
319 hsb_items[0] = Draw_CachePic ("gfx/sb_wsuit", true);
320 hsb_items[1] = Draw_CachePic ("gfx/sb_eshld", true);
322 else if (gamemode == GAME_ROGUE)
324 rsb_invbar[0] = Draw_CachePic ("gfx/r_invbar1", true);
325 rsb_invbar[1] = Draw_CachePic ("gfx/r_invbar2", true);
327 rsb_weapons[0] = Draw_CachePic ("gfx/r_lava", true);
328 rsb_weapons[1] = Draw_CachePic ("gfx/r_superlava", true);
329 rsb_weapons[2] = Draw_CachePic ("gfx/r_gren", true);
330 rsb_weapons[3] = Draw_CachePic ("gfx/r_multirock", true);
331 rsb_weapons[4] = Draw_CachePic ("gfx/r_plasma", true);
333 rsb_items[0] = Draw_CachePic ("gfx/r_shield1", true);
334 rsb_items[1] = Draw_CachePic ("gfx/r_agrav1", true);
336 // PGM 01/19/97 - team color border
337 rsb_teambord = Draw_CachePic ("gfx/r_teambord", true);
338 // PGM 01/19/97 - team color border
340 rsb_ammo[0] = Draw_CachePic ("gfx/r_ammolava", true);
341 rsb_ammo[1] = Draw_CachePic ("gfx/r_ammomulti", true);
342 rsb_ammo[2] = Draw_CachePic ("gfx/r_ammoplasma", true);
346 sb_ranking = Draw_CachePic ("gfx/ranking", true);
347 sb_complete = Draw_CachePic ("gfx/complete", true);
348 sb_inter = Draw_CachePic ("gfx/inter", true);
349 sb_finale = Draw_CachePic ("gfx/finale", true);
352 void sbar_shutdown(void)
356 void sbar_newmap(void)
360 void Sbar_Init (void)
362 Cmd_AddCommand("+showscores", Sbar_ShowScores, "show scoreboard");
363 Cmd_AddCommand("-showscores", Sbar_DontShowScores, "hide scoreboard");
364 Cvar_RegisterVariable(&showfps);
365 Cvar_RegisterVariable(&showtime);
366 Cvar_RegisterVariable(&showtime_format);
367 Cvar_RegisterVariable(&showdate);
368 Cvar_RegisterVariable(&showdate_format);
369 Cvar_RegisterVariable(&sbar_alpha_bg);
370 Cvar_RegisterVariable(&sbar_alpha_fg);
371 Cvar_RegisterVariable(&sbar_hudselector);
372 Cvar_RegisterVariable(&cl_deathscoreboard);
374 Cvar_RegisterVariable(&crosshair_color_red);
375 Cvar_RegisterVariable(&crosshair_color_green);
376 Cvar_RegisterVariable(&crosshair_color_blue);
377 Cvar_RegisterVariable(&crosshair_color_alpha);
378 Cvar_RegisterVariable(&crosshair_size);
380 R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
384 //=============================================================================
386 // drawing routines are relative to the status bar location
395 void Sbar_DrawStretchPic (int x, int y, cachepic_t *pic, float alpha, float overridewidth, float overrideheight)
397 DrawQ_Pic (sbar_x + x, sbar_y + y, pic, overridewidth, overrideheight, 1, 1, 1, alpha, 0);
400 void Sbar_DrawPic (int x, int y, cachepic_t *pic)
402 DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
405 void Sbar_DrawAlphaPic (int x, int y, cachepic_t *pic, float alpha)
407 DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, alpha, 0);
414 Draws one solid graphics character
417 void Sbar_DrawCharacter (int x, int y, int num)
419 DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, true);
427 void Sbar_DrawString (int x, int y, char *str)
429 DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, false);
437 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
442 l = sprintf(str, "%i", num);
456 Sbar_DrawPic (x, y, sb_nums[color][frame]);
469 void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
474 l = sprintf(str, "%i", num);
479 x += (digits-l) * lettersize;
488 DrawQ_Pic (sbar_x + x, sbar_y + y, sb_nums[0][frame],lettersize,lettersize,r,g,b,a * sbar_alpha_fg.value,flags);
495 //=============================================================================
498 int Sbar_IsTeammatch()
500 // currently only nexuiz uses the team score board
501 return ((gamemode == GAME_NEXUIZ)
502 && (teamplay.integer > 0));
510 static int fragsort[MAX_SCOREBOARD];
511 static int scoreboardlines;
513 //[515]: Sbar_GetPlayer for csqc "getplayerkey" func
514 int Sbar_GetPlayer (int index)
519 if(index >= scoreboardlines)
521 index = fragsort[index];
523 if(index >= scoreboardlines)
528 static scoreboard_t teams[MAX_SCOREBOARD];
529 static int teamsort[MAX_SCOREBOARD];
530 static int teamlines;
531 void Sbar_SortFrags (void)
537 for (i=0 ; i<cl.maxclients ; i++)
539 if (cl.scores[i].name[0])
541 fragsort[scoreboardlines] = i;
546 for (i=0 ; i<scoreboardlines ; i++)
547 for (j=0 ; j<scoreboardlines-1-i ; j++)
548 if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
551 fragsort[j] = fragsort[j+1];
556 if (Sbar_IsTeammatch ())
558 // now sort players by teams.
559 for (i=0 ; i<scoreboardlines ; i++)
561 for (j=0 ; j<scoreboardlines-1-i ; j++)
563 if (cl.scores[fragsort[j]].colors < cl.scores[fragsort[j+1]].colors)
566 fragsort[j] = fragsort[j+1];
572 // calculate team scores
574 for (i=0 ; i<scoreboardlines ; i++)
576 if (color != (cl.scores[fragsort[i]].colors & 15))
578 const char* teamname;
580 color = cl.scores[fragsort[i]].colors & 15;
586 teamname = "^1Red Team";
589 teamname = "^4Blue Team";
592 teamname = "^6Pink Team";
595 teamname = "^3Yellow Team";
598 teamname = "Total Team Score";
601 strlcpy(teams[teamlines-1].name, teamname, sizeof(teams[teamlines-1].name));
603 teams[teamlines-1].frags = 0;
604 teams[teamlines-1].colors = color + 16 * color;
607 if (cl.scores[fragsort[i]].frags != -666)
609 // do not add spedcators
610 // (ugly hack for nexuiz)
611 teams[teamlines-1].frags += cl.scores[fragsort[i]].frags;
615 // now sort teams by scores.
616 for (i=0 ; i<teamlines ; i++)
618 for (i=0 ; i<teamlines ; i++)
620 for (j=0 ; j<teamlines-1-i ; j++)
622 if (teams[teamsort[j]].frags < teams[teamsort[j+1]].frags)
625 teamsort[j] = teamsort[j+1];
638 void Sbar_SoloScoreboard (void)
641 char str[80], timestr[40];
643 int minutes, seconds;
646 t = (cl.intermission ? cl.completed_time : cl.time);
647 minutes = (int)(t / 60);
648 seconds = (int)(t - 60*floor(t/60));
650 // monsters and secrets are now both on the top row
651 if (cl.stats[STAT_TOTALMONSTERS])
652 Sbar_DrawString(8, 4, va("Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]));
653 if (cl.stats[STAT_TOTALSECRETS])
654 Sbar_DrawString(8+22*8, 4, va("Secrets:%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]));
656 // figure out the map's filename without path or extension
657 strlcpy(str, FS_FileWithoutPath(cl.worldmodel ? cl.worldmodel->name : ""), sizeof(str));
658 if (strrchr(str, '.'))
659 *(strrchr(str, '.')) = 0;
661 // append a : separator and then the full title
662 strlcat(str, ":", sizeof(str));
663 strlcat(str, cl.levelname, sizeof(str));
665 // if there's a newline character, terminate the string there
666 if (strchr(str, '\n'))
667 *(strchr(str, '\n')) = 0;
669 // make the time string
670 timelen = sprintf(timestr, " %i:%02i", minutes, seconds);
672 // truncate the level name if necessary to make room for time
674 if ((int)strlen(str) > max)
677 // print the filename and message
678 Sbar_DrawString(8, 12, str);
681 Sbar_DrawString(8 + max*8, 12, timestr);
685 int minutes, seconds, tens, units;
688 if (gamemode != GAME_NEXUIZ) {
689 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
690 Sbar_DrawString (8, 4, str);
692 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
693 Sbar_DrawString (8, 12, str);
697 minutes = (int)(cl.time / 60);
698 seconds = (int)(cl.time - 60*minutes);
700 units = seconds - 10*tens;
701 sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
702 Sbar_DrawString (184, 4, str);
705 if (gamemode == GAME_NEXUIZ) {
706 l = (int) strlen (cl.worldmodel->name);
707 Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
709 l = (int) strlen (cl.levelname);
710 Sbar_DrawString (232 - l*4, 12, cl.levelname);
720 void Sbar_DrawScoreboard (void)
722 Sbar_SoloScoreboard ();
723 // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
724 //if (cl.gametype == GAME_DEATHMATCH)
726 Sbar_DeathmatchOverlay ();
729 //=============================================================================
731 // AK to make DrawInventory smaller
732 static void Sbar_DrawWeapon(int nr, float fade, int active)
734 if (sbar_hudselector.integer == 1)
736 // width = 300, height = 100
737 const int w_width = 32, w_height = 12, w_space = 2, font_size = 8;
739 DrawQ_Pic((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr, vid_conheight.integer - w_height, sb_weapons[0][nr], w_width, w_height, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 0.6, (active ? 1 : 0.6) * fade * sbar_alpha_fg.value, DRAWFLAG_NORMAL);
740 DrawQ_String((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr + w_space, vid_conheight.integer - w_height + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 1, 0, sbar_alpha_fg.value, 0, NULL, true);
744 // width = 300, height = 100
745 const int w_width = 300, w_height = 100, w_space = 10;
746 const float w_scale = 0.4;
748 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_NORMAL);
749 //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, NULL, true);
758 void Sbar_DrawInventory (void)
765 if (gamemode == GAME_ROGUE)
767 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
768 Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], sbar_alpha_bg.value);
770 Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], sbar_alpha_bg.value);
773 Sbar_DrawAlphaPic (0, -24, sb_ibar, sbar_alpha_bg.value);
776 for (i=0 ; i<7 ; i++)
778 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
780 time = cl.item_gettime[i];
781 flashon = (int)(max(0, cl.time - time)*10);
784 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
790 flashon = (flashon%5) + 2;
792 Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
798 if (gamemode == GAME_HIPNOTIC)
800 int grenadeflashing=0;
801 for (i=0 ; i<4 ; i++)
803 if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
805 time = max(0, cl.item_gettime[hipweapons[i]]);
806 flashon = (int)((cl.time - time)*10);
809 if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i]) )
815 flashon = (flashon%5) + 2;
817 // check grenade launcher
820 if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
825 Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
831 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
833 if (!grenadeflashing)
834 Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
837 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
840 Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
845 if (gamemode == GAME_ROGUE)
847 // check for powered up weapon.
848 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
850 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
851 Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
855 for (i=0 ; i<4 ; i++)
857 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
859 Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
861 Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
863 Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
867 for (i=0 ; i<6 ; i++)
868 if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
870 //MED 01/04/97 changed keys
871 if (gamemode != GAME_HIPNOTIC || (i>1))
872 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
875 //MED 01/04/97 added hipnotic items
877 if (gamemode == GAME_HIPNOTIC)
879 for (i=0 ; i<2 ; i++)
880 if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
881 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
884 if (gamemode == GAME_ROGUE)
887 for (i=0 ; i<2 ; i++)
888 if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
889 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
894 for (i=0 ; i<4 ; i++)
895 if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
896 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
900 //=============================================================================
907 void Sbar_DrawFrags (void)
917 l = min(scoreboardlines, 4);
921 for (i = 0;i < l;i++)
927 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
928 DrawQ_Fill (sbar_x + x + 10, sbar_y - 23, 28, 4, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
929 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
930 DrawQ_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 28, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
934 sprintf (num, "%3i",f);
936 if (k == cl.viewentity - 1)
938 Sbar_DrawCharacter ( x + 2, -24, 16);
939 Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
941 Sbar_DrawCharacter (x + 8, -24, num[0]);
942 Sbar_DrawCharacter (x + 16, -24, num[1]);
943 Sbar_DrawCharacter (x + 24, -24, num[2]);
948 //=============================================================================
956 void Sbar_DrawFace (void)
960 // PGM 01/19/97 - team color drawing
961 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
962 if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
968 s = &cl.scores[cl.viewentity - 1];
970 Sbar_DrawPic (112, 0, rsb_teambord);
971 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
972 DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+3, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
973 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
974 DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+12, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
978 sprintf (num, "%3i",f);
980 if ((s->colors & 0xf0)==0)
983 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
985 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
987 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
991 Sbar_DrawCharacter ( 109, 3, num[0]);
992 Sbar_DrawCharacter ( 116, 3, num[1]);
993 Sbar_DrawCharacter ( 123, 3, num[2]);
998 // PGM 01/19/97 - team color drawing
1000 if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
1001 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
1002 else if (cl.stats[STAT_ITEMS] & IT_QUAD)
1003 Sbar_DrawPic (112, 0, sb_face_quad );
1004 else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
1005 Sbar_DrawPic (112, 0, sb_face_invis );
1006 else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1007 Sbar_DrawPic (112, 0, sb_face_invuln);
1010 f = cl.stats[STAT_HEALTH] / 20;
1012 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
1016 void Sbar_ShowFPS(void)
1018 float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
1020 char timestring[32];
1021 char datestring[32];
1022 qboolean red = false;
1026 if (showfps.integer)
1029 static double nexttime = 0, lasttime = 0;
1030 static double framerate = 0;
1031 static int framecount = 0;
1034 if (newtime >= nexttime)
1036 framerate = framecount / (newtime - lasttime);
1038 nexttime = max(nexttime + 1, lasttime - 1);
1044 if ((red = (calc < 1.0f)))
1045 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
1047 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
1049 if (showtime.integer)
1050 strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
1051 if (showdate.integer)
1052 strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
1053 if (fpsstring[0] || timestring[0])
1057 fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
1058 //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
1059 //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
1060 fps_y = vid_conheight.integer - fps_height;
1063 fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
1064 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
1066 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0, NULL, true);
1068 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
1069 fps_y += fps_scaley;
1073 fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
1074 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
1075 DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
1076 fps_y += fps_scaley;
1080 fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
1081 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
1082 DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
1083 fps_y += fps_scaley;
1088 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)
1091 c2 = bound(0, c2, 1);
1092 c1 = bound(0, c1, 1 - c2);
1094 r[1] = rangey + rangeheight * (c2 + c1);
1095 r[2] = rangey + rangeheight * (c2);
1099 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);
1101 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);
1103 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);
1105 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);
1113 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
1114 extern cvar_t v_kicktime;
1115 void Sbar_Draw (void)
1119 if(cl.csqc_vidvars.drawenginesbar) //[515]: csqc drawsbar
1122 Sbar_DrawScoreboard ();
1123 else if (cl.intermission == 1)
1125 if(gamemode == GAME_NEXUIZ) // display full scoreboard (that is, show scores + map name)
1127 Sbar_DrawScoreboard();
1130 Sbar_IntermissionOverlay();
1132 else if (cl.intermission == 2)
1133 Sbar_FinaleOverlay();
1134 else if (gamemode == GAME_NETHERWORLD)
1137 else if (gamemode == GAME_SOM)
1139 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1140 Sbar_DrawScoreboard ();
1143 // this is the top left of the sbar area
1145 sbar_y = vid_conheight.integer - 24*3;
1148 if (cl.stats[STAT_ARMOR])
1150 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1151 Sbar_DrawPic(0, 0, somsb_armor[2]);
1152 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1153 Sbar_DrawPic(0, 0, somsb_armor[1]);
1154 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1155 Sbar_DrawPic(0, 0, somsb_armor[0]);
1156 Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1160 Sbar_DrawPic(0, 24, somsb_health);
1161 Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1164 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1165 Sbar_DrawPic(0, 48, somsb_ammo[0]);
1166 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1167 Sbar_DrawPic(0, 48, somsb_ammo[1]);
1168 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1169 Sbar_DrawPic(0, 48, somsb_ammo[2]);
1170 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1171 Sbar_DrawPic(0, 48, somsb_ammo[3]);
1172 Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
1173 if (cl.stats[STAT_SHELLS])
1174 Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
1177 else if (gamemode == GAME_NEXUIZ)
1179 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1181 sbar_x = (vid_conwidth.integer - 640)/2;
1182 sbar_y = vid_conheight.integer - 47;
1183 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1184 Sbar_DrawScoreboard ();
1186 else if (sb_lines && sbar_hudselector.integer == 1)
1190 int redflag, blueflag;
1192 sbar_x = (vid_conwidth.integer - 320)/2;
1193 sbar_y = vid_conheight.integer - 24 - 16;
1195 // calculate intensity to draw weapons bar at
1196 fade = 3.2 - 2 * (cl.time - cl.weapontime);
1197 fade = bound(0.7, fade, 1);
1198 for (i = 0; i < 8;i++)
1199 if (cl.stats[STAT_ITEMS] & (1 << i))
1200 Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1201 if((cl.stats[STAT_ITEMS] & (1<<12)))
1202 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1205 redflag = ((cl.stats[STAT_ITEMS]>>15) & 3);
1206 blueflag = ((cl.stats[STAT_ITEMS]>>17) & 3);
1207 if (redflag == 3 && blueflag == 3)
1209 // The Impossible Combination[tm]
1210 // Can only happen in Key Hunt mode...
1211 Sbar_DrawPic (10 - sbar_x, -179, sb_items[14]);
1216 Sbar_DrawPic (10 - sbar_x, -109, sb_items[redflag+10]);
1218 Sbar_DrawPic (10 - sbar_x, -169, sb_items[blueflag+14]);
1222 if (cl.stats[STAT_ARMOR] > 0)
1224 Sbar_DrawStretchPic (0, 0, sb_armor[0], sbar_alpha_fg.value, 24, 24);
1225 if(cl.stats[STAT_ARMOR] > 100)
1226 Sbar_DrawXNum(24,0,cl.stats[STAT_ARMOR],3,24,1,1,0,1,0);
1227 else if(cl.stats[STAT_ARMOR] > 25)
1228 Sbar_DrawXNum(24,0,cl.stats[STAT_ARMOR],3,24,0.6,0.7,0.8,1,0);
1230 Sbar_DrawXNum(24,0,cl.stats[STAT_ARMOR],3,24,0.7,0,0,1,0);
1234 if (cl.stats[STAT_HEALTH] != 0)
1236 Sbar_DrawStretchPic (112, 0, sb_health, sbar_alpha_fg.value, 24, 24);
1237 if(cl.stats[STAT_HEALTH] > 100)
1238 Sbar_DrawXNum(136,0,cl.stats[STAT_HEALTH],3,24,1,1,0,1,0);
1239 else if(cl.stats[STAT_HEALTH] > 25)
1240 Sbar_DrawXNum(136,0,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1242 Sbar_DrawXNum(136,0,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1246 if ((cl.stats[STAT_ITEMS] & (NEX_IT_SHELLS | NEX_IT_BULLETS | NEX_IT_ROCKETS | NEX_IT_CELLS)) || cl.stats[STAT_AMMO] != 0)
1248 if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1249 Sbar_DrawStretchPic (224, 0, sb_ammo[0], sbar_alpha_fg.value, 24, 24);
1250 else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1251 Sbar_DrawStretchPic (224, 0, sb_ammo[1], sbar_alpha_fg.value, 24, 24);
1252 else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1253 Sbar_DrawStretchPic (224, 0, sb_ammo[2], sbar_alpha_fg.value, 24, 24);
1254 else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1255 Sbar_DrawStretchPic (224, 0, sb_ammo[3], sbar_alpha_fg.value, 24, 24);
1256 if(cl.stats[STAT_AMMO] > 10)
1257 Sbar_DrawXNum(248, 0, cl.stats[STAT_AMMO], 3, 24, 0.6,0.7,0.8,1,0);
1259 Sbar_DrawXNum(248, 0, cl.stats[STAT_AMMO], 3, 24, 0.7,0,0,1,0);
1262 if (sbar_x + 320 + 160 <= vid_conwidth.integer)
1263 Sbar_MiniDeathmatchOverlay (sbar_x + 320, sbar_y);
1269 int redflag, blueflag;
1271 sbar_x = (vid_conwidth.integer - 640)/2;
1272 sbar_y = vid_conheight.integer - 47;
1274 // calculate intensity to draw weapons bar at
1275 fade = 3 - 2 * (cl.time - cl.weapontime);
1278 fade = min(fade, 1);
1279 for (i = 0; i < 8;i++)
1280 if (cl.stats[STAT_ITEMS] & (1 << i))
1281 Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1283 if((cl.stats[STAT_ITEMS] & (1<<12)))
1284 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1287 //if (!cl.islocalgame)
1288 // Sbar_DrawFrags ();
1291 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_fg.value);
1293 Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
1296 redflag = ((cl.stats[STAT_ITEMS]>>15) & 3);
1297 blueflag = ((cl.stats[STAT_ITEMS]>>17) & 3);
1298 if (redflag == 3 && blueflag == 3)
1300 // The Impossible Combination[tm]
1301 // Can only happen in Key Hunt mode...
1302 Sbar_DrawPic (10 - sbar_x, -179, sb_items[14]);
1307 Sbar_DrawPic (10 - sbar_x, -109, sb_items[redflag+10]);
1309 Sbar_DrawPic (10 - sbar_x, -169, sb_items[blueflag+14]);
1313 Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
1316 if(cl.stats[STAT_HEALTH] > 100)
1317 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
1318 else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
1319 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1321 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1323 // AK dont draw ammo for the laser
1324 if(cl.stats[STAT_ACTIVEWEAPON] != 12)
1326 if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1327 Sbar_DrawPic (519, 0, sb_ammo[0]);
1328 else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1329 Sbar_DrawPic (519, 0, sb_ammo[1]);
1330 else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1331 Sbar_DrawPic (519, 0, sb_ammo[2]);
1332 else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1333 Sbar_DrawPic (519, 0, sb_ammo[3]);
1335 if(cl.stats[STAT_AMMO] <= 10)
1336 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
1338 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
1343 DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay,0,0,1,1,1,1,DRAWFLAG_MODULATE);
1345 if (sbar_x + 600 + 160 <= vid_conwidth.integer)
1346 Sbar_MiniDeathmatchOverlay (sbar_x + 600, sbar_y);
1349 else if (gamemode == GAME_ZYMOTIC)
1352 float scale = 64.0f / 256.0f;
1353 float kickoffset[3];
1354 VectorClear(kickoffset);
1357 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1358 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1360 sbar_x = (int)((vid_conwidth.integer - 256 * scale)/2 + kickoffset[0]);
1361 sbar_y = (int)((vid_conheight.integer - 256 * scale)/2 + kickoffset[1]);
1362 // left1 16, 48 : 126 -66
1363 // left2 16, 128 : 196 -66
1364 // right 176, 48 : 196 -136
1365 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);
1366 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);
1367 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);
1368 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1370 float scale = 128.0f / 256.0f;
1371 float healthstart, healthheight, healthstarttc, healthendtc;
1372 float shieldstart, shieldheight, shieldstarttc, shieldendtc;
1373 float ammostart, ammoheight, ammostarttc, ammoendtc;
1374 float clipstart, clipheight, clipstarttc, clipendtc;
1375 float kickoffset[3], offset;
1376 VectorClear(kickoffset);
1379 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1380 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1382 sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1383 sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1384 offset = 0; // TODO: offset should be controlled by recoil (question: how to detect firing?)
1385 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);
1386 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);
1387 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);
1388 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);
1389 healthheight = cl.stats[STAT_HEALTH] * (152.0f / 300.0f);
1390 shieldheight = cl.stats[STAT_ARMOR] * (152.0f / 300.0f);
1391 healthstart = 204 - healthheight;
1392 shieldstart = healthstart - shieldheight;
1393 healthstarttc = healthstart * (1.0f / 256.0f);
1394 healthendtc = (healthstart + healthheight) * (1.0f / 256.0f);
1395 shieldstarttc = shieldstart * (1.0f / 256.0f);
1396 shieldendtc = (shieldstart + shieldheight) * (1.0f / 256.0f);
1397 ammoheight = cl.stats[STAT_SHELLS] * (62.0f / 200.0f);
1398 ammostart = 114 - ammoheight;
1399 ammostarttc = ammostart * (1.0f / 256.0f);
1400 ammoendtc = (ammostart + ammoheight) * (1.0f / 256.0f);
1401 clipheight = cl.stats[STAT_AMMO] * (122.0f / 200.0f);
1402 clipstart = 190 - clipheight;
1403 clipstarttc = clipstart * (1.0f / 256.0f);
1404 clipendtc = (clipstart + clipheight) * (1.0f / 256.0f);
1405 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);
1406 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);
1407 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);
1408 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);
1409 DrawQ_Pic(sbar_x + 0 * scale, sbar_y + 0 * scale, zymsb_crosshair_background, 256 * scale, 256 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1410 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1413 else // Quake and others
1415 sbar_y = vid_conheight.integer - SBAR_HEIGHT;
1416 // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1417 //if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
1418 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1421 sbar_x = (vid_conwidth.integer - 320)/2;
1425 if (gamemode != GAME_GOODVSBAD2)
1426 Sbar_DrawInventory ();
1427 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1431 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1433 if (gamemode != GAME_GOODVSBAD2)
1434 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1435 Sbar_DrawScoreboard ();
1439 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_bg.value);
1441 // keys (hipnotic only)
1442 //MED 01/04/97 moved keys here so they would not be overwritten
1443 if (gamemode == GAME_HIPNOTIC)
1445 if (cl.stats[STAT_ITEMS] & IT_KEY1)
1446 Sbar_DrawPic (209, 3, sb_items[0]);
1447 if (cl.stats[STAT_ITEMS] & IT_KEY2)
1448 Sbar_DrawPic (209, 12, sb_items[1]);
1451 if (gamemode != GAME_GOODVSBAD2)
1453 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1455 Sbar_DrawNum (24, 0, 666, 3, 1);
1456 Sbar_DrawPic (0, 0, sb_disc);
1460 if (gamemode == GAME_ROGUE)
1462 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1463 if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
1464 Sbar_DrawPic (0, 0, sb_armor[2]);
1465 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
1466 Sbar_DrawPic (0, 0, sb_armor[1]);
1467 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
1468 Sbar_DrawPic (0, 0, sb_armor[0]);
1472 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1473 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1474 Sbar_DrawPic (0, 0, sb_armor[2]);
1475 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1476 Sbar_DrawPic (0, 0, sb_armor[1]);
1477 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1478 Sbar_DrawPic (0, 0, sb_armor[0]);
1487 Sbar_DrawNum (136, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1490 if (gamemode == GAME_ROGUE)
1492 if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
1493 Sbar_DrawPic (224, 0, sb_ammo[0]);
1494 else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
1495 Sbar_DrawPic (224, 0, sb_ammo[1]);
1496 else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
1497 Sbar_DrawPic (224, 0, sb_ammo[2]);
1498 else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
1499 Sbar_DrawPic (224, 0, sb_ammo[3]);
1500 else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
1501 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1502 else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
1503 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1504 else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
1505 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1509 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1510 Sbar_DrawPic (224, 0, sb_ammo[0]);
1511 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1512 Sbar_DrawPic (224, 0, sb_ammo[1]);
1513 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1514 Sbar_DrawPic (224, 0, sb_ammo[2]);
1515 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1516 Sbar_DrawPic (224, 0, sb_ammo[3]);
1519 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1523 // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1524 //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1525 if (!cl.islocalgame && vid_conwidth.integer > 320)
1527 if (gamemode == GAME_TRANSFUSION)
1528 Sbar_MiniDeathmatchOverlay (0, 0);
1530 Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
1537 if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && crosshair.integer <= NUMCROSSHAIRS && !cl.intermission && !r_letterbox.value && (pic = r_crosshairs[crosshair.integer]))
1538 DrawQ_Pic((vid_conwidth.integer - pic->width * crosshair_size.value) * 0.5f, (vid_conheight.integer - pic->height * crosshair_size.value) * 0.5f, pic, pic->width * crosshair_size.value, pic->height * crosshair_size.value, crosshair_color_red.value, crosshair_color_green.value, crosshair_color_blue.value, crosshair_color_alpha.value, 0);
1540 if (cl_prydoncursor.integer)
1541 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);
1544 //=============================================================================
1548 Sbar_DeathmatchOverlay
1552 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1556 minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : cl.time - s->qw_entertime) / 60.0);
1557 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1559 if (s->qw_spectator)
1561 if (s->qw_ping || s->qw_packetloss)
1562 DrawQ_String(x, y, va("%4i %3i %4i spectator %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1564 DrawQ_String(x, y, va(" %4i spectator %c%s", minutes, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1568 // draw colors behind score
1569 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1570 DrawQ_Fill(x + 14*8, y+1, 40, 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);
1571 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1572 DrawQ_Fill(x + 14*8, y+4, 40, 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);
1574 //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, NULL, true);
1575 if (s->qw_ping || s->qw_packetloss)
1576 DrawQ_String(x, y, va("%4i %3i %4i %5i %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1578 DrawQ_String(x, y, va(" %4i %5i %-4s %c%s", minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1583 if (s->qw_spectator)
1585 if (s->qw_ping || s->qw_packetloss)
1586 DrawQ_String(x, y, va("%4i %3i spect %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1588 DrawQ_String(x, y, va(" spect %c%s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1592 // draw colors behind score
1593 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1594 DrawQ_Fill(x + 9*8, y+1, 40, 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);
1595 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1596 DrawQ_Fill(x + 9*8, y+4, 40, 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);
1598 //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, NULL, true);
1599 if (s->qw_ping || s->qw_packetloss)
1600 DrawQ_String(x, y, va("%4i %3i %5i %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (int) s->frags, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1602 DrawQ_String(x, y, va(" %5i %c%s", (int) s->frags, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1608 void Sbar_DeathmatchOverlay (void)
1612 // request new ping times every two second
1613 if (cl.last_ping_request < realtime - 2 && cls.netcon)
1615 cl.last_ping_request = realtime;
1616 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1618 MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
1619 MSG_WriteString(&cls.netcon->message, "pings");
1621 else if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6/* || cls.protocol == PROTOCOL_DARKPLACES7*/)
1623 // these servers usually lack the pings command and so a less efficient "ping" command must be sent, which on modern DP servers will also reply with a pingplreport command after the ping listing
1624 static int ping_anyway_counter = 0;
1625 if(cl.parsingtextexpectingpingforscores == 1)
1627 Con_DPrintf("want to send ping, but still waiting for other reply\n");
1628 if(++ping_anyway_counter >= 5)
1629 cl.parsingtextexpectingpingforscores = 0;
1631 if(cl.parsingtextexpectingpingforscores != 1)
1633 ping_anyway_counter = 0;
1634 cl.parsingtextexpectingpingforscores = 1; // hide the output of the next ping report
1635 MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
1636 MSG_WriteString(&cls.netcon->message, "ping");
1641 // newer server definitely has pings command, so use it for more efficiency, avoids ping reports spamming the console if they are misparsed, and saves a little bandwidth
1642 MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
1643 MSG_WriteString(&cls.netcon->message, "pings");
1647 DrawQ_Pic ((vid_conwidth.integer - sb_ranking->width)/2, 8, sb_ranking, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1653 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1655 x = (vid_conwidth.integer - (26 + 15) * 8) / 2; // 26 characters until name, then we assume 15 character names (they can be longer but usually aren't)
1656 DrawQ_String(x, y, va("ping pl%% time frags team name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1660 x = (vid_conwidth.integer - (16 + 15) * 8) / 2; // 16 characters until name, then we assume 15 character names (they can be longer but usually aren't)
1661 DrawQ_String(x, y, va("ping pl%% frags name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1665 if (Sbar_IsTeammatch ())
1667 // show team scores first
1668 for (i = 0;i < teamlines && y < vid_conheight.integer;i++)
1669 y += (int)Sbar_PrintScoreboardItem((teams + teamsort[i]), x, y);
1673 for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
1674 y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1679 Sbar_DeathmatchOverlay
1683 void Sbar_MiniDeathmatchOverlay (int x, int y)
1687 // decide where to print
1688 if (gamemode == GAME_TRANSFUSION)
1689 numlines = (vid_conwidth.integer - x + 127) / 128;
1691 numlines = (vid_conheight.integer - y + 7) / 8;
1693 // give up if there isn't room
1694 if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
1701 for (i = 0; i < scoreboardlines; i++)
1702 if (fragsort[i] == cl.playerentity - 1)
1707 i = min(i, scoreboardlines - numlines);
1710 if (gamemode == GAME_TRANSFUSION)
1712 for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
1713 x += 128 + (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1717 for (;i < scoreboardlines && y < vid_conheight.integer;i++)
1718 y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1724 Sbar_IntermissionOverlay
1728 void Sbar_IntermissionOverlay (void)
1733 // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1734 //if (cl.gametype == GAME_DEATHMATCH)
1735 if (!cl.islocalgame)
1737 Sbar_DeathmatchOverlay ();
1741 sbar_x = (vid_conwidth.integer - 320) >> 1;
1742 sbar_y = (vid_conheight.integer - 200) >> 1;
1744 DrawQ_Pic (sbar_x + 64, sbar_y + 24, sb_complete, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1745 DrawQ_Pic (sbar_x + 0, sbar_y + 56, sb_inter, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1748 dig = (int)cl.completed_time / 60;
1749 Sbar_DrawNum (160, 64, dig, 3, 0);
1750 num = (int)cl.completed_time - dig*60;
1751 if (gamemode != GAME_NEXUIZ)
1752 Sbar_DrawPic (234,64,sb_colon);
1753 Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1754 Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1756 Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1757 if (gamemode != GAME_NEXUIZ)
1758 Sbar_DrawPic (232, 104, sb_slash);
1759 Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1761 Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1762 if (gamemode != GAME_NEXUIZ)
1763 Sbar_DrawPic (232, 144, sb_slash);
1764 Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1775 void Sbar_FinaleOverlay (void)
1777 DrawQ_Pic((vid_conwidth.integer - sb_finale->width)/2, 16, sb_finale, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);