diff --git a/SilentPatchSA/ModelInfoSA.cpp b/SilentPatchSA/ModelInfoSA.cpp index 3fed5e4..e071438 100644 --- a/SilentPatchSA/ModelInfoSA.cpp +++ b/SilentPatchSA/ModelInfoSA.cpp @@ -48,9 +48,6 @@ void CVehicleModelInfo::Shutdown() delete[] m_dirtMaterials; m_dirtMaterials = nullptr; - - delete m_apPlateMaterials; - m_apPlateMaterials = nullptr; } void CVehicleModelInfo::FindEditableMaterialList() @@ -103,10 +100,6 @@ void CVehicleModelInfo::SetCarCustomPlate() { m_plateText[0] = '\0'; m_nPlateType = -1; - - m_apPlateMaterials = new PlateMaterialsData; - - CCustomCarPlateMgr::SetupClump(reinterpret_cast(pRwObject), m_apPlateMaterials); } void CVehicleModelInfo::ResetCompsForNoExtras() @@ -115,59 +108,7 @@ void CVehicleModelInfo::ResetCompsForNoExtras() ms_compsToUse[0] = ms_compsToUse[1] = -2; } -void CCustomCarPlateMgr::PollPlates( RpClump* clump, PlateMaterialsData* materials ) -{ - std::vector carplates; - std::vector carpbacks; - - RpClumpForAllAtomics( clump, [&] ( RpAtomic* atomic ) -> RpAtomic* { - RpGeometryForAllMaterials( RpAtomicGetGeometry(atomic), [&] ( RpMaterial* material ) -> RpMaterial* { - if ( RwTexture* texture = RpMaterialGetTexture(material) ) - { - if ( const char* texName = RwTextureGetName(texture) ) - { - if ( strcmp( texName, "carplate" ) == 0 ) - { - carplates.push_back( material ); - } - else if ( strcmp( texName, "carpback" ) == 0 ) - { - carpbacks.push_back( material ); - } - } - } - - return material; - } ); - return atomic; - } ); - - materials->m_numPlates = carplates.size(); - materials->m_numPlatebacks = carpbacks.size(); - - if ( materials->m_numPlates > 0 ) - { - materials->m_plates = new RpMaterial* [materials->m_numPlates]; - std::copy( carplates.begin(), carplates.end(), stdext::make_checked_array_iterator(materials->m_plates, materials->m_numPlates) ); - } - - if ( materials->m_numPlatebacks > 0 ) - { - materials->m_platebacks = new RpMaterial* [materials->m_numPlatebacks]; - std::copy( carpbacks.begin(), carpbacks.end(), stdext::make_checked_array_iterator(materials->m_platebacks, materials->m_numPlatebacks) ); - } -} - -void CCustomCarPlateMgr::SetupClump(RpClump* pClump, PlateMaterialsData* pMatsArray) -{ - PollPlates( pClump, pMatsArray ); -} - -void CCustomCarPlateMgr::SetupClumpAfterVehicleUpgrade(RpClump* pClump, PlateMaterialsData* pMatsArray, signed char nDesign) +void CCustomCarPlateMgr::SetupClumpAfterVehicleUpgrade(RpClump* pClump, void* /*unused*/, signed char nDesign) { UNREFERENCED_PARAMETER(nDesign); - if ( pMatsArray != nullptr ) - { - PollPlates( pClump, pMatsArray ); - } } \ No newline at end of file diff --git a/SilentPatchSA/ModelInfoSA.h b/SilentPatchSA/ModelInfoSA.h index 97de730..df9f974 100644 --- a/SilentPatchSA/ModelInfoSA.h +++ b/SilentPatchSA/ModelInfoSA.h @@ -222,27 +222,14 @@ public: virtual void SetClump(RpClump* pClump); }; -struct PlateMaterialsData // Added in SilentPatch -{ - RpMaterial** m_plates = nullptr; - RpMaterial** m_platebacks = nullptr; - - size_t m_numPlates = 0; - size_t m_numPlatebacks = 0; - - ~PlateMaterialsData() - { - delete[] m_plates; - delete[] m_platebacks; - } -}; - class NOVMT CVehicleModelInfo : public CClumpModelInfo { public: static const size_t PLATE_TEXT_LEN = 8; - PlateMaterialsData* m_apPlateMaterials; // Changed in SilentPatch + // m_pCustomPlateMaterial in the stock game, m_apPlateMaterials in older SilentPatch, + // now entirely deprecated. Points to a dummy variable just to satisfy some existing null checks + void* __removedInSilentPatch; char m_plateText[PLATE_TEXT_LEN]; char field_30; signed char m_nPlateType; @@ -344,11 +331,7 @@ public: static signed char (*GetMapRegionPlateDesign)(); static void (*SetupMaterialPlatebackTexture)(RpMaterial* pMaterial, signed char nDesign); - static void SetupClump(RpClump* pClump, PlateMaterialsData* pMatsArray); - static void SetupClumpAfterVehicleUpgrade(RpClump* pClump, PlateMaterialsData* pMatsArray, signed char nDesign); - -private: - static void PollPlates( RpClump* clump, PlateMaterialsData* materials ); + static void SetupClumpAfterVehicleUpgrade(RpClump* pClump, void* /*unused*/, signed char nDesign); }; static_assert(sizeof(CBaseModelInfo) == 0x20, "Wrong size: CBaseModelInfo"); diff --git a/SilentPatchSA/SilentPatchSA.cpp b/SilentPatchSA/SilentPatchSA.cpp index 9067bdf..0f3872e 100644 --- a/SilentPatchSA/SilentPatchSA.cpp +++ b/SilentPatchSA/SilentPatchSA.cpp @@ -919,7 +919,11 @@ CVehicleModelInfo* (__thiscall *orgVehicleModelInfoCtor)(CVehicleModelInfo*); CVehicleModelInfo* __fastcall VehicleModelInfoCtor(CVehicleModelInfo* me) { orgVehicleModelInfoCtor(me); - me->m_apPlateMaterials = nullptr; + + // Hack to satisfy some null checks + static uintptr_t DUMMY; + me->__removedInSilentPatch = &DUMMY; + me->m_dirtMaterials = nullptr; me->m_numDirtMaterials = 0; std::fill( std::begin( me->m_staticDirtMaterials ), std::end( me->m_staticDirtMaterials ), nullptr ); @@ -2947,13 +2951,13 @@ BOOL InjectDelayedPatches_10() // Properly random numberplates DWORD* pVMT = *(DWORD**)0x4C75FC; Patch(&pVMT[7], &CVehicleModelInfo::Shutdown_Stub); - Patch(0x6D0E43, 0xEB); InjectHook(0x4C9660, &CVehicleModelInfo::SetCarCustomPlate); InjectHook(0x6D6A58, &CVehicle::CustomCarPlate_TextureCreate); InjectHook(0x6D651C, &CVehicle::CustomCarPlate_BeforeRenderingStart); InjectHook(0x6FDFE0, CCustomCarPlateMgr::SetupClumpAfterVehicleUpgrade, HookType::Jump); - //InjectMethodVP(0x6D0E53, CVehicle::CustomCarPlate_AfterRenderingStop, PATCH_NOTHING); + InjectHook(0x6D0E53, &CVehicle::CustomCarPlate_AfterRenderingStop); Nop(0x6D6517, 2); + Nop(0x6D0E43, 2); } // SSE conflicts @@ -3383,7 +3387,6 @@ BOOL InjectDelayedPatches_11() // Properly random numberplates DWORD* pVMT = *(DWORD**)0x4C767C; Patch(&pVMT[7], &CVehicleModelInfo::Shutdown_Stub); - Patch(0x6D1663, 0xEB); InjectHook(0x4C984D, &CVehicleModelInfo::SetCarCustomPlate); InjectHook(0x6D7288, &CVehicle::CustomCarPlate_TextureCreate); InjectHook(0x6D6D4C, &CVehicle::CustomCarPlate_BeforeRenderingStart); @@ -3560,12 +3563,10 @@ BOOL InjectDelayedPatches_Steam() // Properly random numberplates DWORD* pVMT = *(DWORD**)0x4D1E9A; Patch(&pVMT[7], &CVehicleModelInfo::Shutdown_Stub); - Patch(0x70C094, 0xEB); InjectHook(0x4D3F65, &CVehicleModelInfo::SetCarCustomPlate); InjectHook(0x711F28, &CVehicle::CustomCarPlate_TextureCreate); InjectHook(0x71194D, &CVehicle::CustomCarPlate_BeforeRenderingStart); InjectHook(0x736BD0, CCustomCarPlateMgr::SetupClumpAfterVehicleUpgrade, HookType::Jump); - //InjectMethodVP(0x6D0E53, CVehicle::CustomCarPlate_AfterRenderingStop, PATCH_NOTHING); Nop(0x711948, 2); } diff --git a/SilentPatchSA/VehicleSA.cpp b/SilentPatchSA/VehicleSA.cpp index 70f4e70..4261e2b 100644 --- a/SilentPatchSA/VehicleSA.cpp +++ b/SilentPatchSA/VehicleSA.cpp @@ -297,17 +297,41 @@ bool CVehicle::CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo) return true; } +static std::vector> originalPlateMaterials; void CVehicle::CustomCarPlate_BeforeRenderingStart(CVehicleModelInfo* pModelInfo) { - for ( size_t i = 0; i < pModelInfo->m_apPlateMaterials->m_numPlates; i++ ) - { - RpMaterialSetTexture(pModelInfo->m_apPlateMaterials->m_plates[i], PlateTexture); - } + RpClumpForAllAtomics(reinterpret_cast(m_pRwObject), [&] (RpAtomic* atomic) -> RpAtomic* { + RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), [&] (RpMaterial* material) -> RpMaterial* { + if ( RwTexture* texture = RpMaterialGetTexture(material) ) + { + if ( const char* texName = RwTextureGetName(texture) ) + { + if ( strcmp( texName, "carplate" ) == 0 ) + { + originalPlateMaterials.emplace_back(material, texture); + RpMaterialSetTexture(material, PlateTexture); + } + else if ( strcmp( texName, "carpback" ) == 0 ) + { + originalPlateMaterials.emplace_back(material, texture); + CCustomCarPlateMgr::SetupMaterialPlatebackTexture(material, PlateDesign); + } + } + } - for ( size_t i = 0; i < pModelInfo->m_apPlateMaterials->m_numPlatebacks; i++ ) + return material; + } ); + return atomic; + } ); +} + +void CVehicle::CustomCarPlate_AfterRenderingStop(CVehicleModelInfo* pModelInfo) +{ + for (const auto& platesToRestore : originalPlateMaterials) { - CCustomCarPlateMgr::SetupMaterialPlatebackTexture(pModelInfo->m_apPlateMaterials->m_platebacks[i], PlateDesign); + RpMaterialSetTexture(platesToRestore.first, platesToRestore.second); } + originalPlateMaterials.clear(); } void CVehicle::SetComponentRotation( RwFrame* component, eRotAxis axis, float angle, bool absolute ) diff --git a/SilentPatchSA/VehicleSA.h b/SilentPatchSA/VehicleSA.h index 7fe9074..f0704bc 100644 --- a/SilentPatchSA/VehicleSA.h +++ b/SilentPatchSA/VehicleSA.h @@ -260,7 +260,7 @@ public: bool CustomCarPlate_TextureCreate(CVehicleModelInfo* pModelInfo); void CustomCarPlate_BeforeRenderingStart(CVehicleModelInfo* pModelInfo); - //void CustomCarPlate_AfterRenderingStop(CVehicleModelInfo* pModelInfo); + void CustomCarPlate_AfterRenderingStop(CVehicleModelInfo* pModelInfo); bool HasFirelaLadder() const; void* PlayPedHitSample_GetColModel();