diff --git a/src/d_net.cpp b/src/d_net.cpp index fcfe4e7d78..609311cb42 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2851,6 +2851,34 @@ void Net_SkipCommand (int type, uint8_t **stream) *stream += skip; } +// This was taken out of shared_hud, because UI code shouldn't do low level calculations that may change if the backing implementation changes. +int Net_GetLatency(int *ld, int *ad) +{ + int i, localdelay = 0, arbitratordelay = 0; + + for (i = 0; i < BACKUPTICS; i++) localdelay += netdelay[0][i]; + for (i = 0; i < BACKUPTICS; i++) arbitratordelay += netdelay[nodeforplayer[Net_Arbitrator]][i]; + arbitratordelay = ((arbitratordelay / BACKUPTICS) * ticdup) * (1000 / TICRATE); + localdelay = ((localdelay / BACKUPTICS) * ticdup) * (1000 / TICRATE); + int severity = 0; + + if (MAX(localdelay, arbitratordelay) > 200) + { + severity = 1; + } + if (MAX(localdelay, arbitratordelay) > 400) + { + severity = 2; + } + if (MAX(localdelay, arbitratordelay) >= ((BACKUPTICS / 2 - 1) * ticdup) * (1000 / TICRATE)) + { + severity = 3; + } + *ld = localdelay; + *ad = arbitratordelay; + return severity; +} + // [RH] List "ping" times CCMD (pings) { diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 2c89f51abc..d70789f2b9 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -123,8 +123,6 @@ static int statspace; DObject *althud; // scripted parts. This is here to make a gradual transition -DVector2 AM_GetPosition(); - //--------------------------------------------------------------------------- // // Draws an image into a box with its bottom center at the bottom @@ -300,8 +298,11 @@ static void DrawInventory(player_t * CPlayer, int x, int y) static void DrawFrags(player_t * CPlayer, int x, int y) { - DrawImageToBox(fragpic, x, y, 31, 17); - DrawHudNumber(HudFont, CR_GRAY, CPlayer->fragcount, x + 33, y + 17); + IFVM(AltHud, DrawFrags) + { + VMValue params[] = { althud, CPlayer, x, y }; + VMCall(func, params, countof(params), nullptr, 0); + } } @@ -314,70 +315,10 @@ static void DrawFrags(player_t * CPlayer, int x, int y) static void DrawCoordinates(player_t * CPlayer) { - DVector3 pos; - char coordstr[18]; - int h = SmallFont->GetHeight()+1; - - - if (!map_point_coordinates || !automapactive) + IFVM(AltHud, DrawCoordinates) { - pos = CPlayer->mo->Pos(); - } - else - { - DVector2 apos = AM_GetPosition(); - double z = P_PointInSector(apos)->floorplane.ZatPoint(apos); - pos = DVector3(apos, z); - } - - int xpos = hudwidth - SmallFont->StringWidth("X: -00000")-6; - int ypos = 18; - - screen->DrawText(SmallFont, hudcolor_titl, hudwidth - 6 - SmallFont->StringWidth(level.MapName), ypos, level.MapName, - DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); - - screen->DrawText(SmallFont, hudcolor_titl, hudwidth - 6 - SmallFont->StringWidth(level.LevelName), ypos + h, level.LevelName, - DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); - - int linenum = 3; - - typedef struct CoordEntry - { - const char* const format; - double value; - } - CoordEntryList[3]; - - const auto drawentries = [&](CoordEntryList&& entries) - { - for (const auto& entry : entries) - { - mysnprintf(coordstr, countof(coordstr), entry.format, entry.value); - screen->DrawText(SmallFont, hudcolor_xyco, xpos, ypos + linenum * h, coordstr, - DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); - ++linenum; - } - }; - - drawentries({ - { "X: %.0f", pos.X }, - { "Y: %.0f", pos.Y }, - { "Z: %.0f", pos.Z } - }); - - if (hud_showangles) - { - const DRotator& angles = CPlayer->mo->Angles; - ++linenum; - - drawentries({ - { "P: %.1f", angles.Pitch.Degrees }, - { "Y: %.1f", (90.0 - angles.Yaw).Normalized360().Degrees }, - { "R: %.1f", angles.Roll.Degrees }, - }); + VMValue params[] = { althud, CPlayer }; + VMCall(func, params, countof(params), nullptr, 0); } } @@ -390,88 +331,13 @@ static void DrawCoordinates(player_t * CPlayer) // //--------------------------------------------------------------------------- -static void DrawTime() +static void DrawTime(int y) { - if (!ST_IsTimeVisible()) + IFVM(AltHud, DrawTime) { - return; + VMValue params[] = { althud, y }; + VMCall(func, params, countof(params), nullptr, 0); } - - int hours = 0; - int minutes = 0; - int seconds = 0; - - if (hud_showtime < 8) - { - const int timeTicks = - hud_showtime < 4 - ? level.maptime - : (hud_showtime < 6 - ? level.time - : level.totaltime); - const int timeSeconds = Tics2Seconds(timeTicks); - - hours = timeSeconds / 3600; - minutes = (timeSeconds % 3600) / 60; - seconds = timeSeconds % 60; - } - else - { - time_t now; - time(&now); - - struct tm* timeinfo = localtime(&now); - - if (NULL != timeinfo) - { - hours = timeinfo->tm_hour; - minutes = timeinfo->tm_min; - seconds = timeinfo->tm_sec; - } - } - - const bool showMillis = 1 == hud_showtime; - const bool showSeconds = showMillis || (0 == hud_showtime % 2); - - char timeString[sizeof "HH:MM:SS.MMM"]; - - if (showMillis) - { - const int millis = (level.time % TICRATE) * (1000 / TICRATE); - - mysnprintf(timeString, sizeof(timeString), "%02i:%02i:%02i.%03i", hours, minutes, seconds, millis); - } - else if (showSeconds) - { - mysnprintf(timeString, sizeof(timeString), "%02i:%02i:%02i", hours, minutes, seconds); - } - else - { - mysnprintf(timeString, sizeof(timeString), "%02i:%02i", hours, minutes); - } - - const int characterCount = static_cast( sizeof "HH:MM" - 1 - + (showSeconds ? sizeof ":SS" - 1 : 0) - + (showMillis ? sizeof ".MMM" - 1 : 0) ); - const int width = SmallFont->GetCharWidth('0') * characterCount + 2; // small offset from screen's border - const int height = SmallFont->GetHeight(); - - DrawHudText(SmallFont, hud_timecolor, timeString, hudwidth - width, height, 0x10000); -} - -static bool IsAltHUDTextVisible() -{ - return hud_althud - && !automapactive - && (SCREENHEIGHT == viewheight) - && (11 == screenblocks); -} - -bool ST_IsTimeVisible() -{ - return IsAltHUDTextVisible() - && (hud_showtime > 0) - && (hud_showtime <= 9); } //--------------------------------------------------------------------------- @@ -480,8 +346,15 @@ bool ST_IsTimeVisible() // //--------------------------------------------------------------------------- -static void DrawLatency() +static void DrawLatency(int y) { + IFVM(AltHud, DrawLatency) + { + VMValue params[] = { althud, y }; + VMCall(func, params, countof(params), nullptr, 0); + } + + /* if (!ST_IsLatencyVisible()) { return; @@ -512,17 +385,9 @@ static void DrawLatency() const int characterCount = (int)strlen(tempstr); const int width = SmallFont->GetCharWidth('0') * characterCount + 2; // small offset from screen's border - const int height = SmallFont->GetHeight() * (ST_IsTimeVisible() ? 2 : 1); - DrawHudText(SmallFont, color, tempstr, hudwidth - width, height, 0x10000); -} - -bool ST_IsLatencyVisible() -{ - return IsAltHUDTextVisible() - && (hud_showlag > 0) - && (hud_showlag != 1 || netgame) - && (hud_showlag <= 2); + DrawHudText(SmallFont, color, tempstr, hudwidth - width, y, 0x10000); + */ } //--------------------------------------------------------------------------- @@ -608,6 +473,7 @@ void DrawHUD() althud->IntVar("tnt1a0") = tnt1a0.GetIndex(); althud->IntVar("invgem_left") = invgems[0]->id.GetIndex(); althud->IntVar("invgem_right") = invgems[1]->id.GetIndex(); + althud->IntVar("fragpic") = fragpic? fragpic->id.GetIndex() : -1; althud->PointerVar("HUDFont") = HudFont; althud->PointerVar("IndexFont") = IndexFont; @@ -632,8 +498,8 @@ void DrawHUD() DrawInventory(CPlayer, 144, hudheight-28); if (idmypos) DrawCoordinates(CPlayer); - DrawTime(); - DrawLatency(); + DrawTime(SmallFont->GetHeight()); + DrawLatency(SmallFont->GetHeight()*2); // to be fixed when fully scripted. DrawPowerups(CPlayer); } else diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 264749d23b..2f895081aa 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -52,9 +52,6 @@ enum EHudState HUD_AltHud // Used for passing through popups to the alt hud }; -bool ST_IsTimeVisible(); -bool ST_IsLatencyVisible(); - // HUD Message base object -------------------------------------------------- // This is a mo-op base class to allow derived ZScript message types that can be managed by the status bar. diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp index 0e63f1fcd1..9fab4326fe 100644 --- a/src/scripting/vmthunks.cpp +++ b/src/scripting/vmthunks.cpp @@ -41,6 +41,9 @@ #include "p_acs.h" #include "a_pickups.h" +DVector2 AM_GetPosition(); +int Net_GetLatency(int *ld, int *ad); + //===================================================================================== // // sector_t exports @@ -2092,14 +2095,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(DHUDFont, Create, CreateHudFont) // //===================================================================================== -void FormatMapName(FLevelLocals *self, int cr, FString *result) +static void FormatMapName(FLevelLocals *self, int cr, FString *result) { char mapnamecolor[3] = { '\34', char(cr + 'A'), 0 }; ST_FormatMapName(*result, mapnamecolor); } - -DEFINE_ACTION_FUNCTION(FLevelLocals, FormatMapName) +DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, FormatMapName, FormatMapName) { PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); PARAM_INT(cr); @@ -2108,6 +2110,43 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, FormatMapName) ACTION_RETURN_STRING(rets); } +static void GetAutomapPosition(DVector2 *pos) +{ + *pos = AM_GetPosition(); +} + +DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, GetAutomapPosition, GetAutomapPosition) +{ + PARAM_PROLOGUE; + ACTION_RETURN_VEC2(AM_GetPosition()); +} + + +static int GetRealTime() +{ + time_t now; + time(&now); + struct tm* timeinfo = localtime(&now); + return timeinfo ? timeinfo->tm_sec + timeinfo->tm_min * 60 + timeinfo->tm_hour * 3600 : 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_AltHUD, GetRealTime, GetRealTime) +{ + PARAM_PROLOGUE; + ACTION_RETURN_INT(GetRealTime()); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_AltHUD, GetLatency, Net_GetLatency) +{ + PARAM_PROLOGUE; + int ld, ad; + int severity = Net_GetLatency(&ld, &ad); + if (numret > 0) ret[0].SetInt(severity); + if (numret > 1) ret[1].SetInt(ld); + if (numret > 2) ret[2].SetInt(ad); + return numret; +} + DEFINE_FIELD_X(Sector, sector_t, floorplane) diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index a3e907af34..0d321dc139 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -680,6 +680,7 @@ struct LevelLocals native native static void StartSlideshow(Name whichone = 'none'); native static void WorldDone(); native static void RemoveAllBots(bool fromlist); + native static Vector2 GetAutomapPosition(); native void SetInterMusic(String nextmap); native String FormatMapName(int mapnamecolor); native bool IsJumpingAllowed() const; diff --git a/wadsrc/static/zscript/mapdata.txt b/wadsrc/static/zscript/mapdata.txt index 4db3a765d1..cf2458c10b 100644 --- a/wadsrc/static/zscript/mapdata.txt +++ b/wadsrc/static/zscript/mapdata.txt @@ -365,7 +365,7 @@ struct Sector native play native double, Sector, F3DFloor NextLowestFloorAt(double x, double y, double z, int flags = 0, double steph = 0); native void RemoveForceField(); - native static Sector PointInSector(Vector2 pt); + native static clearscope Sector PointInSector(Vector2 pt); native bool PlaneMoving(int pos); native int GetFloorLight(); diff --git a/wadsrc/static/zscript/statusbar/alt_hud.txt b/wadsrc/static/zscript/statusbar/alt_hud.txt index 15271c5ab9..f04c0389e0 100644 --- a/wadsrc/static/zscript/statusbar/alt_hud.txt +++ b/wadsrc/static/zscript/statusbar/alt_hud.txt @@ -33,10 +33,6 @@ /* -// Icons -static FTexture * fragpic; // Frags icon -static FTexture * invgems[2]; // Inventory arrows - DVector2 AM_GetPosition(); */ @@ -45,11 +41,13 @@ class AltHud ui TextureID healthPic, berserkPic; TextureID tnt1a0; TextureID invgem_left, invgem_right; + TextureID fragpic; int hudwidth, hudheight; int statspace; Font HudFont; // The font for the health and armor display Font IndexFont; // The font for the inventory indices Array< Class > orderedammos; + const POWERUPICONSIZE = 32; //--------------------------------------------------------------------------- // @@ -660,4 +658,163 @@ class AltHud ui } } + //--------------------------------------------------------------------------- + // + // Draw the Frags + // + //--------------------------------------------------------------------------- + + void DrawFrags(PlayerInfo CPlayer, int x, int y) + { + DrawImageToBox(fragpic, x, y, 31, 17); + DrawHudNumber(HudFont, Font.CR_GRAY, CPlayer.fragcount, x + 33, y + 17); + } + + //--------------------------------------------------------------------------- + // + // PROC DrawCoordinates + // + //--------------------------------------------------------------------------- + + void DrawCoordinateEntry(int xpos, int ypos, String coordstr) + { + screen.DrawText(SmallFont, hudcolor_xyco, xpos, ypos, coordstr, + DTA_KeepRatio, true, + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight); + } + + void DrawCoordinates(PlayerInfo CPlayer) + { + Vector3 pos; + String coordstr; + int h = SmallFont.GetHeight() + 1; + let mo = CPlayer.mo; + + if (!map_point_coordinates || !automapactive) + { + pos = mo.Pos; + } + else + { + pos.xy = Level.GetAutomapPosition(); + pos.z = Sector.PointInSector(pos.xy).floorplane.ZatPoint(pos.xy); + } + + int xpos = hudwidth - SmallFont.StringWidth("X: -00000")-6; + int ypos = 18; + + screen.DrawText(SmallFont, hudcolor_titl, hudwidth - 6 - SmallFont.StringWidth(level.MapName), ypos, level.MapName, + DTA_KeepRatio, true, + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight); + + screen.DrawText(SmallFont, hudcolor_titl, hudwidth - 6 - SmallFont.StringWidth(level.LevelName), ypos + h, level.LevelName, + DTA_KeepRatio, true, + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight); + + + ypos += 3 * h; + DrawCoordinateEntry(xpos, ypos, String.Format("X: %.0f", pos.X)); + ypos += h; + DrawCoordinateEntry(xpos, ypos, String.Format("Y: %.0f", pos.Y)); + ypos += h; + DrawCoordinateEntry(xpos, ypos, String.Format("Z: %.0f", pos.Z)); + ypos += h; + + if (hud_showangles) + { + DrawCoordinateEntry(xpos, ypos, String.Format("Y: %.0f", Actor.Normalize180(mo.Angle))); + ypos += h; + DrawCoordinateEntry(xpos, ypos, String.Format("P: %.0f", Actor.Normalize180(mo.Pitch))); + ypos += h; + DrawCoordinateEntry(xpos, ypos, String.Format("R: %.0f", Actor.Normalize180(mo.Roll))); + } + } + + //--------------------------------------------------------------------------- + // + // Draw in-game time + // + // Check AltHUDTime option value in wadsrc/static/menudef.txt + // for meaning of all display modes + // + //--------------------------------------------------------------------------- + private native static int GetRealTime(); + + void DrawTime(int y) + { + if (hud_showtime > 0 && hud_showtime <= 9) + { + int timeSeconds; + + if (hud_showtime < 8) + { + int timeTicks = + hud_showtime < 4 + ? level.maptime + : (hud_showtime < 6 + ? level.time + : level.totaltime); + timeSeconds = Thinker.Tics2Seconds(timeTicks); + } + else + { + timeSeconds = GetRealTime(); + } + + int hours = timeSeconds / 3600; + int minutes = (timeSeconds % 3600) / 60; + int seconds = timeSeconds % 60; + + bool showMillis = 1 == hud_showtime; + bool showSeconds = showMillis || (0 == hud_showtime % 2); + + String timeString; + + if (showMillis) + { + int millis = (level.time % Thinker.TICRATE) * (1000 / Thinker.TICRATE); + timeString = String.Format("%02i:%02i:%02i.%03i", hours, minutes, seconds, millis); + } + else if (showSeconds) + { + timeString = String.Format("%02i:%02i:%02i", hours, minutes, seconds); + } + else + { + timeString = String.Format("%02i:%02i", hours, minutes); + } + + int characterCount = timeString.length(); + int width = SmallFont.GetCharWidth("0") * characterCount + 2; // small offset from screen's border + DrawHudText(SmallFont, hud_timecolor, timeString, hudwidth - width, y, 1); + } + } + + //--------------------------------------------------------------------------- + // + // Draw in-game latency + // + // + // + //--------------------------------------------------------------------------- + native static int, int, int GetLatency(); + + static void DrawLatency(int y) + { + if ((hud_showlag > 0) && (hud_showlag != 1 || netgame) && (hud_showlag <= 2) + { + int severity, localdelay, arbitratordelay; + [severity, localdelay, arbitratordelay] = GetLatency(); + int color = severity == 0? Font.CR_GREEN : severity == 1? Font.CR_YELLOW : severity == 2? Font.CR_ORANGE : Font.CR_RED; + + String tempstr = String.Format("a:%dms - l:%dms", arbitratordelay, localdelay); + + const int characterCount = tempstr.Length(); + const int width = SmallFont.GetCharWidth("0") * characterCount + 2; // small offset from screen's border + + DrawHudText(SmallFont, color, tempstr, hudwidth - width, y, 1); + } + } + + } \ No newline at end of file