Skip to content

Commit

Permalink
Add integer scaling
Browse files Browse the repository at this point in the history
Upgrade XNAUI to 2.3.22
  • Loading branch information
SadPencil committed Sep 28, 2024
1 parent b77fbb4 commit c0579e4
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 48 deletions.
16 changes: 14 additions & 2 deletions ClientCore/ClientConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class ClientConfiguration
private const string SETTINGS = "Settings";
private const string LINKS = "Links";
private const string TRANSLATIONS = "Translations";
private const string USER_DEFAULTS = "UserDefaults";

private const string CLIENT_SETTINGS = "DTACnCNetClient.ini";
private const string GAME_OPTIONS = "GameOptions.ini";
Expand Down Expand Up @@ -193,7 +194,8 @@ public void RefreshSettings()

public int MaximumRenderHeight => clientDefinitionsIni.GetIntValue(SETTINGS, "MaximumRenderHeight", 800);

public string[] RecommendedResolutions => clientDefinitionsIni.GetStringValue(SETTINGS, "RecommendedResolutions", "1280x720,2560x1440,3840x2160").Split(',');
public string[] RecommendedResolutions => clientDefinitionsIni.GetStringValue(SETTINGS, "RecommendedResolutions",
$"{MinimumRenderWidth}x{MinimumRenderHeight},{MaximumRenderWidth}x{MaximumRenderHeight}").Split(',');

public string WindowTitle => clientDefinitionsIni.GetStringValue(SETTINGS, "WindowTitle", string.Empty)
.L10N("INI:ClientDefinitions:WindowTitle");
Expand Down Expand Up @@ -405,6 +407,16 @@ public IEnumerable<string> SupplementalMapFileExtensions

#endregion

#region User default settings

public bool UserDefault_BorderlessWindowedClient => clientDefinitionsIni.GetBooleanValue(USER_DEFAULTS, "BorderlessWindowedClient", true);

public bool UserDefault_IntegerScaledClient => clientDefinitionsIni.GetBooleanValue(USER_DEFAULTS, "IntegerScaledClient", false);

public bool UserDefault_WriteInstallationPathToRegistry => clientDefinitionsIni.GetBooleanValue(USER_DEFAULTS, "WriteInstallationPathToRegistry", true);

#endregion

public List<string> GetIRCServers()
{
List<string> servers = [];
Expand All @@ -419,7 +431,7 @@ public List<string> GetIRCServers()
}

public bool DiscordIntegrationGloballyDisabled => string.IsNullOrWhiteSpace(DiscordAppId) || DisableDiscordIntegration;

public OSVersion GetOperatingSystemVersion()
{
#if NETFRAMEWORK
Expand Down
6 changes: 4 additions & 2 deletions ClientCore/Settings/UserINISettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ protected UserINISettings(IniFile iniFile)
Renderer = new StringSetting(iniFile, COMPATIBILITY, "Renderer", string.Empty);
WindowedMode = new BoolSetting(iniFile, VIDEO, WINDOWED_MODE_KEY, false);
BorderlessWindowedMode = new BoolSetting(iniFile, VIDEO, "NoWindowFrame", false);
BorderlessWindowedClient = new BoolSetting(iniFile, VIDEO, "BorderlessWindowedClient", true);
BorderlessWindowedClient = new BoolSetting(iniFile, VIDEO, "BorderlessWindowedClient", ClientConfiguration.Instance.UserDefault_BorderlessWindowedClient);
IntegerScaledClient = new BoolSetting(iniFile, VIDEO, "IntegerScaledClient", ClientConfiguration.Instance.UserDefault_IntegerScaledClient);
ClientFPS = new IntSetting(iniFile, VIDEO, "ClientFPS", 60);
DisplayToggleableExtraTextures = new BoolSetting(iniFile, VIDEO, "DisplayToggleableExtraTextures", true);

Expand All @@ -86,7 +87,7 @@ protected UserINISettings(IniFile iniFile)
ChatColor = new IntSetting(iniFile, MULTIPLAYER, "ChatColor", -1);
LANChatColor = new IntSetting(iniFile, MULTIPLAYER, "LANChatColor", -1);
PingUnofficialCnCNetTunnels = new BoolSetting(iniFile, MULTIPLAYER, "PingCustomTunnels", true);
WritePathToRegistry = new BoolSetting(iniFile, OPTIONS, "WriteInstallationPathToRegistry", true);
WritePathToRegistry = new BoolSetting(iniFile, OPTIONS, "WriteInstallationPathToRegistry", ClientConfiguration.Instance.UserDefault_WriteInstallationPathToRegistry);
PlaySoundOnGameHosted = new BoolSetting(iniFile, MULTIPLAYER, "PlaySoundOnGameHosted", true);
SkipConnectDialog = new BoolSetting(iniFile, MULTIPLAYER, "SkipConnectDialog", false);
PersistentMode = new BoolSetting(iniFile, MULTIPLAYER, "PersistentMode", false);
Expand Down Expand Up @@ -151,6 +152,7 @@ protected UserINISettings(IniFile iniFile)
public IntSetting ClientResolutionX { get; set; }
public IntSetting ClientResolutionY { get; set; }
public BoolSetting BorderlessWindowedClient { get; private set; }
public BoolSetting IntegerScaledClient { get; private set; }
public IntSetting ClientFPS { get; private set; }
public BoolSetting DisplayToggleableExtraTextures { get; private set; }

Expand Down
4 changes: 3 additions & 1 deletion DTAConfig/OptionPanels/DisplayOptionsPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public override void Initialize()
var maximumIngameResolution = new ScreenResolution(ClientConfiguration.Instance.MaximumIngameWidth, ClientConfiguration.Instance.MaximumIngameHeight);

#if XNA
if (!ScreenResolution.HiDefLimitResolution.Fit(maximumIngameResolution))
if (!ScreenResolution.HiDefLimitResolution.Fits(maximumIngameResolution))
maximumIngameResolution = ScreenResolution.HiDefLimitResolution;
#endif

Expand Down Expand Up @@ -769,6 +769,8 @@ public override bool Save()
clientRes.Height != IniSettings.ClientResolutionY.Value)
restartRequired = true;

// TODO: since DTAConfig must not rely on DXMainClient, we can't notify the client to dynamically change the resolution or togging borderless windowed mode. Thus, we need to restart the client as a workaround.

(IniSettings.ClientResolutionX.Value, IniSettings.ClientResolutionY.Value) = clientRes;

if (IniSettings.BorderlessWindowedClient.Value != chkBorderlessClient.Checked)
Expand Down
28 changes: 25 additions & 3 deletions DTAConfig/ScreenResolution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DTAConfig
Expand All @@ -28,6 +29,12 @@ public ScreenResolution(int width, int height)
Height = height;
}

public ScreenResolution(Rectangle rectangle)
{
Width = rectangle.Width;
Height = rectangle.Height;
}

public ScreenResolution(string resolution)
{
List<int> resolutionList = resolution.Trim().Split('x').Take(2).Select(int.Parse).ToList();
Expand All @@ -51,32 +58,44 @@ public void Deconstruct(out int width, out int height)

public static implicit operator (int Width, int Height)(ScreenResolution resolution) => new(resolution.Width, resolution.Height);

public bool Fit(ScreenResolution child) => this.Width >= child.Width && this.Height >= child.Height;
public bool Fits(ScreenResolution child) => this.Width >= child.Width && this.Height >= child.Height;

public int CompareTo(ScreenResolution other) => (this.Width, this.Height).CompareTo(other);

// Accessing GraphicsAdapter.DefaultAdapter requiring DXMainClient.GameClass has been constructed. Lazy loading prevents possible null reference issues for now.
private static ScreenResolution _desktopResolution = null;

/// <summary>
/// The resolution of primary monitor.
/// </summary>
public static ScreenResolution DesktopResolution =>
_desktopResolution ??= new(GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width, GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height);

// The default graphic profile supports resolution up to 4096x4096. The number gets even smaller in practice. Therefore, we select 3840 as the limit.
public static ScreenResolution HiDefLimitResolution { get; } = "3840x3840";

private static ScreenResolution _safeMaximumResolution = null;

/// <summary>
/// The resolution of primary monitor, or the maximum resolution supported by the graphic profile, whichever is smaller.
/// </summary>
public static ScreenResolution SafeMaximumResolution
{
get
{
#if XNA
return _safeMaximumResolution ??= HiDefLimitResolution.Fit(DesktopResolution) ? DesktopResolution : HiDefLimitResolution;
return _safeMaximumResolution ??= HiDefLimitResolution.Fits(DesktopResolution) ? DesktopResolution : HiDefLimitResolution;
#else
return _safeMaximumResolution ??= DesktopResolution;
#endif
}
}

private static ScreenResolution _safeFullScreenResolution = null;

/// <summary>
/// The maximum resolution supported by the graphic profile, or the largest full screen resolution supported by the primary monitor, whichever is smaller.
/// </summary>
public static ScreenResolution SafeFullScreenResolution => _safeFullScreenResolution ??= GetFullScreenResolutions(minWidth: 800, minHeight: 600).Max();

public static SortedSet<ScreenResolution> GetFullScreenResolutions(int minWidth, int minHeight) =>
Expand Down Expand Up @@ -123,7 +142,7 @@ public SortedSet<ScreenResolution> GetIntegerScaledResolutions(ScreenResolution
{
ScreenResolution scaledResolution = (this.Width * i, this.Height * i);

if (maxResolution.Fit(scaledResolution))
if (maxResolution.Fits(scaledResolution))
resolutions.Add(scaledResolution);
else
break;
Expand All @@ -149,6 +168,9 @@ public static SortedSet<ScreenResolution> GetWindowedResolutions(IEnumerable<Scr
if (optimalResolution.Width < minWidth || optimalResolution.Height < minHeight)
continue;

if (!maxResolution.Fits(optimalResolution))
continue;

windowedResolutions.Add(optimalResolution);
}

Expand Down
Loading

0 comments on commit c0579e4

Please sign in to comment.