diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 8f1b624b906..16eecbc9978 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -801,8 +801,18 @@ void CModelInfoSA::SetTextureDictionaryID(unsigned short usID) if (!m_pInterface) return; - // Remove ref from the old TXD - CTxdStore_RemoveRef(m_pInterface->usTextureDictionary); + // CBaseModelInfo::AddRef adds references to model and TXD + // We need transfer added references from old TXD to new TXD + size_t referencesCount = m_pInterface->usNumberOfRefs; + + // +1 reference for active rwObject + // The current textures will be removed in RpAtomicDestroy + // RenderWare uses an additional reference counter per texture + if (m_pInterface->pRwObject) + referencesCount++; + + for (size_t i = 0; i < referencesCount; i++) + CTxdStore_RemoveRef(m_pInterface->usTextureDictionary); // Store vanilla TXD ID if (!MapContains(ms_DefaultTxdIDMap, m_dwModelID)) @@ -810,7 +820,9 @@ void CModelInfoSA::SetTextureDictionaryID(unsigned short usID) // Set new TXD and increase ref of it m_pInterface->usTextureDictionary = usID; - CTxdStore_AddRef(usID); + + for (size_t i = 0; i < referencesCount; i++) + CTxdStore_AddRef(usID); } void CModelInfoSA::ResetTextureDictionaryID() diff --git a/Client/game_sa/CRenderWareSA.TextureReplacing.cpp b/Client/game_sa/CRenderWareSA.TextureReplacing.cpp index f8c43130790..c6356288676 100644 --- a/Client/game_sa/CRenderWareSA.TextureReplacing.cpp +++ b/Client/game_sa/CRenderWareSA.TextureReplacing.cpp @@ -266,8 +266,10 @@ void CRenderWareSA::ModelInfoTXDRemoveTextures(SReplacementTextures* pReplacemen ListRemove(currentTextures, pOriginalTexture); } assert(currentTextures.empty()); - #endif + int32_t refsCount = CTxdStore_GetNumRefs(pInfo->usTxdId); + assert(refsCount > 0, "Should have at least one TXD reference here"); + #endif // Remove info CTxdStore_RemoveRef(pInfo->usTxdId); MapRemove(ms_ModelTexturesInfoMap, usTxdId);