private int ReleaseImpl(IntPtr device) { if (_releaseRecursionLock) { Debug.WriteLine($"[DX9 Release] Discarding via Recursion Lock"); return(_releaseHook.OriginalFunction.Value.Invoke(device)); } _releaseRecursionLock = true; try { var count = _releaseHook.OriginalFunction.Value.Invoke(device); if (count == 0 && _device == device) { Debug.WriteLine($"[DX9 Release] Shutting Down {(long)device:X}"); Shutdown(); } return(count); } finally { _releaseRecursionLock = false; } }
private IntPtr ResetImpl(IntPtr device, PresentParameters *presentParameters) { // With multi-viewports, ImGui might call EndScene again; so we need to prevent stack overflow here. if (_resetRecursionLock) { Debug.WriteLine($"[DX9 Reset] Discarding via Recursion Lock"); return(_endSceneHook.OriginalFunction.Value.Invoke(device)); } _resetRecursionLock = true; try { // Ignore windows which don't belong to us. if (!ImguiHook.CheckWindowHandle(presentParameters->DeviceWindowHandle)) { Debug.WriteLine($"[DX9 Reset] Discarding Window Handle {(long)presentParameters->DeviceWindowHandle:X}"); return(_resetHook.OriginalFunction.Value.Invoke(device, presentParameters)); } Debug.WriteLine($"[DX9 Reset] Reset with Handle {(long)presentParameters->DeviceWindowHandle:X}"); ImGui.ImGuiImplDX9InvalidateDeviceObjects(); var result = _resetHook.OriginalFunction.Value.Invoke(device, presentParameters); ImGui.ImGuiImplDX9CreateDeviceObjects(); return(result); } finally { _resetRecursionLock = false; } }
private void Shutdown() { Debug.WriteLine($"[DX9 Shutdown] Shutdown"); ImGui.ImGuiImplDX9Shutdown(); _windowHandle = IntPtr.Zero; _device = IntPtr.Zero; _initialized = false; ImguiHook.Shutdown(); }
private unsafe IntPtr EndSceneImpl(IntPtr device) { // With multi-viewports, ImGui might call EndScene again; so we need to prevent stack overflow here. if (_endSceneRecursionLock) { Debug.WriteLine($"[DX9 EndScene] Discarding via Recursion Lock"); return(_endSceneHook.OriginalFunction.Value.Invoke(device)); } _endSceneRecursionLock = true; try { var dev = new Device(device); using var swapChain = dev.GetSwapChain(0); var windowHandle = dev.CreationParameters.HFocusWindow; var swapChainHandle = swapChain.PresentParameters.DeviceWindowHandle; windowHandle = windowHandle == IntPtr.Zero ? swapChainHandle : windowHandle; // Ignore windows which don't belong to us. if (!ImguiHook.CheckWindowHandle(windowHandle)) { Debug.WriteLine($"[DX9 EndScene] Discarding Window Handle {(long)windowHandle:X}"); return(_endSceneHook.OriginalFunction.Value.Invoke(device)); } if (!_initialized) { _device = device; _windowHandle = windowHandle; if (_windowHandle == IntPtr.Zero) { return(_endSceneHook.OriginalFunction.Value.Invoke(device)); } Debug.WriteLine($"[DX9 EndScene] Init, Window Handle {(long)windowHandle:X}"); ImguiHook.InitializeWithHandle(windowHandle); ImGui.ImGuiImplDX9Init((void *)device); _initialized = true; } ImGui.ImGuiImplDX9NewFrame(); ImguiHook.NewFrame(); using var drawData = ImGui.GetDrawData(); ImGui.ImGuiImplDX9RenderDrawData(drawData); return(_endSceneHook.OriginalFunction.Value.Invoke(device)); } finally { _endSceneRecursionLock = false; } }
/// <summary> /// Gets the DirectX version loaded into the current process. /// </summary> /// <param name="candidates">Candidate implementations to check for support.</param> /// <param name="retryTime">Time between retries in milliseconds.</param> /// <param name="timeout">Timeout in milliseconds to determine DX version.</param> public static async Task <List <IImguiHook> > GetSupportedImplementations(List <IImguiHook> candidates, int retryTime = 64, int timeout = 20000) { // Store the amount of attempts taken at hooking DirectX for a process. var stopWatch = new Stopwatch(); stopWatch.Start(); // Loop until DirectX module found. var result = new List <IImguiHook>(); while (true) { foreach (var candidate in candidates) { if (candidate.IsApiSupported()) { result.Add(candidate); } } // Check timeout. if (stopWatch.ElapsedMilliseconds > timeout) { throw new Exception("No working implementation found. The application is either not a DirectX/OpenGL/??? application or uses an unsupported version of the Graphics API."); } // Check every X milliseconds. if (result.Count > 0) { var impls = ""; foreach (var res in result) { impls += $"{res.GetType().Name} |"; } Debug.WriteLine($"| Supported Implementations Detected: {impls}"); return(result); } await Task.Delay(retryTime).ConfigureAwait(false); } }