summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTharo <17233964+Thar0@users.noreply.github.com>2024-05-17 13:29:19 +0100
committerGitHub <noreply@github.com>2024-05-17 08:29:19 -0400
commitc609d3dcae48ec2bd261c800f6cf75911a7bd1b2 (patch)
treee2af33178a712f1a008d9c61af4c44a5f5dfdab2 /include
parent27aa3f748b838efd6e779655e35c4cd1c38b09e1 (diff)
c_keyframe.c decompiled and documented (#1630)
* 2 non-matching * 1 function left Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Fully matching Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> * Documented, has bss reordering issues * Fixes * Apply suggestions * Format * Re-add cast oops * Remove != 0 for override and transform limb draws, format --------- Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com> Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Diffstat (limited to 'include')
-rw-r--r--include/functions.h41
-rw-r--r--include/macros.h1
-rw-r--r--include/z64.h1
-rw-r--r--include/z64animation.h69
-rw-r--r--include/z64keyframe.h199
5 files changed, 201 insertions, 110 deletions
diff --git a/include/functions.h b/include/functions.h
index a208b48c0..715a385bc 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -588,47 +588,6 @@ s32 Math3D_YZInSphere(Sphere16* sphere, f32 y, f32 z);
// void func_8017FD44(void);
void func_80183070(void);
-// void func_801830A0(void);
-// void func_801830C8(void);
-// void func_801830E8(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_80183148(void);
-// void func_80183224(void);
-// void func_801832B0(void);
-// void func_8018332C(void);
-// void func_8018340C(void);
-void func_80183430(SkeletonInfo* skeletonInfo, void* arg1, void* arg2, Vec3s* arg3, Vec3s* arg4, UnkKeyframeCallback* callbacks);
-void func_8018349C(UNK_PTR arg0);
-void func_801834A8(SkeletonInfo* skeletonInfo, void* arg1);
-// void func_80183510(void);
-// void func_80183580(void);
-void func_801835EC(UNK_PTR arg0, UNK_PTR 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);
-// void func_801837CC(void);
-// void func_80183808(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6);
-// void func_80183880(void);
-// void func_80183A3C(void);
-// void func_80183B08(void);
-// void func_80183B68(void);
-s32 func_80183DE0(SkeletonInfo* skeletonInfo);
-// 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, Actor* actor);
-// 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);
-// void func_801846AC(void);
-// void func_80184728(void);
-// void func_801847A0(void);
-// void func_80184818(void);
-// void func_80184898(void);
-// void func_80184914(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, UNK_TYPE4 param_10);
-// void func_801849A0(void);
-// void func_801849DC(void);
-// void func_80184C48(void);
-// void func_801850A0(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_801853C8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6);
-// void func_80185460(void);
AudioTask* AudioThread_Update(void);
void AudioThread_QueueCmdF32(u32 opArgs, f32 data);
diff --git a/include/macros.h b/include/macros.h
index 6d7433037..1038838e4 100644
--- a/include/macros.h
+++ b/include/macros.h
@@ -65,6 +65,7 @@
0)
#define SQ(x) ((x) * (x))
+#define CB(x) ((x) * (x) * (x))
#define ABS(x) ((x) >= 0 ? (x) : -(x))
#define ABS_ALT(x) ((x) < 0 ? -(x) : (x))
#define DECR(x) ((x) == 0 ? 0 : --(x))
diff --git a/include/z64.h b/include/z64.h
index b4d805ea6..c18c20688 100644
--- a/include/z64.h
+++ b/include/z64.h
@@ -70,6 +70,7 @@
#include "z64rumble.h"
#include "z64transition.h"
#include "z64view.h"
+#include "z64keyframe.h"
#include "regs.h"
diff --git a/include/z64animation.h b/include/z64animation.h
index 4c255a739..bf38b5da6 100644
--- a/include/z64animation.h
+++ b/include/z64animation.h
@@ -244,75 +244,6 @@ typedef struct AnimationSpeedInfo {
/* 0xC */ f32 morphFrames;
} AnimationSpeedInfo; // size = 0x10
-struct SkeletonInfo;
-
-typedef s32 (*UnkKeyframeCallback)(struct PlayState* play, struct SkeletonInfo* skeletonInfo, s32* arg2, Gfx** dList,
- u8* arg4, void* arg5);
-
-// Keyframe limb?
-typedef struct {
- /* 0x0 */ Gfx* dList;
- /* 0x4 */ u8 unk_4;
- /* 0x5 */ u8 flags;
- /* 0x6 */ Vec3s root;
-} Struct_801BFA14_Arg1_Field4; // size = 0xC
-
-// Other limb type?
-typedef struct {
- /* 0x0 */ Gfx* dList;
- /* 0x4 */ u8 unk_4;
- /* 0x5 */ u8 flags;
- /* 0x6 */ u8 unk_6; // transform limb draw index
-} Struct_801BFA14_Arg1_Field4_2; // size = 0x8
-
-typedef struct {
- /* 0x00 */ u8 limbCount;
- /* 0x01 */ u8 unk_1; // non-zero in object files, number of non-null-dlist limbs?
- /* 0x04 */ union {
- Struct_801BFA14_Arg1_Field4* unk_4; // arrays
- Struct_801BFA14_Arg1_Field4_2* unk_4_2;
- };
- /* 0x08 */ s16* unk_8;
- /* 0x0C */ s16* unk_C;
- /* 0x10 */ char unk_10[0x2];
- /* 0x12 */ s16 unk_12;
-} Struct_801BFA14_Arg1; // size = 0x14
-
-typedef struct {
- /* 0x00 */ u16* unk_0;
- /* 0x04 */ s16* unk_4;
- /* 0x08 */ s16* unk_8;
- /* 0x0C */ s16* unk_C;
- /* 0x10 */ char unk_10[0x2];
- /* 0x12 */ s16 unk_12;
-} SkeletonInfo_1C; // size = 0x14
-
-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; // size = 0x18
-
-// 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; // size = 0x30
-
-typedef s32 (*OverrideKeyframeDrawScaled)(struct PlayState* play, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList,
- u8* flags, struct Actor* actor, Vec3f* scale, Vec3s* rot, Vec3f* pos);
-
-typedef s32 (*PostKeyframeDrawScaled)(struct PlayState* play, SkeletonInfo* skeleton, s32 limbIndex, Gfx** dList,
- u8* flags, struct Actor* actor, Vec3f* scale, Vec3s* rot, Vec3f* pos);
-
void SkelAnime_DrawLod(struct PlayState* play, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, struct Actor* actor, s32 lod);
void SkelAnime_DrawFlexLod(struct PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawFlex overrideLimbDraw, PostLimbDrawFlex postLimbDraw, struct Actor* actor, s32 lod);
void SkelAnime_DrawOpa(struct PlayState* play, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, struct Actor* actor);
diff --git a/include/z64keyframe.h b/include/z64keyframe.h
new file mode 100644
index 000000000..10d7f8509
--- /dev/null
+++ b/include/z64keyframe.h
@@ -0,0 +1,199 @@
+#ifndef Z64_KEYFRAME_H
+#define Z64_KEYFRAME_H
+
+#include "ultra64.h"
+#include "z64math.h"
+
+struct PlayState;
+
+struct KFSkelAnime;
+struct KFSkelAnimeFlex;
+
+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 (*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 (*KeyframeTransformCallback)(struct PlayState* play, struct KFSkelAnimeFlex* kfSkelAnime, s32 limbIndex,
+ Gfx** dList, u8* flags, void* arg);
+
+// These flags are mutually exclusive, if XLU is set OPA is not set and vice-versa.
+#define KEYFRAME_DRAW_OPA (0 << 0)
+#define KEYFRAME_DRAW_XLU (1 << 0)
+
+typedef enum {
+ /* 0 */ KEYFRAME_NOT_DONE,
+ /* 1 */ KEYFRAME_DONE_ONCE,
+ /* 2 */ KEYFRAME_DONE_LOOP
+} KeyFrameDoneType;
+
+#define KF_CALLBACK_INDEX_NONE 0xFF
+
+typedef struct {
+ /* 0x00 */ Gfx* dList; // Display list for this limb
+ /* 0x04 */ u8 numChildren; // Number of children for this limb
+ /* 0x05 */ u8 drawFlags; // KEYFRAME_DRAW_*, determines which render layer the matrix + display list will be appended to
+ /* 0x06 */ Vec3s jointPos; // For the root limb this is the position in model space; for child limbs it is the relative position to the parent
+} KeyFrameStandardLimb; // size = 0xC
+
+typedef struct {
+ /* 0x00 */ u8 limbCount; // Number of limbs in this skeleton
+ /* 0x01 */ u8 dListCount; // Number of limbs with a non-NULL display list, used to know how many matrices to allocate for drawing
+ /* 0x04 */ KeyFrameStandardLimb* limbs; // Pointer to standard limb array
+} KeyFrameSkeleton; // Size = 0x8
+
+typedef struct {
+ /* 0x00 */ Gfx* dList; // Display list for this limb
+ /* 0x04 */ u8 numChildren; // Number of children for this limb
+ /* 0x05 */ u8 drawFlags; // KEYFRAME_DRAW_*, determines which render layer the matrix + display list will be appended to
+ /* 0x06 */ u8 callbackIndex; // Transform callback function index, KF_CALLBACK_INDEX_NONE indicates no callback
+} KeyFrameFlexLimb; // size = 0x8
+
+typedef struct {
+ /* 0x00 */ u8 limbCount; // Number of limbs in this skeleton
+ /* 0x01 */ u8 dListCount; // Number of limbs with a non-NULL display list, used to know how many matrices to allocate for drawing
+ /* 0x04 */ KeyFrameFlexLimb* limbs; // Pointer to flex limb array
+} KeyFrameFlexSkeleton; // Size = 0x8
+
+typedef struct {
+ /* 0x00 */ s16 frame; // Frame number for this keyframe
+ /* 0x02 */ s16 value; // Value (any of translation, rotation, scale)
+ /* 0x04 */ s16 velocity; // The instantaneous rate of change of the value
+} KeyFrame; // Size = 0x6
+
+typedef struct {
+ // Array of bitflags for each limb indicating whether to do keyframe interpolation
+ // or pull from fixed values that do not change throughout the animation.
+ union {
+ // For standard the bit layout in each array element is:
+ // [5] X Translation (root limb only)
+ // [4] Y Translation (root limb only)
+ // [3] Z Translation (root limb only)
+ // [2] X Rotation (all limbs)
+ // [1] Y Rotation (all limbs)
+ // [0] Z Rotation (all limbs)
+ /* 0x00 */ u8* standard;
+ // For flex the bit layout in each array element is:
+ // [8] X Scale
+ // [7] Y Scale
+ // [6] Z Scale
+ // [5] X Rotation
+ // [4] Y Rotation
+ // [3] Z Rotation
+ // [2] X Translation
+ // [1] Y Translation
+ // [0] Z Translation
+ /* 0x00 */ u16* flex;
+ } bitFlags;
+ /* 0x04 */ KeyFrame* keyFrames; // Array of keyframes determining the motion, grouped by limb
+ /* 0x08 */ s16* kfNums; // Array containing how many keyframes belong to each limb
+ /* 0x0C */ s16* fixedValues; // Array of fixed rotation (standard skeleton) or scale/rotation/translation (flex skeleton) values
+ /* 0x10 */ UNK_TYPE2 unk_10;
+ /* 0x12 */ s16 frameCount; // Length of the animation in 30fps frames
+} KeyFrameAnimation; // Size = 0x14
+
+typedef enum {
+ /* 0 */ KEYFRAME_ANIM_ONCE, // Play once and stop
+ /* 1 */ KEYFRAME_ANIM_LOOP // Play in a loop
+} KeyFrameAnimMode;
+
+typedef struct {
+ /* 0x00 */ f32 start; // Current animation start frame number
+ /* 0x04 */ f32 end; // Current animation end frame number
+ /* 0x08 */ f32 frameCount; // Current animation total frame count
+ /* 0x0C */ f32 speed; // Current play speed
+ /* 0x10 */ f32 curTime; // Current play frame number
+ /* 0x14 */ s32 animMode; // Current play mode (see FrameAnimMode)
+} FrameControl; // Size = 0x18
+
+typedef struct KFSkelAnime {
+ /* 0x00 */ FrameControl frameCtrl; // Current play state
+ /* 0x18 */ KeyFrameSkeleton* skeleton; // Skeleton to animate
+ /* 0x1C */ KeyFrameAnimation* animation; // Currently active animation
+ /* 0x20 */ f32 morphFrames; // Number of frames in which to morph between the previous pose and the current animation
+ /* 0x24 */ Vec3s* jointTable; // Array of data describing the current pose
+ // size = 1 + limbCount, one root translation followed by rotations for each limb
+ /* 0x28 */ Vec3s* morphTable; // Array of data describing the current morph pose to interpolate with
+ // size = 1 + limbCount, one root translation followed by rotations for each limb
+ /* 0x2C */ Vec3s* rotOffsetsTable; // Table of rotations to add to the current pose, may be NULL so that no additional rotations are added
+ // size = limbCount
+} KFSkelAnime; // Size = 0x30
+
+typedef struct KFSkelAnimeFlex {
+ /* 0x00 */ FrameControl frameCtrl; // Current play state
+ /* 0x18 */ KeyFrameFlexSkeleton* skeleton; // Skeleton to animate
+ /* 0x1C */ KeyFrameAnimation* animation; // Currently active animation
+ /* 0x20 */ KeyframeTransformCallback* transformCallbacks; // Pointer to array of limb transform callbacks, indexed by callbackIndex in KeyFrameFlexLimb
+ /* 0x24 */ f32 morphFrames; // Number of frames in which to morph between the previous pose and the current animation
+ /* 0x28 */ Vec3s* jointTable; // Array of data describing the current pose
+ // size = 3 * limbCount in order of (scale, rotation, translation) for each limb
+ /* 0x2C */ Vec3s* morphTable; // Array of data describing the current morph pose to interpolate with
+ // size = 3 * limbCount in order of (scale, rotation, translation) for each limb
+} KFSkelAnimeFlex; // Size = 0x30
+
+void FrameCtrl_Reset(FrameControl* frameCtrl);
+void FrameCtrl_Init(FrameControl* frameCtrl);
+void FrameCtrl_SetProperties(FrameControl* frameCtrl, f32 startTime, f32 endTime, f32 frameCount, 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, KeyFrameFlexSkeleton* skeleton, KeyFrameAnimation* animation,
+ Vec3s* jointTable, Vec3s* morphTable, KeyframeTransformCallback* transformCallbacks);
+void Keyframe_DestroyFlex(KFSkelAnimeFlex* kfSkelAnime);
+void Keyframe_FlexPlayOnce(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation);
+void Keyframe_FlexPlayOnceSetSpeed(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 speed);
+void Keyframe_FlexMorphToPlayOnce(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 morphFrames);
+void Keyframe_FlexPlayLoop(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation);
+void Keyframe_FlexPlayLoopSetSpeed(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 speed);
+void Keyframe_FlexMorphToPlayLoop(KFSkelAnimeFlex* kfSkelAnime, KeyFrameAnimation* animation, f32 morphFrames);
+void Keyframe_FlexChangeAnim(KFSkelAnimeFlex* kfSkelAnime, KeyFrameFlexSkeleton* 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_MorphInterpolateRotation(f32 t, s16* out, s16 rot1, s16 rot2);
+void Keyframe_MorphInterpolateLinear(s16* jointData, s16* morphData, f32 t);
+void Keyframe_FlexMorphInterpolation(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_StandardPlayOnceSetSpeed(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable,
+ f32 speed);
+void Keyframe_StandardMorphToPlayOnce(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable,
+ f32 morphFrames);
+void Keyframe_StandardPlayLoop(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable);
+void Keyframe_StandardPlayLoopSetSpeed(KFSkelAnime* kfSkelAnime, KeyFrameAnimation* animation, Vec3s* rotOffsetsTable,
+ f32 speed);
+void Keyframe_StandardMorphToPlayLoop(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_StandardMorphInterpolation(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_FlexGetScale(KFSkelAnimeFlex* kfSkelAnime, s32 targetLimbIndex, Vec3s* scale);
+
+#endif