From 1c4a3047dea5649ad703779cdc07854fc623260d Mon Sep 17 00:00:00 2001 From: fullgrowngaming <42490167+fullgrowngaming@users.noreply.github.com> Date: Sun, 11 Oct 2020 10:31:06 -0700 Subject: [PATCH] z_skelanime OK (#34) * initial skelanime commit * Skelanime OK * Forgot to add z64animation.h and skelanime.c --- include/functions.h | 209 ++-- include/macros.h | 15 + include/variables.h | 4 +- include/z64.h | 4 +- include/z64animation.h | 251 +++++ linker_scripts/code_script.txt | 4 +- src/code/z_skelanime.c | 1735 +++++++++++++++++++++++++++++ tables/files_with_nonmatching.txt | 1 + tables/functions.txt | 112 +- tools/gen_mips_to_c_context.py | 2 +- 10 files changed, 2186 insertions(+), 151 deletions(-) create mode 100644 include/z64animation.h create mode 100644 src/code/z_skelanime.c diff --git a/include/functions.h b/include/functions.h index 17fb032c85..ee1a99e21b 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2529,95 +2529,126 @@ void func_80132E9C(void); // func_80132E9C void func_80132FDC(void); // func_80132FDC void func_80133000(void); // func_80133000 void func_80133038(void); // func_80133038 -void func_801330E0(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); // func_801330E0 -void func_801332F0(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); // func_801332F0 -void func_801334A0(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); // func_801334A0 -void func_80133710(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); // func_80133710 -void func_80133948(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); // func_80133948 -void func_80133B3C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // func_80133B3C -void func_80133CDC(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); // func_80133CDC -void func_80133F28(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); // func_80133F28 -void func_80134148(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); // func_80134148 -void func_801343C0(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); // func_801343C0 -void func_80134600(void); // func_80134600 -void func_80134724(void); // func_80134724 -void func_80134748(void); // func_80134748 -void func_80134774(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); // func_80134774 -void func_80134990(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); // func_80134990 -void func_80134B54(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); // func_80134B54 -void func_80134DBC(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); // func_80134DBC -void func_80134FFC(void); // func_80134FFC -void func_801353D4(void); // func_801353D4 -void func_801353F8(void); // func_801353F8 -void func_8013541C(void); // func_8013541C -void func_80135448(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // func_80135448 -void func_801358C8(UNK_PTR param_1); // func_801358C8 -void func_801358D4(void); // func_801358D4 -void func_801358F4(void); // func_801358F4 -void func_8013591C(void); // func_8013591C -void func_80135954(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // func_80135954 -void func_80135A28(void); // func_80135A28 -void func_80135A90(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // func_80135A90 -void func_80135B00(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // func_80135B00 -void func_80135B70(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // func_80135B70 -void func_80135BE0(void); // func_80135BE0 -void func_80135C3C(void); // func_80135C3C -void func_80135C6C(void); // func_80135C6C -void func_80135CDC(void); // func_80135CDC -void func_80135D38(void); // func_80135D38 -void func_80135DB8(void); // func_80135DB8 -void func_80135E3C(void); // func_80135E3C -void func_80135EE8(void); // func_80135EE8 -void func_80135F88(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); // func_80135F88 -void func_801360A8(void); // func_801360A8 -void func_801360E0(void); // func_801360E0 -void func_80136104(void); // func_80136104 -void func_801361BC(void); // func_801361BC -void func_80136288(void); // func_80136288 -void func_8013631C(void); // func_8013631C -void func_801363F0(void); // func_801363F0 -void func_80136414(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_TYPE1 param_7, UNK_TYPE4 param_8); // func_80136414 -void func_8013658C(void); // func_8013658C -void func_801365EC(void); // func_801365EC -void func_80136650(void); // func_80136650 -void func_801366AC(void); // func_801366AC -void func_8013670C(void); // func_8013670C -void func_8013673C(void); // func_8013673C -void func_8013676C(void); // func_8013676C -void func_801367B0(void); // func_801367B0 -void func_801367F4(void); // func_801367F4 -void func_8013682C(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); // func_8013682C -void func_801368CC(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); // func_801368CC -void func_8013696C(void); // func_8013696C -void func_80136990(void); // func_80136990 -void func_80136A48(void); // func_80136A48 -void func_80136A7C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // func_80136A7C -void func_80136B30(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // func_80136B30 -void func_80136BEC(void); // func_80136BEC -void func_80136C84(void); // func_80136C84 -void func_80136CD0(void); // func_80136CD0 -void func_80136CF4(void); // func_80136CF4 -void func_80136D98(void); // func_80136D98 -void func_80136F04(void); // func_80136F04 -void func_8013702C(void); // func_8013702C -void func_801370B0(void); // func_801370B0 -void func_8013713C(void); // func_8013713C -void func_8013722C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE1 param_6, UNK_TYPE4 param_7, UNK_TYPE1 param_8); // func_8013722C -void func_801373E8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE1 param_6, UNK_TYPE4 param_7); // func_801373E8 -void func_80137430(void); // func_80137430 -void func_80137488(void); // func_80137488 -void func_801374E4(void); // func_801374E4 -void func_80137540(void); // func_80137540 -void func_80137594(void); // func_80137594 -void func_801375CC(void); // func_801375CC -void func_80137624(void); // func_80137624 -void func_80137650(void); // func_80137650 -void func_80137674(void); // func_80137674 -void func_801376DC(void); // func_801376DC -void func_80137748(void); // func_80137748 -void func_801378B8(void); // func_801378B8 -void func_801378E0(void); // func_801378E0 -void func_8013792C(void); // func_8013792C +void SkelAnime_LodDrawLimb(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, s32 dListIndex); +void SkelAnime_LodDraw(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, s32 dListIndex); +void SkelAnime_LodDrawLimbSV(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDrawSV overrideLimbDraw, PostLimbDrawSV postLimbDraw, Actor* actor, s32 dListIndex, + RSPMatrix** mtx); +void SkelAnime_LodDrawSV(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, s32 dListCount, + OverrideLimbDrawSV overrideLimbDraw, PostLimbDrawSV postLimbDraw, Actor* actor, s32 dListIndex); +void SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor); +void SkelAnime_Draw(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor); +void SkelAnime_DrawLimbSV(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, + RSPMatrix** limbMatricies); +void SkelAnime_DrawSV(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, s32 dListCount, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor); +void func_80134148(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkDraw, Actor* actor, + RSPMatrix** mtx); +void func_801343C0(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, s32 dListCount, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkDraw, Actor* actor); +void SkelAnime_AnimateFrame(AnimationHeader* animationSeg, s32 currentFrame, s32 limbCount, Vec3s* dst); +s16 SkelAnime_GetTotalFrames(GenericAnimationHeader *animationSeg); +s16 SkelAnime_GetFrameCount(GenericAnimationHeader* animationSeg); +Gfx* SkelAnime_Draw2Limb(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw2 overrideLimbDraw, PostLimbDraw2 postLimbDraw, Actor* actor, Gfx* gfx); +Gfx* SkelAnime_Draw2(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw2 overrideLimbDraw, PostLimbDraw2 postLimbDraw, Actor* actor, Gfx* gfx); +Gfx* SkelAnime_DrawLimbSV2(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw2 overrideLimbDraw, PostLimbDraw2 postLimbDraw, Actor* actor, RSPMatrix** mtx, + Gfx* gfx); +Gfx* SkelAnime_DrawSV2(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, s32 dListCount, + OverrideLimbDraw2 overrideLimbDraw, PostLimbDraw2 postLimbDraw, Actor* actor, Gfx* gfx); +s32 func_80134FFC(s32 arg0, s32 arg1, Vec3s* dst); +s16 func_801353D4(GenericAnimationHeader* animationSeg); +s16 SkelAnime_GetTotalFrames2(GenericAnimationHeader* animationSeg); +s16 SkelAnime_GetFrameCount2(GenericAnimationHeader* animationSeg); +void SkelAnime_InterpolateVec3s(s32 limbCount, Vec3s* dst, Vec3s* vec2, Vec3s* vec3, f32 unkf); +void SkelAnime_AnimationCtxReset(AnimationContext* animationCtx); +void func_801358D4(GlobalContext *globalCtx); +void func_801358F4(GlobalContext *globalCtx); +AnimationEntry* SkelAnime_NextEntry(AnimationContext* animationCtx, AnimationType type); +void SkelAnime_LoadLinkAnimetion(GlobalContext* globalCtx, LinkAnimetionEntry* linkAnimetionSeg, s32 frame, + s32 limbCount, void* ram); +void SkelAnime_LoadAnimationType1(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src); +void SkelAnime_LoadAnimationType2(GlobalContext* globalCtx, s32 limbCount, Vec3s* arg2, Vec3s* arg3, f32 arg4); +void SkelAnime_LoadAnimationType3(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* index); +void SkelAnime_LoadAnimationType4(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* index); +void SkelAnime_LoadAnimationType5(GlobalContext* globalCtx, Actor* actor, SkelAnime* skelAnime, f32 arg3); +void SkelAnime_LinkAnimetionLoaded(GlobalContext* globalCtx, AnimationEntryType0* entry); +void SkelAnime_AnimationType1Loaded(GlobalContext* globalCtx, AnimationEntryType1* entry); +void SkelAnime_AnimationType2Loaded(GlobalContext* globalCtx, AnimationEntryType2* entry); +void SkelAnime_AnimationType3Loaded(GlobalContext* globalCtx, AnimationEntryType3* entry); +void SkelAnime_AnimationType4Loaded(GlobalContext* globalCtx, AnimationEntryType4* entry); +void SkelAnime_AnimationType5Loaded(GlobalContext* globalCtx, AnimationEntryType5* entry); +void func_80135EE8(GlobalContext* globalCtx, AnimationContext* animationCtx); +void SkelAnime_InitLinkAnimetion(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + LinkAnimetionEntry* linkAnimetionEntrySeg, s32 flags, Vec3s* limbDrawTbl, + Vec3s* transitionDrawTbl, s32 limbBufCount); +void func_801360A8(SkelAnime* skelAnime); +s32 func_801360E0(GlobalContext* globalCtx, SkelAnime* skelAnime); +s32 func_80136104(GlobalContext* globalCtx, SkelAnime* skelAnime); +void func_801361BC(GlobalContext* globalCtx, SkelAnime* skelAnime); +s32 func_80136288(GlobalContext* globalCtx, SkelAnime* skelAnime); +s32 func_8013631C(GlobalContext* globalCtx, SkelAnime* skelAnime); +void SkelAnime_SetTransition(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 transitionRate); +void SkelAnime_ChangeLinkAnim(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 playbackSpeed, f32 frame, f32 frameCount, u8 animationMode, f32 transitionRate); +void SkelAnime_ChangeLinkAnimDefaultStop(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg); +void SkelAnime_ChangeLinkAnimPlaybackStop(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, f32 playbackSpeed); +void SkelAnime_ChangeLinkAnimDefaultRepeat(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg); +void SkelAnime_ChangeLinkAnimPlaybackRepeat(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, f32 playbackSpeed); +void func_8013670C(GlobalContext* globalCtx, SkelAnime* skelAnime); +void func_8013673C(GlobalContext* globalCtx, SkelAnime* skelAnime); +void func_8013676C(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, f32 frame); +void func_801367B0(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, f32 frame); +void func_801367F4(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 frame); +void func_8013682C(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 transitionFrame, LinkAnimetionEntry* linkAnimetionEntrySeg2, f32 frame, f32 transitionRate, + Vec3s* limbDrawTbl); +void func_801368CC(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 transitionFrame, LinkAnimetionEntry* linkAnimetionEntrySeg2, f32 frame, f32 transitionRate, + Vec3s* limbDrawTbl); +void SkelAnime_SetModeStop(SkelAnime* skelAnime); +s32 func_80136990(SkelAnime* skelAnime, f32 arg1, f32 updateRate); +s32 func_80136A48(SkelAnime* skelAnime, f32 arg1); +void SkelAnime_Init(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animationSeg, Vec3s* limbDrawTbl, Vec3s* transitionDrawTable, s32 limbCount); +void SkelAnime_InitSV(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animationSeg, Vec3s* limbDrawTbl, Vec3s* transitionDrawTable, s32 limbCount); +void SkelAnime_InitSkin(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animationSeg); +void func_80136C84(SkelAnime* skelAnime); +s32 SkelAnime_FrameUpdateMatrix(SkelAnime* skelAnime); +s32 func_80136CF4(SkelAnime* skelAnime); +s32 func_80136D98(SkelAnime* skelAnime); +void func_80136F04(SkelAnime* skelAnime); +s32 func_8013702C(SkelAnime* skelAnime); +s32 func_801370B0(SkelAnime* skelAnime); +s32 func_8013713C(SkelAnime* skelAnime); +void SkelAnime_ChangeAnimImpl(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed, f32 frame, + f32 frameCount, u8 animationType, f32 transitionRate, s8 unk2); +void SkelAnime_ChangeAnim(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed, f32 frame, + f32 frameCount, u8 mode, f32 transitionRate); +void SkelAnime_ChangeAnimDefaultStop(SkelAnime* skelAnime, AnimationHeader* animationSeg); +void SkelAnime_ChangeAnimTransitionStop(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 transitionRate); +void SkelAnime_ChangeAnimPlaybackStop(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed); +void SkelAnime_ChangeAnimDefaultRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg); +void SkelAnime_ChangeAnimTransitionRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 transitionRate); +void SkelAnime_ChangeAnimPlaybackRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed); +void SkelAnime_AnimSetStop(SkelAnime* skelAnime); +void SkelAnime_AnimReverse(SkelAnime* skelAnime); +void func_80137674(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* index); +void func_801376DC(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* arg3); +void func_80137748(SkelAnime* skelAnime, Vec3f* pos, s16 angle); +s32 func_801378B8(SkelAnime* skelAnime, f32 arg1); +void SkelAnime_Free(SkelAnime* skelAnime, GlobalContext* globalCtx); +void SkelAnime_CopyVec3s(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src); void func_80137970(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // func_80137970 void func_80137B34(void); // func_80137B34 void func_80137EBC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // func_80137EBC diff --git a/include/macros.h b/include/macros.h index 2928f32103..a06ba888b3 100644 --- a/include/macros.h +++ b/include/macros.h @@ -21,4 +21,19 @@ (curState)->nextGameStateInit = (GameStateFunc)newInit; \ (curState)->nextGameStateSize = sizeof(newStruct); +extern GraphicsContext* oGfxCtx; + +#define OPEN_DISPS(gfxCtx, file, line) \ + { \ + GraphicsContext* oGfxCtx; \ + Gfx* dispRefs[4]; \ + oGfxCtx = gfxCtx; \ + +#define CLOSE_DISPS(gfxCtx, file, line) \ + } \ + (void)0 + +#define GRAPH_ALLOC(gfxCtx, size) \ + ((gfxCtx)->polyOpa.d = (Gfx*)((u8*)(gfxCtx)->polyOpa.d - (size))) + #endif // _MACROS_H_ diff --git a/include/variables.h b/include/variables.h index 887ff204b3..feb79205be 100644 --- a/include/variables.h +++ b/include/variables.h @@ -4043,8 +4043,8 @@ extern Quake2Context sQuake2Context; // D_801F5A90 extern s32 gSceneProcStep; // D_801F5AA0 extern u32 gSceneProcFlags; // D_801F5AA4 extern f32 gSceneProcFlashingAlpha; // D_801F5AA8 -extern UNK_TYPE1 D_801F5AB0; // D_801F5AB0 -extern UNK_TYPE1 D_801F5AB4; // D_801F5AB4 +extern s32 D_801F5AB0; // D_801F5AB0 +extern s32 D_801F5AB4; // D_801F5AB4 extern UNK_TYPE1 D_801F5AC0; // D_801F5AC0 extern UNK_TYPE1 D_801F69D0; // D_801F69D0 extern UNK_TYPE1 D_801F6A10; // D_801F6A10 diff --git a/include/z64.h b/include/z64.h index 13a7c55d40..97c41f8f91 100644 --- a/include/z64.h +++ b/include/z64.h @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -1615,7 +1616,8 @@ struct GlobalContext { /* 0x17000 */ u16 unk17000; /* 0x17002 */ UNK_TYPE1 pad17002[0x2]; /* 0x17004 */ KankyoContext kankyoContext; - /* 0x170F8 */ UNK_TYPE1 pad170F8[0xC90]; + /* 0x170F8 */ UNK_TYPE1 pad170F8[0xC]; + /* 0x17104 */ AnimationContext animationCtx; /* 0x17D88 */ SceneContext sceneContext; /* 0x186E0 */ RoomContext roomContext; /* 0x18760 */ u8 transitionActorCount; diff --git a/include/z64animation.h b/include/z64animation.h new file mode 100644 index 0000000000..b3e14b39ca --- /dev/null +++ b/include/z64animation.h @@ -0,0 +1,251 @@ +#ifndef _Z64_ANIMATION_H +#define _Z64_ANIMATION_H + +#include +#include +#include +#include + +#define LINK_ANIMETION_OFFSET(addr, offset) \ + (((u32)&_link_animetionSegmentRomStart) + ((u32)addr & 0xFFFFFF) + ((u32)offset)) +#define LIMB_DONE 0xFF +#define ANIMATION_ENTRY_MAX 50 + +#define ANIM_FLAG_UPDATEXZ 0x02 +#define ANIM_FLAG_UPDATEY 0x10 + +struct GlobalContext; +struct Actor; +typedef struct SkelAnime SkelAnime; + +typedef struct { + /* 0x000 */ Vec3s translation; // Translation relative to parent limb. root limb is a tranlation for entire model. + /* 0x006 */ u8 firstChildIndex; // The first child's index into the limb table. + /* 0x007 */ u8 nextLimbIndex; // The parent limb's next limb index into the limb table. + /* 0x008 */ Gfx* displayLists[1]; // Display lists for the limb. Index 0 is the normal display list, index 1 is the + // far model display list. +} SkelLimbEntry; // Size = 0xC or 0x10 + +typedef struct { + /* 0x000 */ SkelLimbEntry* limbs[1]; // One or more limbs, index 0 is the root limb. +} Skeleton; // Size >= 4 + +typedef struct { + /* 0x000 */ Skeleton* skeletonSeg; // Segment address of SkelLimbIndex. + /* 0x004 */ u8 limbCount; // Number of limbs in the model. + /* 0x005 */ char unk05[3]; // unknown, maybe padding? + /* 0x008 */ u8 dListCount; // Number of display lists in the model. +} SkeletonHeader; // Size = 0xC + +typedef s16 AnimationRotationValue; + +typedef struct { + /* 0x000 */ u16 x; + /* 0x002 */ u16 y; + /* 0x004 */ u16 z; +} AnimationRotationIndex; // size = 0x06 + +typedef struct { + /* 0x000 */ s16 frameCount; + /* 0x002 */ s16 unk02; +} GenericAnimationHeader; // size = 0x4 + +typedef struct { + /* 0x000 */ GenericAnimationHeader genericHeader; + /* 0x004 */ u32 rotationValueSeg; // referenced as tbl + /* 0x008 */ u32 rotationIndexSeg; // referenced as ref_tbl + /* 0x00C */ u16 limit; +} AnimationHeader; // size = 0x10 + +typedef enum { + ANIMATION_LINKANIMETION, + ANIMATION_TYPE1, + ANIMATION_TYPE2, + ANIMATION_TYPE3, + ANIMATION_TYPE4, + ANIMATION_TYPE5 +} AnimationType; + +typedef struct { + /* 0x000 */ DmaRequest req; + /* 0x020 */ OSMesgQueue msgQueue; + /* 0x038 */ OSMesg msg; +} AnimationEntryType0; // size = 0x3C + +typedef struct { + /* 0x000 */ u8 unk00; + /* 0x001 */ u8 vecCount; + /* 0x004 */ Vec3s* dst; + /* 0x008 */ Vec3s* src; +} AnimationEntryType1; // size = 0xC + +typedef struct { + /* 0x000 */ u8 unk00; + /* 0x001 */ u8 limbCount; + /* 0x004 */ Vec3s* unk04; + /* 0x008 */ Vec3s* unk08; + /* 0x00C */ f32 unk0C; +} AnimationEntryType2; // size = 0x10 + +typedef struct { + /* 0x000 */ u8 unk00; + /* 0x001 */ u8 vecCount; + /* 0x004 */ Vec3s* dst; + /* 0x008 */ Vec3s* src; + /* 0x00C */ u8* index; +} AnimationEntryType3; // size = 0x10 + +typedef struct { + /* 0x000 */ u8 unk00; + /* 0x001 */ u8 vecCount; + /* 0x002 */ char unk02[0x2]; + /* 0x004 */ Vec3s* dst; + /* 0x008 */ Vec3s* src; + /* 0x00C */ u8* index; +} AnimationEntryType4; // size = 0x10 + +typedef struct { + /* 0x000 */ struct Actor* actor; + /* 0x004 */ SkelAnime* skelAnime; + /* 0x008 */ f32 unk08; +} AnimationEntryType5; // size = 0xC + +typedef struct { + /* 0x000 */ u8 raw[0x3C]; +} AnimationEntryRaw; // size = 0x3C + +typedef union { + AnimationEntryRaw raw; + AnimationEntryType0 type0; + AnimationEntryType1 type1; + AnimationEntryType2 type2; + AnimationEntryType3 type3; + AnimationEntryType4 type4; + AnimationEntryType5 type5; +} AnimationEntryType; // size = 0x3C + +typedef struct { + /* 0x000 */ u8 type; + /* 0x001 */ u8 unk01; + /* 0x004 */ AnimationEntryType types; +} AnimationEntry; // size = 0x40 + +typedef struct AnimationContext { + /* 0x000 */ s16 animationCount; + /* 0x002 */ char unk02[2]; + /* 0x004 */ AnimationEntry entries[ANIMATION_ENTRY_MAX]; +} AnimationContext; // size = 0xC84 + +typedef struct { + /* 0x000 */ GenericAnimationHeader genericHeader; + /* 0x004 */ u32 animationSegAddress; +} LinkAnimetionEntry; // size = 0x8 + +struct SkelAnime { + /* 0x00 */ u8 limbCount; // joint_Num + /* modes 0 and 1 repeat the animation indefinitely + * modes 2 and 3 play the animaton once then stop + * modes >= 4 play the animation once, and always start at frame 0. + */ + /* 0x01 */ u8 mode; + /* 0x02 */ u8 dListCount; + /* 0x03 */ s8 unk03; + /* 0x04 */ Skeleton* skeleton; + /* 0x08 */ + union { + AnimationHeader* animCurrentSeg; + LinkAnimetionEntry* linkAnimetionSeg; + GenericAnimationHeader* genericSeg; + }; + /* 0x0C */ f32 initialFrame; + /* 0x10 */ f32 animFrameCount; + /* 0x14 */ f32 totalFrames; + /* 0x18 */ f32 animCurrentFrame; + /* 0x1C */ f32 animPlaybackSpeed; + /* 0x20 */ Vec3s* limbDrawTbl; // now_joint + /* 0x24 */ Vec3s* transitionDrawTbl; // morf_joint + /* 0x28 */ f32 transCurrentFrame; + /* 0x2C */ f32 transitionStep; + /* 0x30 */ s32 (*animUpdate)(); + /* 0x34 */ s8 initFlags; + /* 0x35 */ u8 flags; + /* 0x36 */ s16 prevFrameRot; + /* 0x38 */ Vec3s prevFramePos; + /* 0x3E */ Vec3s unk3E; +}; // size = 0x44 + +typedef s32 (*OverrideLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + struct Actor* actor); + +typedef void (*PostLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + struct Actor* actor); + +typedef s32 (*OverrideLimbDraw2)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + struct Actor* actor, Gfx** gfx); + +typedef void (*PostLimbDraw2)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + struct Actor* actor, Gfx** gfx); + +typedef s32 (*OverrideLimbDrawSV)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + struct Actor* actor); + +typedef void (*PostLimbDrawSV)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList1, Gfx** dList2, Vec3s* rot, + struct Actor* actor); + +typedef void (*UnkActorDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* actor); + +typedef void (*AnimationEntryCallback)(struct GlobalContext*, AnimationEntryType*); + +extern u32 link_animetion_segment; + +// fcurve_skelanime structs +typedef struct { + /* 0x0000 */ u16 unk00; // appears to be flags + /* 0x0002 */ s16 unk02; + /* 0x0004 */ s16 unk04; + /* 0x0006 */ s16 unk06; + /* 0x0008 */ f32 unk08; +} TransformData; // size = 0xC + +typedef struct { + /* 0x0000 */ u8* refIndex; + /* 0x0004 */ TransformData* transformData; + /* 0x0008 */ s16* copyValues; + /* 0x000C */ s16 unk0C; + /* 0x000E */ s16 unk10; +} TransformUpdateIndex; // size 0x10 + +typedef struct { + /* 0x0000 */ u8 firstChildIdx; + /* 0x0001 */ u8 nextLimbIdx; + /* 0x0004 */ Gfx* dList[2]; +} SkelCurveLimb; // size >= 0x8 + +typedef struct { + /* 0x0000 */ SkelCurveLimb** limbs; + /* 0x0004 */ u8 limbCount; +} SkelCurveLimbList; // size = 0x8 + +typedef struct { + /* 0x0000 */ Vec3s scale; + /* 0x0006 */ Vec3s rot; + /* 0x000C */ Vec3s pos; +} LimbTransform; // size = 0x12 + +typedef struct { + /* 0x0000 */ u8 limbCount; + /* 0x0004 */ SkelCurveLimb** limbList; + /* 0x0008 */ TransformUpdateIndex* transUpdIdx; + /* 0x000C */ f32 unk0C; // seems to be unused + /* 0x0010 */ f32 animFinalFrame; + /* 0x0014 */ f32 animSpeed; + /* 0x0018 */ f32 animCurFrame; + /* 0x001C */ LimbTransform* transforms; +} SkelAnimeCurve; // size = 0x20 + +typedef s32 (*OverrideCurveLimbDraw)(struct GlobalContext* globalCtx, SkelAnimeCurve* skelCuve, s32 limbIndex, + struct Actor* actor); +typedef void (*PostCurveLimbDraw)(struct GlobalContext* globalCtx, SkelAnimeCurve* skelCuve, s32 limbIndex, + struct Actor* actor); + +#endif diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index 225cf4d3a5..47e50e8978 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -384,7 +384,7 @@ SECTIONS build/src/code/z_scene_proc.o(.text) build/asm/z_scene_table.o(.text) build/asm/code_0x801323D0.o(.text) - build/asm/z_skelanime.o(.text) + build/src/code/z_skelanime.o(.text) build/asm/z_skin.o(.text) build/asm/z_skin_awb.o(.text) build/asm/code_0x80138BA0.o(.text) @@ -503,7 +503,7 @@ SECTIONS build/asm/code_data_z_scene_proc.o(.data) build/asm/code_data_z_scene_table.o(.data) build/asm/code_data_0x801323D0.o(.data) - build/asm/code_data_z_skelanime.o(.data) + build/src/code/z_skelanime.o(.data) build/asm/code_data_0x80138BA0.o(.data) build/asm/code_data_z_sub_s.o(.data) build/asm/code_data_z_vimode.o(.data) diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c new file mode 100644 index 0000000000..d7fca3c489 --- /dev/null +++ b/src/code/z_skelanime.c @@ -0,0 +1,1735 @@ +#include +#include + +s32 func_80136288(GlobalContext* globalCtx, SkelAnime* skelAnime); +s32 func_8013631C(GlobalContext* globalCtx, SkelAnime* skelAnime); +s32 func_8013702C(SkelAnime* skelAnime); +s32 func_801370B0(SkelAnime* skelAnime); +s32 func_8013713C(SkelAnime* skelAnime); +void SkelAnime_ChangeAnimDefaultRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg); +void func_80137748(SkelAnime* skelAnime, Vec3f* pos, s16 angle); +void SkelAnime_ChangeLinkAnim(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 playbackSpeed, f32 frame, f32 frameCount, u8 animationMode, f32 transitionRate); +void SkelAnime_CopyVec3s(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src); +void SkelAnime_LinkAnimetionLoaded(GlobalContext* globalCtx, AnimationEntryType0* entry); +void SkelAnime_AnimationType1Loaded(GlobalContext* globalCtx, AnimationEntryType1* entry); +void SkelAnime_AnimationType2Loaded(GlobalContext* globalCtx, AnimationEntryType2* entry); +void SkelAnime_AnimationType3Loaded(GlobalContext* globalCtx, AnimationEntryType3* entry); +void SkelAnime_AnimationType4Loaded(GlobalContext* globalCtx, AnimationEntryType4* entry); +void SkelAnime_AnimationType5Loaded(GlobalContext* globalCtx, AnimationEntryType5* entry); + +static AnimationEntryCallback sAnimationLoadDone[] = { + SkelAnime_LinkAnimetionLoaded, SkelAnime_AnimationType1Loaded, SkelAnime_AnimationType2Loaded, + SkelAnime_AnimationType3Loaded, SkelAnime_AnimationType4Loaded, SkelAnime_AnimationType5Loaded, +}; + +s32 D_801F5AB0; +s32 D_801F5AB4; + +/* + * Draws the limb at `limbIndex` with a level of detail display lists index by `dListIndex` + */ +void SkelAnime_LodDrawLimb(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, s32 dListIndex) { + SkelLimbEntry* limbEntry; + Gfx* dList; + Vec3f pos; + Vec3s rot; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s32 pad; + + SysMatrix_StatePush(); + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[limbIndex]); + limbIndex++; + rot = limbDrawTable[limbIndex]; + + pos.x = limbEntry->translation.x; + pos.y = limbEntry->translation.y; + pos.z = limbEntry->translation.z; + + dList = limbEntry->displayLists[dListIndex]; + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, limbIndex, &dList, &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList != NULL) { + Gfx* polyTemp = gfxCtx->polyOpa.p; + + gSPMatrix(polyTemp, SysMatrix_AppendStateToPolyOpaDisp(globalCtx->state.gfxCtx), G_MTX_LOAD); + + gSPDisplayList(polyTemp + 1, dList); + gfxCtx->polyOpa.p = polyTemp + 2; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &dList, &rot, actor); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + SkelAnime_LodDrawLimb(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, dListIndex); + } + + SysMatrix_StatePop(); + + if (limbEntry->nextLimbIndex != LIMB_DONE) { + SkelAnime_LodDrawLimb(globalCtx, limbEntry->nextLimbIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, dListIndex); + } +} + +/* + * Draws the Skeleton described by `skeleton` with a level of detail display list indexed by `dListIndex` + */ +void SkelAnime_LodDraw(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, s32 dListIndex) { + SkelLimbEntry* limbEntry; + s32 pad; + Gfx* dList; + Vec3f pos; + Vec3s rot; + GraphicsContext* gfxCtx; + s32 pad2; + + if (skeleton == NULL) { + return; + } + + gfxCtx = globalCtx->state.gfxCtx; + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[0]); + pos.x = limbDrawTable[0].x; + pos.y = limbDrawTable[0].y; + pos.z = limbDrawTable[0].z; + + rot = limbDrawTable[1]; + dList = limbEntry->displayLists[dListIndex]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, 1, &dList, &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList != NULL) { + Gfx* polyTemp = gfxCtx->polyOpa.p; + + gSPMatrix(polyTemp, SysMatrix_AppendStateToPolyOpaDisp(globalCtx->state.gfxCtx), G_MTX_LOAD); + + gSPDisplayList(polyTemp + 1, dList); + + gfxCtx->polyOpa.p = polyTemp + 2; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &dList, &rot, actor); + } + + if (limbEntry->firstChildIndex != 0xFF) { + SkelAnime_LodDrawLimb(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, dListIndex); + } + + SysMatrix_StatePop(); +} + +/* + * Draws the limb at `limbIndex` with a level of detail display lists index by `dListIndex`, Limb matrices come + * from a dynamic allocation from the graph arena. + */ +void SkelAnime_LodDrawLimbSV(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDrawSV overrideLimbDraw, PostLimbDrawSV postLimbDraw, Actor* actor, + s32 dListIndex, RSPMatrix** mtx) { + SkelLimbEntry* limbEntry; + Gfx* dList[2]; + Vec3f pos; + Vec3s rot; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s32 pad; + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[limbIndex]); + limbIndex++; + + rot = limbDrawTable[limbIndex]; + + pos.x = limbEntry->translation.x; + pos.y = limbEntry->translation.y; + pos.z = limbEntry->translation.z; + // Double assignment here would not work. + dList[0] = limbEntry->displayLists[dListIndex]; + dList[1] = dList[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, limbIndex, &dList[1], &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList[1] != NULL) { + SysMatrix_GetStateAsRSPMatrix(*mtx); + gSPMatrix(gfxCtx->polyOpa.p++, *mtx, G_MTX_LOAD); + gSPDisplayList(gfxCtx->polyOpa.p++, dList[1]); + (*mtx)++; + } else if (dList[0] != NULL) { + SysMatrix_GetStateAsRSPMatrix(*mtx); + (*mtx)++; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &dList[1], &dList[0], &rot, actor); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + SkelAnime_LodDrawLimbSV(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, dListIndex, mtx); + } + + SysMatrix_StatePop(); + + if (limbEntry->nextLimbIndex != LIMB_DONE) { + SkelAnime_LodDrawLimbSV(globalCtx, limbEntry->nextLimbIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, dListIndex, mtx); + } +} + +/* + * Draws the Skeleton described by `skeleton` with a level of detail display list indexed by `dListIndex` + * Matricies for the limbs are dynamically allocted from the graph arena. The dynamic allocation occurs + * because the Skeleton is too large to be supported by the normal matrix stack. + */ +void SkelAnime_LodDrawSV(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, s32 dListCount, + OverrideLimbDrawSV overrideLimbDraw, PostLimbDrawSV postLimbDraw, Actor* actor, + s32 dListIndex) { + SkelLimbEntry* limbEntry; + s32 pad; + Gfx* dList[2]; + Vec3f pos; + Vec3s rot; + RSPMatrix* mtx; + GraphicsContext* gfxCtx; + s32 pad2; + + mtx = (RSPMatrix*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(RSPMatrix) * dListCount)); + + if (skeleton == NULL) { + return; + } + + gfxCtx = globalCtx->state.gfxCtx; + + gSPSegment(gfxCtx->polyOpa.p++, 0xD, mtx); + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[0]); + pos.x = limbDrawTable[0].x; + pos.y = limbDrawTable[0].y; + pos.z = limbDrawTable[0].z; + + rot = limbDrawTable[1]; + + dList[0] = limbEntry->displayLists[dListIndex]; + dList[1] = dList[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, 1, &dList[1], &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList[1] != NULL) { + Gfx* polyTemp = gfxCtx->polyOpa.p; + + gSPMatrix(polyTemp, SysMatrix_GetStateAsRSPMatrix(mtx), G_MTX_LOAD); + gSPDisplayList(polyTemp + 1, dList[1]); + gfxCtx->polyOpa.p = polyTemp + 2; + mtx++; + } else if (dList[0] != NULL) { + SysMatrix_GetStateAsRSPMatrix(mtx); + mtx++; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &dList[1], &dList[0], &rot, actor); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + SkelAnime_LodDrawLimbSV(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, dListIndex, &mtx); + } + + SysMatrix_StatePop(); +} + +/* + * Draws the limb of the Skeleton `skeleton` at `limbIndex` + */ +void SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor) { + SkelLimbEntry* limbEntry; + Gfx* dList; + Vec3f pos; + Vec3s rot; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s32 pad; + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[limbIndex]); + limbIndex++; + rot = limbDrawTable[limbIndex]; + pos.x = limbEntry->translation.x; + pos.y = limbEntry->translation.y; + pos.z = limbEntry->translation.z; + dList = limbEntry->displayLists[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, limbIndex, &dList, &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList != NULL) { + Gfx* polyTemp = gfxCtx->polyOpa.p; + + gSPMatrix(polyTemp, SysMatrix_AppendStateToPolyOpaDisp(globalCtx->state.gfxCtx), G_MTX_LOAD); + gSPDisplayList(polyTemp + 1, dList); + gfxCtx->polyOpa.p = polyTemp + 2; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &dList, &rot, actor); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + SkelAnime_DrawLimb(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor); + } + + SysMatrix_StatePop(); + + if (limbEntry->nextLimbIndex != LIMB_DONE) { + SkelAnime_DrawLimb(globalCtx, limbEntry->nextLimbIndex, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, + actor); + } +} + +void SkelAnime_Draw(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor) { + SkelLimbEntry* rootLimb; + s32 pad; + Gfx* dList; + Vec3f pos; + Vec3s rot; + GraphicsContext* gfxCtx; + s32 pad2; + + if (skeleton == NULL) { + return; + } + + gfxCtx = globalCtx->state.gfxCtx; + + SysMatrix_StatePush(); + rootLimb = Lib_PtrSegToVirt(skeleton->limbs[0]); + + pos.x = limbDrawTable[0].x; + pos.y = limbDrawTable[0].y; + pos.z = limbDrawTable[0].z; + + rot = limbDrawTable[1]; + dList = rootLimb->displayLists[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, 1, &dList, &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList != NULL) { + Gfx* polyTemp = gfxCtx->polyOpa.p; + + gSPMatrix(polyTemp, SysMatrix_AppendStateToPolyOpaDisp(globalCtx->state.gfxCtx), G_MTX_LOAD); + gSPDisplayList(polyTemp + 1, dList); + gfxCtx->polyOpa.p = polyTemp + 2; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &dList, &rot, actor); + } + + if (rootLimb->firstChildIndex != LIMB_DONE) { + SkelAnime_DrawLimb(globalCtx, rootLimb->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor); + } + + SysMatrix_StatePop(); +} + +void SkelAnime_DrawLimbSV(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, + RSPMatrix** limbMatricies) { + SkelLimbEntry* limbEntry; + Gfx* dList[2]; + Vec3f pos; + Vec3s rot; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s32 pad; + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[limbIndex]); + limbIndex++; + rot = limbDrawTable[limbIndex]; + + pos.x = limbEntry->translation.x; + pos.y = limbEntry->translation.y; + pos.z = limbEntry->translation.z; + + dList[0] = limbEntry->displayLists[0]; + dList[1] = dList[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, limbIndex, &dList[1], &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList[1] != NULL) { + SysMatrix_GetStateAsRSPMatrix(*limbMatricies); + gSPMatrix(gfxCtx->polyOpa.p++, *limbMatricies, G_MTX_LOAD); + gSPDisplayList(gfxCtx->polyOpa.p++, dList[1]); + (*limbMatricies)++; + } else if (dList[0] != NULL) { + SysMatrix_GetStateAsRSPMatrix(*limbMatricies); + (*limbMatricies)++; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &dList[0], &rot, actor); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + SkelAnime_DrawLimbSV(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, limbMatricies); + } + + SysMatrix_StatePop(); + + if (limbEntry->nextLimbIndex != LIMB_DONE) { + SkelAnime_DrawLimbSV(globalCtx, limbEntry->nextLimbIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, limbMatricies); + } +} + +void SkelAnime_DrawSV(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, s32 dListCount, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor) { + SkelLimbEntry* limbEntry; + s32 pad; + Gfx* dList[2]; + Vec3f pos; + Vec3s rot; + RSPMatrix* mtx; + GraphicsContext* gfxCtx; + s32 pad2; + + mtx = (RSPMatrix*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(RSPMatrix) * dListCount)); + + if (skeleton == NULL) { + return; + } + + gfxCtx = globalCtx->state.gfxCtx; + + gSPSegment(gfxCtx->polyOpa.p++, 0xD, mtx); + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[0]); + + pos.x = limbDrawTable[0].x; + pos.y = limbDrawTable[0].y; + pos.z = limbDrawTable[0].z; + rot = limbDrawTable[1]; + + dList[0] = limbEntry->displayLists[0]; + dList[1] = dList[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, 1, &dList[1], &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList[1] != NULL) { + Gfx* polyTemp = gfxCtx->polyOpa.p; + + gSPMatrix(polyTemp, SysMatrix_GetStateAsRSPMatrix(mtx), G_MTX_LOAD); + gSPDisplayList(polyTemp + 1, dList[1]); + gfxCtx->polyOpa.p = polyTemp + 2; + mtx++; + } else { + if (dList[0] != NULL) { + SysMatrix_GetStateAsRSPMatrix(mtx); + mtx++; + } + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &dList[0], &rot, actor); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + SkelAnime_DrawLimbSV(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, &mtx); + } + + SysMatrix_StatePop(); +} + +void func_80134148(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkDraw, Actor* actor, + RSPMatrix** mtx) { + SkelLimbEntry* limbEntry; + Gfx* dList[2]; + Vec3f pos; + Vec3s rot; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s32 pad2; + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[limbIndex]); + limbIndex++; + + rot = limbDrawTable[limbIndex]; + pos.x = limbEntry->translation.x; + pos.y = limbEntry->translation.y; + pos.z = limbEntry->translation.z; + + dList[0] = limbEntry->displayLists[0]; + dList[1] = dList[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, limbIndex, &dList[1], &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + SysMatrix_StatePush(); + unkDraw(globalCtx, limbIndex, actor); + if (dList[1] != NULL) { + Gfx* polyTemp = gfxCtx->polyOpa.p; + + gSPMatrix(polyTemp, SysMatrix_GetStateAsRSPMatrix(*mtx), G_MTX_LOAD); + gSPDisplayList(polyTemp + 1, dList[1]); + gfxCtx->polyOpa.p = polyTemp + 2; + (*mtx)++; + } else { + if (dList[0] != NULL) { + SysMatrix_GetStateAsRSPMatrix(*mtx); + (*mtx)++; + } + } + SysMatrix_StatePop(); + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &dList[0], &rot, actor); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + func_80134148(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, + unkDraw, actor, mtx); + } + + SysMatrix_StatePop(); + + if (limbEntry->nextLimbIndex != LIMB_DONE) { + func_80134148(globalCtx, limbEntry->nextLimbIndex, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, + unkDraw, actor, mtx); + } +} + +void func_801343C0(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, s32 dListCount, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkDraw, Actor* actor) { + SkelLimbEntry* limbEntry; + s32 pad; + Gfx* dList[2]; + Vec3f pos; + Vec3s rot; + RSPMatrix* mtx; + GraphicsContext* gfxCtx; + s32 pad2; + + if (skeleton == NULL) { + return; + } + + gfxCtx = globalCtx->state.gfxCtx; + + mtx = (RSPMatrix*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(RSPMatrix) * dListCount)); + + gSPSegment(gfxCtx->polyOpa.p++, 0xD, mtx); + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[0]); + + pos.x = limbDrawTable[0].x; + pos.y = limbDrawTable[0].y; + pos.z = limbDrawTable[0].z; + rot = limbDrawTable[1]; + + dList[0] = limbEntry->displayLists[0]; + dList[1] = dList[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, 1, &dList[1], &pos, &rot, actor) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + SysMatrix_StatePush(); + unkDraw(globalCtx, 1, actor); + if (dList[1] != NULL) { + Gfx* polyTemp = gfxCtx->polyOpa.p; + + gSPMatrix(polyTemp, SysMatrix_GetStateAsRSPMatrix(mtx), G_MTX_LOAD); + gSPDisplayList(polyTemp + 1, dList[1]); + gfxCtx->polyOpa.p = polyTemp + 2; + mtx++; + } else { + if (dList[0] != NULL) { + SysMatrix_GetStateAsRSPMatrix(mtx++); + } + } + SysMatrix_StatePop(); + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &dList[0], &rot, actor); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + func_80134148(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, + unkDraw, actor, &mtx); + } + + SysMatrix_StatePop(); +} + +/* + * Copies the rotation values from the rotation value table, indexed by the rotation index table + * When a rotation index is >= the animation limit, the output rotation value is copied from the frame's + * rotation value list, otherwise it is copied from the initial rotation value list + */ +void SkelAnime_AnimateFrame(AnimationHeader* animationSeg, s32 currentFrame, s32 limbCount, Vec3s* dst) { + AnimationHeader* animationHeader = Lib_PtrSegToVirt(animationSeg); + AnimationRotationIndex* index = Lib_PtrSegToVirt(animationHeader->rotationIndexSeg); + AnimationRotationValue* rotationValueTable = Lib_PtrSegToVirt(animationHeader->rotationValueSeg); + AnimationRotationValue* frameRotationValueTable = &rotationValueTable[currentFrame]; + s32 i; + u16 limit = animationHeader->limit; + + for (i = 0; i < limbCount; i++) { + // Debug prints here, this is needed to prevent loop unrolling + if (0) { + if (0) {}; + } + dst->x = index->x >= limit ? frameRotationValueTable[index->x] : rotationValueTable[index->x]; + dst->y = index->y >= limit ? frameRotationValueTable[index->y] : rotationValueTable[index->y]; + dst->z = index->z >= limit ? frameRotationValueTable[index->z] : rotationValueTable[index->z]; + index++, dst++; + } +} + +s16 SkelAnime_GetTotalFrames(GenericAnimationHeader* animationSeg) { + GenericAnimationHeader* animation = Lib_PtrSegToVirt(animationSeg); + return animation->frameCount; +} + +s16 SkelAnime_GetFrameCount(GenericAnimationHeader* animationSeg) { + GenericAnimationHeader* animation = Lib_PtrSegToVirt(animationSeg); + + return (u16)animation->frameCount - 1; +} + +/* + * Draws the Skeleton `skeleton`'s limb at index `limbIndex`. Appends all generated graphics commands to + * `gfx`. Returns a pointer to the next gfx to be appended to. + */ +Gfx* SkelAnime_Draw2Limb(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw2 overrideLimbDraw, PostLimbDraw2 postLimbDraw, Actor* actor, Gfx* gfx) { + SkelLimbEntry* limbEntry; + Gfx* dList; + Vec3f pos; + Vec3s rot; + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[limbIndex]); + limbIndex++; + + rot = limbDrawTable[limbIndex]; + pos.x = limbEntry->translation.x; + pos.y = limbEntry->translation.y; + pos.z = limbEntry->translation.z; + + dList = limbEntry->displayLists[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, limbIndex, &dList, &pos, &rot, actor, &gfx) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList != NULL) { + gSPMatrix(gfx, SysMatrix_AppendStateToPolyOpaDisp(globalCtx->state.gfxCtx), G_MTX_LOAD); + gSPDisplayList(gfx + 1, dList); + gfx = gfx + 2; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &dList, &rot, actor, &gfx); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + gfx = SkelAnime_Draw2Limb(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, gfx); + } + + SysMatrix_StatePop(); + + if (limbEntry->nextLimbIndex != LIMB_DONE) { + gfx = SkelAnime_Draw2Limb(globalCtx, limbEntry->nextLimbIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, gfx); + } + + return gfx; +} + +/* + * Draws the Skeleton `skeleton` Appends all generated graphics to `gfx`, and returns a pointer to the + * next gfx to be appended to. + */ +Gfx* SkelAnime_Draw2(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw2 overrideLimbDraw, PostLimbDraw2 postLimbDraw, Actor* actor, Gfx* gfx) { + SkelLimbEntry* limbEntry; + s32 pad; + Gfx* dList; + Vec3f pos; + Vec3s rot; + + if (skeleton == NULL) { + return NULL; + } + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[0]); + + pos.x = limbDrawTable[0].x; + pos.y = limbDrawTable[0].y; + pos.z = limbDrawTable[0].z; + rot = limbDrawTable[1]; + + dList = limbEntry->displayLists[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, 1, &dList, &pos, &rot, actor, &gfx) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList != NULL) { + gSPMatrix(gfx, SysMatrix_AppendStateToPolyOpaDisp(globalCtx->state.gfxCtx), G_MTX_LOAD); + gSPDisplayList(gfx + 1, dList); + gfx = gfx + 2; + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &dList, &rot, actor, &gfx); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + gfx = SkelAnime_Draw2Limb(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, gfx); + } + + SysMatrix_StatePop(); + + return gfx; +} + +/* + * Draws the Skeleton `skeleton` Appends all generated graphics to `gfx`, and returns a pointer to the + * next gfx to be appended to. Allocates matricies for display lists on the graph heap. + */ +Gfx* SkelAnime_DrawLimbSV2(GlobalContext* globalCtx, s32 limbIndex, Skeleton* skeleton, Vec3s* limbDrawTable, + OverrideLimbDraw2 overrideLimbDraw, PostLimbDraw2 postLimbDraw, Actor* actor, + RSPMatrix** mtx, Gfx* gfx) { + SkelLimbEntry* limbEntry; + Gfx* dList1; + Gfx* dList2; + Vec3f pos; + Vec3s rot; + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[limbIndex]); + limbIndex++; + rot = limbDrawTable[limbIndex]; + + pos.x = limbEntry->translation.x; + pos.y = limbEntry->translation.y; + pos.z = limbEntry->translation.z; + + dList1 = dList2 = limbEntry->displayLists[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, limbIndex, &dList1, &pos, &rot, actor, &gfx) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList1 != NULL) { + gSPMatrix(gfx, SysMatrix_GetStateAsRSPMatrix(*mtx), G_MTX_LOAD); + gSPDisplayList(gfx + 1, dList1); + gfx = gfx + 2; + (*mtx)++; + } else { + if (dList2 != NULL) { + SysMatrix_GetStateAsRSPMatrix(*mtx); + (*mtx)++; + } + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &dList2, &rot, actor, &gfx); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + gfx = SkelAnime_DrawLimbSV2(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, mtx, gfx); + } + + SysMatrix_StatePop(); + + if (limbEntry->nextLimbIndex != LIMB_DONE) { + gfx = SkelAnime_DrawLimbSV2(globalCtx, limbEntry->nextLimbIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, mtx, gfx); + } + + return gfx; +} + +Gfx* SkelAnime_DrawSV2(GlobalContext* globalCtx, Skeleton* skeleton, Vec3s* limbDrawTable, s32 dListCount, + OverrideLimbDraw2 overrideLimbDraw, PostLimbDraw2 postLimbDraw, Actor* actor, Gfx* gfx) { + SkelLimbEntry* limbEntry; + s32 pad; + Gfx* dList1; + Gfx* dList2; + Vec3f pos; + Vec3s rot; + RSPMatrix* mtx; + + if (skeleton == NULL) { + return NULL; + } + + mtx = (RSPMatrix*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(RSPMatrix) * dListCount)); + + gSPSegment(gfx++, 0xD, mtx); + + SysMatrix_StatePush(); + + limbEntry = Lib_PtrSegToVirt(skeleton->limbs[0]); + + pos.x = limbDrawTable[0].x; + pos.y = limbDrawTable[0].y; + pos.z = limbDrawTable[0].z; + + rot = limbDrawTable[1]; + + dList1 = dList2 = limbEntry->displayLists[0]; + + if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, 1, &dList1, &pos, &rot, actor, &gfx) == 0)) { + SysMatrix_RotateAndTranslateState(&pos, &rot); + if (dList1 != NULL) { + gSPMatrix(gfx, SysMatrix_GetStateAsRSPMatrix(mtx), G_MTX_LOAD); + gSPDisplayList(gfx + 1, dList1); + gfx = gfx + 2; + mtx++; + } else { + if (dList2 != NULL) { + SysMatrix_GetStateAsRSPMatrix(mtx); + mtx++; + } + } + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &dList2, &rot, actor, &gfx); + } + + if (limbEntry->firstChildIndex != LIMB_DONE) { + gfx = SkelAnime_DrawLimbSV2(globalCtx, limbEntry->firstChildIndex, skeleton, limbDrawTable, overrideLimbDraw, + postLimbDraw, actor, &mtx, gfx); + } + + SysMatrix_StatePop(); + + return gfx; +} + +//Function is unused. +GLOBAL_ASM("asm/non_matchings/z_skelanime/func_80134FFC.asm") + +s16 func_801353D4(GenericAnimationHeader* animationSeg) { + GenericAnimationHeader* animation = Lib_PtrSegToVirt(animationSeg); + + return animation->unk02; +} + +/* + * Appears to be unused anywhere in the game. Appears to be a clone of + * SkelAnime_GetTotalFrames + */ +s16 SkelAnime_GetTotalFrames2(GenericAnimationHeader* animationSeg) { + GenericAnimationHeader* animation = Lib_PtrSegToVirt(animationSeg); + + return animation->frameCount; +} + +/* + * Appears to be unused anywhere in the game. Appears to be a clone of + * SkelAnime_GetFrameCount + */ +s16 SkelAnime_GetFrameCount2(GenericAnimationHeader* animationSeg) { + GenericAnimationHeader* animation = Lib_PtrSegToVirt(animationSeg); + + return animation->frameCount - 1; +} + +void SkelAnime_InterpolateVec3s(s32 limbCount, Vec3s* dst, Vec3s* vec2, Vec3s* vec3, f32 unkf) { + s32 i; + s16 dist; + s16 temp2; + + if (unkf < 1.0f) { + for (i = 0; i < limbCount; i++, dst++, vec2++, vec3++) { + temp2 = vec2->x; + dist = vec3->x - temp2; + dst->x = (s16)(dist * unkf) + temp2; + temp2 = vec2->y; + dist = vec3->y - temp2; + dst->y = (s16)(dist * unkf) + temp2; + temp2 = vec2->z; + dist = vec3->z - temp2; + dst->z = (s16)(dist * unkf) + temp2; + } + } else { + for (i = 0; i < limbCount; i++, dst++, vec3++) { + dst->x = vec3->x; + dst->y = vec3->y; + dst->z = vec3->z; + } + } +} + +void SkelAnime_AnimationCtxReset(AnimationContext* animationCtx) { + animationCtx->animationCount = 0; +} + +void func_801358D4(GlobalContext* globalCtx) { + D_801F5AB0 *= 2; +} + +void func_801358F4(GlobalContext* globalCtx) { + D_801F5AB4 |= D_801F5AB0; +} + +AnimationEntry* SkelAnime_NextEntry(AnimationContext* animationCtx, AnimationType type) { + AnimationEntry* entry; + s16 index = animationCtx->animationCount; + + if (index >= ANIMATION_ENTRY_MAX) { + return NULL; + } + + animationCtx->animationCount = index + 1; + entry = &animationCtx->entries[index]; + entry->type = type; + return entry; +} + +/* + * The next 6 functions are coordinate with the AnimationType enum + */ + +void SkelAnime_LoadLinkAnimetion(GlobalContext* globalCtx, LinkAnimetionEntry* linkAnimetionSeg, s32 frame, + s32 limbCount, void* ram) { + AnimationEntry* entry; + LinkAnimetionEntry* linkAnimetionEntry; + s32 pad; + + entry = SkelAnime_NextEntry(&globalCtx->animationCtx, ANIMATION_LINKANIMETION); + + if (entry != NULL) { + linkAnimetionEntry = Lib_PtrSegToVirt(linkAnimetionSeg); + osCreateMesgQueue(&entry->types.type0.msgQueue, &entry->types.type0.msg, 1); + DmaMgr_SendRequestImpl( + &entry->types.type0.req, ram, + LINK_ANIMETION_OFFSET(linkAnimetionEntry->animationSegAddress, (sizeof(Vec3s) * limbCount + 2) * frame), + sizeof(Vec3s) * limbCount + 2, 0, &entry->types.type0.msgQueue, NULL); + } +} + +void SkelAnime_LoadAnimationType1(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src) { + AnimationEntry* entry = SkelAnime_NextEntry(&globalCtx->animationCtx, ANIMATION_TYPE1); + + if (entry != NULL) { + entry->types.type1.unk00 = D_801F5AB0; + entry->types.type1.vecCount = vecCount; + entry->types.type1.dst = dst; + entry->types.type1.src = src; + } +} + +void SkelAnime_LoadAnimationType2(GlobalContext* globalCtx, s32 limbCount, Vec3s* arg2, Vec3s* arg3, f32 arg4) { + AnimationEntry* entry = SkelAnime_NextEntry(&globalCtx->animationCtx, ANIMATION_TYPE2); + + if (entry != NULL) { + entry->types.type2.unk00 = D_801F5AB0; + entry->types.type2.limbCount = limbCount; + entry->types.type2.unk04 = arg2; + entry->types.type2.unk08 = arg3; + entry->types.type2.unk0C = arg4; + } +} + +void SkelAnime_LoadAnimationType3(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* index) { + AnimationEntry* entry = SkelAnime_NextEntry(&globalCtx->animationCtx, ANIMATION_TYPE3); + + if (entry != NULL) { + entry->types.type3.unk00 = D_801F5AB0; + entry->types.type3.vecCount = vecCount; + entry->types.type3.dst = dst; + entry->types.type3.src = src; + entry->types.type3.index = index; + } +} + +void SkelAnime_LoadAnimationType4(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* index) { + AnimationEntry* entry = SkelAnime_NextEntry(&globalCtx->animationCtx, ANIMATION_TYPE4); + + if (entry != NULL) { + entry->types.type4.unk00 = D_801F5AB0; + entry->types.type4.vecCount = vecCount; + entry->types.type4.dst = dst; + entry->types.type4.src = src; + entry->types.type4.index = index; + } +} + +void SkelAnime_LoadAnimationType5(GlobalContext* globalCtx, Actor* actor, SkelAnime* skelAnime, f32 arg3) { + AnimationEntry* entry = SkelAnime_NextEntry(&globalCtx->animationCtx, ANIMATION_TYPE5); + + if (entry != NULL) { + entry->types.type5.actor = actor; + entry->types.type5.skelAnime = skelAnime; + entry->types.type5.unk08 = arg3; + } +} + +/* The next functions are callbacks to loading animations */ + +void SkelAnime_LinkAnimetionLoaded(GlobalContext* globalCtx, AnimationEntryType0* entry) { + osRecvMesg(&entry->msgQueue, NULL, OS_MESG_BLOCK); +} + +void SkelAnime_AnimationType1Loaded(GlobalContext* globalCtx, AnimationEntryType1* entry) { + s32 i; + Vec3s* dst; + Vec3s* src; + AnimationEntryRaw* genericEntry = (AnimationEntryRaw*)entry; + + if ((genericEntry->raw[0] & D_801F5AB4) != 0) { + return; + } + + for (dst = entry->dst, src = entry->src, i = 0; i < genericEntry->raw[1]; i++) { + *dst++ = *src++; + } +} + +void SkelAnime_AnimationType2Loaded(GlobalContext* globalCtx, AnimationEntryType2* entry) { + if ((entry->unk00 & D_801F5AB4) == 0) { + SkelAnime_InterpolateVec3s(entry->limbCount, entry->unk04, entry->unk04, entry->unk08, entry->unk0C); + } +} + +void SkelAnime_AnimationType3Loaded(GlobalContext* globalCtx, AnimationEntryType3* entry) { + s32 i; + Vec3s* dst; + Vec3s* src; + u8* index; + AnimationEntryRaw* rawEntry = (AnimationEntryRaw*)entry; + + if ((rawEntry->raw[0] & D_801F5AB4) == 0) { + for (dst = entry->dst, src = entry->src, index = entry->index, i = 0; i < rawEntry->raw[1]; i++, dst++, src++) { + if (*index++) { + *dst = *src; + } + } + } +} + +void SkelAnime_AnimationType4Loaded(GlobalContext* globalCtx, AnimationEntryType4* entry) { + s32 i; + Vec3s* dst; + Vec3s* src; + u8* index; + AnimationEntryRaw* rawEntry = (AnimationEntryRaw*)entry; + + if ((rawEntry->raw[0] & D_801F5AB4) == 0) { + for (dst = entry->dst, src = entry->src, index = entry->index, i = 0; i < rawEntry->raw[1]; i++, dst++, src++) { + if (*index++ < 1U) { + *dst = *src; + } + } + } +} + +void SkelAnime_AnimationType5Loaded(GlobalContext* globalCtx, AnimationEntryType5* entry) { + s32 pad; + Actor* actor = entry->actor; + Vec3f pos; + + func_80137748(entry->skelAnime, &pos, actor->shape.rot.y); + actor->currPosRot.pos.x += (pos.x * actor->scale.x) * entry->unk08; + actor->currPosRot.pos.y += (pos.y * actor->scale.y) * entry->unk08; + actor->currPosRot.pos.z += (pos.z * actor->scale.z) * entry->unk08; +} + +void func_80135EE8(GlobalContext* globalCtx, AnimationContext* animationCtx) { + AnimationEntry* entry = animationCtx->entries; + + for (; animationCtx->animationCount != 0; entry++, animationCtx->animationCount--) { + sAnimationLoadDone[entry->type](globalCtx, &entry->types); + } + + D_801F5AB0 = 1; + D_801F5AB4 = 0; +} + +void SkelAnime_InitLinkAnimetion(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + LinkAnimetionEntry* linkAnimetionEntrySeg, s32 flags, Vec3s* limbDrawTbl, + Vec3s* transitionDrawTbl, s32 limbBufCount) { + SkeletonHeader* skeletonHeader; + s32 headerCount; + s32 limbCount; + u32 allocSize; + + skeletonHeader = Lib_PtrSegToVirt(skeletonHeaderSeg); + headerCount = skeletonHeader->limbCount; + skelAnime->initFlags = flags; + limbCount = (flags & 2) ? headerCount : 1; + + if (flags & 1) { + limbCount += headerCount; + } + + if (flags & 4) { + limbCount += headerCount; + } + + skelAnime->limbCount = limbCount; + skelAnime->dListCount = skeletonHeader->dListCount; + skelAnime->skeleton = Lib_PtrSegToVirt(skeletonHeader->skeletonSeg); + allocSize = sizeof(Vec3s) * limbCount; + + if (flags & 8) { + allocSize += 2; + } + + if (limbDrawTbl == NULL) { + skelAnime->limbDrawTbl = zelda_malloc(allocSize); + skelAnime->transitionDrawTbl = zelda_malloc(allocSize); + } else { + skelAnime->limbDrawTbl = (Vec3s*)ALIGN16((u32)limbDrawTbl); + skelAnime->transitionDrawTbl = (Vec3s*)ALIGN16((u32)transitionDrawTbl); + } + + SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, linkAnimetionEntrySeg, 1.0f, 0.0f, 0.0f, 0, 0.0f); +} + +void func_801360A8(SkelAnime* skelAnime) { + if (skelAnime->mode < 2) { + skelAnime->animUpdate = func_80136288; + } else { + skelAnime->animUpdate = func_8013631C; + } + skelAnime->transCurrentFrame = 0.0f; +} + +s32 func_801360E0(GlobalContext* globalCtx, SkelAnime* skelAnime) { + return skelAnime->animUpdate(globalCtx, skelAnime); +} + +s32 func_80136104(GlobalContext* globalCtx, SkelAnime* skelAnime) { + f32 prevUnk28 = skelAnime->transCurrentFrame; + f32 updateRate = (s32)globalCtx->state.framerateDivisor * 0.5f; + + skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; + if (skelAnime->transCurrentFrame <= 0.0f) { + func_801360A8(skelAnime); + } + + SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->transitionDrawTbl, + 1.0f - (skelAnime->transCurrentFrame / prevUnk28)); + return 0; +} + +void func_801361BC(GlobalContext* globalCtx, SkelAnime* skelAnime) { + SkelAnime_LoadLinkAnimetion(globalCtx, skelAnime->linkAnimetionSeg, skelAnime->animCurrentFrame, + skelAnime->limbCount, skelAnime->limbDrawTbl); + if (skelAnime->transCurrentFrame != 0) { + f32 updateRate = (s32)globalCtx->state.framerateDivisor * 0.5f; + skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; + if (skelAnime->transCurrentFrame <= 0.0f) { + skelAnime->transCurrentFrame = 0.0f; + } else { + SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, + skelAnime->transitionDrawTbl, skelAnime->transCurrentFrame); + } + } +} + +s32 func_80136288(GlobalContext* globalCtx, SkelAnime* skelAnime) { + f32 updateRate = (s32)globalCtx->state.framerateDivisor * 0.5f; + + skelAnime->animCurrentFrame += skelAnime->animPlaybackSpeed * updateRate; + if (skelAnime->animCurrentFrame < 0.0f) { + skelAnime->animCurrentFrame += skelAnime->totalFrames; + } else if (skelAnime->totalFrames <= skelAnime->animCurrentFrame) { + skelAnime->animCurrentFrame -= skelAnime->totalFrames; + } + func_801361BC(globalCtx, skelAnime); + return 0; +} + +s32 func_8013631C(GlobalContext* globalCtx, SkelAnime* skelAnime) { + f32 updateRate = (s32)globalCtx->state.framerateDivisor * 0.5f; + + if (skelAnime->animCurrentFrame == skelAnime->animFrameCount) { + func_801361BC(globalCtx, skelAnime); + return 1; + } + + skelAnime->animCurrentFrame += skelAnime->animPlaybackSpeed * updateRate; + + if (((skelAnime->animCurrentFrame - skelAnime->animFrameCount) * skelAnime->animPlaybackSpeed) > 0.0f) { + skelAnime->animCurrentFrame = skelAnime->animFrameCount; + } else { + if (skelAnime->animCurrentFrame < 0.0f) { + skelAnime->animCurrentFrame += skelAnime->totalFrames; + } else if (skelAnime->totalFrames <= skelAnime->animCurrentFrame) { + skelAnime->animCurrentFrame -= skelAnime->totalFrames; + } + } + func_801361BC(globalCtx, skelAnime); + return 0; +} + +void SkelAnime_SetTransition(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 transitionRate) { + skelAnime->transCurrentFrame = 1.0f; + skelAnime->transitionStep = 1.0f / transitionRate; +} + +void SkelAnime_ChangeLinkAnim(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 playbackSpeed, f32 frame, f32 frameCount, u8 animationMode, f32 transitionRate) { + skelAnime->mode = animationMode; + if ((transitionRate != 0.0f) && + ((linkAnimetionEntrySeg != skelAnime->linkAnimetionSeg) || (frame != skelAnime->animCurrentFrame))) { + if (transitionRate < 0) { + func_801360A8(skelAnime); + SkelAnime_CopyVec3s(skelAnime, skelAnime->transitionDrawTbl, skelAnime->limbDrawTbl); + transitionRate = -transitionRate; + } else { + skelAnime->animUpdate = func_80136104; + SkelAnime_LoadLinkAnimetion(globalCtx, linkAnimetionEntrySeg, (s32)frame, skelAnime->limbCount, + skelAnime->transitionDrawTbl); + } + skelAnime->transCurrentFrame = 1.0f; + skelAnime->transitionStep = 1.0f / transitionRate; + } else { + func_801360A8(skelAnime); + SkelAnime_LoadLinkAnimetion(globalCtx, linkAnimetionEntrySeg, (s32)frame, skelAnime->limbCount, + skelAnime->limbDrawTbl); + skelAnime->transCurrentFrame = 0.0f; + } + + skelAnime->linkAnimetionSeg = linkAnimetionEntrySeg; + skelAnime->animCurrentFrame = 0.0f; + skelAnime->initialFrame = frame; + skelAnime->animCurrentFrame = frame; + skelAnime->animFrameCount = frameCount; + skelAnime->totalFrames = SkelAnime_GetTotalFrames(linkAnimetionEntrySeg); + skelAnime->animPlaybackSpeed = playbackSpeed; +} + +void SkelAnime_ChangeLinkAnimDefaultStop(GlobalContext* globalCtx, SkelAnime* skelAnime, + LinkAnimetionEntry* linkAnimetionEntrySeg) { + SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, linkAnimetionEntrySeg, 1.0f, 0.0f, + SkelAnime_GetFrameCount(&linkAnimetionEntrySeg->genericHeader), 2, 0.0f); +} + +void SkelAnime_ChangeLinkAnimPlaybackStop(GlobalContext* globalCtx, SkelAnime* skelAnime, + LinkAnimetionEntry* linkAnimetionEntrySeg, f32 playbackSpeed) { + SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, linkAnimetionEntrySeg, playbackSpeed, 0.0f, + SkelAnime_GetFrameCount(&linkAnimetionEntrySeg->genericHeader), 2, 0.0f); +} + +void SkelAnime_ChangeLinkAnimDefaultRepeat(GlobalContext* globalCtx, SkelAnime* skelAnime, + LinkAnimetionEntry* linkAnimetionEntrySeg) { + SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, linkAnimetionEntrySeg, 1.0f, 0.0f, + SkelAnime_GetFrameCount(&linkAnimetionEntrySeg->genericHeader), 0, 0.0f); +} + +void SkelAnime_ChangeLinkAnimPlaybackRepeat(GlobalContext* globalCtx, SkelAnime* skelAnime, + LinkAnimetionEntry* linkAnimetionEntrySeg, f32 playbackSpeed) { + SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, linkAnimetionEntrySeg, playbackSpeed, 0.0f, + SkelAnime_GetFrameCount(&linkAnimetionEntrySeg->genericHeader), 0, 0.0f); +} + +void func_8013670C(GlobalContext* globalCtx, SkelAnime* skelAnime) { + SkelAnime_LoadAnimationType1(globalCtx, skelAnime->limbCount, skelAnime->transitionDrawTbl, skelAnime->limbDrawTbl); +} + +void func_8013673C(GlobalContext* globalCtx, SkelAnime* skelAnime) { + SkelAnime_LoadAnimationType1(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->transitionDrawTbl); +} + +void func_8013676C(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 frame) { + SkelAnime_LoadLinkAnimetion(globalCtx, linkAnimetionEntrySeg, (s32)frame, skelAnime->limbCount, + skelAnime->transitionDrawTbl); +} + +void func_801367B0(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 frame) { + SkelAnime_LoadLinkAnimetion(globalCtx, linkAnimetionEntrySeg, (s32)frame, skelAnime->limbCount, + skelAnime->limbDrawTbl); +} + +void func_801367F4(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 frame) { + SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->transitionDrawTbl, + frame); +} + +void func_8013682C(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 transitionFrame, LinkAnimetionEntry* linkAnimetionEntrySeg2, f32 frame, f32 transitionRate, + Vec3s* limbDrawTbl) { + Vec3s* alignedLimbDrawTbl; + SkelAnime_LoadLinkAnimetion(globalCtx, linkAnimetionEntrySeg, (s32)transitionFrame, skelAnime->limbCount, + skelAnime->limbDrawTbl); + + alignedLimbDrawTbl = (Vec3s*)ALIGN16((u32)limbDrawTbl); + + SkelAnime_LoadLinkAnimetion(globalCtx, linkAnimetionEntrySeg2, (s32)frame, skelAnime->limbCount, + alignedLimbDrawTbl); + SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, alignedLimbDrawTbl, + transitionRate); +} + +void func_801368CC(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimetionEntry* linkAnimetionEntrySeg, + f32 transitionFrame, LinkAnimetionEntry* linkAnimetionEntrySeg2, f32 frame, f32 transitionRate, + Vec3s* limbDrawTbl) { + Vec3s* alignedLimbDrawTbl; + + SkelAnime_LoadLinkAnimetion(globalCtx, linkAnimetionEntrySeg, (s32)transitionFrame, skelAnime->limbCount, + skelAnime->transitionDrawTbl); + + alignedLimbDrawTbl = (Vec3s*)ALIGN16((u32)limbDrawTbl); + + SkelAnime_LoadLinkAnimetion(globalCtx, linkAnimetionEntrySeg2, (s32)frame, skelAnime->limbCount, + alignedLimbDrawTbl); + SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->transitionDrawTbl, alignedLimbDrawTbl, + transitionRate); +} + +void SkelAnime_SetModeStop(SkelAnime* skelAnime) { + skelAnime->mode = 2; + func_801360A8(skelAnime); +} + +s32 func_80136990(SkelAnime* skelAnime, f32 arg1, f32 updateRate) { + f32 updateSpeed; + f32 temp_f12; + f32 nextFrame; + + updateSpeed = skelAnime->animPlaybackSpeed * updateRate; + nextFrame = skelAnime->animCurrentFrame - updateSpeed; + if (nextFrame < 0.0f) { + nextFrame += skelAnime->totalFrames; + } else if (skelAnime->totalFrames <= nextFrame) { + nextFrame -= skelAnime->totalFrames; + } + + if ((arg1 == 0.0f) && (updateSpeed > 0.0f)) { + arg1 = skelAnime->totalFrames; + } + + temp_f12 = (nextFrame + updateSpeed) - arg1; + if ((0.0f <= (temp_f12 * updateSpeed)) && (((temp_f12 - updateSpeed) * updateSpeed) < 0.0f)) { + return 1; + } + return 0; +} + +s32 func_80136A48(SkelAnime* skelAnime, f32 arg1) { + f32 updateRate = gFramerateDivisorHalf; + + return func_80136990(skelAnime, arg1, updateRate); +} + +void SkelAnime_Init(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animationSeg, Vec3s* limbDrawTbl, Vec3s* transitionDrawTable, s32 limbCount) { + SkeletonHeader* skeletonHeader; + + skeletonHeader = Lib_PtrSegToVirt(skeletonHeaderSeg); + skelAnime->limbCount = skeletonHeader->limbCount + 1; + skelAnime->skeleton = Lib_PtrSegToVirt(skeletonHeader->skeletonSeg); + if (limbDrawTbl == NULL) { + skelAnime->limbDrawTbl = zelda_malloc(sizeof(*skelAnime->limbDrawTbl) * skelAnime->limbCount); + skelAnime->transitionDrawTbl = zelda_malloc(sizeof(*skelAnime->transitionDrawTbl) * skelAnime->limbCount); + } else { + skelAnime->limbDrawTbl = limbDrawTbl; + skelAnime->transitionDrawTbl = transitionDrawTable; + } + + if (animationSeg != NULL) { + SkelAnime_ChangeAnimDefaultRepeat(skelAnime, animationSeg); + } +} + +void SkelAnime_InitSV(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animationSeg, Vec3s* limbDrawTbl, Vec3s* transitionDrawTable, s32 limbCount) { + SkeletonHeader* skeletonHeader; + + skeletonHeader = Lib_PtrSegToVirt(skeletonHeaderSeg); + skelAnime->limbCount = skeletonHeader->limbCount + 1; + skelAnime->dListCount = skeletonHeader->dListCount; + skelAnime->skeleton = Lib_PtrSegToVirt(skeletonHeader->skeletonSeg); + + if (limbDrawTbl == NULL) { + skelAnime->limbDrawTbl = zelda_malloc(sizeof(*skelAnime->limbDrawTbl) * skelAnime->limbCount); + + skelAnime->transitionDrawTbl = zelda_malloc(sizeof(*skelAnime->transitionDrawTbl) * skelAnime->limbCount); + } else { + skelAnime->limbDrawTbl = limbDrawTbl; + skelAnime->transitionDrawTbl = transitionDrawTable; + } + + if (animationSeg != NULL) { + SkelAnime_ChangeAnimDefaultRepeat(skelAnime, animationSeg); + } +} + +void SkelAnime_InitSkin(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animationSeg) { + SkeletonHeader* skeletonHeader; + + skeletonHeader = Lib_PtrSegToVirt(skeletonHeaderSeg); + skelAnime->limbCount = skeletonHeader->limbCount + 1; + skelAnime->skeleton = Lib_PtrSegToVirt(skeletonHeader->skeletonSeg); + skelAnime->limbDrawTbl = zelda_malloc(sizeof(*skelAnime->limbDrawTbl) * skelAnime->limbCount); + skelAnime->transitionDrawTbl = zelda_malloc(sizeof(*skelAnime->transitionDrawTbl) * skelAnime->limbCount); + + // Debug prints here, required to match. + if (1) {}; + + if (animationSeg != NULL) { + SkelAnime_ChangeAnimDefaultRepeat(skelAnime, animationSeg); + } +} + +void func_80136C84(SkelAnime* skelAnime) { + if (skelAnime->mode < 2) { + skelAnime->animUpdate = func_8013702C; + } else if (skelAnime->mode < 4) { + skelAnime->animUpdate = func_8013713C; + } else { + skelAnime->animUpdate = func_801370B0; + } +} + +s32 SkelAnime_FrameUpdateMatrix(SkelAnime* skelAnime) { + return skelAnime->animUpdate(skelAnime); +} + +s32 func_80136CF4(SkelAnime* skelAnime) { + f32 prevUnk28 = skelAnime->transCurrentFrame; + f32 updateRate = gFramerateDivisorThird; + + skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; + if (skelAnime->transCurrentFrame <= 0.0f) { + func_80136C84(skelAnime); + skelAnime->transCurrentFrame = 0.0f; + } + SkelAnime_InterpolateVec3s(skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->limbDrawTbl, + skelAnime->transitionDrawTbl, 1.0f - (skelAnime->transCurrentFrame / prevUnk28)); + return 0; +} + +s32 func_80136D98(SkelAnime* skelAnime) { + s16 temp_a2 = (s16)(skelAnime->transCurrentFrame * 16384.0f); + s16 temp_a1; + f32 sp28; + f32 phi_f2; + f32 updateRate = gFramerateDivisorThird; + + skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; + if (skelAnime->transCurrentFrame <= 0.0f) { + func_80136C84(skelAnime); + skelAnime->transCurrentFrame = 0.0f; + } + temp_a1 = (s16)(skelAnime->transCurrentFrame * 16384.0f); + if (skelAnime->unk03 < 0) { + sp28 = 1.0f - Math_Coss(temp_a2); + phi_f2 = 1.0f - Math_Coss(temp_a1); + } else { + sp28 = Math_Sins(temp_a2); + phi_f2 = Math_Sins(temp_a1); + } + if (phi_f2 != 0.0f) { + phi_f2 /= sp28; + } else { + phi_f2 = 0.0f; + } + SkelAnime_InterpolateVec3s(skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->limbDrawTbl, + skelAnime->transitionDrawTbl, 1.0f - phi_f2); + return 0; +} + +void func_80136F04(SkelAnime* skelAnime) { + s32 t; + s32 pad[2]; + Vec3s sp38[98]; + f32 temp_f10; + f32 temp_f2; + + SkelAnime_AnimateFrame(skelAnime->animCurrentSeg, skelAnime->animCurrentFrame, skelAnime->limbCount, + skelAnime->limbDrawTbl); + if (skelAnime->mode & 0x1) { + t = (s32)skelAnime->animCurrentFrame; + temp_f10 = t; + temp_f2 = skelAnime->animCurrentFrame - temp_f10; + t++; + if (t >= (s32)skelAnime->totalFrames) { + t = 0; + } + SkelAnime_AnimateFrame(skelAnime->animCurrentSeg, t, skelAnime->limbCount, sp38); + SkelAnime_InterpolateVec3s(skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->limbDrawTbl, sp38, temp_f2); + } + if (skelAnime->transCurrentFrame != 0) { + f32 updateRate = gFramerateDivisorThird; + skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; + if (skelAnime->transCurrentFrame <= 0.0f) { + skelAnime->transCurrentFrame = 0.0f; + return; + } + SkelAnime_InterpolateVec3s(skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->limbDrawTbl, + skelAnime->transitionDrawTbl, skelAnime->transCurrentFrame); + } +} + +s32 func_8013702C(SkelAnime* skelAnime) { + f32 updateRate = gFramerateDivisorThird; + + skelAnime->animCurrentFrame += skelAnime->animPlaybackSpeed * updateRate; + if (skelAnime->animCurrentFrame < 0.0f) { + skelAnime->animCurrentFrame += skelAnime->totalFrames; + } else if (skelAnime->totalFrames <= skelAnime->animCurrentFrame) { + skelAnime->animCurrentFrame -= skelAnime->totalFrames; + } + + func_80136F04(skelAnime); + return 0; +} + +s32 func_801370B0(SkelAnime* skelAnime) { + f32 updateRate = gFramerateDivisorThird; + + skelAnime->animCurrentFrame += skelAnime->animPlaybackSpeed * updateRate; + if (skelAnime->animCurrentFrame < skelAnime->initialFrame) { + skelAnime->animCurrentFrame = + (skelAnime->animCurrentFrame - skelAnime->initialFrame) + skelAnime->animFrameCount; + } else if (skelAnime->animFrameCount <= skelAnime->animCurrentFrame) { + skelAnime->animCurrentFrame = + (skelAnime->animCurrentFrame - skelAnime->animFrameCount) + skelAnime->initialFrame; + } + + func_80136F04(skelAnime); + return 0; +} + +s32 func_8013713C(SkelAnime* skelAnime) { + f32 updateRate = gFramerateDivisorThird; + + if (skelAnime->animCurrentFrame == skelAnime->animFrameCount) { + SkelAnime_AnimateFrame(skelAnime->animCurrentSeg, (s32)skelAnime->animCurrentFrame, skelAnime->limbCount, + skelAnime->limbDrawTbl); + func_80136F04(skelAnime); + return 1; + } + + skelAnime->animCurrentFrame += skelAnime->animPlaybackSpeed * updateRate; + if (((skelAnime->animCurrentFrame - skelAnime->animFrameCount) * skelAnime->animPlaybackSpeed) > 0.0f) { + skelAnime->animCurrentFrame = skelAnime->animFrameCount; + } else { + if (skelAnime->animCurrentFrame < 0.0f) { + skelAnime->animCurrentFrame += skelAnime->totalFrames; + } else { + if (skelAnime->totalFrames <= skelAnime->animCurrentFrame) { + skelAnime->animCurrentFrame -= skelAnime->totalFrames; + } + } + } + func_80136F04(skelAnime); + return 0; +} + +void SkelAnime_ChangeAnimImpl(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed, f32 frame, + f32 frameCount, u8 animationType, f32 transitionRate, s8 unk2) { + skelAnime->mode = animationType; + if ((transitionRate != 0.0f) && + ((animationSeg != skelAnime->animCurrentSeg) || (frame != skelAnime->animCurrentFrame))) { + if (transitionRate < 0) { + func_80136C84(skelAnime); + SkelAnime_CopyVec3s(skelAnime, skelAnime->transitionDrawTbl, skelAnime->limbDrawTbl); + transitionRate = -transitionRate; + } else { + if (unk2 != 0) { + skelAnime->animUpdate = func_80136D98; + skelAnime->unk03 = unk2; + } else { + skelAnime->animUpdate = func_80136CF4; + } + SkelAnime_AnimateFrame(animationSeg, frame, skelAnime->limbCount, skelAnime->transitionDrawTbl); + } + skelAnime->transCurrentFrame = 1.0f; + skelAnime->transitionStep = 1.0f / transitionRate; + } else { + func_80136C84(skelAnime); + SkelAnime_AnimateFrame(animationSeg, frame, skelAnime->limbCount, skelAnime->limbDrawTbl); + skelAnime->transCurrentFrame = 0.0f; + } + + skelAnime->animCurrentSeg = animationSeg; + skelAnime->initialFrame = frame; + skelAnime->animFrameCount = frameCount; + skelAnime->totalFrames = SkelAnime_GetTotalFrames(&animationSeg->genericHeader); + if (skelAnime->mode >= 4) { + skelAnime->animCurrentFrame = 0.0f; + } else { + skelAnime->animCurrentFrame = frame; + if (skelAnime->mode < 2) { + skelAnime->animFrameCount = skelAnime->totalFrames - 1.0f; + } + } + skelAnime->animPlaybackSpeed = playbackSpeed; +} + +void SkelAnime_ChangeAnim(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed, f32 frame, + f32 frameCount, u8 mode, f32 transitionRate) { + SkelAnime_ChangeAnimImpl(skelAnime, animationSeg, playbackSpeed, frame, frameCount, mode, transitionRate, 0); +} + +void SkelAnime_ChangeAnimDefaultStop(SkelAnime* skelAnime, AnimationHeader* animationSeg) { + SkelAnime_ChangeAnim(skelAnime, animationSeg, 1.0f, 0.0f, SkelAnime_GetFrameCount(&animationSeg->genericHeader), 2, + 0.0f); +} + +void SkelAnime_ChangeAnimTransitionStop(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 transitionRate) { + SkelAnime_ChangeAnim(skelAnime, animationSeg, 1.0f, 0, SkelAnime_GetFrameCount(&animationSeg->genericHeader), 2, + transitionRate); +} + +void SkelAnime_ChangeAnimPlaybackStop(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed) { + SkelAnime_ChangeAnim(skelAnime, animationSeg, playbackSpeed, 0.0f, + SkelAnime_GetFrameCount(&animationSeg->genericHeader), 2, 0.0f); +} + +void SkelAnime_ChangeAnimDefaultRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg) { + SkelAnime_ChangeAnim(skelAnime, animationSeg, 1.0f, 0.0f, SkelAnime_GetFrameCount(&animationSeg->genericHeader), 0, + 0.0f); +} + +void SkelAnime_ChangeAnimTransitionRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 transitionRate) { + SkelAnime_ChangeAnim(skelAnime, animationSeg, 1.0f, 0.0f, 0.0f, 0, transitionRate); +} + +void SkelAnime_ChangeAnimPlaybackRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed) { + SkelAnime_ChangeAnim(skelAnime, animationSeg, playbackSpeed, 0.0f, + SkelAnime_GetFrameCount(&animationSeg->genericHeader), 0, 0.0f); +} + +void SkelAnime_AnimSetStop(SkelAnime* skelAnime) { + skelAnime->mode = 2; + skelAnime->animFrameCount = skelAnime->totalFrames; + func_80136C84(skelAnime); +} + +void SkelAnime_AnimReverse(SkelAnime* skelAnime) { + f32 initialFrame = skelAnime->initialFrame; + + skelAnime->initialFrame = skelAnime->animFrameCount; + skelAnime->animPlaybackSpeed = -skelAnime->animPlaybackSpeed; + skelAnime->animFrameCount = initialFrame; +} + +void func_80137674(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* index) { + s32 i; + + for (i = 0; i < skelAnime->limbCount; i++, dst++, src++) { + if (*index++) { + *dst = *src; + } + } +} + +void func_801376DC(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* arg3) { + s32 i; + + for (i = 0; i < skelAnime->limbCount; i++, dst++, src++) { + if (*arg3++ < 1U) { + *dst = *src; + } + } +} + +/* + * Moves `pos` backwards on the xz plane from `angle` + */ +void func_80137748(SkelAnime* skelAnime, Vec3f* pos, s16 angle) { + f32 x; + f32 z; + f32 sin; + f32 cos; + + if (skelAnime->flags & 0x10) { + pos->z = 0.0f; + pos->x = 0.0f; + } else { + // `angle` rotation around y axis. + x = skelAnime->limbDrawTbl->x - skelAnime->prevFramePos.x; + z = skelAnime->limbDrawTbl->z - skelAnime->prevFramePos.z; + sin = Math_Sins(angle); + cos = Math_Coss(angle); + pos->x = x * cos + z * sin; + pos->z = z * cos - x * sin; + } + + skelAnime->prevFramePos.x = skelAnime->limbDrawTbl->x; + skelAnime->limbDrawTbl->x = skelAnime->unk3E.x; + skelAnime->prevFramePos.z = skelAnime->limbDrawTbl->z; + skelAnime->limbDrawTbl->z = skelAnime->unk3E.z; + if (skelAnime->flags & ANIM_FLAG_UPDATEXZ) { + if (skelAnime->flags & ANIM_FLAG_UPDATEY) { + pos->y = 0.0f; + } else { + pos->y = skelAnime->limbDrawTbl->y - skelAnime->prevFramePos.y; + } + skelAnime->prevFramePos.y = skelAnime->limbDrawTbl->y; + skelAnime->limbDrawTbl->y = skelAnime->unk3E.y; + } else { + pos->y = 0.0f; + skelAnime->prevFramePos.y = skelAnime->limbDrawTbl->y; + } + skelAnime->flags &= ~ANIM_FLAG_UPDATEY; +} + +s32 func_801378B8(SkelAnime* skelAnime, f32 arg1) { + return func_80136990(skelAnime, arg1, 1.0f); +} + +void SkelAnime_Free(SkelAnime* skelAnime, GlobalContext* globalCtx) { + if (skelAnime->limbDrawTbl != NULL) { + zelda_free(skelAnime->limbDrawTbl); + } + + if (skelAnime->transitionDrawTbl != NULL) { + zelda_free(skelAnime->transitionDrawTbl); + } +} + +void SkelAnime_CopyVec3s(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src) { + _bcopy(src, dst, sizeof(Vec3s) * skelAnime->limbCount); +} diff --git a/tables/files_with_nonmatching.txt b/tables/files_with_nonmatching.txt index 899251880b..a2dc744258 100644 --- a/tables/files_with_nonmatching.txt +++ b/tables/files_with_nonmatching.txt @@ -590,3 +590,4 @@ ovl_Obj_Swprize_0x80C25360 ovl_En_Invisible_Ruppe_0x80C258A0 ovl_Obj_Ending_0x80C25BC0 ovl_En_Rsn_0x80C25D40 +z_skelanime diff --git a/tables/functions.txt b/tables/functions.txt index 3cf302a0fb..8a295006d7 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -2528,58 +2528,58 @@ 0x80132FDC:("func_80132FDC",), 0x80133000:("func_80133000",), 0x80133038:("func_80133038",), - 0x801330E0:("func_801330E0",), - 0x801332F0:("func_801332F0",), - 0x801334A0:("func_801334A0",), - 0x80133710:("func_80133710",), - 0x80133948:("func_80133948",), - 0x80133B3C:("func_80133B3C",), - 0x80133CDC:("func_80133CDC",), - 0x80133F28:("func_80133F28",), + 0x801330E0:("SkelAnime_LodDrawLimb",), + 0x801332F0:("SkelAnime_LodDraw",), + 0x801334A0:("SkelAnime_LodDrawLimbSV",), + 0x80133710:("SkelAnime_LodDrawSV",), + 0x80133948:("SkelAnime_DrawLimb",), + 0x80133B3C:("SkelAnime_Draw",), + 0x80133CDC:("SkelAnime_DrawLimbSV",), + 0x80133F28:("SkelAnime_DrawSV",), 0x80134148:("func_80134148",), 0x801343C0:("func_801343C0",), - 0x80134600:("func_80134600",), - 0x80134724:("func_80134724",), - 0x80134748:("func_80134748",), - 0x80134774:("func_80134774",), - 0x80134990:("func_80134990",), - 0x80134B54:("func_80134B54",), - 0x80134DBC:("func_80134DBC",), + 0x80134600:("SkelAnime_AnimateFrame",), + 0x80134724:("SkelAnime_GetTotalFrames",), + 0x80134748:("SkelAnime_GetFrameCount",), + 0x80134774:("SkelAnime_Draw2Limb",), + 0x80134990:("SkelAnime_Draw2",), + 0x80134B54:("SkelAnime_DrawLimbSV2",), + 0x80134DBC:("SkelAnime_DrawSV2",), 0x80134FFC:("func_80134FFC",), 0x801353D4:("func_801353D4",), - 0x801353F8:("func_801353F8",), - 0x8013541C:("func_8013541C",), - 0x80135448:("func_80135448",), - 0x801358C8:("func_801358C8",), + 0x801353F8:("SkelAnime_GetTotalFrames2",), + 0x8013541C:("SkelAnime_GetFrameCount2",), + 0x80135448:("SkelAnime_InterpolateVec3s",), + 0x801358C8:("SkelAnime_AnimationCtxReset",), 0x801358D4:("func_801358D4",), 0x801358F4:("func_801358F4",), - 0x8013591C:("func_8013591C",), - 0x80135954:("func_80135954",), - 0x80135A28:("func_80135A28",), - 0x80135A90:("func_80135A90",), - 0x80135B00:("func_80135B00",), - 0x80135B70:("func_80135B70",), - 0x80135BE0:("func_80135BE0",), - 0x80135C3C:("func_80135C3C",), - 0x80135C6C:("func_80135C6C",), - 0x80135CDC:("func_80135CDC",), - 0x80135D38:("func_80135D38",), - 0x80135DB8:("func_80135DB8",), - 0x80135E3C:("func_80135E3C",), + 0x8013591C:("SkelAnime_NextEntry",), + 0x80135954:("SkelAnime_LoadLinkAnimetion",), + 0x80135A28:("SkelAnime_LoadAnimationType1",), + 0x80135A90:("SkelAnime_LoadAnimationType2",), + 0x80135B00:("SkelAnime_LoadAnimationType3",), + 0x80135B70:("SkelAnime_LoadAnimationType4",), + 0x80135BE0:("SkelAnime_LoadAnimationType5",), + 0x80135C3C:("SkelAnime_LinkAnimetionLoaded",), + 0x80135C6C:("SkelAnime_AnimationType1Loaded",), + 0x80135CDC:("SkelAnime_AnimationType2Loaded",), + 0x80135D38:("SkelAnime_AnimationType3Loaded",), + 0x80135DB8:("SkelAnime_AnimationType4Loaded",), + 0x80135E3C:("SkelAnime_AnimationType5Loaded",), 0x80135EE8:("func_80135EE8",), - 0x80135F88:("func_80135F88",), + 0x80135F88:("SkelAnime_InitLinkAnimetion",), 0x801360A8:("func_801360A8",), 0x801360E0:("func_801360E0",), 0x80136104:("func_80136104",), 0x801361BC:("func_801361BC",), 0x80136288:("func_80136288",), 0x8013631C:("func_8013631C",), - 0x801363F0:("func_801363F0",), - 0x80136414:("func_80136414",), - 0x8013658C:("func_8013658C",), - 0x801365EC:("func_801365EC",), - 0x80136650:("func_80136650",), - 0x801366AC:("func_801366AC",), + 0x801363F0:("SkelAnime_SetTransition",), + 0x80136414:("SkelAnime_ChangeLinkAnim",), + 0x8013658C:("SkelAnime_ChangeLinkAnimDefaultStop",), + 0x801365EC:("SkelAnime_ChangeLinkAnimPlaybackStop",), + 0x80136650:("SkelAnime_ChangeLinkAnimDefaultRepeat",), + 0x801366AC:("SkelAnime_ChangeLinkAnimPlaybackRepeat",), 0x8013670C:("func_8013670C",), 0x8013673C:("func_8013673C",), 0x8013676C:("func_8013676C",), @@ -2587,36 +2587,36 @@ 0x801367F4:("func_801367F4",), 0x8013682C:("func_8013682C",), 0x801368CC:("func_801368CC",), - 0x8013696C:("func_8013696C",), + 0x8013696C:("SkelAnime_SetModeStop",), 0x80136990:("func_80136990",), 0x80136A48:("func_80136A48",), - 0x80136A7C:("func_80136A7C",), - 0x80136B30:("func_80136B30",), - 0x80136BEC:("func_80136BEC",), + 0x80136A7C:("SkelAnime_Init",), + 0x80136B30:("SkelAnime_InitSV",), + 0x80136BEC:("SkelAnime_InitSkin",), 0x80136C84:("func_80136C84",), - 0x80136CD0:("func_80136CD0",), + 0x80136CD0:("SkelAnime_FrameUpdateMatrix",), 0x80136CF4:("func_80136CF4",), 0x80136D98:("func_80136D98",), 0x80136F04:("func_80136F04",), 0x8013702C:("func_8013702C",), 0x801370B0:("func_801370B0",), 0x8013713C:("func_8013713C",), - 0x8013722C:("func_8013722C",), - 0x801373E8:("func_801373E8",), - 0x80137430:("func_80137430",), - 0x80137488:("func_80137488",), - 0x801374E4:("func_801374E4",), - 0x80137540:("func_80137540",), - 0x80137594:("func_80137594",), - 0x801375CC:("func_801375CC",), - 0x80137624:("func_80137624",), - 0x80137650:("func_80137650",), + 0x8013722C:("SkelAnime_ChangeAnimImpl",), + 0x801373E8:("SkelAnime_ChangeAnim",), + 0x80137430:("SkelAnime_ChangeAnimDefaultStop",), + 0x80137488:("SkelAnime_ChangeAnimTransitionStop",), + 0x801374E4:("SkelAnime_ChangeAnimPlaybackStop",), + 0x80137540:("SkelAnime_ChangeAnimDefaultRepeat",), + 0x80137594:("SkelAnime_ChangeAnimTransitionRepeat",), + 0x801375CC:("SkelAnime_ChangeAnimPlaybackRepeat",), + 0x80137624:("SkelAnime_AnimSetStop",), + 0x80137650:("SkelAnime_AnimReverse",), 0x80137674:("func_80137674",), 0x801376DC:("func_801376DC",), 0x80137748:("func_80137748",), 0x801378B8:("func_801378B8",), - 0x801378E0:("func_801378E0",), - 0x8013792C:("func_8013792C",), + 0x801378E0:("SkelAnime_Free",), + 0x8013792C:("SkelAnime_CopyVec3s",), 0x80137970:("func_80137970",), 0x80137B34:("func_80137B34",), 0x80137EBC:("func_80137EBC",), diff --git a/tools/gen_mips_to_c_context.py b/tools/gen_mips_to_c_context.py index 104602a684..efcc5a1160 100755 --- a/tools/gen_mips_to_c_context.py +++ b/tools/gen_mips_to_c_context.py @@ -16,7 +16,7 @@ src_dir = root_dir + "src/" def find_build_command_line(c_file): rel_c_file = os.path.relpath(c_file, root_dir) - make_cmd = ["make", "--always-make", "--dry-run", "--debug=j", "PERMUTER=1"] + make_cmd = ["make", "rom.z64", "--always-make", "--dry-run", "--debug=j", "PERMUTER=1"] debug_output = ( subprocess.check_output(make_cmd, cwd=root_dir).decode("utf-8").split("\n") )