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_SOM)
152 sb_disc = Sbar_NewPic("gfx/disc");
154 for (i = 0;i < 10;i++)
155 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
157 somsb_health = Sbar_NewPic("gfx/hud_health");
158 somsb_ammo[0] = Sbar_NewPic("gfx/sb_shells");
159 somsb_ammo[1] = Sbar_NewPic("gfx/sb_nails");
160 somsb_ammo[2] = Sbar_NewPic("gfx/sb_rocket");
161 somsb_ammo[3] = Sbar_NewPic("gfx/sb_cells");
162 somsb_armor[0] = Sbar_NewPic("gfx/sb_armor1");
163 somsb_armor[1] = Sbar_NewPic("gfx/sb_armor2");
164 somsb_armor[2] = Sbar_NewPic("gfx/sb_armor3");
166 else if (gamemode == GAME_NEXUIZ)
168 for (i = 0;i < 10;i++)
169 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
170 sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
172 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
173 sb_ammo[1] = Sbar_NewPic ("gfx/sb_bullets");
174 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
175 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
177 sb_items[2] = Sbar_NewPic ("gfx/sb_slowmo");
178 sb_items[3] = Sbar_NewPic ("gfx/sb_invinc");
179 sb_items[4] = Sbar_NewPic ("gfx/sb_energy");
180 sb_items[5] = Sbar_NewPic ("gfx/sb_str");
182 sb_sbar = Sbar_NewPic("gfx/sbar");
183 sb_sbar_minimal = Sbar_NewPic("gfx/sbar_minimal");
184 sb_sbar_overlay = Sbar_NewPic("gfx/sbar_overlay");
186 for(i = 0; i < 9;i++)
187 sb_weapons[0][i] = Sbar_NewPic(va("gfx/inv_weapon%i",i));
189 else if (gamemode == GAME_ZYMOTIC)
191 zymsb_crosshair_center = Sbar_NewPic ("gfx/hud/crosshair_center");
192 zymsb_crosshair_line = Sbar_NewPic ("gfx/hud/crosshair_line");
193 zymsb_crosshair_health = Sbar_NewPic ("gfx/hud/crosshair_health");
194 zymsb_crosshair_clip = Sbar_NewPic ("gfx/hud/crosshair_clip");
195 zymsb_crosshair_ammo = Sbar_NewPic ("gfx/hud/crosshair_ammo");
196 zymsb_crosshair_background = Sbar_NewPic ("gfx/hud/crosshair_background");
197 zymsb_crosshair_left1 = Sbar_NewPic ("gfx/hud/crosshair_left1");
198 zymsb_crosshair_left2 = Sbar_NewPic ("gfx/hud/crosshair_left2");
199 zymsb_crosshair_right = Sbar_NewPic ("gfx/hud/crosshair_right");
203 sb_disc = Sbar_NewPic("gfx/disc");
205 for (i = 0;i < 10;i++)
207 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
208 sb_nums[1][i] = Sbar_NewPic (va("gfx/anum_%i",i));
211 sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
212 sb_nums[1][10] = Sbar_NewPic ("gfx/anum_minus");
214 sb_colon = Sbar_NewPic ("gfx/num_colon");
215 sb_slash = Sbar_NewPic ("gfx/num_slash");
217 sb_weapons[0][0] = Sbar_NewPic ("gfx/inv_shotgun");
218 sb_weapons[0][1] = Sbar_NewPic ("gfx/inv_sshotgun");
219 sb_weapons[0][2] = Sbar_NewPic ("gfx/inv_nailgun");
220 sb_weapons[0][3] = Sbar_NewPic ("gfx/inv_snailgun");
221 sb_weapons[0][4] = Sbar_NewPic ("gfx/inv_rlaunch");
222 sb_weapons[0][5] = Sbar_NewPic ("gfx/inv_srlaunch");
223 sb_weapons[0][6] = Sbar_NewPic ("gfx/inv_lightng");
225 sb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_shotgun");
226 sb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_sshotgun");
227 sb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_nailgun");
228 sb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_snailgun");
229 sb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_rlaunch");
230 sb_weapons[1][5] = Sbar_NewPic ("gfx/inv2_srlaunch");
231 sb_weapons[1][6] = Sbar_NewPic ("gfx/inv2_lightng");
233 for (i = 0;i < 5;i++)
235 sb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_shotgun",i+1));
236 sb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_sshotgun",i+1));
237 sb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_nailgun",i+1));
238 sb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_snailgun",i+1));
239 sb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_rlaunch",i+1));
240 sb_weapons[2+i][5] = Sbar_NewPic (va("gfx/inva%i_srlaunch",i+1));
241 sb_weapons[2+i][6] = Sbar_NewPic (va("gfx/inva%i_lightng",i+1));
244 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
245 sb_ammo[1] = Sbar_NewPic ("gfx/sb_nails");
246 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
247 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
249 sb_armor[0] = Sbar_NewPic ("gfx/sb_armor1");
250 sb_armor[1] = Sbar_NewPic ("gfx/sb_armor2");
251 sb_armor[2] = Sbar_NewPic ("gfx/sb_armor3");
253 sb_items[0] = Sbar_NewPic ("gfx/sb_key1");
254 sb_items[1] = Sbar_NewPic ("gfx/sb_key2");
255 sb_items[2] = Sbar_NewPic ("gfx/sb_invis");
256 sb_items[3] = Sbar_NewPic ("gfx/sb_invuln");
257 sb_items[4] = Sbar_NewPic ("gfx/sb_suit");
258 sb_items[5] = Sbar_NewPic ("gfx/sb_quad");
260 sb_sigil[0] = Sbar_NewPic ("gfx/sb_sigil1");
261 sb_sigil[1] = Sbar_NewPic ("gfx/sb_sigil2");
262 sb_sigil[2] = Sbar_NewPic ("gfx/sb_sigil3");
263 sb_sigil[3] = Sbar_NewPic ("gfx/sb_sigil4");
265 sb_faces[4][0] = Sbar_NewPic ("gfx/face1");
266 sb_faces[4][1] = Sbar_NewPic ("gfx/face_p1");
267 sb_faces[3][0] = Sbar_NewPic ("gfx/face2");
268 sb_faces[3][1] = Sbar_NewPic ("gfx/face_p2");
269 sb_faces[2][0] = Sbar_NewPic ("gfx/face3");
270 sb_faces[2][1] = Sbar_NewPic ("gfx/face_p3");
271 sb_faces[1][0] = Sbar_NewPic ("gfx/face4");
272 sb_faces[1][1] = Sbar_NewPic ("gfx/face_p4");
273 sb_faces[0][0] = Sbar_NewPic ("gfx/face5");
274 sb_faces[0][1] = Sbar_NewPic ("gfx/face_p5");
276 sb_face_invis = Sbar_NewPic ("gfx/face_invis");
277 sb_face_invuln = Sbar_NewPic ("gfx/face_invul2");
278 sb_face_invis_invuln = Sbar_NewPic ("gfx/face_inv2");
279 sb_face_quad = Sbar_NewPic ("gfx/face_quad");
281 sb_sbar = Sbar_NewPic ("gfx/sbar");
282 sb_ibar = Sbar_NewPic ("gfx/ibar");
283 sb_scorebar = Sbar_NewPic ("gfx/scorebar");
285 //MED 01/04/97 added new hipnotic weapons
286 if (gamemode == GAME_HIPNOTIC)
288 hsb_weapons[0][0] = Sbar_NewPic ("gfx/inv_laser");
289 hsb_weapons[0][1] = Sbar_NewPic ("gfx/inv_mjolnir");
290 hsb_weapons[0][2] = Sbar_NewPic ("gfx/inv_gren_prox");
291 hsb_weapons[0][3] = Sbar_NewPic ("gfx/inv_prox_gren");
292 hsb_weapons[0][4] = Sbar_NewPic ("gfx/inv_prox");
294 hsb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_laser");
295 hsb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_mjolnir");
296 hsb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_gren_prox");
297 hsb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_prox_gren");
298 hsb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_prox");
300 for (i = 0;i < 5;i++)
302 hsb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_laser",i+1));
303 hsb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_mjolnir",i+1));
304 hsb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_gren_prox",i+1));
305 hsb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_prox_gren",i+1));
306 hsb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_prox",i+1));
309 hsb_items[0] = Sbar_NewPic ("gfx/sb_wsuit");
310 hsb_items[1] = Sbar_NewPic ("gfx/sb_eshld");
312 else if (gamemode == GAME_ROGUE)
314 rsb_invbar[0] = Sbar_NewPic ("gfx/r_invbar1");
315 rsb_invbar[1] = Sbar_NewPic ("gfx/r_invbar2");
317 rsb_weapons[0] = Sbar_NewPic ("gfx/r_lava");
318 rsb_weapons[1] = Sbar_NewPic ("gfx/r_superlava");
319 rsb_weapons[2] = Sbar_NewPic ("gfx/r_gren");
320 rsb_weapons[3] = Sbar_NewPic ("gfx/r_multirock");
321 rsb_weapons[4] = Sbar_NewPic ("gfx/r_plasma");
323 rsb_items[0] = Sbar_NewPic ("gfx/r_shield1");
324 rsb_items[1] = Sbar_NewPic ("gfx/r_agrav1");
326 // PGM 01/19/97 - team color border
327 rsb_teambord = Sbar_NewPic ("gfx/r_teambord");
328 // PGM 01/19/97 - team color border
330 rsb_ammo[0] = Sbar_NewPic ("gfx/r_ammolava");
331 rsb_ammo[1] = Sbar_NewPic ("gfx/r_ammomulti");
332 rsb_ammo[2] = Sbar_NewPic ("gfx/r_ammoplasma");
337 void sbar_shutdown(void)
341 void sbar_newmap(void)
345 void Sbar_Init (void)
347 Cmd_AddCommand ("+showscores", Sbar_ShowScores);
348 Cmd_AddCommand ("-showscores", Sbar_DontShowScores);
349 Cvar_RegisterVariable (&showfps);
350 Cvar_RegisterVariable (&showtime);
351 Cvar_RegisterVariable (&showtime_format);
352 Cvar_RegisterVariable (&showdate);
353 Cvar_RegisterVariable (&showdate_format);
354 Cvar_RegisterVariable (&sbar_alpha_bg);
355 Cvar_RegisterVariable (&sbar_alpha_fg);
356 Cvar_RegisterVariable (&cl_deathscoreboard);
358 R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
362 //=============================================================================
364 // drawing routines are relative to the status bar location
373 void Sbar_DrawPic (int x, int y, sbarpic_t *sbarpic)
375 DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
378 void Sbar_DrawAlphaPic (int x, int y, sbarpic_t *sbarpic, float alpha)
380 DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, alpha, 0);
387 Draws one solid graphics character
390 void Sbar_DrawCharacter (int x, int y, int num)
392 DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
400 void Sbar_DrawString (int x, int y, char *str)
402 DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
410 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
415 l = sprintf(str, "%i", num);
429 Sbar_DrawPic (x, y, sb_nums[color][frame]);
442 void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
447 l = sprintf(str, "%i", num);
452 x += (digits-l) * lettersize;
461 DrawQ_Pic (sbar_x + x, sbar_y + y, sb_nums[0][frame]->name,lettersize,lettersize,r,g,b,a * sbar_alpha_fg.value,flags);
468 //=============================================================================
476 static int fragsort[MAX_SCOREBOARD];
477 static int scoreboardlines;
478 void Sbar_SortFrags (void)
484 for (i=0 ; i<cl.maxclients ; i++)
486 if (cl.scores[i].name[0])
488 fragsort[scoreboardlines] = i;
493 for (i=0 ; i<scoreboardlines ; i++)
494 for (j=0 ; j<scoreboardlines-1-i ; j++)
495 if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
498 fragsort[j] = fragsort[j+1];
508 void Sbar_SoloScoreboard (void)
511 int minutes, seconds, tens, units;
514 if (gamemode != GAME_NEXUIZ) {
515 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
516 Sbar_DrawString (8, 4, str);
518 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
519 Sbar_DrawString (8, 12, str);
523 minutes = cl.time / 60;
524 seconds = cl.time - 60*minutes;
526 units = seconds - 10*tens;
527 sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
528 Sbar_DrawString (184, 4, str);
531 if (gamemode == GAME_NEXUIZ) {
532 l = (int) strlen (cl.worldmodel->name);
533 Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
535 l = (int) strlen (cl.levelname);
536 Sbar_DrawString (232 - l*4, 12, cl.levelname);
545 void Sbar_DrawScoreboard (void)
547 Sbar_SoloScoreboard ();
548 if (cl.gametype == GAME_DEATHMATCH)
549 Sbar_DeathmatchOverlay ();
552 //=============================================================================
554 // AK to make DrawInventory smaller
555 static void Sbar_DrawWeapon(int nr, float fade, int active)
557 // width = 300, height = 100
558 const int w_width = 300, w_height = 100, w_space = 10;
559 const float w_scale = 0.4;
561 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);
562 //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);
565 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);
573 void Sbar_DrawInventory (void)
580 if (gamemode == GAME_ROGUE)
582 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
583 Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], sbar_alpha_bg.value);
585 Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], sbar_alpha_bg.value);
588 Sbar_DrawAlphaPic (0, -24, sb_ibar, sbar_alpha_bg.value);
591 for (i=0 ; i<7 ; i++)
593 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
595 time = cl.item_gettime[i];
596 flashon = (int)((cl.time - time)*10);
599 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
605 flashon = (flashon%5) + 2;
607 Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
613 if (gamemode == GAME_HIPNOTIC)
615 int grenadeflashing=0;
616 for (i=0 ; i<4 ; i++)
618 if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
620 time = cl.item_gettime[hipweapons[i]];
621 flashon = (int)((cl.time - time)*10);
624 if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i]) )
630 flashon = (flashon%5) + 2;
632 // check grenade launcher
635 if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
640 Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
646 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
648 if (!grenadeflashing)
649 Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
652 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
655 Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
660 if (gamemode == GAME_ROGUE)
662 // check for powered up weapon.
663 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
665 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
666 Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
670 for (i=0 ; i<4 ; i++)
672 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
674 Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
676 Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
678 Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
682 for (i=0 ; i<6 ; i++)
683 if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
685 //MED 01/04/97 changed keys
686 if (gamemode != GAME_HIPNOTIC || (i>1))
687 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
690 //MED 01/04/97 added hipnotic items
692 if (gamemode == GAME_HIPNOTIC)
694 for (i=0 ; i<2 ; i++)
695 if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
696 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
699 if (gamemode == GAME_ROGUE)
702 for (i=0 ; i<2 ; i++)
703 if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
704 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
709 for (i=0 ; i<4 ; i++)
710 if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
711 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
715 //=============================================================================
722 void Sbar_DrawFrags (void)
732 l = min(scoreboardlines, 4);
736 for (i = 0;i < l;i++)
742 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
743 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);
744 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
745 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);
749 sprintf (num, "%3i",f);
751 if (k == cl.viewentity - 1)
753 Sbar_DrawCharacter ( x + 2, -24, 16);
754 Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
756 Sbar_DrawCharacter (x + 8, -24, num[0]);
757 Sbar_DrawCharacter (x + 16, -24, num[1]);
758 Sbar_DrawCharacter (x + 24, -24, num[2]);
763 //=============================================================================
771 void Sbar_DrawFace (void)
775 // PGM 01/19/97 - team color drawing
776 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
777 if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
783 s = &cl.scores[cl.viewentity - 1];
785 Sbar_DrawPic (112, 0, rsb_teambord);
786 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
787 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);
788 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
789 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);
793 sprintf (num, "%3i",f);
795 if ((s->colors & 0xf0)==0)
798 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
800 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
802 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
806 Sbar_DrawCharacter ( 109, 3, num[0]);
807 Sbar_DrawCharacter ( 116, 3, num[1]);
808 Sbar_DrawCharacter ( 123, 3, num[2]);
813 // PGM 01/19/97 - team color drawing
815 if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
816 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
817 else if (cl.stats[STAT_ITEMS] & IT_QUAD)
818 Sbar_DrawPic (112, 0, sb_face_quad );
819 else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
820 Sbar_DrawPic (112, 0, sb_face_invis );
821 else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
822 Sbar_DrawPic (112, 0, sb_face_invuln);
825 f = cl.stats[STAT_HEALTH] / 20;
827 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
831 void Sbar_ShowFPS(void)
833 float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
837 qboolean red = false;
844 if (showfps.integer > 1)
846 static double currtime, frametimes[32];
847 double newtime, total;
849 static int framecycle = 0;
851 newtime = Sys_DoubleTime();
852 frametimes[framecycle] = newtime - currtime;
855 while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31])
857 total += frametimes[i];
862 if (showfps.integer == 2)
863 calc = (((double)count / total) + 0.5);
864 else // showfps 3, rapid update
865 calc = ((1.0 / (newtime - currtime)) + 0.5);
870 static double nexttime = 0, lasttime = 0;
871 static float framerate = 0;
872 static int framecount = 0;
874 newtime = Sys_DoubleTime();
875 if (newtime >= nexttime)
877 framerate = ((float)framecount / (newtime - lasttime) + 0.5);
879 nexttime = max(nexttime + 1, lasttime - 1);
886 if ((red = (calc < 1.0f)))
887 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
889 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
891 if (showtime.integer)
892 strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
893 if (showdate.integer)
894 strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
895 if (fpsstring[0] || timestring[0])
899 fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
900 //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
901 //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
902 fps_y = vid_conheight.integer - fps_height;
905 fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
906 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
908 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0);
910 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
915 fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
916 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
917 DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
922 fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
923 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
924 DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
930 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)
933 c2 = bound(0, c2, 1);
934 c1 = bound(0, c1, 1 - c2);
936 r[1] = rangey + rangeheight * (c2 + c1);
937 r[2] = rangey + rangeheight * (c2);
941 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);
943 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);
945 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);
947 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);
955 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
956 extern cvar_t v_kicktime;
957 void Sbar_Draw (void)
959 if (cl.intermission == 1)
961 Sbar_IntermissionOverlay();
964 else if (cl.intermission == 2)
966 Sbar_FinaleOverlay();
970 if (gamemode == GAME_SOM)
972 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
973 Sbar_DrawScoreboard ();
976 // this is the top left of the sbar area
978 sbar_y = vid_conheight.integer - 24*3;
981 if (cl.stats[STAT_ARMOR])
983 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
984 Sbar_DrawPic(0, 0, somsb_armor[2]);
985 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
986 Sbar_DrawPic(0, 0, somsb_armor[1]);
987 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
988 Sbar_DrawPic(0, 0, somsb_armor[0]);
989 Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
993 Sbar_DrawPic(0, 24, somsb_health);
994 Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
997 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
998 Sbar_DrawPic(0, 48, somsb_ammo[0]);
999 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1000 Sbar_DrawPic(0, 48, somsb_ammo[1]);
1001 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1002 Sbar_DrawPic(0, 48, somsb_ammo[2]);
1003 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1004 Sbar_DrawPic(0, 48, somsb_ammo[3]);
1005 Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
1006 if (cl.stats[STAT_SHELLS])
1007 Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
1010 else if (gamemode == GAME_NEXUIZ)
1012 sbar_y = vid_conheight.integer - 47;
1013 sbar_x = (vid_conwidth.integer - 640)/2;
1015 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1017 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1018 Sbar_DrawScoreboard ();
1026 // we have a max time 2s (min time = 0)
1027 if ((time = cl.time - cl.weapontime) < 2)
1029 fade = (1.0 - 0.5 * time);
1031 for (i = 0; i < 8;i++)
1032 if (cl.stats[STAT_ITEMS] & (1 << i))
1033 Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1035 if((cl.stats[STAT_ITEMS] & (1<<12)))
1036 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1039 //if (!cl.islocalgame)
1040 // Sbar_DrawFrags ();
1043 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_fg.value);
1045 Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
1048 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1050 // Nexuiz has no anum pics
1051 //Sbar_DrawNum (36, 0, 666, 3, 1);
1052 // Nexuiz has no disc pic
1053 //Sbar_DrawPic (0, 0, sb_disc);
1057 Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
1060 if(cl.stats[STAT_HEALTH] > 100)
1061 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
1062 else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
1063 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1065 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1067 // AK dont draw ammo for the laser
1068 if(cl.stats[STAT_ACTIVEWEAPON] != 12)
1070 if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1071 Sbar_DrawPic (519, 0, sb_ammo[0]);
1072 else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1073 Sbar_DrawPic (519, 0, sb_ammo[1]);
1074 else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1075 Sbar_DrawPic (519, 0, sb_ammo[2]);
1076 else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1077 Sbar_DrawPic (519, 0, sb_ammo[3]);
1079 if(cl.stats[STAT_AMMO] <= 10)
1080 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
1082 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
1087 DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay->name,0,0,1,1,1,1,DRAWFLAG_MODULATE);
1090 //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1091 // Sbar_MiniDeathmatchOverlay (0, 17);
1093 else if (gamemode == GAME_ZYMOTIC)
1096 float scale = 64.0f / 256.0f;
1097 float kickoffset[3];
1098 VectorClear(kickoffset);
1101 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1102 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1104 sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1105 sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1106 // left1 16, 48 : 126 -66
1107 // left2 16, 128 : 196 -66
1108 // right 176, 48 : 196 -136
1109 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);
1110 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);
1111 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);
1112 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1114 float scale = 128.0f / 256.0f;
1115 float healthstart, healthheight, healthstarttc, healthendtc;
1116 float shieldstart, shieldheight, shieldstarttc, shieldendtc;
1117 float ammostart, ammoheight, ammostarttc, ammoendtc;
1118 float clipstart, clipheight, clipstarttc, clipendtc;
1119 float kickoffset[3], offset;
1120 VectorClear(kickoffset);
1123 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1124 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1126 sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1127 sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1128 offset = 0; // TODO: offset should be controlled by recoil (question: how to detect firing?)
1129 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);
1130 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);
1131 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);
1132 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);
1133 healthheight = cl.stats[STAT_HEALTH] * (152.0f / 300.0f);
1134 shieldheight = cl.stats[STAT_ARMOR] * (152.0f / 300.0f);
1135 healthstart = 204 - healthheight;
1136 shieldstart = healthstart - shieldheight;
1137 healthstarttc = healthstart * (1.0f / 256.0f);
1138 healthendtc = (healthstart + healthheight) * (1.0f / 256.0f);
1139 shieldstarttc = shieldstart * (1.0f / 256.0f);
1140 shieldendtc = (shieldstart + shieldheight) * (1.0f / 256.0f);
1141 ammoheight = cl.stats[STAT_SHELLS] * (62.0f / 200.0f);
1142 ammostart = 114 - ammoheight;
1143 ammostarttc = ammostart * (1.0f / 256.0f);
1144 ammoendtc = (ammostart + ammoheight) * (1.0f / 256.0f);
1145 clipheight = cl.stats[STAT_AMMO] * (122.0f / 200.0f);
1146 clipstart = 190 - clipheight;
1147 clipstarttc = clipstart * (1.0f / 256.0f);
1148 clipendtc = (clipstart + clipheight) * (1.0f / 256.0f);
1149 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);
1150 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);
1151 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);
1152 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);
1153 DrawQ_Pic(sbar_x + 0 * scale, sbar_y + 0 * scale, zymsb_crosshair_background->name, 256 * scale, 256 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1154 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center->name, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1157 else // Quake and others
1159 sbar_y = vid_conheight.integer - SBAR_HEIGHT;
1160 if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
1163 sbar_x = (vid_conwidth.integer - 320)/2;
1167 if (gamemode != GAME_GOODVSBAD2)
1168 Sbar_DrawInventory ();
1169 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1173 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1175 if (gamemode != GAME_GOODVSBAD2)
1176 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1177 Sbar_DrawScoreboard ();
1181 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_bg.value);
1183 // keys (hipnotic only)
1184 //MED 01/04/97 moved keys here so they would not be overwritten
1185 if (gamemode == GAME_HIPNOTIC)
1187 if (cl.stats[STAT_ITEMS] & IT_KEY1)
1188 Sbar_DrawPic (209, 3, sb_items[0]);
1189 if (cl.stats[STAT_ITEMS] & IT_KEY2)
1190 Sbar_DrawPic (209, 12, sb_items[1]);
1193 if (gamemode != GAME_GOODVSBAD2)
1195 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1197 Sbar_DrawNum (24, 0, 666, 3, 1);
1198 Sbar_DrawPic (0, 0, sb_disc);
1202 if (gamemode == GAME_ROGUE)
1204 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1205 if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
1206 Sbar_DrawPic (0, 0, sb_armor[2]);
1207 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
1208 Sbar_DrawPic (0, 0, sb_armor[1]);
1209 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
1210 Sbar_DrawPic (0, 0, sb_armor[0]);
1214 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1215 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1216 Sbar_DrawPic (0, 0, sb_armor[2]);
1217 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1218 Sbar_DrawPic (0, 0, sb_armor[1]);
1219 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1220 Sbar_DrawPic (0, 0, sb_armor[0]);
1229 Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1232 if (gamemode == GAME_ROGUE)
1234 if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
1235 Sbar_DrawPic (224, 0, sb_ammo[0]);
1236 else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
1237 Sbar_DrawPic (224, 0, sb_ammo[1]);
1238 else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
1239 Sbar_DrawPic (224, 0, sb_ammo[2]);
1240 else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
1241 Sbar_DrawPic (224, 0, sb_ammo[3]);
1242 else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
1243 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1244 else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
1245 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1246 else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
1247 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1251 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1252 Sbar_DrawPic (224, 0, sb_ammo[0]);
1253 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1254 Sbar_DrawPic (224, 0, sb_ammo[1]);
1255 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1256 Sbar_DrawPic (224, 0, sb_ammo[2]);
1257 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1258 Sbar_DrawPic (224, 0, sb_ammo[3]);
1261 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1265 if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1267 if (gamemode == GAME_TRANSFUSION)
1268 Sbar_MiniDeathmatchOverlay (0, 0);
1270 Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
1276 R_Draw2DCrosshair();
1278 if (cl_prydoncursor.integer)
1279 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);
1282 //=============================================================================
1286 Sbar_DeathmatchOverlay
1290 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1293 // draw colors behind score
1294 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
1295 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);
1296 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
1297 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);
1299 //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);
1300 // FIXME: use a constant for this color tag instead
1301 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 );
1305 void Sbar_DeathmatchOverlay (void)
1310 pic = Draw_CachePic ("gfx/ranking", true);
1311 DrawQ_Pic ((vid_conwidth.integer - pic->width)/2, 8, "gfx/ranking", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1316 x = (vid_conwidth.integer - (6 + 15) * 8) / 2;
1318 for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
1319 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1324 Sbar_DeathmatchOverlay
1328 void Sbar_MiniDeathmatchOverlay (int x, int y)
1332 // decide where to print
1333 if (gamemode == GAME_TRANSFUSION)
1334 numlines = (vid_conwidth.integer - x + 127) / 128;
1336 numlines = (vid_conheight.integer - y + 7) / 8;
1338 // give up if there isn't room
1339 if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
1346 for (i = 0; i < scoreboardlines; i++)
1347 if (fragsort[i] == cl.playerentity - 1)
1352 i = min(i, scoreboardlines - numlines);
1355 if (gamemode == GAME_TRANSFUSION)
1357 for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
1358 x += 128 + Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1362 for (;i < scoreboardlines && y < vid_conheight.integer;i++)
1363 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1369 Sbar_IntermissionOverlay
1373 void Sbar_IntermissionOverlay (void)
1378 if (cl.gametype == GAME_DEATHMATCH)
1380 Sbar_DeathmatchOverlay ();
1384 sbar_x = (vid_conwidth.integer - 320) >> 1;
1385 sbar_y = (vid_conheight.integer - 200) >> 1;
1387 DrawQ_Pic (sbar_x + 64, sbar_y + 24, "gfx/complete", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1388 DrawQ_Pic (sbar_x + 0, sbar_y + 56, "gfx/inter", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1391 dig = cl.completed_time/60;
1392 Sbar_DrawNum (160, 64, dig, 3, 0);
1393 num = cl.completed_time - dig*60;
1394 if (gamemode != GAME_NEXUIZ)
1395 Sbar_DrawPic (234,64,sb_colon);
1396 Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1397 Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1399 Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1400 if (gamemode != GAME_NEXUIZ)
1401 Sbar_DrawPic (232, 104, sb_slash);
1402 Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1404 Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1405 if (gamemode != GAME_NEXUIZ)
1406 Sbar_DrawPic (232, 144, sb_slash);
1407 Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1418 void Sbar_FinaleOverlay (void)
1422 pic = Draw_CachePic ("gfx/finale", true);
1423 DrawQ_Pic((vid_conwidth.integer - pic->width)/2, 16, "gfx/finale", 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);