From d6e22ca41e208f281403a69ecfc405f71e5bc450 Mon Sep 17 00:00:00 2001 From: Alx Date: Fri, 13 Mar 2026 21:43:01 +0000 Subject: [PATCH] d3dhook rewrite This is a rewrite of d3dhook using minhook which was being used in other places in caster already, this is api compatible with there being a caveat of it returning different strings but those shouldn't affect it where it's being used. The rewrite was done so d3d9 hooking would work on linux and then allowing for some wine specific workarounds to be removed along with enabling the frame limiter in linux. The only problem with this is that it seems to crash on alt-enter on debug builds since dearimgui seems not to like it, unsure if this is linux only or a problem that was happening before. --- 3rdparty/d3dhook/D3DHook.cc | 390 +++++++----------------------------- 3rdparty/d3dhook/hook.cc | 221 ++++++++++++++++++++ Makefile | 2 +- targets/DllHacks.cpp | 2 +- targets/DllMain.cpp | 7 +- targets/DllTrialManager.cpp | 2 - 6 files changed, 294 insertions(+), 330 deletions(-) create mode 100644 3rdparty/d3dhook/hook.cc diff --git a/3rdparty/d3dhook/D3DHook.cc b/3rdparty/d3dhook/D3DHook.cc index f9e2645c..309bd47f 100644 --- a/3rdparty/d3dhook/D3DHook.cc +++ b/3rdparty/d3dhook/D3DHook.cc @@ -1,341 +1,85 @@ #include "D3DHook.h" -#include -#include -#include - #include #include -#include -#include - #include -#include - -using namespace std; - -template -inline string toHexString ( const T& val ) -{ - stringstream ss; - ss << hex << val; - return ss.str(); -} - -// DX interface entry offsets. -#define INTF_QueryInterface 0 -#define INTF_AddRef 1 -#define INTF_Release 2 -#define INTF_DX9_Reset 16 -#define INTF_DX9_Present 17 -#define INTF_DX9_EndScene 42 - -typedef IDirect3D9 * ( __stdcall *DIRECT3DCREATE9 ) ( UINT ); -typedef ULONG ( __stdcall *PFN_DX9_ADDREF ) ( IDirect3DDevice9 *pDevice ); -typedef ULONG ( __stdcall *PFN_DX9_RELEASE ) ( IDirect3DDevice9 *pDevice ); -typedef HRESULT ( __stdcall *PFN_DX9_RESET ) ( IDirect3DDevice9 *pDevice, LPVOID ); -typedef HRESULT ( __stdcall *PFN_DX9_PRESENT ) ( IDirect3DDevice9 *pDevice, const RECT *, const RECT *, HWND, LPVOID ); -typedef HRESULT ( __stdcall *PFN_DX9_ENDSCENE ) ( IDirect3DDevice9 *pDevice ); - -CDllFile g_DX9; -IDirect3DDevice9 *g_pDevice = 0; -ULONG g_iRefCount = 1; -ULONG g_iRefCountMe = 0; -UINT_PTR m_nDX9_Present; -UINT_PTR m_nDX9_Reset; -UINT_PTR m_nDX9_EndScene; - -CHookJump m_Hook_Present; -CHookJump m_Hook_Reset; -CHookJump m_Hook_EndScene; -UINT_PTR *m_Hook_AddRef = 0; -UINT_PTR *m_Hook_Release = 0; - -PFN_DX9_ADDREF s_D3D9_AddRef = 0; -PFN_DX9_RELEASE s_D3D9_Release = 0; -PFN_DX9_RESET s_D3D9_Reset = 0; -PFN_DX9_PRESENT s_D3D9_Present = 0; -PFN_DX9_ENDSCENE s_D3D9_EndScene = 0; - -EXTERN_C ULONG __declspec ( dllexport ) __stdcall DX9_AddRef ( IDirect3DDevice9 *pDevice ) -{ - // New AddRef function - g_iRefCount = s_D3D9_AddRef ( pDevice ); - // DEBUG_TRACE(("DX9_AddRef: called (m_iRefCount = %d)." LOG_CR, g_iRefCount)); - return g_iRefCount; -} - -EXTERN_C ULONG __declspec ( dllexport ) __stdcall DX9_Release ( IDirect3DDevice9 *pDevice ) -{ - // New Release function - // a "fall-through" case - if ( ( g_iRefCount > g_iRefCountMe + 1 ) && s_D3D9_Release ) - { - g_iRefCount = s_D3D9_Release ( pDevice ); - // DEBUG_TRACE(("DX9_Release: called (m_iRefCount = %d)." LOG_CR, g_iRefCount)); - return g_iRefCount; - } - - /* - DEBUG_TRACE(("+++++++++++++++++++++++++++++++++++++" LOG_CR )); - DEBUG_MSG(("DX9_Release: called." LOG_CR)); - DEBUG_TRACE(("DX9_Release: pDevice = %08x" LOG_CR, (UINT_PTR)pDevice)); - DEBUG_TRACE(("DX9_Release: VTABLE[0] = %08x" LOG_CR, ((UINT_PTR*)(*((UINT_PTR*)pDevice)))[0])); - DEBUG_TRACE(("DX9_Release: VTABLE[1] = %08x" LOG_CR, ((UINT_PTR*)(*((UINT_PTR*)pDevice)))[1])); - DEBUG_TRACE(("DX9_Release: VTABLE[2] = %08x" LOG_CR, ((UINT_PTR*)(*((UINT_PTR*)pDevice)))[2])); - */ - - g_pDevice = pDevice; - - // unhook device methods - UnhookDirectX(); - - // reset the pointers - m_Hook_AddRef = 0; - m_Hook_Release = 0; - - // call the real Release() - // DEBUG_MSG(( "DX9_Release: about to call real Release." LOG_CR)); - - g_iRefCount = s_D3D9_Release ( pDevice ); - // DEBUG_MSG(( "DX9_Release: UNHOOK m_iRefCount = %d" LOG_CR, g_iRefCount)); - return g_iRefCount; -} - -void DX9_HooksInit ( IDirect3DDevice9 *pDevice ) -{ - UINT_PTR *pVTable = ( UINT_PTR * ) ( * ( ( UINT_PTR * ) pDevice ) ); - assert ( pVTable ); - m_Hook_AddRef = pVTable + 1; - m_Hook_Release = pVTable + 2; - - // DEBUG_TRACE(("*m_Hook_AddRef = %08x" LOG_CR, *g_DX9.m_Hook_AddRef)); - // DEBUG_TRACE(("*m_Hook_Release = %08x" LOG_CR, *g_DX9.m_Hook_Release)); - - // hook AddRef method - s_D3D9_AddRef = ( PFN_DX9_ADDREF ) ( *m_Hook_AddRef ); - *m_Hook_AddRef = ( UINT_PTR ) DX9_AddRef; - - // hook Release method - s_D3D9_Release = ( PFN_DX9_RELEASE ) ( *m_Hook_Release ); - *m_Hook_Release = ( UINT_PTR ) DX9_Release; -} - -void DX9_HooksVerify ( IDirect3DDevice9 *pDevice ) -{ - // It looks like at certain points, vtable entries get restored to its original values. - // If that happens, we need to re-assign them to our functions again. - // NOTE: we don't want blindly re-assign, because there can be other programs - // hooking on the same methods. Therefore, we only re-assign if we see that - // original addresses are restored by the system. - - UINT_PTR *pVTable = ( UINT_PTR * ) ( * ( ( UINT_PTR * ) pDevice ) ); - assert ( pVTable ); - if ( pVTable[INTF_AddRef] == ( UINT_PTR ) s_D3D9_AddRef ) - { - pVTable[INTF_AddRef] = ( UINT_PTR ) DX9_AddRef; - // DEBUG_MSG(( "DX9_HooksVerify: pDevice->AddRef() re-hooked." LOG_CR)); - } - if ( pVTable[INTF_Release] == ( UINT_PTR ) s_D3D9_Release ) - { - pVTable[INTF_Release] = ( UINT_PTR ) DX9_Release; - // DEBUG_MSG(( "DX9_HooksVerify: pDevice->Release() re-hooked." LOG_CR)); - } -} - -EXTERN_C HRESULT __declspec ( dllexport ) __stdcall DX9_EndScene ( IDirect3DDevice9 *pDevice ) -{ - // New EndScene function - // put back saved code fragment - m_Hook_EndScene.SwapOld ( ( void * ) s_D3D9_EndScene ); - - // LOG(( "DX9_EndScene: called." LOG_CR)); - g_pDevice = pDevice; - - // remember IDirect3DDevice9::Release pointer so that we can clean-up properly. - if ( m_Hook_AddRef == 0 || m_Hook_Release == 0 ) - { - DX9_HooksInit ( pDevice ); +#include +#include "Logger.hpp" + +#include "../minhook/include/MinHook.h" + +#pragma comment(lib, "libMinHook.x86.lib") + +typedef enum { + HOOK_OK, + HOOK_FAILURE, + HOOK_WINDOW, + HOOK_LOAD, + HOOK_CREATE, + HOOK_DEVICE, + HOOK_INTERFACE, + HOOK_MH, + HOOK_ENABLE +} Hook_Status; + +Hook_Status hooks_create(void); +Hook_Status hooks_enable(void); +void hooks_destroy(void); + +void log_status(Hook_Status status) { + switch (status) { + case HOOK_OK: + LOG("DirectX HOOK OK"); + break; + case HOOK_FAILURE: + LOG("DirectX HOOK FAILURE"); + break; + case HOOK_WINDOW: + LOG("DirectX Failure: HOOK WINDOW"); + break; + case HOOK_LOAD: + LOG("DirectX Failure: HOOK LOAD"); + break; + case HOOK_CREATE: + LOG("DirectX Failure: HOOK CREATE"); + break; + case HOOK_DEVICE: + LOG("DirectX Failure: HOOK DEVICE"); + break; + case HOOK_INTERFACE: + LOG("DirectX Failure: HOOK INTERFACE"); + break; + case HOOK_MH: + LOG("DirectX Failure: HOOK MinHook"); + break; + case HOOK_ENABLE: + break; } - - EndScene ( pDevice ); - - // call real EndScene() - HRESULT hRes = s_D3D9_EndScene ( pDevice ); - - DX9_HooksVerify ( pDevice ); - - // DEBUG_MSG(( "DX9_EndScene: done." LOG_CR)); - - // put JMP instruction again - m_Hook_EndScene.SwapReset ( ( void * ) s_D3D9_EndScene ); - return hRes; -} - -EXTERN_C HRESULT __declspec ( dllexport ) __stdcall DX9_Reset ( IDirect3DDevice9 *pDevice, LPVOID params ) -{ - // New Reset function - // put back saved code fragment - m_Hook_Reset.SwapOld ( ( void * ) s_D3D9_Reset ); - - // LOG(( "DX9_Reset: called." LOG_CR)); - - g_pDevice = pDevice; - - InvalidateDeviceObjects(); - - // call real Reset() - HRESULT hRes = s_D3D9_Reset ( pDevice, params ); - - DX9_HooksVerify ( pDevice ); - - // DEBUG_MSG(( "DX9_Reset: done." LOG_CR)); - - // put JMP instruction again - m_Hook_Reset.SwapReset ( ( void * ) s_D3D9_Reset ); - return hRes; } -EXTERN_C HRESULT __declspec ( dllexport ) __stdcall DX9_Present ( - IDirect3DDevice9 *pDevice, const RECT *src, const RECT *dest, HWND hwnd, LPVOID unused ) -{ - // New Present function - m_Hook_Present.SwapOld ( ( void * ) s_D3D9_Present ); - - // DEBUG_TRACE(( "--------------------------------" LOG_CR )); - // DEBUG_TRACE(( "DX9_Present: called." LOG_CR )); - - g_pDevice = pDevice; - - // remember IDirect3DDevice9::Release pointer so that we can clean-up properly. - if ( m_Hook_AddRef == 0 || m_Hook_Release == 0 ) - { - DX9_HooksInit ( pDevice ); +std::string InitDirectX(void *hwnd) { + (void)hwnd; + Hook_Status status; + if ((status = hooks_create()) != HOOK_OK) { + log_status(status); + return "failed to create hooks"; } - - PresentFrameBegin ( pDevice ); - - // call real Present() - HRESULT hRes = s_D3D9_Present ( pDevice, src, dest, hwnd, unused ); - - PresentFrameEnd ( pDevice ); - - DX9_HooksVerify ( pDevice ); - // DEBUG_TRACE(( "DX9_Present: done." LOG_CR )); - - m_Hook_Present.SwapReset ( ( void * ) s_D3D9_Present ); - return hRes; + LOG("DirectX Hook Creation Success"); + return ""; } -string InitDirectX ( void *hwnd ) -{ - // get the offset from the start of the DLL to the interface element we want. - // step 1: Load d3d9.dll - HRESULT hRes = g_DX9.LoadDll ( TEXT ( "d3d9" ) ); - if ( IS_ERROR ( hRes ) ) - { - _com_error err ( hRes ); - return "Failed to load d3d9.dll: [" + toHexString ( hRes ) + "] " + err.ErrorMessage(); - } - - // step 2: Get IDirect3D9 - DIRECT3DCREATE9 pDirect3DCreate9 = ( DIRECT3DCREATE9 ) g_DX9.GetProcAddress ( "Direct3DCreate9" ); - if ( pDirect3DCreate9 == 0 ) - { - return "Unable to find Direct3DCreate9"; - } - - IRefPtr pD3D = pDirect3DCreate9 ( D3D_SDK_VERSION ); - if ( !pD3D.IsValidRefObj() ) - { - return "Direct3DCreate9 failed"; - } - - // step 3: Get IDirect3DDevice9 - D3DDISPLAYMODE d3ddm; - hRes = pD3D->GetAdapterDisplayMode ( D3DADAPTER_DEFAULT, &d3ddm ); - if ( FAILED ( hRes ) ) - { - _com_error err ( hRes ); - return "GetAdapterDisplayMode failed: [" + toHexString ( hRes ) + "] " + err.ErrorMessage(); - } - - D3DPRESENT_PARAMETERS d3dpp; - ZeroMemory ( &d3dpp, sizeof ( d3dpp ) ); - d3dpp.Windowed = true; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.BackBufferFormat = d3ddm.Format; - - IRefPtr pD3DDevice; - hRes = pD3D->CreateDevice ( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, ( HWND ) hwnd, - D3DCREATE_SOFTWARE_VERTEXPROCESSING, - &d3dpp, IREF_GETPPTR ( pD3DDevice, IDirect3DDevice9 ) ); - if ( FAILED ( hRes ) ) - { - _com_error err ( hRes ); - return "CreateDevice failed: [" + toHexString ( hRes ) + "] " + err.ErrorMessage(); +std::string HookDirectX() { + Hook_Status status; + if ((status = hooks_enable()) != HOOK_OK) { + log_status(status); + return "failed to enable hooks"; } - - // step 4: store method addresses in out vars - UINT_PTR *pVTable = ( UINT_PTR * ) ( * ( ( UINT_PTR * ) pD3DDevice.get_RefObj() ) ); - assert ( pVTable ); - m_nDX9_Present = ( pVTable[INTF_DX9_Present] - g_DX9.get_DllInt() ); - m_nDX9_Reset = ( pVTable[INTF_DX9_Reset] - g_DX9.get_DllInt() ); - m_nDX9_EndScene = ( pVTable[INTF_DX9_EndScene] - g_DX9.get_DllInt() ); - - // LOG ( "InitDirectX: %08x, Present=0%x, Reset=0%x ", - // ( UINT_PTR ) pD3DDevice.get_RefObj(), m_nDX9_Present, m_nDX9_Reset ); + LOG("DirectX Hooking Success"); return ""; } -string HookDirectX() -{ - // This function hooks two IDirect3DDevice9 methods, using code overwriting technique. - // hook IDirect3DDevice9::Present(), using code modifications at run-time. - // ALGORITHM: we overwrite the beginning of real IDirect3DDevice9::Present - // with a JMP instruction to our routine (DX9_Present). - // When our routine gets called, first thing that it does - it restores - // the original bytes of IDirect3DDevice9::Present, then performs its pre-call tasks, - // then calls IDirect3DDevice9::Present, then does post-call tasks, then writes - // the JMP instruction back into the beginning of IDirect3DDevice9::Present, and - // returns. - - if ( !m_nDX9_Present || !m_nDX9_Reset || !m_nDX9_EndScene ) - return "No info on 'Present' and/or 'Reset'"; - - s_D3D9_Present = ( PFN_DX9_PRESENT ) ( g_DX9.get_DllInt() + m_nDX9_Present ); - s_D3D9_Reset = ( PFN_DX9_RESET ) ( g_DX9.get_DllInt() + m_nDX9_Reset ); - s_D3D9_EndScene = ( PFN_DX9_ENDSCENE ) ( g_DX9.get_DllInt() + m_nDX9_EndScene ); - - if ( !m_Hook_Present.InstallHook ( ( void * ) s_D3D9_Present, ( void * ) DX9_Present ) ) - return "m_Hook_Present failed"; - - if ( !m_Hook_Reset.InstallHook ( ( void * ) s_D3D9_Reset, ( void * ) DX9_Reset ) ) - return "m_Hook_Reset failed"; - - if ( !m_Hook_EndScene.InstallHook ( ( void * ) s_D3D9_EndScene, ( void * ) DX9_EndScene ) ) - return "m_Hook_EndScene failed"; - - return ""; +void UnhookDirectX() { + hooks_destroy(); } -void UnhookDirectX() -{ - // Restore original Reset() and Present() - if ( m_Hook_AddRef != 0 && s_D3D9_AddRef != 0 ) - { - *m_Hook_AddRef = ( UINT_PTR ) s_D3D9_AddRef; - } - if ( m_Hook_Release != 0 && s_D3D9_Release != 0 ) - { - *m_Hook_Release = ( UINT_PTR ) s_D3D9_Release; - } - - // restore IDirect3D9Device methods - m_Hook_Present.RemoveHook ( ( void * ) s_D3D9_Present ); - m_Hook_Reset.RemoveHook ( ( void * ) s_D3D9_Reset ); - m_Hook_EndScene.RemoveHook ( ( void * ) s_D3D9_EndScene ); - - InvalidateDeviceObjects(); -} diff --git a/3rdparty/d3dhook/hook.cc b/3rdparty/d3dhook/hook.cc new file mode 100644 index 00000000..89a98baa --- /dev/null +++ b/3rdparty/d3dhook/hook.cc @@ -0,0 +1,221 @@ +#include +#include +#include + +#include +#include + +#include "../minhook/include/MinHook.h" + +#define UNREACHABLE assert(false) + +typedef LPDIRECT3D9 (WINAPI *D3D9CreateFn)(UINT); +typedef HRESULT ( __stdcall *ResetFn ) ( IDirect3DDevice9 *pDevice, LPVOID ); +typedef HRESULT ( __stdcall *PresentFn ) ( IDirect3DDevice9 *pDevice, const RECT *, const RECT *, HWND, LPVOID ); +typedef HRESULT ( __stdcall *EndSceneFn ) ( IDirect3DDevice9 *pDevice); + +extern void PresentFrameBegin ( IDirect3DDevice9 *device ); +extern void PresentFrameEnd ( IDirect3DDevice9 *device ); +extern void EndScene ( IDirect3DDevice9 *device ); +extern void InvalidateDeviceObjects(); + +enum d3d9_offsets { + D3D9_RESET = 16, + D3D9_PRESENT = 17, + D3D9_ENDSCENE = 42 +}; + +typedef struct { + HWND window; + WNDCLASSEX wclass; +} Window_Context; + +typedef enum { + HOOK_OK, + HOOK_FAILURE, + HOOK_WINDOW, + HOOK_LOAD, + HOOK_CREATE, + HOOK_DEVICE, + HOOK_INTERFACE, + HOOK_MH, + HOOK_ENABLE +} Hook_Status; + +uintptr_t *VTable = NULL; + +ResetFn old_reset; +PresentFn old_present; +EndSceneFn old_endscene; + +HRESULT __stdcall hook_reset(IDirect3DDevice9 *device, LPVOID params) { + InvalidateDeviceObjects(); + HRESULT res = old_reset(device, params); + return res; +} + +HRESULT __stdcall hook_present(IDirect3DDevice9 *device, const RECT *src, const RECT *dest, HWND window, LPVOID unused) { + PresentFrameBegin(device); + HRESULT res = old_present(device, src, dest, window, unused); + PresentFrameEnd(device); + return res; +} + +HRESULT __stdcall hook_endscene(IDirect3DDevice9 *device) { + EndScene(device); + HRESULT res = old_endscene(device); + return res; +} + +Window_Context create_window(void) { + Window_Context context = (Window_Context){ + .wclass = (WNDCLASSEX){ + .cbSize = sizeof(WNDCLASSEX), + .style = CS_HREDRAW | CS_VREDRAW, + .lpfnWndProc = DefWindowProc, + .hInstance = GetModuleHandle(NULL), + .lpszClassName = "dummy" + } + }; + RegisterClassEx(&context.wclass); + context.window = CreateWindow( + context.wclass.lpszClassName, + "dummy window", + WS_OVERLAPPEDWINDOW, + 0, + 0, + 100, + 100, + NULL, + NULL, + context.wclass.hInstance, + NULL + ); + return context; +} + +Hook_Status hooks_create(void) { + Hook_Status ret = HOOK_FAILURE; + // create dummy window + Window_Context window_context = create_window(); + if (window_context.window == NULL) { + ret = HOOK_WINDOW; + goto CLEANUP_CONTEXT; + } + + // load d3d9.dll + HMODULE d3d9_module; + d3d9_module = GetModuleHandle("d3d9.dll"); + if (d3d9_module == NULL) { + ret = HOOK_LOAD; + goto CLEANUP_WINDOW; + } + + // direct3d object create + D3D9CreateFn d3d9_create; + d3d9_create = (D3D9CreateFn)GetProcAddress(d3d9_module, "Direct3DCreate9"); + if (d3d9_create == NULL) { + ret = HOOK_CREATE; + goto CLEANUP_WINDOW; + } + + IDirect3D9 *d3d9; + d3d9 = d3d9_create(D3D_SDK_VERSION); + if (d3d9 == NULL) { + ret = HOOK_CREATE; + goto CLEANUP_WINDOW; + } + + // create direct3d device + D3DPRESENT_PARAMETERS d3d9_params; + d3d9_params = (D3DPRESENT_PARAMETERS){ + .SwapEffect = D3DSWAPEFFECT_DISCARD, + .hDeviceWindow = window_context.window, + .Windowed = 1 + }; + IDirect3DDevice9 *device; + HRESULT res; + res = d3d9->CreateDevice( + D3DADAPTER_DEFAULT, + D3DDEVTYPE_NULLREF, + window_context.window, + D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT, + &d3d9_params, + &device + ); + if (res != D3D_OK || device == NULL) { + ret = HOOK_DEVICE; + goto CLEANUP_D3D; + } + + // get interface from device + VTable = (uintptr_t *)calloc(119, sizeof(uintptr_t)); + if (VTable == NULL) { + ret = HOOK_INTERFACE; + goto CLEANUP_DEVICE; + } + memcpy(VTable, *(uintptr_t **)device, sizeof(uintptr_t) * 119); + + // create the hooks + if (MH_CreateHook((void *)VTable[D3D9_RESET], (void*)&hook_reset, (void **)&old_reset) != MH_OK) { + ret = HOOK_MH; + goto CLEANUP_DEVICE; + } + if (MH_CreateHook((void *)VTable[D3D9_PRESENT], (void*)&hook_present, (void **)&old_present) != MH_OK) { + ret = HOOK_MH; + goto CLEANUP_DEVICE; + } + if (MH_CreateHook((void *)VTable[D3D9_ENDSCENE], (void*)&hook_endscene, (void **)&old_endscene) != MH_OK) { + ret = HOOK_MH; + goto CLEANUP_DEVICE; + } + + ret = HOOK_OK; + + // cleanup in reverse order +CLEANUP_DEVICE: + device->Release(); +CLEANUP_D3D: + d3d9->Release(); +CLEANUP_WINDOW: + DestroyWindow(window_context.window); +CLEANUP_CONTEXT: + UnregisterClass(window_context.wclass.lpszClassName, window_context.wclass.hInstance); + return ret; +} + +Hook_Status hooks_enable(void) { + if (MH_EnableHook((void *)VTable[D3D9_RESET]) != MH_OK) { + return HOOK_ENABLE; + } + if (MH_EnableHook((void *)VTable[D3D9_PRESENT]) != MH_OK) { + return HOOK_ENABLE; + } + if (MH_EnableHook((void *)VTable[D3D9_ENDSCENE]) != MH_OK) { + return HOOK_ENABLE; + } + return HOOK_OK; +} + +void hooks_destroy(void) { + if (MH_DisableHook((void *)VTable[D3D9_RESET]) != MH_OK) { + UNREACHABLE; + } + if (MH_DisableHook((void *)VTable[D3D9_PRESENT]) != MH_OK) { + UNREACHABLE; + } + if (MH_DisableHook((void *)VTable[D3D9_ENDSCENE]) != MH_OK) { + UNREACHABLE; + } + + if (MH_RemoveHook((void *)VTable[D3D9_RESET]) != MH_OK) { + UNREACHABLE; + } + if (MH_RemoveHook((void *)VTable[D3D9_PRESENT]) != MH_OK) { + UNREACHABLE; + } + if (MH_RemoveHook((void *)VTable[D3D9_ENDSCENE]) != MH_OK) { + UNREACHABLE; + } +} + diff --git a/Makefile b/Makefile index a90fbc39..5dff3f5d 100644 --- a/Makefile +++ b/Makefile @@ -209,7 +209,7 @@ res/rollback.bin: tools/$(GENERATOR) ifeq ($(UNAME),Darwin) wine tools/$(GENERATOR) $@ else ifeq ($(UNAME),Linux) - tools/$(GENERATOR) $@ + wine tools/$(GENERATOR) $@ else tools/$(GENERATOR) $@ endif diff --git a/targets/DllHacks.cpp b/targets/DllHacks.cpp index 8a86c34f..08764b0d 100644 --- a/targets/DllHacks.cpp +++ b/targets/DllHacks.cpp @@ -208,7 +208,7 @@ void initializePostLoad() bool loadFramestep = ( GetAsyncKeyState ( VK_F8 ) & 0x8000 ) == 0x8000; // We can't hook DirectX calls on Wine (yet?). - if ( ProcessManager::isWine() || loadFramestep ) + if ( loadFramestep ) { return; } diff --git a/targets/DllMain.cpp b/targets/DllMain.cpp index 26fa753c..d5b1e956 100644 --- a/targets/DllMain.cpp +++ b/targets/DllMain.cpp @@ -1024,7 +1024,8 @@ struct DllMain #endif // RELEASE // Enable controllers now - if ( ! ProcessManager::isWine() ) + // TODO: I don't think this check is needed here anymore + // if ( ! ProcessManager::isWine() ) ControllerManager::get().startHighFreqPolling(); // Initialize the overlay now @@ -1575,7 +1576,7 @@ struct DllMain } else { netMan.autoReplaySave = false; } - if ( ProcessManager::isWine() || options[Options::FrameLimiter] ) { + if ( options[Options::FrameLimiter] ) { } else { DllFrameRate::enable(); @@ -1865,7 +1866,7 @@ struct DllMain DllControllerManager::displayIPs = true; DllControllerManager::port = std::to_string(serverCtrlSocket->address.port); DllControllerManager::localIP = getInternalIpAddresses(); - + // Update the broadcast port and send over IPC netMan.config.broadcastPort = serverCtrlSocket->address.port; diff --git a/targets/DllTrialManager.cpp b/targets/DllTrialManager.cpp index 742fc961..188b4029 100644 --- a/targets/DllTrialManager.cpp +++ b/targets/DllTrialManager.cpp @@ -1566,8 +1566,6 @@ void DllTrialManager::render() //drawiidx(); if ( TrialManager::inputGuideEnabled ) drawInputGuide(); - if ( ProcessManager::isWine() ) - drawWineOverlay(); if ( TrialManager::inputEditorEnabled ) drawInputEditor(); }