From 6fdc657da7ee772ad0d84ed9fb767547787743be Mon Sep 17 00:00:00 2001 From: Charles the Thobe Date: Tue, 19 May 2026 06:07:25 +0300 Subject: [PATCH 1/4] Get rid of x64 and update required windows SDK --- DPLFusionFix.sln | 6 --- DPLFusionFix/DPLFusionFix.vcxproj | 77 ++----------------------------- 2 files changed, 3 insertions(+), 80 deletions(-) diff --git a/DPLFusionFix.sln b/DPLFusionFix.sln index 010de25..6040cec 100644 --- a/DPLFusionFix.sln +++ b/DPLFusionFix.sln @@ -7,18 +7,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DPLFusionFix", "DPLFusionFi EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 - Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Debug|x64.ActiveCfg = Debug|x64 - {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Debug|x64.Build.0 = Debug|x64 {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Debug|x86.ActiveCfg = Debug|Win32 {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Debug|x86.Build.0 = Debug|Win32 - {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Release|x64.ActiveCfg = Release|x64 - {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Release|x64.Build.0 = Release|x64 {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Release|x86.ActiveCfg = Release|Win32 {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Release|x86.Build.0 = Release|Win32 EndGlobalSection diff --git a/DPLFusionFix/DPLFusionFix.vcxproj b/DPLFusionFix/DPLFusionFix.vcxproj index 7401c6d..9e65151 100644 --- a/DPLFusionFix/DPLFusionFix.vcxproj +++ b/DPLFusionFix/DPLFusionFix.vcxproj @@ -9,49 +9,28 @@ Release Win32 - - Debug - x64 - - - Release - x64 - 15.0 {B2AC0793-8C00-4E71-95DC-CC50A879BE2A} Win32Proj DPLFusionFix - 10.0.22621.0 + 10.0 DynamicLibrary true - v141 + v145 MultiByte DynamicLibrary false - v141 + v145 true MultiByte - - DynamicLibrary - true - v141 - Unicode - - - DynamicLibrary - false - v141 - true - Unicode - @@ -63,27 +42,15 @@ - - - - - - true .asi - - true - false .asi - - false - NotUsing @@ -102,22 +69,6 @@ dinput8.lib - - - Use - Level3 - Disabled - true - _DEBUG;DPLFUSIONFIX_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - - - Windows - true - false - - NotUsing @@ -140,26 +91,6 @@ dinput8.lib - - - Use - Level3 - MaxSpeed - true - true - true - NDEBUG;DPLFUSIONFIX_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - - - Windows - true - true - true - false - - @@ -300,9 +231,7 @@ Create - Create Create - Create From 652bc8b26542d72ab8cc08929daa5316eb9bed5d Mon Sep 17 00:00:00 2001 From: CharlesThobe Date: Fri, 15 May 2026 19:20:03 +0300 Subject: [PATCH 2/4] Update MemoryMgr.h to commit a57211c --- DPLFusionFix/dllmain.cpp | 30 +- DPLFusionFix/dpl/DebugOptions.cpp | 2 +- DPLFusionFix/utils/MemoryMgr.h | 437 +++++++++++++++++------------- 3 files changed, 263 insertions(+), 206 deletions(-) diff --git a/DPLFusionFix/dllmain.cpp b/DPLFusionFix/dllmain.cpp index 0485fb5..b6221a5 100644 --- a/DPLFusionFix/dllmain.cpp +++ b/DPLFusionFix/dllmain.cpp @@ -43,7 +43,7 @@ void OnInitializePlugin() { printf("Windowed mode on\n"); Nop(0x575680, 33); // before the hook, to disable the other code stuff - InjectHook(0x57567C, CreateCustomWindow, PATCH_CALL); // windowed mode / custom window + InjectHook(0x57567C, CreateCustomWindow, HookType::Call); // windowed mode / custom window // windowMode = SW_SHOWNORMAL Patch(0x5FE99F + 1, 1); @@ -109,24 +109,24 @@ void OnInitializePlugin() Nop(0x5ecc3b, 6); Nop(0x5ed472, 6); - InjectHook(0x5ecc3b, HooksClass::PS2_Glow_SFX_Settings_Patch, PATCH_JUMP); + InjectHook(0x5ecc3b, HooksClass::PS2_Glow_SFX_Settings_Patch, HookType::Jump); } // HOOKS // Potentially causing garage crashes for some people - //InjectHook(0x465721, HooksClass::Before_OnEnterGarageState, PATCH_JUMP); + //InjectHook(0x465721, HooksClass::Before_OnEnterGarageState, HookType::Jump); //Nop(0x465e30, 7); - //InjectHook(0x465e30, HooksClass::After_OnEnterGarageState, PATCH_JUMP); + //InjectHook(0x465e30, HooksClass::After_OnEnterGarageState, HookType::Jump); Nop(0x4c4cb9, 9); - InjectHook(0x4c4cb9, HooksClass::ProcessCommandExtension_Frontend, PATCH_JUMP); + InjectHook(0x4c4cb9, HooksClass::ProcessCommandExtension_Frontend, HookType::Jump); Nop(0x45acc4, 7); - InjectHook(0x45acc4, &HooksClass::GameSimulationStep, PATCH_JUMP); + InjectHook(0x45acc4, &HooksClass::GameSimulationStep, HookType::Jump); Nop(0x4def78, 6); - InjectHook(0x4def78, &HooksClass::SimulationDraw, PATCH_JUMP); + InjectHook(0x4def78, &HooksClass::SimulationDraw, HookType::Jump); // this will fix some crashes when going on Era change or back to the menu if (SettingsMgr->bHeapFree_Validation_Fix) @@ -134,33 +134,33 @@ void OnInitializePlugin() WriteAt(0x5fc7e6 + 1, "\x09", 1); Nop(0x5fc7e3, 3); Nop(0x5fc7f1, 9); - InjectHook(0x5fc7f1, HooksClass::HeapFree_Fix_Validation, PATCH_JUMP); + InjectHook(0x5fc7f1, HooksClass::HeapFree_Fix_Validation, HookType::Jump); } // likely unused by the game - //InjectHook(0x4a80c9, &CState_Frontend::OnEnterState, PATCH_CALL); + //InjectHook(0x4a80c9, &CState_Frontend::OnEnterState, HookType::Call); if (SettingsMgr->bLoad_Frontend_Dev_Menu) { Nop(0x4aa075, 6); - InjectHook(0x4aa075, &HooksClass::Custom_Load_Dev_Menu, PATCH_JUMP); + InjectHook(0x4aa075, &HooksClass::Custom_Load_Dev_Menu, HookType::Jump); } if (SettingsMgr->bClassic_BurnOut) { Nop(0x5AF86C, 5); - InjectHook(0x5AF86C, &HooksClass::Classic_BurnOut_Hook, PATCH_JUMP); + InjectHook(0x5AF86C, &HooksClass::Classic_BurnOut_Hook, HookType::Jump); } if (SettingsMgr->bPlayer_Can_Use_Turn_Signal) { Nop(0x49f986, 6); - InjectHook(0x49f986, &HooksClass::Turn_Signal_Feature, PATCH_JUMP); + InjectHook(0x49f986, &HooksClass::Turn_Signal_Feature, HookType::Jump); } // HRESULT __fastcall EndScene__i4HRESULT(CViewport *viewport) //Nop(0x5e455b, 15); // nop all except 'ret' (return) - //InjectHook(0x5e455b, &HooksClass::D3DDevice_EndScene_Patches, PATCH_JUMP); // re-direct the function to ours, like a thunk function + //InjectHook(0x5e455b, &HooksClass::D3DDevice_EndScene_Patches, HookType::Jump); // re-direct the function to ours, like a thunk function //InjectHook(0x4b7f36, HooksClass::GameOverlays_DrawHooked_Debug); @@ -185,9 +185,9 @@ void OnInitializePlugin() // Prevent the player icon into becoming one of them Nop(0x4bdf47, 6); - InjectHook(0x4bdf47, HooksClass::OnCase_EMapItem_Player_CustomBlock, PATCH_JUMP); + InjectHook(0x4bdf47, HooksClass::OnCase_EMapItem_Player_CustomBlock, HookType::Jump); Nop(0x4bdf92, 11); - InjectHook(0x4bdf92, HooksClass::DrawMapItem_ModelCheck, PATCH_JUMP); + InjectHook(0x4bdf92, HooksClass::DrawMapItem_ModelCheck, HookType::Jump); } printf("DPLFusionFix is initialized\n"); diff --git a/DPLFusionFix/dpl/DebugOptions.cpp b/DPLFusionFix/dpl/DebugOptions.cpp index 9177fc6..c602526 100644 --- a/DPLFusionFix/dpl/DebugOptions.cpp +++ b/DPLFusionFix/dpl/DebugOptions.cpp @@ -35,7 +35,7 @@ void Update_Debug_InvincibleToWater() if (bDebug_InvincibleToWater) { Nop(0x4A268D, 6); - InjectHook(0x4A268D, 0x4A27A5, PATCH_JUMP); + InjectHook(0x4A268D, 0x4A27A5, HookType::Jump); } else { diff --git a/DPLFusionFix/utils/MemoryMgr.h b/DPLFusionFix/utils/MemoryMgr.h index b53cf48..178f1b5 100644 --- a/DPLFusionFix/utils/MemoryMgr.h +++ b/DPLFusionFix/utils/MemoryMgr.h @@ -1,91 +1,135 @@ -#ifndef __MEMORYMGR -#define __MEMORYMGR +#pragma once // Switches: -// _MEMORY_NO_CRT - don't include anything "complex" like ScopedUnprotect or memset // _MEMORY_DECLS_ONLY - don't include anything but macroes #define WRAPPER __declspec(naked) #define DEPRECATED __declspec(deprecated) + +#ifdef _MSC_VER #define EAXJMP(a) { _asm mov eax, a _asm jmp eax } #define VARJMP(a) { _asm jmp a } #define WRAPARG(a) ((int)a) +#else +#define EAXJMP(a) __asm__ volatile("mov eax, %0\n" "jmp eax" :: "i" (a)); +#define VARJMP(a) __asm__ volatile("jmp %0" :: "m" (a)); +#define WRAPARG(a) +#endif +#ifdef _MSC_VER #define NOVMT __declspec(novtable) +#else +#define NOVMT +#endif + #define SETVMT(a) *((uintptr_t*)this) = (uintptr_t)a #ifndef _MEMORY_DECLS_ONLY #define WIN32_LEAN_AND_MEAN -#include +#include #include #include -#ifndef _MEMORY_NO_CRT +#include #include -#include -#endif +#include -enum +namespace Memory { - PATCH_CALL, - PATCH_JUMP -}; + enum class HookType + { + Call, + Jump, + }; -template -inline AT DynBaseAddress(AT address) -{ -#ifdef _WIN64 - return (ptrdiff_t)GetModuleHandle(nullptr) - 0x140000000 + address; -#else - return (ptrdiff_t)GetModuleHandle(nullptr) - 0x400000 + address; -#endif -} + template + inline AT DynBaseAddress(AT address) + { + static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized"); + #ifdef _WIN64 + return (ptrdiff_t)GetModuleHandle(nullptr) - 0x140000000 + address; + #else + return (ptrdiff_t)GetModuleHandle(nullptr) - 0x400000 + address; + #endif + } -namespace Memory -{ template inline void Patch(AT address, T value) - {*(T*)address = value; } + { + static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized"); + *(T*)address = value; + } -#ifndef _MEMORY_NO_CRT template inline void Patch(AT address, std::initializer_list list ) { + static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized"); uint8_t* addr = reinterpret_cast(address); - std::copy( list.begin(), list.end(), stdext::make_checked_array_iterator(addr, list.size()) ); + std::copy( list.begin(), list.end(), addr ); + } + + template + inline void Read(AT address, Var& var) + { + static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized"); + var = *(Var*)address; } -#endif template inline void Nop(AT address, size_t count) -#ifndef _MEMORY_NO_CRT - { memset((void*)address, 0x90, count); } -#else - { do { - *(uint8_t*)address++ = 0x90; - } while ( --count != 0 ); } -#endif + { + static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized"); + memset((void*)address, 0x90, count); + } - template - inline void WriteOffsetValue(AT address, Var var) + template + inline void WriteOffsetValue(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0) { + static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized"); intptr_t dstAddr = (intptr_t)address; intptr_t srcAddr; memcpy( &srcAddr, std::addressof(var), sizeof(srcAddr) ); - *(int32_t*)dstAddr = static_cast(srcAddr - dstAddr - (4 + extraBytesAfterOffset)); + *(int32_t*)dstAddr = static_cast(srcAddr - dstAddr - (4 + bytesAfterDisplacement)); } - template - inline void ReadOffsetValue(AT address, Var& var) + template + inline void ReadOffsetValue(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0) { + static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized"); intptr_t srcAddr = (intptr_t)address; - intptr_t dstAddr = srcAddr + (4 + extraBytesAfterOffset) + *(int32_t*)srcAddr; + intptr_t dstAddr = srcAddr + (4 + bytesAfterDisplacement) + *(int32_t*)srcAddr; var = {}; memcpy( std::addressof(var), &dstAddr, sizeof(dstAddr) ); } + template + inline void WriteMemDisplacement(AT address, Var var, [[maybe_unused]] ptrdiff_t bytesAfterDisplacement = 0) + { +#ifdef _WIN64 + WriteOffsetValue(address, var, bytesAfterDisplacement); +#else + Patch(address, var); +#endif + } + + template + inline void ReadMemDisplacement(AT address, Var& var, [[maybe_unused]] ptrdiff_t bytesAfterDisplacement = 0) + { +#ifdef _WIN64 + ReadOffsetValue(address, var, bytesAfterDisplacement); +#else + Read(address, var); +#endif + } + + inline auto InterceptMemDisplacement = [](auto address, auto& orig, auto& var, ptrdiff_t bytesAfterDisplacement = 0) + { + ReadMemDisplacement(address, orig, bytesAfterDisplacement); + WriteMemDisplacement(address, std::addressof(var), bytesAfterDisplacement); + }; + template inline void InjectHook(AT address, Func hook) { @@ -93,9 +137,9 @@ namespace Memory } template - inline void InjectHook(AT address, Func hook, unsigned int nType) + inline void InjectHook(AT address, Func hook, HookType type) { - *(uint8_t*)address = nType == PATCH_JUMP ? 0xE9 : 0xE8; + *(uint8_t*)address = type == HookType::Jump ? 0xE9 : 0xE8; InjectHook(address, hook); } @@ -113,36 +157,53 @@ namespace Memory return reinterpret_cast( addr + offset ); } -#ifndef _MEMORY_NO_CRT + inline auto InterceptCall = [](auto address, auto& func, auto&& hook) + { + ReadCall(address, func); + InjectHook(address, hook); + }; + inline bool MemEquals(uintptr_t address, std::initializer_list val) { const uint8_t* mem = reinterpret_cast(address); - return std::equal( val.begin(), val.end(), stdext::make_checked_array_iterator(mem, val.size()) ); + return std::equal( val.begin(), val.end(), mem ); } -#endif template inline AT Verify(AT address, uintptr_t expected) { + static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized"); assert( uintptr_t(address) == expected ); return address; } namespace DynBase { + enum class HookType + { + Call, + Jump, + }; + + using Memory::DynBaseAddress; + template inline void Patch(AT address, T value) { Memory::Patch(DynBaseAddress(address), value); } -#ifndef _MEMORY_NO_CRT template inline void Patch(AT address, std::initializer_list list ) { Memory::Patch(DynBaseAddress(address), std::move(list)); } -#endif + + template + inline void Read(AT address, Var& var) + { + Memory::Read(DynBaseAddress(address), var); + } template inline void Nop(AT address, size_t count) @@ -150,28 +211,45 @@ namespace Memory Memory::Nop(DynBaseAddress(address), count); } - template - inline void WriteOffsetValue(AT address, Var var) + template + inline void WriteOffsetValue(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0) { - Memory::WriteOffsetValue(DynBaseAddress(address), var); + Memory::WriteOffsetValue(DynBaseAddress(address), var, bytesAfterDisplacement); } - template - inline void ReadOffsetValue(AT address, Var& var) + template< typename Var, typename AT> + inline void ReadOffsetValue(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0) { - Memory::ReadOffsetValue(DynBaseAddress(address), var); + Memory::ReadOffsetValue(DynBaseAddress(address), var, bytesAfterDisplacement); } - template - inline void InjectHook(AT address, HT hook) + template + inline void WriteMemDisplacement(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0) + { + Memory::WriteMemDisplacement(DynBaseAddress(address), var, bytesAfterDisplacement); + } + + template + inline void ReadMemDisplacement(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0) + { + Memory::ReadMemDisplacement(DynBaseAddress(address), var, bytesAfterDisplacement); + } + + inline auto InterceptMemDisplacement = [](auto address, auto& orig, auto& var, ptrdiff_t bytesAfterDisplacement = 0) + { + Memory::InterceptMemDisplacement(DynBaseAddress(address), orig, var, bytesAfterDisplacement); + }; + + template + inline void InjectHook(AT address, Func hook) { Memory::InjectHook(DynBaseAddress(address), hook); } - template - inline void InjectHook(AT address, HT hook, unsigned int nType) + template + inline void InjectHook(AT address, Func hook, HookType type) { - Memory::InjectHook(DynBaseAddress(address), hook, nType); + Memory::InjectHook(DynBaseAddress(address), hook, static_cast(type)); } template @@ -186,7 +264,11 @@ namespace Memory return Memory::ReadCallFrom(DynBaseAddress(address), offset); } -#ifndef _MEMORY_NO_CRT + constexpr auto InterceptCall = [](auto address, auto& func, auto&& hook) + { + Memory::InterceptCall(DynBaseAddress(address), func, hook); + }; + inline bool MemEquals(uintptr_t address, std::initializer_list val) { return Memory::MemEquals(DynBaseAddress(address), std::move(val)); @@ -197,11 +279,18 @@ namespace Memory { return Memory::Verify(address, DynBaseAddress(expected)); } -#endif }; namespace VP { + enum class HookType + { + Call, + Jump, + }; + + using Memory::DynBaseAddress; + template inline void Patch(AT address, T value) { @@ -211,7 +300,6 @@ namespace Memory VirtualProtect((void*)address, sizeof(T), dwProtect, &dwProtect); } -#ifndef _MEMORY_NO_CRT template inline void Patch(AT address, std::initializer_list list ) { @@ -220,7 +308,12 @@ namespace Memory Memory::Patch(address, std::move(list)); VirtualProtect((void*)address, list.size(), dwProtect, &dwProtect); } -#endif + + template + inline void Read(AT address, Var& var) + { + Memory::Read(address, var); + } template inline void Nop(AT address, size_t count) @@ -231,24 +324,49 @@ namespace Memory VirtualProtect((void*)address, count, dwProtect, &dwProtect); } - template - inline void WriteOffsetValue(AT address, Var var) + template + inline void WriteOffsetValue(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0) { DWORD dwProtect; VirtualProtect((void*)address, 4, PAGE_EXECUTE_READWRITE, &dwProtect); - Memory::WriteOffsetValue(address, var); + Memory::WriteOffsetValue(address, var, bytesAfterDisplacement); VirtualProtect((void*)address, 4, dwProtect, &dwProtect); } - template - inline void ReadOffsetValue(AT address, Var& var) + template + inline void ReadOffsetValue(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0) { - Memory::ReadOffsetValue(address, var); + Memory::ReadOffsetValue(address, var, bytesAfterDisplacement); } - template - inline void InjectHook(AT address, HT hook) + template + inline void WriteMemDisplacement(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0) + { + DWORD dwProtect; + + VirtualProtect((void*)address, 4, PAGE_EXECUTE_READWRITE, &dwProtect); + Memory::WriteMemDisplacement(address, var, bytesAfterDisplacement); + VirtualProtect((void*)address, 4, dwProtect, &dwProtect); + } + + template + inline void ReadMemDisplacement(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0) + { + Memory::ReadMemDisplacement(address, var, bytesAfterDisplacement); + } + + inline auto InterceptMemDisplacement = [](auto address, auto& orig, auto& var, ptrdiff_t bytesAfterDisplacement = 0) + { + DWORD dwProtect; + + VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect); + Memory::InterceptMemDisplacement(address, orig, var, bytesAfterDisplacement); + VirtualProtect((void*)address, 5, dwProtect, &dwProtect); + }; + + template + inline void InjectHook(AT address, Func hook) { DWORD dwProtect; @@ -257,13 +375,13 @@ namespace Memory VirtualProtect((void*)((DWORD_PTR)address + 1), 4, dwProtect, &dwProtect); } - template - inline void InjectHook(AT address, HT hook, unsigned int nType) + template + inline void InjectHook(AT address, Func hook, HookType type) { DWORD dwProtect; VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect); - Memory::InjectHook( address, hook, nType ); + Memory::InjectHook( address, hook, static_cast(type) ); VirtualProtect((void*)address, 5, dwProtect, &dwProtect); } @@ -279,12 +397,19 @@ namespace Memory return Memory::ReadCallFrom(address, offset); } -#ifndef _MEMORY_NO_CRT + constexpr auto InterceptCall = [](auto address, auto& func, auto&& hook) + { + DWORD dwProtect; + + VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect); + Memory::InterceptCall(address, func, hook); + VirtualProtect((void*)address, 5, dwProtect, &dwProtect); + }; + inline bool MemEquals(uintptr_t address, std::initializer_list val) { return Memory::MemEquals(address, std::move(val)); } -#endif template inline AT Verify(AT address, uintptr_t expected) @@ -294,19 +419,31 @@ namespace Memory namespace DynBase { + enum class HookType + { + Call, + Jump, + }; + + using Memory::DynBaseAddress; + template inline void Patch(AT address, T value) { VP::Patch(DynBaseAddress(address), value); } -#ifndef _MEMORY_NO_CRT template inline void Patch(AT address, std::initializer_list list ) { VP::Patch(DynBaseAddress(address), std::move(list)); } -#endif + + template + inline void Read(AT address, Var& var) + { + VP::Read(DynBaseAddress(address), var); + } template inline void Nop(AT address, size_t count) @@ -314,28 +451,45 @@ namespace Memory VP::Nop(DynBaseAddress(address), count); } - template - inline void WriteOffsetValue(AT address, Var var) + template + inline void WriteOffsetValue(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0) + { + VP::WriteOffsetValue(DynBaseAddress(address), var, bytesAfterDisplacement); + } + + template + inline void ReadOffsetValue(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0) { - VP::WriteOffsetValue(DynBaseAddress(address), var); + VP::ReadOffsetValue(DynBaseAddress(address), var, bytesAfterDisplacement); } - template - inline void ReadOffsetValue(AT address, Var& var) + template + inline void WriteMemDisplacement(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0) { - VP::ReadOffsetValue(DynBaseAddress(address), var); + VP::WriteMemDisplacement(DynBaseAddress(address), var, bytesAfterDisplacement); } - template - inline void InjectHook(AT address, HT hook) + template + inline void ReadMemDisplacement(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0) + { + VP::ReadMemDisplacement(DynBaseAddress(address), var, bytesAfterDisplacement); + } + + inline auto InterceptMemDisplacement = [](auto address, auto& orig, auto& var, ptrdiff_t bytesAfterDisplacement = 0) + { + VP::InterceptMemDisplacement(DynBaseAddress(address), orig, var, bytesAfterDisplacement); + }; + + template + inline void InjectHook(AT address, Func hook) { VP::InjectHook(DynBaseAddress(address), hook); } - template - inline void InjectHook(AT address, HT hook, unsigned int nType) + template + inline void InjectHook(AT address, Func hook, HookType type) { - VP::InjectHook(DynBaseAddress(address), hook, nType); + VP::InjectHook(DynBaseAddress(address), hook, static_cast(type)); } template @@ -347,15 +501,18 @@ namespace Memory template inline void* ReadCallFrom(AT address, ptrdiff_t offset = 0) { - Memory::ReadCallFrom(DynBaseAddress(address), offset); + return Memory::ReadCallFrom(DynBaseAddress(address), offset); } -#ifndef _MEMORY_NO_CRT + constexpr auto InterceptCall = [](auto address, auto& func, auto&& hook) + { + VP::InterceptCall(DynBaseAddress(address), func, hook); + }; + inline bool MemEquals(uintptr_t address, std::initializer_list val) { return Memory::MemEquals(DynBaseAddress(address), std::move(val)); } -#endif template inline AT Verify(AT address, uintptr_t expected) @@ -367,104 +524,4 @@ namespace Memory }; }; -#ifndef _MEMORY_NO_CRT - -#include -#include -#include - -namespace ScopedUnprotect -{ - class Unprotect - { - public: - ~Unprotect() - { - for ( auto& it : m_queriedProtects ) - { - DWORD dwOldProtect; - VirtualProtect( std::get<0>(it), std::get<1>(it), std::get<2>(it), &dwOldProtect ); - } - } - - protected: - Unprotect() = default; - - void UnprotectRange( DWORD_PTR BaseAddress, SIZE_T Size ) - { - SIZE_T QueriedSize = 0; - while ( QueriedSize < Size ) - { - MEMORY_BASIC_INFORMATION MemoryInf; - DWORD dwOldProtect; - - VirtualQuery( (LPCVOID)(BaseAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) ); - if ( MemoryInf.State == MEM_COMMIT && (MemoryInf.Type & MEM_IMAGE) != 0 && - (MemoryInf.Protect & (PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY|PAGE_READWRITE|PAGE_WRITECOPY)) == 0 ) - { - const bool wasExecutable = (MemoryInf.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ)) != 0; - VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, wasExecutable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &dwOldProtect ); - m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect ); - } - QueriedSize += MemoryInf.RegionSize; - } - } - - private: - std::forward_list< std::tuple< LPVOID, SIZE_T, DWORD > > m_queriedProtects; - }; - - class Section : public Unprotect - { - public: - Section( HINSTANCE hInstance, const char* name ) - { - PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew); - PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(ntHeader); - - for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; ++i, ++pSection ) - { - if ( strncmp( (const char*)pSection->Name, name, IMAGE_SIZEOF_SHORT_NAME ) == 0 ) - { - const DWORD_PTR VirtualAddress = (DWORD_PTR)hInstance + pSection->VirtualAddress; - const SIZE_T VirtualSize = pSection->Misc.VirtualSize; - UnprotectRange( VirtualAddress, VirtualSize ); - - m_locatedSection = true; - break; - } - } - }; - - bool SectionLocated() const { return m_locatedSection; } - - private: - bool m_locatedSection = false; - }; - - class FullModule : public Unprotect - { - public: - FullModule( HINSTANCE hInstance ) - { - PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew); - UnprotectRange( (DWORD_PTR)hInstance, ntHeader->OptionalHeader.SizeOfImage ); - } - }; - - inline std::unique_ptr UnprotectSectionOrFullModule( HINSTANCE hInstance, const char* name ) - { - std::unique_ptr
section = std::make_unique
( hInstance, name ); - if ( !section->SectionLocated() ) - { - return std::make_unique( hInstance ); - } - return section; - } -}; - #endif - -#endif - -#endif \ No newline at end of file From f3ee6f15814c043fffbe05e98a6b7b6721ceea89 Mon Sep 17 00:00:00 2001 From: Charles the Thobe Date: Mon, 25 May 2026 23:10:57 +0300 Subject: [PATCH 3/4] Fix warnings The code is functionaly the same, no bugs were fixed --- DPLFusionFix/core/Vector.cpp | 14 +++++++------- DPLFusionFix/core/Vector.h | 6 +++--- DPLFusionFix/dpl/Character.cpp | 7 ++++--- DPLFusionFix/dpl/Character.h | 2 +- DPLFusionFix/dpl/EAnimStates.h | 2 +- DPLFusionFix/dpl/FontManager.cpp | 3 ++- DPLFusionFix/dpl/FontManager.h | 2 +- DPLFusionFix/dpl/GameOverlayManager.h | 2 +- DPLFusionFix/dpl/HACK_VehicleTypeSelection.h | 4 ++-- DPLFusionFix/dpl/LevelList.h | 4 ++-- DPLFusionFix/dpl/LifeProgression.h | 4 ++-- DPLFusionFix/dpl/State_Frontend.cpp | 6 +++--- DPLFusionFix/dpl/State_VEdit.cpp | 12 ++++++------ DPLFusionFix/dpl/Vector4.cpp | 2 +- DPLFusionFix/dpl/common.cpp | 4 ++-- 15 files changed, 38 insertions(+), 36 deletions(-) diff --git a/DPLFusionFix/core/Vector.cpp b/DPLFusionFix/core/Vector.cpp index cc63130..3477454 100644 --- a/DPLFusionFix/core/Vector.cpp +++ b/DPLFusionFix/core/Vector.cpp @@ -1,6 +1,6 @@ #include "Vector.h" -inline float RecipSqrt(float x, float y) { return x / sqrt(y); } +inline float RecipSqrt(float x, float y) { return x / sqrtf(y); } inline float RecipSqrt(float x) { return RecipSqrt(1.0f, x); } void Vector::Normalise() @@ -24,16 +24,16 @@ Vector CrossProduct(const Vector& v1, const Vector& v2) // Returns the Y axis (in radians) facing a specific vector float GetYAxisFromDirection(Vector direction) { - return atan2(direction.X, direction.Y); + return atan2f(direction.X, direction.Y); } // Returns a vector with X Y Z axis in radians indicating the direction void GetAxisVectorFromDirection(Vector direction, Vector& vector) { - float x = atan2(direction.Y, GetDistanceBetweenPoints2D(0, 0, direction.X, direction.Z)); + float x = atan2f(direction.Y, GetDistanceBetweenPoints2D(0, 0, direction.X, direction.Z)); while (x > M_PI*2) { - x = x - M_PI*2; + x = static_cast(x - M_PI*2); } vector.X = x; vector.Y = GetYAxisFromDirection(direction); @@ -42,7 +42,7 @@ void GetAxisVectorFromDirection(Vector direction, Vector& vector) float GetDistanceBetweenPoints2D(float x1, float y1, float x2, float y2) { - float dist = pow((x2 - x1) * pow(x2 - x1, 2) + (y2 - y1) * pow(y2 - y1, 2), 0.5f); + float dist = powf((x2 - x1) * powf(x2 - x1, 2) + (y2 - y1) * powf(y2 - y1, 2), 0.5); if (dist < 0) dist = 0; return dist; @@ -53,8 +53,8 @@ float GetDistanceBetweenPoints3D(float x1, float y1, float z1, float x2, float y float dx = x2 - x1; float dy = y2 - y1; float dz = z2 - z1; - float dist = sqrt(dx * dx + dy * dy + dz * dz); + float dist = sqrtf(dx * dx + dy * dy + dz * dz); if (dist < 0) dist = 0; return dist; -} \ No newline at end of file +} diff --git a/DPLFusionFix/core/Vector.h b/DPLFusionFix/core/Vector.h index f2e9134..2316546 100644 --- a/DPLFusionFix/core/Vector.h +++ b/DPLFusionFix/core/Vector.h @@ -14,10 +14,10 @@ class Vector Y = b; Z = c; } - float Heading(void) const { return atan2(-X, Y); } - float Magnitude(void) const { return sqrt(X * X + Y * Y + Z * Z); } + float Heading(void) const { return atan2f(-X, Y); } + float Magnitude(void) const { return sqrtf(X * X + Y * Y + Z * Z); } float MagnitudeSqr(void) const { return X * X + Y * Y + Z * Z; } - float Magnitude2D(void) const { return sqrt(X * X + Y * Y); } + float Magnitude2D(void) const { return sqrtf(X * X + Y * Y); } float MagnitudeSqr2D(void) const { return X * X + Y * Y; } void Normalise(); Vector Lerp(const Vector& target, float t) const { diff --git a/DPLFusionFix/dpl/Character.cpp b/DPLFusionFix/dpl/Character.cpp index b00d7af..35451a7 100644 --- a/DPLFusionFix/dpl/Character.cpp +++ b/DPLFusionFix/dpl/Character.cpp @@ -275,9 +275,9 @@ CWeapon* CCharacter::GetWeapon() return (CWeapon*)((int)this + 208); } -int CCharacter::GetPointer() +uintptr_t CCharacter::GetPointer() { - return (int)(this); + return (uintptr_t)(this); } int CCharacter::GetVTableAddress() @@ -334,8 +334,9 @@ void CCharacter::SetIsSpawned(bool spawned) bool CCharacter::IsValid() { + // FIXME: What is this trying to do? try { - return (this && *(int*)(this->GetPointer())) == 0x64E928; + return this->GetPointer() == uintptr_t(0x64E928); } catch (std::exception ex) { return false; diff --git a/DPLFusionFix/dpl/Character.h b/DPLFusionFix/dpl/Character.h index 4ab9e60..5827247 100644 --- a/DPLFusionFix/dpl/Character.h +++ b/DPLFusionFix/dpl/Character.h @@ -63,7 +63,7 @@ class CCharacter { void SetAnimType(int type); int* GetAnimTypePointer(); - int GetPointer(); + uintptr_t GetPointer(); int GetVTableAddress(); void DrawCrosshair(int Viewport, int unk); diff --git a/DPLFusionFix/dpl/EAnimStates.h b/DPLFusionFix/dpl/EAnimStates.h index 89f5e8d..282fdbb 100644 --- a/DPLFusionFix/dpl/EAnimStates.h +++ b/DPLFusionFix/dpl/EAnimStates.h @@ -14,7 +14,7 @@ enum EnumAnimCondition { eACond_End = 6 }; -typedef enum eAnimState { +enum eAnimState { eAState_Undef = -2, eAState_Bad = -1, eAState_Invalid = -1, diff --git a/DPLFusionFix/dpl/FontManager.cpp b/DPLFusionFix/dpl/FontManager.cpp index 01a8d0d..4a426bb 100644 --- a/DPLFusionFix/dpl/FontManager.cpp +++ b/DPLFusionFix/dpl/FontManager.cpp @@ -80,7 +80,8 @@ void CFontManager::PrintFast(Vector4* dimensions, CPCViewport* piView, FontSpecs void CFontManager::Print(Vector4* dimensions, AutoPtr piView, FontSpecs *spec, const wchar_t* szFormat, int unk1) { - Print(dimensions, piView, spec, (wchar_t*)szFormat, unk1); + //Print(dimensions, piView, spec, (wchar_t*)szFormat, unk1); + // FIXME: Broken function that infinitely calls itself } void CFontManager::Print(Vector4* dimensions, CPCViewport* piView, FontSpecs *spec, const wchar_t* szFormat, int unk1) diff --git a/DPLFusionFix/dpl/FontManager.h b/DPLFusionFix/dpl/FontManager.h index 376a0f3..3f42f00 100644 --- a/DPLFusionFix/dpl/FontManager.h +++ b/DPLFusionFix/dpl/FontManager.h @@ -13,7 +13,7 @@ enum EJustify { }; struct FontSpecs { - struct Vector4 colour { 1, 1, 1, 1 }; + Vector4 colour { 1, 1, 1, 1 }; int fontType; int textType; float x; diff --git a/DPLFusionFix/dpl/GameOverlayManager.h b/DPLFusionFix/dpl/GameOverlayManager.h index 44486f1..041d010 100644 --- a/DPLFusionFix/dpl/GameOverlayManager.h +++ b/DPLFusionFix/dpl/GameOverlayManager.h @@ -146,7 +146,7 @@ struct CMapMarkers { }; struct SGameOverlayGraphic { - struct Vector4 vColour; + Vector4 vColour; float fX; float fY; float fW; diff --git a/DPLFusionFix/dpl/HACK_VehicleTypeSelection.h b/DPLFusionFix/dpl/HACK_VehicleTypeSelection.h index 5725d17..ed581d7 100644 --- a/DPLFusionFix/dpl/HACK_VehicleTypeSelection.h +++ b/DPLFusionFix/dpl/HACK_VehicleTypeSelection.h @@ -10,7 +10,7 @@ struct sNameToEVehicleType extern int* _22VEHICLE_SELECTION_HACK$currentVehicle; extern int* _22VEHICLE_SELECTION_HACK$currentVehicleType; -static class VEHICLE_SELECTION_HACK +class VEHICLE_SELECTION_HACK { public: static sNameToEVehicleType* GetVehicleTypeMatchTable(); @@ -20,4 +20,4 @@ static class VEHICLE_SELECTION_HACK static int GetNumVehicles(); static char* GetCurrentVehicleName(); -}; \ No newline at end of file +}; diff --git a/DPLFusionFix/dpl/LevelList.h b/DPLFusionFix/dpl/LevelList.h index 01031fb..4b81506 100644 --- a/DPLFusionFix/dpl/LevelList.h +++ b/DPLFusionFix/dpl/LevelList.h @@ -4,8 +4,8 @@ class CLevelList { public: - unsigned int m_uCurrentLevel; - unsigned int m_uLevels; + int m_uCurrentLevel; + int m_uLevels; char* buffer; char* GetLevelName(int nLevel); diff --git a/DPLFusionFix/dpl/LifeProgression.h b/DPLFusionFix/dpl/LifeProgression.h index d772b08..e3e1a65 100644 --- a/DPLFusionFix/dpl/LifeProgression.h +++ b/DPLFusionFix/dpl/LifeProgression.h @@ -15,8 +15,8 @@ struct CLifeEventList { uint8_t field7_0xd; uint8_t field8_0xe; uint8_t field9_0xf; - struct Matrix m_restartPosition; - struct Vector4 v4Position; + Matrix m_restartPosition; + Vector4 v4Position; unsigned int eventType; char *filename; struct LocalisedString *m_eventName; diff --git a/DPLFusionFix/dpl/State_Frontend.cpp b/DPLFusionFix/dpl/State_Frontend.cpp index 93ef2c4..0157769 100644 --- a/DPLFusionFix/dpl/State_Frontend.cpp +++ b/DPLFusionFix/dpl/State_Frontend.cpp @@ -1010,7 +1010,7 @@ void CState_Frontend::ProcessCommand_Development(char *szCommand, char *szParame GetGameMenuLink()->SetValue(currentChar); } - uint32_t num_options = 0; + int num_options = 0; if (m_eDebugOptionsType == eDebugOptions_Game) { num_options = sizeof(m_pszGameDebugOptions) / 4; @@ -1052,7 +1052,7 @@ void CState_Frontend::ProcessCommand_Development(char *szCommand, char *szParame int option_idx = GetDebugOptionIndex(szCommand); if (option_idx != -1) { - uint32_t option_num = (m_debugOffset + option_idx); + int option_num = (m_debugOffset + option_idx); char* optName = NULL; SDebugOption* ogopt = NULL; @@ -1101,7 +1101,7 @@ void CState_Frontend::ProcessCommand_Development(char *szCommand, char *szParame // Make the debug options be changed if (m_debugOption >= 0 && m_debugOption < total_num_options) { - uint32_t option_num = (m_debugOption + m_debugOffset); + int option_num = (m_debugOption + m_debugOffset); char* optName = NULL; SDebugOption* ogopt = NULL; diff --git a/DPLFusionFix/dpl/State_VEdit.cpp b/DPLFusionFix/dpl/State_VEdit.cpp index bab9768..22e2efc 100644 --- a/DPLFusionFix/dpl/State_VEdit.cpp +++ b/DPLFusionFix/dpl/State_VEdit.cpp @@ -60,7 +60,7 @@ void CState_VEdit::Step_GarageCamera() // if input down or input up is not pressed within the dead-zone if (inputback < camerainput_deadzone && inputforward < camerainput_deadzone) { - static float cord_elevationStep = 0.1f * 0.014959967; + static float cord_elevationStep = 0.1f * 0.014959967f; if (*m_DisplayElevate < -cord_elevationStep) *m_DisplayElevate += cord_elevationStep; // push camera up @@ -69,17 +69,17 @@ void CState_VEdit::Step_GarageCamera() } if (inputleft > camerainput_deadzone) { - *m_DisplayRotate = *m_DisplayRotate + (inputleft * 0.014959967); + *m_DisplayRotate = *m_DisplayRotate + (inputleft * 0.014959967f); } else if (inputright > camerainput_deadzone) { - *m_DisplayRotate = *m_DisplayRotate - (inputright * 0.014959967); + *m_DisplayRotate = *m_DisplayRotate - (inputright * 0.014959967f); } if (inputback > camerainput_deadzone) { - *m_DisplayElevate = *m_DisplayElevate - (inputback * 0.014959967); + *m_DisplayElevate = *m_DisplayElevate - (inputback * 0.014959967f); } else if (inputforward > camerainput_deadzone) { - *m_DisplayElevate = *m_DisplayElevate + (inputforward * 0.014959967); + *m_DisplayElevate = *m_DisplayElevate + (inputforward * 0.014959967f); } // if rotation is greater than 360 degrees then reset the angle (no effect) @@ -90,7 +90,7 @@ void CState_VEdit::Step_GarageCamera() // if rotation is less than 0 then set the angle to 360 degrees (no effect) if (*m_DisplayRotate < 0) { - *m_DisplayRotate = M_PI * 2; + *m_DisplayRotate = static_cast(M_PI * 2); } // clamp elevation (approx -5.6 degrees to +22.5 degrees in radians) diff --git a/DPLFusionFix/dpl/Vector4.cpp b/DPLFusionFix/dpl/Vector4.cpp index 05e935a..0024945 100644 --- a/DPLFusionFix/dpl/Vector4.cpp +++ b/DPLFusionFix/dpl/Vector4.cpp @@ -89,7 +89,7 @@ float GetDistanceBetweenPoints3D(Vector4 v1, Vector4 v2) float x2 = v2.X; float y2 = v2.Y; float z2 = v2.Z; - float dist = pow((x2 - x1) * pow(x2 - x1, 2) + (y2 - y1) * pow(y2 - y1, 2) + (z2 - z1) * (z2 - z1), 0.5f); + float dist = static_cast(((x2 - x1) * pow(x2 - x1, 2) + (y2 - y1) * pow(y2 - y1, 2) + (z2 - z1) * (z2 - z1), 0.5f)); if (dist < 0) dist = 0; return dist; diff --git a/DPLFusionFix/dpl/common.cpp b/DPLFusionFix/dpl/common.cpp index 2e1e781..f88f7aa 100644 --- a/DPLFusionFix/dpl/common.cpp +++ b/DPLFusionFix/dpl/common.cpp @@ -111,8 +111,8 @@ void OnGameStep() if (SettingsMgr->bWindowed_Mode) { HWND hamsterWnd = GetHamsterHWND(); - int width = GetSystemMetrics(SM_CXSCREEN); - int height = GetSystemMetrics(SM_CYSCREEN); + float width = static_cast(GetSystemMetrics(SM_CXSCREEN)); + float height = static_cast(GetSystemMetrics(SM_CYSCREEN)); if (width != 0 && height != 0) { From 6a17ba29580187a142bb22a2e54b6e9a7acffaa6 Mon Sep 17 00:00:00 2001 From: CharlesThobe Date: Fri, 15 May 2026 22:11:45 +0300 Subject: [PATCH 4/4] Remove utils.h and use functions from MemoryMgr.h instead This also fixes access violation crash when using newer versions of Ultimate ASI Loader --- DPLFusionFix/DPLFusionFix.vcxproj | 2 - DPLFusionFix/DPLFusionFix.vcxproj.filters | 6 --- DPLFusionFix/HooksClass.cpp | 12 ++--- DPLFusionFix/dllmain.cpp | 58 ++++++++++++----------- DPLFusionFix/dllmain.h | 3 -- DPLFusionFix/dpl/DebugOptions.cpp | 18 +++---- DPLFusionFix/dpl/DebugOptions.h | 2 +- DPLFusionFix/utils.cpp | 25 ---------- DPLFusionFix/utils.h | 9 ---- 9 files changed, 47 insertions(+), 88 deletions(-) delete mode 100644 DPLFusionFix/utils.cpp delete mode 100644 DPLFusionFix/utils.h diff --git a/DPLFusionFix/DPLFusionFix.vcxproj b/DPLFusionFix/DPLFusionFix.vcxproj index 9e65151..cebaeb1 100644 --- a/DPLFusionFix/DPLFusionFix.vcxproj +++ b/DPLFusionFix/DPLFusionFix.vcxproj @@ -170,7 +170,6 @@ - @@ -233,7 +232,6 @@ Create Create - diff --git a/DPLFusionFix/DPLFusionFix.vcxproj.filters b/DPLFusionFix/DPLFusionFix.vcxproj.filters index c713b8d..e1b9a92 100644 --- a/DPLFusionFix/DPLFusionFix.vcxproj.filters +++ b/DPLFusionFix/DPLFusionFix.vcxproj.filters @@ -33,9 +33,6 @@ Header files - - External - External\utils @@ -422,9 +419,6 @@ dpl - - External - dpl diff --git a/DPLFusionFix/HooksClass.cpp b/DPLFusionFix/HooksClass.cpp index fc3e747..054371a 100644 --- a/DPLFusionFix/HooksClass.cpp +++ b/DPLFusionFix/HooksClass.cpp @@ -32,8 +32,8 @@ void __declspec(naked) HooksClass::Before_OnEnterGarageState() // Low the ping in and ping out radius to prevent infinite loading lfs->m_fPingInRadius = 100; lfs->m_fPingOutRadius = 115; - *(float*)(0x6414f8) = lfs->m_fPingInRadius; - *(float*)(0x641420) = lfs->m_fPingOutRadius; + Memory::Patch(0x6414f8, lfs->m_fPingInRadius); + Memory::Patch(0x641420, lfs->m_fPingOutRadius); // Restore registers __asm @@ -95,8 +95,8 @@ void __declspec(naked) HooksClass::After_OnEnterGarageState() // Restore ping in and ping out radius lfs->m_fPingInRadius = SettingsMgr->fInstances_Spawn_Radius - 10; lfs->m_fPingOutRadius = SettingsMgr->fInstances_Spawn_Radius; - *(float*)(0x6414f8) = lfs->m_fPingInRadius; - *(float*)(0x641420) = lfs->m_fPingOutRadius; + Memory::Patch(0x6414f8, lfs->m_fPingInRadius); + Memory::Patch(0x641420, lfs->m_fPingOutRadius); // Restore registers __asm @@ -617,8 +617,8 @@ void __declspec(naked) HooksClass::PS2_Glow_SFX_Settings_Patch() */ // Code here - *(int*)(0x976398) = 300; // "Glow pp multiply" - *(int*)(0x9765A4) = 3; // "Glow filter pass count" + Memory::Patch(0x976398, 300); // "Glow pp multiply" + Memory::Patch(0x9765A4, 3); // "Glow filter pass count" /* static int DAT_00976398 = 0x976398; diff --git a/DPLFusionFix/dllmain.cpp b/DPLFusionFix/dllmain.cpp index b6221a5..29bb770 100644 --- a/DPLFusionFix/dllmain.cpp +++ b/DPLFusionFix/dllmain.cpp @@ -1,5 +1,5 @@ #include "pch.h" -#include "utils.h" +#include "utils/MemoryMgr.h" #include "Settings.h" #include "GameChangableSettingsClass.h" #include "HooksClass.h" @@ -15,21 +15,23 @@ #define HWND_Height 600 #define HWND_Style WS_OVERLAPPEDWINDOW //WS_POPUP | WS_CAPTION | WS_SYSMENU +using namespace Memory::VP; + void OnInitializePlugin() { // Patches based on settings if (SettingsMgr != NULL) { // ping in & ping out radius - *(float*)(0x6414f8) = SettingsMgr->fInstances_Spawn_Radius - INSTANCES_SPAWN_RADIUS_PING_IN_OFFSET; - *(float*)(0x641420) = SettingsMgr->fInstances_Spawn_Radius; + Patch(0x6414f8, SettingsMgr->fInstances_Spawn_Radius - INSTANCES_SPAWN_RADIUS_PING_IN_OFFSET); + Patch(0x641420, SettingsMgr->fInstances_Spawn_Radius); - *(float*)(0x6dd660) = SettingsMgr->fVehicles_HeadLight_DegreesAngle; + Patch(0x6dd660, SettingsMgr->fVehicles_HeadLight_DegreesAngle); // float _11SDrawHelper$m_draw_distance[3] - *(float*)(0x6cfcb4) = SettingsMgr->fDraw_Distance1; - *(float*)(0x6cfcb4 + 4) = SettingsMgr->fDraw_Distance2; - *(float*)(0x6cfcb4 + 8) = SettingsMgr->fDraw_Distance3; + Patch(0x6cfcb4, SettingsMgr->fDraw_Distance1); + Patch(0x6cfcb4 + 4, SettingsMgr->fDraw_Distance2); + Patch(0x6cfcb4 + 8, SettingsMgr->fDraw_Distance3); // show console if the settings allow if (SettingsMgr->bShow_Console_Output) @@ -46,11 +48,11 @@ void OnInitializePlugin() InjectHook(0x57567C, CreateCustomWindow, HookType::Call); // windowed mode / custom window // windowMode = SW_SHOWNORMAL - Patch(0x5FE99F + 1, 1); + Patch(0x5FE99F + 1, 1); if (SettingsMgr->bPause_Game_In_Windowed_Mode == false) { - WriteAt(0x57168B + 3, "\x00", 1); // all thanks to my ol' helper - Cheat Engine! + Patch(0x57168B + 3, 0x00); // all thanks to my ol' helper - Cheat Engine! } } @@ -67,20 +69,20 @@ void OnInitializePlugin() // Default patches - WritePointerAt(0x442b4c + 4, reinterpret_cast(&GameChangableSettings::g_fPedDensityBaseNoPingInRadius)); - WritePointerAt(0x442b44 + 4, reinterpret_cast(&GameChangableSettings::g_fPedDensityPingMultiplier)); - WritePointerAt(0x4485f5 + 4, reinterpret_cast(&GameChangableSettings::g_fPedDensitySubtractionNoPingInRadius)); - WritePointerAt(0x448346 + 4, reinterpret_cast(&GameChangableSettings::g_fPedPingOut)); - WritePointerAt(0x448356 + 4, reinterpret_cast(&GameChangableSettings::g_fPedPingIn)); - WritePointerAt(0x404275 + 3, reinterpret_cast(&GameChangableSettings::g_fAICivilianCarGiveUpJourneySquareDistance)); + Patch(0x442b4c + 4, &GameChangableSettings::g_fPedDensityBaseNoPingInRadius); + Patch(0x442b44 + 4, &GameChangableSettings::g_fPedDensityPingMultiplier); + Patch(0x4485f5 + 4, &GameChangableSettings::g_fPedDensitySubtractionNoPingInRadius); + Patch(0x448346 + 4, &GameChangableSettings::g_fPedPingOut); + Patch(0x448356 + 4, &GameChangableSettings::g_fPedPingIn); + Patch(0x404275 + 3, &GameChangableSettings::g_fAICivilianCarGiveUpJourneySquareDistance); if (SettingsMgr->bHighPoly_Civilian_Cars) { // civilian cars' rendering priority is set to 0x5 (eVehiclePriorityForeground or eVehicleControlScripted) - WriteAt(0x40d64c + 1, "\x05", 1); // PARKED CARS - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground); - WriteAt(0x4107dd + 1, "\x05", 1); // VIRTUAL PING IN - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground); - WriteAt(0x410b0f + 1, "\x05", 1); // ??? - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground); - WriteAt(0x412b1e + 1, "\x05", 1); // AIManagerClass step - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground); + Patch(0x40d64c + 1, 0x05); // PARKED CARS - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground); + Patch(0x4107dd + 1, 0x05); // VIRTUAL PING IN - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground); + Patch(0x410b0f + 1, 0x05); // ??? - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground); + Patch(0x412b1e + 1, 0x05); // AIManagerClass step - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground); } // TODO: maybe fix this... it's for the complete mission debug option @@ -99,9 +101,9 @@ void OnInitializePlugin() //WritePointerAt(0x471f54 + 4, reinterpret_cast(&GameChangableSettings::g_fInstances_Ping_In)); //WritePointerAt(0x471f61 + 4, reinterpret_cast(&GameChangableSettings::g_fInstances_Ping_Out)); - *(float*)(0x6778e0) = GameChangableSettings::g_fAICivilianCarTopSpeedForward; - *(float*)(0x6778dc) = GameChangableSettings::g_fAICivilianCarTopSpeedReverse; - *(float*)(0x6778d8) = GameChangableSettings::g_fAICivilianCarGainGrad; + Memory::Patch(0x6778e0, GameChangableSettings::g_fAICivilianCarTopSpeedForward); + Memory::Patch(0x6778dc, GameChangableSettings::g_fAICivilianCarTopSpeedReverse); + Memory::Patch(0x6778d8, GameChangableSettings::g_fAICivilianCarGainGrad); if (SettingsMgr->bPS2_Glow_Effects_Settings) { @@ -131,7 +133,7 @@ void OnInitializePlugin() // this will fix some crashes when going on Era change or back to the menu if (SettingsMgr->bHeapFree_Validation_Fix) { - WriteAt(0x5fc7e6 + 1, "\x09", 1); + Patch(0x5fc7e6 + 1, 0x09); Nop(0x5fc7e3, 3); Nop(0x5fc7f1, 9); InjectHook(0x5fc7f1, HooksClass::HeapFree_Fix_Validation, HookType::Jump); @@ -169,19 +171,19 @@ void OnInitializePlugin() if (SettingsMgr->bDev_Menu_On) { - WriteAt(0x459f8e + 1, "\x01", 1); // pause_devMenuBTN->SetRenderState(1); + Patch(0x459f8e + 1, 0x01); // pause_devMenuBTN->SetRenderState(1); // NOTE: for your safety you better not access frontend dev menu! // it will crash the game, so stick to the pause menu dev menu :/ - WriteAt(0x4aa522 + 1, "\x01", 1); // frontend_devMenuBTN->SetRenderState(1); - + Patch(0x4aa522 + 1, 0x01); // frontend_devMenuBTN->SetRenderState(1); + //Nop(0x4aa3f2, 9); // disable launch_dev_menu //Nop(0x459f8c, 14); } if (SettingsMgr->bMinimap_Driver3_Goons) { - WriteAt(0x4bdf71 + 3, "\x4C", 1); // ambColour.Y = 0; - //WriteAt(0x4bdf92 + 7, "\x05\x00\x35", 4); // instance.hModel = MinimapIcon_AlertedCop; + Patch(0x4bdf71 + 3, 0x4C); // ambColour.Y = 0; + //Patch(0x4bdf92 + 7, {0x05, 0x00, 0x35, 0x00}); // instance.hModel = MinimapIcon_AlertedCop; // Prevent the player icon into becoming one of them Nop(0x4bdf47, 6); diff --git a/DPLFusionFix/dllmain.h b/DPLFusionFix/dllmain.h index adf8e66..40cec7d 100644 --- a/DPLFusionFix/dllmain.h +++ b/DPLFusionFix/dllmain.h @@ -8,6 +8,3 @@ static float g_fPedDensitySubtractionNoPingInRadius; static float g_fPedDensityDensityMultiplier; HWND CreateCustomWindow(HINSTANCE hamsterModule, DWORD zero); - -void WriteAt(unsigned int address, const char* buffer, size_t size); -void WriteAt(unsigned int address, int integer); diff --git a/DPLFusionFix/dpl/DebugOptions.cpp b/DPLFusionFix/dpl/DebugOptions.cpp index c602526..93490d6 100644 --- a/DPLFusionFix/dpl/DebugOptions.cpp +++ b/DPLFusionFix/dpl/DebugOptions.cpp @@ -1,5 +1,7 @@ #include "DebugOptions.h" +using namespace Memory::VP; + bool bDebug_ShowVersion = false; bool bDebug_ShowFPS = false; bool bDebug_CompleteMission = false; @@ -22,11 +24,11 @@ void Update_Debug_DisableLoadingScreen() { if (bDebug_DisableLoadingScreen) { - WriteAt(0x4a76ef, "\xC2\x04\x00", 3); + Patch(0x4a76ef, {0xC2, 0x04, 0x00}); } else { - WriteAt(0x4a76ef, "\x56\x8B\xF1", 3); + Patch(0x4a76ef, {0x56, 0x8B, 0xF1}); } } @@ -39,28 +41,28 @@ void Update_Debug_InvincibleToWater() } else { - WriteAt(0x4A268D, "\x0F\x84\x12\x01\x00\x00", 6); + Patch(0x4A268D, {0x0F, 0x84, 0x12, 0x01, 0x00, 0x00}); } } void Set_Debug_Cop2006InitWep(char newOne) { - WriteAt(0x430046 + 0x1, &newOne, 1); + Patch(0x430046 + 0x1, newOne); } void Set_Debug_Cop1978InitWep(char newOne) { - WriteAt(0x43004a + 0x1, &newOne, 1); + Patch(0x43004a + 0x1, newOne); } void Update_Debug_NoCollisions() { if (bDebug_NoCollisions) { - WriteAt(0x5ccd9d, "\xc3", 1); + Patch(0x5ccd9d, 0xc3); } else { - WriteAt(0x5ccd9d, "\x55", 1); + Patch(0x5ccd9d, 0x55); } -} \ No newline at end of file +} diff --git a/DPLFusionFix/dpl/DebugOptions.h b/DPLFusionFix/dpl/DebugOptions.h index fa786d8..6e67368 100644 --- a/DPLFusionFix/dpl/DebugOptions.h +++ b/DPLFusionFix/dpl/DebugOptions.h @@ -1,5 +1,5 @@ #pragma once -#include "..\utils.h" +#include "../utils/MemoryMgr.h" extern bool bDebug_ShowVersion; extern bool bDebug_ShowFPS; diff --git a/DPLFusionFix/utils.cpp b/DPLFusionFix/utils.cpp deleted file mode 100644 index 5832a47..0000000 --- a/DPLFusionFix/utils.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "utils.h" - -void WriteAt(unsigned int address, const char* buffer, size_t size) -{ - DWORD dwProtect; - VirtualProtect((void*)address, size, PAGE_EXECUTE_READWRITE, &dwProtect); - memcpy((void*)address, buffer, size); - VirtualProtect((void*)address, size, dwProtect, &dwProtect); -} - -void WriteAt(unsigned int address, int integer) -{ - DWORD dwProtect; - VirtualProtect((void*)address, sizeof(int), PAGE_EXECUTE_READWRITE, &dwProtect); - memcpy((void*)address, (void*)integer, sizeof(int)); - VirtualProtect((void*)address, sizeof(int), dwProtect, &dwProtect); -} - -void WritePointerAt(unsigned int address, intptr_t ptr) -{ - DWORD dwProtect; - VirtualProtect((void*)address, sizeof(ptr), PAGE_EXECUTE_READWRITE, &dwProtect); - memcpy((void*)address, &ptr, sizeof(ptr)); - VirtualProtect((void*)address, sizeof(ptr), dwProtect, &dwProtect); -} \ No newline at end of file diff --git a/DPLFusionFix/utils.h b/DPLFusionFix/utils.h deleted file mode 100644 index 1591410..0000000 --- a/DPLFusionFix/utils.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "utils/MemoryMgr.h" - -using namespace Memory::VP; - -void WriteAt(unsigned int address, const char* buffer, size_t size); -void WriteAt(unsigned int address, int integer); - -void WritePointerAt(unsigned int address, intptr_t ptr); \ No newline at end of file