From cc682173eb58b1c5508a3f2f7c14318d3cc6c506 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Sat, 30 Nov 2024 11:57:44 -0500 Subject: [PATCH 01/14] Implement functions in Act3Actor (#1180) * Implement Act3Actor * Minor consistency adjustments --------- Co-authored-by: Christian Semmler --- LEGO1/lego/legoomni/include/act3actors.h | 11 ++- LEGO1/lego/legoomni/include/legopathactor.h | 1 + LEGO1/lego/legoomni/src/actors/act3actors.cpp | 80 +++++++++++++++++-- 3 files changed, 81 insertions(+), 11 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act3actors.h b/LEGO1/lego/legoomni/include/act3actors.h index ac955816..2fce23b3 100644 --- a/LEGO1/lego/legoomni/include/act3actors.h +++ b/LEGO1/lego/legoomni/include/act3actors.h @@ -20,8 +20,8 @@ class Act3Actor : public LegoAnimActor { return "Act3Actor"; } - MxU32 VTable0x90(float, Matrix4&) override; // vtable+0x90 - MxResult VTable0x94(LegoPathActor*, MxBool) override; // vtable+0x94 + MxU32 VTable0x90(float p_float, Matrix4& p_transform) override; // vtable+0x90 + MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 // SYNTHETIC: LEGO1 0x10043330 // Act3Actor::`scalar deleting destructor' @@ -30,7 +30,12 @@ class Act3Actor : public LegoAnimActor { // Act3Actor::~Act3Actor private: - undefined4 m_unk0x1c; // 0x1c + MxFloat m_unk0x1c; // 0x1c + + static Mx3DPointFloat g_unk0x10104ef0; }; +// GLOBAL: LEGO1 0x100d7660 +// Act3Actor::`vbtable' + #endif // ACT3ACTORS_H diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 896d6ccd..9454e637 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -22,6 +22,7 @@ extern const char* g_strHIT_WALL_SOUND; class LegoPathActor : public LegoActor { public: enum { + c_bit2 = 0x02, c_bit3 = 0x04, c_bit9 = 0x100 }; diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index 01359090..a0f1690c 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -1,23 +1,87 @@ #include "act3actors.h" +#include "roi/legoroi.h" + DECOMP_SIZE_ASSERT(Act3Actor, 0x178) -// STUB: LEGO1 0x1003fa50 +// Initialized at LEGO1 0x1003fa20 +// GLOBAL: LEGO1 0x10104ef0 +Mx3DPointFloat Act3Actor::g_unk0x10104ef0 = Mx3DPointFloat(0.0, 5.0, 0.0); + +// FUNCTION: LEGO1 0x1003fa50 Act3Actor::Act3Actor() { m_unk0x1c = 0; } -// STUB: LEGO1 0x1003fb70 -MxU32 Act3Actor::VTable0x90(float, Matrix4&) +// FUNCTION: LEGO1 0x1003fb70 +MxU32 Act3Actor::VTable0x90(float p_float, Matrix4& p_transform) { - // TODO + // Note: Code duplication with LegoExtraActor::VTable0x90 + switch (m_state & 0xff) { + case 0: + case 1: + return TRUE; + case 2: + m_unk0x1c = p_float + 2000.0f; + m_state = 3; + m_actorTime += (p_float - m_lastTime) * m_worldSpeed; + m_lastTime = p_float; + return FALSE; + case 3: + assert(!m_userNavFlag); + Vector3 positionRef(p_transform[3]); + + p_transform = m_roi->GetLocal2World(); + + if (m_unk0x1c > p_float) { + Mx3DPointFloat position; + + position = positionRef; + positionRef.Clear(); + p_transform.RotateX(0.6); + positionRef = position; + + m_actorTime += (p_float - m_lastTime) * m_worldSpeed; + m_lastTime = p_float; + + VTable0x74(p_transform); + return FALSE; + } + else { + m_state = 0; + m_unk0x1c = 0; + + ((Vector3&) positionRef).Sub(g_unk0x10104ef0); + m_roi->FUN_100a58f0(p_transform); + m_roi->VTable0x14(); + return TRUE; + } + } + return FALSE; } -// STUB: LEGO1 0x1003fd90 -MxResult Act3Actor::VTable0x94(LegoPathActor*, MxBool) +// FUNCTION: LEGO1 0x1003fd90 +MxResult Act3Actor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) { - // TODO - return 0; + if (!p_actor->GetUserNavFlag() && p_bool) { + if (p_actor->GetState()) { + return FAILURE; + } + + LegoROI* roi = p_actor->GetROI(); + + MxMatrix local2world; + local2world = roi->GetLocal2World(); + + Vector3(local2world[3]).Add(g_unk0x10104ef0); + + roi->FUN_100a58f0(local2world); + roi->VTable0x14(); + + p_actor->SetState(c_bit2 | c_bit9); + } + + return SUCCESS; } From f066e2ee2e7d81b449bded906d0652d52ca4dc58 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sat, 30 Nov 2024 22:35:07 +0100 Subject: [PATCH 02/14] Implement `Act2Actor::Act2Actor()`, add BETA10 references (#1182) * Implement `Act2Actor::Act2Actor()`, add structure and BETA10 * Add LegoAnimActor BETA10 annotations * Improve LegoAnimActor BETA10 match * More BETA10 annotations * Address review comment * Disable annotation so the CI passes --------- Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/act2actor.h | 14 +++++++++++++- LEGO1/lego/legoomni/include/legoanimactor.h | 1 + LEGO1/lego/legoomni/include/legopathactor.h | 1 + LEGO1/lego/legoomni/src/actors/act2actor.cpp | 18 +++++++++++++++++- .../lego/legoomni/src/paths/legoanimactor.cpp | 11 +++++++++-- .../lego/legoomni/src/paths/legopathactor.cpp | 2 ++ 6 files changed, 43 insertions(+), 4 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index b2446936..ec82cea2 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -5,9 +5,17 @@ // VTABLE: LEGO1 0x100d6078 LegoPathActor // VTABLE: LEGO1 0x100d6148 LegoAnimActor +// VTABLE: BETA10 0x101b80c0 LegoPathActor +// VTABLE: BETA10 0x101b81b0 LegoAnimActor // SIZE 0x1a8 class Act2Actor : public LegoAnimActor { public: + struct UnknownListStructure { + undefined m_unk0x00[28]; + undefined m_unk0x1c; + undefined m_unk0x1d[3]; + }; + Act2Actor(); void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) override; // vtable+0x24 @@ -23,6 +31,10 @@ class Act2Actor : public LegoAnimActor { // SYNTHETIC: LEGO1 0x1001a0a0 // Act2Actor::`scalar deleting destructor' + // GLOBAL: LEGO1 0x100d6070 + // GLOBAL: BETA10 0x101b80b0 + // `vbtable' + private: undefined m_unk0x1c; // 0x1c undefined m_unk0x1d; // 0x1d @@ -30,7 +42,7 @@ class Act2Actor : public LegoAnimActor { MxBool m_unk0x1f; // 0x1f undefined4 m_unk0x20; // 0x20 undefined4 m_unk0x24; // 0x24 - undefined4 m_unk0x28; // 0x28 + undefined m_unk0x28; // 0x28 undefined4 m_unk0x2c; // 0x2c undefined4 m_unk0x30; // 0x30 undefined4 m_unk0x34; // 0x34 diff --git a/LEGO1/lego/legoomni/include/legoanimactor.h b/LEGO1/lego/legoomni/include/legoanimactor.h index f74e8c00..ea4fcb4b 100644 --- a/LEGO1/lego/legoomni/include/legoanimactor.h +++ b/LEGO1/lego/legoomni/include/legoanimactor.h @@ -82,6 +82,7 @@ class LegoAnimActor : public virtual LegoPathActor { // Vector::~Vector // SYNTHETIC: LEGO1 0x10012b90 +// SYNTHETIC: BETA10 0x1000fad0 // LegoAnimActor::`vbase destructor' // TEMPLATE: LEGO1 0x1001c010 diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 9454e637..0fe7a3df 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -18,6 +18,7 @@ extern MxLong g_unk0x100f3308; extern const char* g_strHIT_WALL_SOUND; // VTABLE: LEGO1 0x100d6e28 +// VTABLE: BETA10 0x101bdc08 // SIZE 0x154 class LegoPathActor : public LegoActor { public: diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 6c10caae..d582db05 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -6,8 +6,14 @@ #include "roi/legoroi.h" DECOMP_SIZE_ASSERT(Act2Actor, 0x1a8) +DECOMP_SIZE_ASSERT(Act2Actor::UnknownListStructure, 0x20) -// STUB: LEGO1 0x100187e0 +// TODO: Copy the data once we know more about its fields. Total: 10 entries +// // GLOBAL: LEGO1 0x100f0db8 +Act2Actor::UnknownListStructure g_unk0x100f0db8[] = {{{0}, 0, {0}}}; + +// FUNCTION: LEGO1 0x100187e0 +// FUNCTION: BETA10 0x1000c7fb Act2Actor::Act2Actor() { m_unk0x1c = 0; @@ -26,9 +32,15 @@ Act2Actor::Act2Actor() m_unk0x4c = 0; m_unk0x38 = 0; m_unk0x3c = 0; + + // TODO replace 10 by sizeOfArray once the data are there + for (MxS32 i = 0; i < 10; i++) { + g_unk0x100f0db8[i].m_unk0x1c = 0; + } } // FUNCTION: LEGO1 0x10018940 +// FUNCTION: BETA10 0x1003d65f void Act2Actor::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) { LegoAnimActor::SetROI(p_roi, p_bool1, p_bool2); @@ -36,6 +48,7 @@ void Act2Actor::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) } // FUNCTION: LEGO1 0x100189f0 +// FUNCTION: BETA10 0x1000ca64 MxResult Act2Actor::VTable0x94(LegoPathActor*, MxBool) { if (m_unk0x1f == FALSE) { @@ -55,12 +68,14 @@ MxResult Act2Actor::VTable0x9c() } // STUB: LEGO1 0x10018c30 +// STUB: BETA10 0x1000cb52 void Act2Actor::VTable0x70(float p_und) { // TODO } // FUNCTION: LEGO1 0x10019280 +// FUNCTION: BETA10 0x1000d4a6 void Act2Actor::SetWorldSpeed(MxFloat p_worldSpeed) { LegoAnimActor::SetWorldSpeed(p_worldSpeed); @@ -75,6 +90,7 @@ void Act2Actor::FUN_10019520() } // STUB: LEGO1 0x100195a0 +// STUB: BETA10 0x1000d7d3 MxS32 Act2Actor::VTable0xa0() { // TODO diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index a8180af8..6ed0a8c1 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -12,6 +12,7 @@ DECOMP_SIZE_ASSERT(LegoAnimActor, 0x174) DECOMP_SIZE_ASSERT(LegoAnimActorStruct, 0x20) // FUNCTION: LEGO1 0x1001bf80 +// FUNCTION: BETA10 0x1003dc10 LegoAnimActorStruct::LegoAnimActorStruct(float p_unk0x00, LegoAnim* p_AnimTreePtr, LegoROI** p_roiMap, MxU32 p_numROIs) { m_unk0x00 = p_unk0x00; @@ -48,6 +49,7 @@ LegoAnimActor::~LegoAnimActor() } // FUNCTION: LEGO1 0x1001c1f0 +// FUNCTION: BETA10 0x1003f240 MxResult LegoAnimActor::FUN_1001c1f0(float& p_und) { float duration = (float) m_animMaps[m_curAnim]->m_AnimTreePtr->GetDuration(); @@ -144,9 +146,13 @@ MxResult LegoAnimActor::FUN_1001c360(float p_und, Matrix4& p_transform) } // FUNCTION: LEGO1 0x1001c450 -MxResult LegoAnimActor::FUN_1001c450(LegoAnim* p_animTreePtr, float p_unk0x00, LegoROI** p_roiMap, MxU32 p_numROIs) +// FUNCTION: BETA10 0x1003e590 +MxResult LegoAnimActor::FUN_1001c450(LegoAnim* p_AnimTreePtr, float p_unk0x00, LegoROI** p_roiMap, MxU32 p_numROIs) { - LegoAnimActorStruct* laas = new LegoAnimActorStruct(p_unk0x00, p_animTreePtr, p_roiMap, p_numROIs); + // the capitalization of `p_AnimTreePtr` was taken from BETA10 + assert(p_AnimTreePtr && p_roiMap); + + LegoAnimActorStruct* laas = new LegoAnimActorStruct(p_unk0x00, p_AnimTreePtr, p_roiMap, p_numROIs); for (vector::iterator it = m_animMaps.begin(); it != m_animMaps.end(); it++) { if (p_unk0x00 < (*it)->m_unk0x00) { @@ -162,6 +168,7 @@ MxResult LegoAnimActor::FUN_1001c450(LegoAnim* p_animTreePtr, float p_unk0x00, L } // FUNCTION: LEGO1 0x1001c800 +// FUNCTION: BETA10 0x1003e747 void LegoAnimActor::ClearMaps() { for (MxU32 i = 0; i < m_animMaps.size(); i++) { diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index f5795934..3a1a5427 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -38,6 +38,7 @@ const char* g_strHIT_WALL_SOUND = "HIT_WALL_SOUND"; MxLong g_unk0x100f3308 = 0; // FUNCTION: LEGO1 0x1002d700 +// FUNCTION: BETA10 0x100ae6e0 LegoPathActor::LegoPathActor() { m_boundary = NULL; @@ -57,6 +58,7 @@ LegoPathActor::LegoPathActor() } // FUNCTION: LEGO1 0x1002d820 +// FUNCTION: BETA10 0x100ae80e LegoPathActor::~LegoPathActor() { if (m_grec) { From 8b9f6f10072392944f094a0e1669db4e7df245e3 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:21:59 +0100 Subject: [PATCH 03/14] Implement more functions in `Act2Actor` (#1183) * Implement `Act2Actor::VTable0xa0` * Implement `Act2Actor::FUN_10019520()` * Implement/match `Act2Actor::FUN_100192a0()` * Fix clang32 issue * Address review comments --------- Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/act2actor.h | 17 +- .../legoomni/include/legopathcontroller.h | 11 ++ LEGO1/lego/legoomni/src/actors/act2actor.cpp | 184 ++++++++++++++++-- .../legoomni/src/paths/legopathcontroller.cpp | 18 ++ 4 files changed, 212 insertions(+), 18 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index ec82cea2..3e0cb0dd 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -11,9 +11,10 @@ class Act2Actor : public LegoAnimActor { public: struct UnknownListStructure { - undefined m_unk0x00[28]; - undefined m_unk0x1c; - undefined m_unk0x1d[3]; + MxFloat m_unk0x00[3]; // 0x00 + MxFloat m_unk0x0c[3]; // 0x0c + const char* m_unk0x18; // 0x18 + undefined m_unk0x1c; // 0x1c }; Act2Actor(); @@ -27,6 +28,7 @@ class Act2Actor : public LegoAnimActor { MxS32 VTable0xa0() override; // vtable+0xa0 void FUN_10019520(); + void FUN_100192a0(undefined4 p_param); // SYNTHETIC: LEGO1 0x1001a0a0 // Act2Actor::`scalar deleting destructor' @@ -37,12 +39,12 @@ class Act2Actor : public LegoAnimActor { private: undefined m_unk0x1c; // 0x1c - undefined m_unk0x1d; // 0x1d + MxS8 m_unk0x1d; // 0x1d undefined m_unk0x1e; // 0x1e MxBool m_unk0x1f; // 0x1f undefined4 m_unk0x20; // 0x20 undefined4 m_unk0x24; // 0x24 - undefined m_unk0x28; // 0x28 + MxS8 m_unk0x28; // 0x28 undefined4 m_unk0x2c; // 0x2c undefined4 m_unk0x30; // 0x30 undefined4 m_unk0x34; // 0x34 @@ -50,8 +52,11 @@ class Act2Actor : public LegoAnimActor { undefined4 m_unk0x3c; // 0x3c undefined m_unk0x40; // 0x40 undefined4 m_unk0x44; // 0x44 - undefined m_unk0x48; // 0x48 + MxS8 m_unk0x48; // 0x48 undefined4 m_unk0x4c; // 0x4c }; +// TEMPLATE: LEGO1 0x100194f0 +// list >::list > + #endif // ACT2ACTOR_H diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index ad0b5791..10185666 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -117,6 +117,17 @@ class LegoPathController : public MxCore { LegoUnknown100db7f4*& p_edge, LegoPathBoundary*& p_boundary ); + MxResult FUN_10048310( + LegoPathEdgeContainer* p_grec, + const Vector3& p_position, + const Vector3& p_direction, + LegoPathBoundary* p_boundary1, + const Vector3& p_param5, + const Vector3& p_param6, + LegoPathBoundary* p_boundary2, + MxBool p_param8, + MxFloat* p_param9 + ); static MxResult Init(); static MxResult Reset(); diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index d582db05..36fe47c6 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -1,6 +1,8 @@ #include "act2actor.h" #include "legocachesoundmanager.h" +#include "legopathcontroller.h" +#include "legopathedgecontainer.h" #include "legosoundmanager.h" #include "misc.h" #include "roi/legoroi.h" @@ -8,9 +10,21 @@ DECOMP_SIZE_ASSERT(Act2Actor, 0x1a8) DECOMP_SIZE_ASSERT(Act2Actor::UnknownListStructure, 0x20) -// TODO: Copy the data once we know more about its fields. Total: 10 entries -// // GLOBAL: LEGO1 0x100f0db8 -Act2Actor::UnknownListStructure g_unk0x100f0db8[] = {{{0}, 0, {0}}}; +// GLOBAL: LEGO1 0x100f0db8 +// GLOBAL: BETA10 0x101dbd00 +Act2Actor::UnknownListStructure g_unk0x100f0db8[] = { + {{-47.92, 7.0699968, -31.58}, {-0.999664, 0.0, -0.025916}, "edg01_27", FALSE}, + {{-70.393349, 8.07, 3.151935}, {-0.90653503, 0.0, 0.422131}, "int06", FALSE}, + {{-47.74, 4.079995, -52.3}, {-0.98293, 0.0, -0.18398}, "edg01_08", FALSE}, + {{-26.273487, 0.069, 12.170015}, {0.987199, 0.0, -0.159491}, "INT14", FALSE}, + {{26.16499, 0.069, 5.61}, {0.027719, 0.0, 0.999616}, "INT22", FALSE}, + {{66.383446, 4.07, 32.387417}, {0.979487, 0.0, -0.201506}, "edg02_27", FALSE}, + {{71.843285, 0.069, -49.524852}, {0.99031502, 0.0, 0.13884}, "edg02_39", FALSE}, + {{26.470566, 0.069, -44.670845}, {0.004602, 0.0, -0.99998897}, "int26", FALSE}, + {{-6.323625, 0.069, -47.96045}, {-0.982068, 0.0, 0.188529}, "edg02_53", FALSE}, + {{-36.689, -0.978409, 31.449}, {0.083792, -0.94303, -0.66398698}, "edg00_157", FALSE}, + {{-44.6, 0.1, 45.3}, {0.95, 0.0, -0.3}, "edg00_154", FALSE}, +}; // FUNCTION: LEGO1 0x100187e0 // FUNCTION: BETA10 0x1000c7fb @@ -33,7 +47,7 @@ Act2Actor::Act2Actor() m_unk0x38 = 0; m_unk0x3c = 0; - // TODO replace 10 by sizeOfArray once the data are there + // Odd: The code says < 10, but there are 11 entries in the array for (MxS32 i = 0; i < 10; i++) { g_unk0x100f0db8[i].m_unk0x1c = 0; } @@ -82,19 +96,165 @@ void Act2Actor::SetWorldSpeed(MxFloat p_worldSpeed) m_unk0x44 = 0; } -// STUB: LEGO1 0x10019520 -// STUB: BETA10 0x1000d4d6 -void Act2Actor::FUN_10019520() +// FUNCTION: LEGO1 0x100192a0 +// FUNCTION: BETA10 0x1000d4d6 +void Act2Actor::FUN_100192a0(undefined4 p_param) { - // TODO + Mx3DPointFloat local38(0.0, 0.0, 0.0); + Mx3DPointFloat local4c(0.0, 0.0, 0.0); + + if (m_grec) { + delete m_grec; + } + + m_grec = new LegoPathEdgeContainer(); + assert(m_grec); + + local38 = g_unk0x100f0db8[p_param].m_unk0x00; + local4c = g_unk0x100f0db8[p_param].m_unk0x0c; + + LegoPathBoundary* otherBoundary = m_controller->GetPathBoundary(g_unk0x100f0db8[p_param].m_unk0x18); + + MxResult sts = m_controller->FUN_10048310( + m_grec, + m_roi->GetWorldPosition(), + m_roi->GetWorldDirection(), + m_boundary, + local38, + local4c, + otherBoundary, + TRUE, + NULL + ); + + assert(!sts); + + if (sts) { + delete m_grec; + m_grec = NULL; + } } -// STUB: LEGO1 0x100195a0 -// STUB: BETA10 0x1000d7d3 +// FUNCTION: LEGO1 0x10019520 +void Act2Actor::FUN_10019520() +{ + m_unk0x1e = 4; + SetWorldSpeed(m_unk0x28 + 3); + FUN_100192a0(10); +} + +// FUNCTION: LEGO1 0x100195a0 +// FUNCTION: BETA10 0x1000d7d3 MxS32 Act2Actor::VTable0xa0() { - // TODO - return 0; + undefined4 newLocation; + + CurrentWorld(); + MxU16 randomVal = rand() / (RAND_MAX / 2) + 1; + + if (m_unk0x48 == 8 && m_unk0x1d != 8) { + newLocation = 8; + } + else { + switch (m_unk0x1d) { + case 0: + if (randomVal == 1) { + newLocation = 3; + } + else { + newLocation = 7; + } + break; + case 1: + if (randomVal == 1) { + newLocation = 2; + } + else { + newLocation = 4; + } + break; + case 2: + if (randomVal == 1) { + newLocation = 3; + } + else { + newLocation = 6; + } + break; + case 3: + if (randomVal == 1) { + newLocation = 5; + } + else { + newLocation = 1; + } + break; + case 4: + if (randomVal == 1) { + newLocation = 7; + } + else { + newLocation = 0; + } + break; + case 5: + if (randomVal == 1) { + newLocation = 6; + } + else { + newLocation = 1; + } + break; + case 6: + if (randomVal == 1) { + newLocation = 0; + } + else { + newLocation = 4; + } + break; + case 7: + if (randomVal == 1) { + newLocation = 2; + } + else { + newLocation = 5; + } + break; + case 8: + if (randomVal == 1) { + newLocation = 0; + } + else { + newLocation = 4; + } + } + } + + undefined4 firstChoice = newLocation; + + if (m_unk0x48 < 7 || g_unk0x100f0db8[m_unk0x1d].m_unk0x1c) { + while (g_unk0x100f0db8[newLocation].m_unk0x1c || m_unk0x1d == newLocation) { + if (newLocation == 7) { + newLocation = 0; + } + else { + newLocation++; + } + + assert(newLocation != firstChoice); + } + } + + m_unk0x1d = newLocation; + FUN_100192a0(newLocation); + + if (m_grec) { + return SUCCESS; + } + else { + return FAILURE; + } } // FUNCTION: LEGO1 0x1001a180 diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index 480b43ec..e034db98 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -733,6 +733,24 @@ MxResult LegoPathController::ReadVector(LegoStorage* p_storage, Mx4DPointFloat& return SUCCESS; } +// STUB: LEGO1 0x10048310 +// STUB: BETA10 0x100b8911 +MxResult LegoPathController::FUN_10048310( + LegoPathEdgeContainer* p_grec, + const Vector3& p_position, + const Vector3& p_direction, + LegoPathBoundary* p_boundary1, + const Vector3& p_param5, + const Vector3& p_param6, + LegoPathBoundary* p_boundary2, + MxBool p_param8, + MxFloat* p_param9 +) +{ + // TODO + return SUCCESS; +} + // FUNCTION: LEGO1 0x1004a240 // FUNCTION: BETA10 0x100b9160 MxS32 LegoPathController::FUN_1004a240( From a0a114135acc8e40046166d435aee4be4f2db76d Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 2 Dec 2024 10:58:08 -0700 Subject: [PATCH 04/14] Implement/match `LegoAct2::HandleEndAction` and related (#1184) * Implement/match LegoAct2::HandleEndAction * Reorder --- LEGO1/lego/legoomni/include/act2actor.h | 33 +-- LEGO1/lego/legoomni/include/act2brick.h | 2 + LEGO1/lego/legoomni/include/legoact2.h | 22 +- .../legoomni/include/legoanimationmanager.h | 2 +- LEGO1/lego/legoomni/include/legocachsound.h | 3 +- LEGO1/lego/legoomni/src/actors/act2actor.cpp | 21 +- .../lego/legoomni/src/audio/legocachsound.cpp | 19 +- .../src/common/legoanimationmanager.cpp | 2 +- LEGO1/lego/legoomni/src/entity/act2brick.cpp | 24 ++ LEGO1/lego/legoomni/src/entity/legoactor.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 238 ++++++++++++++++-- 11 files changed, 314 insertions(+), 54 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index 3e0cb0dd..c45effeb 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -27,6 +27,7 @@ class Act2Actor : public LegoAnimActor { MxResult VTable0x9c() override; // vtable+0x9c MxS32 VTable0xa0() override; // vtable+0xa0 + void FUN_10018980(); void FUN_10019520(); void FUN_100192a0(undefined4 p_param); @@ -38,22 +39,22 @@ class Act2Actor : public LegoAnimActor { // `vbtable' private: - undefined m_unk0x1c; // 0x1c - MxS8 m_unk0x1d; // 0x1d - undefined m_unk0x1e; // 0x1e - MxBool m_unk0x1f; // 0x1f - undefined4 m_unk0x20; // 0x20 - undefined4 m_unk0x24; // 0x24 - MxS8 m_unk0x28; // 0x28 - undefined4 m_unk0x2c; // 0x2c - undefined4 m_unk0x30; // 0x30 - undefined4 m_unk0x34; // 0x34 - undefined4 m_unk0x38; // 0x38 - undefined4 m_unk0x3c; // 0x3c - undefined m_unk0x40; // 0x40 - undefined4 m_unk0x44; // 0x44 - MxS8 m_unk0x48; // 0x48 - undefined4 m_unk0x4c; // 0x4c + undefined m_unk0x1c; // 0x1c + MxS8 m_unk0x1d; // 0x1d + undefined m_unk0x1e; // 0x1e + MxBool m_unk0x1f; // 0x1f + undefined4 m_unk0x20; // 0x20 + undefined4 m_unk0x24; // 0x24 + MxS8 m_unk0x28; // 0x28 + undefined4 m_unk0x2c; // 0x2c + undefined4 m_unk0x30; // 0x30 + LegoAnimActorStruct* m_shootAnim; // 0x34 + LegoCacheSound* m_unk0x38; // 0x38 + undefined4 m_unk0x3c; // 0x3c + undefined m_unk0x40; // 0x40 + undefined4 m_unk0x44; // 0x44 + MxS8 m_unk0x48; // 0x48 + undefined4 m_unk0x4c; // 0x4c }; // TEMPLATE: LEGO1 0x100194f0 diff --git a/LEGO1/lego/legoomni/include/act2brick.h b/LEGO1/lego/legoomni/include/act2brick.h index a0399730..6035e11d 100644 --- a/LEGO1/lego/legoomni/include/act2brick.h +++ b/LEGO1/lego/legoomni/include/act2brick.h @@ -31,8 +31,10 @@ class Act2Brick : public LegoPathActor { // SYNTHETIC: LEGO1 0x1007a450 // Act2Brick::`scalar deleting destructor' + void Remove(); void PlayWhistleSound(); void StopWhistleSound(); + void Mute(MxBool p_muted); private: static MxLong g_lastHitActorTime; diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 34c694c7..8bdccb60 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -68,15 +68,6 @@ class LegoAct2 : public LegoWorld { void SetUnknown0x1138(Act2Actor* p_unk0x1138) { m_unk0x1138 = p_unk0x1138; } void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } - undefined4 FUN_10052560( - MxS32 p_param1, - MxBool p_param2, - MxBool p_param3, - Mx3DPointFloat* p_location, - Mx3DPointFloat* p_direction, - Mx3DPointFloat* p_param6 - ); - // SYNTHETIC: LEGO1 0x1004fe20 // LegoAct2::`scalar deleting destructor' @@ -86,8 +77,19 @@ class LegoAct2 : public LegoWorld { MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param); void PlayMusic(JukeboxScript::Script p_objectId); void FUN_10051900(); + void FUN_10051960(); void InitBricks(); void UninitBricks(); + void FUN_10051ac0(); + MxResult FUN_10052560( + Act2mainScript::Script p_objectId, + MxBool p_param2, + MxBool p_param3, + Mx3DPointFloat* p_location, + Mx3DPointFloat* p_direction, + Mx3DPointFloat* p_param6 + ); + MxResult FUN_10052800(); Act2Brick m_bricks[10]; // 0x00f8 undefined m_unk0x10c0; // 0x10c0 @@ -110,7 +112,7 @@ class LegoAct2 : public LegoWorld { undefined4 m_unk0x1134; // 0x1134 Act2Actor* m_unk0x1138; // 0x1138 undefined m_unk0x113c; // 0x113c - undefined4 m_unk0x1140; // 0x1140 + Act2mainScript::Script m_unk0x1140; // 0x1140 Act2mainScript::Script m_unk0x1144; // 0x1144 undefined m_unk0x1148[0x08]; // 0x1148 LegoGameState::Area m_destLocation; // 0x1150 diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index b43dcb49..f09c8dae 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -157,7 +157,7 @@ class LegoAnimationManager : public MxCore { MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info); void FUN_10060480(LegoChar* p_characterNames[], MxU32 p_numCharacterNames); void FUN_100604d0(MxBool p_unk0x08); - void FUN_100604f0(MxS32 p_objectIds[], undefined4 p_numObjectIds); + void FUN_100604f0(MxS32 p_objectIds[], MxU32 p_numObjectIds); void FUN_10060540(MxBool p_unk0x29); void FUN_10060570(MxBool p_unk0x1a); MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity); diff --git a/LEGO1/lego/legoomni/include/legocachsound.h b/LEGO1/lego/legoomni/include/legocachsound.h index 196bfb55..59834811 100644 --- a/LEGO1/lego/legoomni/include/legocachsound.h +++ b/LEGO1/lego/legoomni/include/legocachsound.h @@ -44,7 +44,8 @@ class LegoCacheSound : public MxCore { void Stop(); void FUN_10006be0(); void SetDistance(MxS32 p_min, MxS32 p_max); - void Mute(MxBool p_mute); + void MuteSilence(MxBool p_muted); + void MuteStop(MxBool p_mute); // SYNTHETIC: LEGO1 0x10006610 // LegoCacheSound::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 36fe47c6..d38ee3d1 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -39,12 +39,12 @@ Act2Actor::Act2Actor() m_unk0x28 = 4; m_unk0x2c = 0; m_unk0x30 = 0; - m_unk0x34 = 0; + m_shootAnim = NULL; m_unk0x44 = 0; m_unk0x40 = 1; m_unk0x48 = 0; m_unk0x4c = 0; - m_unk0x38 = 0; + m_unk0x38 = NULL; m_unk0x3c = 0; // Odd: The code says < 10, but there are 11 entries in the array @@ -61,6 +61,23 @@ void Act2Actor::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) m_roi->SetVisibility(FALSE); } +// FUNCTION: LEGO1 0x10018980 +// FUNCTION: BETA10 0x1000c963 +void Act2Actor::FUN_10018980() +{ + for (MxS32 i = 0; i < m_animMaps.size(); i++) { + if (m_animMaps[i]->GetUnknown0x00() == -1.0f) { + m_shootAnim = m_animMaps[i]; + } + } + + assert(m_shootAnim); + + m_unk0x38 = SoundManager()->GetCacheSoundManager()->FindSoundByKey("xarrow"); + m_unk0x38->SetDistance(45, 55); + m_roi->SetVisibility(TRUE); +} + // FUNCTION: LEGO1 0x100189f0 // FUNCTION: BETA10 0x1000ca64 MxResult Act2Actor::VTable0x94(LegoPathActor*, MxBool) diff --git a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp index 47e9b98c..c489fb00 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp @@ -253,9 +253,26 @@ void LegoCacheSound::FUN_10006cd0(undefined4, undefined4) { } +// FUNCTION: LEGO1 0x10006ce0 +void LegoCacheSound::MuteSilence(MxBool p_muted) +{ + if (m_muted != p_muted) { + m_muted = p_muted; + + if (m_muted) { + m_dsBuffer->SetVolume(-3000); + } + else { + MxS32 volume = m_volume * SoundManager()->GetVolume() / 100; + MxS32 attenuation = SoundManager()->GetAttenuation(volume); + m_dsBuffer->SetVolume(attenuation); + } + } +} + // FUNCTION: LEGO1 0x10006d40 // FUNCTION: BETA10 0x10066ec8 -void LegoCacheSound::Mute(MxBool p_muted) +void LegoCacheSound::MuteStop(MxBool p_muted) { if (m_muted != p_muted) { m_muted = p_muted; diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 9f8ede5d..1b885e70 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -903,7 +903,7 @@ void LegoAnimationManager::FUN_100604d0(MxBool p_unk0x08) // FUNCTION: LEGO1 0x100604f0 // FUNCTION: BETA10 0x1004137b -void LegoAnimationManager::FUN_100604f0(MxS32 p_objectIds[], undefined4 p_numObjectIds) +void LegoAnimationManager::FUN_100604f0(MxS32 p_objectIds[], MxU32 p_numObjectIds) { for (MxS32 i = 0; i < p_numObjectIds; i++) { for (MxS32 j = 0; j < m_animCount; j++) { diff --git a/LEGO1/lego/legoomni/src/entity/act2brick.cpp b/LEGO1/lego/legoomni/src/entity/act2brick.cpp index 9724f3b4..78be6cf0 100644 --- a/LEGO1/lego/legoomni/src/entity/act2brick.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2brick.cpp @@ -1,6 +1,7 @@ #include "act2brick.h" #include "legocachesoundmanager.h" +#include "legocharactermanager.h" #include "legosoundmanager.h" #include "legoworld.h" #include "misc.h" @@ -32,6 +33,21 @@ Act2Brick::~Act2Brick() TickleManager()->UnregisterClient(this); } +// FUNCTION: LEGO1 0x1007a620 +// FUNCTION: BETA10 0x10012ba2 +void Act2Brick::Remove() +{ + StopWhistleSound(); + CurrentWorld()->Remove(this); + + if (m_roi != NULL) { + CharacterManager()->ReleaseActor(m_roi->GetName()); + m_roi = NULL; + } + + m_unk0x164 = 0; +} + // FUNCTION: LEGO1 0x1007a750 MxResult Act2Brick::VTable0x94(LegoPathActor* p_actor, MxBool) { @@ -108,3 +124,11 @@ void Act2Brick::StopWhistleSound() m_whistleSound = NULL; } } + +// FUNCTION: LEGO1 0x1007aa00 +void Act2Brick::Mute(MxBool p_muted) +{ + if (m_whistleSound != NULL) { + m_whistleSound->MuteSilence(p_muted); + } +} diff --git a/LEGO1/lego/legoomni/src/entity/legoactor.cpp b/LEGO1/lego/legoomni/src/entity/legoactor.cpp index 93f7c94b..413b5171 100644 --- a/LEGO1/lego/legoomni/src/entity/legoactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoactor.cpp @@ -144,6 +144,6 @@ void LegoActor::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) void LegoActor::Mute(MxBool p_muted) { if (m_sound != NULL) { - m_sound->Mute(p_muted); + m_sound->MuteStop(p_muted); } } diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 7f5d967c..c6699c12 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -9,6 +9,7 @@ #include "legocachesoundmanager.h" #include "legogamestate.h" #include "legoinputmanager.h" +#include "legolocomotionanimpresenter.h" #include "legomain.h" #include "legopathstruct.h" #include "legosoundmanager.h" @@ -20,6 +21,8 @@ #include "mxmisc.h" #include "mxnotificationmanager.h" #include "mxticklemanager.h" +#include "mxtransitionmanager.h" +#include "mxvariabletable.h" #include "scripts.h" #include @@ -28,7 +31,7 @@ DECOMP_SIZE_ASSERT(LegoAct2, 0x1154) DECOMP_SIZE_ASSERT(LegoAct2State, 0x10) // GLOBAL: LEGO1 0x100f4474 -undefined4 g_unk0x100f4474 = 0; +Act2mainScript::Script g_unk0x100f4474 = (Act2mainScript::Script) 0; // GLOBAL: LEGO1 0x100f43f0 // GLOBAL: BETA10 0x101e14a8 @@ -46,6 +49,25 @@ MxS32 g_unk0x100f43f0[] = { // GLOBAL: LEGO1 0x100f4410 LegoChar* g_unk0x100f4410[] = {"bd", "pg", "rd", "sy", "ro", "cl"}; +// GLOBAL: LEGO1 0x100f4428 +MxS32 g_unk0x100f4428[] = { + Act2mainScript::c_snsx07pa_RunAnim, + Act2mainScript::c_snsx12ni_RunAnim, + Act2mainScript::c_snsx15la_RunAnim, + Act2mainScript::c_snsx47cl_RunAnim, + Act2mainScript::c_snsx65pg_RunAnim, + Act2mainScript::c_snsx68pg_RunAnim, + Act2mainScript::c_snsx69rd_RunAnim, + Act2mainScript::c_snsx72sy_RunAnim, + 0, + 0, + 0, + 0 +}; + +// GLOBAL: LEGO1 0x100f4458 +LegoChar* g_unk0x100f4458[] = {"papa", "nick", "laura", "cl", "pg", "rd", "sy"}; + // FUNCTION: LEGO1 0x1004fce0 // FUNCTION: BETA10 0x1003a5a0 LegoAct2::LegoAct2() @@ -59,8 +81,8 @@ LegoAct2::LegoAct2() m_unk0x10c0 = 0; m_unk0x10c1 = 0; m_unk0x1138 = NULL; - m_unk0x1140 = 0; - m_unk0x1144 = Act2mainScript::c__Act2Main; + m_unk0x1140 = (Act2mainScript::Script) 0; + m_unk0x1144 = (Act2mainScript::Script) 0; m_destLocation = LegoGameState::e_undefined; m_music = JukeboxScript::c_MusicTheme1; m_siFile = ""; @@ -175,7 +197,7 @@ MxResult LegoAct2::Tickle() if (g_unk0x100f4474) { if (AnimationManager()->FUN_10064ee0(g_unk0x100f4474)) { FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); - g_unk0x100f4474 = 0; + g_unk0x100f4474 = (Act2mainScript::Script) 0; } } @@ -204,12 +226,12 @@ MxResult LegoAct2::Tickle() distance = DISTSQRD3(pepperPosition, otherPoint); - if (m_unk0x1144 == Act2mainScript::c__Act2Main && distance > 50.0f && pepperPosition[0] > -57.0f) { + if (m_unk0x1144 == (Act2mainScript::Script) 0 && distance > 50.0f && pepperPosition[0] > -57.0f) { FUN_10052560(Act2mainScript::c_Avo906In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); m_unk0x1144 = Act2mainScript::c_Avo906In_PlayWav; } } - else if (m_unk0x10d0 >= 90000 && m_unk0x10d0 % 90000 == 0 && m_unk0x1144 == Act2mainScript::c__Act2Main) { + else if (m_unk0x10d0 >= 90000 && m_unk0x10d0 % 90000 == 0 && m_unk0x1144 == (Act2mainScript::Script) 0) { FUN_10052560(Act2mainScript::c_Avo908In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); m_unk0x1144 = Act2mainScript::c_Avo908In_PlayWav; } @@ -324,10 +346,123 @@ MxLong LegoAct2::Notify(MxParam& p_param) return result; } -// STUB: LEGO1 0x100506f0 +// FUNCTION: LEGO1 0x100506f0 MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param) { - // TODO + if (m_gameState->m_enabled && p_param.GetAction() != NULL) { + MxU32 objectId = p_param.GetAction()->GetObjectId(); + + if (m_unk0x10c4 == 5 && m_unk0x1144 == objectId) { + m_unk0x1144 = (Act2mainScript::Script) 0; + return 0; + } + + if (m_unk0x1140 != objectId) { + return 0; + } + + m_unk0x1140 = (Act2mainScript::Script) 0; + + switch (m_unk0x10c4) { + case 2: + m_unk0x10c4 = 3; + break; + case 4: + FUN_10051960(); + m_unk0x10c4 = 5; + m_unk0x10d0 = 0; + break; + case 6: { + LegoROI* roi; + + roi = FindROI("nick"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("laura"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("motoni"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("motola"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("Block01"); + RemoveActor((LegoPathActor*) roi->GetEntity()); + roi->SetVisibility(FALSE); + + roi = FindROI("Block02"); + RemoveActor((LegoPathActor*) roi->GetEntity()); + roi->SetVisibility(FALSE); + + VariableTable()->SetVariable("ACTOR_01", "brickstr"); + FUN_10052800(); + m_unk0x10c4 = 7; + PlayMusic(JukeboxScript::c_BrickstrChase); + break; + } + case 11: + m_bricks[m_unk0x10c0 - 1].Mute(TRUE); + m_unk0x10c4 = 12; + m_unk0x10d0 = 0; + + FUN_10052560(Act2mainScript::c_tra045la_RunAnim, TRUE, TRUE, NULL, NULL, NULL); + ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3); + AnimationManager()->EnableCamAnims(TRUE); + AnimationManager()->FUN_1005f6d0(TRUE); + AnimationManager()->FUN_100604f0(g_unk0x100f4428, sizeOfArray(g_unk0x100f4428)); + AnimationManager()->FUN_10060480(g_unk0x100f4458, sizeOfArray(g_unk0x100f4458)); + break; + case 12: { + LegoROI* roi; + + roi = FindROI("nick"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("laura"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("motoni"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("motola"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + m_bricks[m_unk0x10c0 - 1].Mute(FALSE); + m_unk0x10c4 = 13; + FUN_10051ac0(); + PlayMusic(JukeboxScript::c_BrickHunt); + ((LegoPathActor*) m_pepper->GetEntity())->SetState(0); + break; + } + case 14: + for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_bricks); i++) { + m_bricks[i].Remove(); + } + + FUN_10051900(); + m_destLocation = LegoGameState::e_copterbuild; + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + break; + } + } + return 0; } @@ -391,7 +526,7 @@ void LegoAct2::Enable(MxBool p_enable) MxDSAction action; MxEndActionNotificationParam param(c_notificationEndAction, NULL, &action, FALSE); - m_unk0x1140 = 0; + m_unk0x1140 = (Act2mainScript::Script) 0; action.SetObjectId(0); HandleEndAction(param); } @@ -407,13 +542,13 @@ void LegoAct2::Enable(MxBool p_enable) UninitBricks(); DeleteObjects(&m_atomId, Act2mainScript::c_VOhead0_PlayWav, Act2mainScript::c_VOhide_PlayWav); - if (m_unk0x1144 != Act2mainScript::c__Act2Main) { + if (m_unk0x1144 != (Act2mainScript::Script) 0) { MxDSAction action; action.SetAtomId(m_atomId); action.SetUnknown24(-2); action.SetObjectId(m_unk0x1144); DeleteObject(action); - m_unk0x1144 = Act2mainScript::c__Act2Main; + m_unk0x1144 = (Act2mainScript::Script) 0; } TickleManager()->UnregisterClient(this); @@ -453,6 +588,30 @@ void LegoAct2::FUN_10051900() } } +// FUNCTION: LEGO1 0x10051960 +// FUNCTION: BETA10 0x1003bf2c +void LegoAct2::FUN_10051960() +{ + LegoROI* roi; + + roi = FindROI("mama"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("papa"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + roi = FindROI("infoman"); + if (roi != NULL) { + roi->SetVisibility(FALSE); + } + + ((LegoPathActor*) m_pepper->GetEntity())->SetState(0); +} + // FUNCTION: LEGO1 0x100519c0 void LegoAct2::VTable0x60() { @@ -500,10 +659,17 @@ void LegoAct2::UninitBricks() } } +// STUB: LEGO1 0x10051ac0 +// STUB: BETA10 0x100138c0 +void LegoAct2::FUN_10051ac0() +{ + // TODO +} + // FUNCTION: LEGO1 0x10052560 // FUNCTION: BETA10 0x100145c6 -undefined4 LegoAct2::FUN_10052560( - MxS32 p_param1, +MxResult LegoAct2::FUN_10052560( + Act2mainScript::Script p_objectId, MxBool p_param2, MxBool p_param3, Mx3DPointFloat* p_location, @@ -511,14 +677,13 @@ undefined4 LegoAct2::FUN_10052560( Mx3DPointFloat* p_param6 ) { - - if (m_unk0x1140 == 0 || p_param3) { + if (m_unk0x1140 == (Act2mainScript::Script) 0 || p_param3) { assert(strlen(m_siFile)); if (!p_param2) { MxDSAction action; - action.SetObjectId(p_param1); + action.SetObjectId(p_objectId); // World index: see LegoOmni::RegisterWorlds action.SetAtomId(*Lego()->GetWorldAtom(15)); @@ -575,19 +740,50 @@ undefined4 LegoAct2::FUN_10052560( MxResult result; - if (p_param1 == Act2mainScript::c_tja009ni_RunAnim) { - result = AnimationManager()->FUN_10060dc0(p_param1, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, TRUE); + if (p_objectId == Act2mainScript::c_tja009ni_RunAnim) { + result = + AnimationManager()->FUN_10060dc0(p_objectId, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, TRUE); } else { result = - AnimationManager()->FUN_10060dc0(p_param1, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, FALSE); + AnimationManager()->FUN_10060dc0(p_objectId, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, FALSE); } if (result == SUCCESS) { - m_unk0x1140 = p_param1; + m_unk0x1140 = p_objectId; } } } - return 0; + return SUCCESS; +} + +// FUNCTION: LEGO1 0x10052800 +// FUNCTION: BETA10 0x10014aa8 +MxResult LegoAct2::FUN_10052800() +{ + LegoPathActor* actor = m_unk0x1138; + LegoLocomotionAnimPresenter* ap; + + PlaceActor(actor, "EDG01_27", 2, 0.5f, 0, 0.5f); + + ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim0"); + assert(ap); + ap->FUN_1006d680(m_unk0x1138, 0.0f); + + ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim2"); + assert(ap); + ap->FUN_1006d680(m_unk0x1138, 6.0f); + + ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim3"); + assert(ap); + ap->FUN_1006d680(m_unk0x1138, 3.0f); + + ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "BrShoot"); + assert(ap); + ap->FUN_1006d680(m_unk0x1138, -1.0f); + + actor->SetWorldSpeed(0.0f); + m_unk0x1138->FUN_10018980(); + return SUCCESS; } From aaf5e1ddc7ef70faf5b0c4c8755597c2be760f4b Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 2 Dec 2024 11:44:42 -0700 Subject: [PATCH 05/14] Implement/match LegoAct2::ReadyWorld (#1185) --- LEGO1/lego/legoomni/include/legoact2.h | 4 +- .../legoomni/src/common/legogamestate.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 49 +++++++++++++++++-- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 8bdccb60..3a61d505 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -94,14 +94,14 @@ class LegoAct2 : public LegoWorld { Act2Brick m_bricks[10]; // 0x00f8 undefined m_unk0x10c0; // 0x10c0 undefined m_unk0x10c1; // 0x10c1 - undefined m_unk0x10c2; // 0x10c2 + MxBool m_ready; // 0x10c2 undefined4 m_unk0x10c4; // 0x10c4 JukeboxScript::Script m_music; // 0x10c8 LegoAct2State* m_gameState; // 0x10cc MxS32 m_unk0x10d0; // 0x10d0 // variable name verified by BETA10 0x10014633 - char* m_siFile; // 0x10d4 + const char* m_siFile; // 0x10d4 LegoROI* m_pepper; // 0x10d8 MxMatrix m_unk0x10dc; // 0x10dc diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index 6943969b..e8835e82 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -197,7 +197,7 @@ void LegoGameState::SetActor(MxU8 p_actorId) delete oldActor; } - newActor->ClearFlag(0x02); + newActor->ClearFlag(LegoEntity::c_managerOwned); SetUserActor(newActor); } diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index c6699c12..9c1eb733 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -1,5 +1,6 @@ #include "legoact2.h" +#include "3dmanager/lego3dmanager.h" #include "act2actor.h" #include "act2main_actions.h" #include "infomain_actions.h" @@ -14,6 +15,7 @@ #include "legopathstruct.h" #include "legosoundmanager.h" #include "legoutils.h" +#include "legovideomanager.h" #include "misc.h" #include "mxactionnotificationparam.h" #include "mxbackgroundaudiomanager.h" @@ -76,7 +78,7 @@ LegoAct2::LegoAct2() m_gameState = NULL; m_pepper = NULL; m_ambulance = NULL; - m_unk0x10c2 = 0; + m_ready = FALSE; m_unk0x1130 = 0; m_unk0x10c0 = 0; m_unk0x10c1 = 0; @@ -100,7 +102,7 @@ MxBool LegoAct2::VTable0x5c() // FUNCTION: BETA10 0x1003a6f0 LegoAct2::~LegoAct2() { - if (m_unk0x10c2) { + if (m_ready) { TickleManager()->UnregisterClient(this); } @@ -477,10 +479,49 @@ MxLong LegoAct2::HandleTransitionEnd() return 1; } -// STUB: LEGO1 0x10050a80 +// FUNCTION: LEGO1 0x10050a80 void LegoAct2::ReadyWorld() { - // TODO + LegoWorld::ReadyWorld(); + + AnimationManager()->Resume(); + TickleManager()->RegisterClient(this, 20); + + m_ready = TRUE; + m_siFile = VariableTable()->GetVariable("ACT2_ANIMS_FILE"); + + GameState()->SetActor(LegoActor::c_pepper); + m_pepper = FindROI("pepper"); + IslePathActor* pepper = (IslePathActor*) m_pepper->GetEntity(); + pepper->SpawnPlayer( + LegoGameState::e_unk50, + TRUE, + IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3 + ); + + LegoROI* roi = FindROI("Block01"); + BoundingSphere sphere = roi->GetBoundingSphere(); + sphere.Radius() *= 1.5; + roi->SetBoundingSphere(sphere); + LegoPathActor* actor = (LegoPathActor*) roi->GetEntity(); + PlaceActor(actor, "EDG01_04", 1, 0.5f, 3, 0.5f); + + MxMatrix local2world = roi->GetLocal2World(); + local2world[3][0] -= 1.5; + roi->FUN_100a58f0(local2world); + roi->VTable0x14(); + + roi = FindROI("Block02"); + sphere = roi->GetBoundingSphere(); + sphere.Radius() *= 1.5; + roi->SetBoundingSphere(sphere); + actor = (LegoPathActor*) roi->GetEntity(); + PlaceActor(actor, "EDG00_149", 0, 0.5f, 2, 0.5f); + + PlayMusic(JukeboxScript::c_Jail_Music); + FUN_10051900(); + VideoManager()->Get3DManager()->SetFrustrum(90.0f, 0.1f, 250.f); + m_gameState->m_enabled = TRUE; } // FUNCTION: LEGO1 0x10050cf0 From 3c624ff14cacf0ba355046fb5c0c34a52c90c3a2 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:12:05 +0100 Subject: [PATCH 06/14] Implement `Act2Actor::VTable0x9c()` (#1186) Co-authored-by: jonschz --- LEGO1/lego/legoomni/src/actors/act2actor.cpp | 23 +++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index d38ee3d1..1ddb4b3d 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -91,11 +91,28 @@ MxResult Act2Actor::VTable0x94(LegoPathActor*, MxBool) return SUCCESS; } -// STUB: LEGO1 0x10018a20 +// FUNCTION: LEGO1 0x10018a20 MxResult Act2Actor::VTable0x9c() { - // TODO - return SUCCESS; + if (m_grec && !(m_grec->m_flags & LegoPathEdgeContainer::c_bit1)) { + delete m_grec; + m_grec = NULL; + return SUCCESS; + } + else { + if (m_unk0x1f) { + MxMatrix matrix = m_roi->GetLocal2World(); + matrix[3][1] -= 3.0f; + m_roi->UpdateTransformationRelativeToParent(matrix); + + LegoROI* brickstrROI = FindROI("brickstr"); + MxMatrix brickstrMatrix = brickstrROI->GetLocal2World(); + brickstrMatrix[3][1] -= 3.0f; + brickstrROI->UpdateTransformationRelativeToParent(brickstrMatrix); + } + + return LegoPathActor::VTable0x9c(); + } } // STUB: LEGO1 0x10018c30 From 5693b1a26622a6a0d278bd9fab58d2b74562c2cb Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 3 Dec 2024 13:31:24 -0700 Subject: [PATCH 07/14] Implement/match `LegoAct2::HandlePathStruct` (#1187) * Implement/match `LegoAct2::HandlePathStruct` * Add Act2Brick::FUN_1007a670 * Add Act2Brick::Create * Name variable * Add stdio.h --- LEGO1/lego/legoomni/include/act2actor.h | 1 + LEGO1/lego/legoomni/include/act2brick.h | 3 + LEGO1/lego/legoomni/include/legoact2.h | 4 +- LEGO1/lego/legoomni/src/actors/act2actor.cpp | 8 ++ LEGO1/lego/legoomni/src/entity/act2brick.cpp | 57 +++++++++++++ LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 85 ++++++++++++++++++-- 6 files changed, 149 insertions(+), 9 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index c45effeb..897d0615 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -29,6 +29,7 @@ class Act2Actor : public LegoAnimActor { void FUN_10018980(); void FUN_10019520(); + void FUN_10019560(); void FUN_100192a0(undefined4 p_param); // SYNTHETIC: LEGO1 0x1001a0a0 diff --git a/LEGO1/lego/legoomni/include/act2brick.h b/LEGO1/lego/legoomni/include/act2brick.h index 6035e11d..1ad730f2 100644 --- a/LEGO1/lego/legoomni/include/act2brick.h +++ b/LEGO1/lego/legoomni/include/act2brick.h @@ -31,12 +31,15 @@ class Act2Brick : public LegoPathActor { // SYNTHETIC: LEGO1 0x1007a450 // Act2Brick::`scalar deleting destructor' + MxResult Create(MxS32 p_index); void Remove(); + void FUN_1007a670(MxMatrix& p_param1, MxMatrix& p_param2, LegoPathBoundary* p_boundary); void PlayWhistleSound(); void StopWhistleSound(); void Mute(MxBool p_muted); private: + static LegoChar* g_lodNames[]; static MxLong g_lastHitActorTime; LegoCacheSound* m_whistleSound; // 0x154 diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 3a61d505..588a53b2 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -81,6 +81,8 @@ class LegoAct2 : public LegoWorld { void InitBricks(); void UninitBricks(); void FUN_10051ac0(); + void FUN_10051fa0(MxS32 p_param1); + void FUN_100521f0(MxS32 p_param1); MxResult FUN_10052560( Act2mainScript::Script p_objectId, MxBool p_param2, @@ -92,7 +94,7 @@ class LegoAct2 : public LegoWorld { MxResult FUN_10052800(); Act2Brick m_bricks[10]; // 0x00f8 - undefined m_unk0x10c0; // 0x10c0 + undefined m_nextBrick; // 0x10c0 undefined m_unk0x10c1; // 0x10c1 MxBool m_ready; // 0x10c2 undefined4 m_unk0x10c4; // 0x10c4 diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 1ddb4b3d..1bb3e335 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -177,6 +177,14 @@ void Act2Actor::FUN_10019520() FUN_100192a0(10); } +// FUNCTION: LEGO1 0x10019560 +void Act2Actor::FUN_10019560() +{ + m_unk0x1e = 5; + SetWorldSpeed(m_unk0x28 + 5); + FUN_100192a0(9); +} + // FUNCTION: LEGO1 0x100195a0 // FUNCTION: BETA10 0x1000d7d3 MxS32 Act2Actor::VTable0xa0() diff --git a/LEGO1/lego/legoomni/src/entity/act2brick.cpp b/LEGO1/lego/legoomni/src/entity/act2brick.cpp index 78be6cf0..a3049c1b 100644 --- a/LEGO1/lego/legoomni/src/entity/act2brick.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2brick.cpp @@ -12,10 +12,15 @@ #include "mxtimer.h" #include "roi/legoroi.h" +#include #include DECOMP_SIZE_ASSERT(Act2Brick, 0x194) +// GLOBAL: LEGO1 0x100f7a38 +LegoChar* Act2Brick::g_lodNames[] = + {"xchbase1", "xchblad1", "xchseat1", "xchtail1", "xhback1", "xhljet1", "xhmidl1", "xhmotr1", "xhsidl1", "xhsidr1"}; + // GLOBAL: LEGO1 0x100f7a60 MxLong Act2Brick::g_lastHitActorTime = 0; @@ -33,6 +38,36 @@ Act2Brick::~Act2Brick() TickleManager()->UnregisterClient(this); } +// FUNCTION: LEGO1 0x1007a4e0 +// FUNCTION: BETA10 0x10012ad5 +MxResult Act2Brick::Create(MxS32 p_index) +{ + if (m_roi != NULL) { + return FAILURE; + } + + char name[12]; + sprintf(name, "chbrick%d", p_index); + + m_roi = CharacterManager()->CreateAutoROI(name, g_lodNames[p_index], FALSE); + + BoundingSphere sphere = m_roi->GetBoundingSphere(); + sphere.Center()[1] -= 0.3; + + if (p_index < 6) { + sphere.Radius() = m_roi->GetBoundingSphere().Radius() * 0.5f; + } + else { + sphere.Radius() = m_roi->GetBoundingSphere().Radius() * 2.0f; + } + + m_roi->SetBoundingSphere(sphere); + m_roi->SetEntity(this); + CurrentWorld()->Add(this); + m_unk0x164 = 1; + return SUCCESS; +} + // FUNCTION: LEGO1 0x1007a620 // FUNCTION: BETA10 0x10012ba2 void Act2Brick::Remove() @@ -48,6 +83,28 @@ void Act2Brick::Remove() m_unk0x164 = 0; } +// FUNCTION: LEGO1 0x1007a670 +// FUNCTION: BETA10 0x10012c04 +void Act2Brick::FUN_1007a670(MxMatrix& p_param1, MxMatrix& p_param2, LegoPathBoundary* p_boundary) +{ + m_unk0x17c = p_param2[3]; + m_unk0x168 = p_param2[3]; + ((Vector3&) m_unk0x168).Sub(p_param1[3]); + ((Vector3&) m_unk0x168).Div(8.0f); + + m_unk0x190 = 0; + TickleManager()->RegisterClient(this, 20); + + m_unk0x164 = 2; + CurrentWorld()->PlaceActor(this); + p_boundary->AddActor(this); + + SetState(LegoPathActor::c_bit3); + m_roi->FUN_100a58f0(p_param1); + m_roi->VTable0x14(); + m_roi->SetVisibility(TRUE); +} + // FUNCTION: LEGO1 0x1007a750 MxResult Act2Brick::VTable0x94(LegoPathActor* p_actor, MxBool) { diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 9c1eb733..5afe4a83 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -80,7 +80,7 @@ LegoAct2::LegoAct2() m_ambulance = NULL; m_ready = FALSE; m_unk0x1130 = 0; - m_unk0x10c0 = 0; + m_nextBrick = 0; m_unk0x10c1 = 0; m_unk0x1138 = NULL; m_unk0x1140 = (Act2mainScript::Script) 0; @@ -246,7 +246,7 @@ MxResult LegoAct2::Tickle() m_unk0x10d0 += 50; if (m_unk0x10d0 >= 200) { - if (m_unk0x10c0 < 5) { + if (m_nextBrick < 5) { m_unk0x10c4 = 7; } else { @@ -412,7 +412,7 @@ MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param) break; } case 11: - m_bricks[m_unk0x10c0 - 1].Mute(TRUE); + m_bricks[m_nextBrick - 1].Mute(TRUE); m_unk0x10c4 = 12; m_unk0x10d0 = 0; @@ -446,7 +446,7 @@ MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param) roi->SetVisibility(FALSE); } - m_bricks[m_unk0x10c0 - 1].Mute(FALSE); + m_bricks[m_nextBrick - 1].Mute(FALSE); m_unk0x10c4 = 13; FUN_10051ac0(); PlayMusic(JukeboxScript::c_BrickHunt); @@ -552,7 +552,7 @@ void LegoAct2::Enable(MxBool p_enable) PlayMusic(m_music); } - if (m_unk0x10c4 == 10 && m_unk0x10c0 == 6 && m_bricks[5].GetROI() != NULL) { + if (m_unk0x10c4 == 10 && m_nextBrick == 6 && m_bricks[5].GetROI() != NULL) { m_bricks[5].PlayWhistleSound(); } else if (m_unk0x10c4 == 13) { @@ -596,11 +596,66 @@ void LegoAct2::Enable(MxBool p_enable) } } -// STUB: LEGO1 0x10051460 -// STUB: BETA10 0x1003bb72 +// FUNCTION: LEGO1 0x10051460 +// FUNCTION: BETA10 0x1003bb72 MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param) { - // TODO + if (m_unk0x10c4 == 5 && p_param.GetData() == 0x32) { + LegoPathActor* actor = (LegoPathActor*) m_pepper->GetEntity(); + actor->SetState(LegoPathActor::c_bit3); + actor->SetWorldSpeed(0.0f); + FUN_10051900(); + + if (m_unk0x10d0 < 90000) { + FUN_10052560(Act2mainScript::c_tra031ni_RunAnim, TRUE, TRUE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_tra032ni_RunAnim, TRUE, TRUE, NULL, NULL, NULL); + } + + m_unk0x112c = 50; + m_unk0x10c4 = 6; + m_unk0x10d0 = 0; + } + else if (m_unk0x10c4 == 5 && p_param.GetData() == 0x2a) { + if (m_unk0x1144 == (Act2mainScript::Script) 0) { + FUN_10052560(Act2mainScript::c_Avo907In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + m_unk0x1144 = Act2mainScript::c_Avo907In_PlayWav; + } + } + else if (m_unk0x10c4 == 5) { + FUN_100521f0(p_param.GetData()); + } + else if (m_unk0x10c4 == 7) { + FUN_10051fa0(p_param.GetData()); + } + else if (m_unk0x10c4 == 10 && p_param.GetData() == 0x165) { + ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3); + + if (FUN_10052560(Act2mainScript::c_VOhide_PlayWav, FALSE, TRUE, NULL, NULL, NULL) == SUCCESS) { + m_unk0x1140 = Act2mainScript::c_VOhide_PlayWav; + } + + m_unk0x1138->FUN_10019560(); + + m_unk0x10c4 = 11; + m_unk0x10d0 = 0; + + if (m_nextBrick < 6) { + m_bricks[m_nextBrick].Create(m_nextBrick); + m_nextBrick++; + } + + MxMatrix local2world = m_ambulance->GetLocal2World(); + MxMatrix local2world2 = local2world; + + LegoPathBoundary* boundary = m_unk0x1138->GetBoundary(); + local2world[3][1] += 1.5; + local2world2[3][1] -= 0.1; + + m_bricks[m_nextBrick - 1].FUN_1007a670(local2world, local2world2, boundary); + } + return 0; } @@ -707,6 +762,20 @@ void LegoAct2::FUN_10051ac0() // TODO } +// STUB: LEGO1 0x10051fa0 +// STUB: BETA10 0x10013fd3 +void LegoAct2::FUN_10051fa0(MxS32 p_param1) +{ + // TODO +} + +// STUB: LEGO1 0x100521f0 +// STUB: BETA10 0x100142f1 +void LegoAct2::FUN_100521f0(MxS32 p_param1) +{ + // TODO +} + // FUNCTION: LEGO1 0x10052560 // FUNCTION: BETA10 0x100145c6 MxResult LegoAct2::FUN_10052560( From 7ece9cf37b319a574ca107f4e492aa042b8af369 Mon Sep 17 00:00:00 2001 From: MS Date: Tue, 3 Dec 2024 17:51:03 -0500 Subject: [PATCH 08/14] Fix MxParam casts in Notify functions (#1188) * First batch * Second batch --- LEGO1/lego/legoomni/src/actors/ambulance.cpp | 3 ++- LEGO1/lego/legoomni/src/actors/buildingentity.cpp | 5 ++++- LEGO1/lego/legoomni/src/actors/bumpbouy.cpp | 4 +++- LEGO1/lego/legoomni/src/actors/isleactor.cpp | 4 +++- LEGO1/lego/legoomni/src/actors/islepathactor.cpp | 4 +++- LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp | 5 ++++- LEGO1/lego/legoomni/src/actors/radio.cpp | 4 +++- LEGO1/lego/legoomni/src/actors/towtrack.cpp | 4 +++- .../legoomni/src/audio/mxbackgroundaudiomanager.cpp | 5 ++++- LEGO1/lego/legoomni/src/build/legocarbuild.cpp | 3 ++- LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp | 4 ++-- LEGO1/lego/legoomni/src/entity/act2brick.cpp | 6 +++++- LEGO1/lego/legoomni/src/entity/act2policestation.cpp | 5 ++++- .../lego/legoomni/src/entity/legocameracontroller.cpp | 1 + LEGO1/lego/legoomni/src/race/legorace.cpp | 3 ++- LEGO1/lego/legoomni/src/race/legoracemap.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/gasstation.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/historybook.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/hospital.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/infocenter.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/isle.cpp | 5 ++++- LEGO1/lego/legoomni/src/worlds/jukebox.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/police.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/registrationbook.cpp | 4 +++- LEGO1/lego/legoomni/src/worlds/score.cpp | 5 ++++- LEGO1/omni/src/common/mxcompositepresenter.cpp | 10 +++++++++- 28 files changed, 92 insertions(+), 28 deletions(-) diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index 8d2d8374..92ce90a7 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -130,8 +130,9 @@ void Ambulance::CreateState() MxLong Ambulance::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationType0: result = HandleNotification0(); break; diff --git a/LEGO1/lego/legoomni/src/actors/buildingentity.cpp b/LEGO1/lego/legoomni/src/actors/buildingentity.cpp index 6ddd84d8..0f0423ee 100644 --- a/LEGO1/lego/legoomni/src/actors/buildingentity.cpp +++ b/LEGO1/lego/legoomni/src/actors/buildingentity.cpp @@ -19,9 +19,12 @@ BuildingEntity::~BuildingEntity() } // FUNCTION: LEGO1 0x100150a0 +// FUNCTION: BETA10 0x10024e37 MxLong BuildingEntity::Notify(MxParam& p_param) { - if (((MxNotificationParam&) p_param).GetNotification() == c_notificationClick) { + MxNotificationParam& param = (MxNotificationParam&) p_param; + + if (param.GetNotification() == c_notificationClick) { return HandleClick((LegoEventNotificationParam&) p_param); } diff --git a/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp b/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp index 24e6d5c7..371e4257 100644 --- a/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp +++ b/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp @@ -33,10 +33,12 @@ BumpBouy::~BumpBouy() MxLong BumpBouy::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; + IslePathActor* user = (IslePathActor*) UserActor(); assert(user); - if (user->IsA("Jetski") && ((MxNotificationParam&) p_param).GetNotification() == c_notificationClick) { + if (user->IsA("Jetski") && param.GetNotification() == c_notificationClick) { VideoManager()->SetRender3D(FALSE); user->SetWorldSpeed(0); user->Exit(); diff --git a/LEGO1/lego/legoomni/src/actors/isleactor.cpp b/LEGO1/lego/legoomni/src/actors/isleactor.cpp index 5bd1f503..6f718b55 100644 --- a/LEGO1/lego/legoomni/src/actors/isleactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/isleactor.cpp @@ -25,11 +25,13 @@ MxResult IsleActor::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x1002c7b0 +// FUNCTION: BETA10 0x1003622e MxLong IsleActor::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationType0: result = VTable0x6c(); break; diff --git a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp index 4aafa214..624fc8a9 100644 --- a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp @@ -46,11 +46,13 @@ void IslePathActor::Destroy(MxBool p_fromDestructor) } // FUNCTION: LEGO1 0x1001a2c0 +// FUNCTION: BETA10 0x100364ca MxLong IslePathActor::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationType0: result = HandleNotification0(); break; diff --git a/LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp b/LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp index 2ac6ed54..ecf0bec8 100644 --- a/LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp +++ b/LEGO1/lego/legoomni/src/actors/jukeboxentity.cpp @@ -30,9 +30,12 @@ JukeBoxEntity::~JukeBoxEntity() } // FUNCTION: LEGO1 0x10085e40 +// FUNCTION: BETA10 0x10038c37 MxLong JukeBoxEntity::Notify(MxParam& p_param) { - if (((MxNotificationParam&) p_param).GetNotification() == c_notificationClick) { + MxNotificationParam& param = (MxNotificationParam&) p_param; + + if (param.GetNotification() == c_notificationClick) { if (!FUN_1003ef60()) { return 1; } diff --git a/LEGO1/lego/legoomni/src/actors/radio.cpp b/LEGO1/lego/legoomni/src/actors/radio.cpp index 3a22ed16..4b84a430 100644 --- a/LEGO1/lego/legoomni/src/actors/radio.cpp +++ b/LEGO1/lego/legoomni/src/actors/radio.cpp @@ -81,12 +81,14 @@ Radio::~Radio() } // FUNCTION: LEGO1 0x1002ca30 +// FUNCTION: BETA10 0x100f19e8 MxLong Radio::Notify(MxParam& p_param) { MxLong result = 0; if (m_unk0x0c) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + MxNotificationParam& param = (MxNotificationParam&) p_param; + switch (param.GetNotification()) { case c_notificationEndAction: result = HandleEndAction((MxEndActionNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index 65ab9105..c329094d 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -113,11 +113,13 @@ void TowTrack::CreateState() } // FUNCTION: LEGO1 0x1004cc80 +// FUNCTION: BETA10 0x100f6de2 MxLong TowTrack::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationType0: result = HandleNotification0(); break; diff --git a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp index 98cf881b..60988521 100644 --- a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp @@ -196,9 +196,12 @@ void MxBackgroundAudioManager::FadeInOrFadeOut() } // FUNCTION: LEGO1 0x1007f170 +// FUNCTION: BETA10 0x100e8eb6 MxLong MxBackgroundAudioManager::Notify(MxParam& p_param) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + MxNotificationParam& param = (MxNotificationParam&) p_param; + + switch (param.GetNotification()) { case c_notificationStartAction: StartAction(p_param); return 1; diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index b86fecd4..e8ac3d7d 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -656,9 +656,10 @@ MxResult LegoCarBuild::Tickle() MxLong LegoCarBuild::Notify(MxParam& p_param) { MxLong result = LegoWorld::Notify(p_param); + MxNotificationParam& param = (MxNotificationParam&) p_param; if (m_worldStarted) { - switch (((MxNotificationParam*) &p_param)->GetNotification()) { + switch (param.GetNotification()) { case c_notificationType0: FUN_10024c20((LegoEventNotificationParam*) &p_param); result = 1; diff --git a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp index 1f854781..ef3df418 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp @@ -215,9 +215,9 @@ void LegoAnimMMPresenter::DoneTickle() MxLong LegoAnimMMPresenter::Notify(MxParam& p_param) { AUTOLOCK(m_criticalSection); + MxNotificationParam& param = (MxNotificationParam&) p_param; - if (((MxNotificationParam&) p_param).GetNotification() == c_notificationEndAction && - ((MxNotificationParam&) p_param).GetSender() == m_presenter) { + if (param.GetNotification() == c_notificationEndAction && param.GetSender() == m_presenter) { m_presenter = NULL; } diff --git a/LEGO1/lego/legoomni/src/entity/act2brick.cpp b/LEGO1/lego/legoomni/src/entity/act2brick.cpp index a3049c1b..427aae48 100644 --- a/LEGO1/lego/legoomni/src/entity/act2brick.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2brick.cpp @@ -12,6 +12,7 @@ #include "mxtimer.h" #include "roi/legoroi.h" +#include #include #include @@ -148,7 +149,9 @@ MxResult Act2Brick::Tickle() // FUNCTION: BETA10 0x10012ec4 MxLong Act2Brick::Notify(MxParam& p_param) { - if (((MxNotificationParam&) p_param).GetNotification() == c_notificationClick && m_roi->GetVisibility()) { + MxNotificationParam& param = (MxNotificationParam&) p_param; + + if (param.GetNotification() == c_notificationClick && m_roi->GetVisibility()) { m_roi->SetVisibility(FALSE); if (m_whistleSound != NULL) { @@ -160,6 +163,7 @@ MxLong Act2Brick::Notify(MxParam& p_param) return 1; } + assert(0); return 0; } diff --git a/LEGO1/lego/legoomni/src/entity/act2policestation.cpp b/LEGO1/lego/legoomni/src/entity/act2policestation.cpp index 0d95454f..0a0f7811 100644 --- a/LEGO1/lego/legoomni/src/entity/act2policestation.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2policestation.cpp @@ -9,9 +9,12 @@ DECOMP_SIZE_ASSERT(Act2PoliceStation, 0x68) // FUNCTION: LEGO1 0x1004e0e0 +// FUNCTION: BETA10 0x100137c0 MxLong Act2PoliceStation::Notify(MxParam& p_param) { - if (((MxNotificationParam&) p_param).GetNotification() == c_notificationClick) { + MxNotificationParam& param = (MxNotificationParam&) p_param; + + if (param.GetNotification() == c_notificationClick) { MxNotificationParam param(c_notificationType23, NULL); NotificationManager()->Send(CurrentWorld(), param); return 1; diff --git a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp index bd757bd5..b9d76039 100644 --- a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp @@ -38,6 +38,7 @@ MxResult LegoCameraController::Create() } // FUNCTION: LEGO1 0x10012020 +// FUNCTION: BETA10 0x10067852 MxLong LegoCameraController::Notify(MxParam& p_param) { switch (((MxNotificationParam&) p_param).GetNotification()) { diff --git a/LEGO1/lego/legoomni/src/race/legorace.cpp b/LEGO1/lego/legoomni/src/race/legorace.cpp index 2564f7a5..83d1eddc 100644 --- a/LEGO1/lego/legoomni/src/race/legorace.cpp +++ b/LEGO1/lego/legoomni/src/race/legorace.cpp @@ -89,10 +89,11 @@ LegoRace::~LegoRace() MxLong LegoRace::Notify(MxParam& p_param) { LegoWorld::Notify(p_param); + MxNotificationParam& param = (MxNotificationParam&) p_param; MxLong result = 0; if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationType0: HandleType0Notification((MxNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/race/legoracemap.cpp b/LEGO1/lego/legoomni/src/race/legoracemap.cpp index 950c344b..73867608 100644 --- a/LEGO1/lego/legoomni/src/race/legoracemap.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracemap.cpp @@ -124,7 +124,9 @@ MxLong LegoRaceMap::Notify(MxParam& p_param) return 1; } - if (((MxNotificationParam&) p_param).GetNotification() == c_notificationControl && + MxNotificationParam& param = (MxNotificationParam&) p_param; + + if (param.GetNotification() == c_notificationControl && m_Map_Ctl->GetAction()->GetObjectId() == ((LegoControlManagerNotificationParam&) p_param).GetClickedObjectId()) { diff --git a/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp b/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp index 8fefddf4..d8f7a05b 100644 --- a/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp +++ b/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp @@ -52,13 +52,15 @@ MxResult ElevatorBottom::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x10018150 +// FUNCTION: BETA10 0x10027d60 MxLong ElevatorBottom::Notify(MxParam& p_param) { + MxNotificationParam& param = (MxNotificationParam&) p_param; MxLong ret = 0; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationControl: ret = HandleControl((LegoControlManagerNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp index ebdf7d4a..43d03cc7 100644 --- a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp +++ b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp @@ -100,13 +100,15 @@ MxResult GasStation::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x10004a60 +// FUNCTION: BETA10 0x10028883 MxLong GasStation::Notify(MxParam& p_param) { + MxNotificationParam& param = (MxNotificationParam&) p_param; MxResult result = 0; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationEndAction: result = HandleEndAction((MxEndActionNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/worlds/historybook.cpp b/LEGO1/lego/legoomni/src/worlds/historybook.cpp index 39f30d14..cf325825 100644 --- a/LEGO1/lego/legoomni/src/worlds/historybook.cpp +++ b/LEGO1/lego/legoomni/src/worlds/historybook.cpp @@ -68,12 +68,14 @@ MxResult HistoryBook::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x10082680 +// FUNCTION: BETA10 0x1002b907 MxLong HistoryBook::Notify(MxParam& p_param) { + MxNotificationParam& param = (MxNotificationParam&) p_param; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationButtonUp: m_destLocation = LegoGameState::Area::e_infoscor; TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); diff --git a/LEGO1/lego/legoomni/src/worlds/hospital.cpp b/LEGO1/lego/legoomni/src/worlds/hospital.cpp index 6b3c8e5a..cfec6955 100644 --- a/LEGO1/lego/legoomni/src/worlds/hospital.cpp +++ b/LEGO1/lego/legoomni/src/worlds/hospital.cpp @@ -106,13 +106,15 @@ MxResult Hospital::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x10074990 +// FUNCTION: BETA10 0x1002ca3b MxLong Hospital::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationEndAction: result = HandleEndAction((MxEndActionNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp index 1e248c07..55f0abc8 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp @@ -225,13 +225,15 @@ MxResult Infocenter::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x1006ef10 +// FUNCTION: BETA10 0x1002eaca MxLong Infocenter::Notify(MxParam& p_param) { + MxNotificationParam& param = (MxNotificationParam&) p_param; MxLong result = 0; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationType0: result = HandleNotification0((MxNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp index 506b21f5..085d76d7 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp @@ -55,13 +55,15 @@ MxResult InfocenterDoor::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x100379e0 +// FUNCTION: BETA10 0x10032227 MxLong InfocenterDoor::Notify(MxParam& p_param) { + MxNotificationParam& param = (MxNotificationParam&) p_param; MxLong result = 0; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationEndAction: if (((MxEndActionNotificationParam&) p_param).GetAction()->GetAtomId() == m_atomId) { BackgroundAudioManager()->RaiseVolume(); diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index a01aece9..e7db6a03 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -129,13 +129,15 @@ MxResult Isle::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x10030c10 +// FUNCTION: BETA10 0x10032b63 MxLong Isle::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationEndAction: result = HandleEndAction((MxEndActionNotificationParam&) p_param); break; @@ -468,6 +470,7 @@ void Isle::UpdateGlobe() } // FUNCTION: LEGO1 0x100315f0 +// FUNCTION: BETA10 0x10033e46 MxLong Isle::HandlePathStruct(LegoPathStructNotificationParam& p_param) { MxLong result = 0; diff --git a/LEGO1/lego/legoomni/src/worlds/jukebox.cpp b/LEGO1/lego/legoomni/src/worlds/jukebox.cpp index fe476499..e7193307 100644 --- a/LEGO1/lego/legoomni/src/worlds/jukebox.cpp +++ b/LEGO1/lego/legoomni/src/worlds/jukebox.cpp @@ -68,13 +68,15 @@ MxResult JukeBox::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x1005d980 +// FUNCTION: BETA10 0x10037daf MxLong JukeBox::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationControl: result = HandleControl((LegoControlManagerNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/worlds/police.cpp b/LEGO1/lego/legoomni/src/worlds/police.cpp index 43bd67bf..7bf48e9b 100644 --- a/LEGO1/lego/legoomni/src/worlds/police.cpp +++ b/LEGO1/lego/legoomni/src/worlds/police.cpp @@ -69,13 +69,15 @@ MxResult Police::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x1005e480 +// FUNCTION: BETA10 0x100f04a3 MxLong Police::Notify(MxParam& p_param) { MxLong result = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationEndAction: result = HandleEndAction((MxEndActionNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp b/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp index a1451cb6..950e0b2e 100644 --- a/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp +++ b/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp @@ -108,13 +108,15 @@ MxResult RegistrationBook::Create(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x100770e0 +// FUNCTION: BETA10 0x100f2d98 MxLong RegistrationBook::Notify(MxParam& p_param) { + MxNotificationParam& param = (MxNotificationParam&) p_param; MxLong result = 0; LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationEndAction: result = HandleEndAction((MxEndActionNotificationParam&) p_param); break; diff --git a/LEGO1/lego/legoomni/src/worlds/score.cpp b/LEGO1/lego/legoomni/src/worlds/score.cpp index 3ecae676..e58d57aa 100644 --- a/LEGO1/lego/legoomni/src/worlds/score.cpp +++ b/LEGO1/lego/legoomni/src/worlds/score.cpp @@ -84,13 +84,16 @@ void Score::DeleteScript() } // FUNCTION: LEGO1 0x10001410 +// FUNCTION: BETA10 0x100f4398 MxLong Score::Notify(MxParam& p_param) { MxLong ret = 0; + MxNotificationParam& param = (MxNotificationParam&) p_param; + LegoWorld::Notify(p_param); if (m_worldStarted) { - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationStartAction: Paint(); ret = 1; diff --git a/LEGO1/omni/src/common/mxcompositepresenter.cpp b/LEGO1/omni/src/common/mxcompositepresenter.cpp index 124d6b0a..4e83d86c 100644 --- a/LEGO1/omni/src/common/mxcompositepresenter.cpp +++ b/LEGO1/omni/src/common/mxcompositepresenter.cpp @@ -8,6 +8,8 @@ #include "mxnotificationmanager.h" #include "mxobjectfactory.h" +#include + DECOMP_SIZE_ASSERT(MxCompositePresenter, 0x4c); // FUNCTION: LEGO1 0x100b60b0 @@ -107,16 +109,22 @@ void MxCompositePresenter::EndAction() } // FUNCTION: LEGO1 0x100b6760 +// FUNCTION: BETA10 0x1013771e MxLong MxCompositePresenter::Notify(MxParam& p_param) { AUTOLOCK(m_criticalSection); + MxNotificationParam& param = (MxNotificationParam&) p_param; - switch (((MxNotificationParam&) p_param).GetNotification()) { + switch (param.GetNotification()) { case c_notificationEndAction: VTable0x58((MxEndActionNotificationParam&) p_param); break; case c_notificationPresenter: VTable0x5c((MxNotificationParam&) p_param); + break; + default: + assert(0); + break; } return 0; From 8dd7bc63be0e4b497caecd54c8d50590bb1da901 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 4 Dec 2024 15:11:16 -0700 Subject: [PATCH 09/14] Implement/match `LegoAct2::SpawnBricks` (#1189) * Implement/match LegoAct2::SpawnBricks * Name brick vars * Add LegoAct2::FUN_10051fa0 * Add LegoAct2::FUN_100521f0 --- LEGO1/lego/legoomni/include/legoact2.h | 10 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 277 +++++++++++++++++++- 2 files changed, 273 insertions(+), 14 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 588a53b2..797b2249 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -80,7 +80,7 @@ class LegoAct2 : public LegoWorld { void FUN_10051960(); void InitBricks(); void UninitBricks(); - void FUN_10051ac0(); + void SpawnBricks(); void FUN_10051fa0(MxS32 p_param1); void FUN_100521f0(MxS32 p_param1); MxResult FUN_10052560( @@ -94,7 +94,7 @@ class LegoAct2 : public LegoWorld { MxResult FUN_10052800(); Act2Brick m_bricks[10]; // 0x00f8 - undefined m_nextBrick; // 0x10c0 + MxU8 m_nextBrick; // 0x10c0 undefined m_unk0x10c1; // 0x10c1 MxBool m_ready; // 0x10c2 undefined4 m_unk0x10c4; // 0x10c4 @@ -116,7 +116,11 @@ class LegoAct2 : public LegoWorld { undefined m_unk0x113c; // 0x113c Act2mainScript::Script m_unk0x1140; // 0x1140 Act2mainScript::Script m_unk0x1144; // 0x1144 - undefined m_unk0x1148[0x08]; // 0x1148 + undefined4 m_unk0x1148; // 0x1148 + undefined m_firstBrick; // 0x114c + undefined m_secondBrick; // 0x114d + undefined m_thirdBrick; // 0x114e + undefined m_fourthBrick; // 0x114e LegoGameState::Area m_destLocation; // 0x1150 }; diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 5afe4a83..29f4986a 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -448,7 +448,7 @@ MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param) m_bricks[m_nextBrick - 1].Mute(FALSE); m_unk0x10c4 = 13; - FUN_10051ac0(); + SpawnBricks(); PlayMusic(JukeboxScript::c_BrickHunt); ((LegoPathActor*) m_pepper->GetEntity())->SetState(0); break; @@ -755,25 +755,280 @@ void LegoAct2::UninitBricks() } } -// STUB: LEGO1 0x10051ac0 -// STUB: BETA10 0x100138c0 -void LegoAct2::FUN_10051ac0() +// FUNCTION: LEGO1 0x10051ac0 +// FUNCTION: BETA10 0x100138c0 +void LegoAct2::SpawnBricks() { - // TODO + MxFloat infobridge[] = {79.0625f, 0.5f, -19.75f}; + MxFloat palmTreeInPark[] = {67.62728f, 0.917197f, 11.49833f}; + MxFloat store[] = {-53.9328f, 2.372259f, -61.2073f}; + MxFloat postOffice[] = {-30.9856f, 0.30453f, -47.4378f}; + MxFloat h3[] = {-71.2397f, 7.319758f, -23.0f}; + MxFloat ht[] = {-59.5102f, 14.37329f, 24.70311f}; + MxFloat posta[] = {74.0625f, 1.5f, -91.125f}; + MxFloat ptree[] = {-20.4375f, 0.5f, -82.5625f}; + MxFloat jail[] = {80.46174f, 0.6f, -59.50533f}; + MxFloat hospital[] = {84.0f, 4.5f, 26.0f}; + + InitBricks(); + + Act2Brick* brick = &m_bricks[m_nextBrick]; + brick->Create(m_nextBrick); + LegoROI* roi = brick->GetROI(); + MxMatrix local2world = roi->GetLocal2World(); + MxFloat* location; + + // Unused but present in BETA + LegoEntity* entity; + + if ((MxS16) (rand() % 2) == 1) { + m_firstBrick = 0; + location = infobridge; + MxTrace("infobridge\n"); + } + else { + m_firstBrick = 1; + location = palmTreeInPark; + MxTrace("palm tree in park\n"); + } + + SET3(local2world[3], location); + roi->FUN_100a58f0(local2world); + roi->SetVisibility(TRUE); + roi->VTable0x14(); + entity = roi->GetEntity(); + brick->PlayWhistleSound(); + m_nextBrick++; + + brick = &m_bricks[m_nextBrick]; + brick->Create(m_nextBrick); + roi = brick->GetROI(); + local2world = roi->GetLocal2World(); + + if ((MxS16) (rand() % 2) == 1) { + m_secondBrick = 2; + location = store; + MxTrace("store\n"); + } + else { + m_secondBrick = 3; + location = postOffice; + MxTrace("p.o.\n"); + } + + SET3(local2world[3], location); + roi->FUN_100a58f0(local2world); + roi->SetVisibility(TRUE); + roi->VTable0x14(); + entity = roi->GetEntity(); + brick->PlayWhistleSound(); + m_nextBrick++; + + brick = &m_bricks[m_nextBrick]; + brick->Create(m_nextBrick); + roi = brick->GetROI(); + local2world = roi->GetLocal2World(); + + if ((MxS16) (rand() % 2) == 1) { + m_thirdBrick = 4; + location = h3; + MxTrace("h3\n"); + } + else { + m_thirdBrick = 5; + location = ht; + MxTrace("ht\n"); + } + + SET3(local2world[3], location); + roi->FUN_100a58f0(local2world); + roi->SetVisibility(TRUE); + roi->VTable0x14(); + entity = roi->GetEntity(); + brick->PlayWhistleSound(); + m_nextBrick++; + + brick = &m_bricks[m_nextBrick]; + brick->Create(m_nextBrick); + roi = brick->GetROI(); + local2world = roi->GetLocal2World(); + + if ((MxS16) (rand() % 2) == 1) { + if ((MxS16) (rand() % 2) == 1) { + m_fourthBrick = 6; + location = posta; + MxTrace("po.sta.\n"); + } + else { + m_fourthBrick = 7; + location = ptree; + MxTrace("p.tree\n"); + } + } + else { + if ((MxS16) (rand() % 2) == 1) { + m_fourthBrick = 8; + location = jail; + MxTrace("jail\n"); + } + else { + m_fourthBrick = 9; + location = hospital; + MxTrace("hospi\n"); + } + } + + SET3(local2world[3], location); + roi->FUN_100a58f0(local2world); + roi->SetVisibility(TRUE); + roi->VTable0x14(); + entity = roi->GetEntity(); + brick->PlayWhistleSound(); + m_nextBrick++; } -// STUB: LEGO1 0x10051fa0 -// STUB: BETA10 0x10013fd3 +// FUNCTION: LEGO1 0x10051fa0 +// FUNCTION: BETA10 0x10013fd3 void LegoAct2::FUN_10051fa0(MxS32 p_param1) { - // TODO + MxU8 randN = rand() / (RAND_MAX / 3); + randN++; + + switch (p_param1) { + case 2: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx50bu_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx51bu_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + case 8: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx29nu_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx30nu_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + case 9: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx33na_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx34na_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + case 14: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx46cl_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx48cl_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + case 23: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx58va_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx60va_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + case 24: + case 25: + FUN_10052560(Act2mainScript::c_snsx31sh_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + break; + case 26: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx52sn_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx53sn_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + case 34: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx15la_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx16la_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + case 36: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx10ni_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx11ni_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + case 38: + case 42: + if (randN == 1) { + FUN_10052560(Act2mainScript::c_snsx03ma_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + else { + FUN_10052560(Act2mainScript::c_snsx04ma_RunAnim, TRUE, FALSE, NULL, NULL, NULL); + } + break; + } } -// STUB: LEGO1 0x100521f0 -// STUB: BETA10 0x100142f1 +// FUNCTION: LEGO1 0x100521f0 +// FUNCTION: BETA10 0x100142f1 void LegoAct2::FUN_100521f0(MxS32 p_param1) { - // TODO + Act2mainScript::Script objectId = (Act2mainScript::Script) 0; + Mx3DPointFloat vec; + + switch (p_param1) { + case 0x02: { + vec = Mx3DPointFloat(-9.1f, 0.0f, -16.5f); + VariableTable()->SetVariable("ACTOR_01", "bd"); + objectId = Act2mainScript::c_tns030bd_RunAnim; + break; + } + case 0x2a: { + vec = Mx3DPointFloat(-9.67f, 0.0f, -44.3f); + VariableTable()->SetVariable("ACTOR_01", "rd"); + objectId = Act2mainScript::c_tns030rd_RunAnim; + break; + } + case 0x133: { + vec = Mx3DPointFloat(25.75f, 0.0f, -13.0f); + VariableTable()->SetVariable("ACTOR_01", "pg"); + objectId = Act2mainScript::c_tns030pg_RunAnim; + break; + } + case 0x134: { + vec = Mx3DPointFloat(43.63f, 0.0f, -46.33f); + VariableTable()->SetVariable("ACTOR_01", "sy"); + objectId = Act2mainScript::c_tns030sy_RunAnim; + break; + } + case 0x135: { + vec = Mx3DPointFloat(50.0f, 0.0f, -34.6f); + VariableTable()->SetVariable("ACTOR_01", "rd"); + objectId = Act2mainScript::c_tns030rd_RunAnim; + break; + } + case 0x138: { + vec = Mx3DPointFloat(-41.15f, 4.0f, 31.0f); + VariableTable()->SetVariable("ACTOR_01", "sy"); + objectId = Act2mainScript::c_tns030sy_RunAnim; + break; + } + } + + if (objectId != (Act2mainScript::Script) 0) { + Mx3DPointFloat local30(vec); + Mx3DPointFloat position(m_pepper->GetWorldPosition()); + ((Vector3&) local30).Sub(position); + Mx3DPointFloat local44 = local30; + local30.Unitize(); + FUN_10052560(objectId, TRUE, TRUE, &vec, &local30, NULL); + } } // FUNCTION: LEGO1 0x10052560 From c51a09af0bae6661f820d1cb00c6af5527ef6347 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 4 Dec 2024 15:32:53 -0700 Subject: [PATCH 10/14] Fix a bug in LegoAct2::Notify (#1190) --- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 29f4986a..174775b2 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -332,7 +332,7 @@ MxLong LegoAct2::Notify(MxParam& p_param) Mx3DPointFloat direction(local2world[2]); Mx3DPointFloat location(local2world[1]); - FUN_10052560(Act2mainScript::c_tns051in_RunAnim, TRUE, TRUE, &location, &direction, NULL); + FUN_10052560(Act2mainScript::c_tns051in_RunAnim, TRUE, TRUE, &local90, &direction, NULL); m_unk0x10c4 = 14; m_unk0x10d0 = 0; From 6ca54824e6e874d8952c3b5876f226f05b089c15 Mon Sep 17 00:00:00 2001 From: MS Date: Wed, 4 Dec 2024 18:19:48 -0500 Subject: [PATCH 11/14] Rename c_notificationDrag* enum (#1191) * Improve functions with drag notifications * Rename drag notifications * A couple more addrs --- .../include/legoeventnotificationparam.h | 8 ++++ .../src/entity/legocameracontroller.cpp | 40 +++++++++---------- .../legoomni/src/input/legoinputmanager.cpp | 30 ++++++++------ LEGO1/omni/include/mxnotificationparam.h | 9 +++-- 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoeventnotificationparam.h b/LEGO1/lego/legoomni/include/legoeventnotificationparam.h index cbb12b61..7cfa28f9 100644 --- a/LEGO1/lego/legoomni/include/legoeventnotificationparam.h +++ b/LEGO1/lego/legoomni/include/legoeventnotificationparam.h @@ -54,9 +54,17 @@ class LegoEventNotificationParam : public MxNotificationParam { MxS32 GetY() const { return m_y; } void SetROI(LegoROI* p_roi) { m_roi = p_roi; } + + // FUNCTION: BETA10 0x1007d620 void SetModifier(MxU8 p_modifier) { m_modifier = p_modifier; } + + // FUNCTION: BETA10 0x1007d6b0 void SetKey(MxU8 p_key) { m_key = p_key; } + + // FUNCTION: BETA10 0x1007d650 void SetX(MxS32 p_x) { m_x = p_x; } + + // FUNCTION: BETA10 0x1007d680 void SetY(MxS32 p_y) { m_y = p_y; } protected: diff --git a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp index b9d76039..71c4114b 100644 --- a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp @@ -43,26 +43,6 @@ MxLong LegoCameraController::Notify(MxParam& p_param) { switch (((MxNotificationParam&) p_param).GetNotification()) { case c_notificationDragEnd: { - if ((((LegoEventNotificationParam&) p_param).GetModifier()) & LegoEventNotificationParam::c_lButtonState) { - OnLButtonDown(MxPoint32( - ((LegoEventNotificationParam&) p_param).GetX(), - ((LegoEventNotificationParam&) p_param).GetY() - )); - } - else if ((((LegoEventNotificationParam&) p_param).GetModifier()) & LegoEventNotificationParam::c_rButtonState) { - OnRButtonDown(MxPoint32( - ((LegoEventNotificationParam&) p_param).GetX(), - ((LegoEventNotificationParam&) p_param).GetY() - )); - } - } break; - case c_notificationDragStart: { - OnMouseMove( - ((LegoEventNotificationParam&) p_param).GetModifier(), - MxPoint32(((LegoEventNotificationParam&) p_param).GetX(), ((LegoEventNotificationParam&) p_param).GetY()) - ); - } break; - case c_notificationDrag: { if (((((LegoEventNotificationParam&) p_param).GetModifier()) & LegoEventNotificationParam::c_lButtonState) == 0) { OnLButtonUp(MxPoint32( @@ -77,6 +57,26 @@ MxLong LegoCameraController::Notify(MxParam& p_param) )); } } break; + case c_notificationDragStart: { + if ((((LegoEventNotificationParam&) p_param).GetModifier()) & LegoEventNotificationParam::c_lButtonState) { + OnLButtonDown(MxPoint32( + ((LegoEventNotificationParam&) p_param).GetX(), + ((LegoEventNotificationParam&) p_param).GetY() + )); + } + else if ((((LegoEventNotificationParam&) p_param).GetModifier()) & LegoEventNotificationParam::c_rButtonState) { + OnRButtonDown(MxPoint32( + ((LegoEventNotificationParam&) p_param).GetX(), + ((LegoEventNotificationParam&) p_param).GetY() + )); + } + } break; + case c_notificationDrag: { + OnMouseMove( + ((LegoEventNotificationParam&) p_param).GetModifier(), + MxPoint32(((LegoEventNotificationParam&) p_param).GetX(), ((LegoEventNotificationParam&) p_param).GetY()) + ); + } break; } return SUCCESS; diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index f546b2bf..31c4eabd 100644 --- a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp +++ b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp @@ -379,7 +379,7 @@ MxBool LegoInputManager::ProcessOneEvent(LegoEventNotificationParam& p_param) if (p_param.GetKey() == VK_SHIFT) { if (m_unk0x195) { m_unk0x80 = FALSE; - p_param.SetNotification(c_notificationDrag); + p_param.SetNotification(c_notificationDragEnd); if (m_camera) { m_camera->Notify(p_param); @@ -489,16 +489,24 @@ MxBool LegoInputManager::ProcessOneEvent(LegoEventNotificationParam& p_param) } // FUNCTION: LEGO1 0x1005cdf0 +// FUNCTION: BETA10 0x10089cc1 MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param) { MxBool result = FALSE; switch (p_param.GetNotification()) { + case c_notificationButtonDown: + m_x = p_param.GetX(); + m_y = p_param.GetY(); + m_unk0x80 = FALSE; + m_unk0x81 = TRUE; + StartAutoDragTimer(); + break; case c_notificationButtonUp: StopAutoDragTimer(); if (m_unk0x80) { - p_param.SetNotification(c_notificationDrag); + p_param.SetNotification(c_notificationDragEnd); result = TRUE; } else if (m_unk0x81) { @@ -511,13 +519,6 @@ MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param) m_unk0x80 = FALSE; m_unk0x81 = FALSE; break; - case c_notificationButtonDown: - m_x = p_param.GetX(); - m_y = p_param.GetY(); - m_unk0x80 = FALSE; - m_unk0x81 = TRUE; - StartAutoDragTimer(); - break; case c_notificationMouseMove: if (m_unk0x195) { p_param.SetModifier(LegoEventNotificationParam::c_lButtonState); @@ -532,18 +533,19 @@ MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param) MxS32 diffX = p_param.GetX() - m_x; MxS32 diffY = p_param.GetY() - m_y; + MxS32 t = diffX * diffX + diffY * diffY; - if (m_unk0x195 || (diffX * diffX) + (diffY * diffY) > m_unk0x74) { + if (m_unk0x195 || t > m_unk0x74) { StopAutoDragTimer(); m_unk0x80 = TRUE; - p_param.SetNotification(c_notificationDragEnd); + p_param.SetNotification(c_notificationDragStart); result = TRUE; p_param.SetX(m_x); p_param.SetY(m_y); } } else { - p_param.SetNotification(c_notificationDragStart); + p_param.SetNotification(c_notificationDrag); result = TRUE; } } @@ -557,7 +559,7 @@ MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param) p_param.SetX(m_x); p_param.SetY(m_y); p_param.SetModifier(LegoEventNotificationParam::c_lButtonState); - p_param.SetNotification(c_notificationDragEnd); + p_param.SetNotification(c_notificationDragStart); result = TRUE; } else { @@ -571,12 +573,14 @@ MxBool LegoInputManager::FUN_1005cdf0(LegoEventNotificationParam& p_param) } // FUNCTION: LEGO1 0x1005cfb0 +// FUNCTION: BETA10 0x10089fc5 void LegoInputManager::StartAutoDragTimer() { m_autoDragTimerID = ::SetTimer(LegoOmni::GetInstance()->GetWindowHandle(), 1, m_autoDragTime, NULL); } // FUNCTION: LEGO1 0x1005cfd0 +// FUNCTION: BETA10 0x1008a005 void LegoInputManager::StopAutoDragTimer() { if (m_autoDragTimerID) { diff --git a/LEGO1/omni/include/mxnotificationparam.h b/LEGO1/omni/include/mxnotificationparam.h index a5b30b24..c2a95de8 100644 --- a/LEGO1/omni/include/mxnotificationparam.h +++ b/LEGO1/omni/include/mxnotificationparam.h @@ -20,9 +20,9 @@ enum NotificationId { c_notificationButtonDown = 9, // 100d6aa0 c_notificationMouseMove = 10, // 100d6aa0 c_notificationClick = 11, // 100d6aa0 - c_notificationDragEnd = 12, - c_notificationDragStart = 13, - c_notificationDrag = 14, + c_notificationDragStart = 12, + c_notificationDrag = 13, + c_notificationDragEnd = 14, c_notificationTimer = 15, // 100d6aa0 c_notificationControl = 17, c_notificationEndAnim = 18, // 100d7e80 @@ -55,7 +55,10 @@ class MxNotificationParam : public MxParam { // FUNCTION: BETA10 0x1003c960 MxCore* GetSender() const { return m_sender; } + // FUNCTION: BETA10 0x1007d5c0 void SetNotification(NotificationId p_type) { m_type = p_type; } + + // FUNCTION: BETA10 0x1007d5f0 void SetSender(MxCore* p_sender) { m_sender = p_sender; } protected: From 4d8098a6c25433ff6a19d206ed637d189ed5d75b Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 6 Dec 2024 12:50:40 -0700 Subject: [PATCH 12/14] Implement `LegoPathController::FUN_10048310` (#1192) * WIP * Rename * Fix * More WIP * WIP * WIP * Fix * Annotations * Add more annotations, improve match * Raise max functions --- .github/workflows/build.yml | 2 +- LEGO1/lego/legoomni/include/act2actor.h | 8 +- .../legoomni/include/legopathcontroller.h | 87 +++++++- .../legoomni/include/legopathedgecontainer.h | 70 ++++++- LEGO1/lego/legoomni/src/actors/act2actor.cpp | 23 +- .../src/common/legoanimationmanager.cpp | 2 +- .../legoomni/src/paths/legopathboundary.cpp | 8 +- .../legoomni/src/paths/legopathcontroller.cpp | 198 ++++++++++++++++-- LEGO1/lego/sources/geom/legounkown100db7f4.h | 43 +++- LEGO1/lego/sources/geom/legoweedge.h | 3 +- LEGO1/lego/sources/geom/legowegedge.h | 1 + LEGO1/mxgeometry/mxgeometry3d.h | 1 + LEGO1/mxstl/stlcompat.h | 1 + LEGO1/realtime/vector.h | 1 + 14 files changed, 390 insertions(+), 58 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 67516cc4..1adb2bca 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -139,7 +139,7 @@ jobs: run: | reccmp-reccmp -S CONFIGPROGRESS.SVG --svg-icon assets/config.png --target CONFIG | tee CONFIGPROGRESS.TXT reccmp-reccmp -S ISLEPROGRESS.SVG --svg-icon assets/isle.png --target ISLE | tee ISLEPROGRESS.TXT - reccmp-reccmp -S LEGO1PROGRESS.SVG -T 4252 --svg-icon assets/lego1.png --target LEGO1 | tee LEGO1PROGRESS.TXT + reccmp-reccmp -S LEGO1PROGRESS.SVG -T 4302 --svg-icon assets/lego1.png --target LEGO1 | tee LEGO1PROGRESS.TXT - name: Compare Accuracy With Current Master shell: bash diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index 897d0615..e830b289 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -11,10 +11,10 @@ class Act2Actor : public LegoAnimActor { public: struct UnknownListStructure { - MxFloat m_unk0x00[3]; // 0x00 - MxFloat m_unk0x0c[3]; // 0x0c - const char* m_unk0x18; // 0x18 - undefined m_unk0x1c; // 0x1c + MxFloat m_position[3]; // 0x00 + MxFloat m_direction[3]; // 0x0c + const char* m_boundary; // 0x18 + undefined m_unk0x1c; // 0x1c }; Act2Actor(); diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 10185666..5450841d 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -22,7 +22,9 @@ class Vector3; // VTABLE: LEGO1 0x100d7da8 // SIZE 0x40 -struct LegoPathCtrlEdge : public LegoUnknown100db7f4 {}; +struct LegoPathCtrlEdge : public LegoUnknown100db7f4 { + undefined4 FUN_10048c40(const Vector3&); +}; struct LegoPathCtrlEdgeCompare { MxU32 operator()(const LegoPathCtrlEdge* p_lhs, const LegoPathCtrlEdge* p_rhs) const @@ -119,13 +121,13 @@ class LegoPathController : public MxCore { ); MxResult FUN_10048310( LegoPathEdgeContainer* p_grec, - const Vector3& p_position, - const Vector3& p_direction, - LegoPathBoundary* p_boundary1, - const Vector3& p_param5, - const Vector3& p_param6, - LegoPathBoundary* p_boundary2, - MxBool p_param8, + const Vector3& p_oldPosition, + const Vector3& p_oldDirection, + LegoPathBoundary* p_oldBoundary, + const Vector3& p_newPosition, + const Vector3& p_newDirection, + LegoPathBoundary* p_newBoundary, + LegoU8 p_mask, MxFloat* p_param9 ); @@ -182,6 +184,15 @@ class LegoPathController : public MxCore { // TEMPLATE: LEGO1 0x100451a0 // _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::~_Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::iterator::_Inc + +// TEMPLATE: LEGO1 0x100452b0 +// _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::erase + +// TEMPLATE: LEGO1 0x10045700 +// _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Erase + // TEMPLATE: LEGO1 0x100457e0 // Set::~Set @@ -221,14 +232,74 @@ class LegoPathController : public MxCore { // SYNTHETIC: LEGO1 0x10047ae0 // LegoUnknown100db7f4::~LegoUnknown100db7f4 +// TEMPLATE: LEGO1 0x10048f00 +// list >::begin + +// TEMPLATE: LEGO1 0x10048f10 +// list >::insert + // TEMPLATE: LEGO1 0x10048f70 // list >::erase +// TEMPLATE: LEGO1 0x10048fc0 +// _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::find + +// TEMPLATE: LEGO1 0x100492f0 +// _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Copy + +// TEMPLATE: LEGO1 0x10049370 +// _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Ubound + +// TEMPLATE: LEGO1 0x10049410 +// list >::insert + +// TEMPLATE: LEGO1 0x10049470 +// list >::_Buynode + +// TEMPLATE: LEGO1 0x100494a0 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::iterator::_Inc + +// TEMPLATE: LEGO1 0x100495b0 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::insert + +// TEMPLATE: LEGO1 0x10049840 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::iterator::_Dec + +// TEMPLATE: LEGO1 0x10049890 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::erase + +// TEMPLATE: LEGO1 0x10049cf0 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Buynode + +// TEMPLATE: LEGO1 0x10049d50 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Init + +// TEMPLATE: LEGO1 0x10049e00 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Insert + +// TEMPLATE: LEGO1 0x1004a090 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Lrotate + +// TEMPLATE: LEGO1 0x1004a0f0 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Rrotate + +// TEMPLATE: LEGO1 0x1004a760 +// _Construct + // TEMPLATE: LEGO1 0x1004a780 // _Construct // GLOBAL: LEGO1 0x100f4360 // _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Nil + +// GLOBAL: LEGO1 0x100f4364 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Nil // clang-format on #endif // LEGOPATHCONTROLLER_H diff --git a/LEGO1/lego/legoomni/include/legopathedgecontainer.h b/LEGO1/lego/legoomni/include/legopathedgecontainer.h index c133122c..5d6a79aa 100644 --- a/LEGO1/lego/legoomni/include/legopathedgecontainer.h +++ b/LEGO1/lego/legoomni/include/legopathedgecontainer.h @@ -6,17 +6,73 @@ #include "mxtypes.h" class LegoPathBoundary; -struct LegoUnknown100db7f4; +struct LegoPathCtrlEdge; // SIZE 0x08 struct LegoBoundaryEdge { - LegoUnknown100db7f4* m_edge; // 0x00 + LegoBoundaryEdge() {} + + // FUNCTION: BETA10 0x100bd620 + LegoBoundaryEdge(LegoPathCtrlEdge* p_edge, LegoPathBoundary* p_boundary) + { + m_edge = p_edge; + m_boundary = p_boundary; + } + + LegoPathCtrlEdge* m_edge; // 0x00 LegoPathBoundary* m_boundary; // 0x04 int operator==(LegoBoundaryEdge) const { return 0; } int operator<(LegoBoundaryEdge) const { return 0; } }; +// SIZE 0x10 +struct LegoBEWithFloat { + LegoBEWithFloat() + { + m_edge = NULL; + m_boundary = NULL; + m_next = NULL; + m_unk0x0c = 0.0f; + } + + // FUNCTION: BETA10 0x100bd9a0 + LegoBEWithFloat(LegoPathCtrlEdge* p_edge, LegoPathBoundary* p_boundary, MxFloat p_unk0x0c) + { + m_edge = p_edge; + m_boundary = p_boundary; + m_next = NULL; + m_unk0x0c = p_unk0x0c; + } + + // FUNCTION: BETA10 0x100bd9f0 + LegoBEWithFloat(LegoPathCtrlEdge* p_edge, LegoPathBoundary* p_boundary, LegoBEWithFloat* p_next, MxFloat p_unk0x0c) + { + m_edge = p_edge; + m_boundary = p_boundary; + m_next = p_next; + m_unk0x0c = p_unk0x0c; + } + + LegoPathCtrlEdge* m_edge; // 0x00 + LegoPathBoundary* m_boundary; // 0x04 + LegoBEWithFloat* m_next; // 0x08 + MxFloat m_unk0x0c; // 0x0c + + int operator==(LegoBEWithFloat) const { return 0; } + int operator<(LegoBEWithFloat) const { return 0; } +}; + +struct LegoBEWithFloatComparator { + // FUNCTION: BETA10 0x100bef80 + bool operator()(LegoBEWithFloat* const& p_a, LegoBEWithFloat* const& p_b) const + { + return p_a->m_unk0x0c < p_b->m_unk0x0c; + } +}; + +typedef multiset LegoBEWithFloatSet; + // SIZE 0x3c struct LegoPathEdgeContainer : public list { enum { @@ -30,9 +86,10 @@ struct LegoPathEdgeContainer : public list { m_flags = 0; } - void SetBit1(MxU32 p_flag) + // FUNCTION: BETA10 0x100bd660 + void SetBit1(MxU32 p_set) { - if (p_flag) { + if (p_set) { m_flags |= c_bit1; } else { @@ -40,10 +97,11 @@ struct LegoPathEdgeContainer : public list { } } + // FUNCTION: BETA10 0x1001cb50 MxU32 GetBit1() { return m_flags & c_bit1; } - Mx3DPointFloat m_unk0x0c; // 0x0c - Mx3DPointFloat m_unk0x20; // 0x20 + Mx3DPointFloat m_position; // 0x0c + Mx3DPointFloat m_direction; // 0x20 LegoPathBoundary* m_boundary; // 0x34 MxU8 m_flags; // 0x38 }; diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index 1bb3e335..b97c08bc 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -134,8 +134,8 @@ void Act2Actor::SetWorldSpeed(MxFloat p_worldSpeed) // FUNCTION: BETA10 0x1000d4d6 void Act2Actor::FUN_100192a0(undefined4 p_param) { - Mx3DPointFloat local38(0.0, 0.0, 0.0); - Mx3DPointFloat local4c(0.0, 0.0, 0.0); + Mx3DPointFloat newPosition(0.0, 0.0, 0.0); + Mx3DPointFloat newDirection(0.0, 0.0, 0.0); if (m_grec) { delete m_grec; @@ -144,26 +144,25 @@ void Act2Actor::FUN_100192a0(undefined4 p_param) m_grec = new LegoPathEdgeContainer(); assert(m_grec); - local38 = g_unk0x100f0db8[p_param].m_unk0x00; - local4c = g_unk0x100f0db8[p_param].m_unk0x0c; - - LegoPathBoundary* otherBoundary = m_controller->GetPathBoundary(g_unk0x100f0db8[p_param].m_unk0x18); + newPosition = g_unk0x100f0db8[p_param].m_position; + newDirection = g_unk0x100f0db8[p_param].m_direction; + LegoPathBoundary* newBoundary = m_controller->GetPathBoundary(g_unk0x100f0db8[p_param].m_boundary); MxResult sts = m_controller->FUN_10048310( m_grec, m_roi->GetWorldPosition(), m_roi->GetWorldDirection(), m_boundary, - local38, - local4c, - otherBoundary, - TRUE, + newPosition, + newDirection, + newBoundary, + LegoUnknown100db7f4::c_bit1, NULL ); - assert(!sts); + assert(!sts); // == SUCCESS - if (sts) { + if (sts != SUCCESS) { delete m_grec; m_grec = NULL; } diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 1b885e70..b60a5381 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -2553,7 +2553,7 @@ MxBool LegoAnimationManager::FUN_10064120(LegoLocation::Boundary* p_boundary, Mx while (local2c--) { if (local34 != NULL) { - if (local34->Unknown(*boundary, LegoWEGEdge::c_bit1) && FUN_10064010(boundary, local34, destScale) && + if (local34->BETA_1004a830(*boundary, LegoWEGEdge::c_bit1) && FUN_10064010(boundary, local34, destScale) && (!p_bool2 || FUN_10064010(boundary, local8, destScale))) { p_boundary->m_srcScale = p_boundary->m_destScale = destScale; p_boundary->m_name = boundary->GetName(); diff --git a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp index 297aa223..d72ee168 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp @@ -92,7 +92,7 @@ void LegoPathBoundary::SwitchBoundary( { LegoUnknown100db7f4* e = p_edge; - if (p_edge->Unknown2(*p_boundary)) { + if (p_edge->BETA_100b53b0(*p_boundary)) { LegoPathBoundary* newBoundary = (LegoPathBoundary*) p_edge->OtherFace(p_boundary); if (newBoundary == NULL) { @@ -102,7 +102,7 @@ void LegoPathBoundary::SwitchBoundary( MxS32 local10 = 0; MxU8 userNavFlag; - if (e->Unknown(*newBoundary, 1)) { + if (e->BETA_1004a830(*newBoundary, 1)) { userNavFlag = p_actor->GetUserNavFlag(); } else { @@ -113,7 +113,7 @@ void LegoPathBoundary::SwitchBoundary( p_edge = (LegoUnknown100db7f4*) p_edge->GetCounterclockwiseEdge(*newBoundary); LegoPathBoundary* local20 = (LegoPathBoundary*) p_edge->OtherFace(newBoundary); - if (p_edge->GetMask0x03() && (userNavFlag || p_edge->Unknown(*local20, 1))) { + if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*local20, 1))) { local10++; } } while (p_edge != e); @@ -141,7 +141,7 @@ void LegoPathBoundary::SwitchBoundary( LegoPathBoundary* local20 = (LegoPathBoundary*) p_edge->OtherFace(newBoundary); - if (p_edge->GetMask0x03() && (userNavFlag || p_edge->Unknown(*local20, 1))) { + if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*local20, 1))) { local8--; } } diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index e034db98..86c89917 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -733,22 +733,196 @@ MxResult LegoPathController::ReadVector(LegoStorage* p_storage, Mx4DPointFloat& return SUCCESS; } -// STUB: LEGO1 0x10048310 -// STUB: BETA10 0x100b8911 +// FUNCTION: LEGO1 0x10048310 +// FUNCTION: BETA10 0x100b8911 MxResult LegoPathController::FUN_10048310( LegoPathEdgeContainer* p_grec, - const Vector3& p_position, - const Vector3& p_direction, - LegoPathBoundary* p_boundary1, - const Vector3& p_param5, - const Vector3& p_param6, - LegoPathBoundary* p_boundary2, - MxBool p_param8, + const Vector3& p_oldPosition, + const Vector3& p_oldDirection, + LegoPathBoundary* p_oldBoundary, + const Vector3& p_newPosition, + const Vector3& p_newDirection, + LegoPathBoundary* p_newBoundary, + LegoU8 p_mask, MxFloat* p_param9 ) +{ + p_grec->m_position = p_newPosition; + p_grec->m_direction = p_newDirection; + p_grec->m_boundary = p_newBoundary; + + if (p_newBoundary == p_oldBoundary) { + p_grec->SetBit1(TRUE); + return SUCCESS; + } + + list boundaryList; + list::iterator boundaryListIt; + + LegoBEWithFloatSet boundarySet; + LegoBEWithFloatSet::iterator boundarySetItA; + LegoBEWithFloatSet::iterator boundarySetItB; + + LegoPathCtrlEdgeSet pathCtrlEdgeSet(m_pfsE); + + MxFloat local14 = 999999.0f; + + p_grec->SetBit1(FALSE); + + for (MxS32 i = 0; i < p_oldBoundary->GetNumEdges(); i++) { + LegoPathCtrlEdge* edge = (LegoPathCtrlEdge*) p_oldBoundary->GetEdges()[i]; + + if (edge->GetMask0x03()) { + LegoPathBoundary* otherFace = (LegoPathBoundary*) edge->OtherFace(p_oldBoundary); + + if (otherFace != NULL && edge->BETA_1004a830(*otherFace, p_mask)) { + if (p_newBoundary == otherFace) { + float dist; + if ((dist = edge->DistanceToMidpoint(p_oldPosition) + edge->DistanceToMidpoint(p_newPosition)) < + local14) { + local14 = dist; + p_grec->erase(p_grec->begin(), p_grec->end()); + p_grec->SetBit1(TRUE); + p_grec->push_back(LegoBoundaryEdge(edge, p_oldBoundary)); + } + } + else { + boundaryList.push_back(LegoBEWithFloat(edge, p_oldBoundary, edge->DistanceToMidpoint(p_oldPosition)) + ); + boundarySet.insert(&boundaryList.back()); + } + } + } + + pathCtrlEdgeSet.erase(edge); + } + + if (!p_grec->GetBit1()) { + while (pathCtrlEdgeSet.size() > 0) { + LegoBEWithFloat edgeWithFloat; + MxFloat local70 = 999999.0f; + + boundarySetItA = boundarySetItB = boundarySet.begin(); + + if (boundarySetItB != boundarySet.end()) { + boundarySetItB++; + } + + while (boundarySetItA != boundarySet.end()) { + MxU32 shouldRemove = TRUE; + + LegoUnknown100db7f4* e = (*boundarySetItA)->m_edge; + LegoPathBoundary* b = (*boundarySetItA)->m_boundary; + assert(e && b); + + LegoPathBoundary* bOther = (LegoPathBoundary*) e->OtherFace(b); + assert(bOther); + + if (e->BETA_1004a830(*bOther, p_mask)) { + if (bOther == p_newBoundary) { + shouldRemove = FALSE; + + LegoBEWithFloat* pfs = *boundarySetItA; + assert(pfs); + + float dist; + if ((dist = pfs->m_edge->DistanceToMidpoint(p_newPosition) + pfs->m_unk0x0c) < local70) { + local70 = dist; + edgeWithFloat.m_edge = NULL; + + if (dist < local14) { + local14 = dist; + p_grec->erase(p_grec->begin(), p_grec->end()); + p_grec->SetBit1(TRUE); + + do { + p_grec->push_front(LegoBoundaryEdge(pfs->m_edge, pfs->m_boundary)); + pfs = pfs->m_next; + } while (pfs != NULL); + } + } + } + else { + for (MxS32 i = 0; i < bOther->GetNumEdges(); i++) { + LegoPathCtrlEdge* edge = (LegoPathCtrlEdge*) bOther->GetEdges()[i]; + + if (edge->GetMask0x03()) { + if (pathCtrlEdgeSet.find(edge) != pathCtrlEdgeSet.end()) { + shouldRemove = FALSE; + + float dist; + if ((dist = edge->DistanceBetweenMidpoints(*e) + (*boundarySetItA)->m_unk0x0c) < + local70) { + local70 = dist; + edgeWithFloat = LegoBEWithFloat(edge, bOther, *boundarySetItA, dist); + } + } + } + } + } + } + + if (shouldRemove) { + boundarySet.erase(boundarySetItA); + } + + if (boundarySetItB != boundarySet.end()) { + boundarySetItA = boundarySetItB; + boundarySetItB++; + } + else { + break; + } + } + + if (edgeWithFloat.m_edge != NULL) { + pathCtrlEdgeSet.erase(edgeWithFloat.m_edge); + boundaryList.push_back(edgeWithFloat); + boundarySet.insert(&boundaryList.back()); + } + else { + break; + } + } + } + + if (p_grec->GetBit1()) { + if (p_grec->size() > 0) { + LegoPathCtrlEdge* edge = p_grec->front().m_edge; + + if (edge->FUN_10048c40(p_oldPosition)) { + p_grec->pop_front(); + } + } + + if (p_grec->size() > 0) { + LegoPathCtrlEdge* edge = p_grec->back().m_edge; + + if (edge->FUN_10048c40(p_newPosition)) { + if (edge->OtherFace(p_grec->back().m_boundary) != NULL && + edge->OtherFace(p_grec->back().m_boundary)->IsEqual(p_newBoundary)) { + p_grec->m_boundary = p_grec->back().m_boundary; + p_grec->pop_back(); + } + } + } + + if (p_param9 != NULL) { + *p_param9 = local14; + } + + return SUCCESS; + } + + return FAILURE; +} + +// STUB: LEGO1 0x10048c40 +// STUB: BETA10 0x1001cc90 +undefined4 LegoPathCtrlEdge::FUN_10048c40(const Vector3&) { // TODO - return SUCCESS; + return 0; } // FUNCTION: LEGO1 0x1004a240 @@ -763,8 +937,8 @@ MxS32 LegoPathController::FUN_1004a240( ) { if (p_grec.size() == 0) { - p_v1 = p_grec.m_unk0x0c; - p_v2 = p_grec.m_unk0x20; + p_v1 = p_grec.m_position; + p_v2 = p_grec.m_direction; p_boundary = p_grec.m_boundary; p_grec.SetBit1(FALSE); return 1; diff --git a/LEGO1/lego/sources/geom/legounkown100db7f4.h b/LEGO1/lego/sources/geom/legounkown100db7f4.h index ae877b58..38de039e 100644 --- a/LEGO1/lego/sources/geom/legounkown100db7f4.h +++ b/LEGO1/lego/sources/geom/legounkown100db7f4.h @@ -24,15 +24,14 @@ struct LegoUnknown100db7f4 : public LegoEdge { // FUNCTION: BETA10 0x100372a0 LegoResult FUN_1002ddc0(LegoWEEdge& p_f, Vector3& p_point) { - if (p_f.IsEqual(*m_faceA)) { + if (p_f.IsEqual(m_faceA)) { p_point[0] = -m_unk0x28.index_operator(0); p_point[1] = -m_unk0x28.index_operator(1); p_point[2] = -m_unk0x28.index_operator(2); } else { // clang-format off - // FIXME: There is no * dereference in the original assertion - assert(p_f.IsEqual( *m_faceB )); + assert(p_f.IsEqual( m_faceB )); // clang-format on p_point = m_unk0x28; } @@ -41,16 +40,20 @@ struct LegoUnknown100db7f4 : public LegoEdge { } // FUNCTION: BETA10 0x1004a830 - LegoU32 Unknown(LegoWEGEdge& p_face, LegoU8 p_mask) + LegoU32 BETA_1004a830(LegoWEGEdge& p_face, LegoU8 p_mask) { - return (p_face.IsEqual(*m_faceB) && (m_flags & c_bit1) && (p_face.GetMask0x03() & p_mask) == p_mask) || - (p_face.IsEqual(*m_faceA) && (m_flags & c_bit2) && (p_face.GetMask0x03() & p_mask) == p_mask); + assert(p_face.IsEqual(m_faceA) || p_face.IsEqual(m_faceB)); + return (p_face.IsEqual(m_faceB) && (m_flags & c_bit1) && (p_face.GetMask0x03() & p_mask) == p_mask) || + (p_face.IsEqual(m_faceA) && (m_flags & c_bit2) && (p_face.GetMask0x03() & p_mask) == p_mask); } // FUNCTION: BETA10 0x100b53b0 - LegoU32 Unknown2(LegoWEGEdge& p_face) + LegoU32 BETA_100b53b0(LegoWEGEdge& p_face) { - return (p_face.IsEqual(*m_faceA) && (m_flags & c_bit1)) || (p_face.IsEqual(*m_faceB) && (m_flags & c_bit2)); + // clang-format off + assert(p_face.IsEqual( m_faceA ) || p_face.IsEqual( m_faceB )); + // clang-format on + return (p_face.IsEqual(m_faceA) && (m_flags & c_bit1)) || (p_face.IsEqual(m_faceB) && (m_flags & c_bit2)); } // FUNCTION: BETA10 0x1001cbe0 @@ -64,6 +67,30 @@ struct LegoUnknown100db7f4 : public LegoEdge { } } + // FUNCTION: BETA10 0x100bd4a0 + LegoFloat DistanceToMidpoint(const Vector3& p_vec) + { + Mx3DPointFloat point(*m_pointA); + ((Vector3&) point).Add(*m_pointB); + ((Vector3&) point).Mul(0.5f); + ((Vector3&) point).Sub(p_vec); + return sqrt(point.LenSquared()); + } + + // FUNCTION: BETA10 0x100bd540 + LegoFloat DistanceBetweenMidpoints(const LegoUnknown100db7f4& p_other) + { + Mx3DPointFloat point1(*m_pointA); + Mx3DPointFloat point2(*p_other.m_pointA); + ((Vector3&) point1).Add(*m_pointB); + ((Vector3&) point1).Mul(0.5f); + ((Vector3&) point2).Add(*p_other.m_pointB); + ((Vector3&) point2).Mul(0.5f); + ((Vector3&) point1).Sub(point2); + return sqrt(point1.LenSquared()); + } + + // FUNCTION: BETA10 0x1001cc60 LegoU32 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } // SYNTHETIC: LEGO1 0x1009a6c0 diff --git a/LEGO1/lego/sources/geom/legoweedge.h b/LEGO1/lego/sources/geom/legoweedge.h index e8436427..bc0f6c3c 100644 --- a/LEGO1/lego/sources/geom/legoweedge.h +++ b/LEGO1/lego/sources/geom/legoweedge.h @@ -22,9 +22,8 @@ class LegoWEEdge { // FUNCTION: BETA10 0x1001cc30 LegoUnknown100db7f4** GetEdges() { return m_edges; } - // TODO: The assertion at BETA10 0x10037352 suggests that this function might take a pointer instead of a reference // FUNCTION: BETA10 0x100373f0 - LegoU32 IsEqual(LegoWEEdge& p_other) { return this == &p_other; } + LegoU32 IsEqual(LegoWEEdge* p_other) { return this == p_other; } void SetEdges(LegoUnknown100db7f4** p_edges, LegoU8 p_numEdges) { diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index 728d7ade..be388c2d 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -62,6 +62,7 @@ class LegoWEGEdge : public LegoWEEdge { } } + // FUNCTION: BETA10 0x1004a980 LegoU8 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } // SYNTHETIC: LEGO1 0x1009a7e0 diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index b2f4d53a..4819790c 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -26,6 +26,7 @@ class Mx3DPointFloat : public Vector3 { // FUNCTION: BETA10 0x10011600 Mx3DPointFloat(const Mx3DPointFloat& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); } + // FUNCTION: LEGO1 0x10048ed0 // FUNCTION: BETA10 0x100151e0 Mx3DPointFloat(const Vector3& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); } diff --git a/LEGO1/mxstl/stlcompat.h b/LEGO1/mxstl/stlcompat.h index c6f525bd..4a6814f3 100644 --- a/LEGO1/mxstl/stlcompat.h +++ b/LEGO1/mxstl/stlcompat.h @@ -16,6 +16,7 @@ #include using std::list; using std::map; +using std::multiset; using std::pair; using std::set; using std::vector; diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 8f871474..0e9ebed0 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -286,6 +286,7 @@ class Vector3 : public Vector2 { void Clear() override { memset(m_data, 0, sizeof(float) * 3); } // vtable+0x2c // FUNCTION: LEGO1 0x10003bd0 + // FUNCTION: BETA10 0x10011530 float LenSquared() const override { return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]; From 94ce89cbaab56dcaac4c2eec8ca368c6bea88f15 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Dec 2024 09:26:22 -0700 Subject: [PATCH 13/14] (Proposal) Introduce arithmetic operators to Vector2 (#1193) --- LEGO1/lego/legoomni/src/actors/act3actors.cpp | 4 +- LEGO1/lego/legoomni/src/actors/helicopter.cpp | 10 ++--- .../legoomni/src/actors/islepathactor.cpp | 6 +-- .../src/common/legoanimationmanager.cpp | 23 +++++----- LEGO1/lego/legoomni/src/entity/act2brick.cpp | 4 +- .../src/entity/legojetskiraceactor.cpp | 2 +- .../legoomni/src/paths/legoextraactor.cpp | 14 +++--- .../lego/legoomni/src/paths/legopathactor.cpp | 44 +++++++++---------- .../legoomni/src/paths/legopathboundary.cpp | 24 +++++----- .../legoomni/src/paths/legopathcontroller.cpp | 9 ++-- .../lego/legoomni/src/race/legoraceactor.cpp | 4 +- LEGO1/lego/legoomni/src/race/legoracers.cpp | 2 +- .../legoomni/src/race/legoracespecial.cpp | 10 ++--- .../legoomni/src/video/legoanimpresenter.cpp | 20 ++++----- .../src/video/legoloopinganimpresenter.cpp | 10 ++--- LEGO1/lego/legoomni/src/worlds/isle.cpp | 4 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 8 ++-- LEGO1/lego/sources/anim/legoanim.cpp | 4 +- LEGO1/lego/sources/geom/legounkown100db7f4.h | 16 +++---- LEGO1/lego/sources/misc/legounknown.cpp | 8 ++-- LEGO1/lego/sources/roi/legoroi.cpp | 24 +++++----- LEGO1/mxgeometry/mxgeometry3d.h | 6 +-- LEGO1/omni/include/mxnotificationmanager.h | 2 +- .../src/stream/mxdiskstreamcontroller.cpp | 1 + LEGO1/realtime/vector.h | 15 +++++++ LEGO1/viewmanager/viewmanager.cpp | 4 +- 26 files changed, 144 insertions(+), 134 deletions(-) diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index a0f1690c..7756cb45 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -52,7 +52,7 @@ MxU32 Act3Actor::VTable0x90(float p_float, Matrix4& p_transform) m_state = 0; m_unk0x1c = 0; - ((Vector3&) positionRef).Sub(g_unk0x10104ef0); + positionRef -= g_unk0x10104ef0; m_roi->FUN_100a58f0(p_transform); m_roi->VTable0x14(); return TRUE; @@ -75,7 +75,7 @@ MxResult Act3Actor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) MxMatrix local2world; local2world = roi->GetLocal2World(); - Vector3(local2world[3]).Add(g_unk0x10104ef0); + Vector3(local2world[3]) += g_unk0x10104ef0; roi->FUN_100a58f0(local2world); roi->VTable0x14(); diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 395ef5a6..1b9c0a76 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -226,8 +226,8 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) dir = m_world->GetCamera()->GetWorldDirection(); lookat = dir; float scale = 3; - lookat.Mul(scale); - lookat.Add(loc); + lookat *= scale; + lookat += loc; Mx3DPointFloat v68, v7c, v90(0, 1, 0), va4; v68 = m_world->GetCamera()->GetWorldUp(); va4.EqualsCross(&v68, &dir); @@ -379,9 +379,9 @@ void Helicopter::VTable0x70(float p_float) mat.SetIdentity(); m_unk0x1f4.Unknown6(mat, f2); v2.SetVector(loc); - v2.Sub(v); - v2.Mul(f2); - v2.Add(v); + v2 -= v; + v2 *= f2; + v2 += v; m_world->GetCamera()->FUN_100123e0(mat, 0); } else { diff --git a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp index 624fc8a9..d38117aa 100644 --- a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp @@ -126,8 +126,8 @@ void IslePathActor::Exit() Mx3DPointFloat local20; e->FUN_1002ddc0(*m_boundary, local20); - ((Vector3&) local20).Mul(m_roi->GetWorldBoundingSphere().Radius()); - ((Vector3&) local20).Add(GetWorldPosition()); + local20 *= m_roi->GetWorldBoundingSphere().Radius(); + local20 += GetWorldPosition(); MxS32 j; for (j = 0; j < m_boundary->GetNumEdges(); j++) { @@ -643,7 +643,7 @@ void IslePathActor::FUN_1001b660() Vector3 direction(transform[1]); Vector3 up(transform[2]); - ((Vector3&) up).Mul(-1.0f); + up *= -1.0f; position.EqualsCross(&direction, &up); m_roi->FUN_100a58f0(transform); m_roi->VTable0x14(); diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index b60a5381..6b5d2d78 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -1599,8 +1599,7 @@ MxU16 LegoAnimationManager::FUN_10062110( if (direction.Dot(&direction, &p_direction) > 0.707) { Mx3DPointFloat position(p_roi->GetWorldPosition()); - // TODO: Fix call - ((Vector3&) position).Sub(p_position); + position -= p_position; float len = position.LenSquared(); float min, max; @@ -1764,9 +1763,7 @@ MxBool LegoAnimationManager::FUN_10062650(Vector3& p_position, float p_und, Lego { if (p_roi != NULL) { Mx3DPointFloat position(p_position); - - // TODO: Fix call - ((Vector3&) position).Sub(p_roi->GetWorldPosition()); + position -= p_roi->GetWorldPosition(); float len = position.LenSquared(); if (len <= 0.0f) { @@ -2174,7 +2171,7 @@ MxBool LegoAnimationManager::FUN_10062e20(LegoROI* p_roi, LegoAnimPresenter* p_p position = p_roi->GetWorldPosition(); direction = p_roi->GetWorldDirection(); - ((Vector3&) direction).Mul(-1.0f); + direction *= -1.0f; m_extras[i].m_speed = -1.0f; if (inExtras) { @@ -2485,17 +2482,17 @@ MxBool LegoAnimationManager::FUN_10064010(LegoPathBoundary* p_boundary, LegoUnkn Vector3* v2 = p_edge->CCWVertex(*p_boundary); p1 = *v2; - ((Vector3&) p1).Sub(*v1); - ((Vector3&) p1).Mul(p_destScale); - ((Vector3&) p1).Add(*v1); + p1 -= *v1; + p1 *= p_destScale; + p1 += *v1; BoundingBox boundingBox; Mx3DPointFloat vec(1.0f, 1.0f, 1.0f); boundingBox.Min() = p1; - boundingBox.Min().Sub(vec); + boundingBox.Min() -= vec; boundingBox.Max() = p1; - boundingBox.Max().Add(vec); + boundingBox.Max() += vec; return GetViewManager()->IsBoundingBoxInFrustum(boundingBox) == FALSE; } @@ -2704,7 +2701,7 @@ MxResult LegoAnimationManager::FUN_10064670(Vector3* p_position) if (p_position != NULL) { Mx3DPointFloat vec(98.875f, 0.0f, -46.1564f); - ((Vector3&) vec).Sub(*p_position); + vec -= *p_position; if (vec.LenSquared() < 800.0f) { success = TRUE; @@ -2728,7 +2725,7 @@ MxResult LegoAnimationManager::FUN_10064740(Vector3* p_position) if (p_position != NULL) { Mx3DPointFloat vec(-21.375f, 0.0f, -41.75f); - ((Vector3&) vec).Sub(*p_position); + vec -= *p_position; if (vec.LenSquared() < 1000.0f) { success = TRUE; diff --git a/LEGO1/lego/legoomni/src/entity/act2brick.cpp b/LEGO1/lego/legoomni/src/entity/act2brick.cpp index 427aae48..c308912c 100644 --- a/LEGO1/lego/legoomni/src/entity/act2brick.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2brick.cpp @@ -90,8 +90,8 @@ void Act2Brick::FUN_1007a670(MxMatrix& p_param1, MxMatrix& p_param2, LegoPathBou { m_unk0x17c = p_param2[3]; m_unk0x168 = p_param2[3]; - ((Vector3&) m_unk0x168).Sub(p_param1[3]); - ((Vector3&) m_unk0x168).Div(8.0f); + m_unk0x168 -= p_param1[3]; + m_unk0x168 /= 8.0f; m_unk0x190 = 0; TickleManager()->RegisterClient(this, 20); diff --git a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp index 79084b69..22a60c40 100644 --- a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp @@ -96,7 +96,7 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ Mx3DPointFloat worldDirection(m_roi->GetWorldDirection()); if (!m_userNavFlag) { - ((Vector2*) &worldDirection)->Mul(-1.0f); + worldDirection *= -1.0f; } if (VTable0x80(m_roi->GetWorldPosition(), worldDirection, a, c)) { diff --git a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp index abeaad10..ebfd17d3 100644 --- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp @@ -97,7 +97,7 @@ MxU32 LegoExtraActor::VTable0x90(float p_time, Matrix4& p_transform) else { m_state = 0; m_scheduledTime = 0.0f; - ((Vector3&) positionRef).Sub(g_unk0x10104c18); // TODO: Fix call + positionRef -= g_unk0x10104c18; m_roi->FUN_100a58f0(p_transform); return TRUE; } @@ -136,8 +136,7 @@ MxResult LegoExtraActor::FUN_1002aae0() Vector3 dirRef(m_unk0xec[2]); Vector3 positionRef(m_unk0xec[3]); - // TODO: Fix call - ((Vector3&) dirRef).Mul(-1.0f); + dirRef *= -1.0f; rightRef.EqualsCross(&upRef, &dirRef); if (m_boundary == m_destEdge->m_faceA) { @@ -216,9 +215,8 @@ MxResult LegoExtraActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) Vector3 positionRef(matrix2[3]); Mx3DPointFloat dir(matrix[2]); - // TODO: Fix calls - ((Mx3DPointFloat&) dir).Mul(2.0f); - ((Vector3&) positionRef).Add(dir); + dir *= 2.0f; + positionRef += dir; for (MxS32 i = 0; i < m_boundary->GetNumEdges(); i++) { Mx4DPointFloat* normal = m_boundary->GetEdgeNormal(i); @@ -251,7 +249,7 @@ MxResult LegoExtraActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) Mx3DPointFloat dir = p_actor->GetWorldDirection(); MxMatrix matrix3 = MxMatrix(roi->GetLocal2World()); Vector3 positionRef(matrix3[3]); - ((Vector3&) positionRef).Add(g_unk0x10104c18); + positionRef += g_unk0x10104c18; roi->FUN_100a58f0(matrix3); #ifdef COMPAT_MODE @@ -463,7 +461,7 @@ MxU32 LegoExtraActor::VTable0x6c( Vector3 local60(local2world[3]); Mx3DPointFloat local54(p_v1); - ((Vector3&) local54).Sub(local60); + local54 -= local60; float local1c = p_v2.Dot(&p_v2, &p_v2); float local24 = p_v2.Dot(&p_v2, &local54) * 2.0f; float local20 = local54.Dot(&local54, &local54); diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 3a1a5427..1d5bb959 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -72,7 +72,7 @@ MxResult LegoPathActor::VTable0x80(const Vector3& p_point1, Vector3& p_point2, V Mx3DPointFloat p1, p2, p3; p1 = p_point3; - ((Vector3&) p1).Sub(p_point1); + p1 -= p_point1; m_BADuration = p1.LenSquared(); if (m_BADuration > 0.0f) { @@ -106,14 +106,14 @@ MxResult LegoPathActor::VTable0x88( Mx3DPointFloat p1, p2, p3, p4, p5; p1 = *v2; - ((Vector3&) p1).Sub(*v1); - ((Vector3&) p1).Mul(p_srcScale); - ((Vector3&) p1).Add(*v1); + p1 -= *v1; + p1 *= p_srcScale; + p1 += *v1; p2 = *v4; - ((Vector3&) p2).Sub(*v3); - ((Vector3&) p2).Mul(p_destScale); - ((Vector3&) p2).Add(*v3); + p2 -= *v3; + p2 *= p_destScale; + p2 += *v3; m_boundary = p_boundary; m_destEdge = &p_destEdge; @@ -124,7 +124,7 @@ MxResult LegoPathActor::VTable0x88( p_destEdge.FUN_1002ddc0(*p_boundary, p3); p4 = p2; - ((Vector3&) p4).Sub(p1); + p4 -= p1; p4.Unitize(); MxMatrix matrix; @@ -139,7 +139,7 @@ MxResult LegoPathActor::VTable0x88( up = *m_boundary->GetUnknown0x14(); if (!m_cameraFlag || !m_userNavFlag) { - ((Vector3&) dir).Mul(-1.0f); + dir *= -1.0f; } right.EqualsCross(&up, &dir); @@ -181,9 +181,9 @@ MxResult LegoPathActor::VTable0x84( Mx3DPointFloat p2, p3, p5; p2 = *v4; - ((Vector3&) p2).Sub(*v3); - ((Vector3&) p2).Mul(p_destScale); - ((Vector3&) p2).Add(*v3); + p2 -= *v3; + p2 *= p_destScale; + p2 += *v3; m_boundary = p_boundary; m_destEdge = &p_destEdge; @@ -205,7 +205,7 @@ MxResult LegoPathActor::VTable0x84( up = *m_boundary->GetUnknown0x14(); if (!m_cameraFlag || !m_userNavFlag) { - ((Vector3&) dir).Mul(-1.0f); + dir *= -1.0f; } right.EqualsCross(&up, &dir); @@ -289,12 +289,12 @@ MxS32 LegoPathActor::VTable0x8c(float p_time, Matrix4& p_transform) m_worldSpeed *= m_unk0x144; nav->SetLinearVel(m_worldSpeed); Mx3DPointFloat p7(p2); - ((Vector3&) p7).Sub(p6); + p7 -= p6; if (p7.Unitize() == 0) { float f = sqrt(p1.LenSquared()) * m_unk0x140; - ((Vector3&) p7).Mul(f); - ((Vector3&) p1).Add(p7); + p7 *= f; + p1 += p7; } } } @@ -479,7 +479,7 @@ MxU32 LegoPathActor::VTable0x6c( MxS32 LegoPathActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) { Mx3DPointFloat v2(p_v2); - ((Vector3&) v2).Sub(p_v1); + v2 -= p_v1; float len = v2.LenSquared(); @@ -488,7 +488,7 @@ MxS32 LegoPathActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) } len = sqrt(len); - ((Vector3&) v2).Div(len); + v2 /= len; float radius = m_roi->GetWorldBoundingSphere().Radius(); list boundaries; @@ -655,16 +655,16 @@ MxResult LegoPathActor::VTable0x9c() Mx3DPointFloat local84(m_unk0xec[2]); Mx3DPointFloat local70(local34); - ((Vector3&) local70).Sub(localc0); + local70 -= localc0; float len = local70.LenSquared(); if (len >= 0.0f) { len = sqrt(len); - ((Vector3&) local84).Mul(len); - ((Vector3&) local48).Mul(len); + local84 *= len; + local48 *= len; } if (!m_userNavFlag) { - ((Vector3&) local84).Mul(-1.0f); + local84 *= -1.0f; } if (VTable0x80(localc0, local84, local34, local48) != SUCCESS) { diff --git a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp index d72ee168..8c98dd87 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp @@ -53,11 +53,11 @@ void LegoPathBoundary::FUN_100575b0(Vector3& p_point1, Vector3& p_point2, LegoPa Mx3DPointFloat v; v = p_point1; - ((Vector3&) v).Sub(*ccwV); + v -= *ccwV; float dot1 = v.Dot(&v, m_unk0x50); v = p_point2; - ((Vector3&) v).Sub(*ccwV); + v -= *ccwV; float dot2 = v.Dot(&v, m_unk0x50); if (dot2 > dot1) { @@ -201,7 +201,7 @@ MxU32 LegoPathBoundary::Intersect( if (local10 == 0) { local10 = 1; vec = p_point2; - ((Vector3&) vec).Sub(p_point1); + vec -= p_point1; len = vec.LenSquared(); if (len <= 0.0f) { @@ -209,7 +209,7 @@ MxU32 LegoPathBoundary::Intersect( } len = sqrt(len); - ((Vector3&) vec).Div(len); + vec /= len; } float dot = vec.Dot(&vec, &m_edgeNormals[i]); @@ -234,11 +234,11 @@ MxU32 LegoPathBoundary::Intersect( Vector3* local5c = e->CWVertex(*this); p_point3 = vec; - p_point3.Mul(localc); - p_point3.Add(p_point1); + p_point3 *= localc; + p_point3 += p_point1; local50 = p_point2; - ((Vector3&) local50).Sub(*local5c); + local50 -= *local5c; e->FUN_1002ddc0(*this, local70); @@ -258,7 +258,7 @@ MxU32 LegoPathBoundary::Intersect( Vector3* local90 = local88->CWVertex(*this); Mx3DPointFloat locala4(p_point3); - ((Vector3&) locala4).Sub(*local90); + locala4 -= *local90; float local8c = locala4.Dot(&locala4, &local84); @@ -285,7 +285,7 @@ MxU32 LegoPathBoundary::Intersect( Vector3* localc4 = locala8->CWVertex(*this); Mx3DPointFloat locald8(p_point3); - ((Vector3&) locald8).Sub(*localc4); + locald8 -= *localc4; float localc0 = locald8.Dot(&locald8, &localbc); @@ -316,8 +316,8 @@ MxU32 LegoPathBoundary::Intersect( } else if (local58 > 0.0f && e->m_unk0x3c > local58) { p_point3 = local70; - p_point3.Mul(local58); - p_point3.Add(*local5c); + p_point3 *= local58; + p_point3 += *local5c; p_edge = e; return 1; } @@ -345,7 +345,7 @@ MxU32 LegoPathBoundary::FUN_10057fe0(LegoAnimPresenter* p_presenter) Mx3DPointFloat unk0x30; unk0x30 = m_unk0x30; - ((Vector3&) unk0x30).Sub(p_presenter->m_unk0xa8); + unk0x30 -= p_presenter->m_unk0xa8; float len = unk0x30.LenSquared(); float local20 = p_presenter->m_unk0xa4 + m_unk0x44; diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index 86c89917..b2d9ceee 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -95,8 +95,7 @@ MxResult LegoPathController::Create(MxU8* p_data, const Vector3& p_location, con } for (i = 0; i < m_numN; i++) { - // TODO: Fix call - ((Vector3&) m_unk0x10[i]).Add(p_location); + m_unk0x10[i] += p_location; } for (i = 0; i < m_numL; i++) { @@ -950,9 +949,9 @@ MxS32 LegoPathController::FUN_1004a240( Mx3DPointFloat vec; p_v1 = *p_edge->CCWVertex(*p_boundary); - p_v1.Sub(*p_edge->CWVertex(*p_boundary)); - p_v1.Mul(p_f1); - p_v1.Add(*p_edge->CWVertex(*p_boundary)); + p_v1 -= *p_edge->CWVertex(*p_boundary); + p_v1 *= p_f1; + p_v1 += *p_edge->CWVertex(*p_boundary); p_edge->FUN_1002ddc0(*p_boundary, vec); p_v2.EqualsCross(p_boundary->GetUnknown0x14(), &vec); return 0; diff --git a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp index 32455e4a..e640b812 100644 --- a/LEGO1/lego/legoomni/src/race/legoraceactor.cpp +++ b/LEGO1/lego/legoomni/src/race/legoraceactor.cpp @@ -84,7 +84,7 @@ MxU32 LegoRaceActor::VTable0x90(float p_float, Matrix4& p_transform) m_state = 0; m_unk0x08 = 0; - ((Vector3&) positionRef).Sub(g_unk0x10102b08); + positionRef -= g_unk0x10102b08; m_roi->FUN_100a58f0(p_transform); return 1; } @@ -108,7 +108,7 @@ MxResult LegoRaceActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) MxMatrix matr; matr = roi->GetLocal2World(); - Vector3(matr[3]).Add(g_unk0x10102b08); + Vector3(matr[3]) += g_unk0x10102b08; roi->FUN_100a58f0(matr); diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index b0214bc1..4b12e8d7 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -442,7 +442,7 @@ MxResult LegoRaceCar::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) MxMatrix matr; matr = roi->GetLocal2World(); - Vector3(matr[3]).Add(g_unk0x10102af0); + Vector3(matr[3]) += g_unk0x10102af0; roi->FUN_100a58f0(matr); p_actor->SetState(2); diff --git a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp index e81bf457..aaabbff3 100644 --- a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp @@ -172,11 +172,11 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg Mx3DPointFloat worldDirection(Vector3(m_roi->GetWorldDirection())); if (!m_userNavFlag) { - ((Vector3*) &worldDirection)->Mul(-1.0f); + worldDirection *= -1.0f; } - ((Vector3*) &worldDirection)->Mul(5.0f); - ((Vector3*) &crossProduct)->Mul(5.0f); + worldDirection *= 5.0f; + crossProduct *= 5.0f; MxResult callResult = VTable0x80(Vector3(m_roi->GetWorldPosition()), worldDirection, pointUnknown, crossProduct); @@ -266,8 +266,8 @@ MxResult LegoCarRaceActor::VTable0x9c() point4.Unitize(); point5.Unitize(); - ((Vector3*) &point4)->Mul(5.0f); - ((Vector3*) &point5)->Mul(5.0f); + point4 *= 5.0f; + point5 *= 5.0f; MxResult res = VTable0x80(m_roi->GetWorldPosition(), point4, point1, point5); diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 7b08d2f8..15140eca 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -649,14 +649,14 @@ void LegoAnimPresenter::PutFrame() up = und; - ((Vector3&) up).Sub(m_currentWorld->GetCamera()->GetWorldLocation()); - ((Vector3&) dir).Div(dirsqr); + up -= m_currentWorld->GetCamera()->GetWorldLocation(); + dir /= dirsqr; pos.EqualsCross(&dir, &up); pos.Unitize(); up.EqualsCross(&pos, &dir); - ((Vector3&) pos).Mul(possqr); - ((Vector3&) dir).Mul(dirsqr); - ((Vector3&) up).Mul(upsqr); + pos *= possqr; + dir *= dirsqr; + up *= upsqr; m_unk0x8c[i]->FUN_100a58f0(mat); m_unk0x8c[i]->VTable0x14(); @@ -1114,10 +1114,10 @@ void LegoAnimPresenter::FUN_1006c7a0() void LegoAnimPresenter::VTable0x8c() { if (m_unk0x78) { - m_unk0xa8.Add((*m_unk0x78)[3]); + m_unk0xa8 += (*m_unk0x78)[3]; } else { - m_unk0xa8.Add(m_action->GetLocation()); + m_unk0xa8 += m_action->GetLocation(); } if (m_currentWorld == NULL) { @@ -1173,11 +1173,11 @@ MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, fl Mx3DPointFloat a, b; b = p_v2; - ((Vector3&) b).Mul(p_f1); - ((Vector3&) b).Add(p_v1); + b *= p_f1; + b += p_v1; a = b; - ((Vector3&) a).Sub(m_unk0xa8); + a -= m_unk0xa8; float len = a.LenSquared(); if (len <= 0.0f) { diff --git a/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp index 56386538..7fa8d7ba 100644 --- a/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp @@ -66,14 +66,14 @@ void LegoLoopingAnimPresenter::PutFrame() up = und; - ((Vector3&) up).Sub(m_currentWorld->GetCamera()->GetWorldLocation()); - ((Vector3&) dir).Div(dirsqr); + up -= m_currentWorld->GetCamera()->GetWorldLocation(); + dir /= dirsqr; pos.EqualsCross(&dir, &up); pos.Unitize(); up.EqualsCross(&pos, &dir); - ((Vector3&) pos).Mul(possqr); - ((Vector3&) dir).Mul(dirsqr); - ((Vector3&) up).Mul(upsqr); + pos *= possqr; + dir *= dirsqr; + up *= upsqr; m_unk0x8c[i]->FUN_100a58f0(mat); m_unk0x8c[i]->VTable0x14(); diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index e7db6a03..ef830926 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -721,13 +721,13 @@ void Isle::Enable(MxBool p_enable) Mx3DPointFloat position(UserActor()->GetROI()->GetWorldPosition()); Mx3DPointFloat sub(-21.375f, 0.0f, -41.75f); - ((Vector3&) sub).Sub(position); + sub -= position; if (sub.LenSquared() < 1024.0f) { AnimationManager()->FUN_10064740(NULL); } Mx3DPointFloat sub2(98.874992f, 0.0f, -46.156292f); - ((Vector3&) sub2).Sub(position); + sub2 -= position; if (sub2.LenSquared() < 1024.0f) { AnimationManager()->FUN_10064670(NULL); } diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 174775b2..9119eb1b 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -313,7 +313,7 @@ MxLong LegoAct2::Notify(MxParam& p_param) Mx3DPointFloat unk0x10d8(m_pepper->GetWorldPosition()); Mx3DPointFloat locala4(unk0x10d8); - ((Vector3&) entityPosition).Sub(unk0x10d8); + entityPosition -= unk0x10d8; MxMatrix local2world(m_pepper->GetLocal2World()); Vector3 local30(local2world[0]); @@ -324,8 +324,8 @@ MxLong LegoAct2::Notify(MxParam& p_param) local28.Unitize(); Mx3DPointFloat local90(local28); - ((Vector3&) local90).Mul(1.25f); - ((Vector3&) locala4).Add(local90); + local90 *= 1.25f; + locala4 += local90; locala4[1] += 0.25; local30.EqualsCross(&localac, &local28); local30.Unitize(); @@ -1024,7 +1024,7 @@ void LegoAct2::FUN_100521f0(MxS32 p_param1) if (objectId != (Act2mainScript::Script) 0) { Mx3DPointFloat local30(vec); Mx3DPointFloat position(m_pepper->GetWorldPosition()); - ((Vector3&) local30).Sub(position); + local30 -= position; Mx3DPointFloat local44 = local30; local30.Unitize(); FUN_10052560(objectId, TRUE, TRUE, &vec, &local30, NULL); diff --git a/LEGO1/lego/sources/anim/legoanim.cpp b/LEGO1/lego/sources/anim/legoanim.cpp index 317e2513..2477a6ef 100644 --- a/LEGO1/lego/sources/anim/legoanim.cpp +++ b/LEGO1/lego/sources/anim/legoanim.cpp @@ -168,7 +168,7 @@ LegoResult LegoAnimScene::FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix) } local54 = localcc; - ((Vector3&) local54).Sub(localb8); + local54 -= localb8; if (local54.Unitize() == 0) { local5c.EqualsCross(&local68, &local54); @@ -177,7 +177,7 @@ LegoResult LegoAnimScene::FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix) local68.EqualsCross(&local54, &local5c); localcc = p_matrix[3]; - ((Vector3&) localcc).Add(localb0[3]); + localcc += localb0[3]; p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = localb0[3][0] = localb0[3][1] = localb0[3][2] = 0; diff --git a/LEGO1/lego/sources/geom/legounkown100db7f4.h b/LEGO1/lego/sources/geom/legounkown100db7f4.h index 38de039e..adae57a9 100644 --- a/LEGO1/lego/sources/geom/legounkown100db7f4.h +++ b/LEGO1/lego/sources/geom/legounkown100db7f4.h @@ -71,9 +71,9 @@ struct LegoUnknown100db7f4 : public LegoEdge { LegoFloat DistanceToMidpoint(const Vector3& p_vec) { Mx3DPointFloat point(*m_pointA); - ((Vector3&) point).Add(*m_pointB); - ((Vector3&) point).Mul(0.5f); - ((Vector3&) point).Sub(p_vec); + point += *m_pointB; + point *= 0.5f; + point -= p_vec; return sqrt(point.LenSquared()); } @@ -82,11 +82,11 @@ struct LegoUnknown100db7f4 : public LegoEdge { { Mx3DPointFloat point1(*m_pointA); Mx3DPointFloat point2(*p_other.m_pointA); - ((Vector3&) point1).Add(*m_pointB); - ((Vector3&) point1).Mul(0.5f); - ((Vector3&) point2).Add(*p_other.m_pointB); - ((Vector3&) point2).Mul(0.5f); - ((Vector3&) point1).Sub(point2); + point1 += *m_pointB; + point1 *= 0.5f; + point2 += *p_other.m_pointB; + point2 *= 0.5f; + point1 -= point2; return sqrt(point1.LenSquared()); } diff --git a/LEGO1/lego/sources/misc/legounknown.cpp b/LEGO1/lego/sources/misc/legounknown.cpp index 67e1423c..12947446 100644 --- a/LEGO1/lego/sources/misc/legounknown.cpp +++ b/LEGO1/lego/sources/misc/legounknown.cpp @@ -42,9 +42,9 @@ LegoResult LegoUnknown::FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, L } else if (p_f1 >= 0.999) { v1 = m_unk0x00[0]; - ((Vector3&) v1).Add(m_unk0x00[1]); - ((Vector3&) v1).Add(m_unk0x00[2]); - ((Vector3&) v1).Add(m_unk0x00[3]); + v1 += m_unk0x00[1]; + v1 += m_unk0x00[2]; + v1 += m_unk0x00[3]; for (LegoS32 i = 0; i < 3; i++) { v4[i] = m_unk0x00[1][i] + m_unk0x00[2][i] * 2.0f + m_unk0x00[3][i] * 3.0f; @@ -61,7 +61,7 @@ LegoResult LegoUnknown::FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, L } if (p_und) { - ((Vector3&) v4).Mul(-1.0f); + v4 *= -1.0f; } if (v4.Unitize() != 0) { diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index c9e0d21a..ec853d19 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -600,8 +600,8 @@ LegoU32 LegoROI::FUN_100a9410( { if (p_collideBox) { Mx3DPointFloat v2(p_v2); - ((Vector3&) v2).Mul(p_f1); - ((Vector3&) v2).Add(p_v1); + v2 *= p_f1; + v2 += p_v1; Mx4DPointFloat localc0; Mx4DPointFloat local9c; @@ -621,8 +621,8 @@ LegoU32 LegoROI::FUN_100a9410( localc0[3] = local9c[3] = local168[3] = 1.0f; local38 = local58; - ((Vector3&) local38).Add(locala8); - ((Vector3&) local38).Mul(0.5f); + local38 += locala8; + local38 *= 0.5f; local70 = localc0; localc0.SetMatrixProduct(&local70, (float*) m_local2world.GetData()); @@ -647,7 +647,7 @@ LegoU32 LegoROI::FUN_100a9410( } if (local150[i][3] + local38.Dot(&local38, &local150[i]) < 0.0f) { - ((Vector4&) local150[i]).Mul(-1.0f); + local150[i] *= -1.0f; } } @@ -659,8 +659,8 @@ LegoU32 LegoROI::FUN_100a9410( if (local50 >= 0.0f && local50 <= p_f1) { Mx3DPointFloat local17c(p_v2); - ((Vector3&) local17c).Mul(local50); - ((Vector3&) local17c).Add(local4c); + local17c *= local50; + local17c += local4c; LegoS32 j; for (j = 0; j < 6; j++) { @@ -680,7 +680,7 @@ LegoU32 LegoROI::FUN_100a9410( } else { Mx3DPointFloat v1(p_v1); - ((Vector3&) v1).Sub(GetWorldBoundingSphere().Center()); + v1 -= GetWorldBoundingSphere().Center(); float local10 = GetWorldBoundingSphere().Radius(); float local8 = p_v2.Dot(&p_v2, &p_v2); @@ -716,8 +716,8 @@ LegoU32 LegoROI::FUN_100a9410( if (local1c >= 0.0f && p_f1 >= local1c) { p_v3 = p_v2; - p_v3.Mul(local1c); - p_v3.Add(p_v1); + p_v3 *= local1c; + p_v3 += p_v1; return 1; } } @@ -744,8 +744,8 @@ void TimeROI::FUN_100a9b40(Matrix4& p_matrix, LegoTime p_time) Mx3DPointFloat targetPosition(p_matrix[3]); Vector3 vec(m_local2world[3]); - ((Vector3&) targetPosition).Sub(vec); - ((Vector3&) targetPosition).Div(time * 0.001); + targetPosition -= vec; + targetPosition /= time * 0.001; FUN_100a5a30(targetPosition); } diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index 4819790c..3e72db9a 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -163,13 +163,13 @@ inline void UnknownMx4DPointFloat::Unknown7() Mx4DPointFloat v2; v1 = m_unk0x00; - ((Vector4&) v1).Add(m_unk0x18); + v1 += m_unk0x18; v2 = m_unk0x00; - ((Vector4&) v2).Sub(m_unk0x18); + v2 -= m_unk0x18; if (v1.Dot(&v1, &v1) < v2.Dot(&v2, &v2)) { - ((Vector4&) m_unk0x18).Mul(-1.0f); + m_unk0x18 *= -1.0f; } } } diff --git a/LEGO1/omni/include/mxnotificationmanager.h b/LEGO1/omni/include/mxnotificationmanager.h index 42563911..ff26751f 100644 --- a/LEGO1/omni/include/mxnotificationmanager.h +++ b/LEGO1/omni/include/mxnotificationmanager.h @@ -40,7 +40,7 @@ class MxNotificationManager : public MxCore { ~MxNotificationManager() override; // vtable+0x00 (scalar deleting destructor) MxResult Tickle() override; // vtable+0x08 - // TODO: Where does this method come from? + virtual MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread); // vtable+0x14 void Register(MxCore* p_listener); void Unregister(MxCore* p_listener); diff --git a/LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp b/LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp index 68d3cee3..2e740764 100644 --- a/LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp +++ b/LEGO1/omni/src/stream/mxdiskstreamcontroller.cpp @@ -287,6 +287,7 @@ MxResult MxDiskStreamController::VTable0x20(MxDSAction* p_action) { AUTOLOCK(m_criticalSection); MxDSStreamingAction* entry = (MxDSStreamingAction*) m_list0x80.Find(p_action); // TODO: is this a seperate class? + if (entry) { MxDSStreamingAction* action = new MxDSStreamingAction(*p_action, 0); action->SetUnknown28(entry->GetUnknown28()); diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 0e9ebed0..02b8d53b 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -118,6 +118,7 @@ class Vector2 { return -1; } // vtable+0x44 +private: // FUNCTION: LEGO1 0x100021c0 virtual void Add(float p_value) { AddImpl(p_value); } // vtable+0x50 @@ -145,6 +146,7 @@ class Vector2 { // FUNCTION: LEGO1 0x10002240 virtual void Div(const float& p_value) { DivScalarImpl((float*) &p_value); } // vtable+0x68 +public: // FUNCTION: LEGO1 0x10002250 virtual void SetVector(float* p_other) { EqualsImpl(p_other); } // vtable+0x70 @@ -170,6 +172,19 @@ class Vector2 { // FUNCTION: BETA10 0x1001d170 const float& operator[](int idx) const { return m_data[idx]; } + void operator+=(float p_value) { Add(p_value); } + void operator+=(float* p_other) { Add(p_other); } + void operator+=(const Vector2& p_other) { Add(p_other); } + + void operator-=(const float* p_other) { Sub(p_other); } + void operator-=(const Vector2& p_other) { Sub(p_other); } + + void operator*=(float* p_other) { Mul(p_other); } + void operator*=(Vector2* p_other) { Mul(p_other); } + void operator*=(const float& p_value) { Mul(p_value); } + + void operator/=(const float& p_value) { Div(p_value); } + protected: float* m_data; // 0x04 }; diff --git a/LEGO1/viewmanager/viewmanager.cpp b/LEGO1/viewmanager/viewmanager.cpp index 677cfb84..3feb3c93 100644 --- a/LEGO1/viewmanager/viewmanager.cpp +++ b/LEGO1/viewmanager/viewmanager.cpp @@ -430,10 +430,10 @@ void ViewManager::UpdateViewTransformations() Vector3 normal(frustum_planes[i]); x = c; - ((Vector3&) x).Sub(b); // TODO: Fix call + x -= b; y = a; - ((Vector3&) y).Sub(b); // TODO: Fix call + y -= b; normal.EqualsCross(&x, &y); normal.Unitize(); From 5be00e1799d0f61629764158440b18159588335b Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Dec 2024 09:58:51 -0700 Subject: [PATCH 14/14] Implement/match LegoPathCtrlEdge::FUN_10048c40 (#1195) * Implement/match LegoPathCtrlEdge::FUN_10048c40 * Improve matches --- .../legoomni/include/legopathcontroller.h | 20 +++++- .../legoomni/src/paths/legopathcontroller.cpp | 72 +++++++++++++++++-- LEGO1/lego/sources/geom/legounkown100db7f4.h | 4 +- 3 files changed, 86 insertions(+), 10 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 5450841d..4bcf17c9 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -23,7 +23,7 @@ class Vector3; // VTABLE: LEGO1 0x100d7da8 // SIZE 0x40 struct LegoPathCtrlEdge : public LegoUnknown100db7f4 { - undefined4 FUN_10048c40(const Vector3&); + inline MxU32 FUN_10048c40(const Vector3& p_position); }; struct LegoPathCtrlEdgeCompare { @@ -256,6 +256,9 @@ class LegoPathController : public MxCore { // TEMPLATE: LEGO1 0x10049370 // _Tree >::_Kfn,LegoPathCtrlEdgeCompare,allocator >::_Ubound +// TEMPLATE: LEGO1 0x100493a0 +// list >::~list > + // TEMPLATE: LEGO1 0x10049410 // list >::insert @@ -265,6 +268,9 @@ class LegoPathController : public MxCore { // TEMPLATE: LEGO1 0x100494a0 // _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::iterator::_Inc +// TEMPLATE: LEGO1 0x100494e0 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::~_Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::insert @@ -283,12 +289,24 @@ class LegoPathController : public MxCore { // TEMPLATE: LEGO1 0x10049e00 // _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Insert +// TEMPLATE: LEGO1 0x10049d10 +// _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Erase + // TEMPLATE: LEGO1 0x1004a090 // _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Lrotate // TEMPLATE: LEGO1 0x1004a0f0 // _Tree >::_Kfn,LegoBEWithFloatComparator,allocator >::_Rrotate +// TEMPLATE: LEGO1 0x1004a150 +// List::~List + +// TEMPLATE: LEGO1 0x1004a1a0 +// Multiset::~Multiset + +// TEMPLATE: LEGO1 0x1004a1f0 +// multiset >::~multiset > + // TEMPLATE: LEGO1 0x1004a760 // _Construct diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index b2d9ceee..4fd0ace2 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -817,7 +817,10 @@ MxResult LegoPathController::FUN_10048310( LegoPathBoundary* bOther = (LegoPathBoundary*) e->OtherFace(b); assert(bOther); - if (e->BETA_1004a830(*bOther, p_mask)) { + if (!e->BETA_1004a830(*bOther, p_mask)) { + // This branch is empty, but present in the BETA - probably had comments only + } + else { if (bOther == p_newBoundary) { shouldRemove = FALSE; @@ -826,9 +829,10 @@ MxResult LegoPathController::FUN_10048310( float dist; if ((dist = pfs->m_edge->DistanceToMidpoint(p_newPosition) + pfs->m_unk0x0c) < local70) { - local70 = dist; edgeWithFloat.m_edge = NULL; + local70 = dist; + // TODO: Match if (dist < local14) { local14 = dist; p_grec->erase(p_grec->begin(), p_grec->end()); @@ -916,12 +920,66 @@ MxResult LegoPathController::FUN_10048310( return FAILURE; } -// STUB: LEGO1 0x10048c40 -// STUB: BETA10 0x1001cc90 -undefined4 LegoPathCtrlEdge::FUN_10048c40(const Vector3&) +// FUNCTION: LEGO1 0x10048c40 +// FUNCTION: BETA10 0x1001cc90 +inline MxU32 LegoPathCtrlEdge::FUN_10048c40(const Vector3& p_position) { - // TODO - return 0; + MxFloat localc, local10; + MxU32 result = FALSE; + + if (m_unk0x28[0] > 0.001 || m_unk0x28[0] < -0.001) { + localc = (p_position[0] - (*m_pointA)[0]) / m_unk0x28[0]; + + if (localc < 0 || localc > 1) { + return FALSE; + } + + result = TRUE; + } + else { + if (p_position[0] > (*m_pointA)[0] + 0.001 || p_position[0] < (*m_pointA)[0] - 0.001) { + return FALSE; + } + } + + if (m_unk0x28[1] > 0.001 || m_unk0x28[1] < -0.001) { + local10 = (p_position[1] - (*m_pointA)[1]) / m_unk0x28[1]; + + if (result) { + if (localc > local10 + 0.001 || localc < local10 - 0.001) { + return FALSE; + } + } + else { + result = TRUE; + localc = local10; + } + } + else { + if (p_position[1] > (*m_pointA)[1] + 0.001 || p_position[1] < (*m_pointA)[1] - 0.001) { + return FALSE; + } + } + + if (m_unk0x28[2] > 0.001 || m_unk0x28[2] < -0.001) { + local10 = (p_position[2] - (*m_pointA)[2]) / m_unk0x28[2]; + + if (result) { + if (localc > local10 + 0.001 || localc < local10 - 0.001) { + return FALSE; + } + } + else { + return TRUE; + } + } + else { + if (p_position[2] > (*m_pointA)[2] + 0.001 || p_position[2] < (*m_pointA)[2] - 0.001) { + return FALSE; + } + } + + return TRUE; } // FUNCTION: LEGO1 0x1004a240 diff --git a/LEGO1/lego/sources/geom/legounkown100db7f4.h b/LEGO1/lego/sources/geom/legounkown100db7f4.h index adae57a9..bd19ee78 100644 --- a/LEGO1/lego/sources/geom/legounkown100db7f4.h +++ b/LEGO1/lego/sources/geom/legounkown100db7f4.h @@ -74,7 +74,7 @@ struct LegoUnknown100db7f4 : public LegoEdge { point += *m_pointB; point *= 0.5f; point -= p_vec; - return sqrt(point.LenSquared()); + return sqrt((double) point.LenSquared()); } // FUNCTION: BETA10 0x100bd540 @@ -87,7 +87,7 @@ struct LegoUnknown100db7f4 : public LegoEdge { point2 += *p_other.m_pointB; point2 *= 0.5f; point1 -= point2; - return sqrt(point1.LenSquared()); + return sqrt((double) point1.LenSquared()); } // FUNCTION: BETA10 0x1001cc60