- implemented proper scaling for the status bar.

Addresses #2.
This commit is contained in:
Christoph Oelckers 2020-07-26 23:06:27 +02:00
parent 530debd24b
commit c0d46f6a69
6 changed files with 58 additions and 186 deletions

View file

@ -218,6 +218,13 @@ CCMD(scaledown)
if (hud_scale != oldscale) gi->PlayHudSound();
}
CUSTOM_CVARD(Float, hud_statscale, 2, CVAR_ARCHIVE, "change the scale of the stats display")
{
if (self < 0.5) self = 0.5;
else if (self > 4) self = 4;
}
CVARD(Bool, hud_stats, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disable level statistics display")
CVARD(Bool, hud_showmapname, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disable map name display on load")
CVARD(Bool, hud_position, false, CVAR_ARCHIVE, "aligns the status bar to the bottom/top")

View file

@ -54,6 +54,7 @@
#include "v_draw.h"
#include "v_font.h"
#include "v_draw.h"
#include "gamecvars.h"
#include "../version.h"
@ -65,14 +66,12 @@
EXTERN_CVAR (Bool, am_showmonsters)
EXTERN_CVAR (Bool, am_showsecrets)
EXTERN_CVAR (Bool, am_showitems)
EXTERN_CVAR (Bool, am_showtime)
EXTERN_CVAR (Bool, am_showtotaltime)
EXTERN_CVAR (Bool, noisedebug)
EXTERN_CVAR (Int, con_scaletext)
EXTERN_CVAR(Bool, vid_fps)
EXTERN_CVAR(Bool, inter_subtitles)
CVAR(Int, newhud_scale, 1, CVAR_ARCHIVE)
CVAR(Bool, log_vgafont, false, CVAR_ARCHIVE)
DBaseStatusBar *StatusBar;
@ -83,29 +82,6 @@ FGameTexture *CrosshairImage;
static int CrosshairNum;
// Stretch status bar to full screen width?
CUSTOM_CVAR (Int, st_scale, 0, CVAR_ARCHIVE)
{
if (self < -1)
{
self = -1;
return;
}
if (StatusBar)
{
StatusBar->SetScale();
setsizeneeded = true;
}
}
CUSTOM_CVAR(Bool, hud_aspectscale, false, CVAR_ARCHIVE)
{
if (StatusBar)
{
StatusBar->SetScale();
setsizeneeded = true;
}
}
CVAR (Bool, crosshairon, true, CVAR_ARCHIVE);
CVAR (Int, crosshair, 0, CVAR_ARCHIVE)
CVAR (Bool, crosshairforce, false, CVAR_ARCHIVE)
@ -151,7 +127,6 @@ DBaseStatusBar::DBaseStatusBar ()
CrosshairSize = 1.;
Displacement = 0;
ShowLog = false;
defaultScale = { (double)CleanXfac, (double)CleanYfac };
SetSize(0);
}
@ -182,47 +157,6 @@ void DBaseStatusBar::SetSize(int reltop, int hres, int vres, int hhres, int hvre
SetDrawSize(reltop, hres, vres);
}
static void ST_CalcCleanFacs(int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany)
{
float ratio;
int cwidth;
int cheight;
int cx1, cy1, cx2, cy2;
ratio = ActiveRatio(realwidth, realheight);
if (AspectTallerThanWide(ratio))
{
cwidth = realwidth;
cheight = realheight * AspectMultiplier(ratio) / 48;
}
else
{
cwidth = realwidth * AspectMultiplier(ratio) / 48;
cheight = realheight;
}
// Use whichever pair of cwidth/cheight or width/height that produces less difference
// between CleanXfac and CleanYfac.
cx1 = MAX(cwidth / designwidth, 1);
cy1 = MAX(cheight / designheight, 1);
cx2 = MAX(realwidth / designwidth, 1);
cy2 = MAX(realheight / designheight, 1);
if (abs(cx1 - cy1) <= abs(cx2 - cy2) || MAX(cx1, cx2) >= 4)
{ // e.g. 640x360 looks better with this.
*cleanx = cx1;
*cleany = cy1;
}
else
{ // e.g. 720x480 looks better with this.
*cleanx = cx2;
*cleany = cy2;
}
if (*cleanx < *cleany)
*cleany = *cleanx;
else
*cleanx = *cleany;
}
void DBaseStatusBar::SetDrawSize(int reltop, int hres, int vres)
{
ValidateResolution(hres, vres);
@ -230,10 +164,6 @@ void DBaseStatusBar::SetDrawSize(int reltop, int hres, int vres)
RelTop = reltop;
HorizontalResolution = hres;
VerticalResolution = vres;
int x, y;
ST_CalcCleanFacs(hres, vres, SCREENWIDTH, SCREENHEIGHT, &x, &y);
defaultScale = { (double)x, (double)y };
SetScale(); // recalculate positioning info.
}
@ -247,55 +177,41 @@ void DBaseStatusBar::SetScale ()
{
ValidateResolution(HorizontalResolution, VerticalResolution);
int w = SCREENWIDTH;
int h = SCREENHEIGHT;
if (st_scale < 0 || ForcedScale)
{
// This is the classic fullscreen scale with aspect ratio compensation.
int sby = VerticalResolution - RelTop;
float aspect = ActiveRatio(w, h);
if (!AspectTallerThanWide(aspect))
{
// Wider or equal than 4:3
SBarTop = Scale(sby, h, VerticalResolution);
double width4_3 = w * 1.333 / aspect;
ST_X = int((w - width4_3) / 2);
}
else
{ // 5:4 resolution
ST_X = 0;
double w = SCREENWIDTH;
double h = SCREENHEIGHT;
double refw, refh;
// this was far more obtuse before...
double height4_3 = h * aspect / 1.333;
SBarTop = int(h - height4_3 + sby * height4_3 / VerticalResolution);
}
Displacement = 0;
SBarScale.X = -1;
ST_Y = 0;
int horz = HorizontalResolution;
int vert = VerticalResolution;
double refaspect = horz / double(vert);
double screenaspect = w / double(h);
if ((horz == 320 && vert == 200) || (horz == 640 && vert == 400))
{
refaspect = 1.333;
}
if (screenaspect < refaspect)
{
refw = w;
refh = w / refaspect;
}
else
{
// 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 = clamp((320 * GetUIScale(twod, st_scale)) / HorizontalResolution, 1, w / HorizontalResolution);
double realscaley = realscale * (hud_aspectscale ? 1.2 : 1.);
ST_X = (w - HorizontalResolution * realscale) / 2;
SBarTop = int(h - RelTop * realscaley);
if (RelTop > 0)
{
Displacement = double((SBarTop * VerticalResolution / h) - (VerticalResolution - RelTop))/RelTop/realscaley;
}
else
{
Displacement = 0;
}
SBarScale.X = realscale;
SBarScale.Y = realscaley;
ST_Y = int(h - VerticalResolution * realscaley);
refh = h;
refw = h * refaspect;
}
refw *= (hud_scale / 100.);
refh *= (hud_scale / 100.);
int sby = VerticalResolution - RelTop;
// Use full pixels for destination size.
ST_X = xs_CRoundToInt((w - refw) / 2);
ST_Y = xs_CRoundToInt(h - refh);
SBarTop = Scale(sby, h, VerticalResolution);
SBarScale.X = refw / horz;
SBarScale.Y = refh / vert;
}
//---------------------------------------------------------------------------
@ -306,22 +222,7 @@ void DBaseStatusBar::SetScale ()
DVector2 DBaseStatusBar::GetHUDScale() const
{
int scale;
if (newhud_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;
}
scale = GetUIScale(twod, newhud_scale);
int hres = HorizontalResolution;
int vres = VerticalResolution;
ValidateResolution(hres, vres);
// 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<int>(1, (320 * scale) / hres);
return{ double(realscale), double(realscale * (hud_aspectscale ? 1.2 : 1.)) };
return SBarScale;
}
//---------------------------------------------------------------------------
@ -330,10 +231,9 @@ DVector2 DBaseStatusBar::GetHUDScale() const
//
//---------------------------------------------------------------------------
void DBaseStatusBar::BeginStatusBar(int resW, int resH, int relTop, bool forceScaled)
void DBaseStatusBar::BeginStatusBar(int resW, int resH, int relTop)
{
SetDrawSize(relTop < 0? BaseRelTop : relTop, resW < 0? BaseSBarHorizontalResolution : resW, resH < 0? BaseSBarVerticalResolution : resH);
ForcedScale = forceScaled;
fullscreenOffsets = false;
}
@ -343,11 +243,10 @@ void DBaseStatusBar::BeginStatusBar(int resW, int resH, int relTop, bool forceSc
//
//---------------------------------------------------------------------------
void DBaseStatusBar::BeginHUD(int resW, int resH, double Alpha, bool forcescaled)
void DBaseStatusBar::BeginHUD(int resW, int resH, double Alpha)
{
SetDrawSize(RelTop, resW < 0? BaseHUDHorizontalResolution : resW, resH < 0? BaseHUDVerticalResolution : resH);
this->Alpha = Alpha;
ForcedScale = forcescaled;
CompleteBorder = false;
fullscreenOffsets = true;
}
@ -360,18 +259,6 @@ void DBaseStatusBar::BeginHUD(int resW, int resH, double Alpha, bool forcescaled
void DBaseStatusBar::Tick ()
{
if (artiflashTick > 0)
artiflashTick--;
if (itemflashFade > 0)
{
itemflashFade -= 1 / 14.;
if (itemflashFade < 0)
{
itemflashFade = 0;
}
}
}
//============================================================================
@ -382,21 +269,10 @@ void DBaseStatusBar::Tick ()
void DBaseStatusBar::StatusbarToRealCoords(double &x, double &y, double &w, double &h) const
{
if (SBarScale.X == -1 || ForcedScale)
{
int hres = HorizontalResolution;
int vres = VerticalResolution;
ValidateResolution(hres, vres);
VirtualToRealCoords(twod, x, y, w, h, hres, vres, true);
}
else
{
x = ST_X + x * SBarScale.X;
y = ST_Y + y * SBarScale.Y;
w *= SBarScale.X;
h *= SBarScale.Y;
}
x = ST_X + x * SBarScale.X;
y = ST_Y + y * SBarScale.Y;
w *= SBarScale.X;
h *= SBarScale.Y;
}
//============================================================================
@ -812,8 +688,6 @@ void FormatNumber(int number, int minsize, int maxsize, int flags, const FString
else fmt.Format("%s%*d", prefix.GetChars(), minsize, number);
}
CVAR(Float, hud_statscale, 2, CVAR_ARCHIVE)
void DBaseStatusBar::PrintLevelStats(FLevelStats &stats)
{
double y;

View file

@ -184,9 +184,8 @@ public:
void TransformRect(double &x, double &y, double &w, double &h, int flags = 0);
void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
void BeginStatusBar(int resW, int resH, int relTop, bool forceScaled);
void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false);
bool ForceHUDScale(bool on) { std::swap(ForcedScale, on); return on; } // This is for SBARINFO which should not use BeginStatusBar or BeginHUD.
void BeginStatusBar(int resW, int resH, int relTop);
void BeginHUD(int resW, int resH, double Alpha);
void StatusbarToRealCoords(double &x, double &y, double &w, double &h) const;
void PrintLevelStats(FLevelStats& stats);
int GetTopOfStatusbar() const
@ -217,8 +216,6 @@ public:
int RelTop;
int HorizontalResolution, VerticalResolution;
bool Scaled; // This needs to go away.
DVector2 defaultScale; // factor for fully scaled fullscreen display.
bool ForcedScale = false;
bool Centering;
bool FixedOrigin;
@ -226,8 +223,6 @@ public:
double CrosshairSize;
double Displacement;
bool ShowLog;
int artiflashTick = 0;
double itemflashFade = 0.75;
double Alpha = 1.;
DVector2 drawOffset = { 0,0 }; // can be set by subclasses to offset drawing operations
@ -235,10 +230,6 @@ public:
bool fullscreenOffsets = false; // current screen is displayed with fullscreen behavior.
private:
bool RepositionCoords (int &x, int &y, int xo, int yo, const int w, const int h) const;
void DrawMessages (int layer, int bottom);
void DrawConsistancy () const;
void DrawWaiting () const;
void SetDrawSize(int reltop, int hres, int vres);
int BaseRelTop;

View file

@ -246,7 +246,7 @@ public:
void DrawHud(int snum, int style)
{
auto p = &ps[snum];
BeginHUD(320, 200, 1.f, false);
BeginHUD(320, 200, 1.f);
if (style == 1)
{
DrawInventory(p, 0, -46, DI_SCREEN_CENTER_BOTTOM);
@ -356,7 +356,7 @@ public:
auto p = &ps[snum];
int h = tilesiz[TILE_BOTTOMSTATUSBAR].y;
int top = 200 - h;
BeginStatusBar(320, 200, h, true);
BeginStatusBar(320, 200, h);
DrawInventory(p, 160, 154, 0);
DrawGraphic(tileGetTexture(TILE_BOTTOMSTATUSBAR), 0, top, DI_ITEM_LEFT_TOP, 1, -1, -1, 1, 1);

View file

@ -223,7 +223,7 @@ public:
void DrawHud(int snum, int style)
{
auto p = &ps[snum];
BeginHUD(320, 200, 1.f, false);
BeginHUD(320, 200, 1.f);
if (style == 1)
{
double y = -40;
@ -291,7 +291,7 @@ public:
auto p = &ps[snum];
double h = tilesiz[BOTTOMSTATUSBAR].y * scale;
double top = 200 - h;
BeginStatusBar(320, 200, h, true);
BeginStatusBar(320, 200, h);
DrawInventory(p, 160, 154, 0);
if (hud_size < 7)

View file

@ -1017,10 +1017,9 @@ OptionMenu "HUDOptions" //protected
{
Title "$OPTMNU_HUD"
ifgame(duke, nam, ww2gi, redneck, redneckrides, fury)
ifgame(duke, nam, ww2gi, redneck, redneckrides)
{
Slider "$DSPLYMNU_SCREENSIZE", "hud_size", 0.0, 11.0, 1.0, -1
Slider "$DSPLYMNU_SBSCALE", "hud_scale", 35, 100, 5, 2
}
ifgame(blood)
{
@ -1034,12 +1033,13 @@ OptionMenu "HUDOptions" //protected
{
Slider "$DSPLYMNU_SCREENSIZE", "hud_size", 0.0, 8.0, 1.0, -1
}
Slider "$DSPLYMNU_SBSCALE", "hud_scale", 36, 100, 4, 2
StaticText ""
Option "$DSPLYMNU_LEVELSTATS", "hud_stats", "OnOff"
ifgame(duke, nam, ww2gi, redneck, redneckrides, fury, Deer)
{
Slider "$DSPLYMNU_TEXTSCALE", "hud_textscale", 100, 400, 20, 2
}
Slider "$DSPLYMNU_STATSCALE", "hud_statscale", .5, 3, 0.25, 2
//Slider "$DSPLYMNU_TEXTSCALE", "hud_textscale", 100, 400, 20, 2
StaticText ""
Option "$DSPLYMNU_MESSAGES", "hud_messages", "HudMessages"
StaticText ""