diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index f1dd8b9a0..cc2482220 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -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; diff --git a/src/v_video.cpp b/src/v_video.cpp index 61a9ceb7b..d82a24704 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -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 () diff --git a/src/v_video.h b/src/v_video.h index 06295b1a8..7f35f3322 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -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__ diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index dedda4602..1e319a146 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -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 };