#include "StdAfxSA.h" #include "ModelInfoSA.h" static void* BaseModelInfoShutdown = AddressByVersion(0x4C4D50, 0x4C4DD0, 0x4CF590); WRAPPER void CBaseModelInfo::Shutdown() { VARJMP(BaseModelInfoShutdown); } RwTexture* (*CCustomCarPlateMgr::CreatePlateTexture)(const char* pText, signed char nDesign) = AddressByVersion(0x6FDEA0, 0x6FE6D0, 0x736AC0); bool (*CCustomCarPlateMgr::GeneratePlateText)(char* pBuf, int nLen) = AddressByVersion(0x6FD5B0, 0x6FDDE0, 0x7360F0); signed char (*CCustomCarPlateMgr::GetMapRegionPlateDesign)() = AddressByVersion(0x6FD7A0, 0x6FDFD0, 0x7363E0); void (*CCustomCarPlateMgr::SetupMaterialPlatebackTexture)(RpMaterial* pMaterial, signed char nDesign) = AddressByVersion(0x6FDE50, 0x6FE680, 0x736A80); CBaseModelInfo** const ms_modelInfoPtrs = *AddressByVersion(0x509CB1, 0x4C0C96, 0x403DB7); const uint32_t m_numModelInfoPtrs = *AddressByVersion(0x4C5956+2, 0, 0); void CVehicleModelInfo::Shutdown() { CBaseModelInfo::Shutdown(); delete m_apPlateMaterials; } void CVehicleModelInfo::FindEditableMaterialList() { std::pair MatsPair = std::make_pair(this, 0); RpClumpForAllAtomics(reinterpret_cast(pRwObject), GetEditableMaterialListCB, &MatsPair); if ( m_pVehicleStruct->m_nNumExtras > 0 ) { for ( int i = 0; i < m_pVehicleStruct->m_nNumExtras; i++ ) GetEditableMaterialListCB(m_pVehicleStruct->m_apExtras[i], &MatsPair); } m_nPrimaryColor = -1; m_nSecondaryColor = -1; m_nTertiaryColor = -1; m_nQuaternaryColor = -1; } void CVehicleModelInfo::SetCarCustomPlate() { m_plateText[0] = '\0'; m_nPlateType = -1; m_apPlateMaterials = reinterpret_cast(new DWORD_PTR[2*NUM_MAX_PLATES]); for ( int i = 0; i < 2*NUM_MAX_PLATES; i++ ) m_apPlateMaterials[i] = nullptr; CCustomCarPlateMgr::SetupClump(reinterpret_cast(pRwObject), m_apPlateMaterials); } RpAtomic* CVehicleModelInfo::GetEditableMaterialListCB(RpAtomic* pAtomic, void* pData) { RpGeometryForAllMaterials(RpAtomicGetGeometry(pAtomic), GetEditableMaterialListCB, pData); return pAtomic; } RpMaterial* CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial* pMaterial, void* pData) { if ( RpMaterialGetTexture(pMaterial) ) { if ( !strncmp(RwTextureGetName(RpMaterialGetTexture(pMaterial)), "vehiclegrunge256", 16) ) { std::pair* pMats = static_cast*>(pData); 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) ) { auto& pCallbackData = *static_cast(pData); assert(std::get<2>(pCallbackData) < NUM_MAX_PLATES); if ( std::get<2>(pCallbackData) < NUM_MAX_PLATES ) { // Append data for ( auto ptr = std::get<0>(pCallbackData); *ptr; ptr++ ) { if ( *ptr == pMaterial ) return pMaterial; } 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; } 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); } void CCustomCarPlateMgr::SetupClumpAfterVehicleUpgrade(RpClump* pClump, RpMaterial** pMatsArray, signed char nDesign) { UNREFERENCED_PARAMETER(nDesign); if ( pMatsArray ) { // Split pMatsArray PlateDataTuple CallbackData = std::make_tuple(pMatsArray, pMatsArray+NUM_MAX_PLATES, 0, 0); RpClumpForAllAtomics(pClump, PollPlateData, &CallbackData); } } void CCustomCarPlateMgr::SetupPlates(RpClump* pClump, RwTexture* pTexture, signed char nDesign) { std::pair CallbackData = std::make_pair(pTexture, nDesign); RpClumpForAllAtomics(pClump, SetPlateData, &CallbackData); }