From 9304b6a060e821b6fcb2d50a7bf07823b1749865 Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 25 Mar 2017 13:46:07 +0100 Subject: [PATCH] Double rear wheels whitelist --- SilentPatchSA/ModelInfoSA.cpp | 1 + SilentPatchSA/ModelInfoSA.h | 1 + SilentPatchSA/SilentPatchSA.cpp | 61 +++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/SilentPatchSA/ModelInfoSA.cpp b/SilentPatchSA/ModelInfoSA.cpp index a13a3c3..b41e934 100644 --- a/SilentPatchSA/ModelInfoSA.cpp +++ b/SilentPatchSA/ModelInfoSA.cpp @@ -10,6 +10,7 @@ signed char (*CCustomCarPlateMgr::GetMapRegionPlateDesign)() = AddressByVersion< void (*CCustomCarPlateMgr::SetupMaterialPlatebackTexture)(RpMaterial* pMaterial, signed char nDesign) = AddressByVersion(0x6FDE50, 0x6FE680, 0x736A80); CBaseModelInfo** const ms_modelInfoPtrs = *AddressByVersion(0x509CB1, 0x4C0C96, 0x403DB7); +const uint32_t m_numModelInfoPtrs = *AddressByVersion(0x4C5956+2, 0, 0); void CVehicleModelInfo::Shutdown() { diff --git a/SilentPatchSA/ModelInfoSA.h b/SilentPatchSA/ModelInfoSA.h index ed52c5c..cfa13a6 100644 --- a/SilentPatchSA/ModelInfoSA.h +++ b/SilentPatchSA/ModelInfoSA.h @@ -298,6 +298,7 @@ public: }; extern CBaseModelInfo** const ms_modelInfoPtrs; +extern const uint32_t m_numModelInfoPtrs; #define NUM_MAX_PLATES 12 diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 735f75f..20771e0 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -18,6 +18,7 @@ #include "FLACDecoderSA.h" #include "Patterns.h" +#include "DelimStringReader.h" // RW wrappers static void* varAtomicDefaultRenderCallBack = AddressByVersion(0x7491C0, 0x749AD0, 0x783180); @@ -1030,6 +1031,55 @@ void DrawScriptSpritesAndRectangles( uint8_t arg ) orgDrawScriptSpritesAndRectangles( arg ); } +std::vector< std::pair > doubleRearWheelsList; +void ReadDoubleRearWheels(const wchar_t* pPath) +{ + const size_t SCRATCH_PAD_SIZE = 32767; + WideDelimStringReader reader( SCRATCH_PAD_SIZE ); + + GetPrivateProfileSectionW( L"DoubleRearWheels", reader.GetBuffer(), reader.GetSize(), pPath ); + while ( const wchar_t* str = reader.GetString() ) + { + wchar_t textLine[32]; + wchar_t* context = nullptr; + wchar_t* token; + + wcscpy_s( textLine, str ); + token = wcstok_s( textLine, L"=", &context ); + + int toList = _wtoi( token ); + if ( toList != 0 ) + { + bool value = _wtoi( wcstok_s( nullptr, L"=", &context ) ) != 0; + doubleRearWheelsList.emplace_back( toList, value ); + } + } +} + +bool __stdcall CheckDoubleRWheelsList( void* modelInfo, uint8_t* handlingData ) +{ + static void* lastModelInfo = nullptr; + static bool lastResult = false; + + if ( modelInfo == lastModelInfo ) return lastResult; + lastModelInfo = modelInfo; + + ptrdiff_t modelID = std::distance( ms_modelInfoPtrs, std::find( ms_modelInfoPtrs, ms_modelInfoPtrs+m_numModelInfoPtrs, modelInfo ) ); + + auto it = std::find_if( doubleRearWheelsList.begin(), doubleRearWheelsList.end(), [modelID]( const auto& item ) { + return item.first == modelID; + } ); + if ( it == doubleRearWheelsList.end() ) + { + uint32_t flags = *(uint32_t*)(handlingData+0xCC); + lastResult = (flags & 0x20000000) != 0; + return lastResult; + } + + lastResult = it->second; + return lastResult; +} + #include @@ -2060,6 +2110,7 @@ BOOL InjectDelayedPatches_10() bool bSARender = GetModuleHandle("SARender.asi") != nullptr; ReadRotorFixExceptions(wcModulePath); + ReadDoubleRearWheels(wcModulePath); if ( GetPrivateProfileIntW(L"SilentPatch", L"SunSizeHack", FALSE, wcModulePath) != FALSE ) { @@ -3150,6 +3201,16 @@ void Patch_SA_10() ReadCall( 0x58C092, orgDrawScriptSpritesAndRectangles ); InjectHook( 0x58C092, DrawScriptSpritesAndRectangles ); + + // Double rwheels whitelist + // push ecx + // push edi + // call CheckDoubleRWheelsWhitelist + // test al, al + Patch( 0x4C9239, 0x5751 ); + InjectHook( 0x4C9239+2, CheckDoubleRWheelsList, PATCH_CALL ); + Patch( 0x4C9239+7, 0xC084 ); + Nop( 0x4C9239+9, 1 ); } void Patch_SA_11()