Skip to content

Commit 8cd1542

Browse files
committed
Fix SA crash @ 0x0116C9C5 (CTxdStore::GetTxd_0). There was prior fixes for this crash offset, but they didn't fix all cases/paths.
1 parent 4ab8484 commit 8cd1542

1 file changed

Lines changed: 18 additions & 12 deletions

File tree

Client/game_sa/CModelInfoSA.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,8 @@ void CModelInfoSA::Remove()
608608
// Remove our reference
609609
if (m_pInterface->usNumberOfRefs > 0)
610610
{
611-
if (CTxdStore_GetTxd(m_pInterface->usTextureDictionary) != nullptr)
611+
if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(m_pInterface->usTextureDictionary) &&
612+
CTxdStore_GetTxd(m_pInterface->usTextureDictionary) != nullptr)
612613
CTxdStore_RemoveRef(m_pInterface->usTextureDictionary);
613614
m_pInterface->usNumberOfRefs--;
614615
}
@@ -1104,6 +1105,10 @@ void CModelInfoSA::SetTextureDictionaryID(unsigned short usID)
11041105
if (usOldTxdId == usID)
11051106
return;
11061107

1108+
// CTxdStore functions (GetTxd, AddRef, RemoveRef) crash on free pool entries.
1109+
if (!pGame || pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usID))
1110+
return;
1111+
11071112
// Slot allocated (e.g. via engineRequestTXD) but TXD data isn't loaded yet.
11081113
// For unloaded models without geometry, record the new TXD ID and transfer
11091114
// entity refs so callers' pre-added refs are consumed. Loaded models fall
@@ -1113,9 +1118,6 @@ void CModelInfoSA::SetTextureDictionaryID(unsigned short usID)
11131118
// texture data arrives later via engineImageLinkTXD + restream.
11141119
if (CTxdStore_GetTxd(usID) == nullptr)
11151120
{
1116-
if (!pGame || pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usID))
1117-
return;
1118-
11191121
if (!m_pInterface->pRwObject)
11201122
{
11211123
if (!MapContains(ms_DefaultTxdIDMap, static_cast<unsigned short>(m_dwModelID)))
@@ -1131,7 +1133,7 @@ void CModelInfoSA::SetTextureDictionaryID(unsigned short usID)
11311133
for (size_t i = 0; i < referencesCount; i++)
11321134
CTxdStore_AddRef(usID);
11331135

1134-
if (CTxdStore_GetTxd(usOldTxdId) != nullptr)
1136+
if (!pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usOldTxdId) && CTxdStore_GetTxd(usOldTxdId) != nullptr)
11351137
{
11361138
for (size_t i = 0; i < referencesCount; i++)
11371139
CTxdStore_RemoveRef(usOldTxdId);
@@ -1196,9 +1198,9 @@ void CModelInfoSA::SetTextureDictionaryID(unsigned short usID)
11961198
}
11971199
}
11981200

1199-
// Release old TXD refs after rebinding completes
1200-
// Only release if old slot is still valid to avoid crash on stale/orphaned TXD slots
1201-
if (CTxdStore_GetTxd(usOldTxdId) != nullptr)
1201+
// Release old TXD refs after rebinding. Skip if the slot was freed between
1202+
// capturing usOldTxdId and here - CTxdStore functions crash on free entries.
1203+
if (!pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(usOldTxdId) && CTxdStore_GetTxd(usOldTxdId) != nullptr)
12021204
{
12031205
for (size_t i = 0; i < referencesCount; i++)
12041206
CTxdStore_RemoveRef(usOldTxdId);
@@ -2198,7 +2200,8 @@ void CModelInfoSA::ResetVehicleDummies(bool bRemoveFromDummiesMap)
21982200
{
21992201
if (pVehicleModel && pVehicleModel->usNumberOfRefs > 0)
22002202
{
2201-
if (CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr)
2203+
if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(pVehicleModel->usTextureDictionary) &&
2204+
CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr)
22022205
CTxdStore_RemoveRef(pVehicleModel->usTextureDictionary);
22032206
pVehicleModel->usNumberOfRefs--;
22042207
}
@@ -2215,7 +2218,8 @@ void CModelInfoSA::ResetVehicleDummies(bool bRemoveFromDummiesMap)
22152218

22162219
if (pVehicleModel->usNumberOfRefs > 0)
22172220
{
2218-
if (CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr)
2221+
if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(pVehicleModel->usTextureDictionary) &&
2222+
CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr)
22192223
CTxdStore_RemoveRef(pVehicleModel->usTextureDictionary);
22202224
pVehicleModel->usNumberOfRefs--;
22212225
}
@@ -2246,7 +2250,8 @@ void CModelInfoSA::ResetAllVehicleDummies()
22462250
{
22472251
if (pVehicleModel && pVehicleModel->usNumberOfRefs > 0)
22482252
{
2249-
if (CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr)
2253+
if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(pVehicleModel->usTextureDictionary) &&
2254+
CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr)
22502255
CTxdStore_RemoveRef(pVehicleModel->usTextureDictionary);
22512256
pVehicleModel->usNumberOfRefs--;
22522257
}
@@ -2260,7 +2265,8 @@ void CModelInfoSA::ResetAllVehicleDummies()
22602265

22612266
if (pVehicleModel->usNumberOfRefs > 0)
22622267
{
2263-
if (CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr)
2268+
if (pGame && !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(pVehicleModel->usTextureDictionary) &&
2269+
CTxdStore_GetTxd(pVehicleModel->usTextureDictionary) != nullptr)
22642270
CTxdStore_RemoveRef(pVehicleModel->usTextureDictionary);
22652271
pVehicleModel->usNumberOfRefs--;
22662272
}

0 commit comments

Comments
 (0)