Add CBSGenerate

Former-commit-id: 368fff5a2e
This commit is contained in:
Henrique Gemignani Passos Lima 2022-10-25 22:35:44 +03:00
parent d6b660c936
commit 0f990300fd
8 changed files with 157 additions and 15 deletions

View File

@ -3,8 +3,8 @@
.section .data
.balign 8
.global lbl_803E2040
lbl_803E2040:
.global __vt__11CBSGenerate
__vt__11CBSGenerate:
# ROM: 0x3DF040
.4byte 0
.4byte 0
@ -31,8 +31,8 @@ __dt__11CBSGenerateFv:
/* 801466C0 00143620 93 E1 00 0C */ stw r31, 0xc(r1)
/* 801466C4 00143624 7C 7F 1B 79 */ or. r31, r3, r3
/* 801466C8 00143628 41 82 00 30 */ beq lbl_801466F8
/* 801466CC 0014362C 3C 60 80 3E */ lis r3, lbl_803E2040@ha
/* 801466D0 00143630 38 03 20 40 */ addi r0, r3, lbl_803E2040@l
/* 801466CC 0014362C 3C 60 80 3E */ lis r3, __vt__11CBSGenerate@ha
/* 801466D0 00143630 38 03 20 40 */ addi r0, r3, __vt__11CBSGenerate@l
/* 801466D4 00143634 90 1F 00 00 */ stw r0, 0(r31)
/* 801466D8 00143638 41 82 00 10 */ beq lbl_801466E8
/* 801466DC 0014363C 3C 60 80 3E */ lis r3, __vt__10CBodyState@ha
@ -307,10 +307,10 @@ lbl_80146A7C:
.global __ct__11CBSGenerateFv
__ct__11CBSGenerateFv:
/* 80146A90 001439F0 3C A0 80 3E */ lis r5, __vt__10CBodyState@ha
/* 80146A94 001439F4 3C 80 80 3E */ lis r4, lbl_803E2040@ha
/* 80146A94 001439F4 3C 80 80 3E */ lis r4, __vt__11CBSGenerate@ha
/* 80146A98 001439F8 38 A5 13 18 */ addi r5, r5, __vt__10CBodyState@l
/* 80146A9C 001439FC 90 A3 00 00 */ stw r5, 0(r3)
/* 80146AA0 00143A00 38 04 20 40 */ addi r0, r4, lbl_803E2040@l
/* 80146AA0 00143A00 38 04 20 40 */ addi r0, r4, __vt__11CBSGenerate@l
/* 80146AA4 00143A04 90 03 00 00 */ stw r0, 0(r3)
/* 80146AA8 00143A08 4E 80 00 20 */ blr

View File

@ -204,7 +204,7 @@ LIBS = [
["MetroidPrime/BodyState/CBSSlide", False],
"MetroidPrime/BodyState/CBSHurled",
"MetroidPrime/BodyState/CBSJump",
"MetroidPrime/BodyState/CBSGenerate",
["MetroidPrime/BodyState/CBSGenerate", False],
"MetroidPrime/Enemies/CPuddleSpore",
"MetroidPrime/BodyState/CBSTaunt",
"MetroidPrime/CSortedLists",

View File

@ -0,0 +1,19 @@
#ifndef _CBSGENERATE
#define _CBSGENERATE
#include "MetroidPrime/BodyState/CBodyState.hpp"
class CBSGenerate : public CBodyState {
public:
CBSGenerate();
~CBSGenerate();
void Start(CBodyController& bc, CStateManager& mgr) override;
pas::EAnimationState UpdateBody(float dt, CBodyController& bc, CStateManager& mgr) override;
void Shutdown(CBodyController&) override;
private:
pas::EAnimationState GetBodyStateTransition(float dt, CBodyController& bc);
};
#endif // _CBSGENERATE

View File

@ -23,6 +23,7 @@ public:
float GetAnimTimeRemaining() const;
void SetDeltaRotation(const CQuaternion& q);
void SetCurrentAnimation(const CAnimPlaybackParms& parms, bool loop, bool noTrans);
void FaceDirection(const CVector3f& v0, float dt);
bool IsAnimationOver() const { return x300_24_animationOver; }
pas::ELocomotionType GetLocomotionType() const { return x2ec_locomotionType; }

View File

@ -20,10 +20,45 @@ public:
float GetWeight() const { return x8_weight; }
};
class CBCSlideCmd : public CBodyStateCmd {
class CBCGenerateCmd : public CBodyStateCmd {
pas::EGenerateType x8_type;
CVector3f xc_targetPos;
int x18_animId;
bool x1c_24_targetTransform : 1;
bool x1c_25_overrideAnim : 1;
public:
explicit CBCSlideCmd() : CBodyStateCmd(kBSC_Slide), x8_type(pas::kSlide_Invalid), xc_dir(CVector3f::Zero()) {}
explicit CBCGenerateCmd() : CBodyStateCmd(kBSC_Generate), xc_targetPos(0.f, 0.f, 0.f) {}
explicit CBCGenerateCmd(pas::EGenerateType type)
: CBodyStateCmd(kBSC_Generate), x8_type(type), xc_targetPos(0.f, 0.f, 0.f) {}
explicit CBCGenerateCmd(pas::EGenerateType type, int animId)
: CBodyStateCmd(kBSC_Generate)
, x8_type(type)
, xc_targetPos(0.f, 0.f, 0.f)
, x18_animId(animId)
, x1c_25_overrideAnim(animId != -1) {}
explicit CBCGenerateCmd(pas::EGenerateType type, const CVector3f& vec,
bool targetTransform = false, bool overrideAnim = false)
: CBodyStateCmd(kBSC_Generate)
, x8_type(type)
, xc_targetPos(vec)
, x1c_24_targetTransform(targetTransform)
, x1c_25_overrideAnim(overrideAnim) {}
pas::EGenerateType GetGenerateType() const { return x8_type; }
const CVector3f& GetExitTargetPos() const { return xc_targetPos; }
bool HasExitTargetPos() const { return x1c_24_targetTransform; }
int GetSpecialAnimId() const { return x18_animId; }
bool UseSpecialAnimId() const { return x1c_25_overrideAnim; }
};
class CBCSlideCmd : public CBodyStateCmd {
public:
explicit CBCSlideCmd()
: CBodyStateCmd(kBSC_Slide), x8_type(pas::kSlide_Invalid), xc_dir(CVector3f::Zero()) {}
explicit CBCSlideCmd(pas::ESlideType type, const CVector3f& dir)
: CBodyStateCmd(kBSC_Slide), x8_type(type), xc_dir(dir) {}
@ -40,9 +75,14 @@ private:
class CBodyStateCmdMgr {
public:
CBodyStateCmd* GetCmd(EBodyStateCmd cmd);
const CVector3f& GetTargetVector() const { return x18_target; }
private:
uchar x0_pad[0x2a0];
CVector3f x0_move;
CVector3f xc_face;
CVector3f x18_target;
CVector3f x24_additiveTarget;
uchar x30_pad[0x270];
};
#endif // _CBODYSTATECMDMGR

View File

@ -14,11 +14,11 @@ private:
float x8_blendWeight;
bool xc_animating;
int x10_;
CVector3f* x14_targetPos;
const CVector3f* x14_targetPos;
bool x18_useLocator;
CQuaternion* x1c_deltaOrient;
CTransform4f* x20_objectXf;
CVector3f* x24_objectScale;
const CQuaternion* x1c_deltaOrient;
const CTransform4f* x20_objectXf;
const CVector3f* x24_objectScale;
public:
CAnimPlaybackParms(int animA, int animB, float blendWeight, bool animating)
@ -32,6 +32,19 @@ public:
, x1c_deltaOrient(nullptr)
, x20_objectXf(nullptr)
, x24_objectScale(nullptr) {}
CAnimPlaybackParms(int anim, const CQuaternion* deltaOrient, const CVector3f* targetPos,
const CTransform4f* xf, const CVector3f* scale, bool useLocator)
: x0_animA(anim)
, x4_animB(-1)
, x8_blendWeight(1.f)
, xc_animating(true)
, x10_(0)
, x14_targetPos(targetPos)
, x18_useLocator(useLocator)
, x1c_deltaOrient(deltaOrient)
, x20_objectXf(xf)
, x24_objectScale(scale) {}
};
CHECK_SIZEOF(CAnimPlaybackParms, 0x28)

View File

@ -92,7 +92,7 @@ public:
bool GetSortThermal() const { return x14_25_sortThermal; }
void SetSortThermal(bool b) { x14_25_sortThermal = b; }
const CVector3f& GetScale() const { return x0_scale; }
CVector3f GetScale() const { return x0_scale; }
void SetScale(const CVector3f& scale) { x0_scale = scale; }
bool GetIsLoop() const;

View File

@ -0,0 +1,69 @@
#include "MetroidPrime/BodyState/CBSGenerate.hpp"
#include "MetroidPrime/BodyState/CBodyController.hpp"
#include "MetroidPrime/CActor.hpp"
#include "MetroidPrime/CAnimPlaybackParms.hpp"
#include "MetroidPrime/CStateManager.hpp"
#include "Kyoto/Animation/CPASAnimParmData.hpp"
#include "Kyoto/Animation/CPASDatabase.hpp"
CBSGenerate::CBSGenerate() {}
void CBSGenerate::Start(CBodyController& bc, CStateManager& mgr) override {
const CBCGenerateCmd* cmd =
static_cast< const CBCGenerateCmd* >(bc.CommandMgr().GetCmd(kBSC_Generate));
int anim;
if (!cmd->UseSpecialAnimId()) {
const CPASDatabase& db = bc.GetPASDatabase();
const CPASAnimParmData parms(pas::kAS_Generate,
CPASAnimParm::FromEnum(s32(cmd->GetGenerateType())));
const rstl::pair< float, int > best = db.FindBestAnimation(parms, *mgr.Random(), -1);
anim = best.second;
} else {
anim = cmd->GetSpecialAnimId();
}
if (cmd->HasExitTargetPos()) {
CVector3f scale(bc.GetOwner().GetModelData()->GetScale());
const CAnimPlaybackParms playParms(anim, nullptr, &cmd->GetExitTargetPos(),
&bc.GetOwner().GetTransform(), &scale, false);
bc.SetCurrentAnimation(playParms, false, false);
} else {
const CAnimPlaybackParms playParms(anim, -1, 1.f, true);
bc.SetCurrentAnimation(playParms, false, false);
}
}
pas::EAnimationState CBSGenerate::UpdateBody(float dt, CBodyController& bc,
CStateManager& mgr) override {
const pas::EAnimationState st = GetBodyStateTransition(dt, bc);
if (st == pas::kAS_Invalid) {
if (bc.GetCommandMgr().GetTargetVector().IsNonZero()) {
bc.FaceDirection(bc.GetCommandMgr().GetTargetVector(), dt);
}
}
return st;
}
void CBSGenerate::Shutdown(CBodyController&) override {}
pas::EAnimationState CBSGenerate::GetBodyStateTransition(float dt, CBodyController& bc) {
CBodyStateCmdMgr& cmdMgr = bc.CommandMgr();
if (cmdMgr.GetCmd(kBSC_Hurled)) {
return pas::kAS_Hurled;
}
if (cmdMgr.GetCmd(kBSC_KnockDown)) {
return pas::kAS_Fall;
}
if (cmdMgr.GetCmd(kBSC_Generate)) {
return pas::kAS_Generate;
}
if (bc.IsAnimationOver() || cmdMgr.GetCmd(kBSC_NextState)) {
return pas::kAS_Locomotion;
}
return pas::kAS_Invalid;
}
CBSGenerate::~CBSGenerate() {}