diff --git a/src/d_main.cpp b/src/d_main.cpp index 25dc4537c..7216881d4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2569,7 +2569,13 @@ void D_DoomMain (void) P_SetupWeapons_ntohton(); //SBarInfo support. - SBarInfo::Load(); + // This needs special checking because there are two distinct methods of defining status bars. + // SBARINFO should only be picked if it is the most recently defined one, so that both + // methods can override each other if loaded in sequence. + if (gameinfo.statusbarfile > gameinfo.statusbarclassfile) + { + SBarInfo::Load(); + } HUD_InitHud(); if (!batchrun) diff --git a/src/g_level.cpp b/src/g_level.cpp index 0347e79d3..1a3d1d073 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -435,59 +435,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel) S_ResumeSound (false); } - if (StatusBar != NULL) - { - StatusBar->Destroy(); - StatusBar = NULL; - } - auto cls = PClass::FindClass("DoomStatusBar"); - - if (bTitleLevel) - { - StatusBar = new DBaseStatusBar (); - StatusBar->SetSize(0); - } - else if (cls && gameinfo.gametype == GAME_Doom) - { - StatusBar = (DBaseStatusBar*)cls->CreateNew(); - } - else if (SBarInfoScript[SCRIPT_CUSTOM] != NULL) - { - int cstype = SBarInfoScript[SCRIPT_CUSTOM]->GetGameType(); - - //Did the user specify a "base" - if(cstype == GAME_Strife) - { - StatusBar = CreateStrifeStatusBar(); - } - else if(cstype == GAME_Any) //Use the default, empty or custom. - { - StatusBar = CreateCustomStatusBar(SCRIPT_CUSTOM); - } - else - { - StatusBar = CreateCustomStatusBar(SCRIPT_DEFAULT); - } - } - if (StatusBar == NULL) - { - if (gameinfo.gametype & (GAME_DoomChex|GAME_Heretic|GAME_Hexen)) - { - StatusBar = CreateCustomStatusBar (SCRIPT_DEFAULT); - } - else if (gameinfo.gametype == GAME_Strife) - { - StatusBar = CreateStrifeStatusBar (); - } - else - { - StatusBar = new DBaseStatusBar(); - StatusBar->SetSize(0); - } - } - GC::WriteBarrier(StatusBar); - StatusBar->AttachToPlayer (&players[consoleplayer]); - StatusBar->NewGame (); + ST_CreateStatusBar(bTitleLevel); setsizeneeded = true; if (gameinfo.gametype == GAME_Strife || (SBarInfoScript[SCRIPT_CUSTOM] != NULL && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife)) diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 0079d5b71..1f8fb62e4 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -390,6 +390,7 @@ public: void DrawTopStuff (EHudState state); void FlashItem (const PClass *itemtype); void AttachToPlayer(player_t *player); + DVector2 GetHUDScale() const; virtual void FlashCrosshair (); virtual void BlendView (float blend[4]); void NewGame (); @@ -406,12 +407,9 @@ public: void DrawString(FFont *font, const FString &cstring, double x, double y, double Alpha, int translation, int align, int screenalign, int spacing = 0, bool monospaced = false, int shadowX = 0, int shadowY = 0); - void GetCoords(int &x, int &y) - { - x = ST_X; - y = ST_Y; - } - + void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false); + 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. //protected: void DrawPowerups (); @@ -423,10 +421,14 @@ public: AInventory *ValidateInvFirst (int numVisible) const; void DrawCrosshair (); + // Sizing info for ths status bar. int ST_X, ST_Y; int RelTop; int HorizontalResolution, VerticalResolution; - bool Scaled; + bool Scaled; // This needs to go away. + DVector2 defaultScale; // factor for fully scaled fullscreen display. + bool ForcedScale = false; + bool Centering; bool FixedOrigin; bool CompleteBorder; @@ -442,7 +444,6 @@ public: DVector2 drawOffset = { 0,0 }; // can be set by subclasses to offset drawing operations double drawClip[4] = { 0,0,0,0 }; // defines a clipping rectangle (not used yet) bool fullscreenOffsets = false; // current screen is displayed with fullscreen behavior. - DVector2 cleanScale; // factor for scaled fullscreen display. FMugShot mugshot; private: @@ -458,7 +459,6 @@ extern DBaseStatusBar *StatusBar; // Status bar factories ----------------------------------------------------- -DBaseStatusBar *CreateStrifeStatusBar(); DBaseStatusBar *CreateCustomStatusBar(int script=0); // Crosshair stuff ---------------------------------------------------------- @@ -466,6 +466,7 @@ DBaseStatusBar *CreateCustomStatusBar(int script=0); void ST_FormatMapName(FString &mapname, const char *mapnamecolor = ""); void ST_LoadCrosshair(bool alwaysload=false); void ST_Clear(); +void ST_CreateStatusBar(bool bTitleLevel); extern FTexture *CrosshairImage; FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale); diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index e747717cc..438c3e3d2 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -47,6 +47,7 @@ #include "a_keys.h" #include "templates.h" #include "i_system.h" +#include "sbar.h" #include "sbarinfo.h" #include "gi.h" #include "r_data/r_translate.h" @@ -72,11 +73,11 @@ enum EXTERN_CVAR(Int, fraglimit) EXTERN_CVAR(Int, screenblocks) EXTERN_CVAR(Bool, vid_fps) -EXTERN_CVAR(Bool, hud_scale) class DSBarInfo; static double nulclip[] = { 0,0,0,0 }; + //////////////////////////////////////////////////////////////////////////////// /** @@ -629,10 +630,10 @@ void SBarInfo::ParseSBarInfo(int lump) break; case SBARINFO_RESOLUTION: sc.MustGetToken(TK_IntConst); - resW = sc.Number; + _resW = sc.Number; sc.MustGetToken(','); sc.MustGetToken(TK_IntConst); - resH = sc.Number; + _resH = sc.Number; sc.MustGetToken(';'); break; case SBARINFO_STATUSBAR: @@ -818,10 +819,8 @@ void SBarInfo::Init() height = 0; spacingCharacter = '\0'; spacingAlignment = ALIGN_CENTER; - resW = 320; - resH = 200; - cleanX = -1; - cleanY = -1; + _resW = 320; + _resH = 200; for(unsigned int i = 0;i < NUMHUDS;i++) huds[i] = new SBarInfoMainBlock(this); @@ -957,14 +956,14 @@ void Popup::close() //////////////////////////////////////////////////////////////////////////////// -inline void adjustRelCenter(bool relX, bool relY, const double &x, const double &y, double &outX, double &outY, const double &xScale, const double &yScale) +inline void adjustRelCenter(bool relX, bool relY, const double &x, const double &y, double &outX, double &outY, double ScaleX, double ScaleY) { if(relX) - outX = x + (SCREENWIDTH/(hud_scale ? xScale*2 : 2)); + outX = x + (SCREENWIDTH/(ScaleX*2)); else outX = x; if(relY) - outY = y + (SCREENHEIGHT/(hud_scale ? yScale*2 : 2)); + outY = y + (SCREENHEIGHT/(ScaleY*2)); else outY = y; } @@ -1016,25 +1015,8 @@ public: CPlayer = player; } - void _ScreenSizeChanged() - { - if (uiscale > 0) - { - script->cleanX = uiscale; - script->cleanY = uiscale; - } - else - { - V_CalcCleanFacs(script->resW, script->resH, SCREENWIDTH, SCREENHEIGHT, &script->cleanX, &script->cleanY); - } - } - void _Draw (EHudState state) { - if (script->cleanX <= 0) - { // Calculate cleanX and cleanY - wrapper->CallScreenSizeChanged(); - } int hud = STBAR_NORMAL; if(state == HUD_StatusBar) { @@ -1055,11 +1037,10 @@ public: { hud = STBAR_NONE; } - bool oldhud_scale = hud_scale; if(script->huds[hud]->ForceScaled()) //scale the statusbar { if(script->huds[hud]->FullScreenOffsets()) - hud_scale = true; + wrapper->ForceHUDScale(true); else if(!Scaled) { scalingWasForced = true; @@ -1145,8 +1126,8 @@ public: else lastPopup = NULL; - // Reset hud_scale - hud_scale = oldhud_scale; + // Reset hud scale + wrapper->ForceHUDScale(false); } void _NewGame () @@ -1161,14 +1142,8 @@ public: return script->huds[STBAR_POPUPLOG]->NumCommands() == 0; } - void _SetMugShotState (const char *state_name, bool wait_till_done, bool reset) - { - script->MugShot.SetState(state_name, wait_till_done, reset); - } - void _Tick () { - script->MugShot.Tick(CPlayer); if(currentPopup != DBaseStatusBar::POP_None) { script->popups[currentPopup-1].tick(); @@ -1188,11 +1163,6 @@ public: lastInventoryBar->Tick(NULL, this, false); } - void _ReceivedWeapon(AWeapon *weapon) - { - script->MugShot.Grin(); - } - // void DSBarInfo::FlashItem(const PClass *itemtype) - Is defined with CommandDrawSelectedInventory void _FlashItem(const PClass *itemtype); @@ -1240,10 +1210,10 @@ public: if(!fullScreenOffsets) { double tmp = 0; - int stX, stY; - wrapper->GetCoords(stX, stY); - dx += stX; - dy += stY - (Scaled ? script->resH : 200) + script->height; + int barW = wrapper->HorizontalResolution, barH = wrapper->VerticalResolution; + + dx += wrapper->ST_X; + dy += wrapper->ST_Y - (Scaled ? barH : 200) + script->height; w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth; h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight; double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble(); @@ -1255,19 +1225,19 @@ public: { if(clip[0] != 0 || clip[1] != 0) { - screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, script->resW, script->resH, true); + screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, barW, barH, true); if (clip[0] == 0) dcx = 0; if (clip[1] == 0) dcy = 0; } if(clip[2] != 0 || clip[3] != 0 || clearDontDraw) - screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, script->resW, script->resH, true); - screen->VirtualToRealCoords(dx, dy, w, h, script->resW, script->resH, true); + screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, barW, barH, true); + screen->VirtualToRealCoords(dx, dy, w, h, barW, barH, true); } else { - dy += 200 - script->resH; - dcy += 200 - script->resH; - dcb += 200 - script->resH; + dy += 200 - barH; + dcy += 200 - barH; + dcb += 200 - barH; } if(clearDontDraw) @@ -1312,10 +1282,9 @@ public: { double rx, ry, rcx=0, rcy=0, rcr=INT_MAX, rcb=INT_MAX; - double xScale = !hud_scale ? 1 : script->cleanX; - double yScale = !hud_scale ? 1 : script->cleanY; + DVector2 Scale = wrapper->GetHUDScale(); - adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, xScale, yScale); + adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, Scale.X, Scale.Y); // Translation: No high res. bool xright = *x < 0 && !x.RelCenter(); @@ -1325,13 +1294,12 @@ public: h = (forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight); if(vid_fps && rx < 0 && ry >= 0) ry += 10; - if(hud_scale) - { - rx *= xScale; - ry *= yScale; - w *= xScale; - h *= yScale; - } + + rx *= Scale.X; + ry *= Scale.Y; + w *= Scale.X; + h *= Scale.Y; + if(xright) rx = SCREENWIDTH + rx; if(ybot) @@ -1340,10 +1308,10 @@ public: // Check for clipping if(clip[0] != 0 || clip[1] != 0 || clip[2] != 0 || clip[3] != 0) { - rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*xScale); - rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*yScale); - rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*xScale); - rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*yScale); + rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*Scale.X); + rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*Scale.Y); + rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*Scale.X); + rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*Scale.Y); } if(clearDontDraw) @@ -1392,8 +1360,7 @@ public: double ax = *x; double ay = *y; - double xScale = 1.0; - double yScale = 1.0; + DVector2 Scale; const uint8_t* str = (const uint8_t*) cstring; const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1); @@ -1401,12 +1368,12 @@ public: if(fullScreenOffsets) { - if(hud_scale) - { - xScale = script->cleanX; - yScale = script->cleanY; - } - adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, xScale, yScale); + Scale = wrapper->GetHUDScale(); + adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, Scale.X, Scale.Y); + } + else + { + Scale = { 1.,1. }; } while(*str != '\0') { @@ -1467,15 +1434,15 @@ public: if(!fullScreenOffsets) { - int stX, stY; - wrapper->GetCoords(stX, stY); - rx += stX; - ry += stY - (Scaled ? script->resH : 200) + script->height; + + int barW = wrapper->HorizontalResolution, barH = wrapper->VerticalResolution; + rx += wrapper->ST_X; + ry += wrapper->ST_Y - (Scaled ? barH : 200) + script->height; if(Scaled) - screen->VirtualToRealCoords(rx, ry, rw, rh, script->resW, script->resH, true); + screen->VirtualToRealCoords(rx, ry, rw, rh, barW, barH, true); else { - ry += (200 - script->resH); + ry += (200 - barH); } } else @@ -1486,13 +1453,11 @@ public: bool xright = rx < 0; bool ybot = ry < 0; - if(hud_scale) - { - rx *= xScale; - ry *= yScale; - rw *= xScale; - rh *= yScale; - } + rx *= Scale.X; + ry *= Scale.Y; + rw *= Scale.X; + rh *= Scale.Y; + if(xright) rx = SCREENWIDTH + rx; if(ybot) @@ -1501,8 +1466,8 @@ public: if(drawshadow) { double salpha = (Alpha *HR_SHADOW); - double srx = rx + (shadowX*xScale); - double sry = ry + (shadowY*yScale); + double srx = rx + (shadowX*Scale.X); + double sry = ry + (shadowY*Scale.Y); screen->DrawChar(font, CR_UNTRANSLATED, srx, sry, character, DTA_DestWidthF, rw, DTA_DestHeightF, rh, @@ -1558,11 +1523,8 @@ void SBarInfoMainBlock::DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statu { if(FullScreenOffsets()) { - if(!hud_scale) - { - rescale = true; - hud_scale = true; - } + rescale = true; + statusBar->wrapper->ForceHUDScale(true); } else if(!statusBar->Scaled) { @@ -1576,7 +1538,7 @@ void SBarInfoMainBlock::DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statu if(rescale) { if(FullScreenOffsets()) - hud_scale = false; + statusBar->wrapper->ForceHUDScale(false); else statusBar->wrapper->SetScaled(false); } @@ -1615,13 +1577,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, AttachToPlayer) return 0; } -DEFINE_ACTION_FUNCTION(DSBarInfo, ScreenSizeChanged) -{ - PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); - self->_ScreenSizeChanged(); - return 0; -} - DEFINE_ACTION_FUNCTION(DSBarInfo, Draw) { PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); @@ -1644,16 +1599,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, MustDrawLog) ACTION_RETURN_BOOL(self->_MustDrawLog((EHudState)State)); } -DEFINE_ACTION_FUNCTION(DSBarInfo, SetMugshotState) -{ - PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); - PARAM_STRING(name); - PARAM_BOOL(wait); - PARAM_BOOL(reset); - self->_SetMugShotState(name, wait, reset); - return 0; -} - DEFINE_ACTION_FUNCTION(DSBarInfo, Tick) { PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); @@ -1661,14 +1606,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, Tick) return 0; } -DEFINE_ACTION_FUNCTION(DSBarInfo, ReceivedWeapon) -{ - PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); - PARAM_OBJECT(w, AWeapon); - self->_ReceivedWeapon(w); - return 0; -} - DEFINE_ACTION_FUNCTION(DSBarInfo, FlashItem) { PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); @@ -1695,7 +1632,7 @@ DBaseStatusBar *CreateCustomStatusBar(int scriptno) auto sbar = (DBaseStatusBar*)PClass::FindClass("SBarInfoWrapper")->CreateNew(); auto core = new DSBarInfo(sbar, script); sbar->PointerVar("core") = core; - sbar->SetSize(script->height, script->resW, script->resH); + sbar->SetSize(script->height, script->_resW, script->_resH); core->_SetScaled(sbar->Scaled); sbar->CompleteBorder = script->completeBorder; return sbar; diff --git a/src/g_statusbar/sbarinfo.h b/src/g_statusbar/sbarinfo.h index 06e426773..136f814f7 100644 --- a/src/g_statusbar/sbarinfo.h +++ b/src/g_statusbar/sbarinfo.h @@ -106,11 +106,9 @@ struct SBarInfo int armorInterpolationSpeed; int height; int gameType; - FMugShot MugShot; - int resW; - int resH; - int cleanX; - int cleanY; + + int _resW; + int _resH; int GetGameType() { return gameType; } void ParseSBarInfo(int lump); diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index ccddc5939..f9b772581 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -1616,7 +1616,7 @@ class CommandDrawMugShot : public SBarInfoCommand void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar) { - FTexture *face = script->MugShot.GetFace(statusBar->CPlayer, defaultFace, accuracy, stateFlags); + FTexture *face = statusBar->wrapper->mugshot.GetFace(statusBar->CPlayer, defaultFace, accuracy, stateFlags); if (face != NULL) statusBar->DrawGraphic(face, x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); } @@ -1661,7 +1661,6 @@ class CommandDrawMugShot : public SBarInfoCommand } void Reset() { - script->MugShot.Reset(); } protected: diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 51106914e..d8c46a1dd 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -4,6 +4,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 1998-2006 Randy Heit +** Copyright 2017 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -59,6 +60,7 @@ #include "virtual.h" #include "p_acs.h" #include "r_data/r_translate.h" +#include "sbarinfo.h" #include "../version.h" @@ -81,8 +83,8 @@ EXTERN_CVAR (Bool, am_showtime) EXTERN_CVAR (Bool, am_showtotaltime) EXTERN_CVAR (Bool, noisedebug) EXTERN_CVAR (Int, con_scaletext) -EXTERN_CVAR(Bool, hud_scale) EXTERN_CVAR(Bool, vid_fps) +CVAR(Int, hud_scale, -1, CVAR_ARCHIVE); int active_con_scaletext(); @@ -90,7 +92,7 @@ DBaseStatusBar *StatusBar; extern int setblocks; -int gST_X, gST_Y; +int gST_Y; FTexture *CrosshairImage; static int CrosshairNum; @@ -222,6 +224,85 @@ void ST_Clear() CrosshairNum = 0; } +//--------------------------------------------------------------------------- +// +// create a new status bar +// +//--------------------------------------------------------------------------- + +void ST_CreateStatusBar(bool bTitleLevel) +{ + if (StatusBar != NULL) + { + StatusBar->Destroy(); + StatusBar = NULL; + } + + if (bTitleLevel) + { + StatusBar = new DBaseStatusBar(); + StatusBar->SetSize(0); + } + else if (gameinfo.statusbarclassfile >= gameinfo.statusbarfile) + { + auto cls = PClass::FindClass(gameinfo.statusbarclass); + if (cls != nullptr) + { + StatusBar = (DBaseStatusBar *)cls->CreateNew(); + IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init) + { + VMValue params[] = { StatusBar }; + GlobalVMStack.Call(func, params, 1, nullptr, 0); + } + } + } + if (StatusBar == nullptr && SBarInfoScript[SCRIPT_CUSTOM] != nullptr) + { + int cstype = SBarInfoScript[SCRIPT_CUSTOM]->GetGameType(); + + //Did the user specify a "base" + if (cstype == GAME_Any) //Use the default, empty or custom. + { + StatusBar = CreateCustomStatusBar(SCRIPT_CUSTOM); + } + else + { + StatusBar = CreateCustomStatusBar(SCRIPT_DEFAULT); + } + } + if (StatusBar == nullptr) + { + FName defname; + + if (gameinfo.gametype & GAME_DoomChex) defname = "DoomStatusBar"; + else if (gameinfo.gametype == GAME_Heretic) defname = "HereticStatusBar"; + else if (gameinfo.gametype == GAME_Hexen) defname = "HexenStatusBar"; + else if (gameinfo.gametype == GAME_Strife) defname = "StrifeStatusBar"; + if (defname != NAME_None) + { + auto cls = PClass::FindClass(defname); + if (cls != nullptr) + { + + StatusBar = (DBaseStatusBar *)cls->CreateNew(); + IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init) + { + VMValue params[] = { StatusBar }; + GlobalVMStack.Call(func, params, 1, nullptr, 0); + } + } + } + } + if (StatusBar == nullptr) + { + StatusBar = new DBaseStatusBar(); + StatusBar->SetSize(0); + } + + GC::WriteBarrier(StatusBar); + StatusBar->AttachToPlayer(&players[consoleplayer]); + StatusBar->NewGame(); +} //--------------------------------------------------------------------------- // // Constructor @@ -238,8 +319,7 @@ DBaseStatusBar::DBaseStatusBar () Displacement = 0; CPlayer = NULL; ShowLog = false; - cleanScale = { (double)CleanXfac, (double)CleanYfac }; - + defaultScale = { (double)CleanXfac, (double)CleanYfac }; } void DBaseStatusBar::SetSize(int reltop, int hres, int vres) @@ -327,7 +407,6 @@ void DBaseStatusBar::SetScaled (bool scale, bool force) } Displacement = 0; } - gST_X = ST_X; } DEFINE_ACTION_FUNCTION(DBaseStatusBar, SetScaled) @@ -349,6 +428,96 @@ void DBaseStatusBar::CallSetScaled(bool scale, bool force) else SetScaled(scale, force); } +//--------------------------------------------------------------------------- +// +// PROC GetHUDScale +// +//--------------------------------------------------------------------------- + +DVector2 DBaseStatusBar::GetHUDScale() const +{ + int scale; + if (hud_scale < 0 || ForcedScale) // a negative value is the equivalent to the old boolean hud_scale. This can yield different values for x and y for higher resolutions. + { + return defaultScale; + } + if (hud_scale > 0) // use the scale as an absolute value, but also factor in the specified resolution of the HUD + { + scale = hud_scale; + } + else if (uiscale == 0) + { + return defaultScale; + } + else + { + scale = MAX(1, uiscale); + } + + // Since status bars and HUDs can be designed for non 320x200 screens this needs to be factored in here. + // The global scaling factors are for resources at 320x200, so if the actual ones are higher resolution + // the resulting scaling factor needs to be reduced accordingly. + int realscale = MAX(1, (320 * scale) / HorizontalResolution); + return{ double(realscale), double(realscale) }; +} + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetHUDScale) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + ACTION_RETURN_VEC2(self->GetHUDScale()); +} + +//--------------------------------------------------------------------------- +// +// PROC GetHUDScale +// +//--------------------------------------------------------------------------- + +void DBaseStatusBar::BeginStatusBar(int resW, int resH, int relTop, bool completeborder, bool forceScaled) +{ + SetSize(relTop, resW, resH); + SetScaled(st_scale, forceScaled); + CompleteBorder = completeborder; + fullscreenOffsets = false; +} + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, BeginStatusBar) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_INT(w); + PARAM_INT(h); + PARAM_INT(r); + PARAM_BOOL_DEF(cb); + PARAM_BOOL_DEF(fs); + self->BeginStatusBar(w, h, r, cb, fs); + return 0; +} +//--------------------------------------------------------------------------- +// +// PROC GetHUDScale +// +//--------------------------------------------------------------------------- + +void DBaseStatusBar::BeginHUD(int resW, int resH, double Alpha, bool forcescaled) +{ + SetSize(0, resW, resH); // this intentionally resets the relative top to force the caller to go through BeginStatusBar and not just reset some variables. + this->Alpha = Alpha; + ForcedScale = forcescaled; + CompleteBorder = false; + fullscreenOffsets = true; +} + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, BeginHUD) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_INT(w); + PARAM_INT(h); + PARAM_FLOAT(a); + PARAM_BOOL_DEF(fs); + self->BeginHUD(w, h, a, fs); + return 0; +} + //--------------------------------------------------------------------------- // // PROC AttachToPlayer @@ -1016,6 +1185,16 @@ bool DBaseStatusBar::MustDrawLog(EHudState state) return true; } +DEFINE_ACTION_FUNCTION(DBaseStatusBar, SetMugshotState) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_STRING(statename); + PARAM_BOOL(wait); + PARAM_BOOL(reset); + self->mugshot.SetState(statename, wait, reset); + return 0; +} + void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, bool reset) { IFVIRTUAL(DBaseStatusBar, SetMugShotState) @@ -1024,7 +1203,6 @@ void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, b VMValue params[] = { (DObject*)this, &statestring, waitTillDone, reset }; GlobalVMStack.Call(func, params, countof(params), nullptr, 0); } - mugshot.SetState(stateName, waitTillDone, reset); } //--------------------------------------------------------------------------- @@ -1223,7 +1401,7 @@ void DBaseStatusBar::ScreenSizeChanged () int x, y; V_CalcCleanFacs(HorizontalResolution, VerticalResolution, SCREENWIDTH, SCREENHEIGHT, &x, &y); - cleanScale = { (double)x, (double)y }; + defaultScale = { (double)x, (double)y }; for (size_t i = 0; i < countof(Messages); ++i) { @@ -1423,13 +1601,12 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, dou if (screenalign == (RIGHT | TOP) && vid_fps) y += 10; - if (hud_scale) - { - x *= cleanScale.X; - y *= cleanScale.Y; - width *= cleanScale.X; - height *= cleanScale.Y; - } + DVector2 Scale = GetHUDScale(); + + x *= Scale.X; + y *= Scale.Y; + width *= Scale.X; + height *= Scale.Y; x += orgx; y += orgy; } @@ -1495,14 +1672,13 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1); int fontcolor = translation; double orgx = 0, orgy = 0; + DVector2 Scale; if (fullscreenOffsets) { - if (hud_scale) - { - shadowX *= (int)cleanScale.X; - shadowY *= (int)cleanScale.Y; - } + Scale = GetHUDScale(); + shadowX *= (int)Scale.X; + shadowY *= (int)Scale.Y; switch (screenalign & HMASK) { @@ -1520,6 +1696,10 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d if (screenalign == (RIGHT | TOP) && vid_fps) orgy += 10; } + else + { + Scale = { 1.,1. }; + } int ch; while (ch = *str++, ch != '\0') { @@ -1582,13 +1762,11 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d } else { - if (hud_scale) - { - rx *= cleanScale.X; - ry *= cleanScale.Y; - rw *= cleanScale.X; - rh *= cleanScale.Y; - } + rx *= Scale.X; + ry *= Scale.Y; + rw *= Scale.X; + rh *= Scale.Y; + rx += orgx; ry += orgy; } @@ -1697,23 +1875,11 @@ DEFINE_FIELD(DBaseStatusBar, Alpha); DEFINE_FIELD(DBaseStatusBar, drawOffset); DEFINE_FIELD(DBaseStatusBar, drawClip); DEFINE_FIELD(DBaseStatusBar, fullscreenOffsets); -DEFINE_FIELD(DBaseStatusBar, cleanScale); +DEFINE_FIELD(DBaseStatusBar, defaultScale); DEFINE_GLOBAL(StatusBar); -DBaseStatusBar *CreateStrifeStatusBar() -{ - auto sb = (DBaseStatusBar *)PClass::FindClass("StrifeStatusBar")->CreateNew(); - IFVIRTUALPTR(sb, DBaseStatusBar, Init) - { - VMValue params[] = { sb }; - GlobalVMStack.Call(func, params, 1, nullptr, 0); - } - return sb; -} - - static DObject *InitObject(PClass *type, int paramnum, VM_ARGS) { auto obj = type->CreateNew(); diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 8b4e11ab5..03f865a99 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -354,6 +354,21 @@ void FGameConfigFile::DoGlobalSetup () SetValueForKey ("5", "use ArtiInvulnerability2"); } } + if (last < 212) + { + FBaseCVar *var = FindCVar("hud_scale", NULL); + if (var != NULL) + { + var->ResetToDefault(); + } + var = FindCVar("snd_channels", NULL); + if (var != NULL) + { + // old settings were default 32, minimum 8, new settings are default 128, minimum 64. + UCVarValue v = var->GetGenericRep(CVAR_Int); + if (v.Int < 64) var->ResetToDefault(); + } + } } } } diff --git a/src/gi.cpp b/src/gi.cpp index 3c53b5b5c..ce0aada05 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -153,6 +153,14 @@ const char* GameInfoBorders[] = gameinfo.key = sc.String; \ } +#define GAMEINFOKEY_STRING_STAMPED(key, variable, stampvar) \ + else if(nextKey.CompareNoCase(variable) == 0) \ + { \ + sc.MustGetToken(TK_StringConst); \ + gameinfo.key = sc.String; \ + gameinfo.stampvar = Wads.GetLumpFile(sc.LumpNum); \ + } + #define GAMEINFOKEY_INT(key, variable) \ else if(nextKey.CompareNoCase(variable) == 0) \ { \ @@ -358,7 +366,8 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_COLOR(defaultbloodcolor, "defaultbloodcolor") GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor") GAMEINFOKEY_STRING(backpacktype, "backpacktype") - GAMEINFOKEY_STRING(statusbar, "statusbar") + GAMEINFOKEY_STRING_STAMPED(statusbar, "statusbar", statusbarfile) + GAMEINFOKEY_STRING_STAMPED(statusbarclass, "statusbarclass", statusbarclassfile) GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic") GAMEINFOKEY_STRING(CursorPic, "CursorPic") GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic") diff --git a/src/gi.h b/src/gi.h index bf9ccd450..d656e80bf 100644 --- a/src/gi.h +++ b/src/gi.h @@ -148,8 +148,11 @@ struct gameinfo_t FString translator; uint32_t defaultbloodcolor; uint32_t defaultbloodparticlecolor; - FName backpacktype; FString statusbar; + int statusbarfile = -1; + FName statusbarclass; + int statusbarclassfile = -1; + FName backpacktype; FString intermissionMusic; int intermissionOrder; FString CursorPic; diff --git a/src/st_stuff.h b/src/st_stuff.h index c95c6e801..a0434f8b4 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -26,7 +26,6 @@ struct event_t; -extern int gST_X; extern int gST_Y; bool ST_Responder(event_t* ev); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index f7e318472..291165239 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -81,7 +81,6 @@ int CleanWidth, CleanHeight; // Above minus 1 (or 1, if they are already 1) int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1; -CVAR (Bool, hud_scale, true, CVAR_ARCHIVE); DEFINE_ACTION_FUNCTION(_Screen, GetWidth) { @@ -210,33 +209,21 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double case DTA_HUDRules: case DTA_HUDRulesC: { - // Note that this has been deprecated because it cannot intelligently decide what scale - // actually needs to be used in conjunction with the active status bar. + // Note that this has been deprecated because the HUD should be drawn by the status bar. bool xright = parms->x < 0; bool ybot = parms->y < 0; + DVector2 scale = StatusBar->GetHUDScale(); - if (hud_scale) - { - parms->x *= CleanXfac; - if (parms->cleanmode == DTA_HUDRulesC) - parms->x += Width * 0.5; - else if (xright) - parms->x = Width + parms->x; - parms->y *= CleanYfac; - if (ybot) - parms->y = Height + parms->y; - parms->destwidth = parms->texwidth * CleanXfac; - parms->destheight = parms->texheight * CleanYfac; - } - else - { - if (parms->cleanmode == DTA_HUDRulesC) - parms->x += Width * 0.5; - else if (xright) - parms->x = Width + parms->x; - if (ybot) - parms->y = Height + parms->y; - } + parms->x *= scale.X; + if (parms->cleanmode == DTA_HUDRulesC) + parms->x += Width * 0.5; + else if (xright) + parms->x = Width + parms->x; + parms->y *= scale.Y; + if (ybot) + parms->y = Height + parms->y; + parms->destwidth = parms->texwidth * scale.X; + parms->destheight = parms->texheight * scale.Y; break; } } diff --git a/src/version.h b/src/version.h index 0bcbbb83e..5e357402f 100644 --- a/src/version.h +++ b/src/version.h @@ -66,7 +66,7 @@ const char *GetVersionString(); // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to // be able to migrate in FGameConfigFile::DoGlobalSetup(). -#define LASTRUNVERSION "211" +#define LASTRUNVERSION "212" // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. diff --git a/wadsrc/static/mapinfo/doomcommon.txt b/wadsrc/static/mapinfo/doomcommon.txt index f24095941..c80a8a030 100644 --- a/wadsrc/static/mapinfo/doomcommon.txt +++ b/wadsrc/static/mapinfo/doomcommon.txt @@ -27,6 +27,7 @@ gameinfo backpacktype = "Backpack" armoricons = "ARM1A0", 0.5, "ARM2A0" statusbar = "sbarinfo/doom.txt" + //statusbarclass = "DoomStatusBar" intermissionmusic = "$MUSIC_DM2INT" intermissioncounter = true weaponslot = 1, "Fist", "Chainsaw" diff --git a/wadsrc/static/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt index 17b8a1924..419c8c13f 100644 --- a/wadsrc/static/mapinfo/strife.txt +++ b/wadsrc/static/mapinfo/strife.txt @@ -66,6 +66,7 @@ gameinfo statscreen_coop = "CoopStatusScreen" statscreen_dm = "DeathmatchStatusScreen" statscreen_single = "RavenStatusScreen" + statusbarclass = "StrifeStatusBar" } DoomEdNums diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index f6f699088..545a9f31c 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -843,7 +843,6 @@ OptionMenu "HUDOptions" Option "$HUDMNU_NAMETAGS", "displaynametags", "DisplayTagsTypes" Option "$HUDMNU_NAMETAGCOLOR", "nametagcolor", "TextColors", "displaynametags" Option "$HUDMNU_SCALESTATBAR", "st_scale", "OnOff" - Option "$HUDMNU_SCALEFULLSCREENHUD", "hud_scale", "OnOff" Option "$HUDMNU_OLDOUCH", "st_oldouch", "OnOff" StaticText " " Option "$HUDMNU_HEXENFLASHES", "pf_hexenweaps", "ZDoomHexen" diff --git a/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt b/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt index e785abdb9..d58e175d1 100644 --- a/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt +++ b/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt @@ -4,13 +4,10 @@ struct SBarInfo native ui native void SetScaled(bool scaled); native void Destroy(); native void AttachToPlayer(PlayerInfo player); - native void ScreenSizeChanged(); native void Draw(int state); native void NewGame(); native bool MustDrawLog(int state); - native void SetMugShotState(String state_name, bool wait_till_done, bool reset); native void Tick(); - native clearscope void ReceivedWeapon(Weapon weapon); native void FlashItem(class itemtype); native void ShowPop(int popnum); } @@ -41,12 +38,6 @@ class SBarInfoWrapper : BaseStatusBar core.AttachToPlayer(player); } - override void ScreenSizeChanged() - { - Super.ScreenSizeChanged(); - core.ScreenSizeChanged(); - } - override void Draw(int state, double TicFrac) { Super.Draw(state, TicFrac); @@ -68,22 +59,12 @@ class SBarInfoWrapper : BaseStatusBar return core.MustDrawLog(state); } - override void SetMugShotState(String state_name, bool wait_till_done, bool reset) - { - core.SetMugShotState(state_name, wait_till_done, reset); - } - override void Tick() { Super.Tick(); core.Tick(); } - override void ReceivedWeapon(Weapon weapon) - { - core.ReceivedWeapon(weapon); - } - override void FlashItem(class itemtype) { core.FlashItem(itemtype); diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index 2a1b92492..97a153e4b 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -157,16 +157,20 @@ class BaseStatusBar native ui native double Displacement; native PlayerInfo CPlayer; native bool ShowLog; + native Vector2 defaultScale; // factor for fully scaled fullscreen display. // These are block properties for the drawers. A child class can set them to have a block of items use the same settings. native double Alpha; native Vector2 drawOffset; // can be set by subclasses to offset drawing operations native double drawClip[4]; // defines a clipping rectangle (not used yet) native bool fullscreenOffsets; // current screen is displayed with fullscreen behavior. - native Vector2 cleanScale; // factor for scaled fullscreen display. 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() {} native virtual void SetScaled(bool scale, bool force = false); @@ -174,6 +178,7 @@ class BaseStatusBar native ui native virtual void Draw (int state, double TicFrac); native virtual void ScreenSizeChanged (); native virtual clearscope void ReceivedWeapon (Weapon weapn); + native virtual clearscope void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false); virtual void FlashItem (class itemtype) {} virtual void AttachToPlayer (PlayerInfo player) { CPlayer = player; } @@ -181,7 +186,6 @@ class BaseStatusBar native ui virtual void NewGame () {} virtual void ShowPop (int popnum) { ShowLog = (popnum == POP_Log && !ShowLog); } virtual bool MustDrawLog(int state) { return true; } - virtual void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false) {} native void RefreshBackground () const; native TextureID GetMugshot(PlayerInfo player, String default_face, int accuracy, int stateflags=MugShot.STANDARD);