diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 424523bb..a5957f26 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -31,6 +31,32 @@ typedef set LegoPathCtrlEdgeSet; // SIZE 0x40 class LegoPathController : public MxCore { public: + // SIZE 0x08 + struct CtrlBoundary { + // FUNCTION: LEGO1 0x10046dc0 + CtrlBoundary() + { + m_controller = NULL; + m_boundary = NULL; + } + + LegoPathController* m_controller; // 0x00 + LegoPathBoundary* m_boundary; // 0x04 + }; + + // SIZE 0x08 + struct CtrlEdge { + // FUNCTION: LEGO1 0x10046dd0 + CtrlEdge() + { + m_controller = NULL; + m_edge = NULL; + } + + LegoPathController* m_controller; // 0x00 + LegoEdge* m_edge; // 0x04 + }; + LegoPathController(); ~LegoPathController() override { Destroy(); } @@ -52,8 +78,8 @@ class LegoPathController : public MxCore { // SYNTHETIC: LEGO1 0x10045740 // LegoPathController::`scalar deleting destructor' - virtual void Create(MxU8* p_data, Vector3& p_location, MxAtomId& p_trigger); // vtable+0x14 - virtual void Destroy(); // vtable+0x18 + virtual MxResult Create(MxU8* p_data, const Vector3& p_location, const MxAtomId& p_trigger); // vtable+0x14 + virtual void Destroy(); // vtable+0x18 MxResult FUN_10045c20( LegoPathActor* p_actor, @@ -70,6 +96,7 @@ class LegoPathController : public MxCore { LegoPathBoundary* GetPathBoundary(const char* p_name); void Enable(MxBool p_enable); void FUN_10046bb0(LegoWorld* p_world); + static MxResult Init(); private: MxResult Read(LegoStorage* p_storage); @@ -79,16 +106,16 @@ class LegoPathController : public MxCore { static MxResult ReadVector(LegoStorage* p_storage, Mx3DPointFloat& p_vec); static MxResult ReadVector(LegoStorage* p_storage, Mx4DPointFloat& p_vec); - LegoPathBoundary* m_unk0x08; // 0x08 - LegoPathCtrlEdge* m_unk0x0c; // 0x0c - Mx3DPointFloat* m_unk0x10; // 0x10 - LegoPathStruct* m_unk0x14; // 0x14 - MxU16 m_numL; // 0x18 - MxU16 m_numE; // 0x1a - MxU16 m_numN; // 0x1c - MxU16 m_numT; // 0x1e - LegoPathCtrlEdgeSet m_pfsE; // 0x20 - LegoPathActorSet m_actors; // 0x30 + LegoPathBoundary* m_boundaries; // 0x08 + LegoPathCtrlEdge* m_edges; // 0x0c + Mx3DPointFloat* m_unk0x10; // 0x10 + LegoPathStruct* m_structs; // 0x14 + MxU16 m_numL; // 0x18 + MxU16 m_numE; // 0x1a + MxU16 m_numN; // 0x1c + MxU16 m_numT; // 0x1e + LegoPathCtrlEdgeSet m_pfsE; // 0x20 + LegoPathActorSet m_actors; // 0x30 }; // clang-format off diff --git a/LEGO1/lego/legoomni/include/legopathstruct.h b/LEGO1/lego/legoomni/include/legopathstruct.h index 99053266..587972ba 100644 --- a/LEGO1/lego/legoomni/include/legopathstruct.h +++ b/LEGO1/lego/legoomni/include/legopathstruct.h @@ -35,6 +35,8 @@ struct LegoPathStruct : public LegoPathStructBase { void VTable0x04(undefined4, undefined4, undefined4); // vtable+0x04 + inline void SetAtomId(const MxAtomId& p_atomId) { m_atomId = p_atomId; } + undefined4 m_unk0x0c; // 0x0c MxAtomId m_atomId; // 0x10 }; diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index 0dc851a6..7635ca2c 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -200,7 +200,7 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p_param) m_viewLODListManager = new ViewLODListManager(); m_textureContainer = new LegoTextureContainer(); m_textureContainer->SetOwnership(FALSE); - // FUN_10046c10 + LegoPathController::Init(); m_characterManager = new LegoCharacterManager(); m_plantManager = new LegoPlantManager(); diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index 940c144a..f04ddc75 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -3,32 +3,132 @@ #include "legopathstruct.h" #include "misc/legostorage.h" #include "mxmisc.h" +#include "mxticklemanager.h" #include "mxtimer.h" DECOMP_SIZE_ASSERT(LegoPathController, 0x40) DECOMP_SIZE_ASSERT(LegoPathCtrlEdge, 0x40) +DECOMP_SIZE_ASSERT(LegoPathController::CtrlBoundary, 0x08) +DECOMP_SIZE_ASSERT(LegoPathController::CtrlEdge, 0x08) + +// GLOBAL: LEGO1 0x100d7cc8 +MxU32 g_unk0x100d7cc8[] = {2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0}; + +// GLOBAL: LEGO1 0x100d7d08 +MxU32 g_unk0x100d7d08[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +// GLOBAL: LEGO1 0x100f42e8 +LegoPathController::CtrlBoundary* g_ctrlBoundariesA = NULL; + +// GLOBAL: LEGO1 0x100f42ec +LegoPathController::CtrlEdge* g_ctrlEdgesA = NULL; + +// GLOBAL: LEGO1 0x100f42f0 +const char* g_unk0x100f42f0[] = { + "edg03_21", + "edg03_23", + "edg03_30", + "edg03_31", + "edg03_39", + "edg03_40", + "edg03_91", + "edg03_92", + "edg03_99", + "edg03_100", + "edg03_112", + "edg03_113", + "edg10_61", + "edg10_62", + "edg10_55", + "edg10_58" +}; + +// GLOBAL: LEGO1 0x100f4330 +const char* g_unk0x100f4330[] = { + "edg03_06", + "edg03_21", + "edg03_30", + "edg03_148", + "edg03_39", + "edg03_91", + "edg03_99", + "edg03_112", + "edg03_800", + "edg03_135" +}; + +// GLOBAL: LEGO1 0x100f4358 +LegoPathController::CtrlBoundary* g_ctrlBoundariesB = NULL; + +// GLOBAL: LEGO1 0x100f435c +LegoPathController::CtrlEdge* g_ctrlEdgesB = NULL; // FUNCTION: LEGO1 0x10044f40 // FUNCTION: BETA10 0x100b6860 LegoPathController::LegoPathController() { - m_unk0x08 = NULL; - m_unk0x0c = NULL; + m_boundaries = NULL; + m_edges = NULL; m_unk0x10 = NULL; - m_unk0x14 = NULL; + m_structs = NULL; m_numL = 0; m_numE = 0; m_numN = 0; m_numT = 0; } -// STUB: LEGO1 0x10045880 -void LegoPathController::Create(MxU8* p_data, Vector3& p_location, MxAtomId& p_trigger) +// FUNCTION: LEGO1 0x10045880 +// FUNCTION: BETA10 0x100b6959 +MxResult LegoPathController::Create(MxU8* p_data, const Vector3& p_location, const MxAtomId& p_trigger) { - // TODO - + MxResult result = FAILURE; LegoMemory storage(p_data); - Read(&storage); + + if ((result = Read(&storage)) == SUCCESS) { + MxS32 i; + + for (i = 0; i < m_numT; i++) { + m_structs[i].SetAtomId(p_trigger); + } + + for (i = 0; i < m_numN; i++) { + // TODO: Fix call + ((Vector3&) m_unk0x10[i]).Add(&p_location); + } + + for (i = 0; i < m_numL; i++) { + LegoPathBoundary& boundary = m_boundaries[i]; + MxS32 j; + + for (j = 0; j < _countof(g_unk0x100f42f0); j++) { + if (!strcmpi(g_unk0x100f42f0[j], boundary.GetName())) { + g_ctrlBoundariesA[j].m_controller = this; + g_ctrlBoundariesA[j].m_boundary = &boundary; + + MxU32 edge = g_unk0x100d7cc8[j]; + g_ctrlEdgesA[j].m_controller = this; + g_ctrlEdgesA[j].m_edge = boundary.GetEdges()[edge]; + } + } + + for (j = 0; j < _countof(g_unk0x100f4330); j++) { + if (!strcmpi(g_unk0x100f4330[j], boundary.GetName())) { + g_ctrlBoundariesB[j].m_controller = this; + g_ctrlBoundariesB[j].m_boundary = &boundary; + g_ctrlEdgesB[j].m_controller = this; + g_ctrlEdgesB[j].m_edge = boundary.GetEdges()[g_unk0x100d7d08[j]]; + } + } + } + + TickleManager()->RegisterClient(this, 10); + } + + if (result != SUCCESS) { + Destroy(); + } + + return result; } // STUB: LEGO1 0x10045b20 @@ -105,8 +205,8 @@ MxResult LegoPathController::FUN_10046b30(LegoPathBoundary** p_path, MxS32& p_va LegoPathBoundary* LegoPathController::GetPathBoundary(const char* p_name) { for (MxS32 i = 0; i < m_numL; i++) { - if (!strcmpi(m_unk0x08[i].GetName(), p_name)) { - return &m_unk0x08[i]; + if (!strcmpi(m_boundaries[i].GetName(), p_name)) { + return &m_boundaries[i]; } } @@ -125,6 +225,21 @@ void LegoPathController::Enable(MxBool p_enable) // TODO } +// FUNCTION: LEGO1 0x10046c10 +// FUNCTION: BETA10 0x100b767a +MxResult LegoPathController::Init() +{ + if (g_ctrlBoundariesA != NULL || g_ctrlEdgesA != NULL || g_ctrlBoundariesB != NULL || g_ctrlEdgesB != NULL) { + return FAILURE; + } + + g_ctrlBoundariesA = new CtrlBoundary[_countof(g_unk0x100f42f0)]; + g_ctrlEdgesA = new CtrlEdge[_countof(g_unk0x100f42f0)]; + g_ctrlBoundariesB = new CtrlBoundary[_countof(g_unk0x100f4330)]; + g_ctrlEdgesB = new CtrlEdge[_countof(g_unk0x100f4330)]; + return SUCCESS; +} + // FUNCTION: LEGO1 0x10046e50 // FUNCTION: BETA10 0x100b781f MxResult LegoPathController::Read(LegoStorage* p_storage) @@ -133,7 +248,7 @@ MxResult LegoPathController::Read(LegoStorage* p_storage) return FAILURE; } if (m_numT > 0) { - m_unk0x14 = new LegoPathStruct[m_numT]; + m_structs = new LegoPathStruct[m_numT]; } if (p_storage->Read(&m_numN, sizeof(m_numN)) != SUCCESS) { @@ -147,14 +262,14 @@ MxResult LegoPathController::Read(LegoStorage* p_storage) return FAILURE; } if (m_numE > 0) { - m_unk0x0c = new LegoPathCtrlEdge[m_numE]; + m_edges = new LegoPathCtrlEdge[m_numE]; } if (p_storage->Read(&m_numL, sizeof(m_numL)) != SUCCESS) { return FAILURE; } if (m_numL > 0) { - m_unk0x08 = new LegoPathBoundary[m_numL]; + m_boundaries = new LegoPathBoundary[m_numL]; } if (m_numT > 0 && ReadStructs(p_storage) != SUCCESS) { @@ -178,7 +293,7 @@ MxResult LegoPathController::Read(LegoStorage* p_storage) } for (MxS32 j = 0; j < m_numE; j++) { - m_pfsE.insert(&m_unk0x0c[j]); + m_pfsE.insert(&m_edges[j]); } return SUCCESS; @@ -196,16 +311,16 @@ MxResult LegoPathController::ReadStructs(LegoStorage* p_storage) } if (length > 0) { - m_unk0x14[i].m_name = new char[length + 1]; + m_structs[i].m_name = new char[length + 1]; - if (p_storage->Read(m_unk0x14[i].m_name, length) != SUCCESS) { + if (p_storage->Read(m_structs[i].m_name, length) != SUCCESS) { return FAILURE; } - m_unk0x14[i].m_name[length] = '\0'; + m_structs[i].m_name[length] = '\0'; } - if (p_storage->Read(&m_unk0x14[i].m_unk0x08, sizeof(m_unk0x14[i].m_unk0x08)) != SUCCESS) { + if (p_storage->Read(&m_structs[i].m_unk0x08, sizeof(m_structs[i].m_unk0x08)) != SUCCESS) { return FAILURE; } } @@ -218,7 +333,7 @@ MxResult LegoPathController::ReadStructs(LegoStorage* p_storage) MxResult LegoPathController::ReadEdges(LegoStorage* p_storage) { for (MxS32 i = 0; i < m_numE; i++) { - LegoPathCtrlEdge& edge = m_unk0x0c[i]; + LegoPathCtrlEdge& edge = m_edges[i]; MxU16 s; if (p_storage->Read(&edge.m_flags, sizeof(edge.m_flags)) != SUCCESS) { @@ -239,34 +354,34 @@ MxResult LegoPathController::ReadEdges(LegoStorage* p_storage) if (p_storage->Read(&s, sizeof(s)) != SUCCESS) { return FAILURE; } - edge.m_faceA = &m_unk0x08[s]; + edge.m_faceA = &m_boundaries[s]; if (p_storage->Read(&s, sizeof(s)) != SUCCESS) { return FAILURE; } - edge.m_ccwA = &m_unk0x0c[s]; + edge.m_ccwA = &m_edges[s]; if (p_storage->Read(&s, sizeof(s)) != SUCCESS) { return FAILURE; } - edge.m_cwA = &m_unk0x0c[s]; + edge.m_cwA = &m_edges[s]; } if (edge.m_flags & LegoUnknown100db7f4::c_bit4) { if (p_storage->Read(&s, sizeof(s)) != SUCCESS) { return FAILURE; } - edge.m_faceB = &m_unk0x08[s]; + edge.m_faceB = &m_boundaries[s]; if (p_storage->Read(&s, sizeof(s)) != SUCCESS) { return FAILURE; } - edge.m_ccwB = &m_unk0x0c[s]; + edge.m_ccwB = &m_edges[s]; if (p_storage->Read(&s, sizeof(s)) != SUCCESS) { return FAILURE; } - edge.m_cwB = &m_unk0x0c[s]; + edge.m_cwB = &m_edges[s]; } if (ReadVector(p_storage, edge.m_unk0x28) != SUCCESS) { @@ -286,7 +401,7 @@ MxResult LegoPathController::ReadEdges(LegoStorage* p_storage) MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage) { for (MxS32 i = 0; i < m_numL; i++) { - LegoPathBoundary& boundary = m_unk0x08[i]; + LegoPathBoundary& boundary = m_boundaries[i]; MxU8 numE; MxU16 s; MxU8 j; @@ -305,7 +420,7 @@ MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage) return FAILURE; } - edges[j] = &m_unk0x0c[s]; + edges[j] = &m_edges[s]; } if (p_storage->Read(&boundary.m_unk0x0c, sizeof(boundary.m_unk0x0c)) != SUCCESS) { @@ -362,7 +477,7 @@ MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage) return FAILURE; } - boundary.m_unk0x4c[j].m_unk0x00 = &m_unk0x14[s]; + boundary.m_unk0x4c[j].m_unk0x00 = &m_structs[s]; if (p_storage->Read(&boundary.m_unk0x4c[j].m_unk0x04, sizeof(boundary.m_unk0x4c[j].m_unk0x04)) != SUCCESS) { diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 7d7a06e4..198ed14b 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -120,7 +120,7 @@ class Vector2 { virtual void Add(float* p_other) { AddImpl(p_other); } // vtable+0x4c // FUNCTION: LEGO1 0x100021e0 - virtual void Add(Vector2* p_other) { AddImpl(p_other->m_data); } // vtable+0x48 + virtual void Add(const Vector2* p_other) { AddImpl((float*) p_other->m_data); } // vtable+0x48 // FUNCTION: LEGO1 0x100021f0 virtual void Sub(const float* p_other) { SubImpl((float*) p_other); } // vtable+0x58