summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Camera.cpp10
-rw-r--r--src/core/ColStore.cpp228
-rw-r--r--src/core/ColStore.h43
-rw-r--r--src/core/Collision.cpp143
-rw-r--r--src/core/Collision.h3
-rw-r--r--src/core/FileLoader.cpp402
-rw-r--r--src/core/FileLoader.h17
-rw-r--r--src/core/Frontend.cpp8
-rw-r--r--src/core/Frontend.h2
-rw-r--r--src/core/Game.cpp13
-rw-r--r--src/core/Game.h30
-rw-r--r--src/core/PlayerInfo.h1
-rw-r--r--src/core/Streaming.cpp444
-rw-r--r--src/core/Streaming.h14
-rw-r--r--src/core/User.cpp4
-rw-r--r--src/core/World.h14
-rw-r--r--src/core/ZoneCull.cpp434
-rw-r--r--src/core/ZoneCull.h69
-rw-r--r--src/core/Zones.cpp393
-rw-r--r--src/core/Zones.h33
-rw-r--r--src/core/config.h63
-rw-r--r--src/core/main.cpp2
-rw-r--r--src/core/re3.cpp2
-rw-r--r--src/core/templates.h6
24 files changed, 1084 insertions, 1294 deletions
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 9b178f35..8579dc64 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -633,7 +633,11 @@ CCamera::CamControl(void)
m_bInitialNodeFound = false;
m_bInitialNoNodeStaticsSet = false;
}
+#ifdef GTA_TRAIN
Process_Train_Camera_Control();
+#else
+ assert(0 && "this can't happen");
+#endif
}else{
if(((CVehicle*)pTargetEntity)->IsBoat())
boatTarget = true;
@@ -930,11 +934,13 @@ CCamera::CamControl(void)
if(CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer())
stairs = true;
// Some hack for Mr Whoopee in a bomb shop
+#ifndef MIAMI // uhh, check this
if(Cams[ActiveCam].Using3rdPersonMouseCam() && CCollision::ms_collisionInMemory == LEVEL_COMMERCIAL){
if(pTargetEntity->GetPosition().x < 83.0f && pTargetEntity->GetPosition().x > 18.0f &&
pTargetEntity->GetPosition().y < -305.0f && pTargetEntity->GetPosition().y > -390.0f)
disableGarageCam = true;
}
+#endif
if(!disableGarageCam && (CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition()) || stairs)){
if(!m_bGarageFixedCamPositionSet && m_bLookingAtPlayer){
if(pToGarageWeAreIn || stairs){
@@ -2707,6 +2713,7 @@ CCamera::DontProcessObbeCinemaCamera(void)
bDidWeProcessAnyCinemaCam = false;
}
+#ifdef GTA_TRAIN
void
CCamera::LoadTrainCamNodes(char const *name)
{
@@ -2884,6 +2891,7 @@ CCamera::Process_Train_Camera_Control(void)
}
}
}
+#endif
void
@@ -3179,7 +3187,7 @@ CCamera::RenderMotionBlur(void)
CMBlur::MotionBlurRender(m_pRwCamera,
m_BlurRed, m_BlurGreen, m_BlurBlue,
- m_motionBlur, m_BlurType, m_imotionBlurAddAlpha);
+ m_motionBlur, m_BlurType);
}
void
diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp
new file mode 100644
index 00000000..0715ae6e
--- /dev/null
+++ b/src/core/ColStore.cpp
@@ -0,0 +1,228 @@
+#include "common.h"
+
+#include "templates.h"
+#include "General.h"
+#include "ModelInfo.h"
+#include "Streaming.h"
+#include "FileLoader.h"
+#include "Script.h"
+#include "Timer.h"
+#include "Camera.h"
+#include "Frontend.h"
+#include "ColStore.h"
+
+CPool<ColDef,ColDef> *CColStore::ms_pColPool;
+
+void
+CColStore::Initialise(void)
+{
+ if(ms_pColPool == nil)
+ ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles");
+ AddColSlot("generic"); // slot 0. not streamed
+}
+
+void
+CColStore::Shutdown(void)
+{
+ int i;
+ for(i = 0; i < COLSTORESIZE; i++)
+ RemoveColSlot(i);
+ if(ms_pColPool)
+ delete ms_pColPool;
+ ms_pColPool = nil;
+}
+
+int
+CColStore::AddColSlot(const char *name)
+{
+ ColDef *def = ms_pColPool->New();
+ assert(def);
+ def->isLoaded = false;
+ def->a = 0;
+ def->bounds.left = 1000000.0f;
+ def->bounds.top = 1000000.0f;
+ def->bounds.right = -1000000.0f;
+ def->bounds.bottom = -1000000.0f;
+ def->minIndex = INT16_MAX;
+ def->maxIndex = INT16_MIN;
+ strcpy(def->name, name);
+ return ms_pColPool->GetJustIndex(def);
+}
+
+void
+CColStore::RemoveColSlot(int slot)
+{
+ if(GetSlot(slot)){
+ if(GetSlot(slot)->isLoaded)
+ RemoveCol(slot);
+ ms_pColPool->Delete(GetSlot(slot));
+ }
+}
+
+int
+CColStore::FindColSlot(const char *name)
+{
+ ColDef *def;
+ int size = ms_pColPool->GetSize();
+ for(int i = 0; i < size; i++){
+ def = GetSlot(i);
+ if(def && !CGeneral::faststricmp(def->name, name))
+ return i;
+ }
+ return -1;
+}
+
+char*
+CColStore::GetColName(int32 slot)
+{
+ return GetSlot(slot)->name;
+}
+
+CRect&
+CColStore::GetBoundingBox(int32 slot)
+{
+ return GetSlot(slot)->bounds;
+}
+
+void
+CColStore::IncludeModelIndex(int32 slot, int32 modelIndex)
+{
+ ColDef *def = GetSlot(slot);
+ if(modelIndex < def->minIndex)
+ def->minIndex = modelIndex;
+ if(modelIndex > def->maxIndex)
+ def->maxIndex = modelIndex;
+}
+
+bool
+CColStore::LoadCol(int32 slot, uint8 *buffer, int32 bufsize)
+{
+ bool success;
+ ColDef *def = GetSlot(slot);
+ if(def->minIndex > def->maxIndex)
+ success = CFileLoader::LoadCollisionFileFirstTime(buffer, bufsize, slot);
+ else
+ success = CFileLoader::LoadCollisionFile(buffer, bufsize, slot);
+ if(success)
+ def->isLoaded = true;
+ else
+ debug("Failed to load Collision\n");
+ return success;
+}
+
+void
+CColStore::RemoveCol(int32 slot)
+{
+ int id;
+ GetSlot(slot)->isLoaded = false;
+ for(id = 0; id < MODELINFOSIZE; id++){
+ CBaseModelInfo *mi = CModelInfo::GetModelInfo(id);
+ if(mi){
+ CColModel *col = mi->GetColModel();
+ if(col && col->level == slot)
+ col->RemoveCollisionVolumes();
+ }
+ }
+}
+
+void
+CColStore::LoadAllCollision(void)
+{
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i))
+ CStreaming::RequestCol(i, 0);
+ CStreaming::LoadAllRequestedModels(false);
+}
+
+void
+CColStore::RemoveAllCollision(void)
+{
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i))
+ if(CStreaming::CanRemoveCol(i))
+ CStreaming::RemoveCol(i);
+}
+
+static bool bLoadAtSecondPosition;
+static CVector2D secondPosition;
+
+void
+CColStore::AddCollisionNeededAtPosn(const CVector2D &pos)
+{
+ bLoadAtSecondPosition = true;
+ secondPosition = pos;
+}
+
+void
+CColStore::LoadCollision(const CVector2D &pos)
+{
+ int i;
+
+ if(CStreaming::ms_disableStreaming)
+ return;
+
+ for(i = 1; i < COLSTORESIZE; i++){
+ if(GetSlot(i) == nil)
+ continue;
+
+ bool wantThisOne = false;
+
+ if(GetBoundingBox(i).IsPointInside(pos) ||
+ bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) ||
+ CGeneral::faststrcmp(GetColName(i), "yacht") == 0){
+ wantThisOne = true;
+ }else{
+ // TODO: check mission cleanup list
+ }
+
+ if(wantThisOne)
+ CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY);
+ else
+ CStreaming::RemoveCol(i);
+ }
+ bLoadAtSecondPosition = false;
+}
+
+void
+CColStore::RequestCollision(const CVector2D &pos)
+{
+ int i;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f))
+ CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY);
+}
+
+void
+CColStore::EnsureCollisionIsInMemory(const CVector2D &pos)
+{
+ int i;
+
+ if(CStreaming::ms_disableStreaming)
+ return;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) &&
+ !CStreaming::HasColLoaded(i)){
+ CStreaming::RequestCol(i, 0);
+ if(TheCamera.GetScreenFadeStatus() == FADE_0)
+ FrontEndMenuManager.MessageScreen("LOADCOL", false);
+ CTimer::Suspend();
+ CStreaming::LoadAllRequestedModels(false);
+ CTimer::Resume();
+ }
+}
+
+bool
+CColStore::HasCollisionLoaded(const CVector2D &pos)
+{
+ int i;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) &&
+ !GetSlot(i)->isLoaded)
+ return false;
+ return true;
+}
diff --git a/src/core/ColStore.h b/src/core/ColStore.h
new file mode 100644
index 00000000..0d686ffd
--- /dev/null
+++ b/src/core/ColStore.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "templates.h"
+
+struct ColDef { // made up name
+ int32 a;
+ bool isLoaded;
+ CRect bounds;
+ char name[20];
+ int16 minIndex;
+ int16 maxIndex;
+};
+
+class CColStore
+{
+ static CPool<ColDef,ColDef> *ms_pColPool;
+
+public:
+ static void Initialise(void);
+ static void Shutdown(void);
+ static int AddColSlot(const char *name);
+ static void RemoveColSlot(int32 slot);
+ static int FindColSlot(const char *name);
+ static char *GetColName(int32 slot);
+ static CRect &GetBoundingBox(int32 slot);
+ static void IncludeModelIndex(int32 slot, int32 modelIndex);
+ static bool LoadCol(int32 storeID, uint8 *buffer, int32 bufsize);
+ static void RemoveCol(int32 slot);
+ static void AddCollisionNeededAtPosn(const CVector2D &pos);
+ static void LoadAllCollision(void);
+ static void RemoveAllCollision(void);
+ static void LoadCollision(const CVector2D &pos);
+ static void RequestCollision(const CVector2D &pos);
+ static void EnsureCollisionIsInMemory(const CVector2D &pos);
+ static bool HasCollisionLoaded(const CVector2D &pos);
+
+ static ColDef *GetSlot(int slot) {
+ assert(slot >= 0);
+ assert(ms_pColPool);
+ assert(slot < ms_pColPool->GetSize());
+ return ms_pColPool->GetSlot(slot);
+ }
+};
diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp
index 0cdacfdb..61cb14db 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -20,6 +20,8 @@
#include "SurfaceTable.h"
#include "Lines.h"
#include "Collision.h"
+#include "Camera.h"
+#include "ColStore.h"
enum Direction
{
@@ -34,57 +36,30 @@ enum Direction
eLevelName CCollision::ms_collisionInMemory;
CLinkList<CColModel*> CCollision::ms_colModelCache;
+//--MIAMI: done
void
CCollision::Init(void)
{
ms_colModelCache.Init(NUMCOLCACHELINKS);
ms_collisionInMemory = LEVEL_NONE;
+ CColStore::Initialise();
}
+//--MIAMI: done
void
CCollision::Shutdown(void)
{
ms_colModelCache.Shutdown();
+ CColStore::Shutdown();
}
+//--MIAMI: done
void
CCollision::Update(void)
{
- CVector playerCoors;
- playerCoors = FindPlayerCoors();
- eLevelName level = CTheZones::m_CurrLevel;
- bool forceLevelChange = false;
-
- if(CTimer::GetTimeInMilliseconds() < 2000 || CCutsceneMgr::IsCutsceneProcessing())
- return;
-
- // hardcode a level if there are no zones
- if(level == LEVEL_NONE){
- if(CGame::currLevel == LEVEL_INDUSTRIAL &&
- playerCoors.x < 400.0f){
- level = LEVEL_COMMERCIAL;
- forceLevelChange = true;
- }else if(CGame::currLevel == LEVEL_SUBURBAN &&
- playerCoors.x > -450.0f && playerCoors.y < -1400.0f){
- level = LEVEL_COMMERCIAL;
- forceLevelChange = true;
- }else{
- if(playerCoors.x > 800.0f){
- level = LEVEL_INDUSTRIAL;
- forceLevelChange = true;
- }else if(playerCoors.x < -800.0f){
- level = LEVEL_SUBURBAN;
- forceLevelChange = true;
- }
- }
- }
- if(level != LEVEL_NONE && level != CGame::currLevel)
- CGame::currLevel = level;
- if(ms_collisionInMemory != CGame::currLevel)
- LoadCollisionWhenINeedIt(forceLevelChange);
- CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
}
+//--MIAMI: unused
eLevelName
GetCollisionInSectorList(CPtrList &list)
{
@@ -101,6 +76,7 @@ GetCollisionInSectorList(CPtrList &list)
return LEVEL_NONE;
}
+//--MIAMI: unused
// Get a level this sector is in based on collision models
eLevelName
GetCollisionInSector(CSector &sect)
@@ -121,111 +97,16 @@ GetCollisionInSector(CSector &sect)
return (eLevelName)level;
}
+//--MIAMI: done
void
CCollision::LoadCollisionWhenINeedIt(bool forceChange)
{
- eLevelName level, l;
- bool multipleLevels;
- CVector playerCoors;
- CVehicle *veh;
- CEntryInfoNode *ei;
- int sx, sy;
- int xmin, xmax, ymin, ymax;
- int x, y;
-
- level = LEVEL_NONE;
-
- playerCoors = FindPlayerCoors();
- sx = CWorld::GetSectorIndexX(playerCoors.x);
- sy = CWorld::GetSectorIndexY(playerCoors.y);
- multipleLevels = false;
-
- veh = FindPlayerVehicle();
- if(veh && veh->IsTrain()){
- if(((CTrain*)veh)->m_nDoorState != TRAIN_DOOR_OPEN)
- return;
- }else if(playerCoors.z < -4.0f && !CCullZones::DoINeedToLoadCollision())
- return;
-
- // Figure out whose level's collisions we're most likely to be interested in
- if(!forceChange){
- if(veh && veh->IsBoat()){
- // on water we expect to be between levels
- multipleLevels = true;
- }else{
- xmin = Max(sx - 1, 0);
- xmax = Min(sx + 1, NUMSECTORS_X-1);
- ymin = Max(sy - 1, 0);
- ymax = Min(sy + 1, NUMSECTORS_Y-1);
-
- for(x = xmin; x <= xmax; x++)
- for(y = ymin; y <= ymax; y++){
- l = GetCollisionInSector(*CWorld::GetSector(x, y));
- if(l != LEVEL_NONE){
- if(level == LEVEL_NONE)
- level = l;
- if(level != l)
- multipleLevels = true;
- }
- }
- }
-
- if(multipleLevels && veh && veh->IsBoat())
- for(ei = veh->m_entryInfoList.first; ei; ei = ei->next){
- level = GetCollisionInSector(*ei->sector);
- if(level != LEVEL_NONE)
- break;
- }
- }
-
- if(level == CGame::currLevel || forceChange){
- CTimer::Stop();
- DMAudio.SetEffectsFadeVol(0);
- CPad::StopPadsShaking();
- LoadCollisionScreen(CGame::currLevel);
- DMAudio.Service();
-
- CPopulation::DealWithZoneChange(ms_collisionInMemory, CGame::currLevel, false);
- CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL);
- CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL);
- CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
- CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL);
- CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL);
- CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN);
- CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
- CStreaming::RemoveUnusedModelsInLoadedList();
- CGame::TidyUpMemory(true, true);
- CFileLoader::LoadCollisionFromDatFile(CGame::currLevel);
- ms_collisionInMemory = CGame::currLevel;
- CReplay::EmptyReplayBuffer();
- if(CGame::currLevel != LEVEL_NONE)
- LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
- CStreaming::RequestBigBuildings(CGame::currLevel);
- CStreaming::LoadAllRequestedModels(true);
- CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
-
- CGame::TidyUpMemory(true, true);
- CTimer::Update();
- DMAudio.SetEffectsFadeVol(127);
- }
}
+//--MIAMI: done
void
CCollision::SortOutCollisionAfterLoad(void)
{
- if(ms_collisionInMemory == CGame::currLevel)
- return;
-
- CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
- if(CGame::currLevel != LEVEL_NONE){
- CFileLoader::LoadCollisionFromDatFile(CGame::currLevel);
- if(!CGame::playingIntro)
- LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- }
- ms_collisionInMemory = CGame::currLevel;
- CGame::TidyUpMemory(true, false);
}
void
@@ -1974,7 +1855,7 @@ CColModel::CColModel(void)
vertices = nil;
triangles = nil;
trianglePlanes = nil;
- level = CGame::currLevel;
+ level = 0; // generic col slot
ownsCollisionVolumes = true;
}
diff --git a/src/core/Collision.h b/src/core/Collision.h
index 895f012a..18fad76b 100644
--- a/src/core/Collision.h
+++ b/src/core/Collision.h
@@ -87,13 +87,14 @@ struct CStoredCollPoly
struct CColModel
{
+ // TODO(MIAMI): CSphere and CBox
CColSphere boundingSphere;
CColBox boundingBox;
int16 numSpheres;
int16 numLines;
int16 numBoxes;
int16 numTriangles;
- int32 level;
+ uint8 level; // colstore slot but probably still named level
bool ownsCollisionVolumes;
CColSphere *spheres;
CColLine *lines;
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index 25c43778..9e7423f4 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -24,6 +24,8 @@
#include "ZoneCull.h"
#include "CdStream.h"
#include "FileLoader.h"
+#include "Streaming.h"
+#include "ColStore.h"
char CFileLoader::ms_line[256];
@@ -46,14 +48,12 @@ CFileLoader::LoadLevel(const char *filename)
{
int fd;
RwTexDictionary *savedTxd;
- eLevelName savedLevel;
bool objectsLoaded;
char *line;
char txdname[64];
savedTxd = RwTexDictionaryGetCurrent();
objectsLoaded = false;
- savedLevel = CGame::currLevel;
if(savedTxd == nil){
savedTxd = RwTexDictionaryCreate();
RwTexDictionarySetCurrent(savedTxd);
@@ -77,12 +77,8 @@ CFileLoader::LoadLevel(const char *filename)
AddTexDictionaries(savedTxd, txd);
RwTexDictionaryDestroy(txd);
}else if(strncmp(line, "COLFILE", 7) == 0){
- int level;
- sscanf(line+8, "%d", &level);
- CGame::currLevel = (eLevelName)level;
LoadingScreenLoadingFile(line+10);
- LoadCollisionFile(line+10);
- CGame::currLevel = savedLevel;
+ LoadCollisionFile(line+10, 0);
}else if(strncmp(line, "MODELFILE", 9) == 0){
LoadingScreenLoadingFile(line + 10);
LoadModelFile(line + 10);
@@ -94,15 +90,15 @@ CFileLoader::LoadLevel(const char *filename)
LoadObjectTypes(line + 4);
}else if(strncmp(line, "IPL", 3) == 0){
if(!objectsLoaded){
- CModelInfo::ConstructMloClumps();
+ LoadingScreenLoadingFile("Collision");
CObjectData::Initialise("DATA\\OBJECT.DAT");
+ CStreaming::Init();
+ CColStore::LoadAllCollision();
+ // TODO(MIAMI): anim indices
objectsLoaded = true;
}
LoadingScreenLoadingFile(line + 4);
LoadScene(line + 4);
- }else if(strncmp(line, "MAPZONE", 7) == 0){
- LoadingScreenLoadingFile(line + 8);
- LoadMapZones(line + 8);
}else if(strncmp(line, "SPLASH", 6) == 0){
LoadSplash(GetRandomSplashScreen());
}else if(strncmp(line, "CDIMAGE", 7) == 0){
@@ -112,30 +108,13 @@ CFileLoader::LoadLevel(const char *filename)
CFileMgr::CloseFile(fd);
RwTexDictionarySetCurrent(savedTxd);
-}
-
-void
-CFileLoader::LoadCollisionFromDatFile(int currlevel)
-{
- int fd;
- char *line;
-
- fd = CFileMgr::OpenFile(CGame::aDatFile, "r");
- assert(fd > 0);
- for(line = LoadLine(fd); line; line = LoadLine(fd)){
- if(*line == '#')
- continue;
-
- if(strncmp(line, "COLFILE", 7) == 0){
- int level;
- sscanf(line+8, "%d", &level);
- if(currlevel == level)
- LoadCollisionFile(line+10);
- }
- }
-
- CFileMgr::CloseFile(fd);
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(CColStore::GetSlot(i))
+ CColStore::GetBoundingBox(i).Grow(120.0f);
+ CWorld::RepositionCertainDynamicObjects();
+ CColStore::RemoveAllCollision();
}
char*
@@ -178,8 +157,9 @@ struct ColHeader
uint32 size;
};
+//--MIAMI: done
void
-CFileLoader::LoadCollisionFile(const char *filename)
+CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
{
int fd;
char modelname[24];
@@ -188,6 +168,7 @@ CFileLoader::LoadCollisionFile(const char *filename)
debug("Loading collision file %s\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){
assert(strncmp(header.ident, "COLL", 4) == 0);
@@ -196,10 +177,11 @@ CFileLoader::LoadCollisionFile(const char *filename)
mi = CModelInfo::GetModelInfo(modelname, nil);
if(mi){
- if(mi->GetColModel()){
+ if(mi->GetColModel() && mi->DoesOwnColModel()){
LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname);
}else{
CColModel *model = new CColModel;
+ model->level = colSlot;
LoadCollisionModel(work_buff+24, *model, modelname);
mi->SetColModel(model, true);
}
@@ -211,6 +193,78 @@ CFileLoader::LoadCollisionFile(const char *filename)
CFileMgr::CloseFile(fd);
}
+bool
+CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot)
+{
+ uint32 modelsize;
+ char modelname[24];
+ CBaseModelInfo *mi;
+ ColHeader *header;
+ int modelIndex;
+
+ while(size > 8){
+ header = (ColHeader*)buffer;
+ modelsize = header->size;
+ if(strncmp(header->ident, "COLL", 4) != 0)
+ return size-8 < CDSTREAM_SECTOR_SIZE;
+ memcpy(modelname, buffer+8, 24);
+ memcpy(work_buff, buffer+32, modelsize-24);
+ size -= 32 + (modelsize-24);
+ buffer += 32 + (modelsize-24);
+ if(modelsize > 15*1024)
+ debug("colmodel %s is huge, size %d\n", modelname, modelsize);
+
+ mi = CModelInfo::GetModelInfo(modelname, &modelIndex);
+ if(mi){
+ CColStore::IncludeModelIndex(colSlot, modelIndex);
+ CColModel *model = new CColModel;
+ model->level = colSlot;
+ LoadCollisionModel(work_buff, *model, modelname);
+ mi->SetColModel(model, true);
+ }else{
+ debug("colmodel %s can't find a modelinfo\n", modelname);
+ }
+ }
+ return true;
+}
+
+bool
+CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot)
+{
+ uint32 modelsize;
+ char modelname[24];
+ CBaseModelInfo *mi;
+ ColHeader *header;
+
+ while(size > 8){
+ header = (ColHeader*)buffer;
+ modelsize = header->size;
+ if(strncmp(header->ident, "COLL", 4) != 0)
+ return size-8 < CDSTREAM_SECTOR_SIZE;
+ memcpy(modelname, buffer+8, 24);
+ memcpy(work_buff, buffer+32, modelsize-24);
+ size -= 32 + (modelsize-24);
+ buffer += 32 + (modelsize-24);
+ if(modelsize > 15*1024)
+ debug("colmodel %s is huge, size %d\n", modelname, modelsize);
+
+ mi = CModelInfo::GetModelInfo(modelname, CColStore::GetSlot(colSlot)->minIndex, CColStore::GetSlot(colSlot)->maxIndex);
+ if(mi){
+ if(mi->GetColModel()){
+ LoadCollisionModel(work_buff, *mi->GetColModel(), modelname);
+ }else{
+ CColModel *model = new CColModel;
+ model->level = colSlot;
+ LoadCollisionModel(work_buff, *model, modelname);
+ mi->SetColModel(model, true);
+ }
+ }else{
+ debug("colmodel %s can't find a modelinfo\n", modelname);
+ }
+ }
+ return true;
+}
+
void
CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
{
@@ -498,8 +552,9 @@ CFileLoader::LoadObjectTypes(const char *filename)
enum {
NONE,
OBJS,
- MLO,
+ MLO, // unused but enum still has it
TOBJ,
+ WEAP,
HIER,
CARS,
PEDS,
@@ -510,16 +565,17 @@ CFileLoader::LoadObjectTypes(const char *filename)
int fd;
int section;
int pathIndex;
- char pathTypeStr[20];
int id, pathType;
- int mlo;
+ int minID, maxID;
section = NONE;
+ minID = INT32_MAX;
+ maxID = -1;
pathIndex = -1;
- mlo = 0;
debug("Loading object types from %s...\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
if(*line == '\0' || *line == '#')
continue;
@@ -527,25 +583,27 @@ CFileLoader::LoadObjectTypes(const char *filename)
if(section == NONE){
if(strncmp(line, "objs", 4) == 0) section = OBJS;
else if(strncmp(line, "tobj", 4) == 0) section = TOBJ;
+ else if(strncmp(line, "weap", 4) == 0) section = WEAP;
else if(strncmp(line, "hier", 4) == 0) section = HIER;
else if(strncmp(line, "cars", 4) == 0) section = CARS;
else if(strncmp(line, "peds", 4) == 0) section = PEDS;
else if(strncmp(line, "path", 4) == 0) section = PATH;
else if(strncmp(line, "2dfx", 4) == 0) section = TWODFX;
}else if(strncmp(line, "end", 3) == 0){
- section = section == MLO ? OBJS : NONE;
+ section = NONE;
}else switch(section){
case OBJS:
- if(strncmp(line, "sta", 3) == 0)
- mlo = LoadMLO(line);
- else
- LoadObject(line);
- break;
- case MLO:
- LoadMLOInstance(mlo, line);
+ id = LoadObject(line);
+ if(id > maxID) maxID = id;
+ if(id < minID) minID = id;
break;
case TOBJ:
- LoadTimeObject(line);
+ id = LoadTimeObject(line);
+ if(id > maxID) maxID = id;
+ if(id < minID) minID = id;
+ break;
+ case WEAP:
+ assert(0 && "can't do this yet");
break;
case HIER:
LoadClumpObject(line);
@@ -558,17 +616,15 @@ CFileLoader::LoadObjectTypes(const char *filename)
break;
case PATH:
if(pathIndex == -1){
- id = LoadPathHeader(line, pathTypeStr);
- if(strncmp(pathTypeStr, "ped", 4) == 0)
- pathType = 1;
- else if(strncmp(pathTypeStr, "car", 4) == 0)
- pathType = 0;
+ id = LoadPathHeader(line, pathType);
pathIndex = 0;
}else{
- if(pathType == 1)
+ if(pathType == 0)
LoadPedPathNode(line, id, pathIndex);
- else if(pathType == 0)
- LoadCarPathNode(line, id, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, id, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, id, pathIndex, true);
pathIndex++;
if(pathIndex == 12)
pathIndex = -1;
@@ -581,7 +637,7 @@ CFileLoader::LoadObjectTypes(const char *filename)
}
CFileMgr::CloseFile(fd);
- for(id = 0; id < MODELINFOSIZE; id++){
+ for(id = minID; id <= maxID; id++){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi && mi->IsSimple())
mi->SetupBigBuilding();
@@ -591,16 +647,20 @@ CFileLoader::LoadObjectTypes(const char *filename)
void
SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags)
{
- mi->m_normalCull = !!(flags & 1);
+ mi->m_wetRoadReflection = !!(flags & 1);
mi->m_noFade = !!(flags & 2);
mi->m_drawLast = !!(flags & (4|8));
mi->m_additive = !!(flags & 8);
mi->m_isSubway = !!(flags & 0x10);
mi->m_ignoreLight = !!(flags & 0x20);
mi->m_noZwrite = !!(flags & 0x40);
+ mi->m_noShadows = !!(flags & 0x80);
+ mi->m_ignoreDrawDist = !!(flags & 0x100);
+ mi->m_isCodeGlass = !!(flags & 0x200);
+ mi->m_isArtistGlass = !!(flags & 0x400);
}
-void
+int
CFileLoader::LoadObject(const char *line)
{
int id, numObjs;
@@ -611,7 +671,7 @@ CFileLoader::LoadObject(const char *line)
CSimpleModelInfo *mi;
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
- return;
+ return 0; // game returns return value
switch(numObjs){
case 1:
@@ -643,60 +703,11 @@ CFileLoader::LoadObject(const char *line)
mi->m_firstDamaged = damaged;
mi->SetTexDictionary(txd);
MatchModelString(model, id);
-}
-int
-CFileLoader::LoadMLO(const char *line)
-{
- char smth[8];
- char name[24];
- int modelIndex;
- float someFloat;
-
- sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &someFloat);
- CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex);
- minfo->SetName(name);
- minfo->field_34 = someFloat;
- int instId = CModelInfo::GetMloInstanceStore().allocPtr;
- minfo->firstInstance = instId;
- minfo->lastInstance = instId;
- minfo->SetTexDictionary("generic");
- return modelIndex;
-}
-
-void
-CFileLoader::LoadMLOInstance(int id, const char *line)
-{
- char name[24];
- RwV3d pos, scale, rot;
- float angle;
- int modelIndex;
-
- CMloModelInfo *minfo = (CMloModelInfo*)CModelInfo::GetModelInfo(id);
- sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
- &modelIndex,
- name,
- &pos.x, &pos.y, &pos.z,
- &scale.x, &scale.y, &scale.z,
- &rot.x, &rot.y, &rot.z,
- &angle);
- float rad = Acos(angle) * 2.0f;
- CInstance *inst = CModelInfo::GetMloInstanceStore().alloc();
- minfo->lastInstance++;
-
- RwMatrix *matrix = RwMatrixCreate();
- RwMatrixScale(matrix, &scale, rwCOMBINEREPLACE);
- RwMatrixRotate(matrix, &rot, -RADTODEG(rad), rwCOMBINEPOSTCONCAT);
- RwMatrixTranslate(matrix, &pos, rwCOMBINEPOSTCONCAT);
-
- inst->GetMatrix() = CMatrix(matrix);
- inst->GetMatrix().UpdateRW();
-
- inst->m_modelIndex = modelIndex;
- RwMatrixDestroy(matrix);
+ return id;
}
-void
+int
CFileLoader::LoadTimeObject(const char *line)
{
int id, numObjs;
@@ -708,7 +719,7 @@ CFileLoader::LoadTimeObject(const char *line)
CTimeModelInfo *mi, *other;
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
- return;
+ return 0; // game returns return value
switch(numObjs){
case 1:
@@ -744,6 +755,8 @@ CFileLoader::LoadTimeObject(const char *line)
if(other)
other->SetOtherTimeModel(id);
MatchModelString(model, id);
+
+ return id;
}
void
@@ -874,33 +887,51 @@ CFileLoader::LoadPedObject(const char *line)
}
int
-CFileLoader::LoadPathHeader(const char *line, char *type)
+CFileLoader::LoadPathHeader(const char *line, int &type)
{
int id;
char modelname[32];
- sscanf(line, "%s %d %s", type, &id, modelname);
+ sscanf(line, "%d %d %s", &type, &id, modelname);
return id;
}
void
CFileLoader::LoadPedPathNode(const char *line, int id, int node)
{
- int type, next, cross;
- float x, y, z, width;
-
- sscanf(line, "%d %d %d %f %f %f %f", &type, &next, &cross, &x, &y, &z, &width);
- ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, 0, !!cross);
+ int type, next, cross, numLeft, numRight, speed, flags;
+ float x, y, z, width, spawnRate;
+
+ if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f",
+ &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight,
+ &speed, &flags, &spawnRate) != 12)
+ spawnRate = 1.0f;
+
+ if(id == -1)
+ ThePaths.StoreDetachedNodeInfoPed(node, type, next, x, y, z,
+ width, !!cross, !!(flags&1), !!(flags&4), spawnRate*15.0f);
+ else
+ ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z,
+ width, !!cross, spawnRate*15.0f);
}
void
-CFileLoader::LoadCarPathNode(const char *line, int id, int node)
+CFileLoader::LoadCarPathNode(const char *line, int id, int node, bool waterPath)
{
- int type, next, cross, numLeft, numRight;
- float x, y, z, width;
-
- sscanf(line, "%d %d %d %f %f %f %f %d %d", &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight);
- ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight);
+ int type, next, cross, numLeft, numRight, speed, flags;
+ float x, y, z, width, spawnRate;
+
+ if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f",
+ &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight,
+ &speed, &flags, &spawnRate) != 12)
+ spawnRate = 1.0f;
+
+ if(id == -1)
+ ThePaths.StoreDetachedNodeInfoCar(node, type, next, x, y, z, width, numLeft, numRight,
+ !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate, false);
+ else
+ ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight,
+ !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate);
}
@@ -993,20 +1024,21 @@ CFileLoader::LoadScene(const char *filename)
INST,
ZONE,
CULL,
+ OCCL,
PICK,
PATH,
};
char *line;
int fd;
int section;
- int pathIndex;
- char pathTypeStr[20];
+ int pathType, pathIndex;
section = NONE;
pathIndex = -1;
debug("Creating objects from %s...\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
if(*line == '\0' || *line == '#')
continue;
@@ -1017,6 +1049,7 @@ CFileLoader::LoadScene(const char *filename)
else if(strncmp(line, "cull", 4) == 0) section = CULL;
else if(strncmp(line, "pick", 4) == 0) section = PICK;
else if(strncmp(line, "path", 4) == 0) section = PATH;
+ else if(strncmp(line, "occl", 4) == 0) section = OCCL;
}else if(strncmp(line, "end", 3) == 0){
section = NONE;
}else switch(section){
@@ -1029,18 +1062,24 @@ CFileLoader::LoadScene(const char *filename)
case CULL:
LoadCullZone(line);
break;
+ case OCCL:
+ // TODO(MIAMI): occlusion
+ break;
case PICK:
// unused
LoadPickup(line);
break;
case PATH:
- // unfinished in the game
if(pathIndex == -1){
- LoadPathHeader(line, pathTypeStr);
- // type not set
+ LoadPathHeader(line, pathType);
pathIndex = 0;
}else{
- // nodes not loaded
+ if(pathType == 0)
+ LoadPedPathNode(line, -1, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, -1, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, -1, pathIndex, true);
pathIndex++;
if(pathIndex == 12)
pathIndex = -1;
@@ -1063,18 +1102,30 @@ CFileLoader::LoadObjectInstance(const char *line)
CSimpleModelInfo *mi;
RwMatrix *xform;
CEntity *entity;
- if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
- &id, name,
+ float area;
+
+ if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f %f",
+ &id, name, &area,
&trans.x, &trans.y, &trans.z,
&scale.x, &scale.y, &scale.z,
- &axis.x, &axis.y, &axis.z, &angle) != 12)
- return;
+ &axis.x, &axis.y, &axis.z, &angle) != 13){
+ if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
+ &id, name,
+ &trans.x, &trans.y, &trans.z,
+ &scale.x, &scale.y, &scale.z,
+ &axis.x, &axis.y, &axis.z, &angle) != 12)
+ return;
+ area = 0;
+ }
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi == nil)
return;
assert(mi->IsSimple());
+ if(!CStreaming::IsObjectInCdImage(id))
+ debug("Not in cdimage %s\n", mi->GetName());
+
angle = -RADTODEG(2.0f * acosf(angle));
xform = RwMatrixCreate();
RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE);
@@ -1089,6 +1140,7 @@ CFileLoader::LoadObjectInstance(const char *line)
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition());
+ entity->m_area = area;
if(mi->IsSimple()){
if(mi->m_isBigBuilding)
entity->SetupBigBuilding();
@@ -1098,14 +1150,23 @@ CFileLoader::LoadObjectInstance(const char *line)
if(mi->GetLargestLodDistance() < 2.0f)
entity->bIsVisible = false;
CWorld::Add(entity);
+
+ CColModel *col = entity->GetColModel();
+ if(col->numSpheres || col->numBoxes || col->numTriangles){
+ if(col->level != 0)
+ CColStore::GetBoundingBox(col->level).ContainRect(entity->GetBoundRect());
+ }else
+ entity->bUsesCollision = false;
+ // TODO(MIAMI): set some flag here if col min is below 6
}else{
entity = new CDummyObject;
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
CWorld::Add(entity);
- if(IsGlass(entity->GetModelIndex()))
+ if(IsGlass(entity->GetModelIndex()) && !mi->m_isArtistGlass)
entity->bIsVisible = false;
entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition());
+ entity->m_area = area;
}
RwMatrixDestroy(xform);
@@ -1150,54 +1211,7 @@ CFileLoader::LoadPickup(const char *line)
sscanf(line, "%d %f %f %f", &id, &x, &y, &z);
}
-void
-CFileLoader::LoadMapZones(const char *filename)
-{
- enum {
- NONE,
- INST,
- ZONE,
- CULL,
- PICK,
- PATH,
- };
- char *line;
- int fd;
- int section;
-
- section = NONE;
- debug("Creating zones from %s...\n", filename);
-
- fd = CFileMgr::OpenFile(filename, "rb");
- for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
- if(*line == '\0' || *line == '#')
- continue;
-
- if(section == NONE){
- if(strncmp(line, "zone", 4) == 0) section = ZONE;
- }else if(strncmp(line, "end", 3) == 0){
- section = NONE;
- }else switch(section){
- case ZONE: {
- char name[24];
- int type, level;
- float minx, miny, minz;
- float maxx, maxy, maxz;
- if(sscanf(line, "%s %d %f %f %f %f %f %f %d",
- &name, &type,
- &minx, &miny, &minz,
- &maxx, &maxy, &maxz,
- &level) == 9)
- CTheZones::CreateMapZone(name, (eZoneType)type, minx, miny, minz, maxx, maxy, maxz, (eLevelName)level);
- }
- break;
- }
- }
- CFileMgr::CloseFile(fd);
-
- debug("Finished loading IPL\n");
-}
-
+//--MIAMI: unused
void
CFileLoader::ReloadPaths(const char *filename)
{
@@ -1208,10 +1222,10 @@ CFileLoader::ReloadPaths(const char *filename)
char *line;
int section = NONE;
int id, pathType, pathIndex = -1;
- char pathTypeStr[20];
debug("Reloading paths from %s...\n", filename);
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '\0' || *line == '#')
continue;
@@ -1227,17 +1241,15 @@ CFileLoader::ReloadPaths(const char *filename)
switch (section) {
case PATH:
if (pathIndex == -1) {
- id = LoadPathHeader(line, pathTypeStr);
- if (strncmp(pathTypeStr, "ped", 4) == 0)
- pathType = 1;
- else if (strncmp(pathTypeStr, "car", 4) == 0)
- pathType = 0;
+ id = LoadPathHeader(line, pathType);
pathIndex = 0;
} else {
- if (pathType == 1)
+ if(pathType == 0)
LoadPedPathNode(line, id, pathIndex);
- else if (pathType == 0)
- LoadCarPathNode(line, id, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, id, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, id, pathIndex, true);
pathIndex++;
if (pathIndex == 12)
pathIndex = -1;
@@ -1267,6 +1279,7 @@ CFileLoader::ReloadObjectTypes(const char *filename)
CFileMgr::ChangeDir("\\DATA\\MAPS\\");
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
CFileMgr::ChangeDir("\\");
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '\0' || *line == '#')
@@ -1342,6 +1355,7 @@ CFileLoader::ReLoadScene(const char *filename)
char *line;
CFileMgr::ChangeDir("\\DATA\\");
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
CFileMgr::ChangeDir("\\");
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h
index 87b8fe61..959c919e 100644
--- a/src/core/FileLoader.h
+++ b/src/core/FileLoader.h
@@ -5,10 +5,11 @@ class CFileLoader
static char ms_line[256];
public:
static void LoadLevel(const char *filename);
- static void LoadCollisionFromDatFile(int currlevel);
static char *LoadLine(int fd);
static RwTexDictionary *LoadTexDictionary(const char *filename);
- static void LoadCollisionFile(const char *filename);
+ static void LoadCollisionFile(const char *filename, uint8 colSlot);
+ static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot);
+ static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot);
static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name);
static void LoadModelFile(const char *filename);
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
@@ -22,16 +23,14 @@ public:
static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src);
static void LoadObjectTypes(const char *filename);
- static void LoadObject(const char *line);
- static int LoadMLO(const char *line);
- static void LoadMLOInstance(int id, const char *line);
- static void LoadTimeObject(const char *line);
+ static int LoadObject(const char *line);
+ static int LoadTimeObject(const char *line);
static void LoadClumpObject(const char *line);
static void LoadVehicleObject(const char *line);
static void LoadPedObject(const char *line);
- static int LoadPathHeader(const char *line, char *type);
+ static int LoadPathHeader(const char *line, int &type);
static void LoadPedPathNode(const char *line, int id, int node);
- static void LoadCarPathNode(const char *line, int id, int node);
+ static void LoadCarPathNode(const char *line, int id, int node, bool waterPath);
static void Load2dEffect(const char *line);
static void LoadScene(const char *filename);
@@ -40,8 +39,6 @@ public:
static void LoadCullZone(const char *line);
static void LoadPickup(const char *line);
- static void LoadMapZones(const char *filename);
-
static void ReloadPaths(const char *filename);
static void ReloadObjectTypes(const char *filename);
static void ReloadObject(const char *line);
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index fc845a4c..e2c2a453 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -1060,10 +1060,10 @@ CMenuManager::Draw()
rightText = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF");
break;
case MENUACTION_PEDROADGROUPS:
- rightText = TheText.Get(gbShowPedRoadGroups ? "FEM_ON" : "FEM_OFF");
+ // REMOVED(MIAMI)
break;
case MENUACTION_CARROADGROUPS:
- rightText = TheText.Get(gbShowCarRoadGroups ? "FEM_ON" : "FEM_OFF");
+ // REMOVED(MIAMI)
break;
case MENUACTION_COLLISIONPOLYS:
rightText = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF");
@@ -4904,11 +4904,11 @@ CMenuManager::ProcessOnOffMenuOptions()
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
break;
case MENUACTION_PEDROADGROUPS:
- gbShowPedRoadGroups = !gbShowPedRoadGroups;
+ // REMOVED(MIAMI)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
break;
case MENUACTION_CARROADGROUPS:
- gbShowCarRoadGroups = !gbShowCarRoadGroups;
+ // REMOVED(MIAMI)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
break;
case MENUACTION_COLLISIONPOLYS:
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 3286f275..a6ca4aa0 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -624,6 +624,8 @@ public:
void LoadAllTextures();
void LoadSettings();
void MessageScreen(const char *);
+ // TODO(MIAMI): implement the second argument
+ void MessageScreen(const char *str, bool) { MessageScreen(str); }
void PickNewPlayerColour();
void PrintBriefs();
static void PrintErrorMessage();
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index d0f412d8..22d4de99 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -89,6 +89,7 @@
eLevelName CGame::currLevel;
+int32 CGame::currArea;
bool CGame::bDemoMode = true;
bool CGame::nastyGame = true;
bool CGame::frenchGame;
@@ -264,7 +265,7 @@ bool CGame::Initialise(const char* datFile)
strcpy(aDatFile, datFile);
CPools::Initialise();
CIniFile::LoadIniFile();
- currLevel = LEVEL_INDUSTRIAL;
+ currLevel = LEVEL_BEACH;
LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen());
gameTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(gameTxdSlot);
@@ -319,7 +320,6 @@ bool CGame::Initialise(const char* datFile)
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
LoadingScreen("Loading the Game", "Setup streaming", nil);
- CStreaming::Init();
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
CStreaming::RequestBigBuildings(LEVEL_NONE);
@@ -367,10 +367,7 @@ bool CGame::Initialise(const char* datFile)
CWaterCannons::Init();
CBridge::Init();
CGarages::Init();
- LoadingScreen("Loading the Game", "Position dynamic objects", nil);
- CWorld::RepositionCertainDynamicObjects();
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
- CCullZones::ResolveVisibilities();
CTrain::InitTrains();
CPlane::InitPlanes();
CCredits::Init();
@@ -381,7 +378,6 @@ bool CGame::Initialise(const char* datFile)
CTheScripts::Process();
TheCamera.Process();
LoadingScreen("Loading the Game", "Load scene", nil);
- CModelInfo::RemoveColModelsFromOtherLevels(currLevel);
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true);
@@ -487,7 +483,6 @@ void CGame::ReInitGameObjectVariables(void)
CSpecialFX::Init();
CWaterCannons::Init();
CParticle::ReloadConfig();
- CCullZones::ResolveVisibilities();
if ( !FrontEndMenuManager.m_bWantToLoad )
{
@@ -519,8 +514,6 @@ void CGame::ReloadIPLs(void)
CRoadBlocks::Init();
CCranes::InitCranes();
CGarages::Init();
- CWorld::RepositionCertainDynamicObjects();
- CCullZones::ResolveVisibilities();
CRenderer::SortBIGBuildings();
CTimer::Update();
}
@@ -592,7 +585,7 @@ void CGame::InitialiseWhenRestarting(void)
CTimer::Initialise();
FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables();
- currLevel = LEVEL_INDUSTRIAL;
+ currLevel = LEVEL_NONE;
CCollision::SortOutCollisionAfterLoad();
}
}
diff --git a/src/core/Game.h b/src/core/Game.h
index 48f31abc..1b8fcb0a 100644
--- a/src/core/Game.h
+++ b/src/core/Game.h
@@ -3,15 +3,37 @@
enum eLevelName {
LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel
LEVEL_NONE = 0,
- LEVEL_INDUSTRIAL,
- LEVEL_COMMERCIAL,
- LEVEL_SUBURBAN
+ LEVEL_BEACH,
+ LEVEL_MAINLAND
+};
+
+enum eAreaName {
+ AREA_MAIN_MAP,
+ AREA_HOTEL,
+ AREA_MANSION,
+ AREA_BANK,
+ AREA_MALL,
+ AREA_STRIP_CLUB,
+ AREA_LAWYERS,
+ AREA_COFFEE_SHOP,
+ AREA_CONCERT_HALL,
+ AREA_STUDIO,
+ AREA_RIFLE_RANGE,
+ AREA_BIKER_BAR,
+ AREA_POLICE_STATION,
+ AREA_EVERYWHERE,
+ AREA_DIRT,
+ AREA_BLOOD,
+ AREA_OVALRING,
+ AREA_MALIBU_CLUB,
+ AREA_PRINT_WORKS
};
class CGame
{
public:
static eLevelName currLevel;
+ static int32 currArea;
static bool bDemoMode;
static bool nastyGame;
static bool frenchGame;
@@ -42,3 +64,5 @@ public:
static void DrasticTidyUpMemory(bool);
static void ProcessTidyUpMemory(void);
};
+
+inline bool IsAreaVisible(int area) { return area == CGame::currArea || area == AREA_EVERYWHERE; }
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index e970e42d..c649d49d 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -80,4 +80,3 @@ public:
~CPlayerInfo() { };
};
-static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index dab8bafb..52886604 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -18,7 +18,6 @@
#include "FileMgr.h"
#include "FileLoader.h"
#include "Zones.h"
-#include "ZoneCull.h"
#include "Radar.h"
#include "Camera.h"
#include "Record.h"
@@ -28,10 +27,10 @@
#include "CutsceneMgr.h"
#include "CdStream.h"
#include "Streaming.h"
-#ifdef FIX_BUGS
#include "Replay.h"
-#endif
#include "main.h"
+#include "ColStore.h"
+#include "DMAudio.h"
bool CStreaming::ms_disableStreaming;
bool CStreaming::ms_bLoadingBigModel;
@@ -53,7 +52,6 @@ int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED];
int32 CStreaming::ms_lastVehicleDeleted;
CDirectory *CStreaming::ms_pExtraObjectsDir;
int32 CStreaming::ms_numPriorityRequests;
-bool CStreaming::ms_hasLoadedLODs;
int32 CStreaming::ms_currentPedGrp;
int32 CStreaming::ms_currentPedLoading;
int32 CStreaming::ms_lastCullZone;
@@ -66,16 +64,10 @@ uint32 CStreaming::ms_memoryAvailable;
int32 desiredNumVehiclesLoaded = 12;
-CEntity *pIslandLODindustEntity;
-CEntity *pIslandLODcomIndEntity;
-CEntity *pIslandLODcomSubEntity;
-CEntity *pIslandLODsubIndEntity;
-CEntity *pIslandLODsubComEntity;
-int32 islandLODindust;
-int32 islandLODcomInd;
-int32 islandLODcomSub;
-int32 islandLODsubInd;
-int32 islandLODsubCom;
+CEntity *pIslandLODmainlandEntity;
+CEntity *pIslandLODbeachEntity;
+int32 islandLODmainland;
+int32 islandLODbeach;
bool
CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
@@ -184,7 +176,6 @@ CStreaming::Init2(void)
ms_pExtraObjectsDir = new CDirectory(EXTRADIRSIZE);
ms_numPriorityRequests = 0;
- ms_hasLoadedLODs = true;
ms_currentPedGrp = -1;
ms_lastCullZone = -1; // unused because RemoveModelsNotVisibleFromCullzone is gone
ms_loadedGangs = 0;
@@ -215,32 +206,12 @@ CStreaming::Init2(void)
// find island LODs
- pIslandLODindustEntity = nil;
- pIslandLODcomIndEntity = nil;
- pIslandLODcomSubEntity = nil;
- pIslandLODsubIndEntity = nil;
- pIslandLODsubComEntity = nil;
- islandLODindust = -1;
- islandLODcomInd = -1;
- islandLODcomSub = -1;
- islandLODsubInd = -1;
- islandLODsubCom = -1;
- CModelInfo::GetModelInfo("IslandLODInd", &islandLODindust);
- CModelInfo::GetModelInfo("IslandLODcomIND", &islandLODcomInd);
- CModelInfo::GetModelInfo("IslandLODcomSUB", &islandLODcomSub);
- CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd);
- CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom);
-
- for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if(building == nil)
- continue;
- if(building->GetModelIndex() == islandLODindust) pIslandLODindustEntity = building;
- if(building->GetModelIndex() == islandLODcomInd) pIslandLODcomIndEntity = building;
- if(building->GetModelIndex() == islandLODcomSub) pIslandLODcomSubEntity = building;
- if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building;
- if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building;
- }
+ pIslandLODmainlandEntity = nil;
+ pIslandLODbeachEntity = nil;
+ islandLODmainland = -1;
+ islandLODbeach = -1;
+ CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland);
+ CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach);
}
void
@@ -278,7 +249,6 @@ CStreaming::Shutdown(void)
void
CStreaming::Update(void)
{
- CEntity *train;
CStreamingInfo *si, *prev;
bool requestedSubway = false;
@@ -292,31 +262,32 @@ CStreaming::Update(void)
if(CTimer::GetIsPaused())
return;
- train = FindPlayerTrain();
- if(train && train->GetPosition().z < 0.0f){
- RequestSubway();
- requestedSubway = true;
- }else if(!ms_disableStreaming)
+ LoadBigBuildingsWhenNeeded();
+ if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f)
AddModelsToRequestList(TheCamera.GetPosition());
DeleteFarAwayRwObjects(TheCamera.GetPosition());
if(!ms_disableStreaming &&
- !CCutsceneMgr::IsRunning() &&
- !requestedSubway &&
- !CGame::playingIntro &&
+ !CCutsceneMgr::IsCutsceneProcessing() &&
ms_numModelsRequested < 5 &&
- !CRenderer::m_loadingPriority
-#ifdef FIX_BUGS
- && !CReplay::IsPlayingBack()
-#endif
- ){
+ !CRenderer::m_loadingPriority &&
+ CGame::currArea == 0 &&
+ !CReplay::IsPlayingBack()){
StreamVehiclesAndPeds();
StreamZoneModels(FindPlayerCoors());
}
LoadRequestedModels();
+ if(CWorld::Players[0].m_pRemoteVehicle){
+ CColStore::AddCollisionNeededAtPosn(FindPlayerCoors());
+ CColStore::LoadCollision(CWorld::Players[0].m_pRemoteVehicle->GetPosition());
+ CColStore::EnsureCollisionIsInMemory(CWorld::Players[0].m_pRemoteVehicle->GetPosition());
+ }else{
+ CColStore::LoadCollision(FindPlayerCoors());
+ CColStore::EnsureCollisionIsInMemory(FindPlayerCoors());
+ }
for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){
prev = si->m_prev;
@@ -363,8 +334,7 @@ void
CStreaming::LoadCdDirectory(const char *dirname, int n)
{
int fd, lastID, imgSelector;
- int modelId, txdId;
- uint32 posn, size;
+ int modelId;
CDirectory::DirectoryInfo direntry;
char *dot;
@@ -375,23 +345,23 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
imgSelector = n<<24;
assert(sizeof(direntry) == 32);
while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){
- dot = strchr(direntry.name, '.');
- if(dot) *dot = '\0';
+ bool bAddToStreaming = false;
+
if(direntry.size > (uint32)ms_streamingBufferSize)
ms_streamingBufferSize = direntry.size;
+ direntry.name[23] = '\0';
+ dot = strchr(direntry.name, '.');
+ if(dot == nil || dot-direntry.name > 20){
+ debug("%s is too long\n", direntry.name);
+ lastID = -1;
+ continue;
+ }
+
+ *dot = '\0';
- if(!CGeneral::faststrcmp(dot+1, "DFF") || !CGeneral::faststrcmp(dot+1, "dff")){
+ if(!CGeneral::faststricmp(dot+1, "DFF")){
if(CModelInfo::GetModelInfo(direntry.name, &modelId)){
- if(ms_aInfoForModel[modelId].GetCdPosnAndSize(posn, size)){
- debug("%s appears more than once in %s\n", direntry.name, dirname);
- lastID = -1;
- }else{
- direntry.offset |= imgSelector;
- ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size);
- if(lastID != -1)
- ms_aInfoForModel[lastID].m_nextID = modelId;
- lastID = modelId;
- }
+ bAddToStreaming = true;
}else{
#ifdef FIX_BUGS
// remember which cdimage this came from
@@ -401,22 +371,36 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
#endif
lastID = -1;
}
- }else if(!CGeneral::faststrcmp(dot+1, "TXD") || !CGeneral::faststrcmp(dot+1, "txd")){
- txdId = CTxdStore::FindTxdSlot(direntry.name);
- if(txdId == -1)
- txdId = CTxdStore::AddTxdSlot(direntry.name);
- if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){
- debug("%s appears more than once in %s\n", direntry.name, dirname);
+ }else if(!CGeneral::faststricmp(dot+1, "TXD")){
+ modelId = CTxdStore::FindTxdSlot(direntry.name);
+ if(modelId == -1)
+ modelId = CTxdStore::AddTxdSlot(direntry.name);
+ modelId += STREAM_OFFSET_TXD;
+ bAddToStreaming = true;
+ }else if(!CGeneral::faststricmp(dot+1, "COL")){
+ modelId = CColStore::FindColSlot(direntry.name);
+ if(modelId == -1)
+ modelId = CColStore::AddColSlot(direntry.name);
+ modelId += STREAM_OFFSET_COL;
+ bAddToStreaming = true;
+ // TODO(MIAMI): IFP
+ }else{
+ *dot = '.';
+ lastID = -1;
+ }
+
+ if(bAddToStreaming){
+ if(ms_aInfoForModel[modelId].GetCdSize()){
+ debug("%s.%s appears more than once in %s\n", direntry.name, dot+1, dirname);
lastID = -1;
}else{
direntry.offset |= imgSelector;
- ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size);
+ ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size);
if(lastID != -1)
- ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD;
- lastID = txdId + STREAM_OFFSET_TXD;
+ ms_aInfoForModel[lastID].m_nextID = modelId;
+ lastID = modelId;
}
- }else
- lastID = -1;
+ }
}
CFileMgr::CloseFile(fd);
@@ -440,6 +424,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
stream = RwStreamOpen(rwSTREAMMEMORY, rwSTREAMREAD, &mem);
if(streamId < STREAM_OFFSET_TXD){
+//--MIAMI: also check animation
// Model
mi = CModelInfo::GetModelInfo(streamId);
@@ -481,7 +466,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
- }else{
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
assert(streamId < NUMSTREAMINFO);
if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 &&
@@ -506,20 +491,19 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
+ }else if(streamId >= STREAM_OFFSET_COL && streamId < NUMSTREAMINFO){
+ if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){
+ debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL));
+ RemoveModel(streamId);
+ ReRequestModel(streamId);
+ RwStreamClose(stream, &mem);
+ return false;
+ }
+ // TODO(MIAMI): IFP
}
RwStreamClose(stream, &mem);
- // We shouldn't even end up here unless load was successful
- if(!success){
- ReRequestModel(streamId);
- if(streamId < STREAM_OFFSET_TXD)
- debug("Failed to load %s.dff\n", mi->GetName());
- else
- debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD));
- return false;
- }
-
if(streamId < STREAM_OFFSET_TXD){
// Model
// Vehicles and Peds not in loaded list
@@ -537,10 +521,11 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
}
- }else{
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
+ // TODO(MIAMI): animations
}
// Mark objects as loaded
@@ -552,10 +537,16 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
timeDiff = endTime - startTime;
if(timeDiff > 5){
+ // TODO: is this inlined?
+ static char objname[32];
if(streamId < STREAM_OFFSET_TXD)
- debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff);
- else
- debug("txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff);
+ sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetName());
+ else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL)
+ sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD));
+ else if(streamId >= STREAM_OFFSET_COL && streamId < NUMSTREAMINFO)
+ sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL));
+ // TODO(MIAMI): IFP
+ debug("%s took %d ms\n", objname, timeDiff);
}
return true;
@@ -672,51 +663,26 @@ CStreaming::RequestModel(int32 id, int32 flags)
}
}
+#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE
+
void
-CStreaming::RequestSubway(void)
-{
- RequestModel(MI_SUBWAY1, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY2, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY3, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY4, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY5, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY6, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY7, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY8, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY9, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY10, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY11, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY12, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY13, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY14, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY15, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY16, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY17, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY18, STREAMFLAGS_NOFADE);
-
- switch(CGame::currLevel){
- case LEVEL_INDUSTRIAL:
- RequestModel(MI_SUBPLATFORM_IND, STREAMFLAGS_NOFADE);
- break;
- case LEVEL_COMMERCIAL:
- if(FindPlayerTrain()->GetPosition().y < -700.0f){
- RequestModel(MI_SUBPLATFORM_COMS, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBPLATFORM_COMS2, STREAMFLAGS_NOFADE);
- }else{
- RequestModel(MI_SUBPLATFORM_COMN, STREAMFLAGS_NOFADE);
- }
- break;
- case LEVEL_SUBURBAN:
- RequestModel(MI_SUBPLATFORM_SUB, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBPLATFORM_SUB2, STREAMFLAGS_NOFADE);
- break;
+CStreaming::RequestBigBuildings(eLevelName level)
+{
+ int i, n;
+ CBuilding *b;
+
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ b = CPools::GetBuildingPool()->GetSlot(i);
+ if(b && b->bIsBIGBuilding && b->m_level == level)
+ if(!b->bStreamBIGBuilding)
+ RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
+ RequestIslands(level);
}
-#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY
-
void
-CStreaming::RequestBigBuildings(eLevelName level)
+CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
{
int i, n;
CBuilding *b;
@@ -725,27 +691,43 @@ CStreaming::RequestBigBuildings(eLevelName level)
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding && b->m_level == level)
- RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
+ if(b->bStreamBIGBuilding){
+ if(CRenderer::ShouldModelBeStreamed(b))
+ RequestModel(b->GetModelIndex(), 0);
+ }else
+ RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
RequestIslands(level);
- ms_hasLoadedLODs = false;
}
void
+CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos)
+{
+ int i, n;
+ CBuilding *b;
+
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ b = CPools::GetBuildingPool()->GetSlot(i);
+ if(b && b->bIsBIGBuilding && b->m_level == level &&
+ b->bStreamBIGBuilding && b->m_rwObject == nil)
+ if(CRenderer::ShouldModelBeStreamed(b))
+ b->CreateRwObject();
+ }
+}
+
+//--MIAMI: done
+void
CStreaming::RequestIslands(eLevelName level)
{
switch(level){
- case LEVEL_INDUSTRIAL:
- RequestModel(islandLODcomInd, BIGBUILDINGFLAGS);
- RequestModel(islandLODsubInd, BIGBUILDINGFLAGS);
- break;
- case LEVEL_COMMERCIAL:
- RequestModel(islandLODindust, BIGBUILDINGFLAGS);
- RequestModel(islandLODsubCom, BIGBUILDINGFLAGS);
+ case LEVEL_MAINLAND:
+ if(islandLODbeach != -1)
+ RequestModel(islandLODbeach, BIGBUILDINGFLAGS);
break;
- case LEVEL_SUBURBAN:
- RequestModel(islandLODindust, BIGBUILDINGFLAGS);
- RequestModel(islandLODcomSub, BIGBUILDINGFLAGS);
+ case LEVEL_BEACH:
+ if(islandLODmainland != -1)
+ RequestModel(islandLODmainland, BIGBUILDINGFLAGS);
break;
}
}
@@ -830,8 +812,11 @@ CStreaming::RemoveModel(int32 id)
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){
if(id < STREAM_OFFSET_TXD)
CModelInfo::GetModelInfo(id)->DeleteRwObject();
- else
+ else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL)
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
+ else if(id >= STREAM_OFFSET_COL && id < NUMSTREAMINFO)
+ CColStore::RemoveCol(id - STREAM_OFFSET_COL);
+ // TODO(MIAMI): IFP
ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE;
}
@@ -852,24 +837,27 @@ CStreaming::RemoveModel(int32 id)
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){
if(id < STREAM_OFFSET_TXD)
RpClumpGtaCancelStream();
- else
+ else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL)
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
+ else if(id >= STREAM_OFFSET_COL && id < NUMSTREAMINFO)
+ CColStore::RemoveCol(id - STREAM_OFFSET_COL);
+ // TODO(MIAMI): IFP
}
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
}
+//--MIAMI: done
void
CStreaming::RemoveUnusedBuildings(eLevelName level)
{
- if(level != LEVEL_INDUSTRIAL)
- RemoveBuildings(LEVEL_INDUSTRIAL);
- if(level != LEVEL_COMMERCIAL)
- RemoveBuildings(LEVEL_COMMERCIAL);
- if(level != LEVEL_SUBURBAN)
- RemoveBuildings(LEVEL_SUBURBAN);
+ if(level != LEVEL_BEACH)
+ RemoveBuildings(LEVEL_BEACH);
+ if(level != LEVEL_MAINLAND)
+ RemoveBuildings(LEVEL_MAINLAND);
}
+//--MIAMI: done
void
CStreaming::RemoveBuildings(eLevelName level)
{
@@ -930,15 +918,14 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
+//--MIAMI: done
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
- if(level != LEVEL_INDUSTRIAL)
- RemoveBigBuildings(LEVEL_INDUSTRIAL);
- if(level != LEVEL_COMMERCIAL)
- RemoveBigBuildings(LEVEL_COMMERCIAL);
- if(level != LEVEL_SUBURBAN)
- RemoveBigBuildings(LEVEL_SUBURBAN);
+ if(level != LEVEL_BEACH)
+ RemoveBigBuildings(LEVEL_BEACH);
+ if(level != LEVEL_MAINLAND)
+ RemoveBigBuildings(LEVEL_MAINLAND);
RemoveIslandsNotUsed(level);
}
@@ -958,32 +945,29 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
+ int i;
+ if(pIslandLODmainlandEntity == nil)
+ for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
+ CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
+ if(building == nil)
+ continue;
+ if(building->GetModelIndex() == islandLODmainland)
+ pIslandLODmainlandEntity = building;
+ if(building->GetModelIndex() == islandLODbeach)
+ pIslandLODbeachEntity = building;
+ }
+
switch(level){
- case LEVEL_INDUSTRIAL:
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubComEntity);
- break;
- case LEVEL_COMMERCIAL:
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
+ case LEVEL_MAINLAND:
+ DeleteIsland(pIslandLODmainlandEntity);
break;
- case LEVEL_SUBURBAN:
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- break;
- default:
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
+ case LEVEL_BEACH:
+ DeleteIsland(pIslandLODbeachEntity);
break;
}
}
+//--MIAMI: done
void
CStreaming::RemoveBigBuildings(eLevelName level)
{
@@ -1188,41 +1172,6 @@ CStreaming::IsObjectInCdImage(int32 id)
}
void
-CStreaming::HaveAllBigBuildingsLoaded(eLevelName level)
-{
- int i, n;
- CEntity *e;
-
- if(ms_hasLoadedLODs)
- return;
-
- if(level == LEVEL_INDUSTRIAL){
- if(ms_aInfoForModel[islandLODcomInd].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODsubInd].m_loadState != STREAMSTATE_LOADED)
- return;
- }else if(level == LEVEL_COMMERCIAL){
- if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODsubCom].m_loadState != STREAMSTATE_LOADED)
- return;
- }else if(level == LEVEL_SUBURBAN){
- if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODcomSub].m_loadState != STREAMSTATE_LOADED)
- return;
- }
-
- 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)
- return;
- }
-
- RemoveUnusedBigBuildings(level);
- ms_hasLoadedLODs = true;
-}
-
-void
CStreaming::SetModelIsDeletable(int32 id)
{
ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_DONT_REMOVE;
@@ -1454,6 +1403,42 @@ CStreaming::RemoveCurrentZonesModels(void)
ms_loadedGangCars = 0;
}
+void
+CStreaming::LoadBigBuildingsWhenNeeded(void)
+{
+ // Very much like CCollision::Update and CCollision::LoadCollisionWhenINeedIt
+ if(CCutsceneMgr::IsCutsceneProcessing())
+ return;
+
+ if(CTheZones::m_CurrLevel == LEVEL_NONE ||
+ CTheZones::m_CurrLevel == CGame::currLevel)
+ return;
+
+ CTimer::Suspend();
+ CGame::currLevel = CTheZones::m_CurrLevel;
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ CCollision::LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+
+ // CPopulation::DealWithZoneChange is unused in VC
+ RemoveUnusedBigBuildings(CGame::currLevel);
+ RemoveUnusedBuildings(CGame::currLevel);
+ RemoveUnusedModelsInLoadedList();
+ CGame::TidyUpMemory(true, true);
+
+ CReplay::EmptyReplayBuffer();
+ if(CGame::currLevel != LEVEL_NONE)
+ LoadSplash(GetLevelSplashScreen(CGame::currLevel));
+
+ CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
+ CStreaming::LoadAllRequestedModels(true);
+
+ CGame::TidyUpMemory(true, true);
+ CTimer::Resume();
+ DMAudio.SetEffectsFadeVol(127);
+}
+
// Find starting offset of the cdimage we next want to read
// Not useful at all on PC...
@@ -1982,8 +1967,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float
if(xmin < pos.x && pos.x < xmax &&
ymin < pos.y && pos.y < ymax &&
(CVector2D(x, y) - pos).MagnitudeSqr() < lodDistSq)
- if(CRenderer::IsEntityCullZoneVisible(e))
- RequestModel(e->GetModelIndex(), 0);
+ RequestModel(e->GetModelIndex(), 0);
}
}
}
@@ -2006,8 +1990,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list)
(!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){
CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex());
if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff()))
- if(CRenderer::IsEntityCullZoneVisible(e))
- RequestModel(e->GetModelIndex(), 0);
+ RequestModel(e->GetModelIndex(), 0);
}
}
}
@@ -2430,13 +2413,26 @@ CStreaming::LoadScene(const CVector &pos)
RemoveModel(si - ms_aInfoForModel);
}
CRenderer::m_loadingPriority = false;
- CCullZones::ForceCullZoneCoors(pos);
DeleteAllRwObjects();
+ if(level == LEVEL_NONE)
+ level = CGame::currLevel;
+ CGame::currLevel = level;
+ RemoveUnusedBigBuildings(level);
+ RequestBigBuildings(level, pos);
+ RequestBigBuildings(LEVEL_NONE, pos);
+ RemoveIslandsNotUsed(level);
+ LoadAllRequestedModels(false);
+ InstanceBigBuildings(level, pos);
+ InstanceBigBuildings(LEVEL_NONE, pos);
AddModelsToRequestList(pos);
CRadar::StreamRadarSections(pos);
- RemoveUnusedBigBuildings(level);
- RequestBigBuildings(level);
+
+ // TODO(MIAMI): stream zone vehicles
LoadAllRequestedModels(false);
+ // TODO(MIAMI): InstanceLoadedModels
+
+ for(int i = 0; i < NUMSTREAMINFO; i++)
+ ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20;
debug("End load scene\n");
}
diff --git a/src/core/Streaming.h b/src/core/Streaming.h
index 84434769..ba868a54 100644
--- a/src/core/Streaming.h
+++ b/src/core/Streaming.h
@@ -4,7 +4,8 @@
enum {
STREAM_OFFSET_TXD = MODELINFOSIZE,
- NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE
+ STREAM_OFFSET_COL = STREAM_OFFSET_TXD+TXDSTORESIZE,
+ NUMSTREAMINFO = STREAM_OFFSET_COL+COLSTORESIZE
};
enum StreamFlags
@@ -14,6 +15,7 @@ enum StreamFlags
STREAMFLAGS_DEPENDENCY = 0x04, // Is this right?
STREAMFLAGS_PRIORITY = 0x08,
STREAMFLAGS_NOFADE = 0x10,
+ STREAMFLAGS_20 = 0x20, // TODO(MIAMI): what's this
STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED,
STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY,
@@ -94,7 +96,6 @@ public:
static int32 ms_lastVehicleDeleted;
static CDirectory *ms_pExtraObjectsDir;
static int32 ms_numPriorityRequests;
- static bool ms_hasLoadedLODs;
static int32 ms_currentPedGrp;
static int32 ms_lastCullZone;
static uint16 ms_loadedGangs;
@@ -115,14 +116,20 @@ public:
static bool FinishLoadingLargeFile(int8 *buf, int32 streamId);
static bool HasModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; }
static bool HasTxdLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_TXD); }
+ static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); }
static bool CanRemoveModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0; }
static bool CanRemoveTxd(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_TXD); }
+ static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); }
static void RequestModel(int32 model, int32 flags);
static void ReRequestModel(int32 model) { RequestModel(model, ms_aInfoForModel[model].m_flags); }
static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); }
static void ReRequestTxd(int32 txd) { ReRequestModel(txd + STREAM_OFFSET_TXD); }
+ static void RequestCol(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_COL, flags); }
+ static void ReRequestCol(int32 col) { ReRequestModel(col + STREAM_OFFSET_COL); }
static void RequestSubway(void);
static void RequestBigBuildings(eLevelName level);
+ static void RequestBigBuildings(eLevelName level, const CVector &pos);
+ static void InstanceBigBuildings(eLevelName level, const CVector &pos);
static void RequestIslands(eLevelName level);
static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags);
static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags);
@@ -131,6 +138,7 @@ public:
static void DecrementRef(int32 id);
static void RemoveModel(int32 id);
static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); }
+ static void RemoveCol(int32 id) { RemoveModel(id + STREAM_OFFSET_COL); }
static void RemoveUnusedBuildings(eLevelName level);
static void RemoveBuildings(eLevelName level);
static void RemoveUnusedBigBuildings(eLevelName level);
@@ -145,7 +153,6 @@ public:
static bool IsTxdUsedByRequestedModels(int32 txdId);
static bool AddToLoadedVehiclesList(int32 modelId);
static bool IsObjectInCdImage(int32 id);
- static void HaveAllBigBuildingsLoaded(eLevelName level);
static void SetModelIsDeletable(int32 id);
static void SetModelTxdIsDeletable(int32 id);
static void SetMissionDoesntRequireModel(int32 id);
@@ -154,6 +161,7 @@ public:
static void StreamVehiclesAndPeds(void);
static void StreamZoneModels(const CVector &pos);
static void RemoveCurrentZonesModels(void);
+ static void LoadBigBuildingsWhenNeeded(void);
static int32 GetCdImageOffset(int32 lastPosn);
static int32 GetNextFileOnCd(int32 position, bool priority);
diff --git a/src/core/User.cpp b/src/core/User.cpp
index f906ae44..716d6393 100644
--- a/src/core/User.cpp
+++ b/src/core/User.cpp
@@ -32,8 +32,8 @@ void
CPlaceName::Process()
{
CVector pos = CWorld::Players[CWorld::PlayerInFocus].GetPos();
- CZone *navigZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_NAVIG);
- CZone *defaultZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_DEFAULT);
+ CZone *navigZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, false, true);
+ CZone *defaultZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, true, false);
if (navigZone == nil) m_pZone = nil;
if (defaultZone == nil) m_pZone2 = nil;
diff --git a/src/core/World.h b/src/core/World.h
index ab3f0192..372cd8b5 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -4,19 +4,19 @@
#include "Lists.h"
#include "PlayerInfo.h"
-/* Sectors span from -2000 to 2000 in x and y.
- * With 100x100 sectors, each is 40x40 units. */
+/* Sectors span from -2400 to 1600 in x and -2000 to 2000 y.
+ * With 80x80 sectors, each is 50x50 units. */
-#define SECTOR_SIZE_X (40.0f)
-#define SECTOR_SIZE_Y (40.0f)
+#define SECTOR_SIZE_X (50.0f)
+#define SECTOR_SIZE_Y (50.0f)
-#define NUMSECTORS_X (100)
-#define NUMSECTORS_Y (100)
+#define NUMSECTORS_X (80)
+#define NUMSECTORS_Y (80)
#define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X)
#define WORLD_SIZE_Y (NUMSECTORS_Y * SECTOR_SIZE_Y)
-#define WORLD_MIN_X (-2000.0f)
+#define WORLD_MIN_X (-2400.0f)
#define WORLD_MIN_Y (-2000.0f)
#define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X)
diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp
index 6dcd0f18..729cc35d 100644
--- a/src/core/ZoneCull.cpp
+++ b/src/core/ZoneCull.cpp
@@ -11,207 +11,22 @@
#include "ZoneCull.h"
#include "Zones.h"
-int32 CCullZones::NumCullZones;
-CCullZone CCullZones::aZones[NUMCULLZONES];
int32 CCullZones::NumAttributeZones;
CAttributeZone CCullZones::aAttributeZones[NUMATTRIBZONES];
-uint16 CCullZones::aIndices[NUMZONEINDICES];
-int16 CCullZones::aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
-int16 CCullZones::aPointersToBigBuildingsForTreadables[NUMTREADABLES];
int32 CCullZones::CurrentWantedLevelDrop_Player;
int32 CCullZones::CurrentFlags_Camera;
int32 CCullZones::CurrentFlags_Player;
-int32 CCullZones::OldCullZone;
-int32 CCullZones::EntityIndicesUsed;
bool CCullZones::bCurrentSubwayIsInvisible;
-bool CCullZones::bCullZonesDisabled;
-
void
CCullZones::Init(void)
{
- int i;
-
NumAttributeZones = 0;
CurrentWantedLevelDrop_Player = 0;
CurrentFlags_Camera = 0;
CurrentFlags_Player = 0;
bCurrentSubwayIsInvisible = false;
- NumCullZones = 0;
- OldCullZone = -1;
- EntityIndicesUsed = 0;
-
- for(i = 0; i < NUMBUILDINGS; i++)
- aPointersToBigBuildingsForBuildings[i] = -1;
- for(i = 0; i < NUMTREADABLES; i++)
- aPointersToBigBuildingsForTreadables[i] = -1;
-}
-
-bool CCullZone::TestLine(CVector vec1, CVector vec2)
-{
- CColPoint colPoint;
- CEntity *entity;
-
- if (CWorld::ProcessLineOfSight(vec1, vec2, colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x + 0.05f, vec1.y, vec1.z), CVector(vec2.x + 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x - 0.05f, vec1.y, vec1.z), CVector(vec2.x - 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y + 0.05f, vec1.z), CVector(vec2.x, vec2.y + 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y - 0.05f, vec1.z), CVector(vec2.x, vec2.y - 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z + 0.05f), CVector(vec2.x, vec2.y, vec2.z + 0.05f), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- return CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z - 0.05f), CVector(vec2.x, vec2.y, vec2.z - 0.05f), colPoint, entity, true, false, false, false, false, true, false);
-}
-
-
-uint16* pTempArrayIndices;
-int TempEntityIndicesUsed;
-
-void
-CCullZones::ResolveVisibilities(void)
-{
- int fd;
-
- CFileMgr::SetDir("");
- fd = CFileMgr::OpenFile("DATA\\cullzone.dat", "rb");
- if(fd > 0){
- CFileMgr::Read(fd, (char*)&NumCullZones, sizeof(NumCullZones));
- CFileMgr::Read(fd, (char*)aZones, sizeof(aZones));
- CFileMgr::Read(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones));
- CFileMgr::Read(fd, (char*)aAttributeZones, sizeof(aAttributeZones));
- CFileMgr::Read(fd, (char*)aIndices, sizeof(aIndices));
- CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings));
- CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables));
- CFileMgr::CloseFile(fd);
- }else{
-#if 0
- // TODO: implement code from mobile to generate data here
- EntityIndicesUsed = 0;
- BuildListForBigBuildings();
- pTempArrayIndices = new uint16[140000];
- TempEntityIndicesUsed = 0;
-
- for (int i = 0; i < NumCullZones; i++) {
- DoVisibilityTestCullZone(i, true);
- }
-
- CompressIndicesArray();
- delete[] pTempArrayIndices;
-
- fd = CFileMgr::OpenFileForWriting("data\\cullzone.dat");
- if (fd != 0) {
- CFileMgr::Write(fd, (char*)&NumCullZones, sizeof(NumCullZones));
- CFileMgr::Write(fd, (char*)aZones, sizeof(aZones));
- CFileMgr::Write(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones));
- CFileMgr::Write(fd, (char*)&aAttributeZones, sizeof(aAttributeZones));
- CFileMgr::Write(fd, (char*)&aIndices, sizeof(aIndices));
- CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings));
- CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables));
- CFileMgr::CloseFile(fd);
- }
-#endif
- }
-}
-
-void
-CCullZones::BuildListForBigBuildings()
-{
- for (int i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--) {
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if (building == nil || !building->bIsBIGBuilding) continue;
- CSimpleModelInfo *nonlod = (CSimpleModelInfo*)((CSimpleModelInfo *)CModelInfo::GetModelInfo(building->GetModelIndex()))->m_atomics[2];
- if (nonlod == nil) continue;
-
- for (int j = i; j >= 0; j--) {
- CBuilding *building2 = CPools::GetBuildingPool()->GetSlot(j);
- if (building2 == nil || building2->bIsBIGBuilding) continue;
- if (CModelInfo::GetModelInfo(building2->GetModelIndex()) == nonlod) {
- if ((building2->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) {
- aPointersToBigBuildingsForBuildings[j] = i;
- }
- }
- }
-
- for (int j = CPools::GetTreadablePool()->GetSize()-1; j >= 0; j--) {
- CTreadable *treadable = CPools::GetTreadablePool()->GetSlot(j);
- if (treadable == nil || treadable->bIsBIGBuilding) continue;
- if (CModelInfo::GetModelInfo(treadable->GetModelIndex()) == nonlod) {
- if ((treadable->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) {
- aPointersToBigBuildingsForTreadables[j] = i;
- }
- }
- }
- }
-}
-
-void
-CCullZones::DoVisibilityTestCullZone(int zoneId, bool doIt)
-{
- aZones[zoneId].m_groupIndexCount[0] = 0;
- aZones[zoneId].m_groupIndexCount[1] = 0;
- aZones[zoneId].m_groupIndexCount[2] = 0;
- aZones[zoneId].m_indexStart = TempEntityIndicesUsed;
- aZones[zoneId].FindTestPoints();
-
- if (!doIt) return;
-
- for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) {
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if (building != nil && !building->bIsBIGBuilding && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForBuildings[i] != -1)) {
- CBuilding *building2 = nil;
- if (aPointersToBigBuildingsForBuildings[i] != -1)
- building2 = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForBuildings[i]);
-
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, building2)) {
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[0]++;
- }
- }
- }
-
- for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) {
- CTreadable* building = CPools::GetTreadablePool()->GetSlot(i);
- if (building != nil && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForTreadables[i] != -1)) {
- CTreadable* building2 = nil;
- if (aPointersToBigBuildingsForTreadables[i] != -1)
- building2 = CPools::GetTreadablePool()->GetSlot(aPointersToBigBuildingsForTreadables[i]);
-
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 10.0f, building2)) {
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[1]++;
- }
- }
- }
-
- for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) {
- CTreadable *building = CPools::GetTreadablePool()->GetSlot(i);
- if (building != nil && aZones[zoneId].CalcDistToCullZoneSquared(building->GetPosition().x, building->GetPosition().y) < 40000.0f) {
- int start = aZones[zoneId].m_groupIndexCount[0] + aZones[zoneId].m_indexStart;
- int end = aZones[zoneId].m_groupIndexCount[1] + start;
-
- bool alreadyAdded = false;
-
- for (int k = start; k < end; k++) {
- if (aIndices[k] == i)
- alreadyAdded = true;
- }
-
- if (!alreadyAdded) {
- CBuilding *building2 = nil;
- if (aPointersToBigBuildingsForTreadables[i] != -1)
- building2 = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForTreadables[i]);
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, building2)) {
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[2]++;
- }
- }
- }
- }
}
void
@@ -219,14 +34,9 @@ CCullZones::Update(void)
{
bool invisible;
- if(bCullZonesDisabled)
- return;
-
switch(CTimer::GetFrameCounter() & 7){
case 0:
case 4:
- /* Update Cull zone */
- ForceCullZoneCoors(TheCamera.GetGameCamPosition());
break;
case 2:
@@ -250,28 +60,6 @@ CCullZones::Update(void)
void
CCullZones::ForceCullZoneCoors(CVector coors)
{
- int32 z;
- z = FindCullZoneForCoors(coors);
- if(z != OldCullZone){
- if(OldCullZone >= 0)
- aZones[OldCullZone].DoStuffLeavingZone();
- if(z >= 0)
- aZones[z].DoStuffEnteringZone();
- OldCullZone = z;
- }
-}
-
-int32
-CCullZones::FindCullZoneForCoors(CVector coors)
-{
- int i;
-
- for(i = 0; i < NumCullZones; i++)
- if(coors.x >= aZones[i].minx && coors.x <= aZones[i].maxx &&
- coors.y >= aZones[i].miny && coors.y <= aZones[i].maxy &&
- coors.z >= aZones[i].minz && coors.z <= aZones[i].maxz)
- return i;
- return -1;
}
int32
@@ -346,218 +134,16 @@ CCullZones::AddCullZone(CVector const &position,
float minz, float maxz,
uint16 flag, int16 wantedLevel)
{
- CCullZone *cull;
CAttributeZone *attrib;
- CVector v;
- if((flag & ATTRZONE_NOTCULLZONE) == 0){
- cull = &aZones[NumCullZones++];
- v = position;
- // WTF is this?
- if((v-CVector(1032.14f, -624.255f, 24.93f)).Magnitude() < 1.0f)
- v = CVector(1061.7f, -613.0f, 19.0f);
- if((v-CVector(1029.48f, -495.757f, 21.98f)).Magnitude() < 1.0f)
- v = CVector(1061.4f, -506.0f, 18.5f);
- cull->position.x = clamp(v.x, minx, maxx);
- cull->position.y = clamp(v.y, miny, maxy);
- cull->position.z = clamp(v.z, minz, maxz);
- cull->minx = minx;
- cull->maxx = maxx;
- cull->miny = miny;
- cull->maxy = maxy;
- cull->minz = minz;
- cull->maxz = maxz;
- cull->m_groupIndexCount[0] = 0;
- cull->m_groupIndexCount[1] = 0;
- cull->m_groupIndexCount[2] = 0;
- cull->m_indexStart = 0;
- }
- if(flag & ~ATTRZONE_NOTCULLZONE){
- attrib = &aAttributeZones[NumAttributeZones++];
- attrib->minx = minx;
- attrib->maxx = maxx;
- attrib->miny = miny;
- attrib->maxy = maxy;
- attrib->minz = minz;
- attrib->maxz = maxz;
- attrib->attributes = flag;
- attrib->wantedLevel = wantedLevel;
- }
+ assert(NumAttributeZones < NUMATTRIBZONES);
+ attrib = &aAttributeZones[NumAttributeZones++];
+ attrib->minx = minx;
+ attrib->maxx = maxx;
+ attrib->miny = miny;
+ attrib->maxy = maxy;
+ attrib->minz = minz;
+ attrib->maxz = maxz;
+ attrib->attributes = flag;
+ attrib->wantedLevel = wantedLevel;
}
-
-
-void
-CCullZone::DoStuffLeavingZone(void)
-{
- int i;
-
- for(i = 0; i < m_numBuildings; i++)
- DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables ; i++)
- DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[m_indexStart + i]);
-}
-
-void
-CCullZone::DoStuffLeavingZone_OneBuilding(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = false;
- bb = CCullZones::aPointersToBigBuildingsForBuildings[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffLeavingZone_OneTreadableBoth(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = false;
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = false;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone(void)
-{
- int i;
-
- for(i = 0; i < m_numBuildings; i++)
- DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m; i++)
- DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables; i++)
- DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[m_indexStart + i]);
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneBuilding(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = true;
- bb = CCullZones::aPointersToBigBuildingsForBuildings[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneTreadablePlus10m(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true;
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = true;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneTreadable(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[i+j]);
- }
-}
-
-float
-CCullZone::CalcDistToCullZoneSquared(float x, float y)
-{
- float rx, ry;
-
- if (x < minx) rx = sq(x - minx);
- else if (x > maxx) rx = sq(x - maxx);
- else rx = 0.0f;
-
- if (y < miny) ry = sq(y - miny);
- else if (y > maxy) ry = sq(y - maxy);
- else ry = 0.0f;
-
- return rx + ry;
-}
-
-bool
-CCullZone::IsEntityCloseEnoughToZone(CEntity *entity, bool checkLevel)
-{
- const CVector &pos = entity->GetPosition();
-
- CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(entity->GetModelIndex());
- float distToZone = CalcDistToCullZone(pos.x, pos.y);
- float lodDist;
- if (minfo->m_isSubway)
- lodDist = minfo->GetLargestLodDistance() + 30.0f;
- else
- lodDist = minfo->GetLargestLodDistance() + 50.0f;
-
- if (lodDist > distToZone) return true;
- if (!checkLevel) return false;
- return CTheZones::GetLevelFromPosition(&pos) == CTheZones::GetLevelFromPosition(&CVector(minx, miny, minz));
-}
-
-bool
-CCullZones::DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set)
-{
- int32 curCount;
- int32 start;
- int32 size;
-
- for (int i = 0; i < NumCullZones; i++) {
- curCount = 0;
- for (int group = 0; group < 3; group++) {
- aZones[i].GetGroupStartAndSize(group, start, size);
-
- int unk = 0; // TODO: figure out
- for (int j = 0; j < size; j++) {
- for (int k = 0; k < 3; k++) {
- if (set[k] == pTempArrayIndices[start+j])
- unk++;
- }
- }
- if (unk == 3 && ++curCount >= count)
- return true;
- }
- }
- return false;
-} \ No newline at end of file
diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h
index 9bc07b8c..e76b7a44 100644
--- a/src/core/ZoneCull.h
+++ b/src/core/ZoneCull.h
@@ -1,57 +1,5 @@
class CEntity;
-class CCullZone
-{
-public:
- CVector position;
- float minx;
- float maxx;
- float miny;
- float maxy;
- float minz;
- float maxz;
-
- int32 m_indexStart;
- int16 m_groupIndexCount[3];
- int16 m_numBuildings;
- int16 m_numTreadablesPlus10m;
- int16 m_numTreadables;
-
- void DoStuffLeavingZone(void);
- static void DoStuffLeavingZone_OneBuilding(uint16 i);
- static void DoStuffLeavingZone_OneTreadableBoth(uint16 i);
- void DoStuffEnteringZone(void);
- static void DoStuffEnteringZone_OneBuilding(uint16 i);
- static void DoStuffEnteringZone_OneTreadablePlus10m(uint16 i);
- static void DoStuffEnteringZone_OneTreadable(uint16 i);
-
-
- static bool TestLine(CVector a1, CVector a2);
- float CalcDistToCullZoneSquared(float x, float y);
- float CalcDistToCullZone(float x, float y) { return Sqrt(CalcDistToCullZoneSquared(x, y)); };
- bool IsEntityCloseEnoughToZone(CEntity* entity, bool checkLevel);
-
- void GetGroupStartAndSize(int32 groupid, int32 &start, int32 &size) {
- switch (groupid) {
- case 1:
- start = m_groupIndexCount[0] + m_indexStart;
- size = m_groupIndexCount[1];
- break;
- case 2:
- start = m_groupIndexCount[0] + m_groupIndexCount[1] + m_indexStart;
- size = m_groupIndexCount[2];
- break;
- default:
- start = m_indexStart;
- size = m_groupIndexCount[0];
- break;
- }
- }
-
- void FindTestPoints() {}; // todo
- bool TestEntityVisibilityFromCullZone(CEntity*, float, CEntity*) { return false; }; // todo
-};
-
enum eZoneAttribs
{
ATTRZONE_CAMCLOSEIN = 1,
@@ -79,27 +27,17 @@ struct CAttributeZone
class CCullZones
{
public:
- static int32 NumCullZones;
- static CCullZone aZones[NUMCULLZONES];
static int32 NumAttributeZones;
static CAttributeZone aAttributeZones[NUMATTRIBZONES];
- static uint16 aIndices[NUMZONEINDICES];
- static int16 aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
- static int16 aPointersToBigBuildingsForTreadables[NUMTREADABLES];
static int32 CurrentWantedLevelDrop_Player;
static int32 CurrentFlags_Camera;
static int32 CurrentFlags_Player;
- static int32 OldCullZone;
- static int32 EntityIndicesUsed;
static bool bCurrentSubwayIsInvisible;
- static bool bCullZonesDisabled;
static void Init(void);
- static void ResolveVisibilities(void);
static void Update(void);
static void ForceCullZoneCoors(CVector coors);
- static int32 FindCullZoneForCoors(CVector coors);
static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel);
static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void);
static void MarkSubwayAsInvisible(bool visible);
@@ -117,9 +55,6 @@ public:
static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; }
static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; }
- static void BuildListForBigBuildings();
- static void DoVisibilityTestCullZone(int zoneId, bool doIt);
- static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set);
-
- static void CompressIndicesArray() {};// todo
+ //--MIAMI: TODO
+ static bool PoliceAbandonCars(void) { return false; }
};
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 22c0735a..b87665ae 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -9,21 +9,21 @@
#include "World.h"
eLevelName CTheZones::m_CurrLevel;
-CZone *CTheZones::m_pPlayersZone;
int16 CTheZones::FindIndex;
uint16 CTheZones::NumberOfAudioZones;
int16 CTheZones::AudioZoneArray[NUMAUDIOZONES];
uint16 CTheZones::TotalNumberOfMapZones;
-uint16 CTheZones::TotalNumberOfZones;
-CZone CTheZones::ZoneArray[NUMZONES];
+uint16 CTheZones::TotalNumberOfInfoZones;
+uint16 CTheZones::TotalNumberOfNavigationZones;
+CZone CTheZones::InfoZoneArray[NUMINFOZONES];
CZone CTheZones::MapZoneArray[NUMMAPZONES];
+CZone CTheZones::NavigationZoneArray[NUMNAVIGZONES];
uint16 CTheZones::TotalNumberOfZoneInfos;
-CZoneInfo CTheZones::ZoneInfoArray[2*NUMZONES];
+CZoneInfo CTheZones::ZoneInfoArray[2*NUMINFOZONES];
-#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
-inline bool IsNormalZone(int type) { return type == ZONE_DEFAULT || type == ZONE_NAVIG || type == ZONE_INFO; }
+#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
static void
CheckZoneInfo(CZoneInfo *info)
@@ -46,12 +46,14 @@ CheckZoneInfo(CZoneInfo *info)
assert(info->gangThreshold[7] <= info->gangThreshold[8]);
}
+//--MIAMI: done
wchar*
CZone::GetTranslatedName(void)
{
return TheText.Get(name);
}
+//--MIAMI: check out zoneinfo
void
CTheZones::Init(void)
{
@@ -60,12 +62,15 @@ CTheZones::Init(void)
AudioZoneArray[i] = -1;
NumberOfAudioZones = 0;
- for(i = 0; i < NUMZONES; i++)
- memset(&ZoneArray[i], 0, sizeof(CZone));
+ for(i = 0; i < NUMNAVIGZONES; i++)
+ memset(&NavigationZoneArray[i], 0, sizeof(CZone));
+
+ for(i = 0; i < NUMINFOZONES; i++)
+ memset(&InfoZoneArray[i], 0, sizeof(CZone));
CZoneInfo *zonei;
int x = 1000/6;
- for(i = 0; i < 2*NUMZONES; i++){
+ for(i = 0; i < 2*NUMINFOZONES; i++){
zonei = &ZoneInfoArray[i];
zonei->carDensity = 10;
zonei->carThreshold[0] = x;
@@ -88,54 +93,63 @@ CTheZones::Init(void)
}
TotalNumberOfZoneInfos = 1; // why 1?
- TotalNumberOfZones = 1;
+ TotalNumberOfNavigationZones = 1;
+ TotalNumberOfInfoZones = 1;
+
+ strcpy(InfoZoneArray[0].name, "CITYINF");
+ InfoZoneArray[0].minx = -2400.0f;
+ InfoZoneArray[0].miny = -2000.0f;
+ InfoZoneArray[0].minz = -500.0f;
+ InfoZoneArray[0].maxx = 1600.0f;
+ InfoZoneArray[0].maxy = 2000.0f;
+ InfoZoneArray[0].maxz = 500.0f;
+ InfoZoneArray[0].level = LEVEL_NONE;
+ InfoZoneArray[0].type = ZONE_INFO;
+
+ strcpy(NavigationZoneArray[0].name, "VICE_C");
+ NavigationZoneArray[0].minx = -2400.0f;
+ NavigationZoneArray[0].miny = -2000.0f;
+ NavigationZoneArray[0].minz = -500.0f;
+ NavigationZoneArray[0].maxx = 1600.0f;
+ NavigationZoneArray[0].maxy = 2000.0f;
+ NavigationZoneArray[0].maxz = 500.0f;
+ NavigationZoneArray[0].level = LEVEL_NONE;
+ NavigationZoneArray[0].type = ZONE_NAVIG;
m_CurrLevel = LEVEL_NONE;
- m_pPlayersZone = &ZoneArray[0];
-
- strcpy(ZoneArray[0].name, "CITYZON");
- ZoneArray[0].minx = -4000.0f;
- ZoneArray[0].miny = -4000.0f;
- ZoneArray[0].minz = -500.0f;
- ZoneArray[0].maxx = 4000.0f;
- ZoneArray[0].maxy = 4000.0f;
- ZoneArray[0].maxz = 500.0f;
- ZoneArray[0].level = LEVEL_NONE;
for(i = 0; i < NUMMAPZONES; i++){
memset(&MapZoneArray[i], 0, sizeof(CZone));
MapZoneArray[i].type = ZONE_MAPZONE;
}
-
- TotalNumberOfMapZones = 1;
-
strcpy(MapZoneArray[0].name, "THEMAP");
- MapZoneArray[0].minx = -4000.0f;
- MapZoneArray[0].miny = -4000.0f;
+ MapZoneArray[0].minx = -2400.0f;
+ MapZoneArray[0].miny = -2000.0f;
MapZoneArray[0].minz = -500.0f;
- MapZoneArray[0].maxx = 4000.0f;
- MapZoneArray[0].maxy = 4000.0f;
+ MapZoneArray[0].maxx = 1600.0f;
+ MapZoneArray[0].maxy = 2000.0f;
MapZoneArray[0].maxz = 500.0f;
MapZoneArray[0].level = LEVEL_NONE;
}
+//--MIAMI: done
void
CTheZones::Update(void)
{
CVector pos;
pos = FindPlayerCoors();
- m_pPlayersZone = FindSmallestZonePosition(&pos);
m_CurrLevel = GetLevelFromPosition(&pos);
}
+//--MIAMI: done
void
CTheZones::CreateZone(char *name, eZoneType type,
float minx, float miny, float minz,
float maxx, float maxy, float maxz,
eLevelName level)
{
+ char tmpname[24];
char *p;
- char tmpname[8];
if(minx > maxx) SWAPF(minx, maxx);
if(miny > maxy) SWAPF(miny, maxy);
@@ -144,73 +158,94 @@ CTheZones::CreateZone(char *name, eZoneType type,
// make upper case
for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
- // add zone
strncpy(tmpname, name, 7);
tmpname[7] = '\0';
- strcpy(ZoneArray[TotalNumberOfZones].name, tmpname);
- ZoneArray[TotalNumberOfZones].type = type;
- ZoneArray[TotalNumberOfZones].minx = minx;
- ZoneArray[TotalNumberOfZones].miny = miny;
- ZoneArray[TotalNumberOfZones].minz = minz;
- ZoneArray[TotalNumberOfZones].maxx = maxx;
- ZoneArray[TotalNumberOfZones].maxy = maxy;
- ZoneArray[TotalNumberOfZones].maxz = maxz;
- ZoneArray[TotalNumberOfZones].level = level;
- if(IsNormalZone(type)){
- ZoneArray[TotalNumberOfZones].zoneinfoDay = TotalNumberOfZoneInfos++;
- ZoneArray[TotalNumberOfZones].zoneinfoNight = TotalNumberOfZoneInfos++;
- }
- TotalNumberOfZones++;
-}
-
-void
-CTheZones::CreateMapZone(char *name, eZoneType type,
- float minx, float miny, float minz,
- float maxx, float maxy, float maxz,
- eLevelName level)
-{
- CZone *zone;
- char *p;
-
- if(minx > maxx) SWAPF(minx, maxx);
- if(miny > maxy) SWAPF(miny, maxy);
- if(minz > maxz) SWAPF(minz, maxz);
-
- // make upper case
- for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
// add zone
- zone = &MapZoneArray[TotalNumberOfMapZones++];
- strncpy(zone->name, name, 7);
- zone->name[7] = '\0';
- zone->type = type;
- zone->minx = minx;
- zone->miny = miny;
- zone->minz = minz;
- zone->maxx = maxx;
- zone->maxy = maxy;
- zone->maxz = maxz;
- zone->level = level;
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ assert(TotalNumberOfNavigationZones < NUMNAVIGZONES);
+ strcpy(NavigationZoneArray[TotalNumberOfNavigationZones].name, tmpname);
+ NavigationZoneArray[TotalNumberOfNavigationZones].type = type;
+ NavigationZoneArray[TotalNumberOfNavigationZones].minx = minx;
+ NavigationZoneArray[TotalNumberOfNavigationZones].miny = miny;
+ NavigationZoneArray[TotalNumberOfNavigationZones].minz = minz;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxx = maxx;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxy = maxy;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxz = maxz;
+ NavigationZoneArray[TotalNumberOfNavigationZones].level = level;
+ TotalNumberOfNavigationZones++;
+ break;
+ case ZONE_INFO:
+ assert(TotalNumberOfInfoZones < NUMINFOZONES);
+ strcpy(InfoZoneArray[TotalNumberOfInfoZones].name, tmpname);
+ InfoZoneArray[TotalNumberOfInfoZones].type = type;
+ InfoZoneArray[TotalNumberOfInfoZones].minx = minx;
+ InfoZoneArray[TotalNumberOfInfoZones].miny = miny;
+ InfoZoneArray[TotalNumberOfInfoZones].minz = minz;
+ InfoZoneArray[TotalNumberOfInfoZones].maxx = maxx;
+ InfoZoneArray[TotalNumberOfInfoZones].maxy = maxy;
+ InfoZoneArray[TotalNumberOfInfoZones].maxz = maxz;
+ InfoZoneArray[TotalNumberOfInfoZones].level = level;
+ InfoZoneArray[TotalNumberOfInfoZones].zoneinfoDay = TotalNumberOfZoneInfos++;
+ InfoZoneArray[TotalNumberOfInfoZones].zoneinfoNight = TotalNumberOfZoneInfos++;
+ TotalNumberOfInfoZones++;
+ break;
+ case ZONE_MAPZONE:
+ assert(TotalNumberOfMapZones < NUMMAPZONES);
+ strcpy(MapZoneArray[TotalNumberOfMapZones].name, tmpname);
+ MapZoneArray[TotalNumberOfMapZones].type = type;
+ MapZoneArray[TotalNumberOfMapZones].minx = minx;
+ MapZoneArray[TotalNumberOfMapZones].miny = miny;
+ MapZoneArray[TotalNumberOfMapZones].minz = minz;
+ MapZoneArray[TotalNumberOfMapZones].maxx = maxx;
+ MapZoneArray[TotalNumberOfMapZones].maxy = maxy;
+ MapZoneArray[TotalNumberOfMapZones].maxz = maxz;
+ MapZoneArray[TotalNumberOfMapZones].level = level;
+ TotalNumberOfMapZones++;
+ break;
+ }
}
+//--MIAMI: done
void
CTheZones::PostZoneCreation(void)
{
int i;
- for(i = 1; i < TotalNumberOfZones; i++)
- InsertZoneIntoZoneHierarchy(&ZoneArray[i]);
+ for(i = 1; i < TotalNumberOfNavigationZones; i++)
+ InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]);
InitialiseAudioZoneArray();
}
+//--MIAMI: done, but does nothing
+void
+CTheZones::CheckZonesForOverlap(void)
+{
+ int i, j;
+ char str[116];
+
+ for(i = 1; i < TotalNumberOfInfoZones; i++){
+ ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[0]);
+
+ for(j = 1; j < TotalNumberOfInfoZones; j++)
+ if(i != j && ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[j]))
+ sprintf(str, "Info zone %s contains %s\n",
+ &InfoZoneArray[j].name, &InfoZoneArray[i].name);
+ }
+}
+
+//--MIAMI: done
void
CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone)
{
zone->child = nil;
zone->parent = nil;
zone->next = nil;
- InsertZoneIntoZoneHierRecursive(zone, &ZoneArray[0]);
+ InsertZoneIntoZoneHierRecursive(zone, &NavigationZoneArray[0]);
}
+//--MIAMI: done
bool
CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer)
{
@@ -254,6 +289,7 @@ CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer)
return true;
}
+//--MIAMI: done
bool
CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer)
{
@@ -278,6 +314,7 @@ CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer)
return true;
}
+//--MIAMI: done
bool
CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone)
{
@@ -286,6 +323,7 @@ CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone)
zone->minz <= v->z && v->z <= zone->maxz;
}
+//--MIAMI: done
eLevelName
CTheZones::GetLevelFromPosition(CVector const *v)
{
@@ -299,35 +337,35 @@ CTheZones::GetLevelFromPosition(CVector const *v)
return MapZoneArray[0].level;
}
+//--MIAMI: done
CZone*
-CTheZones::FindSmallestZonePosition(const CVector *v)
+CTheZones::FindInformationZoneForPosition(const CVector *v)
{
- CZone *best = &ZoneArray[0];
- // zone to test next
- CZone *zone = ZoneArray[0].child;
- while(zone)
- // if in zone, descent into children
- if(PointLiesWithinZone(v, zone)){
- best = zone;
- zone = zone->child;
- // otherwise try next zone
- }else
- zone = zone->next;
- return best;
+ int i;
+// char tmp[116];
+// if(!PointLiesWithinZone(v, &InfoZoneArray[0]))
+// sprintf(tmp, "x = %.3f y= %.3f z = %.3f\n", v.x, v.y, v.z);
+ for(i = 1; i < TotalNumberOfInfoZones; i++)
+ if(PointLiesWithinZone(v, &InfoZoneArray[i]))
+ return &InfoZoneArray[i];
+ return &InfoZoneArray[0];
}
+//--MIAMI: done
CZone*
-CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type)
+CTheZones::FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig)
{
CZone *best = nil;
- if(ZoneArray[0].type == type)
- best = &ZoneArray[0];
+ if(findDefault && NavigationZoneArray[0].type == ZONE_DEFAULT ||
+ findNavig && NavigationZoneArray[0].type == ZONE_NAVIG)
+ best = &NavigationZoneArray[0];
// zone to test next
- CZone *zone = ZoneArray[0].child;
+ CZone *zone = NavigationZoneArray[0].child;
while(zone)
// if in zone, descent into children
if(PointLiesWithinZone(v, zone)){
- if(zone->type == type)
+ if(findDefault && zone->type == ZONE_DEFAULT ||
+ findNavig && zone->type == ZONE_NAVIG)
best = zone;
zone = zone->child;
// otherwise try next zone
@@ -336,43 +374,72 @@ CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type)
return best;
}
-CZone*
-CTheZones::FindSmallestZonePositionILN(const CVector *v)
+//--MIAMI: done
+int16
+CTheZones::FindZoneByLabelAndReturnIndex(char *name, eZoneType type)
{
- CZone *best = nil;
- if(IsNormalZone(ZoneArray[0].type))
- best = &ZoneArray[0];
- // zone to test next
- CZone *zone = ZoneArray[0].child;
- while(zone)
- // if in zone, descent into children
- if(PointLiesWithinZone(v, zone)){
- if(IsNormalZone(zone->type))
- best = zone;
- zone = zone->child;
- // otherwise try next zone
- }else
- zone = zone->next;
- return best;
+ char str[8];
+ memset(str, 0, 8);
+ strncpy(str, name, 8);
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ for(FindIndex = 0; FindIndex < TotalNumberOfNavigationZones; FindIndex++)
+ if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_INFO:
+ for(FindIndex = 0; FindIndex < TotalNumberOfInfoZones; FindIndex++)
+ if(strcmp(GetInfoZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_MAPZONE:
+ for(FindIndex = 0; FindIndex < TotalNumberOfMapZones; FindIndex++)
+ if(strcmp(GetMapZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+ }
+ return -1;
}
+//--MIAMI: done
int16
-CTheZones::FindZoneByLabelAndReturnIndex(char *name)
+CTheZones::FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type)
{
char str[8];
memset(str, 0, 8);
strncpy(str, name, 8);
- for(FindIndex = 0; FindIndex < TotalNumberOfZones; FindIndex++)
- if(strcmp(GetZone(FindIndex)->name, name) == 0)
- return FindIndex;
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ for(; FindIndex < TotalNumberOfNavigationZones; FindIndex++)
+ if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_INFO:
+ for(; FindIndex < TotalNumberOfInfoZones; FindIndex++)
+ if(strcmp(GetInfoZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_MAPZONE:
+ for(; FindIndex < TotalNumberOfMapZones; FindIndex++)
+ if(strcmp(GetMapZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+ }
return -1;
}
+//--MIAMI: done
CZoneInfo*
CTheZones::GetZoneInfo(const CVector *v, uint8 day)
{
CZone *zone;
- zone = FindSmallestZonePositionILN(v);
+ zone = FindInformationZoneForPosition(v);
if(zone == nil)
return &ZoneInfoArray[0];
return &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
@@ -450,7 +517,7 @@ CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
{
CZone *zone;
CZoneInfo *info;
- zone = GetZone(zoneid);
+ zone = GetInfoZone(zoneid);
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
CheckZoneInfo(info);
@@ -515,7 +582,7 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
{
CZone *zone;
CZoneInfo *info;
- zone = GetZone(zoneid);
+ zone = GetInfoZone(zoneid);
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
if(pedDensity != -1) info->pedDensity = pedDensity;
if(copDensity != -1) info->copDensity = copDensity;
@@ -530,33 +597,34 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
if(gang8Density != -1) info->gangDensity[8] = gang8Density;
}
+//--MIAMI: done, unused
void
CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity;
}
+//--MIAMI: done, unused
void
CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity;
}
+//--MIAMI: done
void
CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup;
}
+//--MIAMI: done
int16
CTheZones::FindAudioZone(CVector *pos)
{
@@ -568,18 +636,7 @@ CTheZones::FindAudioZone(CVector *pos)
return -1;
}
-eLevelName
-CTheZones::FindZoneForPoint(const CVector &pos)
-{
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("IND_ZON"))))
- return LEVEL_INDUSTRIAL;
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("COM_ZON"))))
- return LEVEL_COMMERCIAL;
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("SUB_ZON"))))
- return LEVEL_SUBURBAN;
- return LEVEL_NONE;
-}
-
+//--MIAMI: done
void
CTheZones::AddZoneToAudioZoneArray(CZone *zone)
{
@@ -590,12 +647,14 @@ CTheZones::AddZoneToAudioZoneArray(CZone *zone)
/* This is a bit stupid */
z = -1;
- for(i = 0; i < NUMZONES; i++)
- if(&ZoneArray[i] == zone)
+ for(i = 0; i < NUMNAVIGZONES; i++)
+ if(&NavigationZoneArray[i] == zone)
z = i;
+ assert(NumberOfAudioZones < NUMAUDIOZONES);
AudioZoneArray[NumberOfAudioZones++] = z;
}
+//--MIAMI: done
void
CTheZones::InitialiseAudioZoneArray(void)
{
@@ -603,7 +662,7 @@ CTheZones::InitialiseAudioZoneArray(void)
CZone *zone;
gonext = false;
- zone = &ZoneArray[0];
+ zone = &NavigationZoneArray[0];
// Go deep first,
// set gonext when backing up a level to visit the next child
while(zone)
@@ -627,6 +686,7 @@ CTheZones::InitialiseAudioZoneArray(void)
}
}
+//--MIAMI: TODO
void
CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
{
@@ -634,32 +694,39 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
int i;
*size = SAVE_HEADER_SIZE
- + sizeof(int32) // GetIndexForZonePointer
+ sizeof(m_CurrLevel) + sizeof(FindIndex)
+ sizeof(int16) // padding
- + sizeof(ZoneArray) + sizeof(ZoneInfoArray)
- + sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos)
+ + sizeof(NavigationZoneArray) + sizeof(InfoZoneArray) + sizeof(ZoneInfoArray)
+ + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos)
+ sizeof(MapZoneArray) + sizeof(AudioZoneArray)
+ sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones);
WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
- WriteSaveBuf(buffer, GetIndexForZonePointer(m_pPlayersZone));
WriteSaveBuf(buffer, m_CurrLevel);
WriteSaveBuf(buffer, FindIndex);
WriteSaveBuf(buffer, (int16)0); // padding
- for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
- CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]);
- zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child);
- zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent);
- zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next);
+// TODO(MIAMI): implement SaveOneZone
+ for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){
+ CZone *zone = WriteSaveBuf(buffer, NavigationZoneArray[i]);
+ zone->child = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].child);
+ zone->parent = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].parent);
+ zone->next = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].next);
+ }
+
+ for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){
+ CZone *zone = WriteSaveBuf(buffer, InfoZoneArray[i]);
+ zone->child = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].child);
+ zone->parent = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].parent);
+ zone->next = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].next);
}
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
WriteSaveBuf(buffer, ZoneInfoArray[i]);
- WriteSaveBuf(buffer, TotalNumberOfZones);
+ WriteSaveBuf(buffer, TotalNumberOfNavigationZones);
+ WriteSaveBuf(buffer, TotalNumberOfInfoZones);
WriteSaveBuf(buffer, TotalNumberOfZoneInfos);
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) {
@@ -687,6 +754,7 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
VALIDATESAVEBUF(*size)
}
+//--MIAMI: TODO
void
CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
{
@@ -695,23 +763,32 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
CheckSaveHeader(buffer, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE);
- m_pPlayersZone = GetPointerForZoneIndex(ReadSaveBuf<int32>(buffer));
m_CurrLevel = ReadSaveBuf<eLevelName>(buffer);
FindIndex = ReadSaveBuf<int16>(buffer);
ReadSaveBuf<int16>(buffer);
- for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
- ZoneArray[i] = ReadSaveBuf<CZone>(buffer);
+// TODO(MIAMI): implement LoadOneZone
+ for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){
+ NavigationZoneArray[i] = ReadSaveBuf<CZone>(buffer);
+
+ NavigationZoneArray[i].child = GetPointerForZoneIndex((int32)NavigationZoneArray[i].child);
+ NavigationZoneArray[i].parent = GetPointerForZoneIndex((int32)NavigationZoneArray[i].parent);
+ NavigationZoneArray[i].next = GetPointerForZoneIndex((int32)NavigationZoneArray[i].next);
+ }
+
+ for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){
+ InfoZoneArray[i] = ReadSaveBuf<CZone>(buffer);
- ZoneArray[i].child = GetPointerForZoneIndex((int32)ZoneArray[i].child);
- ZoneArray[i].parent = GetPointerForZoneIndex((int32)ZoneArray[i].parent);
- ZoneArray[i].next = GetPointerForZoneIndex((int32)ZoneArray[i].next);
+ InfoZoneArray[i].child = GetPointerForZoneIndex((int32)InfoZoneArray[i].child);
+ InfoZoneArray[i].parent = GetPointerForZoneIndex((int32)InfoZoneArray[i].parent);
+ InfoZoneArray[i].next = GetPointerForZoneIndex((int32)InfoZoneArray[i].next);
}
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer);
- TotalNumberOfZones = ReadSaveBuf<int16>(buffer);
+ TotalNumberOfNavigationZones = ReadSaveBuf<int16>(buffer);
+ TotalNumberOfInfoZones = ReadSaveBuf<int16>(buffer);
TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer);
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){
diff --git a/src/core/Zones.h b/src/core/Zones.h
index 67800569..992bda2d 100644
--- a/src/core/Zones.h
+++ b/src/core/Zones.h
@@ -51,17 +51,18 @@ public:
class CTheZones
{
- static CZone *m_pPlayersZone;
static int16 FindIndex;
static uint16 NumberOfAudioZones;
static int16 AudioZoneArray[NUMAUDIOZONES];
static uint16 TotalNumberOfMapZones;
- static uint16 TotalNumberOfZones;
- static CZone ZoneArray[NUMZONES];
+ static uint16 TotalNumberOfInfoZones;
+ static uint16 TotalNumberOfNavigationZones;
+ static CZone InfoZoneArray[NUMINFOZONES];
static CZone MapZoneArray[NUMMAPZONES];
+ static CZone NavigationZoneArray[NUMNAVIGZONES];
static uint16 TotalNumberOfZoneInfos;
- static CZoneInfo ZoneInfoArray[2*NUMZONES];
+ static CZoneInfo ZoneInfoArray[2*NUMINFOZONES];
public:
static eLevelName m_CurrLevel;
@@ -71,22 +72,21 @@ public:
float minx, float miny, float minz,
float maxx, float maxy, float maxz,
eLevelName level);
- static void CreateMapZone(char *name, eZoneType type,
- float minx, float miny, float minz,
- float maxx, float maxy, float maxz,
- eLevelName level);
- static CZone *GetZone(uint16 i) { return &ZoneArray[i]; }
- static CZone *GetAudioZone(uint16 i) { return &ZoneArray[AudioZoneArray[i]]; }
+ static CZone *GetInfoZone(uint16 i) { return &InfoZoneArray[i]; }
+ static CZone *GetNavigationZone(uint16 i) { return &NavigationZoneArray[i]; }
+ static CZone *GetMapZone(uint16 i) { return &MapZoneArray[i]; }
+ static CZone *GetAudioZone(uint16 i) { return &InfoZoneArray[AudioZoneArray[i]]; }
static void PostZoneCreation(void);
+ static void CheckZonesForOverlap(void);
static void InsertZoneIntoZoneHierarchy(CZone *zone);
static bool InsertZoneIntoZoneHierRecursive(CZone *z1, CZone *z2);
static bool ZoneIsEntirelyContainedWithinOtherZone(CZone *z1, CZone *z2);
static bool PointLiesWithinZone(const CVector *v, CZone *zone);
static eLevelName GetLevelFromPosition(const CVector *v);
- static CZone *FindSmallestZonePosition(const CVector *v);
- static CZone *FindSmallestZonePositionType(const CVector *v, eZoneType type);
- static CZone *FindSmallestZonePositionILN(const CVector *v);
- static int16 FindZoneByLabelAndReturnIndex(char *name);
+ static CZone *FindInformationZoneForPosition(const CVector *v);
+ static CZone *FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig);
+ static int16 FindZoneByLabelAndReturnIndex(char *name, eZoneType type);
+ static int16 FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type);
static CZoneInfo *GetZoneInfo(const CVector *v, uint8 day);
static void GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info);
static void SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
@@ -104,9 +104,8 @@ public:
static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity);
static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
static int16 FindAudioZone(CVector *pos);
- static eLevelName FindZoneForPoint(const CVector &pos);
- static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &ZoneArray[i]; }
- static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
+ static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &InfoZoneArray[i]; }
+ static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - InfoZoneArray; }
static void AddZoneToAudioZoneArray(CZone *zone);
static void InitialiseAudioZoneArray(void);
static void SaveAllZones(uint8 *buffer, uint32 *length);
diff --git a/src/core/config.h b/src/core/config.h
index 7c1fab5b..32facfe6 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -7,44 +7,44 @@ enum Config {
MAX_CDIMAGES = 8, // additional cdimages
MAX_CDCHANNELS = 5,
- MODELINFOSIZE = 5500,
- TXDSTORESIZE = 850,
+ MODELINFOSIZE = 6500,
+ TXDSTORESIZE = 1385,
+ COLSTORESIZE = 31,
EXTRADIRSIZE = 128,
CUTSCENEDIRSIZE = 512,
- SIMPLEMODELSIZE = 5000,
- MLOMODELSIZE = 1,
- MLOINSTANCESIZE = 1,
- TIMEMODELSIZE = 30,
+ SIMPLEMODELSIZE = 5000, // only 3885 in VC???
+ TIMEMODELSIZE = 385,
CLUMPMODELSIZE = 5,
- PEDMODELSIZE = 90,
- VEHICLEMODELSIZE = 120,
- XTRACOMPSMODELSIZE = 2,
- TWODFXSIZE = 2000,
+ WEAPONMODELSIZE = 37,
+ PEDMODELSIZE = 130,
+ VEHICLEMODELSIZE = 120, // only 110 in VC???
+ TWODFXSIZE = 2000, // only 1210 in VC???
MAXVEHICLESLOADED = 50, // 70 on mobile
- NUMOBJECTINFO = 168, // object.dat
+ NUMOBJECTINFO = 400, // TODO(MIAMI): fantasy // object.dat
// Pool sizes
- NUMPTRNODES = 30000, // 26000 on PS2
- NUMENTRYINFOS = 5400, // 3200 on PS2
- NUMPEDS = 140, // 90 on PS2
- NUMVEHICLES = 110, // 70 on PS2
- NUMBUILDINGS = 5500, // 4915 on PS2
- NUMTREADABLES = 1214,
- NUMOBJECTS = 450,
- NUMDUMMIES = 2802, // 2368 on PS2
- NUMAUDIOSCRIPTOBJECTS = 256,
- NUMCUTSCENEOBJECTS = 50,
+ NUMPTRNODES = 50000,
+ NUMENTRYINFOS = 5400, // only 3200 in VC???
+ NUMPEDS = 140,
+ NUMVEHICLES = 110,
+ NUMBUILDINGS = 7000,
+ NUMTREADABLES = 1214, // 1 in VC
+ NUMOBJECTS = 460,
+ NUMDUMMIES = 2802, // 2340 in VC
+ NUMAUDIOSCRIPTOBJECTS = 256, // 192 in VC
+ NUMCUTSCENEOBJECTS = 50, // does not exist in VC
+ // TODO(MIAMI): colmodel pool
NUMTEMPOBJECTS = 30,
// Path data
- NUM_PATHNODES = 4930,
- NUM_CARPATHLINKS = 2076,
+ NUM_PATHNODES = 9650,
+ NUM_CARPATHLINKS = 3500,
NUM_MAPOBJECTS = 1250,
- NUM_PATHCONNECTIONS = 10260,
+ NUM_PATHCONNECTIONS = 20400,
// Link list lengths
NUMALPHALIST = 20,
@@ -53,20 +53,19 @@ enum Config {
NUMREFERENCES = 800,
// Zones
- NUMAUDIOZONES = 36,
- NUMZONES = 50,
- NUMMAPZONES = 25,
+ NUMAUDIOZONES = 14,
+ NUMINFOZONES = 169,
+ NUMMAPZONES = 39,
+ NUMNAVIGZONES = 20,
// Cull zones
- NUMCULLZONES = 512,
- NUMATTRIBZONES = 288,
- NUMZONEINDICES = 55000,
+ NUMATTRIBZONES = 704,
NUMHANDLINGS = 57,
PATHNODESIZE = 4500,
- NUMWEATHERS = 4,
+ NUMWEATHERS = 7,
NUMHOURS = 24,
NUMEXTRADIRECTIONALS = 4,
@@ -110,7 +109,7 @@ enum Config {
NUMMODELSPERPEDGROUP = 8,
NUMSHOTINFOS = 100,
- NUMROADBLOCKS = 600,
+ NUMROADBLOCKS = 300,
NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150,
diff --git a/src/core/main.cpp b/src/core/main.cpp
index ec37fa28..9e0fda15 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -1134,7 +1134,7 @@ void
InitialiseGame(void)
{
LoadingScreen(nil, nil, "loadsc0");
- CGame::Initialise("DATA\\GTA3.DAT");
+ CGame::Initialise("DATA\\GTA_VC.DAT");
}
RsEventStatus
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index a74b81a3..739786b5 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -333,8 +333,6 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Path Links", &gbShowCarPathsLinks, nil);
- DebugMenuAddVarBool8("Render", "Show Ped Road Groups", &gbShowPedRoadGroups, nil);
- DebugMenuAddVarBool8("Render", "Show Car Road Groups", &gbShowCarRoadGroups, nil);
DebugMenuAddVarBool8("Render", "Show Collision Lines", &gbShowCollisionLines, nil);
DebugMenuAddVarBool8("Render", "Show Collision Polys", &gbShowCollisionPolys, nil);
DebugMenuAddVarBool8("Render", "Don't render Buildings", &gbDontRenderBuildings, nil);
diff --git a/src/core/templates.h b/src/core/templates.h
index 921b109a..44ab566b 100644
--- a/src/core/templates.h
+++ b/src/core/templates.h
@@ -34,18 +34,20 @@ class CPool
int m_allocPtr;
public:
+ // TODO(MIAMI): remove ctor without name argument
CPool(int size){
// TODO: use new here
m_entries = (U*)malloc(sizeof(U)*size);
m_flags = (Flags*)malloc(sizeof(Flags)*size);
m_size = size;
- m_allocPtr = 0;
+ m_allocPtr = -1;
for(int i = 0; i < size; i++){
m_flags[i].id = 0;
m_flags[i].free = 1;
}
}
-
+ CPool(int size, const char *name)
+ : CPool(size) {}
~CPool() {
Flush();
}