summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CdStream.cpp12
-rw-r--r--src/FileLoader.cpp252
-rw-r--r--src/FileLoader.h8
-rw-r--r--src/World.cpp2
-rw-r--r--src/World.h1
-rw-r--r--src/control/ObjectData.cpp5
-rw-r--r--src/control/ObjectData.h7
-rw-r--r--src/control/PathFind.cpp6
-rw-r--r--src/control/PathFind.h5
-rw-r--r--src/entities/Building.h5
-rw-r--r--src/entities/Dummy.h3
-rw-r--r--src/entities/DummyObject.cpp13
-rw-r--r--src/entities/DummyObject.h7
-rw-r--r--src/entities/Entity.cpp2
-rw-r--r--src/entities/Entity.h2
-rw-r--r--src/main.cpp24
-rw-r--r--src/main.h4
17 files changed, 345 insertions, 13 deletions
diff --git a/src/CdStream.cpp b/src/CdStream.cpp
index f0cefda5..506e14e9 100644
--- a/src/CdStream.cpp
+++ b/src/CdStream.cpp
@@ -456,12 +456,12 @@ CdStreamAddImage(char const *path)
SetLastError(0);
gImgFiles[gNumImages] = CreateFile(path,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- _gdwCdStreamFlags | FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_READONLY,
- NULL);
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ _gdwCdStreamFlags | FILE_FLAG_RANDOM_ACCESS | FILE_ATTRIBUTE_READONLY,
+ NULL);
ASSERT( gImgFiles[gNumImages] != NULL );
if ( gImgFiles[gNumImages] == NULL )
diff --git a/src/FileLoader.cpp b/src/FileLoader.cpp
index dc70234d..69d8a483 100644
--- a/src/FileLoader.cpp
+++ b/src/FileLoader.cpp
@@ -1,9 +1,12 @@
#include "common.h"
#include "main.h"
#include "patcher.h"
+#include "math/Quaternion.h"
#include "ModelInfo.h"
#include "ModelIndices.h"
#include "TempColModels.h"
+#include "VisibilityPlugins.h"
+#include "FileMgr.h"
#include "HandlingDataMgr.h"
#include "CarCtrl.h"
#include "PedType.h"
@@ -14,8 +17,12 @@
#include "NodeName.h"
#include "TxdStore.h"
#include "PathFind.h"
-#include "VisibilityPlugins.h"
-#include "FileMgr.h"
+#include "ObjectData.h"
+#include "DummyObject.h"
+#include "World.h"
+#include "Zones.h"
+#include "CullZones.h"
+#include "CdStream.h"
#include "FileLoader.h"
char CFileLoader::ms_line[256];
@@ -85,6 +92,21 @@ CFileLoader::LoadLevel(const char *filename)
}else if(strncmp(line, "IDE", 3) == 0){
LoadingScreenLoadingFile(line + 4);
LoadObjectTypes(line + 4);
+ }else if(strncmp(line, "IPL", 3) == 0){
+ if(!objectsLoaded){
+ // CModelInfo::ConstructMloClumps();
+ CObjectData::Initialise("DATA\\OBJECT.DAT");
+ objectsLoaded = true;
+ }
+ LoadingScreenLoadingFile(line + 4);
+ LoadObjectInstance(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){
+ CdStreamAddImage(line + 8);
}
}
@@ -489,7 +511,7 @@ CFileLoader::LoadObjectTypes(const char *filename)
int id, pathType;
// int mlo;
- section = 0;
+ section = NONE;
pathIndex = -1;
// mlo = 0;
debug("Loading object types from %s...\n", filename);
@@ -907,8 +929,225 @@ CFileLoader::Load2dEffect(const char *line)
CTxdStore::PopCurrentTxd();
}
+void
+CFileLoader::LoadScene(const char *filename)
+{
+ enum {
+ NONE,
+ INST,
+ ZONE,
+ CULL,
+ PICK,
+ PATH,
+ };
+ char *line;
+ int fd;
+ int section;
+ int pathIndex;
+ char pathTypeStr[20];
+
+ section = NONE;
+ pathIndex = -1;
+ debug("Creating objects 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, "inst", 4) == 0) section = INST;
+ else if(strncmp(line, "zone", 4) == 0) section = ZONE;
+ 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, "end", 3) == 0){
+ section = NONE;
+ }else switch(section){
+ case INST:
+ LoadObjectInstance(line);
+ break;
+ case ZONE:
+ LoadZone(line);
+ break;
+ case CULL:
+ LoadCullZone(line);
+ break;
+ case PICK:
+ // unused
+ LoadPickup(line);
+ break;
+ case PATH:
+ // unfinished in the game
+ if(pathIndex == -1){
+ LoadPathHeader(line, pathTypeStr);
+ // type not set
+ pathIndex = 0;
+ }else{
+ // nodes not loaded
+ pathIndex++;
+ if(pathIndex == 12)
+ pathIndex = -1;
+ }
+ break;
+ }
+ }
+ CFileMgr::CloseFile(fd);
+
+ debug("Finished loading IPL\n");
+}
+
+void
+CFileLoader::LoadObjectInstance(const char *line)
+{
+ int id;
+ char name[24];
+ RwV3d trans, scale, axis;
+ float angle;
+ CSimpleModelInfo *mi;
+ RwMatrix *xform;
+ CEntity *entity;
+
+ 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;
+
+ mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
+ if(mi == nil)
+ return;
+ assert(mi->IsSimple());
+
+ angle = -RADTODEG(2.0f * acosf(angle));
+ xform = RwMatrixCreate();
+ RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE);
+ RwMatrixTranslate(xform, &trans, rwCOMBINEPOSTCONCAT);
+
+ if(mi->GetObjectID() == -1){
+ if(ThePaths.IsPathObject(id)){
+ entity = new CTreadable;
+ ThePaths.RegisterMapObject((CTreadable*)entity);
+ }else
+ entity = new CBuilding;
+ entity->SetModelIndexNoCreate(id);
+ entity->GetMatrix() = CMatrix(xform);
+ entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition());
+ if(mi->IsSimple()){
+ if(mi->m_isBigBuilding)
+ entity->SetupBigBuilding();
+ if(mi->m_isSubway)
+ entity->bIsSubway = true;
+ }
+ if(mi->GetLargestLodDistance() < 2.0f)
+ entity->bIsVisible = false;
+ CWorld::Add(entity);
+ }else{
+ entity = new CDummyObject;
+ entity->SetModelIndexNoCreate(id);
+ entity->GetMatrix() = CMatrix(xform);
+ CWorld::Add(entity);
+ if(IsGlass(entity->GetModelIndex()))
+ entity->bIsVisible = false;
+ entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition());
+ }
+
+ RwMatrixDestroy(xform);
+}
+
+void
+CFileLoader::LoadZone(const char *line)
+{
+ 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::CreateZone(name, (eZoneType)type, minx, miny, minz, maxx, maxy, maxz, (eLevelName)level);
+}
+
+void
+CFileLoader::LoadCullZone(const char *line)
+{
+ CVector pos;
+ float minx, miny, minz;
+ float maxx, maxy, maxz;
+ int flags;
+ int wantedLevelDrop = 0;
+
+ sscanf(line, "%f %f %f %f %f %f %f %f %f %d %d",
+ &pos.x, &pos.y, &pos.z,
+ &minx, &miny, &minz,
+ &maxx, &maxy, &maxz,
+ &flags, &wantedLevelDrop);
+ CCullZones::AddCullZone(pos, minx, maxx, miny, maxy, minz, maxy, flags, wantedLevelDrop);
+}
+
+// unused
+void
+CFileLoader::LoadPickup(const char *line)
+{
+ int id;
+ float x, y, z;
+
+ 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");
+}
+
STARTPATCHES
+ // this makes my game crash in CGarage!
+ //InjectHook(0x476290, CFileLoader::LoadLevel, PATCH_JUMP);
+
InjectHook(0x476520, CFileLoader::LoadCollisionFromDatFile, PATCH_JUMP);
InjectHook(0x4761D0, CFileLoader::LoadLine, PATCH_JUMP);
InjectHook(0x4765B0, CFileLoader::LoadTexDictionary, PATCH_JUMP);
@@ -933,4 +1172,11 @@ STARTPATCHES
InjectHook(0x477FF0, CFileLoader::LoadCarPathNode, PATCH_JUMP);
InjectHook(0x477F00, CFileLoader::LoadPedPathNode, PATCH_JUMP);
InjectHook(0x4780E0, CFileLoader::Load2dEffect, PATCH_JUMP);
+
+ InjectHook(0x478370, CFileLoader::LoadScene, PATCH_JUMP);
+ InjectHook(0x4786B0, CFileLoader::LoadObjectInstance, PATCH_JUMP);
+ InjectHook(0x478A00, CFileLoader::LoadZone, PATCH_JUMP);
+ InjectHook(0x478A90, CFileLoader::LoadCullZone, PATCH_JUMP);
+
+ InjectHook(0x478550, CFileLoader::LoadMapZones, PATCH_JUMP);
ENDPATCHES
diff --git a/src/FileLoader.h b/src/FileLoader.h
index 0aad884d..f9121ace 100644
--- a/src/FileLoader.h
+++ b/src/FileLoader.h
@@ -31,4 +31,12 @@ public:
static void LoadPedPathNode(const char *line, int id, int node);
static void LoadCarPathNode(const char *line, int id, int node);
static void Load2dEffect(const char *line);
+
+ static void LoadScene(const char *filename);
+ static void LoadObjectInstance(const char *line);
+ static void LoadZone(const char *line);
+ static void LoadCullZone(const char *line);
+ static void LoadPickup(const char *line);
+
+ static void LoadMapZones(const char *filename);
};
diff --git a/src/World.cpp b/src/World.cpp
index 1d45dcc8..b5b7ae5c 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -7,6 +7,8 @@
#include "TempColModels.h"
#include "World.h"
+WRAPPER void CWorld::Add(CEntity *entity) { EAXJMP(0x4AE930); }
+
CPtrList *CWorld::ms_bigBuildingsList = (CPtrList*)0x6FAB60;
CPtrList &CWorld::ms_listMovingEntityPtrs = *(CPtrList*)0x8F433C;
CSector (*CWorld::ms_aSectors)[NUMSECTORS_X] = (CSector (*)[NUMSECTORS_Y])0x665608;
diff --git a/src/World.h b/src/World.h
index 77e0fd99..c1d870e2 100644
--- a/src/World.h
+++ b/src/World.h
@@ -55,6 +55,7 @@ public:
static bool &bForceProcessControl;
static bool &bProcessCutsceneOnly;
+ static void Add(CEntity *entity);
static CSector *GetSector(int x, int y) { return &ms_aSectors[y][x]; }
static CPtrList &GetBigBuildingList(eLevelName i) { return ms_bigBuildingsList[i]; }
diff --git a/src/control/ObjectData.cpp b/src/control/ObjectData.cpp
new file mode 100644
index 00000000..28c34658
--- /dev/null
+++ b/src/control/ObjectData.cpp
@@ -0,0 +1,5 @@
+#include "common.h"
+#include "patcher.h"
+#include "ObjectData.h"
+
+WRAPPER void CObjectData::Initialise(const char *filename) { EAXJMP(0x4BC0E0); }
diff --git a/src/control/ObjectData.h b/src/control/ObjectData.h
new file mode 100644
index 00000000..7df1c845
--- /dev/null
+++ b/src/control/ObjectData.h
@@ -0,0 +1,7 @@
+#pragma once
+
+class CObjectData
+{
+public:
+ static void Initialise(const char *filename);
+};
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index 8cfc17e7..c3af2e30 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -77,6 +77,12 @@ CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x,
}
void
+CPathFind::RegisterMapObject(CTreadable *mapObject)
+{
+ m_mapObjects[m_numMapObjects++] = mapObject;
+}
+
+void
CPathFind::PreparePathData(void)
{
int i, j, k;
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index ed3c7e9f..83b89953 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -67,6 +67,8 @@ struct CPathInfoForObject
int8 numRightLanes;
uint8 crossing : 1;
};
+extern CPathInfoForObject *&InfoForTileCars;
+extern CPathInfoForObject *&InfoForTilePeds;
struct CTempNode
{
@@ -125,6 +127,9 @@ public:
void CalcNodeCoors(int16 x, int16 y, int16 z, int32 id, CVector *out);
void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing);
void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight);
+ void RegisterMapObject(CTreadable *mapObject);
+
+ bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); }
};
static_assert(sizeof(CPathFind) == 0x4c8f4, "CPathFind: error");
diff --git a/src/entities/Building.h b/src/entities/Building.h
index d33aaa4f..612e0fb3 100644
--- a/src/entities/Building.h
+++ b/src/entities/Building.h
@@ -6,7 +6,10 @@ class CBuilding : public CEntity
{
public:
// TODO: ReplaceWithNewModel
- // TODO: ctor
+ CBuilding(void) {
+ m_type = ENTITY_TYPE_BUILDING;
+ bUsesCollision = true;
+ }
static void *operator new(size_t);
static void operator delete(void*, size_t);
diff --git a/src/entities/Dummy.h b/src/entities/Dummy.h
index e7506617..034d4c57 100644
--- a/src/entities/Dummy.h
+++ b/src/entities/Dummy.h
@@ -8,6 +8,9 @@ class CDummy : public CEntity
public:
CEntryInfoList m_entryInfoList;
+ CDummy(void) { m_type = ENTITY_TYPE_DUMMY; }
+ // TODO: Add, Remove
+
static void *operator new(size_t);
static void operator delete(void*, size_t);
};
diff --git a/src/entities/DummyObject.cpp b/src/entities/DummyObject.cpp
new file mode 100644
index 00000000..083ad6c6
--- /dev/null
+++ b/src/entities/DummyObject.cpp
@@ -0,0 +1,13 @@
+#include "common.h"
+#include "patcher.h"
+#include "DummyObject.h"
+#include "Pools.h"
+
+CDummyObject::CDummyObject(CObject *obj)
+{
+ SetModelIndexNoCreate(obj->GetModelIndex());
+ if(obj->m_rwObject)
+ AttachToRwObject(obj->m_rwObject);
+ obj->DetachFromRwObject();
+ m_level = obj->m_level;
+}
diff --git a/src/entities/DummyObject.h b/src/entities/DummyObject.h
index 7bfe3a57..d4dce609 100644
--- a/src/entities/DummyObject.h
+++ b/src/entities/DummyObject.h
@@ -2,7 +2,12 @@
#include "Dummy.h"
-class CDummyObject : CDummy
+class CObject;
+
+class CDummyObject : public CDummy
{
+public:
+ CDummyObject(void) {}
+ CDummyObject(CObject *obj);
};
static_assert(sizeof(CDummyObject) == 0x68, "CDummyObject: error");
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 2338f627..0ab1488d 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -48,7 +48,7 @@ CEntity::CEntity(void)
bHasHitWall = false;
bImBeingRendered = false;
m_flagD8 = false;
- m_flagD10 = false;
+ bIsSubway = false;
bDrawLast = false;
m_flagD40 = false;
m_flagD80 = false;
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index 73a2c668..95294ed8 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -79,7 +79,7 @@ public:
uint32 bHasHitWall : 1;
uint32 bImBeingRendered : 1;
uint32 m_flagD8 : 1;
- uint32 m_flagD10 : 1;
+ uint32 bIsSubway : 1; // set when subway, but maybe different meaning?
uint32 bDrawLast : 1;
uint32 m_flagD40 : 1;
uint32 m_flagD80 : 1; // CObject visibility?
diff --git a/src/main.cpp b/src/main.cpp
index 8f6a9b29..9bdb41fc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "patcher.h"
#include "main.h"
+#include "General.h"
#include "RwHelper.h"
#include "Clouds.h"
#include "Draw.h"
@@ -579,6 +580,29 @@ ResetLoadingScreenBar(void)
NumberOfChunksLoaded = 0.0f;
}
+char*
+GetRandomSplashScreen(void)
+{
+ int index;
+ static int index2 = 0;
+ static char splashName[128];
+ static int splashIndex[24] = {
+ 25, 22, 4, 13,
+ 1, 21, 14, 16,
+ 10, 12, 5, 9,
+ 11, 18, 3, 2,
+ 19, 23, 7, 17,
+ 15, 6, 8, 20
+ };
+
+ index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)];
+ index2++;
+ if(index2 == 6)
+ index2 = 0;
+ sprintf(splashName, "loadsc%d", index);
+ return splashName;
+}
+
#include "rwcore.h"
#include "rpworld.h"
#include "rpmatfx.h"
diff --git a/src/main.h b/src/main.h
index eba79117..45948b34 100644
--- a/src/main.h
+++ b/src/main.h
@@ -11,4 +11,8 @@ extern uint8 work_buff[55000];
extern char gString[256];
extern wchar *gUString;
+class CSprite2d;
+
void LoadingScreen(const char *str1, const char *str2, const char *splashscreen);
+CSprite2d *LoadSplash(const char *name);
+char *GetRandomSplashScreen(void);