diff --git a/mm/src/overlays/actors/ovl_En_Kbt/z_en_kbt.c b/mm/src/overlays/actors/ovl_En_Kbt/z_en_kbt.c index a96612a2e..670a419ab 100644 --- a/mm/src/overlays/actors/ovl_En_Kbt/z_en_kbt.c +++ b/mm/src/overlays/actors/ovl_En_Kbt/z_en_kbt.c @@ -5,6 +5,7 @@ */ #include "z_en_kbt.h" +#include "BenPort.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -14,6 +15,7 @@ void EnKbt_Init(Actor* thisx, PlayState* play); void EnKbt_Destroy(Actor* thisx, PlayState* play); void EnKbt_Update(Actor* thisx, PlayState* play); void EnKbt_Draw(Actor* thisx, PlayState* play); +void EnKbt_Reset(void); s32 func_80B33E64(PlayState* play); s32 func_80B33E8C(PlayState* play); @@ -49,14 +51,43 @@ ActorInit En_Kbt_InitVars = { /**/ EnKbt_Destroy, /**/ EnKbt_Update, /**/ EnKbt_Draw, + /**/ EnKbt_Reset, }; +static JointIndex* origIndicies_004274; + +// #region 2S2H [Port] This data originally stopped at the the entry { 0x000A, 0x000B, 0x000C }. +// The next 3 entries are set to zero because using the data the original game would have read would also have caused an OOB read +static JointIndex object_kbt_Anim_004274JointIndicesFixed[] = { + { 0x0000, 0x000D, 0x0002 }, { 0x0003, 0x002B, 0x0003 }, { 0x0049, 0x0067, 0x0085 }, { 0x0000, 0x0000, 0x00A3 }, + { 0x0000, 0x0000, 0x00C1 }, { 0x00DF, 0x00FD, 0x011B }, { 0x0000, 0x0000, 0x0139 }, { 0x0000, 0x0000, 0x0157 }, + { 0x0000, 0x0000, 0x0175 }, { 0x0000, 0x0193, 0x01B1 }, { 0x01CF, 0x01ED, 0x020B }, { 0x0000, 0x0000, 0x0229 }, + { 0x0004, 0x0005, 0x0006 }, { 0x0000, 0x0000, 0x0000 }, { 0x0007, 0x0008, 0x0009 }, { 0x0000, 0x0000, 0x0247 }, + { 0x000A, 0x000B, 0x000C }, { 0x0000, 0x0000, 0x0000 }, { 0x0060, 0x0000, 0x0000 }, { 0x0000, 0x0000, 0x0000 }, +}; +// #endregion + void EnKbt_Init(Actor* thisx, PlayState* play) { EnKbt* this = THIS; Actor_SetScale(&this->actor, 0.01f); - SkelAnime_InitFlex(play, &this->skelAnime, &object_kbt_Skel_00DEE8, &object_kbt_Anim_004274, this->jointTable, + // #region 2S2H [Port] The animation object_kbt_Anim_004274 has the wrong number of joint indicies. It should have 20 but only has 17. + // We need to do the following steps to correct this. + // First we must tell the animation system to not load the animation when it initializes the skeleton. + // Then we must manually load the animation and change the joint index data see the static JointIndex data above for what we used for the data. + // Finally we manually set the animation + + SkelAnime_InitFlex(play, &this->skelAnime, &object_kbt_Skel_00DEE8, NULL, this->jointTable, this->morphTable, OBJECT_KBT_LIMB_MAX); + + AnimationHeader* anim = (AnimationHeader*)ResourceMgr_LoadAnimByName(object_kbt_Anim_004274); + + origIndicies_004274 = anim->jointIndices; + anim->jointIndices = object_kbt_Anim_004274JointIndicesFixed; + Animation_PlayLoop(&this->skelAnime, object_kbt_Anim_004274); + // #endregion + + this->unk_27C = 0; this->actor.home.rot.z = 0; this->unk_27E = 4; @@ -87,6 +118,13 @@ void EnKbt_Init(Actor* thisx, PlayState* play) { void EnKbt_Destroy(Actor* thisx, PlayState* play) { } +void EnKbt_Reset(void) { + // #region 2S2H [Port] Reset the joint indicies back to their original value from the resource. + AnimationHeader* anim = (AnimationHeader*)ResourceMgr_LoadAnimByName(object_kbt_Anim_004274); + anim->jointIndices = origIndicies_004274; + // #endregion +} + s32 func_80B33E64(PlayState* play) { return gSaveContext.save.saveInfo.permanentSceneFlags[play->sceneId].unk_14 & 1; } diff --git a/mm/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c b/mm/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c index bd4bb8406..65bc39cf1 100644 --- a/mm/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c +++ b/mm/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c @@ -1391,6 +1391,9 @@ void EnOssan_Blink(EnOssan* this) { void EnOssan_CuriosityShopMan_Init(EnOssan* this, PlayState* play) { SkelAnime_InitFlex(play, &this->skelAnime, &gFsnSkel, &gFsnIdleAnim, this->jointTable, this->morphTable, ENOSSAN_LIMB_MAX); + + // #region 2S2H [Port] We need to manually patch this skeleton because OBJECT_FSN lists the wrong amount. Same as in en_fsn + this->skelAnime.limbCount = ENOSSAN_LIMB_MAX; this->actor.draw = EnOssan_CuriosityShopMan_Draw; } diff --git a/mm/src/overlays/actors/ovl_En_Ossan/z_en_ossan.h b/mm/src/overlays/actors/ovl_En_Ossan/z_en_ossan.h index 02c44818f..03b4417b6 100644 --- a/mm/src/overlays/actors/ovl_En_Ossan/z_en_ossan.h +++ b/mm/src/overlays/actors/ovl_En_Ossan/z_en_ossan.h @@ -7,7 +7,9 @@ #include "objects/object_fsn/object_fsn.h" // Note: adding 1 to FSN_LIMB_MAX due to bug in the skeleton, see bug in object_fsn.xml -#define ENOSSAN_LIMB_MAX MAX((s32)FSN_LIMB_MAX + 1, (s32)ANI_LIMB_MAX) +// #region [2S2H] Port FSN_LIMB_MAX is actually the number of limbs. The original game has a bug where it thinks it needs one more because +// the skeleton is bugged. Same fix as en_fsn. +#define ENOSSAN_LIMB_MAX MAX((s32)FSN_LIMB_MAX, (s32)ANI_LIMB_MAX) struct EnOssan;