- 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.
This commit is contained in:
Christoph Oelckers 2018-12-02 14:03:03 +01:00
parent ba905321b0
commit d11b33e8fd
8 changed files with 201 additions and 200 deletions

View file

@ -119,7 +119,6 @@ extern void ReadStatistics();
extern void M_SetDefaultMode (); extern void M_SetDefaultMode ();
extern void G_NewInit (); extern void G_NewInit ();
extern void SetupPlayerClasses (); extern void SetupPlayerClasses ();
extern void HUD_InitHud();
void DeinitMenus(); void DeinitMenus();
const FIWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad); const FIWADInfo *D_FindIWAD(TArray<FString> &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 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(); SBarInfo::Load();
HUD_InitHud();
if (!batchrun) if (!batchrun)
{ {

View file

@ -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 hudwidth, hudheight; // current width/height for HUD display
static int statspace; 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 // Until the script export is complete we need to do some manual setup here
auto cls = PClass::FindClass("AltHud"); auto cls = PClass::FindClass("AltHud");
if (!cls) return; 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<FFont>("HUDFont") = HudFont;
althud->PointerVar<FFont>("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); VMCall(func, params, countof(params), nullptr, 0);
} }
} }
else
IFVM(AltHud, Draw)
{ {
FString mapname; VMValue params[] = { althud, CPlayer, hudwidth, hudheight };
char printstr[256]; VMCall(func, params, countof(params), nullptr, 0);
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);
} }
if (althud) althud->Destroy(); if (althud) althud->Destroy();
althud = nullptr; 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;
}
}
}
}

View file

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

View file

@ -64,6 +64,8 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mSliderColor)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defaultbloodcolor) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defaultbloodcolor)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, telefogheight) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, telefogheight)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defKickback) 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] = const char *GameNames[17] =
{ {

View file

@ -191,6 +191,8 @@ struct gameinfo_t
FName statusscreen_single; FName statusscreen_single;
FName statusscreen_coop; FName statusscreen_coop;
FName statusscreen_dm; FName statusscreen_dm;
int healthpic; // These get filled in from ALTHUDCF
int berserkpic;
const char *GetFinalePage(unsigned int num) const; const char *GetFinalePage(unsigned int num) const;
}; };

View file

@ -50,6 +50,8 @@
#include "d_player.h" #include "d_player.h"
#include "events.h" #include "events.h"
#include "types.h" #include "types.h"
#include "w_wad.h"
#include "g_levellocals.h"
extern void LoadActors (); extern void LoadActors ();
extern void InitBotStuff(); extern void InitBotStuff();
@ -283,6 +285,80 @@ DEFINE_ACTION_FUNCTION(AActor, GetSpriteIndex)
ACTION_RETURN_INT(GetSpriteIndex(sprt.GetChars(), false)); 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 // PClassActor :: StaticInit STATIC
@ -314,6 +390,7 @@ void PClassActor::StaticInit()
if (!batchrun) Printf ("LoadActors: Load actor definitions.\n"); if (!batchrun) Printf ("LoadActors: Load actor definitions.\n");
ClearStrifeTypes(); ClearStrifeTypes();
LoadActors (); LoadActors ();
LoadAltHudStuff();
InitBotStuff(); InitBotStuff();
// reinit GLOBAL static stuff from gameinfo, once classes are loaded. // reinit GLOBAL static stuff from gameinfo, once classes are loaded.

View file

@ -371,6 +371,8 @@ struct GameInfoStruct native
native Color defaultbloodcolor; native Color defaultbloodcolor;
native double telefogheight; native double telefogheight;
native int defKickback; native int defKickback;
native TextureID healthpic;
native TextureID berserkpic;
} }
class Object native class Object native
@ -614,6 +616,9 @@ struct LevelLocals native
//UDMF_Thing // not implemented //UDMF_Thing // not implemented
}; };
const CLUSTER_HUB = 0x00000001; // Cluster uses hub behavior
native Array<@Sector> Sectors; native Array<@Sector> Sectors;
native Array<@Line> Lines; native Array<@Line> Lines;
native Array<@Side> Sides; native Array<@Side> Sides;

View file

@ -38,7 +38,6 @@ DVector2 AM_GetPosition();
class AltHud ui class AltHud ui
{ {
TextureID healthPic, berserkPic;
TextureID tnt1a0; TextureID tnt1a0;
TextureID invgem_left, invgem_right; TextureID invgem_left, invgem_right;
TextureID fragpic; TextureID fragpic;
@ -49,6 +48,37 @@ class AltHud ui
Array< Class<Ammo> > orderedammos; Array< Class<Ammo> > orderedammos;
const POWERUPICONSIZE = 32; 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 // Draws an image into a box with its bottom center at the bottom
@ -123,6 +153,19 @@ class AltHud ui
DrawHudText(fnt, color, String.Format("%d", num), x, y, trans); 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);
}
//=========================================================================== //===========================================================================
// //
@ -195,10 +238,10 @@ class AltHud ui
Font.CR_BLUE; Font.CR_BLUE;
bool haveBerserk = hud_berserk_health bool haveBerserk = hud_berserk_health
&& !berserkpic.IsNull() && !gameinfo.berserkpic.IsNull()
&& CPlayer.mo.FindInventory('PowerStrength'); && 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); DrawHudNumber(HudFont, fontcolor, health, x + 33, y + 17);
} }
@ -855,6 +898,12 @@ class AltHud ui
} }
} }
//---------------------------------------------------------------------------
//
// main drawer
//
//---------------------------------------------------------------------------
virtual void DrawInGame(PlayerInfo CPlayer) virtual void DrawInGame(PlayerInfo CPlayer)
{ {
// No HUD in the title level! // No HUD in the title level!
@ -884,6 +933,60 @@ class AltHud ui
DrawPowerups(CPlayer, y - h + POWERUPICONSIZE * 5 / 4); 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);
}
}
} }