summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Camera.cpp2
-rw-r--r--src/core/ColStore.cpp231
-rw-r--r--src/core/ColStore.h43
-rw-r--r--src/core/Collision.cpp30
-rw-r--r--src/core/Collision.h4
-rw-r--r--src/core/FileLoader.cpp154
-rw-r--r--src/core/FileLoader.h6
-rw-r--r--src/core/Frontend.h4
-rw-r--r--src/core/Game.cpp11
-rw-r--r--src/core/Game.h3
-rw-r--r--src/core/PlayerInfo.h2
-rw-r--r--src/core/Streaming.cpp275
-rw-r--r--src/core/Streaming.h32
-rw-r--r--src/core/ZoneCull.h3
-rw-r--r--src/core/config.h17
-rw-r--r--src/core/templates.h9
16 files changed, 825 insertions, 1 deletions
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 9b178f35..30f4287b 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -930,11 +930,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){
diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp
new file mode 100644
index 00000000..0c3356c5
--- /dev/null
+++ b/src/core/ColStore.cpp
@@ -0,0 +1,231 @@
+#include "common.h"
+#ifdef MIAMI
+
+#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;
+}
+
+#endif
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..f20fee6d 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -20,6 +20,10 @@
#include "SurfaceTable.h"
#include "Lines.h"
#include "Collision.h"
+#ifdef MIAMI
+#include "Camera.h"
+#include "ColStore.h"
+#endif
enum Direction
{
@@ -34,22 +38,32 @@ 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;
+#ifdef MIAMI
+ CColStore::Initialise();
+#endif
}
+//--MIAMI: done
void
CCollision::Shutdown(void)
{
ms_colModelCache.Shutdown();
+#ifdef MIAMI
+ CColStore::Shutdown();
+#endif
}
+//--MIAMI: done
void
CCollision::Update(void)
{
+#ifndef MIAMI
CVector playerCoors;
playerCoors = FindPlayerCoors();
eLevelName level = CTheZones::m_CurrLevel;
@@ -83,8 +97,10 @@ CCollision::Update(void)
if(ms_collisionInMemory != CGame::currLevel)
LoadCollisionWhenINeedIt(forceLevelChange);
CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
+#endif
}
+//--MIAMI: unused
eLevelName
GetCollisionInSectorList(CPtrList &list)
{
@@ -101,6 +117,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,9 +138,11 @@ GetCollisionInSector(CSector &sect)
return (eLevelName)level;
}
+//--MIAMI: done
void
CCollision::LoadCollisionWhenINeedIt(bool forceChange)
{
+#ifndef MIAMI
eLevelName level, l;
bool multipleLevels;
CVector playerCoors;
@@ -210,11 +229,14 @@ CCollision::LoadCollisionWhenINeedIt(bool forceChange)
CTimer::Update();
DMAudio.SetEffectsFadeVol(127);
}
+#endif
}
+//--MIAMI: done
void
CCollision::SortOutCollisionAfterLoad(void)
{
+#ifndef MIAMI
if(ms_collisionInMemory == CGame::currLevel)
return;
@@ -226,6 +248,10 @@ CCollision::SortOutCollisionAfterLoad(void)
}
ms_collisionInMemory = CGame::currLevel;
CGame::TidyUpMemory(true, false);
+#else
+ CColStore::LoadCollision(TheCamera.GetPosition());
+ CStreaming::LoadAllRequestedModels(false);
+#endif
}
void
@@ -1974,7 +2000,11 @@ CColModel::CColModel(void)
vertices = nil;
triangles = nil;
trianglePlanes = nil;
+#ifndef MIAMI
level = CGame::currLevel;
+#else
+ level = 0; // generic col slot
+#endif
ownsCollisionVolumes = true;
}
diff --git a/src/core/Collision.h b/src/core/Collision.h
index 895f012a..fc3c1647 100644
--- a/src/core/Collision.h
+++ b/src/core/Collision.h
@@ -93,7 +93,11 @@ struct CColModel
int16 numLines;
int16 numBoxes;
int16 numTriangles;
+#ifndef MIAMI
int32 level;
+#else
+ uint8 level; // colstore slot but probably same name
+#endif
bool ownsCollisionVolumes;
CColSphere *spheres;
CColLine *lines;
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index a2654369..ab09d72f 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -24,6 +24,10 @@
#include "ZoneCull.h"
#include "CdStream.h"
#include "FileLoader.h"
+#ifdef MIAMI
+#include "Streaming.h"
+#include "ColStore.h"
+#endif
char CFileLoader::ms_line[256];
@@ -53,7 +57,9 @@ CFileLoader::LoadLevel(const char *filename)
savedTxd = RwTexDictionaryGetCurrent();
objectsLoaded = false;
+#ifndef MIAMI
savedLevel = CGame::currLevel;
+#endif
if(savedTxd == nil){
savedTxd = RwTexDictionaryCreate();
RwTexDictionarySetCurrent(savedTxd);
@@ -77,12 +83,17 @@ CFileLoader::LoadLevel(const char *filename)
AddTexDictionaries(savedTxd, txd);
RwTexDictionaryDestroy(txd);
}else if(strncmp(line, "COLFILE", 7) == 0){
+#ifndef MIAMI
int level;
sscanf(line+8, "%d", &level);
CGame::currLevel = (eLevelName)level;
LoadingScreenLoadingFile(line+10);
LoadCollisionFile(line+10);
CGame::currLevel = savedLevel;
+#else
+ LoadingScreenLoadingFile(line+10);
+ LoadCollisionFile(line+10, 0);
+#endif
}else if(strncmp(line, "MODELFILE", 9) == 0){
LoadingScreenLoadingFile(line + 10);
LoadModelFile(line + 10);
@@ -94,8 +105,16 @@ CFileLoader::LoadLevel(const char *filename)
LoadObjectTypes(line + 4);
}else if(strncmp(line, "IPL", 3) == 0){
if(!objectsLoaded){
+#ifndef MIAMI
CModelInfo::ConstructMloClumps();
CObjectData::Initialise("DATA\\OBJECT.DAT");
+#else
+ LoadingScreenLoadingFile("Collision");
+ CObjectData::Initialise("DATA\\OBJECT.DAT");
+ CStreaming::Init();
+ CColStore::LoadAllCollision();
+ // TODO: anim indices
+#endif
objectsLoaded = true;
}
LoadingScreenLoadingFile(line + 4);
@@ -112,8 +131,18 @@ CFileLoader::LoadLevel(const char *filename)
CFileMgr::CloseFile(fd);
RwTexDictionarySetCurrent(savedTxd);
+
+#ifdef MIAMI
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(CColStore::GetSlot(i))
+ CColStore::GetBoundingBox(i).Grow(120.0f);
+ CWorld::RepositionCertainDynamicObjects();
+ CColStore::RemoveAllCollision();
+#endif
}
+#ifndef MIAMI
void
CFileLoader::LoadCollisionFromDatFile(int currlevel)
{
@@ -137,6 +166,7 @@ CFileLoader::LoadCollisionFromDatFile(int currlevel)
CFileMgr::CloseFile(fd);
}
+#endif
char*
CFileLoader::LoadLine(int fd)
@@ -178,8 +208,14 @@ struct ColHeader
uint32 size;
};
+//--MIAMI: done
+#ifndef MIAMI
void
CFileLoader::LoadCollisionFile(const char *filename)
+#else
+void
+CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
+#endif
{
int fd;
char modelname[24];
@@ -196,10 +232,17 @@ CFileLoader::LoadCollisionFile(const char *filename)
mi = CModelInfo::GetModelInfo(modelname, nil);
if(mi){
+#ifndef MIAMI
if(mi->GetColModel()){
+#else
+ if(mi->GetColModel() && mi->DoesOwnColModel()){
+#endif
LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname);
}else{
CColModel *model = new CColModel;
+#ifdef MIAMI
+ model->level = colSlot;
+#endif
LoadCollisionModel(work_buff+24, *model, modelname);
mi->SetColModel(model, true);
}
@@ -211,6 +254,82 @@ CFileLoader::LoadCollisionFile(const char *filename)
CFileMgr::CloseFile(fd);
}
+#ifdef MIAMI
+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){
+if(modelIndex == 855)
+modelIndex = modelIndex;
+ 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;
+}
+#endif
+
void
CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
{
@@ -1063,18 +1182,36 @@ CFileLoader::LoadObjectInstance(const char *line)
CSimpleModelInfo *mi;
RwMatrix *xform;
CEntity *entity;
+#ifdef MIAMI
+ 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) != 13){
+#endif
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;
+#ifdef MIAMI
+ area = 0;
+ }
+#endif
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi == nil)
return;
assert(mi->IsSimple());
+#ifdef MIAMI
+ if(!CStreaming::IsObjectInCdImage(id))
+ debug("Not in cdimage %s\n", mi->GetName());
+#endif
+
angle = -RADTODEG(2.0f * acosf(angle));
xform = RwMatrixCreate();
RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE);
@@ -1089,6 +1226,9 @@ CFileLoader::LoadObjectInstance(const char *line)
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition());
+#ifdef MIAMI
+ entity->m_area = area;
+#endif
if(mi->IsSimple()){
if(mi->m_isBigBuilding)
entity->SetupBigBuilding();
@@ -1098,14 +1238,28 @@ CFileLoader::LoadObjectInstance(const char *line)
if(mi->GetLargestLodDistance() < 2.0f)
entity->bIsVisible = false;
CWorld::Add(entity);
+
+#ifdef MIAMI
+ 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: set some flag here if col min is below 6
+#endif
}else{
entity = new CDummyObject;
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
CWorld::Add(entity);
+//--MIAMI: TODO
if(IsGlass(entity->GetModelIndex()))
entity->bIsVisible = false;
entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition());
+#ifdef MIAMI
+ entity->m_area = area;
+#endif
}
RwMatrixDestroy(xform);
diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h
index 87b8fe61..aa8dcdb8 100644
--- a/src/core/FileLoader.h
+++ b/src/core/FileLoader.h
@@ -8,7 +8,13 @@ public:
static void LoadCollisionFromDatFile(int currlevel);
static char *LoadLine(int fd);
static RwTexDictionary *LoadTexDictionary(const char *filename);
+#ifndef MIAMI
static void LoadCollisionFile(const char *filename);
+#else
+ static void LoadCollisionFile(const char *filename, uint8 colSlot = 0);
+ static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot);
+ static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot);
+#endif
static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name);
static void LoadModelFile(const char *filename);
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 3286f275..c27e5239 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -624,6 +624,10 @@ public:
void LoadAllTextures();
void LoadSettings();
void MessageScreen(const char *);
+#ifdef MIAMI
+ //--MIAMI: TODO: implement the second argument
+ void MessageScreen(const char *str, bool) { MessageScreen(str); }
+#endif
void PickNewPlayerColour();
void PrintBriefs();
static void PrintErrorMessage();
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index d0f412d8..96109e56 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -89,6 +89,9 @@
eLevelName CGame::currLevel;
+#ifdef MIAMI
+int32 CGame::currArea;
+#endif
bool CGame::bDemoMode = true;
bool CGame::nastyGame = true;
bool CGame::frenchGame;
@@ -319,7 +322,9 @@ bool CGame::Initialise(const char* datFile)
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
LoadingScreen("Loading the Game", "Setup streaming", nil);
+#ifndef MIAMI
CStreaming::Init();
+#endif
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
CStreaming::RequestBigBuildings(LEVEL_NONE);
@@ -367,8 +372,10 @@ bool CGame::Initialise(const char* datFile)
CWaterCannons::Init();
CBridge::Init();
CGarages::Init();
+#ifndef MIAMI
LoadingScreen("Loading the Game", "Position dynamic objects", nil);
CWorld::RepositionCertainDynamicObjects();
+#endif
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
CCullZones::ResolveVisibilities();
CTrain::InitTrains();
@@ -381,7 +388,9 @@ bool CGame::Initialise(const char* datFile)
CTheScripts::Process();
TheCamera.Process();
LoadingScreen("Loading the Game", "Load scene", nil);
+#ifndef MIAMI
CModelInfo::RemoveColModelsFromOtherLevels(currLevel);
+#endif
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true);
@@ -519,7 +528,9 @@ void CGame::ReloadIPLs(void)
CRoadBlocks::Init();
CCranes::InitCranes();
CGarages::Init();
+#ifndef MIAMI
CWorld::RepositionCertainDynamicObjects();
+#endif
CCullZones::ResolveVisibilities();
CRenderer::SortBIGBuildings();
CTimer::Update();
diff --git a/src/core/Game.h b/src/core/Game.h
index 48f31abc..8db5adf5 100644
--- a/src/core/Game.h
+++ b/src/core/Game.h
@@ -12,6 +12,9 @@ class CGame
{
public:
static eLevelName currLevel;
+#ifdef MIAMI
+ static int32 currArea;
+#endif
static bool bDemoMode;
static bool nastyGame;
static bool frenchGame;
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index e970e42d..13266331 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -80,4 +80,6 @@ public:
~CPlayerInfo() { };
};
+#ifndef MIAMI
static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
+#endif
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index da9e7d33..daeda35d 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -32,6 +32,10 @@
#include "Replay.h"
#endif
#include "main.h"
+#ifdef MIAMI
+#include "ColStore.h"
+#include "DMAudio.h"
+#endif
bool CStreaming::ms_disableStreaming;
bool CStreaming::ms_bLoadingBigModel;
@@ -53,7 +57,9 @@ int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED];
int32 CStreaming::ms_lastVehicleDeleted;
CDirectory *CStreaming::ms_pExtraObjectsDir;
int32 CStreaming::ms_numPriorityRequests;
+#ifndef MIAMI
bool CStreaming::ms_hasLoadedLODs;
+#endif
int32 CStreaming::ms_currentPedGrp;
int32 CStreaming::ms_currentPedLoading;
int32 CStreaming::ms_lastCullZone;
@@ -184,7 +190,9 @@ CStreaming::Init2(void)
ms_pExtraObjectsDir = new CDirectory(EXTRADIRSIZE);
ms_numPriorityRequests = 0;
+#ifndef MIAMI
ms_hasLoadedLODs = true;
+#endif
ms_currentPedGrp = -1;
ms_lastCullZone = -1; // unused because RemoveModelsNotVisibleFromCullzone is gone
ms_loadedGangs = 0;
@@ -231,6 +239,7 @@ CStreaming::Init2(void)
CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd);
CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom);
+#ifndef MIAMI
for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
if(building == nil)
@@ -241,6 +250,7 @@ CStreaming::Init2(void)
if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building;
if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building;
}
+#endif
}
void
@@ -292,21 +302,35 @@ CStreaming::Update(void)
if(CTimer::GetIsPaused())
return;
+#ifndef MIAMI
train = FindPlayerTrain();
if(train && train->GetPosition().z < 0.0f){
RequestSubway();
requestedSubway = true;
}else if(!ms_disableStreaming)
AddModelsToRequestList(TheCamera.GetPosition());
+#else
+ LoadBigBuildingsWhenNeeded();
+ if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f)
+ AddModelsToRequestList(TheCamera.GetPosition());
+#endif
DeleteFarAwayRwObjects(TheCamera.GetPosition());
if(!ms_disableStreaming &&
+#ifndef MIAMI
!CCutsceneMgr::IsRunning() &&
!requestedSubway &&
!CGame::playingIntro &&
+#else
+ !CCutsceneMgr::IsCutsceneProcessing() &&
+#endif
ms_numModelsRequested < 5 &&
!CRenderer::m_loadingPriority
+#ifdef MIAMI
+ && CGame::currArea == 0
+ // replay is also MIAMI
+#endif
#ifdef FIX_BUGS
&& !CReplay::IsPlayingBack()
#endif
@@ -317,6 +341,16 @@ CStreaming::Update(void)
LoadRequestedModels();
+#ifdef MIAMI
+ 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());
+ }
+#endif
for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){
prev = si->m_prev;
@@ -375,6 +409,7 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
imgSelector = n<<24;
assert(sizeof(direntry) == 32);
while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){
+#ifndef MIAMI
dot = strchr(direntry.name, '.');
if(dot) *dot = '\0';
if(direntry.size > (uint32)ms_streamingBufferSize)
@@ -417,6 +452,64 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
}
}else
lastID = -1;
+#else
+ 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::faststricmp(dot+1, "DFF")){
+ if(CModelInfo::GetModelInfo(direntry.name, &modelId)){
+ bAddToStreaming = true;
+ }else{
+#ifdef FIX_BUGS
+ // remember which cdimage this came from
+ ms_pExtraObjectsDir->AddItem(direntry, n);
+#else
+ ms_pExtraObjectsDir->AddItem(direntry);
+#endif
+ lastID = -1;
+ }
+ }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: 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[modelId].SetCdPosnAndSize(direntry.offset, direntry.size);
+ if(lastID != -1)
+ ms_aInfoForModel[lastID].m_nextID = modelId;
+ lastID = modelId;
+ }
+ }
+#endif
}
CFileMgr::CloseFile(fd);
@@ -440,6 +533,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 +575,11 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
+#ifndef MIAMI
}else{
+#else
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
+#endif
// Txd
assert(streamId < NUMSTREAMINFO);
if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 &&
@@ -506,10 +604,22 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
+#ifdef MIAMI
+ }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: IFPs
+#endif
}
RwStreamClose(stream, &mem);
+#ifndef MIAMI
// We shouldn't even end up here unless load was successful
if(!success){
ReRequestModel(streamId);
@@ -519,6 +629,7 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD));
return false;
}
+#endif
if(streamId < STREAM_OFFSET_TXD){
// Model
@@ -537,7 +648,11 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
}
+#ifndef MIAMI
}else{
+#else
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){ // TODO: animations
+#endif
// Txd
if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
@@ -552,10 +667,23 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
timeDiff = endTime - startTime;
if(timeDiff > 5){
+#ifndef MIAMI
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);
+#else
+ // TODO: is this inlined?
+ static char objname[32];
+ if(streamId < STREAM_OFFSET_TXD)
+ 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: IFP
+ debug("%s took %d ms\n", objname, timeDiff);
+#endif
}
return true;
@@ -713,7 +841,11 @@ CStreaming::RequestSubway(void)
}
}
+#ifndef MIAMI
#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY
+#else
+#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE
+#endif
void
CStreaming::RequestBigBuildings(eLevelName level)
@@ -725,12 +857,54 @@ CStreaming::RequestBigBuildings(eLevelName level)
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding && b->m_level == level)
+#ifdef MIAMI
+ if(!b->bStreamBIGBuilding)
+#endif
RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
RequestIslands(level);
+#ifndef MIAMI
ms_hasLoadedLODs = false;
+#endif
}
+#ifdef MIAMI
+void
+CStreaming::RequestBigBuildings(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)
+ if(b->bStreamBIGBuilding){
+ if(CRenderer::ShouldModelBeStreamed(b))
+ RequestModel(b->GetModelIndex(), 0);
+ }else
+ RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
+ }
+ RequestIslands(level);
+}
+
+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();
+ }
+}
+#endif
+
void
CStreaming::RequestIslands(eLevelName level)
{
@@ -828,10 +1002,20 @@ CStreaming::RemoveModel(int32 id)
return;
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){
+#ifndef MIAMI
if(id < STREAM_OFFSET_TXD)
CModelInfo::GetModelInfo(id)->DeleteRwObject();
else
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
+#else
+ if(id < STREAM_OFFSET_TXD)
+ CModelInfo::GetModelInfo(id)->DeleteRwObject();
+ 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: IFP
+#endif
ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE;
}
@@ -850,15 +1034,26 @@ CStreaming::RemoveModel(int32 id)
}
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){
+#ifndef MIAMI
if(id < STREAM_OFFSET_TXD)
RpClumpGtaCancelStream();
else
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
+#else
+ if(id < STREAM_OFFSET_TXD)
+ RpClumpGtaCancelStream();
+ 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: IFP
+#endif
}
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
}
+//--MIAMI: change islands
void
CStreaming::RemoveUnusedBuildings(eLevelName level)
{
@@ -870,6 +1065,7 @@ CStreaming::RemoveUnusedBuildings(eLevelName level)
RemoveBuildings(LEVEL_SUBURBAN);
}
+//--MIAMI: done
void
CStreaming::RemoveBuildings(eLevelName level)
{
@@ -930,6 +1126,7 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
+//--MIAMI: change islands
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
@@ -958,6 +1155,21 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
+#ifdef MIAMI
+ int i;
+ if(pIslandLODindustEntity == nil)
+ 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;
+ }
+#endif
+
switch(level){
case LEVEL_INDUSTRIAL:
DeleteIsland(pIslandLODindustEntity);
@@ -984,6 +1196,7 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
}
}
+//--MIAMI: done
void
CStreaming::RemoveBigBuildings(eLevelName level)
{
@@ -1187,6 +1400,7 @@ CStreaming::IsObjectInCdImage(int32 id)
return ms_aInfoForModel[id].GetCdPosnAndSize(posn, size);
}
+#ifndef MIAMI
void
CStreaming::HaveAllBigBuildingsLoaded(eLevelName level)
{
@@ -1221,6 +1435,7 @@ CStreaming::HaveAllBigBuildingsLoaded(eLevelName level)
RemoveUnusedBigBuildings(level);
ms_hasLoadedLODs = true;
}
+#endif
void
CStreaming::SetModelIsDeletable(int32 id)
@@ -1454,6 +1669,44 @@ CStreaming::RemoveCurrentZonesModels(void)
ms_loadedGangCars = 0;
}
+#ifdef MIAMI
+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);
+}
+#endif
+
// Find starting offset of the cdimage we next want to read
// Not useful at all on PC...
@@ -2432,11 +2685,33 @@ CStreaming::LoadScene(const CVector &pos)
CRenderer::m_loadingPriority = false;
CCullZones::ForceCullZoneCoors(pos);
DeleteAllRwObjects();
+#ifndef MIAMI
AddModelsToRequestList(pos);
CRadar::StreamRadarSections(pos);
RemoveUnusedBigBuildings(level);
RequestBigBuildings(level);
LoadAllRequestedModels(false);
+#else
+ 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);
+
+ // TODO: stream zone vehicles
+ LoadAllRequestedModels(false);
+ // TODO: InstanceLoadedModels
+
+ for(int i = 0; i < NUMSTREAMINFO; i++)
+ ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20;
+#endif
debug("End load scene\n");
}
diff --git a/src/core/Streaming.h b/src/core/Streaming.h
index 84434769..d2920824 100644
--- a/src/core/Streaming.h
+++ b/src/core/Streaming.h
@@ -4,7 +4,12 @@
enum {
STREAM_OFFSET_TXD = MODELINFOSIZE,
+#ifndef MIAMI
NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE
+#else
+ STREAM_OFFSET_COL = STREAM_OFFSET_TXD+TXDSTORESIZE,
+ NUMSTREAMINFO = STREAM_OFFSET_COL+COLSTORESIZE
+#endif
};
enum StreamFlags
@@ -14,6 +19,9 @@ enum StreamFlags
STREAMFLAGS_DEPENDENCY = 0x04, // Is this right?
STREAMFLAGS_PRIORITY = 0x08,
STREAMFLAGS_NOFADE = 0x10,
+#ifdef MIAMI
+ STREAMFLAGS_20 = 0x20,
+#endif
STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED,
STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY,
@@ -94,7 +102,9 @@ public:
static int32 ms_lastVehicleDeleted;
static CDirectory *ms_pExtraObjectsDir;
static int32 ms_numPriorityRequests;
+#ifndef MIAMI
static bool ms_hasLoadedLODs;
+#endif
static int32 ms_currentPedGrp;
static int32 ms_lastCullZone;
static uint16 ms_loadedGangs;
@@ -115,14 +125,28 @@ 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); }
+#ifdef MIAMI
+ static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); }
+#endif
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); }
+#ifdef MIAMI
+ static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); }
+#endif
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); }
+#ifdef MIAMI
+ static void RequestCol(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_COL, flags); }
+ static void ReRequestCol(int32 col) { ReRequestModel(col + STREAM_OFFSET_COL); }
+#endif
static void RequestSubway(void);
static void RequestBigBuildings(eLevelName level);
+#ifdef MIAMI
+ static void RequestBigBuildings(eLevelName level, const CVector &pos);
+ static void InstanceBigBuildings(eLevelName level, const CVector &pos);
+#endif
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 +155,9 @@ public:
static void DecrementRef(int32 id);
static void RemoveModel(int32 id);
static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); }
+#ifdef MIAMI
+ static void RemoveCol(int32 id) { RemoveModel(id + STREAM_OFFSET_COL); }
+#endif
static void RemoveUnusedBuildings(eLevelName level);
static void RemoveBuildings(eLevelName level);
static void RemoveUnusedBigBuildings(eLevelName level);
@@ -145,7 +172,9 @@ public:
static bool IsTxdUsedByRequestedModels(int32 txdId);
static bool AddToLoadedVehiclesList(int32 modelId);
static bool IsObjectInCdImage(int32 id);
+#ifndef MIAMI
static void HaveAllBigBuildingsLoaded(eLevelName level);
+#endif
static void SetModelIsDeletable(int32 id);
static void SetModelTxdIsDeletable(int32 id);
static void SetMissionDoesntRequireModel(int32 id);
@@ -154,6 +183,9 @@ public:
static void StreamVehiclesAndPeds(void);
static void StreamZoneModels(const CVector &pos);
static void RemoveCurrentZonesModels(void);
+#ifdef MIAMI
+ static void LoadBigBuildingsWhenNeeded(void);
+#endif
static int32 GetCdImageOffset(int32 lastPosn);
static int32 GetNextFileOnCd(int32 position, bool priority);
diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h
index 9bc07b8c..e0a905e4 100644
--- a/src/core/ZoneCull.h
+++ b/src/core/ZoneCull.h
@@ -122,4 +122,7 @@ public:
static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set);
static void CompressIndicesArray() {};// todo
+
+ //--MIAMI: TODO
+ static bool PoliceAbandonCars(void) { return false; }
};
diff --git a/src/core/config.h b/src/core/config.h
index 7c1fab5b..c0597db2 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -7,8 +7,14 @@ enum Config {
MAX_CDIMAGES = 8, // additional cdimages
MAX_CDCHANNELS = 5,
+#ifndef MIAMI
MODELINFOSIZE = 5500,
TXDSTORESIZE = 850,
+#else
+ MODELINFOSIZE = 6500,
+ TXDSTORESIZE = 1385,
+ COLSTORESIZE = 31,
+#endif
EXTRADIRSIZE = 128,
CUTSCENEDIRSIZE = 512,
@@ -41,10 +47,17 @@ enum Config {
NUMTEMPOBJECTS = 30,
// Path data
+#ifndef MIAMI
NUM_PATHNODES = 4930,
NUM_CARPATHLINKS = 2076,
NUM_MAPOBJECTS = 1250,
NUM_PATHCONNECTIONS = 10260,
+#else
+ NUM_PATHNODES = 9650,
+ NUM_CARPATHLINKS = 3500,
+ NUM_MAPOBJECTS = 1250,
+ NUM_PATHCONNECTIONS = 20400,
+#endif
// Link list lengths
NUMALPHALIST = 20,
@@ -110,7 +123,11 @@ enum Config {
NUMMODELSPERPEDGROUP = 8,
NUMSHOTINFOS = 100,
+#ifndef MIAMI
NUMROADBLOCKS = 600,
+#else
+ NUMROADBLOCKS = 300,
+#endif
NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150,
diff --git a/src/core/templates.h b/src/core/templates.h
index 921b109a..74bc4713 100644
--- a/src/core/templates.h
+++ b/src/core/templates.h
@@ -39,13 +39,20 @@ public:
m_entries = (U*)malloc(sizeof(U)*size);
m_flags = (Flags*)malloc(sizeof(Flags)*size);
m_size = size;
+#ifndef MIAMI
m_allocPtr = 0;
+#else
+ m_allocPtr = -1;
+#endif
for(int i = 0; i < size; i++){
m_flags[i].id = 0;
m_flags[i].free = 1;
}
}
-
+#ifdef MIAMI
+ CPool(int size, const char *name)
+ : CPool(size) {}
+#endif
~CPool() {
Flush();
}