mirror of
https://github.com/zeldaret/mm.git
synced 2026-08-01 16:09:55 -04:00
EnAnd OK and documented (#1224)
* EnAnd before data * EnAnd data * EnAnd preliminary renaming * EnAnd document object * EnAnd finalize pre-PR documenting * EnAnd style improvements * EnAnd refactor eye textures * EnAnd make some parts more explicit * EnAnd cutscene refactor according to suggestions * EnAnd style improvements
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user