added GAME_SOM (and its hud), and shuffled some hud code around to make things a...
[divverent/darkplaces.git] / sbar.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
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.
8
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.
12
13 See the GNU General Public License for more details.
14
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.
18
19 */
20 // sbar.c -- status bar code
21
22 #include "quakedef.h"
23
24 typedef struct
25 {
26         char name[32];
27 }
28 sbarpic_t;
29
30 static sbarpic_t sbarpics[256];
31 static int numsbarpics;
32
33 static sbarpic_t *Sbar_NewPic(const char *name)
34 {
35         strcpy(sbarpics[numsbarpics].name, name);
36         // precache it
37         // FIXME: precache on every renderer restart (or move this to client)
38         Draw_CachePic(sbarpics[numsbarpics].name);
39         return sbarpics + (numsbarpics++);
40 }
41
42 sbarpic_t *sb_disc;
43
44 #define STAT_MINUS 10 // num frame for '-' stats digit
45 sbarpic_t *sb_nums[2][11];
46 sbarpic_t *sb_colon, *sb_slash;
47 sbarpic_t *sb_ibar;
48 sbarpic_t *sb_sbar;
49 sbarpic_t *sb_scorebar;
50 // AK only used by NEX(and only if everybody agrees)
51 sbarpic_t *sb_sbar_overlay;
52
53 // AK changed the bound to 9
54 sbarpic_t *sb_weapons[7][9]; // 0 is active, 1 is owned, 2-5 are flashes
55 sbarpic_t *sb_ammo[4];
56 sbarpic_t *sb_sigil[4];
57 sbarpic_t *sb_armor[3];
58 sbarpic_t *sb_items[32];
59
60 // 0-4 are based on health (in 20 increments)
61 // 0 is static, 1 is temporary animation
62 sbarpic_t *sb_faces[5][2];
63
64 sbarpic_t *sb_face_invis;
65 sbarpic_t *sb_face_quad;
66 sbarpic_t *sb_face_invuln;
67 sbarpic_t *sb_face_invis_invuln;
68
69 qboolean sb_showscores;
70
71 int sb_lines;                   // scan lines to draw
72
73 sbarpic_t *rsb_invbar[2];
74 sbarpic_t *rsb_weapons[5];
75 sbarpic_t *rsb_items[2];
76 sbarpic_t *rsb_ammo[3];
77 sbarpic_t *rsb_teambord;                // PGM 01/19/97 - team color border
78
79 //MED 01/04/97 added two more weapons + 3 alternates for grenade launcher
80 sbarpic_t *hsb_weapons[7][5];   // 0 is active, 1 is owned, 2-5 are flashes
81 //MED 01/04/97 added array to simplify weapon parsing
82 int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT};
83 //MED 01/04/97 added hipnotic items array
84 sbarpic_t *hsb_items[2];
85
86 //GAME_SOM stuff:
87 sbarpic_t *somsb_health;
88 sbarpic_t *somsb_ammo[4];
89 sbarpic_t *somsb_armor[3];
90
91 cvar_t  showfps = {CVAR_SAVE, "showfps", "0"};
92 cvar_t  sbar_alpha = {CVAR_SAVE, "sbar_alpha", "1"};
93
94 void Sbar_MiniDeathmatchOverlay (int x, int y);
95 void Sbar_DeathmatchOverlay (void);
96 void Sbar_IntermissionOverlay (void);
97 void Sbar_FinaleOverlay (void);
98
99
100 /*
101 ===============
102 Sbar_ShowScores
103
104 Tab key down
105 ===============
106 */
107 void Sbar_ShowScores (void)
108 {
109         if (sb_showscores)
110                 return;
111         sb_showscores = true;
112 }
113
114 /*
115 ===============
116 Sbar_DontShowScores
117
118 Tab key up
119 ===============
120 */
121 void Sbar_DontShowScores (void)
122 {
123         sb_showscores = false;
124 }
125
126 void sbar_start(void)
127 {
128         int i;
129
130         numsbarpics = 0;
131
132         sb_disc = Sbar_NewPic("gfx/disc");
133
134         for (i = 0;i < 10;i++)
135         {
136                 sb_nums[0][i] = Sbar_NewPic (va("gfx/num_%i",i));
137                 sb_nums[1][i] = Sbar_NewPic (va("gfx/anum_%i",i));
138         }
139
140         sb_nums[0][10] = Sbar_NewPic ("gfx/num_minus");
141         sb_nums[1][10] = Sbar_NewPic ("gfx/anum_minus");
142
143         sb_colon = Sbar_NewPic ("gfx/num_colon");
144         sb_slash = Sbar_NewPic ("gfx/num_slash");
145
146         if (gamemode == GAME_SOM)
147         {
148                 somsb_health = Sbar_NewPic("gfx/hud_health");
149                 somsb_ammo[0] = Sbar_NewPic("gfx/sb_shells");
150                 somsb_ammo[1] = Sbar_NewPic("gfx/sb_nails");
151                 somsb_ammo[2] = Sbar_NewPic("gfx/sb_rocket");
152                 somsb_ammo[3] = Sbar_NewPic("gfx/sb_cells");
153                 somsb_armor[0] = Sbar_NewPic("gfx/sb_armor1");
154                 somsb_armor[1] = Sbar_NewPic("gfx/sb_armor2");
155                 somsb_armor[2] = Sbar_NewPic("gfx/sb_armor3");
156         }
157         else if (gamemode == GAME_NEXUIZ)
158         {
159                 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
160                 sb_ammo[1] = Sbar_NewPic ("gfx/sb_bullets");
161                 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
162                 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
163
164                 sb_items[2] = Sbar_NewPic ("gfx/sb_slowmo");
165                 sb_items[3] = Sbar_NewPic ("gfx/sb_invinc");
166                 sb_items[4] = Sbar_NewPic ("gfx/sb_energy");
167                 sb_items[5] = Sbar_NewPic ("gfx/sb_str");
168
169                 sb_sbar = Sbar_NewPic("gfx/sbar");
170                 sb_sbar_overlay = Sbar_NewPic("gfx/sbar_overlay");
171
172                 for(i = 0; i < 9;i++)
173                         sb_weapons[0][i] = Sbar_NewPic(va("gfx/inv_weapon%i",i));
174         }
175         else
176         {
177                 sb_weapons[0][0] = Sbar_NewPic ("gfx/inv_shotgun");
178                 sb_weapons[0][1] = Sbar_NewPic ("gfx/inv_sshotgun");
179                 sb_weapons[0][2] = Sbar_NewPic ("gfx/inv_nailgun");
180                 sb_weapons[0][3] = Sbar_NewPic ("gfx/inv_snailgun");
181                 sb_weapons[0][4] = Sbar_NewPic ("gfx/inv_rlaunch");
182                 sb_weapons[0][5] = Sbar_NewPic ("gfx/inv_srlaunch");
183                 sb_weapons[0][6] = Sbar_NewPic ("gfx/inv_lightng");
184         
185                 sb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_shotgun");
186                 sb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_sshotgun");
187                 sb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_nailgun");
188                 sb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_snailgun");
189                 sb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_rlaunch");
190                 sb_weapons[1][5] = Sbar_NewPic ("gfx/inv2_srlaunch");
191                 sb_weapons[1][6] = Sbar_NewPic ("gfx/inv2_lightng");
192         
193                 for (i = 0;i < 5;i++)
194                 {
195                         sb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_shotgun",i+1));
196                         sb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_sshotgun",i+1));
197                         sb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_nailgun",i+1));
198                         sb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_snailgun",i+1));
199                         sb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_rlaunch",i+1));
200                         sb_weapons[2+i][5] = Sbar_NewPic (va("gfx/inva%i_srlaunch",i+1));
201                         sb_weapons[2+i][6] = Sbar_NewPic (va("gfx/inva%i_lightng",i+1));
202                 }
203         
204                 sb_ammo[0] = Sbar_NewPic ("gfx/sb_shells");
205                 sb_ammo[1] = Sbar_NewPic ("gfx/sb_nails");
206                 sb_ammo[2] = Sbar_NewPic ("gfx/sb_rocket");
207                 sb_ammo[3] = Sbar_NewPic ("gfx/sb_cells");
208         
209                 sb_armor[0] = Sbar_NewPic ("gfx/sb_armor1");
210                 sb_armor[1] = Sbar_NewPic ("gfx/sb_armor2");
211                 sb_armor[2] = Sbar_NewPic ("gfx/sb_armor3");
212         
213                 sb_items[0] = Sbar_NewPic ("gfx/sb_key1");
214                 sb_items[1] = Sbar_NewPic ("gfx/sb_key2");
215                 sb_items[2] = Sbar_NewPic ("gfx/sb_invis");
216                 sb_items[3] = Sbar_NewPic ("gfx/sb_invuln");
217                 sb_items[4] = Sbar_NewPic ("gfx/sb_suit");
218                 sb_items[5] = Sbar_NewPic ("gfx/sb_quad");
219         
220                 sb_sigil[0] = Sbar_NewPic ("gfx/sb_sigil1");
221                 sb_sigil[1] = Sbar_NewPic ("gfx/sb_sigil2");
222                 sb_sigil[2] = Sbar_NewPic ("gfx/sb_sigil3");
223                 sb_sigil[3] = Sbar_NewPic ("gfx/sb_sigil4");
224         
225                 sb_faces[4][0] = Sbar_NewPic ("gfx/face1");
226                 sb_faces[4][1] = Sbar_NewPic ("gfx/face_p1");
227                 sb_faces[3][0] = Sbar_NewPic ("gfx/face2");
228                 sb_faces[3][1] = Sbar_NewPic ("gfx/face_p2");
229                 sb_faces[2][0] = Sbar_NewPic ("gfx/face3");
230                 sb_faces[2][1] = Sbar_NewPic ("gfx/face_p3");
231                 sb_faces[1][0] = Sbar_NewPic ("gfx/face4");
232                 sb_faces[1][1] = Sbar_NewPic ("gfx/face_p4");
233                 sb_faces[0][0] = Sbar_NewPic ("gfx/face5");
234                 sb_faces[0][1] = Sbar_NewPic ("gfx/face_p5");
235         
236                 sb_face_invis = Sbar_NewPic ("gfx/face_invis");
237                 sb_face_invuln = Sbar_NewPic ("gfx/face_invul2");
238                 sb_face_invis_invuln = Sbar_NewPic ("gfx/face_inv2");
239                 sb_face_quad = Sbar_NewPic ("gfx/face_quad");
240         
241                 sb_sbar = Sbar_NewPic ("gfx/sbar");
242                 sb_ibar = Sbar_NewPic ("gfx/ibar");
243                 sb_scorebar = Sbar_NewPic ("gfx/scorebar");
244         
245         //MED 01/04/97 added new hipnotic weapons
246                 if (gamemode == GAME_HIPNOTIC)
247                 {
248                         hsb_weapons[0][0] = Sbar_NewPic ("gfx/inv_laser");
249                         hsb_weapons[0][1] = Sbar_NewPic ("gfx/inv_mjolnir");
250                         hsb_weapons[0][2] = Sbar_NewPic ("gfx/inv_gren_prox");
251                         hsb_weapons[0][3] = Sbar_NewPic ("gfx/inv_prox_gren");
252                         hsb_weapons[0][4] = Sbar_NewPic ("gfx/inv_prox");
253         
254                         hsb_weapons[1][0] = Sbar_NewPic ("gfx/inv2_laser");
255                         hsb_weapons[1][1] = Sbar_NewPic ("gfx/inv2_mjolnir");
256                         hsb_weapons[1][2] = Sbar_NewPic ("gfx/inv2_gren_prox");
257                         hsb_weapons[1][3] = Sbar_NewPic ("gfx/inv2_prox_gren");
258                         hsb_weapons[1][4] = Sbar_NewPic ("gfx/inv2_prox");
259         
260                         for (i = 0;i < 5;i++)
261                         {
262                                 hsb_weapons[2+i][0] = Sbar_NewPic (va("gfx/inva%i_laser",i+1));
263                                 hsb_weapons[2+i][1] = Sbar_NewPic (va("gfx/inva%i_mjolnir",i+1));
264                                 hsb_weapons[2+i][2] = Sbar_NewPic (va("gfx/inva%i_gren_prox",i+1));
265                                 hsb_weapons[2+i][3] = Sbar_NewPic (va("gfx/inva%i_prox_gren",i+1));
266                                 hsb_weapons[2+i][4] = Sbar_NewPic (va("gfx/inva%i_prox",i+1));
267                         }
268         
269                         hsb_items[0] = Sbar_NewPic ("gfx/sb_wsuit");
270                         hsb_items[1] = Sbar_NewPic ("gfx/sb_eshld");
271                 }
272                 else if (gamemode == GAME_ROGUE)
273                 {
274                         rsb_invbar[0] = Sbar_NewPic ("gfx/r_invbar1");
275                         rsb_invbar[1] = Sbar_NewPic ("gfx/r_invbar2");
276         
277                         rsb_weapons[0] = Sbar_NewPic ("gfx/r_lava");
278                         rsb_weapons[1] = Sbar_NewPic ("gfx/r_superlava");
279                         rsb_weapons[2] = Sbar_NewPic ("gfx/r_gren");
280                         rsb_weapons[3] = Sbar_NewPic ("gfx/r_multirock");
281                         rsb_weapons[4] = Sbar_NewPic ("gfx/r_plasma");
282         
283                         rsb_items[0] = Sbar_NewPic ("gfx/r_shield1");
284                         rsb_items[1] = Sbar_NewPic ("gfx/r_agrav1");
285         
286         // PGM 01/19/97 - team color border
287                         rsb_teambord = Sbar_NewPic ("gfx/r_teambord");
288         // PGM 01/19/97 - team color border
289         
290                         rsb_ammo[0] = Sbar_NewPic ("gfx/r_ammolava");
291                         rsb_ammo[1] = Sbar_NewPic ("gfx/r_ammomulti");
292                         rsb_ammo[2] = Sbar_NewPic ("gfx/r_ammoplasma");
293                 }
294         }
295 }
296
297 void sbar_shutdown(void)
298 {
299 }
300
301 void sbar_newmap(void)
302 {
303 }
304
305 void Sbar_Init (void)
306 {
307         Cmd_AddCommand ("+showscores", Sbar_ShowScores);
308         Cmd_AddCommand ("-showscores", Sbar_DontShowScores);
309         Cvar_RegisterVariable (&showfps);
310         Cvar_RegisterVariable (&sbar_alpha);
311
312         R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
313 }
314
315
316 //=============================================================================
317
318 // drawing routines are relative to the status bar location
319
320 int sbar_x, sbar_y;
321
322 /*
323 =============
324 Sbar_DrawPic
325 =============
326 */
327 void Sbar_DrawPic (int x, int y, sbarpic_t *sbarpic)
328 {
329         DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, sbar_alpha.value, 0);
330 }
331
332 void Sbar_DrawAlphaPic (int x, int y, sbarpic_t *sbarpic, float alpha)
333 {
334         DrawQ_Pic (sbar_x + x, sbar_y + y, sbarpic->name, 0, 0, 1, 1, 1, alpha * sbar_alpha.value, 0);
335 }
336
337 /*
338 ================
339 Sbar_DrawCharacter
340
341 Draws one solid graphics character
342 ================
343 */
344 void Sbar_DrawCharacter (int x, int y, int num)
345 {
346         DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha.value, 0);
347 }
348
349 /*
350 ================
351 Sbar_DrawString
352 ================
353 */
354 void Sbar_DrawString (int x, int y, char *str)
355 {
356         DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha.value, 0);
357 }
358
359 /*
360 =============
361 Sbar_DrawNum
362 =============
363 */
364 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
365 {
366         char str[32], *ptr;
367         int l, frame;
368
369         l = sprintf(str, "%i", num);
370         ptr = str;
371         if (l > digits)
372                 ptr += (l-digits);
373         if (l < digits)
374                 x += (digits-l)*24;
375
376         while (*ptr)
377         {
378                 if (*ptr == '-')
379                         frame = STAT_MINUS;
380                 else
381                         frame = *ptr -'0';
382
383                 Sbar_DrawPic (x, y, sb_nums[color][frame]);
384                 x += 24;
385
386                 ptr++;
387         }
388 }
389
390 /*
391 =============
392 Sbar_DrawXNum
393 =============
394 */
395
396 void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
397 {
398         char str[32], *ptr;
399         int l, frame;
400
401         l = sprintf(str, "%i", num);
402         ptr = str;
403         if (l > digits)
404                 ptr += (l-digits);
405         if (l < digits)
406                 x += (digits-l) * lettersize;
407
408         while (*ptr)
409         {
410                 if (*ptr == '-')
411                         frame = STAT_MINUS;
412                 else
413                         frame = *ptr -'0';
414
415                 DrawQ_Pic (sbar_x + x, sbar_y + y, sb_nums[0][frame]->name,lettersize,lettersize,r,g,b,a * sbar_alpha.value,flags);
416                 x += lettersize;
417
418                 ptr++;
419         }
420 }
421
422 //=============================================================================
423
424
425 /*
426 ===============
427 Sbar_SortFrags
428 ===============
429 */
430 static int fragsort[MAX_SCOREBOARD];
431 static int scoreboardlines;
432 void Sbar_SortFrags (void)
433 {
434         int             i, j, k;
435
436 // sort by frags
437         scoreboardlines = 0;
438         for (i=0 ; i<cl.maxclients ; i++)
439         {
440                 if (cl.scores[i].name[0])
441                 {
442                         fragsort[scoreboardlines] = i;
443                         scoreboardlines++;
444                 }
445         }
446
447         for (i=0 ; i<scoreboardlines ; i++)
448                 for (j=0 ; j<scoreboardlines-1-i ; j++)
449                         if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
450                         {
451                                 k = fragsort[j];
452                                 fragsort[j] = fragsort[j+1];
453                                 fragsort[j+1] = k;
454                         }
455 }
456
457 /*
458 ===============
459 Sbar_SoloScoreboard
460 ===============
461 */
462 void Sbar_SoloScoreboard (void)
463 {
464         char    str[80];
465         int             minutes, seconds, tens, units;
466         int             l;
467
468         sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
469         Sbar_DrawString (8, 4, str);
470
471         sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
472         Sbar_DrawString (8, 12, str);
473
474 // time
475         minutes = cl.time / 60;
476         seconds = cl.time - 60*minutes;
477         tens = seconds / 10;
478         units = seconds - 10*tens;
479         sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
480         Sbar_DrawString (184, 4, str);
481
482 // draw level name
483         l = strlen (cl.levelname);
484         Sbar_DrawString (232 - l*4, 12, cl.levelname);
485 }
486
487 /*
488 ===============
489 Sbar_DrawScoreboard
490 ===============
491 */
492 void Sbar_DrawScoreboard (void)
493 {
494         Sbar_SoloScoreboard ();
495         if (cl.gametype == GAME_DEATHMATCH)
496                 Sbar_DeathmatchOverlay ();
497 }
498
499 //=============================================================================
500
501 // AK to make DrawInventory smaller
502 static void Sbar_DrawWeapon(int nr, float fade, int active)
503 {
504         // width = 300, height = 100
505         const int w_width = 300, w_height = 100, w_space = 10, font_size = 10;
506         const float w_scale = 0.4;
507
508         DrawQ_Pic(vid.conwidth - (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.value, DRAWFLAG_ADDITIVE);
509         DrawQ_String(vid.conwidth - (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);
510
511         if (active)
512                 DrawQ_Fill(vid.conwidth - (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.value, DRAWFLAG_ADDITIVE);
513 }
514
515 /*
516 ===============
517 Sbar_DrawInventory
518 ===============
519 */
520 void Sbar_DrawInventory (void)
521 {
522         int i;
523         char num[6];
524         float time;
525         int flashon;
526
527         if (gamemode == GAME_ROGUE)
528         {
529                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
530                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], 0.4);
531                 else
532                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], 0.4);
533         }
534         else
535                 Sbar_DrawAlphaPic (0, -24, sb_ibar, 0.4);
536
537         // weapons
538         for (i=0 ; i<7 ; i++)
539         {
540                 if (cl.items & (IT_SHOTGUN<<i) )
541                 {
542                         time = cl.item_gettime[i];
543                         flashon = (int)((cl.time - time)*10);
544                         if (flashon >= 10)
545                         {
546                                 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i)  )
547                                         flashon = 1;
548                                 else
549                                         flashon = 0;
550                         }
551                         else
552                                 flashon = (flashon%5) + 2;
553
554                         Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], 0.4);
555                 }
556         }
557
558         // MED 01/04/97
559         // hipnotic weapons
560         if (gamemode == GAME_HIPNOTIC)
561         {
562                 int grenadeflashing=0;
563                 for (i=0 ; i<4 ; i++)
564                 {
565                         if (cl.items & (1<<hipweapons[i]) )
566                         {
567                                 time = cl.item_gettime[hipweapons[i]];
568                                 flashon = (int)((cl.time - time)*10);
569                                 if (flashon >= 10)
570                                 {
571                                         if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i])  )
572                                                 flashon = 1;
573                                         else
574                                                 flashon = 0;
575                                 }
576                                 else
577                                         flashon = (flashon%5) + 2;
578
579                                 // check grenade launcher
580                                 if (i==2)
581                                 {
582                                         if (cl.items & HIT_PROXIMITY_GUN)
583                                         {
584                                                 if (flashon)
585                                                 {
586                                                         grenadeflashing = 1;
587                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
588                                                 }
589                                         }
590                                 }
591                                 else if (i==3)
592                                 {
593                                         if (cl.items & (IT_SHOTGUN<<4))
594                                         {
595                                                 if (!grenadeflashing)
596                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
597                                         }
598                                         else
599                                                 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
600                                 }
601                                 else
602                                         Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
603                         }
604                 }
605         }
606
607         if (gamemode == GAME_ROGUE)
608         {
609                 // check for powered up weapon.
610                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
611                         for (i=0;i<5;i++)
612                                 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
613                                         Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
614         }
615
616         // ammo counts
617         for (i=0 ; i<4 ; i++)
618         {
619                 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
620                 if (num[0] != ' ')
621                         Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
622                 if (num[1] != ' ')
623                         Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
624                 if (num[2] != ' ')
625                         Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
626         }
627
628         // items
629         for (i=0 ; i<6 ; i++)
630                 if (cl.items & (1<<(17+i)))
631                 {
632                         //MED 01/04/97 changed keys
633                         if (gamemode != GAME_HIPNOTIC || (i>1))
634                                 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
635                 }
636
637         //MED 01/04/97 added hipnotic items
638         // hipnotic items
639         if (gamemode == GAME_HIPNOTIC)
640         {
641                 for (i=0 ; i<2 ; i++)
642                         if (cl.items & (1<<(24+i)))
643                                 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
644         }
645
646         if (gamemode == GAME_ROGUE)
647         {
648                 // new rogue items
649                 for (i=0 ; i<2 ; i++)
650                         if (cl.items & (1<<(29+i)))
651                                 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
652         }
653         else
654         {
655                 // sigils
656                 for (i=0 ; i<4 ; i++)
657                         if (cl.items & (1<<(28+i)))
658                                 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
659         }
660 }
661
662 //=============================================================================
663
664 /*
665 ===============
666 Sbar_DrawFrags
667 ===============
668 */
669 void Sbar_DrawFrags (void)
670 {
671         int i, k, l, x, f;
672         char num[12];
673         scoreboard_t *s;
674         qbyte *c;
675
676         Sbar_SortFrags ();
677
678         // draw the text
679         l = scoreboardlines <= 4 ? scoreboardlines : 4;
680
681         x = 23 * 8;
682
683         for (i = 0;i < l;i++)
684         {
685                 k = fragsort[i];
686                 s = &cl.scores[k];
687                 if (!s->name[0])
688                         continue;
689
690                 // draw background
691                 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
692                 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.value, 0);
693                 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
694                 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.value, 0);
695
696                 // draw number
697                 f = s->frags;
698                 sprintf (num, "%3i",f);
699
700                 Sbar_DrawCharacter (x +  8, -24, num[0]);
701                 Sbar_DrawCharacter (x + 16, -24, num[1]);
702                 Sbar_DrawCharacter (x + 24, -24, num[2]);
703
704                 if (k == cl.viewentity - 1)
705                 {
706                         Sbar_DrawCharacter ( x      + 2, -24, 16);
707                         Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
708                 }
709                 x += 32;
710         }
711 }
712
713 //=============================================================================
714
715
716 /*
717 ===============
718 Sbar_DrawFace
719 ===============
720 */
721 void Sbar_DrawFace (void)
722 {
723         int f;
724
725 // PGM 01/19/97 - team color drawing
726 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
727         if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
728         {
729                 char num[12];
730                 scoreboard_t *s;
731                 qbyte *c;
732
733                 s = &cl.scores[cl.viewentity - 1];
734                 // draw background
735                 Sbar_DrawPic (112, 0, rsb_teambord);
736                 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
737                 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) * sbar_alpha.value, 0);
738                 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
739                 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) * sbar_alpha.value, 0);
740
741                 // draw number
742                 f = s->frags;
743                 sprintf (num, "%3i",f);
744
745                 if ((s->colors & 0xf0)==0)
746                 {
747                         if (num[0] != ' ')
748                                 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
749                         if (num[1] != ' ')
750                                 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
751                         if (num[2] != ' ')
752                                 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
753                 }
754                 else
755                 {
756                         Sbar_DrawCharacter ( 109, 3, num[0]);
757                         Sbar_DrawCharacter ( 116, 3, num[1]);
758                         Sbar_DrawCharacter ( 123, 3, num[2]);
759                 }
760
761                 return;
762         }
763 // PGM 01/19/97 - team color drawing
764
765         if ( (cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
766                 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
767         else if (cl.items & IT_QUAD)
768                 Sbar_DrawPic (112, 0, sb_face_quad );
769         else if (cl.items & IT_INVISIBILITY)
770                 Sbar_DrawPic (112, 0, sb_face_invis );
771         else if (cl.items & IT_INVULNERABILITY)
772                 Sbar_DrawPic (112, 0, sb_face_invuln);
773         else
774         {
775                 f = cl.stats[STAT_HEALTH] / 20;
776                 f = bound(0, f, 4);
777                 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
778         }
779 }
780
781 void Sbar_ShowFPS(void)
782 {
783         if (showfps.integer)
784         {
785                 int calc;
786                 char temp[32];
787                 float fps_x, fps_y, fps_scalex, fps_scaley;
788                 if (showfps.integer > 1)
789                 {
790                         static double currtime, frametimes[32];
791                         double newtime, total;
792                         int count, i;
793                         static int framecycle = 0;
794
795                         newtime = Sys_DoubleTime();
796                         frametimes[framecycle] = newtime - currtime;
797                         total = 0;
798                         count = 0;
799                         while(total < 0.2 && count < 32 && frametimes[i = (framecycle - count) & 31])
800                         {
801                                 total += frametimes[i];
802                                 count++;
803                         }
804                         framecycle++;
805                         framecycle &= 31;
806                         if (showfps.integer == 2)
807                                 calc = (int) (((double) count / total) + 0.5);
808                         else // showfps 3, rapid update
809                                 calc = (int) ((1.0 / (newtime - currtime)) + 0.5);
810                         currtime = newtime;
811                 }
812                 else
813                 {
814                         static double nexttime = 0, lasttime = 0;
815                         static int framerate = 0, framecount = 0;
816                         double newtime;
817                         newtime = Sys_DoubleTime();
818                         if (newtime < nexttime)
819                                 framecount++;
820                         else
821                         {
822                                 framerate = (int) (framecount / (newtime - lasttime) + 0.5);
823                                 lasttime = newtime;
824                                 nexttime = lasttime + 0.2;
825                                 framecount = 1;
826                         }
827                         calc = framerate;
828                 }
829                 sprintf(temp, "%4i", calc);
830                 fps_scalex = 12;
831                 fps_scaley = 12;
832                 fps_x = vid.conwidth - (fps_scalex * strlen(temp));
833                 fps_y = vid.conheight - sb_lines/* - 8*/; // yes this might draw over the sbar
834                 if (fps_y > vid.conheight - fps_scaley)
835                         fps_y = vid.conheight - fps_scaley;
836                 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(temp), fps_scaley, 0, 0, 0, 0.5 * sbar_alpha.value, 0);
837                 DrawQ_String(fps_x, fps_y, temp, 0, fps_scalex, fps_scaley, 1, 1, 1, 1 * sbar_alpha.value, 0);
838         }
839 }
840
841 /*
842 ===============
843 Sbar_Draw
844 ===============
845 */
846 void Sbar_Draw (void)
847 {
848         if (scr_con_current == vid.conheight)
849                 return;         // console is full screen
850
851         if (cl.intermission == 1)
852         {
853                 Sbar_IntermissionOverlay();
854                 return;
855         }
856         else if (cl.intermission == 2)
857         {
858                 Sbar_FinaleOverlay();
859                 return;
860         }
861
862         if (gamemode == GAME_SOM)
863         {
864                 if (sb_showscores || cl.stats[STAT_HEALTH] <= 0)
865                         Sbar_DrawScoreboard ();
866                 else if (sb_lines)
867                 {
868                         // this is the top left of the sbar area
869                         sbar_x = 0;
870                         sbar_y = vid.conheight - 24*3;
871
872                         // armor
873                         if (cl.stats[STAT_ARMOR])
874                         {
875                                 if (cl.items & IT_ARMOR3)
876                                         Sbar_DrawPic(0, 0, somsb_armor[2]);
877                                 else if (cl.items & IT_ARMOR2)
878                                         Sbar_DrawPic(0, 0, somsb_armor[1]);
879                                 else if (cl.items & IT_ARMOR1)
880                                         Sbar_DrawPic(0, 0, somsb_armor[0]);
881                                 Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
882                         }
883
884                         // health
885                         Sbar_DrawPic(0, 24, somsb_health);
886                         Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
887
888                         // ammo icon
889                         if (cl.items & IT_SHELLS)
890                                 Sbar_DrawPic(0, 48, somsb_ammo[0]);
891                         else if (cl.items & IT_NAILS)
892                                 Sbar_DrawPic(0, 48, somsb_ammo[1]);
893                         else if (cl.items & IT_ROCKETS)
894                                 Sbar_DrawPic(0, 48, somsb_ammo[2]);
895                         else if (cl.items & IT_CELLS)
896                                 Sbar_DrawPic(0, 48, somsb_ammo[3]);
897                         Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
898                         if (cl.stats[STAT_SHELLS])
899                                 Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
900                 }
901         }
902         else if (gamemode == GAME_NEXUIZ)
903         {
904                 sbar_y = vid.conheight - 47;
905                 sbar_x = (vid.conwidth - 640)/2;
906
907                 if (sb_lines)
908                 {
909                         int i;
910                         double time;
911                         float fade;
912                         // we have a max time 2s (min time = 0)
913                         if ((time = cl.time - cl.weapontime) < 2)
914                         {
915                                 fade = (1.0 - 0.5 * time);
916                                 fade *= fade;
917                                 for (i = 0; i < 8;i++)
918                                 {
919                                         if (!(cl.items & (1 << i)))
920                                                 continue;
921                                         Sbar_DrawWeapon(i + 1, fade, (i == cl.stats[STAT_ACTIVEWEAPON]));
922                                 }
923                         
924                                 if((cl.items & (1<<12)))
925                                         Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 12));
926                         }
927                         if (!cl.islocalgame)
928                                 Sbar_DrawFrags ();
929                 }
930
931                 if (sb_showscores || cl.stats[STAT_HEALTH] <= 0)
932                 {
933                         Sbar_DrawAlphaPic (0, 0, sb_scorebar, 0.4);
934                         Sbar_DrawScoreboard ();
935                 }
936                 else if (sb_lines)
937                 {
938                         Sbar_DrawPic (0, 0, sb_sbar);
939
940                         // special items
941                         if (cl.items & IT_INVULNERABILITY)
942                         {
943                                 Sbar_DrawNum (36, 0, 666, 3, 1);
944                                 Sbar_DrawPic (0, 0, sb_disc);
945                         }
946
947                         // armor
948                         Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
949
950                         // health
951                         if(cl.stats[STAT_HEALTH] > 100)
952                                 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
953                         else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
954                                 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
955                         else
956                                 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
957
958                         // AK dont draw ammo for the laser
959                         if(cl.stats[STAT_ACTIVEWEAPON] != 12)
960                         {
961                                 if (cl.items & NEX_IT_SHELLS)
962                                         Sbar_DrawPic (519, 0, sb_ammo[0]);
963                                 else if (cl.items & NEX_IT_BULLETS)
964                                         Sbar_DrawPic (519, 0, sb_ammo[1]);
965                                 else if (cl.items & NEX_IT_ROCKETS)
966                                         Sbar_DrawPic (519, 0, sb_ammo[2]);
967                                 else if (cl.items & NEX_IT_CELLS)
968                                         Sbar_DrawPic (519, 0, sb_ammo[3]);
969
970                                 if(cl.stats[STAT_AMMO] <= 10)
971                                         Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
972                                 else
973                                         Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
974
975                         }
976
977                         DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay->name,0,0,1,1,1,1,DRAWFLAG_MODULATE);
978                 }
979
980                 if (vid.conwidth > 320 && cl.gametype == GAME_DEATHMATCH)
981                         Sbar_MiniDeathmatchOverlay (0, 0);
982         }
983         else // Quake and others
984         {
985                 sbar_y = vid.conheight - SBAR_HEIGHT;
986                 if (cl.gametype == GAME_DEATHMATCH)
987                         sbar_x = 0;
988                 else
989                         sbar_x = (vid.conwidth - 320)/2;
990
991                 if (sb_lines > 24)
992                 {
993                         if (gamemode != GAME_GOODVSBAD2)
994                                 Sbar_DrawInventory ();
995                         if (!cl.islocalgame)
996                                 Sbar_DrawFrags ();
997                 }
998
999                 if (sb_showscores || cl.stats[STAT_HEALTH] <= 0)
1000                 {
1001                         if (gamemode != GAME_GOODVSBAD2)
1002                                 Sbar_DrawAlphaPic (0, 0, sb_scorebar, 0.4);
1003                         Sbar_DrawScoreboard ();
1004                 }
1005                 else if (sb_lines)
1006                 {
1007                         Sbar_DrawAlphaPic (0, 0, sb_sbar, 0.4);
1008
1009                         // keys (hipnotic only)
1010                         //MED 01/04/97 moved keys here so they would not be overwritten
1011                         if (gamemode == GAME_HIPNOTIC)
1012                         {
1013                                 if (cl.items & IT_KEY1)
1014                                         Sbar_DrawPic (209, 3, sb_items[0]);
1015                                 if (cl.items & IT_KEY2)
1016                                         Sbar_DrawPic (209, 12, sb_items[1]);
1017                         }
1018                         // armor
1019                         if (gamemode != GAME_GOODVSBAD2)
1020                         {
1021                                 if (cl.items & IT_INVULNERABILITY)
1022                                 {
1023                                         Sbar_DrawNum (24, 0, 666, 3, 1);
1024                                         Sbar_DrawPic (0, 0, sb_disc);
1025                                 }
1026                                 else
1027                                 {
1028                                         if (gamemode == GAME_ROGUE)
1029                                         {
1030                                                 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1031                                                 if (cl.items & RIT_ARMOR3)
1032                                                         Sbar_DrawPic (0, 0, sb_armor[2]);
1033                                                 else if (cl.items & RIT_ARMOR2)
1034                                                         Sbar_DrawPic (0, 0, sb_armor[1]);
1035                                                 else if (cl.items & RIT_ARMOR1)
1036                                                         Sbar_DrawPic (0, 0, sb_armor[0]);
1037                                         }
1038                                         else
1039                                         {
1040                                                 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1041                                                 if (cl.items & IT_ARMOR3)
1042                                                         Sbar_DrawPic (0, 0, sb_armor[2]);
1043                                                 else if (cl.items & IT_ARMOR2)
1044                                                         Sbar_DrawPic (0, 0, sb_armor[1]);
1045                                                 else if (cl.items & IT_ARMOR1)
1046                                                         Sbar_DrawPic (0, 0, sb_armor[0]);
1047                                         }
1048                                 }
1049                         }
1050
1051                         // face
1052                         Sbar_DrawFace ();
1053
1054                         // health
1055                         Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1056
1057                         // ammo icon
1058                         if (gamemode == GAME_ROGUE)
1059                         {
1060                                 if (cl.items & RIT_SHELLS)
1061                                         Sbar_DrawPic (224, 0, sb_ammo[0]);
1062                                 else if (cl.items & RIT_NAILS)
1063                                         Sbar_DrawPic (224, 0, sb_ammo[1]);
1064                                 else if (cl.items & RIT_ROCKETS)
1065                                         Sbar_DrawPic (224, 0, sb_ammo[2]);
1066                                 else if (cl.items & RIT_CELLS)
1067                                         Sbar_DrawPic (224, 0, sb_ammo[3]);
1068                                 else if (cl.items & RIT_LAVA_NAILS)
1069                                         Sbar_DrawPic (224, 0, rsb_ammo[0]);
1070                                 else if (cl.items & RIT_PLASMA_AMMO)
1071                                         Sbar_DrawPic (224, 0, rsb_ammo[1]);
1072                                 else if (cl.items & RIT_MULTI_ROCKETS)
1073                                         Sbar_DrawPic (224, 0, rsb_ammo[2]);
1074                         }
1075                         else
1076                         {
1077                                 if (cl.items & IT_SHELLS)
1078                                         Sbar_DrawPic (224, 0, sb_ammo[0]);
1079                                 else if (cl.items & IT_NAILS)
1080                                         Sbar_DrawPic (224, 0, sb_ammo[1]);
1081                                 else if (cl.items & IT_ROCKETS)
1082                                         Sbar_DrawPic (224, 0, sb_ammo[2]);
1083                                 else if (cl.items & IT_CELLS)
1084                                         Sbar_DrawPic (224, 0, sb_ammo[3]);
1085                         }
1086
1087                         Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1088
1089                 }
1090
1091                 if (vid.conwidth > 320 && cl.gametype == GAME_DEATHMATCH)
1092                         Sbar_MiniDeathmatchOverlay (324, vid.conheight - sb_lines);
1093         }
1094
1095         Sbar_ShowFPS();
1096
1097         R_Draw2DCrosshair();
1098 }
1099
1100 //=============================================================================
1101
1102 /*
1103 ==================
1104 Sbar_DeathmatchOverlay
1105
1106 ==================
1107 */
1108 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1109 {
1110         qbyte *c;
1111         if (s->name[0] || s->frags || s->colors || (s - cl.scores) == cl.playerentity - 1)
1112         {
1113                 // draw colors behind score
1114                 c = (qbyte *)&palette_complete[(s->colors & 0xf0) + 8];
1115                 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.value, 0);
1116                 c = (qbyte *)&palette_complete[((s->colors & 15)<<4) + 8];
1117                 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.value, 0);
1118                 // print the text
1119                 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.value, 0);
1120                 return 8;
1121         }
1122         else
1123                 return 0;
1124 }
1125
1126 void Sbar_DeathmatchOverlay (void)
1127 {
1128         int i, x, y;
1129         cachepic_t *pic;
1130
1131         pic = Draw_CachePic ("gfx/ranking.lmp");
1132         DrawQ_Pic ((vid.conwidth - pic->width)/2, 8, "gfx/ranking.lmp", 0, 0, 1, 1, 1, 1 * sbar_alpha.value, 0);
1133
1134         // scores
1135         Sbar_SortFrags ();
1136         // draw the text
1137         x = (vid.conwidth - (6 + 15) * 8) / 2;
1138         y = 40;
1139         for (i = 0;i < scoreboardlines && y < vid.conheight;i++)
1140                 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1141 }
1142
1143 /*
1144 ==================
1145 Sbar_DeathmatchOverlay
1146
1147 ==================
1148 */
1149 void Sbar_MiniDeathmatchOverlay (int x, int y)
1150 {
1151         int i, numlines;
1152
1153         // decide where to print
1154
1155         numlines = (vid.conheight - y) / 8;
1156         // give up if there isn't room
1157         if (x + (6 + 15) * 8 > vid.conwidth || numlines < 1)
1158                 return;
1159
1160         // scores
1161         Sbar_SortFrags ();
1162
1163         //find us
1164         for (i = 0; i < scoreboardlines; i++)
1165                 if (fragsort[i] == cl.playerentity - 1)
1166                         break;
1167
1168         if (i == scoreboardlines) // we're not there
1169                 i = 0;
1170         else // figure out start
1171         {
1172                 i -= numlines/2;
1173                 i = bound(0, i, scoreboardlines - numlines);
1174         }
1175
1176         for (;i < scoreboardlines && y < vid.conheight;i++)
1177                 y += Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1178 }
1179
1180 /*
1181 ==================
1182 Sbar_IntermissionOverlay
1183
1184 ==================
1185 */
1186 void Sbar_IntermissionOverlay (void)
1187 {
1188         int             dig;
1189         int             num;
1190
1191         if (cl.gametype == GAME_DEATHMATCH)
1192         {
1193                 Sbar_DeathmatchOverlay ();
1194                 return;
1195         }
1196
1197         sbar_x = (vid.conwidth - 320) >> 1;
1198         sbar_y = (vid.conheight - 200) >> 1;
1199
1200         DrawQ_Pic (sbar_x + 64, sbar_y + 24, "gfx/complete.lmp", 0, 0, 1, 1, 1, 1 * sbar_alpha.value, 0);
1201         DrawQ_Pic (sbar_x + 0, sbar_y + 56, "gfx/inter.lmp", 0, 0, 1, 1, 1, 1 * sbar_alpha.value, 0);
1202
1203 // time
1204         dig = cl.completed_time/60;
1205         Sbar_DrawNum (160, 64, dig, 3, 0);
1206         num = cl.completed_time - dig*60;
1207         Sbar_DrawPic (234,64,sb_colon);
1208         Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1209         Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1210
1211         Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1212         Sbar_DrawPic (232, 104, sb_slash);
1213         Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1214
1215         Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1216         Sbar_DrawPic (232, 144, sb_slash);
1217         Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1218
1219 }
1220
1221
1222 /*
1223 ==================
1224 Sbar_FinaleOverlay
1225
1226 ==================
1227 */
1228 void Sbar_FinaleOverlay (void)
1229 {
1230         cachepic_t      *pic;
1231
1232         pic = Draw_CachePic ("gfx/finale.lmp");
1233         DrawQ_Pic((vid.conwidth - pic->width)/2, 16, "gfx/finale.lmp", 0, 0, 1, 1, 1, 1 * sbar_alpha.value, 0);
1234 }
1235