From 1e3ca1188643a262f11bc81b01a4e243ab4e9a43 Mon Sep 17 00:00:00 2001 From: Nathan M Gilbert Date: Tue, 26 Mar 2024 13:51:52 -0400 Subject: [PATCH] Implement/match LegoAnimActor (#730) * Implement/match LegoAnimActor * Name changes (deviation from original source) * Attempt to fix modern build * Add missing override * Match LegoAnimActor::SetWorldSpeed * Remove junk * Style changes and implement WEEdge * Add override * Match LegoAnimActor::FUN_1001c1f0, style * Style * Add missing annotations, STUB LegoPathBoundary * Style --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 3 + LEGO1/define.cpp | 4 + LEGO1/define.h | 1 + LEGO1/lego/legoomni/include/bumpbouy.h | 9 +- LEGO1/lego/legoomni/include/islepathactor.h | 8 +- LEGO1/lego/legoomni/include/legoanimactor.h | 68 ++++-- .../lego/legoomni/include/legoanimpresenter.h | 3 + LEGO1/lego/legoomni/include/legopathactor.h | 32 +-- .../lego/legoomni/include/legopathboundary.h | 28 ++- .../legoomni/include/legopathcontroller.h | 25 ++- LEGO1/lego/legoomni/src/actors/bumpbouy.cpp | 26 +-- LEGO1/lego/legoomni/src/actors/helicopter.cpp | 2 +- .../legoomni/src/actors/islepathactor.cpp | 2 +- .../legoomni/src/common/legogamestate.cpp | 2 +- .../lego/legoomni/src/paths/legoanimactor.cpp | 211 +++++++++++++++++- .../legoomni/src/paths/legopathboundary.cpp | 10 + .../legoomni/src/video/legoanimpresenter.cpp | 6 + LEGO1/lego/legoomni/src/worlds/isle.cpp | 4 +- LEGO1/lego/sources/geom/legoweedge.cpp | 55 +++++ LEGO1/lego/sources/geom/legoweedge.h | 39 ++++ LEGO1/lego/sources/geom/legowegedge.cpp | 44 ++++ LEGO1/lego/sources/geom/legowegedge.h | 35 +++ LEGO1/lego/sources/roi/legoroi.cpp | 6 + LEGO1/lego/sources/roi/legoroi.h | 2 + tools/ncc/skip.yml | 3 + 25 files changed, 534 insertions(+), 94 deletions(-) create mode 100644 LEGO1/lego/legoomni/src/paths/legopathboundary.cpp create mode 100644 LEGO1/lego/sources/geom/legoweedge.cpp create mode 100644 LEGO1/lego/sources/geom/legoweedge.h create mode 100644 LEGO1/lego/sources/geom/legowegedge.cpp create mode 100644 LEGO1/lego/sources/geom/legowegedge.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e4ff9d4d..d7f18ad8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,6 +150,8 @@ add_library(geom STATIC LEGO1/lego/sources/geom/legomesh.cpp LEGO1/lego/sources/geom/legosphere.cpp LEGO1/lego/sources/geom/legovertex.cpp + LEGO1/lego/sources/geom/legoweedge.cpp + LEGO1/lego/sources/geom/legowegedge.cpp ) register_lego1_target(geom) set_property(TARGET geom PROPERTY ARCHIVE_OUTPUT_NAME "geom$<$:d>") @@ -366,6 +368,7 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/paths/legoanimactor.cpp LEGO1/lego/legoomni/src/paths/legoextraactor.cpp LEGO1/lego/legoomni/src/paths/legopathactor.cpp + LEGO1/lego/legoomni/src/paths/legopathboundary.cpp LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp LEGO1/lego/legoomni/src/paths/legopathpresenter.cpp LEGO1/lego/legoomni/src/pizzeria/pizzamissionstate.cpp diff --git a/LEGO1/define.cpp b/LEGO1/define.cpp index 82dafb7d..32577f04 100644 --- a/LEGO1/define.cpp +++ b/LEGO1/define.cpp @@ -4,6 +4,10 @@ // STRING: LEGO1 0x10102040 const char* g_strACTION = "ACTION"; +// GLOBAL: LEGO1 0x1010204c +// STRING: LEGO1 0x10102034 +const char* g_strANIMATION = "ANIMATION"; + // GLOBAL: LEGO1 0x1010209c // STRING: LEGO1 0x10101f58 const char* g_strOBJECT = "OBJECT"; diff --git a/LEGO1/define.h b/LEGO1/define.h index 84400d36..bb049a0e 100644 --- a/LEGO1/define.h +++ b/LEGO1/define.h @@ -7,6 +7,7 @@ extern const char* g_parseExtraTokens; extern const char* g_strWORLD; extern const char* g_strSOUND; extern const char* g_strOBJECT; +extern const char* g_strANIMATION; extern const char* g_strACTION; extern const char* g_strVISIBILITY; diff --git a/LEGO1/lego/legoomni/include/bumpbouy.h b/LEGO1/lego/legoomni/include/bumpbouy.h index 6f9dee2d..1609f5f9 100644 --- a/LEGO1/lego/legoomni/include/bumpbouy.h +++ b/LEGO1/lego/legoomni/include/bumpbouy.h @@ -14,7 +14,7 @@ class BumpBouy : public LegoAnimActor { BumpBouy(); MxLong Notify(MxParam& p_param) override; // vtable+0x04 - // FUNCTION: LEGO1 0x100274e0 + // FUNCTION: LEGO1 0x10027510 inline const char* ClassName() const override // vtable+0x0c { // STRING: LEGO1 0x100f0394 @@ -27,12 +27,7 @@ class BumpBouy : public LegoAnimActor { return !strcmp(p_name, BumpBouy::ClassName()) || LegoAnimActor::IsA(p_name); } - void ParseAction(char*) override; // vtable+0x20 - void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 - void VTable0x70(float p_float) override; // vtable+0x70 - void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 - - // SYNTHETIC: LEGO1 0x10027490 + // SYNTHETIC: LEGO1 0x100274a0 // BumpBouy::`scalar deleting destructor' }; diff --git a/LEGO1/lego/legoomni/include/islepathactor.h b/LEGO1/lego/legoomni/include/islepathactor.h index c8286903..d4f572fa 100644 --- a/LEGO1/lego/legoomni/include/islepathactor.h +++ b/LEGO1/lego/legoomni/include/islepathactor.h @@ -51,10 +51,10 @@ class IslePathActor : public LegoPathActor { // FUNCTION: LEGO1 0x10002e00 virtual MxU32 VTable0xdc(MxType19NotificationParam&) { return 0; } // vtable+0xdc - virtual void VTable0xe0(); // vtable+0xe0 - virtual void VTable0xe4(); // vtable+0xe4 - virtual void VTable0xe8(LegoGameState::Area, MxBool, MxU8); // vtable+0xe8 - virtual void VTable0xec(MxMatrix, MxU32, MxBool); // vtable+0xec + virtual void VTable0xe0(); // vtable+0xe0 + virtual void VTable0xe4(); // vtable+0xe4 + virtual void VTable0xe8(LegoGameState::Area, MxBool, MxU8); // vtable+0xe8 + virtual void VTable0xec(MxMatrix, LegoPathBoundary*, MxBool); // vtable+0xec // SYNTHETIC: LEGO1 0x10002ff0 // IslePathActor::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoanimactor.h b/LEGO1/lego/legoomni/include/legoanimactor.h index 42763b84..eb96d632 100644 --- a/LEGO1/lego/legoomni/include/legoanimactor.h +++ b/LEGO1/lego/legoomni/include/legoanimactor.h @@ -1,42 +1,82 @@ #ifndef LEGOANIMACTOR_H #define LEGOANIMACTOR_H +#include "anim/legoanim.h" #include "decomp.h" #include "legopathactor.h" -/* - VTABLE: LEGO1 0x100d5440 LegoPathActor - VTABLE: LEGO1 0x100d5510 LegoAnimActor -*/ +// SIZE 0x20 +struct LegoAnimActorStruct { + LegoAnimActorStruct(float p_unk0x00, LegoAnim* p_AnimTreePtr, LegoROI** p_roiMap, MxU32 p_numROIs); + ~LegoAnimActorStruct(); + + float GetDuration(); + + float m_unk0x00; // 0x00 + LegoAnim* m_AnimTreePtr; // 0x04 + LegoROI** m_roiMap; // 0x08 + MxU32 m_numROIs; // 0x0c + vector m_unk0x10; // 0x10 +}; + +// VTABLE: LEGO1 0x100d5440 LegoPathActor +// VTABLE: LEGO1 0x100d5510 LegoAnimActor // SIZE 0x174 class LegoAnimActor : public virtual LegoPathActor { public: - LegoAnimActor() { m_index = -1; } + LegoAnimActor() { m_curAnim = -1; } + ~LegoAnimActor() override; - // FUNCTION: LEGO1 0x1000fb90 + // FUNCTION: LEGO1 0x1000fba0 inline const char* ClassName() const override // vtable+0x0c { // STRING: LEGO1 0x100f057c return "LegoAnimActor"; } - // FUNCTION: LEGO1 0x1000fbb0 + // FUNCTION: LEGO1 0x1000fbc0 inline MxBool IsA(const char* p_name) const override // vtable+0x10 { return !strcmp(p_name, LegoAnimActor::ClassName()) || LegoPathActor::IsA(p_name); } - virtual MxResult FUN_1001c1f0(float& p_out); - virtual MxResult FUN_1001c360(float, undefined4); - virtual MxResult FUN_1001c450(undefined4, undefined4, undefined4, undefined4); - virtual void FUN_1001c800(); + void ParseAction(char* p_extra) override; // vtable+0x20 + void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 + void VTable0x70(float p_und) override; // vtable+0x70 + void VTable0x74(Matrix4& p_transform) override; // vtable+0x74 - // SYNTHETIC: LEGO1 0x1000fb50 + virtual MxResult FUN_1001c1f0(float& p_und); + virtual MxResult FUN_1001c360(float, Matrix4& p_transform); + virtual MxResult FUN_1001c450(LegoAnim* p_AnimTreePtr, float p_unk0x00, LegoROI** p_roiMap, MxU32 p_numROIs); + virtual void ClearMaps(); + + // SYNTHETIC: LEGO1 0x1000fb60 // LegoAnimActor::`scalar deleting destructor' private: - vector m_unk0x08; // 0x08 - MxU16 m_index; // 0x18 + vector m_animMaps; // 0x08 + MxS16 m_curAnim; // 0x18 }; +// TEMPLATE: LEGO1 0x1000da60 +// Vector::~Vector + +// TEMPLATE: LEGO1 0x1001c010 +// vector >::~vector > + +// TEMPLATE: LEGO1 0x1001c050 +// Vector::~Vector + +// TEMPLATE: LEGO1 0x1001c7c0 +// vector >::size + +// TEMPLATE: LEGO1 0x1001c7e0 +// vector >::_Destroy + +// TEMPLATE: LEGO1 0x1001c9e0 +// uninitialized_fill_n + +// TEMPLATE: LEGO1 0x1001ca10 +// uninitialized_copy + #endif // LEGOANIMACTOR_H diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index d57080c6..0c86a6b0 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -8,6 +8,7 @@ class LegoWorld; class LegoAnimClass; +class LegoAnimActor; // VTABLE: LEGO1 0x100d90c8 // SIZE 0xbc @@ -54,6 +55,8 @@ class LegoAnimPresenter : public MxVideoPresenter { virtual void VTable0xa0(); // vtable+0xa0 + void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value); + inline LegoAnim* GetAnimation() { return m_anim; } const char* GetActionObjectName(); diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 5c0fb670..adff5952 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -2,6 +2,7 @@ #define LEGOPATHACTOR_H #include "legoactor.h" +#include "legopathboundary.h" #include "mxtypes.h" #include "realtime/matrix.h" @@ -34,10 +35,10 @@ class LegoPathActor : public LegoActor { virtual void VTable0x74(Matrix4& p_transform); // vtable+0x74 // FUNCTION: LEGO1 0x10002d20 - virtual void VTable0x78(MxU8 p_unk0xea) { m_unk0xea = p_unk0xea; } // vtable+0x78 + virtual void SetUserNavFlag(MxBool p_userNavFlag) { m_userNavFlag = p_userNavFlag; } // vtable+0x78 // FUNCTION: LEGO1 0x10002d30 - virtual MxU8 VTable0x7c() { return m_unk0xea; } // vtable+0x7c + virtual MxU8 GetUserNavFlag() { return m_userNavFlag; } // vtable+0x7c virtual void VTable0x80(); // vtable+0x80 virtual void VTable0x84(); // vtable+0x84 @@ -83,10 +84,10 @@ class LegoPathActor : public LegoActor { // FUNCTION: LEGO1 0x10002de0 virtual void VTable0xc8(MxU8 p_unk0x148) { m_unk0x148 = p_unk0x148; } // vtable+0xc8 - inline MxU32 GetUnknown88() { return m_unk0x88; } + inline LegoPathBoundary* GetBoundary() { return m_boundary; } inline LegoPathController* GetController() { return m_controller; } - inline void SetUnknown88(MxU32 p_unk0x88) { m_unk0x88 = p_unk0x88; } + inline void SetBoundary(LegoPathBoundary* p_boundary) { m_boundary = p_boundary; } inline void SetUnknownDC(MxU32 p_unk0xdc) { m_unk0xdc = p_unk0xdc; } inline void ClearController() { m_controller = NULL; } @@ -94,18 +95,21 @@ class LegoPathActor : public LegoActor { // LegoPathActor::`scalar deleting destructor' protected: - undefined m_unk0x78[0xa]; // 0x78 - MxBool m_userNavFlag; // 0x82 - undefined4 m_unk0x84; // 0x84 - MxU32 m_unk0x88; // 0x88 - undefined4 m_boundary; // 0x8c - undefined m_unk0x8c[0x4c]; // 0x90 + MxFloat m_BADuration; // 0x78 + undefined4 m_unk0x7c; // 0x7c + MxFloat m_unk0x80; // 0x80 + MxFloat m_unk0x84; // 0x84 + LegoPathBoundary* m_boundary; // 0x88 + undefined m_unk0x8c[0x14]; // 0x8c + MxFloat m_unk0xa0; // 0xa0 + undefined m_unk0xa4[0x38]; // 0xa4 MxU32 m_unk0xdc; // 0xdc - undefined4 m_unk0xe0; // 0xe0 - undefined4 m_destEdge; // 0xe4 + undefined4 m_destEdge; // 0xe0 + undefined4 m_unk0xe4; // 0xe4 undefined2 m_unk0xe8; // 0xe8 - MxU8 m_unk0xea; // 0xea - undefined m_unk0xef[0x4d]; // 0xef + MxBool m_userNavFlag; // 0xea + MxMatrix m_unk0xec; // 0xec + undefined4 m_unk0x134; // 0x134 LegoPathController* m_controller; // 0x138 MxFloat m_unk0x13c; // 0x13c MxFloat m_unk0x140; // 0x140 diff --git a/LEGO1/lego/legoomni/include/legopathboundary.h b/LEGO1/lego/legoomni/include/legopathboundary.h index f2b1441a..11a97230 100644 --- a/LEGO1/lego/legoomni/include/legopathboundary.h +++ b/LEGO1/lego/legoomni/include/legopathboundary.h @@ -1,6 +1,26 @@ -#ifndef LEGOPATHBOUNDARH_H -#define LEGOPATHBOUNDARH_H +#ifndef LEGOPATHBOUNDARY_H +#define LEGOPATHBOUNDARY_H -class LegoPathBoundary {}; +#include "geom/legowegedge.h" +#include "mxstl/stlcompat.h" +#include "mxtypes.h" -#endif // LEGOPATHBOUNDARH_H +struct LegoPathBoundaryComparator { + MxBool operator()(const undefined*, const undefined*) const { return 0; } +}; + +// VTABLE: LEGO1 0x100d8618 +// SIZE 0x74 +class LegoPathBoundary : public LegoWEGEdge { +public: + LegoPathBoundary(); + + // STUB: LEGO1 0x10047a80 + // LegoPathBoundary::`scalar deleting destructor' + +private: + map m_unk0x54; // 0x54 + map m_unk0x64; // 0x64 +}; + +#endif // LEGOPATHBOUNDARY_H diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index ba8674e1..35bf5aa5 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -8,6 +8,10 @@ class LegoPathBoundary; class LegoWorld; +struct LegoPathControllerComparator { + MxBool operator()(const undefined*, const undefined*) const { return 0; } +}; + // VTABLE: LEGO1 0x100d7d60 // SIZE 0x40 class LegoPathController : public MxCore { @@ -42,17 +46,16 @@ class LegoPathController : public MxCore { void FUN_10046bb0(LegoWorld* p_world); private: - undefined4 m_unk0x08; // 0x08 - undefined4 m_unk0x0c; // 0x0c - undefined4 m_unk0x10; // 0x10 - undefined4 m_unk0x14; // 0x14 - undefined2 m_unk0x18; // 0x18 - undefined2 m_unk0x1a; // 0x1a - undefined2 m_unk0x1c; // 0x1c - undefined2 m_unk0x1e; // 0x1e - // These 2 are some sort of template class - undefined m_unk0x20[0x10]; // 0x20 - undefined m_unk0x30[0x10]; // 0x30 + LegoPathBoundary* m_unk0x08; // 0x08 + undefined4 m_unk0x0c; // 0x0c + undefined4 m_unk0x10; // 0x10 + undefined4 m_unk0x14; // 0x14 + MxS16 m_numL; // 0x18 + MxS16 m_numE; // 0x1a + MxS16 m_numN; // 0x1c + MxS16 m_numT; // 0x1e + map m_pfsE; // 0x20 + map m_unk0x30; // 0x30 }; #endif // LEGOPATHCONTROLLER_H diff --git a/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp b/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp index db86db35..9e556501 100644 --- a/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp +++ b/LEGO1/lego/legoomni/src/actors/bumpbouy.cpp @@ -2,36 +2,12 @@ DECOMP_SIZE_ASSERT(BumpBouy, 0x174) -// STUB: LEGO1 0x1000fd00 -void BumpBouy::ParseAction(char*) -{ - // TODO -} - -// STUB: LEGO1 0x1000fd10 -void BumpBouy::SetWorldSpeed(MxFloat p_worldSpeed) -{ - // TODO -} - -// STUB: LEGO1 0x1000fd20 -void BumpBouy::VTable0x70(float p_float) -{ - // TODO -} - -// STUB: LEGO1 0x1000fd30 -void BumpBouy::VTable0x74(Matrix4& p_transform) -{ - // TODO -} - // STUB: LEGO1 0x10027220 BumpBouy::BumpBouy() { } -// STUB: LEGO1 0x100274d0 +// STUB: LEGO1 0x10027400 MxLong BumpBouy::Notify(MxParam& p_param) { // TODO diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 1a85c4e6..2f8de444 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -311,7 +311,7 @@ MxU32 Helicopter::VTable0xd8(MxType18NotificationParam& p_param) // FUNCTION: LEGO1 0x10003e90 void Helicopter::VTable0x74(Matrix4& p_transform) { - if (m_unk0xea != 0) { + if (m_userNavFlag) { m_roi->FUN_100a46b0(p_transform); FUN_10010c30(); } diff --git a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp index af0baa4e..6b6d540d 100644 --- a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp @@ -72,7 +72,7 @@ void IslePathActor::VTable0xe8(LegoGameState::Area, MxBool, MxU8) } // STUB: LEGO1 0x1001b5b0 -void IslePathActor::VTable0xec(MxMatrix, MxU32, MxBool) +void IslePathActor::VTable0xec(MxMatrix, LegoPathBoundary*, MxBool) { // TODO } diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index b67763ee..09ebf305 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -181,7 +181,7 @@ void LegoGameState::SetActor(MxU8 p_actorId) if (oldActor) { newActor->GetROI()->FUN_100a58f0(oldActor->GetROI()->GetLocal2World()); - newActor->SetUnknown88(oldActor->GetUnknown88()); + newActor->SetBoundary(oldActor->GetBoundary()); delete oldActor; } diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index 66320dd1..71745847 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -1,27 +1,218 @@ #include "legoanimactor.h" +#include "define.h" +#include "legoanimpresenter.h" +#include "legoworld.h" +#include "misc.h" +#include "mxutilities.h" + DECOMP_SIZE_ASSERT(LegoAnimActor, 0x174) +DECOMP_SIZE_ASSERT(LegoAnimActorStruct, 0x20) -// STUB: LEGO1 0x1001c1f0 -MxResult LegoAnimActor::FUN_1001c1f0(float& p_out) +// FUNCTION: LEGO1 0x1001bf80 +LegoAnimActorStruct::LegoAnimActorStruct(float p_unk0x00, LegoAnim* p_AnimTreePtr, LegoROI** p_roiMap, MxU32 p_numROIs) { - // TODO + m_unk0x00 = p_unk0x00; + m_AnimTreePtr = p_AnimTreePtr; + m_roiMap = p_roiMap; + m_numROIs = p_numROIs; +} + +// FUNCTION: LEGO1 0x1001c0a0 +LegoAnimActorStruct::~LegoAnimActorStruct() +{ + for (MxU16 i = 0; i < m_unk0x10.size(); i++) { + delete m_unk0x10[i]; + } +} + +// FUNCTION: LEGO1 0x1001c130 +float LegoAnimActorStruct::GetDuration() +{ + return m_AnimTreePtr->GetDuration(); +} + +// FUNCTION: LEGO1 0x1001c140 +LegoAnimActor::~LegoAnimActor() +{ + for (MxS32 i = 0; i < m_animMaps.size(); i++) { + if (m_animMaps[i]) { + delete m_animMaps[i]; + } + } +} + +// FUNCTION: LEGO1 0x1001c1f0 +MxResult LegoAnimActor::FUN_1001c1f0(float& p_und) +{ + float duration = (float) m_animMaps[m_curAnim]->m_AnimTreePtr->GetDuration(); + p_und = m_unk0x80 - duration * ((MxS32) (m_unk0x80 / duration)); return SUCCESS; } -// STUB: LEGO1 0x1001c360 -MxResult LegoAnimActor::FUN_1001c360(float, undefined4) +// FUNCTION: LEGO1 0x1001c240 +void LegoAnimActor::VTable0x74(Matrix4& p_transform) { - return FAILURE; + float und; + LegoPathActor::VTable0x74(p_transform); + + if (m_curAnim >= 0) { + FUN_1001c1f0(und); + FUN_1001c360(und, p_transform); + } } -// STUB: LEGO1 0x1001c450 -MxResult LegoAnimActor::FUN_1001c450(undefined4, undefined4, undefined4, undefined4) +// FUNCTION: LEGO1 0x1001c290 +void LegoAnimActor::VTable0x70(float p_float) { + if (m_unk0x84 == 0) { + m_unk0x84 = p_float - 1.0f; + } + + if (m_unk0xdc == 0 && !m_userNavFlag && m_worldSpeed <= 0) { + if (m_curAnim >= 0) { + MxMatrix matrix(m_unk0xec); + float f; + FUN_1001c1f0(f); + FUN_1001c360(f, matrix); + } + + m_unk0x84 = m_unk0x80 = p_float; + } + else { + LegoPathActor::VTable0x70(p_float); + } +} + +// FUNCTION: LEGO1 0x1001c360 +MxResult LegoAnimActor::FUN_1001c360(float p_und, Matrix4& p_transform) +{ + if (p_und >= 0) { + LegoROI** roiMap = m_animMaps[m_curAnim]->m_roiMap; + MxU32 numROIs = m_animMaps[m_curAnim]->m_numROIs; + + if (!m_boundary->GetFlag0x10()) { + MxU32 i; + m_roi->SetVisibility(FALSE); + + for (i = 0; i < numROIs; i++) { + LegoROI* roi = roiMap[i]; + + if (roi != NULL && m_roi != roi) { + roi->SetVisibility(FALSE); + } + } + } + else { + MxU32 i; + LegoTreeNode* root = m_animMaps[m_curAnim]->m_AnimTreePtr->GetRoot(); + m_roi->SetVisibility(TRUE); + + for (i = 0; i < numROIs; i++) { + LegoROI* roi = roiMap[i]; + + if (roi != NULL && m_roi != roi) { + roi->SetVisibility(TRUE); + } + } + + for (i = 0; i < root->GetNumChildren(); i++) { + LegoROI::FUN_100a8e80(root->GetChild(i), p_transform, p_und, roiMap); + } + + if (m_cameraFlag) { + FUN_10010c30(); + } + } + + return SUCCESS; + } + else { + return FAILURE; + } +} + +// FUNCTION: LEGO1 0x1001c450 +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); + + for (vector::iterator it = m_animMaps.begin(); it != m_animMaps.end(); it++) { + if (p_unk0x00 < (*it)->m_unk0x00) { + m_animMaps.insert(it, laas); + SetWorldSpeed(m_worldSpeed); + return SUCCESS; + } + } + + m_animMaps.push_back(laas); + SetWorldSpeed(m_worldSpeed); return SUCCESS; } -// STUB: LEGO1 0x1001c800 -void LegoAnimActor::FUN_1001c800() +// FUNCTION: LEGO1 0x1001c800 +void LegoAnimActor::ClearMaps() { + for (MxU32 i = 0; i < m_animMaps.size(); i++) { + delete m_animMaps[i]; + } + + m_animMaps.clear(); + m_curAnim = -1; +} + +// FUNCTION: LEGO1 0x1001c870 +void LegoAnimActor::SetWorldSpeed(MxFloat p_worldSpeed) +{ + if (p_worldSpeed < 0) { + m_worldSpeed = 0; + } + else { + m_worldSpeed = p_worldSpeed; + } + + if (m_animMaps.size() > 0) { + m_curAnim = 0; + + if (m_worldSpeed >= m_animMaps[m_animMaps.size() - 1]->m_unk0x00) { + m_curAnim = m_animMaps.size() - 1; + } + else { + for (MxU32 i = 0; i < m_animMaps.size(); i++) { + if (m_worldSpeed <= m_animMaps[i]->m_unk0x00) { + m_curAnim = i; + break; + } + } + } + } +} + +// FUNCTION: LEGO1 0x1001c920 +void LegoAnimActor::ParseAction(char* p_extra) +{ + LegoPathActor::ParseAction(p_extra); + + LegoWorld* world = CurrentWorld(); + char value[256]; + + if (world) { + if (KeyValueStringParse(value, g_strANIMATION, p_extra)) { + char* token = strtok(value, g_parseExtraTokens); + + while (token) { + LegoAnimPresenter* presenter = (LegoAnimPresenter*) world->Find("LegoAnimPresenter", token); + + if (presenter != NULL) { + token = strtok(NULL, g_parseExtraTokens); + + if (token) { + presenter->FUN_1006d680(this, atof(token)); + } + } + + token = strtok(NULL, g_parseExtraTokens); + } + } + } } diff --git a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp new file mode 100644 index 00000000..641ece72 --- /dev/null +++ b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp @@ -0,0 +1,10 @@ +#include "legopathboundary.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(LegoPathBoundary, 0x74) + +// STUB: LEGO1 0x10056a70 +LegoPathBoundary::LegoPathBoundary() +{ +} diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index d0e05e4c..a295df96 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -517,3 +517,9 @@ void LegoAnimPresenter::VTable0x98() { // TODO } + +// STUB: LEGO1 0x1006d680 +void LegoAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value) +{ + // TODO +} diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 9f6c8353..cf692fd9 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -796,8 +796,8 @@ void Isle::FUN_10032620() switch (GameState()->m_currentArea) { case LegoGameState::e_unk66: { MxMatrix mat(CurrentActor()->GetROI()->GetLocal2World()); - MxU32 unk0x88 = CurrentActor()->GetUnknown88(); - CurrentActor()->VTable0xec(mat, unk0x88, TRUE); + LegoPathBoundary* boundary = CurrentActor()->GetBoundary(); + CurrentActor()->VTable0xec(mat, boundary, TRUE); break; } case LegoGameState::e_unk4: diff --git a/LEGO1/lego/sources/geom/legoweedge.cpp b/LEGO1/lego/sources/geom/legoweedge.cpp new file mode 100644 index 00000000..ac2ee6b3 --- /dev/null +++ b/LEGO1/lego/sources/geom/legoweedge.cpp @@ -0,0 +1,55 @@ +#include "legoweedge.h" + +DECOMP_SIZE_ASSERT(Edge, 0x24) +DECOMP_SIZE_ASSERT(LegoWEEdge, 0x0c) + +// FUNCTION: LEGO1 0x1009a550 +LegoWEEdge::LegoWEEdge() +{ + m_edges = NULL; + m_numEdges = 0; +} + +// FUNCTION: LEGO1 0x1009a590 +LegoWEEdge::~LegoWEEdge() +{ + if (m_edges) { + delete m_edges; + } +} + +// FUNCTION: LEGO1 0x1009a5b0 +LegoResult LegoWEEdge::VTable0x04() +{ + for (LegoS32 i = 0; i < m_numEdges; i++) { + Edge* e1 = m_edges[i]; + Edge* e2 = (m_numEdges - i) == 1 ? m_edges[0] : m_edges[i + 1]; + + if (e2->m_pointA == e1->m_pointA) { + e1->m_faceA = this; + e2->m_faceB = this; + e1->m_ccwA = e2; + e2->m_cwB = e1; + } + else if (e2->m_pointB == e1->m_pointA) { + e1->m_faceA = this; + e2->m_faceA = this; + e1->m_ccwA = e2; + e2->m_cwA = e1; + } + else if (e1->m_pointB == e2->m_pointA) { + e1->m_faceB = this; + e2->m_faceB = this; + e1->m_ccwB = e2; + e2->m_cwB = e1; + } + else { + e1->m_faceB = this; + e2->m_faceA = this; + e1->m_ccwB = e2; + e2->m_cwA = e1; + } + } + + return SUCCESS; +} diff --git a/LEGO1/lego/sources/geom/legoweedge.h b/LEGO1/lego/sources/geom/legoweedge.h new file mode 100644 index 00000000..0dd672b9 --- /dev/null +++ b/LEGO1/lego/sources/geom/legoweedge.h @@ -0,0 +1,39 @@ +#ifndef __LEGOWEEDGE_H +#define __LEGOWEEDGE_H + +#include "decomp.h" +#include "misc/legotypes.h" + +class LegoWEEdge; + +// SIZE 0x24 +struct Edge { + undefined4 m_unk0x00; // 0x00 + LegoWEEdge* m_faceA; // 0x04 + LegoWEEdge* m_faceB; // 0x08 + Edge* m_ccwA; // 0x0c + Edge* m_cwA; // 0x10 + Edge* m_ccwB; // 0x14 + Edge* m_cwB; // 0x18 + undefined* m_pointA; // 0x1c + undefined* m_pointB; // 0x20 +}; + +// VTABLE: LEGO1 0x100db7c0 +// SIZE 0x0c +class LegoWEEdge { +public: + LegoWEEdge(); + virtual ~LegoWEEdge(); + + virtual LegoResult VTable0x04(); // vtable+0x04 + + // SYNTHETIC: LEGO1 0x1009a570 + // LegoWEEdge::`scalar deleting destructor' + +protected: + LegoU8 m_numEdges; // 0x04 + Edge** m_edges; // 0x08 +}; + +#endif // __LEGOWEEDGE_H diff --git a/LEGO1/lego/sources/geom/legowegedge.cpp b/LEGO1/lego/sources/geom/legowegedge.cpp new file mode 100644 index 00000000..36157313 --- /dev/null +++ b/LEGO1/lego/sources/geom/legowegedge.cpp @@ -0,0 +1,44 @@ +#include "legowegedge.h" + +DECOMP_SIZE_ASSERT(LegoWEGEdge, 0x54) + +// FUNCTION: LEGO1 0x1009a730 +LegoWEGEdge::LegoWEGEdge() +{ + m_unk0x0d = 0; + m_name = NULL; + m_unk0x14.Clear(); + m_edgeNormals = NULL; + m_unk0x0c = 0; + m_unk0x48 = 0; + m_unk0x4c = NULL; + m_unk0x50 = NULL; +} + +// FUNCTION: LEGO1 0x1009a800 +LegoWEGEdge::~LegoWEGEdge() +{ + if (m_edges) { + delete[] m_edges; + m_edges = NULL; + } + if (m_name) { + delete[] m_name; + } + if (m_edgeNormals) { + delete[] m_edgeNormals; + } + if (m_unk0x4c) { + delete m_unk0x4c; + } + if (m_unk0x50) { + delete m_unk0x50; + } +} + +// STUB: LEGO1 0x1009a8c0 +LegoResult LegoWEGEdge::VTable0x04() +{ + // TODO + return SUCCESS; +} diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h new file mode 100644 index 00000000..d4f931a6 --- /dev/null +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -0,0 +1,35 @@ +#ifndef __LEGOWEGEDGE_H +#define __LEGOWEGEDGE_H + +#include "decomp.h" +#include "legoweedge.h" +#include "mxgeometry/mxgeometry3d.h" + +// VTABLE: LEGO1 0x100db7f8 +// SIZE 0x54 +class LegoWEGEdge : public LegoWEEdge { +public: + LegoWEGEdge(); + ~LegoWEGEdge() override; + + LegoResult VTable0x04() override; // vtable+0x04 + + inline LegoU32 GetFlag0x10() { return m_unk0x0c & 0x10 ? FALSE : TRUE; } + + // SYNTHETIC: LEGO1 0x1009a7e0 + // LegoWEGEdge::`scalar deleting destructor' + +private: + LegoU8 m_unk0x0c; // 0x0c + LegoU8 m_unk0x0d; // 0x0d + LegoChar* m_name; // 0x10 + Mx4DPointFloat m_unk0x14; // 0x14 + Mx4DPointFloat* m_edgeNormals; // 0x2c + Mx3DPointFloat m_unk0x30; // 0x30 + LegoU32 m_unk0x44; // 0x44 + LegoU8 m_unk0x48; // 0x48 + undefined* m_unk0x4c; // 0x4c + undefined* m_unk0x50; // 0x50 +}; + +#endif // __LEGOWEGEDGE_H diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index 8f57866c..36e5551e 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -407,6 +407,12 @@ LegoResult LegoROI::FUN_100a8da0(LegoTreeNode* p_node, const Matrix4& p_matrix, return SUCCESS; } +// STUB: LEGO1 0x100a8e80 +void LegoROI::FUN_100a8e80(LegoTreeNode*, Matrix4&, LegoTime, LegoROI**) +{ + // TODO +} + // FUNCTION: LEGO1 0x100a90f0 LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time) { diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index 60c0e790..32ce1371 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -13,6 +13,7 @@ class LegoStorage; class LegoAnim; class LegoAnimNodeData; class LegoTreeNode; +struct LegoAnimActorEntry; // VTABLE: LEGO1 0x100dbe38 // SIZE 0x108 @@ -31,6 +32,7 @@ class LegoROI : public ViewROI { ); LegoROI* FUN_100a8ce0(const LegoChar* p_name, LegoROI* p_roi); LegoResult FUN_100a8da0(LegoTreeNode* p_node, const Matrix4& p_matrix, LegoTime p_time, LegoROI* p_roi); + static void FUN_100a8e80(LegoTreeNode*, Matrix4&, LegoTime, LegoROI**); LegoResult SetFrame(LegoAnim* p_anim, LegoTime p_time); LegoResult FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha); LegoResult FUN_100a9210(LegoTextureInfo* p_textureInfo); diff --git a/tools/ncc/skip.yml b/tools/ncc/skip.yml index b33cec77..0c9a6441 100644 --- a/tools/ncc/skip.yml +++ b/tools/ncc/skip.yml @@ -21,3 +21,6 @@ delta_pos: "Allow original naming from 1996" rot_mat: "Allow original naming from 1996" new_pos: "Allow original naming from 1996" new_dir: "Allow original naming from 1996" +p_AnimTreePtr: "Allow original naming from beta" +m_AnimTreePtr: "Allow original naming from beta" +m_BADuration: "Allow original naming from beta" \ No newline at end of file