/// <summary> /// Instantiates the DirectX overlay, by first finding the applicable /// version of DirectX for the application and then finding the individual /// details. For more details, see <see cref="DX9Overlay"/> /// Note: This method is blocking and Reloaded mods are required to return in order /// to boot up the games, please do not assign this statically - instead assign it in a background thread! /// </summary> /// <param name="renderDelegate"> /// A delegate type to use for DirectX rendering. The delegate type should /// contain an appropriate DirectX <see cref="Direct3D9Device_EndSceneDelegate"/> /// object for drawing overlays. /// </param> /// <param name="resetDelegate"> /// A delegate or function of type of <see cref="Direct3D9Device_ResetDelegate"/> to call when D3D9 fires its Reset function, /// called on resolution change or windowed/fullscreen change - we can reset some things as well. /// </param> /// <param name="hookDelay"> /// Specifies the amount of time to wait until the hook is instantiation begins. /// Some games are known to crash if DirectX is hooked too early. /// </param> public static async Task <DX9Overlay> CreateDirectXOverlay(Direct3D9Device_EndSceneDelegate renderDelegate, Direct3D9Device_ResetDelegate resetDelegate, int hookDelay) { // Wait the hook delay. await Task.Delay(hookDelay); // Create a new self-object. DX9Overlay dx9Overlay = new DX9Overlay(); // Wait for DirectX Direct3DVersion direct3DVersion = await DXHookCommon.DetermineDirectXVersion(); // Return nothing if not D3D9 if (direct3DVersion != Direct3DVersion.Direct3D9) { Bindings.PrintError( "libReloaded Hooking: DirectX 9 module not found, the application is either not" + "a DirectX 9 application or uses an unsupported version of DirectX."); return(null); } // Instantiate DX9 hook dx9Overlay.DirectX9Hook = new DX9Hook(); // Obtain Virtual Function Table Entries VirtualFunctionTable.TableEntry endSceneTableEntry = dx9Overlay.DirectX9Hook.DirectXFunctions[(int)Direct3DDevice9.EndScene]; VirtualFunctionTable.TableEntry resetTableEntry = dx9Overlay.DirectX9Hook.DirectXFunctions[(int)Direct3DDevice9.Reset]; // Hook relevant DirectX functions. dx9Overlay.EndSceneHook = new FunctionHook <Direct3D9Device_EndSceneDelegate>((long)endSceneTableEntry.FunctionPointer, renderDelegate); dx9Overlay.ResetHook = new FunctionHook <Direct3D9Device_ResetDelegate>((long)resetTableEntry.FunctionPointer, resetDelegate); // Return our DX9Overlay return(dx9Overlay); }
/// <summary> /// Generates a wrapper function for an individual virtual function table entry /// in a virtual function table. /// </summary> /// <typeparam name="TFunction">Delegate type marked with complete ReloadedFunction Attribute/X64 Reloaded Function Attribute that defines the individual function properties.</typeparam> /// <param name="tableEntry">The individual Virtual function table entry to create a wrapper function for.</param> /// <returns>Delegate to assign back to ReloadedFunction marked game function.</returns> public static TFunction CreateWrapperFunction <TFunction>(this VirtualFunctionTable.TableEntry tableEntry) { // Create X86/X64 wrapper conditionally. if (IntPtr.Size == 4) { return(FunctionWrapper.CreateWrapperFunction <TFunction>((long)tableEntry.FunctionPointer)); } if (IntPtr.Size == 8) { return(X64FunctionWrapper.CreateWrapperFunction <TFunction>((long)tableEntry.FunctionPointer)); } // Null case return(default(TFunction)); }
/// <summary> /// Instantiates the DirectX overlay, by first finding the applicable /// version of DirectX for the application and then finding the individual /// details. For more details, see <see cref="DX11Overlay"/> /// /// Note: The delegates you will need to call the original function are members of this class, see <see cref="PresentHook"/> and <see cref="ResizeTargetHook"/> /// Note: This method is blocking and Reloaded mods are required to return in order /// to boot up the games, please do not assign this statically - instead assign it in a background thread! /// </summary> /// <param name="DXGIPresentDelegate"> /// A delegate type to use for DirectX rendering. The delegate type should /// contain an appropriate DirectX <see cref="DXGISwapChain_PresentDelegate"/> /// object for drawing overlays. /// </param> /// <param name="DXGIResizeTargetDelegate"> /// A delegate or function of type of <see cref="DXGISwapChain_ResizeTargetDelegate"/> to call when DXGI Buffer /// commits a resolution change or windowed/fullscreen change. /// </param> /// <param name="hookDelay"> /// Specifies the amount of time to wait until the hook is instantiation begins. /// Some games are known to crash if DirectX is hooked too early. /// </param> /// <remarks>The delegates you will need to call the original function are members of this class, see <see cref="PresentHook"/> and <see cref="ResizeTargetHook"/></remarks> public static async Task <DX11Overlay> CreateDirectXOverlay(DXGISwapChain_PresentDelegate DXGIPresentDelegate, DXGISwapChain_ResizeTargetDelegate DXGIResizeTargetDelegate, int hookDelay) { // Wait the hook delay. await Task.Delay(hookDelay); // Create a new self-object. DX11Overlay dx11Overlay = new DX11Overlay(); // Wait for DirectX Direct3DVersion direct3DVersion = await DXHookCommon.GetDirectXVersion(); // Return nothing if not D3D9 if (direct3DVersion != Direct3DVersion.Direct3D11 && direct3DVersion != Direct3DVersion.Direct3D11_1 && direct3DVersion != Direct3DVersion.Direct3D11_3 && direct3DVersion != Direct3DVersion.Direct3D11_4) { Bindings.PrintError( "libReloaded Hooking: DirectX 11 module not found, the application is either not " + "a DirectX 11 application or uses an unsupported version of DirectX."); return(null); } // Instantiate DX9 hook dx11Overlay.DirectX11Hook = new DX11Hook();; // Obtain Virtual Function Table Entries VirtualFunctionTable.TableEntry presentTableEntry = dx11Overlay.DirectX11Hook.DXGISwapChainFunctions[(int)IDXGISwapChain.Present]; VirtualFunctionTable.TableEntry resizeTableEntry = dx11Overlay.DirectX11Hook.DXGISwapChainFunctions[(int)IDXGISwapChain.ResizeTarget]; // Hook relevant DirectX functions. if (IntPtr.Size == 4) { // X86 dx11Overlay.PresentHook = FunctionHook <DXGISwapChain_PresentDelegate> .Create((long)presentTableEntry.FunctionPointer, DXGIPresentDelegate); dx11Overlay.ResizeTargetHook = FunctionHook <DXGISwapChain_ResizeTargetDelegate> .Create((long)resizeTableEntry.FunctionPointer, DXGIResizeTargetDelegate); } else if (IntPtr.Size == 8) { // X64 dx11Overlay.PresentHook64 = X64FunctionHook <DXGISwapChain_PresentDelegate> .Create((long)presentTableEntry.FunctionPointer, DXGIPresentDelegate); dx11Overlay.ResizeTargetHook64 = X64FunctionHook <DXGISwapChain_ResizeTargetDelegate> .Create((long)resizeTableEntry.FunctionPointer, DXGIResizeTargetDelegate); } // Return our DX9Overlay return(dx11Overlay); }
/// <summary> /// Sets up the individual Direct3D Contstants and objects used for rendering. /// </summary> /// <param name="device"></param> private static unsafe void SetupRenderingConstants(Device device) { // Create our individual devices and fonts if necessary. // (Normally you would do this on initialization, not in the render function but this is just for clarity). if (!_initialized) { // Let's create a line for us to draw later. _sampleLine = new Line(device); _lineVertices = new[] { new RawVector2(100, 300), new RawVector2(150, 200), new RawVector2(250, 200) }; // Create a font for us to draw later (SharpDX D3D9 Font) _sampleFont = new Font(device, 20, 0, FontWeight.Normal, 1, false, FontCharacterSet.Ansi, FontPrecision.Default, FontQuality.ClearType, FontPitchAndFamily.Modern, "Times New Roman"); // Set position of text and colour of line + text. _semiTransparentGray = new RawColorBGRA(255, 255, 255, 128); _textRectangle = new RawRectangle(100, 100, 9999, 9999); // Create triangle vertices. // Fun fact: W acts as the blend factor here. _triangleVertices = new[] { new Vertex() { Color = Color.Red, Position = new Vector4(400.0f, 100.0f, 0.5f, 1.0f) }, new Vertex() { Color = Color.Blue, Position = new Vector4(650.0f, 500.0f, 0.5f, 1.0f) }, new Vertex() { Color = Color.Green, Position = new Vector4(150.0f, 500.0f, 0.5f, 1.0f) } }; // Set vertex render mode for our vertices. _vertexRenderingModes = new[] { VertexRenderingMode.RedToGreen, VertexRenderingMode.BlueToRed, VertexRenderingMode.GreenToBlue }; // Create vertex buffer. _localVertexBuffer = new VertexBuffer(device, sizeof(Vertex) * 3, 0, VertexFormat.None, Pool.Default); _localVertexBuffer.Lock(0, 0, LockFlags.None).WriteRange(_triangleVertices); _localVertexBuffer.Unlock(); // Specifies the Vertex Format var vertexElems = new[] { new VertexElement(0, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.PositionTransformed, 0), new VertexElement(0, 16, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0), VertexElement.VertexDeclarationEnd }; _vertexDeclaration = new VertexDeclaration(device, vertexElems); // Wrap SetPixelShader for us to call later (otherwise our shape may not show) // This uses Reloaded's Virtual Function Table Utility Class if (_directX9Overlay != null) { VirtualFunctionTable.TableEntry vTableEntry = _directX9Overlay.DirectX9Hook.DirectXFunctions[(int)Direct3DDevice9.SetPixelShader]; _setPixelShaderFunction = vTableEntry.CreateWrapperFunction <SetPixelShaderDelegate>(); } // Never run this again. _initialized = true; } }
/// <summary> /// Hooks an individual virtual function table entry in a virtual function table. /// </summary> /// <typeparam name="TFunction">Delegate type marked with complete ReloadedFunction Attribute/X64 Reloaded Function Attribute that defines the individual function properties.</typeparam> /// <param name="tableEntry">The individual Virtual function table entry to hook.</param> /// <param name="delegateType">The delegate type of your own individual function, such as an instance of the delegate.</param> /// <returns>Delegate to assign back to ReloadedFunction marked game function.</returns> public static X64FunctionHook <TFunction> CreateFunctionHook64 <TFunction>(this VirtualFunctionTable.TableEntry tableEntry, TFunction delegateType) { return(X64FunctionHook <TFunction> .Create((long)tableEntry.FunctionPointer, delegateType)); }
/// <summary> /// Generates a wrapper function for an individual virtual function table entry /// in a virtual function table. /// </summary> /// <typeparam name="TFunction">Delegate type marked with complete ReloadedFunction Attribute that defines the individual function properties.</typeparam> /// <param name="tableEntry">The individual Virtual function table entry to create a wrapper function for.</param> /// <returns>Delegate to assign back to ReloadedFunction marked game function.</returns> public static TFunction CreateX86WrapperFunction <TFunction>(this VirtualFunctionTable.TableEntry tableEntry) { return(FunctionWrapper.CreateWrapperFunction <TFunction>((long)tableEntry.FunctionPointer)); }