From 5d2d187b84574566afd0c05420f6465b7f88b03e Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Tue, 31 Dec 2019 09:41:42 -0500 Subject: [PATCH] - allow custom pixel ratio scaling --- src/menu/resolutionmenu.cpp | 4 +-- src/rendering/r_videoscale.cpp | 44 ++++++++++++++------------------- src/rendering/r_videoscale.h | 2 +- src/rendering/v_framebuffer.cpp | 14 +++-------- src/rendering/v_video.cpp | 6 +---- 5 files changed, 25 insertions(+), 45 deletions(-) diff --git a/src/menu/resolutionmenu.cpp b/src/menu/resolutionmenu.cpp index 77a5648f3c..0faf24e68f 100644 --- a/src/menu/resolutionmenu.cpp +++ b/src/menu/resolutionmenu.cpp @@ -45,7 +45,7 @@ CVAR(Int, menu_resolution_custom_height, 480, 0) EXTERN_CVAR(Bool, 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) @@ -87,7 +87,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/src/rendering/r_videoscale.cpp b/src/rendering/r_videoscale.cpp index f5ee42707e..bb5ad1c1e4 100644 --- a/src/rendering/r_videoscale.cpp +++ b/src/rendering/r_videoscale.cpp @@ -53,7 +53,7 @@ CUSTOM_CVAR(Int, vid_scale_customheight, VID_MIN_HEIGHT, CVAR_ARCHIVE | CVAR_GLO setsizeneeded = true; } CVAR(Bool, vid_scale_customlinear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CUSTOM_CVAR(Bool, vid_scale_customstretched, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Float, vid_scale_custompixelaspect, 1.0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { setsizeneeded = true; } @@ -63,16 +63,6 @@ namespace uint32_t min_width = VID_MIN_WIDTH; uint32_t min_height = VID_MIN_HEIGHT; - 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; - }; - float v_MinimumToFill(uint32_t inwidth, uint32_t inheight) { // sx = screen x dimension, sy = same for y @@ -127,18 +117,20 @@ namespace 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; bool isLinear; 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[NUMSCALEMODES] = { - // 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 - { true, false, [](uint32_t Width, uint32_t Height)->uint32_t { return 320; }, [](uint32_t Width, uint32_t Height)->uint32_t { return 200; }, true, false }, // 7 - 320x200 + { true, false, [](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, true, [](uint32_t Width, uint32_t Height)->uint32_t { return Width; }, [](uint32_t Width, uint32_t Height)->uint32_t { return Height; }, 1.0f, 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; }, 1.2f, 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; }, 1.2f, 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; }, 1.2f, 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; }, 1.0f, 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); }, 1.0f, false }, // 6 - Minimum Scale to Fill Entire Screen + { true, false, [](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) { @@ -204,14 +196,14 @@ int ViewportScaledHeight(int width, int height) return (int)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() @@ -263,7 +255,7 @@ CCMD (vid_setscale) vid_scale_customlinear = atob(argv[3]); if (argv.argc() > 4) { - vid_scale_customstretched = atob(argv[4]); + vid_scale_custompixelaspect = atof(argv[4]); } } vid_scalemode = 5; @@ -286,7 +278,7 @@ CCMD (vid_scaletolowest) 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; diff --git a/src/rendering/r_videoscale.h b/src/rendering/r_videoscale.h index 2fcbbc85b8..025b73a9ad 100644 --- a/src/rendering/r_videoscale.h +++ b/src/rendering/r_videoscale.h @@ -27,5 +27,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/src/rendering/v_framebuffer.cpp b/src/rendering/v_framebuffer.cpp index 15ef76ddce..eeea50f36a 100644 --- a/src/rendering/v_framebuffer.cpp +++ b/src/rendering/v_framebuffer.cpp @@ -352,16 +352,8 @@ void DFrameBuffer::SetViewportRects(IntRect *bounds) int screenWidth = GetWidth(); int screenHeight = GetHeight(); float scaleX, scaleY; - if (ViewportIsScaled43()) - { - scaleX = MIN(clientWidth / (float)screenWidth, clientHeight / (screenHeight * 1.2f)); - scaleY = scaleX * 1.2f; - } - else - { - scaleX = MIN(clientWidth / (float)screenWidth, clientHeight / (float)screenHeight); - scaleY = scaleX; - } + scaleX = 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; @@ -382,7 +374,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/src/rendering/v_video.cpp b/src/rendering/v_video.cpp index 607503bfc4..d276eca143 100644 --- a/src/rendering/v_video.cpp +++ b/src/rendering/v_video.cpp @@ -668,10 +668,6 @@ int ActiveFakeRatio(int width, int height) fakeratio = 3; } } - else if (vid_aspect == 0 && ViewportIsScaled43()) - { - fakeratio = 0; - } return fakeratio; } @@ -694,7 +690,7 @@ float ActiveRatio(int width, int height, float *trueratio) if (trueratio) *trueratio = ratio; - return (fakeratio != -1) ? forcedRatioTypes[fakeratio] : ratio; + return (fakeratio != -1) ? forcedRatioTypes[fakeratio] : (ratio / ViewportPixelAspect()); } DEFINE_ACTION_FUNCTION(_Screen, GetAspectRatio)