@@ -1121,27 +1121,58 @@ void CRenderWareSA::TxdForceUnload(ushort usTxdId, bool bDestroyTextures)
11211121 if (!pTxd)
11221122 return ;
11231123
1124- // We can abandon the textures instead of destroy. It might be safer, but will cause a memory leak
1124+ constexpr int kMaxTextureUnrefs = 10000 ;
1125+ constexpr int kMaxTxdUnrefs = 1000 ;
1126+
11251127 if (bDestroyTextures)
11261128 {
1127- // Unref the textures
11281129 std::vector<RwTexture*> textureList;
1129- pGame-> GetRenderWareSA ()-> GetTxdTextures (textureList, pTxd);
1130- for (std::vector< RwTexture*>::iterator iter = textureList. begin (); iter != textureList. end (); iter++ )
1130+ GetTxdTextures (textureList, pTxd);
1131+ for (RwTexture* pTexture : textureList)
11311132 {
1132- RwTexture* pTexture = *iter;
1133- while (pTexture->refs > 1 )
1133+ if (!pTexture)
1134+ continue ;
1135+
1136+ if (pTexture->refs < 1 )
1137+ continue ;
1138+
1139+ int textureUnrefCount = 0 ;
1140+ while (pTexture->refs > 1 && textureUnrefCount < kMaxTextureUnrefs )
1141+ {
1142+ RwTextureDestroy (pTexture);
1143+ ++textureUnrefCount;
1144+ }
1145+
1146+ int remainingRefs = pTexture->refs ;
1147+ if (textureUnrefCount >= kMaxTextureUnrefs && remainingRefs > 1 )
1148+ {
1149+ AddReportLog (8625 , SString (" TxdForceUnload: Texture unref limit hit for TXD %d (refs remaining: %d)" , usTxdId, remainingRefs));
1150+ continue ;
1151+ }
1152+
1153+ if (remainingRefs == 1 )
11341154 RwTextureDestroy (pTexture);
1135- RwTextureDestroy (pTexture);
11361155 }
11371156 }
11381157
1139- // Need to have at least one ref for RemoveRef to work correctly
11401158 if (CTxdStore_GetNumRefs (usTxdId) == 0 )
11411159 CRenderWareSA::DebugTxdAddRef (usTxdId);
11421160
1143- while (CTxdStore_GetNumRefs (usTxdId) > 0 )
1161+ int txdUnrefCount = 0 ;
1162+ while (CTxdStore_GetNumRefs (usTxdId) > 0 && txdUnrefCount < kMaxTxdUnrefs )
1163+ {
11441164 CRenderWareSA::DebugTxdRemoveRef (usTxdId);
1165+ ++txdUnrefCount;
1166+ }
1167+
1168+ if (txdUnrefCount >= kMaxTxdUnrefs )
1169+ {
1170+ int remainingTxdRefs = CTxdStore_GetNumRefs (usTxdId);
1171+ if (remainingTxdRefs > 0 )
1172+ {
1173+ AddReportLog (8626 , SString (" TxdForceUnload: TXD unref limit hit for TXD %d (refs remaining: %d)" , usTxdId, remainingTxdRefs));
1174+ }
1175+ }
11451176}
11461177
11471178namespace
0 commit comments