1+ #include " pch.h"
2+ #include " d3dhook.h"
3+ #include " ../depend/kiero/kiero.h"
4+ #include " ../depend/kiero/minhook/MinHook.h"
5+ #include " ../depend/imgui/imgui_impl_dx9.h"
6+ #include " ../depend/imgui/imgui_impl_dx11.h"
7+ #include " ../depend/imgui/imgui_impl_win32.h"
8+ #include < dinput.h>
9+
10+ #define DIMOUSE ((LPDIRECTINPUTDEVICE8)(RsGlobal.ps->diMouse))
11+ extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
12+
13+ bool D3dHook::GetMouseState ()
14+ {
15+ return mouseShown;
16+ }
17+
18+ void D3dHook::SetMouseState (bool state)
19+ {
20+ mouseShown = state;
21+ }
22+
23+ LRESULT D3dHook::hkWndProc (const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
24+ {
25+ ImGui_ImplWin32_WndProcHandler (hWnd, uMsg, wParam, lParam);
26+
27+ if (ImGui::GetIO ().WantTextInput )
28+ {
29+ #ifdef GTASA
30+ Call<0x53F1E0 >(); // CPad::ClearKeyboardHistory
31+ #endif
32+ return 1 ;
33+ }
34+
35+ return CallWindowProc (oWndProc, hWnd, uMsg, wParam, lParam);
36+ }
37+
38+ HRESULT D3dHook::hkReset (IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
39+ {
40+ ImGui_ImplDX9_InvalidateDeviceObjects ();
41+
42+ return oReset (pDevice, pPresentationParameters);
43+ }
44+
45+ void D3dHook::ProcessFrame (void * ptr)
46+ {
47+ if (!ImGui::GetCurrentContext ())
48+ {
49+ ImGui::CreateContext ();
50+ }
51+
52+ ImGuiIO& io = ImGui::GetIO ();
53+ static bool init;
54+ if (init)
55+ {
56+ ProcessMouse ();
57+
58+ // Scale the menu if game resolution changed
59+ static ImVec2 fScreenSize = ImVec2 (-1 , -1 );
60+ ImVec2 size (screen::GetScreenWidth (), screen::GetScreenHeight ());
61+ if (fScreenSize .x != size.x && fScreenSize .y != size.y )
62+ {
63+ FontMgr::ReloadFonts ();
64+
65+ if (gRenderer == Render_DirectX9)
66+ {
67+ ImGui_ImplDX9_InvalidateDeviceObjects ();
68+ }
69+ else
70+ {
71+ ImGui_ImplDX11_InvalidateDeviceObjects ();
72+ }
73+
74+ ImGuiStyle* style = &ImGui::GetStyle ();
75+ float scaleX = size.x / 1366 .0f ;
76+ float scaleY = size.y / 768 .0f ;
77+
78+ style->FramePadding = ImVec2 (5 * scaleX, 5 * scaleY);
79+ style->ItemSpacing = ImVec2 (8 * scaleX, 4 * scaleY);
80+ style->ScrollbarSize = 12 * scaleX;
81+ style->IndentSpacing = 20 * scaleX;
82+ style->ItemInnerSpacing = ImVec2 (5 * scaleX, 5 * scaleY);
83+
84+ fScreenSize = size;
85+ }
86+
87+ ImGui_ImplWin32_NewFrame ();
88+ if (gRenderer == Render_DirectX9)
89+ {
90+ ImGui_ImplDX9_NewFrame ();
91+ }
92+ else
93+ {
94+ ImGui_ImplDX11_NewFrame ();
95+ }
96+
97+ ImGui::NewFrame ();
98+
99+ if (pCallbackFunc != nullptr )
100+ {
101+ ((void (*)())pCallbackFunc)();
102+ }
103+
104+ ImGui::EndFrame ();
105+ ImGui::Render ();
106+
107+ if (gRenderer == Render_DirectX9)
108+ {
109+ ImGui_ImplDX9_RenderDrawData (ImGui::GetDrawData ());
110+ }
111+ else
112+ {
113+ ImGui_ImplDX11_RenderDrawData (ImGui::GetDrawData ());
114+ }
115+ }
116+ else
117+ {
118+ init = true ;
119+ ImGui_ImplWin32_Init (RsGlobal.ps ->window );
120+
121+ #ifdef GTASA
122+ patch::Nop (0x00531155 , 5 ); // shift trigger fix
123+ #endif
124+
125+ if (gRenderer == Render_DirectX9)
126+ {
127+ ImGui_ImplDX9_Init (reinterpret_cast <IDirect3DDevice9*>(ptr));
128+ }
129+ else
130+ {
131+ // for dx11 device ptr is swapchain
132+ reinterpret_cast <IDXGISwapChain*>(ptr)->GetDevice (__uuidof (ID3D11Device), &ptr);
133+ ID3D11DeviceContext* context;
134+ reinterpret_cast <ID3D11Device*>(ptr)->GetImmediateContext (&context);
135+
136+ ImGui_ImplDX11_Init (reinterpret_cast <ID3D11Device*>(ptr), context);
137+ }
138+
139+ ImGui_ImplWin32_EnableDpiAwareness ();
140+
141+ // Loading fonts
142+ io.FontDefault = FontMgr::LoadFont (" text" , 1 .0f );
143+ FontMgr::LoadFont (" title" , 2 .0f );
144+ FontMgr::LoadFont (" header" , 1 .25f );
145+
146+ io.IniFilename = nullptr ;
147+ io.LogFilename = nullptr ;
148+ io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
149+ oWndProc = (WNDPROC)SetWindowLongPtr (RsGlobal.ps ->window , GWL_WNDPROC, (LRESULT)hkWndProc);
150+ }
151+ }
152+
153+ HRESULT D3dHook::hkEndScene (IDirect3DDevice9* pDevice)
154+ {
155+ ProcessFrame (pDevice);
156+ return oEndScene (pDevice);
157+ }
158+
159+ HRESULT D3dHook::hkPresent (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
160+ {
161+ ProcessFrame (pSwapChain);
162+ return oPresent (pSwapChain, SyncInterval, Flags);
163+ }
164+
165+ void D3dHook::ProcessMouse ()
166+ {
167+ // Disable player controls for controllers
168+ bool bMouseDisabled = false ;
169+ bool isController = patch::Get<BYTE>(BY_GAME (0xBA6818 , 0x86968B , 0x5F03D8 ));
170+
171+ #ifdef GTA3
172+ isController = !isController;
173+ #endif
174+
175+ if (isController && (mouseShown || bMouseDisabled))
176+ {
177+
178+ #ifdef GTASA
179+ CPlayerPed *player = FindPlayerPed ();
180+ CPad *pad = player ? player->GetPadFromPlayer () : NULL ;
181+ #else
182+ CPad *pad = CPad::GetPad (0 );
183+ #endif
184+
185+ if (pad)
186+ {
187+ if (mouseShown)
188+ {
189+ bMouseDisabled = true ;
190+ #ifdef GTA3
191+ pad->m_bDisablePlayerControls = true ;
192+ #else
193+ pad->DisablePlayerControls = true ;
194+ #endif
195+ }
196+ else
197+ {
198+ bMouseDisabled = false ;
199+ #ifdef GTA3
200+ pad->m_bDisablePlayerControls = false ;
201+ #else
202+ pad->DisablePlayerControls = false ;
203+ #endif
204+ }
205+ }
206+ }
207+
208+ static bool mouseState;
209+ if (mouseState != mouseShown)
210+ {
211+ ImGui::GetIO ().MouseDrawCursor = mouseShown;
212+
213+ if (mouseShown)
214+ {
215+
216+ patch::SetUChar (BY_GAME (0x6194A0 , 0x6020A0 , 0x580D20 ), 0xC3 ); // psSetMousePos
217+ patch::Nop (BY_GAME (0x541DD7 , 0x4AB6CA , 0x49272F ), 5 ); // don't call CPad::UpdateMouse()
218+ }
219+ else
220+ {
221+
222+ patch::SetUChar (BY_GAME (0x6194A0 , 0x6020A0 , 0x580D20 ), BY_GAME (0xE9 , 0x53 , 0x53 ));
223+ #ifdef GTASA
224+ patch::SetRaw (0x541DD7 , (char *)" \xE8\xE4\xD5\xFF\xFF " , 5 );
225+ #elif GTAVC
226+ patch::SetRaw (0x4AB6CA , (char *)" \xE8\x51\x21\x00\x00 " , 5 );
227+ #else
228+ patch::SetRaw (0x49272F , (char *)" \xE8\x6C\xF5\xFF\xFF " , 5 );
229+ #endif
230+ }
231+
232+ CPad::NewMouseControllerState.X = 0 ;
233+ CPad::NewMouseControllerState.Y = 0 ;
234+ #ifdef GTA3
235+ CPad::GetPad (0 )->ClearMouseHistory ();
236+ #else
237+ CPad::ClearMouseHistory ();
238+ #endif
239+ CPad::UpdatePads ();
240+ mouseState = mouseShown;
241+ }
242+ }
243+
244+ bool D3dHook::InjectHook (void *pCallback)
245+ {
246+ static bool hookInjected;
247+ if (hookInjected)
248+ {
249+ return false ;
250+ }
251+
252+ ImGui::CreateContext ();
253+
254+ /*
255+ Must check for d3d9 first!
256+ Seems to crash with nvidia geforce experience overlay
257+ if anything else is checked before d3d9
258+ */
259+ if (init (kiero::RenderType::D3D9) == kiero::Status::Success)
260+ {
261+ gRenderer = Render_DirectX9;
262+ kiero::bind (16 , (void **)&oReset, hkReset);
263+ kiero::bind (42 , (void **)&oEndScene, hkEndScene);
264+ pCallbackFunc = pCallback;
265+ hookInjected = true ;
266+ }
267+ else
268+ {
269+
270+ if (init (kiero::RenderType::D3D11) == kiero::Status::Success)
271+ {
272+ gRenderer = Render_DirectX11;
273+ kiero::bind (8 , (void **)&oPresent, hkPresent);
274+ pCallbackFunc = pCallback;
275+ hookInjected = true ;
276+ }
277+ }
278+
279+ return hookInjected;
280+ }
281+
282+ void D3dHook::RemoveHook ()
283+ {
284+ pCallbackFunc = nullptr ;
285+ SetWindowLongPtr (RsGlobal.ps ->window , GWL_WNDPROC, (LRESULT)oWndProc);
286+ ImGui_ImplDX9_Shutdown ();
287+ ImGui_ImplWin32_Shutdown ();
288+ ImGui::DestroyContext ();
289+ kiero::shutdown ();
290+ }
0 commit comments