@@ -629,39 +629,68 @@ namespace
629629 return true ;
630630 }
631631
632- void ReplaceTextureInModel (CModelInfoSA* pModelInfo, TextureSwapMap& swapMap)
632+ bool ReplaceTextureInModel (CModelInfoSA* pModelInfo, TextureSwapMap& swapMap)
633633 {
634634 if (!pModelInfo || swapMap.empty ())
635- return ;
635+ return false ;
636636
637637 RwObject* pRwObject = pModelInfo->GetRwObject ();
638638 if (!pRwObject)
639- return ;
639+ return false ;
640+
641+ const unsigned char rwType = pRwObject->type ;
642+ const eModelInfoType modelType = pModelInfo->GetModelType ();
643+
644+ if (modelType == eModelInfoType::UNKNOWN)
645+ {
646+ if (rwType == RP_TYPE_ATOMIC)
647+ {
648+ auto * pAtomic = reinterpret_cast <RpAtomic*>(pRwObject);
649+ ReplaceTextureInGeometry (pAtomic ? pAtomic->geometry : nullptr , swapMap);
650+ return true ;
651+ }
652+
653+ if (rwType == RP_TYPE_CLUMP)
654+ {
655+ auto * pClump = reinterpret_cast <RpClump*>(pRwObject);
656+ if (pClump)
657+ RpClumpForAllAtomics (pClump, ReplaceTextureInAtomicCB, &swapMap);
658+ return true ;
659+ }
660+
661+ return false ;
662+ }
640663
641- switch (pModelInfo-> GetModelType () )
664+ switch (modelType )
642665 {
643666 case eModelInfoType::ATOMIC:
644667 case eModelInfoType::TIME:
645668 case eModelInfoType::LOD_ATOMIC:
646669 {
670+ if (rwType != RP_TYPE_ATOMIC)
671+ return false ;
672+
647673 RpAtomic* pAtomic = reinterpret_cast <RpAtomic*>(pRwObject);
648- if (pAtomic)
649- ReplaceTextureInGeometry (pAtomic->geometry , swapMap);
650- break ;
674+ ReplaceTextureInGeometry (pAtomic ? pAtomic->geometry : nullptr , swapMap);
675+ return true ;
651676 }
652677
653678 case eModelInfoType::WEAPON:
654679 case eModelInfoType::CLUMP:
655680 case eModelInfoType::VEHICLE:
656681 case eModelInfoType::PED:
657- case eModelInfoType::UNKNOWN:
658- default :
659682 {
683+ if (rwType != RP_TYPE_CLUMP)
684+ return false ;
685+
660686 RpClump* pClump = reinterpret_cast <RpClump*>(pRwObject);
661687 if (pClump)
662688 RpClumpForAllAtomics (pClump, ReplaceTextureInAtomicCB, &swapMap);
663- break ;
689+ return true ;
664690 }
691+
692+ default :
693+ return false ;
665694 }
666695 }
667696
@@ -750,7 +779,7 @@ namespace
750779 // This prevents ModelInfoTXDAddTextures from failing due to a model referencing a dead/reused slot.
751780 if (pModelInfo->GetTextureDictionaryID () == txdId)
752781 {
753- if (slot && slot->rwTexDictonary && slot->usParentIndex == parentTxdId)
782+ if (slot && slot->rwTexDictonary && slot->usParentIndex == parentTxdId && CTxdStore_GetNumRefs (txdId) == 0 )
754783 {
755784 RwTexDictionary* pTxd = slot->rwTexDictonary ;
756785 RwListEntry* pRoot = &pTxd->textures .root ;
@@ -952,6 +981,17 @@ void CRenderWareSA::ProcessPendingIsolatedTxdParents()
952981 const unsigned short childTxdId = it->second .usTxdId ;
953982 const unsigned short parentTxdId = it->second .usParentTxdId ;
954983
984+ auto * pModelInfoForCheck = static_cast <CModelInfoSA*>(pGame->GetModelInfo (modelId));
985+ if (!pModelInfoForCheck || !pModelInfoForCheck->IsAllocatedInArchive ())
986+ {
987+ g_PendingIsolatedTxdParentsByModelId.erase (modelId);
988+ g_IsolatedTxdSlotsByModelId.erase (modelId);
989+ continue ;
990+ }
991+
992+ if (!pModelInfoForCheck->GetRwObject ())
993+ continue ;
994+
955995 if (CTxdStore_GetTxd (parentTxdId) == nullptr )
956996 continue ;
957997
@@ -969,14 +1009,20 @@ void CRenderWareSA::ProcessPendingIsolatedTxdParents()
9691009 RwObject* pRwObject = pModelInfo->GetRwObject ();
9701010 if (pRwObject)
9711011 {
972- const eModelInfoType modelType = pModelInfo->GetModelType ();
1012+ eModelInfoType modelType = pModelInfo->GetModelType ();
1013+ if (modelType == eModelInfoType::UNKNOWN)
1014+ {
1015+ if (pRwObject->type == RP_TYPE_ATOMIC)
1016+ modelType = eModelInfoType::ATOMIC;
1017+ else if (pRwObject->type == RP_TYPE_CLUMP)
1018+ modelType = eModelInfoType::CLUMP;
1019+ }
9731020 switch (modelType)
9741021 {
9751022 case eModelInfoType::PED:
9761023 case eModelInfoType::WEAPON:
9771024 case eModelInfoType::VEHICLE:
9781025 case eModelInfoType::CLUMP:
979- case eModelInfoType::UNKNOWN:
9801026 {
9811027 RebindClumpTexturesToTxd (reinterpret_cast <RpClump*>(pRwObject), childTxdId);
9821028 break ;
@@ -1112,11 +1158,14 @@ CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(unsigned short usModelId
11121158 for (unsigned short modelId : pReplacement->usedInModelIds )
11131159 {
11141160 auto itCache = modelInfoCache.find (modelId);
1115- if (itCache != modelInfoCache. end () && itCache-> second )
1161+ if (!pModelInfo )
11161162 {
11171163 CModelInfoSA* pModInfo = itCache->second ;
11181164 if (pModInfo->GetTextureDictionaryID () == usTxdId)
11191165 {
1166+
1167+ if (!pModelInfo->GetRwObject ())
1168+ continue ;
11201169 modelIds.push_back (modelId);
11211170 }
11221171 }
@@ -1432,8 +1481,6 @@ CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(unsigned short usModelId
14321481 else
14331482 {
14341483 CRenderWareSA::DebugTxdAddRef (usTxdId, " GetModelTexturesInfo-cache-hit" );
1435- if (pModelInfo->GetModelType () == eModelInfoType::PED)
1436- ((void (__cdecl*)(unsigned short ))FUNC_RemoveModel)(usModelId);
14371484 }
14381485
14391486 if (!pTxd)
@@ -1585,9 +1632,6 @@ bool CRenderWareSA::ModelInfoTXDAddTextures(SReplacementTextures* pReplacementTe
15851632 const unsigned short usParentTxdId = pParentInfo ? pParentInfo->GetTextureDictionaryID () : 0 ;
15861633
15871634 EnsureIsolatedTxdForRequestedModel (usModelId);
1588-
1589- if (pModelInfo->GetTextureDictionaryID () == usParentTxdId && usParentTxdId != 0 )
1590- return false ;
15911635 }
15921636 }
15931637 }
@@ -1796,25 +1840,13 @@ bool CRenderWareSA::ModelInfoTXDAddTextures(SReplacementTextures* pReplacementTe
17961840 for (unsigned short modelId : pReplacementTextures->usedInModelIds )
17971841 {
17981842 CModelInfoSA* pModelInfo = static_cast <CModelInfoSA*>(pGame->GetModelInfo (modelId));
1799- if (pModelInfo)
1800- targetModels.insert (pModelInfo);
1843+ if (!pModelInfo || !pModelInfo->GetRwObject ())
1844+ continue ;
1845+ targetModels.insert (pModelInfo);
18011846 }
18021847
18031848 for (CModelInfoSA* pModelInfo : targetModels)
18041849 ReplaceTextureInModel (pModelInfo, swapMap);
1805-
1806- for (CModelInfoSA* pModelInfo : targetModels)
1807- {
1808- if (!pModelInfo->GetRwObject ())
1809- {
1810- for (const auto & entry : swapMap)
1811- {
1812- if (entry.first )
1813- texturesStillReferenced.insert (entry.first );
1814- }
1815- break ;
1816- }
1817- }
18181850 }
18191851
18201852 std::unordered_set<RwTexture*> copiesToDestroy;
@@ -2754,7 +2786,6 @@ void CRenderWareSA::ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacemen
27542786 }
27552787 }
27562788
2757- bool bSwapFailed = false ;
27582789 if (!swapMap.empty ())
27592790 {
27602791 std::vector<CModelInfoSA*> targetModels;
@@ -2767,22 +2798,20 @@ void CRenderWareSA::ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacemen
27672798 if (!pModelInfo)
27682799 continue ;
27692800
2801+ if (!pModelInfo->GetRwObject ())
2802+ continue ;
2803+
27702804 if (seenModels.insert (pModelInfo).second )
27712805 targetModels.push_back (pModelInfo);
27722806 }
27732807
27742808 for (CModelInfoSA* pModelInfo : targetModels)
27752809 {
2776- ReplaceTextureInModel ( pModelInfo, swapMap);
2777- }
2810+ if (! pModelInfo)
2811+ continue ;
27782812
2779- for (CModelInfoSA* pModelInfo : targetModels)
2780- {
2781- if (!pModelInfo->GetRwObject ())
2782- {
2783- bSwapFailed = true ;
2784- break ;
2785- }
2813+ if (pModelInfo->GetRwObject ())
2814+ ReplaceTextureInModel (pModelInfo, swapMap);
27862815 }
27872816 }
27882817
@@ -2793,9 +2822,6 @@ void CRenderWareSA::ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacemen
27932822
27942823 bool bWasSwapped = swapMap.find (pOldTexture) != swapMap.end ();
27952824
2796- if (bSwapFailed && bWasSwapped)
2797- continue ;
2798-
27992825 if (!bWasSwapped && !IsReadableTexture (pOldTexture))
28002826 continue ;
28012827
0 commit comments