Implement CScriptSpecialFunction::ThinkSpinnerController

This commit is contained in:
Henrique Gemignani Passos Lima 2022-10-03 14:55:03 +03:00
parent 7c6a4be3fc
commit d26a30f186
No known key found for this signature in database
GPG Key ID: E224F951761145F8
10 changed files with 65 additions and 42 deletions

View File

@ -1309,8 +1309,8 @@ GetAnimationManager__9CAnimDataFv:
/* 8002A500 00027460 90 04 00 04 */ stw r0, 4(r4) /* 8002A500 00027460 90 04 00 04 */ stw r0, 4(r4)
/* 8002A504 00027464 4E 80 00 20 */ blr /* 8002A504 00027464 4E 80 00 20 */ blr
.global sub_8002a508 .global SetPhase__9CAnimDataFf
sub_8002a508: SetPhase__9CAnimDataFf:
/* 8002A508 00027468 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8002A508 00027468 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 8002A50C 0002746C 7C 08 02 A6 */ mflr r0 /* 8002A50C 0002746C 7C 08 02 A6 */ mflr r0
/* 8002A510 00027470 90 01 00 14 */ stw r0, 0x14(r1) /* 8002A510 00027470 90 01 00 14 */ stw r0, 0x14(r1)
@ -9688,4 +9688,3 @@ lbl_803CCD20:
.asciz " has invalid initial animation, so defaulting to first.\n" .asciz " has invalid initial animation, so defaulting to first.\n"
.balign 4 .balign 4
.4byte 0 .4byte 0

View File

@ -1807,7 +1807,7 @@ lbl_801508E0:
/* 801508F8 0014D858 EF 40 00 72 */ fmuls f26, f0, f1 /* 801508F8 0014D858 EF 40 00 72 */ fmuls f26, f0, f1
/* 801508FC 0014D85C C0 22 9D 9C */ lfs f1, lbl_805ABABC@sda21(r2) /* 801508FC 0014D85C C0 22 9D 9C */ lfs f1, lbl_805ABABC@sda21(r2)
/* 80150900 0014D860 80 63 00 10 */ lwz r3, 0x10(r3) /* 80150900 0014D860 80 63 00 10 */ lwz r3, 0x10(r3)
/* 80150904 0014D864 4B ED 9C 05 */ bl sub_8002a508 /* 80150904 0014D864 4B ED 9C 05 */ bl SetPhase__9CAnimDataFf
/* 80150908 0014D868 80 7F 00 64 */ lwz r3, 0x64(r31) /* 80150908 0014D868 80 7F 00 64 */ lwz r3, 0x64(r31)
/* 8015090C 0014D86C C0 22 9D B4 */ lfs f1, lbl_805ABAD4@sda21(r2) /* 8015090C 0014D86C C0 22 9D B4 */ lfs f1, lbl_805ABAD4@sda21(r2)
/* 80150910 0014D870 80 63 00 10 */ lwz r3, 0x10(r3) /* 80150910 0014D870 80 63 00 10 */ lwz r3, 0x10(r3)

View File

@ -6,7 +6,12 @@
#include "Kyoto/Math/CVector2f.hpp" #include "Kyoto/Math/CVector2f.hpp"
#include "Kyoto/Math/CVector3f.hpp" #include "Kyoto/Math/CVector3f.hpp"
#include "math.h"
static bool close_enough(const CVector2f& a, const CVector2f& b, f32 epsilon = 0.001f); static bool close_enough(const CVector2f& a, const CVector2f& b, f32 epsilon = 0.001f);
static bool close_enough(const CVector3f& a, const CVector3f& b, f32 epsilon = 0.001f); static bool close_enough(const CVector3f& a, const CVector3f& b, f32 epsilon = 0.001f);
inline bool close_enough(float a, float b, f32 epsilon = 0.001f) {
return fabs(a - b) < epsilon;
}
#endif // __CLOSEENOUGH_HPP__ #endif // __CLOSEENOUGH_HPP__

View File

@ -91,20 +91,21 @@ public:
// Render__9CAnimDataCFRC13CSkinnedModelRC11CModelFlagsRCQ24rstl37optional_object<18CVertexMorphEffect>PCf // Render__9CAnimDataCFRC13CSkinnedModelRC11CModelFlagsRCQ24rstl37optional_object<18CVertexMorphEffect>PCf
// RenderAuxiliary__9CAnimDataCFRC14CFrustumPlanes // RenderAuxiliary__9CAnimDataCFRC14CFrustumPlanes
// RecalcPoseBuilder__9CAnimDataCFPC13CCharAnimTime // RecalcPoseBuilder__9CAnimDataCFPC13CCharAnimTime
// GetAnimationDuration__9CAnimDataCFi float GetAnimationDuration(int animIn) const;
// GetAnimTimeRemaining__9CAnimDataCFRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator> // GetAnimTimeRemaining__9CAnimDataCFRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>
// IsAnimTimeRemaining__9CAnimDataCFfRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator> // IsAnimTimeRemaining__9CAnimDataCFfRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>
// GetLocatorTransform__9CAnimDataCFRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>PC13CCharAnimTime // GetLocatorTransform__9CAnimDataCFRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator>PC13CCharAnimTime
// GetLocatorTransform__9CAnimDataCF6CSegIdPC13CCharAnimTime // GetLocatorTransform__9CAnimDataCF6CSegIdPC13CCharAnimTime
// CalcPlaybackAlignmentParms__9CAnimDataFRC18CAnimPlaybackParmsRCQ24rstl25ncrc_ptr<13CAnimTreeNode> // CalcPlaybackAlignmentParms__9CAnimDataFRC18CAnimPlaybackParmsRCQ24rstl25ncrc_ptr<13CAnimTreeNode>
// SetRandomPlaybackRate__9CAnimDataFR9CRandom16 // SetRandomPlaybackRate__9CAnimDataFR9CRandom16
// SetPlaybackRate__9CAnimDataFf void SetPlaybackRate(float set);
// MultiplyPlaybackRate__9CAnimDataFf // MultiplyPlaybackRate__9CAnimDataFf
// GetTimeOfUserEvent__9CAnimDataCF14EUserEventTypeRC13CCharAnimTime // GetTimeOfUserEvent__9CAnimDataCF14EUserEventTypeRC13CCharAnimTime
// GetAdvancementDeltas__9CAnimDataCFRC13CCharAnimTimeRC13CCharAnimTime // GetAdvancementDeltas__9CAnimDataCFRC13CCharAnimTimeRC13CCharAnimTime
// Touch__9CAnimDataCFRC13CSkinnedModeli // Touch__9CAnimDataCFRC13CSkinnedModeli
// InitializeEffects__9CAnimDataFR13CStateManagerRC9CVector3f // InitializeEffects__9CAnimDataFR13CStateManagerRC9CVector3f
// SetPhase__9CAnimDataFf -> SetPhase__11IAnimReaderFf // SetPhase__9CAnimDataFf -> SetPhase__11IAnimReaderFf
void SetPhase(float ph);
// AddAdditiveAnimation__9CAnimDataFUifbb // AddAdditiveAnimation__9CAnimDataFUifbb
// DelAdditiveAnimation__9CAnimDataFUi // DelAdditiveAnimation__9CAnimDataFUi
// IsAdditiveAnimationActive__9CAnimDataCFUi // IsAdditiveAnimationActive__9CAnimDataCFUi
@ -119,6 +120,7 @@ public:
// GetAnimationManager__9CAnimDataFv // GetAnimationManager__9CAnimDataFv
// SetPoseValid__9CAnimDataFb // SetPoseValid__9CAnimDataFb
u16 GetDefaultAnimation() const { return x208_defaultAnim; }
// GetCharacterInfo__9CAnimDataCFv // GetCharacterInfo__9CAnimDataCFv
// GetCharLayoutInfo__9CAnimDataCFv // GetCharLayoutInfo__9CAnimDataCFv
// GetDeltaRotation__9CAnimDataCFv // GetDeltaRotation__9CAnimDataCFv

View File

@ -5,16 +5,15 @@
#include "Kyoto/Math/CVector3f.hpp" #include "Kyoto/Math/CVector3f.hpp"
class CAxisAngle { class CAxisAngle : CVector3f {
public: public:
CAxisAngle(f32 x, f32 y, f32 z) : x(x), y(y), z(z) {} CAxisAngle(f32 x, f32 y, f32 z) : CVector3f(x, y, z) {}
CAxisAngle(const CAxisAngle& other) : x(other.x), y(other.y), z(other.z) {} CAxisAngle(const CAxisAngle& other) : CVector3f(other) {}
static const CAxisAngle& Identity(); static const CAxisAngle& Identity();
const CVector3f& GetVector() const;
private:
// maybe CUnitVector3f?
f32 x, y, z;
}; };
CHECK_SIZEOF(CAxisAngle, 0xc) CHECK_SIZEOF(CAxisAngle, 0xc)

View File

@ -40,6 +40,6 @@ private:
bool xb4_24_updatesEnabled : 1; bool xb4_24_updatesEnabled : 1;
bool xb4_25_anySystemsDrawnWithModel : 1; bool xb4_25_anySystemsDrawnWithModel : 1;
}; };
CHECK_SIZEOF(CParticleDatabase, 0xb5) CHECK_SIZEOF(CParticleDatabase, 0xb8)
#endif #endif

View File

@ -69,6 +69,7 @@ public:
void MoveCollisionPrimitive(const CVector3f&); void MoveCollisionPrimitive(const CVector3f&);
void SetVelocityWR(const CVector3f&); void SetVelocityWR(const CVector3f&);
void SetAngularVelocityWR(const CAxisAngle& angVel); void SetAngularVelocityWR(const CAxisAngle& angVel);
CAxisAngle GetAngularVelocityOR() const;
void ClearForcesAndTorques(); void ClearForcesAndTorques();
void Stop(); void Stop();

View File

@ -152,6 +152,7 @@ public:
CTransform4f CreateTransformFromMovementDirection() const; CTransform4f CreateTransformFromMovementDirection() const;
EPlayerOrbitState GetOrbitState() const { return x304_orbitState; } EPlayerOrbitState GetOrbitState() const { return x304_orbitState; }
const CVector3f& GetMovementDirection() const { return x50c_moveDir; } const CVector3f& GetMovementDirection() const { return x50c_moveDir; }
EPlayerMorphBallState GetMorphballTransitionState() const { return x2f8_morphBallState; }
void SetHudDisable(float staticTimer, float outSpeed, float inSpeed); void SetHudDisable(float staticTimer, float outSpeed, float inSpeed);
void IncrementPhazon(); void IncrementPhazon();
void DecrementPhazon(); void DecrementPhazon();

View File

@ -67,6 +67,8 @@ public:
TUniqueId GetWaypoint(CStateManager& mgr); TUniqueId GetWaypoint(CStateManager& mgr);
TUniqueId GetNext(TUniqueId uid, CStateManager& mgr); TUniqueId GetNext(TUniqueId uid, CStateManager& mgr);
void SetControlledAnimation(bool controlled) { x356_25_controlledAnimation = controlled; }
static void AddRider(rstl::vector< SRiders >& riders, TUniqueId riderId, static void AddRider(rstl::vector< SRiders >& riders, TUniqueId riderId,
const CPhysicsActor* ridee, CStateManager& mgr); const CPhysicsActor* ridee, CStateManager& mgr);
static TEntityList BuildNearListFromRiders(CStateManager& mgr, static TEntityList BuildNearListFromRiders(CStateManager& mgr,

View File

@ -1,6 +1,7 @@
#include "MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp" #include "MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp"
#include "MetroidPrime/CActorParameters.hpp" #include "MetroidPrime/CActorParameters.hpp"
#include "MetroidPrime/CAnimData.hpp"
#include "MetroidPrime/CEnvFxManager.hpp" #include "MetroidPrime/CEnvFxManager.hpp"
#include "MetroidPrime/CMain.hpp" #include "MetroidPrime/CMain.hpp"
#include "MetroidPrime/CStateManager.hpp" #include "MetroidPrime/CStateManager.hpp"
@ -9,8 +10,10 @@
#include "MetroidPrime/Player/CGameState.hpp" #include "MetroidPrime/Player/CGameState.hpp"
#include "MetroidPrime/Player/CPlayer.hpp" #include "MetroidPrime/Player/CPlayer.hpp"
#include "MetroidPrime/Player/CPlayerState.hpp" #include "MetroidPrime/Player/CPlayerState.hpp"
#include "MetroidPrime/ScriptObjects/CScriptPlatform.hpp"
#include "MetroidPrime/TCastTo.hpp" #include "MetroidPrime/TCastTo.hpp"
#include "Collision/CMaterialFilter.hpp" #include "Collision/CMaterialFilter.hpp"
#include "Kyoto/Audio/CSfxManager.hpp" #include "Kyoto/Audio/CSfxManager.hpp"
@ -19,9 +22,20 @@
#include "Kyoto/Math/CRelAngle.hpp" #include "Kyoto/Math/CRelAngle.hpp"
#include "Kyoto/Math/CUnitVector3f.hpp" #include "Kyoto/Math/CUnitVector3f.hpp"
#include "Kyoto/Math/CVector2i.hpp" #include "Kyoto/Math/CVector2i.hpp"
#include "Kyoto/Math/CloseEnough.hpp"
#include "Runtime/w_fmod.h"
#include "rstl/math.hpp" #include "rstl/math.hpp"
namespace rstl {
static int string_find(const string& haystack, const string& needle, int) {
// TODO: proper implementation
return 0;
}
}
CScriptSpecialFunction::CScriptSpecialFunction( CScriptSpecialFunction::CScriptSpecialFunction(
TUniqueId uid, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf, TUniqueId uid, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf,
ESpecialFunction func, const rstl::string& lcName, float f1, float f2, float f3, float f4, ESpecialFunction func, const rstl::string& lcName, float f1, float f2, float f3, float f4,
@ -710,8 +724,8 @@ void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager& mgr)
void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr, void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr,
ESpinnerControllerMode mode) { ESpinnerControllerMode mode) {
// rstl::string_find is found in CScriptSpecialFunction.s as sub_80150d98 // rstl::string_find is found in CScriptSpecialFunction.s as sub_80150d98
// const bool allowWrap = rstl::string_find(xec_locatorName, "AllowWrap") != std::string::npos; const bool allowWrap = rstl::string_find(xec_locatorName, rstl::string_l("AllowWrap"), 0) != -1;
// const bool noBackward = rstl::string_find(xec_locatorName, "NoBackward") != std::string::npos; const bool noBackward = rstl::string_find(xec_locatorName, rstl::string_l("NoBackward"), 0) != -1;
const float pointOneByDt = 0.1f * dt; const float pointOneByDt = 0.1f * dt;
const float twoByDt = 2.f * dt; const float twoByDt = 2.f * dt;
@ -721,11 +735,11 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
continue; continue;
} }
/* const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId);
const auto search = mgr.GetIdListForScript(conn->x8_objId); if (it.first != it.second) {
for (auto it = search.first; it != search.second; ++it) { TUniqueId uid = it.first->second;
if (const TCastToPtr<CScriptPlatform> plat = mgr.ObjectById((*it).second)) { if (CScriptPlatform* plat = TCastToPtr< CScriptPlatform >(mgr.ObjectById(uid))) {
if (plat->HasModelData() && plat->GetModelData()->HasAnimData()) { if (plat->HasModelData() && plat->GetModelData()->GetAnimationData()) {
plat->SetControlledAnimation(true); plat->SetControlledAnimation(true);
if (!x1e4_24_spinnerInitializedXf) { if (!x1e4_24_spinnerInitializedXf) {
x13c_spinnerInitialXf = plat->GetTransform(); x13c_spinnerInitialXf = plat->GetTransform();
@ -737,16 +751,17 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
if (mode == kSCM_Zero) { if (mode == kSCM_Zero) {
if (x1e4_25_spinnerCanMove) { if (x1e4_25_spinnerCanMove) {
const CPlayer& pl = mgr.GetPlayer(); const CPlayer& pl = *mgr.GetPlayer();
const CVector3f angVel = pl.GetAngularVelocityOR().getVector(); const CVector3f angVel = pl.GetAngularVelocityOR().GetVector();
float mag = 0.f; float mag = 0.f;
if (angVel.canBeNormalized()) { if (angVel.CanBeNormalized()) {
mag = angVel.magnitude(); mag = angVel.Magnitude();
} }
const float spinImpulse = const float spinImpulse =
(pl.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ? (pl.GetMorphballTransitionState() == CPlayer::kMS_Morphed ? 0.025f * mag : 0.f);
0.025f * mag : 0.f); if (spinImpulse >= x180_) { SendScriptMsgs(kSS_Play, mgr, kSM_None); if (spinImpulse >= x180_) {
SendScriptMsgs(kSS_Play, mgr, kSM_None);
} }
x180_ = spinImpulse; x180_ = spinImpulse;
@ -764,7 +779,7 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
if (!noBackward) { if (!noBackward) {
x138_ -= f29; x138_ -= f29;
if (std::fabs(x16c_) < dt) { if (CMath::AbsF(x16c_) < dt) {
x16c_ = 0.f; x16c_ = 0.f;
} else { } else {
x16c_ -= (dt * (x16c_ <= 0.f ? -1.f : 1.f)); x16c_ -= (dt * (x16c_ <= 0.f ? -1.f : 1.f));
@ -773,21 +788,21 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
} }
if (allowWrap) { if (allowWrap) {
x138_ = std::fmod(x138_, 1.f); x138_ = fmod(x138_, 1.f);
if (x138_ < 0.f) { if (x138_ < 0.f) {
x138_ += 1.f; x138_ += 1.f;
} }
} else { } else {
x138_ = zeus::clamp(0.f, x138_, 1.f); x138_ = CMath::Clamp(0.f, x138_, 1.f);
} }
bool r23 = true; bool r23 = true;
f28 = x138_ - f28; // always 0? f28 = x138_ - f28; // always 0?
if (zeus::close_enough(x138_, 1.f, FLT_EPSILON)) { if (close_enough(x138_, 1.f, FLT_EPSILON)) {
if (!x1e4_27_sfx3Played) { if (!x1e4_27_sfx3Played) {
if (x174_sfx3 != 0xFFFF) { if (x174_sfx3 != 0xFFFF) {
CSfxManager::AddEmitter(x174_sfx3, GetTranslation(), {}, true, false, 0x7F, CSfxManager::AddEmitter(x174_sfx3, GetTranslation(), CVector3f::Zero(), true, false,
kInvalidAreaId); 0x7F, kInvalidAreaId.value);
} }
x1e4_27_sfx3Played = true; x1e4_27_sfx3Played = true;
@ -799,11 +814,11 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
x1e4_27_sfx3Played = false; x1e4_27_sfx3Played = false;
} }
if (zeus::close_enough(x138_, 0.f, FLT_EPSILON)) { if (close_enough(x138_, 0.f, FLT_EPSILON)) {
if (!x1e4_26_sfx2Played) { if (!x1e4_26_sfx2Played) {
if (x172_sfx2 != 0xFFFF) { if (x172_sfx2 != 0xFFFF) {
CSfxManager::AddEmitter(x172_sfx2, GetTranslation(), {}, true, false, 0x7F, CSfxManager::AddEmitter(x172_sfx2, GetTranslation(), CVector3f::Zero(), true, false,
kInvalidAreaId); 0x7F, kInvalidAreaId.value);
} }
x1e4_26_sfx2Played = true; x1e4_26_sfx2Played = true;
@ -818,25 +833,24 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
if (r23) { if (r23) {
if (x170_sfx1 != 0xFFFF) { if (x170_sfx1 != 0xFFFF) {
x184_.AddValue(0.f <= f28 ? 100 : 0x7f); x184_.AddValue(0.f <= f28 ? 100 : 0x7f);
const std::optional<float> avg = x184_.GetAverage(); const rstl::optional_object< float > avg = x184_.GetAverage();
AddOrUpdateEmitter(0.f <= f28 ? x108_float4 : 1.f, x178_sfxHandle, x170_sfx1, AddOrUpdateEmitter(0.f <= f28 ? x108_float4 : 1.f, x178_sfxHandle, x170_sfx1,
GetTranslation(), avg.value()); GetTranslation(), avg.data());
} }
} else { } else {
DeleteEmitter(x178_sfxHandle); DeleteEmitter(x178_sfxHandle);
} }
CAnimData* animData = plat->GetModelData()->GetAnimationData(); CAnimData* animData = plat->ModelData()->AnimationData();
const float dur = animData->GetAnimationDuration(animData->GetDefaultAnimation()) * x138_; const float dur = animData->GetAnimationDuration(animData->GetDefaultAnimation()) * x138_;
animData->SetPhase(0.f); animData->SetPhase(0.f);
animData->SetPlaybackRate(1.f); animData->SetPlaybackRate(1.f);
const SAdvancementDeltas& deltas = plat->UpdateAnimation(dur, mgr, true); // Redundant copy is needed
plat->SetTransform(x13c_spinnerInitialXf * SAdvancementDeltas deltas = plat->UpdateAnimation(dur, mgr, true);
deltas.xc_rotDelta.toTransform(deltas.x0_posDelta)); plat->SetTransform(x13c_spinnerInitialXf * deltas.xc_rotDelta.BuildTransform4f(deltas.x0_posDelta));
} }
} }
} }
*/
} }
} }