diff --git a/Client/game_sa/CRenderWareSA.ShaderMatching.cpp b/Client/game_sa/CRenderWareSA.ShaderMatching.cpp index 8af89402d8..753156923e 100644 --- a/Client/game_sa/CRenderWareSA.ShaderMatching.cpp +++ b/Client/game_sa/CRenderWareSA.ShaderMatching.cpp @@ -112,6 +112,25 @@ void CMatchChannelManager::RemoveTexture(STexInfo* pTexInfo) dassert(MapContains(pTexNameInfo->usedByTexInfoList, pTexInfo)); MapRemove(pTexNameInfo->usedByTexInfoList, pTexInfo); pTexInfo->pAssociatedTexNameInfo = NULL; + + MaybeDeleteTexNameInfo(pTexNameInfo); +} + +////////////////////////////////////////////////////////////////// +// +// CMatchChannelManager::MaybeDeleteTexNameInfo +// +// Both lists together are every reference that can exist: the texinfos +// pointing back at it, and the channels holding it in m_MatchedTextureList. +// +////////////////////////////////////////////////////////////////// +void CMatchChannelManager::MaybeDeleteTexNameInfo(STexNameInfo* pTexNameInfo) +{ + if (pTexNameInfo->usedByTexInfoList.empty() && pTexNameInfo->matchChannelList.empty()) + { + MapRemove(m_AllTextureList, pTexNameInfo->strTextureName); + delete pTexNameInfo; + } } ////////////////////////////////////////////////////////////////// @@ -614,6 +633,7 @@ void CMatchChannelManager::ProcessRematchTexturesQueue() pChannel->RemoveTexture(pTexNameInfo); MapRemove(pTexNameInfo->matchChannelList, pChannel); pTexNameInfo->ResetReplacementResults(); // Do this here as it won't get picked up in RecalcEverything now + MaybeDeleteTexNameInfo(pTexNameInfo); } // Rematch against texture list @@ -822,6 +842,7 @@ void CMatchChannelManager::DeleteChannel(CMatchChannel* pChannel) // Reset shader matches now as this channel is going pTexNameInfo->ResetReplacementResults(); + MaybeDeleteTexNameInfo(pTexNameInfo); } #ifdef SHADER_DEBUG_CHECKS diff --git a/Client/game_sa/CRenderWareSA.ShaderMatching.h b/Client/game_sa/CRenderWareSA.ShaderMatching.h index dceb1e3f12..0f31c96150 100644 --- a/Client/game_sa/CRenderWareSA.ShaderMatching.h +++ b/Client/game_sa/CRenderWareSA.ShaderMatching.h @@ -292,6 +292,7 @@ class CMatchChannelManager STexShaderReplacement* UpdateTexShaderReplacement(STexNameInfo* pTexNameInfo, CClientEntityBase* pClientEntity, int iEntityType); void UpdateTexShaderReplacementNoEntity(STexNameInfo* pTexNameInfo, STexShaderReplacement& texNoEntityShader, int iEntityType); + void MaybeDeleteTexNameInfo(STexNameInfo* pTexNameInfo); void FinalizeLayers(SShaderInfoLayers& shaderLayers); bool m_bChangesPending; diff --git a/Client/game_sa/CRenderWareSA.ShaderSupport.cpp b/Client/game_sa/CRenderWareSA.ShaderSupport.cpp index aa2927788c..c4308c0ef6 100644 --- a/Client/game_sa/CRenderWareSA.ShaderSupport.cpp +++ b/Client/game_sa/CRenderWareSA.ShaderSupport.cpp @@ -77,8 +77,7 @@ static CMappedArray ms_txdStreamEventList; __declspec(noinline) void _cdecl OnStreamingAddedTxd(DWORD dwTxdId) { ushort usTxdId = (ushort)dwTxdId; - // Ensure there are no previous events for this txd - ms_txdStreamEventList.remove(STxdStreamEvent(false, usTxdId)); + // Drop a duplicate 'added' only - a pending 'removed' still has to reach the watch ms_txdStreamEventList.remove(STxdStreamEvent(true, usTxdId)); // Append 'added' ms_txdStreamEventList.push_back(STxdStreamEvent(true, usTxdId)); @@ -113,7 +112,7 @@ static void __declspec(naked) HOOK_CTxdStore_SetupTxdParent() //////////////////////////////////////////////////////////////// __declspec(noinline) void _cdecl OnStreamingRemoveTxd(DWORD dwTxdId) { - ushort usTxdId = (ushort)dwTxdId - pGame->GetBaseIDforTXD(); + ushort usTxdId = (ushort)dwTxdId; // Ensure there are no previous events for this txd ms_txdStreamEventList.remove(STxdStreamEvent(true, usTxdId)); ms_txdStreamEventList.remove(STxdStreamEvent(false, usTxdId)); @@ -131,9 +130,9 @@ static void __declspec(naked) HOOK_CTxdStore_RemoveTxd() { // Hooked from 731E90 6 bytes - // esi - txd id + 20000 + // __cdecl txd id - esi still holds the caller's value at this address pushad - push esi + push [esp+32+4*1] call OnStreamingRemoveTxd add esp, 4 popad