summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2021-01-25 10:30:34 +0100
committerGitHub <noreply@github.com>2021-01-25 10:30:34 +0100
commitd6544933aaa391072178532dbb6872d0e3c479f8 (patch)
tree8d924704b6f622bb50275ca1565b55a51e8cfb62
parent1ab96abb91df1852cbbd76c356da027c68c6aa60 (diff)
parentce7f166ba387c5368d500faffa676243bc9a3476 (diff)
Merge pull request #984 from aap/lcs
modelinfos
-rw-r--r--src/collision/ColModel.cpp7
-rw-r--r--src/collision/ColModel.h2
-rw-r--r--src/collision/TempColModels.cpp85
-rw-r--r--src/collision/TempColModels.h13
-rw-r--r--src/control/Garages.cpp2
-rw-r--r--src/core/AnimViewer.cpp2
-rw-r--r--src/core/FileLoader.cpp43
-rw-r--r--src/core/Game.cpp5
-rw-r--r--src/core/Leeds.cpp14
-rw-r--r--src/core/Leeds.h36
-rw-r--r--src/core/main.cpp3
-rw-r--r--src/core/main.h3
-rw-r--r--src/extras/custompipes_d3d9.cpp3
-rw-r--r--src/fakerw/rpworld.h1
-rw-r--r--src/leeds/base/relocatableChunk.h2
-rw-r--r--src/modelinfo/BaseModelInfo.cpp82
-rw-r--r--src/modelinfo/BaseModelInfo.h22
-rw-r--r--src/modelinfo/ClumpModelInfo.cpp68
-rw-r--r--src/modelinfo/ClumpModelInfo.h9
-rw-r--r--src/modelinfo/PedModelInfo.cpp121
-rw-r--r--src/modelinfo/PedModelInfo.h10
-rw-r--r--src/modelinfo/SimpleModelInfo.cpp212
-rw-r--r--src/modelinfo/SimpleModelInfo.h37
-rw-r--r--src/modelinfo/TimeModelInfo.cpp29
-rw-r--r--src/modelinfo/TimeModelInfo.h9
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp435
-rw-r--r--src/modelinfo/VehicleModelInfo.h32
-rw-r--r--src/modelinfo/WeaponModelInfo.cpp22
-rw-r--r--src/modelinfo/WeaponModelInfo.h10
-rw-r--r--src/rw/VisibilityPlugins.cpp42
-rw-r--r--src/rw/VisibilityPlugins.h3
-rw-r--r--src/vehicles/Automobile.cpp2
-rw-r--r--src/vehicles/Heli.cpp2
-rw-r--r--src/vehicles/Vehicle.cpp4
-rw-r--r--src/weapons/Weapon.cpp2
35 files changed, 1181 insertions, 193 deletions
diff --git a/src/collision/ColModel.cpp b/src/collision/ColModel.cpp
index 49847dbd..ccd679b2 100644
--- a/src/collision/ColModel.cpp
+++ b/src/collision/ColModel.cpp
@@ -204,3 +204,10 @@ CColModel::operator=(const CColModel &other)
}
return *this;
}
+
+bool
+CColModel::Write(base::cRelocatableChunkWriter &writer, bool allocSpace)
+{
+ assert(0 && "TODO(LCS)");
+ return 1;
+}
diff --git a/src/collision/ColModel.h b/src/collision/ColModel.h
index cd5ae651..c58a4d9b 100644
--- a/src/collision/ColModel.h
+++ b/src/collision/ColModel.h
@@ -36,4 +36,6 @@ struct CColModel
void *operator new(size_t);
void operator delete(void *p, size_t);
CColModel& operator=(const CColModel& other);
+
+ bool Write(base::cRelocatableChunkWriter &writer, bool allocSpace);
}; \ No newline at end of file
diff --git a/src/collision/TempColModels.cpp b/src/collision/TempColModels.cpp
index 32f2285c..148b86fe 100644
--- a/src/collision/TempColModels.cpp
+++ b/src/collision/TempColModels.cpp
@@ -1,11 +1,12 @@
#include "common.h"
+#include "main.h"
#include "TempColModels.h"
#include "Game.h"
-CColModel CTempColModels::ms_colModelPed1;
+// LCS: haven't yet checked the numbers but they probably haven't changed
+
CColModel CTempColModels::ms_colModelPed2;
-CColModel CTempColModels::ms_colModelBBox;
CColModel CTempColModels::ms_colModelBumper1;
CColModel CTempColModels::ms_colModelWheel1;
CColModel CTempColModels::ms_colModelPanel1;
@@ -16,7 +17,9 @@ CColModel CTempColModels::ms_colModelPedGroundHit;
CColModel CTempColModels::ms_colModelBoot1;
CColModel CTempColModels::ms_colModelDoor1;
CColModel CTempColModels::ms_colModelBonnet1;
-CColModel CTempColModels::ms_colModelWeapon;
+CColModel CTempColModels::ms_colModelFerryDocked;
+
+CTempColModels *gpTempColModels;
CColSphere s_aPedSpheres[3];
@@ -34,6 +37,7 @@ CColSphere s_aBootSpheres[4];
CColSphere s_aWheelSpheres[2];
CColSphere s_aBodyPartSpheres1[2];
CColSphere s_aBodyPartSpheres2[2];
+CColBox S_aFerryDockedBoxes[1];
void
CTempColModels::Initialise(void)
@@ -44,11 +48,26 @@ CTempColModels::Initialise(void)
colmodel.level = LEVEL_GENERIC;\
colmodel.ownsCollisionVolumes = false;
- int i;
+ if(gMakeResources){
+ if(gpTempColModels == nil){
+ gpTempColModels = new CTempColModels;
+ gpTempColModels->Initialise();
+ return;
+ }
+
+ ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
+ ms_colModelBBox.level = LEVEL_GENERIC;
- ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
- ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
- ms_colModelBBox.level = LEVEL_GENERIC;
+ ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f));
+ SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
+
+ ms_colModelWeapon.boundingSphere.Set(0.25f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelWeapon.boundingBox.Set(CVector(-0.25f, -0.25f, -0.25f), CVector(0.25f, 0.25f, 0.25f));
+ }
+
+ int i;
for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
@@ -74,10 +93,6 @@ CTempColModels::Initialise(void)
s_aPedSpheres[i].piece = 0;
}
- ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f));
- ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f));
- SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
-
// Ped 2 Spheres
s_aPed2Spheres[0].radius = 0.3f;
@@ -294,13 +309,47 @@ CTempColModels::Initialise(void)
SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);
- ms_colModelWeapon.boundingSphere.radius = 0.25f;
- ms_colModelWeapon.boundingBox.min.x = -0.25f;
- ms_colModelWeapon.boundingBox.min.y = -0.25f;
- ms_colModelWeapon.boundingBox.min.z = -0.25f;
- ms_colModelWeapon.boundingBox.max.x = 0.25f;
- ms_colModelWeapon.boundingBox.max.y = 0.25f;
- ms_colModelWeapon.boundingBox.max.z = 0.25f;
+ // Ferry Docked
+
+ S_aFerryDockedBoxes[0].Set(CVector(-6.3f, -22.78f, -2.0f), CVector(6.3f, 22.78f, 2.8f), SURFACE_THICK_METAL_PLATE, SURFACE_DEFAULT);
+
+ ms_colModelFerryDocked.boundingSphere.Set(35.0f, CVector(0.0f, -0.0f, 0.0f));
+ ms_colModelFerryDocked.boundingBox.Set(S_aFerryDockedBoxes[0].min, S_aFerryDockedBoxes[0].max);
+ ms_colModelFerryDocked.spheres = nil;
+ ms_colModelFerryDocked.numSpheres = 0;
+ ms_colModelFerryDocked.boxes = S_aFerryDockedBoxes;
+ ms_colModelFerryDocked.numBoxes = ARRAY_SIZE(S_aFerryDockedBoxes);
+ ms_colModelFerryDocked.level = LEVEL_GENERIC;
+
#undef SET_COLMODEL_SPHERES
}
+
+void
+CTempColModels::Write(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), 0x10, false, true);
+
+ ms_colModelBBox.Write(writer, false);
+ writer.AddPatch(&ms_colModelBBox);
+
+ ms_colModelPed1.Write(writer, false);
+ writer.AddPatch(&ms_colModelPed1);
+
+ ms_colModelWeapon.Write(writer, false);
+ writer.AddPatch(&ms_colModelWeapon);
+
+ for(int i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++)
+ ms_colModelCutObj[i].Write(writer, true);
+ ms_colModelPed2.Write(writer, true);
+ ms_colModelPedGroundHit.Write(writer, true);
+ ms_colModelDoor1.Write(writer, true);
+ ms_colModelBumper1.Write(writer, true);
+ ms_colModelPanel1.Write(writer, true);
+ ms_colModelBonnet1.Write(writer, true);
+ ms_colModelBoot1.Write(writer, true);
+ ms_colModelWheel1.Write(writer, true);
+ ms_colModelBodyPart1.Write(writer, true);
+ ms_colModelBodyPart2.Write(writer, true);
+ ms_colModelFerryDocked.Write(writer, true);
+}
diff --git a/src/collision/TempColModels.h b/src/collision/TempColModels.h
index e8a39695..0f1f06c3 100644
--- a/src/collision/TempColModels.h
+++ b/src/collision/TempColModels.h
@@ -5,9 +5,11 @@
class CTempColModels
{
public:
- static CColModel ms_colModelPed1;
+ CColModel ms_colModelPed1;
+ CColModel ms_colModelBBox;
+ CColModel ms_colModelWeapon;
+
static CColModel ms_colModelPed2;
- static CColModel ms_colModelBBox;
static CColModel ms_colModelBumper1;
static CColModel ms_colModelWheel1;
static CColModel ms_colModelPanel1;
@@ -18,7 +20,10 @@ public:
static CColModel ms_colModelBoot1;
static CColModel ms_colModelDoor1;
static CColModel ms_colModelBonnet1;
- static CColModel ms_colModelWeapon;
+ static CColModel ms_colModelFerryDocked;
- static void Initialise(void);
+ void Initialise(void);
+ void Write(base::cRelocatableChunkWriter &writer);
};
+
+extern CTempColModels *gpTempColModels;
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index 9238f51d..0b1f8e19 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -502,7 +502,7 @@ void CGarage::Update()
pos.x = CGeneral::GetRandomNumberInRange(m_fInfX + 0.5f, m_fSupX - 0.5f);
pos.y = CGeneral::GetRandomNumberInRange(m_fInfY + 0.5f, m_fSupY - 0.5f);
pos.z = CGeneral::GetRandomNumberInRange(m_fDoor1Z - 3.0f, m_fDoor1Z + 1.0f);
- CParticle::AddParticle(PARTICLE_GARAGEPAINT_SPRAY, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, CVehicleModelInfo::ms_vehicleColourTable[colour1]);
+ CParticle::AddParticle(PARTICLE_GARAGEPAINT_SPRAY, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, CVehicleModelInfo::mspInfo->ms_vehicleColourTable[colour1]);
}
}
}
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp
index 854ec7d4..1a7facc1 100644
--- a/src/core/AnimViewer.cpp
+++ b/src/core/AnimViewer.cpp
@@ -81,7 +81,7 @@ CAnimViewer::Initialise(void) {
CCollision::Init();
CWorld::Initialise();
mod_HandlingManager.Initialise();
- CTempColModels::Initialise();
+ gpTempColModels->Initialise();
CAnimManager::Initialise();
CModelInfo::Initialise();
CParticle::Initialise();
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index c13252f6..2818007b 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -607,11 +607,14 @@ CFileLoader::LoadObjectTypes(const char *filename)
int section;
int pathIndex;
int id, pathType;
- int minID, maxID;
+ //int minID, maxID;
+
+ for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
+ m_sTempIdeData[i].id = -1;
section = NONE;
- minID = INT32_MAX;
- maxID = -1;
+ //minID = INT32_MAX;
+ //maxID = -1;
pathIndex = -1;
debug("Loading object types from %s...\n", filename);
@@ -635,13 +638,13 @@ CFileLoader::LoadObjectTypes(const char *filename)
}else switch(section){
case OBJS:
id = LoadObject(line);
- if(id > maxID) maxID = id;
- if(id < minID) minID = id;
+ //if(id > maxID) maxID = id;
+ //if(id < minID) minID = id;
break;
case TOBJ:
id = LoadTimeObject(line);
- if(id > maxID) maxID = id;
- if(id < minID) minID = id;
+ //if(id > maxID) maxID = id;
+ //if(id < minID) minID = id;
break;
case WEAP:
LoadWeaponObject(line);
@@ -678,10 +681,10 @@ CFileLoader::LoadObjectTypes(const char *filename)
}
CFileMgr::CloseFile(fd);
- for(id = minID; id <= maxID; id++){
+ for(id = 0; id < MODELINFOSIZE; id++){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi && mi->IsBuilding())
- mi->SetupBigBuilding(minID, maxID);
+ mi->SetupBigBuilding();
}
}
@@ -714,6 +717,13 @@ CFileLoader::LoadObject(const char *line)
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
return 0; // game returns return value
+ for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
+ if(m_sTempIdeData[i].id == -1){
+ m_sTempIdeData[i].id = id;
+ strcpy(m_sTempIdeData[i].name, model);
+ break;
+ }
+
switch(numObjs){
case 1:
sscanf(line, "%d %s %s %d %f %d",
@@ -762,6 +772,13 @@ CFileLoader::LoadTimeObject(const char *line)
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
return 0; // game returns return value
+ for(int i = 0; i < ARRAY_SIZE(m_sTempIdeData); i++)
+ if(m_sTempIdeData[i].id < 0){
+ m_sTempIdeData[i].id = id;
+ strcpy(m_sTempIdeData[i].name, model);
+ break;
+ }
+
switch(numObjs){
case 1:
sscanf(line, "%d %s %s %d %f %d %d %d",
@@ -792,7 +809,7 @@ CFileLoader::LoadTimeObject(const char *line)
mi->m_firstDamaged = damaged;
mi->SetTimes(timeOn, timeOff);
mi->SetTexDictionary(txd);
- other = mi->FindOtherTimeModel();
+ other = mi->FindOtherTimeModel(model);
if(other)
other->SetOtherTimeModel(id);
MatchModelString(model, id);
@@ -816,7 +833,7 @@ CFileLoader::LoadWeaponObject(const char *line)
mi->m_lodDistances[0] = dist;
mi->SetTexDictionary(txd);
mi->SetAnimFile(animFile);
- mi->SetColModel(&CTempColModels::ms_colModelWeapon);
+ mi->SetColModel(&gpTempColModels->ms_colModelWeapon);
MatchModelString(model, id);
return id;
}
@@ -832,7 +849,7 @@ CFileLoader::LoadClumpObject(const char *line)
mi = CModelInfo::AddClumpModel(id);
mi->SetModelName(model);
mi->SetTexDictionary(txd);
- mi->SetColModel(&CTempColModels::ms_colModelBBox);
+ mi->SetColModel(&gpTempColModels->ms_colModelBBox);
}
}
@@ -939,7 +956,7 @@ CFileLoader::LoadPedObject(const char *line)
mi->SetModelName(model);
mi->SetTexDictionary(txd);
mi->SetAnimFile(animFile);
- mi->SetColModel(&CTempColModels::ms_colModelPed1);
+ mi->SetColModel(&gpTempColModels->ms_colModelPed1);
mi->m_pedType = CPedType::FindPedType(pedType);
mi->m_pedStatType = CPedStats::GetPedStatType(pedStats);
for(animGroupId = 0; animGroupId < NUM_ANIM_ASSOC_GROUPS; animGroupId++)
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index e0becc43..b5b4b90d 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -316,7 +316,7 @@ bool CGame::InitialiseOnceAfterRW(void)
{
TheText.Load();
CTimer::Initialise();
- CTempColModels::Initialise();
+ gpTempColModels->Initialise();
mod_HandlingManager.Initialise();
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
@@ -366,6 +366,9 @@ bool CGame::Initialise(const char* datFile)
CPools::Initialise();
+ if(gMakeResources)
+ CVehicleModelInfo::Load(nil);
+
#ifndef GTA_PS2
CIniFile::LoadIniFile();
#endif
diff --git a/src/core/Leeds.cpp b/src/core/Leeds.cpp
new file mode 100644
index 00000000..cda50605
--- /dev/null
+++ b/src/core/Leeds.cpp
@@ -0,0 +1,14 @@
+#include "common.h"
+#include "Leeds.h"
+
+void LoadResource(RpAtomic *atomic) {}
+void LoadResource(RpClump *clump) {}
+
+
+void SaveResource(RwTexture *tex, base::cRelocatableChunkWriter &writer) {}
+void SaveResource(RwTexDictionary *txd, base::cRelocatableChunkWriter &writer) {}
+void SaveResource(RpMaterial *mat, base::cRelocatableChunkWriter &writer) {}
+void SaveResource(RpMaterialList *matlist, base::cRelocatableChunkWriter &writer) {}
+void SaveResource(RpGeometry *geo, base::cRelocatableChunkWriter &writer) {}
+void SaveResource(RpAtomic *atomic, base::cRelocatableChunkWriter &writer) {}
+void SaveResource(RpClump *clump, base::cRelocatableChunkWriter &writer) {}
diff --git a/src/core/Leeds.h b/src/core/Leeds.h
new file mode 100644
index 00000000..bf71d7e0
--- /dev/null
+++ b/src/core/Leeds.h
@@ -0,0 +1,36 @@
+#pragma once
+
+/*
+PatchElementModelInfo(RslElement *,void *)
+ChunkName(char const*)
+DestroyAndFreeResourceImage(void)
+WriteOrder(char const*)
+UnpatchTextures(void)
+IsChunked(int)
+SaveResourceImage(void)
+LoadResourceImage(void)
+SaveResource(RslNode *,base::cRelocatableChunkWriter &)
+SaveResource(RslTAnimTree *,base::cRelocatableChunkWriter &)
+SaveResource(RslSkin *,base::cRelocatableChunkWriter &)
+SaveResource(CAnimBlendTree *,base::cRelocatableChunkWriter &)
+PatchElementTextures(RslElement *)
+PatchElementGroupTextures(RslElementGroup *)
+*/
+
+void LoadResource(RpAtomic *atomic);
+void LoadResource(RpClump *clump);
+
+/*
+cRelocatableChunkWriterGTA::Save(char const*,uint,uint,bool)
+cRelocatableChunkGTA::cRelocatableChunkGTA(char const*,uint,uint,bool)
+SaveAnimBlock(int)
+SaveModel(int,bool)
+*/
+
+void SaveResource(RwTexture *tex, base::cRelocatableChunkWriter &writer);
+void SaveResource(RwTexDictionary *txd, base::cRelocatableChunkWriter &writer);
+void SaveResource(RpMaterial *mat, base::cRelocatableChunkWriter &writer);
+void SaveResource(RpMaterialList *matlist, base::cRelocatableChunkWriter &writer);
+void SaveResource(RpGeometry *geo, base::cRelocatableChunkWriter &writer);
+void SaveResource(RpAtomic *atomic, base::cRelocatableChunkWriter &writer);
+void SaveResource(RpClump *clump, base::cRelocatableChunkWriter &writer);
diff --git a/src/core/main.cpp b/src/core/main.cpp
index dc75daf8..824255f6 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -85,6 +85,9 @@ wchar gUString2[256];
// leeds
bool gMakeResources = true;
bool gUseChunkFiles = false;
+bool gSecondExportPass;
+bool gUseModelResources;
+bool gUseResources;
float FramesPerSecond = 30.0f;
diff --git a/src/core/main.h b/src/core/main.h
index 38dce115..98813470 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -27,6 +27,9 @@ extern bool gbPrintMemoryUsage;
// leeds
extern bool gMakeResources;
extern bool gUseChunkFiles;
+extern bool gSecondExportPass;
+extern bool gUseModelResources;
+extern bool gUseResources;
class CSprite2d;
diff --git a/src/extras/custompipes_d3d9.cpp b/src/extras/custompipes_d3d9.cpp
index 68337fb6..cb5fcadc 100644
--- a/src/extras/custompipes_d3d9.cpp
+++ b/src/extras/custompipes_d3d9.cpp
@@ -22,7 +22,8 @@
#error "Need librw for EXTENDED_PIPELINES"
#endif
-extern RwTexture *gpWhiteTexture; // from vehicle model info
+//extern RwTexture *gpWhiteTexture; // from vehicle model info
+static RwTexture *gpWhiteTexture; // nil works as white in librw currently
namespace CustomPipes {
diff --git a/src/fakerw/rpworld.h b/src/fakerw/rpworld.h
index f10a3754..8e3b09f0 100644
--- a/src/fakerw/rpworld.h
+++ b/src/fakerw/rpworld.h
@@ -13,6 +13,7 @@
//struct RpMaterial;
typedef rw::Material RpMaterial;
+typedef rw::MaterialList RpMaterialList;
typedef RpMaterial *(*RpMaterialCallBack)(RpMaterial *material, void *data);
diff --git a/src/leeds/base/relocatableChunk.h b/src/leeds/base/relocatableChunk.h
index ea910240..2658aa21 100644
--- a/src/leeds/base/relocatableChunk.h
+++ b/src/leeds/base/relocatableChunk.h
@@ -19,6 +19,8 @@ namespace base
void* Shrink(void* data);
};
+#define VTABLE_ADDR(obj) ((void*)obj) // TODO: make this portable
+
class cRelocatableChunkClassInfo
{
public:
diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp
index fd13dfb5..ffd934ba 100644
--- a/src/modelinfo/BaseModelInfo.cpp
+++ b/src/modelinfo/BaseModelInfo.cpp
@@ -7,6 +7,9 @@
#include "BaseModelInfo.h"
#include "ModelInfo.h"
#include "KeyGen.h"
+#include "Streaming.h"
+#include "smallHeap.h"
+#include "TempColModels.h"
CBaseModelInfo::CBaseModelInfo(ModelInfoType type)
{
@@ -18,7 +21,11 @@ CBaseModelInfo::CBaseModelInfo(ModelInfoType type)
m_type = type;
m_num2dEffects = 0;
m_bOwnsColModel = false;
+ m_nameKey = 0;
+ m_unk1 = 0;
+ m_unk2 = 0;
m_name = new char[MAX_MODEL_NAME];
+ *(int32*)m_name = 0;
}
void
@@ -26,6 +33,7 @@ CBaseModelInfo::Shutdown(void)
{
DeleteCollisionModel();
DeleteRwObject();
+ DeleteChunk();
m_2dEffectsID = -1;
m_num2dEffects = 0;
m_txdSlot = -1;
@@ -34,11 +42,11 @@ CBaseModelInfo::Shutdown(void)
void
CBaseModelInfo::DeleteCollisionModel(void)
{
- if(m_colModel && m_bOwnsColModel){
+ if(!gUseChunkFiles && m_colModel && m_bOwnsColModel){
if(m_colModel)
delete m_colModel;
- m_colModel = nil;
}
+ m_colModel = nil;
}
void
@@ -51,15 +59,17 @@ CBaseModelInfo::AddRef(void)
void
CBaseModelInfo::RemoveRef(void)
{
- m_refCount--;
- RemoveTexDictionaryRef();
+ if(m_refCount > 0){
+ m_refCount--;
+ RemoveTexDictionaryRef();
+ }
}
void
CBaseModelInfo::SetTexDictionary(const char *name)
{
int slot = CTxdStore::FindTxdSlot(name);
- if(slot < 0)
+ if(slot == -1)
slot = CTxdStore::AddTxdSlot(name);
m_txdSlot = slot;
}
@@ -71,12 +81,24 @@ CBaseModelInfo::AddTexDictionaryRef(void)
}
void
+CBaseModelInfo::AddTexDictionaryRefGu(void)
+{
+ CTxdStore::AddRefGu(m_txdSlot);
+}
+
+void
CBaseModelInfo::RemoveTexDictionaryRef(void)
{
CTxdStore::RemoveRef(m_txdSlot);
}
void
+CBaseModelInfo::RemoveTexDictionaryRefGu(void)
+{
+ CTxdStore::RemoveRefGu(m_txdSlot);
+}
+
+void
CBaseModelInfo::Init2dEffects(void)
{
m_2dEffectsID = -1;
@@ -110,4 +132,52 @@ CBaseModelInfo::SetModelName(const char *name)
m_nameKey = CKeyGen::GetUppercaseKey(name);
if (!gUseChunkFiles)
strcpy(m_name, name);
-} \ No newline at end of file
+}
+
+void
+CBaseModelInfo::DeleteChunk(void)
+{
+ // BUG? what if we're not using chunks?
+ if(m_chunk){
+ CStreaming::UnregisterPointer(&m_chunk, 2);
+ cSmallHeap::msInstance.Free(m_chunk);
+ m_chunk = nil;
+ }
+}
+
+inline int
+GetColmodelID(CColModel *model)
+{
+ int colModelid = 0;
+ if(model == &gpTempColModels->ms_colModelBBox) colModelid = 1;
+ if(model == &gpTempColModels->ms_colModelPed1) colModelid = 2;
+ if(model == &gpTempColModels->ms_colModelWeapon) colModelid = 3;
+ if(model == &CTempColModels::ms_colModelPed2) colModelid = 4;
+ if(model == &CTempColModels::ms_colModelPedGroundHit) colModelid = 5;
+ if(model == &CTempColModels::ms_colModelDoor1) colModelid = 6;
+ if(model == &CTempColModels::ms_colModelBumper1) colModelid = 7;
+ if(model == &CTempColModels::ms_colModelPanel1) colModelid = 8;
+ if(model == &CTempColModels::ms_colModelBonnet1) colModelid = 9;
+ if(model == &CTempColModels::ms_colModelBoot1) colModelid = 10;
+ if(model == &CTempColModels::ms_colModelWheel1) colModelid = 11;
+ if(model == &CTempColModels::ms_colModelBodyPart1) colModelid = 12;
+ if(model == &CTempColModels::ms_colModelBodyPart2) colModelid = 13;
+ if(model == &CTempColModels::ms_colModelCutObj[0]) colModelid = 14;
+ if(model == &CTempColModels::ms_colModelCutObj[1]) colModelid = 15;
+ if(model == &CTempColModels::ms_colModelCutObj[2]) colModelid = 16;
+ if(model == &CTempColModels::ms_colModelCutObj[3]) colModelid = 17;
+ if(model == &CTempColModels::ms_colModelCutObj[4]) colModelid = 18;
+ return colModelid;
+}
+
+void
+CBaseModelInfo::Write(base::cRelocatableChunkWriter &writer)
+{
+ m_chunk = nil;
+ RcWriteThis(writer);
+ if(m_colModel){
+ if(m_bOwnsColModel || GetColmodelID(m_colModel) != 0)
+ m_colModel->Write(writer, true);
+ writer.AddPatch(&m_colModel);
+ }
+}
diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h
index f3fddf20..c9ea13bb 100644
--- a/src/modelinfo/BaseModelInfo.h
+++ b/src/modelinfo/BaseModelInfo.h
@@ -2,7 +2,7 @@
struct CColModel;
-#define MAX_MODEL_NAME (21)
+#define MAX_MODEL_NAME (24)
enum ModelInfoType
{
@@ -23,9 +23,13 @@ class C2dEffect;
class CBaseModelInfo
{
protected:
- char *m_name;
+ uint32 m_unk1;
+ uint32 m_unk2;
uint32 m_nameKey;
- RwObject *m_object;
+ union {
+ char *m_name; // if not using chunks
+ void *m_chunk; // else
+ };
uint8 m_type;
uint8 m_num2dEffects;
bool m_bOwnsColModel;
@@ -53,6 +57,16 @@ public:
virtual void ConvertAnimFileIndex(void) {}
virtual int GetAnimFileIndex(void) { return -1; }
+ virtual void LoadModel(void *model, const void *chunk) = 0;
+ virtual void DeleteChunk(void);
+ // this writes the modelinfo struct, possibly including actual RW models
+ virtual void Write(base::cRelocatableChunkWriter &writer);
+ // this writes the RW models
+ virtual void *WriteModel(base::cRelocatableChunkWriter &writer) { return nil; } // = 0; // this is not in the vtable for some reason???
+ // these allocate the space for a modelinfo struct and patch the vtable pointer
+ virtual void RcWriteThis(base::cRelocatableChunkWriter &writer) = 0;
+ virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer) = 0;
+
// one day it becomes virtual
uint8 GetModelType() const { return m_type; }
bool IsBuilding(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME; }
@@ -74,7 +88,9 @@ public:
void RemoveRef(void);
void SetTexDictionary(const char *name);
void AddTexDictionaryRef(void);
+ void AddTexDictionaryRefGu(void);
void RemoveTexDictionaryRef(void);
+ void RemoveTexDictionaryRefGu(void);
void Init2dEffects(void);
void Add2dEffect(C2dEffect *fx);
C2dEffect *Get2dEffect(int n);
diff --git a/src/modelinfo/ClumpModelInfo.cpp b/src/modelinfo/ClumpModelInfo.cpp
index ba18bfa7..00c2c0fe 100644
--- a/src/modelinfo/ClumpModelInfo.cpp
+++ b/src/modelinfo/ClumpModelInfo.cpp
@@ -1,17 +1,30 @@
#include "common.h"
+#include "main.h"
#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
#include "AnimManager.h"
+#include "Streaming.h"
+#include "Leeds.h"
+
+base::cRelocatableChunkClassInfo CClumpModelInfo::msClassInfo("CElementGroupModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance)); // the real name
+CClumpModelInfo CClumpModelInfo::msClassInstance;
void
CClumpModelInfo::DeleteRwObject(void)
{
if(m_clump){
- RpClumpDestroy(m_clump);
+ if(!gUseChunkFiles)
+ RpClumpDestroy(m_clump);
+ else{
+ CStreaming::UnregisterClump(m_clump);
+ CStreaming::UnregisterPointer(&m_clump, 2);
+ DeleteChunk();
+ }
+
m_clump = nil;
RemoveTexDictionaryRef();
if(GetAnimFileIndex() != -1)
@@ -52,6 +65,7 @@ CClumpModelInfo::CreateInstance(RwMatrix *m)
if(m_clump){
RpClump *clump = (RpClump*)CreateInstance();
*RwFrameGetMatrix(RpClumpGetFrame(clump)) = *m;
+ CStreaming::RegisterInstance(clump);
return (RwObject*)clump;
}
return nil;
@@ -73,14 +87,15 @@ CClumpModelInfo::SetClump(RpClump *clump)
if(GetAnimFileIndex() != -1)
CAnimManager::AddAnimBlockRef(GetAnimFileIndex());
if(IsClumpSkinned(clump)){
- int i;
+ //int i;
RpHAnimHierarchy *hier;
- RpAtomic *skinAtomic;
- RpSkin *skin;
+ //RpAtomic *skinAtomic;
+ //RpSkin *skin;
hier = GetAnimHierarchyFromClump(clump);
assert(hier);
RpClumpForAllAtomics(clump, SetHierarchyForSkinAtomic, hier);
+/*
skinAtomic = GetFirstAtomic(clump);
assert(skinAtomic);
@@ -94,6 +109,7 @@ CClumpModelInfo::SetClump(RpClump *clump)
weights->w2 /= sum;
weights->w3 /= sum;
}
+*/
RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
}
}
@@ -203,3 +219,47 @@ CClumpModelInfo::GetFrameFromId(RpClump *clump, int32 id)
RwFrameForAllChildren(RpClumpGetFrame(clump), FindFrameFromIdCB, &assoc);
return assoc.frame;
}
+
+
+void
+CClumpModelInfo::LoadModel(void *clump, const void *chunk)
+{
+ m_chunk = (void*)chunk;
+ m_clump = (RpClump*)clump;
+ LoadResource(m_clump);
+ CStreaming::RegisterPointer(&m_chunk, 2, true);
+ CStreaming::RegisterClump(m_clump);
+ CStreaming::RegisterPointer(&m_clump, 2, true);
+}
+
+void
+CClumpModelInfo::Write(base::cRelocatableChunkWriter &writer)
+{
+ CBaseModelInfo::Write(writer);
+ if(m_clump){
+ writer.AddPatch(&m_clump);
+ SaveResource(m_clump, writer);
+ }
+}
+
+void*
+CClumpModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
+{
+ if(m_clump)
+ SaveResource(m_clump, writer);
+ return m_clump;
+}
+
+void
+CClumpModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
+
+void
+CClumpModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
diff --git a/src/modelinfo/ClumpModelInfo.h b/src/modelinfo/ClumpModelInfo.h
index 0113d340..b8507e5f 100644
--- a/src/modelinfo/ClumpModelInfo.h
+++ b/src/modelinfo/ClumpModelInfo.h
@@ -35,6 +35,9 @@ public:
char *m_animFileName;
};
+ static base::cRelocatableChunkClassInfo msClassInfo;
+ static CClumpModelInfo msClassInstance;
+
CClumpModelInfo(void) : CBaseModelInfo(MITYPE_CLUMP) { m_animFileIndex = -1; }
CClumpModelInfo(ModelInfoType id) : CBaseModelInfo(id) { m_animFileIndex = -1; }
~CClumpModelInfo() {}
@@ -48,6 +51,12 @@ public:
virtual void ConvertAnimFileIndex(void);
virtual int GetAnimFileIndex(void) { return m_animFileIndex; }
+ virtual void LoadModel(void *model, const void *chunk);
+ virtual void Write(base::cRelocatableChunkWriter &writer);
+ virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
+
static RpAtomic *SetAtomicRendererCB(RpAtomic *atomic, void *data);
void SetFrameIds(RwObjectNameIdAssocation *assocs);
static RwFrame *FindFrameFromNameCB(RwFrame *frame, void *data);
diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp
index 28de2507..1d519b10 100644
--- a/src/modelinfo/PedModelInfo.cpp
+++ b/src/modelinfo/PedModelInfo.cpp
@@ -1,5 +1,6 @@
#include "common.h"
+#include "main.h"
#include "RwHelper.h"
#include "General.h"
#include "Bones.h"
@@ -9,12 +10,19 @@
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
#include "custompipes.h"
+#include "Streaming.h"
+#include "Leeds.h"
+#include "TempColModels.h"
+
+base::cRelocatableChunkClassInfo CPedModelInfo::msClassInfo("CPedModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
+CPedModelInfo CPedModelInfo::msClassInstance;
void
CPedModelInfo::DeleteRwObject(void)
{
+ CStreaming::UnregisterPointer(&m_hitColModel, 2);
CClumpModelInfo::DeleteRwObject();
- if(m_hitColModel)
+ if(!gUseChunkFiles && m_hitColModel)
delete m_hitColModel;
m_hitColModel = nil;
}
@@ -41,13 +49,15 @@ CPedModelInfo::SetClump(RpClump *clump)
#ifdef EXTENDED_PIPELINES
CustomPipes::AttachRimPipe(clump);
#endif
+ if(!IsClumpSkinned(clump))
+ return;
CClumpModelInfo::SetClump(clump);
SetFrameIds(m_pPedIds); // not needed in VC actually
if(m_hitColModel == nil)
CreateHitColModelSkinned(clump);
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedCB);
- if(strcmp(GetModelName(), "player") == 0)
- RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
+ //if(strcmp(GetModelName(), "player") == 0)
+ // RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
}
struct ColNodeInfo
@@ -73,40 +83,27 @@ ColNodeInfo m_pColNodeInfos[NUMPEDINFONODES] = {
{ nil, PED_FOOTR, PEDPIECE_RIGHTLEG, 0.0f, 0.15f, 0.15f },
};
-void
+bool
CPedModelInfo::CreateHitColModelSkinned(RpClump *clump)
{
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
CColModel *colmodel = new CColModel;
CColSphere *spheres = (CColSphere*)RwMalloc(NUMPEDINFONODES*sizeof(CColSphere));
- RwFrame *root = RpClumpGetFrame(m_clump);
- RwMatrix *invmat = RwMatrixCreate();
- RwMatrix *mat = RwMatrixCreate();
- RwMatrixInvert(invmat, RwFrameGetMatrix(RpClumpGetFrame(clump)));
for(int i = 0; i < NUMPEDINFONODES; i++){
- *mat = *invmat;
- int id = ConvertPedNode2BoneTag(m_pColNodeInfos[i].pedNode); // this is wrong, wtf R* ???
- int idx = RpHAnimIDGetIndex(hier, id);
-
- // This doesn't really work as the positions are not initialized yet
- RwMatrixTransform(mat, &RpHAnimHierarchyGetMatrixArray(hier)[idx], rwCOMBINEPRECONCAT);
- RwV3d pos = { 0.0f, 0.0f, 0.0f };
- RwV3dTransformPoints(&pos, &pos, 1, mat);
-
- spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
+ spheres[i].center.x = 0.0f;
+ spheres[i].center.y = 0.0f;
+ spheres[i].center.z = 0.0f;
spheres[i].radius = m_pColNodeInfos[i].radius;
spheres[i].surface = SURFACE_PED;
spheres[i].piece = m_pColNodeInfos[i].pieceType;
}
- RwMatrixDestroy(invmat);
- RwMatrixDestroy(mat);
colmodel->spheres = spheres;
colmodel->numSpheres = NUMPEDINFONODES;
colmodel->boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
colmodel->boundingBox.Set(CVector(-0.5f, -0.5f, -1.2f), CVector(0.5f, 0.5f, 1.2f));
colmodel->level = LEVEL_GENERIC;
m_hitColModel = colmodel;
+ return true;
}
CColModel*
@@ -114,28 +111,27 @@ CPedModelInfo::AnimatePedColModelSkinned(RpClump *clump)
{
if(m_hitColModel == nil){
CreateHitColModelSkinned(clump);
+#ifndef FIX_BUGS
return m_hitColModel;
+#endif
+ // we should really animate this now
}
- RwMatrix *invmat, *mat;
+ RwMatrix invmat, mat;
CColSphere *spheres = m_hitColModel->spheres;
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(clump);
- invmat = RwMatrixCreate();
- mat = RwMatrixCreate();
- RwMatrixInvert(invmat, RwFrameGetMatrix(RpClumpGetFrame(clump)));
+ RwMatrixInvert(&invmat, RwFrameGetMatrix(RpClumpGetFrame(clump)));
for(int i = 0; i < NUMPEDINFONODES; i++){
- *mat = *invmat;
+ mat = invmat;
int id = ConvertPedNode2BoneTag(m_pColNodeInfos[i].pedNode);
int idx = RpHAnimIDGetIndex(hier, id);
- RwMatrixTransform(mat, &RpHAnimHierarchyGetMatrixArray(hier)[idx], rwCOMBINEPRECONCAT);
- RwV3d pos = { 0.0f, 0.0f, 0.0f };
- RwV3dTransformPoints(&pos, &pos, 1, mat);
+ RwMatrixTransform(&mat, &RpHAnimHierarchyGetMatrixArray(hier)[idx], rwCOMBINEPRECONCAT);
+ RwV3d pos = { 0.0f, 0.0f, 0.0f }; // actually CVector
+ RwV3dTransformPoints(&pos, &pos, 1, &mat);
spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
}
- RwMatrixDestroy(invmat);
- RwMatrixDestroy(mat);
return m_hitColModel;
}
@@ -153,10 +149,71 @@ CPedModelInfo::AnimatePedColModelSkinnedWorld(RpClump *clump)
int idx = RpHAnimIDGetIndex(hier, id);
mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- RwV3d pos = { 0.0f, 0.0f, 0.0f };
+ RwV3d pos = { 0.0f, 0.0f, 0.0f }; // actually CVector
RwV3dTransformPoints(&pos, &pos, 1, mat);
spheres[i].center = pos + CVector(m_pColNodeInfos[i].x, 0.0f, m_pColNodeInfos[i].z);
}
return m_hitColModel;
}
+
+
+struct PedChunk
+{
+ CColModel *colmodel;
+ RpClump *clump;
+};
+
+void
+CPedModelInfo::LoadModel(void *data, const void *chunk)
+{
+ PedChunk *chk = (PedChunk*)data;
+ m_hitColModel = chk->colmodel;
+ CStreaming::RegisterPointer(&m_hitColModel, 2, true);
+ CClumpModelInfo::LoadModel(chk->clump, chunk);
+}
+
+void
+CPedModelInfo::Write(base::cRelocatableChunkWriter &writer)
+{
+ SetColModel(&gpTempColModels->ms_colModelPed1);
+ CClumpModelInfo::Write(writer);
+ if(m_hitColModel){
+ writer.AddPatch(&m_hitColModel);
+ m_hitColModel->Write(writer, true);
+ }
+}
+
+void*
+CPedModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
+{
+ PedChunk *chunk = new PedChunk; // LEAK
+ chunk->colmodel = nil;
+ chunk->clump = nil;
+ writer.AllocateRaw(chunk, sizeof(*chunk), sizeof(void*), false, true);
+
+ chunk->clump = (RpClump*)CClumpModelInfo::WriteModel(writer);
+ if(chunk->clump)
+ writer.AddPatch(&chunk->clump);
+
+ chunk->colmodel = m_hitColModel;
+ if(chunk->colmodel){
+ writer.AddPatch(&chunk->colmodel);
+ chunk->colmodel->Write(writer, true);
+ }
+ return nil;
+}
+
+void
+CPedModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
+
+void
+CPedModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
diff --git a/src/modelinfo/PedModelInfo.h b/src/modelinfo/PedModelInfo.h
index 79bd7eaa..7baa2bd8 100644
--- a/src/modelinfo/PedModelInfo.h
+++ b/src/modelinfo/PedModelInfo.h
@@ -38,6 +38,8 @@ public:
CColModel *m_hitColModel;
int8 radio1, radio2;
+ static base::cRelocatableChunkClassInfo msClassInfo;
+ static CPedModelInfo msClassInstance;
static RwObjectNameIdAssocation m_pPedIds[PED_NODE_MAX];
CPedModelInfo(void) : CClumpModelInfo(MITYPE_PED) { m_hitColModel = nil; }
@@ -45,7 +47,13 @@ public:
void DeleteRwObject(void);
void SetClump(RpClump *);
- void CreateHitColModelSkinned(RpClump *clump);
+ virtual void LoadModel(void *model, const void *chunk);
+ virtual void Write(base::cRelocatableChunkWriter &writer);
+ virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
+
+ bool CreateHitColModelSkinned(RpClump *clump);
CColModel *GetHitColModel(void) { return m_hitColModel; }
CColModel *AnimatePedColModelSkinned(RpClump *clump);
CColModel *AnimatePedColModelSkinnedWorld(RpClump *clump);
diff --git a/src/modelinfo/SimpleModelInfo.cpp b/src/modelinfo/SimpleModelInfo.cpp
index 9ca4d292..1199c200 100644
--- a/src/modelinfo/SimpleModelInfo.cpp
+++ b/src/modelinfo/SimpleModelInfo.cpp
@@ -1,38 +1,60 @@
#include "common.h"
+#include "main.h"
#include "General.h"
+#include "Renderer.h"
#include "Camera.h"
#include "ModelInfo.h"
#include "AnimManager.h"
#include "custompipes.h"
+#include "Streaming.h"
+#include "smallHeap.h"
+#include "Leeds.h"
-#define LOD_DISTANCE (300.0f)
+TempIdeData m_sTempIdeData[800];
+
+base::cRelocatableChunkClassInfo CSimpleModelInfo::msClassInfo("CSimpleModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
+CSimpleModelInfo CSimpleModelInfo::msClassInstance;
void
CSimpleModelInfo::DeleteRwObject(void)
{
int i;
RwFrame *f;
- for(i = 0; i < m_numAtomics; i++)
- if(m_atomics[i]){
- f = RpAtomicGetFrame(m_atomics[i]);
- RpAtomicDestroy(m_atomics[i]);
- RwFrameDestroy(f);
- m_atomics[i] = nil;
- RemoveTexDictionaryRef();
- if(GetAnimFileIndex() != -1)
- CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
- }
+ if(m_atomics == nil)
+ return;
+ if(!gUseChunkFiles){
+ for(i = 0; i < m_numAtomics; i++)
+ if(m_atomics[i]){
+ f = RpAtomicGetFrame(m_atomics[i]);
+ RpAtomicDestroy(m_atomics[i]);
+ RwFrameDestroy(f);
+ m_atomics[i] = nil;
+ RemoveTexDictionaryRef();
+ if(GetAnimFileIndex() != -1)
+ CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
+ }
+ }else if(m_chunk){
+ CStreaming::UnregisterPointer(&m_atomics, 2);
+ for(i = 0; i < m_numAtomics; i++)
+ CStreaming::UnregisterAtomic(m_atomics[i], nil);
+ DeleteChunk();
+ RemoveTexDictionaryRef();
+ if(GetAnimFileIndex() != -1)
+ CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
+ }
+ m_atomics = nil;
}
RwObject*
CSimpleModelInfo::CreateInstance(void)
{
RpAtomic *atomic;
- if(m_atomics[0] == nil)
+ if(m_atomics && m_atomics[0] == nil)
return nil;
atomic = RpAtomicClone(m_atomics[0]);
RpAtomicSetFrame(atomic, RwFrameCreate());
+ CStreaming::RegisterInstance(atomic, nil);
return (RwObject*)atomic;
}
@@ -42,21 +64,20 @@ CSimpleModelInfo::CreateInstance(RwMatrix *matrix)
RpAtomic *atomic;
RwFrame *frame;
- if(m_atomics[0] == nil)
+ if(m_atomics && m_atomics[0] == nil)
return nil;
atomic = RpAtomicClone(m_atomics[0]);
frame = RwFrameCreate();
*RwFrameGetMatrix(frame) = *matrix;
RpAtomicSetFrame(atomic, frame);
+ CStreaming::RegisterInstance(atomic, nil);
return (RwObject*)atomic;
}
void
CSimpleModelInfo::Init(void)
{
- m_atomics[0] = nil;
- m_atomics[1] = nil;
- m_atomics[2] = nil;
+ m_atomics = new RpAtomic*[3];
m_numAtomics = 0;
m_firstDamaged = 0;
m_wetRoadReflection = 0;
@@ -72,21 +93,30 @@ CSimpleModelInfo::Init(void)
m_ignoreDrawDist = 0;
m_isCodeGlass = 0;
m_isArtistGlass = 0;
+ m_relatedModel = nil;
}
void
CSimpleModelInfo::SetAtomic(int n, RpAtomic *atomic)
{
- AddTexDictionaryRef();
+ if(m_atomics == nil){
+ m_atomics = new RpAtomic*[3];
+ m_atomics[0] = nil;
+ m_atomics[1] = nil;
+ m_atomics[2] = nil;
+ }
m_atomics[n] = atomic;
+ AddTexDictionaryRef();
if(GetAnimFileIndex() != -1)
CAnimManager::AddAnimBlockRef(GetAnimFileIndex());
RpGeometry *geo = RpAtomicGetGeometry(atomic);
if(m_ignoreLight)
RpGeometrySetFlags(geo, RpGeometryGetFlags(geo) & ~rpGEOMETRYLIGHT);
+/*
if(RpGeometryGetFlags(geo) & rpGEOMETRYNORMALS &&
RpGeometryGetNumTriangles(geo) > 200)
debug("%s has %d polys\n", m_name, RpGeometryGetNumTriangles(geo));
+*/
#ifdef EXTENDED_PIPELINES
if(m_wetRoadReflection)
@@ -137,6 +167,40 @@ CSimpleModelInfo::GetLargestLodDistance(void)
}
RpAtomic*
+CSimpleModelInfo::GetLodAtomic(int n)
+{
+ if(m_atomics == nil || n >= m_numAtomics)
+ return nil;
+ return m_atomics[n];
+}
+
+RpAtomic*
+CSimpleModelInfo::GetLastAtomic(void)
+{
+ if(m_atomics == nil)
+ return nil;
+ if(m_firstDamaged == 0 || m_isDamaged)
+ return m_atomics[m_numAtomics-1];
+ else
+ return m_atomics[m_firstDamaged-1];
+}
+
+RpAtomic*
+CSimpleModelInfo::GetLastAtomic(float dist)
+{
+ int n;
+ if(m_atomics == nil)
+ return nil;
+ if(m_firstDamaged == 0 || m_isDamaged)
+ n = m_numAtomics-1;
+ else
+ n = m_firstDamaged-1;
+ if(dist < m_lodDistances[n] * TheCamera.LODDistMultiplier)
+ return m_atomics[n];
+ return nil;
+}
+
+RpAtomic*
CSimpleModelInfo::GetAtomicFromDistance(float dist)
{
int i;
@@ -152,20 +216,40 @@ CSimpleModelInfo::GetAtomicFromDistance(float dist)
RpAtomic*
CSimpleModelInfo::GetFirstAtomicFromDistance(float dist)
{
+// HACk until we figure out what's going on
+if(m_atomics == nil) return nil;
if(dist < m_lodDistances[0] * TheCamera.LODDistMultiplier)
return m_atomics[0];
return nil;
}
void
-CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID)
+CSimpleModelInfo::FindRelatedModel(void)
{
- int i;
CBaseModelInfo *mi;
- for(i = minID; i <= maxID; i++){
- mi = CModelInfo::GetModelInfo(i);
+ int thisIndex, otherIndex;
+
+ // find our own index in temp data
+ for(thisIndex = 0; thisIndex < ARRAY_SIZE(m_sTempIdeData); thisIndex++){
+ if(m_sTempIdeData[thisIndex].id == -1)
+ break;
+ if(this == CModelInfo::GetModelInfo(m_sTempIdeData[thisIndex].id))
+ goto found;
+ }
+ thisIndex = -1;
+found:
+#ifdef FIX_BUGS
+ if(thisIndex == -1)
+ return;
+#endif
+
+ for(otherIndex = 0; otherIndex < ARRAY_SIZE(m_sTempIdeData); otherIndex++){
+ if(m_sTempIdeData[otherIndex].id == -1)
+ break;
+
+ mi = CModelInfo::GetModelInfo(m_sTempIdeData[otherIndex].id);
if(mi && mi != this &&
- !CGeneral::faststrcmp(GetModelName()+3, mi->GetModelName()+3)){
+ !CGeneral::faststrcmp(m_sTempIdeData[thisIndex].name+3, m_sTempIdeData[otherIndex].name+3)){
assert(mi->IsSimple());
this->SetRelatedModel((CSimpleModelInfo*)mi);
return;
@@ -176,12 +260,14 @@ CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID)
#define NEAR_DRAW_DIST 100.0f // 0.0f in vice city
void
-CSimpleModelInfo::SetupBigBuilding(int32 minID, int32 maxID)
+CSimpleModelInfo::SetupBigBuilding(void)
{
CSimpleModelInfo *related;
- if(m_lodDistances[0] > LOD_DISTANCE && GetRelatedModel() == nil){
+ if(m_lodDistances[0] < 0.0f)
+ m_lodDistances[0] = -m_lodDistances[0]; // what?
+ else if(m_lodDistances[0] > LOD_DISTANCE && GetRelatedModel() == nil){
m_isBigBuilding = 1;
- FindRelatedModel(minID, maxID);
+ FindRelatedModel();
related = GetRelatedModel();
if(related){
m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier;
@@ -193,3 +279,79 @@ CSimpleModelInfo::SetupBigBuilding(int32 minID, int32 maxID)
m_lodDistances[2] = NEAR_DRAW_DIST;
}
}
+
+
+void
+CSimpleModelInfo::LoadModel(void *atomics, const void *chunk)
+{
+ int i;
+ m_chunk = (void*)chunk;
+ m_atomics = (RpAtomic**)atomics;
+ CStreaming::RegisterPointer(m_chunk, 2, true);
+ CStreaming::RegisterPointer(m_atomics, 2, true);
+ for(i = 0; i < m_numAtomics; i++){
+ LoadResource(m_atomics[i]);
+ CStreaming::RegisterAtomic(m_atomics[i], nil);
+ }
+}
+
+void
+CSimpleModelInfo::Write(base::cRelocatableChunkWriter &writer)
+{
+ CBaseModelInfo::Write(writer);
+ if(WriteModel(writer))
+ writer.AddPatch(&m_atomics);
+ else
+ m_atomics = nil;
+ if(m_isBigBuilding)
+ writer.AddPatch(&m_relatedModel);
+}
+
+void*
+CSimpleModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
+{
+ int i;
+ if(m_atomics == nil || m_atomics[0] == nil)
+ return nil;
+
+ // remove empty atomics
+ int numAtomics = 0;
+ for(i = 0; i < m_numAtomics; i++)
+ if(m_atomics[i]){
+ m_atomics[numAtomics] = m_atomics[i];
+#ifdef FIX_BUGS
+ m_lodDistances[numAtomics] = m_lodDistances[i];
+#endif
+ numAtomics++;
+ }
+ if(m_firstDamaged){
+ int firstDam = m_firstDamaged - m_numAtomics + numAtomics;
+ if(firstDam < numAtomics)
+ m_firstDamaged = firstDam;
+ else
+ m_firstDamaged = 0;
+ }
+ m_numAtomics = numAtomics;
+
+ // write the actual models
+ writer.AllocateRaw(m_atomics, m_numAtomics*sizeof(void*), sizeof(void*), false, true);
+ for(i = 0; m_numAtomics; i++){
+ writer.AddPatch(&m_atomics[i]);
+ SaveResource(m_atomics[i], writer);
+ }
+ return m_atomics;
+}
+
+void
+CSimpleModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), 0x10, false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
+
+void
+CSimpleModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), 0x10, false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
diff --git a/src/modelinfo/SimpleModelInfo.h b/src/modelinfo/SimpleModelInfo.h
index 986cb886..f9191944 100644
--- a/src/modelinfo/SimpleModelInfo.h
+++ b/src/modelinfo/SimpleModelInfo.h
@@ -2,11 +2,18 @@
#include "BaseModelInfo.h"
+// For linking up models by name
+struct TempIdeData
+{
+ char name[24];
+ int16 id;
+};
+extern TempIdeData m_sTempIdeData[800];
+
class CSimpleModelInfo : public CBaseModelInfo
{
public:
- // atomics[2] is often a pointer to the non-LOD modelinfo
- RpAtomic *m_atomics[3];
+ RpAtomic **m_atomics;
// m_lodDistances[2] holds the near distance for LODs
float m_lodDistances[3];
uint8 m_numAtomics;
@@ -31,15 +38,26 @@ public:
uint16 m_isCodeGlass : 1;
uint16 m_isArtistGlass : 1;
+ CSimpleModelInfo *m_relatedModel;
+
+ static base::cRelocatableChunkClassInfo msClassInfo;
+ static CSimpleModelInfo msClassInstance;
+
CSimpleModelInfo(void) : CBaseModelInfo(MITYPE_SIMPLE) {}
CSimpleModelInfo(ModelInfoType id) : CBaseModelInfo(id) {}
~CSimpleModelInfo() {}
void DeleteRwObject(void);
RwObject *CreateInstance(void);
RwObject *CreateInstance(RwMatrix *);
- RwObject *GetRwObject(void) { return (RwObject*)m_atomics[0]; }
+ RwObject *GetRwObject(void) { return m_atomics ? (RwObject*)m_atomics[0] : nil; }
+
+ virtual void LoadModel(void *atomics, const void *chunk);
+ virtual void Write(base::cRelocatableChunkWriter &writer);
+ virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
- virtual void SetAtomic(int n, RpAtomic *atomic);
+ /*virtual*/ void SetAtomic(int n, RpAtomic *atomic);
void Init(void);
void IncreaseAlpha(void);
@@ -47,15 +65,18 @@ public:
float GetLodDistance(int i);
float GetNearDistance(void);
float GetLargestLodDistance(void);
+ RpAtomic *GetLodAtomic(int n);
+ RpAtomic *GetLastAtomic(void);
+ RpAtomic *GetLastAtomic(float dist);
RpAtomic *GetAtomicFromDistance(float dist);
RpAtomic *GetFirstAtomicFromDistance(float dist);
- void FindRelatedModel(int32 minID, int32 maxID);
- void SetupBigBuilding(int32 minID, int32 maxID);
+ void FindRelatedModel(void);
+ void SetupBigBuilding(void);
void SetNumAtomics(int n) { m_numAtomics = n; }
CSimpleModelInfo *GetRelatedModel(void){
- return (CSimpleModelInfo*)m_atomics[2]; }
+ return m_relatedModel; }
void SetRelatedModel(CSimpleModelInfo *m){
- m_atomics[2] = (RpAtomic*)m; }
+ m_relatedModel = m; }
};
//static_assert(sizeof(CSimpleModelInfo) == 0x4C, "CSimpleModelInfo: error");
diff --git a/src/modelinfo/TimeModelInfo.cpp b/src/modelinfo/TimeModelInfo.cpp
index 0db5fb78..85b59e43 100644
--- a/src/modelinfo/TimeModelInfo.cpp
+++ b/src/modelinfo/TimeModelInfo.cpp
@@ -3,15 +3,20 @@
#include "Camera.h"
#include "ModelInfo.h"
#include "General.h"
+#include "KeyGen.h"
+
+base::cRelocatableChunkClassInfo CTimeModelInfo::msClassInfo("CTimeModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
+CTimeModelInfo CTimeModelInfo::msClassInstance;
+
CTimeModelInfo*
-CTimeModelInfo::FindOtherTimeModel(void)
+CTimeModelInfo::FindOtherTimeModel(const char *modelname)
{
char name[40];
char *p;
int i;
- strcpy(name, GetModelName());
+ strcpy(name, modelname);
// change _nt to _dy
if(p = strstr(name, "_nt"))
strncpy(p, "_dy", 4);
@@ -21,13 +26,29 @@ CTimeModelInfo::FindOtherTimeModel(void)
else
return nil;
+ uint32 nameKey = CKeyGen::GetUppercaseKey(name);
+
for(i = 0; i < MODELINFOSIZE; i++){
CBaseModelInfo *mi = CModelInfo::GetModelInfo(i);
- if (mi && mi->GetModelType() == MITYPE_TIME &&
- !CGeneral::faststrncmp(name, mi->GetModelName(), MAX_MODEL_NAME)){
+ if (mi && mi->GetModelType() == MITYPE_TIME && nameKey == mi->GetNameHashKey()){
m_otherTimeModelID = i;
return (CTimeModelInfo*)mi;
}
}
return nil;
}
+
+
+void
+CTimeModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
+
+void
+CTimeModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
diff --git a/src/modelinfo/TimeModelInfo.h b/src/modelinfo/TimeModelInfo.h
index 6e3c64fb..67273b21 100644
--- a/src/modelinfo/TimeModelInfo.h
+++ b/src/modelinfo/TimeModelInfo.h
@@ -7,14 +7,21 @@ class CTimeModelInfo : public CSimpleModelInfo
int32 m_timeOn;
int32 m_timeOff;
int32 m_otherTimeModelID;
+
+ static base::cRelocatableChunkClassInfo msClassInfo;
+ static CTimeModelInfo msClassInstance;
+
public:
CTimeModelInfo(void) : CSimpleModelInfo(MITYPE_TIME) { m_otherTimeModelID = -1; }
+ virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
+
int32 GetTimeOn(void) { return m_timeOn; }
int32 GetTimeOff(void) { return m_timeOff; }
void SetTimes(int32 on, int32 off) { m_timeOn = on; m_timeOff = off; }
int32 GetOtherTimeModel(void) { return m_otherTimeModelID; }
void SetOtherTimeModel(int32 other) { m_otherTimeModelID = other; }
- CTimeModelInfo *FindOtherTimeModel(void);
+ CTimeModelInfo *FindOtherTimeModel(const char *name);
};
//static_assert(sizeof(CTimeModelInfo) == 0x58, "CTimeModelInfo: error");
diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp
index 4fc455de..bc29d649 100644
--- a/src/modelinfo/VehicleModelInfo.cpp
+++ b/src/modelinfo/VehicleModelInfo.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include <rpmatfx.h>
+#include "main.h"
#include "RwHelper.h"
#include "General.h"
#include "NodeName.h"
@@ -20,14 +21,21 @@
#include "ModelIndices.h"
#include "ModelInfo.h"
#include "custompipes.h"
+#include "Streaming.h"
+#include "Leeds.h"
-int8 CVehicleModelInfo::ms_compsToUse[2] = { -2, -2 };
-int8 CVehicleModelInfo::ms_compsUsed[2];
-RwRGBA CVehicleModelInfo::ms_vehicleColourTable[256];
-RwTexture *CVehicleModelInfo::ms_colourTextureTable[256];
+base::cRelocatableChunkClassInfo CVehicleModelInfo::msClassInfo("CVehicleModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
+CVehicleModelInfo CVehicleModelInfo::msClassInstance;
-RwTexture *gpWhiteTexture;
-RwFrame *pMatFxIdentityFrame;
+//int8 CVehicleModelInfo::ms_compsToUse[2] = { -2, -2 };
+//int8 CVehicleModelInfo::ms_compsUsed[2];
+//RwRGBA CVehicleModelInfo::ms_vehicleColourTable[256];
+CVehicleModelInfo::Statics *CVehicleModelInfo::mspInfo;
+
+//RwTexture *CVehicleModelInfo::ms_colourTextureTable[256];
+
+//RwTexture *gpWhiteTexture;
+//RwFrame *pMatFxIdentityFrame;
enum {
VEHICLE_FLAG_COLLAPSE = 0x2,
@@ -168,6 +176,29 @@ RwObjectNameIdAssocation *CVehicleModelInfo::ms_vehicleDescs[] = {
bool gbBlackCars;
bool gbPinkCars;
+void
+CVehicleModelInfo::Load(void *inst)
+{
+ if(inst)
+ mspInfo = (CVehicleModelInfo::Statics*)inst;
+ else{
+ mspInfo = new CVehicleModelInfo::Statics;
+ memset(mspInfo, 0, sizeof(*mspInfo));
+ mspInfo->ms_compsToUse[0] = -2;
+ mspInfo->ms_compsToUse[1] = -2;
+ }
+}
+
+void*
+CVehicleModelInfo::WriteStaticInfo(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(mspInfo, sizeof(*mspInfo), sizeof(void*), false, true);
+ if(mspInfo->unknown)
+ writer.AddPatch(&mspInfo->unknown);
+ return mspInfo;
+
+}
+
CVehicleModelInfo::CVehicleModelInfo(void)
: CClumpModelInfo(MITYPE_VEHICLE)
{
@@ -178,7 +209,12 @@ CVehicleModelInfo::CVehicleModelInfo(void)
m_positions[i].z = 0.0f;
}
m_numColours = 0;
+ CClumpModelInfo::m_animFileIndex = -1;
+
+ memset(m_materials1, 0, sizeof(m_materials1));
+ memset(m_materials2, 0, sizeof(m_materials2));
m_animFileIndex = -1;
+ m_normalSplay = 0.3f;
}
void
@@ -187,16 +223,74 @@ CVehicleModelInfo::DeleteRwObject(void)
int32 i;
RwFrame *f;
- for(i = 0; i < m_numComps; i++){
- f = RpAtomicGetFrame(m_comps[i]);
- RpAtomicDestroy(m_comps[i]);
- RwFrameDestroy(f);
+ if(!gUseChunkFiles){
+ for(i = 0; i < m_numComps; i++){
+ f = RpAtomicGetFrame(m_comps[i]);
+ RpAtomicDestroy(m_comps[i]);
+ RwFrameDestroy(f);
+ }
+#ifdef FIX_BUGS
+ delete[] m_comps;
+ m_comps = nil;
+#endif
+ m_numComps = 0;
}
- m_numComps = 0;
+
+ RemoveWheels();
+
+ for(i = 0; i < ARRAY_SIZE(m_materials1); i++)
+ CStreaming::UnregisterPointer(&m_materials1[i], 2);
+ for(i = 0; i < ARRAY_SIZE(m_materials2); i++)
+ CStreaming::UnregisterPointer(&m_materials2[i], 2);
+
+ if(m_numComps > 0){
+ CStreaming::UnregisterPointer(&m_comps, 2);
+ for(i = 0; i < m_numComps; i++)
+ CStreaming::UnregisterAtomic(m_comps[i], nil);
+ m_comps = nil;
+ }
+
CClumpModelInfo::DeleteRwObject();
}
RwObject*
+RemoveWheelCB(RwObject *object, void *arg)
+{
+ RpAtomic *atomic = (RpAtomic*)object;
+ if(RwObjectGetType(object) == rpATOMIC){
+ RpClumpRemoveAtomic((RpClump*)arg, atomic);
+#ifdef LIBRW
+ CStreaming::UnregisterPointer(&atomic->inClump.next, 2);
+ CStreaming::UnregisterPointer(&atomic->inClump.prev, 2);
+ CStreaming::UnregisterPointer(&atomic->object.object.parent, 2);
+ CStreaming::UnregisterPointer(&atomic->object.inFrame.next, 2);
+ CStreaming::UnregisterPointer(&atomic->object.inFrame.prev, 2);
+ CStreaming::UnregisterPointer(&atomic->clump, 2);
+#endif
+ RpAtomicDestroy(atomic);
+ }
+ return object;
+}
+
+void
+CVehicleModelInfo::RemoveWheels(void)
+{
+ RwObjectNameIdAssocation *desc = ms_vehicleDescs[m_vehicleType];
+ for(int i = 0; desc[i].name; i++){
+ RwObjectIdAssociation assoc;
+
+ if(desc[i].flags & (VEHICLE_FLAG_COMP|VEHICLE_FLAG_POS))
+ continue;
+ assoc.frame = nil;
+ assoc.id = desc[i].hierId;
+ RwFrameForAllChildren(RpClumpGetFrame(m_clump),
+ FindFrameFromIdCB, &assoc);
+ if(assoc.frame && desc[i].flags & VEHICLE_FLAG_ADD_WHEEL && m_wheelId != -1)
+ RwFrameForAllObjects(assoc.frame, RemoveWheelCB, m_clump);
+ }
+}
+
+RwObject*
CVehicleModelInfo::CreateInstance(void)
{
RpClump *clump;
@@ -205,7 +299,7 @@ CVehicleModelInfo::CreateInstance(void)
int32 comp1, comp2;
clump = (RpClump*)CClumpModelInfo::CreateInstance();
- if(m_numComps != 0){
+ if(clump && m_numComps != 0 && strcmp(m_gameName, "POLICAR") != 0){
clumpframe = RpClumpGetFrame(clump);
comp1 = ChooseComponent();
@@ -219,7 +313,7 @@ CVehicleModelInfo::CreateInstance(void)
RpClumpAddAtomic(clump, atomic);
RwFrameAddChild(clumpframe, f);
}
- ms_compsUsed[0] = comp1;
+ mspInfo->ms_compsUsed[0] = comp1;
comp2 = ChooseSecondComponent();
if(comp2 != -1 && m_comps[comp2]){
@@ -232,18 +326,27 @@ CVehicleModelInfo::CreateInstance(void)
RpClumpAddAtomic(clump, atomic);
RwFrameAddChild(clumpframe, f);
}
- ms_compsUsed[1] = comp2;
+ mspInfo->ms_compsUsed[1] = comp2;
}else{
- ms_compsUsed[0] = -1;
- ms_compsUsed[1] = -1;
+ mspInfo->ms_compsUsed[0] = -1;
+ mspInfo->ms_compsUsed[1] = -1;
}
+ CStreaming::RegisterInstance(clump);
return (RwObject*)clump;
}
+RpAtomic*
+SplayNormals(RpAtomic *atomic, void *arg)
+{
+ // PSP only?
+ return atomic;
+}
+
void
CVehicleModelInfo::SetClump(RpClump *clump)
{
CClumpModelInfo::SetClump(clump);
+ RpClumpForAllAtomics((RpClump*)GetRwObject(), SplayNormals, this);
SetAtomicRenderCallbacks();
SetFrameIds(ms_vehicleDescs[m_vehicleType]);
PreprocessHierarchy();
@@ -339,7 +442,7 @@ CVehicleModelInfo::SetAtomicRendererCB(RpAtomic *atomic, void *data)
}else if(strstr(name, "_lo")){
RpClumpRemoveAtomic(clump, atomic);
RpAtomicDestroy(atomic);
- return atomic; // BUG: not done by gta
+ return atomic; // BUG: nil in gta
}else if(strstr(name, "_vlo"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB);
else
@@ -398,6 +501,33 @@ CVehicleModelInfo::SetAtomicRendererCB_Train(RpAtomic *atomic, void *data)
}
RpAtomic*
+CVehicleModelInfo::SetAtomicRendererCB_Ferry(RpAtomic *atomic, void *data)
+{
+ char *name;
+ bool alpha;
+
+ name = GetFrameNodeName(RpAtomicGetFrame(atomic));
+ alpha = false;
+ RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha);
+ if(strstr(name, "_hi")){
+ if(alpha)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderTrainHiDetailAlphaCB);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderTrainHiDetailCB);
+ }else if(strstr(name, "_lo")){
+ if(alpha)
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle);
+ }else if(strstr(name, "_vlo"))
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+ HideDamagedAtomicCB(atomic, nil);
+ return atomic;
+}
+
+RpAtomic*
CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
{
RpClump *clump;
@@ -414,7 +544,31 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
RpAtomicDestroy(atomic);
return atomic; // BUG: not done by gta
}else if(strstr(name, "_vlo"))
- CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLoDetailCB_Boat);
+ else
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
+ HideDamagedAtomicCB(atomic, nil);
+ return atomic;
+}
+
+RpAtomic*
+CVehicleModelInfo::SetAtomicRendererCB_Boat_Far(RpAtomic *atomic, void *data)
+{
+ RpClump *clump;
+ char *name;
+
+ clump = (RpClump*)data;
+ name = GetFrameNodeName(RpAtomicGetFrame(atomic));
+ if(strcmp(name, "boat_hi") == 0 || !CGeneral::faststrncmp(name, "extra", 5))
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat_Far);
+ else if(strstr(name, "_hi"))
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB);
+ else if(strstr(name, "_lo")){
+ RpClumpRemoveAtomic(clump, atomic);
+ RpAtomicDestroy(atomic);
+ return atomic; // BUG: not done by gta
+ }else if(strstr(name, "_vlo"))
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleLoDetailCB_Boat_Far);
else
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
HideDamagedAtomicCB(atomic, nil);
@@ -424,6 +578,7 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
RpAtomic*
CVehicleModelInfo::SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data)
{
+/* // LCS: gone, may be better to keep it though
char *name;
name = GetFrameNodeName(RpAtomicGetFrame(atomic));
@@ -432,6 +587,7 @@ CVehicleModelInfo::SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data)
else if(strncmp(name, "rearrotor", 9) == 0)
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleTailRotorAlphaCB);
else
+*/
CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil);
return atomic;
}
@@ -459,7 +615,7 @@ CVehicleModelInfo::SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data)
}else if(strstr(name, "_lo")){
RpClumpRemoveAtomic(clump, atomic);
RpAtomicDestroy(atomic);
- return atomic; // BUG: not done by gta
+ return atomic; // BUG: nil in gta
}else if(strstr(name, "_vlo"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleReallyLowDetailCB);
else
@@ -476,13 +632,18 @@ CVehicleModelInfo::SetAtomicRenderCallbacks(void)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Train, nil);
else
#endif
- if(m_vehicleType == VEHICLE_TYPE_HELI)
+ if(m_vehicleType == VEHICLE_TYPE_FERRY)
+ RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Ferry, nil);
+ else if(m_vehicleType == VEHICLE_TYPE_HELI)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Heli, nil);
else if(m_vehicleType == VEHICLE_TYPE_PLANE)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_BigVehicle, nil);
- else if(m_vehicleType == VEHICLE_TYPE_BOAT)
- RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat, m_clump);
- else if(mod_HandlingManager.GetHandlingData((tVehicleType)m_handlingId)->Flags & HANDLING_IS_HELI)
+ else if(m_vehicleType == VEHICLE_TYPE_BOAT){
+ if(strcmp(m_gameName, "REEFER") == 0)
+ RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat_Far, m_clump);
+ else
+ RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat, m_clump);
+ }else if(mod_HandlingManager.GetHandlingData((tVehicleType)m_handlingId)->Flags & HANDLING_IS_HELI)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_RealHeli, m_clump);
else
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, m_clump);
@@ -530,6 +691,8 @@ CVehicleModelInfo::PreprocessHierarchy(void)
m_numDoors = 0;
m_numComps = 0;
+ m_comps = new RpAtomic*[7];
+
for(i = 0; desc[i].name; i++){
RwObjectNameAssociation assoc;
@@ -587,21 +750,23 @@ CVehicleModelInfo::PreprocessHierarchy(void)
SetVehicleComponentFlags(assoc.frame, desc[i].flags);
- if(desc[i].flags & VEHICLE_FLAG_ADD_WHEEL){
- if(m_wheelId == -1)
- RwFrameDestroy(assoc.frame);
- else{
- RwV3d scale;
- atomic = (RpAtomic*)CModelInfo::GetModelInfo(m_wheelId)->CreateInstance();
- RwFrameDestroy(RpAtomicGetFrame(atomic));
- RpAtomicSetFrame(atomic, assoc.frame);
- RpClumpAddAtomic(m_clump, atomic);
- CVisibilityPlugins::SetAtomicRenderCallback(atomic,
- CVisibilityPlugins::RenderWheelAtomicCB);
- scale.x = m_wheelScale;
- scale.y = m_wheelScale;
- scale.z = m_wheelScale;
- RwFrameScale(assoc.frame, &scale, rwCOMBINEPRECONCAT);
+ if(!(gMakeResources && gUseResources)){
+ if(desc[i].flags & VEHICLE_FLAG_ADD_WHEEL){
+ if(m_wheelId == -1)
+ RwFrameDestroy(assoc.frame);
+ else{
+ RwV3d scale;
+ atomic = (RpAtomic*)CModelInfo::GetModelInfo(m_wheelId)->CreateInstance();
+ RwFrameDestroy(RpAtomicGetFrame(atomic));
+ RpAtomicSetFrame(atomic, assoc.frame);
+ RpClumpAddAtomic(m_clump, atomic);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic,
+ CVisibilityPlugins::RenderWheelAtomicCB);
+ scale.x = m_wheelScale;
+ scale.y = m_wheelScale;
+ scale.z = m_wheelScale;
+ RwFrameScale(assoc.frame, &scale, rwCOMBINEPRECONCAT);
+ }
}
}
}
@@ -629,9 +794,9 @@ CVehicleModelInfo::SetVehicleComponentFlags(RwFrame *frame, uint32 flags)
SETFLAGS(ATOMIC_FLAG_FRONT);
else if(flags & VEHICLE_FLAG_REAR && (handling->Flags & HANDLING_IS_VAN || (flags & (VEHICLE_FLAG_LEFT|VEHICLE_FLAG_RIGHT)) == 0))
SETFLAGS(ATOMIC_FLAG_REAR);
- if(flags & VEHICLE_FLAG_LEFT)
+ else if(flags & VEHICLE_FLAG_LEFT)
SETFLAGS(ATOMIC_FLAG_LEFT);
- if(flags & VEHICLE_FLAG_RIGHT)
+ else if(flags & VEHICLE_FLAG_RIGHT)
SETFLAGS(ATOMIC_FLAG_RIGHT);
if(flags & VEHICLE_FLAG_REARDOOR)
@@ -746,7 +911,7 @@ CVehicleModelInfo::ChooseComponent(void)
int32 n;
comp = -1;
- if(ms_compsToUse[0] == -2){
+ if(mspInfo->ms_compsToUse[0] == -2){
if(COMPRULE_RULE(m_compRules) && IsValidCompRule(COMPRULE_RULE(m_compRules)))
comp = ::ChooseComponent(COMPRULE_RULE(m_compRules), COMPRULE_COMPS(m_compRules));
else if(CGeneral::GetRandomNumberInRange(0, 3) < 2){
@@ -755,8 +920,8 @@ CVehicleModelInfo::ChooseComponent(void)
comp = comps[(int)CGeneral::GetRandomNumberInRange(0, n)];
}
}else{
- comp = ms_compsToUse[0];
- ms_compsToUse[0] = -2;
+ comp = mspInfo->ms_compsToUse[0];
+ mspInfo->ms_compsToUse[0] = -2;
}
return comp;
}
@@ -769,7 +934,7 @@ CVehicleModelInfo::ChooseSecondComponent(void)
int32 n;
comp = -1;
- if(ms_compsToUse[1] == -2){
+ if(mspInfo->ms_compsToUse[1] == -2){
if(COMPRULE2_RULE(m_compRules) && IsValidCompRule(COMPRULE2_RULE(m_compRules)))
comp = ::ChooseComponent(COMPRULE2_RULE(m_compRules), COMPRULE2_COMPS(m_compRules));
else if(COMPRULE_RULE(m_compRules) && IsValidCompRule(COMPRULE_RULE(m_compRules)) &&
@@ -780,8 +945,8 @@ CVehicleModelInfo::ChooseSecondComponent(void)
comp = comps[(int)CGeneral::GetRandomNumberInRange(0, n)];
}
}else{
- comp = ms_compsToUse[1];
- ms_compsToUse[1] = -2;
+ comp = mspInfo->ms_compsToUse[1];
+ mspInfo->ms_compsToUse[1] = -2;
}
return comp;
}
@@ -796,7 +961,7 @@ struct editableMatCBData
RpMaterial*
CVehicleModelInfo::GetEditableMaterialListCB(RpMaterial *material, void *data)
{
- static RwRGBA white = { 255, 255, 255, 255 };
+ RwRGBA white = { 255, 255, 255, 255 };
const RwRGBA *col;
editableMatCBData *cbdata;
@@ -849,7 +1014,7 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
RpMaterial **matp;
if(c1 != m_currentColour1){
- col = ms_vehicleColourTable[c1];
+ col = mspInfo->ms_vehicleColourTable[c1];
for(matp = m_materials1; *matp; matp++){
colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red;
@@ -860,7 +1025,7 @@ CVehicleModelInfo::SetVehicleColour(uint8 c1, uint8 c2)
}
if(c2 != m_currentColour2){
- col = ms_vehicleColourTable[c2];
+ col = mspInfo->ms_vehicleColourTable[c2];
for(matp = m_materials2; *matp; matp++){
colp = (RwRGBA*)RpMaterialGetColor(*matp); // get rid of const
colp->red = col.red;
@@ -985,8 +1150,8 @@ CVehicleModelInfo::LoadVehicleColours(void)
fd = CFileMgr::OpenFile("CARCOLS.DAT", "r");
CFileMgr::ChangeDir("\\");
- for(i = 0; i < 256; i++)
- ms_colourTextureTable[i] = nil;
+ //for(i = 0; i < 256; i++)
+ // ms_colourTextureTable[i] = nil;
section = 0;
numCols = 0;
@@ -1018,10 +1183,10 @@ CVehicleModelInfo::LoadVehicleColours(void)
}else if(section == COLOURS){
sscanf(&line[start], // BUG: games doesn't add start
"%d %d %d", &r, &g, &b);
- ms_vehicleColourTable[numCols].red = r;
- ms_vehicleColourTable[numCols].green = g;
- ms_vehicleColourTable[numCols].blue = b;
- ms_vehicleColourTable[numCols].alpha = 0xFF;
+ mspInfo->ms_vehicleColourTable[numCols].red = r;
+ mspInfo->ms_vehicleColourTable[numCols].green = g;
+ mspInfo->ms_vehicleColourTable[numCols].blue = b;
+ mspInfo->ms_vehicleColourTable[numCols].alpha = 0xFF;
numCols++;
}else if(section == CARS){
n = sscanf(&line[start], // BUG: games doesn't add start
@@ -1051,6 +1216,7 @@ CVehicleModelInfo::LoadVehicleColours(void)
void
CVehicleModelInfo::DeleteVehicleColourTextures(void)
{
+/*
int i;
for(i = 0; i < 256; i++){
@@ -1059,6 +1225,7 @@ CVehicleModelInfo::DeleteVehicleColourTextures(void)
ms_colourTextureTable[i] = nil;
}
}
+*/
}
RpMaterial*
@@ -1070,6 +1237,7 @@ CVehicleModelInfo::GetMatFXEffectMaterialCB(RpMaterial *material, void *data)
return nil;
}
+/*
RpMaterial*
CVehicleModelInfo::SetDefaultEnvironmentMapCB(RpMaterial *material, void *data)
{
@@ -1086,7 +1254,9 @@ CVehicleModelInfo::SetDefaultEnvironmentMapCB(RpMaterial *material, void *data)
}
return material;
}
+*/
+/*
RpAtomic*
CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data)
{
@@ -1102,6 +1272,7 @@ CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data)
}
return atomic;
}
+*/
void
CVehicleModelInfo::SetEnvironmentMap(void)
@@ -1178,10 +1349,162 @@ CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(int id)
}
if(n == 0)
- return id == MI_RCBANDIT || id == MI_PIZZABOY || id == MI_BAGGAGE ? 0 : 1;
+ return id == MI_RCBANDIT /*|| id == MI_PIZZABOY || id == MI_BAGGAGE*/ ? 0 : 1;
if(id == MI_COACH)
return 8;
return n - 1;
}
+
+
+struct VehicleChunk
+{
+ RpClump *clump;
+ int32 numComps;
+ RpAtomic **comp;
+ RpMaterial *materials1[NUM_FIRST_MATERIALS];
+ RpMaterial *materials2[NUM_SECOND_MATERIALS];
+};
+
+void
+CVehicleModelInfo::LoadModel(void *data, const void *chunk)
+{
+ int i;
+ VehicleChunk *chk = (VehicleChunk*)data;
+ CClumpModelInfo::LoadModel(chk->clump, chunk);
+
+ // editable materials
+ for(i = 0; i < NUM_FIRST_MATERIALS; i++){
+ m_materials1[i] = chk->materials1[i];
+ if(m_materials1[i])
+ CStreaming::RegisterPointer(&m_materials1[i], 2, true);
+ }
+ for(i = 0; i < NUM_SECOND_MATERIALS; i++){
+ m_materials2[i] = chk->materials2[i];
+ if(m_materials2[i])
+ CStreaming::RegisterPointer(&m_materials2[i], 2, true);
+ }
+
+ // extra components
+ m_numComps = chk->numComps;
+ if(m_numComps > 0){
+ m_comps = chk->comp;
+ CStreaming::RegisterPointer(&m_comps, 2, true);
+ for(i = 0; i < m_numComps; i++){
+ LoadResource(m_comps[i]);
+ CStreaming::RegisterAtomic(m_comps[i], nil);
+ }
+ }else
+ m_comps = nil;
+
+ m_currentColour1 = -1;
+ m_currentColour2 = -1;
+
+ // add wheels
+ RwObjectNameIdAssocation *desc = ms_vehicleDescs[m_vehicleType];
+ for(i = 0; desc[i].name; i++){
+ RwObjectIdAssociation assoc;
+
+ if(desc[i].flags & (VEHICLE_FLAG_COMP|VEHICLE_FLAG_POS))
+ continue;
+ assoc.frame = nil;
+ assoc.id = desc[i].hierId;
+ RwFrameForAllChildren(RpClumpGetFrame(m_clump),
+ FindFrameFromIdCB, &assoc);
+ if(assoc.frame && desc[i].flags & VEHICLE_FLAG_ADD_WHEEL && m_wheelId != -1){
+ RwV3d scale;
+ RpAtomic *atomic = (RpAtomic*)CModelInfo::GetModelInfo(m_wheelId)->CreateInstance();
+ RwFrameDestroy(RpAtomicGetFrame(atomic));
+ RpAtomicSetFrame(atomic, assoc.frame);
+ RpClumpAddAtomic(m_clump, atomic);
+ CVisibilityPlugins::SetAtomicRenderCallback(atomic,
+ CVisibilityPlugins::RenderWheelAtomicCB);
+ scale.x = m_wheelScale;
+ scale.y = m_wheelScale;
+ scale.z = m_wheelScale;
+ RwFrameScale(assoc.frame, &scale, rwCOMBINEPRECONCAT);
+#ifdef LIBRW
+ CStreaming::RegisterPointer(&atomic->inClump.next, 2, true);
+ CStreaming::RegisterPointer(&atomic->inClump.prev, 2, true);
+ CStreaming::RegisterPointer(&atomic->object.object.parent, 2, true);
+ CStreaming::RegisterPointer(&atomic->object.inFrame.next, 2, true);
+ CStreaming::RegisterPointer(&atomic->object.inFrame.prev, 2, true);
+ CStreaming::RegisterPointer(&atomic->clump, 2, true);
+#endif
+ }
+ }
+}
+
+void
+CVehicleModelInfo::Write(base::cRelocatableChunkWriter &writer)
+{
+ CClumpModelInfo::Write(writer);
+}
+
+void*
+CVehicleModelInfo::WriteModel(base::cRelocatableChunkWriter &writer)
+{
+ if(GetRwObject() == nil)
+ return nil;
+
+ int i;
+ VehicleChunk *chk = new VehicleChunk;
+ memset(chk, 0, sizeof(*chk));
+ writer.AllocateRaw(chk, sizeof(*chk), sizeof(void*), false, true);
+
+ // clump
+ chk->clump = (RpClump*)CClumpModelInfo::WriteModel(writer);
+ if(chk->clump)
+ writer.AddPatch(&chk->clump);
+
+ // materials
+ for(i = 0; i < NUM_FIRST_MATERIALS; i++){
+ if(m_materials1[i] == nil || m_vehicleType == VEHICLE_TYPE_FERRY)
+ chk->materials1[i] = nil;
+ else{
+ SaveResource(m_materials1[i], writer);
+ chk->materials1[i] = m_materials1[i];
+ writer.AddPatch(&chk->materials1[i]);
+ }
+ }
+ for(i = 0; i < NUM_SECOND_MATERIALS; i++){
+ if(m_materials2[i] == nil || m_vehicleType == VEHICLE_TYPE_FERRY)
+ chk->materials2[i] = nil;
+ else{
+ SaveResource(m_materials2[i], writer);
+ chk->materials2[i] = m_materials2[i];
+ writer.AddPatch(&chk->materials2[i]);
+ }
+ }
+
+ // extra components
+ chk->numComps = m_numComps;
+ chk->comp = nil;
+ if(m_numComps > 0){
+ chk->comp = m_comps;
+ writer.AddPatch(&chk->comp);
+
+ writer.AllocateRaw(m_comps, m_numComps*sizeof(void*), sizeof(void*), false, true);
+ for(i = 0; i < m_numComps; i++)
+ if(m_comps[i]){
+ SaveResource(m_comps[i], writer);
+ writer.AddPatch(&m_comps[i]);
+ }
+ }
+ return chk;
+}
+
+void
+CVehicleModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
+
+void
+CVehicleModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h
index f9217a41..f979c2c0 100644
--- a/src/modelinfo/VehicleModelInfo.h
+++ b/src/modelinfo/VehicleModelInfo.h
@@ -98,19 +98,30 @@ public:
uint8 m_lastColorVariation;
uint8 m_currentColour1;
uint8 m_currentColour2;
- RpAtomic *m_comps[6]; // LCS(TODO): pointer
+ RpAtomic **m_comps;
+ float m_normalSplay;
// This is stupid, CClumpModelInfo already has it!
union {
int32 m_animFileIndex;
char *m_animFileName;
};
- static int8 ms_compsToUse[2];
- static int8 ms_compsUsed[2];
- static RwRGBA ms_vehicleColourTable[256];
- static RwTexture *ms_colourTextureTable[256];
+ static base::cRelocatableChunkClassInfo msClassInfo;
+ static CVehicleModelInfo msClassInstance;
+
+ struct Statics {
+ void *unknown; // unused too it seems
+ RwRGBA ms_vehicleColourTable[256];
+ int8 ms_compsUsed[2];
+ int8 ms_compsToUse[2];
+ };
+ //static RwTexture *ms_colourTextureTable[256];
+ static Statics *mspInfo;
static RwObjectNameIdAssocation *ms_vehicleDescs[NUM_VEHICLE_TYPES];
+ static void Load(void *inst);
+ static void *WriteStaticInfo(base::cRelocatableChunkWriter &writer);
+
CVehicleModelInfo(void);
void DeleteRwObject(void);
RwObject *CreateInstance(void);
@@ -119,6 +130,12 @@ public:
void ConvertAnimFileIndex(void);
int GetAnimFileIndex(void) { return m_animFileIndex; }
+ virtual void LoadModel(void *model, const void *chunk);
+ virtual void Write(base::cRelocatableChunkWriter &writer);
+ virtual void *WriteModel(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
+
static RwFrame *CollapseFramesCB(RwFrame *frame, void *data);
static RwObject *MoveObjectsCB(RwObject *object, void *data);
static RpAtomic *HideDamagedAtomicCB(RpAtomic *atomic, void *data);
@@ -128,13 +145,16 @@ public:
static RpAtomic *SetAtomicRendererCB(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_BigVehicle(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Train(RpAtomic *atomic, void *data);
+ static RpAtomic *SetAtomicRendererCB_Ferry(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data);
+ static RpAtomic *SetAtomicRendererCB_Boat_Far(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_Heli(RpAtomic *atomic, void *data);
static RpAtomic *SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data);
void SetAtomicRenderCallbacks(void);
static RwObject *SetAtomicFlagCB(RwObject *object, void *data);
static RwObject *ClearAtomicFlagCB(RwObject *atomic, void *data);
+ void RemoveWheels(void);
void SetVehicleComponentFlags(RwFrame *frame, uint32 flags);
void PreprocessHierarchy(void);
void GetWheelPosn(int32 n, CVector &pos);
@@ -160,7 +180,7 @@ public:
static void ShutdownEnvironmentMaps(void);
static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id);
- static void SetComponentsToUse(int8 c1, int8 c2) { ms_compsToUse[0] = c1; ms_compsToUse[1] = c2; }
+ static void SetComponentsToUse(int8 c1, int8 c2) { mspInfo->ms_compsToUse[0] = c1; mspInfo->ms_compsToUse[1] = c2; }
};
extern bool gbBlackCars;
diff --git a/src/modelinfo/WeaponModelInfo.cpp b/src/modelinfo/WeaponModelInfo.cpp
index d9294c3f..1d194ec4 100644
--- a/src/modelinfo/WeaponModelInfo.cpp
+++ b/src/modelinfo/WeaponModelInfo.cpp
@@ -4,6 +4,9 @@
#include "AnimManager.h"
#include "VisibilityPlugins.h"
+base::cRelocatableChunkClassInfo CWeaponModelInfo::msClassInfo("CWeaponModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance));
+CWeaponModelInfo CWeaponModelInfo::msClassInstance;
+
void
CWeaponModelInfo::SetAnimFile(const char *file)
{
@@ -35,19 +38,34 @@ CWeaponModelInfo::Init(void)
void
CWeaponModelInfo::SetWeaponInfo(int32 weaponId)
{
- m_atomics[2] = (RpAtomic*)weaponId;
+ m_relatedModel = (CSimpleModelInfo*)weaponId;
}
eWeaponType
CWeaponModelInfo::GetWeaponInfo(void)
{
- return (eWeaponType)(uintptr)m_atomics[2];
+ return (eWeaponType)(uintptr)m_relatedModel;
}
+/*
void
CWeaponModelInfo::SetAtomic(int n, RpAtomic *atomic)
{
CSimpleModelInfo::SetAtomic(n, atomic);
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderWeaponCB);
}
+*/
+
+void
+CWeaponModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
+void
+CWeaponModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer)
+{
+ writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true);
+ writer.Class(VTABLE_ADDR(this), msClassInfo);
+}
diff --git a/src/modelinfo/WeaponModelInfo.h b/src/modelinfo/WeaponModelInfo.h
index 548bf8a6..8dc9baf1 100644
--- a/src/modelinfo/WeaponModelInfo.h
+++ b/src/modelinfo/WeaponModelInfo.h
@@ -9,13 +9,21 @@ class CWeaponModelInfo : public CSimpleModelInfo
int32 m_animFileIndex;
char *m_animFileName;
};
+
+ static base::cRelocatableChunkClassInfo msClassInfo;
+ static CWeaponModelInfo msClassInstance;
+
public:
CWeaponModelInfo(void) : CSimpleModelInfo(MITYPE_WEAPON) { m_animFileIndex = -1; }
virtual void SetAnimFile(const char *file);
virtual void ConvertAnimFileIndex(void);
virtual int GetAnimFileIndex(void) { return m_animFileIndex; }
- virtual void SetAtomic(int n, RpAtomic *atomic);
+
+ virtual void RcWriteThis(base::cRelocatableChunkWriter &writer);
+ virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer);
+
+ //virtual void SetAtomic(int n, RpAtomic *atomic);
void Init(void);
void SetWeaponInfo(int32 weaponId);
diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp
index c50531c6..754c8778 100644
--- a/src/rw/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -455,6 +455,14 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic)
{
+ if(DistToCameraSq < ms_vehicleLod0Dist)
+ RENDERCALLBACK(atomic);
+ return atomic;
+}
+
+RpAtomic*
+CVisibilityPlugins::RenderVehicleHiDetailCB_Boat_Far(RpAtomic *atomic)
+{
if(DistToCameraSq < ms_bigVehicleLod1Dist)
RENDERCALLBACK(atomic);
return atomic;
@@ -474,6 +482,40 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic)
}
RpAtomic*
+CVisibilityPlugins::RenderVehicleLoDetailCB_Boat(RpAtomic *atomic)
+{
+ RpClump *clump;
+ int32 alpha;
+
+ clump = RpAtomicGetClump(atomic);
+ if(DistToCameraSq >= ms_vehicleLod0Dist){
+ alpha = GetClumpAlpha(clump);
+ if(alpha == 255)
+ RENDERCALLBACK(atomic);
+ else
+ RenderAlphaAtomic(atomic, alpha);
+ }
+ return atomic;
+}
+
+RpAtomic*
+CVisibilityPlugins::RenderVehicleLoDetailCB_Boat_Far(RpAtomic *atomic)
+{
+ RpClump *clump;
+ int32 alpha;
+
+ clump = RpAtomicGetClump(atomic);
+ if(DistToCameraSq >= ms_bigVehicleLod1Dist){
+ alpha = GetClumpAlpha(clump);
+ if(alpha == 255)
+ RENDERCALLBACK(atomic);
+ else
+ RenderAlphaAtomic(atomic, alpha);
+ }
+ return atomic;
+}
+
+RpAtomic*
CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic)
{
RwFrame *clumpframe;
diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h
index 13365c7a..f188096c 100644
--- a/src/rw/VisibilityPlugins.h
+++ b/src/rw/VisibilityPlugins.h
@@ -61,6 +61,9 @@ public:
static RpAtomic *RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailCB_Boat(RpAtomic *atomic);
static RpAtomic *RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic);
+ static RpAtomic *RenderVehicleHiDetailCB_Boat_Far(RpAtomic *atomic);
+ static RpAtomic *RenderVehicleLoDetailCB_Boat(RpAtomic *atomic);
+ static RpAtomic *RenderVehicleLoDetailCB_Boat_Far(RpAtomic *atomic);
static RpAtomic *RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic);
static RpAtomic *RenderVehicleReallyLowDetailCB(RpAtomic *atomic);
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index a4d9e5c3..6d6b4833 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -4174,7 +4174,7 @@ CAutomobile::dmgDrawCarCollidingParticles(const CVector &pos, float amount)
CGeneral::GetRandomNumberInRange(0.1f, 0.25f)),
nil,
CGeneral::GetRandomNumberInRange(0.02f, 0.08f),
- CVehicleModelInfo::ms_vehicleColourTable[m_currentColour1],
+ CVehicleModelInfo::mspInfo->ms_vehicleColourTable[m_currentColour1],
CGeneral::GetRandomNumberInRange(-40.0f, 40.0f),
0,
CGeneral::GetRandomNumberInRange(0.0f, 4.0f));
diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp
index 38550c38..0546888a 100644
--- a/src/vehicles/Heli.cpp
+++ b/src/vehicles/Heli.cpp
@@ -756,7 +756,7 @@ CHeli::InitHelis(void)
for(i = 0; i < NUM_HELIS; i++)
pHelis[i] = nil;
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1);
+ ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&gpTempColModels->ms_colModelPed1);
}
CHeli*
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index 1b4e7581..a3d07d5c 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -217,8 +217,8 @@ void
CVehicle::SetModelIndex(uint32 id)
{
CEntity::SetModelIndex(id);
- m_aExtras[0] = CVehicleModelInfo::ms_compsUsed[0];
- m_aExtras[1] = CVehicleModelInfo::ms_compsUsed[1];
+ m_aExtras[0] = CVehicleModelInfo::mspInfo->ms_compsUsed[0];
+ m_aExtras[1] = CVehicleModelInfo::mspInfo->ms_compsUsed[1];
m_nNumMaxPassengers = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(id);
}
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index 1d12e548..78d21b0a 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -513,7 +513,7 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
if ( SQR(victimPedRadius) > (victimPedPos-fireSource).MagnitudeSqr() )
{
CVector collisionDist;
- CColModel* victimPedCol = &CTempColModels::ms_colModelPed1;
+ CColModel* victimPedCol = &gpTempColModels->ms_colModelPed1;
bool useLocalPos = false;
if (victimPed->m_nPedState == PED_FALL
|| victimPed->m_nPedState == PED_DIE && victimPed->bIsPedDieAnimPlaying