Adds the option to fit the viewport to vertical screenspace (#27061)

* Adds the option to fit your viewport to your vertical screenspace

* fixes documentation

* Removes commented-out leftover

* Hides the viewport width slider and also we dont know if the viewport width causing stretching/squishing was a bug present before but we fixed that while we were at it

* Removes commented out leftovers
This commit is contained in:
deathride58
2024-04-20 02:46:02 -04:00
committed by GitHub
parent 5c69031d11
commit 396c613366
7 changed files with 82 additions and 3 deletions

View File

@@ -36,6 +36,9 @@
<CheckBox Name="IntegerScalingCheckBox" <CheckBox Name="IntegerScalingCheckBox"
Text="{Loc 'ui-options-vp-integer-scaling'}" Text="{Loc 'ui-options-vp-integer-scaling'}"
ToolTip="{Loc 'ui-options-vp-integer-scaling-tooltip'}" /> ToolTip="{Loc 'ui-options-vp-integer-scaling-tooltip'}" />
<CheckBox Name="ViewportVerticalFitCheckBox"
Text="{Loc 'ui-options-vp-vertical-fit'}"
ToolTip="{Loc 'ui-options-vp-vertical-fit-tooltip'}" />
<CheckBox Name="ViewportLowResCheckBox" Text="{Loc 'ui-options-vp-low-res'}" /> <CheckBox Name="ViewportLowResCheckBox" Text="{Loc 'ui-options-vp-low-res'}" />
<CheckBox Name="ParallaxLowQualityCheckBox" Text="{Loc 'ui-options-parallax-low-quality'}" /> <CheckBox Name="ParallaxLowQualityCheckBox" Text="{Loc 'ui-options-parallax-low-quality'}" />
<CheckBox Name="FpsCounterCheckBox" Text="{Loc 'ui-options-fps-counter'}" /> <CheckBox Name="FpsCounterCheckBox" Text="{Loc 'ui-options-fps-counter'}" />

View File

@@ -67,6 +67,12 @@ namespace Content.Client.Options.UI.Tabs
UpdateApplyButton(); UpdateApplyButton();
}; };
ViewportVerticalFitCheckBox.OnToggled += _ =>
{
UpdateViewportScale();
UpdateApplyButton();
};
IntegerScalingCheckBox.OnToggled += OnCheckBoxToggled; IntegerScalingCheckBox.OnToggled += OnCheckBoxToggled;
ViewportLowResCheckBox.OnToggled += OnCheckBoxToggled; ViewportLowResCheckBox.OnToggled += OnCheckBoxToggled;
ParallaxLowQualityCheckBox.OnToggled += OnCheckBoxToggled; ParallaxLowQualityCheckBox.OnToggled += OnCheckBoxToggled;
@@ -79,6 +85,7 @@ namespace Content.Client.Options.UI.Tabs
ViewportScaleSlider.Value = _cfg.GetCVar(CCVars.ViewportFixedScaleFactor); ViewportScaleSlider.Value = _cfg.GetCVar(CCVars.ViewportFixedScaleFactor);
ViewportStretchCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportStretch); ViewportStretchCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportStretch);
IntegerScalingCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportSnapToleranceMargin) != 0; IntegerScalingCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportSnapToleranceMargin) != 0;
ViewportVerticalFitCheckBox.Pressed = _cfg.GetCVar(CCVars.ViewportVerticalFit);
ViewportLowResCheckBox.Pressed = !_cfg.GetCVar(CCVars.ViewportScaleRender); ViewportLowResCheckBox.Pressed = !_cfg.GetCVar(CCVars.ViewportScaleRender);
ParallaxLowQualityCheckBox.Pressed = _cfg.GetCVar(CCVars.ParallaxLowQuality); ParallaxLowQualityCheckBox.Pressed = _cfg.GetCVar(CCVars.ParallaxLowQuality);
FpsCounterCheckBox.Pressed = _cfg.GetCVar(CCVars.HudFpsCounterVisible); FpsCounterCheckBox.Pressed = _cfg.GetCVar(CCVars.HudFpsCounterVisible);
@@ -111,6 +118,7 @@ namespace Content.Client.Options.UI.Tabs
_cfg.SetCVar(CCVars.ViewportFixedScaleFactor, (int) ViewportScaleSlider.Value); _cfg.SetCVar(CCVars.ViewportFixedScaleFactor, (int) ViewportScaleSlider.Value);
_cfg.SetCVar(CCVars.ViewportSnapToleranceMargin, _cfg.SetCVar(CCVars.ViewportSnapToleranceMargin,
IntegerScalingCheckBox.Pressed ? CCVars.ViewportSnapToleranceMargin.DefaultValue : 0); IntegerScalingCheckBox.Pressed ? CCVars.ViewportSnapToleranceMargin.DefaultValue : 0);
_cfg.SetCVar(CCVars.ViewportVerticalFit, ViewportVerticalFitCheckBox.Pressed);
_cfg.SetCVar(CCVars.ViewportScaleRender, !ViewportLowResCheckBox.Pressed); _cfg.SetCVar(CCVars.ViewportScaleRender, !ViewportLowResCheckBox.Pressed);
_cfg.SetCVar(CCVars.ParallaxLowQuality, ParallaxLowQualityCheckBox.Pressed); _cfg.SetCVar(CCVars.ParallaxLowQuality, ParallaxLowQualityCheckBox.Pressed);
_cfg.SetCVar(CCVars.HudFpsCounterVisible, FpsCounterCheckBox.Pressed); _cfg.SetCVar(CCVars.HudFpsCounterVisible, FpsCounterCheckBox.Pressed);
@@ -140,6 +148,7 @@ namespace Content.Client.Options.UI.Tabs
var isVPStretchSame = ViewportStretchCheckBox.Pressed == _cfg.GetCVar(CCVars.ViewportStretch); var isVPStretchSame = ViewportStretchCheckBox.Pressed == _cfg.GetCVar(CCVars.ViewportStretch);
var isVPScaleSame = (int) ViewportScaleSlider.Value == _cfg.GetCVar(CCVars.ViewportFixedScaleFactor); var isVPScaleSame = (int) ViewportScaleSlider.Value == _cfg.GetCVar(CCVars.ViewportFixedScaleFactor);
var isIntegerScalingSame = IntegerScalingCheckBox.Pressed == (_cfg.GetCVar(CCVars.ViewportSnapToleranceMargin) != 0); var isIntegerScalingSame = IntegerScalingCheckBox.Pressed == (_cfg.GetCVar(CCVars.ViewportSnapToleranceMargin) != 0);
var isVPVerticalFitSame = ViewportVerticalFitCheckBox.Pressed == _cfg.GetCVar(CCVars.ViewportVerticalFit);
var isVPResSame = ViewportLowResCheckBox.Pressed == !_cfg.GetCVar(CCVars.ViewportScaleRender); var isVPResSame = ViewportLowResCheckBox.Pressed == !_cfg.GetCVar(CCVars.ViewportScaleRender);
var isPLQSame = ParallaxLowQualityCheckBox.Pressed == _cfg.GetCVar(CCVars.ParallaxLowQuality); var isPLQSame = ParallaxLowQualityCheckBox.Pressed == _cfg.GetCVar(CCVars.ParallaxLowQuality);
var isFpsCounterVisibleSame = FpsCounterCheckBox.Pressed == _cfg.GetCVar(CCVars.HudFpsCounterVisible); var isFpsCounterVisibleSame = FpsCounterCheckBox.Pressed == _cfg.GetCVar(CCVars.HudFpsCounterVisible);
@@ -152,6 +161,7 @@ namespace Content.Client.Options.UI.Tabs
isVPStretchSame && isVPStretchSame &&
isVPScaleSame && isVPScaleSame &&
isIntegerScalingSame && isIntegerScalingSame &&
isVPVerticalFitSame &&
isVPResSame && isVPResSame &&
isPLQSame && isPLQSame &&
isFpsCounterVisibleSame && isFpsCounterVisibleSame &&
@@ -235,6 +245,8 @@ namespace Content.Client.Options.UI.Tabs
{ {
ViewportScaleBox.Visible = !ViewportStretchCheckBox.Pressed; ViewportScaleBox.Visible = !ViewportStretchCheckBox.Pressed;
IntegerScalingCheckBox.Visible = ViewportStretchCheckBox.Pressed; IntegerScalingCheckBox.Visible = ViewportStretchCheckBox.Pressed;
ViewportVerticalFitCheckBox.Visible = ViewportStretchCheckBox.Pressed;
ViewportWidthSlider.Visible = ViewportWidthSliderDisplay.Visible = !ViewportStretchCheckBox.Pressed || ViewportStretchCheckBox.Pressed && !ViewportVerticalFitCheckBox.Pressed;
ViewportScaleText.Text = Loc.GetString("ui-options-vp-scale", ("scale", ViewportScaleSlider.Value)); ViewportScaleText.Text = Loc.GetString("ui-options-vp-scale", ("scale", ViewportScaleSlider.Value));
} }

View File

@@ -51,6 +51,7 @@ namespace Content.Client.UserInterface.Controls
var stretch = _cfg.GetCVar(CCVars.ViewportStretch); var stretch = _cfg.GetCVar(CCVars.ViewportStretch);
var renderScaleUp = _cfg.GetCVar(CCVars.ViewportScaleRender); var renderScaleUp = _cfg.GetCVar(CCVars.ViewportScaleRender);
var fixedFactor = _cfg.GetCVar(CCVars.ViewportFixedScaleFactor); var fixedFactor = _cfg.GetCVar(CCVars.ViewportFixedScaleFactor);
var verticalFit = _cfg.GetCVar(CCVars.ViewportVerticalFit);
if (stretch) if (stretch)
{ {
@@ -60,6 +61,7 @@ namespace Content.Client.UserInterface.Controls
// Did not find a snap, enable stretching. // Did not find a snap, enable stretching.
Viewport.FixedStretchSize = null; Viewport.FixedStretchSize = null;
Viewport.StretchMode = ScalingViewportStretchMode.Bilinear; Viewport.StretchMode = ScalingViewportStretchMode.Bilinear;
Viewport.IgnoreDimension = verticalFit ? ScalingViewportIgnoreDimension.Horizontal : ScalingViewportIgnoreDimension.None;
if (renderScaleUp) if (renderScaleUp)
{ {
@@ -104,6 +106,8 @@ namespace Content.Client.UserInterface.Controls
// where we are clipping the viewport to make it fit. // where we are clipping the viewport to make it fit.
var cfgToleranceClip = _cfg.GetCVar(CCVars.ViewportSnapToleranceClip); var cfgToleranceClip = _cfg.GetCVar(CCVars.ViewportSnapToleranceClip);
var cfgVerticalFit = _cfg.GetCVar(CCVars.ViewportVerticalFit);
// Calculate if the viewport, when rendered at an integer scale, // Calculate if the viewport, when rendered at an integer scale,
// is close enough to the control size to enable "snapping" to NN, // is close enough to the control size to enable "snapping" to NN,
// potentially cutting a tiny bit off/leaving a margin. // potentially cutting a tiny bit off/leaving a margin.
@@ -123,7 +127,8 @@ namespace Content.Client.UserInterface.Controls
// The rule for which snap fits is that at LEAST one axis needs to be in the tolerance size wise. // The rule for which snap fits is that at LEAST one axis needs to be in the tolerance size wise.
// One axis MAY be larger but not smaller than tolerance. // One axis MAY be larger but not smaller than tolerance.
// Obviously if it's too small it's bad, and if it's too big on both axis we should stretch up. // Obviously if it's too small it's bad, and if it's too big on both axis we should stretch up.
if (Fits(dx) && Fits(dy) || Fits(dx) && Larger(dy) || Larger(dx) && Fits(dy)) // Additionally, if the viewport's supposed to be vertically fit, then the horizontal scale should just be ignored where appropriate.
if ((Fits(dx) || cfgVerticalFit) && Fits(dy) || !cfgVerticalFit && Fits(dx) && Larger(dy) || Larger(dx) && Fits(dy))
{ {
// Found snap that fits. // Found snap that fits.
return i; return i;

View File

@@ -25,6 +25,7 @@ public sealed class ViewportUIController : UIController
_configurationManager.OnValueChanged(CCVars.ViewportMinimumWidth, _ => UpdateViewportRatio()); _configurationManager.OnValueChanged(CCVars.ViewportMinimumWidth, _ => UpdateViewportRatio());
_configurationManager.OnValueChanged(CCVars.ViewportMaximumWidth, _ => UpdateViewportRatio()); _configurationManager.OnValueChanged(CCVars.ViewportMaximumWidth, _ => UpdateViewportRatio());
_configurationManager.OnValueChanged(CCVars.ViewportWidth, _ => UpdateViewportRatio()); _configurationManager.OnValueChanged(CCVars.ViewportWidth, _ => UpdateViewportRatio());
_configurationManager.OnValueChanged(CCVars.ViewportVerticalFit, _ => UpdateViewportRatio());
var gameplayStateLoad = UIManager.GetUIController<GameplayStateLoadController>(); var gameplayStateLoad = UIManager.GetUIController<GameplayStateLoadController>();
gameplayStateLoad.OnScreenLoad += OnScreenLoad; gameplayStateLoad.OnScreenLoad += OnScreenLoad;
@@ -45,13 +46,19 @@ public sealed class ViewportUIController : UIController
var min = _configurationManager.GetCVar(CCVars.ViewportMinimumWidth); var min = _configurationManager.GetCVar(CCVars.ViewportMinimumWidth);
var max = _configurationManager.GetCVar(CCVars.ViewportMaximumWidth); var max = _configurationManager.GetCVar(CCVars.ViewportMaximumWidth);
var width = _configurationManager.GetCVar(CCVars.ViewportWidth); var width = _configurationManager.GetCVar(CCVars.ViewportWidth);
var verticalfit = _configurationManager.GetCVar(CCVars.ViewportVerticalFit) && _configurationManager.GetCVar(CCVars.ViewportStretch);
if (width < min || width > max) if (verticalfit)
{
width = max;
}
else if (width < min || width > max)
{ {
width = CCVars.ViewportWidth.DefaultValue; width = CCVars.ViewportWidth.DefaultValue;
} }
Viewport.Viewport.ViewportSize = (EyeManager.PixelsPerMeter * width, EyeManager.PixelsPerMeter * ViewportHeight); Viewport.Viewport.ViewportSize = (EyeManager.PixelsPerMeter * width, EyeManager.PixelsPerMeter * ViewportHeight);
Viewport.UpdateCfg();
} }
public void ReloadViewport() public void ReloadViewport()

View File

@@ -32,6 +32,7 @@ namespace Content.Client.Viewport
private int _curRenderScale; private int _curRenderScale;
private ScalingViewportStretchMode _stretchMode = ScalingViewportStretchMode.Bilinear; private ScalingViewportStretchMode _stretchMode = ScalingViewportStretchMode.Bilinear;
private ScalingViewportRenderScaleMode _renderScaleMode = ScalingViewportRenderScaleMode.Fixed; private ScalingViewportRenderScaleMode _renderScaleMode = ScalingViewportRenderScaleMode.Fixed;
private ScalingViewportIgnoreDimension _ignoreDimension = ScalingViewportIgnoreDimension.None;
private int _fixedRenderScale = 1; private int _fixedRenderScale = 1;
private readonly List<CopyPixelsDelegate<Rgba32>> _queuedScreenshots = new(); private readonly List<CopyPixelsDelegate<Rgba32>> _queuedScreenshots = new();
@@ -106,6 +107,17 @@ namespace Content.Client.Viewport
} }
} }
[ViewVariables(VVAccess.ReadWrite)]
public ScalingViewportIgnoreDimension IgnoreDimension
{
get => _ignoreDimension;
set
{
_ignoreDimension = value;
InvalidateViewport();
}
}
public ScalingViewport() public ScalingViewport()
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
@@ -178,7 +190,19 @@ namespace Content.Client.Viewport
if (FixedStretchSize == null) if (FixedStretchSize == null)
{ {
var (ratioX, ratioY) = ourSize / vpSize; var (ratioX, ratioY) = ourSize / vpSize;
var ratio = Math.Min(ratioX, ratioY); var ratio = 1f;
switch (_ignoreDimension)
{
case ScalingViewportIgnoreDimension.None:
ratio = Math.Min(ratioX, ratioY);
break;
case ScalingViewportIgnoreDimension.Vertical:
ratio = ratioX;
break;
case ScalingViewportIgnoreDimension.Horizontal:
ratio = ratioY;
break;
}
var size = vpSize * ratio; var size = vpSize * ratio;
// Size // Size
@@ -357,4 +381,25 @@ namespace Content.Client.Viewport
/// </summary> /// </summary>
CeilInt CeilInt
} }
/// <summary>
/// If the viewport is allowed to freely scale, this determines which dimensions should be ignored while fitting the viewport
/// </summary>
public enum ScalingViewportIgnoreDimension
{
/// <summary>
/// The viewport won't ignore any dimension.
/// </summary>
None = 0,
/// <summary>
/// The viewport will ignore the horizontal dimension, and will exclusively consider the vertical dimension for scaling.
/// </summary>
Horizontal,
/// <summary>
/// The viewport will ignore the vertical dimension, and will exclusively consider the horizontal dimension for scaling.
/// </summary>
Vertical
}
} }

View File

@@ -1555,6 +1555,9 @@ namespace Content.Shared.CCVar
public static readonly CVarDef<int> ViewportWidth = public static readonly CVarDef<int> ViewportWidth =
CVarDef.Create("viewport.width", 21, CVar.CLIENTONLY | CVar.ARCHIVE); CVarDef.Create("viewport.width", 21, CVar.CLIENTONLY | CVar.ARCHIVE);
public static readonly CVarDef<bool> ViewportVerticalFit =
CVarDef.Create("viewport.vertical_fit", true, CVar.CLIENTONLY | CVar.ARCHIVE);
/* /*
* UI * UI
*/ */

View File

@@ -83,6 +83,10 @@ ui-options-vp-integer-scaling-tooltip = If this option is enabled, the viewport
at specific resolutions. While this results in crisp textures, it also often at specific resolutions. While this results in crisp textures, it also often
means that black bars appear at the top/bottom of the screen or that part means that black bars appear at the top/bottom of the screen or that part
of the viewport is not visible. of the viewport is not visible.
ui-options-vp-vertical-fit = Vertical viewport fitting
ui-options-vp-vertical-fit-tooltip = When enabled, the main viewport will ignore the horizontal axis entirely when
fitting to your screen. If your screen is smaller than the viewport, then this
will cause the viewport to be cut off on the horizontal axis.
ui-options-vp-low-res = Low-resolution viewport ui-options-vp-low-res = Low-resolution viewport
ui-options-parallax-low-quality = Low-quality Parallax (background) ui-options-parallax-low-quality = Low-quality Parallax (background)
ui-options-fps-counter = Show FPS counter ui-options-fps-counter = Show FPS counter