Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ImGui spam of ShowCursor/HideCursor #1005

Merged
merged 1 commit into from
Mar 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions src/d3d12/D3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,11 @@

void D3D12::SetTrapInputInImGui(const bool acEnabled)
{
// Must have an out-condition to this otherwise infinite loop
static int constexpr maxCursorDepth = 8;
int showCursorTries = 0;
int showCursorState;
if (acEnabled)
do
{
showCursorState = ShowCursor(TRUE);
} while (showCursorState < 0 && showCursorTries++ < maxCursorDepth);
else
do
{
showCursorState = ShowCursor(FALSE);
} while (showCursorState >= 0 && showCursorTries++ < maxCursorDepth);

// Turn off software cursor
if (showCursorTries < maxCursorDepth || acEnabled == false)
ImGui::GetIO().MouseDrawCursor = false;
static const RED4ext::CName cReason = "ImGui";
static RED4ext::UniversalRelocFunc<void (*)(RED4ext::CBaseEngine::UnkD0* apThis, RED4ext::CName aReason, bool aShow)>
forceCursor(CyberEngineTweaks::AddressHashes::InputSystemWin32Base_ForceCursor);

// Enable software cursor as fallback if necessary
else
ImGui::GetIO().MouseDrawCursor = acEnabled;
forceCursor(RED4ext::CGameEngine::Get()->unkD0, cReason, acEnabled);

m_trapInputInImGui = acEnabled;
}
Expand Down
4 changes: 3 additions & 1 deletion src/d3d12/D3D12_Functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ bool D3D12::Initialize()

D3D12_DESCRIPTOR_HEAP_DESC srvdesc = {};
srvdesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
srvdesc.NumDescriptors = buffersCounts;
srvdesc.NumDescriptors = 200; // Same number as is used in scripting/Texture
srvdesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
if (FAILED(m_pd3d12Device->CreateDescriptorHeap(&srvdesc, IID_PPV_ARGS(&m_pd3dSrvDescHeap))))
{
Expand Down Expand Up @@ -313,6 +313,8 @@ bool D3D12::InitializeImGui(size_t aBuffersCounts)
ImGui::GetStyle() = m_styleReference;
ImGui::GetStyle().ScaleAllSizes(scaleFromReference);

ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; // Do not modify cursor from ImGui backend

if (!ImGui_ImplWin32_Init(m_window.GetWindow()))
{
Log::Error("D3D12::InitializeImGui() - ImGui_ImplWin32_Init call failed!");
Expand Down
14 changes: 2 additions & 12 deletions src/d3d12/D3D12_Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,6 @@

#include <VersionHelpers.h>

void* ApplyHook(void** vtable, size_t index, void* target)
{
DWORD oldProtect;
VirtualProtect(vtable + index, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
const auto ret = vtable[index];
vtable[index] = target;
VirtualProtect(vtable + index, 8, oldProtect, nullptr);

return ret;
}

void* D3D12::CRenderNode_Present_InternalPresent(int32_t* apDeviceIndex, uint8_t aSomeSync, UINT aSyncInterval)
{
auto& d3d12 = CET::Get().GetD3D12();
Expand Down Expand Up @@ -80,10 +69,11 @@ ID3D12Device* D3D12::GetDevice() const
std::tuple<D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_GPU_DESCRIPTOR_HANDLE> D3D12::CreateTextureDescriptor()
{
const UINT handle_increment = m_pd3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
static std::atomic descriptor_index = 1;
static std::atomic descriptor_index = 1; // 0 is used for ImGui font texture

const auto index = descriptor_index++;

// We allocate 200 descriptors
if (index >= 200)
return {{}, {}};

Expand Down
51 changes: 2 additions & 49 deletions src/overlay/Overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ void Overlay::PostInitialize()

auto& d3d12 = CET::Get().GetD3D12();
d3d12.DelayedSetTrapInputInImGui(true);
ClipToCenter(RED4ext::CGameEngine::Get()->unkD0);
}
else
{
Expand Down Expand Up @@ -194,8 +193,6 @@ void Overlay::Update()

auto& d3d12 = CET::Get().GetD3D12();
d3d12.DelayedSetTrapInputInImGui(m_enabled);
auto* pEngine = RED4ext::CGameEngine::Get();
ClipToCenter(pEngine->unkD0);
m_toggled = false;
}
}
Expand All @@ -211,9 +208,9 @@ void Overlay::Update()
ImGui::RenderNotifications();

//——————————————————————————————— WARNING ———————————————————————————————
// Argument MUST match the amount of ImGui::PushStyleVar() calls
// Argument MUST match the amount of ImGui::PushStyleVar() calls
ImGui::PopStyleVar(2);
// Argument MUST match the amount of ImGui::PushStyleColor() calls
// Argument MUST match the amount of ImGui::PushStyleColor() calls
ImGui::PopStyleColor(1);

if (!m_enabled)
Expand All @@ -240,48 +237,6 @@ bool Overlay::IsInitialized() const noexcept
return m_initialized;
}

BOOL Overlay::ClipToCenter(RED4ext::CGameEngine::UnkD0* apThis)
{
const auto wnd = static_cast<HWND>(apThis->hWnd);
const HWND foreground = GetForegroundWindow();

if (wnd == foreground && apThis->unk174 && !apThis->unk164 && !CET::Get().GetOverlay().IsEnabled())
{
RECT rect;
GetClientRect(wnd, &rect);
ClientToScreen(wnd, reinterpret_cast<POINT*>(&rect.left));
ClientToScreen(wnd, reinterpret_cast<POINT*>(&rect.right));
rect.left = (rect.left + rect.right) / 2;
rect.right = rect.left;
rect.bottom = (rect.bottom + rect.top) / 2;
rect.top = rect.bottom;
apThis->isClipped = true;
ShowCursor(FALSE);
return ClipCursor(&rect);
}

if (apThis->isClipped)
{
apThis->isClipped = false;
return ClipCursor(nullptr);
}

return 1;
}

void Overlay::Hook()
{
const RED4ext::UniversalRelocPtr<uint8_t> func(CyberEngineTweaks::AddressHashes::CWinapi_ClipToCenter);

if (auto* pLocation = func.GetAddr())
{
if (MH_CreateHook(pLocation, reinterpret_cast<void*>(&ClipToCenter), reinterpret_cast<void**>(&m_realClipToCenter)) != MH_OK || MH_EnableHook(pLocation) != MH_OK)
Log::Error("Could not hook mouse clip function!");
else
Log::Info("Hook mouse clip function!");
}
}

Overlay::Overlay(VKBindings& aBindings, Options& aOptions, PersistentState& aPersistentState, LuaVM& aVm)
: m_console(aOptions, aPersistentState, aVm)
, m_bindings(aBindings, aVm)
Expand All @@ -291,8 +246,6 @@ Overlay::Overlay(VKBindings& aBindings, Options& aOptions, PersistentState& aPer
, m_persistentState(aPersistentState)
, m_vm(aVm)
{
Hook();

GameMainThread::Get().AddBaseInitializationTask(
[this]
{
Expand Down
9 changes: 0 additions & 9 deletions src/overlay/Overlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
#include "widgets/GameLog.h"
#include "widgets/ImGuiDebug.h"

using TClipToCenter = HWND(RED4ext::CGameEngine::UnkD0*);

struct Overlay
{
Overlay(VKBindings& aBindings, Options& aOptions, PersistentState& aPersistentState, LuaVM& aVm);
Expand All @@ -27,11 +25,6 @@ struct Overlay

void Update();

protected:
void Hook();

static BOOL ClipToCenter(RED4ext::CGameEngine::UnkD0* apThis);

private:
void DrawToolbar();

Expand All @@ -42,8 +35,6 @@ struct Overlay
GameLog m_gameLog;
ImGuiDebug m_imguiDebug;

TClipToCenter* m_realClipToCenter{nullptr};

std::atomic_bool m_enabled{false};
std::atomic_bool m_toggled{false};
bool m_initialized{false};
Expand Down
4 changes: 2 additions & 2 deletions src/reverse/Addresses.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ constexpr uint32_t CScript_TweakDBLoad = 3602585178UL; // game::data::
constexpr uint32_t CShutdownState_OnTick = 4069332669UL; // red::GameAppShutdownState::OnTick
#pragma endregion

#pragma region CWinapi
constexpr uint32_t CWinapi_ClipToCenter = 261693736UL; // input::InputSystemWin32Base::Update
#pragma region InputSystemWin32Base
constexpr uint32_t InputSystemWin32Base_ForceCursor = 2130646213UL; // input::InputSystemWin32Base::ForceCursor
#pragma endregion

#pragma region gameIGameSystem
Expand Down