]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sbar.c
Rollback last change which was meant to be many smaller pieces.
[xonotic/darkplaces.git] / sbar.c
diff --git a/sbar.c b/sbar.c
index 6398a7a625439a43d868e0ac2d84fa8137f735c3..9cc3b870fb8bb4e432875b29fb50eca821a84aed 100644 (file)
--- a/sbar.c
+++ b/sbar.c
@@ -20,6 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // sbar.c -- status bar code
 
 #include "quakedef.h"
+#include <time.h>
+#include "cl_collision.h"
+#include "csprogs.h"
 
 cachepic_t *sb_disc;
 
@@ -43,6 +46,7 @@ cachepic_t *sb_items[32];
 // 0-4 are based on health (in 20 increments)
 // 0 is static, 1 is temporary animation
 cachepic_t *sb_faces[5][2];
+cachepic_t *sb_health; // GAME_NEXUIZ
 
 cachepic_t *sb_face_invis;
 cachepic_t *sb_face_quad;
@@ -66,11 +70,6 @@ int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BI
 //MED 01/04/97 added hipnotic items array
 cachepic_t *hsb_items[2];
 
-//GAME_SOM stuff:
-cachepic_t *somsb_health;
-cachepic_t *somsb_ammo[4];
-cachepic_t *somsb_armor[3];
-
 cachepic_t *zymsb_crosshair_center;
 cachepic_t *zymsb_crosshair_line;
 cachepic_t *zymsb_crosshair_health;
@@ -87,12 +86,24 @@ cachepic_t *sb_inter;
 cachepic_t *sb_finale;
 
 cvar_t showfps = {CVAR_SAVE, "showfps", "0", "shows your rendered fps (frames per second)"};
+cvar_t showsound = {CVAR_SAVE, "showsound", "0", "shows number of active sound sources, sound latency, and other statistics"};
+cvar_t showblur = {CVAR_SAVE, "showblur", "0", "shows the current alpha level of motionblur"};
+cvar_t showspeed = {CVAR_SAVE, "showspeed", "0", "shows your current speed (qu per second); number selects unit: 1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots"};
+cvar_t showtopspeed = {CVAR_SAVE, "showtopspeed", "0", "shows your top speed (kept on screen for max 3 seconds); value -1 takes over the unit from showspeed, otherwise it's an unit number just like in showspeed"};
 cvar_t showtime = {CVAR_SAVE, "showtime", "0", "shows current time of day (useful on screenshots)"};
 cvar_t showtime_format = {CVAR_SAVE, "showtime_format", "%H:%M:%S", "format string for time of day"};
 cvar_t showdate = {CVAR_SAVE, "showdate", "0", "shows current date (useful on screenshots)"};
 cvar_t showdate_format = {CVAR_SAVE, "showdate_format", "%Y-%m-%d", "format string for date"};
+cvar_t showtex = {0, "showtex", "0", "shows the name of the texture on the crosshair (for map debugging)"};
 cvar_t sbar_alpha_bg = {CVAR_SAVE, "sbar_alpha_bg", "0.4", "opacity value of the statusbar background image"};
 cvar_t sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1", "opacity value of the statusbar weapon/item icons and numbers"};
+cvar_t sbar_hudselector = {CVAR_SAVE, "sbar_hudselector", "0", "selects which of the builtin hud layouts to use (meaning is somewhat dependent on gamemode, so nexuiz has a very different set of hud layouts than quake for example)"};
+cvar_t sbar_scorerank = {CVAR_SAVE, "sbar_scorerank", "1", "shows an overlay for your score (or team score) and rank in the scoreboard"};
+cvar_t sbar_gametime = {CVAR_SAVE, "sbar_gametime", "1", "shows an overlay for the time left in the current match/level (or current game time if there is no timelimit set)"};
+cvar_t sbar_miniscoreboard_size = {CVAR_SAVE, "sbar_miniscoreboard_size", "-1", "sets the size of the mini deathmatch overlay in items, or disables it when set to 0, or sets it to a sane default when set to -1"};
+cvar_t sbar_flagstatus_right = {CVAR_SAVE, "sbar_flagstatus_right", "0", "moves Nexuiz flag status icons to the right"};
+cvar_t sbar_flagstatus_pos = {CVAR_SAVE, "sbar_flagstatus_pos", "115", "pixel position of the Nexuiz flag status icons, from the bottom"};
+cvar_t sbar_info_pos = {CVAR_SAVE, "sbar_info_pos", "0", "pixel position of the info strings (such as showfps), from the bottom"};
 
 cvar_t cl_deathscoreboard = {0, "cl_deathscoreboard", "1", "shows scoreboard (+showscores) while dead"};
 
@@ -102,10 +113,11 @@ cvar_t crosshair_color_blue = {CVAR_SAVE, "crosshair_color_blue", "0", "customiz
 cvar_t crosshair_color_alpha = {CVAR_SAVE, "crosshair_color_alpha", "1", "how opaque the crosshair should be"};
 cvar_t crosshair_size = {CVAR_SAVE, "crosshair_size", "1", "adjusts size of the crosshair on the screen"};
 
-void Sbar_MiniDeathmatchOverlay (int x, int y);
-void Sbar_DeathmatchOverlay (void);
-void Sbar_IntermissionOverlay (void);
-void Sbar_FinaleOverlay (void);
+static void Sbar_MiniDeathmatchOverlay (int x, int y);
+static void Sbar_DeathmatchOverlay (void);
+static void Sbar_IntermissionOverlay (void);
+static void Sbar_FinaleOverlay (void);
+
 
 
 /*
@@ -115,11 +127,12 @@ Sbar_ShowScores
 Tab key down
 ===============
 */
-void Sbar_ShowScores (void)
+static void Sbar_ShowScores (void)
 {
        if (sb_showscores)
                return;
        sb_showscores = true;
+       CL_VM_UpdateShowingScoresState(sb_showscores);
 }
 
 /*
@@ -129,223 +142,216 @@ Sbar_DontShowScores
 Tab key up
 ===============
 */
-void Sbar_DontShowScores (void)
+static void Sbar_DontShowScores (void)
 {
        sb_showscores = false;
+       CL_VM_UpdateShowingScoresState(sb_showscores);
 }
 
-void sbar_start(void)
+static void sbar_start(void)
 {
+       char vabuf[1024];
        int i;
 
-       if (gamemode == GAME_NETHERWORLD)
-       {
-       }
-       else if (gamemode == GAME_SOM)
+       if (gamemode == GAME_DELUXEQUAKE || gamemode == GAME_BLOODOMNICIDE)
        {
-               sb_disc = Draw_CachePic("gfx/disc", true);
-
-               for (i = 0;i < 10;i++)
-                       sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
-
-               somsb_health = Draw_CachePic("gfx/hud_health", true);
-               somsb_ammo[0] = Draw_CachePic("gfx/sb_shells", true);
-               somsb_ammo[1] = Draw_CachePic("gfx/sb_nails", true);
-               somsb_ammo[2] = Draw_CachePic("gfx/sb_rocket", true);
-               somsb_ammo[3] = Draw_CachePic("gfx/sb_cells", true);
-               somsb_armor[0] = Draw_CachePic("gfx/sb_armor1", true);
-               somsb_armor[1] = Draw_CachePic("gfx/sb_armor2", true);
-               somsb_armor[2] = Draw_CachePic("gfx/sb_armor3", true);
        }
-       else if (gamemode == GAME_NEXUIZ)
+       else if (IS_OLDNEXUIZ_DERIVED(gamemode))
        {
                for (i = 0;i < 10;i++)
-                       sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
-               sb_nums[0][10] = Draw_CachePic ("gfx/num_minus", true);
-
-               sb_ammo[0] = Draw_CachePic ("gfx/sb_shells", true);
-               sb_ammo[1] = Draw_CachePic ("gfx/sb_bullets", true);
-               sb_ammo[2] = Draw_CachePic ("gfx/sb_rocket", true);
-               sb_ammo[3] = Draw_CachePic ("gfx/sb_cells", true);
-
-               sb_items[2] = Draw_CachePic ("gfx/sb_slowmo", true);
-               sb_items[3] = Draw_CachePic ("gfx/sb_invinc", true);
-               sb_items[4] = Draw_CachePic ("gfx/sb_energy", true);
-               sb_items[5] = Draw_CachePic ("gfx/sb_str", true);
-
-               sb_items[11] = Draw_CachePic ("gfx/sb_flag_red_taken", true);
-               sb_items[12] = Draw_CachePic ("gfx/sb_flag_red_lost", true);
-               sb_items[13] = Draw_CachePic ("gfx/sb_flag_red_carrying", true);
-               sb_items[14] = Draw_CachePic ("gfx/sb_key_carrying", true);
-               sb_items[15] = Draw_CachePic ("gfx/sb_flag_blue_taken", true);
-               sb_items[16] = Draw_CachePic ("gfx/sb_flag_blue_lost", true);
-               sb_items[17] = Draw_CachePic ("gfx/sb_flag_blue_carrying", true);
-
-               sb_sbar = Draw_CachePic("gfx/sbar", true);
-               sb_sbar_minimal = Draw_CachePic("gfx/sbar_minimal", true);
-               sb_sbar_overlay = Draw_CachePic("gfx/sbar_overlay", true);
+                       sb_nums[0][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/num_%i",i), CACHEPICFLAG_QUIET);
+               sb_nums[0][10] = Draw_CachePic_Flags ("gfx/num_minus", CACHEPICFLAG_QUIET);
+               sb_colon = Draw_CachePic_Flags ("gfx/num_colon", CACHEPICFLAG_QUIET);
+
+               sb_ammo[0] = Draw_CachePic_Flags ("gfx/sb_shells", CACHEPICFLAG_QUIET);
+               sb_ammo[1] = Draw_CachePic_Flags ("gfx/sb_bullets", CACHEPICFLAG_QUIET);
+               sb_ammo[2] = Draw_CachePic_Flags ("gfx/sb_rocket", CACHEPICFLAG_QUIET);
+               sb_ammo[3] = Draw_CachePic_Flags ("gfx/sb_cells", CACHEPICFLAG_QUIET);
+
+               sb_armor[0] = Draw_CachePic_Flags ("gfx/sb_armor", CACHEPICFLAG_QUIET);
+               sb_armor[1] = NULL;
+               sb_armor[2] = NULL;
+
+               sb_health = Draw_CachePic_Flags ("gfx/sb_health", CACHEPICFLAG_QUIET);
+
+               sb_items[2] = Draw_CachePic_Flags ("gfx/sb_slowmo", CACHEPICFLAG_QUIET);
+               sb_items[3] = Draw_CachePic_Flags ("gfx/sb_invinc", CACHEPICFLAG_QUIET);
+               sb_items[4] = Draw_CachePic_Flags ("gfx/sb_energy", CACHEPICFLAG_QUIET);
+               sb_items[5] = Draw_CachePic_Flags ("gfx/sb_str", CACHEPICFLAG_QUIET);
+
+               sb_items[11] = Draw_CachePic_Flags ("gfx/sb_flag_red_taken", CACHEPICFLAG_QUIET);
+               sb_items[12] = Draw_CachePic_Flags ("gfx/sb_flag_red_lost", CACHEPICFLAG_QUIET);
+               sb_items[13] = Draw_CachePic_Flags ("gfx/sb_flag_red_carrying", CACHEPICFLAG_QUIET);
+               sb_items[14] = Draw_CachePic_Flags ("gfx/sb_key_carrying", CACHEPICFLAG_QUIET);
+               sb_items[15] = Draw_CachePic_Flags ("gfx/sb_flag_blue_taken", CACHEPICFLAG_QUIET);
+               sb_items[16] = Draw_CachePic_Flags ("gfx/sb_flag_blue_lost", CACHEPICFLAG_QUIET);
+               sb_items[17] = Draw_CachePic_Flags ("gfx/sb_flag_blue_carrying", CACHEPICFLAG_QUIET);
+
+               sb_sbar = Draw_CachePic_Flags ("gfx/sbar", CACHEPICFLAG_QUIET);
+               sb_sbar_minimal = Draw_CachePic_Flags ("gfx/sbar_minimal", CACHEPICFLAG_QUIET);
+               sb_sbar_overlay = Draw_CachePic_Flags ("gfx/sbar_overlay", CACHEPICFLAG_QUIET);
 
                for(i = 0; i < 9;i++)
-                       sb_weapons[0][i] = Draw_CachePic(va("gfx/inv_weapon%i",i), true);
+                       sb_weapons[0][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inv_weapon%i",i), CACHEPICFLAG_QUIET);
        }
        else if (gamemode == GAME_ZYMOTIC)
        {
-               zymsb_crosshair_center = Draw_CachePic ("gfx/hud/crosshair_center", true);
-               zymsb_crosshair_line = Draw_CachePic ("gfx/hud/crosshair_line", true);
-               zymsb_crosshair_health = Draw_CachePic ("gfx/hud/crosshair_health", true);
-               zymsb_crosshair_clip = Draw_CachePic ("gfx/hud/crosshair_clip", true);
-               zymsb_crosshair_ammo = Draw_CachePic ("gfx/hud/crosshair_ammo", true);
-               zymsb_crosshair_background = Draw_CachePic ("gfx/hud/crosshair_background", true);
-               zymsb_crosshair_left1 = Draw_CachePic ("gfx/hud/crosshair_left1", true);
-               zymsb_crosshair_left2 = Draw_CachePic ("gfx/hud/crosshair_left2", true);
-               zymsb_crosshair_right = Draw_CachePic ("gfx/hud/crosshair_right", true);
+               zymsb_crosshair_center = Draw_CachePic_Flags ("gfx/hud/crosshair_center", CACHEPICFLAG_QUIET);
+               zymsb_crosshair_line = Draw_CachePic_Flags ("gfx/hud/crosshair_line", CACHEPICFLAG_QUIET);
+               zymsb_crosshair_health = Draw_CachePic_Flags ("gfx/hud/crosshair_health", CACHEPICFLAG_QUIET);
+               zymsb_crosshair_clip = Draw_CachePic_Flags ("gfx/hud/crosshair_clip", CACHEPICFLAG_QUIET);
+               zymsb_crosshair_ammo = Draw_CachePic_Flags ("gfx/hud/crosshair_ammo", CACHEPICFLAG_QUIET);
+               zymsb_crosshair_background = Draw_CachePic_Flags ("gfx/hud/crosshair_background", CACHEPICFLAG_QUIET);
+               zymsb_crosshair_left1 = Draw_CachePic_Flags ("gfx/hud/crosshair_left1", CACHEPICFLAG_QUIET);
+               zymsb_crosshair_left2 = Draw_CachePic_Flags ("gfx/hud/crosshair_left2", CACHEPICFLAG_QUIET);
+               zymsb_crosshair_right = Draw_CachePic_Flags ("gfx/hud/crosshair_right", CACHEPICFLAG_QUIET);
        }
        else
        {
-               sb_disc = Draw_CachePic("gfx/disc", true);
+               sb_disc = Draw_CachePic_Flags ("gfx/disc", CACHEPICFLAG_QUIET);
 
                for (i = 0;i < 10;i++)
                {
-                       sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
-                       sb_nums[1][i] = Draw_CachePic (va("gfx/anum_%i",i), true);
+                       sb_nums[0][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/num_%i",i), CACHEPICFLAG_QUIET);
+                       sb_nums[1][i] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/anum_%i",i), CACHEPICFLAG_QUIET);
                }
 
-               sb_nums[0][10] = Draw_CachePic ("gfx/num_minus", true);
-               sb_nums[1][10] = Draw_CachePic ("gfx/anum_minus", true);
+               sb_nums[0][10] = Draw_CachePic_Flags ("gfx/num_minus", CACHEPICFLAG_QUIET);
+               sb_nums[1][10] = Draw_CachePic_Flags ("gfx/anum_minus", CACHEPICFLAG_QUIET);
 
-               sb_colon = Draw_CachePic ("gfx/num_colon", true);
-               sb_slash = Draw_CachePic ("gfx/num_slash", true);
+               sb_colon = Draw_CachePic_Flags ("gfx/num_colon", CACHEPICFLAG_QUIET);
+               sb_slash = Draw_CachePic_Flags ("gfx/num_slash", CACHEPICFLAG_QUIET);
 
-               sb_weapons[0][0] = Draw_CachePic ("gfx/inv_shotgun", true);
-               sb_weapons[0][1] = Draw_CachePic ("gfx/inv_sshotgun", true);
-               sb_weapons[0][2] = Draw_CachePic ("gfx/inv_nailgun", true);
-               sb_weapons[0][3] = Draw_CachePic ("gfx/inv_snailgun", true);
-               sb_weapons[0][4] = Draw_CachePic ("gfx/inv_rlaunch", true);
-               sb_weapons[0][5] = Draw_CachePic ("gfx/inv_srlaunch", true);
-               sb_weapons[0][6] = Draw_CachePic ("gfx/inv_lightng", true);
+               sb_weapons[0][0] = Draw_CachePic_Flags ("gfx/inv_shotgun", CACHEPICFLAG_QUIET);
+               sb_weapons[0][1] = Draw_CachePic_Flags ("gfx/inv_sshotgun", CACHEPICFLAG_QUIET);
+               sb_weapons[0][2] = Draw_CachePic_Flags ("gfx/inv_nailgun", CACHEPICFLAG_QUIET);
+               sb_weapons[0][3] = Draw_CachePic_Flags ("gfx/inv_snailgun", CACHEPICFLAG_QUIET);
+               sb_weapons[0][4] = Draw_CachePic_Flags ("gfx/inv_rlaunch", CACHEPICFLAG_QUIET);
+               sb_weapons[0][5] = Draw_CachePic_Flags ("gfx/inv_srlaunch", CACHEPICFLAG_QUIET);
+               sb_weapons[0][6] = Draw_CachePic_Flags ("gfx/inv_lightng", CACHEPICFLAG_QUIET);
 
-               sb_weapons[1][0] = Draw_CachePic ("gfx/inv2_shotgun", true);
-               sb_weapons[1][1] = Draw_CachePic ("gfx/inv2_sshotgun", true);
-               sb_weapons[1][2] = Draw_CachePic ("gfx/inv2_nailgun", true);
-               sb_weapons[1][3] = Draw_CachePic ("gfx/inv2_snailgun", true);
-               sb_weapons[1][4] = Draw_CachePic ("gfx/inv2_rlaunch", true);
-               sb_weapons[1][5] = Draw_CachePic ("gfx/inv2_srlaunch", true);
-               sb_weapons[1][6] = Draw_CachePic ("gfx/inv2_lightng", true);
+               sb_weapons[1][0] = Draw_CachePic_Flags ("gfx/inv2_shotgun", CACHEPICFLAG_QUIET);
+               sb_weapons[1][1] = Draw_CachePic_Flags ("gfx/inv2_sshotgun", CACHEPICFLAG_QUIET);
+               sb_weapons[1][2] = Draw_CachePic_Flags ("gfx/inv2_nailgun", CACHEPICFLAG_QUIET);
+               sb_weapons[1][3] = Draw_CachePic_Flags ("gfx/inv2_snailgun", CACHEPICFLAG_QUIET);
+               sb_weapons[1][4] = Draw_CachePic_Flags ("gfx/inv2_rlaunch", CACHEPICFLAG_QUIET);
+               sb_weapons[1][5] = Draw_CachePic_Flags ("gfx/inv2_srlaunch", CACHEPICFLAG_QUIET);
+               sb_weapons[1][6] = Draw_CachePic_Flags ("gfx/inv2_lightng", CACHEPICFLAG_QUIET);
 
                for (i = 0;i < 5;i++)
                {
-                       sb_weapons[2+i][0] = Draw_CachePic (va("gfx/inva%i_shotgun",i+1), true);
-                       sb_weapons[2+i][1] = Draw_CachePic (va("gfx/inva%i_sshotgun",i+1), true);
-                       sb_weapons[2+i][2] = Draw_CachePic (va("gfx/inva%i_nailgun",i+1), true);
-                       sb_weapons[2+i][3] = Draw_CachePic (va("gfx/inva%i_snailgun",i+1), true);
-                       sb_weapons[2+i][4] = Draw_CachePic (va("gfx/inva%i_rlaunch",i+1), true);
-                       sb_weapons[2+i][5] = Draw_CachePic (va("gfx/inva%i_srlaunch",i+1), true);
-                       sb_weapons[2+i][6] = Draw_CachePic (va("gfx/inva%i_lightng",i+1), true);
+                       sb_weapons[2+i][0] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_shotgun",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][1] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_sshotgun",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][2] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_nailgun",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][3] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_snailgun",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][4] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_rlaunch",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][5] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_srlaunch",i+1), CACHEPICFLAG_QUIET);
+                       sb_weapons[2+i][6] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_lightng",i+1), CACHEPICFLAG_QUIET);
                }
 
-               sb_ammo[0] = Draw_CachePic ("gfx/sb_shells", true);
-               sb_ammo[1] = Draw_CachePic ("gfx/sb_nails", true);
-               sb_ammo[2] = Draw_CachePic ("gfx/sb_rocket", true);
-               sb_ammo[3] = Draw_CachePic ("gfx/sb_cells", true);
-
-               sb_armor[0] = Draw_CachePic ("gfx/sb_armor1", true);
-               sb_armor[1] = Draw_CachePic ("gfx/sb_armor2", true);
-               sb_armor[2] = Draw_CachePic ("gfx/sb_armor3", true);
-
-               sb_items[0] = Draw_CachePic ("gfx/sb_key1", true);
-               sb_items[1] = Draw_CachePic ("gfx/sb_key2", true);
-               sb_items[2] = Draw_CachePic ("gfx/sb_invis", true);
-               sb_items[3] = Draw_CachePic ("gfx/sb_invuln", true);
-               sb_items[4] = Draw_CachePic ("gfx/sb_suit", true);
-               sb_items[5] = Draw_CachePic ("gfx/sb_quad", true);
-
-               sb_sigil[0] = Draw_CachePic ("gfx/sb_sigil1", true);
-               sb_sigil[1] = Draw_CachePic ("gfx/sb_sigil2", true);
-               sb_sigil[2] = Draw_CachePic ("gfx/sb_sigil3", true);
-               sb_sigil[3] = Draw_CachePic ("gfx/sb_sigil4", true);
-
-               sb_faces[4][0] = Draw_CachePic ("gfx/face1", true);
-               sb_faces[4][1] = Draw_CachePic ("gfx/face_p1", true);
-               sb_faces[3][0] = Draw_CachePic ("gfx/face2", true);
-               sb_faces[3][1] = Draw_CachePic ("gfx/face_p2", true);
-               sb_faces[2][0] = Draw_CachePic ("gfx/face3", true);
-               sb_faces[2][1] = Draw_CachePic ("gfx/face_p3", true);
-               sb_faces[1][0] = Draw_CachePic ("gfx/face4", true);
-               sb_faces[1][1] = Draw_CachePic ("gfx/face_p4", true);
-               sb_faces[0][0] = Draw_CachePic ("gfx/face5", true);
-               sb_faces[0][1] = Draw_CachePic ("gfx/face_p5", true);
-
-               sb_face_invis = Draw_CachePic ("gfx/face_invis", true);
-               sb_face_invuln = Draw_CachePic ("gfx/face_invul2", true);
-               sb_face_invis_invuln = Draw_CachePic ("gfx/face_inv2", true);
-               sb_face_quad = Draw_CachePic ("gfx/face_quad", true);
-
-               sb_sbar = Draw_CachePic ("gfx/sbar", true);
-               sb_ibar = Draw_CachePic ("gfx/ibar", true);
-               sb_scorebar = Draw_CachePic ("gfx/scorebar", true);
+               sb_ammo[0] = Draw_CachePic_Flags ("gfx/sb_shells", CACHEPICFLAG_QUIET);
+               sb_ammo[1] = Draw_CachePic_Flags ("gfx/sb_nails", CACHEPICFLAG_QUIET);
+               sb_ammo[2] = Draw_CachePic_Flags ("gfx/sb_rocket", CACHEPICFLAG_QUIET);
+               sb_ammo[3] = Draw_CachePic_Flags ("gfx/sb_cells", CACHEPICFLAG_QUIET);
+
+               sb_armor[0] = Draw_CachePic_Flags ("gfx/sb_armor1", CACHEPICFLAG_QUIET);
+               sb_armor[1] = Draw_CachePic_Flags ("gfx/sb_armor2", CACHEPICFLAG_QUIET);
+               sb_armor[2] = Draw_CachePic_Flags ("gfx/sb_armor3", CACHEPICFLAG_QUIET);
+
+               sb_items[0] = Draw_CachePic_Flags ("gfx/sb_key1", CACHEPICFLAG_QUIET);
+               sb_items[1] = Draw_CachePic_Flags ("gfx/sb_key2", CACHEPICFLAG_QUIET);
+               sb_items[2] = Draw_CachePic_Flags ("gfx/sb_invis", CACHEPICFLAG_QUIET);
+               sb_items[3] = Draw_CachePic_Flags ("gfx/sb_invuln", CACHEPICFLAG_QUIET);
+               sb_items[4] = Draw_CachePic_Flags ("gfx/sb_suit", CACHEPICFLAG_QUIET);
+               sb_items[5] = Draw_CachePic_Flags ("gfx/sb_quad", CACHEPICFLAG_QUIET);
+
+               sb_sigil[0] = Draw_CachePic_Flags ("gfx/sb_sigil1", CACHEPICFLAG_QUIET);
+               sb_sigil[1] = Draw_CachePic_Flags ("gfx/sb_sigil2", CACHEPICFLAG_QUIET);
+               sb_sigil[2] = Draw_CachePic_Flags ("gfx/sb_sigil3", CACHEPICFLAG_QUIET);
+               sb_sigil[3] = Draw_CachePic_Flags ("gfx/sb_sigil4", CACHEPICFLAG_QUIET);
+
+               sb_faces[4][0] = Draw_CachePic_Flags ("gfx/face1", CACHEPICFLAG_QUIET);
+               sb_faces[4][1] = Draw_CachePic_Flags ("gfx/face_p1", CACHEPICFLAG_QUIET);
+               sb_faces[3][0] = Draw_CachePic_Flags ("gfx/face2", CACHEPICFLAG_QUIET);
+               sb_faces[3][1] = Draw_CachePic_Flags ("gfx/face_p2", CACHEPICFLAG_QUIET);
+               sb_faces[2][0] = Draw_CachePic_Flags ("gfx/face3", CACHEPICFLAG_QUIET);
+               sb_faces[2][1] = Draw_CachePic_Flags ("gfx/face_p3", CACHEPICFLAG_QUIET);
+               sb_faces[1][0] = Draw_CachePic_Flags ("gfx/face4", CACHEPICFLAG_QUIET);
+               sb_faces[1][1] = Draw_CachePic_Flags ("gfx/face_p4", CACHEPICFLAG_QUIET);
+               sb_faces[0][0] = Draw_CachePic_Flags ("gfx/face5", CACHEPICFLAG_QUIET);
+               sb_faces[0][1] = Draw_CachePic_Flags ("gfx/face_p5", CACHEPICFLAG_QUIET);
+
+               sb_face_invis = Draw_CachePic_Flags ("gfx/face_invis", CACHEPICFLAG_QUIET);
+               sb_face_invuln = Draw_CachePic_Flags ("gfx/face_invul2", CACHEPICFLAG_QUIET);
+               sb_face_invis_invuln = Draw_CachePic_Flags ("gfx/face_inv2", CACHEPICFLAG_QUIET);
+               sb_face_quad = Draw_CachePic_Flags ("gfx/face_quad", CACHEPICFLAG_QUIET);
+
+               sb_sbar = Draw_CachePic_Flags ("gfx/sbar", CACHEPICFLAG_QUIET);
+               sb_ibar = Draw_CachePic_Flags ("gfx/ibar", CACHEPICFLAG_QUIET);
+               sb_scorebar = Draw_CachePic_Flags ("gfx/scorebar", CACHEPICFLAG_QUIET);
 
        //MED 01/04/97 added new hipnotic weapons
-               if (gamemode == GAME_HIPNOTIC)
+               if (gamemode == GAME_HIPNOTIC || gamemode == GAME_QUOTH)
                {
-                       hsb_weapons[0][0] = Draw_CachePic ("gfx/inv_laser", true);
-                       hsb_weapons[0][1] = Draw_CachePic ("gfx/inv_mjolnir", true);
-                       hsb_weapons[0][2] = Draw_CachePic ("gfx/inv_gren_prox", true);
-                       hsb_weapons[0][3] = Draw_CachePic ("gfx/inv_prox_gren", true);
-                       hsb_weapons[0][4] = Draw_CachePic ("gfx/inv_prox", true);
-
-                       hsb_weapons[1][0] = Draw_CachePic ("gfx/inv2_laser", true);
-                       hsb_weapons[1][1] = Draw_CachePic ("gfx/inv2_mjolnir", true);
-                       hsb_weapons[1][2] = Draw_CachePic ("gfx/inv2_gren_prox", true);
-                       hsb_weapons[1][3] = Draw_CachePic ("gfx/inv2_prox_gren", true);
-                       hsb_weapons[1][4] = Draw_CachePic ("gfx/inv2_prox", true);
+                       hsb_weapons[0][0] = Draw_CachePic_Flags ("gfx/inv_laser", CACHEPICFLAG_QUIET);
+                       hsb_weapons[0][1] = Draw_CachePic_Flags ("gfx/inv_mjolnir", CACHEPICFLAG_QUIET);
+                       hsb_weapons[0][2] = Draw_CachePic_Flags ("gfx/inv_gren_prox", CACHEPICFLAG_QUIET);
+                       hsb_weapons[0][3] = Draw_CachePic_Flags ("gfx/inv_prox_gren", CACHEPICFLAG_QUIET);
+                       hsb_weapons[0][4] = Draw_CachePic_Flags ("gfx/inv_prox", CACHEPICFLAG_QUIET);
+
+                       hsb_weapons[1][0] = Draw_CachePic_Flags ("gfx/inv2_laser", CACHEPICFLAG_QUIET);
+                       hsb_weapons[1][1] = Draw_CachePic_Flags ("gfx/inv2_mjolnir", CACHEPICFLAG_QUIET);
+                       hsb_weapons[1][2] = Draw_CachePic_Flags ("gfx/inv2_gren_prox", CACHEPICFLAG_QUIET);
+                       hsb_weapons[1][3] = Draw_CachePic_Flags ("gfx/inv2_prox_gren", CACHEPICFLAG_QUIET);
+                       hsb_weapons[1][4] = Draw_CachePic_Flags ("gfx/inv2_prox", CACHEPICFLAG_QUIET);
 
                        for (i = 0;i < 5;i++)
                        {
-                               hsb_weapons[2+i][0] = Draw_CachePic (va("gfx/inva%i_laser",i+1), true);
-                               hsb_weapons[2+i][1] = Draw_CachePic (va("gfx/inva%i_mjolnir",i+1), true);
-                               hsb_weapons[2+i][2] = Draw_CachePic (va("gfx/inva%i_gren_prox",i+1), true);
-                               hsb_weapons[2+i][3] = Draw_CachePic (va("gfx/inva%i_prox_gren",i+1), true);
-                               hsb_weapons[2+i][4] = Draw_CachePic (va("gfx/inva%i_prox",i+1), true);
+                               hsb_weapons[2+i][0] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_laser",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][1] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_mjolnir",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][2] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_gren_prox",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][3] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_prox_gren",i+1), CACHEPICFLAG_QUIET);
+                               hsb_weapons[2+i][4] = Draw_CachePic_Flags (va(vabuf, sizeof(vabuf), "gfx/inva%i_prox",i+1), CACHEPICFLAG_QUIET);
                        }
 
-                       hsb_items[0] = Draw_CachePic ("gfx/sb_wsuit", true);
-                       hsb_items[1] = Draw_CachePic ("gfx/sb_eshld", true);
+                       hsb_items[0] = Draw_CachePic_Flags ("gfx/sb_wsuit", CACHEPICFLAG_QUIET);
+                       hsb_items[1] = Draw_CachePic_Flags ("gfx/sb_eshld", CACHEPICFLAG_QUIET);
                }
                else if (gamemode == GAME_ROGUE)
                {
-                       rsb_invbar[0] = Draw_CachePic ("gfx/r_invbar1", true);
-                       rsb_invbar[1] = Draw_CachePic ("gfx/r_invbar2", true);
+                       rsb_invbar[0] = Draw_CachePic_Flags ("gfx/r_invbar1", CACHEPICFLAG_QUIET);
+                       rsb_invbar[1] = Draw_CachePic_Flags ("gfx/r_invbar2", CACHEPICFLAG_QUIET);
 
-                       rsb_weapons[0] = Draw_CachePic ("gfx/r_lava", true);
-                       rsb_weapons[1] = Draw_CachePic ("gfx/r_superlava", true);
-                       rsb_weapons[2] = Draw_CachePic ("gfx/r_gren", true);
-                       rsb_weapons[3] = Draw_CachePic ("gfx/r_multirock", true);
-                       rsb_weapons[4] = Draw_CachePic ("gfx/r_plasma", true);
+                       rsb_weapons[0] = Draw_CachePic_Flags ("gfx/r_lava", CACHEPICFLAG_QUIET);
+                       rsb_weapons[1] = Draw_CachePic_Flags ("gfx/r_superlava", CACHEPICFLAG_QUIET);
+                       rsb_weapons[2] = Draw_CachePic_Flags ("gfx/r_gren", CACHEPICFLAG_QUIET);
+                       rsb_weapons[3] = Draw_CachePic_Flags ("gfx/r_multirock", CACHEPICFLAG_QUIET);
+                       rsb_weapons[4] = Draw_CachePic_Flags ("gfx/r_plasma", CACHEPICFLAG_QUIET);
 
-                       rsb_items[0] = Draw_CachePic ("gfx/r_shield1", true);
-                       rsb_items[1] = Draw_CachePic ("gfx/r_agrav1", true);
+                       rsb_items[0] = Draw_CachePic_Flags ("gfx/r_shield1", CACHEPICFLAG_QUIET);
+                       rsb_items[1] = Draw_CachePic_Flags ("gfx/r_agrav1", CACHEPICFLAG_QUIET);
 
        // PGM 01/19/97 - team color border
-                       rsb_teambord = Draw_CachePic ("gfx/r_teambord", true);
+                       rsb_teambord = Draw_CachePic_Flags ("gfx/r_teambord", CACHEPICFLAG_QUIET);
        // PGM 01/19/97 - team color border
 
-                       rsb_ammo[0] = Draw_CachePic ("gfx/r_ammolava", true);
-                       rsb_ammo[1] = Draw_CachePic ("gfx/r_ammomulti", true);
-                       rsb_ammo[2] = Draw_CachePic ("gfx/r_ammoplasma", true);
+                       rsb_ammo[0] = Draw_CachePic_Flags ("gfx/r_ammolava", CACHEPICFLAG_QUIET);
+                       rsb_ammo[1] = Draw_CachePic_Flags ("gfx/r_ammomulti", CACHEPICFLAG_QUIET);
+                       rsb_ammo[2] = Draw_CachePic_Flags ("gfx/r_ammoplasma", CACHEPICFLAG_QUIET);
                }
        }
 
-       sb_ranking = Draw_CachePic ("gfx/ranking", true);
-       sb_complete = Draw_CachePic ("gfx/complete", true);
-       sb_inter = Draw_CachePic ("gfx/inter", true);
-       sb_finale = Draw_CachePic ("gfx/finale", true);
+       sb_ranking = Draw_CachePic_Flags ("gfx/ranking", CACHEPICFLAG_QUIET);
+       sb_complete = Draw_CachePic_Flags ("gfx/complete", CACHEPICFLAG_QUIET);
+       sb_inter = Draw_CachePic_Flags ("gfx/inter", CACHEPICFLAG_QUIET);
+       sb_finale = Draw_CachePic_Flags ("gfx/finale", CACHEPICFLAG_QUIET);
 }
 
-void sbar_shutdown(void)
+static void sbar_shutdown(void)
 {
 }
 
-void sbar_newmap(void)
+static void sbar_newmap(void)
 {
 }
 
@@ -354,12 +360,22 @@ void Sbar_Init (void)
        Cmd_AddCommand("+showscores", Sbar_ShowScores, "show scoreboard");
        Cmd_AddCommand("-showscores", Sbar_DontShowScores, "hide scoreboard");
        Cvar_RegisterVariable(&showfps);
+       Cvar_RegisterVariable(&showsound);
+       Cvar_RegisterVariable(&showblur);
+       Cvar_RegisterVariable(&showspeed);
+       Cvar_RegisterVariable(&showtopspeed);
        Cvar_RegisterVariable(&showtime);
        Cvar_RegisterVariable(&showtime_format);
        Cvar_RegisterVariable(&showdate);
        Cvar_RegisterVariable(&showdate_format);
+       Cvar_RegisterVariable(&showtex);
        Cvar_RegisterVariable(&sbar_alpha_bg);
        Cvar_RegisterVariable(&sbar_alpha_fg);
+       Cvar_RegisterVariable(&sbar_hudselector);
+       Cvar_RegisterVariable(&sbar_scorerank);
+       Cvar_RegisterVariable(&sbar_gametime);
+       Cvar_RegisterVariable(&sbar_miniscoreboard_size);
+       Cvar_RegisterVariable(&sbar_info_pos);
        Cvar_RegisterVariable(&cl_deathscoreboard);
 
        Cvar_RegisterVariable(&crosshair_color_red);
@@ -368,7 +384,10 @@ void Sbar_Init (void)
        Cvar_RegisterVariable(&crosshair_color_alpha);
        Cvar_RegisterVariable(&crosshair_size);
 
-       R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
+       Cvar_RegisterVariable(&sbar_flagstatus_right); // (GAME_NEXUZI ONLY)
+       Cvar_RegisterVariable(&sbar_flagstatus_pos); // (GAME_NEXUIZ ONLY)
+
+       R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap, NULL, NULL);
 }
 
 
@@ -383,12 +402,17 @@ int sbar_x, sbar_y;
 Sbar_DrawPic
 =============
 */
-void Sbar_DrawPic (int x, int y, cachepic_t *pic)
+static void Sbar_DrawStretchPic (int x, int y, cachepic_t *pic, float alpha, float overridewidth, float overrideheight)
+{
+       DrawQ_Pic (sbar_x + x, sbar_y + y, pic, overridewidth, overrideheight, 1, 1, 1, alpha, 0);
+}
+
+static void Sbar_DrawPic (int x, int y, cachepic_t *pic)
 {
        DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
 }
 
-void Sbar_DrawAlphaPic (int x, int y, cachepic_t *pic, float alpha)
+static void Sbar_DrawAlphaPic (int x, int y, cachepic_t *pic, float alpha)
 {
        DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, alpha, 0);
 }
@@ -400,9 +424,10 @@ Sbar_DrawCharacter
 Draws one solid graphics character
 ================
 */
-void Sbar_DrawCharacter (int x, int y, int num)
+static void Sbar_DrawCharacter (int x, int y, int num)
 {
-       DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, true);
+       char vabuf[1024];
+       DrawQ_String (sbar_x + x + 4 , sbar_y + y, va(vabuf, sizeof(vabuf), "%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, true, FONT_SBAR);
 }
 
 /*
@@ -410,9 +435,9 @@ void Sbar_DrawCharacter (int x, int y, int num)
 Sbar_DrawString
 ================
 */
-void Sbar_DrawString (int x, int y, char *str)
+static void Sbar_DrawString (int x, int y, char *str)
 {
-       DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, true);
+       DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR);
 }
 
 /*
@@ -420,12 +445,12 @@ void Sbar_DrawString (int x, int y, char *str)
 Sbar_DrawNum
 =============
 */
-void Sbar_DrawNum (int x, int y, int num, int digits, int color)
+static void Sbar_DrawNum (int x, int y, int num, int digits, int color)
 {
        char str[32], *ptr;
        int l, frame;
 
-       l = sprintf(str, "%i", num);
+       l = dpsnprintf(str, sizeof(str), "%i", num);
        ptr = str;
        if (l > digits)
                ptr += (l-digits);
@@ -452,12 +477,18 @@ Sbar_DrawXNum
 =============
 */
 
-void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
+static void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
 {
        char str[32], *ptr;
        int l, frame;
 
-       l = sprintf(str, "%i", num);
+       if (digits < 0)
+       {
+               digits = -digits;
+               l = dpsnprintf(str, sizeof(str), "%0*i", digits, num);
+       }
+       else
+               l = dpsnprintf(str, sizeof(str), "%i", num);
        ptr = str;
        if (l > digits)
                ptr += (l-digits);
@@ -481,10 +512,10 @@ void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r,
 //=============================================================================
 
 
-int Sbar_IsTeammatch()
+static int Sbar_IsTeammatch(void)
 {
        // currently only nexuiz uses the team score board
-       return ((gamemode == GAME_NEXUIZ)
+       return (IS_OLDNEXUIZ_DERIVED(gamemode)
                && (teamplay.integer > 0));
 }
 
@@ -496,19 +527,9 @@ Sbar_SortFrags
 static int fragsort[MAX_SCOREBOARD];
 static int scoreboardlines;
 
-//[515]: Sbar_GetPlayer for csqc "getplayerkey" func
-int Sbar_GetPlayer (int index)
+int Sbar_GetSortedPlayerIndex (int index)
 {
-       if(index < 0)
-       {
-               index = -1-index;
-               if(index >= scoreboardlines)
-                       return -1;
-               index = fragsort[index];
-       }
-       if(index >= scoreboardlines)
-               return -1;
-       return index;
+       return index >= 0 && index < scoreboardlines ? fragsort[index] : -1;
 }
 
 static scoreboard_t teams[MAX_SCOREBOARD];
@@ -621,58 +642,61 @@ void Sbar_SortFrags (void)
 Sbar_SoloScoreboard
 ===============
 */
-void Sbar_SoloScoreboard (void)
+static void Sbar_SoloScoreboard (void)
 {
 #if 1
        char    str[80], timestr[40];
-       int             i, max;
+       int             max, timelen;
        int             minutes, seconds;
        double  t;
+       char vabuf[1024];
 
        t = (cl.intermission ? cl.completed_time : cl.time);
        minutes = (int)(t / 60);
        seconds = (int)(t - 60*floor(t/60));
 
        // monsters and secrets are now both on the top row
-       if (gamemode != GAME_NEXUIZ)
-               Sbar_DrawString(8, 4, va("Monsters:%3i /%3i    Secrets :%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS], cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]));
+       if (cl.stats[STAT_TOTALMONSTERS])
+               Sbar_DrawString(8, 4, va(vabuf, sizeof(vabuf), "Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]));
+       else if (cl.stats[STAT_MONSTERS]) // LA: Display something if monsters_killed is non-zero, but total_monsters is zero
+               Sbar_DrawString(8, 4, va(vabuf, sizeof(vabuf), "Monsters:%3i", cl.stats[STAT_MONSTERS]));
 
-       // figure out the map's filename without path or extension
-       strlcpy(str, FS_FileWithoutPath(cl.worldmodel ? cl.worldmodel->name : ""), sizeof(str));
-       if (strrchr(str, '.'))
-               *(strrchr(str, '.')) = 0;
+       if (cl.stats[STAT_TOTALSECRETS])
+               Sbar_DrawString(8+22*8, 4, va(vabuf, sizeof(vabuf), "Secrets:%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]));
+       else if (cl.stats[STAT_SECRETS]) // LA: And similarly for secrets
+               Sbar_DrawString(8+22*8, 4, va(vabuf, sizeof(vabuf), "Secrets:%3i", cl.stats[STAT_SECRETS]));
 
-       // append a : separator and then the full title
-       strlcat(str, ":", sizeof(str));
-       strlcat(str, cl.levelname, sizeof(str));
-
-       // make the time string
-       max = 38 - sprintf(timestr, " %i:%02i", minutes, seconds);
+       // format is like this: e1m1:The Sligpate Complex
+       dpsnprintf(str, sizeof(str), "%s:%s", cl.worldbasename, cl.worldmessage);
 
        // if there's a newline character, terminate the string there
        if (strchr(str, '\n'))
                *(strchr(str, '\n')) = 0;
 
-       // pad with spaces to fill the allotted space and append the time
-       i = bound(0, (int)strlen(str), max);
-       while (i < max)
-               str[i++] = ' ';
-       str[i] = 0;
-       strlcat(str, timestr, sizeof(str));
+       // make the time string
+       timelen = dpsnprintf(timestr, sizeof(timestr), " %i:%02i", minutes, seconds);
+
+       // truncate the level name if necessary to make room for time
+       max = 38 - timelen;
+       if ((int)strlen(str) > max)
+               str[max] = 0;
 
-       // print the line of text
+       // print the filename and message
        Sbar_DrawString(8, 12, str);
 
+       // print the time
+       Sbar_DrawString(8 + max*8, 12, timestr);
+
 #else
        char    str[80];
        int             minutes, seconds, tens, units;
        int             l;
 
-       if (gamemode != GAME_NEXUIZ) {
-               sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
+       if (IS_OLDNEXUIZ_DERIVED(gamemode)) {
+               dpsnprintf (str, sizeof(str), "Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
                Sbar_DrawString (8, 4, str);
 
-               sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
+               dpsnprintf (str, sizeof(str), "Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
                Sbar_DrawString (8, 12, str);
        }
 
@@ -681,16 +705,16 @@ void Sbar_SoloScoreboard (void)
        seconds = (int)(cl.time - 60*minutes);
        tens = seconds / 10;
        units = seconds - 10*tens;
-       sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
+       dpsnprintf (str, sizeof(str), "Time :%3i:%i%i", minutes, tens, units);
        Sbar_DrawString (184, 4, str);
 
 // draw level name
-       if (gamemode == GAME_NEXUIZ) {
-               l = (int) strlen (cl.worldmodel->name);
-               Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
+       if (IS_OLDNEXUIZ_DERIVED(gamemode)) {
+               l = (int) strlen (cl.worldname);
+               Sbar_DrawString (232 - l*4, 12, cl.worldname);
        } else {
-               l = (int) strlen (cl.levelname);
-               Sbar_DrawString (232 - l*4, 12, cl.levelname);
+               l = (int) strlen (cl.worldmessage);
+               Sbar_DrawString (232 - l*4, 12, cl.worldmessage);
        }
 #endif
 }
@@ -700,7 +724,7 @@ void Sbar_SoloScoreboard (void)
 Sbar_DrawScoreboard
 ===============
 */
-void Sbar_DrawScoreboard (void)
+static void Sbar_DrawScoreboard (void)
 {
        Sbar_SoloScoreboard ();
        // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
@@ -714,12 +738,25 @@ void Sbar_DrawScoreboard (void)
 // AK to make DrawInventory smaller
 static void Sbar_DrawWeapon(int nr, float fade, int active)
 {
-       // width = 300, height = 100
-       const int w_width = 300, w_height = 100, w_space = 10;
-       const float w_scale = 0.4;
+       char vabuf[1024];
+       if (sbar_hudselector.integer == 1)
+       {
+               // width = 300, height = 100
+               const int w_width = 32, w_height = 12, w_space = 2, font_size = 8;
 
-       DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, sb_weapons[0][nr], 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_NORMAL);
-       //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, NULL, true);
+               DrawQ_Pic((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr, vid_conheight.integer - w_height, sb_weapons[0][nr], w_width, w_height, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 0.6, (active ? 1 : 0.6) * fade * sbar_alpha_fg.value, DRAWFLAG_NORMAL);
+               // FIXME ??
+               DrawQ_String((vid_conwidth.integer - w_width * 9) * 0.5 + w_width * nr + w_space, vid_conheight.integer - w_height + w_space, va(vabuf, sizeof(vabuf), "%i",nr+1), 0, font_size, font_size, 1, 1, 0, sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
+       }
+       else
+       {
+               // width = 300, height = 100
+               const int w_width = 300, w_height = 100, w_space = 10;
+               const float w_scale = 0.4;
+
+               DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, sb_weapons[0][nr], 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_NORMAL);
+               //DrawQ_String(vid_conwidth.integer - (w_space + font_size ), (w_height + w_space) * w_scale * nr + w_space, va(vabuf, sizeof(vabuf), "%i",nr+1), 0, font_size, font_size, 1, 0, 0, fade, 0, NULL, true, FONT_DEFAULT);
+       }
 }
 
 /*
@@ -727,7 +764,7 @@ static void Sbar_DrawWeapon(int nr, float fade, int active)
 Sbar_DrawInventory
 ===============
 */
-void Sbar_DrawInventory (void)
+static void Sbar_DrawInventory (void)
 {
        int i;
        char num[6];
@@ -761,13 +798,13 @@ void Sbar_DrawInventory (void)
                        else
                                flashon = (flashon%5) + 2;
 
-                       Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
+                       Sbar_DrawPic (i*24, -16, sb_weapons[flashon][i]);
                }
        }
 
        // MED 01/04/97
        // hipnotic weapons
-       if (gamemode == GAME_HIPNOTIC)
+       if (gamemode == GAME_HIPNOTIC || gamemode == GAME_QUOTH)
        {
                int grenadeflashing=0;
                for (i=0 ; i<4 ; i++)
@@ -826,13 +863,15 @@ void Sbar_DrawInventory (void)
        // ammo counts
        for (i=0 ; i<4 ; i++)
        {
-               sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
+               dpsnprintf (num, sizeof(num), "%4i",cl.stats[STAT_SHELLS+i] );
                if (num[0] != ' ')
-                       Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
+                       Sbar_DrawCharacter ( (6*i+0)*8 - 2, -24, 18 + num[0] - '0');
                if (num[1] != ' ')
-                       Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
+                       Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[1] - '0');
                if (num[2] != ' ')
-                       Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
+                       Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[2] - '0');
+               if (num[3] != ' ')
+                       Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[3] - '0');
        }
 
        // items
@@ -840,13 +879,13 @@ void Sbar_DrawInventory (void)
                if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
                {
                        //MED 01/04/97 changed keys
-                       if (gamemode != GAME_HIPNOTIC || (i>1))
+                       if (!(gamemode == GAME_HIPNOTIC || gamemode == GAME_QUOTH) || (i>1))
                                Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
                }
 
        //MED 01/04/97 added hipnotic items
        // hipnotic items
-       if (gamemode == GAME_HIPNOTIC)
+       if (gamemode == GAME_HIPNOTIC || gamemode == GAME_QUOTH)
        {
                for (i=0 ; i<2 ; i++)
                        if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
@@ -876,7 +915,7 @@ void Sbar_DrawInventory (void)
 Sbar_DrawFrags
 ===============
 */
-void Sbar_DrawFrags (void)
+static void Sbar_DrawFrags (void)
 {
        int i, k, l, x, f;
        char num[12];
@@ -896,14 +935,14 @@ void Sbar_DrawFrags (void)
                s = &cl.scores[k];
 
                // draw background
-               c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
-               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);
-               c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
-               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);
+               c = palette_rgb_pantsscoreboard[(s->colors & 0xf0) >> 4];
+               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), sbar_alpha_fg.value, 0);
+               c = palette_rgb_shirtscoreboard[s->colors & 0xf];
+               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), sbar_alpha_fg.value, 0);
 
                // draw number
                f = s->frags;
-               sprintf (num, "%3i",f);
+               dpsnprintf (num, sizeof(num), "%3i",f);
 
                if (k == cl.viewentity - 1)
                {
@@ -925,7 +964,7 @@ void Sbar_DrawFrags (void)
 Sbar_DrawFace
 ===============
 */
-void Sbar_DrawFace (void)
+static void Sbar_DrawFace (void)
 {
        int f;
 
@@ -940,14 +979,14 @@ void Sbar_DrawFace (void)
                s = &cl.scores[cl.viewentity - 1];
                // draw background
                Sbar_DrawPic (112, 0, rsb_teambord);
-               c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
-               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);
-               c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
-               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);
+               c = palette_rgb_pantsscoreboard[(s->colors & 0xf0) >> 4];
+               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), sbar_alpha_fg.value, 0);
+               c = palette_rgb_shirtscoreboard[s->colors & 0xf];
+               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), sbar_alpha_fg.value, 0);
 
                // draw number
                f = s->frags;
-               sprintf (num, "%3i",f);
+               dpsnprintf (num, sizeof(num), "%3i",f);
 
                if ((s->colors & 0xf0)==0)
                {
@@ -984,80 +1023,281 @@ void Sbar_DrawFace (void)
                Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
        }
 }
+double topspeed = 0;
+double topspeedxy = 0;
+time_t current_time = 3;
+time_t top_time = 0;
+time_t topxy_time = 0;
+
+static void get_showspeed_unit(int unitnumber, double *conversion_factor, const char **unit)
+{
+       if(unitnumber < 0)
+               unitnumber = showspeed.integer;
+       switch(unitnumber)
+       {
+               default:
+               case 1:
+                       if(IS_NEXUIZ_DERIVED(gamemode))
+                               *unit = "in/s";
+                       else
+                               *unit = "qu/s";
+                       *conversion_factor = 1.0;
+                       break;
+               case 2:
+                       *unit = "m/s";
+                       *conversion_factor = 0.0254;
+                       if(!IS_NEXUIZ_DERIVED(gamemode))
+                               *conversion_factor *= 1.5;
+                       // 1qu=1.5in is for non-Nexuiz/Xonotic only - Nexuiz/Xonotic players are overly large, but 1qu=1in fixes that
+                       break;
+               case 3:
+                       *unit = "km/h";
+                       *conversion_factor = 0.0254 * 3.6;
+                       if(!IS_NEXUIZ_DERIVED(gamemode))
+                               *conversion_factor *= 1.5;
+                       break;
+               case 4:
+                       *unit = "mph";
+                       *conversion_factor = 0.0254 * 3.6 * 0.6213711922;
+                       if(!IS_NEXUIZ_DERIVED(gamemode))
+                               *conversion_factor *= 1.5;
+                       break;
+               case 5:
+                       *unit = "knots";
+                       *conversion_factor = 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
+                       if(!IS_NEXUIZ_DERIVED(gamemode))
+                               *conversion_factor *= 1.5;
+                       break;
+       }
+}
+
+static double showfps_nexttime = 0, showfps_lasttime = -1;
+static double showfps_framerate = 0;
+static int showfps_framecount = 0;
+
+void Sbar_ShowFPS_Update(void)
+{
+       double interval = 1;
+       double newtime;
+       newtime = realtime;
+       if (newtime >= showfps_nexttime)
+       {
+               showfps_framerate = showfps_framecount / (newtime - showfps_lasttime);
+               if (showfps_nexttime < newtime - interval * 1.5)
+                       showfps_nexttime = newtime;
+               showfps_lasttime = newtime;
+               showfps_nexttime += interval;
+               showfps_framecount = 0;
+       }
+       showfps_framecount++;
+}
 
 void Sbar_ShowFPS(void)
 {
-       float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
+       float fps_x, fps_y, fps_scalex, fps_scaley, fps_strings = 0;
+       char soundstring[32];
        char fpsstring[32];
        char timestring[32];
        char datestring[32];
+       char timedemostring1[32];
+       char timedemostring2[32];
+       char speedstring[32];
+       char blurstring[32];
+       char topspeedstring[48];
+       char texstring[MAX_QPATH];
        qboolean red = false;
+       soundstring[0] = 0;
        fpsstring[0] = 0;
+       timedemostring1[0] = 0;
+       timedemostring2[0] = 0;
        timestring[0] = 0;
        datestring[0] = 0;
+       speedstring[0] = 0;
+       blurstring[0] = 0;
+       texstring[0] = 0;
+       topspeedstring[0] = 0;
        if (showfps.integer)
        {
-               float calc;
-               static double nexttime = 0, lasttime = 0;
-               static double framerate = 0;
-               static int framecount = 0;
-               double newtime;
-               newtime = realtime;
-               if (newtime >= nexttime)
+               red = (showfps_framerate < 1.0f);
+               if(showfps.integer == 2)
+                       dpsnprintf(fpsstring, sizeof(fpsstring), "%7.3f mspf", (1000.0 / showfps_framerate));
+               else if (red)
+                       dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0 / showfps_framerate + 0.5));
+               else
+                       dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(showfps_framerate + 0.5));
+               fps_strings++;
+               if (cls.timedemo)
                {
-                       framerate = framecount / (newtime - lasttime);
-                       lasttime = newtime;
-                       nexttime = max(nexttime + 1, lasttime - 1);
-                       framecount = 0;
+                       dpsnprintf(timedemostring1, sizeof(timedemostring1), "frame%4i %f", cls.td_frames, realtime - cls.td_starttime);
+                       dpsnprintf(timedemostring2, sizeof(timedemostring2), "%i seconds %3.0f/%3.0f/%3.0f fps", cls.td_onesecondavgcount, cls.td_onesecondminfps, cls.td_onesecondavgfps / max(1, cls.td_onesecondavgcount), cls.td_onesecondmaxfps);
+                       fps_strings++;
+                       fps_strings++;
                }
-               framecount++;
-               calc = framerate;
-
-               if ((red = (calc < 1.0f)))
-                       dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
-               else
-                       dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
        }
        if (showtime.integer)
+       {
                strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
+               fps_strings++;
+       }
        if (showdate.integer)
+       {
                strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
-       if (fpsstring[0] || timestring[0])
+               fps_strings++;
+       }
+       if (showblur.integer)
+       {
+               dpsnprintf(blurstring, sizeof(blurstring), "%3i%% blur", (int)(cl.motionbluralpha * 100));
+               fps_strings++;
+       }
+       if (showsound.integer)
+       {
+               dpsnprintf(soundstring, sizeof(soundstring), "%4i/4%i at %3ims", cls.soundstats.mixedsounds, cls.soundstats.totalsounds, cls.soundstats.latency_milliseconds);
+               fps_strings++;
+       }
+       if (showspeed.integer || showtopspeed.integer)
+       {
+               double speed, speedxy, f;
+               const char *unit;
+               speed = VectorLength(cl.movement_velocity);
+               speedxy = sqrt(cl.movement_velocity[0] * cl.movement_velocity[0] + cl.movement_velocity[1] * cl.movement_velocity[1]);
+               if (showspeed.integer)
+               {
+                       get_showspeed_unit(showspeed.integer, &f, &unit);
+                       dpsnprintf(speedstring, sizeof(speedstring), "%.0f (%.0f) %s", f*speed, f*speedxy, unit);
+                       fps_strings++;
+               }
+               if (showtopspeed.integer)
+               {
+                       qboolean topspeed_latched = false, topspeedxy_latched = false;
+                       get_showspeed_unit(showtopspeed.integer, &f, &unit);
+                       if (speed >= topspeed || current_time - top_time > 3)
+                       {
+                               topspeed = speed;
+                               time(&top_time);
+                       }
+                       else
+                               topspeed_latched = true;
+                       if (speedxy >= topspeedxy || current_time - topxy_time > 3)
+                       {
+                               topspeedxy = speedxy;
+                               time(&topxy_time);
+                       }
+                       else
+                               topspeedxy_latched = true;
+                       dpsnprintf(topspeedstring, sizeof(topspeedstring), "%s%.0f%s (%s%.0f%s) %s",
+                               topspeed_latched ? "^1" : "^xf88", f*topspeed, "^xf88",
+                               topspeedxy_latched ? "^1" : "^xf88", f*topspeedxy, "^xf88",
+                               unit);
+                       time(&current_time);
+                       fps_strings++;
+               }
+       }
+       if (showtex.integer)
+       {
+               vec3_t org;
+               vec3_t dest;
+               vec3_t temp;
+               trace_t trace;
+
+               Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, org);
+               VectorSet(temp, 65536, 0, 0);
+               Matrix4x4_Transform(&r_refdef.view.matrix, temp, dest);
+               trace.hittexture = NULL; // to make sure
+               // TODO change this trace to be stopped by anything "visible" (i.e. with a drawsurface), but not stuff like weapclip
+               // probably needs adding a new SUPERCONTENTS type
+               trace = CL_TraceLine(org, dest, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID, collision_extendmovelength.value, true, false, NULL, true, true);
+               if(trace.hittexture)
+                       strlcpy(texstring, trace.hittexture->name, sizeof(texstring));
+               else
+                       strlcpy(texstring, "(no texture hit)", sizeof(texstring));
+               fps_strings++;
+       }
+       if (fps_strings)
        {
                fps_scalex = 12;
                fps_scaley = 12;
-               fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
                //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
-               //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
-               fps_y = vid_conheight.integer - fps_height;
+               //fps_y = bound(0, fps_y, vid_conheight.integer - fps_strings*fps_scaley);
+               fps_y = vid_conheight.integer - sbar_info_pos.integer - fps_strings*fps_scaley;
+               if (soundstring[0])
+               {
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(soundstring, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, soundstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+                       fps_y += fps_scaley;
+               }
                if (fpsstring[0])
                {
-                       fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
-                       DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
+                       r_draw2d_force = true;
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(fpsstring, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
                        if (red)
-                               DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0, NULL, true);
+                               DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0, NULL, true, FONT_INFOBAR);
                        else
-                               DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
+                               DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+                       fps_y += fps_scaley;
+                       r_draw2d_force = false;
+               }
+               if (timedemostring1[0])
+               {
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(timedemostring1, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, timedemostring1, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+                       fps_y += fps_scaley;
+               }
+               if (timedemostring2[0])
+               {
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(timedemostring2, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, timedemostring2, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
                        fps_y += fps_scaley;
                }
                if (timestring[0])
                {
-                       fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
-                       DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
-                       DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(timestring, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
                        fps_y += fps_scaley;
                }
                if (datestring[0])
                {
-                       fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
-                       DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
-                       DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(datestring, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+                       fps_y += fps_scaley;
+               }
+               if (speedstring[0])
+               {
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(speedstring, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, speedstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+                       fps_y += fps_scaley;
+               }
+               if (topspeedstring[0])
+               {
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(topspeedstring, 0, fps_scalex, fps_scaley, false, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, topspeedstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, false, FONT_INFOBAR);
+                       fps_y += fps_scaley;
+               }
+               if (blurstring[0])
+               {
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(blurstring, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, blurstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
+                       fps_y += fps_scaley;
+               }
+               if (texstring[0])
+               {
+                       fps_x = vid_conwidth.integer - DrawQ_TextWidth(texstring, 0, fps_scalex, fps_scaley, true, FONT_INFOBAR);
+                       DrawQ_Fill(fps_x, fps_y, vid_conwidth.integer - fps_x, fps_scaley, 0, 0, 0, 0.5, 0);
+                       DrawQ_String(fps_x, fps_y, texstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true, FONT_INFOBAR);
                        fps_y += fps_scaley;
                }
        }
 }
 
-void Sbar_DrawGauge(float x, float y, cachepic_t *pic, 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)
+static void Sbar_DrawGauge(float x, float y, cachepic_t *pic, 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)
 {
        float r[5];
        c2 = bound(0, c2, 1);
@@ -1084,92 +1324,141 @@ Sbar_Draw
 */
 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
 extern cvar_t v_kicktime;
+void Sbar_Score (int margin);
 void Sbar_Draw (void)
 {
        cachepic_t *pic;
+       char vabuf[1024];
 
        if(cl.csqc_vidvars.drawenginesbar)      //[515]: csqc drawsbar
        {
-               if (cl.intermission == 1)
+               if (sb_showscores)
+                       Sbar_DrawScoreboard ();
+               else if (cl.intermission == 1)
                {
-                       if(gamemode == GAME_NEXUIZ) // display full scoreboard (that is, show scores + map name)
+                       if(IS_OLDNEXUIZ_DERIVED(gamemode)) // display full scoreboard (that is, show scores + map name)
                        {
                                Sbar_DrawScoreboard();
                                return;
                        }
                        Sbar_IntermissionOverlay();
-                       return;
                }
                else if (cl.intermission == 2)
-               {
-                       if(gamemode == GAME_NEXUIZ) // Nexuiz allows TAB to override the voting screens to recall the scores
-                               if(sb_showscores)
-                               {
-                                       Sbar_DrawScoreboard();
-                                       return;
-                               }
                        Sbar_FinaleOverlay();
-                       return;
-               }
-
-               if (gamemode == GAME_NETHERWORLD)
+               else if (gamemode == GAME_DELUXEQUAKE)
                {
                }
-               else if (gamemode == GAME_SOM)
+               else if (IS_OLDNEXUIZ_DERIVED(gamemode))
                {
                        if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
+                       {
+                               sbar_x = (vid_conwidth.integer - 640)/2;
+                               sbar_y = vid_conheight.integer - 47;
+                               Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
                                Sbar_DrawScoreboard ();
-                       else if (sb_lines)
+                       }
+                       else if (sb_lines && sbar_hudselector.integer == 1)
                        {
-                               // this is the top left of the sbar area
-                               sbar_x = 0;
-                               sbar_y = vid_conheight.integer - 24*3;
+                               int i;
+                               float fade;
+                               int redflag, blueflag;
+                               float x;
+
+                               sbar_x = (vid_conwidth.integer - 320)/2;
+                               sbar_y = vid_conheight.integer - 24 - 16;
+
+                               // calculate intensity to draw weapons bar at
+                               fade = 3.2 - 2 * (cl.time - cl.weapontime);
+                               fade = bound(0.7, fade, 1);
+                               for (i = 0; i < 8;i++)
+                                       if (cl.stats[STAT_ITEMS] & (1 << i))
+                                               Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
+                               if((cl.stats[STAT_ITEMS] & (1<<12)))
+                                       Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
+
+                               // flag icons
+                               redflag = ((cl.stats[STAT_ITEMS]>>15) & 3);
+                               blueflag = ((cl.stats[STAT_ITEMS]>>17) & 3);
+                               x = sbar_flagstatus_right.integer ? vid_conwidth.integer - 10 - sbar_x - 64 : 10 - sbar_x;
+                               if (redflag == 3 && blueflag == 3)
+                               {
+                                       // The Impossible Combination[tm]
+                                       // Can only happen in Key Hunt mode...
+                                       Sbar_DrawPic ((int) x, (int) ((vid_conheight.integer - sbar_y) - (sbar_flagstatus_pos.value + 128)), sb_items[14]);
+                               }
+                               else
+                               {
+                                       if (redflag)
+                                               Sbar_DrawPic ((int) x, (int) ((vid_conheight.integer - sbar_y) - (sbar_flagstatus_pos.value + 64)), sb_items[redflag+10]);
+                                       if (blueflag)
+                                               Sbar_DrawPic ((int) x, (int) ((vid_conheight.integer - sbar_y) - (sbar_flagstatus_pos.value + 128)), sb_items[blueflag+14]);
+                               }
 
                                // armor
-                               if (cl.stats[STAT_ARMOR])
+                               if (cl.stats[STAT_ARMOR] > 0)
                                {
-                                       if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
-                                               Sbar_DrawPic(0, 0, somsb_armor[2]);
-                                       else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
-                                               Sbar_DrawPic(0, 0, somsb_armor[1]);
-                                       else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
-                                               Sbar_DrawPic(0, 0, somsb_armor[0]);
-                                       Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
+                                       Sbar_DrawStretchPic (72, 0, sb_armor[0], sbar_alpha_fg.value, 24, 24);
+                                       if(cl.stats[STAT_ARMOR] > 200)
+                                               Sbar_DrawXNum(0,0,cl.stats[STAT_ARMOR],3,24,0,1,0,1,0);
+                                       else if(cl.stats[STAT_ARMOR] > 100)
+                                               Sbar_DrawXNum(0,0,cl.stats[STAT_ARMOR],3,24,0.2,1,0.2,1,0);
+                                       else if(cl.stats[STAT_ARMOR] > 50)
+                                               Sbar_DrawXNum(0,0,cl.stats[STAT_ARMOR],3,24,0.6,0.7,0.8,1,0);
+                                       else if(cl.stats[STAT_ARMOR] > 25)
+                                               Sbar_DrawXNum(0,0,cl.stats[STAT_ARMOR],3,24,1,1,0.2,1,0);
+                                       else
+                                               Sbar_DrawXNum(0,0,cl.stats[STAT_ARMOR],3,24,0.7,0,0,1,0);
                                }
 
                                // health
-                               Sbar_DrawPic(0, 24, somsb_health);
-                               Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
+                               if (cl.stats[STAT_HEALTH] != 0)
+                               {
+                                       Sbar_DrawStretchPic (184, 0, sb_health, sbar_alpha_fg.value, 24, 24);
+                                       if(cl.stats[STAT_HEALTH] > 200)
+                                               Sbar_DrawXNum(112,0,cl.stats[STAT_HEALTH],3,24,0,1,0,1,0);
+                                       else if(cl.stats[STAT_HEALTH] > 100)
+                                               Sbar_DrawXNum(112,0,cl.stats[STAT_HEALTH],3,24,0.2,1,0.2,1,0);
+                                       else if(cl.stats[STAT_HEALTH] > 50)
+                                               Sbar_DrawXNum(112,0,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
+                                       else if(cl.stats[STAT_HEALTH] > 25)
+                                               Sbar_DrawXNum(112,0,cl.stats[STAT_HEALTH],3,24,1,1,0.2,1,0);
+                                       else
+                                               Sbar_DrawXNum(112,0,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
+                               }
 
-                               // ammo icon
-                               if (cl.stats[STAT_ITEMS] & IT_SHELLS)
-                                       Sbar_DrawPic(0, 48, somsb_ammo[0]);
-                               else if (cl.stats[STAT_ITEMS] & IT_NAILS)
-                                       Sbar_DrawPic(0, 48, somsb_ammo[1]);
-                               else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
-                                       Sbar_DrawPic(0, 48, somsb_ammo[2]);
-                               else if (cl.stats[STAT_ITEMS] & IT_CELLS)
-                                       Sbar_DrawPic(0, 48, somsb_ammo[3]);
-                               Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
-                               if (cl.stats[STAT_SHELLS])
-                                       Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
-                       }
-               }
-               else if (gamemode == GAME_NEXUIZ)
-               {
-                       sbar_y = vid_conheight.integer - 47;
-                       sbar_x = (vid_conwidth.integer - 640)/2;
+                               // ammo
+                               if ((cl.stats[STAT_ITEMS] & (NEX_IT_SHELLS | NEX_IT_BULLETS | NEX_IT_ROCKETS | NEX_IT_CELLS)) || cl.stats[STAT_AMMO] != 0)
+                               {
+                                       if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
+                                               Sbar_DrawStretchPic (296, 0, sb_ammo[0], sbar_alpha_fg.value, 24, 24);
+                                       else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
+                                               Sbar_DrawStretchPic (296, 0, sb_ammo[1], sbar_alpha_fg.value, 24, 24);
+                                       else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
+                                               Sbar_DrawStretchPic (296, 0, sb_ammo[2], sbar_alpha_fg.value, 24, 24);
+                                       else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
+                                               Sbar_DrawStretchPic (296, 0, sb_ammo[3], sbar_alpha_fg.value, 24, 24);
+                                       if(cl.stats[STAT_AMMO] > 10)
+                                               Sbar_DrawXNum(224, 0, cl.stats[STAT_AMMO], 3, 24, 0.6,0.7,0.8,1,0);
+                                       else
+                                               Sbar_DrawXNum(224, 0, cl.stats[STAT_AMMO], 3, 24, 0.7,0,0,1,0);
+                               }
 
-                       if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
-                       {
-                               Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
-                               Sbar_DrawScoreboard ();
+                               if (sbar_x + 320 + 160 <= vid_conwidth.integer)
+                                       Sbar_MiniDeathmatchOverlay (sbar_x + 320, sbar_y);
+                               if (sbar_x > 0)
+                                       Sbar_Score(16);
+                                       // The margin can be at most 8 to support 640x480 console size:
+                                       //   320 + 2 * (144 + 16) = 640
                        }
                        else if (sb_lines)
                        {
                                int i;
                                float fade;
                                int redflag, blueflag;
+                               float x;
+
+                               sbar_x = (vid_conwidth.integer - 640)/2;
+                               sbar_y = vid_conheight.integer - 47;
 
                                // calculate intensity to draw weapons bar at
                                fade = 3 - 2 * (cl.time - cl.weapontime);
@@ -1195,18 +1484,19 @@ void Sbar_Draw (void)
                                // flag icons
                                redflag = ((cl.stats[STAT_ITEMS]>>15) & 3);
                                blueflag = ((cl.stats[STAT_ITEMS]>>17) & 3);
+                               x = sbar_flagstatus_right.integer ? vid_conwidth.integer - 10 - sbar_x - 64 : 10 - sbar_x;
                                if (redflag == 3 && blueflag == 3)
                                {
                                        // The Impossible Combination[tm]
                                        // Can only happen in Key Hunt mode...
-                                       Sbar_DrawPic (10 - sbar_x, -179, sb_items[14]);
+                                       Sbar_DrawPic ((int) x, -179, sb_items[14]);
                                }
                                else
                                {
                                        if (redflag)
-                                               Sbar_DrawPic (10 - sbar_x, -109, sb_items[redflag+10]);
+                                               Sbar_DrawPic ((int) x, -117, sb_items[redflag+10]);
                                        if (blueflag)
-                                               Sbar_DrawPic (10 - sbar_x, -169, sb_items[blueflag+14]);
+                                               Sbar_DrawPic ((int) x, -177, sb_items[blueflag+14]);
                                }
 
                                // armor
@@ -1241,10 +1531,23 @@ void Sbar_Draw (void)
 
                                if (sb_lines > 24)
                                        DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay,0,0,1,1,1,1,DRAWFLAG_MODULATE);
-                       }
 
-                       //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
-                       //      Sbar_MiniDeathmatchOverlay (0, 17);
+                               if (sbar_x + 600 + 160 <= vid_conwidth.integer)
+                                       Sbar_MiniDeathmatchOverlay (sbar_x + 600, sbar_y);
+
+                               if (sbar_x > 0)
+                                       Sbar_Score(-16);
+                                       // Because:
+                                       //   Mini scoreboard uses 12*4 per other team, that is, 144
+                                       //   pixels when there are four teams...
+                                       //   Nexuiz by default sets vid_conwidth to 800... makes
+                                       //   sbar_x == 80...
+                                       //   so we need to shift it by 64 pixels to the right to fit
+                                       //   BUT: then it overlaps with the image that gets drawn
+                                       //   for viewsize 100! Therefore, just account for 3 teams,
+                                       //   that is, 96 pixels mini scoreboard size, needing 16 pixels
+                                       //   to the right!
+                       }
                }
                else if (gamemode == GAME_ZYMOTIC)
                {
@@ -1312,13 +1615,10 @@ void Sbar_Draw (void)
                }
                else // Quake and others
                {
+                       sbar_x = (vid_conwidth.integer - 320)/2;
                        sbar_y = vid_conheight.integer - SBAR_HEIGHT;
                        // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
                        //if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
-                       if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
-                               sbar_x = 0;
-                       else
-                               sbar_x = (vid_conwidth.integer - 320)/2;
 
                        if (sb_lines > 24)
                        {
@@ -1340,7 +1640,7 @@ void Sbar_Draw (void)
 
                                // keys (hipnotic only)
                                //MED 01/04/97 moved keys here so they would not be overwritten
-                               if (gamemode == GAME_HIPNOTIC)
+                               if (gamemode == GAME_HIPNOTIC || gamemode == GAME_QUOTH)
                                {
                                        if (cl.stats[STAT_ITEMS] & IT_KEY1)
                                                Sbar_DrawPic (209, 3, sb_items[0]);
@@ -1418,27 +1718,27 @@ void Sbar_Draw (void)
 
                                Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
 
-                       }
-
-                       // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
-                       //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
-                       if (!cl.islocalgame && vid_conwidth.integer > 320)
-                       {
-                               if (gamemode == GAME_TRANSFUSION)
-                                       Sbar_MiniDeathmatchOverlay (0, 0);
-                               else
-                                       Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
+                               // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
+                               if ((!cl.islocalgame || cl.gametype != GAME_COOP))
+                               {
+                                       if (gamemode == GAME_TRANSFUSION)
+                                               Sbar_MiniDeathmatchOverlay (0, 0);
+                                       else
+                                               Sbar_MiniDeathmatchOverlay (sbar_x + 324, vid_conheight.integer - 8*8);
+                                       Sbar_Score(24);
+                               }
                        }
                }
        }
 
-       Sbar_ShowFPS();
-
-       if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && crosshair.integer <= NUMCROSSHAIRS && !cl.intermission && !r_letterbox.value && (pic = r_crosshairs[crosshair.integer]))
+       if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && !cl.intermission && !r_letterbox.value)
+       {
+               pic = Draw_CachePic (va(vabuf, sizeof(vabuf), "gfx/crosshair%i", crosshair.integer));
                DrawQ_Pic((vid_conwidth.integer - pic->width * crosshair_size.value) * 0.5f, (vid_conheight.integer - pic->height * crosshair_size.value) * 0.5f, pic, pic->width * crosshair_size.value, pic->height * crosshair_size.value, crosshair_color_red.value, crosshair_color_green.value, crosshair_color_blue.value, crosshair_color_alpha.value, 0);
+       }
 
-       if (cl_prydoncursor.integer)
-               DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid_conwidth.integer, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid_conheight.integer, Draw_CachePic(va("gfx/prydoncursor%03i", cl_prydoncursor.integer), true), 0, 0, 1, 1, 1, 1, 0);
+       if (cl_prydoncursor.integer > 0)
+               DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid_conwidth.integer, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid_conheight.integer, Draw_CachePic (va(vabuf, sizeof(vabuf), "gfx/prydoncursor%03i", cl_prydoncursor.integer)), 0, 0, 1, 1, 1, 1, 0);
 }
 
 //=============================================================================
@@ -1449,33 +1749,47 @@ Sbar_DeathmatchOverlay
 
 ==================
 */
-float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
+static float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
 {
        int minutes;
+       qboolean myself = false;
        unsigned char *c;
+       char vabuf[1024];
        minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : cl.time - s->qw_entertime) / 60.0);
+
+       if((s - cl.scores) == cl.playerentity - 1)
+               myself = true;
+       if((s - teams) >= 0 && (s - teams) < MAX_SCOREBOARD)
+               if((s->colors & 15) == (cl.scores[cl.playerentity - 1].colors & 15))
+                       myself = true;
+
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
                if (s->qw_spectator)
                {
                        if (s->qw_ping || s->qw_packetloss)
-                               DrawQ_String(x, y, va("%4i %3i %4i spectator  %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%4i %3i %4i spectator  %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                        else
-                               DrawQ_String(x, y, va("         %4i spectator  %c%s", minutes, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "         %4i spectator  %c%s", minutes, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                }
                else
                {
                        // draw colors behind score
-                       c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
-                       DrawQ_Fill(x + 14*8, y+1, 40, 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);
-                       c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
-                       DrawQ_Fill(x + 14*8, y+4, 40, 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);
+                       //
+                       //
+                       //
+                       //
+                       //
+                       c = palette_rgb_pantsscoreboard[(s->colors & 0xf0) >> 4];
+                       DrawQ_Fill(x + 14*8*FONT_SBAR->maxwidth, y+1, 40*FONT_SBAR->maxwidth, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), sbar_alpha_fg.value, 0);
+                       c = palette_rgb_shirtscoreboard[s->colors & 0xf];
+                       DrawQ_Fill(x + 14*8*FONT_SBAR->maxwidth, y+4, 40*FONT_SBAR->maxwidth, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), sbar_alpha_fg.value, 0);
                        // print the text
-                       //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, NULL, true);
+                       //DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
                        if (s->qw_ping || s->qw_packetloss)
-                               DrawQ_String(x, y, va("%4i %3i %4i %5i %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%4i %3i %4i %5i %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                        else
-                               DrawQ_String(x, y, va("         %4i %5i %-4s %c%s", minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "         %4i %5i %-4s %c%s", minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                }
        }
        else
@@ -1483,23 +1797,23 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
                if (s->qw_spectator)
                {
                        if (s->qw_ping || s->qw_packetloss)
-                               DrawQ_String(x, y, va("%4i %3i spect %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%4i %3i spect %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                        else
-                               DrawQ_String(x, y, va("         spect %c%s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "         spect %c%s", myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                }
                else
                {
                        // draw colors behind score
-                       c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
-                       DrawQ_Fill(x + 9*8, y+1, 40, 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);
-                       c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
-                       DrawQ_Fill(x + 9*8, y+4, 40, 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);
+                       c = palette_rgb_pantsscoreboard[(s->colors & 0xf0) >> 4];
+                       DrawQ_Fill(x + 9*8*FONT_SBAR->maxwidth, y+1, 40*FONT_SBAR->maxwidth, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), sbar_alpha_fg.value, 0);
+                       c = palette_rgb_shirtscoreboard[s->colors & 0xf];
+                       DrawQ_Fill(x + 9*8*FONT_SBAR->maxwidth, y+4, 40*FONT_SBAR->maxwidth, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), sbar_alpha_fg.value, 0);
                        // print the text
-                       //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, NULL, true);
+                       //DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%c%4i %s", myself ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, true, FONT_DEFAULT);
                        if (s->qw_ping || s->qw_packetloss)
-                               DrawQ_String(x, y, va("%4i %3i %5i %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (int) s->frags, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "%4i %3i %5i %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (int) s->frags, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                        else
-                               DrawQ_String(x, y, va("         %5i %c%s", (int) s->frags, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+                               DrawQ_String(x, y, va(vabuf, sizeof(vabuf), "         %5i %c%s", (int) s->frags, myself ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
                }
        }
        return 8;
@@ -1507,7 +1821,8 @@ float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
 
 void Sbar_DeathmatchOverlay (void)
 {
-       int i, x, y;
+       int i, y, xmin, xmax, ymin, ymax;
+       char vabuf[1024];
 
        // request new ping times every two second
        if (cl.last_ping_request < realtime - 2 && cls.netcon)
@@ -1518,7 +1833,7 @@ void Sbar_DeathmatchOverlay (void)
                        MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
                        MSG_WriteString(&cls.netcon->message, "pings");
                }
-               else if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6/* || cls.protocol == PROTOCOL_DARKPLACES7*/)
+               else if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_NEHAHRABJP || cls.protocol == PROTOCOL_NEHAHRABJP2 || cls.protocol == PROTOCOL_NEHAHRABJP3 || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6/* || cls.protocol == PROTOCOL_DARKPLACES7*/)
                {
                        // these servers usually lack the pings command and so a less efficient "ping" command must be sent, which on modern DP servers will also reply with a pingplreport command after the ping listing
                        static int ping_anyway_counter = 0;
@@ -1544,21 +1859,32 @@ void Sbar_DeathmatchOverlay (void)
                }
        }
 
-       DrawQ_Pic ((vid_conwidth.integer - sb_ranking->width)/2, 8, sb_ranking, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
-
        // scores
        Sbar_SortFrags ();
+
+       ymin = 8;
+       ymax = 40 + 8 + (Sbar_IsTeammatch() ? (teamlines * 8 + 5): 0) + scoreboardlines * 8 - 1;
+
+       if (cls.protocol == PROTOCOL_QUAKEWORLD)
+               xmin = (int) (vid_conwidth.integer - (26 + 15) * 8 * FONT_SBAR->maxwidth) / 2; // 26 characters until name, then we assume 15 character names (they can be longer but usually aren't)
+       else
+               xmin = (int) (vid_conwidth.integer - (16 + 25) * 8 * FONT_SBAR->maxwidth) / 2; // 16 characters until name, then we assume 25 character names (they can be longer but usually aren't)
+       xmax = vid_conwidth.integer - xmin;
+
+       if(IS_OLDNEXUIZ_DERIVED(gamemode))
+               DrawQ_Pic (xmin - 8, ymin - 8, 0, xmax-xmin+1 + 2*8, ymax-ymin+1 + 2*8, 0, 0, 0, sbar_alpha_bg.value, 0);
+
+       DrawQ_Pic ((vid_conwidth.integer - sb_ranking->width)/2, 8, sb_ranking, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
+
        // draw the text
        y = 40;
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
-               x = (vid_conwidth.integer - (26 + 15) * 8) / 2; // 26 characters until name, then we assume 15 character names (they can be longer but usually aren't)
-               DrawQ_String(x, y, va("ping pl%% time frags team  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+               DrawQ_String(xmin, y, va(vabuf, sizeof(vabuf), "ping pl%% time frags team  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
        }
        else
        {
-               x = (vid_conwidth.integer - (16 + 15) * 8) / 2; // 16 characters until name, then we assume 15 character names (they can be longer but usually aren't)
-               DrawQ_String(x, y, va("ping pl%% frags  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
+               DrawQ_String(xmin, y, va(vabuf, sizeof(vabuf), "ping pl%% frags  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false, FONT_SBAR );
        }
        y += 8;
 
@@ -1566,23 +1892,33 @@ void Sbar_DeathmatchOverlay (void)
        {
                // show team scores first
                for (i = 0;i < teamlines && y < vid_conheight.integer;i++)
-                       y += (int)Sbar_PrintScoreboardItem((teams + teamsort[i]), x, y);
+                       y += (int)Sbar_PrintScoreboardItem((teams + teamsort[i]), xmin, y);
                y += 5;
        }
 
        for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
-               y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
+               y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], xmin, y);
 }
 
 /*
 ==================
-Sbar_DeathmatchOverlay
+Sbar_MiniDeathmatchOverlay
 
 ==================
 */
 void Sbar_MiniDeathmatchOverlay (int x, int y)
 {
-       int i, numlines;
+       int i, j, numlines, range_begin, range_end, myteam, teamsep;
+
+       // do not draw this if sbar_miniscoreboard_size is zero
+       if(sbar_miniscoreboard_size.value == 0)
+               return;
+       // adjust the given y if sbar_miniscoreboard_size doesn't indicate default (< 0)
+       if(sbar_miniscoreboard_size.value > 0)
+               y = (int) (vid_conheight.integer - sbar_miniscoreboard_size.value * 8);
+
+       // scores
+       Sbar_SortFrags ();
 
        // decide where to print
        if (gamemode == GAME_TRANSFUSION)
@@ -1594,31 +1930,228 @@ void Sbar_MiniDeathmatchOverlay (int x, int y)
        if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
                return;
 
-       // scores
-       Sbar_SortFrags ();
-
        //find us
        for (i = 0; i < scoreboardlines; i++)
                if (fragsort[i] == cl.playerentity - 1)
                        break;
 
+       range_begin = 0;
+       range_end = scoreboardlines;
+       teamsep = 0;
+
+       if (gamemode != GAME_TRANSFUSION)
+               if (Sbar_IsTeammatch ())
+               {
+                       // reserve space for the team scores
+                       numlines -= teamlines;
+
+                       // find first and last player of my team (only draw the team totals and my own team)
+                       range_begin = range_end = i;
+                       myteam = cl.scores[fragsort[i]].colors & 15;
+                       while(range_begin > 0 && (cl.scores[fragsort[range_begin-1]].colors & 15) == myteam)
+                               --range_begin;
+                       while(range_end < scoreboardlines && (cl.scores[fragsort[range_end]].colors & 15) == myteam)
+                               ++range_end;
+
+                       // looks better than two players
+                       if(numlines == 2)
+                       {
+                               teamsep = 8;
+                               numlines = 1;
+                       }
+               }
+
        // figure out start
        i -= numlines/2;
-       i = min(i, scoreboardlines - numlines);
-       i = max(i, 0);
+       i = min(i, range_end - numlines);
+       i = max(i, range_begin);
 
        if (gamemode == GAME_TRANSFUSION)
        {
-               for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
+               for (;i < range_end && x < vid_conwidth.integer;i++)
                        x += 128 + (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
        }
        else
        {
-               for (;i < scoreboardlines && y < vid_conheight.integer;i++)
+               if(range_end - i < numlines) // won't draw to bottom?
+                       y += 8 * (numlines - (range_end - i)); // bottom align
+               // show team scores first
+               for (j = 0;j < teamlines && y < vid_conheight.integer;j++)
+                       y += (int)Sbar_PrintScoreboardItem((teams + teamsort[j]), x, y);
+               y += teamsep;
+               for (;i < range_end && y < vid_conheight.integer;i++)
                        y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
        }
 }
 
+static int Sbar_TeamColorCompare(const void *t1_, const void *t2_)
+{
+       static int const sortorder[16] =
+       {
+               1001,
+               1002,
+               1003,
+               1004,
+               1, // red
+               1005,
+               1006,
+               1007,
+               1008,
+               4, // pink
+               1009,
+               1010,
+               3, // yellow
+               2, // blue
+               1011,
+               1012
+       };
+       const scoreboard_t *t1 = *(scoreboard_t **) t1_;
+       const scoreboard_t *t2 = *(scoreboard_t **) t2_;
+       int tc1 = sortorder[t1->colors & 15];
+       int tc2 = sortorder[t2->colors & 15];
+       return tc1 - tc2;
+}
+
+void Sbar_Score (int margin)
+{
+       int i, me, score, otherleader, place, distribution, minutes, seconds;
+       double timeleft;
+       int sbar_x_save = sbar_x;
+       int sbar_y_save = sbar_y;
+
+
+       sbar_y = (int) (vid_conheight.value - (32+12));
+       sbar_x -= margin;
+
+       me = cl.playerentity - 1;
+       if (sbar_scorerank.integer && me >= 0 && me < cl.maxclients)
+       {
+               if(Sbar_IsTeammatch())
+               {
+                       // Layout:
+                       //
+                       //   team1 team3 team4
+                       //
+                       //         TEAM2
+
+                       scoreboard_t *teamcolorsort[16];
+
+                       Sbar_SortFrags();
+                       for(i = 0; i < teamlines; ++i)
+                               teamcolorsort[i] = &(teams[i]);
+
+                       // Now sort them by color
+                       qsort(teamcolorsort, teamlines, sizeof(*teamcolorsort), Sbar_TeamColorCompare);
+
+                       // : margin
+                       // -12*4: four digits space
+                       place = (teamlines - 1) * (-12 * 4);
+
+                       for(i = 0; i < teamlines; ++i)
+                       {
+                               int cindex = teamcolorsort[i]->colors & 15;
+                               unsigned char *c = palette_rgb_shirtscoreboard[cindex];
+                               float cm = max(max(c[0], c[1]), c[2]);
+                               float cr = c[0] / cm;
+                               float cg = c[1] / cm;
+                               float cb = c[2] / cm;
+                               if(cindex == (cl.scores[cl.playerentity - 1].colors & 15)) // my team
+                               {
+                                       Sbar_DrawXNum(-32*4, 0, teamcolorsort[i]->frags, 4, 32, cr, cg, cb, 1, 0);
+                               }
+                               else // other team
+                               {
+                                       Sbar_DrawXNum(place, -12, teamcolorsort[i]->frags, 4, 12, cr, cg, cb, 1, 0);
+                                       place += 4 * 12;
+                               }
+                       }
+               }
+               else
+               {
+                       // Layout:
+                       //
+                       //   leading  place
+                       //
+                       //        FRAGS
+                       //
+                       // find leading score other than ourselves, to calculate distribution
+                       // find our place in the scoreboard
+                       score = cl.scores[me].frags;
+                       for (i = 0, otherleader = -1, place = 1;i < cl.maxclients;i++)
+                       {
+                               if (cl.scores[i].name[0] && i != me)
+                               {
+                                       if (otherleader == -1 || cl.scores[i].frags > cl.scores[otherleader].frags)
+                                               otherleader = i;
+                                       if (score < cl.scores[i].frags || (score == cl.scores[i].frags && i < me))
+                                               place++;
+                               }
+                       }
+                       distribution = otherleader >= 0 ? score - cl.scores[otherleader].frags : 0;
+                       if (place == 1)
+                               Sbar_DrawXNum(-3*12, -12, place, 3, 12, 1, 1, 1, 1, 0);
+                       else if (place == 2)
+                               Sbar_DrawXNum(-3*12, -12, place, 3, 12, 1, 1, 0, 1, 0);
+                       else
+                               Sbar_DrawXNum(-3*12, -12, place, 3, 12, 1, 0, 0, 1, 0);
+                       if (otherleader < 0)
+                               Sbar_DrawXNum(-32*4,   0, score, 4, 32, 1, 1, 1, 1, 0);
+                       if (distribution >= 0)
+                       {
+                               Sbar_DrawXNum(-7*12, -12, distribution, 4, 12, 1, 1, 1, 1, 0);
+                               Sbar_DrawXNum(-32*4,   0, score, 4, 32, 1, 1, 1, 1, 0);
+                       }
+                       else if (distribution >= -5)
+                       {
+                               Sbar_DrawXNum(-7*12, -12, distribution, 4, 12, 1, 1, 0, 1, 0);
+                               Sbar_DrawXNum(-32*4,   0, score, 4, 32, 1, 1, 0, 1, 0);
+                       }
+                       else
+                       {
+                               Sbar_DrawXNum(-7*12, -12, distribution, 4, 12, 1, 0, 0, 1, 0);
+                               Sbar_DrawXNum(-32*4,   0, score, 4, 32, 1, 0, 0, 1, 0);
+                       }
+               }
+       }
+
+       if (sbar_gametime.integer && cl.statsf[STAT_TIMELIMIT])
+       {
+               timeleft = max(0, cl.statsf[STAT_TIMELIMIT] * 60 - cl.time);
+               minutes = (int)floor(timeleft / 60);
+               seconds = (int)(floor(timeleft) - minutes * 60);
+               if (minutes >= 5)
+               {
+                       Sbar_DrawXNum(-12*6, 32, minutes,  3, 12, 1, 1, 1, 1, 0);
+                       if(sb_colon && sb_colon->tex != r_texture_notexture)
+                               DrawQ_Pic(sbar_x + -12*3, sbar_y + 32, sb_colon, 12, 12, 1, 1, 1, sbar_alpha_fg.value, 0);
+                       Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 1, 1, 1, 0);
+               }
+               else if (minutes >= 1)
+               {
+                       Sbar_DrawXNum(-12*6, 32, minutes,  3, 12, 1, 1, 0, 1, 0);
+                       if(sb_colon && sb_colon->tex != r_texture_notexture)
+                               DrawQ_Pic(sbar_x + -12*3, sbar_y + 32, sb_colon, 12, 12, 1, 1, 0, sbar_alpha_fg.value, 0);
+                       Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 1, 0, 1, 0);
+               }
+               else if ((int)(timeleft * 4) & 1)
+                       Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 1, 1, 1, 0);
+               else
+                       Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 0, 0, 1, 0);
+       }
+       else if (sbar_gametime.integer)
+       {
+               minutes = (int)floor(cl.time / 60);
+               seconds = (int)(floor(cl.time) - minutes * 60);
+               Sbar_DrawXNum(-12*6, 32, minutes,  3, 12, 1, 1, 1, 1, 0);
+               if(sb_colon && sb_colon->tex != r_texture_notexture)
+                       DrawQ_Pic(sbar_x + -12*3, sbar_y + 32, sb_colon, 12, 12, 1, 1, 1, sbar_alpha_fg.value, 0);
+               Sbar_DrawXNum(-12*2, 32, seconds, -2, 12, 1, 1, 1, 1, 0);
+       }
+
+       sbar_x = sbar_x_save;
+       sbar_y = sbar_y_save;
+}
+
 /*
 ==================
 Sbar_IntermissionOverlay
@@ -1630,9 +2163,7 @@ void Sbar_IntermissionOverlay (void)
        int             dig;
        int             num;
 
-       // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
-       //if (cl.gametype == GAME_DEATHMATCH)
-       if (!cl.islocalgame)
+       if (cl.gametype == GAME_DEATHMATCH)
        {
                Sbar_DeathmatchOverlay ();
                return;
@@ -1648,21 +2179,34 @@ void Sbar_IntermissionOverlay (void)
        dig = (int)cl.completed_time / 60;
        Sbar_DrawNum (160, 64, dig, 3, 0);
        num = (int)cl.completed_time - dig*60;
-       if (gamemode != GAME_NEXUIZ)
-               Sbar_DrawPic (234,64,sb_colon);
+       Sbar_DrawPic (234,64,sb_colon);
        Sbar_DrawPic (246,64,sb_nums[0][num/10]);
        Sbar_DrawPic (266,64,sb_nums[0][num%10]);
 
-       Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
-       if (gamemode != GAME_NEXUIZ)
-               Sbar_DrawPic (232, 104, sb_slash);
-       Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
-
-       Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
-       if (gamemode != GAME_NEXUIZ)
-               Sbar_DrawPic (232, 144, sb_slash);
-       Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
+// LA: Display as "a" instead of "a/b" if b is 0
+       if(cl.stats[STAT_TOTALSECRETS])
+       {
+               Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
+               if (!IS_OLDNEXUIZ_DERIVED(gamemode))
+                       Sbar_DrawPic (232, 104, sb_slash);
+               Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
+       }
+       else
+       {
+               Sbar_DrawNum (240, 104, cl.stats[STAT_SECRETS], 3, 0);
+       }
 
+       if(cl.stats[STAT_TOTALMONSTERS])
+       {
+               Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
+               if (!IS_OLDNEXUIZ_DERIVED(gamemode))
+                       Sbar_DrawPic (232, 144, sb_slash);
+               Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
+       }
+       else
+       {
+               Sbar_DrawNum (240, 144, cl.stats[STAT_MONSTERS], 3, 0);
+       }
 }