From d11b33e8fd3ac3f1186d8868c7c56139077814ef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 2 Dec 2018 14:03:03 +0100 Subject: [PATCH] - scriptified the last components of the alternative HUD. - moved the ALTHUDCF parser PClass::StaticInit, so that it gets done right after creating the actor definitions. All left to do is not to reallocate the AltHud object for each frame but store it in a better suited place. --- src/d_main.cpp | 2 - src/g_shared/shared_hud.cpp | 200 +------------------- src/g_statusbar/shared_sbar.cpp | 4 +- src/gi.cpp | 2 + src/gi.h | 2 + src/info.cpp | 77 ++++++++ wadsrc/static/zscript/base.txt | 5 + wadsrc/static/zscript/statusbar/alt_hud.txt | 109 ++++++++++- 8 files changed, 201 insertions(+), 200 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 0a02f6d99..ac83318ad 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -119,7 +119,6 @@ extern void ReadStatistics(); extern void M_SetDefaultMode (); extern void G_NewInit (); extern void SetupPlayerClasses (); -extern void HUD_InitHud(); void DeinitMenus(); const FIWADInfo *D_FindIWAD(TArray &wadfiles, const char *iwad, const char *basewad); @@ -2536,7 +2535,6 @@ void D_DoomMain (void) //SBarInfo support. Note that the first SBARINFO lump contains the mugshot definition so it even needs to be read when a regular status bar is being used. SBarInfo::Load(); - HUD_InitHud(); if (!batchrun) { diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index f8e0e64f0..c10af90e1 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -121,55 +121,6 @@ static FTextureID tnt1a0; // We need this to check for empty sprites. static int hudwidth, hudheight; // current width/height for HUD display static int statspace; -DObject *althud; // scripted parts. This is here to make a gradual transition - -//--------------------------------------------------------------------------- -// -// Draws an image into a box with its bottom center at the bottom -// center of the box. The image is scaled down if it doesn't fit -// -//--------------------------------------------------------------------------- -static void DrawImageToBox(FTexture * tex, int x, int y, int w, int h, double trans = 0.75) -{ - IFVM(AltHud, DrawImageToBox) - { - VMValue params[] = { althud, tex->id.GetIndex(), x, y, w, h, trans }; - VMCall(func, params, countof(params), nullptr, 0); - } -} - - -//--------------------------------------------------------------------------- -// -// Draws a text but uses a fixed width for all characters -// -//--------------------------------------------------------------------------- - -static void DrawHudText(FFont *font, int color, char * text, int x, int y, double trans = 0.75) -{ - IFVM(AltHud, DrawHudText) - { - FString string = text; - VMValue params[] = { althud, font, color, &string, x, y, trans }; - VMCall(func, params, countof(params), nullptr, 0); - } -} - - -//--------------------------------------------------------------------------- -// -// Draws a number with a fixed width for all digits -// -//--------------------------------------------------------------------------- - -static void DrawHudNumber(FFont *font, int color, int num, int x, int y, double trans = 0.75) -{ - IFVM(AltHud, DrawHudNumber) - { - VMValue params[] = { althud, font, color, num, x, y, trans }; - VMCall(func, params, countof(params), nullptr, 0); - } -} //--------------------------------------------------------------------------- // @@ -189,160 +140,23 @@ void DrawHUD() // Until the script export is complete we need to do some manual setup here auto cls = PClass::FindClass("AltHud"); if (!cls) return; + DObject *althud = cls->CreateNew(); // scripted parts. This is here to make a gradual transition - althud = cls->CreateNew(); - althud->IntVar("hudwidth") = hudwidth; - althud->IntVar("hudheight") = hudheight; - althud->IntVar("statspace") = statspace; - althud->IntVar("healthpic") = healthpic? healthpic->id.GetIndex() : -1; - althud->IntVar("berserkpic") = berserkpic? berserkpic->id.GetIndex() : -1; - 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; - - if (!automapactive) { - IFVIRTUALPTRNAME(althud, "AltHud", DrawInGame) + IFVM(AltHud, Init) { - VMValue params[] = { althud, CPlayer }; + VMValue params[] = { althud }; VMCall(func, params, countof(params), nullptr, 0); } } - else + + IFVM(AltHud, Draw) { - FString mapname; - char printstr[256]; - int seconds; - int length=8*SmallFont->GetCharWidth('0'); - int fonth=SmallFont->GetHeight()+1; - int bottom=hudheight-1; - - if (am_showtotaltime) - { - seconds = Tics2Seconds(level.totaltime); - mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); - DrawHudText(SmallFont, hudcolor_ttim, printstr, hudwidth-length, bottom, 0x10000); - bottom -= fonth; - } - - if (am_showtime) - { - if (level.clusterflags&CLUSTER_HUB) - { - seconds = Tics2Seconds(level.time); - mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); - DrawHudText(SmallFont, hudcolor_time, printstr, hudwidth-length, bottom, 0x10000); - bottom -= fonth; - } - - // Single level time for hubs - seconds= Tics2Seconds(level.maptime); - mysnprintf(printstr, countof(printstr), "%02i:%02i:%02i", seconds/3600, (seconds%3600)/60, seconds%60); - DrawHudText(SmallFont, hudcolor_ltim, printstr, hudwidth-length, bottom, 0x10000); - } - - ST_FormatMapName(mapname); - screen->DrawText(SmallFont, hudcolor_titl, 1, hudheight-fonth-1, mapname, - DTA_KeepRatio, true, - DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); - - //DrawCoordinates(CPlayer); + VMValue params[] = { althud, CPlayer, hudwidth, hudheight }; + VMCall(func, params, countof(params), nullptr, 0); } if (althud) althud->Destroy(); althud = nullptr; } -///////////////////////////////////////////////////////////////////////// -// -// Initialize the fonts and other data -// -///////////////////////////////////////////////////////////////////////// - -void HUD_InitHud() -{ - switch (gameinfo.gametype) - { - case GAME_Heretic: - case GAME_Hexen: - healthpic = TexMan.FindTexture("ARTIPTN2"); - HudFont=FFont::FindFont("HUDFONT_RAVEN"); - break; - - case GAME_Strife: - healthpic = TexMan.FindTexture("I_MDKT"); - HudFont=BigFont; // Strife doesn't have anything nice so use the standard font - break; - - default: - healthpic = TexMan.FindTexture("MEDIA0"); - berserkpic = TexMan.FindTexture("PSTRA0"); - HudFont=FFont::FindFont("HUDFONT_DOOM"); - break; - } - - IndexFont = V_GetFont("INDEXFONT"); - - if (HudFont == NULL) HudFont = BigFont; - if (IndexFont == NULL) IndexFont = ConFont; // Emergency fallback - - invgems[0] = TexMan.FindTexture("INVGEML1"); - invgems[1] = TexMan.FindTexture("INVGEMR1"); - tnt1a0 = TexMan.CheckForTexture("TNT1A0", ETextureType::Sprite); - - fragpic = TexMan.FindTexture("HU_FRAGS"); // Sadly, I don't have anything usable for this. :( - - statspace = SmallFont->StringWidth("Ac:"); - - - - // Now read custom icon overrides - int lump, lastlump = 0; - - while ((lump = Wads.FindLump ("ALTHUDCF", &lastlump)) != -1) - { - FScanner sc(lump); - while (sc.GetString()) - { - if (sc.Compare("Health")) - { - sc.MustGetString(); - FTextureID tex = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch); - if (tex.isValid()) healthpic = TexMan[tex]; - } - else if (sc.Compare("Berserk")) - { - sc.MustGetString(); - FTextureID tex = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch); - if (tex.isValid()) berserkpic = TexMan[tex]; - } - else - { - PClass *ti = PClass::FindClass(sc.String); - if (!ti) - { - Printf("Unknown item class '%s' in ALTHUDCF\n", sc.String); - } - else if (!ti->IsDescendantOf(RUNTIME_CLASS(AInventory))) - { - Printf("Invalid item class '%s' in ALTHUDCF\n", sc.String); - ti=NULL; - } - sc.MustGetString(); - FTextureID tex; - - if (!sc.Compare("0") && !sc.Compare("NULL") && !sc.Compare("")) - { - tex = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch); - } - else tex.SetInvalid(); - - if (ti) ((AInventory*)GetDefaultByType(ti))->AltHUDIcon = tex; - } - } - } -} - diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 5ccbdd57f..3b03a100f 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -513,7 +513,7 @@ DVector2 DBaseStatusBar::GetHUDScale() const //--------------------------------------------------------------------------- // -// PROC GetHUDScale +// // //--------------------------------------------------------------------------- @@ -526,7 +526,7 @@ void DBaseStatusBar::BeginStatusBar(int resW, int resH, int relTop, bool forceSc //--------------------------------------------------------------------------- // -// PROC GetHUDScale +// // //--------------------------------------------------------------------------- diff --git a/src/gi.cpp b/src/gi.cpp index 8587aa143..ba7a5ede5 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -64,6 +64,8 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mSliderColor) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defaultbloodcolor) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, telefogheight) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defKickback) +DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, healthpic) +DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, berserkpic) const char *GameNames[17] = { diff --git a/src/gi.h b/src/gi.h index b4aacbaf7..4dcb972b8 100644 --- a/src/gi.h +++ b/src/gi.h @@ -191,6 +191,8 @@ struct gameinfo_t FName statusscreen_single; FName statusscreen_coop; FName statusscreen_dm; + int healthpic; // These get filled in from ALTHUDCF + int berserkpic; const char *GetFinalePage(unsigned int num) const; }; diff --git a/src/info.cpp b/src/info.cpp index 00a66b45b..ff598d4ea 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -50,6 +50,8 @@ #include "d_player.h" #include "events.h" #include "types.h" +#include "w_wad.h" +#include "g_levellocals.h" extern void LoadActors (); extern void InitBotStuff(); @@ -283,6 +285,80 @@ DEFINE_ACTION_FUNCTION(AActor, GetSpriteIndex) ACTION_RETURN_INT(GetSpriteIndex(sprt.GetChars(), false)); } +//========================================================================== +// +// Load alt HUD icons. This is meant to be an override of the item's own settings. +// +//========================================================================== + +static void LoadAltHudStuff() +{ + // Now read custom icon overrides + int lump, lastlump = 0; + + switch (gameinfo.gametype) + { + case GAME_Heretic: + case GAME_Hexen: + gameinfo.healthpic = TexMan.CheckForTexture("ARTIPTN2", ETextureType::MiscPatch).GetIndex(); + gameinfo.berserkpic = -1; + break; + + case GAME_Strife: + gameinfo.healthpic = TexMan.CheckForTexture("I_MDKT", ETextureType::MiscPatch).GetIndex(); + gameinfo.berserkpic = -1; + break; + + default: + gameinfo.healthpic = TexMan.CheckForTexture("MEDIA0", ETextureType::Sprite).GetIndex(); + gameinfo.berserkpic = TexMan.CheckForTexture("PSTRA0", ETextureType::Sprite).GetIndex(); + break; + } + + while ((lump = Wads.FindLump("ALTHUDCF", &lastlump)) != -1) + { + FScanner sc(lump); + while (sc.GetString()) + { + if (sc.Compare("Health")) + { + sc.MustGetString(); + FTextureID tex = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch); + if (tex.isValid()) gameinfo.healthpic = tex.GetIndex(); + } + else if (sc.Compare("Berserk")) + { + sc.MustGetString(); + FTextureID tex = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch); + if (tex.isValid()) gameinfo.berserkpic = tex.GetIndex(); + } + else + { + PClass *ti = PClass::FindClass(sc.String); + if (!ti) + { + Printf("Unknown item class '%s' in ALTHUDCF\n", sc.String); + } + else if (!ti->IsDescendantOf(RUNTIME_CLASS(AInventory))) + { + Printf("Invalid item class '%s' in ALTHUDCF\n", sc.String); + ti = NULL; + } + sc.MustGetString(); + FTextureID tex; + + if (!sc.Compare("0") && !sc.Compare("NULL") && !sc.Compare("")) + { + tex = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch); + } + else tex.SetInvalid(); + + if (ti) ((AInventory*)GetDefaultByType(ti))->AltHUDIcon = tex; + } + } + } +} + //========================================================================== // // PClassActor :: StaticInit STATIC @@ -314,6 +390,7 @@ void PClassActor::StaticInit() if (!batchrun) Printf ("LoadActors: Load actor definitions.\n"); ClearStrifeTypes(); LoadActors (); + LoadAltHudStuff(); InitBotStuff(); // reinit GLOBAL static stuff from gameinfo, once classes are loaded. diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index ce7a8805b..2842ddc30 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -371,6 +371,8 @@ struct GameInfoStruct native native Color defaultbloodcolor; native double telefogheight; native int defKickback; + native TextureID healthpic; + native TextureID berserkpic; } class Object native @@ -613,6 +615,9 @@ struct LevelLocals native UDMF_Sector, //UDMF_Thing // not implemented }; + + const CLUSTER_HUB = 0x00000001; // Cluster uses hub behavior + native Array<@Sector> Sectors; native Array<@Line> Lines; diff --git a/wadsrc/static/zscript/statusbar/alt_hud.txt b/wadsrc/static/zscript/statusbar/alt_hud.txt index 38f838954..0ac24c4ec 100644 --- a/wadsrc/static/zscript/statusbar/alt_hud.txt +++ b/wadsrc/static/zscript/statusbar/alt_hud.txt @@ -38,7 +38,6 @@ DVector2 AM_GetPosition(); class AltHud ui { - TextureID healthPic, berserkPic; TextureID tnt1a0; TextureID invgem_left, invgem_right; TextureID fragpic; @@ -49,6 +48,37 @@ class AltHud ui Array< Class > orderedammos; const POWERUPICONSIZE = 32; + + void Init() + { + switch (gameinfo.gametype) + { + case GAME_Heretic: + case GAME_Hexen: + HudFont = Font.FindFont("HUDFONT_RAVEN"); + break; + + case GAME_Strife: + HudFont = BigFont; // Strife doesn't have anything nice so use the standard font + break; + + default: + HudFont = Font.FindFont("HUDFONT_DOOM"); + break; + } + + IndexFont = Font.GetFont("INDEXFONT"); + + if (HudFont == NULL) HudFont = BigFont; + if (IndexFont == NULL) IndexFont = ConFont; // Emergency fallback + + invgem_left = TexMan.CheckForTexture("INVGEML1", TexMan.Type_MiscPatch); + invgem_left = TexMan.CheckForTexture("INVGEMR1", TexMan.Type_MiscPatch); + tnt1a0 = TexMan.CheckForTexture("TNT1A0", TexMan.Type_Sprite); + fragpic = TexMan.CheckForTexture("HU_FRAGS", TexMan.Type_MiscPatch); + statspace = SmallFont.StringWidth("Ac:"); + } + //--------------------------------------------------------------------------- // // Draws an image into a box with its bottom center at the bottom @@ -123,7 +153,20 @@ class AltHud ui DrawHudText(fnt, color, String.Format("%d", num), x, y, trans); } + //--------------------------------------------------------------------------- + // + // Draws a time string as hh:mm:ss + // + //--------------------------------------------------------------------------- + void DrawTimeString(Font fnt, int color, int timer, int x, int y, double trans = 0.75) + { + let seconds = Thinker.Tics2Seconds(timer); + String s = String.Format("%02i:%02i:%02i", seconds / 3600, (seconds % 3600) / 60, seconds % 60); + int length = 8 * fnt.GetCharWidth("0"); + DrawHudText(SmallFont, color, s, x-length, y, trans); + } + //=========================================================================== // // draw the status (number of kills etc) @@ -195,10 +238,10 @@ class AltHud ui Font.CR_BLUE; bool haveBerserk = hud_berserk_health - && !berserkpic.IsNull() + && !gameinfo.berserkpic.IsNull() && CPlayer.mo.FindInventory('PowerStrength'); - DrawImageToBox(haveBerserk ? berserkpic : healthpic, x, y, 31, 17); + DrawImageToBox(haveBerserk ? gameinfo.berserkpic : gameinfo.healthpic, x, y, 31, 17); DrawHudNumber(HudFont, fontcolor, health, x + 33, y + 17); } @@ -855,6 +898,12 @@ class AltHud ui } } + //--------------------------------------------------------------------------- + // + // main drawer + // + //--------------------------------------------------------------------------- + virtual void DrawInGame(PlayerInfo CPlayer) { // No HUD in the title level! @@ -884,6 +933,60 @@ class AltHud ui DrawPowerups(CPlayer, y - h + POWERUPICONSIZE * 5 / 4); } + //--------------------------------------------------------------------------- + // + // automap drawer + // + //--------------------------------------------------------------------------- + virtual void DrawAutomap(PlayerInfo CPlayer) + { + int fonth=SmallFont.GetHeight() + 1; + int bottom = hudheight - 1; + + if (am_showtotaltime) + { + DrawTimeString(SmallFont, hudcolor_ttim, level.totaltime, hudwidth-2, bottom, 1); + bottom -= fonth; + } + + if (am_showtime) + { + if (level.clusterflags & level.CLUSTER_HUB) + { + DrawTimeString(SmallFont, hudcolor_time, level.time, hudwidth-2, bottom, 1); + bottom -= fonth; + } + + // Single level time for hubs + DrawTimeString(SmallFont, hudcolor_ltim, level.maptime, hudwidth-2, bottom, 1); + } + + screen.DrawText(SmallFont, 0, 1, hudheight - fonth - 1, level.FormatMapName(hudcolor_titl), + DTA_KeepRatio, true, + DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight); + + DrawCoordinates(CPlayer); + } + + //--------------------------------------------------------------------------- + // + // main drawer + // + //--------------------------------------------------------------------------- + + void Draw(PlayerInfo CPlayer, int w, int h) + { + hudwidth = w; + hudheight = h; + if (!automapactive) + { + DrawInGame(CPlayer); + } + else + { + DrawAutomap(CPlayer); + } + } } \ No newline at end of file