core: Send WM_ resize msgs instead of requesting device resize
This commit is contained in:
parent
3831b5f64f
commit
78ff318397
6 changed files with 107 additions and 33 deletions
|
@ -79,12 +79,12 @@ public sealed class MainCmd : Cmd
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case "debugsizeold":
|
case "debugsizeold":
|
||||||
Service.DebugConfig.SetSizeMode = SetSizeMode.LegacyHookSetWindowPos;
|
Service.DebugConfig.ForceSizeMode = ForceSizeMode.LegacyRequestResolutionChange;
|
||||||
Service.PrintChat("Switched to legacy size mode. Please report your use case / any bugs with the new mode to 0x0ade.");
|
Service.PrintChat("Switched to legacy size mode. Please report your use case / any bugs with the new mode to 0x0ade.");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case "debugsizenew":
|
case "debugsizenew":
|
||||||
Service.DebugConfig.SetSizeMode = SetSizeMode.InterceptSystemConfig;
|
Service.DebugConfig.ForceSizeMode = ForceSizeMode.FakeWindowResize;
|
||||||
Service.PrintChat("Switched back to new size mode.");
|
Service.PrintChat("Switched back to new size mode.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,15 @@ public class DebugConfiguration
|
||||||
{
|
{
|
||||||
public bool IsDebug { get; set; } = false;
|
public bool IsDebug { get; set; } = false;
|
||||||
|
|
||||||
public SetSizeMode SetSizeMode { get; set; } = SetSizeMode.InterceptSystemConfig;
|
public SetWindowSizeMode SetWindowSizeMode { get; set; } = SetWindowSizeMode.InterceptSystemConfig;
|
||||||
|
|
||||||
|
public ForceSizeMode ForceSizeMode { get; set; } = ForceSizeMode.FakeWindowResize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SetSizeMode
|
public enum SetWindowSizeMode
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Intercept the system config width / height and scale it, but don't intercept window size sets.
|
/// Intercept the system config width / height and scale it to the window size, and 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,
|
/// 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...
|
/// 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
|
/// ... and even then, I'm probably the only one who's going to read this and care about this. -jade
|
||||||
|
@ -22,8 +24,10 @@ public enum SetSizeMode
|
||||||
InterceptSystemConfig = 0,
|
InterceptSystemConfig = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Legacy mode, went through more testing, works well except for the game getting confused about windowed mode size.
|
/// Legacy mode, went through more initial testing, works well except for the game getting confused about windowed mode size.
|
||||||
/// Might revert or remove depending on how InterceptSystemConfig testing / fixups proceed.
|
/// Might revert or remove depending on how InterceptSystemConfig testing / fixups proceed.
|
||||||
|
///
|
||||||
|
/// Hook SetWindowPos and turn the wanted size from scaled to window size on the fly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
LegacyHookSetWindowPos = 1
|
LegacyHookSetWindowPos = 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,13 +62,18 @@ public sealed unsafe class WindowRectHooks : IDisposable
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SetWindowPosOrig(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags)
|
||||||
|
{
|
||||||
|
return _setWindowPosHook.Original(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags);
|
||||||
|
}
|
||||||
|
|
||||||
private bool SetWindowPosDetour(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags)
|
private bool SetWindowPosDetour(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags)
|
||||||
{
|
{
|
||||||
#if false
|
#if false
|
||||||
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 && hWnd == Service.Plugin.CurrentHWND)
|
if (Service.DebugConfig.SetWindowSizeMode == SetWindowSizeMode.LegacyHookSetWindowPos && hWnd == Service.Plugin.CurrentHWND)
|
||||||
{
|
{
|
||||||
Service.Plugin.ConvertCoordsGameToWin(ref cx, ref cy);
|
Service.Plugin.ConvertCoordsGameToWin(ref cx, ref cy);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,32 +74,32 @@ public sealed unsafe class WndProcHook : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParamToCoords(LPARAM param, out int x, out int y)
|
public static void ParamToCoords(LPARAM param, out int x, out int y)
|
||||||
{
|
{
|
||||||
x = (short) (ushort) (param.Value & 0xFFFF);
|
x = (short) (ushort) (param.Value & 0xFFFF);
|
||||||
y = (short) (ushort) (param.Value >> 16 & 0xFFFF);
|
y = (short) (ushort) ((param.Value >> 16) & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LPARAM CoordsToParam(int x, int y)
|
public static LPARAM CoordsToParam(int x, int y)
|
||||||
{
|
{
|
||||||
nint value = 0;
|
nint value = 0;
|
||||||
value |= ((ushort) (short) x) & 0xFFFF;
|
value |= ((ushort) (short) x) & 0xFFFF;
|
||||||
value |= ((ushort) (short) y) >> 16 & 0xFFFF;
|
value |= (((ushort) (short) y) & 0xFFFF) << 16;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParamToSize(LPARAM param, out uint x, out uint y)
|
public static void ParamToSize(LPARAM param, out uint x, out uint y)
|
||||||
{
|
{
|
||||||
x = (ushort) (param.Value & 0xFFFF);
|
x = (ushort) (param.Value & 0xFFFF);
|
||||||
y = (ushort) (param.Value >> 16 & 0xFFFF);
|
y = (ushort) ((param.Value >> 16) & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LPARAM SizeToParam(uint x, uint y)
|
public static LPARAM SizeToParam(uint x, uint y)
|
||||||
{
|
{
|
||||||
nint value = 0;
|
nint value = 0;
|
||||||
value |= ((ushort) x) & 0xFFFF;
|
value |= ((ushort) x) & 0xFFFF;
|
||||||
value |= ((ushort) y) >> 16 & 0xFFFF;
|
value |= (((ushort) y) & 0xFFFF) << 16;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Dalamud.Game.ClientState.Keys;
|
using CustomResolution.Hooks;
|
||||||
|
using Dalamud.Game.ClientState.Keys;
|
||||||
using Dalamud.Game.Config;
|
using Dalamud.Game.Config;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
|
@ -29,6 +30,8 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
||||||
private RECT _currentClientRect;
|
private RECT _currentClientRect;
|
||||||
private DXVKDWMHackMode _currentDXVKDWMHackMode = DXVKDWMHackMode.Off;
|
private DXVKDWMHackMode _currentDXVKDWMHackMode = DXVKDWMHackMode.Off;
|
||||||
private bool _ignoreConfigChanges = false;
|
private bool _ignoreConfigChanges = false;
|
||||||
|
private bool _currentlyFakeResize = false;
|
||||||
|
private bool _requestedResolutionChange = false;
|
||||||
|
|
||||||
public Plugin(IDalamudPluginInterface pluginInterface)
|
public Plugin(IDalamudPluginInterface pluginInterface)
|
||||||
{
|
{
|
||||||
|
@ -226,14 +229,9 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint width, height;
|
|
||||||
|
|
||||||
var enabled = !_unloading && Service.Config.IsEnabled;
|
var enabled = !_unloading && Service.Config.IsEnabled;
|
||||||
if (_wasEnabled != enabled)
|
|
||||||
{
|
uint width, height;
|
||||||
Service.PluginLog.Info($"Changing state to: {enabled}");
|
|
||||||
_wasEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Service.Config.IsScale || !enabled)
|
if (Service.Config.IsScale || !enabled)
|
||||||
{
|
{
|
||||||
|
@ -258,15 +256,61 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
||||||
height = 256;
|
height = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (width != dev->Width || height != dev->Height)
|
_requestedResolutionChange |= (*_dev_RequestResolutionChange) != 0;
|
||||||
|
|
||||||
|
if (!_currentlyFakeResize && (_unloading || enabled || _wasEnabled || _requestedResolutionChange) &&
|
||||||
|
(width != dev->Width || height != dev->Height))
|
||||||
{
|
{
|
||||||
Service.PluginLog.Info($"Changing graphics resolution from {dev->Width} x {dev->Height} to {width} x {height}");
|
Service.PluginLog.Info($"Changing graphics resolution from {dev->Width} x {dev->Height} to {width} x {height}");
|
||||||
*_dev_NewWidth = width;
|
var mode = Service.DebugConfig.ForceSizeMode;
|
||||||
*_dev_NewHeight = height;
|
if (_requestedResolutionChange)
|
||||||
*_dev_RequestResolutionChange = 1;
|
{
|
||||||
Service.PluginLog.Info($"Changing game window from {win->WindowWidth} x {win->WindowHeight} to {width} x {height}");
|
// Let's try to be cautious about other plugins (f.e. SimpleTweaks) changing the game resolution.
|
||||||
win->WindowWidth = (int) width;
|
Service.PluginLog.Info($"Game resolution was changed externally - forcing resize via device, not window resize.");
|
||||||
win->WindowHeight = (int) height;
|
mode = ForceSizeMode.LegacyRequestResolutionChange;
|
||||||
|
_requestedResolutionChange = false;
|
||||||
|
}
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case ForceSizeMode.Skip:
|
||||||
|
break;
|
||||||
|
case ForceSizeMode.LegacyRequestResolutionChange:
|
||||||
|
*_dev_NewWidth = width;
|
||||||
|
*_dev_NewHeight = height;
|
||||||
|
*_dev_RequestResolutionChange = 1;
|
||||||
|
Service.PluginLog.Info($"Changing game window from {win->WindowWidth} x {win->WindowHeight} to {width} x {height}");
|
||||||
|
win->WindowWidth = (int) width;
|
||||||
|
win->WindowHeight = (int) height;
|
||||||
|
break;
|
||||||
|
case ForceSizeMode.FakeWindowResize:
|
||||||
|
var adjustedClientRect = new RECT(0, 0, rectWidth, rectHeight);
|
||||||
|
AdjustWindowRect(&adjustedClientRect, (uint) GetWindowLongPtr(_currentHwnd, GWL.GWL_STYLE), false);
|
||||||
|
var adjustedWidth = adjustedClientRect.right - adjustedClientRect.left;
|
||||||
|
var adjustedHeight = adjustedClientRect.bottom - adjustedClientRect.top;
|
||||||
|
Service.PluginLog.Info($"Resizing window to {adjustedWidth} x {adjustedHeight}");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_currentlyFakeResize = true;
|
||||||
|
SendMessage(_currentHwnd, WM.WM_ENTERSIZEMOVE, 0, 0);
|
||||||
|
SendMessage(_currentHwnd, WM.WM_SIZE, SIZE_MAXSHOW, WndProcHook.SizeToParam((uint) adjustedWidth, (uint) adjustedHeight));
|
||||||
|
SendMessage(_currentHwnd, WM.WM_PAINT, 0, 0);
|
||||||
|
SendMessage(_currentHwnd, WM.WM_EXITSIZEMOVE, 0, 0);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_currentlyFakeResize = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Service.PluginLog.Error($"Unknown ForceSizeMode: {Service.DebugConfig.ForceSizeMode}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_wasEnabled != enabled)
|
||||||
|
{
|
||||||
|
Service.PluginLog.Info($"Changed state to: {enabled}");
|
||||||
|
_wasEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Service.PluginLog.Debug($"NewWidth 0x{(long) (IntPtr) (&dev->NewWidth):X16}");
|
//Service.PluginLog.Debug($"NewWidth 0x{(long) (IntPtr) (&dev->NewWidth):X16}");
|
||||||
|
@ -423,7 +467,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
||||||
{
|
{
|
||||||
case SystemConfigOption.ScreenWidth:
|
case SystemConfigOption.ScreenWidth:
|
||||||
case SystemConfigOption.ScreenHeight:
|
case SystemConfigOption.ScreenHeight:
|
||||||
if (Service.DebugConfig.SetSizeMode == SetSizeMode.InterceptSystemConfig)
|
if (Service.DebugConfig.SetWindowSizeMode == SetWindowSizeMode.InterceptSystemConfig)
|
||||||
{
|
{
|
||||||
var name = e.ConfigOption.ToString();
|
var name = e.ConfigOption.ToString();
|
||||||
var valueOrig = Service.GameConfig.System.GetUInt(name);
|
var valueOrig = Service.GameConfig.System.GetUInt(name);
|
||||||
|
@ -448,3 +492,22 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ForceSizeMode
|
||||||
|
{
|
||||||
|
Skip = -1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fake a window resize event.
|
||||||
|
/// </summary>
|
||||||
|
FakeWindowResize = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Legacy mode, went through more initial testing, works well except for conflicts with other plugins.
|
||||||
|
/// Might revert or remove depending on how FakeWindowResize testing / fixups proceed.
|
||||||
|
///
|
||||||
|
/// Update the graphics device width / height and set RequestResolutionChange.
|
||||||
|
/// This is the same method that other plugins such as SimpleTweaks or XIVWindowResizer use.
|
||||||
|
/// </summary>
|
||||||
|
LegacyRequestResolutionChange = 1
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ time than I have on my hands right now.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details><summary>I'm using DLSS, and my game looks pixelated / is small!</summary>
|
<details><summary>I'm using DLSS, and my game looks pixelated / is small!</summary>
|
||||||
DLSS and cres at very small scales (width / height under about 500 pixels) seems to be a conflicting combo.
|
DLSS in FFXIV is bugged. No, I'm not joking: even without any plugins or mods loaded, it can glitch out when
|
||||||
Resizing the game window usually undoes any miniaturization, but I've yet to figure out why the game pixelates. Sorry!
|
simply resizing the window (most notably by rapidly pressing WinKey + Down and WinKey + Up).
|
||||||
|
|
||||||
|
This issue doesn't happen with FSR and non-DLSS dynamic resolution.
|
||||||
</details>
|
</details>
|
||||||
|
|
Loading…
Add table
Reference in a new issue