summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ControllerConfig.cpp1
-rw-r--r--src/core/ControllerConfig.h62
-rw-r--r--src/core/CutsceneMgr.cpp3
-rw-r--r--src/core/CutsceneMgr.h2
-rw-r--r--src/core/FileLoader.cpp2
-rw-r--r--src/core/FileLoader.h2
-rw-r--r--src/core/Fire.cpp1
-rw-r--r--src/core/Fire.h1
-rw-r--r--src/core/Game.cpp165
-rw-r--r--src/core/Game.h1
-rw-r--r--src/core/Messages.cpp26
-rw-r--r--src/core/Messages.h56
-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/Text.cpp276
-rw-r--r--src/core/Text.h56
-rw-r--r--src/core/User.cpp5
-rw-r--r--src/core/User.h10
-rw-r--r--src/core/Wanted.h2
-rw-r--r--src/core/World.cpp2
-rw-r--r--src/core/World.h2
-rw-r--r--src/core/ZoneCull.cpp12
-rw-r--r--src/core/templates.h17
24 files changed, 355 insertions, 463 deletions
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index e3a586b2..6eef4d3d 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -22,6 +22,7 @@ WRAPPER void CControllerConfigManager::ClearSimButtonPressCheckers() { EAXJMP(0x
WRAPPER void CControllerConfigManager::AffectPadFromKeyBoard() { EAXJMP(0x58D0C0); }
WRAPPER void CControllerConfigManager::AffectPadFromMouse() { EAXJMP(0x58D1A0); }
WRAPPER void CControllerConfigManager::ClearSettingsAssociatedWithAction(int, int) { EAXJMP(0x58EB40); }
+WRAPPER void CControllerConfigManager::GetWideStringOfCommandKeys(uint16, wchar*, uint16) { EAXJMP(0x58F460); }
void CControllerConfigManager::LoadSettings(int32 file)
{
diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h
index b064a381..ab17577b 100644
--- a/src/core/ControllerConfig.h
+++ b/src/core/ControllerConfig.h
@@ -9,10 +9,64 @@ enum eControllerType
OPTIONAL_EXTRA,
MOUSE,
JOYSTICK,
+ TOTAL_CONTROLLER_TYPES
+};
+
+enum e_ControllerAction
+{
+ PED_FIREWEAPON = 0,
+ PED_CYCLE_WEAPON_RIGHT,
+ PED_CYCLE_WEAPON_LEFT,
+ GO_FORWARD,
+ GO_BACK,
+ GO_LEFT,
+ GO_RIGHT,
+ PED_SNIPER_ZOOM_IN,
+ PED_SNIPER_ZOOM_OUT,
+ VEHICLE_ENTER_EXIT,
+ CAMERA_CHANGE_VIEW_ALL_SITUATIONS,
+ PED_JUMPING,
+ PED_SPRINT,
+ PED_LOOKBEHIND,
+ //PED_DUCK, // VC
+ //PED_ANSWER_PHONE, // VC
+ VEHICLE_ACCELERATE,
+ VEHICLE_BRAKE,
+ VEHICLE_CHANGE_RADIO_STATION,
+ VEHICLE_HORN,
+ TOGGLE_SUBMISSIONS,
+ VEHICLE_HANDBRAKE,
+ PED_1RST_PERSON_LOOK_LEFT,
+ PED_1RST_PERSON_LOOK_RIGHT,
+ VEHICLE_LOOKLEFT,
+ VEHICLE_LOOKRIGHT,
+ VEHICLE_LOOKBEHIND,
+ VEHICLE_TURRETLEFT,
+ VEHICLE_TURRETRIGHT,
+ VEHICLE_TURRETUP,
+ VEHICLE_TURRETDOWN,
+ PED_CYCLE_TARGET_LEFT,
+ PED_CYCLE_TARGET_RIGHT,
+ PED_CENTER_CAMERA_BEHIND_PLAYER,
+ PED_LOCK_TARGET,
+ NETWORK_TALK,
+ PED_1RST_PERSON_LOOK_UP,
+ PED_1RST_PERSON_LOOK_DOWN,
+
+ CONTROLLERACTION_36, // unk, unused?
+
+ TOGGLE_DPAD,
+ SWITCH_DEBUG_CAM_ON,
+ TAKE_SCREEN_SHOT,
+ SHOW_MOUSE_POINTER_TOGGLE,
+
+ TOTAL_CONTROL_ACTIONS
};
class CMouseControllerState;
+#define ACTIONNAME_LENGTH 40
+
class CControllerConfigManager
{
public:
@@ -23,16 +77,13 @@ public:
};
bool firstCapture;
- char _pad0[3];
DIJOYSTATE2 m_OldState;
DIJOYSTATE2 m_NewState;
- wchar m_aActionNames[41][40];
+ wchar m_aActionNames[TOTAL_CONTROL_ACTIONS][ACTIONNAME_LENGTH];
bool m_aButtonStates[17];
- char _pad1[3];
- tControllerConfigBind m_aSettings[41][4];
+ tControllerConfigBind m_aSettings[TOTAL_CONTROL_ACTIONS][TOTAL_CONTROLLER_TYPES];
uint8 m_aSimCheckers[4][4];
bool m_bMouseAssociated;
- char _pad2[3];
void UpdateJoyButtonState(int padnumber);
void UpdateJoyInConfigMenus_ButtonDown(int button, int padnumber);
@@ -52,6 +103,7 @@ public:
void AffectPadFromMouse();
void ClearSettingsAssociatedWithAction(int, int);
+ void GetWideStringOfCommandKeys(uint16, wchar*, uint16);
};
VALIDATE_SIZE(CControllerConfigManager, 0x143C);
diff --git a/src/core/CutsceneMgr.cpp b/src/core/CutsceneMgr.cpp
index b446cd5d..95abfcc9 100644
--- a/src/core/CutsceneMgr.cpp
+++ b/src/core/CutsceneMgr.cpp
@@ -107,8 +107,7 @@ const struct {
int
FindCutsceneAudioTrackId(const char *szCutsceneName)
{
- for (int i = 0; musicNameIdAssoc[i].szTrackName; i++)
- {
+ for (int i = 0; musicNameIdAssoc[i].szTrackName; i++) {
if (!strcmpi(musicNameIdAssoc[i].szTrackName, szCutsceneName))
return musicNameIdAssoc[i].iTrackId;
}
diff --git a/src/core/CutsceneMgr.h b/src/core/CutsceneMgr.h
index 7215a123..8c4a918b 100644
--- a/src/core/CutsceneMgr.h
+++ b/src/core/CutsceneMgr.h
@@ -21,10 +21,10 @@ class CCutsceneMgr
static CAnimBlendAssocGroup &ms_cutsceneAssociations;
static CVector &ms_cutsceneOffset;
static float &ms_cutsceneTimer;
+ static bool &ms_cutsceneProcessing;
public:
static CDirectory *&ms_pCutsceneDir;
static uint32 &ms_cutsceneLoadStatus;
- static bool &ms_cutsceneProcessing;
static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index e9c06201..6f3b0971 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -25,6 +25,8 @@
#include "CdStream.h"
#include "FileLoader.h"
+WRAPPER void CFileLoader::ReloadPaths(const char *filename) { EAXJMP(0x476DB0); }
+
char CFileLoader::ms_line[256];
const char*
diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h
index ea7f47d9..7ef96da3 100644
--- a/src/core/FileLoader.h
+++ b/src/core/FileLoader.h
@@ -39,4 +39,6 @@ public:
static void LoadPickup(const char *line);
static void LoadMapZones(const char *filename);
+
+ static void ReloadPaths(const char *filename);
};
diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp
index 2181f91c..0317ccbe 100644
--- a/src/core/Fire.cpp
+++ b/src/core/Fire.cpp
@@ -32,4 +32,5 @@ CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance)
}
WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); }
+WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); }
WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); }
diff --git a/src/core/Fire.h b/src/core/Fire.h
index 5080fd89..c752b2a6 100644
--- a/src/core/Fire.h
+++ b/src/core/Fire.h
@@ -31,6 +31,7 @@ class CFireManager
CFire m_aFires[NUM_FIRES];
public:
void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32);
+ void Update(void);
CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float);
CFire *FindNearestFire(CVector, float*);
uint32 GetTotalActiveFires() const { return m_nTotalFires; }
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index b488a217..00d50fa8 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -2,8 +2,60 @@
#include "patcher.h"
#include "Game.h"
#include "main.h"
+#include "AccidentManager.h"
+#include "Antennas.h"
+#include "Bridge.h"
+#include "Camera.h"
+#include "CarCtrl.h"
+#include "CarGen.h"
#include "CdStream.h"
+#include "Clock.h"
+#include "Clouds.h"
+#include "Collision.h"
+#include "Coronas.h"
+#include "Cranes.h"
+#include "CutsceneMgr.h"
+#include "Darkel.h"
+#include "EventList.h"
+#include "FileLoader.h"
#include "FileMgr.h"
+#include "Fire.h"
+#include "Fluff.h"
+#include "Font.h"
+#include "Frontend.h"
+#include "GameLogic.h"
+#include "Garages.h"
+#include "Glass.h"
+#include "Heli.h"
+#include "Pad.h"
+#include "Particle.h"
+#include "Phones.h"
+#include "Pickups.h"
+#include "Plane.h"
+#include "Population.h"
+#include "Record.h"
+#include "Renderer.h"
+#include "Replay.h"
+#include "RoadBlocks.h"
+#include "Rubbish.h"
+#include "SceneEdit.h"
+#include "Script.h"
+#include "Shadows.h"
+#include "Skidmarks.h"
+#include "SpecialFX.h"
+#include "Sprite2d.h"
+#include "Streaming.h"
+#include "TimeCycle.h"
+#include "TrafficLights.h"
+#include "Train.h"
+#include "TxdStore.h"
+#include "User.h"
+#include "WaterCannon.h"
+#include "Weapon.h"
+#include "Weather.h"
+#include "World.h"
+#include "ZoneCull.h"
+#include "Zones.h"
eLevelName &CGame::currLevel = *(eLevelName*)0x941514;
bool &CGame::bDemoMode = *(bool*)0x5F4DD0;
@@ -25,14 +77,125 @@ CGame::InitialiseOnceBeforeRW(void)
}
WRAPPER void CGame::Initialise(const char *datFile) { EAXJMP(0x48BED0); }
+#if 0
WRAPPER void CGame::Process(void) { EAXJMP(0x48C850); }
+#else
+void CGame::Process(void)
+{
+ CPad::UpdatePads();
+ TheCamera.SetMotionBlurAlpha(0);
+ if (TheCamera.m_BlurType == MBLUR_NONE || TheCamera.m_BlurType == MBLUR_SNIPER || TheCamera.m_BlurType == MBLUR_NORMAL)
+ TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE);
+ CCutsceneMgr::Update();
+ if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
+ FrontEndMenuManager.Process();
+ CStreaming::Update();
+ if (!CTimer::GetIsPaused())
+ {
+ CTheZones::Update();
+ CSprite2d::SetRecipNearClip();
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ CRecordDataForGame::SaveOrRetrieveDataForThisFrame();
+ CRecordDataForChase::SaveOrRetrieveDataForThisFrame();
+ CPad::DoCheats();
+ CClock::Update();
+ CWeather::Update();
+ CTheScripts::Process();
+ CCollision::Update();
+ CTrain::UpdateTrains();
+ CPlane::UpdatePlanes();
+ CHeli::UpdateHelis();
+ CDarkel::Update();
+ CSkidmarks::Update();
+ CAntennas::Update();
+ CGlass::Update();
+ CSceneEdit::Update();
+ CEventList::Update();
+ CParticle::Update();
+ gFireManager.Update();
+ CPopulation::Update();
+ CWeapon::UpdateWeapons();
+ if (!CCutsceneMgr::IsRunning())
+ CTheCarGenerators::Process();
+ if (!CReplay::IsPlayingBack())
+ CCranes::UpdateCranes();
+ CClouds::Update();
+ CMovingThings::Update();
+ CWaterCannons::Update();
+ CUserDisplay::Process();
+ CReplay::Update();
+ CWorld::Process();
+ gAccidentManager.Update();
+ CPacManPickups::Update();
+ CPickups::Update();
+ CGarages::Update();
+ CRubbish::Update();
+ CSpecialFX::Update();
+ CTimeCycle::Update();
+ if (CReplay::ShouldStandardCameraBeProcessed())
+ TheCamera.Process();
+ CCullZones::Update();
+ if (!CReplay::IsPlayingBack())
+ CGameLogic::Update();
+ CBridge::Update();
+ CCoronas::DoSunAndMoon();
+ CCoronas::Update();
+ CShadows::UpdateStaticShadows();
+ CShadows::UpdatePermanentShadows();
+ gPhoneInfo.Update();
+ if (!CReplay::IsPlayingBack())
+ {
+ CCarCtrl::GenerateRandomCars();
+ CRoadBlocks::GenerateRoadBlocks();
+ CCarCtrl::RemoveDistantCars();
+ }
+ }
+}
+#endif
+void CGame::ReloadIPLs(void)
+{
+ CTimer::Stop();
+ CWorld::RemoveStaticObjects();
+ ThePaths.Init();
+ CCullZones::Init();
+ CFileLoader::ReloadPaths("GTA3.IDE");
+ CFileLoader::LoadScene("INDUST.IPL");
+ CFileLoader::LoadScene("COMMER.IPL");
+ CFileLoader::LoadScene("SUBURBAN.IPL");
+ CFileLoader::LoadScene("CULL.IPL");
+ ThePaths.PreparePathData();
+ CTrafficLights::ScanForLightsOnMap();
+ CRoadBlocks::Init();
+ CCranes::InitCranes();
+ CGarages::Init();
+ CWorld::RepositionCertainDynamicObjects();
+ CCullZones::ResolveVisibilities();
+ CRenderer::SortBIGBuildings();
+ 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(0x48BEC0, CGame::FinalShutdown, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/core/Game.h b/src/core/Game.h
index 3bc3e633..dca38bdb 100644
--- a/src/core/Game.h
+++ b/src/core/Game.h
@@ -30,6 +30,7 @@ public:
static void FinalShutdown(void);
static void ShutDownForRestart(void);
static void Process(void);
+ static void ReloadIPLs(void);
// NB: these do something on PS2
static void TidyUpMemory(bool, bool) {}
diff --git a/src/core/Messages.cpp b/src/core/Messages.cpp
deleted file mode 100644
index 9b5342ac..00000000
--- a/src/core/Messages.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "common.h"
-#include "patcher.h"
-#include "Messages.h"
-
-WRAPPER void CMessages::Display(void) { EAXJMP(0x529800); }
-WRAPPER void CMessages::ClearAllMessagesDisplayedByGame(void) { EAXJMP(0x52B670); }
-WRAPPER int CMessages::WideStringCopy(wchar* dst, wchar* src, unsigned short size) { EAXJMP(0x5294B0); }
-WRAPPER char CMessages::WideStringCompare(wchar* str1, wchar* str2, unsigned short size) { EAXJMP(0x529510); }
-WRAPPER void CMessages::InsertNumberInString(wchar* src, int n1, int n2, int n3, int n4, int n5, int n6, wchar* dst) { EAXJMP(0x52A1A0); }
-WRAPPER void CMessages::InsertPlayerControlKeysInString(wchar* src) { EAXJMP(0x52A490); }
-WRAPPER int CMessages::GetWideStringLength(wchar* src) { EAXJMP(0x529490); }
-WRAPPER void CMessages::AddBigMessage(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529EB0); }
-WRAPPER void CMessages::AddBigMessageWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52AD10); }
-WRAPPER void CMessages::AddBigMessageWithNumberQ(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52AE00); }
-WRAPPER void CMessages::AddMessage(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529900); }
-WRAPPER void CMessages::AddMessageJumpQ(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529A10); }
-WRAPPER void CMessages::AddMessageSoon(wchar* key, uint32 time, uint16 pos) { EAXJMP(0x529AF0); }
-WRAPPER void CMessages::AddMessageWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52A850); }
-WRAPPER void CMessages::AddMessageJumpQWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52A9A0); }
-WRAPPER void CMessages::AddMessageSoonWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6) { EAXJMP(0x52AAC0); }
-WRAPPER void CMessages::ClearMessages() { EAXJMP(0x529CE0); }
-WRAPPER void CMessages::Init() { EAXJMP(0x529310); }
-WRAPPER void CMessages::Process() { EAXJMP(0x529580); }
-tPreviousBrief *CMessages::PreviousBriefs = (tPreviousBrief *)0x713C08;
-tMessage *CMessages::BriefMessages = (tMessage *)0x8786E0;
-tBigMessage *CMessages::BIGMessages = (tBigMessage *)0x773628;
diff --git a/src/core/Messages.h b/src/core/Messages.h
deleted file mode 100644
index 7caf5786..00000000
--- a/src/core/Messages.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#pragma once
-
-struct tMessage
-{
- wchar *m_pText;
- uint16 m_nFlag;
-private:
- int8 _pad6[2];
-public:
- uint32 m_nTime;
- uint32 m_nStartTime;
- int32 m_nNumber[6];
- wchar *m_pString;
-};
-
-struct tBigMessage
-{
- tMessage m_Current;
- tMessage m_Stack[3];
-};
-
-struct tPreviousBrief
-{
- wchar *m_pText;
- int32 m_nNumber[6];
- wchar *m_pString;
-};
-
-class CMessages
-{
-public:
- static tPreviousBrief *PreviousBriefs;
- static tMessage *BriefMessages;
- static tBigMessage *BIGMessages;
-
-public:
- static void Display(void);
- static void ClearAllMessagesDisplayedByGame(void);
- static int WideStringCopy(wchar* dst, wchar* src, unsigned short size);
- static char WideStringCompare(wchar* str1, wchar* str2, unsigned short size);
- static void InsertNumberInString(wchar* src, int n1, int n2, int n3, int n4, int n5, int n6, wchar* dst);
- static void InsertPlayerControlKeysInString(wchar* src);
- static int GetWideStringLength(wchar *src);
- static void AddBigMessage(wchar* key, uint32 time, uint16 pos);
- static void AddBigMessageWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
- static void AddBigMessageWithNumberQ(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
- static void AddMessage(wchar* key, uint32 time, uint16 pos);
- static void AddMessageJumpQ(wchar* key, uint32 time, uint16 pos);
- static void AddMessageSoon(wchar* key, uint32 time, uint16 pos);
- static void AddMessageWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
- static void AddMessageJumpQWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
- static void AddMessageSoonWithNumber(wchar* key, uint32 time, uint16 pos, int n1, int n2, int n3, int n4, int n5, int n6);
- static void ClearMessages();
- static void Init();
- static void Process();
-};
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/Text.cpp b/src/core/Text.cpp
deleted file mode 100644
index dfa9815c..00000000
--- a/src/core/Text.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-#include "common.h"
-#include "patcher.h"
-#include "FileMgr.h"
-#include "Frontend.h"
-#include "Messages.h"
-#include "Text.h"
-
-static wchar WideErrorString[25];
-
-CText &TheText = *(CText*)0x941520;
-
-CText::CText(void)
-{
- keyArray.entries = nil;
- keyArray.numEntries = 0;
- data.chars = nil;
- data.numChars = 0;
- encoding = 101;
- memset(WideErrorString, 0, sizeof(WideErrorString));
-}
-
-CText::~CText(void)
-{
- data.Unload();
- keyArray.Unload();
-}
-
-void
-CText::Load(void)
-{
- uint8 *filedata;
- char filename[32], type[4];
- int length;
- int offset, sectlen;
-
- Unload();
- filedata = new uint8[0x40000];
-
- CFileMgr::SetDir("TEXT");
- switch(CMenuManager::m_PrefsLanguage){
- case LANGUAGE_AMERICAN:
- sprintf(filename, "AMERICAN.GXT");
- break;
- case LANGUAGE_FRENCH:
- sprintf(filename, "FRENCH.GXT");
- break;
- case LANGUAGE_GERMAN:
- sprintf(filename, "GERMAN.GXT");
- break;
- case LANGUAGE_ITALIAN:
- sprintf(filename, "ITALIAN.GXT");
- break;
- case LANGUAGE_SPANISH:
- sprintf(filename, "SPANISH.GXT");
- break;
- }
-
- length = CFileMgr::LoadFile(filename, filedata, 0x40000, "rb");
- CFileMgr::SetDir("");
-
- offset = 0;
- while(offset < length){
- type[0] = filedata[offset++];
- type[1] = filedata[offset++];
- type[2] = filedata[offset++];
- type[3] = filedata[offset++];
- sectlen = (int)filedata[offset+3]<<24 | (int)filedata[offset+2]<<16 |
- (int)filedata[offset+1]<<8 | (int)filedata[offset+0];
- offset += 4;
- if(sectlen != 0){
- if(strncmp(type, "TKEY", 4) == 0)
- keyArray.Load(sectlen, filedata, &offset);
- else if(strncmp(type, "TDAT", 4) == 0)
- data.Load(sectlen, filedata, &offset);
- else
- offset += sectlen;
- }
- }
-
- keyArray.Update(data.chars);
-
- delete[] filedata;
-}
-
-void
-CText::Unload(void)
-{
- CMessages::ClearAllMessagesDisplayedByGame();
- data.Unload();
- keyArray.Unload();
-}
-
-wchar*
-CText::Get(const char *key)
-{
- return keyArray.Search(key);
-}
-
-wchar
-CText::GetUpperCase(wchar c)
-{
- // TODO: do this depending on encoding
- if(islower(c))
- return toupper(c);
- return c;
-}
-
-void
-CText::UpperCase(wchar *s)
-{
- while(*s){
- *s = GetUpperCase(*s);
- s++;
- }
-}
-
-
-void
-CKeyArray::Load(uint32 length, uint8 *data, int *offset)
-{
- uint32 i;
- uint8 *rawbytes;
-
- numEntries = length / sizeof(CKeyEntry);
- entries = new CKeyEntry[numEntries];
- rawbytes = (uint8*)entries;
-
- for(i = 0; i < length; i++)
- rawbytes[i] = data[(*offset)++];
-}
-
-void
-CKeyArray::Unload(void)
-{
- delete[] entries;
- entries = nil;
- numEntries = 0;
-}
-
-void
-CKeyArray::Update(wchar *chars)
-{
- int i;
- for(i = 0; i < numEntries; i++)
- entries[i].value = (wchar*)((uint8*)chars + (uintptr)entries[i].value);
-}
-
-CKeyEntry*
-CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high)
-{
- int mid;
- int diff;
-
- if(low > high)
- return nil;
-
- mid = (low + high)/2;
- diff = strcmp(key, entries[mid].key);
- if(diff == 0)
- return &entries[mid];
- if(diff < 0)
- return BinarySearch(key, entries, low, mid-1);
- if(diff > 0)
- return BinarySearch(key, entries, mid+1, high);
- return nil;
-}
-
-wchar*
-CKeyArray::Search(const char *key)
-{
- CKeyEntry *found;
- char errstr[25];
- int i;
-
- found = BinarySearch(key, entries, 0, numEntries-1);
- if(found)
- return found->value;
- sprintf(errstr, "%s missing", key);
- for(i = 0; i < 25; i++)
- WideErrorString[i] = errstr[i];
- return WideErrorString;
-}
-
-
-void
-CData::Load(uint32 length, uint8 *data, int *offset)
-{
- uint32 i;
- uint8 *rawbytes;
-
- numChars = length / sizeof(wchar);
- chars = new wchar[numChars];
- rawbytes = (uint8*)chars;
-
- for(i = 0; i < length; i++)
- rawbytes[i] = data[(*offset)++];
-}
-
-void
-CData::Unload(void)
-{
- delete[] chars;
- chars = nil;
- numChars = 0;
-}
-
-void
-AsciiToUnicode(const char *src, uint16 *dst)
-{
- while((*dst++ = *src++) != '\0');
-}
-
-char*
-UnicodeToAscii(wchar *src)
-{
- static char aStr[256];
- int len;
- for(len = 0; src && *src != 0 && len < 256-1; len++, src++)
- if(*src < 256)
- aStr[len] = *src;
- else
- aStr[len] = '#';
- aStr[len] = '\0';
- return aStr;
-}
-
-char*
-UnicodeToAsciiForSaveLoad(wchar *src)
-{
- // exact same code as above
- static char aStr[256];
- int len;
- for(len = 0; src && *src != 0 && len < 256-1; len++, src++)
- if(*src < 256)
- aStr[len] = *src;
- else
- aStr[len] = '#';
- aStr[len] = '\0';
- return aStr;
-}
-
-void
-UnicodeStrcpy(wchar *dst, const wchar *src)
-{
- while((*dst++ = *src++) != '\0');
-}
-
-int
-UnicodeStrlen(const wchar *str)
-{
- int len;
- for(len = 0; *str != 0; len++, str++);
- return len;
-}
-
-void
-TextCopy(wchar *dst, const wchar *src)
-{
- while((*dst++ = *src++) != '\0');
-}
-
-
-STARTPATCHES
- InjectHook(0x52C3C0, &CText::Load, PATCH_JUMP);
- InjectHook(0x52C580, &CText::Unload, PATCH_JUMP);
- InjectHook(0x52C5A0, &CText::Get, PATCH_JUMP);
-
- InjectHook(0x52BE70, &CKeyArray::Load, PATCH_JUMP);
- InjectHook(0x52BF60, &CKeyArray::Unload, PATCH_JUMP);
- InjectHook(0x52BF80, &CKeyArray::Update, PATCH_JUMP);
- InjectHook(0x52C060, &CKeyArray::BinarySearch, PATCH_JUMP);
- InjectHook(0x52BFB0, &CKeyArray::Search, PATCH_JUMP);
-
- InjectHook(0x52C120, &CData::Load, PATCH_JUMP);
- InjectHook(0x52C200, &CData::Unload, PATCH_JUMP);
-ENDPATCHES
diff --git a/src/core/Text.h b/src/core/Text.h
deleted file mode 100644
index f554628c..00000000
--- a/src/core/Text.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#pragma once
-
-void AsciiToUnicode(const char *src, wchar *dst);
-char *UnicodeToAscii(wchar *src);
-char *UnicodeToAsciiForSaveLoad(wchar *src);
-void UnicodeStrcpy(wchar *dst, const wchar *src);
-int UnicodeStrlen(const wchar *str);
-void TextCopy(wchar *dst, const wchar *src);
-
-struct CKeyEntry
-{
- wchar *value;
- char key[8];
-};
-// If this fails, CKeyArray::Load will have to be fixed
-static_assert(sizeof(CKeyEntry) == 12, "CKeyEntry: error");
-
-class CKeyArray
-{
-public:
- CKeyEntry *entries;
- int numEntries;
-
- void Load(uint32 length, uint8 *data, int *offset);
- void Unload(void);
- void Update(wchar *chars);
- CKeyEntry *BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 high);
- wchar *Search(const char *key);
-};
-
-class CData
-{
-public:
- wchar *chars;
- int numChars;
-
- void Load(uint32 length, uint8 *data, int *offset);
- void Unload(void);
-};
-
-class CText
-{
- CKeyArray keyArray;
- CData data;
- int8 encoding;
-public:
- CText(void);
- ~CText(void);
- void Load(void);
- void Unload(void);
- wchar *Get(const char *key);
- wchar GetUpperCase(wchar c);
- void UpperCase(wchar *s);
-};
-
-extern CText &TheText;
diff --git a/src/core/User.cpp b/src/core/User.cpp
index f40a06db..600fa443 100644
--- a/src/core/User.cpp
+++ b/src/core/User.cpp
@@ -13,7 +13,7 @@ COnscreenTimer& CUserDisplay::OnscnTimer = *(COnscreenTimer*)0x862238;
CPager& CUserDisplay::Pager = *(CPager*)0x8F2744;
CCurrentVehicle& CUserDisplay::CurrentVehicle = *(CCurrentVehicle*)0x8F5FE8;
-WRAPPER void CPager::AddMessage(wchar*, uint16, uint16, uint16) { EAXJMP(0x52B940); }
+WRAPPER void CUserDisplay::Process(void) { EAXJMP(0x4AD690); }
void COnscreenTimer::Init() {
m_bDisabled = false;
@@ -125,8 +125,7 @@ void COnscreenTimerEntry::Process() {
*timerPtr = (uint32)newTime;
uint32 oldTimeSeconds = oldTime / 1000;
if(oldTimeSeconds <= 11 && newTime / 1000 != oldTimeSeconds) {
- // TODO: use an enum here
- DMAudio.PlayFrontEndSound(0x93, newTime / 1000);
+ DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, newTime / 1000);
}
}
}
diff --git a/src/core/User.h b/src/core/User.h
index cac2a318..90b2da55 100644
--- a/src/core/User.h
+++ b/src/core/User.h
@@ -1,5 +1,7 @@
#pragma once
+#include "Pager.h"
+
class COnscreenTimerEntry
{
public:
@@ -50,12 +52,6 @@ class CCurrentVehicle
{
};
-class CPager
-{
-public:
- void AddMessage(wchar*, uint16, uint16, uint16);
-};
-
class CUserDisplay
{
public:
@@ -63,4 +59,6 @@ public:
static COnscreenTimer &OnscnTimer;
static CPager &Pager;
static CCurrentVehicle &CurrentVehicle;
+
+ static void Process(void);
};
diff --git a/src/core/Wanted.h b/src/core/Wanted.h
index 1303365d..15bff1a5 100644
--- a/src/core/Wanted.h
+++ b/src/core/Wanted.h
@@ -43,7 +43,7 @@ class CWanted
public:
int32 m_nChaos;
int32 m_nLastUpdateTime;
- int32 m_nLastWantedLevelChange;
+ uint32 m_nLastWantedLevelChange;
float m_fCrimeSensitivity;
uint8 m_CurrentCops;
uint8 m_MaxCops;
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 3a8367f1..5dea09bd 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -39,6 +39,8 @@ bool &CWorld::bDoingCarCollisions = *(bool*)0x95CD8C;
bool &CWorld::bIncludeCarTyres = *(bool*)0x95CDAA;
WRAPPER void CWorld::ShutDown(void) { EAXJMP(0x4AE450); }
+WRAPPER void CWorld::RepositionCertainDynamicObjects() { EAXJMP(0x4B42B0); }
+WRAPPER void CWorld::RemoveStaticObjects() { EAXJMP(0x4B4D50); }
WRAPPER void CWorld::RemoveReferencesToDeletedObject(CEntity*) { EAXJMP(0x4B3BF0); }
WRAPPER void CWorld::FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool){ EAXJMP(0x4B2A30); }
WRAPPER void CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, uint8) { EAXJMP(0x4B4E70) };
diff --git a/src/core/World.h b/src/core/World.h
index f420207c..a1aa0376 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -122,6 +122,8 @@ public:
static void Initialise();
static void ShutDown();
+ static void RepositionCertainDynamicObjects();
+ static void RemoveStaticObjects();
static void Process();
};
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);