From d75e5c07f711c2a2c7db72e52ba63959545ce6db Mon Sep 17 00:00:00 2001 From: Revo Date: Sun, 14 Jan 2024 23:21:44 -0500 Subject: [PATCH] update c_keyframe (#52) --- mm/include/functions.h | 6 - mm/include/macros.h | 2 + mm/include/z64keyframe.h | 199 +++- mm/src/code/c_keyframe.c | 1052 +++++++++-------- .../actors/ovl_Demo_Moonend/z_demo_moonend.c | 27 +- .../actors/ovl_Demo_Moonend/z_demo_moonend.h | 2 +- .../actors/ovl_Demo_Syoten/z_demo_syoten.c | 13 +- .../actors/ovl_Demo_Syoten/z_demo_syoten.h | 2 +- .../actors/ovl_Eff_Change/z_eff_change.c | 18 +- .../actors/ovl_Eff_Change/z_eff_change.h | 2 +- .../overlays/actors/ovl_En_Fall2/z_en_fall2.c | 13 +- .../overlays/actors/ovl_En_Fall2/z_en_fall2.h | 2 +- .../overlays/actors/ovl_En_Test/z_en_test.c | 19 +- .../overlays/actors/ovl_En_Test/z_en_test.h | 2 +- .../overlays/actors/ovl_En_Test7/z_en_test7.c | 18 +- .../overlays/actors/ovl_En_Test7/z_en_test7.h | 2 +- 16 files changed, 766 insertions(+), 613 deletions(-) diff --git a/mm/include/functions.h b/mm/include/functions.h index ce040f8f9..b77f4a7c8 100644 --- a/mm/include/functions.h +++ b/mm/include/functions.h @@ -1114,12 +1114,8 @@ void func_80183070(void); // void func_801832B0(void); // void func_8018332C(void); // void func_8018340C(void); -void func_80183430(SkeletonInfo* skeleton, Struct_801BFA14_Arg1* arg1, SkeletonInfo_1C* arg2, Vec3s* frameData, s16* arg4, UnkKeyframeCallback* callbacks); -void func_8018349C(SkeletonInfo* skeleton); -void func_801834A8(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1); // void func_80183510(void); // void func_80183580(void); -void func_801835EC(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1); // void func_80183658(void); // void func_801836CC(void); // void func_8018373C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9); @@ -1129,9 +1125,7 @@ void func_801835EC(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1); // void func_80183A3C(void); // void func_80183B08(void); // void func_80183B68(void); -s32 func_80183DE0(SkeletonInfo* skeleton); // void func_8018410C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); -void func_8018450C(PlayState* play, SkeletonInfo* skeleton, Mtx* mtx, OverrideKeyframeDrawScaled overrideKeyframeDraw, PostKeyframeDrawScaled postKeyframeDraw, void* arg); // void func_801845A4(void); // void func_801845C8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_80184638(void); diff --git a/mm/include/macros.h b/mm/include/macros.h index 001e301c7..5081f5f0c 100644 --- a/mm/include/macros.h +++ b/mm/include/macros.h @@ -72,6 +72,8 @@ (flag & 0x1) ? 0 : \ 0) +#define CB(x) ((x) * (x) * (x)) + /** * `x` vertex x * `y` vertex y diff --git a/mm/include/z64keyframe.h b/mm/include/z64keyframe.h index 30130d95b..eb0f7375a 100644 --- a/mm/include/z64keyframe.h +++ b/mm/include/z64keyframe.h @@ -6,91 +6,170 @@ struct PlayState; -#define KEYFRAME_OPA (0 << 0) -#define KEYFRAME_XLU (1 << 0) +struct KFSkelAnimeFlex; +struct KFSkelAnime; -struct SkeletonInfo; -struct SkeletonInfo2; +typedef s32 (*OverrideKeyframeDraw)(struct PlayState* play, struct KFSkelAnime* kfSkelAnime, s32 limbIndex, + Gfx** dList, u8* flags, void* arg, Vec3s* rot, Vec3f* pos); +typedef s32 (*PostKeyframeDraw)(struct PlayState* play, struct KFSkelAnime* kfSkelAnime, s32 limbIndex, + Gfx** dList, u8* flags, void* arg, Vec3s* rot, Vec3f* pos); -typedef s32 (*OverrideKeyframeDraw)(struct PlayState* play, struct SkeletonInfo2* skeleton, s32 limbIndex, Gfx** dList, - u8* flags, void* arg, Vec3s* rot, Vec3f* pos); -typedef void (*PostKeyframeDraw)(struct PlayState* play, struct SkeletonInfo2* skeleton, s32 limbIndex, Gfx** dList, - u8* flags, void* arg, Vec3s* rot, Vec3f* pos); +typedef s32 (*OverrideKeyframeDrawScaled)(struct PlayState* play, struct KFSkelAnimeFlex* kfSkelAnime, s32 limbIndex, + Gfx** dList, u8* flags, void* arg, Vec3f* scale, Vec3s* rot, Vec3f* pos); +typedef s32 (*PostKeyframeDrawScaled)(struct PlayState* play, struct KFSkelAnimeFlex* kfSkelAnime, s32 limbIndex, + Gfx** dList, u8* flags, void* arg, Vec3f* scale, Vec3s* rot, Vec3f* pos); -typedef s32 (*OverrideKeyframeDrawScaled)(struct PlayState* play, struct SkeletonInfo* skeleton, s32 limbIndex, Gfx** dList, - u8* flags, void* arg, Vec3f* scale, Vec3s* rot, Vec3f* pos); -typedef void (*PostKeyframeDrawScaled)(struct PlayState* play, struct SkeletonInfo* skeleton, s32 limbIndex, Gfx** dList, - u8* flags, void* arg, Vec3f* scale, Vec3s* rot, Vec3f* pos); +typedef s32 (*UnkKeyframeCallback)(struct PlayState* play, struct KFSkelAnimeFlex* kfSkelAnime, s32 limbIndex, + Gfx** dList, u8* flags, void* arg); -typedef s32 (*UnkKeyframeCallback)(struct PlayState* play, struct SkeletonInfo* skeletonInfo, s32* arg2, Gfx** dList, u8* arg4, void*); +#define KEYFRAME_DRAW_OPA (0 << 0) +#define KEYFRAME_DRAW_XLU (1 << 0) + +typedef enum { + KEYFRAME_NOT_DONE, + KEYFRAME_DONE_ONCE, + KEYFRAME_DONE_LOOP +} KeyFrameDoneType; + +#define KF_CALLBACK_INDEX_NONE 0xFF // Keyframe limb? typedef struct { /* 0x00 */ Gfx* dList; - /* 0x04 */ u8 unk_4; + /* 0x04 */ u8 numChildren; /* 0x05 */ u8 flags; - /* 0x06 */ Vec3s root; -} Struct_801BFA14_Arg1_Field4; // size = 0xC + /* 0x06 */ Vec3s translation; // FlexLimbs have translation data in their animations instead +} KeyFrameStandardLimb; // size = 0xC // Other limb type? typedef struct { /* 0x00 */ Gfx* dList; - /* 0x04 */ u8 unk_4; + /* 0x04 */ u8 numChildren; /* 0x05 */ u8 flags; - /* 0x06 */ u8 unk_6; // transform limb draw index -} Struct_801BFA14_Arg1_Field4_2; // size = 0x8 + /* 0x06 */ u8 callbackIndex; // transform callback index +} KeyFrameFlexLimb; // size = 0x8 typedef struct { /* 0x00 */ u8 limbCount; - /* 0x01 */ u8 unk_1; // non-zero in object files, number of non-null-dlist limbs? + /* 0x01 */ u8 dListCount; // non-zero in object files, number of non-null-dlist limbs? used to know how many matrices to alloc for drawing /* 0x04 */ union { - Struct_801BFA14_Arg1_Field4* unk_4; // arrays - Struct_801BFA14_Arg1_Field4_2* unk_4_2; + KeyFrameStandardLimb* limbsStandard; + KeyFrameFlexLimb* limbsFlex; }; - /* 0x08 */ s16* unk_8; - /* 0x0C */ s16* unk_C; - /* 0x0C */ char unk_10[0x2]; - /* 0x12 */ s16 unk_12; -} Struct_801BFA14_Arg1; +} KeyFrameSkeleton; // Size = 0x8 typedef struct { - /* 0x00 */ u16* unk_0; - /* 0x04 */ s16* unk_4; - /* 0x08 */ s16* unk_8; - /* 0x0C */ s16* unk_C; - /* 0x0C */ char unk_10[0x2]; - /* 0x12 */ s16 unk_12; -} SkeletonInfo_1C; + /* 0x00 */ s16 frame; + /* 0x02 */ s16 value; + /* 0x04 */ s16 velocity; +} KeyFrame; // Size = 0x6 typedef struct { - /* 0x00 */ f32 unk_0; - /* 0x04 */ f32 unk_4; - /* 0x08 */ f32 unk_8; - /* 0x0C */ f32 unk_C; - /* 0x10 */ f32 unk_10; - /* 0x14 */ s32 unk_14; -} FrameControl; + union { + /* 0x00 */ u8* bitFlags; // bitflags indicating whether to do keyframe interpolation or pull from preset values + /* 0x00 */ u16* bitFlagsFlex; // bitflags indicating whether to do keyframe interpolation or pull from preset values + }; + /* 0x04 */ KeyFrame* keyFrames; // keyframes array + /* 0x08 */ s16* kfNums; // number of keyframes for each limb + /* 0x0C */ s16* presetValues; // preset rotation (standard) or scale/rotation/translation (flex) values + /* 0x0C */ char unk_10[0x2]; + /* 0x12 */ s16 duration; +} KeyFrameAnimation; // Size = 0x14 -// FlexKeyframeSkeleton ? -typedef struct SkeletonInfo { - /* 0x00 */ FrameControl frameCtrl; - /* 0x18 */ Struct_801BFA14_Arg1* unk_18; // array - /* 0x1C */ SkeletonInfo_1C* unk_1C; - /* 0x20 */ UnkKeyframeCallback* unk_20; // pointer to array of functions - /* 0x24 */ f32 unk_24; // duration? current time? - /* 0x28 */ Vec3s* frameData; // array of 3 Vec3s - /* 0x2C */ s16* unk_2C; -} SkeletonInfo; +typedef enum { + /* 0 */ KEYFRAME_ANIM_ONCE, + /* 1 */ KEYFRAME_ANIM_LOOP +} FrameAnimMode; -// KeyframeSkeleton ? -typedef struct SkeletonInfo2 { +typedef struct { + /* 0x00 */ f32 start; + /* 0x04 */ f32 end; + /* 0x08 */ f32 duration; + /* 0x0C */ f32 speed; + /* 0x10 */ f32 curTime; + /* 0x14 */ s32 animMode; +} FrameControl; // Size = 0x18 + +// Original name: ckf_Skeleton_Info_SV ? +typedef struct KFSkelAnimeFlex { /* 0x00 */ FrameControl frameCtrl; - /* 0x18 */ Struct_801BFA14_Arg1* unk_18; // array - /* 0x1C */ SkeletonInfo_1C* unk_1C; - /* 0x20 */ f32 unk_20; // duration? current time? - /* 0x24 */ Vec3s* frameData; - /* 0x28 */ s16* unk_28; - /* 0x2C */ Vec3s* unk_2C; -} SkeletonInfo2; + /* 0x18 */ KeyFrameSkeleton* skeleton; + /* 0x1C */ KeyFrameAnimation* animation; + /* 0x20 */ UnkKeyframeCallback* callbacks; // pointer to array of functions, probably for transformlimbdraw purposes + /* 0x24 */ f32 morphFrames; + /* 0x28 */ Vec3s* jointTable; // Size 3 * limbCount + /* 0x2C */ Vec3s* morphTable; // Size 3 * limbCount +} KFSkelAnimeFlex; // Size = 0x30 + +// Original name: ckf_Skeleton_Info ? +typedef struct KFSkelAnime { + /* 0x00 */ FrameControl frameCtrl; + /* 0x18 */ KeyFrameSkeleton* skeleton; + /* 0x1C */ KeyFrameAnimation* animation; + /* 0x20 */ f32 morphFrames; + /* 0x24 */ Vec3s* jointTable; + /* 0x28 */ Vec3s* morphTable; + /* 0x2C */ Vec3s* rotOffsetsTable; +} KFSkelAnime; // Size = 0x30 + +void FrameCtrl_Reset(FrameControl* frameCtrl); +void FrameCtrl_Init(FrameControl* frameCtrl); +void FrameCtrl_SetProperties(FrameControl* frameCtrl, f32 startTime, f32 endTime, f32 duration, f32 t, f32 speed, + s32 animMode); +s32 FrameCtrl_PassCheck(FrameControl* frameCtrl, f32 t, f32* remainingTime); +s32 FrameCtrl_UpdateOnce(FrameControl* frameCtrl); +s32 FrameCtrl_UpdateLoop(FrameControl* frameCtrl); +s32 FrameCtrl_Update(FrameControl* frameCtrl); + +void Keyframe_ResetFlex(KFSkelAnimeFlex* kfSkelAnime); +void Keyframe_InitFlex(KFSkelAnimeFlex* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + Vec3s* jointTable, Vec3s* morphTable, UnkKeyframeCallback* callbacks); +void Keyframe_DestroyFlex(KFSkelAnimeFlex* kfSkelAnime); +void Keyframe_FlexPlayOnce(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation); +void Keyframe_FlexPlayOnceWithSpeed(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 speed); +void Keyframe_FlexPlayOnceWithMorph(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 morphFrames); +void Keyframe_FlexPlayLoop(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation); +void Keyframe_FlexPlayLoopWithSpeed(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 speed); +void Keyframe_FlexPlayLoopWithMorph(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 morphFrames); +void Keyframe_FlexChangeAnim(KFSkelAnimeFlex* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + f32 startTime, f32 endTime, f32 t, f32 speed, f32 morphFrames, s32 animMode); +void Keyframe_FlexChangeAnimQuick(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation); +f32 Keyframe_Interpolate(f32 t, f32 delta, f32 x0, f32 x1, f32 v0, f32 v1); +s16 Keyframe_KeyCalc(s16 kfStart, s16 kfNum, KeyFrame* keyFrames, f32 t); +void Keyframe_RotationInterpolate(f32 t, s16* out, s16 rot1, s16 rot2); +void Keyframe_MorphInterpolate(s16* jointData, s16* morphData, f32 t); +void Keyframe_UpdateFlexLimbs(KFSkelAnimeFlex* kfSkelAnime); +s32 Keyframe_UpdateFlex(KFSkelAnimeFlex* kfSkelAnime); +void Keyframe_DrawFlex(struct PlayState* play, KFSkelAnimeFlex* kfSkelAnime, Mtx* mtxStack, + OverrideKeyframeDrawScaled overrideKeyframeDraw, PostKeyframeDrawScaled postKeyframeDraw, + void* arg); + +void Keyframe_ResetStandard(KFSkelAnime* kfSkelAnime); +void Keyframe_InitStandard(KFSkelAnime* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + Vec3s* jointTable, Vec3s* morphTable); +void Keyframe_DestroyStandard(KFSkelAnime* kfSkelAnime); +void Keyframe_StandardPlayOnce(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable); +void Keyframe_StandardPlayOnceWithSpeed(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable, + f32 speed); +void Keyframe_StandardPlayOnceWithMorph(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable, + f32 morphFrames); +void Keyframe_StandardPlayLoop(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable); +void Keyframe_StandardPlayLoopWithSpeed(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable, + f32 speed); +void Keyframe_StandardPlayLoopWithMorph(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable, + f32 morphFrames); +void Keyframe_StandardChangeAnim(KFSkelAnime* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + f32 startTime, f32 endTime, f32 t, f32 speed, f32 morphFrames, s32 animMode, + Vec3s* rotOffsetsTable); +void Keyframe_StandardChangeAnimQuick(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation); +void Keyframe_UpdateStandardLimbs(KFSkelAnime* kfSkelAnime); +s32 Keyframe_UpdateStandard(KFSkelAnime* kfSkelAnime); +void Keyframe_DrawStandardLimb(struct PlayState* play, KFSkelAnime* kfSkelAnime, s32* limbIndex, + OverrideKeyframeDraw overrideKeyframeDraw, PostKeyframeDraw postKeyframeDraw, void* arg, + Mtx** mtxStack); +void Keyframe_DrawStandard(struct PlayState* play, KFSkelAnime* kfSkelAnime, Mtx* mtxStack, + OverrideKeyframeDraw overrideKeyframeDraw, PostKeyframeDraw postKeyframeDraw, void* arg); + +void Keyframe_FlexGetScales(KFSkelAnime* kfSkelAnime, s32 targetLimbIndex, s16* scalesOut); #endif diff --git a/mm/src/code/c_keyframe.c b/mm/src/code/c_keyframe.c index 23a63e0a4..f84a7d6e2 100644 --- a/mm/src/code/c_keyframe.c +++ b/mm/src/code/c_keyframe.c @@ -1,382 +1,427 @@ #include "global.h" -#include "fixed_point.h" + #define FMOD(x, mod) ((x) - ((s32)((x) * (1.0f / (mod))) * (f32)(mod))) // cKF_FrameControl_zeroClera -void func_801830A0(FrameControl* frameCtrl) { - frameCtrl->unk_8 = 0.0f; - frameCtrl->unk_10 = 0.0f; - frameCtrl->unk_C = 0.0f; - frameCtrl->unk_4 = 0.0f; - frameCtrl->unk_0 = 0.0f; - frameCtrl->unk_14 = false; +void FrameCtrl_Reset(FrameControl* frameCtrl) { + frameCtrl->duration = 0.0f; + frameCtrl->curTime = 0.0f; + frameCtrl->speed = 0.0f; + frameCtrl->end = 0.0f; + frameCtrl->start = 0.0f; + frameCtrl->animMode = KEYFRAME_ANIM_ONCE; } // cKF_FrameControl_ct -void func_801830C8(FrameControl* frameCtrl) { - func_801830A0(frameCtrl); +void FrameCtrl_Init(FrameControl* frameCtrl) { + FrameCtrl_Reset(frameCtrl); } // cKF_FrameControl_setFrame -void func_801830E8(FrameControl* frameCtrl, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, s32 arg6) { - frameCtrl->unk_0 = arg1; - frameCtrl->unk_4 = (arg2 < 1.0f) ? arg3 : arg2; - frameCtrl->unk_8 = arg3; - frameCtrl->unk_C = arg5; - frameCtrl->unk_10 = arg4; - frameCtrl->unk_14 = arg6; +void FrameCtrl_SetProperties(FrameControl* frameCtrl, f32 startTime, f32 endTime, f32 duration, f32 t, f32 speed, + s32 animMode) { + frameCtrl->start = startTime; + frameCtrl->end = (endTime < 1.0f) ? duration : endTime; + frameCtrl->duration = duration; + frameCtrl->speed = speed; + frameCtrl->curTime = t; + frameCtrl->animMode = animMode; } -s32 func_80183148(FrameControl* frameCtrl, f32 arg1, f32* out) { - f32 temp_f0; - f32 temp_f14; - f32 phi_f2; +// cKF_FrameControl_passCheck +s32 FrameCtrl_PassCheck(FrameControl* frameCtrl, f32 t, f32* remainingTime) { + f32 curTime; + f32 speed; - *out = 0.0f; - temp_f0 = frameCtrl->unk_10; + *remainingTime = 0.0f; + curTime = frameCtrl->curTime; - if (arg1 == temp_f0) { + if (t == curTime) { return false; } - phi_f2 = (frameCtrl->unk_0 < frameCtrl->unk_4) ? frameCtrl->unk_C : -frameCtrl->unk_C; - temp_f14 = phi_f2 * 1.5f; + speed = ((frameCtrl->start < frameCtrl->end) ? frameCtrl->speed : -frameCtrl->speed) * 1.5f; - if ((temp_f14 >= 0.0f && temp_f0 < arg1 && arg1 <= temp_f0 + temp_f14) || - (temp_f14 < 0.0f && arg1 < temp_f0 && temp_f0 + temp_f14 <= arg1)) { + if (((speed >= 0.0f) && (curTime < t) && (t <= curTime + speed)) || + ((speed < 0.0f) && (t < curTime) && (curTime + speed <= t))) { - *out = temp_f0 + temp_f14 - arg1; + *remainingTime = curTime + speed - t; return true; } return false; } -s32 func_80183224(FrameControl* frameCtrl) { - f32 sp1C; +// cKF_FrameControl_stop_proc +s32 FrameCtrl_UpdateOnce(FrameControl* frameCtrl) { + f32 remainingTime; - if (frameCtrl->unk_10 == frameCtrl->unk_4) { - return 1; + if (frameCtrl->curTime == frameCtrl->end) { + return KEYFRAME_DONE_ONCE; } - if (func_80183148(frameCtrl, frameCtrl->unk_4, &sp1C)) { - frameCtrl->unk_10 = frameCtrl->unk_4; - return 1; + if (FrameCtrl_PassCheck(frameCtrl, frameCtrl->end, &remainingTime)) { + frameCtrl->curTime = frameCtrl->end; + return KEYFRAME_DONE_ONCE; } - if (func_80183148(frameCtrl, frameCtrl->unk_0, &sp1C)) { - frameCtrl->unk_10 = frameCtrl->unk_4; - return 1; + if (FrameCtrl_PassCheck(frameCtrl, frameCtrl->start, &remainingTime)) { + frameCtrl->curTime = frameCtrl->end; + return KEYFRAME_DONE_ONCE; } - return 0; + return KEYFRAME_NOT_DONE; } -s32 func_801832B0(FrameControl* frameCtrl) { - f32 sp1C; +// cKF_FrameControl_repeat_proc +s32 FrameCtrl_UpdateLoop(FrameControl* frameCtrl) { + f32 remainingTime; - if (func_80183148(frameCtrl, frameCtrl->unk_4, &sp1C)) { - frameCtrl->unk_10 = frameCtrl->unk_0 + sp1C; - return 2; + if (FrameCtrl_PassCheck(frameCtrl, frameCtrl->end, &remainingTime)) { + frameCtrl->curTime = frameCtrl->start + remainingTime; + return KEYFRAME_DONE_LOOP; } - if (func_80183148(frameCtrl, frameCtrl->unk_0, &sp1C)) { - frameCtrl->unk_10 = frameCtrl->unk_4 + sp1C; - return 2; + if (FrameCtrl_PassCheck(frameCtrl, frameCtrl->start, &remainingTime)) { + frameCtrl->curTime = frameCtrl->end + remainingTime; + return KEYFRAME_DONE_LOOP; } - return 0; + return KEYFRAME_NOT_DONE; } -s32 func_8018332C(FrameControl* frameCtrl) { - s32 phi_v0; - f32 phi_f0; +// cKF_FrameControl_play +s32 FrameCtrl_Update(FrameControl* frameCtrl) { + s32 result; + f32 speed; - if (!frameCtrl->unk_14) { - phi_v0 = func_80183224(frameCtrl); + if (frameCtrl->animMode == KEYFRAME_ANIM_ONCE) { + result = FrameCtrl_UpdateOnce(frameCtrl); } else { - phi_v0 = func_801832B0(frameCtrl); + result = FrameCtrl_UpdateLoop(frameCtrl); } - if (phi_v0 == 0) { - phi_f0 = (frameCtrl->unk_0 < frameCtrl->unk_4) ? frameCtrl->unk_C : -frameCtrl->unk_C; - frameCtrl->unk_10 = frameCtrl->unk_10 + phi_f0 * 1.5f; + + if (result == KEYFRAME_NOT_DONE) { + speed = (frameCtrl->start < frameCtrl->end) ? frameCtrl->speed : -frameCtrl->speed; + frameCtrl->curTime = frameCtrl->curTime + speed * 1.5f; } - if (frameCtrl->unk_10 < 1.0f) { - frameCtrl->unk_10 = (frameCtrl->unk_10 - 1.0f) + frameCtrl->unk_8; - } else if (frameCtrl->unk_8 < frameCtrl->unk_10) { - frameCtrl->unk_10 = (frameCtrl->unk_10 - frameCtrl->unk_8) + 1.0f; + + if (frameCtrl->curTime < 1.0f) { + frameCtrl->curTime = (frameCtrl->curTime - 1.0f) + frameCtrl->duration; + } else if (frameCtrl->duration < frameCtrl->curTime) { + frameCtrl->curTime = (frameCtrl->curTime - frameCtrl->duration) + 1.0f; } - return phi_v0; + + return result; } // cKF_SkeletonInfo_R_zeroClear -void func_8018340C(SkeletonInfo* skeleton) { - skeleton->unk_18 = NULL; - skeleton->unk_1C = NULL; - skeleton->frameData = NULL; - skeleton->unk_20 = NULL; - skeleton->unk_2C = NULL; - skeleton->unk_24 = 0.0f; +void Keyframe_ResetFlex(KFSkelAnimeFlex* kfSkelAnime) { + kfSkelAnime->skeleton = NULL; + kfSkelAnime->animation = NULL; + kfSkelAnime->jointTable = NULL; + kfSkelAnime->callbacks = NULL; + kfSkelAnime->morphTable = NULL; + kfSkelAnime->morphFrames = 0.0f; } // cKF_SkeletonInfo_R_ct -void func_80183430(SkeletonInfo* skeleton, Struct_801BFA14_Arg1* arg1, SkeletonInfo_1C* arg2, Vec3s* frameData, - s16* arg4, UnkKeyframeCallback* callbacks) { - func_8018340C(skeleton); - func_801830C8(&skeleton->frameCtrl); - skeleton->unk_18 = (Struct_801BFA14_Arg1*)Lib_SegmentedToVirtual(arg1); - skeleton->unk_1C = (SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg2); - skeleton->frameData = frameData; - skeleton->unk_2C = arg4; - skeleton->unk_20 = callbacks; +void Keyframe_InitFlex(KFSkelAnimeFlex* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + Vec3s* jointTable, Vec3s* morphTable, UnkKeyframeCallback* callbacks) { + Keyframe_ResetFlex(kfSkelAnime); + FrameCtrl_Init(&kfSkelAnime->frameCtrl); + kfSkelAnime->skeleton = (KeyFrameSkeleton*)Lib_SegmentedToVirtual(skeleton); + kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation); + kfSkelAnime->jointTable = jointTable; + kfSkelAnime->morphTable = morphTable; + kfSkelAnime->callbacks = callbacks; } // cKF_SkeletonInfo_R_dt -void func_8018349C(SkeletonInfo* skeleton) { +void Keyframe_DestroyFlex(KFSkelAnimeFlex* kfSkelAnime) { } -void func_8018373C(SkeletonInfo* skeleton, Struct_801BFA14_Arg1* arg1, SkeletonInfo_1C* arg2, f32 arg3, f32 arg4, - f32 arg5, f32 arg6, f32 arg7, s32 arg8); +void Keyframe_FlexChangeAnim(KFSkelAnimeFlex* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + f32 startTime, f32 endTime, f32 t, f32 speed, f32 morphFrames, s32 animMode); -void func_801834A8(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1) { - func_8018373C(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, 1.0f, 0.0f, false); +void Keyframe_FlexPlayOnce(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation) { + Keyframe_FlexChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, 1.0f, 0.0f, + KEYFRAME_ANIM_ONCE); } -void func_80183510(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1, f32 arg2) { - func_8018373C(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, arg2, 0.0f, false); +void Keyframe_FlexPlayOnceWithSpeed(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 speed) { + Keyframe_FlexChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, speed, 0.0f, + KEYFRAME_ANIM_ONCE); } -void func_80183580(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1, f32 arg2) { - func_8018373C(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, 1.0f, arg2, false); +void Keyframe_FlexPlayOnceWithMorph(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 morphFrames) { + Keyframe_FlexChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, 1.0f, morphFrames, + KEYFRAME_ANIM_ONCE); } -void func_801835EC(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1) { - func_8018373C(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, 1.0f, 0.0f, true); +void Keyframe_FlexPlayLoop(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation) { + Keyframe_FlexChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, 1.0f, 0.0f, + KEYFRAME_ANIM_LOOP); } -void func_80183658(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1, f32 arg2) { - func_8018373C(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, arg2, 0.0f, true); +void Keyframe_FlexPlayLoopWithSpeed(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 speed) { + Keyframe_FlexChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, speed, 0.0f, + KEYFRAME_ANIM_LOOP); } -void func_801836CC(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1, f32 arg2) { - func_8018373C(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, 1.0f, arg2, true); +void Keyframe_FlexPlayLoopWithMorph(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 morphFrames) { + Keyframe_FlexChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, 1.0f, morphFrames, + KEYFRAME_ANIM_LOOP); } -void func_8018373C(SkeletonInfo* skeleton, Struct_801BFA14_Arg1* arg1, SkeletonInfo_1C* arg2, f32 arg3, f32 arg4, - f32 arg5, f32 arg6, f32 arg7, s32 arg8) { - skeleton->unk_24 = arg7; +void Keyframe_FlexChangeAnim(KFSkelAnimeFlex* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + f32 startTime, f32 endTime, f32 t, f32 speed, f32 morphFrames, s32 animMode) { + kfSkelAnime->morphFrames = morphFrames; - if (skeleton->unk_18 != arg1) { - skeleton->unk_18 = (Struct_801BFA14_Arg1*)Lib_SegmentedToVirtual(arg1); + if (kfSkelAnime->skeleton != skeleton) { + kfSkelAnime->skeleton = (KeyFrameSkeleton*)Lib_SegmentedToVirtual(skeleton); } - skeleton->unk_1C = (SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg2); + kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation); - func_801830E8(&skeleton->frameCtrl, arg3, arg4, skeleton->unk_1C->unk_12, arg5, arg6, arg8); + FrameCtrl_SetProperties(&kfSkelAnime->frameCtrl, startTime, endTime, kfSkelAnime->animation->duration, t, speed, + animMode); } -void func_801837CC(SkeletonInfo* skeleton, SkeletonInfo_1C* arg1) { - skeleton->unk_1C = (SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1); - skeleton->frameCtrl.unk_8 = skeleton->unk_1C->unk_12; +void Keyframe_FlexChangeAnimQuick(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation) { + kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation); + kfSkelAnime->frameCtrl.duration = kfSkelAnime->animation->duration; } -#define CB(x) ((x) * (x) * (x)) - // cKF_HermitCalc // hermite interpolation -f32 func_80183808(f32 t, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5) { +f32 Keyframe_Interpolate(f32 t, f32 delta, f32 x0, f32 x1, f32 v0, f32 v1) { f32 p = 3.0f * SQ(t) - 2.0f * CB(t); - return (1.0f - p) * arg2 + p * arg3 + ((CB(t) - 2.0f * SQ(t) + t) * arg4 + (CB(t) - SQ(t)) * arg5) * arg1; + return (1.0f - p) * x0 + p * x1 + ((CB(t) - 2.0f * SQ(t) + t) * v0 + (CB(t) - SQ(t)) * v1) * delta; } // cKF_KeyCalc -s16 func_80183880(s16 arg0, s16 arg1, Vec3s* arg2, f32 arg3) { - Vec3s* temp_a3 = &arg2[arg0]; - Vec3s* temp_v1 = &temp_a3[arg1]; - f32 temp_f2; - s16 phi_v0; - s16 phi_v1; +s16 Keyframe_KeyCalc(s16 kfStart, s16 kfNum, KeyFrame* keyFrames, f32 t) { + KeyFrame* keyFrames2 = &keyFrames[kfStart]; + f32 delta; + s16 kf2; + s16 kf1; - if (arg3 <= temp_a3->x) { - return temp_a3->y; + if (t <= keyFrames2->frame) { + return keyFrames2->value; } - if (temp_a3[arg1 - 1].x <= arg3) { - return temp_a3[arg1 - 1].y; + if (keyFrames2[kfNum - 1].frame <= t) { + return keyFrames2[kfNum - 1].value; } - for (phi_v0 = 1, phi_v1 = 0; true; phi_v0++, phi_v1++) { - if (arg3 < temp_a3[phi_v0].x) { - temp_f2 = temp_a3[phi_v0].x - temp_a3[phi_v1].x; + for (kf2 = 1, kf1 = 0; true; kf2++, kf1++) { + if (t < keyFrames2[kf2].frame) { + delta = keyFrames2[kf2].frame - keyFrames2[kf1].frame; - if (!IS_ZERO(temp_f2)) { - return nearbyint(func_80183808((arg3 - temp_a3[phi_v1].x) / temp_f2, temp_f2 * (1.0f / 30), - temp_a3[phi_v1].y, temp_a3[phi_v0].y, temp_a3[phi_v1].z, - temp_a3[phi_v0].z)); + if (!IS_ZERO(delta)) { + return nearbyint(Keyframe_Interpolate((t - keyFrames2[kf1].frame) / delta, delta * (1.0f / 30), + keyFrames2[kf1].value, keyFrames2[kf2].value, + keyFrames2[kf1].velocity, keyFrames2[kf2].velocity)); + } else { + return keyFrames2[kf1].value; } - return temp_a3[phi_v1].y; } } } -// cKF_SkeletonInfo_subRotInterpolation -void func_80183A3C(f32 t, s16* out, s16 rot1, s16 rot2) { +/** + * Morph interpolator for rotation + */ +void Keyframe_RotationInterpolate(f32 t, s16* out, s16 rot1, s16 rot2) { u16 urot1 = rot1; s32 pad; u16 urot2 = rot2; - f32 f1 = rot1; - f32 signedDiff = rot2 - f1; - f32 f2 = urot1; - f32 unsignedDiff = urot2 - f2; + f32 rot1f = rot1; + f32 signedDiff = rot2 - rot1f; + f32 urot1f = urot1; + f32 unsignedDiff = urot2 - urot1f; if (fabsf(signedDiff) < fabsf(unsignedDiff)) { - *out = f1 + signedDiff * t; + *out = rot1f + signedDiff * t; } else { - *out = f2 + unsignedDiff * t; + *out = urot1f + unsignedDiff * t; } } -// lerp -// cKF_SkeletonInfo_morphST -void func_80183B08(s16 arg0[3], s16 arg1[3], f32 t) { +/** + * Morph interpolator for translation and scale + */ +void Keyframe_MorphInterpolate(s16* jointData, s16* morphData, f32 t) { s32 i; for (i = 0; i < 3; i++) { - if (*arg0 != *arg1) { - f32 f1 = *arg0; - f32 f2 = *arg1; - *arg0 = f1 + (f2 - f1) * t; + if (*jointData != *morphData) { + f32 f1 = *jointData; + f32 f2 = *morphData; + *jointData = f1 + (f2 - f1) * t; } - arg0++; - arg1++; + jointData++; + morphData++; } } -void func_80183B68(SkeletonInfo* skeleton) { - Vec3s* frameData = skeleton->frameData; - Vec3s* phi_s1 = (Vec3s*)skeleton->unk_2C; - f32 t = 1.0f / fabsf(skeleton->unk_24); - s32 i; +void Keyframe_UpdateFlexLimbs(KFSkelAnimeFlex* kfSkelAnime) { + Vec3s* jointTable = kfSkelAnime->jointTable; + Vec3s* morphTable = kfSkelAnime->morphTable; + f32 t = 1.0f / fabsf(kfSkelAnime->morphFrames); + s32 limbIndex; - for (i = 0; i < skeleton->unk_18->limbCount; i++) { - Vec3s temp_a2; - Vec3s temp_a3; + for (limbIndex = 0; limbIndex < kfSkelAnime->skeleton->limbCount; limbIndex++) { + Vec3s frameRot; + Vec3s morphRot; - func_80183B08((s16*)frameData, (s16*)phi_s1, t); + // Interpolate scale + Keyframe_MorphInterpolate((s16*)jointTable, (s16*)morphTable, t); + jointTable++; + morphTable++; - frameData++; - phi_s1++; + // Read rotation + frameRot.x = jointTable->x; + frameRot.y = jointTable->y; + frameRot.z = jointTable->z; - temp_a2.x = frameData->x; - temp_a2.y = frameData->y; - temp_a2.z = frameData->z; + morphRot.x = morphTable->x; + morphRot.y = morphTable->y; + morphRot.z = morphTable->z; - temp_a3.x = phi_s1->x; - temp_a3.y = phi_s1->y; - temp_a3.z = phi_s1->z; + // Interpolate rotation + if (frameRot.x != morphRot.x || frameRot.y != morphRot.y || frameRot.z != morphRot.z) { + Vec3s frameRotInv; + f32 norm1; + f32 norm2; - if (temp_a2.x != temp_a3.x || temp_a2.y != temp_a3.y || temp_a2.z != temp_a3.z) { - Vec3s temp_a0; - f32 v1; - f32 v2; + frameRotInv.x = 0x7FFF + frameRot.x; + frameRotInv.y = 0x7FFF - frameRot.y; + frameRotInv.z = 0x7FFF + frameRot.z; - temp_a0.x = 0x7FFF + temp_a2.x; - temp_a0.y = 0x7FFF - temp_a2.y; - temp_a0.z = 0x7FFF + temp_a2.z; + // Compute L1 norms + norm1 = fabsf((f32)morphRot.x - frameRot.x) + fabsf((f32)morphRot.y - frameRot.y) + + fabsf((f32)morphRot.z - frameRot.z); + norm2 = fabsf((f32)morphRot.x - frameRotInv.x) + fabsf((f32)morphRot.y - frameRotInv.y) + + fabsf((f32)morphRot.z - frameRotInv.z); - v1 = fabsf((f32)temp_a3.x - temp_a2.x) + fabsf((f32)temp_a3.y - temp_a2.y) + - fabsf((f32)temp_a3.z - temp_a2.z); - v2 = fabsf((f32)temp_a3.x - temp_a0.x) + fabsf((f32)temp_a3.y - temp_a0.y) + - fabsf((f32)temp_a3.z - temp_a0.z); - - if (v1 < v2) { - func_80183A3C(t, &frameData->x, temp_a2.x, temp_a3.x); - func_80183A3C(t, &frameData->y, temp_a2.y, temp_a3.y); - func_80183A3C(t, &frameData->z, temp_a2.z, temp_a3.z); + if (norm1 < norm2) { + // frameRot is closer to morphRot than frameRotInv, interpolate between these two + Keyframe_RotationInterpolate(t, &jointTable->x, frameRot.x, morphRot.x); + Keyframe_RotationInterpolate(t, &jointTable->y, frameRot.y, morphRot.y); + Keyframe_RotationInterpolate(t, &jointTable->z, frameRot.z, morphRot.z); } else { - func_80183A3C(t, &frameData->x, temp_a0.x, temp_a3.x); - func_80183A3C(t, &frameData->y, temp_a0.y, temp_a3.y); - func_80183A3C(t, &frameData->z, temp_a0.z, temp_a3.z); + // frameRotInv is closer to morphRot than frameRot, interpolate between these two + Keyframe_RotationInterpolate(t, &jointTable->x, frameRotInv.x, morphRot.x); + Keyframe_RotationInterpolate(t, &jointTable->y, frameRotInv.y, morphRot.y); + Keyframe_RotationInterpolate(t, &jointTable->z, frameRotInv.z, morphRot.z); } } - phi_s1++; - frameData++; - func_80183B08((s16*)frameData, (s16*)phi_s1, t); - frameData++; - phi_s1++; + morphTable++; + jointTable++; + + // Interpolate translation + Keyframe_MorphInterpolate((s16*)jointTable, (s16*)morphTable, t); + jointTable++; + morphTable++; } } -s32 func_80183DE0(SkeletonInfo* skeleton) { - s32 sp9C; - s32 pad[7]; - s16* sp7C; - Vec3s* sp78; - s16* sp74; - s32 pad1[3]; - u16* phi_v1; - s32 phi_s1; - s16* phi_s2; - u32 phi_s3; - s32 phi_s4 = 0; - s32 phi_s5 = 0; - s32 phi_s6 = 0; - s32 phi_s7; +s32 Keyframe_UpdateFlex(KFSkelAnimeFlex* kfSkelAnime) { + s32 limbIndex; + s32 pad[2]; + u16* bitFlags; + s16* outputValues; + s32 kfn = 0; + s32 presetIndex = 0; + s32 kfStart = 0; + s16* presetValues; + KeyFrame* keyFrames; + s16* kfNums; + u32 bit; + s32 i; + s32 j; - if (skeleton->unk_24 != 0.0f) { - phi_s2 = skeleton->unk_2C; + if (kfSkelAnime->morphFrames != 0.0f) { + outputValues = (s16*)kfSkelAnime->morphTable; } else { - phi_s2 = (s16*)skeleton->frameData; + outputValues = (s16*)kfSkelAnime->jointTable; } - sp7C = (s16*)Lib_SegmentedToVirtual(skeleton->unk_1C->unk_C); - sp74 = (s16*)Lib_SegmentedToVirtual(skeleton->unk_1C->unk_8); - sp78 = (Vec3s*)Lib_SegmentedToVirtual(skeleton->unk_1C->unk_4); - phi_v1 = (u16*)Lib_SegmentedToVirtual(skeleton->unk_1C->unk_0); + // Array of preset values to pull from + presetValues = (s16*)Lib_SegmentedToVirtual(kfSkelAnime->animation->presetValues); - for (sp9C = 0; sp9C < skeleton->unk_18->limbCount; sp9C++, phi_v1++) { - for (phi_s3 = 256, phi_s7 = 0; phi_s7 < 3; phi_s7++) { - for (phi_s1 = 0; phi_s1 < 3; phi_s1++, phi_s2++) { - if (*phi_v1 & phi_s3) { - *phi_s2 = func_80183880(phi_s6, sp74[phi_s4], sp78, skeleton->frameCtrl.unk_10); - phi_s6 += sp74[phi_s4]; - phi_s4++; + // Array of number of keyframes belonging to each limb + kfNums = (s16*)Lib_SegmentedToVirtual(kfSkelAnime->animation->kfNums); + + // Array of keyframes, ordered by frame number + keyFrames = (KeyFrame*)Lib_SegmentedToVirtual(kfSkelAnime->animation->keyFrames); + + // Array of flags for each limb. + // Each limb takes up 16 bits, the 9 least significant bits are used to indicate whether to interpolate with + // keyframes (if the bit is set) otherwise to pull a preset value (if the bit is not set) + // [8] : Scale x + // [7] : Scale y + // [6] : Scale z + // [5] : Rotate x + // [4] : Rotate y + // [3] : Rotate z + // [2] : Translate x + // [1] : Translate y + // [0] : Translate z + bitFlags = (u16*)Lib_SegmentedToVirtual(kfSkelAnime->animation->bitFlagsFlex); + + // For each limb + for (limbIndex = 0; limbIndex < kfSkelAnime->skeleton->limbCount; limbIndex++) { + bit = 1 << (3 * 3 - 1); + + // 3 iter (scale, rotate, translate) + for (i = 0; i < 3; i++) { + // 3 iter (x, y, z ?) + for (j = 0; j < 3; j++, outputValues++) { + if (bitFlags[limbIndex] & bit) { + // If the bit is set, interpolate with keyframes + *outputValues = Keyframe_KeyCalc(kfStart, kfNums[kfn], keyFrames, kfSkelAnime->frameCtrl.curTime); + kfStart += kfNums[kfn]; + kfn++; } else { - *phi_s2 = sp7C[phi_s5]; - phi_s5++; + // If the bit is not set, pull from preset values + *outputValues = presetValues[presetIndex]; + presetIndex++; } - phi_s3 >>= 1; - if (phi_s7 == 1) { - *phi_s2 = FMOD(*phi_s2 * 0.1f, 360) * 182.04445f; + + bit >>= 1; + + if (i == 1) { + *outputValues = FMOD(*outputValues * 0.1f, 360) * 182.04445f; } } } } - if (IS_ZERO(skeleton->unk_24)) { - return func_8018332C(&skeleton->frameCtrl); - } else if (skeleton->unk_24 > 0.0f) { - func_80183B68(skeleton); - skeleton->unk_24 -= 1.0f; - if (skeleton->unk_24 <= 0.0f) { - skeleton->unk_24 = 0.0f; + if (IS_ZERO(kfSkelAnime->morphFrames)) { + return FrameCtrl_Update(&kfSkelAnime->frameCtrl); + } else if (kfSkelAnime->morphFrames > 0.0f) { + Keyframe_UpdateFlexLimbs(kfSkelAnime); + kfSkelAnime->morphFrames -= 1.0f; + if (kfSkelAnime->morphFrames <= 0.0f) { + kfSkelAnime->morphFrames = 0.0f; } - return 0; + return KEYFRAME_NOT_DONE; } else { - func_80183B68(skeleton); - skeleton->unk_24 += 1.0f; - if (skeleton->unk_24 >= 0.0f) { - skeleton->unk_24 = 0.0f; + Keyframe_UpdateFlexLimbs(kfSkelAnime); + kfSkelAnime->morphFrames += 1.0f; + if (kfSkelAnime->morphFrames >= 0.0f) { + kfSkelAnime->morphFrames = 0.0f; } - return func_8018332C(&skeleton->frameCtrl); + return FrameCtrl_Update(&kfSkelAnime->frameCtrl); } } -// cKF_Si3_draw_SV_R_child -void func_8018410C(PlayState* play, SkeletonInfo* skeleton, s32* limbIndex, - OverrideKeyframeDrawScaled overrideKeyframeDraw, PostKeyframeDrawScaled postKeyframeDraw, void* arg, - Mtx** mtx) { - Struct_801BFA14_Arg1_Field4_2* limb = - (Struct_801BFA14_Arg1_Field4_2*)Lib_SegmentedToVirtual(skeleton->unk_18->unk_4_2); +void Keyframe_DrawFlexLimb(PlayState* play, KFSkelAnimeFlex* kfSkelAnime, s32* limbIndex, + OverrideKeyframeDrawScaled overrideKeyframeDraw, PostKeyframeDrawScaled postKeyframeDraw, + void* arg, Mtx** mtxStack) { + KeyFrameFlexLimb* limb = (KeyFrameFlexLimb*)Lib_SegmentedToVirtual(kfSkelAnime->skeleton->limbsFlex); s32 i; Gfx* newDList; Gfx* limbDList; @@ -384,28 +429,28 @@ void func_8018410C(PlayState* play, SkeletonInfo* skeleton, s32* limbIndex, Vec3f scale; Vec3s rot; Vec3f pos; - Vec3s* frameData; + Vec3s* jointData; OPEN_DISPS(play->state.gfxCtx); limb += *limbIndex; - frameData = &skeleton->frameData[*limbIndex * 3]; + jointData = &kfSkelAnime->jointTable[*limbIndex * 3]; - scale.x = frameData->x * 0.01f; - scale.y = frameData->y * 0.01f; - scale.z = frameData->z * 0.01f; + scale.x = jointData->x * 0.01f; + scale.y = jointData->y * 0.01f; + scale.z = jointData->z * 0.01f; - frameData++; + jointData++; - rot.x = frameData->x; - rot.y = frameData->y; - rot.z = frameData->z; + rot.x = jointData->x; + rot.y = jointData->y; + rot.z = jointData->z; - frameData++; + jointData++; - pos.x = frameData->x; - pos.y = frameData->y; - pos.z = frameData->z; + pos.x = jointData->x; + pos.y = jointData->y; + pos.z = jointData->z; Matrix_Push(); @@ -414,9 +459,10 @@ void func_8018410C(PlayState* play, SkeletonInfo* skeleton, s32* limbIndex, if (overrideKeyframeDraw == NULL || (overrideKeyframeDraw != NULL && - overrideKeyframeDraw(play, skeleton, *limbIndex, &newDList, &flags, arg, &scale, &rot, &pos) != 0)) { - if ((skeleton->unk_20 == NULL) || (limb->unk_6 == 0xFF) || (skeleton->unk_20[limb->unk_6] == NULL) || - skeleton->unk_20[limb->unk_6](play, skeleton, *limbIndex, &newDList, &flags, arg) != 0) { + overrideKeyframeDraw(play, kfSkelAnime, *limbIndex, &newDList, &flags, arg, &scale, &rot, &pos) != 0)) { + if ((kfSkelAnime->callbacks == NULL) || (limb->callbackIndex == KF_CALLBACK_INDEX_NONE) || + (kfSkelAnime->callbacks[limb->callbackIndex] == NULL) || + kfSkelAnime->callbacks[limb->callbackIndex](play, kfSkelAnime, *limbIndex, &newDList, &flags, arg) != 0) { Matrix_TranslateRotateZYX(&pos, &rot); @@ -425,334 +471,360 @@ void func_8018410C(PlayState* play, SkeletonInfo* skeleton, s32* limbIndex, } if (newDList != NULL) { - Matrix_ToMtx(*mtx); + Matrix_ToMtx(*mtxStack); - if (flags & KEYFRAME_XLU) { - gSPMatrix(POLY_XLU_DISP++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + if (flags & KEYFRAME_DRAW_XLU) { + gSPMatrix(POLY_XLU_DISP++, *mtxStack, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, newDList); } else { - gSPMatrix(POLY_OPA_DISP++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_OPA_DISP++, *mtxStack, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, newDList); } - (*mtx)++; + (*mtxStack)++; } else if (limbDList != NULL) { - gSPMatrix(POLY_OPA_DISP++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - Matrix_ToMtx(*mtx); + gSPMatrix(POLY_OPA_DISP++, *mtxStack, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + Matrix_ToMtx(*mtxStack); - (*mtx)++; + (*mtxStack)++; } } } if (postKeyframeDraw != NULL) { - postKeyframeDraw(play, skeleton, *limbIndex, &newDList, &flags, arg, &scale, &rot, &pos); + postKeyframeDraw(play, kfSkelAnime, *limbIndex, &newDList, &flags, arg, &scale, &rot, &pos); } (*limbIndex)++; - for (i = 0; i < limb->unk_4; i++) { - func_8018410C(play, skeleton, limbIndex, overrideKeyframeDraw, postKeyframeDraw, arg, mtx); + for (i = 0; i < limb->numChildren; i++) { + Keyframe_DrawFlexLimb(play, kfSkelAnime, limbIndex, overrideKeyframeDraw, postKeyframeDraw, arg, mtxStack); } Matrix_Pop(); CLOSE_DISPS(play->state.gfxCtx); } -// cKF_Si3_draw_R_SV -void func_8018450C(PlayState* play, SkeletonInfo* skeleton, Mtx* mtx, OverrideKeyframeDrawScaled overrideKeyframeDraw, - PostKeyframeDrawScaled postKeyframeDraw, void* arg) { +void Keyframe_DrawFlex(PlayState* play, KFSkelAnimeFlex* kfSkelAnime, Mtx* mtxStack, + OverrideKeyframeDrawScaled overrideKeyframeDraw, PostKeyframeDrawScaled postKeyframeDraw, + void* arg) { s32 limbIndex; - if (mtx == NULL) { + if (mtxStack == NULL) { return; } OPEN_DISPS(play->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); - gSPSegment(POLY_XLU_DISP++, 0x0D, mtx); + gSPSegment(POLY_OPA_DISP++, 0x0D, mtxStack); + gSPSegment(POLY_XLU_DISP++, 0x0D, mtxStack); limbIndex = 0; - func_8018410C(play, skeleton, &limbIndex, overrideKeyframeDraw, postKeyframeDraw, arg, &mtx); + Keyframe_DrawFlexLimb(play, kfSkelAnime, &limbIndex, overrideKeyframeDraw, postKeyframeDraw, arg, &mtxStack); CLOSE_DISPS(play->state.gfxCtx); } -void func_801845A4(SkeletonInfo2* skeleton) { - skeleton->unk_18 = 0; - skeleton->unk_1C = 0; - skeleton->frameData = NULL; - skeleton->unk_28 = 0; - skeleton->unk_2C = 0; - skeleton->unk_20 = 0.0f; +void Keyframe_ResetStandard(KFSkelAnime* kfSkelAnime) { + kfSkelAnime->skeleton = NULL; + kfSkelAnime->animation = NULL; + kfSkelAnime->jointTable = NULL; + kfSkelAnime->morphTable = NULL; + kfSkelAnime->rotOffsetsTable = NULL; + kfSkelAnime->morphFrames = 0.0f; } -void func_801845C8(SkeletonInfo2* skeleton, Struct_801BFA14_Arg1* arg1, SkeletonInfo_1C* arg2, Vec3s* frameData, - s16* arg4) { - func_801845A4(skeleton); - func_801830C8(&skeleton->frameCtrl); - skeleton->unk_18 = (Struct_801BFA14_Arg1*)Lib_SegmentedToVirtual(arg1); - skeleton->unk_1C = (SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg2); - skeleton->frameData = frameData; - skeleton->unk_28 = arg4; +void Keyframe_InitStandard(KFSkelAnime* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + Vec3s* jointTable, Vec3s* morphTable) { + Keyframe_ResetStandard(kfSkelAnime); + FrameCtrl_Init(&kfSkelAnime->frameCtrl); + kfSkelAnime->skeleton = (KeyFrameSkeleton*)Lib_SegmentedToVirtual(skeleton); + kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation); + kfSkelAnime->jointTable = jointTable; + kfSkelAnime->morphTable = morphTable; } -void func_8018462C(SkeletonInfo2* skeleton) { +void Keyframe_DestroyStandard(KFSkelAnime* kfSkelAnime) { } -void func_80184914(SkeletonInfo2* skeleton, Struct_801BFA14_Arg1* arg1, SkeletonInfo_1C* arg2, f32 arg3, f32 arg4, - f32 arg5, f32 arg6, f32 arg7, s32 arg8, s32 arg9); +void Keyframe_StandardChangeAnim(KFSkelAnime* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + f32 startTime, f32 endTime, f32 t, f32 speed, f32 morphFrames, s32 animMode, + Vec3s* rotOffsetsTable); -void func_80184638(SkeletonInfo2* skeleton, SkeletonInfo_1C* arg1, s32 arg2) { - func_80184914(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, 1.0f, 0.0f, false, arg2); +void Keyframe_StandardPlayOnce(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable) { + Keyframe_StandardChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, 1.0f, 0.0f, + KEYFRAME_ANIM_ONCE, rotOffsetsTable); } -void func_801846AC(SkeletonInfo2* skeleton, SkeletonInfo_1C* arg1, s32 arg2, f32 arg3) { - func_80184914(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, arg3, 0.0f, false, arg2); +void Keyframe_StandardPlayOnceWithSpeed(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable, + f32 speed) { + Keyframe_StandardChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, speed, 0.0f, + KEYFRAME_ANIM_ONCE, rotOffsetsTable); } -void func_80184728(SkeletonInfo2* skeleton, SkeletonInfo_1C* arg1, s32 arg2, f32 arg3) { - func_80184914(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, 1.0f, arg3, false, arg2); +void Keyframe_StandardPlayOnceWithMorph(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable, + f32 morphFrames) { + Keyframe_StandardChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, 1.0f, + morphFrames, KEYFRAME_ANIM_ONCE, rotOffsetsTable); } -void func_801847A0(SkeletonInfo2* skeleton, SkeletonInfo_1C* arg1, s32 arg2) { - func_80184914(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, 1.0f, 0.0f, true, arg2); +void Keyframe_StandardPlayLoop(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable) { + Keyframe_StandardChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, 1.0f, 0.0f, + KEYFRAME_ANIM_LOOP, rotOffsetsTable); } -void func_80184818(SkeletonInfo2* skeleton, SkeletonInfo_1C* arg1, s32 arg2, f32 arg3) { - func_80184914(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, arg3, 0.0f, true, arg2); +void Keyframe_StandardPlayLoopWithSpeed(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable, + f32 speed) { + Keyframe_StandardChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, speed, 0.0f, + KEYFRAME_ANIM_LOOP, rotOffsetsTable); } -void func_80184898(SkeletonInfo2* skeleton, SkeletonInfo_1C* arg1, s32 arg2, f32 arg3) { - func_80184914(skeleton, skeleton->unk_18, arg1, 1.0f, ((SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg1))->unk_12, - 1.0f, 1.0f, arg3, true, arg2); +void Keyframe_StandardPlayLoopWithMorph(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable, + f32 morphFrames) { + Keyframe_StandardChangeAnim(kfSkelAnime, kfSkelAnime->skeleton, animation, 1.0f, + ((KeyFrameAnimation*)Lib_SegmentedToVirtual(animation))->duration, 1.0f, 1.0f, + morphFrames, KEYFRAME_ANIM_LOOP, rotOffsetsTable); } -void func_80184914(SkeletonInfo2* skeleton, Struct_801BFA14_Arg1* arg1, SkeletonInfo_1C* arg2, f32 arg3, f32 arg4, - f32 arg5, f32 arg6, f32 arg7, s32 arg8, s32 arg9) { - skeleton->unk_20 = arg7; - skeleton->unk_18 = (Struct_801BFA14_Arg1*)Lib_SegmentedToVirtual(arg1); - skeleton->unk_1C = (SkeletonInfo_1C*)Lib_SegmentedToVirtual(arg2); +void Keyframe_StandardChangeAnim(KFSkelAnime* kfSkelAnime, KeyFrameSkeleton* skeleton, KeyFrameAnimation* animation, + f32 startTime, f32 endTime, f32 t, f32 speed, f32 morphFrames, s32 animMode, + Vec3s* rotOffsetsTable) { + kfSkelAnime->morphFrames = morphFrames; + kfSkelAnime->skeleton = (KeyFrameSkeleton*)Lib_SegmentedToVirtual(skeleton); + kfSkelAnime->animation = (KeyFrameAnimation*)Lib_SegmentedToVirtual(animation); - func_801830E8(&skeleton->frameCtrl, arg3, arg4, skeleton->unk_1C->unk_12, arg5, arg6, arg8); - skeleton->unk_2C = arg9; + FrameCtrl_SetProperties(&kfSkelAnime->frameCtrl, startTime, endTime, kfSkelAnime->animation->duration, t, speed, + animMode); + kfSkelAnime->rotOffsetsTable = rotOffsetsTable; } -void func_801849A0(SkeletonInfo2* skeleton, SkeletonInfo_1C* arg1) { - skeleton->unk_1C = Lib_SegmentedToVirtual(arg1); - skeleton->frameCtrl.unk_8 = skeleton->unk_1C->unk_12; +void Keyframe_StandardChangeAnimQuick(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation) { + kfSkelAnime->animation = Lib_SegmentedToVirtual(animation); + kfSkelAnime->frameCtrl.duration = kfSkelAnime->animation->duration; } -void func_801849DC(SkeletonInfo2* skeleton) { - Vec3s* frameData = skeleton->frameData; - Vec3s* phi_s7 = (Vec3s*)skeleton->unk_28; - f32 t = 1.0f / fabsf(skeleton->unk_20); - s32 i; +void Keyframe_UpdateStandardLimbs(KFSkelAnime* kfSkelAnime) { + Vec3s* jointTable = kfSkelAnime->jointTable; + Vec3s* morphTable = kfSkelAnime->morphTable; + f32 t = 1.0f / fabsf(kfSkelAnime->morphFrames); + s32 limbIndex; - func_80183B08((s16*)frameData, (s16*)phi_s7, t); + Keyframe_MorphInterpolate((s16*)jointTable, (s16*)morphTable, t); - frameData++; - phi_s7++; + // Skip translation + jointTable++; + morphTable++; - for (i = 0; i < skeleton->unk_18->limbCount; i++) { - Vec3s temp_a2; - Vec3s temp_a3; + // Interpolate rotation + for (limbIndex = 0; limbIndex < kfSkelAnime->skeleton->limbCount; limbIndex++) { + Vec3s frameRot; + Vec3s morphRot; - temp_a2.x = frameData->x; - temp_a2.y = frameData->y; - temp_a2.z = frameData->z; + frameRot.x = jointTable->x; + frameRot.y = jointTable->y; + frameRot.z = jointTable->z; - temp_a3.x = phi_s7->x; - temp_a3.y = phi_s7->y; - temp_a3.z = phi_s7->z; + morphRot.x = morphTable->x; + morphRot.y = morphTable->y; + morphRot.z = morphTable->z; - if (temp_a2.x != temp_a3.x || temp_a2.y != temp_a3.y || temp_a2.z != temp_a3.z) { - Vec3s temp_a0; - f32 v1; - f32 v2; + if (frameRot.x != morphRot.x || frameRot.y != morphRot.y || frameRot.z != morphRot.z) { + Vec3s frameRotInv; + f32 norm1; + f32 norm2; - temp_a0.x = temp_a2.x + 0x7FFF; - temp_a0.y = 0x7FFF - temp_a2.y; - temp_a0.z = temp_a2.z + 0x7FFF; + frameRotInv.x = 0x7FFF + frameRot.x; + frameRotInv.y = 0x7FFF - frameRot.y; + frameRotInv.z = 0x7FFF + frameRot.z; - v1 = fabsf((f32)temp_a3.x - temp_a2.x) + fabsf((f32)temp_a3.y - temp_a2.y) + - fabsf((f32)temp_a3.z - temp_a2.z); - v2 = fabsf((f32)temp_a3.x - temp_a0.x) + fabsf((f32)temp_a3.y - temp_a0.y) + - fabsf((f32)temp_a3.z - temp_a0.z); + norm1 = fabsf((f32)morphRot.x - frameRot.x) + fabsf((f32)morphRot.y - frameRot.y) + + fabsf((f32)morphRot.z - frameRot.z); + norm2 = fabsf((f32)morphRot.x - frameRotInv.x) + fabsf((f32)morphRot.y - frameRotInv.y) + + fabsf((f32)morphRot.z - frameRotInv.z); - if (v1 < v2) { - func_80183A3C(t, &frameData->x, temp_a2.x, temp_a3.x); - func_80183A3C(t, &frameData->y, temp_a2.y, temp_a3.y); - func_80183A3C(t, &frameData->z, temp_a2.z, temp_a3.z); + if (norm1 < norm2) { + Keyframe_RotationInterpolate(t, &jointTable->x, frameRot.x, morphRot.x); + Keyframe_RotationInterpolate(t, &jointTable->y, frameRot.y, morphRot.y); + Keyframe_RotationInterpolate(t, &jointTable->z, frameRot.z, morphRot.z); } else { - func_80183A3C(t, &frameData->x, temp_a0.x, temp_a3.x); - func_80183A3C(t, &frameData->y, temp_a0.y, temp_a3.y); - func_80183A3C(t, &frameData->z, temp_a0.z, temp_a3.z); + Keyframe_RotationInterpolate(t, &jointTable->x, frameRotInv.x, morphRot.x); + Keyframe_RotationInterpolate(t, &jointTable->y, frameRotInv.y, morphRot.y); + Keyframe_RotationInterpolate(t, &jointTable->z, frameRotInv.z, morphRot.z); } } - phi_s7++; - frameData++; + morphTable++; + jointTable++; } } -s32 func_80184C48(SkeletonInfo2* skeleton) { - s32 sp84; - u32 phi_s2; - u8* phi_t0; - s32 phi_s3; - s32 phi_s4 = 0; - s32 phi_s5 = 0; - s32 phi_s6 = 0; - s16* sp68; - Vec3s* sp64; - s16* sp60; - s16* phi_s1; +s32 Keyframe_UpdateStandard(KFSkelAnime* kfSkelAnime) { + s32 limbIndex; + u32 bit; + u8* bitFlags; + s32 i; + s32 kfn = 0; + s32 presetIndex = 0; + s32 kfStart = 0; + s16* presetValues; + KeyFrame* keyFrames; + s16* kfNums; + s16* outputValues; - if (skeleton->unk_20 != 0.0f) { - phi_s1 = skeleton->unk_28; + if (kfSkelAnime->morphFrames != 0.0f) { + outputValues = (s16*)kfSkelAnime->morphTable; } else { - phi_s1 = (s16*)skeleton->frameData; + outputValues = (s16*)kfSkelAnime->jointTable; } - sp68 = (s16*)Lib_SegmentedToVirtual(skeleton->unk_1C->unk_C); - sp60 = (s16*)Lib_SegmentedToVirtual(skeleton->unk_1C->unk_8); - sp64 = (Vec3s*)Lib_SegmentedToVirtual(skeleton->unk_1C->unk_4); - phi_t0 = (u8*)Lib_SegmentedToVirtual(skeleton->unk_1C->unk_0); + presetValues = (s16*)Lib_SegmentedToVirtual(kfSkelAnime->animation->presetValues); + kfNums = (s16*)Lib_SegmentedToVirtual(kfSkelAnime->animation->kfNums); + keyFrames = (KeyFrame*)Lib_SegmentedToVirtual(kfSkelAnime->animation->keyFrames); + bitFlags = (u8*)Lib_SegmentedToVirtual(kfSkelAnime->animation->bitFlags); - for (phi_s2 = 32, phi_s3 = 0; phi_s3 < 3; phi_s3++, phi_s2 >>= 1) { - if (phi_t0[0] & phi_s2) { - *phi_s1 = func_80183880(phi_s6, sp60[phi_s4], sp64, skeleton->frameCtrl.unk_10); - phi_s6 += sp60[phi_s4++]; + // Translation + bit = 1 << (3 * 2 - 1); + + for (i = 0; i < 3; i++, bit >>= 1) { // xyz + if (*bitFlags & bit) { + *outputValues = Keyframe_KeyCalc(kfStart, kfNums[kfn], keyFrames, kfSkelAnime->frameCtrl.curTime); + kfStart += kfNums[kfn++]; } else { - *phi_s1 = sp68[phi_s5++]; + *outputValues = presetValues[presetIndex++]; } - phi_s1++; + outputValues++; } - for (sp84 = 0; sp84 < skeleton->unk_18->limbCount; sp84++) { - for (phi_s2 = 4, phi_s3 = 0; phi_s3 < 3; phi_s3++) { + // Rotation only + for (limbIndex = 0; limbIndex < kfSkelAnime->skeleton->limbCount; limbIndex++) { + bit = 1 << (3 - 1); + + for (i = 0; i < 3; i++) { // xyz s32 pad; - if (phi_t0[sp84] & phi_s2) { - *phi_s1 = func_80183880(phi_s6, sp60[phi_s4], sp64, skeleton->frameCtrl.unk_10); - phi_s6 += sp60[phi_s4++]; + if (bitFlags[limbIndex] & bit) { + *outputValues = Keyframe_KeyCalc(kfStart, kfNums[kfn], keyFrames, kfSkelAnime->frameCtrl.curTime); + kfStart += kfNums[kfn++]; } else { - *phi_s1 = sp68[phi_s5++]; + *outputValues = presetValues[presetIndex++]; } - *phi_s1 = FMOD(*phi_s1 * 0.1f, 360) * 182.04445f; - phi_s2 >>= 1; - phi_s1++; + *outputValues = FMOD(*outputValues * 0.1f, 360) * 182.04445f; + bit >>= 1; + outputValues++; } } - if (skeleton->unk_2C != NULL) { - Vec3s* phi_v0; + if (kfSkelAnime->rotOffsetsTable != NULL) { + Vec3s* table; - if (skeleton->unk_20 != 0.0f) { - phi_v0 = (Vec3s*)skeleton->unk_28; + if (kfSkelAnime->morphFrames != 0.0f) { + table = kfSkelAnime->morphTable; } else { - phi_v0 = skeleton->frameData; + table = kfSkelAnime->jointTable; } - phi_v0++; - for (sp84 = 0; sp84 < skeleton->unk_18->limbCount; sp84++, phi_v0++) { - phi_v0->x = phi_v0->x + skeleton->unk_2C[sp84].x; - phi_v0->y = phi_v0->y + skeleton->unk_2C[sp84].y; - phi_v0->z = phi_v0->z + skeleton->unk_2C[sp84].z; + table++; // Skip translation? + + // Add all offsets to rotations + for (limbIndex = 0; limbIndex < kfSkelAnime->skeleton->limbCount; limbIndex++, table++) { + table->x = table->x + kfSkelAnime->rotOffsetsTable[limbIndex].x; + table->y = table->y + kfSkelAnime->rotOffsetsTable[limbIndex].y; + table->z = table->z + kfSkelAnime->rotOffsetsTable[limbIndex].z; } } - if (IS_ZERO(skeleton->unk_20)) { - return func_8018332C(&skeleton->frameCtrl); + if (IS_ZERO(kfSkelAnime->morphFrames)) { + return FrameCtrl_Update(&kfSkelAnime->frameCtrl); } - if (skeleton->unk_20 > 0.0f) { - func_801849DC(skeleton); - skeleton->unk_20 -= 1.0f; - if (skeleton->unk_20 <= 0.0f) { - skeleton->unk_20 = 0.0f; + if (kfSkelAnime->morphFrames > 0.0f) { + Keyframe_UpdateStandardLimbs(kfSkelAnime); + kfSkelAnime->morphFrames -= 1.0f; + if (kfSkelAnime->morphFrames <= 0.0f) { + kfSkelAnime->morphFrames = 0.0f; } - return 0; + return KEYFRAME_NOT_DONE; } - func_801849DC(skeleton); - skeleton->unk_20 += 1.0f; - if (skeleton->unk_20 >= 0.0f) { - skeleton->unk_20 = 0.0f; + Keyframe_UpdateStandardLimbs(kfSkelAnime); + kfSkelAnime->morphFrames += 1.0f; + if (kfSkelAnime->morphFrames >= 0.0f) { + kfSkelAnime->morphFrames = 0.0f; } - return func_8018332C(&skeleton->frameCtrl); + return FrameCtrl_Update(&kfSkelAnime->frameCtrl); } -void func_801850A0(PlayState* play, SkeletonInfo2* skeleton, s32* limbIndex, OverrideKeyframeDraw overrideKeyframeDraw, - PostKeyframeDraw postKeyframeDraw, void* arg, Mtx** mtx) { - Struct_801BFA14_Arg1_Field4* jointData = - *limbIndex + (Struct_801BFA14_Arg1_Field4*)Lib_SegmentedToVirtual(skeleton->unk_18->unk_4); +void Keyframe_DrawStandardLimb(PlayState* play, KFSkelAnime* kfSkelAnime, s32* limbIndex, + OverrideKeyframeDraw overrideKeyframeDraw, PostKeyframeDraw postKeyframeDraw, void* arg, + Mtx** mtxStack) { + KeyFrameStandardLimb* limb = + *limbIndex + (KeyFrameStandardLimb*)Lib_SegmentedToVirtual(kfSkelAnime->skeleton->limbsStandard); s32 i; Gfx* newDList; Gfx* limbDList; u8 flags; Vec3s rot; - Vec3s* frameData = &skeleton->frameData[*limbIndex]; + Vec3s* jointData = &kfSkelAnime->jointTable[*limbIndex]; Vec3f pos; if (*limbIndex != 0) { - pos.x = jointData->root.x; - pos.y = jointData->root.y; - pos.z = jointData->root.z; + pos.x = limb->translation.x; + pos.y = limb->translation.y; + pos.z = limb->translation.z; } else { - pos.x = frameData->x; - pos.y = frameData->y; - pos.z = frameData->z; + pos.x = jointData->x; + pos.y = jointData->y; + pos.z = jointData->z; } - frameData++; + jointData++; - rot.x = frameData->x; - rot.y = frameData->y; - rot.z = frameData->z; + rot.x = jointData->x; + rot.y = jointData->y; + rot.z = jointData->z; OPEN_DISPS(play->state.gfxCtx); Matrix_Push(); - newDList = limbDList = jointData->dList; - flags = jointData->flags; + newDList = limbDList = limb->dList; + flags = limb->flags; if (overrideKeyframeDraw == NULL || (overrideKeyframeDraw != NULL && - overrideKeyframeDraw(play, skeleton, *limbIndex, &newDList, &flags, arg, &rot, &pos) != 0)) { - Matrix_TranslateRotateZYX(&pos, &rot); - if (newDList != NULL) { - Matrix_ToMtx(*mtx); + overrideKeyframeDraw(play, kfSkelAnime, *limbIndex, &newDList, &flags, arg, &rot, &pos) != 0)) { - if (flags & KEYFRAME_XLU) { - gSPMatrix(POLY_XLU_DISP++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + Matrix_TranslateRotateZYX(&pos, &rot); + + if (newDList != NULL) { + Matrix_ToMtx(*mtxStack); + + if (flags & KEYFRAME_DRAW_XLU) { + gSPMatrix(POLY_XLU_DISP++, *mtxStack, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, newDList); } else { - gSPMatrix(POLY_OPA_DISP++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_OPA_DISP++, *mtxStack, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, newDList); } - (*mtx)++; + (*mtxStack)++; } else if (limbDList != NULL) { - Matrix_ToMtx(*mtx); + Matrix_ToMtx(*mtxStack); - gSPMatrix(POLY_OPA_DISP++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - (*mtx)++; + gSPMatrix(POLY_OPA_DISP++, *mtxStack, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + (*mtxStack)++; } } if (postKeyframeDraw != NULL) { - postKeyframeDraw(play, skeleton, *limbIndex, &newDList, &flags, arg, &rot, &pos); + postKeyframeDraw(play, kfSkelAnime, *limbIndex, &newDList, &flags, arg, &rot, &pos); } (*limbIndex)++; - for (i = 0; i < jointData->unk_4; i++) { - func_801850A0(play, skeleton, limbIndex, overrideKeyframeDraw, postKeyframeDraw, arg, mtx); + for (i = 0; i < limb->numChildren; i++) { + Keyframe_DrawStandardLimb(play, kfSkelAnime, limbIndex, overrideKeyframeDraw, postKeyframeDraw, arg, mtxStack); } Matrix_Pop(); @@ -760,69 +832,71 @@ void func_801850A0(PlayState* play, SkeletonInfo2* skeleton, s32* limbIndex, Ove CLOSE_DISPS(play->state.gfxCtx); } -void func_801853C8(PlayState* play, SkeletonInfo2* skeleton, Mtx* mtx, OverrideKeyframeDraw overrideKeyframeDraw, - PostKeyframeDraw postKeyframeDraw, void* arg) { +void Keyframe_DrawStandard(PlayState* play, KFSkelAnime* kfSkelAnime, Mtx* mtxStack, + OverrideKeyframeDraw overrideKeyframeDraw, PostKeyframeDraw postKeyframeDraw, void* arg) { s32 limbIndex; - if (mtx == NULL) { + if (mtxStack == NULL) { return; } OPEN_DISPS(play->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); - gSPSegment(POLY_XLU_DISP++, 0x0D, mtx); + gSPSegment(POLY_OPA_DISP++, 0x0D, mtxStack); + gSPSegment(POLY_XLU_DISP++, 0x0D, mtxStack); limbIndex = 0; - func_801850A0(play, skeleton, &limbIndex, overrideKeyframeDraw, postKeyframeDraw, arg, &mtx); + Keyframe_DrawStandardLimb(play, kfSkelAnime, &limbIndex, overrideKeyframeDraw, postKeyframeDraw, arg, &mtxStack); CLOSE_DISPS(play->state.gfxCtx); } -void func_80185460(SkeletonInfo2* arg0, s32 arg1, s16* arg2) { - s16* temp_fp; - s32 sp78; - s32 var_s3 = 0; - s32 var_s4 = 0; - s32 var_s5 = 0; - s32 var_s1; - u16* var_v1; - s16* var_s6 = arg2; - s16* sp5C; - Vec3s* sp58; - s32 sp44; +void Keyframe_FlexGetScales(KFSkelAnime* kfSkelAnime, s32 targetLimbIndex, s16* scalesOut) { + s16* kfNums; + s32 i; + s32 kfn = 0; + s32 presetIndex = 0; + s32 kfStart = 0; + s32 j; + u16* bitFlags; + s16* scales = scalesOut; + s16* presetValues; + KeyFrame* keyFrames; + s32 limbIndex; - sp5C = (s16*)Lib_SegmentedToVirtual(arg0->unk_1C->unk_C); - temp_fp = (s16*)Lib_SegmentedToVirtual(arg0->unk_1C->unk_8); - sp58 = (Vec3s*)Lib_SegmentedToVirtual(arg0->unk_1C->unk_4); - var_v1 = (u16*)Lib_SegmentedToVirtual(arg0->unk_1C->unk_0); + presetValues = (s16*)Lib_SegmentedToVirtual(kfSkelAnime->animation->presetValues); + kfNums = (s16*)Lib_SegmentedToVirtual(kfSkelAnime->animation->kfNums); + keyFrames = (KeyFrame*)Lib_SegmentedToVirtual(kfSkelAnime->animation->keyFrames); + bitFlags = (u16*)Lib_SegmentedToVirtual(kfSkelAnime->animation->bitFlagsFlex); - for (sp44 = 0; sp44 < arg0->unk_18->limbCount; sp44++) { - u32 var_s2 = 256; + for (limbIndex = 0; limbIndex < kfSkelAnime->skeleton->limbCount; limbIndex++) { + u32 bit = 1 << (3 * 3 - 1); - for (sp78 = 0; sp78 < 3; sp78++) { - if ((sp44 == arg1) && (sp78 == 0)) { - for (var_s1 = 0; var_s1 < 3; var_s1++) { - if (var_v1[sp44] & var_s2) { - *var_s6 = func_80183880(var_s5, temp_fp[var_s3], sp58, arg0->frameCtrl.unk_10); - var_s5 += temp_fp[var_s3]; - var_s3++; + for (i = 0; i < 3; i++) { + if ((limbIndex == targetLimbIndex) && (i == 0)) { + // Is the target limb and is scale data + for (j = 0; j < 3; j++) { + if (bitFlags[limbIndex] & bit) { + *scales = Keyframe_KeyCalc(kfStart, kfNums[kfn], keyFrames, kfSkelAnime->frameCtrl.curTime); + kfStart += kfNums[kfn]; + kfn++; } else { - *var_s6 = sp5C[var_s4]; - var_s4++; + *scales = presetValues[presetIndex]; + presetIndex++; } - var_s2 >>= 1; - var_s6++; + bit >>= 1; + scales++; } } else { - for (var_s1 = 0; var_s1 < 3; var_s1++) { - if (var_v1[sp44] & var_s2) { - var_s5 += temp_fp[var_s3]; - var_s3++; + // Not the target limb, step over values + for (j = 0; j < 3; j++) { + if (bitFlags[limbIndex] & bit) { + kfStart += kfNums[kfn]; + kfn++; } else { - var_s4++; + presetIndex++; } - var_s2 >>= 1; + bit >>= 1; } } } diff --git a/mm/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c b/mm/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c index ee0c33e09..d00597419 100644 --- a/mm/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c +++ b/mm/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c @@ -46,14 +46,15 @@ void DemoMoonend_Init(Actor* thisx, PlayState* play) { this->actionFunc = func_80C17B60; } else { Actor_SetScale(&this->actor, 0.095f); - func_80183430(&this->skeletonInfo, (void*)object_moonend_Blob_00B5A0, (void*)object_moonend_Blob_001214, this->jointTable, + Keyframe_InitFlex(&this->skeletonInfo, (void*)object_moonend_Blob_00B5A0, (void*)object_moonend_Blob_001214, + this->jointTable, this->morphTable, NULL); - func_801834A8(&this->skeletonInfo, (void*)object_moonend_Blob_001214); + Keyframe_FlexPlayOnce(&this->skeletonInfo, (void*)object_moonend_Blob_001214); this->cueType = CS_CMD_ACTOR_CUE_560; this->actionFunc = func_80C17C48; this->actor.home.rot.z = 0; this->actor.draw = NULL; - this->skeletonInfo.frameCtrl.unk_C = 2.0f / 3.0f; + this->skeletonInfo.frameCtrl.speed = 2.0f / 3.0f; } } @@ -61,7 +62,7 @@ void DemoMoonend_Destroy(Actor* thisx, PlayState* play) { DemoMoonend* this = THIS; if (DEMOMOONEND_GET_PARAM_F(thisx) != 1) { - func_8018349C(&this->skeletonInfo); + Keyframe_DestroyFlex(&this->skeletonInfo); } } @@ -97,7 +98,7 @@ void func_80C17B60(DemoMoonend* this, PlayState* play) { } void func_80C17C48(DemoMoonend* this, PlayState* play) { - if (func_80183DE0(&this->skeletonInfo)) { + if (Keyframe_UpdateFlex(&this->skeletonInfo)) { this->actor.home.rot.z = 0; } if (Cutscene_IsCueInChannel(play, this->cueType)) { @@ -110,14 +111,14 @@ void func_80C17C48(DemoMoonend* this, PlayState* play) { switch (this->cueId) { case 1: this->actor.draw = DemoMoonend_Draw; - func_801834A8(&this->skeletonInfo, (void*)object_moonend_Blob_001214); - this->skeletonInfo.frameCtrl.unk_C = 0.0f; + Keyframe_FlexPlayOnce(&this->skeletonInfo, (void*)object_moonend_Blob_001214); + this->skeletonInfo.frameCtrl.speed = 0.0f; break; case 2: this->actor.draw = DemoMoonend_Draw; - func_801834A8(&this->skeletonInfo, (void*)object_moonend_Blob_001214); - this->skeletonInfo.frameCtrl.unk_C = 2.0f / 3.0f; + Keyframe_FlexPlayOnce(&this->skeletonInfo, (void*)object_moonend_Blob_001214); + this->skeletonInfo.frameCtrl.speed = 2.0f / 3.0f; Actor_PlaySfx(&this->actor, NA_SE_EV_MOON_EXPLOSION); this->actor.home.rot.z = 1; break; @@ -166,7 +167,7 @@ void DemoMoonend_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); } -s32 func_80C17E70(PlayState* play, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, void* thisx, +s32 func_80C17E70(PlayState* play, KFSkelAnimeFlex* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, void* thisx, Vec3f* scale, Vec3s* rot, Vec3f* pos) { DemoMoonend* this = THIS; @@ -178,7 +179,7 @@ s32 func_80C17E70(PlayState* play, SkeletonInfo* skeletonInfo, s32 limbIndex, Gf return true; } -s32 func_80C17EE0(PlayState* play, SkeletonInfo* skeleton, s32 limbIndex, Gfx** dList, u8* flags, void* thisx, +s32 func_80C17EE0(PlayState* play, KFSkelAnimeFlex* skeleton, s32 limbIndex, Gfx** dList, u8* flags, void* thisx, Vec3f* scale, Vec3s* rot, Vec3f* pos) { DemoMoonend* this = THIS; @@ -195,12 +196,12 @@ void DemoMoonend_Draw(Actor* thisx, PlayState* play) { AnimatedMat_Draw(play, (AnimatedMaterial*)Lib_SegmentedToVirtual(object_moonend_Matanimheader_00B540)); - mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.unk_18->unk_1 * sizeof(Mtx)); + mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.skeleton->dListCount * sizeof(Mtx)); if (mtx != NULL) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); Gfx_SetupDL25_Opa(play->state.gfxCtx); - func_8018450C(play, &this->skeletonInfo, mtx, func_80C17E70, func_80C17EE0, &this->actor); + Keyframe_DrawFlex(play, &this->skeletonInfo, mtx, func_80C17E70, func_80C17EE0, &this->actor); } } diff --git a/mm/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.h b/mm/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.h index b56c60a9b..50b502a5c 100644 --- a/mm/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.h +++ b/mm/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.h @@ -12,7 +12,7 @@ typedef void (*DemoMoonendActionFunc)(struct DemoMoonend*, PlayState*); typedef struct DemoMoonend { /* 0x000 */ Actor actor; - /* 0x144 */ SkeletonInfo skeletonInfo; + /* 0x144 */ KFSkelAnimeFlex skeletonInfo; /* 0x174 */ Vec3s jointTable[30]; /* 0x228 */ Vec3s morphTable[30]; /* 0x2DC */ u16 cueType; diff --git a/mm/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c b/mm/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c index 5b4341e2e..176be28f6 100644 --- a/mm/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c +++ b/mm/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c @@ -73,9 +73,10 @@ void DemoSyoten_Init(Actor* thisx, PlayState* play) { switch (DEMOSYOTEN_GET_F(&this->actor)) { case DEMOSYOTEN_F_0: - func_80183430(&this->unk_144, (void*)object_syoten_Blob_001328, (void*)object_syoten_Blob_00023C, this->unk_174, + Keyframe_InitFlex(&this->unk_144, (void*)object_syoten_Blob_001328, (void*)object_syoten_Blob_00023C, + this->unk_174, this->unk_2A6, NULL); - func_801835EC(&this->unk_144, (void*)object_syoten_Blob_00023C); + Keyframe_FlexPlayLoop(&this->unk_144, (void*)object_syoten_Blob_00023C); this->actor.draw = NULL; this->actionFunc = func_80C16A74; this->actor.child = @@ -131,7 +132,7 @@ void DemoSyoten_Destroy(Actor* thisx, PlayState* play) { DemoSyoten* this = THIS; if (DEMOSYOTEN_GET_F(&this->actor) == DEMOSYOTEN_F_0) { - func_8018349C(&this->unk_144); + Keyframe_DestroyFlex(&this->unk_144); } } @@ -221,7 +222,7 @@ void func_80C16A64(DemoSyoten* this, PlayState* play) { void func_80C16A74(DemoSyoten* this, PlayState* play) { u16 cueId; - func_80183DE0(&this->unk_144); + Keyframe_UpdateFlex(&this->unk_144); if (Cutscene_IsCueInChannel(play, this->cueType)) { if ((play->csCtx.curFrame >= 160) && (play->csCtx.curFrame < 322)) { Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_IKANA_SOUL_LV - SFX_FLAG); @@ -484,12 +485,12 @@ void func_80C173B4(Actor* thisx, PlayState* play) { AnimatedMat_DrawXlu(play, Lib_SegmentedToVirtual(&object_syoten_Matanimheader_001298)); - mtx = GRAPH_ALLOC(play->state.gfxCtx, this->unk_144.unk_18->unk_1 * sizeof(Mtx)); + mtx = GRAPH_ALLOC(play->state.gfxCtx, this->unk_144.skeleton->dListCount * sizeof(Mtx)); if (mtx != NULL) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY); - func_8018450C(play, &this->unk_144, mtx, (void*)func_80C170F8, 0, &this->actor); + Keyframe_DrawFlex(play, &this->unk_144, mtx, (void*)func_80C170F8, 0, &this->actor); } } diff --git a/mm/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.h b/mm/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.h index 19f99bf2f..68995cdeb 100644 --- a/mm/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.h +++ b/mm/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.h @@ -22,7 +22,7 @@ typedef enum { typedef struct DemoSyoten { /* 0x000 */ Actor actor; - /* 0x144 */ SkeletonInfo unk_144; + /* 0x144 */ KFSkelAnimeFlex unk_144; /* 0x174 */ Vec3s unk_174[51]; /* 0x2A6 */ Vec3s unk_2A6[51]; /* 0x3D8 */ f32 unk_3D8; diff --git a/mm/src/overlays/actors/ovl_Eff_Change/z_eff_change.c b/mm/src/overlays/actors/ovl_Eff_Change/z_eff_change.c index 9839d29d5..9928a18ac 100644 --- a/mm/src/overlays/actors/ovl_Eff_Change/z_eff_change.c +++ b/mm/src/overlays/actors/ovl_Eff_Change/z_eff_change.c @@ -50,19 +50,19 @@ void EffChange_Init(Actor* thisx, PlayState* play) { EffChange_SetColors(this, EFFCHANGE_GET_COLORS(thisx)); Actor_SetScale(&this->actor, 0.075f); this->primColors[3] = 0; - func_80183430(&this->skeletonInfo, gameplay_keep_Blob_02900C, gameplay_keep_Blob_0281DC, this->jointTable, + Keyframe_InitFlex(&this->skeletonInfo, gameplay_keep_Blob_02900C, gameplay_keep_Blob_0281DC, this->jointTable, this->morphTable, NULL); - func_801834A8(&this->skeletonInfo, gameplay_keep_Blob_0281DC); + Keyframe_FlexPlayOnce(&this->skeletonInfo, gameplay_keep_Blob_0281DC); this->step = 0; this->actor.shape.rot.y = 0; - this->skeletonInfo.frameCtrl.unk_C = (2.0f / 3.0f); + this->skeletonInfo.frameCtrl.speed = (2.0f / 3.0f); CutsceneManager_Queue(CS_ID_GLOBAL_ELEGY); } void EffChange_Destroy(Actor* thisx, PlayState* play) { EffChange* this = THIS; - func_8018349C(&this->skeletonInfo); + Keyframe_DestroyFlex(&this->skeletonInfo); } void EffChange_SetColors(EffChange* this, s32 arg1) { @@ -78,7 +78,7 @@ void EffChange_SetColors(EffChange* this, s32 arg1) { void func_80A4C5CC(EffChange* this, PlayState* play) { f32 phi_fv0; - if (func_80183DE0(&this->skeletonInfo)) { + if (Keyframe_UpdateFlex(&this->skeletonInfo)) { Actor_Kill(&this->actor); CutsceneManager_Stop(CS_ID_GLOBAL_ELEGY); Environment_AdjustLights(play, 0.0f, 850.0f, 0.2f, 0.0f); @@ -86,13 +86,13 @@ void func_80A4C5CC(EffChange* this, PlayState* play) { } this->step++; - if (this->skeletonInfo.frameCtrl.unk_10 < 20.0f) { + if (this->skeletonInfo.frameCtrl.curTime < 20.0f) { if ((this->primColors[3]) < 242) { this->primColors[3] += 13; } else { this->primColors[3] = 255; } - } else if (this->skeletonInfo.frameCtrl.unk_10 > 70.0f) { + } else if (this->skeletonInfo.frameCtrl.curTime > 70.0f) { if ((this->primColors[3]) >= 14) { this->primColors[3] -= 13; } else { @@ -130,7 +130,7 @@ void EffChange_Draw(Actor* thisx, PlayState* play) { EffChange* this = THIS; AnimatedMat_DrawStepXlu(play, Lib_SegmentedToVirtual(&gameplay_keep_Matanimheader_028FEC), this->step); - mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.unk_18->unk_1 * sizeof(Mtx)); + mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.skeleton->dListCount * sizeof(Mtx)); if (mtx != NULL) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); @@ -141,7 +141,7 @@ void EffChange_Draw(Actor* thisx, PlayState* play) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, this->primColors[0], this->primColors[1], this->primColors[2], this->primColors[3]); gDPSetEnvColor(POLY_XLU_DISP++, this->envColors[0], this->envColors[1], this->envColors[2], 255); - func_8018450C(play, &this->skeletonInfo, mtx, NULL, NULL, &this->actor); + Keyframe_DrawFlex(play, &this->skeletonInfo, mtx, NULL, NULL, &this->actor); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/mm/src/overlays/actors/ovl_Eff_Change/z_eff_change.h b/mm/src/overlays/actors/ovl_Eff_Change/z_eff_change.h index 194ae3ee2..980e2b78a 100644 --- a/mm/src/overlays/actors/ovl_Eff_Change/z_eff_change.h +++ b/mm/src/overlays/actors/ovl_Eff_Change/z_eff_change.h @@ -12,7 +12,7 @@ typedef void (*EffChangeActionFunc)(struct EffChange*, PlayState*); typedef struct EffChange { /* 0x000 */ Actor actor; - /* 0x144 */ SkeletonInfo skeletonInfo; + /* 0x144 */ KFSkelAnimeFlex skeletonInfo; /* 0x174 */ Vec3s jointTable[PINK_DEKU_FLOWER_LIMB_BACK_RIGHT_PETAL]; /* 0x198 */ Vec3s morphTable[PINK_DEKU_FLOWER_LIMB_BACK_RIGHT_PETAL]; /* 0x1BC */ s16 step; diff --git a/mm/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c b/mm/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c index ad34a8487..59390b3ad 100644 --- a/mm/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c +++ b/mm/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c @@ -35,9 +35,10 @@ void EnFall2_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 1.0f); this->actionFunc = EnFall2_DoNothing; - func_80183430(&this->skeletonInfo, (void*)object_fall2_Blob_008898, (void*)object_fall2_Blob_005EF4, this->unk174, this->unk228, + Keyframe_InitFlex(&this->skeletonInfo, (void*)object_fall2_Blob_008898, (void*)object_fall2_Blob_005EF4, + this->unk174, this->unk228, NULL); - func_801835EC(&this->skeletonInfo, (void*)object_fall2_Blob_005EF4); + Keyframe_FlexPlayLoop(&this->skeletonInfo, (void*)object_fall2_Blob_005EF4); this->unk2DC = Lib_SegmentedToVirtual((void*)object_fall2_Matanimheader_008840); Actor_SetScale(&this->actor, 0.02f); this->actionFunc = EnFall2_HandleCutscene; @@ -48,7 +49,7 @@ void EnFall2_Init(Actor* thisx, PlayState* play) { void EnFall2_Destroy(Actor* thisx, PlayState* play) { EnFall2* this = THIS; - func_8018349C(&this->skeletonInfo); + Keyframe_DestroyFlex(&this->skeletonInfo); } static u8 sAlphaTableIndices[] = { @@ -125,7 +126,7 @@ void func_80C1B8F0(EnFall2* this) { } void EnFall2_HandleCutscene(EnFall2* this, PlayState* play) { - func_80183DE0(&this->skeletonInfo); + Keyframe_UpdateFlex(&this->skeletonInfo); if (Cutscene_IsCueInChannel(play, this->cueType)) { Cutscene_ActorTranslateAndYaw(&this->actor, play, Cutscene_GetCueChannel(play, this->cueType)); if (this->cueId != play->csCtx.actorCues[Cutscene_GetCueChannel(play, this->cueType)]->id) { @@ -157,12 +158,12 @@ void EnFall2_Draw(Actor* thisx, PlayState* play) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); AnimatedMat_DrawXlu(play, Lib_SegmentedToVirtual(object_fall2_Matanimheader_008840)); - mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.unk_18->unk_1 * sizeof(Mtx)); + mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.skeleton->dListCount * sizeof(Mtx)); if (mtx != NULL) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); Matrix_RotateYS((s16)(Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000), MTXMODE_APPLY); - func_8018450C(play, &this->skeletonInfo, mtx, NULL, NULL, &this->actor); + Keyframe_DrawFlex(play, &this->skeletonInfo, mtx, NULL, NULL, &this->actor); } } } diff --git a/mm/src/overlays/actors/ovl_En_Fall2/z_en_fall2.h b/mm/src/overlays/actors/ovl_En_Fall2/z_en_fall2.h index 3555595f3..fef77c15f 100644 --- a/mm/src/overlays/actors/ovl_En_Fall2/z_en_fall2.h +++ b/mm/src/overlays/actors/ovl_En_Fall2/z_en_fall2.h @@ -10,7 +10,7 @@ typedef void (*EnFall2ActionFunc)(struct EnFall2*, PlayState*); typedef struct EnFall2 { /* 0x000 */ Actor actor; - /* 0x144 */ SkeletonInfo skeletonInfo; + /* 0x144 */ KFSkelAnimeFlex skeletonInfo; /* 0x174 */ Vec3s unk174[30]; /* 0x228 */ Vec3s unk228[30]; /* 0x2DC */ AnimatedMaterial* unk2DC; diff --git a/mm/src/overlays/actors/ovl_En_Test/z_en_test.c b/mm/src/overlays/actors/ovl_En_Test/z_en_test.c index 4c8f90b6d..d49dbb4a5 100644 --- a/mm/src/overlays/actors/ovl_En_Test/z_en_test.c +++ b/mm/src/overlays/actors/ovl_En_Test/z_en_test.c @@ -186,26 +186,27 @@ void EnTest_Init(Actor* thisx, PlayState* play2) { this->surfaceMaterial = SurfaceType_GetMaterial(&play->colCtx, thisx->floorPoly, bgId); } - func_80183430(&this->skeletonInfo, (void*)gameplay_keep_Blob_06EB70, (void*)gameplay_keep_Blob_06BB0C, this->unk_178, + Keyframe_InitFlex(&this->skeletonInfo, (void*)gameplay_keep_Blob_06EB70, (void*)gameplay_keep_Blob_06BB0C, + this->unk_178, this->unk_1C0, NULL); - func_801834A8(&this->skeletonInfo, (void*)gameplay_keep_Blob_06BB0C); - this->skeletonInfo.frameCtrl.unk_10 = 9.0f; + Keyframe_FlexPlayOnce(&this->skeletonInfo, (void*)gameplay_keep_Blob_06BB0C); + this->skeletonInfo.frameCtrl.curTime = 9.0f; func_80862B70(this->unk_20C); } void EnTest_Destroy(Actor* thisx, PlayState* play) { EnTest* this = THIS; - func_8018349C(&this->skeletonInfo); + Keyframe_DestroyFlex(&this->skeletonInfo); } void EnTest_Update(Actor* thisx, PlayState* play) { EnTest* this = THIS; s32 i; - this->unk_208 = this->skeletonInfo.frameCtrl.unk_10; + this->unk_208 = this->skeletonInfo.frameCtrl.curTime; - if (func_80183DE0(&this->skeletonInfo) && (this->actor.parent == NULL) && (this->actor.params != -1)) { + if (Keyframe_UpdateFlex(&this->skeletonInfo) && (this->actor.parent == NULL) && (this->actor.params != -1)) { this->unk_209++; if (this->unk_209 > 20) { Actor_Kill(&this->actor); @@ -224,7 +225,7 @@ void EnTest_Update(Actor* thisx, PlayState* play) { func_80862EDC(this->unk_20C); } -s32 EnTest_OverrideKeyframeDraw(PlayState* play, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, +s32 EnTest_OverrideKeyframeDraw(PlayState* play, KFSkelAnimeFlex* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, void* thisx, Vec3f* scale, Vec3s* rot, Vec3f* pos) { EnTest* this = THIS; @@ -264,11 +265,11 @@ void EnTest_Draw(Actor* thisx, PlayState* play) { AnimatedMat_DrawStep(play, Lib_SegmentedToVirtual(gameplay_keep_Matanimheader_06B6A0), sp2C); } - mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.unk_18->unk_1 * sizeof(Mtx)); + mtx = GRAPH_ALLOC(play->state.gfxCtx, this->skeletonInfo.skeleton->dListCount * sizeof(Mtx)); if (mtx != NULL) { Gfx_SetupDL25_Xlu(play->state.gfxCtx); - func_8018450C(play, &this->skeletonInfo, mtx, EnTest_OverrideKeyframeDraw, NULL, thisx); + Keyframe_DrawFlex(play, &this->skeletonInfo, mtx, EnTest_OverrideKeyframeDraw, NULL, thisx); func_80863048(play, this->unk_20C); } } diff --git a/mm/src/overlays/actors/ovl_En_Test/z_en_test.h b/mm/src/overlays/actors/ovl_En_Test/z_en_test.h index 68395a96a..d9991c514 100644 --- a/mm/src/overlays/actors/ovl_En_Test/z_en_test.h +++ b/mm/src/overlays/actors/ovl_En_Test/z_en_test.h @@ -18,7 +18,7 @@ typedef struct { typedef struct EnTest { /* 0x000 */ Actor actor; - /* 0x144 */ SkeletonInfo skeletonInfo; + /* 0x144 */ KFSkelAnimeFlex skeletonInfo; /* 0x174 */ s32 unk_174; /* 0x178 */ Vec3s unk_178[12]; /* 0x1C0 */ Vec3s unk_1C0[12]; diff --git a/mm/src/overlays/actors/ovl_En_Test7/z_en_test7.c b/mm/src/overlays/actors/ovl_En_Test7/z_en_test7.c index 6c2c6f461..917bf6579 100644 --- a/mm/src/overlays/actors/ovl_En_Test7/z_en_test7.c +++ b/mm/src/overlays/actors/ovl_En_Test7/z_en_test7.c @@ -397,9 +397,9 @@ void EnTest7_Init(Actor* thisx, PlayState* play2) { this->unk_1E90 = player->actor.scale.x; this->unk_1E94 = player->actor.scale.z; - func_80183430(&this->unk_18CC, &gameplay_keep_Blob_085640, &gameplay_keep_Blob_083534, this->unk_18FC, + Keyframe_InitFlex(&this->unk_18CC, &gameplay_keep_Blob_085640, &gameplay_keep_Blob_083534, this->unk_18FC, this->unk_1BA8, NULL); - func_801834A8(&this->unk_18CC, &gameplay_keep_Blob_083534); + Keyframe_FlexPlayOnce(&this->unk_18CC, &gameplay_keep_Blob_083534); func_80AF0838(this->unk_15C); func_80AF1730(&this->unk_148); @@ -495,20 +495,20 @@ void func_80AF1B68(EnTest7* this, PlayState* play) { void func_80AF1CA0(EnTest7* this, PlayState* play) { Vec3f sp34; - if (func_80183DE0(&this->unk_18CC)) { + if (Keyframe_UpdateFlex(&this->unk_18CC)) { func_80AF082C(this, func_80AF1E44); } - if (this->unk_18CC.frameCtrl.unk_10 > 60.0f) { + if (this->unk_18CC.frameCtrl.curTime > 60.0f) { func_80AF1B68(this, play); } - if ((this->unk_18CC.frameCtrl.unk_10 > 20.0f) && !(this->unk_144 & 0x40)) { + if ((this->unk_18CC.frameCtrl.curTime > 20.0f) && !(this->unk_144 & 0x40)) { this->unk_144 |= 0x40; Audio_PlaySfx_AtPos(&this->actor.projectedPos, NA_SE_PL_WARP_WING_CLOSE); } - if (this->unk_18CC.frameCtrl.unk_10 > 42.0f) { + if (this->unk_18CC.frameCtrl.curTime > 42.0f) { if (!(this->unk_144 & 0x80)) { this->unk_144 |= 0x80; Audio_PlaySfx_AtPos(&this->actor.projectedPos, NA_SE_PL_WARP_WING_ROLL); @@ -945,7 +945,7 @@ void EnTest7_Update(Actor* thisx, PlayState* play) { func_80AF118C(play, this->unk_15C, this, (this->unk_144 & 8) != 0, (this->unk_144 & 0x10) != 0); } -s32 func_80AF31D0(PlayState* play, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, Actor* thisx, +s32 func_80AF31D0(PlayState* play, KFSkelAnimeFlex* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, Actor* thisx, Vec3f* scale, Vec3s* rot, Vec3f* pos) { EnTest7* this = THIS; Vec3f sp18; @@ -963,10 +963,10 @@ void EnTest7_Draw(Actor* thisx, PlayState* play) { s32 sp40; if (this->unk_144 & 1) { - Mtx* mtx = GRAPH_ALLOC(play->state.gfxCtx, this->unk_18CC.unk_18->unk_1 * sizeof(Mtx)); + Mtx* mtx = GRAPH_ALLOC(play->state.gfxCtx, this->unk_18CC.skeleton->dListCount * sizeof(Mtx)); if (mtx != NULL) { - func_8018450C(play, &this->unk_18CC, mtx, func_80AF31D0, NULL, &this->actor); + Keyframe_DrawFlex(play, &this->unk_18CC, mtx, func_80AF31D0, NULL, &this->actor); } else { return; } diff --git a/mm/src/overlays/actors/ovl_En_Test7/z_en_test7.h b/mm/src/overlays/actors/ovl_En_Test7/z_en_test7.h index 30bf8e73c..5ba5e8120 100644 --- a/mm/src/overlays/actors/ovl_En_Test7/z_en_test7.h +++ b/mm/src/overlays/actors/ovl_En_Test7/z_en_test7.h @@ -45,7 +45,7 @@ typedef struct EnTest7 { /* 0x0144 */ s32 unk_144; /* 0x0148 */ EnTest7Struct unk_148; /* 0x015C */ EnTest7Struct2 unk_15C[100]; - /* 0x18CC */ SkeletonInfo unk_18CC; + /* 0x18CC */ KFSkelAnimeFlex unk_18CC; /* 0x18FC */ Vec3s unk_18FC[114]; /* 0x1BA8 */ Vec3s unk_1BA8[114]; /* 0x1E54 */ s32 unk_1E54;