diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj
index 79fe912dd..336b1ed3d 100644
--- a/Dalamud/Dalamud.csproj
+++ b/Dalamud/Dalamud.csproj
@@ -48,6 +48,7 @@
+
diff --git a/Dalamud/Game/Internal/DXGI/DXHookD3D11.cs b/Dalamud/Game/Internal/DXGI/DXHookD3D11.cs
new file mode 100644
index 000000000..92739ae6e
--- /dev/null
+++ b/Dalamud/Game/Internal/DXGI/DXHookD3D11.cs
@@ -0,0 +1,89 @@
+using SharpDX.Direct3D;
+using SharpDX.Direct3D11;
+using SharpDX.DXGI;
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Dalamud.Game.Internal.DXGI
+{
+ public class DXHookD3D11
+ {
+ const int DXGI_SWAPCHAIN_METHOD_COUNT = 18;
+ const int D3D11_DEVICE_METHOD_COUNT = 43;
+
+ public static SharpDX.DXGI.SwapChainDescription CreateSwapChainDescription(IntPtr renderForm)
+ {
+ return new SharpDX.DXGI.SwapChainDescription
+ {
+ BufferCount = 1,
+ Flags = SharpDX.DXGI.SwapChainFlags.None,
+ IsWindowed = true,
+ ModeDescription = new SharpDX.DXGI.ModeDescription(100, 100, new Rational(60, 1), SharpDX.DXGI.Format.R8G8B8A8_UNorm),
+ OutputHandle = renderForm,
+ SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
+ SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
+ Usage = SharpDX.DXGI.Usage.RenderTargetOutput
+ };
+ }
+
+ protected IntPtr[] GetVTblAddresses(IntPtr pointer, int numberOfMethods)
+ {
+ return GetVTblAddresses(pointer, 0, numberOfMethods);
+ }
+
+ protected IntPtr[] GetVTblAddresses(IntPtr pointer, int startIndex, int numberOfMethods)
+ {
+ List vtblAddresses = new List();
+ IntPtr vTable = Marshal.ReadIntPtr(pointer);
+ for (int i = startIndex; i < startIndex + numberOfMethods; i++)
+ vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size)); // using IntPtr.Size allows us to support both 32 and 64-bit processes
+
+ return vtblAddresses.ToArray();
+ }
+
+ List _d3d11VTblAddresses = null;
+ List _dxgiSwapChainVTblAddresses = null;
+
+ #region Internal device resources
+ SharpDX.Direct3D11.Device _device;
+ SharpDX.DXGI.SwapChain _swapChain;
+ SharpDX.Windows.RenderForm _renderForm;
+ #endregion
+
+ #region Main device resources
+ public SharpDX.Windows.RenderForm RenderForm { get => _renderForm; set => _renderForm = value; }
+ #endregion
+
+ public IntPtr Hook()
+ {
+
+ if (_d3d11VTblAddresses == null)
+ {
+ _d3d11VTblAddresses = new List();
+ _dxgiSwapChainVTblAddresses = new List();
+
+ #region Get Device and SwapChain method addresses
+ // Create temporary device + swapchain and determine method addresses
+ RenderForm = new SharpDX.Windows.RenderForm();
+ SharpDX.Direct3D11.Device.CreateWithSwapChain(
+ DriverType.Hardware,
+ DeviceCreationFlags.BgraSupport,
+ CreateSwapChainDescription(RenderForm.Handle),
+ out _device,
+ out _swapChain
+ );
+ if (_device != null && _swapChain != null)
+ {
+ _d3d11VTblAddresses.AddRange(GetVTblAddresses(_device.NativePointer, D3D11_DEVICE_METHOD_COUNT));
+ _dxgiSwapChainVTblAddresses.AddRange(GetVTblAddresses(_swapChain.NativePointer, DXGI_SWAPCHAIN_METHOD_COUNT));
+ }
+ _device.Dispose();
+ _swapChain.Dispose();
+ #endregion
+ }
+
+ return _dxgiSwapChainVTblAddresses[8];
+ }
+ }
+}
diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs
index 4b1be233f..a5d585fcd 100644
--- a/Dalamud/Interface/InterfaceManager.cs
+++ b/Dalamud/Interface/InterfaceManager.cs
@@ -27,7 +27,7 @@ namespace Dalamud.Interface
private readonly Hook presentHook;
- private SwapChainAddressResolver Address { get; }
+ private DXHookD3D11 dXHookD3D11 = new DXHookD3D11();
private RawDX11Scene scene;
@@ -38,16 +38,15 @@ namespace Dalamud.Interface
public InterfaceManager(SigScanner scanner)
{
- Address = new SwapChainAddressResolver();
- Address.Setup(scanner);
+ IntPtr addr = dXHookD3D11.Hook();
Log.Verbose("===== S W A P C H A I N =====");
- Log.Verbose("Present address {Present}", Address.Present);
+ Log.Verbose("Present address {Present}", addr);
this.presentHook =
- new Hook(Address.Present,
- new PresentDelegate(PresentDetour),
- this);
+ new Hook(addr,
+ new PresentDelegate(PresentDetour),
+ this);
}
public void Enable()