diff --git a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs b/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs index 0bc05ee39..32e297337 100644 --- a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs +++ b/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Runtime.InteropServices; using Dalamud.Game.Internal.DXGI.Definitions; @@ -26,6 +28,11 @@ namespace Dalamud.Game.Internal.DXGI /// public IntPtr ResizeBuffers { get; set; } + /// + /// Gets a value indicating whether or not ReShade is loaded/used. + /// + public bool IsReshade { get; private set; } + /// protected override unsafe void Setup64Bit(SigScanner sig) { @@ -34,6 +41,32 @@ namespace Dalamud.Game.Internal.DXGI var scVtbl = GetVTblAddresses(new IntPtr(kernelDev->SwapChain->DXGISwapChain), Enum.GetValues(typeof(IDXGISwapChainVtbl)).Length); this.Present = scVtbl[(int)IDXGISwapChainVtbl.Present]; + + var modules = Process.GetCurrentProcess().Modules; + foreach (ProcessModule processModule in modules) + { + if (processModule.FileName != null && processModule.FileName.EndsWith("game\\dxgi.dll")) + { + // reshade master@4232872 RVA + // var p = processModule.BaseAddress + 0x82C7E0; // DXGISwapChain::Present + // var p = processModule.BaseAddress + 0x82FAC0; // DXGISwapChain::runtime_present + + var scanner = new SigScanner(processModule); + try + { + var p = scanner.ScanText("F6 C2 01 0F 85 ?? ?? ?? ??"); + Log.Information($"ReShade DLL: {processModule.FileName} with DXGISwapChain::runtime_present at {p:X}"); + + this.Present = p; + this.IsReshade = true; + } + catch (Exception ex) + { + Log.Error(ex, "Could not find reshade DXGISwapChain::runtime_present offset!"); + } + } + } + this.ResizeBuffers = scVtbl[(int)IDXGISwapChainVtbl.ResizeBuffers]; } diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs index eb76e05ac..0f218f4e5 100644 --- a/Dalamud/Interface/Internal/InterfaceManager.cs +++ b/Dalamud/Interface/Internal/InterfaceManager.cs @@ -320,6 +320,10 @@ namespace Dalamud.Interface.Internal Util.Fatal($"One or more files required by XIVLauncher were not found.\nPlease restart and report this error if it occurs again.\n\n{path}", "Error"); } + /* + * NOTE(goat): When hooking ReShade DXGISwapChain::runtime_present, this is missing the syncInterval arg. + * Seems to work fine regardless, I guess, so whatever. + */ private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags) { if (this.scene != null && swapChain != this.scene.SwapChain.NativePointer) @@ -398,6 +402,22 @@ namespace Dalamud.Interface.Internal Service.Get().Enable(); } + if (this.address.IsReshade) + { + var pRes = this.presentHook.Original(swapChain, syncInterval, presentFlags); + + this.RenderImGui(); + + return pRes; + } + + this.RenderImGui(); + + return this.presentHook.Original(swapChain, syncInterval, presentFlags); + } + + private void RenderImGui() + { // Process information needed by ImGuiHelpers each frame. ImGuiHelpers.NewFrame(); @@ -405,8 +425,6 @@ namespace Dalamud.Interface.Internal this.CheckViewportState(); this.scene.Render(); - - return this.presentHook.Original(swapChain, syncInterval, presentFlags); } private void CheckViewportState()