- make the clean scaling system more consistent.

Now, all menus will use the same scale, i.e. it only depends on the screen width and a base size of 640. This nearly universally yields better results than trying to make a 320x200 screen fit.
The only exceptions to this are the intermission screens and the level summary. These, unlike the menu need to try to make a 320x200 screen fit, but without all the hackery that was present to adjust the menu display.
Note that since this affects globally visible script variables, both the intermission and summary drawers will not use their own set but instead temporarily override the global setting as long as they run their own code.
Changing the use of variables here might cause much worse problems with menu code so it wasn't attempted
This commit is contained in:
Christoph Oelckers 2019-03-17 12:06:09 +01:00
parent 0ff703c361
commit 4f7ad5b130
4 changed files with 49 additions and 56 deletions

View file

@ -847,6 +847,7 @@ void DIntermissionController::OnDestroy ()
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t state)
{
ScaleOverrider s;
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Destroy();
@ -892,6 +893,7 @@ void F_StartIntermission(FName seq, uint8_t state)
bool F_Responder (event_t* ev)
{
ScaleOverrider s;
if (DIntermissionController::CurrentIntermission != NULL)
{
return DIntermissionController::CurrentIntermission->Responder(ev);
@ -907,6 +909,7 @@ bool F_Responder (event_t* ev)
void F_Ticker ()
{
ScaleOverrider s;
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Ticker();
@ -921,6 +924,7 @@ void F_Ticker ()
void F_Drawer ()
{
ScaleOverrider s;
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Drawer();
@ -936,6 +940,7 @@ void F_Drawer ()
void F_EndFinale ()
{
ScaleOverrider s;
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->Destroy();
@ -951,6 +956,7 @@ void F_EndFinale ()
void F_AdvanceIntermission()
{
ScaleOverrider s;
if (DIntermissionController::CurrentIntermission != NULL)
{
DIntermissionController::CurrentIntermission->mAdvance = true;

View file

@ -539,13 +539,10 @@ CCMD(clean)
void V_UpdateModeSize (int width, int height)
{
int cx1, cx2;
V_CalcCleanFacs(320, 200, width, height, &CleanXfac, &CleanYfac, &cx1, &cx2);
CleanWidth = width / CleanXfac;
CleanHeight = height / CleanYfac;
assert(CleanWidth >= 320 && CleanHeight >= 200);
{
// This calculates the menu scale.
// The optimal scale will always be to fit a virtual 640 pixel wide display onto the screen.
// Exceptions are made for a few ranges where the available virtual width is > 480.
int w = screen->GetWidth();
int factor;
@ -554,9 +551,9 @@ void V_UpdateModeSize (int width, int height)
else if (w >= 1600 && w < 1920) factor = 3;
else factor = w / 640;
CleanXfac_1 = CleanYfac_1 = factor;
CleanWidth_1 = width / CleanXfac_1;
CleanHeight_1 = height / CleanYfac_1;
CleanXfac = CleanYfac = CleanXfac_1 = CleanYfac_1 = factor;
CleanWidth = CleanWidth_1 = width / CleanXfac_1;
CleanHeight = CleanHeight_1 = height / CleanYfac_1;
DisplayWidth = width;
DisplayHeight = height;
@ -581,52 +578,8 @@ void V_OutputResized (int width, int height)
void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *_cx1, int *_cx2)
{
float ratio;
int cwidth;
int cheight;
int cx1, cy1, cx2, cy2;
// For larger screems always use at least a 16:9 ratio for clean factor calculation, even if the actual ratio is narrower.
if (realwidth > 1280 && (double)realwidth / realheight < 16./9)
{
realheight = realwidth * 9 / 16;
}
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;
if (_cx1 != NULL) *_cx1 = cx1;
if (_cx2 != NULL) *_cx2 = cx2;
if (designheight < 240 && realheight >= 480) designheight = 240;
*cleanx = *cleany = std::min(realwidth / designwidth, realheight / designheight);
}
bool IVideo::SetResolution ()

View file

@ -628,4 +628,35 @@ inline int active_con_scale()
}
class ScaleOverrider
{
int savedxfac, savedyfac, savedwidth, savedheight;
public:
// This is to allow certain elements to use an optimal fullscreen scale which for the menu would be too large.
// The old code contained far too much mess to compensate for the menus which negatively affected everything else.
// However, for compatibility reasons the currently used variables cannot be changed so they have to be overridden temporarily.
// This class provides a safe interface for this because it ensures that the values get restored afterward.
// Currently, the intermission and the level summary screen use this.
ScaleOverrider()
{
savedxfac = CleanXfac;
savedyfac = CleanYfac;
savedwidth = CleanWidth;
savedheight = CleanHeight;
V_CalcCleanFacs(320, 200, screen->GetWidth(), screen->GetHeight(), &CleanXfac, &CleanYfac);
CleanWidth = screen->GetWidth() / CleanXfac;
CleanHeight = screen->GetHeight() / CleanYfac;
}
~ScaleOverrider()
{
CleanXfac = savedxfac;
CleanYfac = savedyfac;
CleanWidth = savedwidth;
CleanHeight = savedheight;
}
};
#endif // __V_VIDEO_H__

View file

@ -701,6 +701,7 @@ void WI_Ticker()
{
if (WI_Screen)
{
ScaleOverrider s;
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Ticker)
{
VMValue self = WI_Screen;
@ -720,6 +721,7 @@ void WI_Drawer()
{
if (WI_Screen)
{
ScaleOverrider s;
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Drawer)
{
VMValue self = WI_Screen;
@ -767,6 +769,7 @@ void WI_Start(wbstartstruct_t *wbstartstruct)
SN_StopAllSequences(Level);
}
WI_Screen = cls->CreateNew();
ScaleOverrider s;
IFVIRTUALPTRNAME(WI_Screen, "StatusScreen", Start)
{
VMValue val[2] = { WI_Screen, wbstartstruct };