Convert screen to client, client to screen, when scaling

This commit is contained in:
Jade Macho 2024-02-16 00:05:51 +01:00
parent 209f22c19c
commit e541a157b2
Signed by: 0x0ade
GPG Key ID: E1960710FE4FBEEF
5 changed files with 112 additions and 14 deletions

View File

@ -55,6 +55,10 @@
<HintPath>$(DalamudLibPath)Lumina.Excel.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Serilog">
<HintPath>$(DalamudLibPath)Serilog.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<ItemGroup>

View File

@ -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);
}

View File

@ -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);
}

View File

@ -16,6 +16,9 @@ public sealed unsafe class Plugin : IDalamudPlugin
private readonly List<Cmd> _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;

View File

@ -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();
}