III/VC: Improve the way RwD3D8Get/SetRenderState is located

Improves compatibility with other mods and provides a safe fallback.

Fixes #65
This commit is contained in:
Silent 2024-11-01 17:33:33 +01:00
parent 2f79eb1c8f
commit 75a3f16ffb
No known key found for this signature in database
GPG key ID: AE53149BB0C45AF1
7 changed files with 59 additions and 6 deletions

View file

@ -7,6 +7,7 @@
#include "SVF.h" #include "SVF.h"
#include "ParseUtils.hpp" #include "ParseUtils.hpp"
#include "Random.h" #include "Random.h"
#include "RWGTA.h"
#include "Utils/DelimStringReader.h" #include "Utils/DelimStringReader.h"
@ -195,6 +196,8 @@ namespace Common {
using namespace Memory; using namespace Memory;
using namespace hook::txn; using namespace hook::txn;
const bool HasRwD3D8 = RWGTA::Patches::TryLocateRwD3D8();
// Delayed patching // Delayed patching
try try
{ {
@ -249,7 +252,7 @@ namespace Common {
// Fixed static shadows not rendering under fire and pickups // Fixed static shadows not rendering under fire and pickups
try if (HasRwD3D8) try
{ {
using namespace StaticShadowAlphaFix; using namespace StaticShadowAlphaFix;

View file

@ -4,6 +4,7 @@
#define RwEngineInstance (*rwengine) #define RwEngineInstance (*rwengine)
#include <rwcore.h> #include <rwcore.h>
#include "RWGTA.h"
// GTA versions of RenderWare functions/macros for GTA III/Vice City // GTA versions of RenderWare functions/macros for GTA III/Vice City
// since we cannot use RwEngineInstance directly // since we cannot use RwEngineInstance directly
@ -39,14 +40,16 @@ void** rwengine = []() -> void** {
return nullptr; return nullptr;
}(); }();
static void* varRwD3D8SetRenderState = Memory::ReadCallFrom( hook::get_pattern( "0F 8C ? ? ? ? 6A 05 6A 19", 10 ) ); static decltype(::RwD3D8SetRenderState)* fnRwD3D8SetRenderState;
WRAPPER RwBool RwD3D8SetRenderState(RwUInt32 state, RwUInt32 value) { VARJMP(varRwD3D8SetRenderState); } RwBool RwD3D8SetRenderState(RwUInt32 state, RwUInt32 value)
{
return fnRwD3D8SetRenderState(state, value);
}
static RwUInt32* _rwD3D8RenderStates = *static_cast<RwUInt32**>(Memory::ReadCallFrom( hook::get_pattern( "0F 8C ? ? ? ? 6A 05 6A 19", 10 ), 8 + 3 )); static decltype(::RwD3D8GetRenderState)* fnRwD3D8GetRenderState;
void RwD3D8GetRenderState(RwUInt32 state, void* value) void RwD3D8GetRenderState(RwUInt32 state, void* value)
{ {
RwUInt32* valuePtr = static_cast<RwUInt32*>(value); fnRwD3D8GetRenderState(state, value);
*valuePtr = _rwD3D8RenderStates[ 2 * state ];
} }
RwReal RwIm2DGetNearScreenZ() RwReal RwIm2DGetNearScreenZ()
@ -66,3 +69,36 @@ RwBool RwRenderStateSet(RwRenderState state, void *value)
// Unreachable stub // Unreachable stub
RwBool RwMatrixDestroy(RwMatrix* mpMat) { assert(!"Unreachable!"); return TRUE; } 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<decltype(RwD3D8SetRenderState)*>(get_pattern("39 0C C5 ? ? ? ? 74 31", -8));
} catch (const hook::txn_exception&) {
// III Steam
return static_cast<decltype(RwD3D8SetRenderState)*>(get_pattern("8B 0C C5 ? ? ? ? 3B CA", -8));
}
}();
auto fnRwD3D8GetRenderState = [] {
try {
// Everything except for III Steam
return static_cast<decltype(RwD3D8GetRenderState)*>(get_pattern("8B 0C C5 ? ? ? ? 89 0A C3", -8));
} catch (const hook::txn_exception&) {
// III Steam
return static_cast<decltype(RwD3D8GetRenderState)*>(get_pattern("8B 04 C5 ? ? ? ? 89 02 C3", -8));
}
}();
::fnRwD3D8SetRenderState = fnRwD3D8SetRenderState;
::fnRwD3D8GetRenderState = fnRwD3D8GetRenderState;
return true;
}
catch (const hook::txn_exception&)
{
return false;
}

6
SilentPatch/RWGTA.h Normal file
View file

@ -0,0 +1,6 @@
#pragma once
namespace RWGTA::Patches
{
bool TryLocateRwD3D8();
}

View file

@ -73,6 +73,7 @@
<ClInclude Include="..\SilentPatch\Maths.h" /> <ClInclude Include="..\SilentPatch\Maths.h" />
<ClInclude Include="..\SilentPatch\ParseUtils.hpp" /> <ClInclude Include="..\SilentPatch\ParseUtils.hpp" />
<ClInclude Include="..\SilentPatch\Random.h" /> <ClInclude Include="..\SilentPatch\Random.h" />
<ClInclude Include="..\SilentPatch\RWGTA.h" />
<ClInclude Include="..\SilentPatch\StdAfx.h" /> <ClInclude Include="..\SilentPatch\StdAfx.h" />
<ClInclude Include="..\SilentPatch\StoredCar.h" /> <ClInclude Include="..\SilentPatch\StoredCar.h" />
<ClInclude Include="..\SilentPatch\SVF.h" /> <ClInclude Include="..\SilentPatch\SVF.h" />

View file

@ -113,6 +113,9 @@
<ClInclude Include="..\SilentPatch\Random.h"> <ClInclude Include="..\SilentPatch\Random.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\SilentPatch\RWGTA.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc"> <ResourceCompile Include="..\SilentPatch\SilentPatch.rc">

View file

@ -166,6 +166,7 @@
<ClInclude Include="..\SilentPatch\Maths.h" /> <ClInclude Include="..\SilentPatch\Maths.h" />
<ClInclude Include="..\SilentPatch\ParseUtils.hpp" /> <ClInclude Include="..\SilentPatch\ParseUtils.hpp" />
<ClInclude Include="..\SilentPatch\Random.h" /> <ClInclude Include="..\SilentPatch\Random.h" />
<ClInclude Include="..\SilentPatch\RWGTA.h" />
<ClInclude Include="..\SilentPatch\RWUtils.hpp" /> <ClInclude Include="..\SilentPatch\RWUtils.hpp" />
<ClInclude Include="..\SilentPatch\StdAfx.h" /> <ClInclude Include="..\SilentPatch\StdAfx.h" />
<ClInclude Include="..\SilentPatch\StoredCar.h" /> <ClInclude Include="..\SilentPatch\StoredCar.h" />

View file

@ -75,6 +75,9 @@
<ClInclude Include="EntityVC.h"> <ClInclude Include="EntityVC.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\SilentPatch\RWGTA.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\SilentPatch\Timer.cpp"> <ClCompile Include="..\SilentPatch\Timer.cpp">