From 21ba23f36dd16524d2e2d66d5e384a2a16d83a5b Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Wed, 1 Jan 2020 23:42:09 -0500 Subject: [PATCH] - pull most recent video scale changes from gzdoom --- source/common/menu/resolutionmenu.cpp | 7 +- source/common/rendering/r_videoscale.cpp | 121 ++++++++++++++-------- source/common/rendering/r_videoscale.h | 2 +- source/common/rendering/v_framebuffer.cpp | 14 +-- source/common/rendering/v_video.cpp | 6 +- source/common/rendering/v_video.h | 3 + 6 files changed, 91 insertions(+), 62 deletions(-) diff --git a/source/common/menu/resolutionmenu.cpp b/source/common/menu/resolutionmenu.cpp index 55bf7c516..99c511905 100644 --- a/source/common/menu/resolutionmenu.cpp +++ b/source/common/menu/resolutionmenu.cpp @@ -42,8 +42,7 @@ CVAR(Int, menu_resolution_custom_height, 480, 0) EXTERN_CVAR(Bool, vid_fullscreen) EXTERN_CVAR(Bool, win_maximized) -EXTERN_CVAR(Bool, vid_scale_customlinear) -EXTERN_CVAR(Bool, vid_scale_customstretched) +EXTERN_CVAR(Float, vid_scale_custompixelaspect) EXTERN_CVAR(Int, vid_scale_customwidth) EXTERN_CVAR(Int, vid_scale_customheight) EXTERN_CVAR(Int, vid_scalemode) @@ -73,7 +72,7 @@ CCMD (menu_resolution_commit_changes) if (do_fullscreen == false) { - vid_scalemode = vid_scale_customlinear; + vid_scalemode = 0; vid_scalefactor = 1.; screen->SetWindowSize(menu_resolution_custom_width, menu_resolution_custom_height); V_OutputResized(screen->GetClientWidth(), screen->GetClientHeight()); @@ -85,7 +84,7 @@ CCMD (menu_resolution_commit_changes) vid_scalefactor = 1.; vid_scale_customwidth = menu_resolution_custom_width; vid_scale_customheight = menu_resolution_custom_height; - vid_scale_customstretched = false; + vid_scale_custompixelaspect = 1.0; } } diff --git a/source/common/rendering/r_videoscale.cpp b/source/common/rendering/r_videoscale.cpp index d0331aca1..031334f62 100644 --- a/source/common/rendering/r_videoscale.cpp +++ b/source/common/rendering/r_videoscale.cpp @@ -35,13 +35,21 @@ #include "c_cvars.h" #include "v_video.h" #include "templates.h" -#include "printf.h" +#include "r_videoscale.h" -#define NUMSCALEMODES 7 +#include "console/c_console.h" +#include "menu/menu.h" + +#define NUMSCALEMODES countof(vScaleTable) bool setsizeneeded; +//extern bool generic_ui; EXTERN_CVAR(Int, vid_aspect) + +EXTERN_CVAR(Bool, log_vgafont) +EXTERN_CVAR(Bool, dlg_vgafont) + CUSTOM_CVAR(Int, vid_scale_customwidth, VID_MIN_WIDTH, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { if (self < VID_MIN_WIDTH) @@ -54,23 +62,18 @@ CUSTOM_CVAR(Int, vid_scale_customheight, VID_MIN_HEIGHT, CVAR_ARCHIVE | CVAR_GLO self = VID_MIN_HEIGHT; setsizeneeded = true; } -CVAR(Bool, vid_scale_customlinear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CUSTOM_CVAR(Bool, vid_scale_customstretched, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, vid_scale_linear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Float, vid_scale_custompixelaspect, 1.0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { setsizeneeded = true; + if (self < 0.2 || self > 5.0) + self = 1.0; } namespace { - struct v_ScaleTable - { - bool isValid; - bool isLinear; - uint32_t(*GetScaledWidth)(uint32_t Width, uint32_t Height); - uint32_t(*GetScaledHeight)(uint32_t Width, uint32_t Height); - bool isScaled43; - bool isCustom; - }; + uint32_t min_width = VID_MIN_WIDTH; + uint32_t min_height = VID_MIN_HEIGHT; float v_MinimumToFill(uint32_t inwidth, uint32_t inheight) { @@ -82,7 +85,7 @@ namespace if (sx <= 0. || sy <= 0.) return 1.; // prevent x/0 error // set absolute minimum scale to fill the entire screen but get as close to 640x400 as possible - float ssx = (float)(VID_MIN_WIDTH) / sx, ssy = (float)(VID_MIN_HEIGHT) / sy; + float ssx = (float)(min_width) / sx, ssy = (float)(min_height) / sy; result = (ssx < ssy) ? ssy : ssx; lastsx = sx; lastsy = sy; @@ -97,17 +100,49 @@ namespace { return (uint32_t)((float)inheight * v_MinimumToFill(inwidth, inheight)); } - - v_ScaleTable vScaleTable[NUMSCALEMODES] = + inline void refresh_minimums() { - // isValid, isLinear, GetScaledWidth(), GetScaledHeight(), isScaled43, isCustom - { true, false, [](uint32_t Width, uint32_t Height)->uint32_t { return Width; }, [](uint32_t Width, uint32_t Height)->uint32_t { return Height; }, false, false }, // 0 - Native - { true, true, [](uint32_t Width, uint32_t Height)->uint32_t { return Width; }, [](uint32_t Width, uint32_t Height)->uint32_t { return Height; }, false, false }, // 1 - Native (Linear) - { true, false, [](uint32_t Width, uint32_t Height)->uint32_t { return 640; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 400; }, true, false }, // 2 - 640x400 (formerly 320x200) - { true, true, [](uint32_t Width, uint32_t Height)->uint32_t { return 960; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 600; }, true, false }, // 3 - 960x600 (formerly 640x400) - { true, true, [](uint32_t Width, uint32_t Height)->uint32_t { return 1280; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 800; }, true, false }, // 4 - 1280x800 - { true, true, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customwidth; }, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customheight; }, true, true }, // 5 - Custom - { true, true, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillX(Width, Height); }, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillY(Width, Height); }, false, false }, // 6 - Minimum Scale to Fill Entire Screen + // specialUI is tracking a state where high-res console fonts are actually required, and + // aren't actually rendered correctly in 320x200. this forces the game to revert to the 640x400 + // minimum set in GZDoom 4.0.0, but only while those fonts are required. + + static bool lastspecialUI = false; + bool isInActualMenu = false; + +// bool specialUI = (generic_ui || !!log_vgafont || !!dlg_vgafont || ConsoleState != c_up || +// (menuactive == MENU_On && CurrentMenu && !CurrentMenu->IsKindOf("ConversationMenu"))); + bool specialUI = true; + + if (specialUI == lastspecialUI) + return; + + lastspecialUI = specialUI; + setsizeneeded = true; + + if (!specialUI) + { + min_width = VID_MIN_WIDTH; + min_height = VID_MIN_HEIGHT; + } + else + { + min_width = VID_MIN_UI_WIDTH; + min_height = VID_MIN_UI_HEIGHT; + } + } + + // the odd formatting of this struct definition is meant to resemble a table header. set your tab stops to 4 when editing this file. + struct v_ScaleTable + { bool isValid; uint32_t(*GetScaledWidth)(uint32_t Width, uint32_t Height); uint32_t(*GetScaledHeight)(uint32_t Width, uint32_t Height); float pixelAspect; bool isCustom; }; + v_ScaleTable vScaleTable[] = + { + { true, [](uint32_t Width, uint32_t Height)->uint32_t { return Width; }, [](uint32_t Width, uint32_t Height)->uint32_t { return Height; }, 1.0f, false }, // 0 - Native + { true, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillX(Width, Height); }, [](uint32_t Width, uint32_t Height)->uint32_t { return v_mfillY(Width, Height); }, 1.0f, false }, // 6 - Minimum Scale to Fill Entire Screen + { true, [](uint32_t Width, uint32_t Height)->uint32_t { return 640; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 400; }, 1.2f, false }, // 2 - 640x400 (formerly 320x200) + { true, [](uint32_t Width, uint32_t Height)->uint32_t { return 960; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 600; }, 1.2f, false }, // 3 - 960x600 (formerly 640x400) + { true, [](uint32_t Width, uint32_t Height)->uint32_t { return 1280; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 800; }, 1.2f, false }, // 4 - 1280x800 + { true, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customwidth; }, [](uint32_t Width, uint32_t Height)->uint32_t { return vid_scale_customheight; }, 1.0f, true }, // 5 - Custom + { true, [](uint32_t Width, uint32_t Height)->uint32_t { return 320; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 200; }, 1.2f, false }, // 7 - 320x200 }; bool isOutOfBounds(int x) { @@ -141,23 +176,28 @@ bool ViewportLinearScale() { if (isOutOfBounds(vid_scalemode)) vid_scalemode = 0; - // hack - use custom scaling if in "custom" mode - if (vScaleTable[vid_scalemode].isCustom) - return vid_scale_customlinear; - // vid_scalefactor > 1 == forced linear scale - return (vid_scalefactor > 1.0) ? true : vScaleTable[vid_scalemode].isLinear; + // always use linear if supersampling + int x = screen->GetClientWidth(), y = screen->GetClientHeight(); + float aspectmult = ViewportPixelAspect(); + if (aspectmult > 1.f) + aspectmult = 1.f / aspectmult; + if ((ViewportScaledWidth(x,y) > (x * aspectmult)) || (ViewportScaledHeight(x,y) > (y * aspectmult))) + return true; + + return vid_scale_linear; } int ViewportScaledWidth(int width, int height) { if (isOutOfBounds(vid_scalemode)) vid_scalemode = 0; + refresh_minimums(); if (vid_cropaspect && height > 0) { width = ((float)width/height > ActiveRatio(width, height)) ? (int)(height * ActiveRatio(width, height)) : width; height = ((float)width/height < ActiveRatio(width, height)) ? (int)(width / ActiveRatio(width, height)) : height; } - return (int)std::max((int32_t)VID_MIN_WIDTH, (int32_t)(vid_scalefactor * vScaleTable[vid_scalemode].GetScaledWidth(width, height))); + return (int)std::max((int32_t)min_width, (int32_t)(vid_scalefactor * vScaleTable[vid_scalemode].GetScaledWidth(width, height))); } int ViewportScaledHeight(int width, int height) @@ -169,17 +209,17 @@ int ViewportScaledHeight(int width, int height) height = ((float)width/height < ActiveRatio(width, height)) ? (int)(width / ActiveRatio(width, height)) : height; width = ((float)width/height > ActiveRatio(width, height)) ? (int)(height * ActiveRatio(width, height)) : width; } - return (int)std::max((int32_t)VID_MIN_HEIGHT, (int32_t)(vid_scalefactor * vScaleTable[vid_scalemode].GetScaledHeight(width, height))); + return (int)std::max((int32_t)min_height, (int32_t)(vid_scalefactor * vScaleTable[vid_scalemode].GetScaledHeight(width, height))); } -bool ViewportIsScaled43() +float ViewportPixelAspect() { if (isOutOfBounds(vid_scalemode)) vid_scalemode = 0; // hack - use custom scaling if in "custom" mode if (vScaleTable[vid_scalemode].isCustom) - return vid_scale_customstretched; - return vScaleTable[vid_scalemode].isScaled43; + return vid_scale_custompixelaspect; + return vScaleTable[vid_scalemode].pixelAspect; } void R_ShowCurrentScaling() @@ -228,10 +268,10 @@ CCMD (vid_setscale) vid_scale_customheight = atoi(argv[2]); if (argv.argc() > 3) { - vid_scale_customlinear = atob(argv[3]); + vid_scale_linear = atob(argv[3]); if (argv.argc() > 4) { - vid_scale_customstretched = atob(argv[4]); + vid_scale_custompixelaspect = (float)atof(argv[4]); } } vid_scalemode = 5; @@ -239,7 +279,7 @@ CCMD (vid_setscale) } else { - Printf("Usage: vid_setscale [bool linear] [bool long-pixel-shape]\nThis command will create a custom viewport scaling mode.\n"); + Printf("Usage: vid_setscale [bool linear] [float pixel-shape]\nThis command will create a custom viewport scaling mode.\n"); } } @@ -253,17 +293,16 @@ CCMD (vid_scaletolowest) case 1: // Method 1: set a custom video scaling vid_scalemode = 5; vid_scalefactor = 1.0; - vid_scale_customlinear = 1; - vid_scale_customstretched = 0; + vid_scale_custompixelaspect = 1.0; vid_scale_customwidth = v_mfillX(screen->GetClientWidth(), screen->GetClientHeight()); vid_scale_customheight = v_mfillY(screen->GetClientWidth(), screen->GetClientHeight()); break; case 2: // Method 2: use the actual downscaling mode directly - vid_scalemode = 6; + vid_scalemode = 1; vid_scalefactor = 1.0; break; default: // Default method: use vid_scalefactor to achieve the result on a default scaling mode - vid_scalemode = 1; + vid_scalemode = 0; vid_scalefactor = v_MinimumToFill(screen->GetClientWidth(), screen->GetClientHeight()); break; } diff --git a/source/common/rendering/r_videoscale.h b/source/common/rendering/r_videoscale.h index c927aa44d..430ad1555 100644 --- a/source/common/rendering/r_videoscale.h +++ b/source/common/rendering/r_videoscale.h @@ -36,5 +36,5 @@ EXTERN_CVAR (Int, vid_scalemode) bool ViewportLinearScale(); int ViewportScaledWidth(int width, int height); int ViewportScaledHeight(int width, int height); -bool ViewportIsScaled43(); +float ViewportPixelAspect(); #endif //__VIDEOSCALE_H__ \ No newline at end of file diff --git a/source/common/rendering/v_framebuffer.cpp b/source/common/rendering/v_framebuffer.cpp index 7f6f7169a..425ba93fc 100644 --- a/source/common/rendering/v_framebuffer.cpp +++ b/source/common/rendering/v_framebuffer.cpp @@ -254,16 +254,8 @@ void DFrameBuffer::SetViewportRects(IntRect *bounds) int screenWidth = GetWidth(); int screenHeight = GetHeight(); float scaleX, scaleY; - if (ViewportIsScaled43()) - { - scaleX = std::min(clientWidth / (float)screenWidth, clientHeight / (screenHeight * 1.2f)); - scaleY = scaleX * 1.2f; - } - else - { - scaleX = std::min(clientWidth / (float)screenWidth, clientHeight / (float)screenHeight); - scaleY = scaleX; - } + scaleX = std::min(clientWidth / (float)screenWidth, clientHeight / ((float)screenHeight * ViewportPixelAspect())); + scaleY = scaleX * ViewportPixelAspect(); mOutputLetterbox.width = (int)round(screenWidth * scaleX); mOutputLetterbox.height = (int)round(screenHeight * scaleY); mOutputLetterbox.left = (clientWidth - mOutputLetterbox.width) / 2; @@ -284,7 +276,7 @@ void DFrameBuffer::SetViewportRects(IntRect *bounds) // Scale viewports to fit letterbox bool notScaled = ((mScreenViewport.width == ViewportScaledWidth(mScreenViewport.width, mScreenViewport.height)) && (mScreenViewport.width == ViewportScaledHeight(mScreenViewport.width, mScreenViewport.height)) && - !ViewportIsScaled43()); + (ViewportPixelAspect() == 1.0)); if (gl_scale_viewport && !IsFullscreen() && notScaled) { mScreenViewport.width = mOutputLetterbox.width; diff --git a/source/common/rendering/v_video.cpp b/source/common/rendering/v_video.cpp index 1986b85ad..51044762d 100644 --- a/source/common/rendering/v_video.cpp +++ b/source/common/rendering/v_video.cpp @@ -626,7 +626,7 @@ void V_Init2() } // Helper for ActiveRatio and CheckRatio. Returns the forced ratio type, or -1 if none. -static int ActiveFakeRatio(int width, int height) +int ActiveFakeRatio(int width, int height) { int fakeratio = -1; if ((vid_aspect >= 1) && (vid_aspect <= 6)) @@ -642,10 +642,6 @@ static int ActiveFakeRatio(int width, int height) fakeratio = 3; } } - else if (vid_aspect == 0 && ViewportIsScaled43()) - { - fakeratio = 0; - } return fakeratio; } diff --git a/source/common/rendering/v_video.h b/source/common/rendering/v_video.h index 0da33a170..5904470c1 100644 --- a/source/common/rendering/v_video.h +++ b/source/common/rendering/v_video.h @@ -49,6 +49,9 @@ static const int VID_MIN_WIDTH = 640; static const int VID_MIN_HEIGHT = 400; +static const int VID_MIN_UI_WIDTH = 640; +static const int VID_MIN_UI_HEIGHT = 400; + struct sector_t; class FTexture; struct FPortalSceneState;