Skip to content

Commit 4ce785b

Browse files
committed
Addendum to 41e422c
1 parent bfaed0a commit 4ce785b

1 file changed

Lines changed: 136 additions & 13 deletions

File tree

Client/game_sa/CRenderWareSA.TextureReplacing.cpp

Lines changed: 136 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,11 @@ CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(unsigned short usModelId
14711471

14721472
if (bIsStaleEntry)
14731473
{
1474+
unsigned int uiTxdStreamId = usTxdId + pGame->GetBaseIDforTXD();
1475+
CStreamingInfo* pStreamInfoBusyCheck = pGame->GetStreaming()->GetStreamingInfo(uiTxdStreamId);
1476+
bool bBusy = pStreamInfoBusyCheck && (pStreamInfoBusyCheck->loadState == eModelLoadState::LOADSTATE_READING || pStreamInfoBusyCheck->loadState == eModelLoadState::LOADSTATE_FINISHING);
1477+
if (bBusy && !pCurrentTxd)
1478+
return nullptr;
14741479

14751480
// Cache replacement textures to re-apply after TXD reload
14761481
std::unordered_map<unsigned short, CModelInfoSA*> modelInfoCache;
@@ -1485,8 +1490,11 @@ CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(unsigned short usModelId
14851490
}
14861491

14871492
std::vector<std::pair<SReplacementTextures*, std::vector<unsigned short>>> replacementsToReapply;
1493+
std::vector<SReplacementTextures*> originalUsed;
14881494
for (SReplacementTextures* pReplacement : info.usedByReplacements)
14891495
{
1496+
if (pReplacement)
1497+
originalUsed.push_back(pReplacement);
14901498
std::vector<unsigned short> modelIds;
14911499
for (unsigned short modelId : pReplacement->usedInModelIds)
14921500
{
@@ -1693,18 +1701,47 @@ CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(unsigned short usModelId
16931701
}
16941702
info.usedByReplacements.clear();
16951703

1704+
auto restoreState = [&]()
1705+
{
1706+
for (SReplacementTextures* pReplacement : originalUsed)
1707+
{
1708+
if (!pReplacement)
1709+
continue;
1710+
if (std::find(info.usedByReplacements.begin(), info.usedByReplacements.end(), pReplacement) == info.usedByReplacements.end())
1711+
info.usedByReplacements.push_back(pReplacement);
1712+
}
1713+
for (auto& entry : replacementsToReapply)
1714+
{
1715+
SReplacementTextures* pReplacement = entry.first;
1716+
if (!pReplacement)
1717+
continue;
1718+
for (unsigned short modelId : entry.second)
1719+
pReplacement->usedInModelIds.insert(modelId);
1720+
}
1721+
};
1722+
16961723
if (pCurrentTxd)
16971724
{
16981725
info.pTxd = pCurrentTxd;
16991726
PopulateOriginalTextures(info, pCurrentTxd);
1727+
restoreState();
17001728
}
17011729
else
17021730
{
17031731
unsigned int uiTxdStreamId = usTxdId + pGame->GetBaseIDforTXD();
1704-
pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16);
1705-
pGame->GetStreaming()->LoadAllRequestedModels(true, "CRenderWareSA::GetModelTexturesInfo-TXD");
1706-
1707-
pModelInfo->Request(BLOCKING, "CRenderWareSA::GetModelTexturesInfo");
1732+
CStreamingInfo* pStreamInfo = pGame->GetStreaming()->GetStreamingInfo(uiTxdStreamId);
1733+
bool bLoaded = pStreamInfo && pStreamInfo->loadState == eModelLoadState::LOADSTATE_LOADED;
1734+
bool bBusyStream = pStreamInfo && (pStreamInfo->loadState == eModelLoadState::LOADSTATE_READING || pStreamInfo->loadState == eModelLoadState::LOADSTATE_FINISHING);
1735+
if (bBusyStream)
1736+
{
1737+
restoreState();
1738+
return nullptr;
1739+
}
1740+
if (!bLoaded)
1741+
{
1742+
pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16);
1743+
pGame->GetStreaming()->LoadAllRequestedModels(false, "GetModelTexturesInfo-txd");
1744+
}
17081745

17091746
unsigned short uiNewTxdId = pModelInfo->GetTextureDictionaryID();
17101747

@@ -1727,12 +1764,69 @@ CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(unsigned short usModelId
17271764
}
17281765
else
17291766
{
1730-
if (!info.bHasLeakedTextures && CTxdStore_GetNumRefs(usTxdId) > 0)
1731-
CRenderWareSA::DebugTxdRemoveRef(usTxdId, "GetModelTexturesInfo-blocking-fail");
1732-
else if (info.bHasLeakedTextures)
1733-
g_PendingLeakedTxdRefs.insert(usTxdId);
1734-
MapRemove(ms_ModelTexturesInfoMap, usTxdId);
1735-
return nullptr;
1767+
pGame->GetStreaming()->LoadAllRequestedModels(false, "GetModelTexturesInfo-txd-retry");
1768+
pCurrentTxd = CTxdStore_GetTxd(usTxdId);
1769+
1770+
if (pCurrentTxd)
1771+
{
1772+
info.pTxd = pCurrentTxd;
1773+
PopulateOriginalTextures(info, pCurrentTxd);
1774+
restoreState();
1775+
}
1776+
else
1777+
{
1778+
CStreamingInfo* pStreamInfoRetry = pGame->GetStreaming()->GetStreamingInfo(uiTxdStreamId);
1779+
bool bBusyRetry = pStreamInfoRetry && (pStreamInfoRetry->loadState == eModelLoadState::LOADSTATE_READING || pStreamInfoRetry->loadState == eModelLoadState::LOADSTATE_FINISHING);
1780+
if (bBusyRetry)
1781+
{
1782+
restoreState();
1783+
return nullptr;
1784+
}
1785+
1786+
// Second pass: if TXD still not present and stream isn't marked loaded, push a fresh request before the final load pass.
1787+
if (!pStreamInfoRetry || pStreamInfoRetry->loadState != eModelLoadState::LOADSTATE_LOADED)
1788+
pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16);
1789+
pGame->GetStreaming()->LoadAllRequestedModels(false, "GetModelTexturesInfo-txd-retry2");
1790+
pCurrentTxd = CTxdStore_GetTxd(usTxdId);
1791+
1792+
if (pCurrentTxd)
1793+
{
1794+
info.pTxd = pCurrentTxd;
1795+
PopulateOriginalTextures(info, pCurrentTxd);
1796+
}
1797+
else
1798+
{
1799+
CStreamingInfo* pStreamInfoRetry2 = pGame->GetStreaming()->GetStreamingInfo(uiTxdStreamId);
1800+
bool bBusy = pStreamInfoRetry2 && (pStreamInfoRetry2->loadState == eModelLoadState::LOADSTATE_READING || pStreamInfoRetry2->loadState == eModelLoadState::LOADSTATE_FINISHING);
1801+
if (bBusy)
1802+
{
1803+
restoreState();
1804+
return nullptr;
1805+
}
1806+
1807+
if (!pStreamInfoRetry2 || pStreamInfoRetry2->loadState != eModelLoadState::LOADSTATE_LOADED)
1808+
pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16);
1809+
pGame->GetStreaming()->LoadAllRequestedModels(true, "GetModelTexturesInfo-txd-retry3");
1810+
pCurrentTxd = CTxdStore_GetTxd(usTxdId);
1811+
1812+
if (pCurrentTxd)
1813+
{
1814+
info.pTxd = pCurrentTxd;
1815+
PopulateOriginalTextures(info, pCurrentTxd);
1816+
restoreState();
1817+
}
1818+
else
1819+
{
1820+
restoreState();
1821+
if (!info.bHasLeakedTextures && CTxdStore_GetNumRefs(usTxdId) > 0)
1822+
CRenderWareSA::DebugTxdRemoveRef(usTxdId, "GetModelTexturesInfo-blocking-fail");
1823+
else if (info.bHasLeakedTextures)
1824+
g_PendingLeakedTxdRefs.insert(usTxdId);
1825+
MapRemove(ms_ModelTexturesInfoMap, usTxdId);
1826+
return nullptr;
1827+
}
1828+
}
1829+
}
17361830
}
17371831
}
17381832

@@ -1807,10 +1901,39 @@ CModelTexturesInfo* CRenderWareSA::GetModelTexturesInfo(unsigned short usModelId
18071901
if (!pTxd)
18081902
{
18091903
unsigned int uiTxdStreamId = usTxdId + pGame->GetBaseIDforTXD();
1810-
pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16);
1811-
pGame->GetStreaming()->LoadAllRequestedModels(true, "CRenderWareSA::GetModelTexturesInfo-TXD");
1812-
1904+
CStreamingInfo* pStreamInfo = pGame->GetStreaming()->GetStreamingInfo(uiTxdStreamId);
1905+
bool bLoaded = pStreamInfo && pStreamInfo->loadState == eModelLoadState::LOADSTATE_LOADED;
1906+
if (!bLoaded)
1907+
{
1908+
pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16);
1909+
pGame->GetStreaming()->LoadAllRequestedModels(false, "GetModelTexturesInfo-txd");
1910+
}
18131911
pTxd = CTxdStore_GetTxd(usTxdId);
1912+
1913+
if (!pTxd)
1914+
{
1915+
CStreamingInfo* pStreamInfoRetry = pGame->GetStreaming()->GetStreamingInfo(uiTxdStreamId);
1916+
bool bBusy = pStreamInfoRetry && (pStreamInfoRetry->loadState == eModelLoadState::LOADSTATE_READING || pStreamInfoRetry->loadState == eModelLoadState::LOADSTATE_FINISHING);
1917+
if (bBusy)
1918+
return nullptr;
1919+
1920+
pGame->GetStreaming()->LoadAllRequestedModels(false, "GetModelTexturesInfo-txd-retry");
1921+
pTxd = CTxdStore_GetTxd(usTxdId);
1922+
1923+
if (!pTxd)
1924+
{
1925+
CStreamingInfo* pStreamInfoRetry2 = pGame->GetStreaming()->GetStreamingInfo(uiTxdStreamId);
1926+
bool bBusyRetry = pStreamInfoRetry2 && (pStreamInfoRetry2->loadState == eModelLoadState::LOADSTATE_READING || pStreamInfoRetry2->loadState == eModelLoadState::LOADSTATE_FINISHING);
1927+
if (bBusyRetry)
1928+
return nullptr;
1929+
1930+
if (!pStreamInfoRetry2 || pStreamInfoRetry2->loadState != eModelLoadState::LOADSTATE_LOADED)
1931+
pGame->GetStreaming()->RequestModel(uiTxdStreamId, 0x16);
1932+
pGame->GetStreaming()->LoadAllRequestedModels(false, "GetModelTexturesInfo-txd-retry2");
1933+
pTxd = CTxdStore_GetTxd(usTxdId);
1934+
}
1935+
}
1936+
18141937
if (pTxd)
18151938
CRenderWareSA::DebugTxdAddRef(usTxdId, "GetModelTexturesInfo-cache-miss");
18161939
}

0 commit comments

Comments
 (0)