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"};
103 cvar_t showtime = {CVAR_SAVE, "showtime", "0"};
104 cvar_t showtime_format = {CVAR_SAVE, "showtime_format", "%H:%M:%S"};
105 cvar_t showdate = {CVAR_SAVE, "showdate", "0"};
106 cvar_t showdate_format = {CVAR_SAVE, "showdate_format", "%Y-%m-%d"};
107 cvar_t sbar_alpha_bg = {CVAR_SAVE, "sbar_alpha_bg", "0.4"};
108 cvar_t sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1"};
110 cvar_t cl_deathscoreboard = {0, "cl_deathscoreboard", "1"};
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);
351 Cmd_AddCommand ("-showscores", Sbar_DontShowScores);
352 Cvar_RegisterVariable (&showfps);
353 Cvar_RegisterVariable (&showtime);
354 Cvar_RegisterVariable (&showtime_format);
355 Cvar_RegisterVariable (&showdate);
356 Cvar_RegisterVariable (&showdate_format);
357 Cvar_RegisterVariable (&sbar_alpha_bg);
358 Cvar_RegisterVariable (&sbar_alpha_fg);
359 Cvar_RegisterVariable (&cl_deathscoreboard);
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 //=============================================================================
479 static int fragsort[MAX_SCOREBOARD];
480 static int scoreboardlines;
481 void Sbar_SortFrags (void)
487 for (i=0 ; i<cl.maxclients ; i++)
489 if (cl.scores[i].name[0])
491 fragsort[scoreboardlines] = i;
496 for (i=0 ; i<scoreboardlines ; i++)
497 for (j=0 ; j<scoreboardlines-1-i ; j++)
498 if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
501 fragsort[j] = fragsort[j+1];
511 void Sbar_SoloScoreboard (void)
514 int minutes, seconds, tens, units;
517 if (gamemode != GAME_NEXUIZ) {
518 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
519 Sbar_DrawString (8, 4, str);
521 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
522 Sbar_DrawString (8, 12, str);
526 minutes = cl.time / 60;
527 seconds = cl.time - 60*minutes;
529 units = seconds - 10*tens;
530 sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
531 Sbar_DrawString (184, 4, str);
534 if (gamemode == GAME_NEXUIZ) {
535 l = (int) strlen (cl.worldmodel->name);
536 Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
538 l = (int) strlen (cl.levelname);
539 Sbar_DrawString (232 - l*4, 12, cl.levelname);
548 void Sbar_DrawScoreboard (void)
550 Sbar_SoloScoreboard ();
551 if (cl.gametype == GAME_DEATHMATCH)
552 Sbar_DeathmatchOverlay ();
555 //=============================================================================
557 // AK to make DrawInventory smaller
558 static void Sbar_DrawWeapon(int nr, float fade, int active)
560 // width = 300, height = 100
561 const int w_width = 300, w_height = 100, w_space = 10;
562 const float w_scale = 0.4;
564 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);
565 //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);
568 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);
576 void Sbar_DrawInventory (void)
583 if (gamemode == GAME_ROGUE)
585 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
586 Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], sbar_alpha_bg.value);
588 Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], sbar_alpha_bg.value);
591 Sbar_DrawAlphaPic (0, -24, sb_ibar, sbar_alpha_bg.value);
594 for (i=0 ; i<7 ; i++)
596 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
598 time = cl.item_gettime[i];
599 flashon = (int)((cl.time - time)*10);
602 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
608 flashon = (flashon%5) + 2;
610 Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
616 if (gamemode == GAME_HIPNOTIC)
618 int grenadeflashing=0;
619 for (i=0 ; i<4 ; i++)
621 if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
623 time = cl.item_gettime[hipweapons[i]];
624 flashon = (int)((cl.time - time)*10);
627 if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i]) )
633 flashon = (flashon%5) + 2;
635 // check grenade launcher
638 if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
643 Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
649 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
651 if (!grenadeflashing)
652 Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
655 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
658 Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
663 if (gamemode == GAME_ROGUE)
665 // check for powered up weapon.
666 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
668 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
669 Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
673 for (i=0 ; i<4 ; i++)
675 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
677 Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
679 Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
681 Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
685 for (i=0 ; i<6 ; i++)
686 if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
688 //MED 01/04/97 changed keys
689 if (gamemode != GAME_HIPNOTIC || (i>1))
690 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
693 //MED 01/04/97 added hipnotic items
695 if (gamemode == GAME_HIPNOTIC)
697 for (i=0 ; i<2 ; i++)
698 if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
699 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
702 if (gamemode == GAME_ROGUE)
705 for (i=0 ; i<2 ; i++)
706 if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
707 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
712 for (i=0 ; i<4 ; i++)
713 if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
714 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
718 //=============================================================================
725 void Sbar_DrawFrags (void)
735 l = min(scoreboardlines, 4);
739 for (i = 0;i < l;i++)
745 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
746 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);
747 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
748 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);
752 sprintf (num, "%3i",f);
754 if (k == cl.viewentity - 1)
756 Sbar_DrawCharacter ( x + 2, -24, 16);
757 Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
759 Sbar_DrawCharacter (x + 8, -24, num[0]);
760 Sbar_DrawCharacter (x + 16, -24, num[1]);
761 Sbar_DrawCharacter (x + 24, -24, num[2]);
766 //=============================================================================
774 void Sbar_DrawFace (void)
778 // PGM 01/19/97 - team color drawing
779 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
780 if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
786 s = &cl.scores[cl.viewentity - 1];
788 Sbar_DrawPic (112, 0, rsb_teambord);
789 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
790 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);
791 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
792 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);
796 sprintf (num, "%3i",f);
798 if ((s->colors & 0xf0)==0)
801 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
803 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
805 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
809 Sbar_DrawCharacter ( 109, 3, num[0]);
810 Sbar_DrawCharacter ( 116, 3, num[1]);
811 Sbar_DrawCharacter ( 123, 3, num[2]);
816 // PGM 01/19/97 - team color drawing
818 if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
819 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
820 else if (cl.stats[STAT_ITEMS] & IT_QUAD)
821 Sbar_DrawPic (112, 0, sb_face_quad );
822 else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
823 Sbar_DrawPic (112, 0, sb_face_invis );
824 else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
825 Sbar_DrawPic (112, 0, sb_face_invuln);
828 f = cl.stats[STAT_HEALTH] / 20;
830 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
834 void Sbar_ShowFPS(void)
836 float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
840 qboolean red = false;
847 if (showfps.integer > 1)
849 static double currtime, frametimes[32];
850 double newtime, total;
852 static int framecycle = 0;
854 newtime = Sys_DoubleTime();
855 frametimes[framecycle] = newtime - currtime;
858 while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31])
860 total += frametimes[i];
865 if (showfps.integer == 2)
866 calc = (((double)count / total) + 0.5);
867 else // showfps 3, rapid update
868 calc = ((1.0 / (newtime - currtime)) + 0.5);
873 static double nexttime = 0, lasttime = 0;
874 static float framerate = 0;
875 static int framecount = 0;
877 newtime = Sys_DoubleTime();
878 if (newtime >= nexttime)
880 framerate = ((float)framecount / (newtime - lasttime) + 0.5);
882 nexttime = max(nexttime + 1, lasttime - 1);
889 if ((red = (calc < 1.0f)))
890 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
892 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
894 if (showtime.integer)
895 strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
896 if (showdate.integer)
897 strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
898 if (fpsstring[0] || timestring[0])
902 fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
903 //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
904 //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
905 fps_y = vid_conheight.integer - fps_height;
908 fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
909 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
911 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0);
913 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
918 fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
919 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
920 DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
925 fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
926 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
927 DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
933 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)
936 c2 = bound(0, c2, 1);
937 c1 = bound(0, c1, 1 - c2);
939 r[1] = rangey + rangeheight * (c2 + c1);
940 r[2] = rangey + rangeheight * (c2);
944 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);
946 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);
948 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);
950 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);
958 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
959 extern cvar_t v_kicktime;
960 void Sbar_Draw (void)
962 if (cl.intermission == 1)
964 Sbar_IntermissionOverlay();
967 else if (cl.intermission == 2)
969 Sbar_FinaleOverlay();
973 if (gamemode == GAME_NETHERWORLD)
976 else if (gamemode == GAME_SOM)
978 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
979 Sbar_DrawScoreboard ();
982 // this is the top left of the sbar area
984 sbar_y = vid_conheight.integer - 24*3;
987 if (cl.stats[STAT_ARMOR])
989 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
990 Sbar_DrawPic(0, 0, somsb_armor[2]);
991 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
992 Sbar_DrawPic(0, 0, somsb_armor[1]);
993 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
994 Sbar_DrawPic(0, 0, somsb_armor[0]);
995 Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
999 Sbar_DrawPic(0, 24, somsb_health);
1000 Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1003 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1004 Sbar_DrawPic(0, 48, somsb_ammo[0]);
1005 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1006 Sbar_DrawPic(0, 48, somsb_ammo[1]);
1007 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1008 Sbar_DrawPic(0, 48, somsb_ammo[2]);
1009 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1010 Sbar_DrawPic(0, 48, somsb_ammo[3]);
1011 Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
1012 if (cl.stats[STAT_SHELLS])
1013 Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
1016 else if (gamemode == GAME_NEXUIZ)
1018 sbar_y = vid_conheight.integer - 47;
1019 sbar_x = (vid_conwidth.integer - 640)/2;
1021 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1023 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1024 Sbar_DrawScoreboard ();
1032 // we have a max time 2s (min time = 0)
1033 if ((time = cl.time - cl.weapontime) < 2)
1035 fade = (1.0 - 0.5 * time);
1037 for (i = 0; i < 8;i++)
1038 if (cl.stats[STAT_ITEMS] & (1 << i))
1039 Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1041 if((cl.stats[STAT_ITEMS] & (1<<12)))
1042 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1045 //if (!cl.islocalgame)
1046 // Sbar_DrawFrags ();
1049 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_fg.value);
1051 Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
1054 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1056 // Nexuiz has no anum pics
1057 //Sbar_DrawNum (36, 0, 666, 3, 1);
1058 // Nexuiz has no disc pic
1059 //Sbar_DrawPic (0, 0, sb_disc);
1063 Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
1066 if(cl.stats[STAT_HEALTH] > 100)
1067 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
1068 else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
1069 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1071 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1073 // AK dont draw ammo for the laser
1074 if(cl.stats[STAT_ACTIVEWEAPON] != 12)
1076 if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1077 Sbar_DrawPic (519, 0, sb_ammo[0]);
1078 else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1079 Sbar_DrawPic (519, 0, sb_ammo[1]);
1080 else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1081 Sbar_DrawPic (519, 0, sb_ammo[2]);
1082 else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1083 Sbar_DrawPic (519, 0, sb_ammo[3]);
1085 if(cl.stats[STAT_AMMO] <= 10)
1086 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
1088 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
1093 DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay->name,0,0,1,1,1,1,DRAWFLAG_MODULATE);
1096 //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1097 // Sbar_MiniDeathmatchOverlay (0, 17);
1099 else if (gamemode == GAME_ZYMOTIC)
1102 float scale = 64.0f / 256.0f;
1103 float kickoffset[3];
1104 VectorClear(kickoffset);
1107 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1108 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1110 sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1111 sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1112 // left1 16, 48 : 126 -66
1113 // left2 16, 128 : 196 -66
1114 // right 176, 48 : 196 -136
1115 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);
1116 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);
1117 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);
1118 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1120 float scale = 128.0f / 256.0f;
1121 float healthstart, healthheight, healthstarttc, healthendtc;
1122 float shieldstart, shieldheight, shieldstarttc, shieldendtc;
1123 float ammostart, ammoheight, ammostarttc, ammoendtc;
1124 float clipstart, clipheight, clipstarttc, clipendtc;
1125 float kickoffset[3], offset;
1126 VectorClear(kickoffset);
1129 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1130 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1132 sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1133 sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1134 offset = 0; // TODO: offset should be controlled by recoil (question: how to detect firing?)
1135 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);
1136 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);
1137 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);
1138 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);
1139 healthheight = cl.stats[STAT_HEALTH] * (152.0f / 300.0f);
1140 shieldheight = cl.stats[STAT_ARMOR] * (152.0f / 300.0f);
1141 healthstart = 204 - healthheight;
1142 shieldstart = healthstart - shieldheight;
1143 healthstarttc = healthstart * (1.0f / 256.0f);
1144 healthendtc = (healthstart + healthheight) * (1.0f / 256.0f);
1145 shieldstarttc = shieldstart * (1.0f / 256.0f);
1146 shieldendtc = (shieldstart + shieldheight) * (1.0f / 256.0f);
1147 ammoheight = cl.stats[STAT_SHELLS] * (62.0f / 200.0f);
1148 ammostart = 114 - ammoheight;
1149 ammostarttc = ammostart * (1.0f / 256.0f);
1150 ammoendtc = (ammostart + ammoheight) * (1.0f / 256.0f);
1151 clipheight = cl.stats[STAT_AMMO] * (122.0f / 200.0f);
1152 clipstart = 190 - clipheight;
1153 clipstarttc = clipstart * (1.0f / 256.0f);
1154 clipendtc = (clipstart + clipheight) * (1.0f / 256.0f);
1155 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);
1156 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);
1157 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);
1158 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);
1159 DrawQ_Pic(sbar_x + 0 * scale, sbar_y + 0 * scale, zymsb_crosshair_background->name, 256 * scale, 256 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1160 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1163 else // Quake and others
1165 sbar_y = vid_conheight.integer - SBAR_HEIGHT;
1166 if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
1169 sbar_x = (vid_conwidth.integer - 320)/2;
1173 if (gamemode != GAME_GOODVSBAD2)
1174 Sbar_DrawInventory ();
1175 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1179 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1181 if (gamemode != GAME_GOODVSBAD2)
1182 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1183 Sbar_DrawScoreboard ();
1187 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_bg.value);
1189 // keys (hipnotic only)
1190 //MED 01/04/97 moved keys here so they would not be overwritten
1191 if (gamemode == GAME_HIPNOTIC)
1193 if (cl.stats[STAT_ITEMS] & IT_KEY1)
1194 Sbar_DrawPic (209, 3, sb_items[0]);
1195 if (cl.stats[STAT_ITEMS] & IT_KEY2)
1196 Sbar_DrawPic (209, 12, sb_items[1]);
1199 if (gamemode != GAME_GOODVSBAD2)
1201 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1203 Sbar_DrawNum (24, 0, 666, 3, 1);
1204 Sbar_DrawPic (0, 0, sb_disc);
1208 if (gamemode == GAME_ROGUE)
1210 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1211 if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
1212 Sbar_DrawPic (0, 0, sb_armor[2]);
1213 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
1214 Sbar_DrawPic (0, 0, sb_armor[1]);
1215 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
1216 Sbar_DrawPic (0, 0, sb_armor[0]);
1220 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1221 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1222 Sbar_DrawPic (0, 0, sb_armor[2]);
1223 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1224 Sbar_DrawPic (0, 0, sb_armor[1]);
1225 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1226 Sbar_DrawPic (0, 0, sb_armor[0]);
1235 Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1238 if (gamemode == GAME_ROGUE)
1240 if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
1241 Sbar_DrawPic (224, 0, sb_ammo[0]);
1242 else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
1243 Sbar_DrawPic (224, 0, sb_ammo[1]);
1244 else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
1245 Sbar_DrawPic (224, 0, sb_ammo[2]);
1246 else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
1247 Sbar_DrawPic (224, 0, sb_ammo[3]);
1248 else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
1249 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1250 else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
1251 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1252 else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
1253 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1257 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1258 Sbar_DrawPic (224, 0, sb_ammo[0]);
1259 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1260 Sbar_DrawPic (224, 0, sb_ammo[1]);
1261 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1262 Sbar_DrawPic (224, 0, sb_ammo[2]);
1263 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1264 Sbar_DrawPic (224, 0, sb_ammo[3]);
1267 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1271 if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1273 if (gamemode == GAME_TRANSFUSION)
1274 Sbar_MiniDeathmatchOverlay (0, 0);
1276 Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
1282 R_Draw2DCrosshair();
1284 if (cl_prydoncursor.integer)
1285 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);
1288 //=============================================================================
1292 Sbar_DeathmatchOverlay
1296 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1299 // draw colors behind score
1300 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1301 DrawQ_Fill(x + 8, y+1, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
1302 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1303 DrawQ_Fill(x + 8, y+4, 32, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
1305 //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);
1306 // FIXME: use a constant for this color tag instead
1307 DrawQ_ColoredString(x, y, va("%c%4i %s" STRING_COLOR_DEFAULT_STR, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
1311 void Sbar_DeathmatchOverlay (void)
1316 pic = Draw_CachePic ("gfx/ranking", true);
1317 DrawQ_Pic ((vid_conwidth.integer - pic->width)/2, 8, "gfx/ranking", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1322 x = (vid_conwidth.integer - (6 + 15) * 8) / 2;
1324 for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
1325 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1330 Sbar_DeathmatchOverlay
1334 void Sbar_MiniDeathmatchOverlay (int x, int y)
1338 // decide where to print
1339 if (gamemode == GAME_TRANSFUSION)
1340 numlines = (vid_conwidth.integer - x + 127) / 128;
1342 numlines = (vid_conheight.integer - y + 7) / 8;
1344 // give up if there isn't room
1345 if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
1352 for (i = 0; i < scoreboardlines; i++)
1353 if (fragsort[i] == cl.playerentity - 1)
1358 i = min(i, scoreboardlines - numlines);
1361 if (gamemode == GAME_TRANSFUSION)
1363 for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
1364 x += 128 + Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1368 for (;i < scoreboardlines && y < vid_conheight.integer;i++)
1369 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1375 Sbar_IntermissionOverlay
1379 void Sbar_IntermissionOverlay (void)
1384 if (cl.gametype == GAME_DEATHMATCH)
1386 Sbar_DeathmatchOverlay ();
1390 sbar_x = (vid_conwidth.integer - 320) >> 1;
1391 sbar_y = (vid_conheight.integer - 200) >> 1;
1393 DrawQ_Pic (sbar_x + 64, sbar_y + 24, "gfx/complete", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1394 DrawQ_Pic (sbar_x + 0, sbar_y + 56, "gfx/inter", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1397 dig = cl.completed_time/60;
1398 Sbar_DrawNum (160, 64, dig, 3, 0);
1399 num = cl.completed_time - dig*60;
1400 if (gamemode != GAME_NEXUIZ)
1401 Sbar_DrawPic (234,64,sb_colon);
1402 Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1403 Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1405 Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1406 if (gamemode != GAME_NEXUIZ)
1407 Sbar_DrawPic (232, 104, sb_slash);
1408 Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1410 Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1411 if (gamemode != GAME_NEXUIZ)
1412 Sbar_DrawPic (232, 144, sb_slash);
1413 Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1424 void Sbar_FinaleOverlay (void)
1428 pic = Draw_CachePic ("gfx/finale", true);
1429 DrawQ_Pic((vid_conwidth.integer - pic->width)/2, 16, "gfx/finale", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);