diff options
| author | petrie911 <69443847+petrie911@users.noreply.github.com> | 2020-12-29 16:46:46 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-29 17:46:46 -0500 |
| commit | 2dfa188706524e77ca60984663e17f060bc03529 (patch) | |
| tree | 69c5afc90225d2cb7a4af159c1f07a85bfce7066 /src/code | |
| parent | e4d88bf94287c3661d7ae5195e063f6bef13dfc6 (diff) | |
Docs for the Anime part of SkelAnime (#517)
* Darkmeiro decompilation
Bg_Gnd_Darkmeiro decompiled, matched, and documented.
* give this a shot
* fix conflict
* one more try
* could be useful
* whoops
* ZAP2 stuff
* ZAP why
* ZAP again
* more names
* so many names
* we got subsystems now
* slight cleanup
* merge part 2
* new naming scheme
* slight adjustment
* no limit
* syms maybe
* step one
* OK, it's fixed
* table
* some names and such
* comments**
* update zap
* gitkeep to please jenkins
* ZAP
* fixer
* fixer2
* fixer3
* zap
Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain>
Co-authored-by: fig <fig02srl@gmail.com>
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/z_actor.c | 12 | ||||
| -rw-r--r-- | src/code/z_fcurve_data_skelanime.c | 6 | ||||
| -rw-r--r-- | src/code/z_play.c | 8 | ||||
| -rw-r--r-- | src/code/z_player_lib.c | 45 | ||||
| -rw-r--r-- | src/code/z_skelanime.c | 1307 |
5 files changed, 727 insertions, 651 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c index b5a27fd78..70e572b6b 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -887,7 +887,7 @@ void func_8002D9A4(Actor* actor, f32 arg1) { void func_8002D9F8(Actor* actor, SkelAnime* skelAnime) { Vec3f sp1C; - func_800A54FC(skelAnime, &sp1C, actor->shape.rot.y); + SkelAnime_UpdateTranslation(skelAnime, &sp1C, actor->shape.rot.y); actor->posRot.pos.x += sp1C.x * actor->scale.x; actor->posRot.pos.y += sp1C.y * actor->scale.y; actor->posRot.pos.z += sp1C.z * actor->scale.z; @@ -3806,7 +3806,7 @@ void func_80034BA0(GlobalContext* globalCtx, SkelAnime* skelAnime, OverrideLimbD gDPPipeSync(POLY_OPA_DISP++); gSPSegment(POLY_OPA_DISP++, 0x0C, func_80034B28(globalCtx->state.gfxCtx)); - POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, skelAnime->skeleton, skelAnime->limbDrawTbl, skelAnime->dListCount, + POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, skelAnime->skeleton, skelAnime->jointTable, skelAnime->dListCount, overrideLimbDraw, postLimbDraw, actor, POLY_OPA_DISP); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 8860); @@ -3822,7 +3822,7 @@ void func_80034CC4(GlobalContext* globalCtx, SkelAnime* skelAnime, OverrideLimbD gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, alpha); gSPSegment(POLY_XLU_DISP++, 0x0C, func_80034B54(globalCtx->state.gfxCtx)); - POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, skelAnime->skeleton, skelAnime->limbDrawTbl, skelAnime->dListCount, + POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, skelAnime->skeleton, skelAnime->jointTable, skelAnime->dListCount, overrideLimbDraw, postLimbDraw, actor, POLY_XLU_DISP); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 8904); @@ -3857,11 +3857,11 @@ void func_80034EC0(SkelAnime* skelAnime, struct_80034EC0_Entry* arg1, s32 arg2) if (arg1->frameCount > 0.0f) { frameCount = arg1->frameCount; } else { - frameCount = SkelAnime_GetFrameCount(arg1->animation); + frameCount = Animation_GetLastFrame(arg1->animation); } - SkelAnime_ChangeAnim(skelAnime, arg1->animation, arg1->playbackSpeed, arg1->unk_08, frameCount, arg1->unk_10, - arg1->transitionRate); + Animation_Change(skelAnime, arg1->animation, arg1->playbackSpeed, arg1->unk_08, frameCount, arg1->unk_10, + arg1->transitionRate); } void func_80034F54(GlobalContext* globalCtx, s16* arg1, s16* arg2, s32 arg3) { diff --git a/src/code/z_fcurve_data_skelanime.c b/src/code/z_fcurve_data_skelanime.c index 24c31d92d..e01e0517e 100644 --- a/src/code/z_fcurve_data_skelanime.c +++ b/src/code/z_fcurve_data_skelanime.c @@ -115,9 +115,9 @@ void SkelCurve_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, SkelAnimeCurve* Vec3s* transform; transform = &skelCurve->transforms[limbIndex]; - scale.x = transform->x * (1.0f / 1024.0f); - scale.y = transform->y * (1.0f / 1024.0f); - scale.z = transform->z * (1.0f / 1024.0f); + scale.x = transform->x / 1024.0f; + scale.y = transform->y / 1024.0f; + scale.z = transform->z / 1024.0f; transform++; rot.x = transform->x; rot.y = transform->y; diff --git a/src/code/z_play.c b/src/code/z_play.c index 4d27f4d13..ecce97a8e 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -243,7 +243,7 @@ void Gameplay_Init(GameState* thisx) { Effect_InitContext(globalCtx); EffectSs_InitInfo(globalCtx, 0x55); func_8005D3BC(globalCtx, &globalCtx->colChkCtx); - SkelAnime_AnimationCtxReset(&globalCtx->animationCtx); + AnimationContext_Reset(&globalCtx->animationCtx); func_8006450C(globalCtx, &globalCtx->csCtx); if (gSaveContext.nextCutsceneIndex != 0xFFEF) { @@ -407,7 +407,7 @@ void Gameplay_Init(GameState* thisx) { gSaveContext.seqIndex = globalCtx->soundCtx.seqIndex; gSaveContext.nightSeqIndex = globalCtx->soundCtx.nightSeqIndex; func_8002DF18(globalCtx, PLAYER); - func_800A390C(globalCtx, &globalCtx->animationCtx); + AnimationContext_Update(globalCtx, &globalCtx->animationCtx); gSaveContext.respawnFlag = 0; if (dREG(95) != 0) { @@ -803,7 +803,7 @@ void Gameplay_Update(GlobalContext* globalCtx) { LOG_NUM("1", 1, "../z_play.c", 3555); } - SkelAnime_AnimationCtxReset(&globalCtx->animationCtx); + AnimationContext_Reset(&globalCtx->animationCtx); if (1 && HREG(63)) { LOG_NUM("1", 1, "../z_play.c", 3561); @@ -981,7 +981,7 @@ void Gameplay_Update(GlobalContext* globalCtx) { LOG_NUM("1", 1, "../z_play.c", 3765); } - func_800A390C(globalCtx, &globalCtx->animationCtx); + AnimationContext_Update(globalCtx, &globalCtx->animationCtx); if (1 && HREG(63)) { LOG_NUM("1", 1, "../z_play.c", 3771); diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index 6d1d6204a..1942a8b33 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -625,12 +625,12 @@ Gfx* sBootDListGroups[][2] = { { 0x06025BA8, 0x06025DB0 }, }; -void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTable, s32 dListCount, s32 lod, s32 tunic, +void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, s32 lod, s32 tunic, s32 boots, s32 face, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* data) { Color_RGB8* color; - s32 eyeIndex = (limbDrawTable[22].x & 0xF) - 1; - s32 mouthIndex = (limbDrawTable[22].x >> 4) - 1; + s32 eyeIndex = (jointTable[22].x & 0xF) - 1; + s32 mouthIndex = (jointTable[22].x >> 4) - 1; OPEN_DISPS(globalCtx->state.gfxCtx, "../z_player_lib.c", 1721); @@ -651,7 +651,7 @@ void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTab sDListsLodOffset = lod * 2; - SkelAnime_DrawFlexLod(globalCtx, skeleton, limbDrawTable, dListCount, overrideLimbDraw, postLimbDraw, data, lod); + SkelAnime_DrawFlexLod(globalCtx, skeleton, jointTable, dListCount, overrideLimbDraw, postLimbDraw, data, lod); if ((overrideLimbDraw != func_800902F0) && (overrideLimbDraw != func_80090440) && (gSaveContext.gameMode != 3)) { if (LINK_IS_ADULT) { @@ -733,7 +733,7 @@ void func_8008F87C(GlobalContext* globalCtx, Player* this, SkelAnime* skelAnime, Matrix_Push(); Matrix_JointPosition(pos, rot); Matrix_MultVec3f(&D_8012602C, &spA4); - Matrix_JointPosition(&D_80126038[(void)0, gSaveContext.linkAge], &skelAnime->limbDrawTbl[shinLimbIndex]); + Matrix_JointPosition(&D_80126038[(void)0, gSaveContext.linkAge], &skelAnime->jointTable[shinLimbIndex]); Matrix_Translate(D_80126050[(void)0, gSaveContext.linkAge], 0.0f, 0.0f, MTXMODE_APPLY); Matrix_MultVec3f(&D_8012602C, &sp98); Matrix_MultVec3f(&D_80126070, &footprintPos); @@ -768,19 +768,18 @@ void func_8008F87C(GlobalContext* globalCtx, Player* this, SkelAnime* skelAnime, sp50 = Math_FAtan2F(sp58, sp60); temp1 = (M_PI - (Math_FAtan2F(sp5C, sp58) + ((M_PI / 2) - sp50))) * 10430.378f; - temp1 = temp1 - skelAnime->limbDrawTbl[shinLimbIndex].z; + temp1 = temp1 - skelAnime->jointTable[shinLimbIndex].z; - if ((s16)(ABS(skelAnime->limbDrawTbl[shinLimbIndex].x) + ABS(skelAnime->limbDrawTbl[shinLimbIndex].y)) < - 0) { + if ((s16)(ABS(skelAnime->jointTable[shinLimbIndex].x) + ABS(skelAnime->jointTable[shinLimbIndex].y)) < 0) { temp1 += 0x8000; } temp2 = (sp50 - sp54) * 10430.378f; rot->z -= temp2; - skelAnime->limbDrawTbl[thighLimbIndex].z = skelAnime->limbDrawTbl[thighLimbIndex].z - temp2; - skelAnime->limbDrawTbl[shinLimbIndex].z = skelAnime->limbDrawTbl[shinLimbIndex].z + temp1; - skelAnime->limbDrawTbl[footLimbIndex].z = skelAnime->limbDrawTbl[footLimbIndex].z + temp2 - temp1; + skelAnime->jointTable[thighLimbIndex].z = skelAnime->jointTable[thighLimbIndex].z - temp2; + skelAnime->jointTable[shinLimbIndex].z = skelAnime->jointTable[shinLimbIndex].z + temp1; + skelAnime->jointTable[footLimbIndex].z = skelAnime->jointTable[footLimbIndex].z + temp2 - temp1; temp3 = func_80041D4C(&globalCtx->colCtx, sp88, sp84); @@ -801,12 +800,12 @@ s32 func_8008FCC8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p D_80160000 = &this->swordInfo[2].base; if (LINK_IS_CHILD) { - if (!(this->skelAnime.flags & 4) || (this->skelAnime.flags & 1)) { + if (!(this->skelAnime.moveFlags & 4) || (this->skelAnime.moveFlags & 1)) { pos->x *= 0.64f; pos->z *= 0.64f; } - if (!(this->skelAnime.flags & 4) || (this->skelAnime.flags & 2)) { + if (!(this->skelAnime.moveFlags & 4) || (this->skelAnime.moveFlags & 2)) { pos->y *= 0.64f; } } @@ -849,13 +848,13 @@ s32 func_8008FCC8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p } else if (limbIndex == PLAYER_LIMB_R_THIGH) { func_8008F87C(globalCtx, this, &this->skelAnime, pos, rot, PLAYER_LIMB_R_THIGH, PLAYER_LIMB_R_SHIN, PLAYER_LIMB_R_FOOT); - return 0; + return false; } else { - return 0; + return false; } } - return 0; + return false; } s32 func_80090014(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { @@ -907,7 +906,7 @@ s32 func_80090014(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p } } - return 0; + return false; } s32 func_800902F0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { @@ -931,7 +930,7 @@ s32 func_800902F0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p } } - return 0; + return false; } s32 func_80090440(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { @@ -939,7 +938,7 @@ s32 func_80090440(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p *dList = NULL; } - return 0; + return false; } u8 func_80090480(GlobalContext* globalCtx, ColliderQuad* collider, WeaponInfo* weaponInfo, Vec3f* newTip, @@ -1367,8 +1366,8 @@ u32 func_80091738(GlobalContext* globalCtx, u8* segment, SkelAnime* skelAnime) { gSegments[4] = VIRTUAL_TO_PHYSICAL(segment + 0x3800); gSegments[6] = VIRTUAL_TO_PHYSICAL(segment + 0x8800); - SkelAnime_InitLinkAnimation(globalCtx, skelAnime, gPlayerSkelHeaders[(void)0, gSaveContext.linkAge], &D_04003238, 9, - ptr, ptr, PLAYER_LIMB_MAX); + SkelAnime_InitLink(globalCtx, skelAnime, gPlayerSkelHeaders[(void)0, gSaveContext.linkAge], &D_04003238, 9, ptr, + ptr, PLAYER_LIMB_MAX); return size + 0x8890; } @@ -1509,7 +1508,7 @@ void func_80091A24(GlobalContext* globalCtx, void* seg04, void* seg06, SkelAnime gSPSegment(POLY_OPA_DISP++, 0x0C, gCullBackDList); - func_8008F470(globalCtx, arg3->skeleton, arg3->limbDrawTbl, arg3->dListCount, 0, tunic, boots, 0, func_80091880, + func_8008F470(globalCtx, arg3->skeleton, arg3->jointTable, arg3->dListCount, 0, tunic, boots, 0, func_80091880, NULL, &sp12C); gSPEndDisplayList(POLY_OPA_DISP++); @@ -1549,7 +1548,7 @@ void func_8009214C(GlobalContext* globalCtx, u8* segment, SkelAnime* arg2, Vec3f } srcTable = SEGMENTED_TO_VIRTUAL(srcTable); - destTable = arg2->limbDrawTbl; + destTable = arg2->jointTable; for (i = 0; i < arg2->limbCount; i++) { *destTable++ = *srcTable++; } diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c index 2ab52c9e2..0d3e5dc87 100644 --- a/src/code/z_skelanime.c +++ b/src/code/z_skelanime.c @@ -1,22 +1,24 @@ #include "global.h" #include "vt.h" -s32 func_800A3D70(GlobalContext* globalCtx, SkelAnime* skelAnime); -s32 func_800A3E0C(GlobalContext* globalCtx, SkelAnime* skelAnime); -s32 func_800A4D9C(SkelAnime* skelAnime); -s32 func_800A4EE0(SkelAnime* skelAnime); -s32 func_800A4E38(SkelAnime* skelAnime); +#define ANIM_INTERP 1 + +s32 LinkAnimation_Loop(GlobalContext* globalCtx, SkelAnime* skelAnime); +s32 LinkAnimation_Once(GlobalContext* globalCtx, SkelAnime* skelAnime); +s32 SkelAnime_LoopFull(SkelAnime* skelAnime); +s32 SkelAnime_Once(SkelAnime* skelAnime); +s32 SkelAnime_LoopPartial(SkelAnime* skelAnime); void SkelAnime_CopyVec3s(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src); -static u32 D_8012A480 = 0; -static u32 D_801600B0; +static u32 sDisableAnimQueueFlags = 0; +static u32 sAnimQueueFlags; -/* +/** * Draw a limb of type `LodLimb` * Near or far display list is specified via `lod` */ -void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* limbDrawTable, +void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, s32 lod) { LodLimb* limb; Gfx* dList; @@ -28,7 +30,7 @@ void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skele Matrix_Push(); limb = (LodLimb*)SEGMENTED_TO_VIRTUAL(skeleton[limbIndex]); limbIndex++; - rot = limbDrawTable[limbIndex]; + rot = jointTable[limbIndex]; pos.x = limb->jointPos.x; pos.y = limb->jointPos.y; @@ -51,25 +53,23 @@ void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skele } if (limb->child != LIMB_DONE) { - SkelAnime_DrawLimbLod(globalCtx, limb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg, - lod); + SkelAnime_DrawLimbLod(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, lod); } Matrix_Pull(); if (limb->sibling != LIMB_DONE) { - SkelAnime_DrawLimbLod(globalCtx, limb->sibling, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg, - lod); + SkelAnime_DrawLimbLod(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, lod); } CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_skelanime.c", 821); } -/* +/** * Draw all limbs of type `LodLimb` in a given skeleton * Near or far display list is specified via `lod` */ -void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTable, +void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, s32 lod) { LodLimb* rootLimb; s32 pad; @@ -89,11 +89,11 @@ void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDra Matrix_Push(); rootLimb = (LodLimb*)SEGMENTED_TO_VIRTUAL(skeleton[0]); - pos.x = limbDrawTable[0].x; - pos.y = limbDrawTable[0].y; - pos.z = limbDrawTable[0].z; + pos.x = jointTable[0].x; + pos.y = jointTable[0].y; + pos.z = jointTable[0].z; - rot = limbDrawTable[1]; + rot = jointTable[1]; dList = rootLimb->dLists[lod]; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &dList, &pos, &rot, arg)) { @@ -108,7 +108,7 @@ void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDra } if (rootLimb->child != LIMB_DONE) { - SkelAnime_DrawLimbLod(globalCtx, rootLimb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg, + SkelAnime_DrawLimbLod(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, lod); } @@ -117,11 +117,11 @@ void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDra CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_skelanime.c", 894); } -/* +/** * Draw a limb of type `LodLimb` contained within a flexible skeleton * Near or far display list is specified via `lod` */ -void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* limbDrawTable, +void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, s32 lod, Mtx** mtx) { LodLimb* limb; @@ -135,7 +135,7 @@ void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** s limb = (LodLimb*)SEGMENTED_TO_VIRTUAL(skeleton[limbIndex]); limbIndex++; - rot = limbDrawTable[limbIndex]; + rot = jointTable[limbIndex]; pos.x = limb->jointPos.x; pos.y = limb->jointPos.y; @@ -163,24 +163,24 @@ void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** s postLimbDraw(globalCtx, limbIndex, &limbDList, &rot, arg); } if (limb->child != LIMB_DONE) { - SkelAnime_DrawFlexLimbLod(globalCtx, limb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg, + SkelAnime_DrawFlexLimbLod(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, lod, mtx); } Matrix_Pull(); if (limb->sibling != LIMB_DONE) { - SkelAnime_DrawFlexLimbLod(globalCtx, limb->sibling, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, - arg, lod, mtx); + SkelAnime_DrawFlexLimbLod(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, + lod, mtx); } } -/* +/** * Draws all limbs of type `LodLimb` in a given flexible skeleton * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs. * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up. */ -void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTable, s32 dListCount, +void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, s32 lod) { LodLimb* rootLimb; s32 pad; @@ -205,11 +205,11 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* lim Matrix_Push(); rootLimb = (LodLimb*)SEGMENTED_TO_VIRTUAL(skeleton[0]); - pos.x = limbDrawTable[0].x; - pos.y = limbDrawTable[0].y; - pos.z = limbDrawTable[0].z; + pos.x = jointTable[0].x; + pos.y = jointTable[0].y; + pos.z = jointTable[0].z; - rot = limbDrawTable[1]; + rot = jointTable[1]; newDList = limbDList = rootLimb->dLists[lod]; @@ -230,8 +230,8 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* lim postLimbDraw(globalCtx, 1, &limbDList, &rot, arg); } if (rootLimb->child != LIMB_DONE) { - SkelAnime_DrawFlexLimbLod(globalCtx, rootLimb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, - arg, lod, &mtx); + SkelAnime_DrawFlexLimbLod(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, + lod, &mtx); } Matrix_Pull(); @@ -239,10 +239,10 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* lim CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_skelanime.c", 1053); } -/* +/** * Draw a limb of type `StandardLimb` to the polyOpa buffer */ -void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* limbDrawTable, +void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg) { StandardLimb* limb; Gfx* dList; @@ -254,7 +254,7 @@ void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skele limb = (StandardLimb*)SEGMENTED_TO_VIRTUAL(skeleton[limbIndex]); limbIndex++; - rot = limbDrawTable[limbIndex]; + rot = jointTable[limbIndex]; pos.x = limb->jointPos.x; pos.y = limb->jointPos.y; pos.z = limb->jointPos.z; @@ -275,21 +275,21 @@ void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skele } if (limb->child != LIMB_DONE) { - SkelAnime_DrawLimbOpa(globalCtx, limb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg); + SkelAnime_DrawLimbOpa(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg); } Matrix_Pull(); if (limb->sibling != LIMB_DONE) { - SkelAnime_DrawLimbOpa(globalCtx, limb->sibling, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg); + SkelAnime_DrawLimbOpa(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg); } CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_skelanime.c", 1121); } -/* +/** * Draw all limbs of type `StandardLimb` in a given skeleton to the polyOpa buffer */ -void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTable, +void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg) { StandardLimb* rootLimb; s32 pad; @@ -309,11 +309,11 @@ void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDra Matrix_Push(); rootLimb = (StandardLimb*)SEGMENTED_TO_VIRTUAL(skeleton[0]); - pos.x = limbDrawTable[0].x; - pos.y = limbDrawTable[0].y; - pos.z = limbDrawTable[0].z; + pos.x = jointTable[0].x; + pos.y = jointTable[0].y; + pos.z = jointTable[0].z; - rot = limbDrawTable[1]; + rot = jointTable[1]; dList = rootLimb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &dList, &pos, &rot, arg)) { @@ -329,7 +329,7 @@ void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDra } if (rootLimb->child != LIMB_DONE) { - SkelAnime_DrawLimbOpa(globalCtx, rootLimb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg); + SkelAnime_DrawLimbOpa(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg); } Matrix_Pull(); @@ -337,10 +337,10 @@ void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDra CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_skelanime.c", 1190); } -/* +/** * Draw a limb of type `StandardLimb` contained within a flexible skeleton to the polyOpa buffer */ -void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* limbDrawTable, +void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, Mtx** limbMatricies) { StandardLimb* limb; @@ -355,7 +355,7 @@ void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** s limb = (StandardLimb*)SEGMENTED_TO_VIRTUAL(skeleton[limbIndex]); limbIndex++; - rot = limbDrawTable[limbIndex]; + rot = jointTable[limbIndex]; pos.x = limb->jointPos.x; pos.y = limb->jointPos.y; @@ -381,25 +381,25 @@ void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** s } if (limb->child != LIMB_DONE) { - SkelAnime_DrawFlexLimbOpa(globalCtx, limb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg, + SkelAnime_DrawFlexLimbOpa(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, limbMatricies); } Matrix_Pull(); if (limb->sibling != LIMB_DONE) { - SkelAnime_DrawFlexLimbOpa(globalCtx, limb->sibling, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, - arg, limbMatricies); + SkelAnime_DrawFlexLimbOpa(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, + limbMatricies); } CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_skelanime.c", 1265); } -/* +/** * Draw all limbs of type `StandardLimb` in a given flexible skeleton to the polyOpa buffer * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs. * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up. */ -void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTable, s32 dListCount, +void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg) { StandardLimb* rootLimb; s32 pad; @@ -426,11 +426,11 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* lim rootLimb = SEGMENTED_TO_VIRTUAL(skeleton[0]); - pos.x = limbDrawTable[0].x; - pos.y = limbDrawTable[0].y; - pos.z = limbDrawTable[0].z; + pos.x = jointTable[0].x; + pos.y = jointTable[0].y; + pos.z = jointTable[0].z; - rot = limbDrawTable[1]; + rot = jointTable[1]; newDList = limbDList = rootLimb->dList; @@ -452,57 +452,61 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* lim } if (rootLimb->child != LIMB_DONE) { - SkelAnime_DrawFlexLimbOpa(globalCtx, rootLimb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, - arg, &mtx); + SkelAnime_DrawFlexLimbOpa(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, + &mtx); } Matrix_Pull(); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_skelanime.c", 1347); } -/* - * 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 +/** + * Copies frame data from the frame data table, indexed by the joint index table. + * Indices below limit are copied from that entry in the static frame data table. + * Indices above limit are offsets to a frame data array indexed by the frame. */ -void SkelAnime_AnimateFrame(AnimationHeader* animationSeg, s32 currentFrame, s32 limbCount, Vec3s* dst) { - AnimationHeader* animHeader = SEGMENTED_TO_VIRTUAL(animationSeg); - AnimationRotationIndex* index = SEGMENTED_TO_VIRTUAL(animHeader->rotationIndexSeg); - AnimationRotationValue* rotationValueTable = SEGMENTED_TO_VIRTUAL(animHeader->rotationValueSeg); - AnimationRotationValue* frameRotationValueTable = &rotationValueTable[currentFrame]; - u16 limit = animHeader->limit; +void SkelAnime_GetFrameData(AnimationHeader* animation, s32 frame, s32 limbCount, Vec3s* frameTable) { + AnimationHeader* animHeader = SEGMENTED_TO_VIRTUAL(animation); + JointIndex* jointIndices = SEGMENTED_TO_VIRTUAL(animHeader->jointIndices); + s16* frameData = SEGMENTED_TO_VIRTUAL(animHeader->frameData); + s16* staticData = &frameData[0]; + s16* dynamicData = &frameData[frame]; + u16 staticIndexMax = animHeader->staticIndexMax; s32 i; - for (i = 0; i < limbCount; i++, dst++, index++) { - if ((dst == NULL) || (index == NULL) || (frameRotationValueTable == NULL) || (rotationValueTable == NULL)) { - LOG_ADDRESS("out", dst, "../z_skelanime.c", 1392); - LOG_ADDRESS("ref_tbl", index, "../z_skelanime.c", 1393); - LOG_ADDRESS("frame_tbl", frameRotationValueTable, "../z_skelanime.c", 1394); - LOG_ADDRESS("tbl", rotationValueTable, "../z_skelanime.c", 1395); + for (i = 0; i < limbCount; i++, frameTable++, jointIndices++) { + if ((frameTable == NULL) || (jointIndices == NULL) || (dynamicData == NULL) || (staticData == NULL)) { + LOG_ADDRESS("out", frameTable, "../z_skelanime.c", 1392); + LOG_ADDRESS("ref_tbl", jointIndices, "../z_skelanime.c", 1393); + LOG_ADDRESS("frame_tbl", dynamicData, "../z_skelanime.c", 1394); + LOG_ADDRESS("tbl", staticData, "../z_skelanime.c", 1395); } - 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]; + frameTable->x = + (jointIndices->x >= staticIndexMax) ? dynamicData[jointIndices->x] : staticData[jointIndices->x]; + frameTable->y = + (jointIndices->y >= staticIndexMax) ? dynamicData[jointIndices->y] : staticData[jointIndices->y]; + frameTable->z = + (jointIndices->z >= staticIndexMax) ? dynamicData[jointIndices->z] : staticData[jointIndices->z]; } } -s16 SkelAnime_GetTotalFrames(void* animationSeg) { - GenericAnimationHeader* animation = SEGMENTED_TO_VIRTUAL(animationSeg); +s16 Animation_GetLength(void* animation) { + AnimationHeaderCommon* common = SEGMENTED_TO_VIRTUAL(animation); - return animation->frameCount; + return common->frameCount; } -s16 SkelAnime_GetFrameCount(void* animationSeg) { - GenericAnimationHeader* animation = SEGMENTED_TO_VIRTUAL(animationSeg); +s16 Animation_GetLastFrame(void* animation) { + AnimationHeaderCommon* common = SEGMENTED_TO_VIRTUAL(animation); // Loads an unsigned half for some reason. - return (u16)animation->frameCount - 1; + return (u16)common->frameCount - 1; } -/* +/** * Draw a limb of type `StandardLimb` to the specified display buffer */ -Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* limbDrawTable, +Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, void* arg, Gfx* gfx) { StandardLimb* limb; Gfx* dList; @@ -514,7 +518,7 @@ Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton limb = (StandardLimb*)SEGMENTED_TO_VIRTUAL(skeleton[limbIndex]); limbIndex++; - rot = limbDrawTable[limbIndex]; + rot = jointTable[limbIndex]; pos.x = limb->jointPos.x; pos.y = limb->jointPos.y; @@ -535,24 +539,24 @@ Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton } if (limb->child != LIMB_DONE) { - gfx = SkelAnime_DrawLimb(globalCtx, limb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg, - gfx); + gfx = + SkelAnime_DrawLimb(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, gfx); } Matrix_Pull(); if (limb->sibling != LIMB_DONE) { - gfx = SkelAnime_DrawLimb(globalCtx, limb->sibling, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, arg, + gfx = SkelAnime_DrawLimb(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, gfx); } return gfx; } -/* +/** * Draw all limbs of type `StandardLimb` in a given skeleton to the specified display buffer */ -Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTable, OverrideLimbDraw overrideLimbDraw, +Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, void* arg, Gfx* gfx) { StandardLimb* rootLimb; s32 pad; @@ -571,11 +575,11 @@ Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTa rootLimb = (StandardLimb*)SEGMENTED_TO_VIRTUAL(skeleton[0]); - pos.x = limbDrawTable[0].x; - pos.y = limbDrawTable[0].y; - pos.z = limbDrawTable[0].z; + pos.x = jointTable[0].x; + pos.y = jointTable[0].y; + pos.z = jointTable[0].z; - rot = limbDrawTable[1]; + rot = jointTable[1]; dList = rootLimb->dList; @@ -592,8 +596,8 @@ Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTa } if (rootLimb->child != LIMB_DONE) { - gfx = SkelAnime_DrawLimb(globalCtx, rootLimb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, - arg, gfx); + gfx = SkelAnime_DrawLimb(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, + gfx); } Matrix_Pull(); @@ -601,10 +605,10 @@ Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTa return gfx; } -/* +/** * Draw a limb of type `StandardLimb` contained within a flexible skeleton to the specified display buffer */ -Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* limbDrawTable, +Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, void* arg, Mtx** mtx, Gfx* gfx) { StandardLimb* limb; @@ -617,7 +621,7 @@ Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skel limb = (StandardLimb*)SEGMENTED_TO_VIRTUAL(skeleton[limbIndex]); limbIndex++; - rot = limbDrawTable[limbIndex]; + rot = jointTable[limbIndex]; pos.x = limb->jointPos.x; pos.y = limb->jointPos.y; @@ -640,26 +644,26 @@ Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skel postLimbDraw(globalCtx, limbIndex, &limbDList, &rot, arg, &gfx); } if (limb->child != LIMB_DONE) { - gfx = SkelAnime_DrawFlexLimb(globalCtx, limb->child, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, - arg, mtx, gfx); + gfx = SkelAnime_DrawFlexLimb(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, + mtx, gfx); } Matrix_Pull(); if (limb->sibling != LIMB_DONE) { - gfx = SkelAnime_DrawFlexLimb(globalCtx, limb->sibling, skeleton, limbDrawTable, overrideLimbDraw, postLimbDraw, + gfx = SkelAnime_DrawFlexLimb(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, arg, mtx, gfx); } return gfx; } -/* +/** * Draw all limbs of type `StandardLimb` in a given flexible skeleton to the specified display buffer * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs. * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up. */ -Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDrawTable, s32 dListCount, +Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, void* arg, Gfx* gfx) { StandardLimb* rootLimb; s32 pad; @@ -682,11 +686,11 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDr Matrix_Push(); rootLimb = (StandardLimb*)SEGMENTED_TO_VIRTUAL(skeleton[0]); - pos.x = limbDrawTable[0].x; - pos.y = limbDrawTable[0].y; - pos.z = limbDrawTable[0].z; + pos.x = jointTable[0].x; + pos.y = jointTable[0].y; + pos.z = jointTable[0].z; - rot = limbDrawTable[1]; + rot = jointTable[1]; newDList = limbDList = rootLimb->dList; @@ -706,8 +710,8 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDr postLimbDraw(globalCtx, 1, &limbDList, &rot, arg, &gfx); } if (rootLimb->child != LIMB_DONE) { - gfx = SkelAnime_DrawFlexLimb(globalCtx, rootLimb->child, skeleton, limbDrawTable, overrideLimbDraw, - postLimbDraw, arg, &mtx, gfx); + gfx = SkelAnime_DrawFlexLimb(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, + arg, &mtx, gfx); } Matrix_Pull(); @@ -716,119 +720,134 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* limbDr } // unused -s32 func_800A29BC(s32 arg0, s32 arg1, Vec3s* arg2) { - AnimationHeader* temp_v0 = SEGMENTED_TO_VIRTUAL(arg0); - s32 t = temp_v0->genericHeader.unk_02; - s16* temp_a3 = SEGMENTED_TO_VIRTUAL(temp_v0->rotationIndexSeg); - s16* temp_t1 = SEGMENTED_TO_VIRTUAL(temp_v0->rotationValueSeg); - s32 phi_v0; - - arg2->x = arg1 < temp_a3[0] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[1]] : temp_t1[temp_a3[1]]; - arg2->y = arg1 < temp_a3[2] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[3]] : temp_t1[temp_a3[3]]; - arg2->z = arg1 < temp_a3[4] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[5]] : temp_t1[temp_a3[5]]; - - phi_v0 = 1; - arg2++; - temp_a3 += 6; - - if (t & 1) {} - - if (t > 0) { - if (t & 1) { - phi_v0++; - arg2->x = arg1 < temp_a3[0] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[1]] : temp_t1[temp_a3[1]]; - arg2->y = arg1 < temp_a3[2] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[3]] : temp_t1[temp_a3[3]]; - arg2->z = arg1 < temp_a3[4] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[5]] : temp_t1[temp_a3[5]]; - temp_a3 += 6; - arg2++; - if (t + 1 == phi_v0) { +s32 SkelAnime_GetFrameData2(AnimationHeader2* animation, s32 frame, Vec3s* frameTable) { + AnimationHeader2* animHeader = SEGMENTED_TO_VIRTUAL(animation); + s32 limbCount = animHeader->limbCount; + JointKey* key = SEGMENTED_TO_VIRTUAL(animHeader->jointKey); + s16* frameData = SEGMENTED_TO_VIRTUAL(animHeader->frameData); + s16* staticData = &frameData[0]; + s16* dynamicData = &frameData[frame]; + s32 i; + + /** + *Equivalent to the following, but the compiler optimizes the loop in a way I can't replicate + */ + + // for(i = 0, dst++, key++; i < limbCount + 1; i++, key++, dst++) { + // dst->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; + // dst->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; + // dst->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; + // } + + frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; + frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; + frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; + + i = 1; + frameTable++; + key++; + + if (limbCount & 1) {} + + if (limbCount > 0) { + if (limbCount & 1) { + i++; + frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; + frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; + frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; + key++; + frameTable++; + if (limbCount + 1 == i) { goto ret; } } do { - phi_v0 += 2; - arg2->x = arg1 < temp_a3[0] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[1]] : temp_t1[temp_a3[1]]; - arg2->y = arg1 < temp_a3[2] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[3]] : temp_t1[temp_a3[3]]; - arg2->z = arg1 < temp_a3[4] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[5]] : temp_t1[temp_a3[5]]; - temp_a3 += 6; - arg2++; - arg2->x = arg1 < temp_a3[0] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[1]] : temp_t1[temp_a3[1]]; - arg2->y = arg1 < temp_a3[2] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[3]] : temp_t1[temp_a3[3]]; - arg2->z = arg1 < temp_a3[4] ? ((s16*)((arg1 * 2) + (u32)temp_t1))[temp_a3[5]] : temp_t1[temp_a3[5]]; - temp_a3 += 6; - arg2++; - } while (phi_v0 != t + 1); + i += 2; + frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; + frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; + frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; + key++; + frameTable++; + frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; + frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; + frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; + key++; + frameTable++; + } while (i != limbCount + 1); } ret: - return t; + return limbCount; } -// unused -s16 func_800A2DBC(void* animationSeg) { - GenericAnimationHeader* animation = SEGMENTED_TO_VIRTUAL(animationSeg); +/** + * Used by legacy animation format + */ +s16 Animation_GetLimbCount2(AnimationHeader2* animation) { + AnimationHeader2* animHeader = SEGMENTED_TO_VIRTUAL(animation); - return animation->unk_02; + return animHeader->limbCount; } -/* - * Appears to be unused anywhere in the game. Appears to be a clone of - * SkelAnime_GetTotalFrames +/** + * Used by legacy animation format */ -s16 SkelAnime_GetTotalFrames2(void* animationSeg) { - GenericAnimationHeader* animation = SEGMENTED_TO_VIRTUAL(animationSeg); +s16 Animation_GetLength2(AnimationHeader2* animation) { + AnimationHeader2* animHeader = SEGMENTED_TO_VIRTUAL(animation); - return animation->frameCount; + return animHeader->frameCount; } -/* - * Appears to be unused anywhere in the game. Appears to be a clone of - * SkelAnime_GetFrameCount +/** + * Used by legacy animation format */ -s16 SkelAnime_GetFrameCount2(void* animationSeg) { - GenericAnimationHeader* animation = SEGMENTED_TO_VIRTUAL(animationSeg); +s16 Animation_GetLastFrame2(AnimationHeader2* animation) { + AnimationHeader2* animHeader = SEGMENTED_TO_VIRTUAL(animation); - return animation->frameCount - 1; + return animHeader->frameCount - 1; } -void SkelAnime_InterpolateVec3s(s32 limbCount, Vec3s* dst, Vec3s* vec2, Vec3s* vec3, f32 unkf) { +/** + * Linearly interpolates between vector arrays start and target at the given weight. + */ +void SkelAnime_InterpVec3s(s32 limbCount, Vec3s* dst, Vec3s* start, Vec3s* target, f32 weight) { 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; + s16 diff; + s16 base; + + if (weight < 1.0f) { + for (i = 0; i < limbCount; i++, dst++, start++, target++) { + base = start->x; + diff = target->x - base; + dst->x = (s16)(diff * weight) + base; + base = start->y; + diff = target->y - base; + dst->y = (s16)(diff * weight) + base; + base = start->z; + diff = target->z - base; + dst->z = (s16)(diff * weight) + base; } } else { - for (i = 0; i < limbCount; i++, dst++, vec3++) { - dst->x = vec3->x; - dst->y = vec3->y; - dst->z = vec3->z; + for (i = 0; i < limbCount; i++, dst++, target++) { + dst->x = target->x; + dst->y = target->y; + dst->z = target->z; } } } -void SkelAnime_AnimationCtxReset(AnimationContext* animationCtx) { +void AnimationContext_Reset(AnimationContext* animationCtx) { animationCtx->animationCount = 0; } -void func_800A32F4(GlobalContext* globalCtx) { - D_801600B0 <<= 1; +void AnimationContext_SetNextQueue(GlobalContext* globalCtx) { + sAnimQueueFlags <<= 1; } -void func_800A3310(GlobalContext* globalCtx) { - D_8012A480 |= D_801600B0; +void AnimationContext_DisableQueue(GlobalContext* globalCtx) { + sDisableAnimQueueFlags |= sAnimQueueFlags; } -AnimationEntry* SkelAnime_AddEntry(AnimationContext* animationCtx, AnimationType type) { +AnimationEntry* AnimationContext_AddEntry(AnimationContext* animationCtx, AnimationType type) { AnimationEntry* entry; s16 index = animationCtx->animationCount; @@ -841,93 +860,113 @@ AnimationEntry* SkelAnime_AddEntry(AnimationContext* animationCtx, AnimationType return entry; } -// The next 6 functions are coordinate with the AnimationType enum - -void SkelAnime_LoadLinkAnimation(GlobalContext* globalCtx, LinkAnimationHeader* segment, s32 frame, s32 limbCount, - Vec3s* drawTbl) { - AnimationEntry* entry = SkelAnime_AddEntry(&globalCtx->animationCtx, ANIMATION_LINK); +/** + * Requests loading frame data from the Link animation at segment into frameTable + */ +void AnimationContext_SetLoadFrame(GlobalContext* globalCtx, LinkAnimationHeader* segment, s32 frame, s32 limbCount, + Vec3s* frameTable) { + AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMENTRY_LOADFRAME); if (entry != NULL) { LinkAnimationHeader* linkAnimHeader = SEGMENTED_TO_VIRTUAL(segment); - u32 ram = drawTbl; + u32 ram = frameTable; - osCreateMesgQueue(&entry->data.type0.msgQueue, &entry->data.type0.msg, 1); - DmaMgr_SendRequest2(&entry->data.type0.req, ram, + osCreateMesgQueue(&entry->data.load.msgQueue, &entry->data.load.msg, 1); + DmaMgr_SendRequest2(&entry->data.load.req, ram, LINK_ANIMATION_OFFSET(linkAnimHeader->segment, ((sizeof(Vec3s) * limbCount + 2) * frame)), - sizeof(Vec3s) * limbCount + 2, 0, &entry->data.type0.msgQueue, NULL, "../z_skelanime.c", + sizeof(Vec3s) * limbCount + 2, 0, &entry->data.load.msgQueue, NULL, "../z_skelanime.c", 2004); } } -void SkelAnime_LoadAnimationType1(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src) { - AnimationEntry* entry = SkelAnime_AddEntry(&globalCtx->animationCtx, ANIMATION_TYPE1); +/** + * Requests copying all vectors from src into dst + */ +void AnimationContext_SetCopyAll(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src) { + AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMENTRY_COPYALL); if (entry != NULL) { - entry->data.type1.unk_00 = D_801600B0; - entry->data.type1.vecCount = vecCount; - entry->data.type1.dst = dst; - entry->data.type1.src = src; + entry->data.copy.queueFlag = sAnimQueueFlags; + entry->data.copy.vecCount = vecCount; + entry->data.copy.dst = dst; + entry->data.copy.src = src; } } -void SkelAnime_LoadAnimationType2(GlobalContext* globalCtx, s32 limbCount, Vec3s* arg2, Vec3s* arg3, f32 arg4) { - AnimationEntry* entry = SkelAnime_AddEntry(&globalCtx->animationCtx, ANIMATION_TYPE2); +/** + * Requests interpolating between base and mod with the given weight, placing the result in base + */ +void AnimationContext_SetInterp(GlobalContext* globalCtx, s32 vecCount, Vec3s* base, Vec3s* mod, f32 weight) { + AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMENTRY_INTERP); if (entry != NULL) { - entry->data.type2.unk_00 = D_801600B0; - entry->data.type2.limbCount = limbCount; - entry->data.type2.unk_04 = arg2; - entry->data.type2.unk_08 = arg3; - entry->data.type2.unk_0C = arg4; + entry->data.interp.queueFlag = sAnimQueueFlags; + entry->data.interp.vecCount = vecCount; + entry->data.interp.base = base; + entry->data.interp.mod = mod; + entry->data.interp.weight = weight; } } -void SkelAnime_LoadAnimationType3(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* index) { - AnimationEntry* entry = SkelAnime_AddEntry(&globalCtx->animationCtx, ANIMATION_TYPE3); +/** + * Requests copying vectors from src to dst whose copy flag is true + */ +void AnimationContext_SetCopyTrue(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* copyFlag) { + AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMENTRY_COPYTRUE); if (entry != NULL) { - entry->data.type3.unk_00 = D_801600B0; - entry->data.type3.vecCount = vecCount; - entry->data.type3.dst = dst; - entry->data.type3.src = src; - entry->data.type3.index = index; + entry->data.copy1.queueFlag = sAnimQueueFlags; + entry->data.copy1.vecCount = vecCount; + entry->data.copy1.dst = dst; + entry->data.copy1.src = src; + entry->data.copy1.copyFlag = copyFlag; } } -void SkelAnime_LoadAnimationType4(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* index) { - AnimationEntry* entry = SkelAnime_AddEntry(&globalCtx->animationCtx, ANIMATION_TYPE4); +/** + * Requests copying vectors from src to dst whose copy flag is false + */ +void AnimationContext_SetCopyFalse(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* copyFlag) { + AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMENTRY_COPYFALSE); if (entry != NULL) { - entry->data.type4.unk_00 = D_801600B0; - entry->data.type4.vecCount = vecCount; - entry->data.type4.dst = dst; - entry->data.type4.src = src; - entry->data.type4.index = index; + entry->data.copy0.queueFlag = sAnimQueueFlags; + entry->data.copy0.vecCount = vecCount; + entry->data.copy0.dst = dst; + entry->data.copy0.src = src; + entry->data.copy0.copyFlag = copyFlag; } } -void SkelAnime_LoadAnimationType5(GlobalContext* globalCtx, Actor* actor, SkelAnime* skelAnime, f32 arg3) { - AnimationEntry* entry = SkelAnime_AddEntry(&globalCtx->animationCtx, ANIMATION_TYPE5); +/** + * Requests moving an actor according to the translation of its root limb + */ +void AnimationContext_SetMoveActor(GlobalContext* globalCtx, Actor* actor, SkelAnime* skelAnime, f32 arg3) { + AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMENTRY_MOVEACTOR); if (entry != NULL) { - entry->data.type5.actor = actor; - entry->data.type5.skelAnime = skelAnime; - entry->data.type5.unk_08 = arg3; + entry->data.move.actor = actor; + entry->data.move.skelAnime = skelAnime; + entry->data.move.unk_08 = arg3; } } -// The next functions are callbacks to loading animations - -void SkelAnime_LinkAnimationLoaded(GlobalContext* globalCtx, AnimationEntryData* data) { - AnimationEntryType0* entry = &data->type0; +/** + * Receives the request for Link's animation frame data + */ +void AnimationContext_LoadFrame(GlobalContext* globalCtx, AnimationEntryData* data) { + AnimEntryLoadFrame* entry = &data->load; osRecvMesg(&entry->msgQueue, NULL, OS_MESG_BLOCK); } -void SkelAnime_AnimationType1Loaded(GlobalContext* globalCtx, AnimationEntryData* data) { - AnimationEntryType1* entry = &data->type1; +/** + * If the entry's queue is enabled, copies all vectors from src to dst + */ +void AnimationContext_CopyAll(GlobalContext* globalCtx, AnimationEntryData* data) { + AnimEntryCopyAll* entry = &data->copy; - if (!(entry->unk_00 & D_8012A480)) { + if (!(entry->queueFlag & sDisableAnimQueueFlags)) { Vec3s* dst = entry->dst; Vec3s* src = entry->src; s32 i; @@ -938,77 +977,92 @@ void SkelAnime_AnimationType1Loaded(GlobalContext* globalCtx, AnimationEntryData } } -void SkelAnime_AnimationType2Loaded(GlobalContext* globalCtx, AnimationEntryData* data) { - AnimationEntryType2* entry = &data->type2; +/** + * If the entry's queue is enabled, interpolates between base and mod, placing the result in base + */ +void AnimationContext_Interp(GlobalContext* globalCtx, AnimationEntryData* data) { + AnimEntryInterp* entry = &data->interp; - if (!(entry->unk_00 & D_8012A480)) { - SkelAnime_InterpolateVec3s(entry->limbCount, entry->unk_04, entry->unk_04, entry->unk_08, entry->unk_0C); + if (!(entry->queueFlag & sDisableAnimQueueFlags)) { + SkelAnime_InterpVec3s(entry->vecCount, entry->base, entry->base, entry->mod, entry->weight); } } -void SkelAnime_AnimationType3Loaded(GlobalContext* globalCtx, AnimationEntryData* data) { - AnimationEntryType3* entry = &data->type3; +/** + * If the entry's queue is enabled, copies all vectors from src to dst whose copy flag is true + */ +void AnimationContext_CopyTrue(GlobalContext* globalCtx, AnimationEntryData* data) { + AnimEntryCopyTrue* entry = &data->copy1; - if (!(entry->unk_00 & D_8012A480)) { + if (!(entry->queueFlag & sDisableAnimQueueFlags)) { Vec3s* dst = entry->dst; Vec3s* src = entry->src; - u8* index = entry->index; + u8* copyFlag = entry->copyFlag; s32 i; for (i = 0; i < entry->vecCount; i++, dst++, src++) { - if (*index++) { + if (*copyFlag++) { *dst = *src; } } } } -void SkelAnime_AnimationType4Loaded(GlobalContext* globalCtx, AnimationEntryData* data) { - AnimationEntryType4* entry = &data->type4; +/** + * If the entry's queue is enabled, copies all vectors from src to dst whose copy flag is false + */ +void AnimationContext_CopyFalse(GlobalContext* globalCtx, AnimationEntryData* data) { + AnimEntryCopyFalse* entry = &data->copy0; - if (!(entry->unk_00 & D_8012A480)) { + if (!(entry->queueFlag & sDisableAnimQueueFlags)) { Vec3s* dst = entry->dst; Vec3s* src = entry->src; - u8* index = entry->index; + u8* copyFlag = entry->copyFlag; s32 i; for (i = 0; i < entry->vecCount; i++, dst++, src++) { - if (!(*index++)) { + if (!(*copyFlag++)) { *dst = *src; } } } } -void SkelAnime_AnimationType5Loaded(GlobalContext* globalCtx, AnimationEntryData* data) { - AnimationEntryType5* entry = &data->type5; +/** + * Moves an actor according to the translation of its root limb + */ +void AnimationContext_MoveActor(GlobalContext* globalCtx, AnimationEntryData* data) { + AnimEntryMoveActor* entry = &data->move; Actor* actor = entry->actor; - Vec3f pos; + Vec3f diff; - func_800A54FC(entry->skelAnime, &pos, actor->shape.rot.y); - actor->posRot.pos.x += pos.x * actor->scale.x; - actor->posRot.pos.y += pos.y * actor->scale.y * entry->unk_08; - actor->posRot.pos.z += pos.z * actor->scale.z; + SkelAnime_UpdateTranslation(entry->skelAnime, &diff, actor->shape.rot.y); + actor->posRot.pos.x += diff.x * actor->scale.x; + actor->posRot.pos.y += diff.y * actor->scale.y * entry->unk_08; + actor->posRot.pos.z += diff.z * actor->scale.z; } -void func_800A390C(GlobalContext* globalCtx, AnimationContext* animationCtx) { - static AnimationEntryCallback sAnimationLoadDone[] = { - SkelAnime_LinkAnimationLoaded, SkelAnime_AnimationType1Loaded, SkelAnime_AnimationType2Loaded, - SkelAnime_AnimationType3Loaded, SkelAnime_AnimationType4Loaded, SkelAnime_AnimationType5Loaded, +/** + * Performs all requests in the animation queue, then resets the queue flags. + */ +void AnimationContext_Update(GlobalContext* globalCtx, AnimationContext* animationCtx) { + static AnimationEntryCallback animFuncs[] = { + AnimationContext_LoadFrame, AnimationContext_CopyAll, AnimationContext_Interp, + AnimationContext_CopyTrue, AnimationContext_CopyFalse, AnimationContext_MoveActor, }; AnimationEntry* entry; for (entry = animationCtx->entries; animationCtx->animationCount != 0; entry++, animationCtx->animationCount--) { - sAnimationLoadDone[entry->type](globalCtx, &entry->data); + animFuncs[entry->type](globalCtx, &entry->data); } - D_801600B0 = 1; - D_8012A480 = 0; + sAnimQueueFlags = 1; + sDisableAnimQueueFlags = 0; } -void SkelAnime_InitLinkAnimation(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, - LinkAnimationHeader* segment, s32 flags, Vec3s* limbDrawTbl, Vec3s* transitionDrawTbl, - s32 limbBufCount) { +void SkelAnime_InitLink(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, + LinkAnimationHeader* segment, s32 flags, Vec3s* jointTable, Vec3s* morphTable, + s32 limbBufCount) { FlexSkeletonHeader* skeletonHeader = SEGMENTED_TO_VIRTUAL(skeletonHeaderSeg); s32 headerJointCount = skeletonHeader->sh.limbCount; s32 limbCount; @@ -1034,634 +1088,657 @@ void SkelAnime_InitLinkAnimation(GlobalContext* globalCtx, SkelAnime* skelAnime, allocSize += 2; } - if (limbDrawTbl == NULL) { - skelAnime->limbDrawTbl = ZeldaArena_MallocDebug(allocSize, "../z_skelanime.c", 2364); - skelAnime->transitionDrawTbl = ZeldaArena_MallocDebug(allocSize, "../z_skelanime.c", 2365); + if (jointTable == NULL) { + skelAnime->jointTable = ZeldaArena_MallocDebug(allocSize, "../z_skelanime.c", 2364); + skelAnime->morphTable = ZeldaArena_MallocDebug(allocSize, "../z_skelanime.c", 2365); } else { if (limbBufCount != limbCount) { __assert("joint_buff_num == joint_num", "../z_skelanime.c", 2369); } - skelAnime->limbDrawTbl = (Vec3s*)ALIGN16((u32)limbDrawTbl); - skelAnime->transitionDrawTbl = (Vec3s*)ALIGN16((u32)transitionDrawTbl); + skelAnime->jointTable = (Vec3s*)ALIGN16((u32)jointTable); + skelAnime->morphTable = (Vec3s*)ALIGN16((u32)morphTable); } - if ((skelAnime->limbDrawTbl == NULL) || (skelAnime->transitionDrawTbl == NULL)) { + if ((skelAnime->jointTable == NULL) || (skelAnime->morphTable == NULL)) { osSyncPrintf(VT_FGCOL(RED)); osSyncPrintf( "Skeleton_Info_Rom_SV_ct メモリアロケーションエラー\n"); // Skeleton_Info_Rom_SV_ct Memory allocation error osSyncPrintf(VT_RST); } - SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, segment, 1.0f, 0.0f, 0.0f, 0, 0.0f); + LinkAnimation_Change(globalCtx, skelAnime, segment, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f); } -void func_800A3B8C(SkelAnime* skelAnime) { - if (skelAnime->mode < 2) { - skelAnime->update = func_800A3D70; +void LinkAnimation_SetUpdateFunction(SkelAnime* skelAnime) { + if (skelAnime->mode <= ANIMMODE_LOOP_INTERP) { + skelAnime->update = LinkAnimation_Loop; } else { - skelAnime->update = func_800A3E0C; + skelAnime->update = LinkAnimation_Once; } - skelAnime->transCurrentFrame = 0.0f; + skelAnime->morphWeight = 0.0f; } -s32 func_800A3BC0(GlobalContext* globalCtx, SkelAnime* skelAnime) { +s32 LinkAnimation_Update(GlobalContext* globalCtx, SkelAnime* skelAnime) { return skelAnime->update(globalCtx, skelAnime); } -s32 func_800A3BE4(GlobalContext* globalCtx, SkelAnime* skelAnime) { - f32 transPrevFRame = skelAnime->transCurrentFrame; +s32 LinkAnimation_Morph(GlobalContext* globalCtx, SkelAnime* skelAnime) { + f32 prevMorphWeight = skelAnime->morphWeight; f32 updateRate = R_UPDATE_RATE * 0.5f; - skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; + skelAnime->morphWeight -= skelAnime->morphRate * updateRate; - if (skelAnime->transCurrentFrame <= 0.0f) { - func_800A3B8C(skelAnime); + if (skelAnime->morphWeight <= 0.0f) { + LinkAnimation_SetUpdateFunction(skelAnime); } - SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->transitionDrawTbl, - 1.0f - (skelAnime->transCurrentFrame / transPrevFRame)); + AnimationContext_SetInterp(globalCtx, skelAnime->limbCount, skelAnime->jointTable, skelAnime->morphTable, + 1.0f - (skelAnime->morphWeight / prevMorphWeight)); return 0; } -void func_800A3C9C(GlobalContext* globalCtx, SkelAnime* skelAnime) { - SkelAnime_LoadLinkAnimation(globalCtx, skelAnime->animation, skelAnime->animCurrentFrame, skelAnime->limbCount, - skelAnime->limbDrawTbl); - if (skelAnime->transCurrentFrame != 0) { +void LinkAnimation_AnimateFrame(GlobalContext* globalCtx, SkelAnime* skelAnime) { + AnimationContext_SetLoadFrame(globalCtx, skelAnime->animation, skelAnime->curFrame, skelAnime->limbCount, + skelAnime->jointTable); + if (skelAnime->morphWeight != 0) { f32 updateRate = R_UPDATE_RATE * 0.5f; - skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; - if (skelAnime->transCurrentFrame <= 0.0f) { - skelAnime->transCurrentFrame = 0.0f; + skelAnime->morphWeight -= skelAnime->morphRate * updateRate; + if (skelAnime->morphWeight <= 0.0f) { + skelAnime->morphWeight = 0.0f; } else { - SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, - skelAnime->transitionDrawTbl, skelAnime->transCurrentFrame); + AnimationContext_SetInterp(globalCtx, skelAnime->limbCount, skelAnime->jointTable, skelAnime->morphTable, + skelAnime->morphWeight); } } } -s32 func_800A3D70(GlobalContext* globalCtx, SkelAnime* skelAnime) { +s32 LinkAnimation_Loop(GlobalContext* globalCtx, SkelAnime* skelAnime) { f32 updateRate = R_UPDATE_RATE * 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; + skelAnime->curFrame += skelAnime->playSpeed * updateRate; + if (skelAnime->curFrame < 0.0f) { + skelAnime->curFrame += skelAnime->animLength; + } else if (skelAnime->animLength <= skelAnime->curFrame) { + skelAnime->curFrame -= skelAnime->animLength; } - func_800A3C9C(globalCtx, skelAnime); + LinkAnimation_AnimateFrame(globalCtx, skelAnime); return 0; } -s32 func_800A3E0C(GlobalContext* globalCtx, SkelAnime* skelAnime) { +s32 LinkAnimation_Once(GlobalContext* globalCtx, SkelAnime* skelAnime) { f32 updateRate = R_UPDATE_RATE * 0.5f; - if (skelAnime->animCurrentFrame == skelAnime->animFrameCount) { - func_800A3C9C(globalCtx, skelAnime); + if (skelAnime->curFrame == skelAnime->endFrame) { + LinkAnimation_AnimateFrame(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; + skelAnime->curFrame += skelAnime->playSpeed * updateRate; + if ((skelAnime->curFrame - skelAnime->endFrame) * skelAnime->playSpeed > 0.0f) { + skelAnime->curFrame = skelAnime->endFrame; + } else if (skelAnime->curFrame < 0.0f) { + skelAnime->curFrame += skelAnime->animLength; + } else if (skelAnime->animLength <= skelAnime->curFrame) { + skelAnime->curFrame -= skelAnime->animLength; } - func_800A3C9C(globalCtx, skelAnime); + LinkAnimation_AnimateFrame(globalCtx, skelAnime); return 0; } -void SkelAnime_SetTransition(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 transitionRate) { - skelAnime->transCurrentFrame = 1.0f; - skelAnime->transitionStep = 1.0f / transitionRate; +void Animation_SetMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 morphFrames) { + skelAnime->morphWeight = 1.0f; + skelAnime->morphRate = 1.0f / morphFrames; } -void SkelAnime_ChangeLinkAnim(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, - f32 playbackSpeed, f32 frame, f32 frameCount, u8 animationMode, f32 transitionRate) { - skelAnime->mode = animationMode; - if ((transitionRate != 0.0f) && ((segment != skelAnime->animation) || (frame != skelAnime->animCurrentFrame))) { - if (transitionRate < 0) { - func_800A3B8C(skelAnime); - SkelAnime_CopyVec3s(skelAnime, skelAnime->transitionDrawTbl, skelAnime->limbDrawTbl); - transitionRate = -transitionRate; +void LinkAnimation_Change(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, f32 playSpeed, + f32 startFrame, f32 endFrame, u8 mode, f32 morphFrames) { + skelAnime->mode = mode; + if ((morphFrames != 0.0f) && ((segment != skelAnime->animation) || (startFrame != skelAnime->curFrame))) { + if (morphFrames < 0) { + LinkAnimation_SetUpdateFunction(skelAnime); + SkelAnime_CopyVec3s(skelAnime, skelAnime->morphTable, skelAnime->jointTable); + morphFrames = -morphFrames; } else { - skelAnime->update = func_800A3BE4; - SkelAnime_LoadLinkAnimation(globalCtx, segment, (s32)frame, skelAnime->limbCount, - skelAnime->transitionDrawTbl); + skelAnime->update = LinkAnimation_Morph; + AnimationContext_SetLoadFrame(globalCtx, segment, (s32)startFrame, skelAnime->limbCount, + skelAnime->morphTable); } - skelAnime->transCurrentFrame = 1.0f; - skelAnime->transitionStep = 1.0f / transitionRate; + skelAnime->morphWeight = 1.0f; + skelAnime->morphRate = 1.0f / morphFrames; } else { - func_800A3B8C(skelAnime); - SkelAnime_LoadLinkAnimation(globalCtx, segment, (s32)frame, skelAnime->limbCount, skelAnime->limbDrawTbl); - skelAnime->transCurrentFrame = 0.0f; + LinkAnimation_SetUpdateFunction(skelAnime); + AnimationContext_SetLoadFrame(globalCtx, segment, (s32)startFrame, skelAnime->limbCount, skelAnime->jointTable); + skelAnime->morphWeight = 0.0f; } skelAnime->animation = segment; - skelAnime->animCurrentFrame = 0.0f; - skelAnime->initialFrame = frame; - skelAnime->animCurrentFrame = frame; - skelAnime->animFrameCount = frameCount; - skelAnime->totalFrames = SkelAnime_GetTotalFrames(segment); - skelAnime->animPlaybackSpeed = playbackSpeed; + skelAnime->curFrame = 0.0f; + skelAnime->startFrame = startFrame; + skelAnime->curFrame = startFrame; + skelAnime->endFrame = endFrame; + skelAnime->animLength = Animation_GetLength(segment); + skelAnime->playSpeed = playSpeed; } -void SkelAnime_ChangeLinkAnimDefaultStop(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment) { - SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, segment, 1.0f, 0.0f, SkelAnime_GetFrameCount(segment), 2, 0.0f); +void LinkAnimation_PlayOnce(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment) { + LinkAnimation_Change(globalCtx, skelAnime, segment, 1.0f, 0.0f, Animation_GetLastFrame(segment), ANIMMODE_ONCE, + 0.0f); } -void SkelAnime_ChangeLinkAnimPlaybackStop(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, - f32 playbackSpeed) { - SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, segment, playbackSpeed, 0.0f, SkelAnime_GetFrameCount(segment), 2, - 0.0f); +void LinkAnimation_PlayOnceSetSpeed(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, + f32 playSpeed) { + LinkAnimation_Change(globalCtx, skelAnime, segment, playSpeed, 0.0f, Animation_GetLastFrame(segment), ANIMMODE_ONCE, + 0.0f); } -void SkelAnime_ChangeLinkAnimDefaultRepeat(GlobalContext* globalCtx, SkelAnime* skelAnime, - LinkAnimationHeader* segment) { - SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, segment, 1.0f, 0.0f, SkelAnime_GetFrameCount(segment), 0, 0.0f); +void LinkAnimation_PlayLoop(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment) { + LinkAnimation_Change(globalCtx, skelAnime, segment, 1.0f, 0.0f, Animation_GetLastFrame(segment), ANIMMODE_LOOP, + 0.0f); } -void SkelAnime_ChangeLinkAnimPlaybackRepeat(GlobalContext* globalCtx, SkelAnime* skelAnime, - LinkAnimationHeader* segment, f32 playbackSpeed) { - SkelAnime_ChangeLinkAnim(globalCtx, skelAnime, segment, playbackSpeed, 0.0f, SkelAnime_GetFrameCount(segment), 0, - 0.0f); +void LinkAnimation_PlayLoopSetSpeed(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, + f32 playSpeed) { + LinkAnimation_Change(globalCtx, skelAnime, segment, playSpeed, 0.0f, Animation_GetLastFrame(segment), ANIMMODE_LOOP, + 0.0f); } -void func_800A41FC(GlobalContext* globalCtx, SkelAnime* skelAnime) { - SkelAnime_LoadAnimationType1(globalCtx, skelAnime->limbCount, skelAnime->transitionDrawTbl, skelAnime->limbDrawTbl); +/** + * Requests copying jointTable to morphTable + */ +void LinkAnimation_CopyJointToMorph(GlobalContext* globalCtx, SkelAnime* skelAnime) { + AnimationContext_SetCopyAll(globalCtx, skelAnime->limbCount, skelAnime->morphTable, skelAnime->jointTable); } -// Unused -void func_800A422C(GlobalContext* globalCtx, SkelAnime* skelAnime) { - SkelAnime_LoadAnimationType1(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->transitionDrawTbl); +/** + * Requests copying morphTable to jointTable + * unused + */ +void LinkAnimation_CopyMorphToJoint(GlobalContext* globalCtx, SkelAnime* skelAnime) { + AnimationContext_SetCopyAll(globalCtx, skelAnime->limbCount, skelAnime->jointTable, skelAnime->morphTable); } -void func_800A425C(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, f32 frame) { - SkelAnime_LoadLinkAnimation(globalCtx, segment, (s32)frame, skelAnime->limbCount, skelAnime->transitionDrawTbl); +/** + * Requests loading frame data from the Link animation at segment into morphTable + */ +void LinkAnimation_LoadToMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, + f32 frame) { + AnimationContext_SetLoadFrame(globalCtx, segment, (s32)frame, skelAnime->limbCount, skelAnime->morphTable); } -void func_800A42A0(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, f32 frame) { - SkelAnime_LoadLinkAnimation(globalCtx, segment, (s32)frame, skelAnime->limbCount, skelAnime->limbDrawTbl); +/** + * Requests loading frame data from the Link animation at segment into jointTable + */ +void LinkAnimation_LoadToJoint(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, + f32 frame) { + AnimationContext_SetLoadFrame(globalCtx, segment, (s32)frame, skelAnime->limbCount, skelAnime->jointTable); } -void func_800A42E4(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 frame) { - SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->transitionDrawTbl, - frame); +/** + * Requests interpolating between jointTable and morphTable, placing the result in jointTable + */ +void LinkAnimation_InterpJointMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 weight) { + AnimationContext_SetInterp(globalCtx, skelAnime->limbCount, skelAnime->jointTable, skelAnime->morphTable, weight); } -void func_800A431C(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, f32 transitionFrame, - LinkAnimationHeader* linkAnimSeg2, f32 frame, f32 transitionRate, Vec3s* limbDrawTbl) { - Vec3s* alignedLimbDrawTbl; +/** + * Requests loading frame data from the Link animation segments and blending them, placing the result in jointTable + */ +void LinkAnimation_BlendToJoint(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation1, + f32 frame1, LinkAnimationHeader* animation2, f32 frame2, f32 blendWeight, + Vec3s* blendTable) { + Vec3s* alignedBlendTable; - SkelAnime_LoadLinkAnimation(globalCtx, segment, (s32)transitionFrame, skelAnime->limbCount, skelAnime->limbDrawTbl); + AnimationContext_SetLoadFrame(globalCtx, animation1, (s32)frame1, skelAnime->limbCount, skelAnime->jointTable); - alignedLimbDrawTbl = (Vec3s*)ALIGN16((u32)limbDrawTbl); + alignedBlendTable = (Vec3s*)ALIGN16((u32)blendTable); - SkelAnime_LoadLinkAnimation(globalCtx, linkAnimSeg2, (s32)frame, skelAnime->limbCount, alignedLimbDrawTbl); - SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->limbDrawTbl, alignedLimbDrawTbl, - transitionRate); + AnimationContext_SetLoadFrame(globalCtx, animation2, (s32)frame2, skelAnime->limbCount, alignedBlendTable); + AnimationContext_SetInterp(globalCtx, skelAnime->limbCount, skelAnime->jointTable, alignedBlendTable, blendWeight); } -void func_800A43B8(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* segment, f32 transitionFrame, - LinkAnimationHeader* linkAnimSeg2, f32 frame, f32 transitionRate, Vec3s* limbDrawTbl) { - Vec3s* alignedLimbDrawTbl; +/** + * Requests loading frame data from the Link animation segments and blending them, placing the result in morphTable + */ +void LinkAnimation_BlendToMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation1, + f32 frame1, LinkAnimationHeader* animation2, f32 frame2, f32 blendWeight, + Vec3s* blendTable) { + Vec3s* alignedBlendTable; - SkelAnime_LoadLinkAnimation(globalCtx, segment, (s32)transitionFrame, skelAnime->limbCount, - skelAnime->transitionDrawTbl); + AnimationContext_SetLoadFrame(globalCtx, animation1, (s32)frame1, skelAnime->limbCount, skelAnime->morphTable); - alignedLimbDrawTbl = (Vec3s*)ALIGN16((u32)limbDrawTbl); + alignedBlendTable = (Vec3s*)ALIGN16((u32)blendTable); - SkelAnime_LoadLinkAnimation(globalCtx, linkAnimSeg2, (s32)frame, skelAnime->limbCount, alignedLimbDrawTbl); - SkelAnime_LoadAnimationType2(globalCtx, skelAnime->limbCount, skelAnime->transitionDrawTbl, alignedLimbDrawTbl, - transitionRate); + AnimationContext_SetLoadFrame(globalCtx, animation2, (s32)frame2, skelAnime->limbCount, alignedBlendTable); + AnimationContext_SetInterp(globalCtx, skelAnime->limbCount, skelAnime->morphTable, alignedBlendTable, blendWeight); } // unused -void SkelAnime_SetModeStop(SkelAnime* skelAnime) { - skelAnime->mode = 2; - func_800A3B8C(skelAnime); +void LinkAnimation_EndLoop(SkelAnime* skelAnime) { + skelAnime->mode = ANIMMODE_ONCE; + LinkAnimation_SetUpdateFunction(skelAnime); } -s32 func_800A4478(SkelAnime* skelAnime, f32 arg1, f32 updateRate) { - f32 updateSpeed = skelAnime->animPlaybackSpeed * updateRate; - f32 nextFrame = skelAnime->animCurrentFrame - updateSpeed; - f32 temp_f12; +s32 Animation_OnFrameImpl(SkelAnime* skelAnime, f32 frame, f32 updateRate) { + f32 updateSpeed = skelAnime->playSpeed * updateRate; + f32 prevFrame = skelAnime->curFrame - updateSpeed; + f32 curFrameDiff; + f32 prevFrameDiff; - if (nextFrame < 0.0f) { - nextFrame += skelAnime->totalFrames; - } else if (skelAnime->totalFrames <= nextFrame) { - nextFrame -= skelAnime->totalFrames; + if (prevFrame < 0.0f) { + prevFrame += skelAnime->animLength; + } else if (prevFrame >= skelAnime->animLength) { + prevFrame -= skelAnime->animLength; } - if ((arg1 == 0.0f) && (updateSpeed > 0.0f)) { - arg1 = skelAnime->totalFrames; + if ((frame == 0.0f) && (updateSpeed > 0.0f)) { + frame = skelAnime->animLength; } - temp_f12 = nextFrame + updateSpeed - arg1; - if ((temp_f12 * updateSpeed >= 0.0f) && (((temp_f12 - updateSpeed) * updateSpeed) < 0.0f)) { - return 1; + curFrameDiff = prevFrame + updateSpeed - frame; + prevFrameDiff = curFrameDiff - updateSpeed; + if ((curFrameDiff * updateSpeed >= 0.0f) && (prevFrameDiff * updateSpeed < 0.0f)) { + return true; } - return 0; + return false; } -s32 func_800A4530(SkelAnime* skelAnime, f32 arg1) { +s32 LinkAnimation_OnFrame(SkelAnime* skelAnime, f32 frame) { f32 updateRate = R_UPDATE_RATE * 0.5f; - return func_800A4478(skelAnime, arg1, updateRate); + return Animation_OnFrameImpl(skelAnime, frame, updateRate); } s32 SkelAnime_Init(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, - AnimationHeader* animationSeg, Vec3s* limbDrawTbl, Vec3s* transitionDrawTable, s32 limbCount) { + AnimationHeader* animation, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount) { SkeletonHeader* skeletonHeader = SEGMENTED_TO_VIRTUAL(skeletonHeaderSeg); skelAnime->limbCount = skeletonHeader->limbCount + 1; skelAnime->skeleton = SEGMENTED_TO_VIRTUAL(skeletonHeader->segment); - if (limbDrawTbl == NULL) { - skelAnime->limbDrawTbl = - ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->limbDrawTbl), "../z_skelanime.c", 2968); - skelAnime->transitionDrawTbl = ZeldaArena_MallocDebug( - skelAnime->limbCount * sizeof(*skelAnime->transitionDrawTbl), "../z_skelanime.c", 2969); + if (jointTable == NULL) { + skelAnime->jointTable = + ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->jointTable), "../z_skelanime.c", 2968); + skelAnime->morphTable = + ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->morphTable), "../z_skelanime.c", 2969); } else { if (limbCount != skelAnime->limbCount) { __assert("joint_buff_num == this->joint_num", "../z_skelanime.c", 2973); } - skelAnime->limbDrawTbl = limbDrawTbl; - skelAnime->transitionDrawTbl = transitionDrawTable; + skelAnime->jointTable = jointTable; + skelAnime->morphTable = morphTable; } - if ((skelAnime->limbDrawTbl == NULL) || (skelAnime->transitionDrawTbl == NULL)) { + if ((skelAnime->jointTable == NULL) || (skelAnime->morphTable == NULL)) { osSyncPrintf(VT_FGCOL(RED)); osSyncPrintf("Skeleton_Info2_ct メモリアロケーションエラー\n"); // Skeleton_Info2_ct memory allocation error osSyncPrintf(VT_RST); } - if (animationSeg != NULL) { - SkelAnime_ChangeAnimDefaultRepeat(skelAnime, animationSeg); + if (animation != NULL) { + Animation_PlayLoop(skelAnime, animation); } } s32 SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, - AnimationHeader* animationSeg, Vec3s* limbDrawTbl, Vec3s* transitionDrawTable, s32 limbCount) { + AnimationHeader* animation, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount) { FlexSkeletonHeader* skeletonHeader = SEGMENTED_TO_VIRTUAL(skeletonHeaderSeg); skelAnime->limbCount = skeletonHeader->sh.limbCount + 1; skelAnime->dListCount = skeletonHeader->dListCount; skelAnime->skeleton = SEGMENTED_TO_VIRTUAL(skeletonHeader->sh.segment); - if (limbDrawTbl == NULL) { - skelAnime->limbDrawTbl = - ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->limbDrawTbl), "../z_skelanime.c", 3047); + if (jointTable == NULL) { + skelAnime->jointTable = + ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->jointTable), "../z_skelanime.c", 3047); - skelAnime->transitionDrawTbl = ZeldaArena_MallocDebug( - skelAnime->limbCount * sizeof(*skelAnime->transitionDrawTbl), "../z_skelanime.c", 3048); + skelAnime->morphTable = + ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->morphTable), "../z_skelanime.c", 3048); } else { if (limbCount != skelAnime->limbCount) { __assert("joint_buff_num == this->joint_num", "../z_skelanime.c", 3052); } - skelAnime->limbDrawTbl = limbDrawTbl; - skelAnime->transitionDrawTbl = transitionDrawTable; + skelAnime->jointTable = jointTable; + skelAnime->morphTable = morphTable; } - if ((skelAnime->limbDrawTbl == NULL) || (skelAnime->transitionDrawTbl == NULL)) { + if ((skelAnime->jointTable == NULL) || (skelAnime->morphTable == NULL)) { osSyncPrintf(VT_FGCOL(RED)); osSyncPrintf( "Skeleton_Info_Rom_SV_ct メモリアロケーションエラー\n"); // Skeleton_Info_Rom_SV_ct Memory allocation error osSyncPrintf(VT_RST); } - if (animationSeg != NULL) { - SkelAnime_ChangeAnimDefaultRepeat(skelAnime, animationSeg); + if (animation != NULL) { + Animation_PlayLoop(skelAnime, animation); } } -void SkelAnime_InitSkin(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, - AnimationHeader* animationSeg) { +s32 SkelAnime_InitSkin(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animation) { SkeletonHeader* skeletonHeader = SEGMENTED_TO_VIRTUAL(skeletonHeaderSeg); skelAnime->limbCount = skeletonHeader->limbCount + 1; skelAnime->skeleton = SEGMENTED_TO_VIRTUAL(skeletonHeader->segment); - skelAnime->limbDrawTbl = - ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->limbDrawTbl), "../z_skelanime.c", 3120); - skelAnime->transitionDrawTbl = - ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->transitionDrawTbl), "../z_skelanime.c", 3121); - if ((skelAnime->limbDrawTbl == NULL) || (skelAnime->transitionDrawTbl == NULL)) { + skelAnime->jointTable = + ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->jointTable), "../z_skelanime.c", 3120); + skelAnime->morphTable = + ZeldaArena_MallocDebug(skelAnime->limbCount * sizeof(*skelAnime->morphTable), "../z_skelanime.c", 3121); + if ((skelAnime->jointTable == NULL) || (skelAnime->morphTable == NULL)) { osSyncPrintf(VT_FGCOL(RED)); osSyncPrintf( "Skeleton_Info2_skin2_ct メモリアロケーションエラー\n"); // Skeleton_Info2_skin2_ct Memory allocation error osSyncPrintf(VT_RST); } - if (animationSeg != NULL) { - SkelAnime_ChangeAnimDefaultRepeat(skelAnime, animationSeg); + if (animation != NULL) { + Animation_PlayLoop(skelAnime, animation); } } -void func_800A49B0(SkelAnime* skelAnime) { - if (skelAnime->mode < 2) { - skelAnime->update = func_800A4D9C; - } else if (skelAnime->mode < 4) { - skelAnime->update = func_800A4EE0; +void SkelAnime_SetUpdate(SkelAnime* skelAnime) { + if (skelAnime->mode <= ANIMMODE_LOOP_INTERP) { + skelAnime->update = SkelAnime_LoopFull; + } else if (skelAnime->mode <= ANIMMODE_ONCE_INTERP) { + skelAnime->update = SkelAnime_Once; } else { - skelAnime->update = func_800A4E38; + skelAnime->update = SkelAnime_LoopPartial; } } -s32 SkelAnime_FrameUpdateMatrix(SkelAnime* skelAnime) { +s32 SkelAnime_Update(SkelAnime* skelAnime) { return skelAnime->update(skelAnime); } -s32 func_800A4A20(SkelAnime* skelAnime) { - f32 transPrevFrame = skelAnime->transCurrentFrame; +s32 SkelAnime_Morph(SkelAnime* skelAnime) { + f32 prevMorphWeight = skelAnime->morphWeight; f32 updateRate = R_UPDATE_RATE * (1.0f / 3.0f); - skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; - if (skelAnime->transCurrentFrame <= 0.0f) { - func_800A49B0(skelAnime); - skelAnime->transCurrentFrame = 0.0f; + skelAnime->morphWeight -= skelAnime->morphRate * updateRate; + if (skelAnime->morphWeight <= 0.0f) { + SkelAnime_SetUpdate(skelAnime); + skelAnime->morphWeight = 0.0f; } - SkelAnime_InterpolateVec3s(skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->limbDrawTbl, - skelAnime->transitionDrawTbl, 1.0f - (skelAnime->transCurrentFrame / transPrevFrame)); + SkelAnime_InterpVec3s(skelAnime->limbCount, skelAnime->jointTable, skelAnime->jointTable, skelAnime->morphTable, + 1.0f - (skelAnime->morphWeight / prevMorphWeight)); return 0; } -s32 func_800A4AD8(SkelAnime* skelAnime) { - s16 temp_a2 = skelAnime->transCurrentFrame * 0x4000; - s16 temp_a1; - f32 sp28; - f32 phi_f2; +s32 SkelAnime_MorphTaper(SkelAnime* skelAnime) { + s16 prevPhase = skelAnime->morphWeight * 0x4000; + s16 curPhase; + f32 prevWeight; + f32 curWeight; f32 updateRate = R_UPDATE_RATE * (1.0f / 3.0f); - skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; - if (skelAnime->transCurrentFrame <= 0.0f) { - func_800A49B0(skelAnime); - skelAnime->transCurrentFrame = 0.0f; + skelAnime->morphWeight -= skelAnime->morphRate * updateRate; + if (skelAnime->morphWeight <= 0.0f) { + SkelAnime_SetUpdate(skelAnime); + skelAnime->morphWeight = 0.0f; } - temp_a1 = skelAnime->transCurrentFrame * 0x4000; - if (skelAnime->unk_03 < 0) { - sp28 = 1.0f - Math_CosS(temp_a2); - phi_f2 = 1.0f - Math_CosS(temp_a1); + curPhase = skelAnime->morphWeight * 0x4000; + if (skelAnime->taper <= ANIMTAPER_DECEL) { + prevWeight = 1.0f - Math_CosS(prevPhase); + curWeight = 1.0f - Math_CosS(curPhase); } else { - sp28 = Math_SinS(temp_a2); - phi_f2 = Math_SinS(temp_a1); + prevWeight = Math_SinS(prevPhase); + curWeight = Math_SinS(curPhase); } - if (phi_f2 != 0.0f) { - phi_f2 /= sp28; + if (curWeight != 0.0f) { + curWeight /= prevWeight; } else { - phi_f2 = 0.0f; + curWeight = 0.0f; } - SkelAnime_InterpolateVec3s(skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->limbDrawTbl, - skelAnime->transitionDrawTbl, 1.0f - phi_f2); + SkelAnime_InterpVec3s(skelAnime->limbCount, skelAnime->jointTable, skelAnime->jointTable, skelAnime->morphTable, + 1.0f - curWeight); return 0; } -void func_800A4C58(SkelAnime* skelAnime) { - Vec3s sp38[100]; +void SkelAnime_AnimateFrame(SkelAnime* skelAnime) { + Vec3s nextjointTable[100]; - SkelAnime_AnimateFrame(skelAnime->animation, skelAnime->animCurrentFrame, skelAnime->limbCount, - skelAnime->limbDrawTbl); - if (skelAnime->mode & 1) { - s32 t = skelAnime->animCurrentFrame; - f32 sp30 = skelAnime->animCurrentFrame - t; + SkelAnime_GetFrameData(skelAnime->animation, skelAnime->curFrame, skelAnime->limbCount, skelAnime->jointTable); + if (skelAnime->mode & ANIM_INTERP) { + s32 frame = skelAnime->curFrame; + f32 partialFrame = skelAnime->curFrame - frame; - if (++t >= (s32)skelAnime->totalFrames) { - t = 0; + if (++frame >= (s32)skelAnime->animLength) { + frame = 0; } - SkelAnime_AnimateFrame(skelAnime->animation, t, skelAnime->limbCount, sp38); - SkelAnime_InterpolateVec3s(skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->limbDrawTbl, sp38, sp30); + SkelAnime_GetFrameData(skelAnime->animation, frame, skelAnime->limbCount, nextjointTable); + SkelAnime_InterpVec3s(skelAnime->limbCount, skelAnime->jointTable, skelAnime->jointTable, nextjointTable, + partialFrame); } - if (skelAnime->transCurrentFrame != 0) { + if (skelAnime->morphWeight != 0) { f32 updateRate = R_UPDATE_RATE * (1.0f / 3.0f); - skelAnime->transCurrentFrame -= skelAnime->transitionStep * updateRate; - if (skelAnime->transCurrentFrame <= 0.0f) { - skelAnime->transCurrentFrame = 0.0f; + skelAnime->morphWeight -= skelAnime->morphRate * updateRate; + if (skelAnime->morphWeight <= 0.0f) { + skelAnime->morphWeight = 0.0f; } else { - SkelAnime_InterpolateVec3s(skelAnime->limbCount, skelAnime->limbDrawTbl, skelAnime->limbDrawTbl, - skelAnime->transitionDrawTbl, skelAnime->transCurrentFrame); + SkelAnime_InterpVec3s(skelAnime->limbCount, skelAnime->jointTable, skelAnime->jointTable, + skelAnime->morphTable, skelAnime->morphWeight); } } } -s32 func_800A4D9C(SkelAnime* skelAnime) { +s32 SkelAnime_LoopFull(SkelAnime* skelAnime) { f32 updateRate = R_UPDATE_RATE * (1.0f / 3.0f); - skelAnime->animCurrentFrame += skelAnime->animPlaybackSpeed * updateRate; - if (skelAnime->animCurrentFrame < 0.0f) { - skelAnime->animCurrentFrame += skelAnime->totalFrames; - } else if (skelAnime->totalFrames <= skelAnime->animCurrentFrame) { - skelAnime->animCurrentFrame -= skelAnime->totalFrames; + skelAnime->curFrame += skelAnime->playSpeed * updateRate; + if (skelAnime->curFrame < 0.0f) { + skelAnime->curFrame += skelAnime->animLength; + } else if (skelAnime->animLength <= skelAnime->curFrame) { + skelAnime->curFrame -= skelAnime->animLength; } - func_800A4C58(skelAnime); + SkelAnime_AnimateFrame(skelAnime); return 0; } -s32 func_800A4E38(SkelAnime* skelAnime) { +s32 SkelAnime_LoopPartial(SkelAnime* skelAnime) { f32 updateRate = R_UPDATE_RATE * (1.0f / 3.0f); - 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; + skelAnime->curFrame += skelAnime->playSpeed * updateRate; + if (skelAnime->curFrame < skelAnime->startFrame) { + skelAnime->curFrame = (skelAnime->curFrame - skelAnime->startFrame) + skelAnime->endFrame; + } else if (skelAnime->endFrame <= skelAnime->curFrame) { + skelAnime->curFrame = (skelAnime->curFrame - skelAnime->endFrame) + skelAnime->startFrame; } - func_800A4C58(skelAnime); + SkelAnime_AnimateFrame(skelAnime); return 0; } -s32 func_800A4EE0(SkelAnime* skelAnime) { +s32 SkelAnime_Once(SkelAnime* skelAnime) { f32 updateRate = R_UPDATE_RATE * (1.0f / 3.0f); - if (skelAnime->animCurrentFrame == skelAnime->animFrameCount) { - SkelAnime_AnimateFrame(skelAnime->animation, (s32)skelAnime->animCurrentFrame, skelAnime->limbCount, - skelAnime->limbDrawTbl); - func_800A4C58(skelAnime); + if (skelAnime->curFrame == skelAnime->endFrame) { + SkelAnime_GetFrameData(skelAnime->animation, (s32)skelAnime->curFrame, skelAnime->limbCount, + skelAnime->jointTable); + SkelAnime_AnimateFrame(skelAnime); return 1; } - skelAnime->animCurrentFrame += skelAnime->animPlaybackSpeed * updateRate; + skelAnime->curFrame += skelAnime->playSpeed * 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; + if ((skelAnime->curFrame - skelAnime->endFrame) * skelAnime->playSpeed > 0.0f) { + skelAnime->curFrame = skelAnime->endFrame; + } else if (skelAnime->curFrame < 0.0f) { + skelAnime->curFrame += skelAnime->animLength; + } else if (skelAnime->animLength <= skelAnime->curFrame) { + skelAnime->curFrame -= skelAnime->animLength; } - func_800A4C58(skelAnime); + SkelAnime_AnimateFrame(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->animation) || (frame != skelAnime->animCurrentFrame))) { - if (transitionRate < 0) { - func_800A49B0(skelAnime); - SkelAnime_CopyVec3s(skelAnime, skelAnime->transitionDrawTbl, skelAnime->limbDrawTbl); - transitionRate = -transitionRate; +void Animation_ChangeImpl(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed, f32 startFrame, f32 endFrame, + u8 mode, f32 morphFrames, s8 taper) { + skelAnime->mode = mode; + if ((morphFrames != 0.0f) && ((animation != skelAnime->animation) || (startFrame != skelAnime->curFrame))) { + if (morphFrames < 0) { + SkelAnime_SetUpdate(skelAnime); + SkelAnime_CopyVec3s(skelAnime, skelAnime->morphTable, skelAnime->jointTable); + morphFrames = -morphFrames; } else { - if (unk2 != 0) { - skelAnime->update = func_800A4AD8; - skelAnime->unk_03 = unk2; + if (taper != ANIMTAPER_NONE) { + skelAnime->update = SkelAnime_MorphTaper; + skelAnime->taper = taper; } else { - skelAnime->update = func_800A4A20; + skelAnime->update = SkelAnime_Morph; } - SkelAnime_AnimateFrame(animationSeg, frame, skelAnime->limbCount, skelAnime->transitionDrawTbl); + SkelAnime_GetFrameData(animation, startFrame, skelAnime->limbCount, skelAnime->morphTable); } - skelAnime->transCurrentFrame = 1.0f; - skelAnime->transitionStep = 1.0f / transitionRate; + skelAnime->morphWeight = 1.0f; + skelAnime->morphRate = 1.0f / morphFrames; } else { - func_800A49B0(skelAnime); - SkelAnime_AnimateFrame(animationSeg, frame, skelAnime->limbCount, skelAnime->limbDrawTbl); - skelAnime->transCurrentFrame = 0.0f; + SkelAnime_SetUpdate(skelAnime); + SkelAnime_GetFrameData(animation, startFrame, skelAnime->limbCount, skelAnime->jointTable); + skelAnime->morphWeight = 0.0f; } - skelAnime->animation = animationSeg; - skelAnime->initialFrame = frame; - skelAnime->animFrameCount = frameCount; - skelAnime->totalFrames = SkelAnime_GetTotalFrames(animationSeg); - if (skelAnime->mode >= 4) { - skelAnime->animCurrentFrame = 0.0f; + skelAnime->animation = animation; + skelAnime->startFrame = startFrame; + skelAnime->endFrame = endFrame; + skelAnime->animLength = Animation_GetLength(animation); + if (skelAnime->mode >= ANIMMODE_LOOP_PARTIAL) { + skelAnime->curFrame = 0.0f; } else { - skelAnime->animCurrentFrame = frame; - if (skelAnime->mode <= 1) { - skelAnime->animFrameCount = skelAnime->totalFrames - 1.0f; + skelAnime->curFrame = startFrame; + if (skelAnime->mode <= ANIMMODE_LOOP_INTERP) { + skelAnime->endFrame = skelAnime->animLength - 1.0f; } } - skelAnime->animPlaybackSpeed = playbackSpeed; + skelAnime->playSpeed = playSpeed; } -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 Animation_Change(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed, f32 startFrame, f32 endFrame, + u8 mode, f32 morphFrames) { + Animation_ChangeImpl(skelAnime, animation, playSpeed, startFrame, endFrame, mode, morphFrames, ANIMTAPER_NONE); } -void SkelAnime_ChangeAnimDefaultStop(SkelAnime* skelAnime, AnimationHeader* animationSeg) { - SkelAnime_ChangeAnim(skelAnime, animationSeg, 1.0f, 0.0f, SkelAnime_GetFrameCount(animationSeg), 2, 0.0f); +void Animation_PlayOnce(SkelAnime* skelAnime, AnimationHeader* animation) { + Animation_Change(skelAnime, animation, 1.0f, 0.0f, Animation_GetLastFrame(animation), ANIMMODE_ONCE, 0.0f); } -void SkelAnime_ChangeAnimTransitionStop(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 transitionRate) { - SkelAnime_ChangeAnim(skelAnime, animationSeg, 1.0f, 0, SkelAnime_GetFrameCount(animationSeg), 2, transitionRate); +void Animation_MorphToPlayOnce(SkelAnime* skelAnime, AnimationHeader* animation, f32 morphFrames) { + Animation_Change(skelAnime, animation, 1.0f, 0.0f, Animation_GetLastFrame(animation), ANIMMODE_ONCE, morphFrames); } -void SkelAnime_ChangeAnimPlaybackStop(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed) { - SkelAnime_ChangeAnim(skelAnime, animationSeg, playbackSpeed, 0.0f, SkelAnime_GetFrameCount(animationSeg), 2, 0.0f); +void Animation_PlayOnceSetSpeed(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed) { + Animation_Change(skelAnime, animation, playSpeed, 0.0f, Animation_GetLastFrame(animation), ANIMMODE_ONCE, 0.0f); } -void SkelAnime_ChangeAnimDefaultRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg) { - SkelAnime_ChangeAnim(skelAnime, animationSeg, 1.0f, 0.0f, SkelAnime_GetFrameCount(animationSeg), 0, 0.0f); +void Animation_PlayLoop(SkelAnime* skelAnime, AnimationHeader* animation) { + Animation_Change(skelAnime, animation, 1.0f, 0.0f, Animation_GetLastFrame(animation), ANIMMODE_LOOP, 0.0f); } -void SkelAnime_ChangeAnimTransitionRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 transitionRate) { - SkelAnime_ChangeAnim(skelAnime, animationSeg, 1.0f, 0.0f, 0.0f, 0, transitionRate); +void Animation_MorphToLoop(SkelAnime* skelAnime, AnimationHeader* animation, f32 morphFrames) { + Animation_Change(skelAnime, animation, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, morphFrames); } -void SkelAnime_ChangeAnimPlaybackRepeat(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed) { - SkelAnime_ChangeAnim(skelAnime, animationSeg, playbackSpeed, 0.0f, SkelAnime_GetFrameCount(animationSeg), 0, 0.0f); +void Animation_PlayLoopSetSpeed(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed) { + Animation_Change(skelAnime, animation, playSpeed, 0.0f, Animation_GetLastFrame(animation), ANIMMODE_LOOP, 0.0f); } // unused -void SkelAnime_AnimSetStop(SkelAnime* skelAnime) { - skelAnime->mode = 2; - skelAnime->animFrameCount = skelAnime->totalFrames; - func_800A49B0(skelAnime); +void Animation_EndLoop(SkelAnime* skelAnime) { + skelAnime->mode = ANIMMODE_ONCE; + skelAnime->endFrame = skelAnime->animLength; + SkelAnime_SetUpdate(skelAnime); } -void SkelAnime_AnimReverse(SkelAnime* skelAnime) { - f32 initialFrame = skelAnime->initialFrame; +void Animation_Reverse(SkelAnime* skelAnime) { + f32 startFrame = skelAnime->startFrame; - skelAnime->initialFrame = skelAnime->animFrameCount; - skelAnime->animPlaybackSpeed = -skelAnime->animPlaybackSpeed; - skelAnime->animFrameCount = initialFrame; + skelAnime->startFrame = skelAnime->endFrame; + skelAnime->playSpeed = -skelAnime->playSpeed; + skelAnime->endFrame = startFrame; } -void func_800A5428(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* index) { +void SkelAnime_CopyVec3sTrue(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* copyFlag) { s32 i; for (i = 0; i < skelAnime->limbCount; i++, dst++, src++) { - if (*index++) { + if (*copyFlag++) { *dst = *src; } } } // unused -void func_800A5490(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* arg3) { +void SkelAnime_CopyVec3sFalse(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* copyFlag) { s32 i; for (i = 0; i < skelAnime->limbCount; i++, dst++, src++) { - if (*arg3++ < 1U) { + if (!*copyFlag++) { *dst = *src; } } } -/* - * Moves `pos` backwards on the xz plane from `angle` +/** + * Updates translation of the root limb and calculates `pos`, the difference between + * the old and new positions of the root limb as rotated by `angle`. Used to allow + * animations to change an actor's position. */ -void func_800A54FC(SkelAnime* skelAnime, Vec3f* pos, s16 angle) { +void SkelAnime_UpdateTranslation(SkelAnime* skelAnime, Vec3f* diff, s16 angle) { f32 x; f32 z; f32 sin; f32 cos; - if (skelAnime->flags & 0x10) { - pos->x = pos->z = 0.0f; + if (skelAnime->moveFlags & ANIM_FLAG_NOMOVE) { + diff->x = diff->z = 0.0f; } else { // `angle` rotation around y axis. - x = skelAnime->limbDrawTbl[0].x; - z = skelAnime->limbDrawTbl[0].z; + x = skelAnime->jointTable[0].x; + z = skelAnime->jointTable[0].z; sin = Math_SinS(angle); cos = Math_CosS(angle); - pos->x = x * cos + z * sin; - pos->z = z * cos - x * sin; - x = skelAnime->prevFramePos.x; - z = skelAnime->prevFramePos.z; - // `prevFrameRot` rotation around y axis. - sin = Math_SinS(skelAnime->prevFrameRot); - cos = Math_CosS(skelAnime->prevFrameRot); - pos->x -= x * cos + z * sin; - pos->z -= z * cos - x * sin; - } - - skelAnime->prevFrameRot = angle; - skelAnime->prevFramePos.x = skelAnime->limbDrawTbl[0].x; - skelAnime->limbDrawTbl[0].x = skelAnime->unk_3E.x; - skelAnime->prevFramePos.z = skelAnime->limbDrawTbl[0].z; - skelAnime->limbDrawTbl[0].z = skelAnime->unk_3E.z; - if (skelAnime->flags & ANIM_FLAG_UPDATEXZ) { - if (skelAnime->flags & ANIM_FLAG_UPDATEY) { - pos->y = 0.0f; + diff->x = x * cos + z * sin; + diff->z = z * cos - x * sin; + x = skelAnime->prevTransl.x; + z = skelAnime->prevTransl.z; + // `prevRot` rotation around y axis. + sin = Math_SinS(skelAnime->prevRot); + cos = Math_CosS(skelAnime->prevRot); + diff->x -= x * cos + z * sin; + diff->z -= z * cos - x * sin; + } + + skelAnime->prevRot = angle; + skelAnime->prevTransl.x = skelAnime->jointTable[0].x; + skelAnime->jointTable[0].x = skelAnime->baseTransl.x; + skelAnime->prevTransl.z = skelAnime->jointTable[0].z; + skelAnime->jointTable[0].z = skelAnime->baseTransl.z; + if (skelAnime->moveFlags & ANIM_FLAG_UPDATEY) { + if (skelAnime->moveFlags & ANIM_FLAG_NOMOVE) { + diff->y = 0.0f; } else { - pos->y = skelAnime->limbDrawTbl[0].y - skelAnime->prevFramePos.y; + diff->y = skelAnime->jointTable[0].y - skelAnime->prevTransl.y; } - skelAnime->prevFramePos.y = skelAnime->limbDrawTbl[0].y; - skelAnime->limbDrawTbl[0].y = skelAnime->unk_3E.y; + skelAnime->prevTransl.y = skelAnime->jointTable[0].y; + skelAnime->jointTable[0].y = skelAnime->baseTransl.y; } else { - pos->y = 0.0f; - skelAnime->prevFramePos.y = skelAnime->limbDrawTbl[0].y; + diff->y = 0.0f; + skelAnime->prevTransl.y = skelAnime->jointTable[0].y; } - skelAnime->flags &= ~ANIM_FLAG_UPDATEY; + skelAnime->moveFlags &= ~ANIM_FLAG_NOMOVE; } -s32 func_800A56C8(SkelAnime* skelAnime, f32 arg1) { - return func_800A4478(skelAnime, arg1, 1.0f); +s32 Animation_OnFrame(SkelAnime* skelAnime, f32 frame) { + return Animation_OnFrameImpl(skelAnime, frame, 1.0f); } void SkelAnime_Free(SkelAnime* skelAnime, GlobalContext* globalCtx) { - if (skelAnime->limbDrawTbl != NULL) { - ZeldaArena_FreeDebug(skelAnime->limbDrawTbl, "../z_skelanime.c", 3729); + if (skelAnime->jointTable != NULL) { + ZeldaArena_FreeDebug(skelAnime->jointTable, "../z_skelanime.c", 3729); } else { - osSyncPrintf("now_joint あきまへん!!\n"); // now_joint Akimane! ! + osSyncPrintf("now_joint あきまへん!!\n"); // now_joint is freed! ! } - if (skelAnime->transitionDrawTbl != NULL) { - ZeldaArena_FreeDebug(skelAnime->transitionDrawTbl, "../z_skelanime.c", 3731); + if (skelAnime->morphTable != NULL) { + ZeldaArena_FreeDebug(skelAnime->morphTable, "../z_skelanime.c", 3731); } else { - osSyncPrintf("morf_joint あきまへん!!\n"); // "morf_joint Akimane !!" + osSyncPrintf("morf_joint あきまへん!!\n"); // "morf_joint is freed !!" } } |
