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; } @@ -70,12 +80,24 @@ CBaseModelInfo::AddTexDictionaryRef(void) CTxdStore::AddRef(m_txdSlot); } +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) { @@ -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) @@ -136,6 +166,40 @@ CSimpleModelInfo::GetLargestLodDistance(void) return d * TheCamera.LODDistMultiplier; } +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) { @@ -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 SetAtomic(int n, RpAtomic *atomic); + 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); 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 +#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,15 +223,73 @@ 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) { @@ -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 @@ -397,6 +500,33 @@ CVehicleModelInfo::SetAtomicRendererCB_Train(RpAtomic *atomic, void *data) return atomic; } +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) { @@ -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 @@ -454,6 +454,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); @@ -473,6 +481,40 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic) return 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) { 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