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;
|
||||
|
||||
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.");
|
||||
return;
|
||||
|
||||
case "debugsizenew":
|
||||
Service.DebugConfig.SetSizeMode = SetSizeMode.InterceptSystemConfig;
|
||||
Service.DebugConfig.ForceSizeMode = ForceSizeMode.FakeWindowResize;
|
||||
Service.PrintChat("Switched back to new size mode.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,13 +8,15 @@ public class DebugConfiguration
|
|||
{
|
||||
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>
|
||||
/// 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,
|
||||
/// 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
|
||||
|
@ -22,8 +24,10 @@ public enum SetSizeMode
|
|||
InterceptSystemConfig = 0,
|
||||
|
||||
/// <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.
|
||||
///
|
||||
/// Hook SetWindowPos and turn the wanted size from scaled to window size on the fly.
|
||||
/// </summary>
|
||||
LegacyHookSetWindowPos = 1
|
||||
}
|
||||
|
|
|
@ -62,13 +62,18 @@ public sealed unsafe class WindowRectHooks : IDisposable
|
|||
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)
|
||||
{
|
||||
#if false
|
||||
Service.PluginLog.Debug($"SetWindowPosDetour A @ {X} {Y} {cx} {cy}");
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
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;
|
||||
value |= ((ushort) (short) x) & 0xFFFF;
|
||||
value |= ((ushort) (short) y) >> 16 & 0xFFFF;
|
||||
value |= (((ushort) (short) y) & 0xFFFF) << 16;
|
||||
|
||||
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);
|
||||
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;
|
||||
value |= ((ushort) x) & 0xFFFF;
|
||||
value |= ((ushort) y) >> 16 & 0xFFFF;
|
||||
value |= (((ushort) y) & 0xFFFF) << 16;
|
||||
|
||||
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.Plugin;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
@ -29,6 +30,8 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
|||
private RECT _currentClientRect;
|
||||
private DXVKDWMHackMode _currentDXVKDWMHackMode = DXVKDWMHackMode.Off;
|
||||
private bool _ignoreConfigChanges = false;
|
||||
private bool _currentlyFakeResize = false;
|
||||
private bool _requestedResolutionChange = false;
|
||||
|
||||
public Plugin(IDalamudPluginInterface pluginInterface)
|
||||
{
|
||||
|
@ -226,14 +229,9 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
|||
return;
|
||||
}
|
||||
|
||||
uint width, height;
|
||||
|
||||
var enabled = !_unloading && Service.Config.IsEnabled;
|
||||
if (_wasEnabled != enabled)
|
||||
{
|
||||
Service.PluginLog.Info($"Changing state to: {enabled}");
|
||||
_wasEnabled = enabled;
|
||||
}
|
||||
|
||||
uint width, height;
|
||||
|
||||
if (Service.Config.IsScale || !enabled)
|
||||
{
|
||||
|
@ -258,15 +256,61 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
|||
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}");
|
||||
var mode = Service.DebugConfig.ForceSizeMode;
|
||||
if (_requestedResolutionChange)
|
||||
{
|
||||
// Let's try to be cautious about other plugins (f.e. SimpleTweaks) changing the game resolution.
|
||||
Service.PluginLog.Info($"Game resolution was changed externally - forcing resize via device, not window resize.");
|
||||
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}");
|
||||
|
@ -423,7 +467,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
|
|||
{
|
||||
case SystemConfigOption.ScreenWidth:
|
||||
case SystemConfigOption.ScreenHeight:
|
||||
if (Service.DebugConfig.SetSizeMode == SetSizeMode.InterceptSystemConfig)
|
||||
if (Service.DebugConfig.SetWindowSizeMode == SetWindowSizeMode.InterceptSystemConfig)
|
||||
{
|
||||
var name = e.ConfigOption.ToString();
|
||||
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><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.
|
||||
Resizing the game window usually undoes any miniaturization, but I've yet to figure out why the game pixelates. Sorry!
|
||||
DLSS in FFXIV is bugged. No, I'm not joking: even without any plugins or mods loaded, it can glitch out when
|
||||
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>
|
||||
|
|
Loading…
Add table
Reference in a new issue