summaryrefslogtreecommitdiffstats
path: root/src/core/FileLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/FileLoader.cpp')
-rw-r--r--src/core/FileLoader.cpp562
1 files changed, 323 insertions, 239 deletions
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index b4da1a5e..635192ea 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -1,4 +1,5 @@
#include "common.h"
+#include <ctype.h>
#include "main.h"
#include "Quaternion.h"
@@ -24,6 +25,11 @@
#include "ZoneCull.h"
#include "CdStream.h"
#include "FileLoader.h"
+#include "Streaming.h"
+#include "ColStore.h"
+#include "Occlusion.h"
+
+//--MIAMI: file done
char CFileLoader::ms_line[256];
@@ -46,14 +52,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 +81,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 +94,17 @@ 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();
+ for(int i = 0; i < MODELINFOSIZE; i++)
+ if(CModelInfo::GetModelInfo(i))
+ CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex();
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){
#ifndef DISABLE_LOADING_SCREEN
LoadSplash(GetRandomSplashScreen());
@@ -114,30 +116,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*
@@ -181,7 +166,7 @@ struct ColHeader
};
void
-CFileLoader::LoadCollisionFile(const char *filename)
+CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
{
int fd;
char modelname[24];
@@ -190,6 +175,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);
@@ -198,10 +184,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);
}
@@ -213,6 +200,79 @@ 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)
{
@@ -242,13 +302,15 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
model.numLines = *(int16*)buf;
buf += 4;
if(model.numLines > 0){
- model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine));
+ //model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine));
for(i = 0; i < model.numLines; i++){
- model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
+ //model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
buf += 24;
}
}else
model.lines = nil;
+ model.numLines = 0;
+ model.lines = nil;
model.numBoxes = *(int16*)buf;
buf += 4;
@@ -267,10 +329,12 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
for(i = 0; i < numVertices; i++){
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
+#if 0
if(Abs(*(float*)buf) >= 256.0f ||
Abs(*(float*)(buf+4)) >= 256.0f ||
Abs(*(float*)(buf+8)) >= 256.0f)
printf("%s:Collision volume too big\n", modelname);
+#endif
buf += 12;
}
}else
@@ -293,7 +357,7 @@ GetNameAndLOD(char *nodename, char *name, int *n)
{
char *underscore = nil;
for(char *s = nodename; *s != '\0'; s++){
- if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L'))
+ if(s[0] == '_' && (s[1] == 'l' || s[1] == 'L') && isdigit(s[2]))
underscore = s;
}
if(underscore){
@@ -319,11 +383,11 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){
assert(mi->IsSimple());
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
mi->SetAtomic(n, atomic);
RpClumpRemoveAtomic(clump, atomic);
RpAtomicSetFrame(atomic, RwFrameCreate());
CVisibilityPlugins::SetAtomicModelInfo(atomic, mi);
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
}else{
debug("Can't find Atomic %s\n", name);
}
@@ -331,6 +395,16 @@ CFileLoader::FindRelatedModelInfoCB(RpAtomic *atomic, void *data)
return atomic;
}
+#ifdef LIBRW
+void
+InitClump(RpClump *clump)
+{
+ RpClumpForAllAtomics(clump, ConvertPlatformAtomic, nil);
+}
+#else
+#define InitClump(clump)
+#endif
+
void
CFileLoader::LoadModelFile(const char *filename)
{
@@ -342,6 +416,7 @@ CFileLoader::LoadModelFile(const char *filename)
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)){
clump = RpClumpStreamRead(stream);
if(clump){
+ InitClump(clump);
RpClumpForAllAtomics(clump, FindRelatedModelInfoCB, clump);
RpClumpDestroy(clump);
}
@@ -367,6 +442,7 @@ CFileLoader::LoadClumpFile(const char *filename)
GetNameAndLOD(nodename, name, &n);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(name, nil);
if(mi){
+ InitClump(clump);
assert(mi->IsClump());
mi->SetClump(clump);
}else
@@ -387,16 +463,9 @@ CFileLoader::LoadClumpFile(RwStream *stream, uint32 id)
clump = RpClumpStreamRead(stream);
if(clump == nil)
return false;
+ InitClump(clump);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
mi->SetClump(clump);
- if (mi->GetModelType() == MITYPE_PED && id != 0 && RwStreamFindChunk(stream, rwID_CLUMP, nil, nil)) {
- // Read LOD ped
- clump = RpClumpStreamRead(stream);
- if(clump){
- ((CPedModelInfo*)mi)->SetLowDetailClump(clump);
- RpClumpDestroy(clump);
- }
- }
return true;
}
@@ -422,6 +491,7 @@ CFileLoader::FinishLoadClumpFile(RwStream *stream, uint32 id)
clump = RpClumpGtaStreamRead2(stream);
if(clump){
+ InitClump(clump);
mi = (CClumpModelInfo*)CModelInfo::GetModelInfo(id);
mi->SetClump(clump);
return true;
@@ -442,6 +512,7 @@ CFileLoader::LoadAtomicFile(RwStream *stream, uint32 id)
clump = RpClumpStreamRead(stream);
if(clump == nil)
return false;
+ InitClump(clump);
gpRelatedModelInfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
RpClumpForAllAtomics(clump, SetRelatedModelInfoCB, clump);
RpClumpDestroy(clump);
@@ -458,11 +529,11 @@ CFileLoader::SetRelatedModelInfoCB(RpAtomic *atomic, void *data)
nodename = GetFrameNodeName(RpAtomicGetFrame(atomic));
GetNameAndLOD(nodename, name, &n);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
gpRelatedModelInfo->SetAtomic(n, atomic);
RpClumpRemoveAtomic(clump, atomic);
RpAtomicSetFrame(atomic, RwFrameCreate());
CVisibilityPlugins::SetAtomicModelInfo(atomic, gpRelatedModelInfo);
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
return atomic;
}
@@ -477,6 +548,8 @@ CFileLoader::LoadAtomicFile2Return(const char *filename)
stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, filename);
if(RwStreamFindChunk(stream, rwID_CLUMP, nil, nil))
clump = RpClumpStreamRead(stream);
+ if(clump)
+ InitClump(clump);
RwStreamClose(stream, nil);
return clump;
}
@@ -500,8 +573,9 @@ CFileLoader::LoadObjectTypes(const char *filename)
enum {
NONE,
OBJS,
- MLO,
+ MLO, // unused but enum still has it
TOBJ,
+ WEAP,
HIER,
CARS,
PEDS,
@@ -512,16 +586,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;
@@ -529,25 +604,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:
+ LoadWeaponObject(line);
break;
case HIER:
LoadClumpObject(line);
@@ -560,17 +637,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;
@@ -583,26 +658,30 @@ 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();
+ if(mi && mi->IsBuilding())
+ mi->SetupBigBuilding(minID, maxID);
}
}
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;
@@ -613,7 +692,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:
@@ -645,60 +724,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;
@@ -710,7 +740,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:
@@ -746,6 +776,29 @@ CFileLoader::LoadTimeObject(const char *line)
if(other)
other->SetOtherTimeModel(id);
MatchModelString(model, id);
+
+ return id;
+}
+
+int
+CFileLoader::LoadWeaponObject(const char *line)
+{
+ int id, numObjs;
+ char model[24], txd[24], animFile[16];
+ float dist;
+ CWeaponModelInfo *mi;
+
+ sscanf(line, "%d %s %s %s %d %f", &id, model, txd, animFile, &numObjs, &dist);
+
+ mi = CModelInfo::AddWeaponModel(id);
+ mi->SetName(model);
+ mi->SetNumAtomics(1);
+ mi->m_lodDistances[0] = dist;
+ mi->SetTexDictionary(txd);
+ mi->SetAnimFile(animFile);
+ mi->SetColModel(&CTempColModels::ms_colModelWeapon);
+ MatchModelString(model, id);
+ return id;
}
void
@@ -768,21 +821,22 @@ CFileLoader::LoadVehicleObject(const char *line)
{
int id;
char model[24], txd[24];
- char type[8], handlingId[16], gamename[32], vehclass[12];
+ char type[8], handlingId[16], gamename[32], animFile[16], vehclass[12];
uint32 frequency, comprules;
int32 level, misc;
float wheelScale;
CVehicleModelInfo *mi;
char *p;
- sscanf(line, "%d %s %s %s %s %s %s %d %d %x %d %f",
+ sscanf(line, "%d %s %s %s %s %s %s %s %d %d %x %d %f",
&id, model, txd,
- type, handlingId, gamename, vehclass,
+ type, handlingId, gamename, animFile, vehclass,
&frequency, &level, &comprules, &misc, &wheelScale);
mi = CModelInfo::AddVehicleModel(id);
mi->SetName(model);
mi->SetTexDictionary(txd);
+ mi->SetAnimFile(animFile);
for(p = gamename; *p; p++)
if(*p == '_') *p = ' ';
strcpy(mi->m_gameName, gamename);
@@ -812,36 +866,34 @@ CFileLoader::LoadVehicleObject(const char *line)
mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId);
- // Well this is kinda dumb....
- if(strncmp(vehclass, "poorfamily", 11) == 0){
+ if(strncmp(vehclass, "normal", 7) == 0)
+ mi->m_vehicleClass = CCarCtrl::NORMAL;
+ else if(strncmp(vehclass, "poorfamily", 11) == 0)
mi->m_vehicleClass = CCarCtrl::POOR;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::POOR);
- }else if(strncmp(vehclass, "richfamily", 11) == 0){
+ else if(strncmp(vehclass, "richfamily", 11) == 0)
mi->m_vehicleClass = CCarCtrl::RICH;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::RICH);
- }else if(strncmp(vehclass, "executive", 10) == 0){
+ else if(strncmp(vehclass, "executive", 10) == 0)
mi->m_vehicleClass = CCarCtrl::EXEC;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::EXEC);
- }else if(strncmp(vehclass, "worker", 7) == 0){
+ else if(strncmp(vehclass, "worker", 7) == 0)
mi->m_vehicleClass = CCarCtrl::WORKER;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::WORKER);
- }else if(strncmp(vehclass, "special", 8) == 0){
- mi->m_vehicleClass = CCarCtrl::SPECIAL;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::SPECIAL);
- }else if(strncmp(vehclass, "big", 4) == 0){
+ else if(strncmp(vehclass, "big", 4) == 0)
mi->m_vehicleClass = CCarCtrl::BIG;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::BIG);
- }else if(strncmp(vehclass, "taxi", 5) == 0){
+ else if(strncmp(vehclass, "taxi", 5) == 0)
mi->m_vehicleClass = CCarCtrl::TAXI;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::TAXI);
+ else if(strncmp(vehclass, "moped", 6) == 0)
+ mi->m_vehicleClass = CCarCtrl::MOPED;
+ else if(strncmp(vehclass, "motorbike", 10) == 0)
+ mi->m_vehicleClass = CCarCtrl::MOTORBIKE;
+ else if(strncmp(vehclass, "leisureboat", 12) == 0)
+ mi->m_vehicleClass = CCarCtrl::LEISUREBOAT;
+ else if(strncmp(vehclass, "workerboat", 11) == 0)
+ mi->m_vehicleClass = CCarCtrl::WORKERBOAT;
+ else if(strncmp(vehclass, "ignore", 11) == 0){
+ mi->m_vehicleClass = -1;
+ return;
}
+ CCarCtrl::AddToCarArray(id, mi->m_vehicleClass);
+ mi->m_frequency = frequency;
}
void
@@ -849,67 +901,87 @@ CFileLoader::LoadPedObject(const char *line)
{
int id;
char model[24], txd[24];
- char pedType[24], pedStats[24], animGroup[24];
+ char pedType[24], pedStats[24], animGroup[24], animFile[16];
int carsCanDrive;
CPedModelInfo *mi;
int animGroupId;
+ int radio1, radio2;
- if(sscanf(line, "%d %s %s %s %s %s %x",
+ sscanf(line, "%d %s %s %s %s %s %x %s %d %d",
&id, model, txd,
- pedType, pedStats, animGroup, &carsCanDrive) != 7)
- return;
+ pedType, pedStats, animGroup, &carsCanDrive,
+ animFile, &radio1, &radio2);
mi = CModelInfo::AddPedModel(id);
mi->SetName(model);
mi->SetTexDictionary(txd);
+ mi->SetAnimFile(animFile);
mi->SetColModel(&CTempColModels::ms_colModelPed1);
mi->m_pedType = CPedType::FindPedType(pedType);
mi->m_pedStatType = CPedStats::GetPedStatType(pedStats);
for(animGroupId = 0; animGroupId < NUM_ANIM_ASSOC_GROUPS; animGroupId++)
if(strcmp(animGroup, CAnimManager::GetAnimGroupName((AssocGroupId)animGroupId)) == 0)
break;
+ assert(animGroupId < NUM_ANIM_ASSOC_GROUPS);
mi->m_animGroup = animGroupId;
mi->m_carsCanDrive = carsCanDrive;
-
- // ???
- CModelInfo::GetModelInfo(MI_LOPOLYGUY)->SetColModel(&CTempColModels::ms_colModelPed1);
+ mi->radio1 = radio1;
+ mi->radio2 = radio2;
}
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 * 15, false);
+ else
+ ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight,
+ !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15);
}
void
CFileLoader::Load2dEffect(const char *line)
{
- int id, r, g, b, a, type;
+ int id, r, g, b, a, type, ptype;
float x, y, z;
char corona[32], shadow[32];
int shadowIntens, lightType, roadReflection, flare, flags, probability;
@@ -982,6 +1054,18 @@ CFileLoader::Load2dEffect(const char *line)
effect->attractor.type = flags;
effect->attractor.probability = probability;
break;
+ case EFFECT_PED_ATTRACTOR:
+ sscanf(line, "%d %f %f %f %d %d %d %d %d %d %f %f %f %f %f %f",
+ &id, &x, &y, &z, &r, &g, &b, &a, &type,
+ &ptype,
+ &effect->pedattr.queueDir.x,
+ &effect->pedattr.queueDir.y,
+ &effect->pedattr.queueDir.z,
+ &effect->pedattr.useDir.x,
+ &effect->pedattr.useDir.y,
+ &effect->pedattr.useDir.z);
+ effect->pedattr.type = ptype;
+ break;
}
CTxdStore::PopCurrentTxd();
@@ -995,20 +1079,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;
@@ -1019,6 +1104,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){
@@ -1031,18 +1117,24 @@ CFileLoader::LoadScene(const char *filename)
case CULL:
LoadCullZone(line);
break;
+ case OCCL:
+ LoadOcclusionVolume(line);
+ 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;
@@ -1065,18 +1157,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);
@@ -1091,7 +1195,8 @@ CFileLoader::LoadObjectInstance(const char *line)
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition());
- if(mi->IsSimple()){
+ entity->m_area = area;
+ if(mi->IsBuilding()){
if(mi->m_isBigBuilding)
entity->SetupBigBuilding();
if(mi->m_isSubway)
@@ -1100,14 +1205,25 @@ 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;
+
+ if(entity->GetPosition().z + col->boundingBox.min.z < 6.0f)
+ entity->bUnderwater = true;
}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);
@@ -1153,53 +1269,21 @@ CFileLoader::LoadPickup(const char *line)
}
void
-CFileLoader::LoadMapZones(const char *filename)
+CFileLoader::LoadOcclusionVolume(const char *line)
{
- 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);
+ float x, y, z;
+ float width, length, height;
+ float angle;
- debug("Finished loading IPL\n");
+ sscanf(line, "%f %f %f %f %f %f %f",
+ &x, &y, &z,
+ &width, &length, &height,
+ &angle);
+ COcclusion::AddOne(x, y, z + height/2.0f, width, length, height, angle);
}
+
+//--MIAMI: unused
void
CFileLoader::ReloadPaths(const char *filename)
{
@@ -1210,10 +1294,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;
@@ -1229,17 +1313,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;
@@ -1269,6 +1351,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 == '#')
@@ -1344,6 +1427,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)) {