From 2ff090f4a4a9a6c186fe39cb92c7ec7f4b6def7a Mon Sep 17 00:00:00 2001 From: Jade Macho Date: Sun, 16 Mar 2025 23:27:21 +0100 Subject: [PATCH] Add new SetSize mode - intercept system config instead of SetWindowPos --- CustomResolution2782/Cmds/MainCmd.cs | 18 +++- .../CustomResolution2782.csproj | 1 + CustomResolution2782/DebugConfiguration.cs | 29 ++++++ CustomResolution2782/Hooks/WindowRectHooks.cs | 5 +- CustomResolution2782/Plugin.cs | 89 ++++++++++++++----- CustomResolution2782/Service.cs | 5 ++ 6 files changed, 120 insertions(+), 27 deletions(-) create mode 100644 CustomResolution2782/DebugConfiguration.cs diff --git a/CustomResolution2782/Cmds/MainCmd.cs b/CustomResolution2782/Cmds/MainCmd.cs index 9a6490b..054c300 100644 --- a/CustomResolution2782/Cmds/MainCmd.cs +++ b/CustomResolution2782/Cmds/MainCmd.cs @@ -64,18 +64,28 @@ public sealed class MainCmd : Cmd return; case "debugon": - Service.Plugin.IsDebug = true; + Service.DebugConfig.IsDebug = true; Service.PrintChat("Enabled cres debug."); return; case "debugoff": - Service.Plugin.IsDebug = false; + Service.DebugConfig.IsDebug = false; Service.PrintChat("Disabled cres debug."); return; case "debug": - Service.Plugin.IsDebug = !Service.Plugin.IsDebug; - Service.PrintChat($"{(Service.Plugin.IsDebug ? "Enabled" : "Disabled")} cres debug."); + Service.DebugConfig.IsDebug = !Service.DebugConfig.IsDebug; + Service.PrintChat($"{(Service.DebugConfig.IsDebug ? "Enabled" : "Disabled")} cres debug."); + return; + + case "debugsizeold": + Service.DebugConfig.SetSizeMode = SetSizeMode.LegacyHookSetWindowPos; + Service.PrintChat("Switched to legacy size mode. Please report your use case / any bugs with the new mode to 0x0ade."); + return; + + case "debugsizenew": + Service.DebugConfig.SetSizeMode = SetSizeMode.InterceptSystemConfig; + Service.PrintChat("Switched back to new size mode."); return; } diff --git a/CustomResolution2782/CustomResolution2782.csproj b/CustomResolution2782/CustomResolution2782.csproj index 2a7a11e..63817d6 100644 --- a/CustomResolution2782/CustomResolution2782.csproj +++ b/CustomResolution2782/CustomResolution2782.csproj @@ -18,6 +18,7 @@ false false true + CustomResolution diff --git a/CustomResolution2782/DebugConfiguration.cs b/CustomResolution2782/DebugConfiguration.cs new file mode 100644 index 0000000..1abd16e --- /dev/null +++ b/CustomResolution2782/DebugConfiguration.cs @@ -0,0 +1,29 @@ +using System; +namespace CustomResolution; + +/// +/// Flags for internal testing. +/// +public class DebugConfiguration +{ + public bool IsDebug { get; set; } = false; + + public SetSizeMode SetSizeMode { get; set; } = SetSizeMode.InterceptSystemConfig; +} + +public enum SetSizeMode +{ + /// + /// Intercept the system config width / height and scale it, but don't intercept window size sets. + /// Has got a mild risk of growing / shrinking windows if any codepath tries to get->set the window size, + /// most notably with other plugins trying to change the window size. You shouldn't mix and match those anyway tho... + /// ... and even then, I'm probably the only one who's going to read this and care about this. -jade + /// + InterceptSystemConfig = 0, + + /// + /// Legacy mode, went through more testing, works well except for the game getting confused about windowed mode size. + /// Might revert or remove depending on how InterceptSystemConfig testing / fixups proceed. + /// + LegacyHookSetWindowPos = 1 +} diff --git a/CustomResolution2782/Hooks/WindowRectHooks.cs b/CustomResolution2782/Hooks/WindowRectHooks.cs index 179a8b4..072c555 100644 --- a/CustomResolution2782/Hooks/WindowRectHooks.cs +++ b/CustomResolution2782/Hooks/WindowRectHooks.cs @@ -65,7 +65,10 @@ public sealed unsafe class WindowRectHooks : IDisposable Service.PluginLog.Debug($"SetWindowPosDetour A @ {X} {Y} {cx} {cy}"); #endif - Service.Plugin.ConvertCoordsGameToWin(ref cx, ref cy); + if (Service.DebugConfig.SetSizeMode == SetSizeMode.LegacyHookSetWindowPos) + { + Service.Plugin.ConvertCoordsGameToWin(ref cx, ref cy); + } #if false Service.PluginLog.Debug($"SetWindowPosDetour B @ {X} {Y} {cx} {cy}"); diff --git a/CustomResolution2782/Plugin.cs b/CustomResolution2782/Plugin.cs index 5c543cd..a5928b5 100644 --- a/CustomResolution2782/Plugin.cs +++ b/CustomResolution2782/Plugin.cs @@ -1,4 +1,5 @@ using Dalamud.Game.ClientState.Keys; +using Dalamud.Game.Config; using Dalamud.Plugin; using Dalamud.Plugin.Services; using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; @@ -25,6 +26,7 @@ public sealed unsafe class Plugin : IDalamudPlugin private HWND _currentHwnd; private RECT _currentClientRect; private DXVKDWMHackMode _currentDXVKDWMHackMode = DXVKDWMHackMode.Off; + private bool _ignoreConfigChanges = false; public Plugin(IDalamudPluginInterface pluginInterface) { @@ -34,6 +36,8 @@ public sealed unsafe class Plugin : IDalamudPlugin Service.Plugin = this; + Service.DebugConfig = new DebugConfiguration(); + Service.Config = Service.PluginInterface.GetPluginConfig() as Configuration ?? new(); Service.Config.Initialize(Service.PluginInterface); @@ -54,6 +58,7 @@ public sealed unsafe class Plugin : IDalamudPlugin } Service.Framework.Update += OnFrameworkUpdate; + Service.GameConfig.SystemChanged += OnSystemConfigChanged; } public string Name => "CustomResolution"; @@ -67,8 +72,6 @@ public sealed unsafe class Plugin : IDalamudPlugin public bool CurrentBorderlessFullscreen { get; private set; } - public bool IsDebug { get; set; } - public void Dispose() { _unloading = true; @@ -76,6 +79,7 @@ public sealed unsafe class Plugin : IDalamudPlugin lock (_disposeLock) { Service.Framework.Update -= OnFrameworkUpdate; + Service.GameConfig.SystemChanged -= OnSystemConfigChanged; Service.Framework.RunOnFrameworkThread(Update); } @@ -101,8 +105,8 @@ public sealed unsafe class Plugin : IDalamudPlugin return; } - float scaleX = CurrentWidth / (float) CurrentWindowWidth; - float scaleY = CurrentHeight / (float) CurrentWindowHeight; + var scaleX = CurrentWidth / (float) CurrentWindowWidth; + var scaleY = CurrentHeight / (float) CurrentWindowHeight; x = (int) Math.Round(x * scaleX); y = (int) Math.Round(y * scaleY); @@ -115,8 +119,8 @@ public sealed unsafe class Plugin : IDalamudPlugin return; } - float scaleX = CurrentWindowWidth / (float) CurrentWidth; - float scaleY = CurrentWindowHeight / (float) CurrentHeight; + var scaleX = CurrentWindowWidth / (float) CurrentWidth; + var scaleY = CurrentWindowHeight / (float) CurrentHeight; x = (int) Math.Round(x * scaleX); y = (int) Math.Round(y * scaleY); @@ -129,8 +133,8 @@ public sealed unsafe class Plugin : IDalamudPlugin return; } - float scaleX = CurrentWidth / (float) CurrentWindowWidth; - float scaleY = CurrentHeight / (float) CurrentWindowHeight; + var scaleX = CurrentWidth / (float) CurrentWindowWidth; + var scaleY = CurrentHeight / (float) CurrentWindowHeight; var p = new POINT(x, y); @@ -152,8 +156,8 @@ public sealed unsafe class Plugin : IDalamudPlugin return; } - float scaleX = CurrentWindowWidth / (float) CurrentWidth; - float scaleY = CurrentWindowHeight / (float) CurrentHeight; + var scaleX = CurrentWindowWidth / (float) CurrentWidth; + var scaleY = CurrentWindowHeight / (float) CurrentHeight; var p = new POINT(x, y); @@ -181,8 +185,8 @@ public sealed unsafe class Plugin : IDalamudPlugin Service.WindowRectHooks.GetClientRectOrig(_currentHwnd, currentClientRectPtr); } - int rectWidth = _currentClientRect.right - _currentClientRect.left; - int rectHeight = _currentClientRect.bottom - _currentClientRect.top; + var rectWidth = _currentClientRect.right - _currentClientRect.left; + var rectHeight = _currentClientRect.bottom - _currentClientRect.top; if ((rectWidth <= 0 || rectHeight <= 0) && !_unloading) { @@ -191,7 +195,7 @@ public sealed unsafe class Plugin : IDalamudPlugin uint width, height; - bool enabled = !_unloading && Service.Config.IsEnabled; + var enabled = !_unloading && Service.Config.IsEnabled; if (_wasEnabled != enabled) { Service.PluginLog.Info($"Changing state to: {enabled}"); @@ -261,15 +265,15 @@ public sealed unsafe class Plugin : IDalamudPlugin * Default windowed style / exstyle is 0x14CF0000 / 0. * WS.WS_VISIBLE | WS.WS_CLIPSIBLINGS | WS.WS_CAPTION | WS.WS_SYSMENU | WS.WS_THICKFRAME | WS.WS_MINIMIZEBOX | WS.WS_MAXIMIZEBOX */ - uint styleOrig = (uint) GetWindowLong(_currentHwnd, GWL.GWL_STYLE); - uint exstyleOrig = (uint) GetWindowLong(_currentHwnd, GWL.GWL_EXSTYLE); + var styleOrig = (uint) GetWindowLong(_currentHwnd, GWL.GWL_STYLE); + var exstyleOrig = (uint) GetWindowLong(_currentHwnd, GWL.GWL_EXSTYLE); - uint style = styleOrig; - uint exstyle = exstyleOrig; + var style = styleOrig; + var exstyle = exstyleOrig; - bool fullscreen = (style & WS.WS_SYSMENU) == 0; + var fullscreen = (style & WS.WS_SYSMENU) == 0; - if (IsDebug) + if (Service.DebugConfig.IsDebug) { Service.PluginLog.Info("--------"); Service.PluginLog.Info($"STYLE: 0x{style:X8}"); @@ -307,7 +311,7 @@ public sealed unsafe class Plugin : IDalamudPlugin exstyle &= ~(uint) WS.WS_EX_COMPOSITED; } - if (IsDebug) + if (Service.DebugConfig.IsDebug) { Service.PluginLog.Info($"NEWSTYLE: 0x{style:X8}"); Service.PluginLog.Info($"NEWEXSTYLE: 0x{exstyle:X8}"); @@ -315,7 +319,7 @@ public sealed unsafe class Plugin : IDalamudPlugin if (style != styleOrig || exstyle != exstyleOrig || _currentDXVKDWMHackMode != mode) { - if (IsDebug) + if (Service.DebugConfig.IsDebug) { Service.PluginLog.Info("UPDATE"); } @@ -326,7 +330,7 @@ public sealed unsafe class Plugin : IDalamudPlugin SetWindowPos(_currentHwnd, HWND.NULL, 0, 0, 0, 0, SWP.SWP_NOZORDER | SWP.SWP_NOMOVE | SWP.SWP_NOSIZE | SWP.SWP_NOACTIVATE | SWP.SWP_DRAWFRAME); ShowWindow(_currentHwnd, SW.SW_SHOW); } - else if (IsDebug) + else if (Service.DebugConfig.IsDebug) { Service.PluginLog.Info("SAME"); } @@ -358,4 +362,45 @@ public sealed unsafe class Plugin : IDalamudPlugin Update(); } } + + private void OnSystemConfigChanged(object? sender, ConfigChangeEvent raw) + { + if (_ignoreConfigChanges) + { + return; + } + + if (raw is not ConfigChangeEvent { } e) + { + return; + } + + switch (e.ConfigOption) + { + case SystemConfigOption.ScreenWidth: + case SystemConfigOption.ScreenHeight: + if (Service.DebugConfig.SetSizeMode == SetSizeMode.InterceptSystemConfig) + { + var name = e.ConfigOption.ToString(); + var valueOrig = Service.GameConfig.System.GetUInt(name); + + var isW = e.ConfigOption == SystemConfigOption.ScreenWidth; + var scale = (isW ? CurrentWindowWidth : CurrentWindowHeight) / (float) (isW ? CurrentWidth : CurrentHeight); + var valueNew = (uint) Math.Round(valueOrig * scale); + + Service.PluginLog.Info($"Intercepting config value change for {name}: {valueOrig} -> {valueNew}"); + try + { + _ignoreConfigChanges = true; + Service.GameConfig.System.Set(name, valueNew); + } + finally + { + _ignoreConfigChanges = false; + } + } + + break; + } + } } diff --git a/CustomResolution2782/Service.cs b/CustomResolution2782/Service.cs index 81f946d..ca29b59 100644 --- a/CustomResolution2782/Service.cs +++ b/CustomResolution2782/Service.cs @@ -12,6 +12,8 @@ public sealed class Service public static Configuration Config { get; internal set; } = null!; + public static DebugConfiguration DebugConfig { get; internal set; } = null!; + public static PluginUI PluginUI { get; internal set; } = null!; public static WndProcHook WndProcHook { get; internal set; } = null!; @@ -42,6 +44,9 @@ public sealed class Service [PluginService] public static IKeyState KeyState { get; private set; } = null!; + [PluginService] + public static IGameConfig GameConfig { get; private set; } = null!; + public static void PrintChat(string msg) { ChatGui.Print(new XivChatEntry