From a7e2bdf73f53c80b4b4c90bf6e69a877a6b6ec0e Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Fri, 28 Oct 2022 15:33:10 +0300 Subject: [PATCH] Match and link CABSReaction --- asm/MetroidPrime/BodyState/CABSReaction.s | 12 +-- configure.py | 2 +- include/Kyoto/Animation/CPASDatabase.hpp | 4 +- .../MetroidPrime/BodyState/CABSReaction.hpp | 23 +++-- .../BodyState/CBodyController.hpp | 1 + .../BodyState/CBodyStateCmdMgr.hpp | 23 +++++ include/MetroidPrime/CAnimData.hpp | 4 +- obj_files.mk | 2 +- src/MetroidPrime/BodyState/CABSReaction.cpp | 91 +++++++++++++++++++ src/MetroidPrime/BodyState/CBSStep.cpp | 1 - 10 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 src/MetroidPrime/BodyState/CABSReaction.cpp diff --git a/asm/MetroidPrime/BodyState/CABSReaction.s b/asm/MetroidPrime/BodyState/CABSReaction.s index 41531eb5..7b8d6d77 100644 --- a/asm/MetroidPrime/BodyState/CABSReaction.s +++ b/asm/MetroidPrime/BodyState/CABSReaction.s @@ -2,8 +2,8 @@ .section .data .balign 8 -.global lbl_803E6758 -lbl_803E6758: +.global __vt__12CABSReaction +__vt__12CABSReaction: # ROM: 0x3E3758 .4byte 0 .4byte 0 @@ -24,8 +24,8 @@ __dt__12CABSReactionFv: /* 801F154C 001EE4AC 93 E1 00 0C */ stw r31, 0xc(r1) /* 801F1550 001EE4B0 7C 7F 1B 79 */ or. r31, r3, r3 /* 801F1554 001EE4B4 41 82 00 30 */ beq lbl_801F1584 -/* 801F1558 001EE4B8 3C 60 80 3E */ lis r3, lbl_803E6758@ha -/* 801F155C 001EE4BC 38 03 67 58 */ addi r0, r3, lbl_803E6758@l +/* 801F1558 001EE4B8 3C 60 80 3E */ lis r3, __vt__12CABSReaction@ha +/* 801F155C 001EE4BC 38 03 67 58 */ addi r0, r3, __vt__12CABSReaction@l /* 801F1560 001EE4C0 90 1F 00 00 */ stw r0, 0(r31) /* 801F1564 001EE4C4 41 82 00 10 */ beq lbl_801F1574 /* 801F1568 001EE4C8 3C 60 80 3E */ lis r3, __vt__18CAdditiveBodyState@ha @@ -377,11 +377,11 @@ lbl_801F1A14: .global __ct__12CABSReactionFv __ct__12CABSReactionFv: /* 801F1A30 001EE990 3C A0 80 3E */ lis r5, __vt__18CAdditiveBodyState@ha -/* 801F1A34 001EE994 3C 80 80 3E */ lis r4, lbl_803E6758@ha +/* 801F1A34 001EE994 3C 80 80 3E */ lis r4, __vt__12CABSReaction@ha /* 801F1A38 001EE998 38 05 13 50 */ addi r0, r5, __vt__18CAdditiveBodyState@l /* 801F1A3C 001EE99C C0 02 AE D8 */ lfs f0, lbl_805ACBF8@sda21(r2) /* 801F1A40 001EE9A0 90 03 00 00 */ stw r0, 0(r3) -/* 801F1A44 001EE9A4 38 A4 67 58 */ addi r5, r4, lbl_803E6758@l +/* 801F1A44 001EE9A4 38 A4 67 58 */ addi r5, r4, __vt__12CABSReaction@l /* 801F1A48 001EE9A8 38 80 FF FF */ li r4, -1 /* 801F1A4C 001EE9AC 38 00 00 00 */ li r0, 0 /* 801F1A50 001EE9B0 90 A3 00 00 */ stw r5, 0(r3) diff --git a/configure.py b/configure.py index 4cd506c1..4ad1b1bb 100755 --- a/configure.py +++ b/configure.py @@ -302,7 +302,7 @@ LIBS = [ "MetroidPrime/CMessageScreen", "MetroidPrime/Enemies/CFlaahgraTentacle", "MetroidPrime/Weapons/GunController/CGSFidget", - "MetroidPrime/BodyState/CABSReaction", + ["MetroidPrime/BodyState/CABSReaction", True], "MetroidPrime/Weapons/CIceProjectile", "MetroidPrime/Enemies/CFlyingPirate", "MetroidPrime/ScriptObjects/CScriptColorModulate", diff --git a/include/Kyoto/Animation/CPASDatabase.hpp b/include/Kyoto/Animation/CPASDatabase.hpp index 1547de98..a91f189b 100644 --- a/include/Kyoto/Animation/CPASDatabase.hpp +++ b/include/Kyoto/Animation/CPASDatabase.hpp @@ -16,9 +16,11 @@ class CPASDatabase { public: bool HasState(int id) const; const CPASAnimState* GetAnimState(int) const; + + rstl::pair< float, int > FindBestAnimation(const CPASAnimParmData& data, int ignoreAnim) const; rstl::pair< float, int > FindBestAnimation(const CPASAnimParmData&, CRandom16&, int) const; - size_t GetNumAnimStates() const; // { return x0_states.size(); } + size_t GetNumAnimStates() const; // { return x0_states.size(); } const CPASAnimState* GetAnimStateByIndex(int index) const; /* { if (index >= x0_states.size()) { return nullptr; diff --git a/include/MetroidPrime/BodyState/CABSReaction.hpp b/include/MetroidPrime/BodyState/CABSReaction.hpp index c0b8e0c3..877a938e 100644 --- a/include/MetroidPrime/BodyState/CABSReaction.hpp +++ b/include/MetroidPrime/BodyState/CABSReaction.hpp @@ -4,18 +4,25 @@ #include "MetroidPrime/BodyState/CAdditiveBodyState.hpp" class CABSReaction : public CAdditiveBodyState { - float x4_weight; - s32 x8_anim; - pas::EAdditiveReactionType xc_type; - bool x10_active; - pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc) const; - void StopAnimation(CBodyController& bc); - public: CABSReaction(); + ~CABSReaction(); + void Start(CBodyController& bc, CStateManager& mgr) override; pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override; - void Shutdown(CBodyController& bc) override { StopAnimation(bc); } + void Shutdown(CBodyController& bc) override; + + float GetWeight() const { return x4_weight; } + bool IsActive() const { return x10_active; } + +private: + float x4_weight; + int x8_anim; + pas::EAdditiveReactionType xc_type; + bool x10_active; + + pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc); + void StopAnimation(CBodyController& bc); }; #endif // _CABSREACTION diff --git a/include/MetroidPrime/BodyState/CBodyController.hpp b/include/MetroidPrime/BodyState/CBodyController.hpp index 407e84a5..0df754db 100644 --- a/include/MetroidPrime/BodyState/CBodyController.hpp +++ b/include/MetroidPrime/BodyState/CBodyController.hpp @@ -28,6 +28,7 @@ public: void FaceDirection(const CVector3f& v0, float dt); void EnableAnimation(bool enable); void PlayBestAnimation(const CPASAnimParmData& parms, CRandom16& r); + bool HasIceBreakoutState(); void SetFallState(pas::EFallState state); // { x2f0_fallState = state; } pas::EFallState GetFallState() const; // { return x2f0_fallState; } diff --git a/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp b/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp index 1993395a..b1e992f4 100644 --- a/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp +++ b/include/MetroidPrime/BodyState/CBodyStateCmdMgr.hpp @@ -128,6 +128,29 @@ private: // +class CBCAdditiveReactionCmd : public CBodyStateCmd { +public: + explicit CBCAdditiveReactionCmd() + : CBodyStateCmd(kBSC_AdditiveReaction) + , x8_weight(1.f) + , xc_type(pas::kART_Invalid) + , x10_active(false) {} + + explicit CBCAdditiveReactionCmd(pas::EAdditiveReactionType type, float weight, bool active) + : CBodyStateCmd(kBSC_AdditiveReaction), x8_weight(weight), xc_type(type), x10_active(active) {} + + pas::EAdditiveReactionType GetType() const { return xc_type; } + float GetWeight() const { return x8_weight; } + bool GetIsActive() const { return x10_active; } + +private: + float x8_weight; + pas::EAdditiveReactionType xc_type; + bool x10_active; +}; + +// + class CBCSlideCmd : public CBodyStateCmd { public: explicit CBCSlideCmd() diff --git a/include/MetroidPrime/CAnimData.hpp b/include/MetroidPrime/CAnimData.hpp index 7de42997..f613de0b 100644 --- a/include/MetroidPrime/CAnimData.hpp +++ b/include/MetroidPrime/CAnimData.hpp @@ -61,7 +61,6 @@ public: count = x218_passedSoundCount; return mSoundPOINodes.data(); } - CParticleDatabase& GetParticleDB() { return x120_particleDB; } const CParticleDatabase& GetParticleDB() const { return x120_particleDB; } // SetIsAnimating__9CAnimDataFb @@ -108,12 +107,13 @@ public: // SetPhase__9CAnimDataFf -> SetPhase__11IAnimReaderFf void SetPhase(float ph); void AddAdditiveAnimation(uint idx, float weight, bool active, bool fadeOut); - // DelAdditiveAnimation__9CAnimDataFUi + void DelAdditiveAnimation(uint idx); // IsAdditiveAnimationActive__9CAnimDataCFUi const rstl::rc_ptr& GetAdditiveAnimationTree(uint idx) const; // GetAnimationTree__9CAnimDataCFv // AnimationTree__9CAnimDataFv // IsAdditiveAnimation__9CAnimDataCFUi + bool IsAdditiveAnimationAdded(uint idx) const; // UpdateAdditiveAnims__9CAnimDataFf // AdvanceAdditiveAnims__9CAnimDataFf // AddAdditiveSegData__9CAnimDataCFRC10CSegIdListR16CSegStatementSet diff --git a/obj_files.mk b/obj_files.mk index 7b2e1388..fae76cb7 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -267,7 +267,7 @@ METROIDPRIME :=\ $(BUILD_DIR)/asm/MetroidPrime/CMessageScreen.o\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CFlaahgraTentacle.o\ $(BUILD_DIR)/asm/MetroidPrime/Weapons/GunController/CGSFidget.o\ - $(BUILD_DIR)/asm/MetroidPrime/BodyState/CABSReaction.o\ + $(BUILD_DIR)/src/MetroidPrime/BodyState/CABSReaction.o\ $(BUILD_DIR)/asm/MetroidPrime/Weapons/CIceProjectile.o\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CFlyingPirate.o\ $(BUILD_DIR)/asm/MetroidPrime/ScriptObjects/CScriptColorModulate.o\ diff --git a/src/MetroidPrime/BodyState/CABSReaction.cpp b/src/MetroidPrime/BodyState/CABSReaction.cpp new file mode 100644 index 00000000..8a45b7dd --- /dev/null +++ b/src/MetroidPrime/BodyState/CABSReaction.cpp @@ -0,0 +1,91 @@ +#include "MetroidPrime/BodyState/CABSReaction.hpp" + +#include "MetroidPrime/BodyState/CBodyController.hpp" +#include "MetroidPrime/CActor.hpp" +#include "MetroidPrime/CAnimData.hpp" +#include "MetroidPrime/CModelData.hpp" +#include "MetroidPrime/CStateManager.hpp" + +#include "Kyoto/Animation/CAnimTreeNode.hpp" +#include "Kyoto/Animation/CPASAnimParmData.hpp" +#include "Kyoto/Math/CloseEnough.hpp" + + +CABSReaction::CABSReaction() +: x4_weight(1.f), x8_anim(-1), xc_type(pas::kART_Invalid), x10_active(false) {} + +void CABSReaction::Start(CBodyController& bc, CStateManager& mgr) { + const CBCAdditiveReactionCmd* cmd = + static_cast< const CBCAdditiveReactionCmd* >(bc.CommandMgr().GetCmd(kBSC_AdditiveReaction)); + x4_weight = cmd->GetWeight(); + xc_type = cmd->GetType(); + x10_active = cmd->GetIsActive(); + + CPASAnimParmData parms(pas::kAS_AdditiveReaction, CPASAnimParm::FromEnum(xc_type)); + rstl::pair< float, int > best = bc.GetPASDatabase().FindBestAnimation(parms, *mgr.Random(), -1); + x8_anim = best.second; + + if (x8_anim != -1) { + CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData(); + animData.AddAdditiveAnimation(x8_anim, GetWeight(), IsActive(), false); + } +} + +pas::EAnimationState CABSReaction::UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) { + pas::EAnimationState st = GetBodyStateTransition(dt, bc); + if (st == pas::kAS_Invalid) { + if (x8_anim == -1) + return pas::kAS_AdditiveIdle; + + CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData(); + if (x10_active) { + if (bc.CommandMgr().GetCmd(kBSC_StopReaction)) { + StopAnimation(bc); + st = pas::kAS_AdditiveIdle; + bc.GetOwner().RemoveEmitter(); + } + } else { + if (animData.IsAdditiveAnimationAdded(x8_anim)) { + CCharAnimTime rem = animData.GetAdditiveAnimationTree(x8_anim)->VGetTimeRemaining(); + if (close_enough(rem.GetSeconds(), 0.0f)) { + StopAnimation(bc); + st = pas::kAS_AdditiveIdle; + } + } else { + st = pas::kAS_AdditiveIdle; + } + } + } + return st; +} + +void CABSReaction::Shutdown(CBodyController& bc) override { StopAnimation(bc); } + +bool CBodyController::HasIceBreakoutState() { + // Inline function that ends here? + CPASAnimParmData parms(pas::kAS_AdditiveReaction, CPASAnimParm::FromEnum(pas::kART_IceBreakout)); + const CPASDatabase& db = GetPASDatabase(); + rstl::pair< float, int > best = db.FindBestAnimation(parms, -1); + return best.first > 0.f; +} + +pas::EAnimationState CABSReaction::GetBodyStateTransition(float dt, CBodyController& bc) { + CBodyStateCmdMgr& commandMgr = bc.CommandMgr(); + + const CBCAdditiveReactionCmd* cmd = + static_cast< const CBCAdditiveReactionCmd* >(bc.CommandMgr().GetCmd(kBSC_AdditiveReaction)); + if (cmd != nullptr && cmd->GetType() == pas::kART_IceBreakout) + return pas::kAS_AdditiveReaction; + + return pas::kAS_Invalid; +} + +void CABSReaction::StopAnimation(CBodyController& bc) { + if (x8_anim != -1) { + CAnimData& animData = *bc.GetOwner().ModelData()->AnimationData(); + animData.DelAdditiveAnimation(x8_anim); + x8_anim = -1; + } +} + +CABSReaction::~CABSReaction() {} diff --git a/src/MetroidPrime/BodyState/CBSStep.cpp b/src/MetroidPrime/BodyState/CBSStep.cpp index 5d5b2c6c..fcafef3d 100644 --- a/src/MetroidPrime/BodyState/CBSStep.cpp +++ b/src/MetroidPrime/BodyState/CBSStep.cpp @@ -3,7 +3,6 @@ #include "MetroidPrime/BodyState/CBodyController.hpp" #include "MetroidPrime/CStateManager.hpp" - #include "Kyoto/Animation/CPASAnimParmData.hpp" CBSStep::CBSStep() {}