From f88f7b115e16d003957697899221405d11720950 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 11 May 2024 13:55:28 -0400 Subject: [PATCH] Implement/match LegoPathController::ReadBoundaries (#908) * Implement/match LegoPathController::ReadBoundaries * Allow spawn --- .../legoomni/include/legopathcontroller.h | 7 +- LEGO1/lego/legoomni/include/legopathstruct.h | 10 +- .../legoomni/src/paths/legopathcontroller.cpp | 117 +++++++++++++++++- LEGO1/lego/sources/geom/legoweedge.h | 7 ++ LEGO1/lego/sources/geom/legowegedge.cpp | 1 + LEGO1/lego/sources/geom/legowegedge.h | 25 +++- LEGO1/mxgeometry/mxgeometry3d.h | 2 + 7 files changed, 152 insertions(+), 17 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 53a4ef36..424523bb 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -9,7 +9,7 @@ #include "mxstl/stlcompat.h" class LegoAnimPresenter; -class LegoPathStruct; +struct LegoPathStruct; class LegoWorld; class MxAtomId; class Vector3; @@ -75,8 +75,9 @@ class LegoPathController : public MxCore { MxResult Read(LegoStorage* p_storage); MxResult ReadStructs(LegoStorage* p_storage); MxResult ReadEdges(LegoStorage* p_storage); - MxResult FUN_10047e90(LegoStorage* p_storage); - static MxResult ReadVector(LegoStorage* p_storage, Mx3DPointFloat&); + MxResult ReadBoundaries(LegoStorage* p_storage); + 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 diff --git a/LEGO1/lego/legoomni/include/legopathstruct.h b/LEGO1/lego/legoomni/include/legopathstruct.h index 6ffdb20f..99053266 100644 --- a/LEGO1/lego/legoomni/include/legopathstruct.h +++ b/LEGO1/lego/legoomni/include/legopathstruct.h @@ -5,11 +5,9 @@ #include "mxatom.h" #include "mxtypes.h" -class LegoPathController; - // VTABLE: LEGO1 0x100d7d9c // SIZE 0x0c -class LegoPathStructBase { +struct LegoPathStructBase { public: LegoPathStructBase() : m_name(NULL), m_unk0x08(0) {} @@ -21,16 +19,13 @@ class LegoPathStructBase { } } - friend class LegoPathController; - -private: char* m_name; // 0x04 undefined4 m_unk0x08; // 0x08 }; // VTABLE: LEGO1 0x100d7da0 // SIZE 0x14 -class LegoPathStruct : public LegoPathStructBase { +struct LegoPathStruct : public LegoPathStructBase { public: // FUNCTION: LEGO1 0x100473a0 LegoPathStruct() : m_unk0x0c(0) {} @@ -40,7 +35,6 @@ class LegoPathStruct : public LegoPathStructBase { void VTable0x04(undefined4, undefined4, undefined4); // vtable+0x04 -private: undefined4 m_unk0x0c; // 0x0c MxAtomId m_atomId; // 0x10 }; diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index 1889e391..940c144a 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -26,6 +26,9 @@ LegoPathController::LegoPathController() void LegoPathController::Create(MxU8* p_data, Vector3& p_location, MxAtomId& p_trigger) { // TODO + + LegoMemory storage(p_data); + Read(&storage); } // STUB: LEGO1 0x10045b20 @@ -170,7 +173,7 @@ MxResult LegoPathController::Read(LegoStorage* p_storage) return FAILURE; } - if (m_numL > 0 && FUN_10047e90(p_storage) != SUCCESS) { + if (m_numL > 0 && ReadBoundaries(p_storage) != SUCCESS) { return FAILURE; } @@ -278,11 +281,106 @@ MxResult LegoPathController::ReadEdges(LegoStorage* p_storage) return SUCCESS; } -// STUB: LEGO1 0x10047e90 +// FUNCTION: LEGO1 0x10047e90 // FUNCTION: BETA10 0x100b8293 -MxResult LegoPathController::FUN_10047e90(LegoStorage* p_storage) +MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage) { - // TODO + for (MxS32 i = 0; i < m_numL; i++) { + LegoPathBoundary& boundary = m_unk0x08[i]; + MxU8 numE; + MxU16 s; + MxU8 j; + + if (p_storage->Read(&numE, sizeof(numE)) != SUCCESS) { + return FAILURE; + } + + boundary.m_edgeNormals = new Mx4DPointFloat[numE]; + + LegoEdge** edges = new LegoEdge*[numE]; + boundary.SetEdges(edges, numE); + + for (j = 0; j < numE; j++) { + if (p_storage->Read(&s, sizeof(s)) != SUCCESS) { + return FAILURE; + } + + edges[j] = &m_unk0x0c[s]; + } + + if (p_storage->Read(&boundary.m_unk0x0c, sizeof(boundary.m_unk0x0c)) != SUCCESS) { + return FAILURE; + } + + if (p_storage->Read(&boundary.m_unk0x0d, sizeof(boundary.m_unk0x0d)) != SUCCESS) { + return FAILURE; + } + + MxU8 length; + if (p_storage->Read(&length, sizeof(length)) != SUCCESS) { + return FAILURE; + } + + if (length > 0) { + boundary.m_name = new char[length + 1]; + + if (p_storage->Read(boundary.m_name, length) != SUCCESS) { + return FAILURE; + } + + boundary.m_name[length] = '\0'; + } + + if (ReadVector(p_storage, boundary.m_unk0x14) != SUCCESS) { + return FAILURE; + } + + for (j = 0; j < numE; j++) { + if (ReadVector(p_storage, boundary.m_edgeNormals[j]) != SUCCESS) { + return FAILURE; + } + } + + if (ReadVector(p_storage, boundary.m_unk0x30) != SUCCESS) { + return FAILURE; + } + + if (p_storage->Read(&boundary.m_unk0x44, sizeof(boundary.m_unk0x44)) != SUCCESS) { + return FAILURE; + } + + if (p_storage->Read(&boundary.m_unk0x48, sizeof(boundary.m_unk0x48)) != SUCCESS) { + return FAILURE; + } + + if (boundary.m_unk0x48 > 0) { + boundary.m_unk0x50 = new Mx3DPointFloat; + boundary.m_unk0x4c = new LegoWEGEdge::Path[boundary.m_unk0x48]; + + for (j = 0; j < boundary.m_unk0x48; j++) { + if (p_storage->Read(&s, sizeof(s)) != SUCCESS) { + return FAILURE; + } + + boundary.m_unk0x4c[j].m_unk0x00 = &m_unk0x14[s]; + + if (p_storage->Read(&boundary.m_unk0x4c[j].m_unk0x04, sizeof(boundary.m_unk0x4c[j].m_unk0x04)) != + SUCCESS) { + return FAILURE; + } + + if (p_storage->Read(&boundary.m_unk0x4c[j].m_unk0x08, sizeof(boundary.m_unk0x4c[j].m_unk0x08)) != + SUCCESS) { + return FAILURE; + } + } + + if (ReadVector(p_storage, *boundary.m_unk0x50) != SUCCESS) { + return FAILURE; + } + } + } + return SUCCESS; } @@ -296,3 +394,14 @@ MxResult LegoPathController::ReadVector(LegoStorage* p_storage, Mx3DPointFloat& return SUCCESS; } + +// FUNCTION: LEGO1 0x100482e0 +// FUNCTION: BETA10 0x100b88a1 +MxResult LegoPathController::ReadVector(LegoStorage* p_storage, Mx4DPointFloat& p_vec) +{ + if (p_storage->Read(p_vec.GetData(), sizeof(float) * 4) != SUCCESS) { + return FAILURE; + } + + return SUCCESS; +} diff --git a/LEGO1/lego/sources/geom/legoweedge.h b/LEGO1/lego/sources/geom/legoweedge.h index c743479d..f433aa63 100644 --- a/LEGO1/lego/sources/geom/legoweedge.h +++ b/LEGO1/lego/sources/geom/legoweedge.h @@ -5,6 +5,7 @@ #include "legoedge.h" #include "misc/legotypes.h" +// might be a struct with public members // VTABLE: LEGO1 0x100db7c0 // SIZE 0x0c class LegoWEEdge { @@ -18,6 +19,12 @@ class LegoWEEdge { inline LegoEdge** GetEdges() { return m_edges; } inline LegoU32 IsEqual(LegoWEEdge& p_other) { return this == &p_other; } + inline void SetEdges(LegoEdge** p_edges, LegoU8 p_numEdges) + { + m_edges = p_edges; + m_numEdges = p_numEdges; + } + // SYNTHETIC: LEGO1 0x1009a570 // LegoWEEdge::`scalar deleting destructor' diff --git a/LEGO1/lego/sources/geom/legowegedge.cpp b/LEGO1/lego/sources/geom/legowegedge.cpp index 36157313..21fee167 100644 --- a/LEGO1/lego/sources/geom/legowegedge.cpp +++ b/LEGO1/lego/sources/geom/legowegedge.cpp @@ -1,6 +1,7 @@ #include "legowegedge.h" DECOMP_SIZE_ASSERT(LegoWEGEdge, 0x54) +DECOMP_SIZE_ASSERT(LegoWEGEdge::Path, 0x0c) // FUNCTION: LEGO1 0x1009a730 LegoWEGEdge::LegoWEGEdge() diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index 8e44fc48..018c9cf8 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -5,10 +5,29 @@ #include "legoweedge.h" #include "mxgeometry/mxgeometry3d.h" +struct LegoPathStruct; + +// might be a struct with public members // VTABLE: LEGO1 0x100db7f8 // SIZE 0x54 class LegoWEGEdge : public LegoWEEdge { public: + // SIZE 0x0c + struct Path { + // FUNCTION: LEGO1 0x10048280 + // FUNCTION: BETA10 0x100bd450 + Path() + { + m_unk0x00 = NULL; + m_unk0x04 = 0; + m_unk0x08 = 0; + } + + LegoPathStruct* m_unk0x00; // 0x00 + undefined4 m_unk0x04; // 0x04 + undefined4 m_unk0x08; // 0x08 + }; + LegoWEGEdge(); ~LegoWEGEdge() override; @@ -22,6 +41,8 @@ class LegoWEGEdge : public LegoWEEdge { // SYNTHETIC: LEGO1 0x1009a7e0 // LegoWEGEdge::`scalar deleting destructor' + friend class LegoPathController; + private: LegoU8 m_unk0x0c; // 0x0c LegoU8 m_unk0x0d; // 0x0d @@ -31,8 +52,8 @@ class LegoWEGEdge : public LegoWEEdge { Mx3DPointFloat m_unk0x30; // 0x30 LegoU32 m_unk0x44; // 0x44 LegoU8 m_unk0x48; // 0x48 - undefined* m_unk0x4c; // 0x4c - undefined* m_unk0x50; // 0x50 + Path* m_unk0x4c; // 0x4c + Mx3DPointFloat* m_unk0x50; // 0x50 }; #endif // __LEGOWEGEDGE_H diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index 5d6d3acc..2fc02932 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -46,7 +46,9 @@ class Mx3DPointFloat : public Vector3 { // SIZE 0x18 class Mx4DPointFloat : public Vector4 { public: + // FUNCTION: LEGO1 0x10048290 inline Mx4DPointFloat() : Vector4(m_elements) {} + inline Mx4DPointFloat(float p_x, float p_y, float p_z, float p_a) : Vector4(m_elements) { m_elements[0] = p_x;