Skip to content

Commit 12873ce

Browse files
authored
Merge pull request #1005 from maximegmd/feature/fix-cursor
Fix ImGui spam of ShowCursor/HideCursor
2 parents c3fd1db + 16557fe commit 12873ce

File tree

6 files changed

+13
-94
lines changed

6 files changed

+13
-94
lines changed

src/d3d12/D3D12.cpp

+4-21
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,11 @@
99

1010
void D3D12::SetTrapInputInImGui(const bool acEnabled)
1111
{
12-
// Must have an out-condition to this otherwise infinite loop
13-
static int constexpr maxCursorDepth = 8;
14-
int showCursorTries = 0;
15-
int showCursorState;
16-
if (acEnabled)
17-
do
18-
{
19-
showCursorState = ShowCursor(TRUE);
20-
} while (showCursorState < 0 && showCursorTries++ < maxCursorDepth);
21-
else
22-
do
23-
{
24-
showCursorState = ShowCursor(FALSE);
25-
} while (showCursorState >= 0 && showCursorTries++ < maxCursorDepth);
26-
27-
// Turn off software cursor
28-
if (showCursorTries < maxCursorDepth || acEnabled == false)
29-
ImGui::GetIO().MouseDrawCursor = false;
12+
static const RED4ext::CName cReason = "ImGui";
13+
static RED4ext::UniversalRelocFunc<void (*)(RED4ext::CBaseEngine::UnkD0* apThis, RED4ext::CName aReason, bool aShow)>
14+
forceCursor(CyberEngineTweaks::AddressHashes::InputSystemWin32Base_ForceCursor);
3015

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

3518
m_trapInputInImGui = acEnabled;
3619
}

src/d3d12/D3D12_Functions.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ bool D3D12::Initialize()
8181

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

316+
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; // Do not modify cursor from ImGui backend
317+
316318
if (!ImGui_ImplWin32_Init(m_window.GetWindow()))
317319
{
318320
Log::Error("D3D12::InitializeImGui() - ImGui_ImplWin32_Init call failed!");

src/d3d12/D3D12_Hooks.cpp

+2-12
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,6 @@
88

99
#include <VersionHelpers.h>
1010

11-
void* ApplyHook(void** vtable, size_t index, void* target)
12-
{
13-
DWORD oldProtect;
14-
VirtualProtect(vtable + index, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
15-
const auto ret = vtable[index];
16-
vtable[index] = target;
17-
VirtualProtect(vtable + index, 8, oldProtect, nullptr);
18-
19-
return ret;
20-
}
21-
2211
void* D3D12::CRenderNode_Present_InternalPresent(int32_t* apDeviceIndex, uint8_t aSomeSync, UINT aSyncInterval)
2312
{
2413
auto& d3d12 = CET::Get().GetD3D12();
@@ -80,10 +69,11 @@ ID3D12Device* D3D12::GetDevice() const
8069
std::tuple<D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_GPU_DESCRIPTOR_HANDLE> D3D12::CreateTextureDescriptor()
8170
{
8271
const UINT handle_increment = m_pd3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
83-
static std::atomic descriptor_index = 1;
72+
static std::atomic descriptor_index = 1; // 0 is used for ImGui font texture
8473

8574
const auto index = descriptor_index++;
8675

76+
// We allocate 200 descriptors
8777
if (index >= 200)
8878
return {{}, {}};
8979

src/overlay/Overlay.cpp

+2-49
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ void Overlay::PostInitialize()
1818

1919
auto& d3d12 = CET::Get().GetD3D12();
2020
d3d12.DelayedSetTrapInputInImGui(true);
21-
ClipToCenter(RED4ext::CGameEngine::Get()->unkD0);
2221
}
2322
else
2423
{
@@ -194,8 +193,6 @@ void Overlay::Update()
194193

195194
auto& d3d12 = CET::Get().GetD3D12();
196195
d3d12.DelayedSetTrapInputInImGui(m_enabled);
197-
auto* pEngine = RED4ext::CGameEngine::Get();
198-
ClipToCenter(pEngine->unkD0);
199196
m_toggled = false;
200197
}
201198
}
@@ -211,9 +208,9 @@ void Overlay::Update()
211208
ImGui::RenderNotifications();
212209

213210
//——————————————————————————————— WARNING ———————————————————————————————
214-
// Argument MUST match the amount of ImGui::PushStyleVar() calls
211+
// Argument MUST match the amount of ImGui::PushStyleVar() calls
215212
ImGui::PopStyleVar(2);
216-
// Argument MUST match the amount of ImGui::PushStyleColor() calls
213+
// Argument MUST match the amount of ImGui::PushStyleColor() calls
217214
ImGui::PopStyleColor(1);
218215

219216
if (!m_enabled)
@@ -240,48 +237,6 @@ bool Overlay::IsInitialized() const noexcept
240237
return m_initialized;
241238
}
242239

243-
BOOL Overlay::ClipToCenter(RED4ext::CGameEngine::UnkD0* apThis)
244-
{
245-
const auto wnd = static_cast<HWND>(apThis->hWnd);
246-
const HWND foreground = GetForegroundWindow();
247-
248-
if (wnd == foreground && apThis->unk174 && !apThis->unk164 && !CET::Get().GetOverlay().IsEnabled())
249-
{
250-
RECT rect;
251-
GetClientRect(wnd, &rect);
252-
ClientToScreen(wnd, reinterpret_cast<POINT*>(&rect.left));
253-
ClientToScreen(wnd, reinterpret_cast<POINT*>(&rect.right));
254-
rect.left = (rect.left + rect.right) / 2;
255-
rect.right = rect.left;
256-
rect.bottom = (rect.bottom + rect.top) / 2;
257-
rect.top = rect.bottom;
258-
apThis->isClipped = true;
259-
ShowCursor(FALSE);
260-
return ClipCursor(&rect);
261-
}
262-
263-
if (apThis->isClipped)
264-
{
265-
apThis->isClipped = false;
266-
return ClipCursor(nullptr);
267-
}
268-
269-
return 1;
270-
}
271-
272-
void Overlay::Hook()
273-
{
274-
const RED4ext::UniversalRelocPtr<uint8_t> func(CyberEngineTweaks::AddressHashes::CWinapi_ClipToCenter);
275-
276-
if (auto* pLocation = func.GetAddr())
277-
{
278-
if (MH_CreateHook(pLocation, reinterpret_cast<void*>(&ClipToCenter), reinterpret_cast<void**>(&m_realClipToCenter)) != MH_OK || MH_EnableHook(pLocation) != MH_OK)
279-
Log::Error("Could not hook mouse clip function!");
280-
else
281-
Log::Info("Hook mouse clip function!");
282-
}
283-
}
284-
285240
Overlay::Overlay(VKBindings& aBindings, Options& aOptions, PersistentState& aPersistentState, LuaVM& aVm)
286241
: m_console(aOptions, aPersistentState, aVm)
287242
, m_bindings(aBindings, aVm)
@@ -291,8 +246,6 @@ Overlay::Overlay(VKBindings& aBindings, Options& aOptions, PersistentState& aPer
291246
, m_persistentState(aPersistentState)
292247
, m_vm(aVm)
293248
{
294-
Hook();
295-
296249
GameMainThread::Get().AddBaseInitializationTask(
297250
[this]
298251
{

src/overlay/Overlay.h

-9
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
#include "widgets/GameLog.h"
88
#include "widgets/ImGuiDebug.h"
99

10-
using TClipToCenter = HWND(RED4ext::CGameEngine::UnkD0*);
11-
1210
struct Overlay
1311
{
1412
Overlay(VKBindings& aBindings, Options& aOptions, PersistentState& aPersistentState, LuaVM& aVm);
@@ -27,11 +25,6 @@ struct Overlay
2725

2826
void Update();
2927

30-
protected:
31-
void Hook();
32-
33-
static BOOL ClipToCenter(RED4ext::CGameEngine::UnkD0* apThis);
34-
3528
private:
3629
void DrawToolbar();
3730

@@ -42,8 +35,6 @@ struct Overlay
4235
GameLog m_gameLog;
4336
ImGuiDebug m_imguiDebug;
4437

45-
TClipToCenter* m_realClipToCenter{nullptr};
46-
4738
std::atomic_bool m_enabled{false};
4839
std::atomic_bool m_toggled{false};
4940
bool m_initialized{false};

src/reverse/Addresses.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ constexpr uint32_t CScript_TweakDBLoad = 3602585178UL; // game::data::
5959
constexpr uint32_t CShutdownState_OnTick = 4069332669UL; // red::GameAppShutdownState::OnTick
6060
#pragma endregion
6161

62-
#pragma region CWinapi
63-
constexpr uint32_t CWinapi_ClipToCenter = 261693736UL; // input::InputSystemWin32Base::Update
62+
#pragma region InputSystemWin32Base
63+
constexpr uint32_t InputSystemWin32Base_ForceCursor = 2130646213UL; // input::InputSystemWin32Base::ForceCursor
6464
#pragma endregion
6565

6666
#pragma region gameIGameSystem

0 commit comments

Comments
 (0)