diff --git a/src/cmdlib.cpp b/src/cmdlib.cpp index 6fc253ff3..342ce05aa 100644 --- a/src/cmdlib.cpp +++ b/src/cmdlib.cpp @@ -596,7 +596,7 @@ int strbin (char *str) case '5': case '6': case '7': - c = 0; + c = *p - '0'; for (i = 0; i < 2; i++) { p++; @@ -699,7 +699,7 @@ FString strbin1 (const char *start) case '5': case '6': case '7': - c = 0; + c = *p - '0'; for (i = 0; i < 2; i++) { p++; diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 3ac2681f1..c27977b1b 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -403,6 +403,7 @@ public: void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false); void ForceHUDScale(bool on) { ForcedScale = on; } // This is for SBARINFO which should not use BeginStatusBar or BeginHUD. void StatusbarToRealCoords(double &x, double &y, double &w, double &h) const; + double GetTopOfStatusbar() const; //protected: void DrawPowerups (); diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index a5ed1f78a..78394038b 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -149,6 +149,16 @@ void ST_FormatMapName(FString &mapname, const char *mapnamecolor) mapname << mapnamecolor << level.LevelName; } +DEFINE_ACTION_FUNCTION(FLevelLocals, FormatMapName) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + PARAM_INT(cr); + char mapnamecolor[3] = { '\34', char(cr + 'A'), 0 }; + FString rets; + ST_FormatMapName(rets, mapnamecolor); + ACTION_RETURN_STRING(rets); +} + //--------------------------------------------------------------------------- // // Load crosshair definitions @@ -1020,88 +1030,10 @@ void DBaseStatusBar::Draw (EHudState state) } else if (automapactive) { - int y, time = Tics2Seconds(level.time), height; - int totaltime = Tics2Seconds(level.totaltime); - EColorRange highlight = (gameinfo.gametype & GAME_DoomChex) ? - CR_UNTRANSLATED : CR_YELLOW; - - height = SmallFont->GetHeight() * CleanYfac; - - // Draw timer - y = 8; - if (am_showtime) + IFVIRTUAL(DBaseStatusBar, DrawAutomapHUD) { - mysnprintf(line, countof(line), "%02d:%02d:%02d", time / 3600, (time % 3600) / 60, time % 60); // Time - screen->DrawText(SmallFont, CR_GREY, SCREENWIDTH - 80 * CleanXfac, y, line, DTA_CleanNoMove, true, TAG_DONE); - y += 8 * CleanYfac; - } - if (am_showtotaltime) - { - mysnprintf(line, countof(line), "%02d:%02d:%02d", totaltime / 3600, (totaltime % 3600) / 60, totaltime % 60); // Total time - screen->DrawText(SmallFont, CR_GREY, SCREENWIDTH - 80 * CleanXfac, y, line, DTA_CleanNoMove, true, TAG_DONE); - } - - FString mapname; - unsigned int numlines; - ST_FormatMapName(mapname, TEXTCOLOR_GREY); - int width = SmallFont->StringWidth(mapname); - FBrokenLines *lines = V_BreakLines(SmallFont, SCREENWIDTH / CleanXfac, mapname, true, &numlines); - int finalwidth = lines[numlines - 1].Width * CleanXfac; - double tmp = 0; - double hres = HorizontalResolution; - StatusbarToRealCoords(tmp, tmp, hres, tmp); - int protrusion = 0; - - IFVIRTUAL(DBaseStatusBar, GetProtrusion) - { - VMValue params[] = { (DObject*)this, finalwidth / hres }; - VMReturn ret(&protrusion); - GlobalVMStack.Call(func, params, 2, &ret, 1); - } - hres = protrusion; - StatusbarToRealCoords(tmp, tmp, tmp, hres); - - // Draw map name - y = gST_Y - height * numlines - int(hres); - - for(unsigned i = 0; i < numlines; i++) - { - screen->DrawText(SmallFont, highlight, (SCREENWIDTH - lines[i].Width * CleanXfac) / 2, y, lines[i].Text, DTA_CleanNoMove, true, TAG_DONE); - y += height; - } - - if (!deathmatch) - { - int y = 8; - - // Draw monster count - if (am_showmonsters) - { - mysnprintf (line, countof(line), "%s" TEXTCOLOR_GREY " %d/%d", - GStrings("AM_MONSTERS"), level.killed_monsters, level.total_monsters); - screen->DrawText (SmallFont, highlight, 8, y, line, - DTA_CleanNoMove, true, TAG_DONE); - y += height; - } - - // Draw secret count - if (am_showsecrets) - { - mysnprintf (line, countof(line), "%s" TEXTCOLOR_GREY " %d/%d", - GStrings("AM_SECRETS"), level.found_secrets, level.total_secrets); - screen->DrawText (SmallFont, highlight, 8, y, line, - DTA_CleanNoMove, true, TAG_DONE); - y += height; - } - - // Draw item count - if (am_showitems) - { - mysnprintf (line, countof(line), "%s" TEXTCOLOR_GREY " %d/%d", - GStrings("AM_ITEMS"), level.found_items, level.total_items); - screen->DrawText (SmallFont, highlight, 8, y, line, - DTA_CleanNoMove, true, TAG_DONE); - } + VMValue params[] = { (DObject*)this, r_viewpoint.TicFrac }; + GlobalVMStack.Call(func, params, countof(params), nullptr, 0); } } } @@ -1564,6 +1496,33 @@ void DBaseStatusBar::StatusbarToRealCoords(double &x, double &y, double &w, doub } } +DEFINE_ACTION_FUNCTION(DBaseStatusBar, StatusbarToRealCoords) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_FLOAT(x); + PARAM_FLOAT_DEF(y); + PARAM_FLOAT_DEF(w); + PARAM_FLOAT_DEF(h); + self->StatusbarToRealCoords(x, y, w, h); + if (numret > 0) ret[0].SetFloat(x); + if (numret > 1) ret[1].SetFloat(y); + if (numret > 2) ret[2].SetFloat(w); + if (numret > 3) ret[3].SetFloat(h); + return MIN(4, numret); +} + + +double DBaseStatusBar::GetTopOfStatusbar() const +{ + return gST_Y; // fixme: Get rid of this global later. +} + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetTopOfStatusbar) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + ACTION_RETURN_FLOAT(self->GetTopOfStatusbar()); +} + //============================================================================ // // draw stuff diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 379e660ce..d92f79b6d 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -521,10 +521,11 @@ struct LevelLocals native native static void WorldDone(); native static void RemoveAllBots(bool fromlist); native void SetInterMusic(String nextmap); + native String FormatMapName(int mapnamecolor); - String TimeFormatted() + String TimeFormatted(bool totals = false) { - int sec = Thinker.Tics2Seconds(time); + int sec = Thinker.Tics2Seconds(totals? totaltime : time); return String.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); } } diff --git a/wadsrc/static/zscript/statusbar/doom_sbar.txt b/wadsrc/static/zscript/statusbar/doom_sbar.txt index b1671889a..25e8bb7b9 100644 --- a/wadsrc/static/zscript/statusbar/doom_sbar.txt +++ b/wadsrc/static/zscript/statusbar/doom_sbar.txt @@ -20,6 +20,12 @@ class DoomStatusBar : BaseStatusBar diparms = InventoryBarState.Create(); } + override void DrawAutomapHUD(double ticFrac) + { + // This uses the normal automap HUD but just changes the highlight color. + DoDrawAutomapHUD(Font.CR_GREY, Font.CR_UNTRANSLATED); + } + override void Draw (int state, double TicFrac) { Super.Draw (state, TicFrac); diff --git a/wadsrc/static/zscript/statusbar/hexen_sbar.txt b/wadsrc/static/zscript/statusbar/hexen_sbar.txt index f88c70070..baac12ba0 100644 --- a/wadsrc/static/zscript/statusbar/hexen_sbar.txt +++ b/wadsrc/static/zscript/statusbar/hexen_sbar.txt @@ -36,7 +36,7 @@ class HexenStatusBar : BaseStatusBar override int GetProtrusion(double scaleratio) const { - return scaleratio > 0.85? 20 : 12; // need to get past the gargoyle's wings + return scaleratio > 0.85? 28 : 12; // need to get past the gargoyle's wings } override void Tick() diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index 7ce351c74..1659fbc50 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -291,13 +291,18 @@ class BaseStatusBar native ui native double drawClip[4]; // defines a clipping rectangle (not used yet) native bool fullscreenOffsets; // current screen is displayed with fullscreen behavior. + private HUDFont mSmallFont; + native void SetSize(int height, int vwidth, int vheight); native Vector2 GetHUDScale(); native void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false); native void BeginHUD(int resW, int resH, double Alpha, bool forcescaled = false); - virtual void Init() {} + virtual void Init() + { + mSmallFont = HUDFont.Create("SmallFont"); + } native virtual void SetScaled(bool scale, bool force = false); native virtual void Tick (); @@ -324,7 +329,8 @@ class BaseStatusBar native ui native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4); native void Fill(Color col, double x, double y, double w, double h, int flags = 0); native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = ""); - + native double, double, double, double StatusbarToRealCoords(double x, double y=0, double w=0, double h=0); + native double GetTopOfStatusBar(); //============================================================================ // @@ -673,6 +679,92 @@ class BaseStatusBar native ui } + //============================================================================ + // + // automap HUD common drawer + // This is not called directly to give a status bar the opportunity to + // change the text colors. If you want to do something different, + // override DrawAutomap directly. + // + //============================================================================ + + protected void DoDrawAutomapHUD(int crdefault, int highlight) + { + let scale = GetHUDScale(); + double textdist = 8. / scale.Y; + int height = SmallFont.GetHeight(); + String printtext; + int SCREENWIDTH = screen.GetWidth(); + + BeginHUD(320, 200, 1., false); + + // Draw timer + let y = textdist; + let width = SmallFont.StringWidth("00:00:00"); + if (am_showtime) + { + printtext = level.TimeFormatted(); + DrawString(mSmallFont, level.TimeFormatted(), (-textdist-width, y), 0, crdefault); + y += height; + } + if (am_showtotaltime) + { + DrawString(mSmallFont, level.TimeFormatted(true), (-textdist-width, y), 0, crdefault); + } + + if (!deathmatch) + { + y = textdist; + + // Draw monster count + if (am_showmonsters) + { + DrawString(mSmallFont, String.Format("%s\34%c %d/%d", Stringtable.Localize("$AM_MONSTERS"), crdefault+65, level.killed_monsters, level.total_monsters), (textdist, y), 0, highlight); + y += height; + } + + // Draw secret count + if (am_showsecrets) + { + DrawString(mSmallFont, String.Format("%s\34%c %d/%d", Stringtable.Localize("$AM_SECRETS"), crdefault+65, level.found_secrets, level.total_secrets), (textdist, y), 0, highlight); + y += height; + } + + // Draw item count + if (am_showitems) + { + DrawString(mSmallFont, String.Format("%s\34%c %d/%d", Stringtable.Localize("$AM_ITEMS"), crdefault+65, level.found_items, level.total_items), (1, y), 0, highlight); + } + } + + String mapname = level.FormatMapName(crdefault); + BrokenLines lines = SmallFont.BreakLines(mapname, SCREENWIDTH / scale.X); + int numlines = lines.Count(); + int finalwidth = SmallFont.StringWidth(lines.StringAt(numlines-1)) * scale.X; + + // calculate the top of the statusbar including any protrusion and transform it from status bar to screen space. + double tmp, hres; + [tmp, tmp, hres] = StatusbarToRealCoords(0, 0, HorizontalResolution); + int protrusion = GetProtrusion(finalwidth / hres); + [tmp, tmp, tmp, hres] = StatusbarToRealCoords(0, 0, 0, protrusion); + + + // transform the top of the status bar position from screen to HUD space (a direct transformation from status bar to HUD space does not exist.) + y = (GetTopOfStatusBar() - hres) / scale.Y - height * numlines; + + // Draw the texts centered above the status bar. + for(int i = 0; i < numlines; i++) + { + DrawString(mSmallFont, lines.StringAt(i), (0, y), DI_TEXT_ALIGN_CENTER|DI_SCREEN_HCENTER|DI_SCREEN_TOP, highlight); + y += height; + } + } + + virtual void DrawAutomapHUD(double ticFrac) + { + DoDrawAutomapHUD(Font.CR_GREY, Font.CR_YELLOW); + } + //--------------------------------------------------------------------------- // // DrawPowerups diff --git a/wadsrc/static/zscript/statusbar/strife_sbar.txt b/wadsrc/static/zscript/statusbar/strife_sbar.txt index c302eebe0..044d49a1c 100644 --- a/wadsrc/static/zscript/statusbar/strife_sbar.txt +++ b/wadsrc/static/zscript/statusbar/strife_sbar.txt @@ -76,7 +76,7 @@ class StrifeStatusBar : BaseStatusBar override int GetProtrusion(double scaleratio) const { - return 8; + return 10; } override void Draw (int state, double TicFrac)