- scriptified and cleaned up the AltHUD's DrawCoordinates, DrawTime and DrawLatency functions.

Some backing functionality was moved elsewhere because scripting should not have access to low level system information.
This commit is contained in:
Christoph Oelckers 2018-12-02 12:24:51 +01:00
parent 4431ec06fd
commit ddaab4d2ab
7 changed files with 258 additions and 170 deletions

View file

@ -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)
{

View file

@ -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<int>( 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<FFont>("HUDFont") = HudFont;
althud->PointerVar<FFont>("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

View file

@ -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.

View file

@ -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)

View file

@ -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;

View file

@ -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();

View file

@ -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<Ammo> > 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);
}
}
}