summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Game.cpp17
-rw-r--r--src/core/Pools.cpp80
-rw-r--r--src/core/Pools.h4
-rw-r--r--src/core/Streaming.cpp30
-rw-r--r--src/core/ZoneCull.cpp12
-rw-r--r--src/core/templates.h17
6 files changed, 128 insertions, 32 deletions
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 3ac4acb0..00d50fa8 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -48,6 +48,7 @@
#include "TimeCycle.h"
#include "TrafficLights.h"
#include "Train.h"
+#include "TxdStore.h"
#include "User.h"
#include "WaterCannon.h"
#include "Weapon.h"
@@ -175,14 +176,26 @@ void CGame::ReloadIPLs(void)
CTimer::Update();
}
+#if 0
+WRAPPER void CGame::FinalShutdown(void) { EAXJMP(0x48BEC0); }
+#else
+void
+CGame::FinalShutdown(void)
+{
+ CTxdStore::Shutdown();
+ CPedStats::Shutdown();
+ CdStreamShutdown();
+}
+#endif
+
WRAPPER bool CGame::InitialiseRenderWare(void) { EAXJMP(0x48BBA0); }
WRAPPER void CGame::ShutdownRenderWare(void) { EAXJMP(0x48BCB0); }
-WRAPPER void CGame::FinalShutdown(void) { EAXJMP(0x48BEC0); }
WRAPPER void CGame::ShutDown(void) { EAXJMP(0x48C3A0); }
WRAPPER void CGame::ShutDownForRestart(void) { EAXJMP(0x48C6B0); }
WRAPPER void CGame::InitialiseWhenRestarting(void) { EAXJMP(0x48C740); }
WRAPPER bool CGame::InitialiseOnceAfterRW(void) { EAXJMP(0x48BD50); }
STARTPATCHES
-InjectHook(0x48C850, CGame::Process, PATCH_JUMP);
+ InjectHook(0x48C850, CGame::Process, PATCH_JUMP);
+ InjectHook(0x48BEC0, CGame::FinalShutdown, PATCH_JUMP);
ENDPATCHES
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index 847fa753..8e66b049 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -1,6 +1,8 @@
#include "common.h"
#include "patcher.h"
#include "Pools.h"
+#include "World.h"
+#include "ProjectileInfo.h"
CCPtrNodePool *&CPools::ms_pPtrNodePool = *(CCPtrNodePool**)0x943044;
CEntryInfoNodePool *&CPools::ms_pEntryInfoNodePool = *(CEntryInfoNodePool**)0x941448;
@@ -12,15 +14,9 @@ CObjectPool *&CPools::ms_pObjectPool = *(CObjectPool**)0x880E28;
CDummyPool *&CPools::ms_pDummyPool = *(CDummyPool**)0x8F2C18;
CAudioScriptObjectPool *&CPools::ms_pAudioScriptObjectPool = *(CAudioScriptObjectPool**)0x8F1B6C;
-WRAPPER void CPools::Initialise(void) { EAXJMP(0x4A1770); }
-WRAPPER void CPools::MakeSureSlotInObjectPoolIsEmpty(int32 handle) { EAXJMP(0x4A2DB0); }
-
-#if 0
void
CPools::Initialise(void)
{
- // TODO: unused right now
- assert(0);
ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES);
ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS);
ms_pPedPool = new CPedPool(NUMPEDS);
@@ -31,7 +27,33 @@ CPools::Initialise(void)
ms_pDummyPool = new CDummyPool(NUMDUMMIES);
ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS);
}
-#endif
+
+void
+CPools::ShutDown(void)
+{
+ debug("PtrNodes left %d\n", ms_pPtrNodePool->GetNoOfUsedSpaces());
+ debug("EntryInfoNodes left %d\n", ms_pEntryInfoNodePool->GetNoOfUsedSpaces());
+ debug("Peds left %d\n", ms_pPedPool->GetNoOfUsedSpaces());
+ debug("Vehicles left %d\n", ms_pVehiclePool->GetNoOfUsedSpaces());
+ debug("Buildings left %d\n", ms_pBuildingPool->GetNoOfUsedSpaces());
+ debug("Treadables left %d\n", ms_pTreadablePool->GetNoOfUsedSpaces());
+ debug("Objects left %d\n", ms_pObjectPool->GetNoOfUsedSpaces());
+ debug("Dummys left %d\n", ms_pDummyPool->GetNoOfUsedSpaces());
+ debug("AudioScriptObjects left %d\n", ms_pAudioScriptObjectPool->GetNoOfUsedSpaces());
+ printf("Shutdown pool started\n");
+
+ delete ms_pPtrNodePool;
+ delete ms_pEntryInfoNodePool;
+ delete ms_pPedPool;
+ delete ms_pVehiclePool;
+ delete ms_pBuildingPool;
+ delete ms_pTreadablePool;
+ delete ms_pObjectPool;
+ delete ms_pDummyPool;
+ delete ms_pAudioScriptObjectPool;
+
+ printf("Shutdown pool done\n");
+}
int32 CPools::GetPedRef(CPed *ped) { return ms_pPedPool->GetIndex(ped); }
CPed *CPools::GetPed(int32 handle) { return ms_pPedPool->GetAt(handle); }
@@ -39,3 +61,47 @@ int32 CPools::GetVehicleRef(CVehicle *vehicle) { return ms_pVehiclePool->GetInde
CVehicle *CPools::GetVehicle(int32 handle) { return ms_pVehiclePool->GetAt(handle); }
int32 CPools::GetObjectRef(CObject *object) { return ms_pObjectPool->GetIndex(object); }
CObject *CPools::GetObject(int32 handle) { return ms_pObjectPool->GetAt(handle); }
+
+void
+CPools::CheckPoolsEmpty()
+{
+ assert(ms_pPedPool->GetNoOfUsedSpaces() == 0);
+ assert(ms_pVehiclePool->GetNoOfUsedSpaces() == 0);
+ printf("pools have beem cleared \n");
+}
+
+
+void
+CPools::MakeSureSlotInObjectPoolIsEmpty(int32 slot)
+{
+ if (ms_pObjectPool->IsFreeSlot(slot)) return;
+
+ CObject *object = ms_pObjectPool->GetSlot(slot);
+ if (object->ObjectCreatedBy == TEMP_OBJECT) {
+ CWorld::Remove(object);
+ delete object;
+ } else if (!CProjectileInfo::RemoveIfThisIsAProjectile(object)) {
+ // relocate to another slot??
+ CObject *newObject = new CObject();
+ CWorld::Remove(object);
+ memcpy(newObject, object, ms_pObjectPool->GetMaxEntrySize());
+ CWorld::Add(newObject);
+ object->m_rwObject = nil;
+ delete object;
+ newObject->m_pFirstReference = nil;
+ }
+}
+
+
+STARTPATCHES
+ InjectHook(0x4A1770, CPools::Initialise, PATCH_JUMP);
+ InjectHook(0x4A1880, CPools::ShutDown, PATCH_JUMP);
+ InjectHook(0x4A1A50, CPools::CheckPoolsEmpty, PATCH_JUMP);
+ InjectHook(0x4A1A80, CPools::GetPedRef, PATCH_JUMP);
+ InjectHook(0x4A1AA0, CPools::GetPed, PATCH_JUMP);
+ InjectHook(0x4A1AC0, CPools::GetVehicleRef, PATCH_JUMP);
+ InjectHook(0x4A1AE0, CPools::GetVehicle, PATCH_JUMP);
+ InjectHook(0x4A1B00, CPools::GetObjectRef, PATCH_JUMP);
+ InjectHook(0x4A1B20, CPools::GetObject, PATCH_JUMP);
+ InjectHook(0x4A2DB0, CPools::MakeSureSlotInObjectPoolIsEmpty, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/core/Pools.h b/src/core/Pools.h
index 4e6bd547..770a1de1 100644
--- a/src/core/Pools.h
+++ b/src/core/Pools.h
@@ -43,11 +43,13 @@ public:
static CAudioScriptObjectPool *GetAudioScriptObjectPool(void) { return ms_pAudioScriptObjectPool; }
static void Initialise(void);
+ static void ShutDown(void);
static int32 GetPedRef(CPed *ped);
static CPed *GetPed(int32 handle);
static int32 GetVehicleRef(CVehicle *vehicle);
static CVehicle *GetVehicle(int32 handle);
static int32 GetObjectRef(CObject *object);
static CObject *GetObject(int32 handle);
- static void MakeSureSlotInObjectPoolIsEmpty(int32 handle);
+ static void CheckPoolsEmpty();
+ static void MakeSureSlotInObjectPoolIsEmpty(int32 slot);
};
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index d9dc8628..69e14869 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -226,7 +226,7 @@ CStreaming::Init(void)
CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd);
CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom);
- for(i = 0; i < CPools::GetBuildingPool()->GetSize(); i++){
+ for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
if(building == nil)
continue;
@@ -682,8 +682,8 @@ CStreaming::RequestBigBuildings(eLevelName level)
int i, n;
CBuilding *b;
- n = CPools::GetBuildingPool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding && b->m_level == level)
RequestModel(b->GetModelIndex(), STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY);
@@ -837,8 +837,8 @@ CStreaming::RemoveBuildings(eLevelName level)
CEntity *e;
CBaseModelInfo *mi;
- n = CPools::GetBuildingPool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
e = CPools::GetBuildingPool()->GetSlot(i);
if(e && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@@ -850,8 +850,8 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
- n = CPools::GetTreadablePool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetTreadablePool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
e = CPools::GetTreadablePool()->GetSlot(i);
if(e && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@@ -863,8 +863,8 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
- n = CPools::GetObjectPool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetObjectPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
e = CPools::GetObjectPool()->GetSlot(i);
if(e && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@@ -876,8 +876,8 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
- n = CPools::GetDummyPool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetDummyPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
e = CPools::GetDummyPool()->GetSlot(i);
if(e && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@@ -951,8 +951,8 @@ CStreaming::RemoveBigBuildings(eLevelName level)
CEntity *e;
CBaseModelInfo *mi;
- n = CPools::GetBuildingPool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
e = CPools::GetBuildingPool()->GetSlot(i);
if(e && e->bIsBIGBuilding && e->m_level == level){
mi = CModelInfo::GetModelInfo(e->GetModelIndex());
@@ -1172,8 +1172,8 @@ CStreaming::HaveAllBigBuildingsLoaded(eLevelName level)
return;
}
- n = CPools::GetBuildingPool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
e = CPools::GetBuildingPool()->GetSlot(i);
if(e && e->bIsBIGBuilding && e->m_level == level &&
ms_aInfoForModel[e->GetModelIndex()].m_loadState != STREAMSTATE_LOADED)
diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp
index dc162147..6d33a1cf 100644
--- a/src/core/ZoneCull.cpp
+++ b/src/core/ZoneCull.cpp
@@ -169,22 +169,22 @@ CCullZones::MarkSubwayAsInvisible(bool visible)
CEntity *e;
CVehicle *v;
- n = CPools::GetBuildingPool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
e = CPools::GetBuildingPool()->GetSlot(i);
if(e && e->bIsSubway)
e->bIsVisible = visible;
}
- n = CPools::GetTreadablePool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetTreadablePool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
e = CPools::GetTreadablePool()->GetSlot(i);
if(e && e->bIsSubway)
e->bIsVisible = visible;
}
- n = CPools::GetVehiclePool()->GetSize();
- for(i = 0; i < n; i++){
+ n = CPools::GetVehiclePool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
v = CPools::GetVehiclePool()->GetSlot(i);
if(v && v->IsTrain() && ((CTrain*)v)->m_nTrackId != TRACK_ELTRAIN)
v->bIsVisible = visible;
diff --git a/src/core/templates.h b/src/core/templates.h
index ef2db33a..f785d647 100644
--- a/src/core/templates.h
+++ b/src/core/templates.h
@@ -44,7 +44,20 @@ public:
m_flags[i].free = 1;
}
}
- int GetSize(void) { return m_size; }
+ ~CPool() {
+ Flush();
+ }
+ void Flush() {
+ if (m_size > 0) {
+ free(m_entries);
+ free(m_flags);
+ m_entries = nil;
+ m_flags = nil;
+ m_size = 0;
+ m_allocPtr = 0;
+ }
+ }
+ int GetSize(void) const { return m_size; }
T *New(void){
bool wrapped = false;
do
@@ -101,12 +114,14 @@ public:
n++;
return n;
}
+ bool IsFreeSlot(int i) { return !!m_flags[i].free; }
void ClearStorage(uint8 *&flags, U *&entries){
free(flags);
free(entries);
flags = nil;
entries = nil;
}
+ uint32 GetMaxEntrySize() const { return sizeof(U); }
void CopyBack(uint8 *&flags, U *&entries){
memcpy(m_flags, flags, sizeof(uint8)*m_size);
memcpy(m_entries, entries, sizeof(U)*m_size);