diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index f4e68791e6..b10b8b418d 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -182,8 +182,10 @@ void OpenGLFrameBuffer::Update() Unlock(); CheckBench(); - int clientWidth = ViewportScaledWidth(IsFullscreen() ? VideoWidth : GetClientWidth()); - int clientHeight = ViewportScaledHeight(IsFullscreen() ? VideoHeight : GetClientHeight()); + int initialWidth = IsFullscreen() ? VideoWidth : GetClientWidth(); + int initialHeight = IsFullscreen() ? VideoHeight : GetClientHeight(); + int clientWidth = ViewportScaledWidth(initialWidth, initialHeight); + int clientHeight = ViewportScaledHeight(initialWidth, initialHeight); if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) { // Do not call Resize here because it's only for software canvases diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp index 937778847f..85bddf8c64 100644 --- a/src/gl/system/gl_swframebuffer.cpp +++ b/src/gl/system/gl_swframebuffer.cpp @@ -1304,8 +1304,8 @@ void OpenGLSWFrameBuffer::Flip() if (!IsFullscreen()) { - int clientWidth = ViewportScaledWidth(GetClientWidth()); - int clientHeight = ViewportScaledHeight(GetClientHeight()); + int clientWidth = ViewportScaledWidth(GetClientWidth(), GetClientHeight()); + int clientHeight = ViewportScaledHeight(GetClientWidth(), GetClientHeight()); if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) { Resize(clientWidth, clientHeight); diff --git a/src/r_videoscale.cpp b/src/r_videoscale.cpp index 29c4eb03e2..0bffc91bfa 100644 --- a/src/r_videoscale.cpp +++ b/src/r_videoscale.cpp @@ -24,6 +24,7 @@ #include #include "c_dispatch.h" #include "c_cvars.h" +#include "v_video.h" #define NUMSCALEMODES 5 @@ -64,6 +65,8 @@ CUSTOM_CVAR(Int, vid_scalemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) self = 0; } +CVAR(Bool, vid_cropaspect, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + bool ViewportLinearScale() { if (isOutOfBounds(vid_scalemode)) @@ -72,17 +75,21 @@ bool ViewportLinearScale() return (vid_scalefactor > 1.0) ? true : vScaleTable[vid_scalemode].isLinear; } -int ViewportScaledWidth(int width) +int ViewportScaledWidth(int width, int height) { if (isOutOfBounds(vid_scalemode)) vid_scalemode = 0; + if (vid_cropaspect && height > 0) + width = (width/height > ActiveRatio(width, height)) ? height * ActiveRatio(width, height) : width; return vScaleTable[vid_scalemode].GetScaledWidth((int)((float)width * vid_scalefactor)); } -int ViewportScaledHeight(int height) +int ViewportScaledHeight(int width, int height) { if (isOutOfBounds(vid_scalemode)) vid_scalemode = 0; + if (vid_cropaspect && height > 0) + height = (width/height < ActiveRatio(width, height)) ? width / ActiveRatio(width, height) : height; return vScaleTable[vid_scalemode].GetScaledHeight((int)((float)height * vid_scalefactor)); } diff --git a/src/r_videoscale.h b/src/r_videoscale.h index 002fc7c38f..2fcbbc85b8 100644 --- a/src/r_videoscale.h +++ b/src/r_videoscale.h @@ -25,7 +25,7 @@ #define __VIDEOSCALE_H__ EXTERN_CVAR (Int, vid_scalemode) bool ViewportLinearScale(); -int ViewportScaledWidth(int width); -int ViewportScaledHeight(int height); +int ViewportScaledWidth(int width, int height); +int ViewportScaledHeight(int width, int height); bool ViewportIsScaled43(); #endif //__VIDEOSCALE_H__ \ No newline at end of file diff --git a/src/v_video.cpp b/src/v_video.cpp index 4bbe646ad9..b9dfeae086 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -783,7 +783,7 @@ void DSimpleCanvas::Unlock () //========================================================================== DFrameBuffer::DFrameBuffer (int width, int height, bool bgra) - : DSimpleCanvas (ViewportScaledWidth(width), ViewportScaledHeight(height), bgra) + : DSimpleCanvas (ViewportScaledWidth(width, height), ViewportScaledHeight(width, height), bgra) { LastMS = LastSec = FrameCount = LastCount = LastTic = 0; Accel2D = false; diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 387477151c..e68c9ae86e 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2191,6 +2191,7 @@ VIDMNU_FULLSCREEN = "Fullscreen"; VIDMNU_HIDPI = "Retina/HiDPI support"; VIDMNU_ASPECTRATIO = "Aspect ratio"; VIDMNU_FORCEASPECT = "Force aspect ratio"; +VIDMNU_CROPASPECT = "Forced ratio style"; VIDMNU_5X4ASPECTRATIO = "Enable 5:4 aspect ratio"; VIDMNU_SCALEMODE = "Resolution scale"; VIDMNU_SCALEFACTOR = "Scale Factor"; @@ -2381,6 +2382,7 @@ OPTVAL_VTAZDOOM = "Auto (ZDoom Preferred)"; OPTVAL_VTAVANILLA = "Auto (Vanilla Preferred)"; OPTVAL_SCALENEAREST = "Scaled (Nearest)"; OPTVAL_SCALELINEAR = "Scaled (Linear)"; +OPTVAL_LETTERBOX = "Letterbox"; // Colors C_BRICK = "\cabrick"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index fd46b153b9..b3cd95a21d 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1868,6 +1868,11 @@ OptionValue ScaleModes 3, "640x400" 4, "1280x800" } +OptionValue CropAspect +{ + 0, "$OPTVAL_STRETCH" + 1, "$OPTVAL_LETTERBOX" +} OptionMenu VideoModeMenu protected { @@ -1880,6 +1885,7 @@ OptionMenu VideoModeMenu protected } Option "$VIDMNU_ASPECTRATIO", "menu_screenratios", "Ratios" Option "$VIDMNU_FORCEASPECT", "vid_aspect", "ForceRatios" + Option "$VIDMNU_CROPASPECT", "vid_cropaspect", "CropAspect" Option "$VIDMNU_5X4ASPECTRATIO", "vid_tft", "YesNo" Option "$VIDMNU_SCALEMODE", "vid_scalemode", "ScaleModes" Slider "$VIDMNU_SCALEFACTOR", "vid_scalefactor", 0.25, 2.0, 0.25, 2