From 75a3f16ffbf88debe5a147cdc9ae459ba6114c5b Mon Sep 17 00:00:00 2001 From: Silent Date: Fri, 1 Nov 2024 17:33:33 +0100 Subject: [PATCH] III/VC: Improve the way RwD3D8Get/SetRenderState is located Improves compatibility with other mods and provides a safe fallback. Fixes #65 --- SilentPatch/Common.cpp | 5 +- SilentPatch/RWGTA.cpp | 46 +++++++++++++++++-- SilentPatch/RWGTA.h | 6 +++ SilentPatchIII/SilentPatchIII.vcxproj | 1 + SilentPatchIII/SilentPatchIII.vcxproj.filters | 3 ++ SilentPatchVC/SilentPatchVC.vcxproj | 1 + SilentPatchVC/SilentPatchVC.vcxproj.filters | 3 ++ 7 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 SilentPatch/RWGTA.h diff --git a/SilentPatch/Common.cpp b/SilentPatch/Common.cpp index 8baeaa5..e64f88b 100644 --- a/SilentPatch/Common.cpp +++ b/SilentPatch/Common.cpp @@ -7,6 +7,7 @@ #include "SVF.h" #include "ParseUtils.hpp" #include "Random.h" +#include "RWGTA.h" #include "Utils/DelimStringReader.h" @@ -195,6 +196,8 @@ namespace Common { using namespace Memory; using namespace hook::txn; + const bool HasRwD3D8 = RWGTA::Patches::TryLocateRwD3D8(); + // Delayed patching try { @@ -249,7 +252,7 @@ namespace Common { // Fixed static shadows not rendering under fire and pickups - try + if (HasRwD3D8) try { using namespace StaticShadowAlphaFix; diff --git a/SilentPatch/RWGTA.cpp b/SilentPatch/RWGTA.cpp index 21e35de..71f2fea 100644 --- a/SilentPatch/RWGTA.cpp +++ b/SilentPatch/RWGTA.cpp @@ -4,6 +4,7 @@ #define RwEngineInstance (*rwengine) #include +#include "RWGTA.h" // GTA versions of RenderWare functions/macros for GTA III/Vice City // since we cannot use RwEngineInstance directly @@ -39,14 +40,16 @@ void** rwengine = []() -> void** { return nullptr; }(); -static void* varRwD3D8SetRenderState = Memory::ReadCallFrom( hook::get_pattern( "0F 8C ? ? ? ? 6A 05 6A 19", 10 ) ); -WRAPPER RwBool RwD3D8SetRenderState(RwUInt32 state, RwUInt32 value) { VARJMP(varRwD3D8SetRenderState); } +static decltype(::RwD3D8SetRenderState)* fnRwD3D8SetRenderState; +RwBool RwD3D8SetRenderState(RwUInt32 state, RwUInt32 value) +{ + return fnRwD3D8SetRenderState(state, value); +} -static RwUInt32* _rwD3D8RenderStates = *static_cast(Memory::ReadCallFrom( hook::get_pattern( "0F 8C ? ? ? ? 6A 05 6A 19", 10 ), 8 + 3 )); +static decltype(::RwD3D8GetRenderState)* fnRwD3D8GetRenderState; void RwD3D8GetRenderState(RwUInt32 state, void* value) { - RwUInt32* valuePtr = static_cast(value); - *valuePtr = _rwD3D8RenderStates[ 2 * state ]; + fnRwD3D8GetRenderState(state, value); } RwReal RwIm2DGetNearScreenZ() @@ -66,3 +69,36 @@ RwBool RwRenderStateSet(RwRenderState state, void *value) // Unreachable stub RwBool RwMatrixDestroy(RwMatrix* mpMat) { assert(!"Unreachable!"); return TRUE; } + +bool RWGTA::Patches::TryLocateRwD3D8() try +{ + using namespace Memory; + using namespace hook::txn; + + auto fnRwD3D8SetRenderState = [] { + try { + // Everything except for III Steam + return static_cast(get_pattern("39 0C C5 ? ? ? ? 74 31", -8)); + } catch (const hook::txn_exception&) { + // III Steam + return static_cast(get_pattern("8B 0C C5 ? ? ? ? 3B CA", -8)); + } + }(); + auto fnRwD3D8GetRenderState = [] { + try { + // Everything except for III Steam + return static_cast(get_pattern("8B 0C C5 ? ? ? ? 89 0A C3", -8)); + } catch (const hook::txn_exception&) { + // III Steam + return static_cast(get_pattern("8B 04 C5 ? ? ? ? 89 02 C3", -8)); + } + }(); + + ::fnRwD3D8SetRenderState = fnRwD3D8SetRenderState; + ::fnRwD3D8GetRenderState = fnRwD3D8GetRenderState; + return true; +} +catch (const hook::txn_exception&) +{ + return false; +} \ No newline at end of file diff --git a/SilentPatch/RWGTA.h b/SilentPatch/RWGTA.h new file mode 100644 index 0000000..e184dc9 --- /dev/null +++ b/SilentPatch/RWGTA.h @@ -0,0 +1,6 @@ +#pragma once + +namespace RWGTA::Patches +{ + bool TryLocateRwD3D8(); +} diff --git a/SilentPatchIII/SilentPatchIII.vcxproj b/SilentPatchIII/SilentPatchIII.vcxproj index 1dfde18..4f2b048 100644 --- a/SilentPatchIII/SilentPatchIII.vcxproj +++ b/SilentPatchIII/SilentPatchIII.vcxproj @@ -73,6 +73,7 @@ + diff --git a/SilentPatchIII/SilentPatchIII.vcxproj.filters b/SilentPatchIII/SilentPatchIII.vcxproj.filters index c630dbd..17a2005 100644 --- a/SilentPatchIII/SilentPatchIII.vcxproj.filters +++ b/SilentPatchIII/SilentPatchIII.vcxproj.filters @@ -113,6 +113,9 @@ Header Files + + Header Files + diff --git a/SilentPatchVC/SilentPatchVC.vcxproj b/SilentPatchVC/SilentPatchVC.vcxproj index f996dff..660d626 100644 --- a/SilentPatchVC/SilentPatchVC.vcxproj +++ b/SilentPatchVC/SilentPatchVC.vcxproj @@ -166,6 +166,7 @@ + diff --git a/SilentPatchVC/SilentPatchVC.vcxproj.filters b/SilentPatchVC/SilentPatchVC.vcxproj.filters index fe68fbd..84c775f 100644 --- a/SilentPatchVC/SilentPatchVC.vcxproj.filters +++ b/SilentPatchVC/SilentPatchVC.vcxproj.filters @@ -75,6 +75,9 @@ Header Files + + Header Files +