From 1c131f503825dc6eaff384f97ea7e8692902b3f3 Mon Sep 17 00:00:00 2001 From: rebtd7 <59185507+rebtd7@users.noreply.github.com> Date: Sat, 1 Feb 2020 17:03:46 -0300 Subject: [PATCH] Changes for 1.4.2 --- Other/FF13Fix.ini | 8 + d3d9ex/AutoFix.cpp | 40 ++- d3d9ex/Context.cpp | 34 ++- d3d9ex/Context.h | 24 +- d3d9ex/IDirect3DDevice9.cpp | 10 +- d3d9ex/IDirect3DDevice9.h | 4 +- d3d9ex/Settings.h | 2 + d3d9ex/Wrapper.h | 520 ++++++++++++++++++------------------ d3d9ex/XInputManager.cpp | 11 +- d3d9ex/XInputManager.h | 6 +- 10 files changed, 346 insertions(+), 313 deletions(-) diff --git a/Other/FF13Fix.ini b/Other/FF13Fix.ini index de7b159..43d2418 100644 --- a/Other/FF13Fix.ini +++ b/Other/FF13Fix.ini @@ -23,6 +23,14 @@ FFXIIIIngameFrameRateLimit = 0 # Enables controller vibration on the first connected XInput device. FFXIIIEnableControllerVibration = true +# FFXIIIDisableIngameControllerHotSwapping +# +# By default FF13Fix disables the game's continuous controller scanning that causes stuttering (especially if you do not have any controller connected) +# If you with you can enable it again (by setting the config to 'false', so you can re-connect your controller while playing. +# Note that FFXIIIEnableControllerVibration is incompatible with the controller hotswapping, +# so it is automatically disabled if FFXIIIDisableIngameControllerHotSwapping is set to 'false' +FFXIIIDisableIngameControllerHotSwapping = true + # FullScreenRefreshRate # # If you are not using any adaptive sync technology (e.g. FreeSync/Gsync) you may want to set this to the highest diff --git a/d3d9ex/AutoFix.cpp b/d3d9ex/AutoFix.cpp index ac6df7c..91b2e0a 100644 --- a/d3d9ex/AutoFix.cpp +++ b/d3d9ex/AutoFix.cpp @@ -106,14 +106,14 @@ HRESULT APIENTRY MainContext::ApplyVertexBufferFix(IDirect3DDevice9* pIDirect3DD void MainContext::FF13_InitializeGameAddresses() { // FF13 always seem to use the same addresses (even if you force ASLR on the OS), but we are calculating the addresses just in case... - byte* baseAddr = (byte*)GetModuleHandle(NULL); // Should be 400000 + uint8_t* baseAddr = (uint8_t*)GetModuleHandle(NULL); // Should be 400000 PrintLog("Base Addr = %x", baseAddr); ff13_frame_pacer_ptr = (float**)(baseAddr + 0x243E34C); ff13_set_framerate_ingame_instruction_address = baseAddr + 0xA8D65F; ff13_continuous_scan_instruction_address = baseAddr + 0x420868; ff13_enemy_scan_box_code_address = baseAddr + 0x54C920; - ff13_base_controller_input_address_ptr = (byte**)(baseAddr + 0x02411220); + ff13_base_controller_input_address_ptr = (uint8_t**)(baseAddr + 0x02411220); ff13_vibration_low_set_zero_address = baseAddr + 0x4210DF; ff13_vibration_high_set_zero_address = baseAddr + 0x4210F3; ff13_internal_res_w = (uint32_t*)(baseAddr + 0x22E5168); @@ -137,6 +137,10 @@ void MainContext::FF13_EnableControllerVibration() PrintLog("Vibration should not be enabled (config file)"); return; } + if (!config.GetFFXIIIDisableIngameControllerHotSwapping()) { + PrintLog("Vibration disabled because FFXIIIDisableIngameControllerHotSwapping is set to false (config file)"); + return; + } PrintLog("Enabling controller vibration..."); ChangeMemoryProtectionToReadWriteExecute(ff13_vibration_low_set_zero_address, 5); @@ -156,12 +160,16 @@ void MainContext::FF13_EnableControllerVibration() } void MainContext::FF13_RemoveContinuousControllerScan() { + if (!config.GetFFXIIIDisableIngameControllerHotSwapping()) { + PrintLog("Continuous controller scanning not disabled (config)"); + return; + } // Disable continuous controller scanning. PrintLog("Removing game slow and synchronous controller continuous controller scanning..."); context.ChangeMemoryProtectionToReadWriteExecute(ff13_continuous_scan_instruction_address, 1); // change a jne to jmp - *(byte*)ff13_continuous_scan_instruction_address = 0xEB; + *(uint8_t*)ff13_continuous_scan_instruction_address = 0xEB; } void MainContext::FF13_FixMissingEnemyScan() { @@ -179,21 +187,21 @@ void MainContext::FF13_FixMissingEnemyScan() { context.ChangeMemoryProtectionToReadWriteExecute(ff13_enemy_scan_box_code_address, 18); //push rectHeight - *(byte*)(ff13_enemy_scan_box_code_address + 0) = 0x68; + *(uint8_t*)(ff13_enemy_scan_box_code_address + 0) = 0x68; *(uint32_t*)(ff13_enemy_scan_box_code_address + 1) = rectHeight; // push rectWidth - *(byte*)(ff13_enemy_scan_box_code_address + 5) = 0x68; + *(uint8_t*)(ff13_enemy_scan_box_code_address + 5) = 0x68; *(uint32_t*)(ff13_enemy_scan_box_code_address + 6) = rectWidth; // push rectPosY - *(byte*)(ff13_enemy_scan_box_code_address + 10) = 0x68; + *(uint8_t*)(ff13_enemy_scan_box_code_address + 10) = 0x68; *(uint32_t*)(ff13_enemy_scan_box_code_address + 11) = rectPosY; // NOP NOP NOP - *(byte*)(ff13_enemy_scan_box_code_address + 15) = 0x90; - *(byte*)(ff13_enemy_scan_box_code_address + 16) = 0x90; - *(byte*)(ff13_enemy_scan_box_code_address + 17) = 0x90; + *(uint8_t*)(ff13_enemy_scan_box_code_address + 15) = 0x90; + *(uint8_t*)(ff13_enemy_scan_box_code_address + 16) = 0x90; + *(uint8_t*)(ff13_enemy_scan_box_code_address + 17) = 0x90; } void MainContext::FF13_NOPIngameFrameRateLimitSetter() { @@ -284,24 +292,28 @@ void MainContext::FF13_2_EnableControllerVibration() void MainContext::FF13_2_InitializeGameAddresses() { // FF13-2 uses address space layout randomization (ASLR) so we can't rely on fixed addresses without considering the base address - byte* baseAddr = (byte*)GetModuleHandle(NULL); + uint8_t* baseAddr = (uint8_t*)GetModuleHandle(NULL); PrintLog("Base Addr = %x", baseAddr); ff13_2_continuous_scan_instruction_address = baseAddr + 0x2A6E7F; ff13_2_set_frame_rate_address = baseAddr + 0x802616; ff13_2_frame_pacer_ptr_address = (float**)(baseAddr + 0x4D67208); - ff13_2_base_controller_input_address_ptr = (byte**)(baseAddr + 0x212A164); + ff13_2_base_controller_input_address_ptr = (uint8_t**)(baseAddr + 0x212A164); ff13_2_vibration_low_set_zero_address = baseAddr + 0x2A7221; ff13_2_vibration_high_set_zero_address = baseAddr + 0x2A7226; } void MainContext::FF13_2_RemoveContinuousControllerScan() { + if (!config.GetFFXIIIDisableIngameControllerHotSwapping()) { + PrintLog("Continuous controller scanning not disabled (config)"); + return; + } // Disable continuous controller scanning. PrintLog("Removing game slow and synchronous controller continuous controller scanning..."); context.ChangeMemoryProtectionToReadWriteExecute(ff13_2_continuous_scan_instruction_address, 1); // change a jne to jmp - *(byte*)ff13_2_continuous_scan_instruction_address = 0xEB; + *(uint8_t*)ff13_2_continuous_scan_instruction_address = 0xEB; } void MainContext::FF13_2_AddHookIngameFrameRateLimitSetter() { @@ -322,7 +334,7 @@ void MainContext::FF13_2_AddHookIngameFrameRateLimitSetter() { void MainContext::FF13_2_CreateSetFrameRateCodeBlock() { const int blockSize = 31; - FF13_2_SET_FRAME_RATE_INJECTED_CODE = new byte[blockSize]; + FF13_2_SET_FRAME_RATE_INJECTED_CODE = new uint8_t[blockSize]; ChangeMemoryProtectionToReadWriteExecute(FF13_2_SET_FRAME_RATE_INJECTED_CODE, blockSize); @@ -377,7 +389,7 @@ void MainContext::ChangeMemoryProtectionToReadWriteExecute(void* address, const } void MainContext::PrintVersionInfo() { - PrintLog("FF13Fix 1.4.1 https://github.com/rebtd7/FF13Fix"); + PrintLog("FF13Fix 1.4.2 https://github.com/rebtd7/FF13Fix"); } bool MainContext::AreAlmostTheSame(float a, float b) { diff --git a/d3d9ex/Context.cpp b/d3d9ex/Context.cpp index 576a8e6..f5c0177 100644 --- a/d3d9ex/Context.cpp +++ b/d3d9ex/Context.cpp @@ -46,22 +46,34 @@ MainContext::MainContext() : oldWndProc(nullptr) if (config.GetAutoFix()) EnableAutoFix(); - MH_Initialize(); + PrintLog("Enabling hooks:"); + const MH_STATUS initializeHooks = MH_Initialize(); + PrintLog("initializeHooks = %d", initializeHooks); - MH_CreateHook(D3D9DLL::Get().Direct3DCreate9, HookDirect3DCreate9, reinterpret_cast(&TrueDirect3DCreate9)); - MH_EnableHook(D3D9DLL::Get().Direct3DCreate9); + const MH_STATUS createHookDirect3DCreate9 = MH_CreateHook(D3D9DLL::Get().Direct3DCreate9, HookDirect3DCreate9, reinterpret_cast(&TrueDirect3DCreate9)); + PrintLog("createHookDirect3DCreate9 = %d", createHookDirect3DCreate9); + const MH_STATUS enableHookDirect3DCreate9 = MH_EnableHook(D3D9DLL::Get().Direct3DCreate9); + PrintLog("enableHookDirect3DCreate9 = %d", enableHookDirect3DCreate9); - MH_CreateHook(CreateWindowExA, HookCreateWindowExA, reinterpret_cast(&TrueCreateWindowExA)); - MH_EnableHook(CreateWindowExA); + const MH_STATUS createHookCreateWindowExA = MH_CreateHook(CreateWindowExA, HookCreateWindowExA, reinterpret_cast(&TrueCreateWindowExA)); + PrintLog("createHookCreateWindowExA = %d", createHookCreateWindowExA); + const MH_STATUS enableHookCreateWindowExA = MH_EnableHook(CreateWindowExA); + PrintLog("enableHookCreateWindowExA = %d", enableHookCreateWindowExA); - MH_CreateHook(CreateWindowExW, HookCreateWindowExW, reinterpret_cast(&TrueCreateWindowExW)); - MH_EnableHook(CreateWindowExW); + const MH_STATUS createHookCreateWindowExW = MH_CreateHook(CreateWindowExW, HookCreateWindowExW, reinterpret_cast(&TrueCreateWindowExW)); + PrintLog("createHookCreateWindowExW = %d", createHookCreateWindowExW); + const MH_STATUS enableHookCreateWindowExW = MH_EnableHook(CreateWindowExW); + PrintLog("enableHookCreateWindowExW = %d", enableHookCreateWindowExW); - MH_CreateHook(SetWindowLongA, HookSetWindowLongA, reinterpret_cast(&TrueSetWindowLongA)); - MH_EnableHook(SetWindowLongA); + const MH_STATUS createHookSetWindowLongA = MH_CreateHook(SetWindowLongA, HookSetWindowLongA, reinterpret_cast(&TrueSetWindowLongA)); + PrintLog("createHookSetWindowLongA = %d", createHookSetWindowLongA); + const MH_STATUS enableHookSetWindowLongA = MH_EnableHook(SetWindowLongA); + PrintLog("enableHookSetWindowLongA = %d", enableHookSetWindowLongA); - MH_CreateHook(SetWindowLongW, HookSetWindowLongW, reinterpret_cast(&TrueSetWindowLongW)); - MH_EnableHook(SetWindowLongW); + const MH_STATUS createHookSetWindowLongW = MH_CreateHook(SetWindowLongW, HookSetWindowLongW, reinterpret_cast(&TrueSetWindowLongW)); + PrintLog("createHookSetWindowLongW = %d", createHookSetWindowLongW); + const MH_STATUS enableHookSetWindowLongW = MH_EnableHook(SetWindowLongW); + PrintLog("enableHookSetWindowLongW = %d", enableHookSetWindowLongW); } diff --git a/d3d9ex/Context.h b/d3d9ex/Context.h index 535af79..1f14f62 100644 --- a/d3d9ex/Context.h +++ b/d3d9ex/Context.h @@ -79,23 +79,23 @@ private: const float MAX_FRAME_RATE_LIMIT = 250000.0F; float** ff13_frame_pacer_ptr = NULL; - byte* ff13_set_framerate_ingame_instruction_address = NULL; - byte* ff13_continuous_scan_instruction_address = NULL; - byte* ff13_enemy_scan_box_code_address = NULL; - byte** ff13_base_controller_input_address_ptr = NULL; - byte* ff13_vibration_high_set_zero_address = NULL; - byte* ff13_vibration_low_set_zero_address = NULL; + uint8_t* ff13_set_framerate_ingame_instruction_address = NULL; + uint8_t* ff13_continuous_scan_instruction_address = NULL; + uint8_t* ff13_enemy_scan_box_code_address = NULL; + uint8_t** ff13_base_controller_input_address_ptr = NULL; + uint8_t* ff13_vibration_high_set_zero_address = NULL; + uint8_t* ff13_vibration_low_set_zero_address = NULL; uint32_t* ff13_internal_res_w; uint32_t* ff13_internal_res_h; - byte* FF13_2_SET_FRAME_RATE_INJECTED_CODE = NULL; - byte* ff13_2_continuous_scan_instruction_address; - byte* ff13_2_set_frame_rate_address; + uint8_t* FF13_2_SET_FRAME_RATE_INJECTED_CODE = NULL; + uint8_t* ff13_2_continuous_scan_instruction_address; + uint8_t* ff13_2_set_frame_rate_address; float** ff13_2_frame_pacer_ptr_address; float ff13_2_targetFrameRate; - byte** ff13_2_base_controller_input_address_ptr = NULL; - byte* ff13_2_vibration_high_set_zero_address = NULL; - byte* ff13_2_vibration_low_set_zero_address = NULL; + uint8_t** ff13_2_base_controller_input_address_ptr = NULL; + uint8_t* ff13_2_vibration_high_set_zero_address = NULL; + uint8_t* ff13_2_vibration_low_set_zero_address = NULL; const float FF13_2_30_FPS = 30.0F; const float FF13_2_MAX_FRAME_CAP = 1000.0F; diff --git a/d3d9ex/IDirect3DDevice9.cpp b/d3d9ex/IDirect3DDevice9.cpp index e13c993..91408b5 100644 --- a/d3d9ex/IDirect3DDevice9.cpp +++ b/d3d9ex/IDirect3DDevice9.cpp @@ -101,7 +101,7 @@ HRESULT APIENTRY hkIDirect3DDevice9::GetSwapChain(UINT iSwapChain, IDirect3DSwap IDirect3DDevice9_PrintLog(__FUNCTION__); // Steam Overlay Fix - // Add some space, 16bytes should be enough + // Add some space, 16uint8_ts should be enough __nop(); __nop(); __nop(); @@ -549,14 +549,14 @@ HRESULT APIENTRY hkIDirect3DDevice9::GetVertexShaderConstantB(UINT StartRegister return m_pWrapped->GetVertexShaderConstantB(StartRegister, pConstantData, BoolCount); } -HRESULT APIENTRY hkIDirect3DDevice9::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) { +HRESULT APIENTRY hkIDirect3DDevice9::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInuint8_ts, UINT Stride) { IDirect3DDevice9_PrintLog(__FUNCTION__); - return m_pWrapped->SetStreamSource(StreamNumber, pStreamData, OffsetInBytes, Stride); + return m_pWrapped->SetStreamSource(StreamNumber, pStreamData, OffsetInuint8_ts, Stride); } -HRESULT APIENTRY hkIDirect3DDevice9::GetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride) { +HRESULT APIENTRY hkIDirect3DDevice9::GetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInuint8_ts, UINT* pStride) { IDirect3DDevice9_PrintLog(__FUNCTION__); - return m_pWrapped->GetStreamSource(StreamNumber, ppStreamData, pOffsetInBytes, pStride); + return m_pWrapped->GetStreamSource(StreamNumber, ppStreamData, pOffsetInuint8_ts, pStride); } HRESULT APIENTRY hkIDirect3DDevice9::SetStreamSourceFreq(UINT StreamNumber, UINT Setting) { diff --git a/d3d9ex/IDirect3DDevice9.h b/d3d9ex/IDirect3DDevice9.h index 86cc02a..bf8e7fe 100644 --- a/d3d9ex/IDirect3DDevice9.h +++ b/d3d9ex/IDirect3DDevice9.h @@ -107,8 +107,8 @@ public: STDMETHOD(GetVertexShaderConstantI)(UINT StartRegister, int* pConstantData, UINT Vector4iCount); STDMETHOD(SetVertexShaderConstantB)(UINT StartRegister, CONST BOOL* pConstantData, UINT BoolCount); STDMETHOD(GetVertexShaderConstantB)(UINT StartRegister, BOOL* pConstantData, UINT BoolCount); - STDMETHOD(SetStreamSource)(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride); - STDMETHOD(GetStreamSource)(UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInBytes, UINT* pStride); + STDMETHOD(SetStreamSource)(UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInuint8_ts, UINT Stride); + STDMETHOD(GetStreamSource)(UINT StreamNumber, IDirect3DVertexBuffer9** ppStreamData, UINT* pOffsetInuint8_ts, UINT* pStride); STDMETHOD(SetStreamSourceFreq)(UINT StreamNumber, UINT Setting); STDMETHOD(GetStreamSourceFreq)(UINT StreamNumber, UINT* pSetting); STDMETHOD(SetIndices)(IDirect3DIndexBuffer9* pIndexData); diff --git a/d3d9ex/Settings.h b/d3d9ex/Settings.h index 545f81d..3fa03b7 100644 --- a/d3d9ex/Settings.h +++ b/d3d9ex/Settings.h @@ -11,8 +11,10 @@ SETTING(bool, BoolValue, ForceHideCursor, Options, false); SETTING(u32, LongValue, BehaviorFlags, Options, 0); SETTING(double, DoubleValue, FFXIIIIngameFrameRateLimit, Options, 0.0); +SETTING(bool, BoolValue, FFXIIIDisableIngameControllerHotSwapping, Options, true); SETTING(bool, BoolValue, FFXIIIEnableControllerVibration, Options, true); + SETTING(bool, BoolValue, Adapter, Adapter, false); SETTING(u32, LongValue, VendorId, Adapter, 0); SETTING(u32, LongValue, DeviceId, Adapter, 0); diff --git a/d3d9ex/Wrapper.h b/d3d9ex/Wrapper.h index cba6379..56c1f6d 100644 --- a/d3d9ex/Wrapper.h +++ b/d3d9ex/Wrapper.h @@ -1,260 +1,260 @@ -#pragma once - -#include "comdef.h" - -#include "d3d9.h" -#include "dinput.h" -#include "xinput.h" - -template -class WrapperBase -{ -public: - WrapperBase(const WrapperBase&) = delete; - const WrapperBase& operator=(WrapperBase& other) = delete; - - WrapperBase(): m_module(nullptr) {} - - ~WrapperBase() - { - if (m_module) - { - FreeLibrary(m_module); - PrintLog("Unloaded %s", module_path.c_str()); - } - } - - static T& Get() - { - static T instance; - return instance; - } - -protected: - void WrapperLoad(const char* module_name) - { - module_path = CreateSystemModulePath(module_name); - m_module = LoadLibraryA(module_path.c_str()); - - if (!m_module) - { - HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); - _com_error err(hr); - - std::string msg = StringFromFormat("Cannot load %s\nHRESULT 0x%08X: \"%s\"", module_path.c_str(), err.Error(), err.ErrorMessage()); - - PrintLog(msg.c_str()); - MessageBoxA(NULL, msg.c_str(), "Error", MB_ICONERROR); - ExitProcess(hr); - } - - PrintLog("Loaded %s", module_path.c_str()); - } - - template - void StoreAddress(T* dest, const char* name) - { - *dest = reinterpret_cast(::GetProcAddress(m_module, name)); - } - -private: - HMODULE m_module; - std::string module_path; -}; - -class D3D9DLL : public WrapperBase -{ -public: - IDirect3D9* (WINAPI* Direct3DCreate9)(UINT SDKVersion); - HRESULT(WINAPI* Direct3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex **ppD3D); - - int (WINAPI* D3DPERF_BeginEvent)(D3DCOLOR col, LPCWSTR wszName); - int (WINAPI* D3DPERF_EndEvent)(void); - - DWORD(WINAPI* D3DPERF_GetStatus)(); - BOOL(WINAPI* D3DPERF_QueryRepeatFrame)(); - void (WINAPI* D3DPERF_SetMarker)(D3DCOLOR col, LPCWSTR wszName); - void (WINAPI* D3DPERF_SetOptions)(DWORD dwOptions); - void (WINAPI* D3DPERF_SetRegion)(D3DCOLOR col, LPCWSTR wszName); - - D3D9DLL() - { - WrapperLoad("d3d9.dll"); - - StoreAddress(&Direct3DCreate9, "Direct3DCreate9"); - StoreAddress(&Direct3DCreate9Ex, "Direct3DCreate9Ex"); - - StoreAddress(&D3DPERF_BeginEvent, "D3DPERF_BeginEvent"); - StoreAddress(&D3DPERF_EndEvent, "D3DPERF_EndEvent"); - - StoreAddress(&D3DPERF_GetStatus, "D3DPERF_GetStatus"); - StoreAddress(&D3DPERF_QueryRepeatFrame, "D3DPERF_QueryRepeatFrame"); - StoreAddress(&D3DPERF_SetMarker, "D3DPERF_SetMarker"); - StoreAddress(&D3DPERF_SetOptions, "D3DPERF_SetOptions"); - StoreAddress(&D3DPERF_SetRegion, "D3DPERF_SetRegion"); - } -}; - -extern "C" -{ - - IDirect3D9 * WINAPI _Direct3DCreate9(UINT SDKVersion) - { - return D3D9DLL::Get().Direct3DCreate9(SDKVersion); - } - - HRESULT WINAPI _Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex **ppD3D) - { - return D3D9DLL::Get().Direct3DCreate9Ex(SDKVersion, ppD3D); - } - - int WINAPI _D3DPERF_BeginEvent(D3DCOLOR col, LPCWSTR wszName) - { - return D3D9DLL::Get().D3DPERF_BeginEvent(col, wszName); - } - - int WINAPI _D3DPERF_EndEvent() - { - return D3D9DLL::Get().D3DPERF_EndEvent(); - } - - DWORD WINAPI _D3DPERF_GetStatus() - { - return D3D9DLL::Get().D3DPERF_GetStatus(); - } - - BOOL WINAPI _D3DPERF_QueryRepeatFrame() - { - return D3D9DLL::Get().D3DPERF_QueryRepeatFrame(); - } - - void WINAPI _D3DPERF_SetMarker(D3DCOLOR col, LPCWSTR wszName) - { - return D3D9DLL::Get().D3DPERF_SetMarker(col, wszName); - } - - void WINAPI _D3DPERF_SetOptions(DWORD dwOptions) - { - return D3D9DLL::Get().D3DPERF_SetOptions(dwOptions); - } - - void WINAPI _D3DPERF_SetRegion(D3DCOLOR col, LPCWSTR wszName) - { - return D3D9DLL::Get().D3DPERF_SetRegion(col, wszName); - } -} - -class DINPUT8DLL : public WrapperBase -{ -public: - - HRESULT (WINAPI* DirectInput8Create)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter); - - DINPUT8DLL() - { - WrapperLoad("dinput8.dll"); - - StoreAddress(&DirectInput8Create, "DirectInput8Create"); - } -}; - -extern "C" -{ - HRESULT WINAPI _DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter) - { - return DINPUT8DLL::Get().DirectInput8Create(hinst, dwVersion, riidltf, ppvOut, punkOuter); - } -} - -class XINPUTDLL : public WrapperBase -{ -public: - - // XInput 1.3 and older functions - DWORD(WINAPI* XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState); - DWORD(WINAPI* XInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration); - DWORD(WINAPI* XInputGetCapabilities)(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities); - VOID(WINAPI* XInputEnable)(BOOL enable); - DWORD(WINAPI* XInputGetDSoundAudioDeviceGuids)(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid); - DWORD(WINAPI* XInputGetBatteryInformation)(DWORD dwUserIndex, BYTE devType, XINPUT_BATTERY_INFORMATION* pBatteryInformation); - DWORD(WINAPI* XInputGetKeystroke)(DWORD dwUserIndex, DWORD dwReserved, PXINPUT_KEYSTROKE pKeystroke); - - // XInput 1.3 undocumented functions - DWORD(WINAPI* XInputGetStateEx)(DWORD dwUserIndex, XINPUT_STATE *pState); // 100 - DWORD(WINAPI* XInputWaitForGuideButton)(DWORD dwUserIndex, DWORD dwFlag, LPVOID pVoid); // 101 - DWORD(WINAPI* XInputCancelGuideButtonWait)(DWORD dwUserIndex); // 102 - DWORD(WINAPI* XInputPowerOffController)(DWORD dwUserIndex); // 103 - - // XInput 1.4 functions - DWORD(WINAPI* XInputGetAudioDeviceIds)(DWORD dwUserIndex, LPWSTR pRenderDeviceId, UINT* pRenderCount, LPWSTR pCaptureDeviceId, UINT* pCaptureCount); - - // XInput 1.4 undocumented functionss - DWORD(WINAPI* XInputGetBaseBusInformation)(DWORD dwUserIndex, struct XINPUT_BUSINFO* pBusinfo); // 104 - DWORD(WINAPI* XInputGetCapabilitiesEx)(DWORD unk1, DWORD dwUserIndex, DWORD dwFlags, struct XINPUT_CAPABILITIESEX* pCapabilitiesEx); // 108 - - XINPUTDLL() - { - WrapperLoad("xinput1_3.dll"); - - // XInput 1.3 and older functions - StoreAddress(&XInputGetState, "XInputGetState"); - StoreAddress(&XInputSetState, "XInputSetState"); - StoreAddress(&XInputGetCapabilities, "XInputGetCapabilities"); - StoreAddress(&XInputEnable, "XInputEnable"); - StoreAddress(&XInputGetDSoundAudioDeviceGuids, "XInputGetDSoundAudioDeviceGuids"); - StoreAddress(&XInputGetBatteryInformation, "XInputGetBatteryInformation"); - StoreAddress(&XInputGetKeystroke, "XInputGetKeystroke"); - - // XInput 1.3 undocumented functions - StoreAddress(&XInputGetStateEx, (const char*)100); - StoreAddress(&XInputWaitForGuideButton, (const char*)101); - StoreAddress(&XInputCancelGuideButtonWait, (const char*)102); - StoreAddress(&XInputPowerOffController, (const char*)103); - - // XInput 1.4 functions - StoreAddress(&XInputGetAudioDeviceIds, "XInputGetAudioDeviceIds"); - - // XInput 1.4 undocumented functionss - StoreAddress(&XInputGetBaseBusInformation, (const char*)104); - StoreAddress(&XInputGetCapabilitiesEx, (const char*)108); - } -}; - -extern "C" -{ - // XInput 1.3 and older functions - DWORD WINAPI _XInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState) - { - return XINPUTDLL::Get().XInputGetState(dwUserIndex, pState); - } - - DWORD WINAPI _XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration) - { - return XINPUTDLL::Get().XInputSetState(dwUserIndex, pVibration); - } - - DWORD WINAPI _XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities) - { - return XINPUTDLL::Get().XInputGetCapabilities(dwUserIndex, dwFlags, pCapabilities); - } - - VOID WINAPI _XInputEnable(BOOL enable) - { - return XINPUTDLL::Get().XInputEnable(enable); - } - - DWORD WINAPI _XInputGetDSoundAudioDeviceGuids(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid) - { - return XINPUTDLL::Get().XInputGetDSoundAudioDeviceGuids(dwUserIndex, pDSoundRenderGuid, pDSoundCaptureGuid); - } - - DWORD WINAPI _XInputGetBatteryInformation(DWORD dwUserIndex, BYTE devType, XINPUT_BATTERY_INFORMATION* pBatteryInformation) - { - return XINPUTDLL::Get().XInputGetBatteryInformation(dwUserIndex, devType, pBatteryInformation); - } - - DWORD WINAPI _XInputGetKeystroke(DWORD dwUserIndex, DWORD dwReserved, PXINPUT_KEYSTROKE pKeystroke) - { - return XINPUTDLL::Get().XInputGetKeystroke(dwUserIndex, dwReserved, pKeystroke); - } -} +#pragma once + +#include "comdef.h" + +#include "d3d9.h" +#include "dinput.h" +#include "xinput.h" + +template +class WrapperBase +{ +public: + WrapperBase(const WrapperBase&) = delete; + const WrapperBase& operator=(WrapperBase& other) = delete; + + WrapperBase(): m_module(nullptr) {} + + ~WrapperBase() + { + if (m_module) + { + FreeLibrary(m_module); + PrintLog("Unloaded %s", module_path.c_str()); + } + } + + static T& Get() + { + static T instance; + return instance; + } + +protected: + void WrapperLoad(const char* module_name) + { + module_path = CreateSystemModulePath(module_name); + m_module = LoadLibraryA(module_path.c_str()); + + if (!m_module) + { + HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); + _com_error err(hr); + + std::string msg = StringFromFormat("Cannot load %s\nHRESULT 0x%08X: \"%s\"", module_path.c_str(), err.Error(), err.ErrorMessage()); + + PrintLog(msg.c_str()); + MessageBoxA(NULL, msg.c_str(), "Error", MB_ICONERROR); + ExitProcess(hr); + } + + PrintLog("Loaded %s", module_path.c_str()); + } + + template + void StoreAddress(T* dest, const char* name) + { + *dest = reinterpret_cast(::GetProcAddress(m_module, name)); + } + +private: + HMODULE m_module; + std::string module_path; +}; + +class D3D9DLL : public WrapperBase +{ +public: + IDirect3D9* (WINAPI* Direct3DCreate9)(UINT SDKVersion); + HRESULT(WINAPI* Direct3DCreate9Ex)(UINT SDKVersion, IDirect3D9Ex **ppD3D); + + int (WINAPI* D3DPERF_BeginEvent)(D3DCOLOR col, LPCWSTR wszName); + int (WINAPI* D3DPERF_EndEvent)(void); + + DWORD(WINAPI* D3DPERF_GetStatus)(); + BOOL(WINAPI* D3DPERF_QueryRepeatFrame)(); + void (WINAPI* D3DPERF_SetMarker)(D3DCOLOR col, LPCWSTR wszName); + void (WINAPI* D3DPERF_SetOptions)(DWORD dwOptions); + void (WINAPI* D3DPERF_SetRegion)(D3DCOLOR col, LPCWSTR wszName); + + D3D9DLL() + { + WrapperLoad("d3d9.dll"); + + StoreAddress(&Direct3DCreate9, "Direct3DCreate9"); + StoreAddress(&Direct3DCreate9Ex, "Direct3DCreate9Ex"); + + StoreAddress(&D3DPERF_BeginEvent, "D3DPERF_BeginEvent"); + StoreAddress(&D3DPERF_EndEvent, "D3DPERF_EndEvent"); + + StoreAddress(&D3DPERF_GetStatus, "D3DPERF_GetStatus"); + StoreAddress(&D3DPERF_QueryRepeatFrame, "D3DPERF_QueryRepeatFrame"); + StoreAddress(&D3DPERF_SetMarker, "D3DPERF_SetMarker"); + StoreAddress(&D3DPERF_SetOptions, "D3DPERF_SetOptions"); + StoreAddress(&D3DPERF_SetRegion, "D3DPERF_SetRegion"); + } +}; + +extern "C" +{ + + IDirect3D9 * WINAPI _Direct3DCreate9(UINT SDKVersion) + { + return D3D9DLL::Get().Direct3DCreate9(SDKVersion); + } + + HRESULT WINAPI _Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex **ppD3D) + { + return D3D9DLL::Get().Direct3DCreate9Ex(SDKVersion, ppD3D); + } + + int WINAPI _D3DPERF_BeginEvent(D3DCOLOR col, LPCWSTR wszName) + { + return D3D9DLL::Get().D3DPERF_BeginEvent(col, wszName); + } + + int WINAPI _D3DPERF_EndEvent() + { + return D3D9DLL::Get().D3DPERF_EndEvent(); + } + + DWORD WINAPI _D3DPERF_GetStatus() + { + return D3D9DLL::Get().D3DPERF_GetStatus(); + } + + BOOL WINAPI _D3DPERF_QueryRepeatFrame() + { + return D3D9DLL::Get().D3DPERF_QueryRepeatFrame(); + } + + void WINAPI _D3DPERF_SetMarker(D3DCOLOR col, LPCWSTR wszName) + { + return D3D9DLL::Get().D3DPERF_SetMarker(col, wszName); + } + + void WINAPI _D3DPERF_SetOptions(DWORD dwOptions) + { + return D3D9DLL::Get().D3DPERF_SetOptions(dwOptions); + } + + void WINAPI _D3DPERF_SetRegion(D3DCOLOR col, LPCWSTR wszName) + { + return D3D9DLL::Get().D3DPERF_SetRegion(col, wszName); + } +} + +class DINPUT8DLL : public WrapperBase +{ +public: + + HRESULT (WINAPI* DirectInput8Create)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter); + + DINPUT8DLL() + { + WrapperLoad("dinput8.dll"); + + StoreAddress(&DirectInput8Create, "DirectInput8Create"); + } +}; + +extern "C" +{ + HRESULT WINAPI _DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter) + { + return DINPUT8DLL::Get().DirectInput8Create(hinst, dwVersion, riidltf, ppvOut, punkOuter); + } +} + +class XINPUTDLL : public WrapperBase +{ +public: + + // XInput 1.3 and older functions + DWORD(WINAPI* XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState); + DWORD(WINAPI* XInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration); + DWORD(WINAPI* XInputGetCapabilities)(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities); + VOID(WINAPI* XInputEnable)(BOOL enable); + DWORD(WINAPI* XInputGetDSoundAudioDeviceGuids)(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid); + DWORD(WINAPI* XInputGetBatteryInformation)(DWORD dwUserIndex, uint8_t devType, XINPUT_BATTERY_INFORMATION* pBatteryInformation); + DWORD(WINAPI* XInputGetKeystroke)(DWORD dwUserIndex, DWORD dwReserved, PXINPUT_KEYSTROKE pKeystroke); + + // XInput 1.3 undocumented functions + DWORD(WINAPI* XInputGetStateEx)(DWORD dwUserIndex, XINPUT_STATE *pState); // 100 + DWORD(WINAPI* XInputWaitForGuideButton)(DWORD dwUserIndex, DWORD dwFlag, LPVOID pVoid); // 101 + DWORD(WINAPI* XInputCancelGuideButtonWait)(DWORD dwUserIndex); // 102 + DWORD(WINAPI* XInputPowerOffController)(DWORD dwUserIndex); // 103 + + // XInput 1.4 functions + DWORD(WINAPI* XInputGetAudioDeviceIds)(DWORD dwUserIndex, LPWSTR pRenderDeviceId, UINT* pRenderCount, LPWSTR pCaptureDeviceId, UINT* pCaptureCount); + + // XInput 1.4 undocumented functionss + DWORD(WINAPI* XInputGetBaseBusInformation)(DWORD dwUserIndex, struct XINPUT_BUSINFO* pBusinfo); // 104 + DWORD(WINAPI* XInputGetCapabilitiesEx)(DWORD unk1, DWORD dwUserIndex, DWORD dwFlags, struct XINPUT_CAPABILITIESEX* pCapabilitiesEx); // 108 + + XINPUTDLL() + { + WrapperLoad("xinput1_3.dll"); + + // XInput 1.3 and older functions + StoreAddress(&XInputGetState, "XInputGetState"); + StoreAddress(&XInputSetState, "XInputSetState"); + StoreAddress(&XInputGetCapabilities, "XInputGetCapabilities"); + StoreAddress(&XInputEnable, "XInputEnable"); + StoreAddress(&XInputGetDSoundAudioDeviceGuids, "XInputGetDSoundAudioDeviceGuids"); + StoreAddress(&XInputGetBatteryInformation, "XInputGetBatteryInformation"); + StoreAddress(&XInputGetKeystroke, "XInputGetKeystroke"); + + // XInput 1.3 undocumented functions + StoreAddress(&XInputGetStateEx, (const char*)100); + StoreAddress(&XInputWaitForGuideButton, (const char*)101); + StoreAddress(&XInputCancelGuideButtonWait, (const char*)102); + StoreAddress(&XInputPowerOffController, (const char*)103); + + // XInput 1.4 functions + StoreAddress(&XInputGetAudioDeviceIds, "XInputGetAudioDeviceIds"); + + // XInput 1.4 undocumented functionss + StoreAddress(&XInputGetBaseBusInformation, (const char*)104); + StoreAddress(&XInputGetCapabilitiesEx, (const char*)108); + } +}; + +extern "C" +{ + // XInput 1.3 and older functions + DWORD WINAPI _XInputGetState(DWORD dwUserIndex, XINPUT_STATE* pState) + { + return XINPUTDLL::Get().XInputGetState(dwUserIndex, pState); + } + + DWORD WINAPI _XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration) + { + return XINPUTDLL::Get().XInputSetState(dwUserIndex, pVibration); + } + + DWORD WINAPI _XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities) + { + return XINPUTDLL::Get().XInputGetCapabilities(dwUserIndex, dwFlags, pCapabilities); + } + + VOID WINAPI _XInputEnable(BOOL enable) + { + return XINPUTDLL::Get().XInputEnable(enable); + } + + DWORD WINAPI _XInputGetDSoundAudioDeviceGuids(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid) + { + return XINPUTDLL::Get().XInputGetDSoundAudioDeviceGuids(dwUserIndex, pDSoundRenderGuid, pDSoundCaptureGuid); + } + + DWORD WINAPI _XInputGetBatteryInformation(DWORD dwUserIndex, uint8_t devType, XINPUT_BATTERY_INFORMATION* pBatteryInformation) + { + return XINPUTDLL::Get().XInputGetBatteryInformation(dwUserIndex, devType, pBatteryInformation); + } + + DWORD WINAPI _XInputGetKeystroke(DWORD dwUserIndex, DWORD dwReserved, PXINPUT_KEYSTROKE pKeystroke) + { + return XINPUTDLL::Get().XInputGetKeystroke(dwUserIndex, dwReserved, pKeystroke); + } +} diff --git a/d3d9ex/XInputManager.cpp b/d3d9ex/XInputManager.cpp index e27d281..da52b87 100644 --- a/d3d9ex/XInputManager.cpp +++ b/d3d9ex/XInputManager.cpp @@ -2,20 +2,19 @@ #include "XInputManager.h" #include -XInputManager::XInputManager(byte** base_controller_input_address_ptr) +XInputManager::XInputManager(uint8_t** base_controller_input_address_ptr) { xinputThread = std::thread(&XInputManager::Run, this, base_controller_input_address_ptr); } -void XInputManager::Run(byte** base_controller_input_address_ptr) +void XInputManager::Run(uint8_t** base_controller_input_address_ptr) { - DWORD controllerState; bool hasConnected = false; for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { XINPUT_STATE state; ZeroMemory(&state, sizeof(XINPUT_STATE)); - controllerState = XInputGetState(i, &state); + const DWORD controllerState = XInputGetState(i, &state); if (controllerState == ERROR_SUCCESS) { controllerId = i; hasConnected = true; @@ -28,7 +27,7 @@ void XInputManager::Run(byte** base_controller_input_address_ptr) } } -void XInputManager::WaitAndSetVibrationAddress(byte** base_controller_input_address_ptr) +void XInputManager::WaitAndSetVibrationAddress(uint8_t** base_controller_input_address_ptr) { do { std::this_thread::sleep_for(std::chrono::milliseconds(4)); @@ -47,7 +46,7 @@ void XInputManager::VibrationLoop() while (true) { const float vibrationStrengthLowFrequency = *vibration_address_low_frequency; const float vibrationStrengthHighFrequency = *vibration_address_high_frequency; - if (vibrationStrengthLowFrequency || vibrationStrengthHighFrequency) { + if (vibrationStrengthLowFrequency > 0.0f || vibrationStrengthHighFrequency > 0.0f) { SetControllerVibration((WORD)(vibrationStrengthLowFrequency * maxVibrationStrength), (WORD)(vibrationStrengthHighFrequency * maxVibrationStrength)); wasVibrating = true; } diff --git a/d3d9ex/XInputManager.h b/d3d9ex/XInputManager.h index 63e961e..fef8e13 100644 --- a/d3d9ex/XInputManager.h +++ b/d3d9ex/XInputManager.h @@ -6,9 +6,9 @@ class XInputManager DWORD controllerId = -1; std::thread xinputThread; public: - XInputManager(byte** base_controller_input_address_ptr); - void Run(byte** base_controller_input_address_ptr); - void WaitAndSetVibrationAddress(byte** base_controller_input_address_ptr); + XInputManager(uint8_t** base_controller_input_address_ptr); + void Run(uint8_t** base_controller_input_address_ptr); + void WaitAndSetVibrationAddress(uint8_t** base_controller_input_address_ptr); void VibrationLoop(); void SetControllerVibration(const WORD& leftMotorVibration, const WORD& rightMotorVibration); };