From a020269bb417498678ef29cfc2d7bf6e6b2f6414 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Thu, 20 Feb 2025 20:33:28 +0300 Subject: [PATCH] Fix invalid references counter to TXD after engineSetTXDID --- Client/game_sa/CModelInfoSA.cpp | 17 ++++++++++++++--- .../game_sa/CRenderWareSA.TextureReplacing.cpp | 4 +++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 8f1b624b90..31646b2a96 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -801,8 +801,17 @@ 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 + // TODO: pRwObject can have to unloaded TXD + 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 +819,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 f8c4313079..c635628867 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);