From e541a157b217f8c5195c0d484f626f3a00aa2ef3 Mon Sep 17 00:00:00 2001 From: Jade Macho Date: Fri, 16 Feb 2024 00:05:51 +0100 Subject: [PATCH] Convert screen to client, client to screen, when scaling --- CustomResolution/CustomResolution.csproj | 4 ++ CustomResolution/Hooks/CursorPosHooks.cs | 21 +++++++- CustomResolution/Hooks/WndProcHook.cs | 17 ++++-- CustomResolution/Plugin.cs | 68 +++++++++++++++++++++--- CustomResolution/Windows/ConfigWindow.cs | 16 +++++- 5 files changed, 112 insertions(+), 14 deletions(-) diff --git a/CustomResolution/CustomResolution.csproj b/CustomResolution/CustomResolution.csproj index f3b05e7..3e89d7b 100644 --- a/CustomResolution/CustomResolution.csproj +++ b/CustomResolution/CustomResolution.csproj @@ -55,6 +55,10 @@ $(DalamudLibPath)Lumina.Excel.dll false + + $(DalamudLibPath)Serilog.dll + false + diff --git a/CustomResolution/Hooks/CursorPosHooks.cs b/CustomResolution/Hooks/CursorPosHooks.cs index 58a829a..d387bb4 100644 --- a/CustomResolution/Hooks/CursorPosHooks.cs +++ b/CustomResolution/Hooks/CursorPosHooks.cs @@ -1,5 +1,6 @@ using CustomResolution.WndProcHookManagerProxyApi; using Dalamud.Hooking; +using Serilog.Events; using System; using System.Linq; using System.Reflection.Emit; @@ -44,14 +45,30 @@ public sealed unsafe class CursorPosHooks : IDisposable return false; } - Service.Plugin.ConvertCoordsWinToGame(ref lpPoint->x, ref lpPoint->y); +#if false + Service.PluginLog.Debug($"GetCursorPos A @ {lpPoint->x} {lpPoint -> y}"); +#endif + + Service.Plugin.ConvertCoordsGlobalToGame(ref lpPoint->x, ref lpPoint->y); + +#if false + Service.PluginLog.Debug($"GetCursorPos B @ {lpPoint->x} {lpPoint->y}"); +#endif return rv; } private bool SetCursorPosDetour(int x, int y) { - Service.Plugin.ConvertCoordsGameToWin(ref x, ref y); +#if false + Service.PluginLog.Debug($"SetCursorPos A @ {x} {y}"); +#endif + + Service.Plugin.ConvertCoordsGameToGlobal(ref x, ref y); + +#if false + Service.PluginLog.Debug($"SetCursorPos B @ {x} {y}"); +#endif return _setCursorPosHook.Original(x, y); } diff --git a/CustomResolution/Hooks/WndProcHook.cs b/CustomResolution/Hooks/WndProcHook.cs index c26094c..4a7dcfc 100644 --- a/CustomResolution/Hooks/WndProcHook.cs +++ b/CustomResolution/Hooks/WndProcHook.cs @@ -1,4 +1,5 @@ using CustomResolution.WndProcHookManagerProxyApi; +using Serilog.Events; using System; using System.Linq; using System.Reflection.Emit; @@ -59,15 +60,15 @@ public sealed class WndProcHook : IDisposable private static void ParamToCoords(LPARAM param, out int x, out int y) { - x = (int)(param.Value & 0xFFFF); - y = (int)(param.Value >> 16 & 0xFFFF); + x = (short) (ushort) (param.Value & 0xFFFF); + y = (short) (ushort) (param.Value >> 16 & 0xFFFF); } private static LPARAM CoordsToParam(int x, int y) { nint value = 0; - value |= x & 0xFFFF; - value |= y >> 16 & 0xFFFF; + value |= ((ushort) (short) x) & 0xFFFF; + value |= ((ushort) (short) y) >> 16 & 0xFFFF; return value; } @@ -81,8 +82,16 @@ public sealed class WndProcHook : IDisposable ParamToCoords(args.LParam, out int x, out int y); +#if false + Service.PluginLog.Debug($"WM_MOUSE A @ {x} {y}"); +#endif + Service.Plugin.ConvertCoordsWinToGame(ref x, ref y); +#if false + Service.PluginLog.Debug($"WM_MOUSE B @ {x} {y}"); +#endif + args.LParam = CoordsToParam(x, y); } diff --git a/CustomResolution/Plugin.cs b/CustomResolution/Plugin.cs index 4432fa9..4ff395d 100644 --- a/CustomResolution/Plugin.cs +++ b/CustomResolution/Plugin.cs @@ -16,6 +16,9 @@ public sealed unsafe class Plugin : IDalamudPlugin private readonly List _cmds; private bool _unloading = false; private int _tickCount = 0; + private HWND _currentHwnd; + private RECT _currentClientRect; + private RECT _currentWindowRect; public Plugin([RequiredVersion("1.0")] DalamudPluginInterface pluginInterface) { @@ -101,16 +104,58 @@ public sealed unsafe class Plugin : IDalamudPlugin y = (int) Math.Round(y * scaleY); } + public void ConvertCoordsGlobalToGame(ref int x, ref int y) + { + if (CurrentWidth == CurrentWindowWidth && CurrentHeight == CurrentWindowHeight) + { + return; + } + + float scaleX = CurrentWidth / (float) CurrentWindowWidth; + float scaleY = CurrentHeight / (float) CurrentWindowHeight; + + var p = new POINT(x, y); + + TerraFX.Interop.Windows.Windows.ScreenToClient(_currentHwnd, &p); + + p.x = (int) Math.Round(p.x * scaleX); + p.y = (int) Math.Round(p.y * scaleY); + + TerraFX.Interop.Windows.Windows.ClientToScreen(_currentHwnd, &p); + + x = p.x; + y = p.y; + } + + public void ConvertCoordsGameToGlobal(ref int x, ref int y) + { + if (CurrentWidth == CurrentWindowWidth && CurrentHeight == CurrentWindowHeight) + { + return; + } + + float scaleX = CurrentWindowWidth / (float) CurrentWidth; + float scaleY = CurrentWindowHeight / (float) CurrentHeight; + + var p = new POINT(x, y); + + TerraFX.Interop.Windows.Windows.ScreenToClient(_currentHwnd, &p); + + p.x = (int) Math.Round(p.x * scaleX); + p.y = (int) Math.Round(p.y * scaleY); + + TerraFX.Interop.Windows.Windows.ClientToScreen(_currentHwnd, &p); + + x = p.x; + y = p.y; + } + public void Update() { var dev = Device.Instance(); - RECT rect = default; - - TerraFX.Interop.Windows.Windows.GetClientRect((HWND) (IntPtr) dev->hWnd, &rect); - - int rectWidth = rect.right - rect.left; - int rectHeight = rect.bottom - rect.top; + int rectWidth = _currentClientRect.right - _currentClientRect.left; + int rectHeight = _currentClientRect.bottom - _currentClientRect.top; if ((rectWidth <= 0 || rectHeight <= 0) && !_unloading) { @@ -159,6 +204,17 @@ public sealed unsafe class Plugin : IDalamudPlugin private void OnFrameworkUpdate(IFramework framework) { + var dev = Device.Instance(); + + _currentHwnd = (HWND) (IntPtr) dev->hWnd; + + fixed (RECT* currentClientRectPtr = &_currentClientRect) + fixed (RECT* currentWindowRectPtr = &_currentWindowRect) + { + TerraFX.Interop.Windows.Windows.GetClientRect(_currentHwnd, currentClientRectPtr); + TerraFX.Interop.Windows.Windows.GetWindowRect(_currentHwnd, currentWindowRectPtr); + } + if (_tickCount++ >= 10) { _tickCount = 0; diff --git a/CustomResolution/Windows/ConfigWindow.cs b/CustomResolution/Windows/ConfigWindow.cs index 7e4ba5a..ad85464 100644 --- a/CustomResolution/Windows/ConfigWindow.cs +++ b/CustomResolution/Windows/ConfigWindow.cs @@ -53,6 +53,7 @@ public class ConfigWindow : Window, IDisposable public override void Draw() { var plugin = Service.Plugin; + var save = false; _displayCurrentWH[0] = (int) plugin.CurrentWidth; _displayCurrentWH[1] = (int) plugin.CurrentHeight; @@ -68,14 +69,25 @@ public class ConfigWindow : Window, IDisposable if (_configIsScale) { - ImGui.InputFloat("Scale", ref _configScale, 0.01f, 0.1f); + if (ImGui.InputFloat("Scale", ref _configScale, 0.01f, 0.1f, "%.3f", ImGuiInputTextFlags.EnterReturnsTrue)) + { + save = true; + } } else { - ImGui.InputInt2("Size in pixels", ref _configWH[0]); + if (ImGui.InputInt2("Size in pixels", ref _configWH[0], ImGuiInputTextFlags.EnterReturnsTrue)) + { + save = true; + } } if (ImGui.Button("Save and apply")) + { + save = true; + } + + if (save) { UpdateToConfig(); }