Updated some RW calls and the shadow alpha test fix

Fixes an incompatibility with the light boxes,
previously overlooked because the widescreen fix disabled them

Fixes #12
This commit is contained in:
Silent 2024-04-18 20:57:47 +02:00
parent f6ba6be75a
commit bbd9164de3
No known key found for this signature in database
GPG key ID: AE53149BB0C45AF1
3 changed files with 37 additions and 49 deletions

View file

@ -31,6 +31,7 @@ namespace HandlingNameLoadFix
// ============= Corona lines rendering fix =============
namespace CoronaLinesFix
{
static decltype(RwIm2DRenderLine)* orgRwIm2DRenderLine;
static RwBool RenderLine_SetRecipZ( RwIm2DVertex *vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2 )
{
const RwReal nearScreenZ = RwIm2DGetNearScreenZ();
@ -44,31 +45,45 @@ namespace CoronaLinesFix
RwIm2DVertexSetRecipCameraZ( &vertices[i], recipZ );
}
return RwIm2DRenderLine( vertices, numVertices, vert1, vert2 );
return orgRwIm2DRenderLine( vertices, numVertices, vert1, vert2 );
}
}
// ============= Static shadow alpha fix =============
namespace StaticShadowAlphaFix
{
static RwUInt32 alphaTestVal;
static constexpr RwUInt32 D3DRS_ALPHAFUNC = 25;
static constexpr RwUInt32 D3DCMP_ALWAYS = 8;
static RwBool RenderStateSet_StoreAlphaTest( RwRenderState state, void* value )
static RwUInt32 alphaFuncVal;
template<std::size_t Index>
static RwBool (*orgRenderStateSet_StoreAlphaTest)(RwRenderState state, void* value);
template<std::size_t Index>
static RwBool RenderStateSet_StoreAlphaTest(RwRenderState state, void* value)
{
RwD3D8GetRenderState( 15, &alphaTestVal ); // D3DRS_ALPHATESTENABLE
RwD3D8SetRenderState( 15, FALSE );
RwD3D8GetRenderState(D3DRS_ALPHAFUNC, &alphaFuncVal);
RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
return RwRenderStateSet( state, value );
return orgRenderStateSet_StoreAlphaTest<Index>(state, value);
}
static RwBool RenderStateSet_RestoreAlphaTest( RwRenderState state, void* value )
{
RwBool result = RwRenderStateSet( state, value );
template<std::size_t Index>
static RwBool (*orgRenderStateSet_RestoreAlphaTest)(RwRenderState state, void* value);
RwD3D8SetRenderState( 15, alphaTestVal );
template<std::size_t Index>
static RwBool RenderStateSet_RestoreAlphaTest(RwRenderState state, void* value)
{
RwBool result = orgRenderStateSet_RestoreAlphaTest<Index>(state, value);
RwD3D8SetRenderState(D3DRS_ALPHAFUNC, alphaFuncVal);
return result;
}
HOOK_EACH_FUNC(StoreAlphaTest, orgRenderStateSet_StoreAlphaTest, RenderStateSet_StoreAlphaTest);
HOOK_EACH_FUNC(RestoreAlphaTest, orgRenderStateSet_RestoreAlphaTest, RenderStateSet_RestoreAlphaTest);
};
// ============= Corrected corona placement for taxi =============
@ -233,7 +248,7 @@ namespace Common {
auto renderLine = get_pattern( "E8 ? ? ? ? 83 C4 10 FF 44 24 1C 43" );
InjectHook( renderLine, RenderLine_SetRecipZ );
InterceptCall(renderLine, orgRwIm2DRenderLine, RenderLine_SetRecipZ);
}
@ -242,36 +257,29 @@ namespace Common {
using namespace StaticShadowAlphaFix;
#if _GTA_III
void* disableAlphaTestAndSetState[] = {
std::array<void*, 2> disableAlphaTestAndSetState = {
get_pattern( "E8 ? ? ? ? 59 59 6A 00 6A 0E E8 ? ? ? ? 31 C0" ),
get_pattern( "E8 ? ? ? ? 0F B7 2D ? ? ? ? 31 C0" )
};
void* setStateAndReenableAlphaTest[] = {
std::array<void*, 2> setStateAndReenableAlphaTest = {
get_pattern( "E8 ? ? ? ? 59 59 6A 01 6A 08 E8 ? ? ? ? 59 59 83 C4 38" ),
get_pattern( "39 44 24 38 0F 8C ? ? ? ? 6A 00 6A 0C", 14 )
};
#elif _GTA_VC
void* disableAlphaTestAndSetState[] = {
std::array<void*, 2> disableAlphaTestAndSetState = {
get_pattern( "E8 ? ? ? ? 59 59 6A 00 6A 0E E8 ? ? ? ? 31 C0" ),
get_pattern( "6A 01 6A 0C E8 ? ? ? ? 59 59 6A 03", 4 )
};
void* setStateAndReenableAlphaTest[] = {
std::array<void*, 2> setStateAndReenableAlphaTest = {
get_pattern( "0F 77 6A 00 6A 0C E8 ? ? ? ? 59", 6 ),
get_pattern( "39 44 24 34 0F 8C ? ? ? ? 6A 00 6A 0C", 14 )
};
#endif
for ( auto match : disableAlphaTestAndSetState )
{
InjectHook( match, RenderStateSet_StoreAlphaTest );
}
for ( auto match : setStateAndReenableAlphaTest )
{
InjectHook( match, RenderStateSet_RestoreAlphaTest );
}
HookEach_StoreAlphaTest(disableAlphaTestAndSetState, InterceptCall);
HookEach_RestoreAlphaTest(setStateAndReenableAlphaTest, InterceptCall);
}

View file

@ -3,6 +3,8 @@
#include "Utils/MemoryMgr.h"
#include "Utils/Patterns.h"
#define RwEngineInstance (*rwengine)
#include <rwcore.h>
// GTA versions of RenderWare functions/macros for GTA III/Vice City
@ -11,7 +13,7 @@
// Anything originally using RwEngineInstance shall be redefined here
// Functions which RW 3.6 inlined can also easily be defined here
void** GTARwEngineInstance = []() -> void** {
void** rwengine = []() -> void** {
// Thanks Steam III...
// Locate RwRenderStateSet
@ -45,21 +47,10 @@ void RwD3D8GetRenderState(RwUInt32 state, void* value)
*valuePtr = _rwD3D8RenderStates[ 2 * state ];
}
RwBool RwRenderStateSet(RwRenderState state, void *value)
{
return GTARWSRCGLOBAL(dOpenDevice).fpRenderStateSet( state, value );
}
RwBool RwIm2DRenderLine(RwIm2DVertex *vertices, RwInt32 numVertices, RwInt32 vert1, RwInt32 vert2)
{
return GTARWSRCGLOBAL(dOpenDevice).fpIm2DRenderLine( vertices, numVertices, vert1, vert2 );
}
RwReal RwIm2DGetNearScreenZ()
{
return GTARWSRCGLOBAL(dOpenDevice).zBufferNear;
return RWSRCGLOBAL(dOpenDevice).zBufferNear;
}
// Unreachable stub
RwBool RwMatrixDestroy(RwMatrix* mpMat) { assert(!"Unreachable!"); return TRUE; }
RwBool RwMatrixDestroy(RwMatrix* mpMat) { assert(!"Unreachable!"); return TRUE; }

View file

@ -1,12 +1 @@
#pragma once
// GTA versions of RenderWare functions/macros for GTA III/Vice City
// since we cannot use RwEngineInstance directly
// Anything originally using RwEngineInstance shall be redefined here
extern void** GTARwEngineInstance;
/* macro used to access global data structure (the root type is RwGlobals) */
#define GTARWSRCGLOBAL(variable) \
(((RwGlobals *)(*GTARwEngineInstance))->variable)