summaryrefslogtreecommitdiff
path: root/src/core/FileLoader.cpp
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2020-05-05 13:02:42 +0200
committeraap <aap@papnet.eu>2020-05-05 13:02:42 +0200
commitb44df26d3ea5fcdaf6d954016303f358d2c64b79 (patch)
tree2921c2c0e2883117f4ce9cec73865c1701f32cec /src/core/FileLoader.cpp
parent84c9484e55874c57c1c017cb2394e0c6b2f32303 (diff)
implemented most of streamed collisions and big buildings
Diffstat (limited to 'src/core/FileLoader.cpp')
-rw-r--r--src/core/FileLoader.cpp164
1 files changed, 160 insertions, 4 deletions
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index b7d82089..06eb5a34 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)
@@ -172,16 +202,25 @@ CFileLoader::LoadTexDictionary(const char *filename)
return txd;
}
+struct ColHeader
+{
+ char ident[4];
+ 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];
CBaseModelInfo *mi;
- struct {
- char ident[4];
- uint32 size;
- } header;
+ ColHeader header;
debug("Loading collision file %s\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
@@ -193,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->m_bOwnsColModel){
+#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);
}
@@ -208,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)
{
@@ -1060,19 +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);
@@ -1087,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();
@@ -1096,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);