Skip to content

Commit

Permalink
Merge branch 'master' into add-lod-model-func
Browse files Browse the repository at this point in the history
  • Loading branch information
Fernando-A-Rocha authored Jan 24, 2025
2 parents 404cd79 + c60f8a2 commit d7eeea5
Show file tree
Hide file tree
Showing 364 changed files with 26,234 additions and 33,648 deletions.
27 changes: 11 additions & 16 deletions Client/game_sa/CBuildingsPoolSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "CPtrNodeSingleListSA.h"
#include "MemSA.h"
#include "CVehicleSA.h"
#include "CBuildingRemovalSA.h"

extern CGameSA* pGame;

Expand Down Expand Up @@ -138,18 +139,11 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding)
--m_buildingPool.count;
}

void CBuildingsPoolSA::RemoveAllBuildings()
void CBuildingsPoolSA::RemoveAllWithBackup()
{
if (m_pOriginalBuildingsBackup)
return;

pGame->GetCoverManager()->RemoveAllCovers();
pGame->GetPlantManager()->RemoveAllPlants();

// Remove all shadows
using CStencilShadowObjects_dtorAll = void* (*)();
((CStencilShadowObjects_dtorAll)0x711390)();

m_pOriginalBuildingsBackup = std::make_unique<std::array<std::pair<bool, CBuildingSAInterface>, MAX_BUILDINGS>>();

auto pBuildsingsPool = (*m_ppBuildingPoolInterface);
Expand All @@ -176,11 +170,14 @@ void CBuildingsPoolSA::RemoveAllBuildings()
}
}

void CBuildingsPoolSA::RestoreAllBuildings()
void CBuildingsPoolSA::RestoreBackup()
{
if (!m_pOriginalBuildingsBackup)
return;

auto* worldSA = pGame->GetWorld();
auto* buildingRemovealSA = static_cast<CBuildingRemovalSA*>(pGame->GetBuildingRemoval());

auto& originalData = *m_pOriginalBuildingsBackup;
auto pBuildsingsPool = (*m_ppBuildingPoolInterface);
for (size_t i = 0; i < MAX_BUILDINGS; i++)
Expand All @@ -191,7 +188,8 @@ void CBuildingsPoolSA::RestoreAllBuildings()
auto pBuilding = pBuildsingsPool->GetObject(i);
*pBuilding = originalData[i].second;

pGame->GetWorld()->Add(pBuilding, CBuildingPool_Constructor);
worldSA->Add(pBuilding, CBuildingPool_Constructor);
buildingRemovealSA->AddDataBuilding(pBuilding);
}
}

Expand All @@ -202,10 +200,7 @@ void CBuildingsPoolSA::RemoveBuildingFromWorld(CBuildingSAInterface* pBuilding)
{
// Remove building from world
pGame->GetWorld()->Remove(pBuilding, CBuildingPool_Destructor);

pBuilding->DeleteRwObject();
pBuilding->ResolveReferences();
pBuilding->RemoveShadows();
pBuilding->RemoveRWObjectWithReferencesCleanup();
}

bool CBuildingsPoolSA::Resize(int size)
Expand Down Expand Up @@ -254,7 +249,7 @@ bool CBuildingsPoolSA::Resize(int size)
newBytemap[i].bEmpty = true;
}

const uint32_t offset = (uint32_t)newObjects - (uint32_t)oldPool;
const std::uint32_t offset = (std::uint32_t)newObjects - (std::uint32_t)oldPool;
if (oldPool != nullptr)
{
UpdateIplEntrysPointers(offset);
Expand All @@ -265,7 +260,7 @@ bool CBuildingsPoolSA::Resize(int size)
UpdateBackupLodPointers(offset);
}

pGame->GetPools()->GetDummyPool().UpdateBuildingLods(oldPool, newObjects);
pGame->GetPools()->GetDummyPool().UpdateBuildingLods(offset);

RemoveVehicleDamageLinks();
RemovePedsContactEnityLinks();
Expand Down
8 changes: 4 additions & 4 deletions Client/game_sa/CBuildingsPoolSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class CBuildingsPoolSA : public CBuildingsPool
void RemoveBuilding(CBuilding* pBuilding);
bool HasFreeBuildingSlot();

void RemoveAllBuildings() override;
void RestoreAllBuildings() override;
void RemoveAllWithBackup() override;
void RestoreBackup() override;
bool Resize(int size) override;
int GetSize() const override { return (*m_ppBuildingPoolInterface)->m_nSize; };

Expand All @@ -40,8 +40,8 @@ class CBuildingsPoolSA : public CBuildingsPool
void RemovePedsContactEnityLinks();

private:
SVectorPoolData<CBuildingSA> m_buildingPool{MAX_BUILDINGS};
CPoolSAInterface<CBuildingSAInterface>** m_ppBuildingPoolInterface;
SVectorPoolData<CBuildingSA> m_buildingPool{MAX_BUILDINGS};
CPoolSAInterface<CBuildingSAInterface>** m_ppBuildingPoolInterface;

std::unique_ptr<std::array<std::pair<bool, CBuildingSAInterface>, MAX_BUILDINGS>> m_pOriginalBuildingsBackup;
};
94 changes: 63 additions & 31 deletions Client/game_sa/CDummyPoolSA.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CDummyPoolSA.cpp
* PURPOSE: Dummy pool class
Expand All @@ -13,64 +13,96 @@

#include "StdInc.h"
#include "CDummyPoolSA.h"
#include "CGameSA.h"
#include <game/CWorld.h>

extern CGameSA* pGame;

CDummyPoolSA::CDummyPoolSA()
{
m_ppDummyPoolInterface = (CPoolSAInterface<CEntitySAInterface>**)0xB744A0;
}

void CDummyPoolSA::RemoveAllBuildingLods()
void CDummyPoolSA::RemoveAllWithBackup()
{
if (m_pLodBackup)
if (m_pOriginalElementsBackup)
return;

m_pLodBackup = std::make_unique<std::array<CEntitySAInterface*, MAX_DUMMIES>>();
m_pOriginalElementsBackup = std::make_unique<pool_backup_t>();

for (int i = 0; i < MAX_DUMMIES; i++)
auto pDummyPool = (*m_ppDummyPoolInterface);
for (auto i = 0; i < MAX_DUMMIES_DEFAULT; i++)
{
CEntitySAInterface* object = (*m_ppDummyPoolInterface)->GetObject(i);
(*m_pLodBackup)[i] = object->m_pLod;
object->m_pLod = nullptr;
if (pDummyPool->IsContains(i))
{
CEntitySAInterface* building = pDummyPool->GetObject(i);

pGame->GetWorld()->Remove(building, CDummyPool_Destructor);
building->RemoveRWObjectWithReferencesCleanup();

pDummyPool->Release(i);

(*m_pOriginalElementsBackup)[i].first = true;
(*m_pOriginalElementsBackup)[i].second = *building;
}
else
{
(*m_pOriginalElementsBackup)[i].first = false;
}
}
}

void CDummyPoolSA::RestoreAllBuildingsLods()
void CDummyPoolSA::RestoreBackup()
{
if (!m_pLodBackup)
if (!m_pOriginalElementsBackup)
return;

for (int i = 0; i < MAX_DUMMIES; i++)
auto& originalData = *m_pOriginalElementsBackup;
auto pDummyPool = (*m_ppDummyPoolInterface);
for (auto i = 0; i < MAX_DUMMIES_DEFAULT; i++)
{
CEntitySAInterface* object = (*m_ppDummyPoolInterface)->GetObject(i);
object->m_pLod = (*m_pLodBackup)[i];
if (originalData[i].first)
{
pDummyPool->AllocateAt(i);
auto pDummy = pDummyPool->GetObject(i);
*pDummy = originalData[i].second;

pGame->GetWorld()->Add(pDummy, CDummyPool_Constructor);
}
}

m_pLodBackup.release();
m_pOriginalElementsBackup = nullptr;
}

void CDummyPoolSA::UpdateBuildingLods(void* oldPool, void* newPool)
void CDummyPoolSA::UpdateBuildingLods(const std::uint32_t offset)
{
const uint32_t offset = (uint32_t)newPool - (uint32_t)oldPool;
if (m_pOriginalElementsBackup)
UpdateBackupLodOffset(offset);
else
UpdateLodsOffestInPool(offset);
}

if (m_pLodBackup)
void CDummyPoolSA::UpdateBackupLodOffset(const std::uint32_t offset)
{
for (auto& it : *m_pOriginalElementsBackup)
{
for (int i = 0; i < MAX_DUMMIES; i++)
if (it.first)
{
if ((*m_pLodBackup)[i] != nullptr)
{
(*m_pLodBackup)[i] = (CEntitySAInterface*)((uint32_t)(*m_pLodBackup)[i] + offset);
}
CEntitySAInterface* object = &it.second;
CEntitySAInterface* lod = object->GetLod();
if (lod)
object->SetLod((CEntitySAInterface*)((std::uint32_t)lod + offset));
}
}
else
}

void CDummyPoolSA::UpdateLodsOffestInPool(const std::uint32_t offset)
{
for (auto i = 0; i < (*m_ppDummyPoolInterface)->Size(); i++)
{
for (int i = 0; i < MAX_DUMMIES; i++)
{
CEntitySAInterface* object = (*m_ppDummyPoolInterface)->GetObject(i);
if (object->m_pLod)
{
object->m_pLod = (CEntitySAInterface*)((uint32_t)object->m_pLod + offset);
}
}
CEntitySAInterface* object = (*m_ppDummyPoolInterface)->GetObject(i);
CEntitySAInterface* lod = object->GetLod();
if (lod)
object->SetLod((CEntitySAInterface*)((std::uint32_t)lod + offset));
}
}
19 changes: 13 additions & 6 deletions Client/game_sa/CDummyPoolSA.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CDummyPoolSA.h
* PURPOSE: Dummy pool class
Expand All @@ -16,18 +16,25 @@
#include "CPoolSAInterface.h"
#include <memory>

class CDummyPoolSA : public CDummyPool
constexpr std::size_t MAX_DUMMIES_DEFAULT = 2500;

class CDummyPoolSA final : public CDummyPool
{
public:
CDummyPoolSA();
~CDummyPoolSA() = default;

void RemoveAllBuildingLods();
void RestoreAllBuildingsLods();
void UpdateBuildingLods(void* oldPool, void* newPool);
void RemoveAllWithBackup() override;
void RestoreBackup() override;
void UpdateBuildingLods(const std::uint32_t offset);

private:
void UpdateBackupLodOffset(const std::uint32_t offest);
void UpdateLodsOffestInPool(const std::uint32_t offset);

private:
CPoolSAInterface<CEntitySAInterface>** m_ppDummyPoolInterface;

std::unique_ptr<std::array<CEntitySAInterface*, MAX_DUMMIES>> m_pLodBackup;
using pool_backup_t = std::array<std::pair<bool, CEntitySAInterface>, MAX_DUMMIES_DEFAULT>;
std::unique_ptr<pool_backup_t> m_pOriginalElementsBackup;
};
10 changes: 10 additions & 0 deletions Client/game_sa/CEntitySA.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ class CEntitySAInterface
// Functions to hide member variable misuse
//

void SetLod(CEntitySAInterface* pLod) noexcept { m_pLod = pLod; };
CEntitySAInterface* GetLod() const noexcept { return m_pLod; };

// Sets
void SetIsLowLodEntity() { numLodChildrenRendered = 0x40; }

Expand Down Expand Up @@ -243,9 +246,16 @@ class CEntitySAInterface
((vtbl_DeleteRwObject)this->vtbl->DeleteRwObject)(this);
};

void RemoveRWObjectWithReferencesCleanup() {
DeleteRwObject();
ResolveReferences();
RemoveShadows();
}

bool HasMatrix() const noexcept { return Placeable.matrix != nullptr; }

void RemoveMatrix() { ((void(__thiscall*)(void*))0x54F3B0)(this); }

};
static_assert(sizeof(CEntitySAInterface) == 0x38, "Invalid size for CEntitySAInterface");

Expand Down
43 changes: 21 additions & 22 deletions Client/game_sa/CGameSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ void CGameSA::Reset()
CModelInfoSA::StaticResetTextureDictionaries();

// Restore default world state
RestoreGameBuildings();
RestoreGameWorld();
}
}

Expand Down Expand Up @@ -1059,46 +1059,45 @@ void CGameSA::GetShaderReplacementStats(SShaderReplacementStats& outStats)
m_pRenderWare->GetShaderReplacementStats(outStats);
}

void CGameSA::RemoveAllBuildings()
void CGameSA::RemoveGameWorld()
{
m_pIplStore->SetDynamicIplStreamingEnabled(false);

m_Pools->GetDummyPool().RemoveAllBuildingLods();
m_Pools->GetBuildingsPool().RemoveAllBuildings();
m_pCoverManager->RemoveAllCovers();
m_pPlantManager->RemoveAllPlants();

auto pBuildingRemoval = static_cast<CBuildingRemovalSA*>(m_pBuildingRemoval);
pBuildingRemoval->DropCaches();
// Remove all shadows in CStencilShadowObjects::dtorAll
((void* (*)())0x711390)();

m_isBuildingsRemoved = true;
m_Pools->GetDummyPool().RemoveAllWithBackup();
m_Pools->GetBuildingsPool().RemoveAllWithBackup();

static_cast<CBuildingRemovalSA*>(m_pBuildingRemoval)->DropCaches();

m_isGameWorldRemoved = true;
}

void CGameSA::RestoreGameBuildings()
void CGameSA::RestoreGameWorld()
{
m_Pools->GetBuildingsPool().RestoreAllBuildings();
m_Pools->GetDummyPool().RestoreAllBuildingsLods();
m_Pools->GetBuildingsPool().RestoreBackup();
m_Pools->GetDummyPool().RestoreBackup();

m_pIplStore->SetDynamicIplStreamingEnabled(true, [](CIplSAInterface* ipl) { return memcmp("barriers", ipl->name, 8) != 0; });
m_isBuildingsRemoved = false;
m_isGameWorldRemoved = false;
}

bool CGameSA::SetBuildingPoolSize(size_t size)
{
const bool shouldRemoveBuilding = !m_isBuildingsRemoved;
if (shouldRemoveBuilding)
{
RemoveAllBuildings();
}
const bool shouldRemoveWorld = !m_isGameWorldRemoved;
if (shouldRemoveWorld)
RemoveGameWorld();
else
{
static_cast<CBuildingRemovalSA*>(m_pBuildingRemoval)->DropCaches();
}

bool status = m_Pools->GetBuildingsPool().Resize(size);

if (shouldRemoveBuilding)
{
RestoreGameBuildings();
}
if (shouldRemoveWorld)
RestoreGameWorld();

return status;
}
Expand Down
Loading

0 comments on commit d7eeea5

Please sign in to comment.