From a9f39d828426df60876f00a5d2164eb50879b5c9 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Mon, 20 Jan 2020 22:41:41 +0200 Subject: [PATCH] MLO, XtraCompsModelInfo, MovingThing, Solid --- src/core/FileLoader.cpp | 59 +++++++++++++++++++-- src/core/FileLoader.h | 2 + src/core/Instance.h | 4 +- src/core/config.h | 3 ++ src/entities/Solid.h | 14 +++++ src/modelinfo/MloModelInfo.cpp | 39 ++++++++++++++ src/modelinfo/MloModelInfo.h | 14 +++++ src/modelinfo/ModelInfo.cpp | 25 +++++++++ src/modelinfo/ModelInfo.h | 8 +++ src/modelinfo/XtraCompsModelInfo.h | 12 +++++ src/render/Fluff.cpp | 84 ++++++++++++++++++++++++++---- src/render/Fluff.h | 31 ++++++++--- 12 files changed, 272 insertions(+), 23 deletions(-) create mode 100644 src/entities/Solid.h create mode 100644 src/modelinfo/MloModelInfo.cpp create mode 100644 src/modelinfo/MloModelInfo.h create mode 100644 src/modelinfo/XtraCompsModelInfo.h diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp index 6f3b0971..4662b508 100644 --- a/src/core/FileLoader.cpp +++ b/src/core/FileLoader.cpp @@ -511,11 +511,11 @@ CFileLoader::LoadObjectTypes(const char *filename) int pathIndex; char pathTypeStr[20]; int id, pathType; -// int mlo; + int mlo; section = NONE; pathIndex = -1; -// mlo = 0; + mlo = 0; debug("Loading object types from %s...\n", filename); fd = CFileMgr::OpenFile(filename, "rb"); @@ -536,12 +536,12 @@ CFileLoader::LoadObjectTypes(const char *filename) }else switch(section){ case OBJS: if(strncmp(line, "sta", 3) == 0) - assert(0); // LoadMLO + mlo = LoadMLO(line); else LoadObject(line); break; case MLO: - assert(0); // LoadMLOInstance + LoadMLOInstance(mlo, line); break; case TOBJ: LoadTimeObject(line); @@ -644,6 +644,57 @@ CFileLoader::LoadObject(const char *line) MatchModelString(model, id); } +int +CFileLoader::LoadMLO(const char *line) +{ + char smth[8]; + char name[24]; + int modelIndex; + float someFloat; + + sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &someFloat); + CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex); + minfo->SetName(name); + minfo->field_34 = someFloat; + int instId = CModelInfo::GetMloInstanceStore()->allocPtr; + minfo->firstInstance = instId; + minfo->lastInstance = instId; + minfo->SetTexDictionary("generic"); + return modelIndex; +} + +void +CFileLoader::LoadMLOInstance(int id, const char *line) +{ + char name[24]; + RwV3d pos, scale, rot; + float angle; + int modelIndex; + + CMloModelInfo *minfo = (CMloModelInfo*)CModelInfo::GetModelInfo(id); + sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f", + &modelIndex, + name, + &pos.x, &pos.y, &pos.z, + &scale.x, &scale.y, &scale.z, + &rot.x, &rot.y, &rot.z, + &angle); + float rad = 2.0f * (PI / 2.0f - atan2(angle, sqrt(1.0f - SQR(angle)))); + CInstance *inst = CModelInfo::GetMloInstanceStore()->alloc(); + minfo->lastInstance++; + + RwMatrix *matrix = RwMatrixCreate(); + RwMatrixScale(matrix, &scale, rwCOMBINEREPLACE); + RwMatrixRotate(matrix, &rot, -RADTODEG(rad), rwCOMBINEPOSTCONCAT); + RwMatrixTranslate(matrix, &pos, rwCOMBINEPOSTCONCAT); + + inst->GetMatrix() = CMatrix(matrix); + inst->GetMatrix().UpdateRW(); + + inst->m_modelIndex = modelIndex; + RwMatrixDestroy(matrix); +} + void CFileLoader::LoadTimeObject(const char *line) { diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h index 7ef96da3..1b390279 100644 --- a/src/core/FileLoader.h +++ b/src/core/FileLoader.h @@ -23,6 +23,8 @@ public: static void LoadObjectTypes(const char *filename); static void LoadObject(const char *line); + static int LoadMLO(const char *line); + static void LoadMLOInstance(int id, const char *line); static void LoadTimeObject(const char *line); static void LoadClumpObject(const char *line); static void LoadVehicleObject(const char *line); diff --git a/src/core/Instance.h b/src/core/Instance.h index bb74ea84..4a7f9aa9 100644 --- a/src/core/Instance.h +++ b/src/core/Instance.h @@ -4,8 +4,10 @@ // unused -class CInstance : CPlaceable +class CInstance : public CPlaceable { +public: + int m_modelIndex; public: ~CInstance() = default; }; diff --git a/src/core/config.h b/src/core/config.h index cbaf4d9a..de96ad1b 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -11,10 +11,13 @@ enum Config { CUTSCENEDIRSIZE = 512, SIMPLEMODELSIZE = 5000, + MLOMODELSIZE = 1, + MLOINSTANCESIZE = 1, TIMEMODELSIZE = 30, CLUMPMODELSIZE = 5, PEDMODELSIZE = 90, VEHICLEMODELSIZE = 120, + XTRACOMPSMODELSIZE = 2, TWODFXSIZE = 2000, MAXVEHICLESLOADED = 50, // 70 on mobile diff --git a/src/entities/Solid.h b/src/entities/Solid.h new file mode 100644 index 00000000..f4679b3b --- /dev/null +++ b/src/entities/Solid.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Entity.h" + +class CSolid : public CEntity +{ +public: + CSolid(void) { + bRemoveFromWorld = true; + bHasHitWall = false; + bImBeingRendered = false; + m_flagE2 = true; + } +}; \ No newline at end of file diff --git a/src/modelinfo/MloModelInfo.cpp b/src/modelinfo/MloModelInfo.cpp new file mode 100644 index 00000000..693f1fb6 --- /dev/null +++ b/src/modelinfo/MloModelInfo.cpp @@ -0,0 +1,39 @@ +#include "common.h" +#include "patcher.h" +#include "VisibilityPlugins.h" +#include "ModelInfo.h" + +void +CMloModelInfo::ConstructClump() +{ + m_clump = RpClumpCreate(); + RwFrame *mainFrame = RwFrameCreate(); + RwFrameSetIdentity(mainFrame); + RpClumpSetFrame(m_clump, mainFrame); + + for (int i = firstInstance; i < lastInstance; i++) { + int modelId = CModelInfo::GetMloInstanceStore()->store[i].m_modelIndex; + RwMatrix *attMat = CModelInfo::GetMloInstanceStore()->store[i].GetMatrix().m_attachment; + CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(modelId); + + if (minfo->m_atomics[0] != nil) { + RpAtomic *newAtomic = RpAtomicClone(minfo->m_atomics[0]); + RwFrame *newFrame = RwFrameCreate(); + if (newAtomic != nil && newFrame != nil) { + *RwFrameGetMatrix(newFrame) = *attMat; + RpAtomicSetFrame(newAtomic, newFrame); + RwFrameAddChild(mainFrame, newFrame); + RpClumpAddAtomic(m_clump, newAtomic); + } else { + debug("Failed to allocate memory while creating template MLO.\n"); + } + } + } + + if (RpClumpGetNumAtomics(m_clump) != 0) { + CVisibilityPlugins::SetClumpModelInfo(m_clump, this); + } else { + RpClumpDestroy(m_clump); + m_clump = nil; + } +} \ No newline at end of file diff --git a/src/modelinfo/MloModelInfo.h b/src/modelinfo/MloModelInfo.h new file mode 100644 index 00000000..19ae63d5 --- /dev/null +++ b/src/modelinfo/MloModelInfo.h @@ -0,0 +1,14 @@ +#pragma once + +#include "ClumpModelInfo.h" + +class CMloModelInfo : public CClumpModelInfo +{ +public: + float field_34; // draw distance? + int firstInstance; + int lastInstance; +public: + CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {} + void ConstructClump(); +}; \ No newline at end of file diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp index c7e18e5f..fdde699b 100644 --- a/src/modelinfo/ModelInfo.cpp +++ b/src/modelinfo/ModelInfo.cpp @@ -11,10 +11,13 @@ CBaseModelInfo **CModelInfo::ms_modelInfoPtrs = (CBaseModelInfo**)0x83D408; //CStore &CModelInfo::ms_timeModelStore = *(CStore*)0x94076C; //CStore &CModelInfo::ms_2dEffectStore = *(CStore*)0x9434F8; CStore CModelInfo::ms_simpleModelStore; +CStore CModelInfo::ms_mloModelStore; +CStore CModelInfo::ms_mloInstanceStore; CStore CModelInfo::ms_timeModelStore; CStore CModelInfo::ms_clumpModelStore; CStore CModelInfo::ms_pedModelStore; CStore CModelInfo::ms_vehicleModelStore; +CStore CModelInfo::ms_xtraCompsModelStore; CStore CModelInfo::ms_2dEffectStore; void @@ -26,8 +29,11 @@ CModelInfo::Initialise(void) for(i = 0; i < MODELINFOSIZE; i++) ms_modelInfoPtrs[i] = nil; ms_2dEffectStore.clear(); + ms_mloInstanceStore.clear(); + ms_xtraCompsModelStore.clear(); ms_simpleModelStore.clear(); ms_timeModelStore.clear(); + ms_mloModelStore.clear(); ms_clumpModelStore.clear(); ms_pedModelStore.clear(); ms_vehicleModelStore.clear(); @@ -109,6 +115,18 @@ CModelInfo::AddSimpleModel(int id) return modelinfo; } +CMloModelInfo * +CModelInfo::AddMloModel(int id) +{ + CMloModelInfo *modelinfo; + modelinfo = CModelInfo::ms_mloModelStore.alloc(); + CModelInfo::ms_modelInfoPtrs[id] = modelinfo; + modelinfo->m_clump = 0; + modelinfo->firstInstance = 0; + modelinfo->lastInstance = 0; + return modelinfo; +} + CTimeModelInfo* CModelInfo::AddTimeModel(int id) { @@ -200,6 +218,13 @@ CModelInfo::RemoveColModelsFromOtherLevels(eLevelName level) } } + +CStore* +CModelInfo::GetMloInstanceStore() +{ + return &CModelInfo::ms_mloInstanceStore; +} + STARTPATCHES InjectHook(0x50B310, CModelInfo::Initialise, PATCH_JUMP); InjectHook(0x50B5B0, CModelInfo::ShutDown, PATCH_JUMP); diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h index ee82276d..1a295264 100644 --- a/src/modelinfo/ModelInfo.h +++ b/src/modelinfo/ModelInfo.h @@ -3,26 +3,33 @@ #include "2dEffect.h" #include "BaseModelInfo.h" #include "SimpleModelInfo.h" +#include "MloModelInfo.h" #include "TimeModelInfo.h" #include "ClumpModelInfo.h" #include "PedModelInfo.h" #include "VehicleModelInfo.h" +#include "XtraCompsModelInfo.h" +#include "Instance.h" class CModelInfo { static CBaseModelInfo **ms_modelInfoPtrs; //[MODELINFOSIZE]; static CStore ms_simpleModelStore; + static CStore ms_mloModelStore; + static CStore ms_mloInstanceStore; static CStore ms_timeModelStore; static CStore ms_clumpModelStore; static CStore ms_pedModelStore; static CStore ms_vehicleModelStore; static CStore ms_2dEffectStore; + static CStore ms_xtraCompsModelStore; public: static void Initialise(void); static void ShutDown(void); static CSimpleModelInfo *AddSimpleModel(int id); + static CMloModelInfo *AddMloModel(int id); static CTimeModelInfo *AddTimeModel(int id); static CClumpModelInfo *AddClumpModel(int id); static CPedModelInfo *AddPedModel(int id); @@ -38,4 +45,5 @@ public: static bool IsBoatModel(int32 id); static bool IsBikeModel(int32 id); static void RemoveColModelsFromOtherLevels(eLevelName level); + static CStore* CModelInfo::GetMloInstanceStore(); }; diff --git a/src/modelinfo/XtraCompsModelInfo.h b/src/modelinfo/XtraCompsModelInfo.h new file mode 100644 index 00000000..bb37ffe3 --- /dev/null +++ b/src/modelinfo/XtraCompsModelInfo.h @@ -0,0 +1,12 @@ +#pragma once + +#include "ClumpModelInfo.h" + +class CXtraCompsModelInfo : public CClumpModelInfo +{ + int field_34; +public: + CXtraCompsModelInfo(void) : CClumpModelInfo(MITYPE_XTRACOMPS) { field_34 = 0; } + void SetClump(RpClump*) {}; + void Shutdown(void) {}; +}; \ No newline at end of file diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index fc68d315..e0db5732 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -1,6 +1,7 @@ #include "common.h" #include "main.h" #include "patcher.h" +#include "Entity.h" #include "Fluff.h" #include "Camera.h" #include "Sprite.h" @@ -90,12 +91,19 @@ enum eScrollBarTypes CScrollBar aScrollBars[11]; CTowerClock aTowerClocks[2]; CDigitalClock aDigitalClocks[3]; + +CMovingThing CMovingThings::StartCloseList; +CMovingThing CMovingThings::EndCloseList; +int16 CMovingThings::Num; +CMovingThing CMovingThings::aMovingThings[NUMMOVINGTHINGS]; void CMovingThings::Init() { - /* - * Some unused code about CMovingThing was here... - */ + StartCloseList.m_pNext = &CMovingThings::EndCloseList; + StartCloseList.m_pPrev = nil; + EndCloseList.m_pNext = nil; + EndCloseList.m_pPrev = &CMovingThings::StartCloseList; + Num = 0; // Initialize scroll bars aScrollBars[0].Init(CVector( 228.3f, -669.0f, 39.0f ), SCROLL_BUSINESS, 0.0, 0.5, 0.5, 255, 128, 0, 0.3); @@ -144,11 +152,22 @@ void CMovingThings::Shutdown() void CMovingThings::Update() { - /* - * Some unused code about CMovingThing was here... - */ + const int TIME_SPAN = 64; // frames to process all aMovingThings + + int16 i; + + int block = CTimer::GetFrameCounter() % TIME_SPAN; + + for (i = (block * NUMMOVINGTHINGS) / TIME_SPAN; i < ((block + 1) * NUMMOVINGTHINGS) / TIME_SPAN; i++) { + if (aMovingThings[i].field_A == 1) + aMovingThings[i].Update(); + } + + for (i = 0; i < CMovingThings::Num; i++) { + if (aMovingThings[i].field_A == 0) + aMovingThings[i].Update(); + } - int i; for (i = 0; i < 11; ++i) { if (aScrollBars[i].IsVisible() || (CTimer::GetFrameCounter() + i) % 8 == 0) @@ -187,9 +206,50 @@ void CMovingThings::Render() } // ---------- CMovingThing ---------- -WRAPPER void CMovingThing::Update() { EAXJMP(0x4FF290); } -WRAPPER void CMovingThing::AddToList() { EAXJMP(0x4FF320); } -WRAPPER void CMovingThing::RemoveFromList() { EAXJMP(0x4FF340); } +void CMovingThing::Update() +{ + m_pEntity->GetMatrix().UpdateRW(); + m_pEntity->UpdateRwFrame(); + + if (SQR(m_pEntity->GetPosition().x - TheCamera.GetPosition().x) + SQR(m_pEntity->GetPosition().y - TheCamera.GetPosition().y) < 40000.0f) { + if (field_A == 1) { + AddToList(&CMovingThings::StartCloseList); + field_A = 0; + } + } else { + if (field_A == 0) { + RemoveFromList(); + field_A = 1; + } + } +} + +void CMovingThing::AddToList(CMovingThing *pThing) +{ + m_pNext = pThing->m_pNext; + m_pPrev = pThing; + pThing->m_pNext = this; + m_pNext->m_pPrev = this; +} + +void CMovingThing::RemoveFromList() +{ + m_pNext->m_pPrev = m_pPrev; + m_pPrev->m_pNext = m_pNext; +} + +int16 CMovingThing::SizeList() +{ + CMovingThing *next = m_pNext; + int16 count = 0; + + while (next != nil) { + next = next->m_pNext; + count++; + } + + return count; +} // ---------- Find message functions ---------- const char* FindTunnelMessage() @@ -806,6 +866,10 @@ void CDigitalClock::Render() } STARTPATCHES +InjectHook(0x4FF290, &CMovingThing::Update, PATCH_JUMP); +InjectHook(0x4FF320, &CMovingThing::AddToList, PATCH_JUMP); +InjectHook(0x4FF340, &CMovingThing::RemoveFromList, PATCH_JUMP); + InjectHook(0x4FE7C0, &CMovingThings::Init, PATCH_JUMP); InjectHook(0x4FF020, &CMovingThings::Shutdown, PATCH_JUMP); InjectHook(0x4FF0D0, &CMovingThings::Update, PATCH_JUMP); diff --git a/src/render/Fluff.h b/src/render/Fluff.h index b189b9a2..7ab2d81d 100644 --- a/src/render/Fluff.h +++ b/src/render/Fluff.h @@ -2,23 +2,38 @@ #include "common.h" #include "Vector.h" +class CMovingThing +{ +public: + CMovingThing *m_pNext; + CMovingThing *m_pPrev; + int16 m_nType; + int16 field_A; + CVector m_vecPosn; + CEntity* m_pEntity; + + void Update(); + void AddToList(CMovingThing *pThing); + void RemoveFromList(); + int16 SizeList(); +}; + +#define NUMMOVINGTHINGS 128 + class CMovingThings { public: + static CMovingThing StartCloseList; + static CMovingThing EndCloseList; + static int16 Num; + static CMovingThing aMovingThings[NUMMOVINGTHINGS]; + static void Init(); static void Shutdown(); static void Update(); static void Render(); }; -class CMovingThing -{ -public: - void Update(); - void AddToList(); - void RemoveFromList(); -}; - class CScrollBar { private: