diff --git a/assets/xml/objects/object_and.xml b/assets/xml/objects/object_and.xml index a076a1c073..69ffebc7b4 100644 --- a/assets/xml/objects/object_and.xml +++ b/assets/xml/objects/object_and.xml @@ -1,79 +1,80 @@  + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spec b/spec index 358a061ab2..57fca6cdaf 100644 --- a/spec +++ b/spec @@ -4884,8 +4884,7 @@ beginseg name "ovl_En_And" compress include "build/src/overlays/actors/ovl_En_And/z_en_and.o" - include "build/data/ovl_En_And/ovl_En_And.data.o" - include "build/data/ovl_En_And/ovl_En_And.reloc.o" + include "build/src/overlays/actors/ovl_En_And/ovl_En_And_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_And/z_en_and.c b/src/overlays/actors/ovl_En_And/z_en_and.c index 5c888ba452..c1f2297517 100644 --- a/src/overlays/actors/ovl_En_And/z_en_and.c +++ b/src/overlays/actors/ovl_En_And/z_en_and.c @@ -10,14 +10,13 @@ #define THIS ((EnAnd*)thisx) +#define EYE_TEXTURES_COUNT 4 + void EnAnd_Init(Actor* thisx, PlayState* play); void EnAnd_Destroy(Actor* thisx, PlayState* play); void EnAnd_Update(Actor* thisx, PlayState* play); void EnAnd_Draw(Actor* thisx, PlayState* play); -void func_80C18C50(EnAnd* this, PlayState* play); - -#if 0 ActorInit En_And_InitVars = { ACTOR_EN_AND, ACTORCAT_NPC, @@ -30,22 +29,163 @@ ActorInit En_And_InitVars = { (ActorFunc)EnAnd_Draw, }; -#endif +static AnimationInfoS sAnimationInfo[] = { + { &gAndStaticAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gAndIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gAndWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gAndRaiseHeadAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gAndRaisedHeadLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gAndRaiseHandAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gAndRaisedHandLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gAndRaisedHandWalkAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, +}; -extern UNK_TYPE D_0600B380; +s32 EnAnd_ChangeAnim(EnAnd* this, s32 animIndex) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_And/func_80C18B90.s") + if (this->animIndex != animIndex) { + this->animIndex = animIndex; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimationInfo, animIndex); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_And/func_80C18BD8.s") +void EnAnd_Blink(EnAnd* this) { + if (DECR(this->blinkTimer) == 0) { + this->eyeTexIndex++; + if (this->eyeTexIndex >= EYE_TEXTURES_COUNT) { + this->blinkTimer = Rand_S16Offset(30, 30); + this->eyeTexIndex = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_And/func_80C18C50.s") +void EnAnd_HandleCutscene(EnAnd* this, PlayState* play) { + s32 csAnimations[] = { 0, 1, 2, 3, 5, 7 }; + u16 cueType; + s32 cueChannel; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_And/EnAnd_Init.s") + if (play->csCtx.state != CS_STATE_IDLE) { + if (!this->isCutscenePlaying) { + // Cutscene is starting + this->cueId = 255; + this->isCutscenePlaying = true; + this->prevAnimIndex = this->animIndex; + } + if (Cutscene_IsCueInChannel(play, CS_CMD_ACTOR_CUE_565)) { + cueChannel = Cutscene_GetCueChannel(play, CS_CMD_ACTOR_CUE_565); + cueType = play->csCtx.actorCues[cueChannel]->id; + if (this->cueId != (u8)cueType) { + this->cueId = cueType; + EnAnd_ChangeAnim(this, csAnimations[cueType]); + } + switch (this->cueId) { + case 3: + case 4: + if ((this->animIndex == 3) || (this->animIndex == 5)) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + EnAnd_ChangeAnim(this, this->animIndex + 1); + } + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_And/EnAnd_Destroy.s") + default: + break; + } + Cutscene_ActorTranslateAndYaw(&this->actor, play, cueChannel); + } + } else if (this->isCutscenePlaying) { + this->isCutscenePlaying = false; + EnAnd_ChangeAnim(this, this->prevAnimIndex); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_And/EnAnd_Update.s") +void EnAnd_Init(Actor* thisx, PlayState* play) { + EnAnd* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_And/func_80C18ED0.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 14.0f); + SkelAnime_InitFlex(play, &this->skelAnime, &gAndSkel, NULL, this->jointTable, this->morphTable, + OBJECT_AND_LIMB_MAX); + this->animIndex = -1; + EnAnd_ChangeAnim(this, 0); + Actor_SetScale(&this->actor, 0.01f); + this->actor.flags &= ~ACTOR_FLAG_1; + this->flags |= 8; + this->actionFunc = EnAnd_HandleCutscene; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_And/EnAnd_Draw.s") +void EnAnd_Destroy(Actor* thisx, PlayState* play) { +} + +void EnAnd_Update(Actor* thisx, PlayState* play) { + EnAnd* this = THIS; + + this->actionFunc(this, play); + SkelAnime_Update(&this->skelAnime); + EnAnd_Blink(this); +} + +void EnAnd_TransformLimbDraw(PlayState* play, s32 limbIndex, Actor* thisx) { + EnAnd* this = THIS; + s32 stepRot; + s32 overrideRot; + + stepRot = this->flags & 8 ? false : true; + overrideRot = this->flags & 2 ? true : false; + if (!stepRot) { + overrideRot = false; + } + + switch (limbIndex) { + case OBJECT_AND_LIMB_HEAD: + SubS_UpdateLimb(this->headRotZ + this->torsoRotZ + 0x4000, + this->headRotY + this->torsoRotY + this->actor.shape.rot.y + 0x4000, &this->headComputedPos, + &this->headComputedRot, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->headComputedPos.x, this->headComputedPos.y, this->headComputedPos.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->headComputedRot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->headComputedRot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->headComputedRot.z, MTXMODE_APPLY); + Matrix_Push(); + break; + + case OBJECT_AND_LIMB_TORSO: + SubS_UpdateLimb(this->torsoRotZ + 0x4000, this->torsoRotY + this->actor.shape.rot.y + 0x4000, + &this->torsoComputedPos, &this->torsoComputedRot, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->torsoComputedPos.x, this->torsoComputedPos.y, this->torsoComputedPos.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->torsoComputedRot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->torsoComputedRot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->torsoComputedRot.z, MTXMODE_APPLY); + Matrix_Push(); + break; + + default: + break; + } +} + +void EnAnd_Draw(Actor* thisx, PlayState* play) { + static TexturePtr sMouthTextures[] = { gAndMouthNeutralTex, gAndMouthSmileTex }; + static TexturePtr sEyeTextures[EYE_TEXTURES_COUNT] = { + gAndEyeOpenTex, + gAndEyeClosingTex, + gAndEyeClosedTex, + gAndEyeOpeningTex, + }; + EnAnd* this = THIS; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C28C(play->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeTexIndex])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(sMouthTextures[0])); + + SkelAnime_DrawTransformFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, EnAnd_TransformLimbDraw, &this->actor); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_And/z_en_and.h b/src/overlays/actors/ovl_En_And/z_en_and.h index a0610a408c..6b5a0bb7db 100644 --- a/src/overlays/actors/ovl_En_And/z_en_and.h +++ b/src/overlays/actors/ovl_En_And/z_en_and.h @@ -2,6 +2,7 @@ #define Z_EN_AND_H #include "global.h" +#include "objects/object_and/object_and.h" struct EnAnd; @@ -9,9 +10,29 @@ typedef void (*EnAndActionFunc)(struct EnAnd*, PlayState*); typedef struct EnAnd { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x44]; + /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ EnAndActionFunc actionFunc; - /* 0x18C */ char unk_18C[0x188]; + /* 0x18C */ u8 cueId; + /* 0x18D */ UNK_TYPE1 pad18D[0x7]; + /* 0x194 */ Vec3f headComputedPos; + /* 0x1A0 */ Vec3f torsoComputedPos; + /* 0x1AC */ Vec3s headComputedRot; + /* 0x1B2 */ Vec3s torsoComputedRot; + /* 0x1B8 */ Vec3s jointTable[OBJECT_AND_LIMB_MAX]; + /* 0x254 */ Vec3s morphTable[OBJECT_AND_LIMB_MAX]; + /* 0x2F0 */ u16 flags; + /* 0x2F2 */ UNK_TYPE1 pad2F2[0x4]; + /* 0x2F6 */ s16 headRotZ; + /* 0x2F8 */ s16 headRotY; + /* 0x2FA */ s16 torsoRotZ; + /* 0x2FC */ s16 torsoRotY; + /* 0x2FE */ UNK_TYPE1 pad2FE[0x2]; + /* 0x300 */ s16 blinkTimer; + /* 0x302 */ s16 eyeTexIndex; + /* 0x304 */ s32 animIndex; + /* 0x308 */ s32 prevAnimIndex; + /* 0x30C */ s32 isCutscenePlaying; + /* 0x310 */ UNK_TYPE1 pad310[4]; } EnAnd; // size = 0x314 #endif // Z_EN_AND_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 157036d0c5..4cb29f0dca 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -16868,13 +16868,13 @@ 0x80C18928:("BgLastBwall_DoNothing",), 0x80C18938:("BgLastBwall_Update",), 0x80C1895C:("BgLastBwall_Draw",), - 0x80C18B90:("func_80C18B90",), - 0x80C18BD8:("func_80C18BD8",), - 0x80C18C50:("func_80C18C50",), + 0x80C18B90:("EnAnd_ChangeAnimation",), + 0x80C18BD8:("EnAnd_Blink",), + 0x80C18C50:("EnAnd_HandleCsAction",), 0x80C18DC8:("EnAnd_Init",), 0x80C18E84:("EnAnd_Destroy",), 0x80C18E94:("EnAnd_Update",), - 0x80C18ED0:("func_80C18ED0",), + 0x80C18ED0:("EnAnd_TransformLimbDraw",), 0x80C19084:("EnAnd_Draw",), 0x80C192A0:("func_80C192A0",), 0x80C192B0:("func_80C192B0",), diff --git a/undefined_syms.txt b/undefined_syms.txt index f0578ff167..1e09ceaab0 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -770,10 +770,6 @@ D_060111E8 = 0x060111E8; D_06012478 = 0x06012478; D_06012618 = 0x06012618; -// ovl_En_And - -D_0600B380 = 0x0600B380; - // ovl_En_Bal D_060005FC = 0x060005FC;