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
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);
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 NX(and only if everybody agrees)
51 sbarpic_t *sb_sbar_overlay;
53 sbarpic_t *sb_weapons[7][8]; // 0 is active, 1 is owned, 2-5 are flashes
54 sbarpic_t *sb_ammo[4];
55 sbarpic_t *sb_sigil[4];
56 sbarpic_t *sb_armor[3];
57 sbarpic_t *sb_items[32];
59 // 0-4 are based on health (in 20 increments)
60 // 0 is static, 1 is temporary animation
61 sbarpic_t *sb_faces[5][2];
63 sbarpic_t *sb_face_invis;
64 sbarpic_t *sb_face_quad;
65 sbarpic_t *sb_face_invuln;
66 sbarpic_t *sb_face_invis_invuln;
68 qboolean sb_showscores;
70 int sb_lines; // scan lines to draw
72 sbarpic_t *rsb_invbar[2];
73 sbarpic_t *rsb_weapons[5];
74 sbarpic_t *rsb_items[2];
75 sbarpic_t *rsb_ammo[3];
76 sbarpic_t *rsb_teambord; // PGM 01/19/97 - team color border
78 //MED 01/04/97 added two more weapons + 3 alternates for grenade launcher
79 sbarpic_t *hsb_weapons[7][5]; // 0 is active, 1 is owned, 2-5 are flashes
80 //MED 01/04/97 added array to simplify weapon parsing
81 int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT};
82 //MED 01/04/97 added hipnotic items array
83 sbarpic_t *hsb_items[2];
85 cvar_t showfps = {CVAR_SAVE, "showfps", "0"};
87 void Sbar_MiniDeathmatchOverlay (void);
88 void Sbar_DeathmatchOverlay (void);
89 void Sbar_IntermissionOverlay (void);
90 void Sbar_FinaleOverlay (void);
100 void Sbar_ShowScores (void)
104 sb_showscores = true;
114 void Sbar_DontShowScores (void)
116 sb_showscores = false;
119 void sbar_start(void)
125 sb_disc = Sbar_NewPic("gfx/disc");
127 for (i = 0;i < 10;i++)
129 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
130 sb_nums[1][i] = Sbar_NewPic (va("gfx/anum_%i",i));
133 sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
134 sb_nums[1][10] = Sbar_NewPic ("gfx/anum_minus");
136 sb_colon = Sbar_NewPic ("gfx/num_colon");
137 sb_slash = Sbar_NewPic ("gfx/num_slash");
139 //AK NX uses his own hud
140 if(gamemode = GAME_NEXUIZ)
142 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
143 sb_ammo[1] = Sbar_NewPic ("gfx/sb_bullets");
144 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
145 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
147 sb_items[2] = Sbar_NewPic ("gfx/sb_slowmo");
148 sb_items[3] = Sbar_NewPic ("gfx/sb_invinc");
149 sb_items[4] = Sbar_NewPic ("gfx/sb_energy");
150 sb_items[5] = Sbar_NewPic ("gfx/sb_str");
152 sb_sbar = Sbar_NewPic("gfx/sbar");
153 sb_sbar_overlay = Sbar_NewPic("gfx/sbar_overlay");
158 sb_weapons[0][0] = Sbar_NewPic ("gfx/inv_shotgun");
159 sb_weapons[0][1] = Sbar_NewPic ("gfx/inv_sshotgun");
160 sb_weapons[0][2] = Sbar_NewPic ("gfx/inv_nailgun");
161 sb_weapons[0][3] = Sbar_NewPic ("gfx/inv_snailgun");
162 sb_weapons[0][4] = Sbar_NewPic ("gfx/inv_rlaunch");
163 sb_weapons[0][5] = Sbar_NewPic ("gfx/inv_srlaunch");
164 sb_weapons[0][6] = Sbar_NewPic ("gfx/inv_lightng");
166 sb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_shotgun");
167 sb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_sshotgun");
168 sb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_nailgun");
169 sb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_snailgun");
170 sb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_rlaunch");
171 sb_weapons[1][5] = Sbar_NewPic ("gfx/inv2_srlaunch");
172 sb_weapons[1][6] = Sbar_NewPic ("gfx/inv2_lightng");
174 for (i = 0;i < 5;i++)
176 sb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_shotgun",i+1));
177 sb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_sshotgun",i+1));
178 sb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_nailgun",i+1));
179 sb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_snailgun",i+1));
180 sb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_rlaunch",i+1));
181 sb_weapons[2+i][5] = Sbar_NewPic (va("gfx/inva%i_srlaunch",i+1));
182 sb_weapons[2+i][6] = Sbar_NewPic (va("gfx/inva%i_lightng",i+1));
185 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
186 sb_ammo[1] = Sbar_NewPic ("gfx/sb_nails");
187 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
188 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
190 sb_armor[0] = Sbar_NewPic ("gfx/sb_armor1");
191 sb_armor[1] = Sbar_NewPic ("gfx/sb_armor2");
192 sb_armor[2] = Sbar_NewPic ("gfx/sb_armor3");
194 sb_items[0] = Sbar_NewPic ("gfx/sb_key1");
195 sb_items[1] = Sbar_NewPic ("gfx/sb_key2");
196 sb_items[2] = Sbar_NewPic ("gfx/sb_invis");
197 sb_items[3] = Sbar_NewPic ("gfx/sb_invuln");
198 sb_items[4] = Sbar_NewPic ("gfx/sb_suit");
199 sb_items[5] = Sbar_NewPic ("gfx/sb_quad");
201 sb_sigil[0] = Sbar_NewPic ("gfx/sb_sigil1");
202 sb_sigil[1] = Sbar_NewPic ("gfx/sb_sigil2");
203 sb_sigil[2] = Sbar_NewPic ("gfx/sb_sigil3");
204 sb_sigil[3] = Sbar_NewPic ("gfx/sb_sigil4");
206 sb_faces[4][0] = Sbar_NewPic ("gfx/face1");
207 sb_faces[4][1] = Sbar_NewPic ("gfx/face_p1");
208 sb_faces[3][0] = Sbar_NewPic ("gfx/face2");
209 sb_faces[3][1] = Sbar_NewPic ("gfx/face_p2");
210 sb_faces[2][0] = Sbar_NewPic ("gfx/face3");
211 sb_faces[2][1] = Sbar_NewPic ("gfx/face_p3");
212 sb_faces[1][0] = Sbar_NewPic ("gfx/face4");
213 sb_faces[1][1] = Sbar_NewPic ("gfx/face_p4");
214 sb_faces[0][0] = Sbar_NewPic ("gfx/face5");
215 sb_faces[0][1] = Sbar_NewPic ("gfx/face_p5");
217 sb_face_invis = Sbar_NewPic ("gfx/face_invis");
218 sb_face_invuln = Sbar_NewPic ("gfx/face_invul2");
219 sb_face_invis_invuln = Sbar_NewPic ("gfx/face_inv2");
220 sb_face_quad = Sbar_NewPic ("gfx/face_quad");
222 sb_sbar = Sbar_NewPic ("gfx/sbar");
223 sb_ibar = Sbar_NewPic ("gfx/ibar");
224 sb_scorebar = Sbar_NewPic ("gfx/scorebar");
226 //MED 01/04/97 added new hipnotic weapons
227 if (gamemode == GAME_HIPNOTIC)
229 hsb_weapons[0][0] = Sbar_NewPic ("gfx/inv_laser");
230 hsb_weapons[0][1] = Sbar_NewPic ("gfx/inv_mjolnir");
231 hsb_weapons[0][2] = Sbar_NewPic ("gfx/inv_gren_prox");
232 hsb_weapons[0][3] = Sbar_NewPic ("gfx/inv_prox_gren");
233 hsb_weapons[0][4] = Sbar_NewPic ("gfx/inv_prox");
235 hsb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_laser");
236 hsb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_mjolnir");
237 hsb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_gren_prox");
238 hsb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_prox_gren");
239 hsb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_prox");
241 for (i = 0;i < 5;i++)
243 hsb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_laser",i+1));
244 hsb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_mjolnir",i+1));
245 hsb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_gren_prox",i+1));
246 hsb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_prox_gren",i+1));
247 hsb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_prox",i+1));
250 hsb_items[0] = Sbar_NewPic ("gfx/sb_wsuit");
251 hsb_items[1] = Sbar_NewPic ("gfx/sb_eshld");
253 else if (gamemode == GAME_ROGUE)
255 rsb_invbar[0] = Sbar_NewPic ("gfx/r_invbar1");
256 rsb_invbar[1] = Sbar_NewPic ("gfx/r_invbar2");
258 rsb_weapons[0] = Sbar_NewPic ("gfx/r_lava");
259 rsb_weapons[1] = Sbar_NewPic ("gfx/r_superlava");
260 rsb_weapons[2] = Sbar_NewPic ("gfx/r_gren");
261 rsb_weapons[3] = Sbar_NewPic ("gfx/r_multirock");
262 rsb_weapons[4] = Sbar_NewPic ("gfx/r_plasma");
264 rsb_items[0] = Sbar_NewPic ("gfx/r_shield1");
265 rsb_items[1] = Sbar_NewPic ("gfx/r_agrav1");
267 // PGM 01/19/97 - team color border
268 rsb_teambord = Sbar_NewPic ("gfx/r_teambord");
269 // PGM 01/19/97 - team color border
271 rsb_ammo[0] = Sbar_NewPic ("gfx/r_ammolava");
272 rsb_ammo[1] = Sbar_NewPic ("gfx/r_ammomulti");
273 rsb_ammo[2] = Sbar_NewPic ("gfx/r_ammoplasma");
277 void sbar_shutdown(void)
281 void sbar_newmap(void)
285 void Sbar_Init (void)
287 Cmd_AddCommand ("+showscores", Sbar_ShowScores);
288 Cmd_AddCommand ("-showscores", Sbar_DontShowScores);
289 Cvar_RegisterVariable (&showfps);
291 R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
295 //=============================================================================
297 // drawing routines are relative to the status bar location
306 void Sbar_DrawPic (int x, int y, sbarpic_t *sbarpic)
308 DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, 1, 0);
311 void Sbar_DrawAlphaPic (int x, int y, sbarpic_t *sbarpic, float alpha)
313 DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, alpha, 0);
320 Draws one solid graphics character
323 void Sbar_DrawCharacter (int x, int y, int num)
325 DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, 1, 0);
333 void Sbar_DrawString (int x, int y, char *str)
335 DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, 1, 0);
343 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
348 l = sprintf(str, "%i", num);
362 Sbar_DrawPic (x, y, sb_nums[color][frame]);
368 //=============================================================================
376 static int fragsort[MAX_SCOREBOARD];
377 static int scoreboardlines;
378 void Sbar_SortFrags (void)
384 for (i=0 ; i<cl.maxclients ; i++)
386 if (cl.scores[i].name[0])
388 fragsort[scoreboardlines] = i;
393 for (i=0 ; i<scoreboardlines ; i++)
394 for (j=0 ; j<scoreboardlines-1-i ; j++)
395 if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
398 fragsort[j] = fragsort[j+1];
408 void Sbar_SoloScoreboard (void)
411 int minutes, seconds, tens, units;
414 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
415 Sbar_DrawString (8, 4, str);
417 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
418 Sbar_DrawString (8, 12, str);
421 minutes = cl.time / 60;
422 seconds = cl.time - 60*minutes;
424 units = seconds - 10*tens;
425 sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
426 Sbar_DrawString (184, 4, str);
429 l = strlen (cl.levelname);
430 Sbar_DrawString (232 - l*4, 12, cl.levelname);
438 void Sbar_DrawScoreboard (void)
440 Sbar_SoloScoreboard ();
441 if (cl.gametype == GAME_DEATHMATCH)
442 Sbar_DeathmatchOverlay ();
445 //=============================================================================
452 void Sbar_DrawInventory (void)
459 if (gamemode == GAME_ROGUE)
461 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
462 Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], 0.4);
464 Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], 0.4);
467 Sbar_DrawAlphaPic (0, -24, sb_ibar, 0.4);
470 for (i=0 ; i<7 ; i++)
472 if (cl.items & (IT_SHOTGUN<<i) )
474 time = cl.item_gettime[i];
475 flashon = (int)((cl.time - time)*10);
478 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
484 flashon = (flashon%5) + 2;
486 Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], 0.4);
492 if (gamemode == GAME_HIPNOTIC)
494 int grenadeflashing=0;
495 for (i=0 ; i<4 ; i++)
497 if (cl.items & (1<<hipweapons[i]) )
499 time = cl.item_gettime[hipweapons[i]];
500 flashon = (int)((cl.time - time)*10);
503 if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i]) )
509 flashon = (flashon%5) + 2;
511 // check grenade launcher
514 if (cl.items & HIT_PROXIMITY_GUN)
519 Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
525 if (cl.items & (IT_SHOTGUN<<4))
527 if (!grenadeflashing)
528 Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
531 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
534 Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
539 if (gamemode == GAME_ROGUE)
541 // check for powered up weapon.
542 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
544 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
545 Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
549 for (i=0 ; i<4 ; i++)
551 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
553 Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
555 Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
557 Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
561 for (i=0 ; i<6 ; i++)
562 if (cl.items & (1<<(17+i)))
564 //MED 01/04/97 changed keys
565 if (gamemode != GAME_HIPNOTIC || (i>1))
566 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
569 //MED 01/04/97 added hipnotic items
571 if (gamemode == GAME_HIPNOTIC)
573 for (i=0 ; i<2 ; i++)
574 if (cl.items & (1<<(24+i)))
575 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
578 if (gamemode == GAME_ROGUE)
581 for (i=0 ; i<2 ; i++)
582 if (cl.items & (1<<(29+i)))
583 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
588 for (i=0 ; i<4 ; i++)
589 if (cl.items & (1<<(28+i)))
590 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
594 //=============================================================================
601 void Sbar_DrawFrags (void)
611 l = scoreboardlines <= 4 ? scoreboardlines : 4;
615 for (i = 0;i < l;i++)
623 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
624 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), 0);
625 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
626 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), 0);
630 sprintf (num, "%3i",f);
632 Sbar_DrawCharacter (x + 8, -24, num[0]);
633 Sbar_DrawCharacter (x + 16, -24, num[1]);
634 Sbar_DrawCharacter (x + 24, -24, num[2]);
636 if (k == cl.viewentity - 1)
638 Sbar_DrawCharacter ( x + 2, -24, 16);
639 Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
645 //=============================================================================
653 void Sbar_DrawFace (void)
657 // PGM 01/19/97 - team color drawing
658 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
659 if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
665 s = &cl.scores[cl.viewentity - 1];
667 Sbar_DrawPic (112, 0, rsb_teambord);
668 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
669 DrawQ_Fill (sbar_x + 113, vid.conheight-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), 0);
670 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
671 DrawQ_Fill (sbar_x + 113, vid.conheight-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), 0);
675 sprintf (num, "%3i",f);
677 if ((s->colors & 0xf0)==0)
680 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
682 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
684 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
688 Sbar_DrawCharacter ( 109, 3, num[0]);
689 Sbar_DrawCharacter ( 116, 3, num[1]);
690 Sbar_DrawCharacter ( 123, 3, num[2]);
695 // PGM 01/19/97 - team color drawing
697 if ( (cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
698 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
699 else if (cl.items & IT_QUAD)
700 Sbar_DrawPic (112, 0, sb_face_quad );
701 else if (cl.items & IT_INVISIBILITY)
702 Sbar_DrawPic (112, 0, sb_face_invis );
703 else if (cl.items & IT_INVULNERABILITY)
704 Sbar_DrawPic (112, 0, sb_face_invuln);
707 f = cl.stats[STAT_HEALTH] / 20;
709 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
713 void Sbar_ShowFPS(void)
719 float fps_x, fps_y, fps_scalex, fps_scaley;
720 if (showfps.integer > 1)
722 static double currtime, frametimes[32];
723 double newtime, total;
725 static int framecycle = 0;
727 newtime = Sys_DoubleTime();
728 frametimes[framecycle] = newtime - currtime;
731 while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31])
733 total += frametimes[i];
738 if (showfps.integer == 2)
739 calc = (int) (((double) count / total) + 0.5);
740 else // showfps 3, rapid update
741 calc = (int) ((1.0 / (newtime - currtime)) + 0.5);
746 static double nexttime = 0, lasttime = 0;
747 static int framerate = 0, framecount = 0;
749 newtime = Sys_DoubleTime();
750 if (newtime < nexttime)
754 framerate = (int) (framecount / (newtime - lasttime) + 0.5);
756 nexttime = lasttime + 0.2;
761 sprintf(temp, "%4i", calc);
764 fps_x = vid.conwidth - (fps_scalex * strlen(temp));
765 fps_y = vid.conheight - sb_lines/* - 8*/; // yes this might draw over the sbar
766 if (fps_y > vid.conheight - fps_scaley)
767 fps_y = vid.conheight - fps_scaley;
768 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(temp), fps_scaley, 0, 0, 0, 0.5, 0);
769 DrawQ_String(fps_x, fps_y, temp, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
778 void Sbar_Draw (void)
780 if (scr_con_current == vid.conheight)
781 return; // console is full screen
783 if (cl.intermission == 1)
785 Sbar_IntermissionOverlay();
788 else if (cl.intermission == 2)
790 Sbar_FinaleOverlay();
794 if(gamemode == GAME_NEXUIZ)
796 sbar_y = vid.conheight - 47;
797 sbar_x = (vid.conwidth - 640)/2;
805 if (sb_showscores || cl.stats[STAT_HEALTH] <= 0)
807 if (gamemode != GAME_GOODVSBAD2)
808 Sbar_DrawAlphaPic (0, 0, sb_scorebar, 0.4);
809 Sbar_DrawScoreboard ();
813 Sbar_DrawPic (0, 0, sb_sbar);
816 if (cl.items & IT_INVULNERABILITY)
818 Sbar_DrawNum (24, 0, 666, 3, 1);
819 Sbar_DrawPic (0, 0, sb_disc);
823 Sbar_DrawNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
826 Sbar_DrawNum ((154-3*24), 12, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
828 if (cl.items & NEX_IT_SHELLS)
829 Sbar_DrawPic (519, 0, sb_ammo[0]);
830 else if (cl.items & NEX_IT_BULLETS)
831 Sbar_DrawPic (519, 0, sb_ammo[1]);
832 else if (cl.items & NEX_IT_ROCKETS)
833 Sbar_DrawPic (519, 0, sb_ammo[2]);
834 else if (cl.items & NEX_IT_CELLS)
835 Sbar_DrawPic (519, 0, sb_ammo[3]);
837 Sbar_DrawNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
839 //Sbar_DrawAlphaPic(0,0,sb_sbar_overlay,0.5);
840 DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay->name,0,0,1,1,1,1,DRAWFLAG_MODULATE);
844 if (vid.conwidth > 320 && cl.gametype == GAME_DEATHMATCH)
845 Sbar_MiniDeathmatchOverlay ();
850 sbar_y = vid.conheight - SBAR_HEIGHT;
851 if (cl.gametype == GAME_DEATHMATCH)
854 sbar_x = (vid.conwidth - 320)/2;
858 if (gamemode != GAME_GOODVSBAD2)
859 Sbar_DrawInventory ();
864 if (sb_showscores || cl.stats[STAT_HEALTH] <= 0)
866 if (gamemode != GAME_GOODVSBAD2)
867 Sbar_DrawAlphaPic (0, 0, sb_scorebar, 0.4);
868 Sbar_DrawScoreboard ();
872 Sbar_DrawAlphaPic (0, 0, sb_sbar, 0.4);
874 // keys (hipnotic only)
875 //MED 01/04/97 moved keys here so they would not be overwritten
876 if (gamemode == GAME_HIPNOTIC)
878 if (cl.items & IT_KEY1)
879 Sbar_DrawPic (209, 3, sb_items[0]);
880 if (cl.items & IT_KEY2)
881 Sbar_DrawPic (209, 12, sb_items[1]);
884 if (gamemode != GAME_GOODVSBAD2)
886 if (cl.items & IT_INVULNERABILITY)
888 Sbar_DrawNum (24, 0, 666, 3, 1);
889 Sbar_DrawPic (0, 0, sb_disc);
893 if (gamemode == GAME_ROGUE)
895 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
896 if (cl.items & RIT_ARMOR3)
897 Sbar_DrawPic (0, 0, sb_armor[2]);
898 else if (cl.items & RIT_ARMOR2)
899 Sbar_DrawPic (0, 0, sb_armor[1]);
900 else if (cl.items & RIT_ARMOR1)
901 Sbar_DrawPic (0, 0, sb_armor[0]);
905 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
906 if (cl.items & IT_ARMOR3)
907 Sbar_DrawPic (0, 0, sb_armor[2]);
908 else if (cl.items & IT_ARMOR2)
909 Sbar_DrawPic (0, 0, sb_armor[1]);
910 else if (cl.items & IT_ARMOR1)
911 Sbar_DrawPic (0, 0, sb_armor[0]);
920 Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
923 if (gamemode == GAME_ROGUE)
925 if (cl.items & RIT_SHELLS)
926 Sbar_DrawPic (224, 0, sb_ammo[0]);
927 else if (cl.items & RIT_NAILS)
928 Sbar_DrawPic (224, 0, sb_ammo[1]);
929 else if (cl.items & RIT_ROCKETS)
930 Sbar_DrawPic (224, 0, sb_ammo[2]);
931 else if (cl.items & RIT_CELLS)
932 Sbar_DrawPic (224, 0, sb_ammo[3]);
933 else if (cl.items & RIT_LAVA_NAILS)
934 Sbar_DrawPic (224, 0, rsb_ammo[0]);
935 else if (cl.items & RIT_PLASMA_AMMO)
936 Sbar_DrawPic (224, 0, rsb_ammo[1]);
937 else if (cl.items & RIT_MULTI_ROCKETS)
938 Sbar_DrawPic (224, 0, rsb_ammo[2]);
942 if (cl.items & IT_SHELLS)
943 Sbar_DrawPic (224, 0, sb_ammo[0]);
944 else if (cl.items & IT_NAILS)
945 Sbar_DrawPic (224, 0, sb_ammo[1]);
946 else if (cl.items & IT_ROCKETS)
947 Sbar_DrawPic (224, 0, sb_ammo[2]);
948 else if (cl.items & IT_CELLS)
949 Sbar_DrawPic (224, 0, sb_ammo[3]);
952 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
958 if (vid.conwidth > 320 && cl.gametype == GAME_DEATHMATCH)
959 Sbar_MiniDeathmatchOverlay ();
966 //=============================================================================
970 Sbar_DeathmatchOverlay
974 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
977 if (s->name[0] || s->frags || s->colors || (s - cl.scores) == cl.playerentity - 1)
979 // draw colors behind score
980 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
981 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), 0);
982 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
983 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), 0);
985 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, 0);
992 void Sbar_DeathmatchOverlay (void)
997 pic = Draw_CachePic ("gfx/ranking.lmp");
998 DrawQ_Pic ((vid.conwidth - pic->width)/2, 8, "gfx/ranking.lmp", 0, 0, 1, 1, 1, 1, 0);
1003 x = (vid.conwidth - (6 + 15) * 8) / 2;
1005 for (i = 0;i < scoreboardlines && y < vid.conheight;i++)
1006 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1011 Sbar_DeathmatchOverlay
1015 void Sbar_MiniDeathmatchOverlay (void)
1017 int i, x, y, numlines;
1019 // decide where to print
1021 y = vid.conheight - sb_lines;
1022 numlines = (vid.conheight - y) / 8;
1023 // give up if there isn't room
1024 if (x + (6 + 15) * 8 > vid.conwidth || numlines < 1)
1031 for (i = 0; i < scoreboardlines; i++)
1032 if (fragsort[i] == cl.playerentity - 1)
1035 if (i == scoreboardlines) // we're not there
1037 else // figure out start
1040 i = bound(0, i, scoreboardlines - numlines);
1043 for (;i < scoreboardlines && y < vid.conheight;i++)
1044 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1049 Sbar_IntermissionOverlay
1053 void Sbar_IntermissionOverlay (void)
1058 if (cl.gametype == GAME_DEATHMATCH)
1060 Sbar_DeathmatchOverlay ();
1064 sbar_x = (vid.conwidth - 320) >> 1;
1065 sbar_y = (vid.conheight - 200) >> 1;
1067 DrawQ_Pic (sbar_x + 64, sbar_y + 24, "gfx/complete.lmp", 0, 0, 1, 1, 1, 1, 0);
1068 DrawQ_Pic (sbar_x + 0, sbar_y + 56, "gfx/inter.lmp", 0, 0, 1, 1, 1, 1, 0);
1071 dig = cl.completed_time/60;
1072 Sbar_DrawNum (160, 64, dig, 3, 0);
1073 num = cl.completed_time - dig*60;
1074 Sbar_DrawPic (234,64,sb_colon);
1075 Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1076 Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1078 Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1079 Sbar_DrawPic (232, 104, sb_slash);
1080 Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1082 Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1083 Sbar_DrawPic (232, 144, sb_slash);
1084 Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1095 void Sbar_FinaleOverlay (void)
1099 pic = Draw_CachePic ("gfx/finale.lmp");
1100 DrawQ_Pic((vid.conwidth - pic->width)/2, 16, "gfx/finale.lmp", 0, 0, 1, 1, 1, 1, 0);