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:
Zakru
2023-05-15 13:51:47 +03:00
committed by GitHub
parent 389a2bf33c
commit 35c45eab70
6 changed files with 257 additions and 100 deletions
+153 -13
View File
@@ -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);
}
+23 -2
View File
@@ -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