Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions Client/game_sa/CGameSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,33 @@ bool CGameSA::SetBuildingPoolSize(size_t size)
return status;
}

void CGameSA::UnloadUnusedModels()
{
// Unload DFF's
// CJ should not be unloaded
const std::size_t baseIdForTxd = GetBaseIDforTXD();
for (std::size_t id = 1; id < baseIdForTxd; id++)
{
CStreamingInfo* streamingInfo = m_pStreaming->GetStreamingInfo(id);
if (streamingInfo->loadState != eModelLoadState::LOADSTATE_NOT_LOADED && streamingInfo->sizeInBlocks > 0)
{
CModelInfoSA& model = ModelInfo[id];
if (model.GetRefCount() == 0)
model.UnloadUnused();
};
}
// Unload TXD
for (std::size_t id = baseIdForTxd; id < GetBaseIDforCOL(); id++)
{
CStreamingInfo* streamingInfo = m_pStreaming->GetStreamingInfo(id);
std::size_t refsCount = GetPools()->GetTxdPool().GetRefsCount(id - baseIdForTxd);
if (streamingInfo->loadState != eModelLoadState::LOADSTATE_NOT_LOADED && streamingInfo->sizeInBlocks > 0 && refsCount == 0)
{
GetStreaming()->RemoveModel(id);
}
}
}

// Ensure models have the default lod distances
void CGameSA::ResetModelLodDistances()
{
Expand Down
2 changes: 2 additions & 0 deletions Client/game_sa/CGameSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ class CGameSA : public CGame

bool SetBuildingPoolSize(size_t size);

void UnloadUnusedModels();

private:
CPools* m_pPools;
CPlayerInfo* m_pPlayerInfo;
Expand Down
9 changes: 3 additions & 6 deletions Client/game_sa/CModelInfoSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,8 @@ void CModelInfoSA::Remove()

bool CModelInfoSA::UnloadUnused()
{
m_pInterface = ppModelInfo[m_dwModelID];

if (m_pInterface->usNumberOfRefs == 0 && !m_pCustomClump && !m_pCustomColModel)
{
pGame->GetStreaming()->RemoveModel(m_dwModelID);
Expand Down Expand Up @@ -743,7 +745,7 @@ CBoundingBox* CModelInfoSA::GetBoundingBox()
bool CModelInfoSA::IsValid()
{
if (m_dwModelID >= MODELINFO_DFF_MAX && m_dwModelID < MODELINFO_TXD_MAX)
return !pGame->GetPools()->IsFreeTextureDictonarySlot(m_dwModelID - MODELINFO_DFF_MAX);
return !pGame->GetPools()->GetTxdPool().IsFreeTextureDictonarySlot(m_dwModelID - MODELINFO_DFF_MAX);

if (m_dwModelID >= pGame->GetBaseIDforTXD() && m_dwModelID < pGame->GetCountOfAllFileIDs())
return true;
Expand Down Expand Up @@ -1077,11 +1079,6 @@ void CModelInfoSA::ModelAddRef(EModelRequestType requestType, const char* szTag)
m_dwReferences++;
}

int CModelInfoSA::GetRefCount()
{
return static_cast<int>(m_dwReferences);
}

void CModelInfoSA::RemoveRef(bool bRemoveExtraGTARef)
{
// Decrement the references
Expand Down
2 changes: 1 addition & 1 deletion Client/game_sa/CModelInfoSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ class CModelInfoSA : public CModelInfo
static void StaticResetAlphaTransparencies();

void ModelAddRef(EModelRequestType requestType, const char* szTag);
int GetRefCount();
int GetRefCount() const override { return static_cast<int>(m_dwReferences); };
void RemoveRef(bool bRemoveExtraGTARef = false);
bool ForceUnload();

Expand Down
2 changes: 1 addition & 1 deletion Client/game_sa/CPoolSAInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class CPoolSAInterface
return !IsEmpty(index);
}

B* GetObject(std::int32_t objectIndex) { return &m_pObjects[objectIndex]; }
B* GetObject(std::int32_t objectIndex) const { return &m_pObjects[objectIndex]; }

uint GetObjectIndex(B* pObject) { return ((DWORD)pObject - (DWORD)m_pObjects) / sizeof(B); }

Expand Down
41 changes: 0 additions & 41 deletions Client/game_sa/CPoolsSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
#include "CTrailerSA.h"
#include "CTrainSA.h"
#include "CWorldSA.h"
#include "CKeyGenSA.h"
#include "CFileLoaderSA.h"
#include "CPtrNodeSingleListSA.h"

extern CGameSA* pGame;

Expand All @@ -35,7 +32,6 @@ CPoolsSA::CPoolsSA()
m_ppPedPoolInterface = (CPoolSAInterface<CPedSAInterface>**)0xB74490;
m_ppObjectPoolInterface = (CPoolSAInterface<CObjectSAInterface>**)0xB7449C;
m_ppVehiclePoolInterface = (CPoolSAInterface<CVehicleSAInterface>**)0xB74494;
m_ppTxdPoolInterface = (CPoolSAInterface<CTextureDictonarySAInterface>**)0xC8800C;

m_bGetVehicleEnabled = true;
}
Expand Down Expand Up @@ -1107,40 +1103,3 @@ void CPoolsSA::InvalidateLocalPlayerClientEntity()
{
m_pedPool.arrayOfClientEntities[0] = {m_pedPool.arrayOfClientEntities[0].pEntity, nullptr};
}

unsigned int CPoolsSA::AllocateTextureDictonarySlot(uint uiSlotId, std::string& strTxdName)
{
CTextureDictonarySAInterface* pTxd = (*m_ppTxdPoolInterface)->AllocateAt(uiSlotId);
if (!pTxd)
return -1;

strTxdName.resize(24);

pTxd->usUsagesCount = 0;
pTxd->hash = pGame->GetKeyGen()->GetUppercaseKey(strTxdName.c_str());
pTxd->rwTexDictonary = nullptr;
pTxd->usParentIndex = -1;

return (*m_ppTxdPoolInterface)->GetObjectIndex(pTxd);
}

void CPoolsSA::RemoveTextureDictonarySlot(uint uiTxdId)
{
if (!(*m_ppTxdPoolInterface)->IsContains(uiTxdId))
return;

typedef uint(__cdecl * Function_TxdReleaseSlot)(uint uiTxdId);
((Function_TxdReleaseSlot)(0x731E90))(uiTxdId);

(*m_ppTxdPoolInterface)->Release(uiTxdId);
}

bool CPoolsSA::IsFreeTextureDictonarySlot(uint uiTxdId)
{
return (*m_ppTxdPoolInterface)->IsEmpty(uiTxdId);
}

ushort CPoolsSA::GetFreeTextureDictonarySlot()
{
return (*m_ppTxdPoolInterface)->GetFreeSlot();
}
11 changes: 3 additions & 8 deletions Client/game_sa/CPoolsSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
#include "CVehicleSA.h"
#include "CObjectSA.h"
#include "CBuildingSA.h"
#include "CTextureDictonarySA.h"
#include "CBuildingsPoolSA.h"
#include "CDummyPoolSA.h"
#include "CTxdPoolSA.h"

#define INVALID_POOL_ARRAY_ID 0xFFFFFFFF

Expand Down Expand Up @@ -91,14 +91,9 @@ class CPoolsSA : public CPools
void ResetPedPoolCount() { m_pedPool.ulCount = 0; }
void InvalidateLocalPlayerClientEntity();

uint AllocateTextureDictonarySlot(uint uiSlotID, std::string& strTxdName);
void RemoveTextureDictonarySlot(uint uiTxdId);
bool IsFreeTextureDictonarySlot(uint uiTxdId);

ushort GetFreeTextureDictonarySlot();

CBuildingsPool& GetBuildingsPool() noexcept override { return m_BuildingsPool; };
CDummyPool& GetDummyPool() noexcept { return m_DummyPool; };
CTxdPool& GetTxdPool() noexcept { return m_TxdPool; };

private:
// Pools
Expand All @@ -109,10 +104,10 @@ class CPoolsSA : public CPools
CPoolSAInterface<CPedSAInterface>** m_ppPedPoolInterface;
CPoolSAInterface<CObjectSAInterface>** m_ppObjectPoolInterface;
CPoolSAInterface<CVehicleSAInterface>** m_ppVehiclePoolInterface;
CPoolSAInterface<CTextureDictonarySAInterface>** m_ppTxdPoolInterface;

CBuildingsPoolSA m_BuildingsPool;
CDummyPoolSA m_DummyPool;
CTxdPoolSA m_TxdPool;

bool m_bGetVehicleEnabled;
};
Expand Down
66 changes: 66 additions & 0 deletions Client/game_sa/CTxdPoolSA.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
*
* Multi Theft Auto is available from https://www.multitheftauto.com/
*
*****************************************************************************/

#include "StdInc.h"
#include "CTxdPoolSA.h"
#include "CGameSA.h"
#include "CKeyGenSA.h"

extern CGameSA* pGame;

CTxdPoolSA::CTxdPoolSA()
{
m_ppTxdPoolInterface = (CPoolSAInterface<CTextureDictonarySAInterface>**)0xC8800C;
}

std::uint32_t CTxdPoolSA::AllocateTextureDictonarySlot(std::uint32_t uiSlotId, std::string& strTxdName)
{
CTextureDictonarySAInterface* pTxd = (*m_ppTxdPoolInterface)->AllocateAt(uiSlotId);
if (!pTxd)
return -1;

strTxdName.resize(24);

pTxd->usUsagesCount = 0;
pTxd->hash = pGame->GetKeyGen()->GetUppercaseKey(strTxdName.c_str());
pTxd->rwTexDictonary = nullptr;
pTxd->usParentIndex = -1;

return (*m_ppTxdPoolInterface)->GetObjectIndex(pTxd);
}

void CTxdPoolSA::RemoveTextureDictonarySlot(std::uint32_t uiTxdId)
{
if (!(*m_ppTxdPoolInterface)->IsContains(uiTxdId))
return;

typedef std::uint32_t(__cdecl * Function_TxdReleaseSlot)(std::uint32_t uiTxdId);
((Function_TxdReleaseSlot)(0x731E90))(uiTxdId);

(*m_ppTxdPoolInterface)->Release(uiTxdId);
}

bool CTxdPoolSA::IsFreeTextureDictonarySlot(std::uint32_t uiTxdId)
{
return (*m_ppTxdPoolInterface)->IsEmpty(uiTxdId);
}

std::uint16_t CTxdPoolSA::GetFreeTextureDictonarySlot()
{
return (*m_ppTxdPoolInterface)->GetFreeSlot();
}

std::uint16_t CTxdPoolSA::GetRefsCount(std::uint16_t slot) const
{
CTextureDictonarySAInterface* pTxd = (*m_ppTxdPoolInterface)->GetObject(slot);
if (!pTxd)
return -1;

return pTxd->usUsagesCount;
}
32 changes: 32 additions & 0 deletions Client/game_sa/CTxdPoolSA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
*
* Multi Theft Auto is available from https://www.multitheftauto.com/
*
*****************************************************************************/

#pragma once

#include <game/CTxdPool.h>
#include "CPoolSAInterface.h"
#include "CBuildingSA.h"
#include "CTextureDictonarySA.h"

class CTxdPoolSA final : public CTxdPool
{
public:
CTxdPoolSA();
~CTxdPoolSA() = default;

std::uint32_t AllocateTextureDictonarySlot(std::uint32_t uiSlotID, std::string& strTxdName);
void RemoveTextureDictonarySlot(std::uint32_t uiTxdId);
bool IsFreeTextureDictonarySlot(std::uint32_t uiTxdId);

std::uint16_t GetFreeTextureDictonarySlot();
std::uint16_t GetRefsCount(std::uint16_t slot) const;

private:
CPoolSAInterface<CTextureDictonarySAInterface>** m_ppTxdPoolInterface;
};
2 changes: 2 additions & 0 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6833,6 +6833,8 @@ void CClientGame::RestreamWorld()

g_pGame->GetStreaming()->RemoveBigBuildings();
g_pGame->GetStreaming()->ReinitStreaming();

g_pGame->UnloadUnusedModels();
}

void CClientGame::ReinitMarkers()
Expand Down
4 changes: 2 additions & 2 deletions Client/mods/deathmatch/logic/CClientModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ void CClientModel::RestoreDFF(CModelInfo* pModelInfo)

bool CClientModel::AllocateTXD(std::string &strTxdName)
{
uint uiSlotID = g_pGame->GetPools()->AllocateTextureDictonarySlot(m_iModelID - MAX_MODEL_DFF_ID, strTxdName);
uint uiSlotID = g_pGame->GetPools()->GetTxdPool().AllocateTextureDictonarySlot(m_iModelID - MAX_MODEL_DFF_ID, strTxdName);
if (uiSlotID != -1)
{
m_bAllocatedByUs = true;
Expand All @@ -237,6 +237,6 @@ void CClientModel::RestoreTXD(CModelInfo* pModelInfo)
pModelInfo->SetTextureDictionaryID(0);
}

g_pGame->GetPools()->RemoveTextureDictonarySlot(uiTextureDictonarySlotID);
g_pGame->GetPools()->GetTxdPool().RemoveTextureDictonarySlot(uiTextureDictonarySlotID);
g_pGame->GetStreaming()->SetStreamingInfo(pModelInfo->GetModel(), 0, 0, 0, -1);
}
2 changes: 1 addition & 1 deletion Client/mods/deathmatch/logic/CClientModelManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ int CClientModelManager::GetFirstFreeModelID(void)

int CClientModelManager::GetFreeTxdModelID()
{
ushort usTxdId = g_pGame->GetPools()->GetFreeTextureDictonarySlot();
ushort usTxdId = g_pGame->GetPools()->GetTxdPool().GetFreeTextureDictonarySlot();
if (usTxdId == -1)
return INVALID_MODEL_ID;
return MAX_MODEL_DFF_ID + usTxdId;
Expand Down
1 change: 1 addition & 0 deletions Client/sdk/game/CGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,5 @@ class __declspec(novtable) CGame

virtual bool SetBuildingPoolSize(size_t size) = 0;

virtual void UnloadUnusedModels() = 0;
};
2 changes: 1 addition & 1 deletion Client/sdk/game/CModelInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class CModelInfo

virtual void ModelAddRef(EModelRequestType requestType, const char* szTag /* = NULL*/) = 0;
virtual void RemoveRef(bool bRemoveExtraGTARef = false) = 0;
virtual int GetRefCount() = 0;
virtual int GetRefCount() const = 0;
virtual bool ForceUnload() = 0;
virtual bool UnloadUnused() = 0;
virtual void DeallocateModel() = 0;
Expand Down
10 changes: 3 additions & 7 deletions Client/sdk/game/CPools.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "Common.h"
#include "CBuildingsPool.h"
#include "CDummyPool.h"
#include "CTxdPool.h"

class CClientEntity;
class CEntity;
Expand Down Expand Up @@ -107,12 +108,7 @@ class CPools
virtual void ResetPedPoolCount() = 0;
virtual void InvalidateLocalPlayerClientEntity() = 0;

virtual uint AllocateTextureDictonarySlot(uint uiSlotID, std::string& strTxdName) = 0;
virtual void RemoveTextureDictonarySlot(uint uiTxdID) = 0;
virtual bool IsFreeTextureDictonarySlot(uint uiTxdID) = 0;

virtual ushort GetFreeTextureDictonarySlot() = 0;

virtual CBuildingsPool& GetBuildingsPool() noexcept = 0;
virtual CDummyPool& GetDummyPool() noexcept = 0;
virtual CDummyPool& GetDummyPool() noexcept = 0;
virtual CTxdPool& GetTxdPool() noexcept = 0;
};
23 changes: 23 additions & 0 deletions Client/sdk/game/CTxdPool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
*
* Multi Theft Auto is available from https://www.multitheftauto.com/
*
*****************************************************************************/

#pragma once

#include "Common.h"

class CTxdPool
{
public:
virtual std::uint32_t AllocateTextureDictonarySlot(std::uint32_t uiSlotID, std::string& strTxdName) = 0;
virtual void RemoveTextureDictonarySlot(std::uint32_t uiTxdID) = 0;
virtual bool IsFreeTextureDictonarySlot(std::uint32_t uiTxdID) = 0;

virtual std::uint16_t GetFreeTextureDictonarySlot() = 0;
virtual std::uint16_t GetRefsCount(std::uint16_t slot) const = 0;
};