refactored to use templated predicates for RW callbacks

This commit is contained in:
Silent 2017-03-27 21:17:43 +02:00
parent d1db161070
commit a5c0dd54eb
13 changed files with 232 additions and 283 deletions

View file

@ -31,10 +31,8 @@ static void ResetEditableMaterials(std::pair<void*,int>* pData)
*static_cast<int*>(i->first) = i->second;
}
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic, void* pData)
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic)
{
UNREFERENCED_PARAMETER(pData);
if ( RpAtomicGetFlags(pAtomic) & rpATOMICRENDER )
{
RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic);
@ -106,7 +104,7 @@ RwCamera* CShadowCamera::Update(CEntity* pEntity)
if ( pEntity->nType == 3 )
static_cast<CPed*>(pEntity)->RenderForShadow();
else
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pEntity->m_pRwObject), ShadowCameraRenderCB, nullptr);
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pEntity->m_pRwObject), ShadowCameraRenderCB);
}
InvertRaster();

View file

@ -32,17 +32,17 @@ public:
friend constexpr CRGBA Blend(const CRGBA& From, const CRGBA& To, double BlendVal)
{ double InvBlendVal = 1.0 - BlendVal;
return CRGBA( To.r * BlendVal + From.r * InvBlendVal,
To.g * BlendVal + From.g * InvBlendVal,
To.b * BlendVal + From.b * InvBlendVal,
To.a * BlendVal + From.a * InvBlendVal); }
return CRGBA( uint8_t(To.r * BlendVal + From.r * InvBlendVal),
uint8_t(To.g * BlendVal + From.g * InvBlendVal),
uint8_t(To.b * BlendVal + From.b * InvBlendVal),
uint8_t(To.a * BlendVal + From.a * InvBlendVal)); }
friend constexpr CRGBA BlendSqr(const CRGBA& From, const CRGBA& To, double BlendVal)
{ double InvBlendVal = 1.0 - BlendVal;
return CRGBA( sqrt((To.r * To.r) * BlendVal + (From.r * From.r) * InvBlendVal),
sqrt((To.g * To.g) * BlendVal + (From.g * From.g) * InvBlendVal),
sqrt((To.b * To.b) * BlendVal + (From.b * From.b) * InvBlendVal),
sqrt((To.a * To.a) * BlendVal + (From.a * From.a) * InvBlendVal)); }
return CRGBA( uint8_t(sqrt((To.r * To.r) * BlendVal + (From.r * From.r) * InvBlendVal)),
uint8_t(sqrt((To.g * To.g) * BlendVal + (From.g * From.g) * InvBlendVal)),
uint8_t(sqrt((To.b * To.b) * BlendVal + (From.b * From.b) * InvBlendVal)),
uint8_t(sqrt((To.a * To.a) * BlendVal + (From.a * From.a) * InvBlendVal))); }
// SilentPatch
CRGBA* BlendGangColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
@ -587,7 +587,7 @@ public:
};
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic, void* pData);
RpAtomic* ShadowCameraRenderCB(RpAtomic* pAtomic);
static_assert(sizeof(CEntity) == 0x38, "Wrong size: CEntity");
static_assert(sizeof(CPhysical) == 0x138, "Wrong size: CPhysical");

View file

@ -17,18 +17,37 @@ void CVehicleModelInfo::Shutdown()
CBaseModelInfo::Shutdown();
delete m_apPlateMaterials;
m_apPlateMaterials = nullptr;
}
void CVehicleModelInfo::FindEditableMaterialList()
{
std::pair<CVehicleModelInfo*,int> MatsPair = std::make_pair(this, 0);
int materialCount = 0;
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pRwObject), GetEditableMaterialListCB, &MatsPair);
auto GetEditableMaterialListCB = [&]( RpAtomic* atomic ) -> RpAtomic* {
RpGeometryForAllMaterials( RpAtomicGetGeometry(atomic), [&]( RpMaterial* material ) -> RpMaterial* {
if ( RwTexture* texture = RpMaterialGetTexture(material) )
{
if ( const char* texName = RwTextureGetName(texture) )
{
if ( _strnicmp(texName, "vehiclegrunge256", 16) == 0 )
{
if ( materialCount < _countof(m_apDirtMaterials) )
m_apDirtMaterials[materialCount++] = material;
}
}
}
return material;
} );
return atomic;
};
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(pRwObject), GetEditableMaterialListCB);
if ( m_pVehicleStruct->m_nNumExtras > 0 )
{
for ( int i = 0; i < m_pVehicleStruct->m_nNumExtras; i++ )
GetEditableMaterialListCB(m_pVehicleStruct->m_apExtras[i], &MatsPair);
GetEditableMaterialListCB(m_pVehicleStruct->m_apExtras[i]);
}
m_nPrimaryColor = -1;
@ -42,150 +61,61 @@ void CVehicleModelInfo::SetCarCustomPlate()
m_plateText[0] = '\0';
m_nPlateType = -1;
m_apPlateMaterials = reinterpret_cast<RpMaterial**>(new DWORD_PTR[2*NUM_MAX_PLATES]);
m_apPlateMaterials = new RpMaterial* [2*CCustomCarPlateMgr::NUM_MAX_PLATES];
for ( int i = 0; i < 2*NUM_MAX_PLATES; i++ )
for ( int i = 0; i < 2*CCustomCarPlateMgr::NUM_MAX_PLATES; i++ )
m_apPlateMaterials[i] = nullptr;
CCustomCarPlateMgr::SetupClump(reinterpret_cast<RpClump*>(pRwObject), m_apPlateMaterials);
}
RpAtomic* CVehicleModelInfo::GetEditableMaterialListCB(RpAtomic* pAtomic, void* pData)
void CCustomCarPlateMgr::PollPlates( RpClump* clump, RpMaterial** materials )
{
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), GetEditableMaterialListCB, pData);
return pAtomic;
}
RpMaterial** carplates = materials;
RpMaterial** carpbacks = materials+NUM_MAX_PLATES;
RpMaterial* CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial* pMaterial, void* pData)
{
if ( RpMaterialGetTexture(pMaterial) )
{
if ( !strncmp(RwTextureGetName(RpMaterialGetTexture(pMaterial)), "vehiclegrunge256", 16) )
{
std::pair<CVehicleModelInfo*,int>* pMats = static_cast<std::pair<CVehicleModelInfo*,int>*>(pData);
int numCarplates = 0, numCarpbacks = 0;
if ( pMats->second < 32 )
pMats->first->m_apDirtMaterials[pMats->second++] = pMaterial;
}
}
return pMaterial;
}
// TODO: FIX IT
typedef std::tuple<RpMaterial**, RpMaterial**, int, int> PlateDataTuple;
static RpMaterial* PollPlateData(RpMaterial* pMaterial, void* pData)
{
if ( RwTexture* pTexture = RpMaterialGetTexture(pMaterial) )
{
const char* pTexName = RwTextureGetName(pTexture);
if ( pTexName )
{
if ( !_strnicmp(pTexName, "carplate", 8) )
RpClumpForAllAtomics( clump, [carplates, carpbacks, &numCarplates, &numCarpbacks] ( RpAtomic* atomic ) -> RpAtomic* {
RpGeometryForAllMaterials( RpAtomicGetGeometry(atomic), [&] ( RpMaterial* material ) -> RpMaterial* {
if ( RwTexture* texture = RpMaterialGetTexture(material) )
{
auto& pCallbackData = *static_cast<PlateDataTuple*>(pData);
assert(std::get<2>(pCallbackData) < NUM_MAX_PLATES);
if ( std::get<2>(pCallbackData) < NUM_MAX_PLATES )
if ( const char* texName = RwTextureGetName(texture) )
{
// Append data
for ( auto ptr = std::get<0>(pCallbackData); *ptr; ptr++ )
if ( _strnicmp( texName, "carplate", 8 ) == 0 )
{
if ( *ptr == pMaterial )
return pMaterial;
assert(numCarplates < NUM_MAX_PLATES);
if ( numCarplates < NUM_MAX_PLATES );
{
carplates[numCarplates++] = material;
}
}
else if ( _strnicmp( texName, "carpback", 8 ) == 0 )
{
assert(numCarpbacks < NUM_MAX_PLATES);
if ( numCarpbacks < NUM_MAX_PLATES );
{
carpbacks[numCarpbacks++] = material;
}
}
while ( std::get<0>(pCallbackData)[std::get<2>(pCallbackData)] )
std::get<2>(pCallbackData)++;
std::get<0>(pCallbackData)[std::get<2>(pCallbackData)++] = pMaterial;
}
}
else if ( !_strnicmp(pTexName, "carpback", 8) )
{
auto& pCallbackData = *static_cast<PlateDataTuple*>(pData);
assert(std::get<3>(pCallbackData) < NUM_MAX_PLATES);
if ( std::get<3>(pCallbackData) < NUM_MAX_PLATES )
{
// Append data
for ( auto ptr = std::get<0>(pCallbackData); *ptr; ptr++ )
{
if ( *ptr == pMaterial )
return pMaterial;
}
while ( std::get<1>(pCallbackData)[std::get<3>(pCallbackData)] )
std::get<3>(pCallbackData)++;
std::get<1>(pCallbackData)[std::get<3>(pCallbackData)] = pMaterial;
}
}
}
}
return pMaterial;
}
static RpAtomic* PollPlateData(RpAtomic* pAtomic, void* pData)
{
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), PollPlateData, pData);
return pAtomic;
}
static RpMaterial* SetPlateData(RpMaterial* pMaterial, void* pData)
{
if ( RwTexture* pTexture = RpMaterialGetTexture(pMaterial) )
{
if ( RwTextureGetName(pTexture) )
{
if ( !_strnicmp(RwTextureGetName(pTexture), "carplate", 8) )
{
auto& pCallbackData = *static_cast<std::pair<RwTexture*,signed char>*>(pData);
RpMaterialSetTexture(pMaterial, pCallbackData.first);
}
else if ( !_strnicmp(RwTextureGetName(pTexture), "carpback", 8) )
{
auto& pCallbackData = *static_cast<std::pair<RwTexture*,signed char>*>(pData);
CCustomCarPlateMgr::SetupMaterialPlatebackTexture(pMaterial, pCallbackData.second);
}
}
}
return pMaterial;
}
static RpAtomic* SetPlateData(RpAtomic* pAtomic, void* pData)
{
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), SetPlateData, pData);
return pAtomic;
return material;
} );
return atomic;
} );
}
void CCustomCarPlateMgr::SetupClump(RpClump* pClump, RpMaterial** pMatsArray)
{
// Split pMatsArray
PlateDataTuple CallbackData = std::make_tuple(pMatsArray, pMatsArray+NUM_MAX_PLATES, 0, 0);
RpClumpForAllAtomics(pClump, PollPlateData, &CallbackData);
PollPlates( pClump, pMatsArray );
}
void CCustomCarPlateMgr::SetupClumpAfterVehicleUpgrade(RpClump* pClump, RpMaterial** pMatsArray, signed char nDesign)
{
UNREFERENCED_PARAMETER(nDesign);
if ( pMatsArray )
if ( pMatsArray != nullptr )
{
// Split pMatsArray
PlateDataTuple CallbackData = std::make_tuple(pMatsArray, pMatsArray+NUM_MAX_PLATES, 0, 0);
RpClumpForAllAtomics(pClump, PollPlateData, &CallbackData);
PollPlates( pClump, pMatsArray );
}
}
void CCustomCarPlateMgr::SetupPlates(RpClump* pClump, RwTexture* pTexture, signed char nDesign)
{
std::pair<RwTexture*,signed char> CallbackData = std::make_pair(pTexture, nDesign);
RpClumpForAllAtomics(pClump, SetPlateData, &CallbackData);
}

View file

@ -292,25 +292,17 @@ public:
void FindEditableMaterialList();
void SetCarCustomPlate();
static RpAtomic* GetEditableMaterialListCB(RpAtomic* pAtomic, void* pData);
static RpMaterial* GetEditableMaterialListCB(RpMaterial* pMaterial, void* pData);
};
extern CBaseModelInfo** const ms_modelInfoPtrs;
extern const uint32_t m_numModelInfoPtrs;
#define NUM_MAX_PLATES 12
class CCustomCarPlateMgr
{
// Pretty much rewritten for SilentPatch
private:
//static RpMaterial** m_pMaterialsWeWorkingWith;
//static unsigned char m_nCurPlateMaterial, m_nCurPlateBackMaterial;
//static signed char m_nCurPlateDesign;
public:
static const size_t NUM_MAX_PLATES = 12;
static RwTexture* (*CreatePlateTexture)(const char* pText, signed char nDesign);
static bool (*GeneratePlateText)(char* pBuf, int nLen);
static signed char (*GetMapRegionPlateDesign)();
@ -319,7 +311,8 @@ public:
static void SetupClump(RpClump* pClump, RpMaterial** pMatsArray);
static void SetupClumpAfterVehicleUpgrade(RpClump* pClump, RpMaterial** pMatsArray, signed char nDesign);
static void SetupPlates(RpClump* pClump, RwTexture* pTexture, signed char nDesign);
private:
static void PollPlates( RpClump* clump, RpMaterial** materials );
};
static_assert(sizeof(CBaseModelInfo) == 0x20, "Wrong size: CBaseModelInfo");

View file

@ -14,16 +14,13 @@ WRAPPER CTaskSimpleJetPack* CPedIntelligence::GetTaskJetPack() const { VARJMP(va
static void* varRenderJetPack = AddressByVersion<void*>(0x67F6A0, 0x67FEC0, 0x6AB110);
WRAPPER void CTaskSimpleJetPack::RenderJetPack(CPed* pPed) { WRAPARG(pPed); VARJMP(varRenderJetPack); }
static RwObject* GetFirstObjectCallback(RwObject* pObject, void* pData)
{
*static_cast<RwObject**>(pData) = pObject;
return nullptr;
}
RwObject* GetFirstObject(RwFrame* pFrame)
{
RwObject* pObject = nullptr;
RwFrameForAllObjects(pFrame, GetFirstObjectCallback, &pObject);
RwFrameForAllObjects( pFrame, [&pObject]( RwObject* object ) -> RwObject* {
pObject = object;
return nullptr;
} );
return pObject;
}
@ -47,13 +44,14 @@ void CPed::RenderWeapon(bool bMuzzleFlash, bool bForShadow)
RwFrameUpdateObjects(pFrame);
if ( bForShadow )
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB, nullptr);
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB);
else if ( !bMuzzleFlash )
RpClumpRender(reinterpret_cast<RpClump*>(m_pWeaponObject));
else if ( m_pMuzzleFlashFrame )
{
SetGunFlashAlpha(false);
RpAtomicRender(reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame)));
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame));
RpAtomicRender( atomic );
}
// Dual weapons
@ -68,13 +66,14 @@ void CPed::RenderWeapon(bool bMuzzleFlash, bool bForShadow)
RwFrameUpdateObjects(pFrame);
if ( bForShadow )
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB, nullptr);
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pWeaponObject), ShadowCameraRenderCB);
else if ( !bMuzzleFlash )
RpClumpRender(reinterpret_cast<RpClump*>(m_pWeaponObject));
else if ( m_pMuzzleFlashFrame )
{
SetGunFlashAlpha(true);
RpAtomicRender(reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame)));
RpAtomic* atomic = reinterpret_cast<RpAtomic*>(GetFirstObject(m_pMuzzleFlashFrame));
RpAtomicRender( atomic );
}
}
if ( bMuzzleFlash )
@ -84,7 +83,7 @@ void CPed::RenderWeapon(bool bMuzzleFlash, bool bForShadow)
void CPed::RenderForShadow()
{
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pRwObject), ShadowCameraRenderCB, nullptr);
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(m_pRwObject), ShadowCameraRenderCB);
RenderWeapon(false, true);
// Render jetpack

View file

@ -261,23 +261,28 @@ static struct
// Regular functions
static RpMaterial* AlphaTest(RpMaterial* pMaterial, void* pData)
static bool AtomicAlphaTest( RpAtomic* atomic )
{
if ( RpMaterialGetTexture(pMaterial) )
{
if ( __rwD3D9TextureHasAlpha(RpMaterialGetTexture(pMaterial)) )
bool hasAlpha = false;
RpGeometryForAllMaterials( RpAtomicGetGeometry(atomic), [&hasAlpha]( RpMaterial* material ) -> RpMaterial* {
if ( RpMaterialGetTexture(material) != nullptr )
{
*static_cast<BOOL*>(pData) = TRUE;
if ( __rwD3D9TextureHasAlpha(RpMaterialGetTexture(material)) )
{
hasAlpha = true;
return nullptr;
}
}
else if ( RpMaterialGetColor(material)->alpha < 255 )
{
hasAlpha = true;
return nullptr;
}
}
else if ( RpMaterialGetColor(pMaterial)->alpha < 255 )
{
*static_cast<BOOL*>(pData) = TRUE;
return nullptr;
}
return pMaterial;
return material;
} );
return hasAlpha;
}
static RpAtomic* RenderAtomic(RpAtomic* pAtomic, float fComp)
@ -422,10 +427,7 @@ void RenderVehicleHiDetailAlphaCB_HunterDoor(RpAtomic* pAtomic)
template <RpAtomic* renderer(RpAtomic*)>
void SetRendererForAtomic(RpAtomic* pAtomic)
{
BOOL bHasAlpha = FALSE;
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), AlphaTest, &bHasAlpha);
if ( bHasAlpha )
if ( AtomicAlphaTest( pAtomic ) )
RpAtomicSetRenderCallBack(pAtomic, renderer);
}
@ -487,10 +489,7 @@ void RenderWeaponPedsForPC()
template <RpAtomic* renderer(RpAtomic*)>
RpAtomic* RenderPedCB(RpAtomic* pAtomic)
{
BOOL bHasAlpha = FALSE;
RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), AlphaTest, &bHasAlpha);
if ( bHasAlpha )
if ( AtomicAlphaTest( pAtomic ) )
return renderer(pAtomic);
return AtomicDefaultRenderCallBack(pAtomic);

View file

@ -174,6 +174,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
<ClInclude Include="PedSA.h" />
<ClInclude Include="PNGFile.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="rwpred.hpp" />
<ClInclude Include="ScriptSA.h" />
<ClInclude Include="StdAfxSA.h" />
<ClInclude Include="TimerSA.h" />

View file

@ -140,6 +140,9 @@
<ClInclude Include="..\SilentPatch\DelimStringReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="rwpred.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Shaders.rc">

View file

@ -25,6 +25,7 @@
#include "MemoryMgr.h"
#include "Maths.h"
#include "rwpred.hpp"
// SA operator delete
extern void (*GTAdelete)(void* data);

View file

@ -1,5 +1,6 @@
#include "StdAfxSA.h"
#include <functional>
#include <algorithm>
#include <vector>
#include "VehicleSA.h"
@ -23,35 +24,50 @@ static int32_t random(int32_t from, int32_t to)
return from + ( Int32Rand() % (to-from) );
}
static RwObject* GetCurrentAtomicObjectCB(RwObject* pObject, void* data)
static RwObject* GetCurrentAtomicObject( RwFrame* frame )
{
if ( RpAtomicGetFlags(pObject) & rpATOMICRENDER )
{
*static_cast<RwObject**>(data) = pObject;
return nullptr;
}
return pObject;
RwObject* obj = nullptr;
RwFrameForAllObjects( frame, [&obj]( RwObject* object ) -> RwObject* {
if ( RpAtomicGetFlags(object) & rpATOMICRENDER )
{
obj = object;
return nullptr;
}
return object;
} );
return obj;
}
static RwFrame* GetFrameFromNameCB(RwFrame* pFrame, void* pData)
static RwFrame* GetFrameFromName( RwFrame* topFrame, const char* name )
{
// Is this a frame we want?
std::pair<const char*,RwFrame*>* pFindData = static_cast<std::pair<const char*,RwFrame*>*>(pData);
if ( !strcmp(pFindData->first, GetFrameNodeName(pFrame)) )
class GetFramePredicate
{
pFindData->second = pFrame;
return nullptr;
}
public:
RwFrame* foundFrame = nullptr;
// Try children
RwFrameForAllChildren(pFrame, GetFrameFromNameCB, pData);
return !pFindData->second ? pFrame : nullptr;
}
GetFramePredicate( const char* name )
: m_name( name )
{
}
static RpMaterial* SetCompAlphaCB(RpMaterial* pMaterial, void* data)
{
pMaterial->color.alpha = reinterpret_cast<RwUInt8>(data);
return pMaterial;
RwFrame* operator() ( RwFrame* frame )
{
if ( strcmp( m_name, GetFrameNodeName(frame) ) == 0 )
{
foundFrame = frame;
return nullptr;
}
RwFrameForAllChildren( frame, std::ref(*this) );
return foundFrame != nullptr ? nullptr : frame;
}
private:
const char* const m_name;
};
GetFramePredicate p( name );
RwFrameForAllChildren( topFrame, std::ref(p) );
return p.foundFrame;
}
void ReadRotorFixExceptions(const wchar_t* pPath)
@ -73,7 +89,10 @@ void CVehicle::SetComponentAtomicAlpha(RpAtomic* pAtomic, int nAlpha)
RpGeometry* pGeometry = RpAtomicGetGeometry(pAtomic);
pGeometry->flags |= rpGEOMETRYMODULATEMATERIALCOLOR;
RpGeometryForAllMaterials(pGeometry, SetCompAlphaCB, reinterpret_cast<void*>(nAlpha));
RpGeometryForAllMaterials( pGeometry, [nAlpha] (RpMaterial* material) {
material->color.alpha = RwUInt8(nAlpha);
return material;
} );
}
bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo)
@ -93,7 +112,7 @@ bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo)
else if ( IsLawEnforcementVehicle() )
PlateDesign = CCustomCarPlateMgr::GetMapRegionPlateDesign();
else
PlateDesign = random(0, 20) == 0 ? random(0, 3) : CCustomCarPlateMgr::GetMapRegionPlateDesign();
PlateDesign = random(0, 20) == 0 ? int8_t(random(0, 3)) : CCustomCarPlateMgr::GetMapRegionPlateDesign();
assert(PlateDesign >= 0 && PlateDesign < 3);
@ -103,53 +122,21 @@ bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo)
return true;
}
//static RwTexture* pPushedTextures[NUM_MAX_PLATES];
void CVehicle::CustomCarPlate_BeforeRenderingStart(CVehicleModelInfo* pModelInfo)
{
//CCustomCarPlateMgr::SetupPlates(reinterpret_cast<RpClump*>(pModelInfo->pRwObject), PlateTexture, PlateDesign);
for ( ptrdiff_t i = 0; i < NUM_MAX_PLATES; i++ )
for ( ptrdiff_t i = 0; i < CCustomCarPlateMgr::NUM_MAX_PLATES; i++ )
{
if ( pModelInfo->m_apPlateMaterials[i] )
if ( pModelInfo->m_apPlateMaterials[i] != nullptr )
{
//RwTexture* pPlateTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[i]);
//RwTextureAddRef(pPlateTex);
//pPushedTextures[i] = pPlateTex;
RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], PlateTexture);
}
if ( pModelInfo->m_apPlateMaterials[NUM_MAX_PLATES+i] )
CCustomCarPlateMgr::SetupMaterialPlatebackTexture(pModelInfo->m_apPlateMaterials[NUM_MAX_PLATES+i], PlateDesign);
//RwTexture* pPlatebackTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[4+i]);
//RwTextureAddRef(pPlatebackTex);
//pPushedTextures[4+i] = pPlateTex;
//RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], PlateTexture);
}
}
// This is not needed
/*void CVehicle::CustomCarPlate_AfterRenderingStop(CVehicleModelInfo* pModelInfo)
{
for ( int i = 0; i < NUM_MAX_PLATES; i++ )
{
if ( pModelInfo->m_apPlateMaterials[i] )
if ( pModelInfo->m_apPlateMaterials[CCustomCarPlateMgr::NUM_MAX_PLATES+i] != nullptr )
{
//RwTexture* pPlateTex = RpMaterialGetTexture(pModelInfo->m_apPlateMaterials[i]);
//RwTextureAddRef(pPlateTex);
//pPushedTextures[i] = pPlateTex;
//RpMaterialSetTexture(pModelInfo->m_apPlateMaterials[i], pPushedTextures[i]);
//RwTextureDestroy(pPushedTextures[i]);
//pPushedTextures[i] = nullptr;
CCustomCarPlateMgr::SetupMaterialPlatebackTexture(pModelInfo->m_apPlateMaterials[CCustomCarPlateMgr::NUM_MAX_PLATES+i], PlateDesign);
}
}
}*/
}
void CHeli::Render()
{
@ -172,35 +159,31 @@ void CHeli::Render()
int nStaticRotorAlpha = static_cast<int>(std::min((1.5-dRotorsSpeed) * 255.0, 255.0));
int nMovingRotorAlpha = static_cast<int>(std::min(dMovingRotorSpeed * 175.0, 175.0));
if ( m_pCarNode[12] )
if ( m_pCarNode[12] != nullptr )
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic);
if ( pOutAtomic )
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[12] );
if ( pOutAtomic != nullptr )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor ? nStaticRotorAlpha : 255);
}
if ( m_pCarNode[14] )
if ( m_pCarNode[14] != nullptr )
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic);
if ( pOutAtomic )
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[14] );
if ( pOutAtomic != nullptr )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor2 ? nStaticRotorAlpha : 255);
}
if ( m_pCarNode[13] )
if ( m_pCarNode[13] != nullptr )
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic);
if ( pOutAtomic )
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[13] );
if ( pOutAtomic != nullptr )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor ? nMovingRotorAlpha : 0);
}
if ( m_pCarNode[15] )
if ( m_pCarNode[15] != nullptr )
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[15], GetCurrentAtomicObjectCB, &pOutAtomic);
if ( pOutAtomic )
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[15] );
if ( pOutAtomic != nullptr )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingRotor2 ? nMovingRotorAlpha : 0);
}
@ -228,35 +211,31 @@ void CPlane::Render()
int nStaticRotorAlpha = static_cast<int>(std::min((1.5-dRotorsSpeed) * 255.0, 255.0));
int nMovingRotorAlpha = static_cast<int>(std::min(dMovingRotorSpeed * 175.0, 175.0));
if ( m_pCarNode[12] )
if ( m_pCarNode[12] != nullptr )
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[12], GetCurrentAtomicObjectCB, &pOutAtomic);
if ( pOutAtomic )
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[12] );
if ( pOutAtomic != nullptr )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp ? nStaticRotorAlpha : 255);
}
if ( m_pCarNode[14] )
if ( m_pCarNode[14] != nullptr )
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[14], GetCurrentAtomicObjectCB, &pOutAtomic);
if ( pOutAtomic )
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[14] );
if ( pOutAtomic != nullptr )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp2 ? nStaticRotorAlpha : 255);
}
if ( m_pCarNode[13] )
if ( m_pCarNode[13] != nullptr )
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[13], GetCurrentAtomicObjectCB, &pOutAtomic);
if ( pOutAtomic )
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[13] );
if ( pOutAtomic != nullptr )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp ? nMovingRotorAlpha : 0);
}
if ( m_pCarNode[15] )
if ( m_pCarNode[15] != nullptr )
{
RpAtomic* pOutAtomic = nullptr;
RwFrameForAllObjects(m_pCarNode[15], GetCurrentAtomicObjectCB, &pOutAtomic);
if ( pOutAtomic )
RpAtomic* pOutAtomic = (RpAtomic*)GetCurrentAtomicObject( m_pCarNode[15] );
if ( pOutAtomic != nullptr )
SetComponentAtomicAlpha(pOutAtomic, bHasMovingProp2 ? nMovingRotorAlpha : 0);
}
@ -288,22 +267,19 @@ void CAutomobile::Fix_SilentPatch()
void CAutomobile::ResetFrames()
{
RpClump* pOrigClump = reinterpret_cast<RpClump*>(ms_modelInfoPtrs[m_nModelIndex]->pRwObject);
if ( pOrigClump )
if ( pOrigClump != nullptr )
{
// Instead of setting frame rotation to (0,0,0) like R* did, obtain the original frame matrix from CBaseNodelInfo clump
for ( ptrdiff_t i = 8; i < 25; i++ )
{
if ( m_pCarNode[i] )
if ( m_pCarNode[i] != nullptr )
{
// Find a frame in CBaseModelInfo object
std::pair<const char*,RwFrame*> FindData = std::make_pair(GetFrameNodeName(m_pCarNode[i]), nullptr);
RwFrameForAllChildren(RpClumpGetFrame(pOrigClump), GetFrameFromNameCB, &FindData);
if ( FindData.second )
RwFrame* origFrame = GetFrameFromName( RpClumpGetFrame(pOrigClump), GetFrameNodeName(m_pCarNode[i]) );
if ( origFrame != nullptr )
{
// Found a frame, reset it
*RwFrameGetMatrix(m_pCarNode[i]) = *RwFrameGetMatrix(FindData.second);
*RwFrameGetMatrix(m_pCarNode[i]) = *RwFrameGetMatrix(origFrame);
RwMatrixUpdate(RwFrameGetMatrix(m_pCarNode[i]));
}
}

View file

@ -123,7 +123,7 @@ protected:
CEntity* pDamagingEntity;
BYTE __pad3[116];
char padpad, padpad2, padpad3;
signed char PlateDesign;
int8_t PlateDesign;
RwTexture* PlateTexture;
BYTE __pad5[20];

49
SilentPatchSA/rwpred.hpp Normal file
View file

@ -0,0 +1,49 @@
#pragma once
#include <rwcore.h>
#include <rpworld.h>
template <typename Pred>
RwFrame* RwFrameForAllChildren(RwFrame* frame, Pred callback)
{
for ( RwFrame* curFrame = frame->child; curFrame != nullptr; curFrame = curFrame->next )
{
if ( callback(curFrame) == nullptr )
break;
}
return frame;
}
template <typename Pred>
RwFrame* RwFrameForAllObjects(RwFrame* frame, Pred callback)
{
for ( RwLLLink* link = rwLinkListGetFirstLLLink(&frame->objectList); link != rwLinkListGetTerminator(&frame->objectList); link = rwLLLinkGetNext(link) )
{
if ( callback(&rwLLLinkGetData(link, RwObjectHasFrame, lFrame)->object) == nullptr )
break;
}
return frame;
}
template <typename Pred>
RpClump* RpClumpForAllAtomics(RpClump* clump, Pred callback)
{
for ( RwLLLink* link = rwLinkListGetFirstLLLink(&clump->atomicList); link != rwLinkListGetTerminator(&clump->atomicList); link = rwLLLinkGetNext(link) )
{
if ( callback(rwLLLinkGetData(link, RpAtomic, inClumpLink)) == nullptr )
break;
}
return clump;
}
template <typename Pred>
RpGeometry* RpGeometryForAllMaterials(RpGeometry* geometry, Pred callback)
{
for ( RwInt32 i = 0, j = geometry->matList.numMaterials; i < j; i++ )
{
if ( callback(geometry->matList.materials[i]) == nullptr )
break;
}
return geometry;
}

View file

@ -5,8 +5,8 @@
<SILENTPATCH_NAME>SilentPatchSA</SILENTPATCH_NAME>
<SILENTPATCH_EXT>.asi</SILENTPATCH_EXT>
<SILENTPATCH_FULL_NAME>SilentPatch for San Andreas</SILENTPATCH_FULL_NAME>
<SILENTPATCH_REVISION_ID>28</SILENTPATCH_REVISION_ID>
<SILENTPATCH_BUILD_ID>5</SILENTPATCH_BUILD_ID>
<SILENTPATCH_REVISION_ID>29</SILENTPATCH_REVISION_ID>
<SILENTPATCH_BUILD_ID>0</SILENTPATCH_BUILD_ID>
<SILENTPATCH_COPYRIGHT>2014-2017</SILENTPATCH_COPYRIGHT>
</PropertyGroup>
<PropertyGroup />