diff options
Diffstat (limited to 'src/modelinfo')
-rw-r--r-- | src/modelinfo/BaseModelInfo.cpp | 95 | ||||
-rw-r--r-- | src/modelinfo/BaseModelInfo.h | 30 | ||||
-rw-r--r-- | src/modelinfo/ClumpModelInfo.cpp | 68 | ||||
-rw-r--r-- | src/modelinfo/ClumpModelInfo.h | 9 | ||||
-rw-r--r-- | src/modelinfo/MloModelInfo.cpp | 21 | ||||
-rw-r--r-- | src/modelinfo/MloModelInfo.h | 6 | ||||
-rw-r--r-- | src/modelinfo/ModelIndices.cpp | 16 | ||||
-rw-r--r-- | src/modelinfo/ModelIndices.h | 1177 | ||||
-rw-r--r-- | src/modelinfo/ModelInfo.cpp | 111 | ||||
-rw-r--r-- | src/modelinfo/ModelInfo.h | 21 | ||||
-rw-r--r-- | src/modelinfo/PedModelInfo.cpp | 127 | ||||
-rw-r--r-- | src/modelinfo/PedModelInfo.h | 10 | ||||
-rw-r--r-- | src/modelinfo/SimpleModelInfo.cpp | 216 | ||||
-rw-r--r-- | src/modelinfo/SimpleModelInfo.h | 37 | ||||
-rw-r--r-- | src/modelinfo/TimeModelInfo.cpp | 29 | ||||
-rw-r--r-- | src/modelinfo/TimeModelInfo.h | 9 | ||||
-rw-r--r-- | src/modelinfo/VehicleModelInfo.cpp | 473 | ||||
-rw-r--r-- | src/modelinfo/VehicleModelInfo.h | 49 | ||||
-rw-r--r-- | src/modelinfo/WeaponModelInfo.cpp | 22 | ||||
-rw-r--r-- | src/modelinfo/WeaponModelInfo.h | 10 | ||||
-rw-r--r-- | src/modelinfo/XtraCompsModelInfo.cpp | 21 | ||||
-rw-r--r-- | src/modelinfo/XtraCompsModelInfo.h | 19 |
22 files changed, 2172 insertions, 404 deletions
diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp index 709420fd..9af21da0 100644 --- a/src/modelinfo/BaseModelInfo.cpp +++ b/src/modelinfo/BaseModelInfo.cpp @@ -1,11 +1,15 @@ #include "common.h" #include "templates.h" +#include "main.h" #include "TxdStore.h" #include "2dEffect.h" #include "BaseModelInfo.h" #include "ModelInfo.h" -#include "ColModel.h" +#include "KeyGen.h" +#include "Streaming.h" +#include "smallHeap.h" +#include "TempColModels.h" CBaseModelInfo::CBaseModelInfo(ModelInfoType type) { @@ -17,6 +21,11 @@ CBaseModelInfo::CBaseModelInfo(ModelInfoType type) m_type = type; m_num2dEffects = 0; m_bOwnsColModel = false; + m_nameKey = 0; + m_unk[0] = 0; + m_unk[1] = 0; + m_name = new char[MAX_MODEL_NAME]; + *(int32*)m_name = 0; } void @@ -24,6 +33,7 @@ CBaseModelInfo::Shutdown(void) { DeleteCollisionModel(); DeleteRwObject(); + DeleteChunk(); m_2dEffectsID = -1; m_num2dEffects = 0; m_txdSlot = -1; @@ -33,11 +43,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 @@ -50,8 +60,10 @@ CBaseModelInfo::AddRef(void) void CBaseModelInfo::RemoveRef(void) { - m_refCount--; - RemoveTexDictionaryRef(); + if(m_refCount > 0){ + m_refCount--; + RemoveTexDictionaryRef(); + } } void @@ -70,12 +82,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; @@ -88,7 +112,7 @@ CBaseModelInfo::Add2dEffect(C2dEffect *fx) if(m_2dEffectsID >= 0) m_num2dEffects++; else{ - m_2dEffectsID = CModelInfo::Get2dEffectStore().GetIndex(fx); + m_2dEffectsID = CModelInfo::Get2dEffectIndex(fx); m_num2dEffects = 1; } } @@ -97,7 +121,64 @@ C2dEffect* CBaseModelInfo::Get2dEffect(int n) { if(m_2dEffectsID >= 0) - return CModelInfo::Get2dEffectStore().GetItem(m_2dEffectsID+n); + return CModelInfo::Get2dEffect(m_2dEffectsID+n); else return nil; } + + +void +CBaseModelInfo::SetModelName(const char *name) +{ + m_nameKey = CKeyGen::GetUppercaseKey(name); + if (!gUseChunkFiles) + strcpy(m_name, name); +} + +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 2d1dc8ac..f9020335 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,11 +23,18 @@ class C2dEffect; class CBaseModelInfo { protected: - char m_name[MAX_MODEL_NAME]; + uint32 m_unk[2]; // somehow related to GU texture stuff, unused here + uint32 m_nameKey; + union { + char *m_name; // if not using chunks + void *m_chunk; // else + }; uint8 m_type; uint8 m_num2dEffects; bool m_bOwnsColModel; +public: // need this in colstore CColModel *m_colModel; +protected: int16 m_2dEffectsID; int16 m_objectId; uint16 m_refCount; @@ -35,7 +42,11 @@ protected: public: CBaseModelInfo(ModelInfoType type); +#ifdef FIX_BUGS + virtual ~CBaseModelInfo() { delete []m_name; } +#else virtual ~CBaseModelInfo() {} +#endif virtual void Shutdown(void); virtual void DeleteRwObject(void) = 0; virtual RwObject *CreateInstance(void) = 0; @@ -45,13 +56,24 @@ 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; } bool IsSimple(void) { return m_type == MITYPE_SIMPLE || m_type == MITYPE_TIME || m_type == MITYPE_WEAPON; } bool IsClump(void) { return m_type == MITYPE_CLUMP || m_type == MITYPE_PED || m_type == MITYPE_VEHICLE; } char *GetModelName(void) { return m_name; } - void SetModelName(const char *name) { strncpy(m_name, name, MAX_MODEL_NAME); } + void SetModelName(const char *name); + uint32 GetNameHashKey() { return m_nameKey; } void SetColModel(CColModel *col, bool owns = false){ m_colModel = col; m_bOwnsColModel = owns; } CColModel *GetColModel(void) { return m_colModel; } @@ -65,7 +87,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/MloModelInfo.cpp b/src/modelinfo/MloModelInfo.cpp index fa12b900..dc5e64fa 100644 --- a/src/modelinfo/MloModelInfo.cpp +++ b/src/modelinfo/MloModelInfo.cpp @@ -3,10 +3,13 @@ #include "VisibilityPlugins.h" #include "ModelInfo.h" -/* +base::cRelocatableChunkClassInfo CMloModelInfo::msClassInfo("CMloModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance)); +CMloModelInfo CMloModelInfo::msClassInstance; + void CMloModelInfo::ConstructClump() { +/* m_clump = RpClumpCreate(); RwFrame *mainFrame = RwFrameCreate(); RwFrameSetIdentity(mainFrame); @@ -37,5 +40,19 @@ CMloModelInfo::ConstructClump() RpClumpDestroy(m_clump); m_clump = nil; } +*/ +} + +void +CMloModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer) +{ + writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true); + writer.Class(VTABLE_ADDR(this), msClassInfo); +} + +void +CMloModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer) +{ + writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true); + writer.Class(VTABLE_ADDR(this), msClassInfo); } -*/
\ No newline at end of file diff --git a/src/modelinfo/MloModelInfo.h b/src/modelinfo/MloModelInfo.h index b1ae3298..918efb89 100644 --- a/src/modelinfo/MloModelInfo.h +++ b/src/modelinfo/MloModelInfo.h @@ -11,4 +11,10 @@ public: public: CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {} void ConstructClump(); + + virtual void RcWriteThis(base::cRelocatableChunkWriter &writer); + virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer); + + static base::cRelocatableChunkClassInfo msClassInfo; + static CMloModelInfo msClassInstance; };
\ No newline at end of file diff --git a/src/modelinfo/ModelIndices.cpp b/src/modelinfo/ModelIndices.cpp index 98c7fb38..83539404 100644 --- a/src/modelinfo/ModelIndices.cpp +++ b/src/modelinfo/ModelIndices.cpp @@ -2,17 +2,25 @@ #include "General.h" #include "ModelIndices.h" +#include "main.h" -#define X(name, var) int16 var = -1; +CModelIndices *gpModelIndices; + +/*#define X(name, var) int16 var = -1; MODELINDICES -#undef X +#undef X*/ void InitModelIndices(void) { -#define X(name, var) var = -1; +/*#define X(name, var) var = -1; MODELINDICES -#undef X +#undef X*/ + if (gMakeResources) + { + gpModelIndices = new CModelIndices; + memset(gpModelIndices, -1, sizeof(CModelIndices)); + } } void diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index 836c4092..d24c8549 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -2,8 +2,591 @@ #include "ModelInfo.h" +struct CModelIndices +{ + int16 TRAFFICLIGHTS; + int16 TLIGHT_POST; + int16 TLIGHT_WALK; + int16 TLIGHT_BOX1; + int16 TLIGHT_BOX2; + int16 TRAFFICLIGHTS_VERTICAL; + int16 TRAFFICLIGHTS_MIAMI; + int16 TRAFFICLIGHTS_TWOVERTICAL; + int16 SINGLESTREETLIGHTS1; + int16 SINGLESTREETLIGHTS2; + int16 SINGLESTREETLIGHTS3; + int16 DOUBLESTREETLIGHTS; + int16 STREETLAMP1; + int16 STREETLAMP2; + int16 ROADSFORROADBLOCKSSTART; + int16 ROADSFORROADBLOCKSEND; + int16 TREE2; + int16 TREE3; + int16 TREE6; + int16 TREE8; + int16 TREE1; + int16 TREE4; + int16 TREE5; + int16 TREE7; + int16 TREE9; + int16 TREE10; + int16 TREE11; + int16 TREE12; + int16 TREE13; + int16 TREE14; + int16 CRANE_1; + int16 CRANE_2; + int16 CRANE_3; + int16 CRANE_4; + int16 CRANE_5; + int16 CRANE_6; + int16 PARKINGMETER; + int16 PARKINGMETER2; + int16 MALLFAN; + int16 HOTELFAN_NIGHT; + int16 HOTELFAN_DAY; + int16 HOTROOMFAN; + int16 PHONEBOOTH1; + int16 WASTEBIN; + int16 BIN; + int16 POSTBOX1; + int16 NEWSSTAND; + int16 TRAFFICCONE; + int16 DUMP1; + int16 ROADWORKBARRIER1; + int16 BUSSIGN1; + int16 NOPARKINGSIGN1; + int16 PHONESIGN; + int16 TAXISIGN; + int16 FISHSTALL01; + int16 FISHSTALL02; + int16 FISHSTALL03; + int16 FISHSTALL04; + int16 BAGELSTAND2; + int16 FIRE_HYDRANT; + int16 COLLECTABLE1; + int16 MONEY; + int16 CARMINE; + int16 GARAGEDOOR1; + int16 GARAGEDOOR2; + int16 GARAGEDOOR3; + int16 GARAGEDOOR4; + int16 GARAGEDOOR5; + int16 GARAGEDOOR6; + int16 GARAGEDOOR7; + int16 GARAGEDOOR9; + int16 GARAGEDOOR10; + int16 GARAGEDOOR11; + int16 GARAGEDOOR12; + int16 GARAGEDOOR13; + int16 GARAGEDOOR14; + int16 GARAGEDOOR15; + int16 GARAGEDOOR16; + int16 GARAGEDOOR17; + int16 GARAGEDOOR18; + int16 GARAGEDOOR19; + int16 GARAGEDOOR20; + int16 GARAGEDOOR21; + int16 GARAGEDOOR22; + int16 GARAGEDOOR23; + int16 GARAGEDOOR24; + int16 GARAGEDOOR25; + int16 GARAGEDOOR26; + int16 GARAGEDOOR27; + int16 GARAGEDOOR28; + int16 GARAGEDOOR29; + int16 GARAGEDOOR30; + int16 GARAGEDOOR31; + int16 GARAGEDOOR32; + int16 GARAGEDOOR33; + int16 GARAGEDOOR34; + int16 GARAGEDOOR35; + int16 GARAGEDOOR36; + int16 GARAGEDOOR37; + int16 GARAGEDOOR38; + int16 GARAGEDOOR39; + int16 TESTRAMP1; // UNUSED + int16 TESTRAMP2; + int16 NAUTICALMINE; + int16 CRUSHERBODY; + int16 CRUSHERLID; + int16 DONKEYMAG; + int16 BULLION; + int16 FLOATPACKAGE1; + int16 BRIEFCASE; + int16 CHINABANNER1; + int16 CHINABANNER2; + int16 CHINABANNER3; + int16 CHINABANNER4; + int16 CHINABANNER5; + int16 CHINABANNER6; + int16 CHINABANNER7; + int16 CHINABANNER8; + int16 CHINABANNER9; + int16 CHINABANNER10; + int16 CHINABANNER11; + int16 CHINABANNER12; + int16 CHINALANTERN; + int16 GLASS1; + int16 GLASS2; + int16 GLASS3; + int16 GLASS4; + int16 GLASS5; + int16 GLASS6; + int16 GLASS7; + int16 GLASS8; + int16 BRIDGELIFT; + int16 BRIDGEWEIGHT; + int16 BRIDGEROADSEGMENT; + int16 EXPLODINGBARREL; + int16 ITALYBANNER1; + int16 MEGADAMAGE; + int16 REGENERATOR; + int16 INVISIBLE; + int16 GOOD_CAR; + int16 BAD_CAR; + int16 PICKUP_ADRENALINE; + int16 PICKUP_BODYARMOUR; + int16 PICKUP_INFO; + int16 PICKUP_HEALTH; + int16 PICKUP_BONUS; + int16 PICKUP_BRIBE; + int16 PICKUP_KILLFRENZY; + int16 PICKUP_CAMERA; + int16 PICKUP_REVENUE; + int16 PICKUP_SAVEGAME; + int16 PICKUP_PROPERTY; + int16 PICKUP_PROPERTY_FORSALE; + int16 PICKUP_CLOTHES; + int16 BOLLARDLIGHT; + int16 CA_SP1; + int16 CA_SP2; + int16 CA_SP3; + int16 CA_SP4; + int16 PACKAGE1IZZY; + int16 MAGNET; + int16 RAILTRACKS; + int16 FENCE; + int16 FENCE2; + int16 PETROLPUMP; + int16 PETROLPUMP2; + int16 BODYCAST; + int16 IZZY_CONFDOOR; + int16 SHIPDOOR; + int16 IZZY_JDDOOR; + int16 IZZY_JDDOOR_SLIDER; + int16 LITEHOUSE_GATE; + int16 COFFEE; + int16 BUOY; + int16 PARKTABLE; + int16 SUBWAY1; + int16 SUBWAY2; + int16 SUBWAY3; + int16 SUBWAY4; + int16 SUBWAY5; + int16 SUBWAY6; + int16 SUBWAY7; + int16 SUBWAY8; + int16 SUBWAY9; + int16 SUBWAY10; + int16 SUBWAY11; + int16 SUBWAY12; + int16 SUBWAY13; + int16 SUBWAY14; + int16 SUBWAY15; + int16 SUBWAY16; + int16 SUBWAY17; + int16 SUBWAY18; + int16 SUBPLATFORM_IND; + int16 SUBPLATFORM_COMS; + int16 SUBPLATFORM_COMS2; + int16 SUBPLATFORM_COMN; + int16 SUBPLATFORM_SUB; + int16 SUBPLATFORM_SUB2; + int16 FILES; + int16 LAMPPOST1; + int16 VEG_PALM01; + int16 VEG_PALM02; + int16 VEG_PALM03; + int16 VEG_PALM04; + int16 VEG_PALM05; + int16 VEG_PALM06; + int16 VEG_PALM07; + int16 VEG_PALM08; + int16 MLAMPPOST; + int16 BARRIER1; + int16 LITTLEHA_POLICE; + int16 TELPOLE02; + int16 TRAFFICLIGHT01; + int16 PARKBENCH; + int16 PLC_STINGER; + int16 LIGHTBEAM; + int16 AIRPORTRADAR; + int16 RCBOMB; + int16 JM_SALRADIO; + int16 BEACHBALL; + int16 SANDCASTLE1; + int16 SANDCASTLE2; + int16 JELLYFISH; + int16 JELLYFISH01; + int16 FISH1SINGLE; + int16 FISH1S; + int16 FISH2SINGLE; + int16 FISH2S; + int16 FISH3SINGLE; + int16 FISH3S; + int16 TURTLE; + int16 DOLPHIN; + int16 SHARK; + int16 SUBMARINE; + int16 ESCALATORSTEP; + int16 LOUNGE_WOOD_UP; + int16 LOUNGE_TOWEL_UP; + int16 LOUNGE_WOOD_DN; + int16 LOTION; + int16 BEACHTOWEL01; + int16 BEACHTOWEL02; + int16 BEACHTOWEL03; + int16 BEACHTOWEL04; + int16 BLIMP_NIGHT; + int16 BLIMP_DAY; + int16 YT_MAIN_BODY; + int16 YT_MAIN_BODY2; + int16 SMALL_HELIX; + int16 PT_BARRIER; + int16 SUBWAYGATE; + int16 IN_PMBRIDRAMP3; + int16 IN_PMBRIDG2_UPGS; + int16 IN_PMBRIDGE2; + int16 IN_PMBRIDG1_UPGS; + int16 PM_LIGHTRIG3; + int16 PM_LIGHTRIG1; + int16 IN_PMSCAFF_UPS; + int16 IN_PM_CONCBLOK2; + int16 IN_PMSCAFFH_NS; + int16 IN_PM_GRAVL_JMP; + int16 IN_PM_SCAFFCOVR; + int16 IN_PM_GIRDER2; + int16 IN_PM_SCAFFH_WE; + int16 IN_PM_SIXCONC2; + int16 IN_BMBRIDRAMP3; + int16 IN_BMBRIDG2_UPGS; + int16 IN_BMBRIDGE2; + int16 IN_BMBRIDG1_UPGS; + int16 BM_LIGHTRIG3; + int16 BM_LIGHTRIG1; + int16 IN_BMSCAFF_UPS; + int16 IN_BM_CONCBLOK2; + int16 IN_BMSCAFFH_NS; + int16 IN_BM_GRAVL_JMP; + int16 IN_BM_SCAFFCOVR; + int16 IN_BM_GIRDER2; + int16 IN_BM_SCAFFH_WE; + int16 IN_BM_SIXCONC2; + int16 CRATE_SJL; + int16 DOOR1_SJL; + int16 DOOR2_SJL; + int16 SJL_PORTACABIN; + int16 SJL_PORTACABINRED; + int16 advert_test; // txd +}; + +extern CModelIndices *gpModelIndices; + +#define MI_TRAFFICLIGHTS gpModelIndices->TRAFFICLIGHTS +#define MI_TLIGHT_POST gpModelIndices->TLIGHT_POST +#define MI_TLIGHT_WALK gpModelIndices->TLIGHT_WALK +#define MI_TLIGHT_BOX1 gpModelIndices->TLIGHT_BOX1 +#define MI_TLIGHT_BOX2 gpModelIndices->TLIGHT_BOX2 +#define MI_TRAFFICLIGHTS_VERTICAL gpModelIndices->TRAFFICLIGHTS_VERTICAL +#define MI_TRAFFICLIGHTS_MIAMI gpModelIndices->TRAFFICLIGHTS_MIAMI +#define MI_TRAFFICLIGHTS_TWOVERTICAL gpModelIndices->TRAFFICLIGHTS_TWOVERTICAL +#define MI_SINGLESTREETLIGHTS1 gpModelIndices->SINGLESTREETLIGHTS1 +#define MI_SINGLESTREETLIGHTS2 gpModelIndices->SINGLESTREETLIGHTS2 +#define MI_SINGLESTREETLIGHTS3 gpModelIndices->SINGLESTREETLIGHTS3 +#define MI_DOUBLESTREETLIGHTS gpModelIndices->DOUBLESTREETLIGHTS +#define MI_STREETLAMP1 gpModelIndices->STREETLAMP1 +#define MI_STREETLAMP2 gpModelIndices->STREETLAMP2 +#define MI_ROADSFORROADBLOCKSSTART gpModelIndices->ROADSFORROADBLOCKSSTART +#define MI_ROADSFORROADBLOCKSEND gpModelIndices->ROADSFORROADBLOCKSEND +#define MI_TREE2 gpModelIndices->TREE2 +#define MI_TREE3 gpModelIndices->TREE3 +#define MI_TREE6 gpModelIndices->TREE6 +#define MI_TREE8 gpModelIndices->TREE8 +#define MI_TREE1 gpModelIndices->TREE1 +#define MI_TREE4 gpModelIndices->TREE4 +#define MI_TREE5 gpModelIndices->TREE5 +#define MI_TREE7 gpModelIndices->TREE7 +#define MI_TREE9 gpModelIndices->TREE9 +#define MI_TREE10 gpModelIndices->TREE10 +#define MI_TREE11 gpModelIndices->TREE11 +#define MI_TREE12 gpModelIndices->TREE12 +#define MI_TREE13 gpModelIndices->TREE13 +#define MI_TREE14 gpModelIndices->TREE14 +#define MODELID_CRANE_1 gpModelIndices->CRANE_1 +#define MODELID_CRANE_2 gpModelIndices->CRANE_2 +#define MODELID_CRANE_3 gpModelIndices->CRANE_3 +#define MODELID_CRANE_4 gpModelIndices->CRANE_4 +#define MODELID_CRANE_5 gpModelIndices->CRANE_5 +#define MODELID_CRANE_6 gpModelIndices->CRANE_6 +#define MI_PARKINGMETER gpModelIndices->PARKINGMETER +#define MI_PARKINGMETER2 gpModelIndices->PARKINGMETER2 +#define MI_MALLFAN gpModelIndices->MALLFAN +#define MI_HOTELFAN_NIGHT gpModelIndices->HOTELFAN_NIGHT +#define MI_HOTELFAN_DAY gpModelIndices->HOTELFAN_DAY +#define MI_HOTROOMFAN gpModelIndices->HOTROOMFAN +#define MI_PHONEBOOTH1 gpModelIndices->PHONEBOOTH1 +#define MI_WASTEBIN gpModelIndices->WASTEBIN +#define MI_BIN gpModelIndices->BIN +#define MI_POSTBOX1 gpModelIndices->POSTBOX1 +#define MI_NEWSSTAND gpModelIndices->NEWSSTAND +#define MI_TRAFFICCONE gpModelIndices->TRAFFICCONE +#define MI_DUMP1 gpModelIndices->DUMP1 +#define MI_ROADWORKBARRIER1 gpModelIndices->ROADWORKBARRIER1 +#define MI_BUSSIGN1 gpModelIndices->BUSSIGN1 +#define MI_NOPARKINGSIGN1 gpModelIndices->NOPARKINGSIGN1 +#define MI_PHONESIGN gpModelIndices->PHONESIGN +#define MI_TAXISIGN gpModelIndices->TAXISIGN +#define MI_FISHSTALL01 gpModelIndices->FISHSTALL01 +#define MI_FISHSTALL02 gpModelIndices->FISHSTALL02 +#define MI_FISHSTALL03 gpModelIndices->FISHSTALL03 +#define MI_FISHSTALL04 gpModelIndices->FISHSTALL04 +#define MI_BAGELSTAND2 gpModelIndices->BAGELSTAND2 +#define MI_FIRE_HYDRANT gpModelIndices->FIRE_HYDRANT +#define MI_COLLECTABLE1 gpModelIndices->COLLECTABLE1 +#define MI_MONEY gpModelIndices->MONEY +#define MI_CARMINE gpModelIndices->CARMINE +#define MI_GARAGEDOOR1 gpModelIndices->GARAGEDOOR1 +#define MI_GARAGEDOOR2 gpModelIndices->GARAGEDOOR2 +#define MI_GARAGEDOOR3 gpModelIndices->GARAGEDOOR3 +#define MI_GARAGEDOOR4 gpModelIndices->GARAGEDOOR4 +#define MI_GARAGEDOOR5 gpModelIndices->GARAGEDOOR5 +#define MI_GARAGEDOOR6 gpModelIndices->GARAGEDOOR6 +#define MI_GARAGEDOOR7 gpModelIndices->GARAGEDOOR7 +#define MI_GARAGEDOOR9 gpModelIndices->GARAGEDOOR9 +#define MI_GARAGEDOOR10 gpModelIndices->GARAGEDOOR10 +#define MI_GARAGEDOOR11 gpModelIndices->GARAGEDOOR11 +#define MI_GARAGEDOOR12 gpModelIndices->GARAGEDOOR12 +#define MI_GARAGEDOOR13 gpModelIndices->GARAGEDOOR13 +#define MI_GARAGEDOOR14 gpModelIndices->GARAGEDOOR14 +#define MI_GARAGEDOOR15 gpModelIndices->GARAGEDOOR15 +#define MI_GARAGEDOOR16 gpModelIndices->GARAGEDOOR16 +#define MI_GARAGEDOOR17 gpModelIndices->GARAGEDOOR17 +#define MI_GARAGEDOOR18 gpModelIndices->GARAGEDOOR18 +#define MI_GARAGEDOOR19 gpModelIndices->GARAGEDOOR19 +#define MI_GARAGEDOOR20 gpModelIndices->GARAGEDOOR20 +#define MI_GARAGEDOOR21 gpModelIndices->GARAGEDOOR21 +#define MI_GARAGEDOOR22 gpModelIndices->GARAGEDOOR22 +#define MI_GARAGEDOOR23 gpModelIndices->GARAGEDOOR23 +#define MI_GARAGEDOOR24 gpModelIndices->GARAGEDOOR24 +#define MI_GARAGEDOOR25 gpModelIndices->GARAGEDOOR25 +#define MI_GARAGEDOOR26 gpModelIndices->GARAGEDOOR26 +#define MI_GARAGEDOOR27 gpModelIndices->GARAGEDOOR27 +#define MI_GARAGEDOOR28 gpModelIndices->GARAGEDOOR28 +#define MI_GARAGEDOOR29 gpModelIndices->GARAGEDOOR29 +#define MI_GARAGEDOOR30 gpModelIndices->GARAGEDOOR30 +#define MI_GARAGEDOOR31 gpModelIndices->GARAGEDOOR31 +#define MI_GARAGEDOOR32 gpModelIndices->GARAGEDOOR32 +#define MI_GARAGEDOOR33 gpModelIndices->GARAGEDOOR33 +#define MI_GARAGEDOOR34 gpModelIndices->GARAGEDOOR34 +#define MI_GARAGEDOOR35 gpModelIndices->GARAGEDOOR35 +#define MI_GARAGEDOOR36 gpModelIndices->GARAGEDOOR36 +#define MI_GARAGEDOOR37 gpModelIndices->GARAGEDOOR37 +#define MI_GARAGEDOOR38 gpModelIndices->GARAGEDOOR38 +#define MI_GARAGEDOOR39 gpModelIndices->GARAGEDOOR39 +#define MI_TESTRAMP1 gpModelIndices->TESTRAMP1 // UNUSED +#define MI_TESTRAMP2 gpModelIndices->TESTRAMP2 +#define MI_NAUTICALMINE gpModelIndices->NAUTICALMINE +#define MI_CRUSHERBODY gpModelIndices->CRUSHERBODY +#define MI_CRUSHERLID gpModelIndices->CRUSHERLID +#define MI_DONKEYMAG gpModelIndices->DONKEYMAG +#define MI_BULLION gpModelIndices->BULLION +#define MI_FLOATPACKAGE1 gpModelIndices->FLOATPACKAGE1 +#define MI_BRIEFCASE gpModelIndices->BRIEFCASE +#define MI_CHINABANNER1 gpModelIndices->CHINABANNER1 +#define MI_CHINABANNER2 gpModelIndices->CHINABANNER2 +#define MI_CHINABANNER3 gpModelIndices->CHINABANNER3 +#define MI_CHINABANNER4 gpModelIndices->CHINABANNER4 +#define MI_CHINABANNER5 gpModelIndices->CHINABANNER5 +#define MI_CHINABANNER6 gpModelIndices->CHINABANNER6 +#define MI_CHINABANNER7 gpModelIndices->CHINABANNER7 +#define MI_CHINABANNER8 gpModelIndices->CHINABANNER8 +#define MI_CHINABANNER9 gpModelIndices->CHINABANNER9 +#define MI_CHINABANNER10 gpModelIndices->CHINABANNER10 +#define MI_CHINABANNER11 gpModelIndices->CHINABANNER11 +#define MI_CHINABANNER12 gpModelIndices->CHINABANNER12 +#define MI_CHINALANTERN gpModelIndices->CHINALANTERN +#define MI_GLASS1 gpModelIndices->GLASS1 +#define MI_GLASS2 gpModelIndices->GLASS2 +#define MI_GLASS3 gpModelIndices->GLASS3 +#define MI_GLASS4 gpModelIndices->GLASS4 +#define MI_GLASS5 gpModelIndices->GLASS5 +#define MI_GLASS6 gpModelIndices->GLASS6 +#define MI_GLASS7 gpModelIndices->GLASS7 +#define MI_GLASS8 gpModelIndices->GLASS8 +#define MI_BRIDGELIFT gpModelIndices->BRIDGELIFT +#define MI_BRIDGEWEIGHT gpModelIndices->BRIDGEWEIGHT +#define MI_BRIDGEROADSEGMENT gpModelIndices->BRIDGEROADSEGMENT +#define MI_EXPLODINGBARREL gpModelIndices->EXPLODINGBARREL +#define MI_ITALYBANNER1 gpModelIndices->ITALYBANNER1 +#define MI_MEGADAMAGE gpModelIndices->MEGADAMAGE +#define MI_REGENERATOR gpModelIndices->REGENERATOR +#define MI_INVISIBLE gpModelIndices->INVISIBLE +#define MI_GOOD_CAR gpModelIndices->GOOD_CAR +#define MI_BAD_CAR gpModelIndices->BAD_CAR +#define MI_PICKUP_ADRENALINE gpModelIndices->PICKUP_ADRENALINE +#define MI_PICKUP_BODYARMOUR gpModelIndices->PICKUP_BODYARMOUR +#define MI_PICKUP_INFO gpModelIndices->PICKUP_INFO +#define MI_PICKUP_HEALTH gpModelIndices->PICKUP_HEALTH +#define MI_PICKUP_BONUS gpModelIndices->PICKUP_BONUS +#define MI_PICKUP_BRIBE gpModelIndices->PICKUP_BRIBE +#define MI_PICKUP_KILLFRENZY gpModelIndices->PICKUP_KILLFRENZY +#define MI_PICKUP_CAMERA gpModelIndices->PICKUP_CAMERA +#define MI_PICKUP_REVENUE gpModelIndices->PICKUP_REVENUE +#define MI_PICKUP_SAVEGAME gpModelIndices->PICKUP_SAVEGAME +#define MI_PICKUP_PROPERTY gpModelIndices->PICKUP_PROPERTY +#define MI_PICKUP_PROPERTY_FORSALE gpModelIndices->PICKUP_PROPERTY_FORSALE +#define MI_PICKUP_CLOTHES gpModelIndices->PICKUP_CLOTHES +#define MI_BOLLARDLIGHT gpModelIndices->BOLLARDLIGHT +#define MI_CA_SP1 gpModelIndices->CA_SP1 +#define MI_CA_SP2 gpModelIndices->CA_SP2 +#define MI_CA_SP3 gpModelIndices->CA_SP3 +#define MI_CA_SP4 gpModelIndices->CA_SP4 +#define MI_PACKAGE1IZZY gpModelIndices->PACKAGE1IZZY +#define MI_MAGNET gpModelIndices->MAGNET +#define MI_RAILTRACKS gpModelIndices->RAILTRACKS +#define MI_FENCE gpModelIndices->FENCE +#define MI_FENCE2 gpModelIndices->FENCE2 +#define MI_PETROLPUMP gpModelIndices->PETROLPUMP +#define MI_PETROLPUMP2 gpModelIndices->PETROLPUMP2 +#define MI_BODYCAST gpModelIndices->BODYCAST +#define MI_IZZY_CONFDOOR gpModelIndices->IZZY_CONFDOOR +#define MI_SHIPDOOR gpModelIndices->SHIPDOOR +#define MI_IZZY_JDDOOR gpModelIndices->IZZY_JDDOOR +#define MI_IZZY_JDDOOR_SLIDER gpModelIndices->IZZY_JDDOOR_SLIDER +#define MI_LITEHOUSE_GATE gpModelIndices->LITEHOUSE_GATE +#define MI_COFFEE gpModelIndices->COFFEE +#define MI_BUOY gpModelIndices->BUOY +#define MI_PARKTABLE gpModelIndices->PARKTABLE +#define MI_SUBWAY1 gpModelIndices->SUBWAY1 +#define MI_SUBWAY2 gpModelIndices->SUBWAY2 +#define MI_SUBWAY3 gpModelIndices->SUBWAY3 +#define MI_SUBWAY4 gpModelIndices->SUBWAY4 +#define MI_SUBWAY5 gpModelIndices->SUBWAY5 +#define MI_SUBWAY6 gpModelIndices->SUBWAY6 +#define MI_SUBWAY7 gpModelIndices->SUBWAY7 +#define MI_SUBWAY8 gpModelIndices->SUBWAY8 +#define MI_SUBWAY9 gpModelIndices->SUBWAY9 +#define MI_SUBWAY10 gpModelIndices->SUBWAY10 +#define MI_SUBWAY11 gpModelIndices->SUBWAY11 +#define MI_SUBWAY12 gpModelIndices->SUBWAY12 +#define MI_SUBWAY13 gpModelIndices->SUBWAY13 +#define MI_SUBWAY14 gpModelIndices->SUBWAY14 +#define MI_SUBWAY15 gpModelIndices->SUBWAY15 +#define MI_SUBWAY16 gpModelIndices->SUBWAY16 +#define MI_SUBWAY17 gpModelIndices->SUBWAY17 +#define MI_SUBWAY18 gpModelIndices->SUBWAY18 +#define MI_SUBPLATFORM_IND gpModelIndices->SUBPLATFORM_IND +#define MI_SUBPLATFORM_COMS gpModelIndices->SUBPLATFORM_COMS +#define MI_SUBPLATFORM_COMS2 gpModelIndices->SUBPLATFORM_COMS2 +#define MI_SUBPLATFORM_COMN gpModelIndices->SUBPLATFORM_COMN +#define MI_SUBPLATFORM_SUB gpModelIndices->SUBPLATFORM_SUB +#define MI_SUBPLATFORM_SUB2 gpModelIndices->SUBPLATFORM_SUB2 +#define MI_FILES gpModelIndices->FILES +#define MI_LAMPPOST1 gpModelIndices->LAMPPOST1 +#define MI_VEG_PALM01 gpModelIndices->VEG_PALM01 +#define MI_VEG_PALM02 gpModelIndices->VEG_PALM02 +#define MI_VEG_PALM03 gpModelIndices->VEG_PALM03 +#define MI_VEG_PALM04 gpModelIndices->VEG_PALM04 +#define MI_VEG_PALM05 gpModelIndices->VEG_PALM05 +#define MI_VEG_PALM06 gpModelIndices->VEG_PALM06 +#define MI_VEG_PALM07 gpModelIndices->VEG_PALM07 +#define MI_VEG_PALM08 gpModelIndices->VEG_PALM08 +#define MI_MLAMPPOST gpModelIndices->MLAMPPOST +#define MI_BARRIER1 gpModelIndices->BARRIER1 +#define MI_LITTLEHA_POLICE gpModelIndices->LITTLEHA_POLICE +#define MI_TELPOLE02 gpModelIndices->TELPOLE02 +#define MI_TRAFFICLIGHT01 gpModelIndices->TRAFFICLIGHT01 +#define MI_PARKBENCH gpModelIndices->PARKBENCH +#define MI_PLC_STINGER gpModelIndices->PLC_STINGER +#define MI_LIGHTBEAM gpModelIndices->LIGHTBEAM +#define MI_AIRPORTRADAR gpModelIndices->AIRPORTRADAR +#define MI_RCBOMB gpModelIndices->RCBOMB +#define MI_JM_SALRADIO gpModelIndices->JM_SALRADIO +#define MI_BEACHBALL gpModelIndices->BEACHBALL +#define MI_SANDCASTLE1 gpModelIndices->SANDCASTLE1 +#define MI_SANDCASTLE2 gpModelIndices->SANDCASTLE2 +#define MI_JELLYFISH gpModelIndices->JELLYFISH +#define MI_JELLYFISH01 gpModelIndices->JELLYFISH01 +#define MI_FISH1SINGLE gpModelIndices->FISH1SINGLE +#define MI_FISH1S gpModelIndices->FISH1S +#define MI_FISH2SINGLE gpModelIndices->FISH2SINGLE +#define MI_FISH2S gpModelIndices->FISH2S +#define MI_FISH3SINGLE gpModelIndices->FISH3SINGLE +#define MI_FISH3S gpModelIndices->FISH3S +#define MI_TURTLE gpModelIndices->TURTLE +#define MI_DOLPHIN gpModelIndices->DOLPHIN +#define MI_SHARK gpModelIndices->SHARK +#define MI_SUBMARINE gpModelIndices->SUBMARINE +#define MI_ESCALATORSTEP gpModelIndices->ESCALATORSTEP +#define MI_LOUNGE_WOOD_UP gpModelIndices->LOUNGE_WOOD_UP +#define MI_LOUNGE_TOWEL_UP gpModelIndices->LOUNGE_TOWEL_UP +#define MI_LOUNGE_WOOD_DN gpModelIndices->LOUNGE_WOOD_DN +#define MI_LOTION gpModelIndices->LOTION +#define MI_BEACHTOWEL01 gpModelIndices->BEACHTOWEL01 +#define MI_BEACHTOWEL02 gpModelIndices->BEACHTOWEL02 +#define MI_BEACHTOWEL03 gpModelIndices->BEACHTOWEL03 +#define MI_BEACHTOWEL04 gpModelIndices->BEACHTOWEL04 +#define MI_BLIMP_NIGHT gpModelIndices->BLIMP_NIGHT +#define MI_BLIMP_DAY gpModelIndices->BLIMP_DAY +#define MI_YT_MAIN_BODY gpModelIndices->YT_MAIN_BODY +#define MI_YT_MAIN_BODY2 gpModelIndices->YT_MAIN_BODY2 +#define MI_SMALL_HELIX gpModelIndices->SMALL_HELIX +#define MI_PT_BARRIER gpModelIndices->PT_BARRIER +#define MI_SUBWAYGATE gpModelIndices->SUBWAYGATE +#define MI_IN_PMBRIDRAMP3 gpModelIndices->IN_PMBRIDRAMP3 +#define MI_IN_PMBRIDG2_UPGS gpModelIndices->IN_PMBRIDG2_UPGS +#define MI_IN_PMBRIDGE2 gpModelIndices->IN_PMBRIDGE2 +#define MI_IN_PMBRIDG1_UPGS gpModelIndices->IN_PMBRIDG1_UPGS +#define MI_PM_LIGHTRIG3 gpModelIndices->PM_LIGHTRIG3 +#define MI_PM_LIGHTRIG1 gpModelIndices->PM_LIGHTRIG1 +#define MI_IN_PMSCAFF_UPS gpModelIndices->IN_PMSCAFF_UPS +#define MI_IN_PM_CONCBLOK2 gpModelIndices->IN_PM_CONCBLOK2 +#define MI_IN_PMSCAFFH_NS gpModelIndices->IN_PMSCAFFH_NS +#define MI_IN_PM_GRAVL_JMP gpModelIndices->IN_PM_GRAVL_JMP +#define MI_IN_PM_SCAFFCOVR gpModelIndices->IN_PM_SCAFFCOVR +#define MI_IN_PM_GIRDER2 gpModelIndices->IN_PM_GIRDER2 +#define MI_IN_PM_SCAFFH_WE gpModelIndices->IN_PM_SCAFFH_WE +#define MI_IN_PM_SIXCONC2 gpModelIndices->IN_PM_SIXCONC2 +#define MI_IN_BMBRIDRAMP3 gpModelIndices->IN_BMBRIDRAMP3 +#define MI_IN_BMBRIDG2_UPGS gpModelIndices->IN_BMBRIDG2_UPGS +#define MI_IN_BMBRIDGE2 gpModelIndices->IN_BMBRIDGE2 +#define MI_IN_BMBRIDG1_UPGS gpModelIndices->IN_BMBRIDG1_UPGS +#define MI_BM_LIGHTRIG3 gpModelIndices->BM_LIGHTRIG3 +#define MI_BM_LIGHTRIG1 gpModelIndices->BM_LIGHTRIG1 +#define MI_IN_BMSCAFF_UPS gpModelIndices->IN_BMSCAFF_UPS +#define MI_IN_BM_CONCBLOK2 gpModelIndices->IN_BM_CONCBLOK2 +#define MI_IN_BMSCAFFH_NS gpModelIndices->IN_BMSCAFFH_NS +#define MI_IN_BM_GRAVL_JMP gpModelIndices->IN_BM_GRAVL_JMP +#define MI_IN_BM_SCAFFCOVR gpModelIndices->IN_BM_SCAFFCOVR +#define MI_IN_BM_GIRDER2 gpModelIndices->IN_BM_GIRDER2 +#define MI_IN_BM_SCAFFH_WE gpModelIndices->IN_BM_SCAFFH_WE +#define MI_IN_BM_SIXCONC2 gpModelIndices->IN_BM_SIXCONC2 +#define MI_CRATE_SJL gpModelIndices->CRATE_SJL +#define MI_DOOR1_SJL gpModelIndices->DOOR1_SJL +#define MI_DOOR2_SJL gpModelIndices->DOOR2_SJL +#define MI_SJL_PORTACABIN gpModelIndices->SJL_PORTACABIN +#define MI_SJL_PORTACABINRED gpModelIndices->SJL_PORTACABINRED + #define MODELINDICES \ X("fire_hydrant", MI_FIRE_HYDRANT) \ + X("fire_hydrant", MI_FIRE_HYDRANT) /* BUG: second time */ \ + X("bagelstnd02", MI_BAGELSTAND2) \ + X("fish01", MI_FISHSTALL01) \ + X("fishstall02", MI_FISHSTALL02) \ + X("fishstall03", MI_FISHSTALL03) \ + X("fishstall04", MI_FISHSTALL04) \ + X("taxisign", MI_TAXISIGN) \ X("phonesign", MI_PHONESIGN) \ X("noparkingsign1", MI_NOPARKINGSIGN1) \ X("bussign1", MI_BUSSIGN1) \ @@ -16,12 +599,17 @@ X("wastebin", MI_WASTEBIN) \ X("phonebooth1", MI_PHONEBOOTH1) \ X("parkingmeter", MI_PARKINGMETER) \ + X("trafficlight1", MI_TRAFFICLIGHTS) \ + X("tlight_post", MI_TLIGHT_POST) \ + X("tlight_walk", MI_TLIGHT_WALK) \ + X("tlight_box1", MI_TLIGHT_BOX1) \ + X("tlight_box2", MI_TLIGHT_BOX2) \ X("parkingmeterg", MI_PARKINGMETER2) \ X("mall_fans", MI_MALLFAN) \ X("htl_fan_rotate_nt", MI_HOTELFAN_NIGHT) \ X("htl_fan_rotate_dy", MI_HOTELFAN_DAY) \ X("hotroomfan", MI_HOTROOMFAN) \ - X("trafficlight1", MI_TRAFFICLIGHTS) \ + X("trafficlight1", MI_TRAFFICLIGHTS) /* BUG: second time */ \ X("MTraffic4", MI_TRAFFICLIGHTS_VERTICAL) \ X("MTraffic1", MI_TRAFFICLIGHTS_MIAMI) \ X("MTraffic2", MI_TRAFFICLIGHTS_TWOVERTICAL) \ @@ -31,47 +619,110 @@ X("doublestreetlght1", MI_DOUBLESTREETLIGHTS) \ X("Streetlamp1", MI_STREETLAMP1) \ X("Streetlamp2", MI_STREETLAMP2) \ + X("rd_Road2A10", MI_ROADSFORROADBLOCKSSTART) \ + X("rd_Road1A30", MI_ROADSFORROADBLOCKSEND) \ + X("veg_tree1", MI_TREE1) \ X("veg_tree3", MI_TREE2) \ X("veg_treea1", MI_TREE3) \ + X("veg_treenew01", MI_TREE4) \ + X("veg_treenew05", MI_TREE5) \ X("veg_treeb1", MI_TREE6) \ + X("veg_treenew10", MI_TREE7) \ X("veg_treea3", MI_TREE8) \ - X("doc_crane_cab0", MODELID_CRANE_1) \ - X("doc_crane_cab01", MODELID_CRANE_2) \ - X("doc_crane_cab02", MODELID_CRANE_3) \ - X("doc_crane_cab03", MODELID_CRANE_4) \ - X("boatcranelg0", MODELID_CRANE_5) \ - X("LODnetopa0", MODELID_CRANE_6) \ + X("veg_treenew09", MI_TREE9) \ + X("veg_treenew08", MI_TREE10) \ + X("veg_treenew03", MI_TREE11) \ + X("veg_treenew16", MI_TREE12) \ + X("veg_treenew17", MI_TREE13) \ + X("veg_treenew06", MI_TREE14) \ + X("crusher_crane", MODELID_CRANE_1) \ X("package1", MI_COLLECTABLE1) \ X("Money", MI_MONEY) \ X("barrel1", MI_CARMINE) \ - X("dk_paynspraydoor", MI_GARAGEDOOR2) \ - X("dk_waretankdoor1", MI_GARAGEDOOR3) \ - X("hav_garagedoor1", MI_GARAGEDOOR4) \ - X("hav_garagedoor02", MI_GARAGEDOOR5) \ - X("hav_garagedoor03", MI_GARAGEDOOR6) \ - X("hav_garagedoor04", MI_GARAGEDOOR7) \ - X("lh_showdoor03", MI_GARAGEDOOR9) \ - X("lh_showdoor1", MI_GARAGEDOOR10) \ - X("lhtankdoor", MI_GARAGEDOOR11) \ - X("nbtgardoor", MI_GARAGEDOOR12) \ - X("dk_camjonesdoor", MI_GARAGEDOOR13) \ - X("nbtgardoor02", MI_GARAGEDOOR14) \ - X("dt_savedra", MI_GARAGEDOOR15) \ - X("dt_savedrb", MI_GARAGEDOOR16) \ - X("dk_bombdoor", MI_GARAGEDOOR18) \ - X("haiwshpnsdoor", MI_GARAGEDOOR19) \ - X("wshpnsdoor", MI_GARAGEDOOR20) \ - X("nbecpnsdoor", MI_GARAGEDOOR21) \ - X("nbtgardoor03", MI_GARAGEDOOR22) \ - X("dt_savedrc", MI_GARAGEDOOR23) \ - X("dt_savedrd", MI_GARAGEDOOR24) \ - X("man_frntstepGD", MI_GARAGEDOOR25) \ - X("svegrgedoor", MI_GARAGEDOOR26) \ + X("oddjgaragdoor", MI_GARAGEDOOR1) \ + X("bombdoor", MI_GARAGEDOOR2) \ + X("door_bombshop", MI_GARAGEDOOR3) \ + X("vheistlocdoor", MI_GARAGEDOOR4) \ + X("door2_garage", MI_GARAGEDOOR5) \ + X("ind_slidedoor", MI_GARAGEDOOR6) \ + X("bankjobdoor", MI_GARAGEDOOR7) \ + X("door_jmsgrage", MI_GARAGEDOOR9) \ + X("ind_safeh_gdoor", MI_GARAGEDOOR10) \ + X("door_sfehousegrge", MI_GARAGEDOOR11) \ + X("shedgaragedoor", MI_GARAGEDOOR12) \ + X("door4_garage", MI_GARAGEDOOR13) \ + X("door_col_compnd_01", MI_GARAGEDOOR14) \ + X("door_col_compnd_02", MI_GARAGEDOOR15) \ + X("door_col_compnd_03", MI_GARAGEDOOR16) \ + X("door_col_compnd_04", MI_GARAGEDOOR17) \ + X("door_col_compnd_05", MI_GARAGEDOOR18) \ + X("impex_door", MI_GARAGEDOOR19) \ + X("SalvGarage", MI_GARAGEDOOR20) \ + X("door3_garage", MI_GARAGEDOOR21) \ + X("leveldoor2", MI_GARAGEDOOR22) \ + X("double_garage_dr", MI_GARAGEDOOR23) \ + X("amcogaragedoor", MI_GARAGEDOOR24) \ + X("towergaragedoor1", MI_GARAGEDOOR25) \ + X("towergaragedoor2", MI_GARAGEDOOR26) \ + X("towergaragedoor3", MI_GARAGEDOOR27) \ + X("plysve_gragedoor", MI_GARAGEDOOR28) \ + X("impexpsubgrgdoor", MI_GARAGEDOOR29) \ + X("Sub_sprayshopdoor", MI_GARAGEDOOR30) \ + X("ind_plyrwoor", MI_GARAGEDOOR31) \ + X("8ballsuburbandoor", MI_GARAGEDOOR32) \ + X("door_nthgrage", MI_GARAGEDOOR33) \ + X("hangardoor1", MI_GARAGEDOOR34) \ + X("hangardoor2", MI_GARAGEDOOR35) \ + X("neds_door", MI_GARAGEDOOR36) \ + X("fs_wrhsedoor", MI_GARAGEDOOR37) \ + X("jm_ContraGarage", MI_GARAGEDOOR38) \ + X("jm_imp_SalvGarage", MI_GARAGEDOOR39) \ + X("Testramp1", MI_TESTRAMP1) /* BUG: LCS used MI_TESTRAMP2 here */ \ + X("Testramp2", MI_TESTRAMP2) \ X("barrel2", MI_NAUTICALMINE) \ + X("crushercrush", MI_CRUSHERBODY) \ + X("crushertop", MI_CRUSHERLID) \ + X("donkeymag", MI_DONKEYMAG) \ + X("bullion", MI_BULLION) \ + X("floatpackge1", MI_FLOATPACKAGE1) \ X("briefcase", MI_BRIEFCASE) \ - X("wglasssmash", MI_GLASS1) \ + X("chinabanner1", MI_CHINABANNER1) \ + X("chinabanner2", MI_CHINABANNER2) \ + X("chinabanner3", MI_CHINABANNER3) \ + X("chinabanner4", MI_CHINABANNER4) \ + X("iten_chinatown5", MI_CHINABANNER5) \ + X("iten_chinatown7", MI_CHINABANNER6) \ + X("iten_chinatown3", MI_CHINABANNER7) \ + X("iten_chinatown2", MI_CHINABANNER8) \ + X("iten_chinatown4", MI_CHINABANNER9) \ + X("iten_washline01", MI_CHINABANNER10) \ + X("iten_washline02", MI_CHINABANNER11) \ + X("iten_washline03", MI_CHINABANNER12) \ + X("chinalanterns", MI_CHINALANTERN) \ + X("glassfx1", MI_GLASS1) \ + X("glassfx2", MI_GLASS2) \ + X("glassfx3", MI_GLASS3) \ + X("glassfx4", MI_GLASS4) \ + X("glassfx55", MI_GLASS5) \ + X("glassfxsub1", MI_GLASS6) \ + X("glassfxsub2", MI_GLASS7) \ X("glassfx_composh", MI_GLASS8) \ + X("bridge_liftsec", MI_BRIDGELIFT) \ + X("bridge_liftweight", MI_BRIDGEWEIGHT) \ + X("subbridge_lift", MI_BRIDGEROADSEGMENT) \ + X("flagsitaly", MI_ITALYBANNER1) \ + X("small_helix", MI_SMALL_HELIX) \ X("barrel4", MI_EXPLODINGBARREL) \ + X("Crate_sjl", MI_CRATE_SJL) \ + X("Door1_sjl", MI_DOOR1_SJL) \ + X("Door2_sjl", MI_DOOR2_SJL) \ + X("SJL_PortaCabin", MI_SJL_PORTACABIN) \ + X("SJL_PortaCabinred", MI_SJL_PORTACABINRED) \ + X("megaDamage", MI_MEGADAMAGE) \ + X("regenerator", MI_REGENERATOR) \ + X("invisible", MI_INVISIBLE) \ + X("good_car", MI_GOOD_CAR) \ + X("bad_car", MI_BAD_CAR) \ X("adrenaline", MI_PICKUP_ADRENALINE) \ X("bodyarmour", MI_PICKUP_BODYARMOUR) \ X("info", MI_PICKUP_INFO) \ @@ -82,16 +733,57 @@ X("camerapickup", MI_PICKUP_CAMERA) \ X("bigdollar", MI_PICKUP_REVENUE) \ X("pickupsave", MI_PICKUP_SAVEGAME) \ + X("clothesp", MI_PICKUP_CLOTHES) \ X("property_locked", MI_PICKUP_PROPERTY) \ X("property_fsale", MI_PICKUP_PROPERTY_FORSALE) \ - X("clothesp", MI_PICKUP_CLOTHES) \ X("bollardlight", MI_BOLLARDLIGHT) \ + X("ca_sp1", MI_CA_SP1) \ + X("ca_sp2", MI_CA_SP2) \ + X("ca_sp3", MI_CA_SP3) \ + X("ca_sp4", MI_CA_SP4) \ + X("package1izzy", MI_PACKAGE1IZZY) \ + X("magnet", MI_MAGNET) \ + X("streetlamp1", MI_STREETLAMP1) \ + X("streetlamp2", MI_STREETLAMP2) \ + X("railtrax_lo4b", MI_RAILTRACKS) \ X("bar_barrier10", MI_FENCE) \ X("bar_barrier12", MI_FENCE2) \ X("petrolpump", MI_PETROLPUMP) \ X("washgaspump", MI_PETROLPUMP2) \ + X("bodycast", MI_BODYCAST) \ + X("izzy_confDoor", MI_IZZY_CONFDOOR) \ + X("shipdoor", MI_SHIPDOOR) \ + X("izzy_jdDoor", MI_IZZY_JDDOOR) \ + X("izzy_jdDoor_slider", MI_IZZY_JDDOOR_SLIDER) \ + X("litehouse_gate", MI_LITEHOUSE_GATE) \ + X("coffee", MI_COFFEE) \ X("bouy", MI_BUOY) \ X("parktable1", MI_PARKTABLE) \ + X("sbwy_tunl_start", MI_SUBWAY1) \ + X("sbwy_tunl_bit", MI_SUBWAY2) \ + X("sbwy_tunl_bend", MI_SUBWAY3) \ + X("sbwy_tunl_cstm6", MI_SUBWAY4) \ + X("sbwy_tunl_cstm7", MI_SUBWAY5) \ + X("sbwy_tunl_cstm8", MI_SUBWAY6) \ + X("sbwy_tunl_cstm10", MI_SUBWAY7) \ + X("sbwy_tunl_cstm9", MI_SUBWAY8) \ + X("sbwy_tunl_cstm11", MI_SUBWAY9) \ + X("sbwy_tunl_cstm1", MI_SUBWAY10) \ + X("sbwy_tunl_cstm2", MI_SUBWAY11) \ + X("sbwy_tunl_cstm4", MI_SUBWAY12) \ + X("sbwy_tunl_cstm3", MI_SUBWAY13) \ + X("sbwy_tunl_cstm5", MI_SUBWAY14) \ + X("subplatform_n2", MI_SUBWAY15) \ + X("suby_tunl_start", MI_SUBWAY16) \ + X("sbwy_tunl_start2", MI_SUBWAY17) \ + X("indy_tunl_start", MI_SUBWAY18) \ + X("indsubway03", MI_SUBPLATFORM_IND) \ + X("comerside_subway", MI_SUBPLATFORM_COMS) \ + X("subplatform", MI_SUBPLATFORM_COMS2) \ + X("subplatform_n", MI_SUBPLATFORM_COMN) \ + X("Otherside_subway", MI_SUBPLATFORM_SUB) \ + X("subplatform_sub", MI_SUBPLATFORM_SUB2) \ + X("files", MI_FILES) \ X("lamppost1", MI_LAMPPOST1) \ X("veg_palm04", MI_VEG_PALM01) \ X("veg_palwee02", MI_VEG_PALM02) \ @@ -107,10 +799,12 @@ X("telgrphpole02", MI_TELPOLE02) \ X("trafficlight1", MI_TRAFFICLIGHT01) \ X("parkbench1", MI_PARKBENCH) \ + X("Money", MI_MONEY) \ X("plc_stinger", MI_PLC_STINGER) \ X("od_lightbeam", MI_LIGHTBEAM) \ X("ap_radar1_01", MI_AIRPORTRADAR) \ X("rcbomb", MI_RCBOMB) \ + X("jm_salradio", MI_JM_SALRADIO) \ X("beachball", MI_BEACHBALL) \ X("sandcastle1", MI_SANDCASTLE1) \ X("sandcastle2", MI_SANDCASTLE2) \ @@ -138,11 +832,42 @@ X("blimp_night", MI_BLIMP_NIGHT) \ X("blimp_day", MI_BLIMP_DAY) \ X("yt_main_body", MI_YT_MAIN_BODY) \ - X("yt_main_body2", MI_YT_MAIN_BODY2) + X("pt_barrier", MI_PT_BARRIER) \ + X("subwaygate", MI_SUBWAYGATE) \ + X("in_PMbridramp3", MI_IN_PMBRIDRAMP3) \ + X("in_PMbridg2_upgs", MI_IN_PMBRIDG2_UPGS) \ + X("in_PMbridge2", MI_IN_PMBRIDGE2) \ + X("in_PMbridg1_upgs", MI_IN_PMBRIDG1_UPGS) \ + X("pm_lightrig3", MI_PM_LIGHTRIG3) \ + X("pm_lightrig1", MI_PM_LIGHTRIG1) \ + X("in_pmSCAFF_UPS", MI_IN_PMSCAFF_UPS) \ + X("in_pm_concblok2", MI_IN_PM_CONCBLOK2) \ + X("in_pmSCAFFH_ns", MI_IN_PMSCAFFH_NS) \ + X("in_pm_gravl_jmp", MI_IN_PM_GRAVL_JMP) \ + X("in_pm_scaffcovr", MI_IN_PM_SCAFFCOVR) \ + X("in_pm_girder2", MI_IN_PM_GIRDER2) \ + X("in_pm_scaffH_we", MI_IN_PM_SCAFFH_WE) \ + X("in_pm_sixconc2", MI_IN_PM_SIXCONC2) \ + X("in_BMbridramp3", MI_IN_BMBRIDRAMP3) \ + X("in_BMbridg2_upgs", MI_IN_BMBRIDG2_UPGS) \ + X("in_BMbridge2", MI_IN_BMBRIDGE2) \ + X("in_BMbridg1_upgs", MI_IN_BMBRIDG1_UPGS) \ + X("Bm_lightrig3", MI_BM_LIGHTRIG3) \ + X("bm_lightrig1", MI_BM_LIGHTRIG1) \ + X("in_BmSCAFF_UPS", MI_IN_BMSCAFF_UPS) \ + X("in_Bm_concblok2", MI_IN_BM_CONCBLOK2) \ + X("in_BmSCAFFH_ns", MI_IN_BMSCAFFH_NS) \ + X("in_Bm_gravl_jmp", MI_IN_BM_GRAVL_JMP) \ + X("in_Bm_scaffcovr", MI_IN_BM_SCAFFCOVR) \ + X("in_Bm_girder2", MI_IN_BM_GIRDER2) \ + X("in_Bm_scaffH_we", MI_IN_BM_SCAFFH_WE) \ + X("in_Bm_sixconc2", MI_IN_BM_SIXCONC2) + + /*X("yt_main_body2", MI_YT_MAIN_BODY2) \*/ -#define X(name, var) extern int16 var; - MODELINDICES -#undef X +//#define X(name, var) extern int16 var; +// MODELINDICES +//#undef X // and some hardcoded ones // expand as needed @@ -157,96 +882,87 @@ enum MI_FIREMAN, MI_MALE01, - MI_HFYST = 9, - MI_HFOST, - MI_HMYST, - MI_HMOST, - MI_HFYRI, - MI_HFORI, - MI_HMYRI, - MI_HMORI, - MI_HFYBE, - MI_HFOBE, - MI_HMYBE, - MI_HMOBE, - MI_HFYBU, - MI_HFYMD, - MI_HFYCG, - MI_HFYPR, - MI_HFOTR, - MI_HMOTR, - MI_HMYAP, - MI_HMOCA, - MI_TAXI_D = MI_HMOCA, - MI_BMODK, - MI_BMYKR, - MI_BFYST, - MI_BFOST, - MI_BMYST, - MI_BMOST, - MI_BFYRI, - MI_BFORI, - MI_BMYRI, - MI_BFYBE, - MI_BMYBE, - MI_BFOBE, - MI_BMOBE, - MI_BMYBU, - MI_BFYPR, - MI_BFOTR, - MI_BMOTR, - MI_BMYPI, - MI_BMYBB, - MI_WMYCR, - MI_WFYST, - MI_WFOST, - MI_WMYST, - MI_WMOST, - MI_WFYRI, - MI_WFORI, - MI_WMYRI, - MI_WMORI, - MI_WFYBE, - MI_WMYBE, - MI_WFOBE, - MI_WMOBE, - MI_WMYCW, - MI_WMYGO, - MI_WFOGO, - MI_WMOGO, - MI_WFYLG, - MI_WMYLG, - MI_WFYBU, - MI_WMYBU, - MI_WMOBU, - MI_WFYPR, - MI_WFOTR, - MI_WMOTR, - MI_WMYPI, - MI_WMOCA, - MI_WFYJG, - MI_WMYJG, - MI_WFYSK, - MI_WMYSK, - MI_WFYSH, - MI_WFOSH, - MI_JFOTO, - MI_JMOTO, + MI_TAXI_D = 9, + MI_PIMP, + MI_CRIMINAL01, + MI_CRIMINAL02, + MI_MALE02, + MI_MALE03, + MI_FATMALE01, + MI_FATMALE02, + MI_FEMALE01, + MI_FEMALE02, + MI_FEMALE03, + MI_FATFEMALE01, + MI_FATFEMALE02, + MI_PROSTITUTE, + MI_PROSTITUTE2, + MI_P_MAN1, + MI_P_MAN2, + MI_P_WOM1, + MI_P_WOM2, + MI_CT_MAN1, + MI_CT_MAN2, + MI_CT_WOM1, + MI_CT_WOM2, + MI_LI_MAN1, + MI_LI_MAN2, + MI_LI_WOM1, + MI_LI_WOM2, + MI_DOCKER1, + MI_DOCKER2, + MI_SCUM_MAN, + MI_SCUM_WOM, + MI_WORKER1, + MI_WORKER2, + MI_B_MAN1, + MI_B_MAN2, + MI_B_MAN3, + MI_B_WOM1, + MI_B_WOM2, + MI_B_WOM3, + MI_MOD_MAN, + MI_MOD_WOM, + MI_ST_MAN, + MI_ST_WOM, + MI_FAN_MAN1, + MI_FAN_MAN2, + MI_FAN_WOM, + MI_HOS_MAN, + MI_HOS_WOM, + MI_CONST1, + MI_CONST2, + MI_SHOPPER1, + MI_SHOPPER2, + MI_SHOPPER3, + MI_STUD_MAN, + MI_STUD_WOM, + MI_CAS_MAN, + MI_CAS_WOM, + MI_CAMP_MAN, + MI_CAMP_WOM, + MI_HITMAN, - MI_CBA,// = 83, - MI_CBB, - MI_HNA, - MI_HNB, - MI_SGA, - MI_SGB, - MI_CLA, - MI_CLB, - MI_GDA, - MI_GDB, - MI_BKA, - MI_BKB, - MI_PGA, - MI_PGB, + MI_JFOTO = 77, + MI_JMOTO, + MI_GANG01, + MI_GANG02, + MI_GANG03, + MI_GANG04, + MI_GANG05, + MI_GANG06, + MI_GANG07, + MI_GANG08, + MI_GANG09, + MI_GANG10, + MI_GANG11, + MI_GANG12, + MI_GANG13, + MI_GANG14, + MI_GANG15, + MI_GANG16, + MI_GANG17, + MI_GANG18, MI_VICE1, MI_VICE2, MI_VICE3, @@ -283,19 +999,20 @@ enum MI_LAST_PED = MI_SPECIAL21, MI_FIRST_VEHICLE, - MI_LANDSTAL = MI_FIRST_VEHICLE, + MI_SPIDER = MI_FIRST_VEHICLE, + MI_LANDSTAL, MI_IDAHO, MI_STINGER, MI_LINERUN, MI_PEREN, MI_SENTINEL, - MI_RIO, + MI_PATRIOT, MI_FIRETRUCK, MI_TRASH, MI_STRETCH, MI_MANANA, MI_INFERNUS, - MI_VOODOO, + MI_BLISTA, MI_PONY, MI_MULE, MI_CHEETAH, @@ -304,100 +1021,125 @@ enum MI_MOONBEAM, MI_ESPERANT, MI_TAXI, - MI_WASHING, + MI_KURUMA, MI_BOBCAT, MI_MRWHOOP, MI_BFINJECT, - MI_HUNTER, + MI_HEARSE, MI_POLICE, MI_ENFORCER, MI_SECURICA, MI_BANSHEE, - MI_PREDATOR, MI_BUS, MI_RHINO, MI_BARRACKS, - MI_CUBAN, - MI_CHOPPER, - MI_ANGEL, + MI_DODO, MI_COACH, MI_CABBIE, MI_STALLION, MI_RUMPO, MI_RCBANDIT, - MI_ROMERO, - MI_PACKER, - MI_SENTXS, - MI_ADMIRAL, - MI_SQUALO, - MI_SEASPAR, - MI_PIZZABOY, - MI_GANGBUR, - MI_AIRTRAIN, - MI_DEADDODO, - MI_SPEEDER, - MI_REEFER, - MI_TROPIC, + MI_BELLYUP, + MI_MRWONGS, + MI_MAFIA, + MI_YARDIE, + MI_YAKUZA, + MI_DIABLOS, + MI_COLUMB, + MI_HOODS, + MI_PANLANT, MI_FLATBED, MI_YANKEE, - MI_CADDY, - MI_ZEBRA, + MI_BORGNINE, MI_TOPFUN, - MI_SKIMMER, + MI_CAMPVAN, + MI_BALLOT, + MI_SHELBY, + MI_PONTIAC, + MI_ESPRIT, + MI_AMMOTRUK, + MI_HOTROD, + MI_SINDACCO_CAR, + MI_FORELLI_CAR, + MI_FERRY, + MI_GHOST, + MI_SPEEDER, + MI_REEFER, + MI_PREDATOR, + MI_TRAIN, + MI_ESCAPE, + MI_CHOPPER, + MI_AIRTRAIN, + MI_DEADDODO, + MI_ANGEL, + MI_PIZZABOY, + MI_NOODLEBOY, MI_PCJ600, MI_FAGGIO, MI_FREEWAY, - MI_RCBARON, - MI_RCRAIDER, - MI_GLENDALE, - MI_OCEANIC, + MI_ANGEL2, + MI_SANCHEZ2, MI_SANCHEZ, - MI_SPARROW, - MI_PATRIOT, - MI_LOVEFIST, + MI_RCGOBLIN, + MI_RCRAIDER, + MI_HUNTER, + MI_MAVERICK, + MI_POLMAV, + MI_VCNMAV, + + MI_LAST_VEHICLE = MI_VCNMAV, + + + // these indices are original + MI_CADDY = -999, + MI_MARQUIS = -990, + MI_SEASPAR = -986, + MI_SPARROW = -985, + MI_VOODOO = -984, + MI_FBIRANCH = -982, + MI_SANDKING = -981, + MI_COMET = -972, + MI_PHEONIX = -973, + MI_KAUFMAN = -967, + MI_BAGGAGE = -963, + MI_VICECHEE = -954, + MI_RCBARON = -955, + + // these two are unknown + MI_RIO = -992, + MI_TROPIC = -988, + + // HACK HACK, hopefully temporary + MI_SQUALO = -2000, + MI_JETMAX, MI_COASTG, MI_DINGHY, - MI_HERMES, + MI_SKIMMER, + MI_CUBAN, MI_SABRE, + MI_VIRGO, + MI_RANCHER, + MI_BLISTAC, + MI_WASHING, + MI_ADMIRAL, MI_SABRETUR, - MI_PHEONIX, - MI_WALTON, - MI_REGINA, - MI_COMET, MI_DELUXO, + MI_HOTRING, + MI_REGINA, + MI_SENTXS, + MI_GLENDALE, + MI_OCEANIC, + MI_HERMES, + MI_GREENWOO, + MI_LOVEFIST, + MI_GANGBUR, MI_BURRITO, MI_SPAND, - MI_MARQUIS, - MI_BAGGAGE, - MI_KAUFMAN, - MI_MAVERICK, - MI_VCNMAV, - MI_RANCHER, - MI_FBIRANCH, - MI_VIRGO, - MI_GREENWOO, - MI_JETMAX, - MI_HOTRING, - MI_SANDKING, - MI_BLISTAC, - MI_POLMAV, - MI_BOXVILLE, - MI_BENSON, - MI_MESA, - MI_RCGOBLIN, - MI_HOTRINA, - MI_HOTRINB, - MI_BLOODRA, - MI_BLOODRB, - MI_VICECHEE, - - // HACK - MI_TRAIN = -1, - MI_DODO = -2, - - MI_LAST_VEHICLE = MI_VICECHEE, + MI_PACKER, + MI_WALTON, + MI_ROMERO, - MI_WHEEL_RIM, + MI_WHEEL_RIM = 237, MI_WHEEL_OFFROAD, MI_WHEEL_TRUCK, @@ -458,14 +1200,18 @@ enum MI_FINGERS, MI_MINIGUN2, - MI_CUTOBJ01,// = 295, + MI_CUTOBJ01 = 120, MI_CUTOBJ02, MI_CUTOBJ03, MI_CUTOBJ04, MI_CUTOBJ05, + MI_CUTOBJ06, + MI_CUTOBJ07, + MI_CUTOBJ08, + MI_CUTOBJ09, + MI_CUTOBJ10, - - NUM_DEFAULT_MODELS,// = 300 + NUM_DEFAULT_MODELS = 300 }; enum{ @@ -519,11 +1265,7 @@ IsLightThatNeedsRepositioning(int16 id) return id == MI_SINGLESTREETLIGHTS1 || id == MI_SINGLESTREETLIGHTS2 || id == MI_SINGLESTREETLIGHTS3 || - id == MI_TRAFFICLIGHTS_MIAMI || - id == MI_TRAFFICLIGHTS_TWOVERTICAL || - id == MI_MLAMPPOST || - id == MI_STREETLAMP1 || - id == MI_STREETLAMP2; + id == MI_DOUBLESTREETLIGHTS; } inline bool @@ -535,7 +1277,9 @@ IsLightObject(int16 id) id == MI_SINGLESTREETLIGHTS2 || id == MI_SINGLESTREETLIGHTS3 || id == MI_DOUBLESTREETLIGHTS || - id == MI_TRAFFICLIGHTS_TWOVERTICAL; + id == MI_TRAFFICLIGHTS_TWOVERTICAL || + id == MI_TRAFFICLIGHTS || + id == MI_FENCE; } inline bool @@ -554,6 +1298,15 @@ IsLampPost(int16 id) } inline bool +IsLCSTrafficLight(int16 id) +{ + return id == MI_TLIGHT_POST || + id == MI_TLIGHT_WALK || + id == MI_TLIGHT_BOX1 || + id == MI_TLIGHT_BOX2; +} + +inline bool IsBodyPart(int16 id) { return id == MI_BODYPARTA || id == MI_BODYPARTB; @@ -567,24 +1320,26 @@ IsPedModel(int16 id) inline bool IsPalmTreeModel(int16 id) { - return id == MI_VEG_PALM01 || - id == MI_VEG_PALM02 || - id == MI_VEG_PALM03 || - id == MI_VEG_PALM04 || - id == MI_VEG_PALM05 || - id == MI_VEG_PALM06 || - id == MI_VEG_PALM07 || - id == MI_VEG_PALM08; + return false; } inline bool IsTreeModel(int16 id) { - return id == MI_TREE2 || + return id == MI_TREE1 || + id == MI_TREE2 || id == MI_TREE3 || + id == MI_TREE4 || + id == MI_TREE5 || id == MI_TREE6 || + id == MI_TREE7 || id == MI_TREE8 || - IsPalmTreeModel(id); + id == MI_TREE9 || + id == MI_TREE10 || + id == MI_TREE11 || + id == MI_TREE12 || + id == MI_TREE13 || + id == MI_TREE14; } inline bool diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp index 41515e20..2f2bf8bc 100644 --- a/src/modelinfo/ModelInfo.cpp +++ b/src/modelinfo/ModelInfo.cpp @@ -4,8 +4,10 @@ #include "TempColModels.h" #include "ModelIndices.h" #include "ModelInfo.h" +#include "KeyGen.h" -CBaseModelInfo *CModelInfo::ms_modelInfoPtrs[MODELINFOSIZE]; +CBaseModelInfo **CModelInfo::ms_modelInfoPtrs; +int32 CModelInfo::msNumModelInfos; CStore<CSimpleModelInfo, SIMPLEMODELSIZE> CModelInfo::ms_simpleModelStore; CStore<CTimeModelInfo, TIMEMODELSIZE> CModelInfo::ms_timeModelStore; @@ -15,6 +17,8 @@ CStore<CPedModelInfo, PEDMODELSIZE> CModelInfo::ms_pedModelStore; CStore<CVehicleModelInfo, VEHICLEMODELSIZE> CModelInfo::ms_vehicleModelStore; CStore<C2dEffect, TWODFXSIZE> CModelInfo::ms_2dEffectStore; +C2dEffect *gp2dEffects; + void CModelInfo::Initialise(void) { @@ -29,9 +33,12 @@ CModelInfo::Initialise(void) debug("sizeof PedModelStore %d\n", sizeof(ms_pedModelStore)); debug("sizeof 2deffectsModelStore %d\n", sizeof(ms_2dEffectStore)); + ms_modelInfoPtrs = new CBaseModelInfo*[MODELINFOSIZE]; + msNumModelInfos = MODELINFOSIZE; for(i = 0; i < MODELINFOSIZE; i++) ms_modelInfoPtrs[i] = nil; ms_2dEffectStore.Clear(); + gp2dEffects = ms_2dEffectStore.store; ms_simpleModelStore.Clear(); ms_timeModelStore.Clear(); ms_weaponModelStore.Clear(); @@ -107,13 +114,13 @@ CModelInfo::ShutDown(void) for(i = 0; i < ms_2dEffectStore.allocPtr; i++) ms_2dEffectStore.store[i].Shutdown(); - ms_2dEffectStore.Clear(); ms_simpleModelStore.Clear(); ms_timeModelStore.Clear(); ms_weaponModelStore.Clear(); - ms_pedModelStore.Clear(); ms_clumpModelStore.Clear(); ms_vehicleModelStore.Clear(); + ms_pedModelStore.Clear(); + ms_2dEffectStore.Clear(); } CSimpleModelInfo* @@ -184,10 +191,11 @@ CModelInfo::AddVehicleModel(int id) CBaseModelInfo* CModelInfo::GetModelInfo(const char *name, int *id) { + uint32 hashKey = CKeyGen::GetUppercaseKey(name); CBaseModelInfo *modelinfo; - for(int i = 0; i < MODELINFOSIZE; i++){ + for(int i = 0; i < msNumModelInfos; i++){ modelinfo = CModelInfo::ms_modelInfoPtrs[i]; - if(modelinfo && !CGeneral::faststricmp(modelinfo->GetModelName(), name)){ + if(modelinfo && hashKey == modelinfo->GetNameHashKey()){ if(id) *id = i; return modelinfo; @@ -199,51 +207,80 @@ CModelInfo::GetModelInfo(const char *name, int *id) CBaseModelInfo* CModelInfo::GetModelInfo(const char *name, int minIndex, int maxIndex) { + uint32 hashKey = CKeyGen::GetUppercaseKey(name); if (minIndex > maxIndex) return 0; CBaseModelInfo *modelinfo; for(int i = minIndex; i <= maxIndex; i++){ modelinfo = CModelInfo::ms_modelInfoPtrs[i]; - if(modelinfo && !CGeneral::faststricmp(modelinfo->GetModelName(), name)) + if(modelinfo && hashKey == modelinfo->GetNameHashKey()) return modelinfo; } return nil; } +CBaseModelInfo* +CModelInfo::GetModelInfoFromHashKey(uint32 hashKey, int *id) +{ + CBaseModelInfo *modelinfo; + for(int i = 0; i < msNumModelInfos; i++){ + modelinfo = CModelInfo::ms_modelInfoPtrs[i]; + if(modelinfo && hashKey == modelinfo->GetNameHashKey()){ + if(id) + *id = i; + return modelinfo; + } + } + return nil; +} + bool CModelInfo::IsBoatModel(int32 id) { - return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && - ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_BOAT; + CBaseModelInfo *mi = GetModelInfo(id); + return mi && mi->GetModelType() == MITYPE_VEHICLE && + ((CVehicleModelInfo*)mi)->m_vehicleType == VEHICLE_TYPE_BOAT; } bool CModelInfo::IsBikeModel(int32 id) { - return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && - ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_BIKE; + CBaseModelInfo *mi = GetModelInfo(id); + return mi && mi->GetModelType() == MITYPE_VEHICLE && + ((CVehicleModelInfo*)mi)->m_vehicleType == VEHICLE_TYPE_BIKE; } bool CModelInfo::IsCarModel(int32 id) { - return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && - ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_CAR; + CBaseModelInfo *mi = GetModelInfo(id); + return mi && mi->GetModelType() == MITYPE_VEHICLE && + ((CVehicleModelInfo*)mi)->m_vehicleType == VEHICLE_TYPE_CAR; +} + +bool +CModelInfo::IsTrainModel(int32 id) +{ + CBaseModelInfo *mi = GetModelInfo(id); + return mi && mi->GetModelType() == MITYPE_VEHICLE && + ((CVehicleModelInfo*)mi)->m_vehicleType == VEHICLE_TYPE_TRAIN; } bool CModelInfo::IsHeliModel(int32 id) { - return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && - ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_HELI; + CBaseModelInfo *mi = GetModelInfo(id); + return mi && mi->GetModelType() == MITYPE_VEHICLE && + ((CVehicleModelInfo*)mi)->m_vehicleType == VEHICLE_TYPE_HELI; } bool CModelInfo::IsPlaneModel(int32 id) { - return GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE && - ((CVehicleModelInfo*)GetModelInfo(id))->m_vehicleType == VEHICLE_TYPE_PLANE; + CBaseModelInfo *mi = GetModelInfo(id); + return mi && mi->GetModelType() == MITYPE_VEHICLE && + ((CVehicleModelInfo*)mi)->m_vehicleType == VEHICLE_TYPE_PLANE; } void @@ -251,8 +288,48 @@ CModelInfo::ReInit2dEffects() { ms_2dEffectStore.Clear(); - for (int i = 0; i < MODELINFOSIZE; i++) { + for (int i = 0; i < msNumModelInfos; i++) { if (ms_modelInfoPtrs[i]) ms_modelInfoPtrs[i]->Init2dEffects(); } } + +void +CModelInfo::Load(uint32 numModelInfos, CBaseModelInfo **modelInfos) +{ + int i; + + msNumModelInfos = numModelInfos; + ms_modelInfoPtrs = modelInfos; + for(i = 0; i < msNumModelInfos; i++) + if(ms_modelInfoPtrs[i] && ms_modelInfoPtrs[i]->GetModelType() == MITYPE_VEHICLE && + ms_modelInfoPtrs[i]->GetRwObject()) + ((CVehicleModelInfo*)ms_modelInfoPtrs[i])->SetAtomicRenderCallbacks(); +} + +void +CModelInfo::Load2dEffects(uint32 numEffects, C2dEffect *effects) +{ + ms_2dEffectStore.allocPtr = numEffects; + gp2dEffects = effects; +} + +CModelInfo* +CModelInfo::Write(base::cRelocatableChunkWriter &writer) +{ + uint32 i; + uint32 numModelInfos; + + for(numModelInfos = msNumModelInfos; ms_modelInfoPtrs[numModelInfos-1] == nil; numModelInfos--); + writer.AllocateRaw(ms_modelInfoPtrs, sizeof(void*)*numModelInfos, sizeof(void*), false, true); + for(i = 0; i < numModelInfos; i++) + if(ms_modelInfoPtrs[i]){ + writer.AddPatch(ms_modelInfoPtrs[i]); + ms_modelInfoPtrs[i]->Write(writer); + } + + resNumModelInfos = numModelInfos; + resModelInfoPtrs = ms_modelInfoPtrs; + + return this; +} diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h index a0ee0015..60a5e98f 100644 --- a/src/modelinfo/ModelInfo.h +++ b/src/modelinfo/ModelInfo.h @@ -8,11 +8,15 @@ #include "ClumpModelInfo.h" #include "PedModelInfo.h" #include "VehicleModelInfo.h" +#include "XtraCompsModelInfo.h" #include "templates.h" +extern C2dEffect *gp2dEffects; + class CModelInfo { - static CBaseModelInfo *ms_modelInfoPtrs[MODELINFOSIZE]; + static CBaseModelInfo **ms_modelInfoPtrs; + static int32 msNumModelInfos; static CStore<CSimpleModelInfo, SIMPLEMODELSIZE> ms_simpleModelStore; static CStore<CTimeModelInfo, TIMEMODELSIZE> ms_timeModelStore; static CStore<CWeaponModelInfo, WEAPONMODELSIZE> ms_weaponModelStore; @@ -22,6 +26,10 @@ class CModelInfo static CStore<C2dEffect, TWODFXSIZE> ms_2dEffectStore; public: + // these fields are in the resource image + int32 resNumModelInfos; + CBaseModelInfo **resModelInfoPtrs; + static void Initialise(void); static void ShutDown(void); @@ -33,12 +41,18 @@ public: static CVehicleModelInfo *AddVehicleModel(int id); static CStore<C2dEffect, TWODFXSIZE> &Get2dEffectStore(void) { return ms_2dEffectStore; } + static C2dEffect *Get2dEffect(int32 id) { return &gp2dEffects[id]; } + static int32 Get2dEffectIndex(C2dEffect *effect) { return effect - gp2dEffects; } + static int32 GetNumModelInfos(void) { return msNumModelInfos; } static CBaseModelInfo *GetModelInfo(const char *name, int *id); static CBaseModelInfo *GetModelInfo(int id){ + if(id < 0 || id >= msNumModelInfos) + return nil; return ms_modelInfoPtrs[id]; } static CBaseModelInfo *GetModelInfo(const char *name, int minIndex, int maxIndex); + static CBaseModelInfo *GetModelInfoFromHashKey(uint32 hashKey, int *id); static CColModel *GetColModel(int id){ return ms_modelInfoPtrs[id]->GetColModel(); } @@ -46,7 +60,12 @@ public: static bool IsBoatModel(int32 id); static bool IsBikeModel(int32 id); static bool IsCarModel(int32 id); + static bool IsTrainModel(int32 id); static bool IsHeliModel(int32 id); static bool IsPlaneModel(int32 id); static void ReInit2dEffects(); + + static void Load(uint32 numModelInfos, CBaseModelInfo **modelInfos); + static void Load2dEffects(uint32 numEffects, C2dEffect *effects); + CModelInfo *Write(base::cRelocatableChunkWriter &writer); }; diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp index 25b260d3..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,46 +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; - - // From LCS. Otherwise gives FPE -#ifdef FIX_BUGS - spheres[i].center = CVector(0.0f, 0.0f, 0.0f); -#else - 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); -#endif + 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* @@ -120,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; } @@ -159,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 18eb7e5f..ba1cfb40 100644 --- a/src/modelinfo/SimpleModelInfo.cpp +++ b/src/modelinfo/SimpleModelInfo.cpp @@ -1,37 +1,61 @@ #include "common.h" +#include "main.h" #include "General.h" +#include "Renderer.h" #include "Camera.h" #include "Renderer.h" #include "ModelInfo.h" #include "AnimManager.h" #include "custompipes.h" +#include "Streaming.h" +#include "smallHeap.h" +#include "Leeds.h" + +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 == nil || m_atomics[0] == nil) return nil; atomic = RpAtomicClone(m_atomics[0]); RpAtomicSetFrame(atomic, RwFrameCreate()); + CStreaming::RegisterInstance(atomic, nil); return (RwObject*)atomic; } @@ -41,21 +65,20 @@ CSimpleModelInfo::CreateInstance(RwMatrix *matrix) RpAtomic *atomic; RwFrame *frame; - if(m_atomics[0] == nil) + if(m_atomics == nil || 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; @@ -71,21 +94,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,10 +168,46 @@ 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; i = 0; + if(m_atomics == nil) + return nil; if(m_isDamaged) i = m_firstDamaged; for(; i < m_numAtomics; i++) @@ -151,20 +219,40 @@ CSimpleModelInfo::GetAtomicFromDistance(float dist) RpAtomic* CSimpleModelInfo::GetFirstAtomicFromDistance(float dist) { + 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; @@ -172,15 +260,17 @@ CSimpleModelInfo::FindRelatedModel(int32 minID, int32 maxID) } } -#define NEAR_DRAW_DIST 0.0f // 100.0f in liberty city +#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; @@ -192,3 +282,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 d31962ce..21583709 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" @@ -14,20 +15,28 @@ #include "Automobile.h" #include "Boat.h" #include "Train.h" +#include "Ferry.h" #include "Plane.h" #include "Heli.h" #include "Bike.h" #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, @@ -114,6 +123,22 @@ RwObjectNameIdAssocation trainIds[] = { { nil, 0, 0 } }; +RwObjectNameIdAssocation ferryIds[] = { + { "door_front_dummy", FERRY_DOOR_FRONT, VEHICLE_FLAG_LEFT | VEHICLE_FLAG_COLLAPSE }, + { "door_back_dummy", FERRY_DOOR_BACK, VEHICLE_FLAG_LEFT | VEHICLE_FLAG_COLLAPSE }, + { "ramp_front_dummy", FERRY_RAMP_FRONT, VEHICLE_FLAG_LEFT | VEHICLE_FLAG_COLLAPSE }, + { "ramp_back_dummy", FERRY_RAMP_BACK, VEHICLE_FLAG_LEFT | VEHICLE_FLAG_COLLAPSE }, + { "light_front", FERRY_POS_LIGHT_FRONT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "light_rear", FERRY_POS_LIGHT_REAR, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "chim_left", FERRY_POS_CHIM_LEFT, VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "ped_point", FERRY_POS_PED_POINT, VEHICLE_FLAG_DOOR | VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "car1_dummy", FERRY_POS_CAR1, VEHICLE_FLAG_DOOR | VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "car2_dummy", FERRY_POS_CAR2, VEHICLE_FLAG_DOOR | VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "car3_dummy", FERRY_POS_CAR3, VEHICLE_FLAG_DOOR | VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { "car4_dummy", FERRY_POS_CAR4, VEHICLE_FLAG_DOOR | VEHICLE_FLAG_POS | CLUMP_FLAG_NO_HIERID }, + { nil, 0, 0 } +}; + RwObjectNameIdAssocation heliIds[] = { { "chassis_dummy", HELI_CHASSIS, VEHICLE_FLAG_COLLAPSE }, { "toprotor", HELI_TOPROTOR, 0 }, @@ -162,12 +187,36 @@ RwObjectNameIdAssocation *CVehicleModelInfo::ms_vehicleDescs[] = { trainIds, heliIds, planeIds, - bikeIds + bikeIds, + ferryIds }; 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 +227,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 +241,78 @@ 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) +{ +#ifdef FIX_BUGS + if(m_clump == nil) + return; +#endif + 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 +321,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 +335,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 +348,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(); @@ -398,35 +523,76 @@ CVehicleModelInfo::SetAtomicRendererCB_Train(RpAtomic *atomic, void *data) } RpAtomic* -CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data) +CVehicleModelInfo::SetAtomicRendererCB_Ferry(RpAtomic *atomic, void *data) { - RpClump *clump; char *name; bool alpha; - clump = (RpClump*)data; name = GetFrameNodeName(RpAtomicGetFrame(atomic)); alpha = false; RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha); - if(strcmp(name, "boat_hi") == 0 || !CGeneral::faststrncmp(name, "extra", 5)) - CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat); - else if(strstr(name, "_hi")){ + if(strstr(name, "_hi")){ if(alpha) - CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat); + CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderTrainHiDetailAlphaCB); else - CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB); + 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; + 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); + 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); - else{ - if(alpha) - CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat); - else - CVisibilityPlugins::SetAtomicRenderCallback(atomic, nil); - } + 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); return atomic; } @@ -434,6 +600,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)); @@ -442,6 +609,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; } @@ -486,13 +654,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); @@ -540,6 +713,8 @@ CVehicleModelInfo::PreprocessHierarchy(void) m_numDoors = 0; m_numComps = 0; + m_comps = new RpAtomic*[7]; + for(i = 0; desc[i].name; i++){ RwObjectNameAssociation assoc; @@ -597,21 +772,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); + } } } } @@ -756,7 +933,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){ @@ -765,8 +942,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; } @@ -779,7 +956,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)) && @@ -790,8 +967,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; } @@ -859,7 +1036,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; @@ -870,7 +1047,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; @@ -995,8 +1172,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; @@ -1028,10 +1205,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 @@ -1061,6 +1238,7 @@ CVehicleModelInfo::LoadVehicleColours(void) void CVehicleModelInfo::DeleteVehicleColourTextures(void) { +/* int i; for(i = 0; i < 256; i++){ @@ -1069,6 +1247,7 @@ CVehicleModelInfo::DeleteVehicleColourTextures(void) ms_colourTextureTable[i] = nil; } } +*/ } RpMaterial* @@ -1080,6 +1259,7 @@ CVehicleModelInfo::GetMatFXEffectMaterialCB(RpMaterial *material, void *data) return nil; } +/* RpMaterial* CVehicleModelInfo::SetDefaultEnvironmentMapCB(RpMaterial *material, void *data) { @@ -1096,7 +1276,9 @@ CVehicleModelInfo::SetDefaultEnvironmentMapCB(RpMaterial *material, void *data) } return material; } +*/ +/* RpAtomic* CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data) { @@ -1112,10 +1294,12 @@ CVehicleModelInfo::SetEnvironmentMapCB(RpAtomic *atomic, void *data) } return atomic; } +*/ void CVehicleModelInfo::SetEnvironmentMap(void) { +/* CSimpleModelInfo *wheelmi; int32 i; @@ -1133,6 +1317,7 @@ CVehicleModelInfo::SetEnvironmentMap(void) for(i = 0; i < wheelmi->m_numAtomics; i++) SetEnvironmentMapCB(wheelmi->m_atomics[i], nil); } +*/ #ifdef EXTENDED_PIPELINES CustomPipes::AttachVehiclePipe(m_clump); @@ -1147,21 +1332,23 @@ CVehicleModelInfo::LoadEnvironmentMaps(void) txdslot = CTxdStore::FindTxdSlot("particle"); CTxdStore::PushCurrentTxd(); CTxdStore::SetCurrentTxd(txdslot); - if(gpWhiteTexture == nil){ + /*if(gpWhiteTexture == nil){ gpWhiteTexture = RwTextureRead("white", nil); RwTextureGetName(gpWhiteTexture)[0] = '@'; RwTextureSetFilterMode(gpWhiteTexture, rwFILTERLINEAR); - } + }*/ CTxdStore::PopCurrentTxd(); } void CVehicleModelInfo::ShutdownEnvironmentMaps(void) { +/* RwTextureDestroy(gpWhiteTexture); gpWhiteTexture = nil; RwFrameDestroy(pMatFxIdentityFrame); pMatFxIdentityFrame = nil; +*/ } int @@ -1184,10 +1371,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 c7a41126..6f2cea3c 100644 --- a/src/modelinfo/VehicleModelInfo.h +++ b/src/modelinfo/VehicleModelInfo.h @@ -3,8 +3,8 @@ #include "ClumpModelInfo.h" enum { - NUM_FIRST_MATERIALS = 24, - NUM_SECOND_MATERIALS = 20, + NUM_FIRST_MATERIALS = 25, + NUM_SECOND_MATERIALS = 25, NUM_VEHICLE_COLOURS = 8, }; @@ -31,6 +31,7 @@ enum eVehicleType { VEHICLE_TYPE_HELI, VEHICLE_TYPE_PLANE, VEHICLE_TYPE_BIKE, + VEHICLE_TYPE_FERRY, NUM_VEHICLE_TYPES }; @@ -48,6 +49,18 @@ enum eBoatPositions BOAT_POS_FRONTSEAT }; +enum eFerryPositions +{ + FERRY_POS_LIGHT_FRONT, + FERRY_POS_LIGHT_REAR, + FERRY_POS_CHIM_LEFT, + FERRY_POS_PED_POINT, + FERRY_POS_CAR1, + FERRY_POS_CAR2, + FERRY_POS_CAR3, + FERRY_POS_CAR4 +}; + enum eTrainPositions { TRAIN_POS_LIGHT_FRONT, @@ -97,19 +110,30 @@ public: uint8 m_lastColorVariation; uint8 m_currentColour1; uint8 m_currentColour2; - RpAtomic *m_comps[6]; + 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); @@ -118,6 +142,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); @@ -127,13 +157,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); @@ -159,7 +192,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/modelinfo/XtraCompsModelInfo.cpp b/src/modelinfo/XtraCompsModelInfo.cpp new file mode 100644 index 00000000..c11edaf8 --- /dev/null +++ b/src/modelinfo/XtraCompsModelInfo.cpp @@ -0,0 +1,21 @@ +#include "common.h" + +#include "VisibilityPlugins.h" +#include "ModelInfo.h" + +base::cRelocatableChunkClassInfo CXtraCompsModelInfo::msClassInfo("CXtraCompsModelInfo", VTABLE_ADDR(&msClassInstance), sizeof(msClassInstance)); +CXtraCompsModelInfo CXtraCompsModelInfo::msClassInstance; + +void +CXtraCompsModelInfo::RcWriteThis(base::cRelocatableChunkWriter &writer) +{ + writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true); + writer.Class(VTABLE_ADDR(this), msClassInfo); +} + +void +CXtraCompsModelInfo::RcWriteEmpty(base::cRelocatableChunkWriter &writer) +{ + writer.AllocateRaw(this, sizeof(*this), sizeof(void*), false, true); + writer.Class(VTABLE_ADDR(this), msClassInfo); +} diff --git a/src/modelinfo/XtraCompsModelInfo.h b/src/modelinfo/XtraCompsModelInfo.h new file mode 100644 index 00000000..7cd9b7ea --- /dev/null +++ b/src/modelinfo/XtraCompsModelInfo.h @@ -0,0 +1,19 @@ +#pragma once + +#include "ClumpModelInfo.h" + +class CXtraCompsModelInfo : public CClumpModelInfo +{ + int field_34; +public: + CXtraCompsModelInfo(void) : CClumpModelInfo(MITYPE_XTRACOMPS) { field_34 = 0; } + void Shutdown(void) {}; + RwObject *CreateInstance(void) { return nil; } + void SetClump(RpClump*) {}; + + virtual void RcWriteThis(base::cRelocatableChunkWriter &writer); + virtual void RcWriteEmpty(base::cRelocatableChunkWriter &writer); + + static base::cRelocatableChunkClassInfo msClassInfo; + static CXtraCompsModelInfo msClassInstance; +};
\ No newline at end of file |