From 1b46859cf6ea3cfc64812e1d8ead990645c319b2 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Wed, 21 Aug 2024 22:30:27 +0200 Subject: [PATCH] Implement `RaceSkel`, add BETA10 annotations (#1088) * Implement `RaceSkel`, add BETA10 annotations * fix formatting * Fix order * Address some review comments --------- Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/carrace.h | 9 +++- LEGO1/lego/legoomni/include/legoanimactor.h | 6 +++ LEGO1/lego/legoomni/include/legoextraactor.h | 1 + .../lego/legoomni/include/legoobjectfactory.h | 1 + LEGO1/lego/legoomni/include/raceskel.h | 19 ++++++-- .../legoomni/src/common/legoobjectfactory.cpp | 5 +++ LEGO1/lego/legoomni/src/entity/legoworld.cpp | 1 + .../lego/legoomni/src/paths/legoanimactor.cpp | 26 ++++++++--- LEGO1/lego/legoomni/src/race/carrace.cpp | 2 +- LEGO1/lego/legoomni/src/race/legoracers.cpp | 3 +- LEGO1/lego/legoomni/src/race/raceskel.cpp | 44 ++++++++++++++++++- LEGO1/lego/sources/roi/legoroi.h | 1 + LEGO1/mxgeometry/mxgeometry3d.h | 1 + LEGO1/omni/include/mxobjectfactory.h | 1 + LEGO1/omni/src/common/mxobjectfactory.cpp | 2 + 15 files changed, 104 insertions(+), 18 deletions(-) diff --git a/LEGO1/lego/legoomni/include/carrace.h b/LEGO1/lego/legoomni/include/carrace.h index 954c1326..38a6e77a 100644 --- a/LEGO1/lego/legoomni/include/carrace.h +++ b/LEGO1/lego/legoomni/include/carrace.h @@ -4,6 +4,8 @@ #include "decomp.h" #include "legorace.h" +class RaceSkel; + // VTABLE: LEGO1 0x100d4b70 // VTABLE: BETA10 0x101bd5f0 // SIZE 0x2c @@ -59,14 +61,17 @@ public: MxLong HandleType0Notification(MxNotificationParam&) override; // vtable+0x78 // FUNCTION: BETA10 0x100cd060 - undefined4 GetUnk0x150() { return m_unk0x150; } + RaceSkel* GetSkeleton() { return m_skeleton; } + + // FUNCTION: BETA10 0x100f16f0 + void SetSkeleton(RaceSkel* p_skeleton) { m_skeleton = p_skeleton; } // SYNTHETIC: LEGO1 0x10016c70 // CarRace::`scalar deleting destructor' private: undefined m_unk0x144[12]; // 0x144 - undefined4 m_unk0x150; // 0x150 + RaceSkel* m_skeleton; // 0x150 }; #endif // CARRACE_H diff --git a/LEGO1/lego/legoomni/include/legoanimactor.h b/LEGO1/lego/legoomni/include/legoanimactor.h index 72f6bc1c..f74e8c00 100644 --- a/LEGO1/lego/legoomni/include/legoanimactor.h +++ b/LEGO1/lego/legoomni/include/legoanimactor.h @@ -28,13 +28,18 @@ struct LegoAnimActorStruct { // VTABLE: LEGO1 0x100d5440 LegoPathActor // VTABLE: LEGO1 0x100d5510 LegoAnimActor +// VTABLE: BETA10 0x101b81d8 LegoPathActor +// VTABLE: BETA10 0x101b82c8 LegoAnimActor // SIZE 0x174 class LegoAnimActor : public virtual LegoPathActor { public: + // FUNCTION: BETA10 0x1000f6c0 LegoAnimActor() { m_curAnim = -1; } + ~LegoAnimActor() override; // FUNCTION: LEGO1 0x1000fba0 + // FUNCTION: BETA10 0x10012400 const char* ClassName() const override // vtable+0x0c { // STRING: LEGO1 0x100f057c @@ -42,6 +47,7 @@ public: } // FUNCTION: LEGO1 0x1000fbc0 + // FUNCTION: BETA10 0x10012440 MxBool IsA(const char* p_name) const override // vtable+0x10 { return !strcmp(p_name, LegoAnimActor::ClassName()) || LegoPathActor::IsA(p_name); diff --git a/LEGO1/lego/legoomni/include/legoextraactor.h b/LEGO1/lego/legoomni/include/legoextraactor.h index d933ff44..dfb880f8 100644 --- a/LEGO1/lego/legoomni/include/legoextraactor.h +++ b/LEGO1/lego/legoomni/include/legoextraactor.h @@ -6,6 +6,7 @@ // VTABLE: LEGO1 0x100d6c00 LegoAnimActor // VTABLE: LEGO1 0x100d6c10 LegoPathActor // VTABLE: LEGO1 0x100d6cdc LegoExtraActor +// VTABLE: BETA10 0x101bc2b8 LegoAnimActor // SIZE 0x1dc class LegoExtraActor : public virtual LegoAnimActor { public: diff --git a/LEGO1/lego/legoomni/include/legoobjectfactory.h b/LEGO1/lego/legoomni/include/legoobjectfactory.h index e77cb802..4cb450be 100644 --- a/LEGO1/lego/legoomni/include/legoobjectfactory.h +++ b/LEGO1/lego/legoomni/include/legoobjectfactory.h @@ -106,6 +106,7 @@ X(AnimState) // VTABLE: LEGO1 0x100d4768 +// VTABLE: BETA10 0x101bccd8 // SIZE 0x1c8 class LegoObjectFactory : public MxObjectFactory { public: diff --git a/LEGO1/lego/legoomni/include/raceskel.h b/LEGO1/lego/legoomni/include/raceskel.h index fca57dde..48830bea 100644 --- a/LEGO1/lego/legoomni/include/raceskel.h +++ b/LEGO1/lego/legoomni/include/raceskel.h @@ -3,19 +3,30 @@ #include "legoanimactor.h" -/* - VTABLE: LEGO1 0x100d7668 LegoPathActor - VTABLE: LEGO1 0x100d7738 LegoAnimActor -*/ +// VTABLE: LEGO1 0x100d93f8 LegoPathActor +// VTABLE: LEGO1 0x100d94c8 LegoAnimActor +// VTABLE: BETA10 0x101bf9d0 LegoPathActor +// VTABLE: BETA10 0x101bfac0 LegoAnimActor // SIZE 0x178 class RaceSkel : public LegoAnimActor { public: RaceSkel(); + ~RaceSkel() override; + + void ParseAction(char* p_extra) override; // vtable+0x20 + + MxResult FUN_1001c360(float p_und, Matrix4& p_transform) override; void GetCurrentAnimData(float* p_outCurAnimPosition, float* p_outCurAnimDuration); + // SYNTHETIC: LEGO1 0x10071cf0 + // RaceSkel::`scalar deleting destructor' + private: float m_animPosition; // 0x1c }; +// GLOBAL: LEGO1 0x100d93f0 +// RaceSkel::`vbtable' + #endif // RACESKEL_H diff --git a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp index 4eebe624..0c4a7314 100644 --- a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp +++ b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp @@ -184,6 +184,7 @@ LegoObjectFactory::LegoObjectFactory() } // FUNCTION: LEGO1 0x10009a90 +// FUNCTION: BETA10 0x100a1021 MxCore* LegoObjectFactory::Create(const char* p_name) { MxCore* object = NULL; @@ -491,6 +492,10 @@ MxCore* LegoObjectFactory::Create(const char* p_name) object = MxObjectFactory::Create(p_name); } + // clang-format off + assert(object!=NULL); + // clang-format on + return object; } diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index fd449d52..b8cdc37e 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -541,6 +541,7 @@ void LegoWorld::Remove(MxCore* p_object) } // FUNCTION: LEGO1 0x100213a0 +// FUNCTION: BETA10 0x100db027 MxCore* LegoWorld::Find(const char* p_class, const char* p_name) { if (!strcmp(p_class, "MxControlPresenter")) { diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index eaad8ba9..a8180af8 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -37,6 +37,7 @@ float LegoAnimActorStruct::GetDuration() } // FUNCTION: LEGO1 0x1001c140 +// FUNCTION: BETA10 0x1003dfe4 LegoAnimActor::~LegoAnimActor() { for (MxS32 i = 0; i < m_animMaps.size(); i++) { @@ -89,9 +90,12 @@ void LegoAnimActor::VTable0x70(float p_float) } // FUNCTION: LEGO1 0x1001c360 +// FUNCTION: BETA10 0x1003e2d3 MxResult LegoAnimActor::FUN_1001c360(float p_und, Matrix4& p_transform) { if (p_und >= 0) { + assert((m_curAnim >= 0) && (m_curAnim < m_animMaps.size())); + LegoROI** roiMap = m_animMaps[m_curAnim]->m_roiMap; MxU32 numROIs = m_animMaps[m_curAnim]->m_numROIs; @@ -108,7 +112,11 @@ MxResult LegoAnimActor::FUN_1001c360(float p_und, Matrix4& p_transform) } } else { - LegoTreeNode* root = m_animMaps[m_curAnim]->m_AnimTreePtr->GetRoot(); + // name verified by BETA10 0x1003e407 + LegoTreeNode* n = m_animMaps[m_curAnim]->m_AnimTreePtr->GetRoot(); + + assert(roiMap && n && m_roi && m_boundary); + m_roi->SetVisibility(TRUE); for (MxU32 i = 0; i < numROIs; i++) { @@ -119,8 +127,8 @@ MxResult LegoAnimActor::FUN_1001c360(float p_und, Matrix4& p_transform) } } - for (MxS32 j = 0; j < root->GetNumChildren(); j++) { - LegoROI::FUN_100a8e80(root->GetChild(j), p_transform, p_und, roiMap); + for (MxS32 j = 0; j < n->GetNumChildren(); j++) { + LegoROI::FUN_100a8e80(n->GetChild(j), p_transform, p_und, roiMap); } if (m_cameraFlag) { @@ -192,6 +200,7 @@ void LegoAnimActor::SetWorldSpeed(MxFloat p_worldSpeed) } // FUNCTION: LEGO1 0x1001c920 +// FUNCTION: BETA10 0x1003e914 void LegoAnimActor::ParseAction(char* p_extra) { LegoPathActor::ParseAction(p_extra); @@ -201,17 +210,20 @@ void LegoAnimActor::ParseAction(char* p_extra) if (world) { if (KeyValueStringParse(value, g_strANIMATION, p_extra)) { + // name verified by BETA10 0x1003ea46 char* token = strtok(value, g_parseExtraTokens); while (token) { - LegoLocomotionAnimPresenter* presenter = - (LegoLocomotionAnimPresenter*) world->Find("LegoAnimPresenter", token); + // name verified by BETA10 0x1003e9f5 + LegoLocomotionAnimPresenter* p = (LegoLocomotionAnimPresenter*) world->Find("LegoAnimPresenter", token); - if (presenter != NULL) { + assert(p); + + if (p != NULL) { token = strtok(NULL, g_parseExtraTokens); if (token) { - presenter->FUN_1006d680(this, atof(token)); + p->FUN_1006d680(this, atof(token)); } } diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index 5552df4d..6ffb2ebd 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -7,7 +7,7 @@ DECOMP_SIZE_ASSERT(CarRace, 0x154) // FUNCTION: LEGO1 0x10016a90 CarRace::CarRace() { - this->m_unk0x150 = 0; + this->m_skeleton = NULL; this->m_unk0x130 = MxRect32(0x16c, 0x154, 0x1ec, 0x15e); } diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index d9f15050..7a60d59c 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -304,11 +304,10 @@ MxU32 LegoRaceCar::HandleSkeletonKicks(float p_param1) { const SkeletonKickPhase* current = g_skeletonKickPhases; - // TODO: Type is guesswork so far CarRace* r = (CarRace*) CurrentWorld(); // called `r` in BETA10 assert(r); - RaceSkel* s = (RaceSkel*) r->GetUnk0x150(); // called `s` in BETA10 + RaceSkel* s = r->GetSkeleton(); // called `s` in BETA10 assert(s); float skeletonCurAnimPosition; diff --git a/LEGO1/lego/legoomni/src/race/raceskel.cpp b/LEGO1/lego/legoomni/src/race/raceskel.cpp index 2d5c71bf..213e788d 100644 --- a/LEGO1/lego/legoomni/src/race/raceskel.cpp +++ b/LEGO1/lego/legoomni/src/race/raceskel.cpp @@ -1,13 +1,53 @@ #include "raceskel.h" +#include "carrace.h" +#include "legoworld.h" +#include "misc.h" + #include DECOMP_SIZE_ASSERT(RaceSkel, 0x178) -// STUB: LEGO1 0x100719b0 +// FUNCTION: LEGO1 0x100719b0 +// FUNCTION: BETA10 0x100f1240 RaceSkel::RaceSkel() { - // TODO + m_animPosition = 0.0f; +} + +// FUNCTION: LEGO1 0x10071ad0 +RaceSkel::~RaceSkel() +{ +} + +// FUNCTION: LEGO1 0x10071b50 +// FUNCTION: BETA10 0x100f13cf +MxResult RaceSkel::FUN_1001c360(float p_und, Matrix4& p_transform) +{ + p_transform[3][0] = -630.0f; + p_transform[3][1] = -4.688f; + p_transform[3][2] = 323.0f; + + m_animPosition = p_und; + + return LegoAnimActor::FUN_1001c360(p_und, p_transform); +} + +// FUNCTION: LEGO1 0x10071b90 +// FUNCTION: BETA10 0x100f1444 +void RaceSkel::ParseAction(char* p_extra) +{ + LegoAnimActor::ParseAction(p_extra); + + // name verified by BETA10 0x100f147d + CarRace* w = (CarRace*) CurrentWorld(); + assert(w); + w->SetSkeleton(this); + + assert(m_roi); + BoundingSphere sphere = m_roi->GetBoundingSphere(); + sphere.Radius() *= 100.0f; + m_roi->SetBoundingSphere(sphere); } // FUNCTION: LEGO1 0x10071cb0 diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index d570ac56..fb96b2a5 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -64,6 +64,7 @@ public: const LegoChar* GetName() const { return m_name; } LegoEntity* GetEntity() { return m_entity; } + BoundingSphere& GetBoundingSphere() { return m_sphere; } void SetEntity(LegoEntity* p_entity) { m_entity = p_entity; } void SetComp(CompoundObject* p_comp) { comp = p_comp; } diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index f675a350..0e2e00b3 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -21,6 +21,7 @@ public: // FUNCTION: BETA10 0x10011600 Mx3DPointFloat(const Mx3DPointFloat& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); } + // FUNCTION: BETA10 0x100151e0 Mx3DPointFloat(const Vector3& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); } // SYNTHETIC: LEGO1 0x1001d170 diff --git a/LEGO1/omni/include/mxobjectfactory.h b/LEGO1/omni/include/mxobjectfactory.h index aad3f2b2..4abdf766 100644 --- a/LEGO1/omni/include/mxobjectfactory.h +++ b/LEGO1/omni/include/mxobjectfactory.h @@ -19,6 +19,7 @@ X(MxLoopingMIDIPresenter) // VTABLE: LEGO1 0x100dc220 +// VTABLE: BETA10 0x101c2280 class MxObjectFactory : public MxCore { public: MxObjectFactory(); diff --git a/LEGO1/omni/src/common/mxobjectfactory.cpp b/LEGO1/omni/src/common/mxobjectfactory.cpp index 3722bb0e..3e733dfe 100644 --- a/LEGO1/omni/src/common/mxobjectfactory.cpp +++ b/LEGO1/omni/src/common/mxobjectfactory.cpp @@ -25,6 +25,7 @@ MxObjectFactory::MxObjectFactory() } // FUNCTION: LEGO1 0x100b12c0 +// FUNCTION: BETA10 0x10143177 MxCore* MxObjectFactory::Create(const char* p_name) { MxCore* object = NULL; @@ -43,6 +44,7 @@ MxCore* MxObjectFactory::Create(const char* p_name) } // FUNCTION: LEGO1 0x100b1a30 +// FUNCTION: BETA10 0x10143814 void MxObjectFactory::Destroy(MxCore* p_object) { delete p_object;