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
24 typedef struct sbarpic_s
30 static sbarpic_t sbarpics[256];
31 static int numsbarpics;
33 static sbarpic_t *Sbar_NewPic(const char *name)
35 strcpy(sbarpics[numsbarpics].name, name);
37 // FIXME: precache on every renderer restart (or move this to client)
38 Draw_CachePic(sbarpics[numsbarpics].name, true);
39 return sbarpics + (numsbarpics++);
44 #define STAT_MINUS 10 // num frame for '-' stats digit
45 sbarpic_t *sb_nums[2][11];
46 sbarpic_t *sb_colon, *sb_slash;
49 sbarpic_t *sb_scorebar;
50 // AK only used by NEX
51 sbarpic_t *sb_sbar_minimal;
52 sbarpic_t *sb_sbar_overlay;
54 // AK changed the bound to 9
55 sbarpic_t *sb_weapons[7][9]; // 0 is active, 1 is owned, 2-5 are flashes
56 sbarpic_t *sb_ammo[4];
57 sbarpic_t *sb_sigil[4];
58 sbarpic_t *sb_armor[3];
59 sbarpic_t *sb_items[32];
61 // 0-4 are based on health (in 20 increments)
62 // 0 is static, 1 is temporary animation
63 sbarpic_t *sb_faces[5][2];
65 sbarpic_t *sb_face_invis;
66 sbarpic_t *sb_face_quad;
67 sbarpic_t *sb_face_invuln;
68 sbarpic_t *sb_face_invis_invuln;
70 qboolean sb_showscores;
72 int sb_lines; // scan lines to draw
74 sbarpic_t *rsb_invbar[2];
75 sbarpic_t *rsb_weapons[5];
76 sbarpic_t *rsb_items[2];
77 sbarpic_t *rsb_ammo[3];
78 sbarpic_t *rsb_teambord; // PGM 01/19/97 - team color border
80 //MED 01/04/97 added two more weapons + 3 alternates for grenade launcher
81 sbarpic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes
82 //MED 01/04/97 added array to simplify weapon parsing
83 int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT};
84 //MED 01/04/97 added hipnotic items array
85 sbarpic_t *hsb_items[2];
88 sbarpic_t *somsb_health;
89 sbarpic_t *somsb_ammo[4];
90 sbarpic_t *somsb_armor[3];
92 sbarpic_t *zymsb_crosshair_center;
93 sbarpic_t *zymsb_crosshair_line;
94 sbarpic_t *zymsb_crosshair_health;
95 sbarpic_t *zymsb_crosshair_ammo;
96 sbarpic_t *zymsb_crosshair_clip;
97 sbarpic_t *zymsb_crosshair_background;
98 sbarpic_t *zymsb_crosshair_left1;
99 sbarpic_t *zymsb_crosshair_left2;
100 sbarpic_t *zymsb_crosshair_right;
102 cvar_t showfps = {CVAR_SAVE, "showfps", "0", "shows your rendered fps (frames per second)"};
103 cvar_t showtime = {CVAR_SAVE, "showtime", "0", "shows current time of day (useful on screenshots)"};
104 cvar_t showtime_format = {CVAR_SAVE, "showtime_format", "%H:%M:%S", "format string for time of day"};
105 cvar_t showdate = {CVAR_SAVE, "showdate", "0", "shows current date (useful on screenshots)"};
106 cvar_t showdate_format = {CVAR_SAVE, "showdate_format", "%Y-%m-%d", "format string for date"};
107 cvar_t sbar_alpha_bg = {CVAR_SAVE, "sbar_alpha_bg", "0.4", "opacity value of the statusbar background image"};
108 cvar_t sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1", "opacity value of the statusbar weapon/item icons and numbers"};
110 cvar_t cl_deathscoreboard = {0, "cl_deathscoreboard", "1", "shows scoreboard (+showscores) while dead"};
112 void Sbar_MiniDeathmatchOverlay (int x, int y);
113 void Sbar_DeathmatchOverlay (void);
114 void Sbar_IntermissionOverlay (void);
115 void Sbar_FinaleOverlay (void);
125 void Sbar_ShowScores (void)
129 sb_showscores = true;
139 void Sbar_DontShowScores (void)
141 sb_showscores = false;
144 void sbar_start(void)
150 if (gamemode == GAME_NETHERWORLD)
153 else if (gamemode == GAME_SOM)
155 sb_disc = Sbar_NewPic("gfx/disc");
157 for (i = 0;i < 10;i++)
158 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
160 somsb_health = Sbar_NewPic("gfx/hud_health");
161 somsb_ammo[0] = Sbar_NewPic("gfx/sb_shells");
162 somsb_ammo[1] = Sbar_NewPic("gfx/sb_nails");
163 somsb_ammo[2] = Sbar_NewPic("gfx/sb_rocket");
164 somsb_ammo[3] = Sbar_NewPic("gfx/sb_cells");
165 somsb_armor[0] = Sbar_NewPic("gfx/sb_armor1");
166 somsb_armor[1] = Sbar_NewPic("gfx/sb_armor2");
167 somsb_armor[2] = Sbar_NewPic("gfx/sb_armor3");
169 else if (gamemode == GAME_NEXUIZ)
171 for (i = 0;i < 10;i++)
172 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
173 sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
175 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
176 sb_ammo[1] = Sbar_NewPic ("gfx/sb_bullets");
177 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
178 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
180 sb_items[2] = Sbar_NewPic ("gfx/sb_slowmo");
181 sb_items[3] = Sbar_NewPic ("gfx/sb_invinc");
182 sb_items[4] = Sbar_NewPic ("gfx/sb_energy");
183 sb_items[5] = Sbar_NewPic ("gfx/sb_str");
185 sb_sbar = Sbar_NewPic("gfx/sbar");
186 sb_sbar_minimal = Sbar_NewPic("gfx/sbar_minimal");
187 sb_sbar_overlay = Sbar_NewPic("gfx/sbar_overlay");
189 for(i = 0; i < 9;i++)
190 sb_weapons[0][i] = Sbar_NewPic(va("gfx/inv_weapon%i",i));
192 else if (gamemode == GAME_ZYMOTIC)
194 zymsb_crosshair_center = Sbar_NewPic ("gfx/hud/crosshair_center");
195 zymsb_crosshair_line = Sbar_NewPic ("gfx/hud/crosshair_line");
196 zymsb_crosshair_health = Sbar_NewPic ("gfx/hud/crosshair_health");
197 zymsb_crosshair_clip = Sbar_NewPic ("gfx/hud/crosshair_clip");
198 zymsb_crosshair_ammo = Sbar_NewPic ("gfx/hud/crosshair_ammo");
199 zymsb_crosshair_background = Sbar_NewPic ("gfx/hud/crosshair_background");
200 zymsb_crosshair_left1 = Sbar_NewPic ("gfx/hud/crosshair_left1");
201 zymsb_crosshair_left2 = Sbar_NewPic ("gfx/hud/crosshair_left2");
202 zymsb_crosshair_right = Sbar_NewPic ("gfx/hud/crosshair_right");
206 sb_disc = Sbar_NewPic("gfx/disc");
208 for (i = 0;i < 10;i++)
210 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
211 sb_nums[1][i] = Sbar_NewPic (va("gfx/anum_%i",i));
214 sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
215 sb_nums[1][10] = Sbar_NewPic ("gfx/anum_minus");
217 sb_colon = Sbar_NewPic ("gfx/num_colon");
218 sb_slash = Sbar_NewPic ("gfx/num_slash");
220 sb_weapons[0][0] = Sbar_NewPic ("gfx/inv_shotgun");
221 sb_weapons[0][1] = Sbar_NewPic ("gfx/inv_sshotgun");
222 sb_weapons[0][2] = Sbar_NewPic ("gfx/inv_nailgun");
223 sb_weapons[0][3] = Sbar_NewPic ("gfx/inv_snailgun");
224 sb_weapons[0][4] = Sbar_NewPic ("gfx/inv_rlaunch");
225 sb_weapons[0][5] = Sbar_NewPic ("gfx/inv_srlaunch");
226 sb_weapons[0][6] = Sbar_NewPic ("gfx/inv_lightng");
228 sb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_shotgun");
229 sb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_sshotgun");
230 sb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_nailgun");
231 sb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_snailgun");
232 sb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_rlaunch");
233 sb_weapons[1][5] = Sbar_NewPic ("gfx/inv2_srlaunch");
234 sb_weapons[1][6] = Sbar_NewPic ("gfx/inv2_lightng");
236 for (i = 0;i < 5;i++)
238 sb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_shotgun",i+1));
239 sb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_sshotgun",i+1));
240 sb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_nailgun",i+1));
241 sb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_snailgun",i+1));
242 sb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_rlaunch",i+1));
243 sb_weapons[2+i][5] = Sbar_NewPic (va("gfx/inva%i_srlaunch",i+1));
244 sb_weapons[2+i][6] = Sbar_NewPic (va("gfx/inva%i_lightng",i+1));
247 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
248 sb_ammo[1] = Sbar_NewPic ("gfx/sb_nails");
249 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
250 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
252 sb_armor[0] = Sbar_NewPic ("gfx/sb_armor1");
253 sb_armor[1] = Sbar_NewPic ("gfx/sb_armor2");
254 sb_armor[2] = Sbar_NewPic ("gfx/sb_armor3");
256 sb_items[0] = Sbar_NewPic ("gfx/sb_key1");
257 sb_items[1] = Sbar_NewPic ("gfx/sb_key2");
258 sb_items[2] = Sbar_NewPic ("gfx/sb_invis");
259 sb_items[3] = Sbar_NewPic ("gfx/sb_invuln");
260 sb_items[4] = Sbar_NewPic ("gfx/sb_suit");
261 sb_items[5] = Sbar_NewPic ("gfx/sb_quad");
263 sb_sigil[0] = Sbar_NewPic ("gfx/sb_sigil1");
264 sb_sigil[1] = Sbar_NewPic ("gfx/sb_sigil2");
265 sb_sigil[2] = Sbar_NewPic ("gfx/sb_sigil3");
266 sb_sigil[3] = Sbar_NewPic ("gfx/sb_sigil4");
268 sb_faces[4][0] = Sbar_NewPic ("gfx/face1");
269 sb_faces[4][1] = Sbar_NewPic ("gfx/face_p1");
270 sb_faces[3][0] = Sbar_NewPic ("gfx/face2");
271 sb_faces[3][1] = Sbar_NewPic ("gfx/face_p2");
272 sb_faces[2][0] = Sbar_NewPic ("gfx/face3");
273 sb_faces[2][1] = Sbar_NewPic ("gfx/face_p3");
274 sb_faces[1][0] = Sbar_NewPic ("gfx/face4");
275 sb_faces[1][1] = Sbar_NewPic ("gfx/face_p4");
276 sb_faces[0][0] = Sbar_NewPic ("gfx/face5");
277 sb_faces[0][1] = Sbar_NewPic ("gfx/face_p5");
279 sb_face_invis = Sbar_NewPic ("gfx/face_invis");
280 sb_face_invuln = Sbar_NewPic ("gfx/face_invul2");
281 sb_face_invis_invuln = Sbar_NewPic ("gfx/face_inv2");
282 sb_face_quad = Sbar_NewPic ("gfx/face_quad");
284 sb_sbar = Sbar_NewPic ("gfx/sbar");
285 sb_ibar = Sbar_NewPic ("gfx/ibar");
286 sb_scorebar = Sbar_NewPic ("gfx/scorebar");
288 //MED 01/04/97 added new hipnotic weapons
289 if (gamemode == GAME_HIPNOTIC)
291 hsb_weapons[0][0] = Sbar_NewPic ("gfx/inv_laser");
292 hsb_weapons[0][1] = Sbar_NewPic ("gfx/inv_mjolnir");
293 hsb_weapons[0][2] = Sbar_NewPic ("gfx/inv_gren_prox");
294 hsb_weapons[0][3] = Sbar_NewPic ("gfx/inv_prox_gren");
295 hsb_weapons[0][4] = Sbar_NewPic ("gfx/inv_prox");
297 hsb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_laser");
298 hsb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_mjolnir");
299 hsb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_gren_prox");
300 hsb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_prox_gren");
301 hsb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_prox");
303 for (i = 0;i < 5;i++)
305 hsb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_laser",i+1));
306 hsb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_mjolnir",i+1));
307 hsb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_gren_prox",i+1));
308 hsb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_prox_gren",i+1));
309 hsb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_prox",i+1));
312 hsb_items[0] = Sbar_NewPic ("gfx/sb_wsuit");
313 hsb_items[1] = Sbar_NewPic ("gfx/sb_eshld");
315 else if (gamemode == GAME_ROGUE)
317 rsb_invbar[0] = Sbar_NewPic ("gfx/r_invbar1");
318 rsb_invbar[1] = Sbar_NewPic ("gfx/r_invbar2");
320 rsb_weapons[0] = Sbar_NewPic ("gfx/r_lava");
321 rsb_weapons[1] = Sbar_NewPic ("gfx/r_superlava");
322 rsb_weapons[2] = Sbar_NewPic ("gfx/r_gren");
323 rsb_weapons[3] = Sbar_NewPic ("gfx/r_multirock");
324 rsb_weapons[4] = Sbar_NewPic ("gfx/r_plasma");
326 rsb_items[0] = Sbar_NewPic ("gfx/r_shield1");
327 rsb_items[1] = Sbar_NewPic ("gfx/r_agrav1");
329 // PGM 01/19/97 - team color border
330 rsb_teambord = Sbar_NewPic ("gfx/r_teambord");
331 // PGM 01/19/97 - team color border
333 rsb_ammo[0] = Sbar_NewPic ("gfx/r_ammolava");
334 rsb_ammo[1] = Sbar_NewPic ("gfx/r_ammomulti");
335 rsb_ammo[2] = Sbar_NewPic ("gfx/r_ammoplasma");
340 void sbar_shutdown(void)
344 void sbar_newmap(void)
348 void Sbar_Init (void)
350 Cmd_AddCommand ("+showscores", Sbar_ShowScores, "show scoreboard");
351 Cmd_AddCommand ("-showscores", Sbar_DontShowScores, "hide scoreboard");
352 Cvar_RegisterVariable (&showfps);
353 Cvar_RegisterVariable (&showtime);
354 Cvar_RegisterVariable (&showtime_format);
355 Cvar_RegisterVariable (&showdate);
356 Cvar_RegisterVariable (&showdate_format);
357 Cvar_RegisterVariable (&sbar_alpha_bg);
358 Cvar_RegisterVariable (&sbar_alpha_fg);
359 Cvar_RegisterVariable (&cl_deathscoreboard);
361 R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
365 //=============================================================================
367 // drawing routines are relative to the status bar location
376 void Sbar_DrawPic (int x, int y, sbarpic_t *sbarpic)
378 DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
381 void Sbar_DrawAlphaPic (int x, int y, sbarpic_t *sbarpic, float alpha)
383 DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, alpha, 0);
390 Draws one solid graphics character
393 void Sbar_DrawCharacter (int x, int y, int num)
395 DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
403 void Sbar_DrawString (int x, int y, char *str)
405 DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
413 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
418 l = sprintf(str, "%i", num);
432 Sbar_DrawPic (x, y, sb_nums[color][frame]);
445 void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
450 l = sprintf(str, "%i", num);
455 x += (digits-l) * lettersize;
464 DrawQ_Pic (sbar_x + x, sbar_y + y, sb_nums[0][frame]->name,lettersize,lettersize,r,g,b,a * sbar_alpha_fg.value,flags);
471 //=============================================================================
474 int Sbar_IsTeammatch()
476 // currently only nexuiz uses the team score board
477 return ((gamemode == GAME_NEXUIZ)
478 && (teamplay.integer > 0));
486 static int fragsort[MAX_SCOREBOARD];
487 static int scoreboardlines;
489 //[515]: Sbar_GetPlayer for csqc "getplayerkey" func
490 int Sbar_GetPlayer (int index)
495 if(index >= scoreboardlines)
497 index = fragsort[index];
499 if(index >= scoreboardlines)
504 static scoreboard_t teams[MAX_SCOREBOARD];
505 static int teamsort[MAX_SCOREBOARD];
506 static int teamlines;
507 void Sbar_SortFrags (void)
513 for (i=0 ; i<cl.maxclients ; i++)
515 if (cl.scores[i].name[0])
517 fragsort[scoreboardlines] = i;
522 for (i=0 ; i<scoreboardlines ; i++)
523 for (j=0 ; j<scoreboardlines-1-i ; j++)
524 if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
527 fragsort[j] = fragsort[j+1];
532 if (Sbar_IsTeammatch ())
534 // now sort players by teams.
535 for (i=0 ; i<scoreboardlines ; i++)
537 for (j=0 ; j<scoreboardlines-1-i ; j++)
539 if (cl.scores[fragsort[j]].colors < cl.scores[fragsort[j+1]].colors)
542 fragsort[j] = fragsort[j+1];
548 // calculate team scores
550 for (i=0 ; i<scoreboardlines ; i++)
552 if (color != (cl.scores[fragsort[i]].colors & 15))
554 color = cl.scores[fragsort[i]].colors & 15;
558 strcpy(teams[teamlines-1].name, "^1Red Team");
559 else if (color == 13)
560 strcpy(teams[teamlines-1].name, "^4Blue Team");
562 strcpy(teams[teamlines-1].name, "^6Pink Team");
563 else if (color == 12)
564 strcpy(teams[teamlines-1].name, "^3Yellow Team");
566 strcpy(teams[teamlines-1].name, "Total Team Score");
568 teams[teamlines-1].frags = 0;
569 teams[teamlines-1].colors = color + 16 * color;
572 if (cl.scores[fragsort[i]].frags != -666)
574 // do not add spedcators
575 // (ugly hack for nexuiz)
576 teams[teamlines-1].frags += cl.scores[fragsort[i]].frags;
580 // now sort teams by scores.
581 for (i=0 ; i<teamlines ; i++)
583 for (i=0 ; i<teamlines ; i++)
585 for (j=0 ; j<teamlines-1-i ; j++)
587 if (teams[teamsort[j]].frags < teams[teamsort[j+1]].frags)
590 teamsort[j] = teamsort[j+1];
603 void Sbar_SoloScoreboard (void)
606 int minutes, seconds, tens, units;
609 if (gamemode != GAME_NEXUIZ) {
610 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
611 Sbar_DrawString (8, 4, str);
613 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
614 Sbar_DrawString (8, 12, str);
618 minutes = cl.time / 60;
619 seconds = cl.time - 60*minutes;
621 units = seconds - 10*tens;
622 sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
623 Sbar_DrawString (184, 4, str);
626 if (gamemode == GAME_NEXUIZ) {
627 l = (int) strlen (cl.worldmodel->name);
628 Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
630 l = (int) strlen (cl.levelname);
631 Sbar_DrawString (232 - l*4, 12, cl.levelname);
640 void Sbar_DrawScoreboard (void)
642 Sbar_SoloScoreboard ();
643 if (cl.gametype == GAME_DEATHMATCH)
644 Sbar_DeathmatchOverlay ();
647 //=============================================================================
649 // AK to make DrawInventory smaller
650 static void Sbar_DrawWeapon(int nr, float fade, int active)
652 // width = 300, height = 100
653 const int w_width = 300, w_height = 100, w_space = 10;
654 const float w_scale = 0.4;
656 DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, sb_weapons[0][nr]->name, w_width * w_scale, w_height * w_scale, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 1, fade * sbar_alpha_fg.value, DRAWFLAG_ADDITIVE);
657 //DrawQ_String(vid_conwidth.integer - (w_space + font_size ), (w_height + w_space) * w_scale * nr + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 0, 0, fade, 0);
660 DrawQ_Fill(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, w_width * w_scale, w_height * w_scale, 0.3, 0.3, 0.3, fade * sbar_alpha_fg.value, DRAWFLAG_ADDITIVE);
668 void Sbar_DrawInventory (void)
675 if (gamemode == GAME_ROGUE)
677 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
678 Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], sbar_alpha_bg.value);
680 Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], sbar_alpha_bg.value);
683 Sbar_DrawAlphaPic (0, -24, sb_ibar, sbar_alpha_bg.value);
686 for (i=0 ; i<7 ; i++)
688 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
690 time = cl.item_gettime[i];
691 flashon = (int)((cl.time - time)*10);
694 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
700 flashon = (flashon%5) + 2;
702 Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
708 if (gamemode == GAME_HIPNOTIC)
710 int grenadeflashing=0;
711 for (i=0 ; i<4 ; i++)
713 if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
715 time = cl.item_gettime[hipweapons[i]];
716 flashon = (int)((cl.time - time)*10);
719 if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i]) )
725 flashon = (flashon%5) + 2;
727 // check grenade launcher
730 if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
735 Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
741 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
743 if (!grenadeflashing)
744 Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
747 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
750 Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
755 if (gamemode == GAME_ROGUE)
757 // check for powered up weapon.
758 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
760 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
761 Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
765 for (i=0 ; i<4 ; i++)
767 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
769 Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
771 Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
773 Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
777 for (i=0 ; i<6 ; i++)
778 if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
780 //MED 01/04/97 changed keys
781 if (gamemode != GAME_HIPNOTIC || (i>1))
782 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
785 //MED 01/04/97 added hipnotic items
787 if (gamemode == GAME_HIPNOTIC)
789 for (i=0 ; i<2 ; i++)
790 if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
791 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
794 if (gamemode == GAME_ROGUE)
797 for (i=0 ; i<2 ; i++)
798 if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
799 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
804 for (i=0 ; i<4 ; i++)
805 if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
806 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
810 //=============================================================================
817 void Sbar_DrawFrags (void)
827 l = min(scoreboardlines, 4);
831 for (i = 0;i < l;i++)
837 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
838 DrawQ_Fill (sbar_x + x + 10, sbar_y - 23, 28, 4, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
839 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
840 DrawQ_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 28, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
844 sprintf (num, "%3i",f);
846 if (k == cl.viewentity - 1)
848 Sbar_DrawCharacter ( x + 2, -24, 16);
849 Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
851 Sbar_DrawCharacter (x + 8, -24, num[0]);
852 Sbar_DrawCharacter (x + 16, -24, num[1]);
853 Sbar_DrawCharacter (x + 24, -24, num[2]);
858 //=============================================================================
866 void Sbar_DrawFace (void)
870 // PGM 01/19/97 - team color drawing
871 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
872 if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
878 s = &cl.scores[cl.viewentity - 1];
880 Sbar_DrawPic (112, 0, rsb_teambord);
881 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
882 DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+3, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
883 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
884 DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+12, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
888 sprintf (num, "%3i",f);
890 if ((s->colors & 0xf0)==0)
893 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
895 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
897 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
901 Sbar_DrawCharacter ( 109, 3, num[0]);
902 Sbar_DrawCharacter ( 116, 3, num[1]);
903 Sbar_DrawCharacter ( 123, 3, num[2]);
908 // PGM 01/19/97 - team color drawing
910 if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
911 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
912 else if (cl.stats[STAT_ITEMS] & IT_QUAD)
913 Sbar_DrawPic (112, 0, sb_face_quad );
914 else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
915 Sbar_DrawPic (112, 0, sb_face_invis );
916 else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
917 Sbar_DrawPic (112, 0, sb_face_invuln);
920 f = cl.stats[STAT_HEALTH] / 20;
922 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
926 void Sbar_ShowFPS(void)
928 float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
932 qboolean red = false;
939 if (showfps.integer > 1)
941 static double currtime, frametimes[32];
942 double newtime, total;
944 static int framecycle = 0;
946 newtime = Sys_DoubleTime();
947 frametimes[framecycle] = newtime - currtime;
950 while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31])
952 total += frametimes[i];
957 if (showfps.integer == 2)
958 calc = (((double)count / total) + 0.5);
959 else // showfps 3, rapid update
960 calc = ((1.0 / (newtime - currtime)) + 0.5);
965 static double nexttime = 0, lasttime = 0;
966 static float framerate = 0;
967 static int framecount = 0;
969 newtime = Sys_DoubleTime();
970 if (newtime >= nexttime)
972 framerate = ((float)framecount / (newtime - lasttime) + 0.5);
974 nexttime = max(nexttime + 1, lasttime - 1);
981 if ((red = (calc < 1.0f)))
982 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
984 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
986 if (showtime.integer)
987 strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
988 if (showdate.integer)
989 strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
990 if (fpsstring[0] || timestring[0])
994 fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
995 //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
996 //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
997 fps_y = vid_conheight.integer - fps_height;
1000 fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
1001 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
1003 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0);
1005 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
1006 fps_y += fps_scaley;
1010 fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
1011 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
1012 DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
1013 fps_y += fps_scaley;
1017 fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
1018 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
1019 DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
1020 fps_y += fps_scaley;
1025 void Sbar_DrawGauge(float x, float y, const char *picname, float width, float height, float rangey, float rangeheight, float c1, float c2, float c1r, float c1g, float c1b, float c1a, float c2r, float c2g, float c2b, float c2a, float c3r, float c3g, float c3b, float c3a, int drawflags)
1028 c2 = bound(0, c2, 1);
1029 c1 = bound(0, c1, 1 - c2);
1031 r[1] = rangey + rangeheight * (c2 + c1);
1032 r[2] = rangey + rangeheight * (c2);
1036 DrawQ_SuperPic(x, y + r[0], picname, width, (r[1] - r[0]), 0,(r[0] / height), c3r,c3g,c3b,c3a, 1,(r[0] / height), c3r,c3g,c3b,c3a, 0,(r[1] / height), c3r,c3g,c3b,c3a, 1,(r[1] / height), c3r,c3g,c3b,c3a, drawflags);
1038 DrawQ_SuperPic(x, y + r[1], picname, width, (r[2] - r[1]), 0,(r[1] / height), c1r,c1g,c1b,c1a, 1,(r[1] / height), c1r,c1g,c1b,c1a, 0,(r[2] / height), c1r,c1g,c1b,c1a, 1,(r[2] / height), c1r,c1g,c1b,c1a, drawflags);
1040 DrawQ_SuperPic(x, y + r[2], picname, width, (r[3] - r[2]), 0,(r[2] / height), c2r,c2g,c2b,c2a, 1,(r[2] / height), c2r,c2g,c2b,c2a, 0,(r[3] / height), c2r,c2g,c2b,c2a, 1,(r[3] / height), c2r,c2g,c2b,c2a, drawflags);
1042 DrawQ_SuperPic(x, y + r[3], picname, width, (r[4] - r[3]), 0,(r[3] / height), c3r,c3g,c3b,c3a, 1,(r[3] / height), c3r,c3g,c3b,c3a, 0,(r[4] / height), c3r,c3g,c3b,c3a, 1,(r[4] / height), c3r,c3g,c3b,c3a, drawflags);
1050 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
1051 extern cvar_t v_kicktime;
1052 void Sbar_Draw (void)
1054 if(cl.csqc_vidvars.drawenginesbar) //[515]: csqc drawsbar
1056 if (cl.intermission == 1)
1058 Sbar_IntermissionOverlay();
1061 else if (cl.intermission == 2)
1063 Sbar_FinaleOverlay();
1067 if (gamemode == GAME_NETHERWORLD)
1070 else if (gamemode == GAME_SOM)
1072 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1073 Sbar_DrawScoreboard ();
1076 // this is the top left of the sbar area
1078 sbar_y = vid_conheight.integer - 24*3;
1081 if (cl.stats[STAT_ARMOR])
1083 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1084 Sbar_DrawPic(0, 0, somsb_armor[2]);
1085 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1086 Sbar_DrawPic(0, 0, somsb_armor[1]);
1087 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1088 Sbar_DrawPic(0, 0, somsb_armor[0]);
1089 Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1093 Sbar_DrawPic(0, 24, somsb_health);
1094 Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1097 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1098 Sbar_DrawPic(0, 48, somsb_ammo[0]);
1099 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1100 Sbar_DrawPic(0, 48, somsb_ammo[1]);
1101 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1102 Sbar_DrawPic(0, 48, somsb_ammo[2]);
1103 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1104 Sbar_DrawPic(0, 48, somsb_ammo[3]);
1105 Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
1106 if (cl.stats[STAT_SHELLS])
1107 Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
1110 else if (gamemode == GAME_NEXUIZ)
1112 sbar_y = vid_conheight.integer - 47;
1113 sbar_x = (vid_conwidth.integer - 640)/2;
1115 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1117 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1118 Sbar_DrawScoreboard ();
1126 // we have a max time 2s (min time = 0)
1127 if ((time = cl.time - cl.weapontime) < 2)
1129 fade = (1.0 - 0.5 * time);
1131 for (i = 0; i < 8;i++)
1132 if (cl.stats[STAT_ITEMS] & (1 << i))
1133 Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1135 if((cl.stats[STAT_ITEMS] & (1<<12)))
1136 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1139 //if (!cl.islocalgame)
1140 // Sbar_DrawFrags ();
1143 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_fg.value);
1145 Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
1148 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1150 // Nexuiz has no anum pics
1151 //Sbar_DrawNum (36, 0, 666, 3, 1);
1152 // Nexuiz has no disc pic
1153 //Sbar_DrawPic (0, 0, sb_disc);
1157 Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
1160 if(cl.stats[STAT_HEALTH] > 100)
1161 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
1162 else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
1163 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1165 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1167 // AK dont draw ammo for the laser
1168 if(cl.stats[STAT_ACTIVEWEAPON] != 12)
1170 if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1171 Sbar_DrawPic (519, 0, sb_ammo[0]);
1172 else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1173 Sbar_DrawPic (519, 0, sb_ammo[1]);
1174 else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1175 Sbar_DrawPic (519, 0, sb_ammo[2]);
1176 else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1177 Sbar_DrawPic (519, 0, sb_ammo[3]);
1179 if(cl.stats[STAT_AMMO] <= 10)
1180 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
1182 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
1187 DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay->name,0,0,1,1,1,1,DRAWFLAG_MODULATE);
1190 //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1191 // Sbar_MiniDeathmatchOverlay (0, 17);
1193 else if (gamemode == GAME_ZYMOTIC)
1196 float scale = 64.0f / 256.0f;
1197 float kickoffset[3];
1198 VectorClear(kickoffset);
1201 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1202 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1204 sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1205 sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1206 // left1 16, 48 : 126 -66
1207 // left2 16, 128 : 196 -66
1208 // right 176, 48 : 196 -136
1209 Sbar_DrawGauge(sbar_x + 16 * scale, sbar_y + 48 * scale, zymsb_crosshair_left1->name, 64*scale, 80*scale, 78*scale, -66*scale, cl.stats[STAT_AMMO] * (1.0 / 200.0), cl.stats[STAT_SHELLS] * (1.0 / 200.0), 0.8f,0.8f,0.0f,1.0f, 0.8f,0.5f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1210 Sbar_DrawGauge(sbar_x + 16 * scale, sbar_y + 128 * scale, zymsb_crosshair_left2->name, 64*scale, 80*scale, 68*scale, -66*scale, cl.stats[STAT_NAILS] * (1.0 / 200.0), cl.stats[STAT_ROCKETS] * (1.0 / 200.0), 0.8f,0.8f,0.0f,1.0f, 0.8f,0.5f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1211 Sbar_DrawGauge(sbar_x + 176 * scale, sbar_y + 48 * scale, zymsb_crosshair_right->name, 64*scale, 160*scale, 148*scale, -136*scale, cl.stats[STAT_ARMOR] * (1.0 / 300.0), cl.stats[STAT_HEALTH] * (1.0 / 300.0), 0.0f,0.5f,1.0f,1.0f, 1.0f,0.0f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1212 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1214 float scale = 128.0f / 256.0f;
1215 float healthstart, healthheight, healthstarttc, healthendtc;
1216 float shieldstart, shieldheight, shieldstarttc, shieldendtc;
1217 float ammostart, ammoheight, ammostarttc, ammoendtc;
1218 float clipstart, clipheight, clipstarttc, clipendtc;
1219 float kickoffset[3], offset;
1220 VectorClear(kickoffset);
1223 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1224 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1226 sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1227 sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1228 offset = 0; // TODO: offset should be controlled by recoil (question: how to detect firing?)
1229 DrawQ_SuperPic(sbar_x + 120 * scale, sbar_y + ( 88 - offset) * scale, zymsb_crosshair_line->name, 16 * scale, 36 * scale, 0,0, 1,1,1,1, 1,0, 1,1,1,1, 0,1, 1,1,1,1, 1,1, 1,1,1,1, 0);
1230 DrawQ_SuperPic(sbar_x + (132 + offset) * scale, sbar_y + 120 * scale, zymsb_crosshair_line->name, 36 * scale, 16 * scale, 0,1, 1,1,1,1, 0,0, 1,1,1,1, 1,1, 1,1,1,1, 1,0, 1,1,1,1, 0);
1231 DrawQ_SuperPic(sbar_x + 120 * scale, sbar_y + (132 + offset) * scale, zymsb_crosshair_line->name, 16 * scale, 36 * scale, 1,1, 1,1,1,1, 0,1, 1,1,1,1, 1,0, 1,1,1,1, 0,0, 1,1,1,1, 0);
1232 DrawQ_SuperPic(sbar_x + ( 88 - offset) * scale, sbar_y + 120 * scale, zymsb_crosshair_line->name, 36 * scale, 16 * scale, 1,0, 1,1,1,1, 1,1, 1,1,1,1, 0,0, 1,1,1,1, 0,1, 1,1,1,1, 0);
1233 healthheight = cl.stats[STAT_HEALTH] * (152.0f / 300.0f);
1234 shieldheight = cl.stats[STAT_ARMOR] * (152.0f / 300.0f);
1235 healthstart = 204 - healthheight;
1236 shieldstart = healthstart - shieldheight;
1237 healthstarttc = healthstart * (1.0f / 256.0f);
1238 healthendtc = (healthstart + healthheight) * (1.0f / 256.0f);
1239 shieldstarttc = shieldstart * (1.0f / 256.0f);
1240 shieldendtc = (shieldstart + shieldheight) * (1.0f / 256.0f);
1241 ammoheight = cl.stats[STAT_SHELLS] * (62.0f / 200.0f);
1242 ammostart = 114 - ammoheight;
1243 ammostarttc = ammostart * (1.0f / 256.0f);
1244 ammoendtc = (ammostart + ammoheight) * (1.0f / 256.0f);
1245 clipheight = cl.stats[STAT_AMMO] * (122.0f / 200.0f);
1246 clipstart = 190 - clipheight;
1247 clipstarttc = clipstart * (1.0f / 256.0f);
1248 clipendtc = (clipstart + clipheight) * (1.0f / 256.0f);
1249 if (healthheight > 0) DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + healthstart * scale, zymsb_crosshair_health->name, 256 * scale, healthheight * scale, 0,healthstarttc, 1.0f,0.0f,0.0f,1.0f, 1,healthstarttc, 1.0f,0.0f,0.0f,1.0f, 0,healthendtc, 1.0f,0.0f,0.0f,1.0f, 1,healthendtc, 1.0f,0.0f,0.0f,1.0f, DRAWFLAG_NORMAL);
1250 if (shieldheight > 0) DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + shieldstart * scale, zymsb_crosshair_health->name, 256 * scale, shieldheight * scale, 0,shieldstarttc, 0.0f,0.5f,1.0f,1.0f, 1,shieldstarttc, 0.0f,0.5f,1.0f,1.0f, 0,shieldendtc, 0.0f,0.5f,1.0f,1.0f, 1,shieldendtc, 0.0f,0.5f,1.0f,1.0f, DRAWFLAG_NORMAL);
1251 if (ammoheight > 0) DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + ammostart * scale, zymsb_crosshair_ammo->name, 256 * scale, ammoheight * scale, 0,ammostarttc, 0.8f,0.8f,0.0f,1.0f, 1,ammostarttc, 0.8f,0.8f,0.0f,1.0f, 0,ammoendtc, 0.8f,0.8f,0.0f,1.0f, 1,ammoendtc, 0.8f,0.8f,0.0f,1.0f, DRAWFLAG_NORMAL);
1252 if (clipheight > 0) DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + clipstart * scale, zymsb_crosshair_clip->name, 256 * scale, clipheight * scale, 0,clipstarttc, 1.0f,1.0f,0.0f,1.0f, 1,clipstarttc, 1.0f,1.0f,0.0f,1.0f, 0,clipendtc, 1.0f,1.0f,0.0f,1.0f, 1,clipendtc, 1.0f,1.0f,0.0f,1.0f, DRAWFLAG_NORMAL);
1253 DrawQ_Pic(sbar_x + 0 * scale, sbar_y + 0 * scale, zymsb_crosshair_background->name, 256 * scale, 256 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1254 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1257 else // Quake and others
1259 sbar_y = vid_conheight.integer - SBAR_HEIGHT;
1260 if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
1263 sbar_x = (vid_conwidth.integer - 320)/2;
1267 if (gamemode != GAME_GOODVSBAD2)
1268 Sbar_DrawInventory ();
1269 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1273 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1275 if (gamemode != GAME_GOODVSBAD2)
1276 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1277 Sbar_DrawScoreboard ();
1281 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_bg.value);
1283 // keys (hipnotic only)
1284 //MED 01/04/97 moved keys here so they would not be overwritten
1285 if (gamemode == GAME_HIPNOTIC)
1287 if (cl.stats[STAT_ITEMS] & IT_KEY1)
1288 Sbar_DrawPic (209, 3, sb_items[0]);
1289 if (cl.stats[STAT_ITEMS] & IT_KEY2)
1290 Sbar_DrawPic (209, 12, sb_items[1]);
1293 if (gamemode != GAME_GOODVSBAD2)
1295 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1297 Sbar_DrawNum (24, 0, 666, 3, 1);
1298 Sbar_DrawPic (0, 0, sb_disc);
1302 if (gamemode == GAME_ROGUE)
1304 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1305 if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
1306 Sbar_DrawPic (0, 0, sb_armor[2]);
1307 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
1308 Sbar_DrawPic (0, 0, sb_armor[1]);
1309 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
1310 Sbar_DrawPic (0, 0, sb_armor[0]);
1314 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1315 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1316 Sbar_DrawPic (0, 0, sb_armor[2]);
1317 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1318 Sbar_DrawPic (0, 0, sb_armor[1]);
1319 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1320 Sbar_DrawPic (0, 0, sb_armor[0]);
1329 Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1332 if (gamemode == GAME_ROGUE)
1334 if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
1335 Sbar_DrawPic (224, 0, sb_ammo[0]);
1336 else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
1337 Sbar_DrawPic (224, 0, sb_ammo[1]);
1338 else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
1339 Sbar_DrawPic (224, 0, sb_ammo[2]);
1340 else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
1341 Sbar_DrawPic (224, 0, sb_ammo[3]);
1342 else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
1343 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1344 else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
1345 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1346 else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
1347 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1351 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1352 Sbar_DrawPic (224, 0, sb_ammo[0]);
1353 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1354 Sbar_DrawPic (224, 0, sb_ammo[1]);
1355 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1356 Sbar_DrawPic (224, 0, sb_ammo[2]);
1357 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1358 Sbar_DrawPic (224, 0, sb_ammo[3]);
1361 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1365 if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1367 if (gamemode == GAME_TRANSFUSION)
1368 Sbar_MiniDeathmatchOverlay (0, 0);
1370 Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
1377 if(cl.csqc_vidvars.drawcrosshair)
1378 R_Draw2DCrosshair();
1380 if (cl_prydoncursor.integer)
1381 DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid_conwidth.integer, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid_conheight.integer, va("gfx/prydoncursor%03i", cl_prydoncursor.integer), 0, 0, 1, 1, 1, 1, 0);
1384 //=============================================================================
1388 Sbar_DeathmatchOverlay
1392 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1396 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1398 // draw colors behind score
1399 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1400 DrawQ_Fill(x + 14*8, y+1, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
1401 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1402 DrawQ_Fill(x + 14*8, y+4, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
1404 //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);
1405 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 );
1409 minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : realtime - s->qw_entertime) / 60.0);
1410 // draw colors behind score
1411 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1412 DrawQ_Fill(x + 1*8, y+1, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
1413 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1414 DrawQ_Fill(x + 1*8, y+4, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
1416 //DrawQ_String(x, y, va("%c%4i %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1417 DrawQ_ColoredString(x, y, va("%c%4i %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
1422 void Sbar_DeathmatchOverlay (void)
1427 // request new ping times every two second
1428 if (cl.last_ping_request < realtime - 2)
1430 cl.last_ping_request = realtime;
1431 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1433 MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
1434 MSG_WriteString(&cls.netcon->message, "pings");
1438 pic = Draw_CachePic ("gfx/ranking", true);
1439 DrawQ_Pic ((vid_conwidth.integer - pic->width)/2, 8, "gfx/ranking", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1444 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1445 x = (vid_conwidth.integer - (6 + 17 + 15) * 8) / 2;
1447 x = (vid_conwidth.integer - (6 + 15) * 8) / 2;
1450 if (Sbar_IsTeammatch ())
1452 // show team scores first
1453 for (i = 0;i < teamlines && y < vid_conheight.integer;i++)
1454 y += Sbar_PrintScoreboardItem((teams + teamsort[i]), x, y);
1458 for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
1459 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1464 Sbar_DeathmatchOverlay
1468 void Sbar_MiniDeathmatchOverlay (int x, int y)
1472 // decide where to print
1473 if (gamemode == GAME_TRANSFUSION)
1474 numlines = (vid_conwidth.integer - x + 127) / 128;
1476 numlines = (vid_conheight.integer - y + 7) / 8;
1478 // give up if there isn't room
1479 if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
1486 for (i = 0; i < scoreboardlines; i++)
1487 if (fragsort[i] == cl.playerentity - 1)
1492 i = min(i, scoreboardlines - numlines);
1495 if (gamemode == GAME_TRANSFUSION)
1497 for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
1498 x += 128 + Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1502 for (;i < scoreboardlines && y < vid_conheight.integer;i++)
1503 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1509 Sbar_IntermissionOverlay
1513 void Sbar_IntermissionOverlay (void)
1518 if (cl.gametype == GAME_DEATHMATCH)
1520 Sbar_DeathmatchOverlay ();
1524 sbar_x = (vid_conwidth.integer - 320) >> 1;
1525 sbar_y = (vid_conheight.integer - 200) >> 1;
1527 DrawQ_Pic (sbar_x + 64, sbar_y + 24, "gfx/complete", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1528 DrawQ_Pic (sbar_x + 0, sbar_y + 56, "gfx/inter", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1531 dig = cl.completed_time/60;
1532 Sbar_DrawNum (160, 64, dig, 3, 0);
1533 num = cl.completed_time - dig*60;
1534 if (gamemode != GAME_NEXUIZ)
1535 Sbar_DrawPic (234,64,sb_colon);
1536 Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1537 Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1539 Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1540 if (gamemode != GAME_NEXUIZ)
1541 Sbar_DrawPic (232, 104, sb_slash);
1542 Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1544 Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1545 if (gamemode != GAME_NEXUIZ)
1546 Sbar_DrawPic (232, 144, sb_slash);
1547 Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1558 void Sbar_FinaleOverlay (void)
1562 pic = Draw_CachePic ("gfx/finale", true);
1563 DrawQ_Pic((vid_conwidth.integer - pic->width)/2, 16, "gfx/finale", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);