Document ImGui multimonitor not working and other possible pitfalls
This commit is contained in:
parent
ada9113b37
commit
4bf0ddf5ff
4 changed files with 84 additions and 10 deletions
|
@ -10,6 +10,8 @@ public sealed unsafe class CursorPosHooks : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Hook<GetCursorPosDelegate> _getCursorPosHook;
|
private readonly Hook<GetCursorPosDelegate> _getCursorPosHook;
|
||||||
private readonly Hook<SetCursorPosDelegate> _setCursorPosHook;
|
private readonly Hook<SetCursorPosDelegate> _setCursorPosHook;
|
||||||
|
private readonly Hook<ScreenToClientDelegate> _screenToClientHook;
|
||||||
|
private readonly Hook<ClientToScreenDelegate> _clientToScreenHook;
|
||||||
|
|
||||||
public CursorPosHooks()
|
public CursorPosHooks()
|
||||||
{
|
{
|
||||||
|
@ -18,6 +20,12 @@ public sealed unsafe class CursorPosHooks : IDisposable
|
||||||
|
|
||||||
_setCursorPosHook = Service.GameInteropProvider.HookFromSymbol<SetCursorPosDelegate>("user32.dll", "SetCursorPos", SetCursorPosDetour);
|
_setCursorPosHook = Service.GameInteropProvider.HookFromSymbol<SetCursorPosDelegate>("user32.dll", "SetCursorPos", SetCursorPosDetour);
|
||||||
_setCursorPosHook.Enable();
|
_setCursorPosHook.Enable();
|
||||||
|
|
||||||
|
_screenToClientHook = Service.GameInteropProvider.HookFromSymbol<ScreenToClientDelegate>("user32.dll", "ScreenToClient", ScreenToClientDetour);
|
||||||
|
_screenToClientHook.Enable();
|
||||||
|
|
||||||
|
_clientToScreenHook = Service.GameInteropProvider.HookFromSymbol<ClientToScreenDelegate>("user32.dll", "ClientToScreen", ClientToScreenDetour);
|
||||||
|
_clientToScreenHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||||
|
@ -26,19 +34,46 @@ public sealed unsafe class CursorPosHooks : IDisposable
|
||||||
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||||
private unsafe delegate bool SetCursorPosDelegate(int x, int y);
|
private unsafe delegate bool SetCursorPosDelegate(int x, int y);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||||
|
private unsafe delegate bool ScreenToClientDelegate(HWND hWnd, POINT* lpPoint);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
|
||||||
|
private unsafe delegate bool ClientToScreenDelegate(HWND hWnd, POINT* lpPoint);
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_getCursorPosHook.Dispose();
|
_getCursorPosHook.Dispose();
|
||||||
_setCursorPosHook.Dispose();
|
_setCursorPosHook.Dispose();
|
||||||
|
_screenToClientHook.Dispose();
|
||||||
|
_clientToScreenHook.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetCursorPosOrig(POINT* lpPoint)
|
||||||
|
{
|
||||||
|
return _getCursorPosHook.Original(lpPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetCursorPosOrig(int x, int y)
|
||||||
|
{
|
||||||
|
return _setCursorPosHook.Original(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ScreenToClientOrig(HWND hWnd, POINT* lpPoint)
|
||||||
|
{
|
||||||
|
return _screenToClientHook.Original(hWnd, lpPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ClientToScreenOrig(HWND hWnd, POINT* lpPoint)
|
||||||
|
{
|
||||||
|
return _clientToScreenHook.Original(hWnd, lpPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool GetCursorPosDetour(POINT* lpPoint)
|
private bool GetCursorPosDetour(POINT* lpPoint)
|
||||||
{
|
{
|
||||||
var rv = _getCursorPosHook.Original(lpPoint);
|
var rv = _getCursorPosHook.Original(lpPoint);
|
||||||
|
if (!rv || lpPoint == null)
|
||||||
if (!rv)
|
|
||||||
{
|
{
|
||||||
return false;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if false
|
#if false
|
||||||
|
@ -69,4 +104,13 @@ public sealed unsafe class CursorPosHooks : IDisposable
|
||||||
return _setCursorPosHook.Original(x, y);
|
return _setCursorPosHook.Original(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ScreenToClientDetour(HWND hWnd, POINT* lpPoint)
|
||||||
|
{
|
||||||
|
return _screenToClientHook.Original(hWnd, lpPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ClientToScreenDetour(HWND hWnd, POINT* lpPoint)
|
||||||
|
{
|
||||||
|
return _clientToScreenHook.Original(hWnd, lpPoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,10 @@ public sealed unsafe class WindowRectHooks : IDisposable
|
||||||
Service.PluginLog.Debug($"GetClientRectDetour A @ {lpRect->left} {lpRect->top} {lpRect->right} {lpRect->bottom}");
|
Service.PluginLog.Debug($"GetClientRectDetour A @ {lpRect->left} {lpRect->top} {lpRect->right} {lpRect->bottom}");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (hWnd == Service.Plugin.CurrentHWND)
|
||||||
|
{
|
||||||
Service.Plugin.ConvertCoordsWinToGame(ref lpRect->right, ref lpRect->bottom);
|
Service.Plugin.ConvertCoordsWinToGame(ref lpRect->right, ref lpRect->bottom);
|
||||||
|
}
|
||||||
|
|
||||||
#if false
|
#if false
|
||||||
Service.PluginLog.Debug($"GetClientRectDetour B @ {lpRect->left} {lpRect->top} {lpRect->right} {lpRect->bottom}");
|
Service.PluginLog.Debug($"GetClientRectDetour B @ {lpRect->left} {lpRect->top} {lpRect->right} {lpRect->bottom}");
|
||||||
|
@ -65,7 +68,7 @@ public sealed unsafe class WindowRectHooks : IDisposable
|
||||||
Service.PluginLog.Debug($"SetWindowPosDetour A @ {X} {Y} {cx} {cy}");
|
Service.PluginLog.Debug($"SetWindowPosDetour A @ {X} {Y} {cx} {cy}");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Service.DebugConfig.SetSizeMode == SetSizeMode.LegacyHookSetWindowPos)
|
if (Service.DebugConfig.SetSizeMode == SetSizeMode.LegacyHookSetWindowPos && hWnd == Service.Plugin.CurrentHWND)
|
||||||
{
|
{
|
||||||
Service.Plugin.ConvertCoordsGameToWin(ref cx, ref cy);
|
Service.Plugin.ConvertCoordsGameToWin(ref cx, ref cy);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
||||||
|
|
||||||
public string Name => "CustomResolution";
|
public string Name => "CustomResolution";
|
||||||
|
|
||||||
public HWND CurrentHWND { get; private set; }
|
public HWND CurrentHWND => _currentHwnd;
|
||||||
|
|
||||||
public uint CurrentWidth { get; private set; }
|
public uint CurrentWidth { get; private set; }
|
||||||
public uint CurrentHeight { get; private set; }
|
public uint CurrentHeight { get; private set; }
|
||||||
|
@ -140,12 +140,12 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
||||||
|
|
||||||
var p = new POINT(x, y);
|
var p = new POINT(x, y);
|
||||||
|
|
||||||
ScreenToClient(_currentHwnd, &p);
|
Service.CursorPosHooks.ScreenToClientOrig(_currentHwnd, &p);
|
||||||
|
|
||||||
p.x = (int) Math.Round(p.x * scaleX);
|
p.x = (int) Math.Round(p.x * scaleX);
|
||||||
p.y = (int) Math.Round(p.y * scaleY);
|
p.y = (int) Math.Round(p.y * scaleY);
|
||||||
|
|
||||||
ClientToScreen(_currentHwnd, &p);
|
Service.CursorPosHooks.ClientToScreenOrig(_currentHwnd, &p);
|
||||||
|
|
||||||
x = p.x;
|
x = p.x;
|
||||||
y = p.y;
|
y = p.y;
|
||||||
|
@ -163,12 +163,12 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
||||||
|
|
||||||
var p = new POINT(x, y);
|
var p = new POINT(x, y);
|
||||||
|
|
||||||
ScreenToClient(_currentHwnd, &p);
|
Service.CursorPosHooks.ScreenToClientOrig(_currentHwnd, &p);
|
||||||
|
|
||||||
p.x = (int) Math.Round(p.x * scaleX);
|
p.x = (int) Math.Round(p.x * scaleX);
|
||||||
p.y = (int) Math.Round(p.y * scaleY);
|
p.y = (int) Math.Round(p.y * scaleY);
|
||||||
|
|
||||||
ClientToScreen(_currentHwnd, &p);
|
Service.CursorPosHooks.ClientToScreenOrig(_currentHwnd, &p);
|
||||||
|
|
||||||
x = p.x;
|
x = p.x;
|
||||||
y = p.y;
|
y = p.y;
|
||||||
|
|
27
README.md
27
README.md
|
@ -4,3 +4,30 @@ Enforces a custom resolution for the game, similar to NVIDIA DSR.
|
||||||
|
|
||||||
Mirrored at https://gitlab.com/0x0ade/dp-customresolution in case you want to submit a merge request.
|
Mirrored at https://gitlab.com/0x0ade/dp-customresolution in case you want to submit a merge request.
|
||||||
Please do ping me on Discord though (I'm in the Dalamud server) as some notifs might fly under my radar.
|
Please do ping me on Discord though (I'm in the Dalamud server) as some notifs might fly under my radar.
|
||||||
|
|
||||||
|
# Troubleshooting
|
||||||
|
|
||||||
|
<details><summary>My multi-monitor windows aren't working correctly!</summary>
|
||||||
|
Similarly to some other plugins (f.e. Umbra), multi-monitor mode in Dalamud might not work correctly.
|
||||||
|
In the case of cres, fixing this would be a huge undertaking to make ImGui handle the cursor inside and outside
|
||||||
|
the main game window differently, and to also handle window positioning correctly (spoiler: there is not one way
|
||||||
|
to handle it correctly - things are already shifting around when just resizing the game normally).
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details><summary>The game UI is really really small! I don't want to scale all my HUD manually!</summary>
|
||||||
|
Good news: You don't need to! XIV itself has got a "High Resolution UI Settings" scaling option in the system
|
||||||
|
configuration window, in the very first category ("Display Settings"), right under the resolution options.
|
||||||
|
|
||||||
|
Bad news: We're currently limited to the very options that XIV gives us. Perhaps a deeper dive into how the game
|
||||||
|
renders the HUD and decoupling that from the actual game render resolution could help, but it's on the same
|
||||||
|
scale of difficulty as fixing multi-monitor windows.
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details><summary>I'm scaling by 3x or higher, but I'm still getting jagged edges!</summary>
|
||||||
|
The plugin currently only gives FFXIV a fake resolution to work with internally, but it doesn't ensure that the
|
||||||
|
extra pixels land on your screen - those will still be used for in-game or ReShade screenshots though.
|
||||||
|
|
||||||
|
Windows should perform basic filtering with 2x scaling (it might not work on some graphics cards?), and I haven't
|
||||||
|
heard back from anyone using this on Linux yet. But an universal fix for this is possible - it just requires more
|
||||||
|
time than I have on my hands right now.
|
||||||
|
</details>
|
||||||
|
|
Loading…
Add table
Reference in a new issue