Example #1
0
        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;
            }
        }
Example #2
0
        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;
            }
        }
Example #3
0
 private void Shutdown()
 {
     Debug.WriteLine($"[DX9 Shutdown] Shutdown");
     ImGui.ImGuiImplDX9Shutdown();
     _windowHandle = IntPtr.Zero;
     _device       = IntPtr.Zero;
     _initialized  = false;
     ImguiHook.Shutdown();
 }
Example #4
0
        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;
            }
        }
Example #5
0
        /// <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);
            }
        }