From a5c0dd54eb2ae522345640c44a03d45125c4fe0c Mon Sep 17 00:00:00 2001 From: Silent Date: Mon, 27 Mar 2017 21:17:43 +0200 Subject: [PATCH] refactored to use templated predicates for RW callbacks --- SilentPatchSA/GeneralSA.cpp | 6 +- SilentPatchSA/GeneralSA.h | 18 +- SilentPatchSA/ModelInfoSA.cpp | 176 ++++++------------- SilentPatchSA/ModelInfoSA.h | 15 +- SilentPatchSA/PedSA.cpp | 23 ++- SilentPatchSA/SilentPatchSA.cpp | 39 +++-- SilentPatchSA/SilentPatchSA.vcxproj | 1 + SilentPatchSA/SilentPatchSA.vcxproj.filters | 3 + SilentPatchSA/StdAfxSA.h | 1 + SilentPatchSA/VehicleSA.cpp | 178 +++++++++----------- SilentPatchSA/VehicleSA.h | 2 +- SilentPatchSA/rwpred.hpp | 49 ++++++ SilentPatchSA/versionmeta.props | 4 +- 13 files changed, 232 insertions(+), 283 deletions(-) create mode 100644 SilentPatchSA/rwpred.hpp diff --git a/SilentPatchSA/GeneralSA.cpp b/SilentPatchSA/GeneralSA.cpp index 8895973..93a686f 100644 --- a/SilentPatchSA/GeneralSA.cpp +++ b/SilentPatchSA/GeneralSA.cpp @@ -31,10 +31,8 @@ static void ResetEditableMaterials(std::pair* pData) *static_cast(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(pEntity)->RenderForShadow(); else - RpClumpForAllAtomics(reinterpret_cast(pEntity->m_pRwObject), ShadowCameraRenderCB, nullptr); + RpClumpForAllAtomics(reinterpret_cast(pEntity->m_pRwObject), ShadowCameraRenderCB); } InvertRaster(); diff --git a/SilentPatchSA/GeneralSA.h b/SilentPatchSA/GeneralSA.h index 0c4f3d8..a2a23b8 100644 --- a/SilentPatchSA/GeneralSA.h +++ b/SilentPatchSA/GeneralSA.h @@ -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"); diff --git a/SilentPatchSA/ModelInfoSA.cpp b/SilentPatchSA/ModelInfoSA.cpp index b41e934..36ef591 100644 --- a/SilentPatchSA/ModelInfoSA.cpp +++ b/SilentPatchSA/ModelInfoSA.cpp @@ -17,18 +17,37 @@ void CVehicleModelInfo::Shutdown() CBaseModelInfo::Shutdown(); delete m_apPlateMaterials; + m_apPlateMaterials = nullptr; } void CVehicleModelInfo::FindEditableMaterialList() { - std::pair MatsPair = std::make_pair(this, 0); + int materialCount = 0; - RpClumpForAllAtomics(reinterpret_cast(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(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(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(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* pMats = static_cast*>(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 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(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(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*>(pData); - - RpMaterialSetTexture(pMaterial, pCallbackData.first); - } - else if ( !_strnicmp(RwTextureGetName(pTexture), "carpback", 8) ) - { - auto& pCallbackData = *static_cast*>(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 CallbackData = std::make_pair(pTexture, nDesign); - - RpClumpForAllAtomics(pClump, SetPlateData, &CallbackData); } \ No newline at end of file diff --git a/SilentPatchSA/ModelInfoSA.h b/SilentPatchSA/ModelInfoSA.h index cfa13a6..7cb0dab 100644 --- a/SilentPatchSA/ModelInfoSA.h +++ b/SilentPatchSA/ModelInfoSA.h @@ -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"); diff --git a/SilentPatchSA/PedSA.cpp b/SilentPatchSA/PedSA.cpp index 070033b..4c66eff 100644 --- a/SilentPatchSA/PedSA.cpp +++ b/SilentPatchSA/PedSA.cpp @@ -14,16 +14,13 @@ WRAPPER CTaskSimpleJetPack* CPedIntelligence::GetTaskJetPack() const { VARJMP(va static void* varRenderJetPack = AddressByVersion(0x67F6A0, 0x67FEC0, 0x6AB110); WRAPPER void CTaskSimpleJetPack::RenderJetPack(CPed* pPed) { WRAPARG(pPed); VARJMP(varRenderJetPack); } -static RwObject* GetFirstObjectCallback(RwObject* pObject, void* pData) -{ - *static_cast(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(m_pWeaponObject), ShadowCameraRenderCB, nullptr); + RpClumpForAllAtomics(reinterpret_cast(m_pWeaponObject), ShadowCameraRenderCB); else if ( !bMuzzleFlash ) RpClumpRender(reinterpret_cast(m_pWeaponObject)); else if ( m_pMuzzleFlashFrame ) { SetGunFlashAlpha(false); - RpAtomicRender(reinterpret_cast(GetFirstObject(m_pMuzzleFlashFrame))); + RpAtomic* atomic = reinterpret_cast(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(m_pWeaponObject), ShadowCameraRenderCB, nullptr); + RpClumpForAllAtomics(reinterpret_cast(m_pWeaponObject), ShadowCameraRenderCB); else if ( !bMuzzleFlash ) RpClumpRender(reinterpret_cast(m_pWeaponObject)); else if ( m_pMuzzleFlashFrame ) { SetGunFlashAlpha(true); - RpAtomicRender(reinterpret_cast(GetFirstObject(m_pMuzzleFlashFrame))); + RpAtomic* atomic = reinterpret_cast(GetFirstObject(m_pMuzzleFlashFrame)); + RpAtomicRender( atomic ); } } if ( bMuzzleFlash ) @@ -84,7 +83,7 @@ void CPed::RenderWeapon(bool bMuzzleFlash, bool bForShadow) void CPed::RenderForShadow() { - RpClumpForAllAtomics(reinterpret_cast(m_pRwObject), ShadowCameraRenderCB, nullptr); + RpClumpForAllAtomics(reinterpret_cast(m_pRwObject), ShadowCameraRenderCB); RenderWeapon(false, true); // Render jetpack diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 20771e0..9b3f503 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -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(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(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 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* RenderPedCB(RpAtomic* pAtomic) { - BOOL bHasAlpha = FALSE; - - RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), AlphaTest, &bHasAlpha); - if ( bHasAlpha ) + if ( AtomicAlphaTest( pAtomic ) ) return renderer(pAtomic); return AtomicDefaultRenderCallBack(pAtomic); diff --git a/SilentPatchSA/SilentPatchSA.vcxproj b/SilentPatchSA/SilentPatchSA.vcxproj index b896c10..632535d 100644 --- a/SilentPatchSA/SilentPatchSA.vcxproj +++ b/SilentPatchSA/SilentPatchSA.vcxproj @@ -174,6 +174,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio + diff --git a/SilentPatchSA/SilentPatchSA.vcxproj.filters b/SilentPatchSA/SilentPatchSA.vcxproj.filters index a69594e..ca03eb6 100644 --- a/SilentPatchSA/SilentPatchSA.vcxproj.filters +++ b/SilentPatchSA/SilentPatchSA.vcxproj.filters @@ -140,6 +140,9 @@ Header Files + + Header Files + diff --git a/SilentPatchSA/StdAfxSA.h b/SilentPatchSA/StdAfxSA.h index 026f2a6..fd30662 100644 --- a/SilentPatchSA/StdAfxSA.h +++ b/SilentPatchSA/StdAfxSA.h @@ -25,6 +25,7 @@ #include "MemoryMgr.h" #include "Maths.h" +#include "rwpred.hpp" // SA operator delete extern void (*GTAdelete)(void* data); diff --git a/SilentPatchSA/VehicleSA.cpp b/SilentPatchSA/VehicleSA.cpp index 9b82a62..2dbd08f 100644 --- a/SilentPatchSA/VehicleSA.cpp +++ b/SilentPatchSA/VehicleSA.cpp @@ -1,5 +1,6 @@ #include "StdAfxSA.h" +#include #include #include #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(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* pFindData = static_cast*>(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(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(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(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(std::min((1.5-dRotorsSpeed) * 255.0, 255.0)); int nMovingRotorAlpha = static_cast(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(std::min((1.5-dRotorsSpeed) * 255.0, 255.0)); int nMovingRotorAlpha = static_cast(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(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 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])); } } diff --git a/SilentPatchSA/VehicleSA.h b/SilentPatchSA/VehicleSA.h index ae852fa..02765a6 100644 --- a/SilentPatchSA/VehicleSA.h +++ b/SilentPatchSA/VehicleSA.h @@ -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]; diff --git a/SilentPatchSA/rwpred.hpp b/SilentPatchSA/rwpred.hpp new file mode 100644 index 0000000..5dadcd1 --- /dev/null +++ b/SilentPatchSA/rwpred.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include + +template +RwFrame* RwFrameForAllChildren(RwFrame* frame, Pred callback) +{ + for ( RwFrame* curFrame = frame->child; curFrame != nullptr; curFrame = curFrame->next ) + { + if ( callback(curFrame) == nullptr ) + break; + } + return frame; +} + +template +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 +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 +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; +} \ No newline at end of file diff --git a/SilentPatchSA/versionmeta.props b/SilentPatchSA/versionmeta.props index 3a3ff7b..296f2e5 100644 --- a/SilentPatchSA/versionmeta.props +++ b/SilentPatchSA/versionmeta.props @@ -5,8 +5,8 @@ SilentPatchSA .asi SilentPatch for San Andreas - 28 - 5 + 29 + 0 2014-2017