diff --git a/spec b/spec index abc0da4add..a05eecaa7d 100644 --- a/spec +++ b/spec @@ -4851,9 +4851,7 @@ beginseg name "ovl_En_Invadepoh_Demo" compress include "build/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.o" - include "build/data/ovl_En_Invadepoh_Demo/ovl_En_Invadepoh_Demo.data.o" - include "build/data/ovl_En_Invadepoh_Demo/ovl_En_Invadepoh_Demo.bss.o" - include "build/data/ovl_En_Invadepoh_Demo/ovl_En_Invadepoh_Demo.reloc.o" + include "build/src/overlays/actors/ovl_En_Invadepoh_Demo/ovl_En_Invadepoh_Demo_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Bom/z_en_bom.c b/src/overlays/actors/ovl_En_Bom/z_en_bom.c index a22bf3e46c..c55c5bb3a1 100644 --- a/src/overlays/actors/ovl_En_Bom/z_en_bom.c +++ b/src/overlays/actors/ovl_En_Bom/z_en_bom.c @@ -139,7 +139,7 @@ void EnBom_Init(Actor* thisx, PlayState* play) { this->actor.colChkInfo.cylHeight = 10; this->flashSpeedScale = 7; - this->isPowderKeg = ENBOM_GETX_1(&this->actor); + this->isPowderKeg = ENBOM_GET_1(&this->actor); if (this->isPowderKeg) { play->actorCtx.flags |= ACTORCTX_FLAG_0; this->timer = gSaveContext.powderKegTimer; @@ -162,9 +162,9 @@ void EnBom_Init(Actor* thisx, PlayState* play) { func_80872648(play, &this->actor.world.pos); } - this->collider2Elements[0].info.toucher.damage += ENBOM_GETZ_FF00(thisx); + this->collider2Elements[0].info.toucher.damage += ENBOM_GET_FF00(thisx); this->actor.shape.rot.z &= 0xFF; - if (ENBOM_GETZ_80(&this->actor)) { + if (ENBOM_GET_80(&this->actor)) { this->actor.shape.rot.z |= 0xFF00; } diff --git a/src/overlays/actors/ovl_En_Bom/z_en_bom.h b/src/overlays/actors/ovl_En_Bom/z_en_bom.h index 7ca26d3cb6..723c11e8ab 100644 --- a/src/overlays/actors/ovl_En_Bom/z_en_bom.h +++ b/src/overlays/actors/ovl_En_Bom/z_en_bom.h @@ -7,9 +7,9 @@ struct EnBom; typedef void (*EnBomActionFunc)(struct EnBom*, PlayState*); -#define ENBOM_GETX_1(thisx) ((thisx)->shape.rot.x & 1) -#define ENBOM_GETZ_80(thisx) ((thisx)->shape.rot.z & 0x80) -#define ENBOM_GETZ_FF00(thisx) (((thisx)->shape.rot.z & 0xFF00) >> 8) +#define ENBOM_GET_1(thisx) ((thisx)->shape.rot.x & 1) +#define ENBOM_GET_80(thisx) ((thisx)->shape.rot.z & 0x80) +#define ENBOM_GET_FF00(thisx) (((thisx)->shape.rot.z & 0xFF00) >> 8) typedef enum BombType { /* 0 */ BOMB_TYPE_BODY, diff --git a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c index 014eea08e5..cb5d73093d 100644 --- a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c +++ b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c @@ -1,9 +1,21 @@ /* * File: z_en_invadepoh_demo.c * Overlay: ovl_En_Invadepoh_Demo - * Description: + * Description: Aliens cutscene actors + * + * This actor is responsible for handling the characters that appear in two cutscenes: + * 1. The cutscene where Romani introduces the aliens to the player. + * 2. The cutscene where the aliens abduct the cows and Romani from the barn. + * + * To be more specific, this actor has five variations: + * 1. An alien + * 2. Romani + * 3. A cow (minus the tail) + * 4. The UFO (which appears as a spinning ball of light) + * 5. A cow tail */ +#include "sys_cfb.h" #include "z_en_invadepoh_demo.h" #define FLAGS (ACTOR_FLAG_10) @@ -15,14 +27,72 @@ void EnInvadepohDemo_Destroy(Actor* thisx, PlayState* play); void EnInvadepohDemo_Update(Actor* thisx, PlayState* play); void EnInvadepohDemo_Draw(Actor* thisx, PlayState* play); -void func_80C19AB4(EnInvadepohDemo* this, PlayState* play); -void func_80C19D00(EnInvadepohDemo* this, PlayState* play); -void func_80C19D48(EnInvadepohDemo* this, PlayState* play); -void func_80C19E04(EnInvadepohDemo* this, PlayState* play); -void func_80C19EC0(EnInvadepohDemo* this, PlayState* play); -void func_80C19F7C(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_DoNothing(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Alien_Init(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Romani_Init(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Cow_Init(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Ufo_Init(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_CowTail_Init(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Cow_Destroy(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_CowTail_Destroy(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Alien_Idle(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Alien_FollowPath(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Romani_Idle(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Romani_FollowPath(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Cow_Idle(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Cow_FollowPath(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Ufo_Idle(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Ufo_FollowPath(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_SelectCueAction(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_CowTail_Idle(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Alien_WaitForObject(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Romani_WaitForObject(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Cow_WaitForObject(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_CowTail_WaitForObject(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Alien_Draw(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Romani_Draw(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Cow_Draw(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_Ufo_Draw(EnInvadepohDemo* this, PlayState* play); +void EnInvadepohDemo_CowTail_Draw(EnInvadepohDemo* this, PlayState* play); + +#define DRAW_FLAG_SHOULD_DRAW 1 +#define EN_INVADEPOH_DEMO_CUEID_NONE -1 + +typedef enum { + /* 0 */ EN_INVADEPOH_DEMO_ALIEN_CUEID_DO_NOTHING, + /* 1 */ EN_INVADEPOH_DEMO_ALIEN_CUEID_IDLE, + /* 2 */ EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_1, + /* 3 */ EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_2, + /* 4 */ EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_3, + /* 5 */ EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_4, + /* 6 */ EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_5, // Doesn't seem to be actually used in the final game + /* 7 */ EN_INVADEPOH_DEMO_ALIEN_CUEID_MAX +} EnInvadepohDemoAlienCueId; + +typedef enum { + /* 0 */ EN_INVADEPOH_DEMO_ROMANI_CUEID_DO_NOTHING, + /* 1 */ EN_INVADEPOH_DEMO_ROMANI_CUEID_IDLE, + /* 2 */ EN_INVADEPOH_DEMO_ROMANI_CUEID_FOLLOW_PATH, + /* 3 */ EN_INVADEPOH_DEMO_ROMANI_CUEID_MAX +} EnInvadepohDemoRomaniCueId; + +typedef enum { + /* 0 */ EN_INVADEPOH_DEMO_COW_CUEID_DO_NOTHING, + /* 1 */ EN_INVADEPOH_DEMO_COW_CUEID_IDLE, + /* 2 */ EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_1, + /* 3 */ EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_2, + /* 4 */ EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_3, + /* 5 */ EN_INVADEPOH_DEMO_COW_CUEID_MAX +} EnInvadepohDemoCowCueId; + +typedef enum { + /* 0 */ EN_INVADEPOH_DEMO_UFO_CUEID_DO_NOTHING, + /* 1 */ EN_INVADEPOH_DEMO_UFO_CUEID_IDLE_1, + /* 2 */ EN_INVADEPOH_DEMO_UFO_CUEID_FOLLOW_PATH, + /* 3 */ EN_INVADEPOH_DEMO_UFO_CUEID_IDLE_2, // Doesn't seem to be actually used in the final game + /* 4 */ EN_INVADEPOH_DEMO_UFO_CUEID_MAX +} EnInvadepohDemoUfoCueId; -#if 0 ActorInit En_Invadepoh_Demo_InitVars = { ACTOR_EN_INVADEPOH_DEMO, ACTORCAT_PROP, @@ -35,134 +105,710 @@ ActorInit En_Invadepoh_Demo_InitVars = { (ActorFunc)EnInvadepohDemo_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C1AA74[] = { - ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 500, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 600, ICHAIN_CONTINUE), - ICHAIN_F32(targetArrowOffset, 6000, ICHAIN_CONTINUE), +static s32 sCueTypes[EN_INVADEPOH_DEMO_TYPE_MAX] = { + CS_CMD_ACTOR_CUE_553, // EN_INVADEPOH_DEMO_TYPE_ALIEN + CS_CMD_ACTOR_CUE_554, // EN_INVADEPOH_DEMO_TYPE_ROMANI + CS_CMD_ACTOR_CUE_563, // EN_INVADEPOH_DEMO_TYPE_COW + CS_CMD_ACTOR_CUE_555, // EN_INVADEPOH_DEMO_TYPE_UFO + CS_CAM_STOP, // EN_INVADEPOH_DEMO_TYPE_COW_TAIL +}; + +static InitChainEntry sAlienInitChain[] = { + ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 500, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 600, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 6000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_STOP), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C1AA88[] = { - ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_CONTINUE), - ICHAIN_F32(targetArrowOffset, 1500, ICHAIN_CONTINUE), - ICHAIN_U8(targetMode, TARGET_MODE_6, ICHAIN_CONTINUE), - ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_STOP), +static InitChainEntry sRomaniInitChain[] = { + ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 1500, ICHAIN_CONTINUE), + ICHAIN_U8(targetMode, TARGET_MODE_6, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_STOP), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C1AAA0[] = { +static InitChainEntry sCowInitChain[] = { ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_STOP), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C1AAB0[] = { - ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_CONTINUE), - ICHAIN_VEC3S(shape.rot, 0, ICHAIN_CONTINUE), - ICHAIN_F32(terminalVelocity, -100, ICHAIN_CONTINUE), - ICHAIN_VEC3F_DIV1000(scale, 800, ICHAIN_STOP), +static InitChainEntry sUfoInitChain[] = { + ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_CONTINUE), ICHAIN_VEC3S(shape.rot, 0, ICHAIN_CONTINUE), + ICHAIN_F32(terminalVelocity, -100, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 800, ICHAIN_STOP), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C1AAC8[] = { +static InitChainEntry sCowTailInitChain[] = { ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_STOP), }; -#endif +static EnInvadepohDemoFunc sInitFuncs[EN_INVADEPOH_DEMO_TYPE_MAX] = { + EnInvadepohDemo_Alien_Init, // EN_INVADEPOH_DEMO_TYPE_ALIEN + EnInvadepohDemo_Romani_Init, // EN_INVADEPOH_DEMO_TYPE_ROMANI + EnInvadepohDemo_Cow_Init, // EN_INVADEPOH_DEMO_TYPE_COW + EnInvadepohDemo_Ufo_Init, // EN_INVADEPOH_DEMO_TYPE_UFO + EnInvadepohDemo_CowTail_Init, // EN_INVADEPOH_DEMO_TYPE_COW_TAIL +}; -extern InitChainEntry D_80C1AA74[]; -extern InitChainEntry D_80C1AA88[]; -extern InitChainEntry D_80C1AAA0[]; -extern InitChainEntry D_80C1AAB0[]; -extern InitChainEntry D_80C1AAC8[]; +static EnInvadepohDemoFunc sDestroyFuncs[EN_INVADEPOH_DEMO_TYPE_MAX] = { + EnInvadepohDemo_DoNothing, // EN_INVADEPOH_DEMO_TYPE_ALIEN + EnInvadepohDemo_DoNothing, // EN_INVADEPOH_DEMO_TYPE_ROMANI + EnInvadepohDemo_Cow_Destroy, // EN_INVADEPOH_DEMO_TYPE_COW + EnInvadepohDemo_DoNothing, // EN_INVADEPOH_DEMO_TYPE_UFO + EnInvadepohDemo_CowTail_Destroy, // EN_INVADEPOH_DEMO_TYPE_COW_TAIL +}; -extern UNK_TYPE D_06000560; -extern UNK_TYPE D_06001D80; -extern UNK_TYPE D_06004264; -extern UNK_TYPE D_06004E98; -extern UNK_TYPE D_06011FC8; -extern UNK_TYPE D_06016588; +static EnInvadepohDemoFunc sAlienCueActionCsFuncs[EN_INVADEPOH_DEMO_ALIEN_CUEID_MAX] = { + EnInvadepohDemo_DoNothing, // EN_INVADEPOH_DEMO_ALIEN_CUEID_DO_NOTHING + EnInvadepohDemo_Alien_Idle, // EN_INVADEPOH_DEMO_ALIEN_CUEID_IDLE + EnInvadepohDemo_Alien_FollowPath, // EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_1 + EnInvadepohDemo_Alien_FollowPath, // EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_2 + EnInvadepohDemo_Alien_FollowPath, // EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_3 + EnInvadepohDemo_Alien_FollowPath, // EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_4 + EnInvadepohDemo_Alien_FollowPath, // EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_5 +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C192A0.s") +static EnInvadepohDemoFunc sRomaniCueActionCsFuncs[EN_INVADEPOH_DEMO_ROMANI_CUEID_MAX] = { + EnInvadepohDemo_DoNothing, // EN_INVADEPOH_DEMO_ROMANI_CUEID_DO_NOTHING + EnInvadepohDemo_Romani_Idle, // EN_INVADEPOH_DEMO_ROMANI_CUEID_IDLE + EnInvadepohDemo_Romani_FollowPath, // EN_INVADEPOH_DEMO_ROMANI_CUEID_FOLLOW_PATH +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C192B0.s") +static EnInvadepohDemoFunc sCowCueActionCsFuncs[EN_INVADEPOH_DEMO_COW_CUEID_MAX] = { + EnInvadepohDemo_DoNothing, // EN_INVADEPOH_DEMO_COW_CUEID_DO_NOTHING + EnInvadepohDemo_Cow_Idle, // EN_INVADEPOH_DEMO_COW_CUEID_IDLE + EnInvadepohDemo_Cow_FollowPath, // EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_1 + EnInvadepohDemo_Cow_FollowPath, // EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_2 + EnInvadepohDemo_Cow_FollowPath, // EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_3 +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19334.s") +static EnInvadepohDemoFunc sUfoCueActionCsFuncs[EN_INVADEPOH_DEMO_UFO_CUEID_MAX] = { + EnInvadepohDemo_DoNothing, // EN_INVADEPOH_DEMO_UFO_CUEID_DO_NOTHING + EnInvadepohDemo_Ufo_Idle, // EN_INVADEPOH_DEMO_UFO_CUEID_IDLE_1 + EnInvadepohDemo_Ufo_FollowPath, // EN_INVADEPOH_DEMO_UFO_CUEID_FOLLOW_PATH + EnInvadepohDemo_Ufo_Idle, // EN_INVADEPOH_DEMO_UFO_CUEID_IDLE_2 +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C193A8.s") +static EnInvadepohDemoFunc sDrawFuncs[EN_INVADEPOH_DEMO_TYPE_MAX] = { + EnInvadepohDemo_Alien_Draw, // EN_INVADEPOH_DEMO_TYPE_ALIEN + EnInvadepohDemo_Romani_Draw, // EN_INVADEPOH_DEMO_TYPE_ROMANI + EnInvadepohDemo_Cow_Draw, // EN_INVADEPOH_DEMO_TYPE_COW + EnInvadepohDemo_Ufo_Draw, // EN_INVADEPOH_DEMO_TYPE_UFO + EnInvadepohDemo_CowTail_Draw, // EN_INVADEPOH_DEMO_TYPE_COW_TAIL +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19454.s") +MtxF sAlienLeftEyeBeamMtxF; +MtxF sAlienRightEyeBeamMtxF; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19498.s") +void EnInvadepohDemo_DoNothing(EnInvadepohDemo* this, PlayState* play) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1950C.s") +void EnInvadepohDemo_Alien_Init(EnInvadepohDemo* this, PlayState* play) { + Actor_ProcessInitChain(&this->actor, sAlienInitChain); + this->actor.flags = ACTOR_FLAG_10 | ACTOR_FLAG_IGNORE_QUAKE | ACTOR_FLAG_80000000; + this->objectIndex = Object_GetIndex(&play->objectCtx, OBJECT_UCH); + if (this->objectIndex < 0) { + Actor_Kill(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19548.s") + this->actionFunc = EnInvadepohDemo_Alien_WaitForObject; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19564.s") +void EnInvadepohDemo_Romani_Init(EnInvadepohDemo* this, PlayState* play) { + Actor_ProcessInitChain(&this->actor, sRomaniInitChain); + this->objectIndex = Object_GetIndex(&play->objectCtx, OBJECT_MA1); + if (this->objectIndex < 0) { + Actor_Kill(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19590.s") + this->actionFunc = EnInvadepohDemo_Romani_WaitForObject; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1965C.s") +void EnInvadepohDemo_Cow_Init(EnInvadepohDemo* this, PlayState* play) { + Actor_ProcessInitChain(&this->actor, sCowInitChain); + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_INVADEPOH_DEMO, 0.0f, 0.0f, 0.0f, 0, 0, 0, + EN_INVADEPOH_DEMO_TYPE_COW_TAIL); + this->objectIndex = Object_GetIndex(&play->objectCtx, OBJECT_COW); + if (this->objectIndex < 0) { + Actor_Kill(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19688.s") + this->actionFunc = EnInvadepohDemo_Cow_WaitForObject; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19754.s") +void EnInvadepohDemo_Ufo_Init(EnInvadepohDemo* this, PlayState* play) { + Actor_ProcessInitChain(&this->actor, sUfoInitChain); + this->actionFunc = EnInvadepohDemo_SelectCueAction; + this->drawFlags |= DRAW_FLAG_SHOULD_DRAW; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1985C.s") +void EnInvadepohDemo_CowTail_Init(EnInvadepohDemo* this, PlayState* play) { + Actor_ProcessInitChain(&this->actor, sCowTailInitChain); + this->objectIndex = Object_GetIndex(&play->objectCtx, OBJECT_COW); + if (this->objectIndex < 0) { + Actor_Kill(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1987C.s") + this->actionFunc = EnInvadepohDemo_CowTail_WaitForObject; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C199BC.s") +void EnInvadepohDemo_Cow_Destroy(EnInvadepohDemo* this, PlayState* play) { + Actor* thisx = &this->actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C199EC.s") + if (thisx->child != NULL) { + thisx->child->parent = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19AB4.s") + Actor_Kill(thisx->child); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19D00.s") +void EnInvadepohDemo_CowTail_Destroy(EnInvadepohDemo* this, PlayState* play) { + if (this->actor.parent != NULL) { + this->actor.parent->child = NULL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19D48.s") +void EnInvadepohDemo_Alien_Idle(EnInvadepohDemo* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19E04.s") +void EnInvadepohDemo_Alien_FollowPath(EnInvadepohDemo* this, PlayState* play) { + Path* path = &play->setupPathList[this->pathIndex]; + s32 pathCount = path->count; + Vec3s* points = Lib_SegmentedToVirtual(path->points); + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19EC0.s") + if (pathCount != 0) { + Math_Vec3s_ToVec3f(&point, &points[this->pointIndex]); + if (Math_Vec3f_StepTo(&this->actor.world.pos, &point, this->speed) < this->speed) { + this->pointIndex++; + if (this->pointIndex >= pathCount) { + Actor_Kill(&this->actor); + } + } else { + SkelAnime_Update(&this->skelAnime); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C19F7C.s") +void EnInvadepohDemo_Romani_Idle(EnInvadepohDemo* this, PlayState* play) { + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A038.s") +void EnInvadepohDemo_Romani_FollowPath(EnInvadepohDemo* this, PlayState* play) { + Path* path = &play->setupPathList[this->pathIndex]; + s32 pathCount = path->count; + Vec3s* points = Lib_SegmentedToVirtual(path->points); + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A070.s") + if (pathCount != 0) { + Math_Vec3s_ToVec3f(&point, &points[this->pointIndex]); + if (Math_Vec3f_StepTo(&this->actor.world.pos, &point, this->speed) < this->speed) { + this->pointIndex++; + if (this->pointIndex >= pathCount) { + Actor_Kill(&this->actor); + } + } else { + SkelAnime_Update(&this->skelAnime); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A168.s") +/** + * Positions the cow tail actor at the appropriate spot on the cow's body and rotates it to + * match the cow's rotation. This function is also responsible for playing the cow's animation. + */ +void EnInvadepohDemo_Cow_UpdateCommon(EnInvadepohDemo* this, PlayState* play) { + s32 pad; + MtxF mtx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A244.s") + if (this->actor.child != NULL) { + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + &this->actor.shape.rot); + Matrix_Translate(0.0f, 57.0f, -36.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x * -0.7f, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z * -0.7f, MTXMODE_APPLY); + Matrix_MultZero(&this->actor.child->world.pos); + Matrix_Get(&mtx); + Matrix_MtxFToYXZRot(&mtx, &this->actor.child->shape.rot, false); + Matrix_Pop(); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A590.s") + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A650.s") +void EnInvadepohDemo_Cow_Idle(EnInvadepohDemo* this, PlayState* play) { + EnInvadepohDemo_Cow_UpdateCommon(this, play); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A670.s") +void EnInvadepohDemo_Cow_FollowPath(EnInvadepohDemo* this, PlayState* play) { + Path* path = &play->setupPathList[this->pathIndex]; + s32 pathCount = path->count; + Vec3s* points = Lib_SegmentedToVirtual(path->points); + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A6C8.s") + if (pathCount != 0) { + if (((this->cueId == EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_1) && (play->csCtx.curFrame == 343)) || + ((this->cueId == EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_2) && (play->csCtx.curFrame == 421)) || + ((this->cueId == EN_INVADEPOH_DEMO_COW_CUEID_FOLLOW_PATH_3) && (play->csCtx.curFrame == 521))) { + Actor_PlaySfx(&this->actor, NA_SE_EV_COW_CRY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/func_80C1A854.s") + Math_Vec3s_ToVec3f(&point, &points[this->pointIndex]); + if (Math_Vec3f_StepTo(&this->actor.world.pos, &point, this->speed) < this->speed) { + this->pointIndex++; + if (this->pointIndex >= pathCount) { + Actor_Kill(&this->actor); + } + } else { + EnInvadepohDemo_Cow_UpdateCommon(this, play); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/EnInvadepohDemo_Init.s") +void EnInvadepohDemo_Ufo_Idle(EnInvadepohDemo* this, PlayState* play) { + this->ufoRotZ += 0x258; + Actor_PlaySfx_Flagged(&this->actor, NA_SE_EV_UFO_FLY - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/EnInvadepohDemo_Destroy.s") +void EnInvadepohDemo_Ufo_FollowPath(EnInvadepohDemo* this, PlayState* play) { + Path* path = &play->setupPathList[this->pathIndex]; + s32 pathCount = path->count; + Vec3s* points = Lib_SegmentedToVirtual(path->points); + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/EnInvadepohDemo_Update.s") + if (pathCount != 0) { + this->ufoRotZ += 0x258; + Math_Vec3s_ToVec3f(&point, &points[this->pointIndex]); + if (Math_Vec3f_StepTo(&this->actor.world.pos, &point, this->speed) < this->speed) { + this->pointIndex++; + if (this->pointIndex >= pathCount) { + Actor_Kill(&this->actor); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invadepoh_Demo/EnInvadepohDemo_Draw.s") +/** + * Updates the actor's cue ID if certain conditions are met and calls a function based + * on their current cue ID. Specifically, cows and aliens offset the cue ID from their + * cue channel (which applies to *all* aliens/cows, not just this specific actor), then + * they compare this offset value to a value read from their params. If these two values + * match, the actor's cue ID is updated. + * + * The distinction between a "global" cue ID from the cue channel and a "local" cue ID + * specific to an instance of this actor is used to prevent all the cows or aliens from + * moving along the path at once. The cow or alien waits in a stationary "idle" state + * until the "global" cue ID changes to a specific value; if the cue ID offset matches + * what this actor specifies in its params, then that acts like a signal to tell the + * actor to update the "local" cue ID and start moving. The other cows or aliens in + * the scene should have different params, meaning the cue ID offset will not match; + * they will thus ignore this "global" cue ID change and remain idle. + */ +void EnInvadepohDemo_SelectCueAction(EnInvadepohDemo* this, PlayState* play) { + CsCmdActorCue* cue; + s32 cueIdOffset; + + if (Cutscene_IsCueInChannel(play, sCueTypes[this->type])) { + this->cueChannel = Cutscene_GetCueChannel(play, sCueTypes[this->type]); + cue = play->csCtx.actorCues[this->cueChannel]; + + switch (this->type) { + case EN_INVADEPOH_DEMO_TYPE_UFO: + if (this->cueId != cue->id) { + if (cue->id == EN_INVADEPOH_DEMO_UFO_CUEID_FOLLOW_PATH) { + Actor_PlaySfx(&this->actor, NA_SE_EV_UFO_DASH); + } + + this->cueId = cue->id; + } + break; + + case EN_INVADEPOH_DEMO_TYPE_ROMANI: + if (this->cueId != cue->id) { + this->cueId = cue->id; + } + break; + + case EN_INVADEPOH_DEMO_TYPE_ALIEN: + if (cue->id > EN_INVADEPOH_DEMO_ALIEN_CUEID_IDLE) { + cueIdOffset = cue->id - EN_INVADEPOH_DEMO_ALIEN_CUEID_FOLLOW_PATH_1; + if (this->cueIdOffset != cueIdOffset) { + break; + } + } + + if (this->cueId != cue->id) { + this->cueId = cue->id; + } + break; + + case EN_INVADEPOH_DEMO_TYPE_COW: + if (cue->id > EN_INVADEPOH_DEMO_COW_CUEID_IDLE) { + cueIdOffset = cue->id - EN_INVADEPOH_DEMO_COW_CUEID_IDLE; + if (this->cueIdOffset != cueIdOffset) { + break; + } + } + + if (this->cueId != cue->id) { + this->cueId = cue->id; + } + break; + + default: + break; + } + + switch (this->type) { + case EN_INVADEPOH_DEMO_TYPE_UFO: + sUfoCueActionCsFuncs[this->cueId](this, play); + break; + + case EN_INVADEPOH_DEMO_TYPE_ALIEN: + sAlienCueActionCsFuncs[this->cueId](this, play); + break; + + case EN_INVADEPOH_DEMO_TYPE_ROMANI: + sRomaniCueActionCsFuncs[this->cueId](this, play); + break; + + case EN_INVADEPOH_DEMO_TYPE_COW: + sCowCueActionCsFuncs[this->cueId](this, play); + break; + + default: + break; + } + } +} + +void EnInvadepohDemo_CowTail_Idle(EnInvadepohDemo* this, PlayState* play) { + if (this->actor.parent == NULL) { + Actor_Kill(&this->actor); + return; + } + + SkelAnime_Update(&this->skelAnime); +} + +void EnInvadepohDemo_Alien_WaitForObject(EnInvadepohDemo* this, PlayState* play) { + s32 pad[2]; + + if (Object_IsLoaded(&play->objectCtx, this->objectIndex)) { + this->actor.objBankIndex = this->objectIndex; + Actor_SetObjectDependency(play, &this->actor); + this->drawFlags |= DRAW_FLAG_SHOULD_DRAW; + this->actionFunc = EnInvadepohDemo_SelectCueAction; + SkelAnime_InitFlex(play, &this->skelAnime, &gAlienSkel, &gAlienFloatAnim, this->jointTable, this->morphTable, + ALIEN_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gAlienFloatAnim); + } +} + +void EnInvadepohDemo_Romani_WaitForObject(EnInvadepohDemo* this, PlayState* play) { + s32 pad[2]; + + if (Object_IsLoaded(&play->objectCtx, this->objectIndex)) { + this->actor.objBankIndex = this->objectIndex; + Actor_SetObjectDependency(play, &this->actor); + this->drawFlags |= DRAW_FLAG_SHOULD_DRAW; + this->actionFunc = EnInvadepohDemo_SelectCueAction; + SkelAnime_InitFlex(play, &this->skelAnime, &gRomaniSkel, &gRomaniAbductedAnim, this->jointTable, + this->morphTable, ROMANI_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gRomaniAbductedAnim); + } +} + +void EnInvadepohDemo_Cow_WaitForObject(EnInvadepohDemo* this, PlayState* play) { + s32 pad[2]; + + if (Object_IsLoaded(&play->objectCtx, this->objectIndex)) { + this->actor.objBankIndex = this->objectIndex; + Actor_SetObjectDependency(play, &this->actor); + this->drawFlags |= DRAW_FLAG_SHOULD_DRAW; + this->actionFunc = EnInvadepohDemo_SelectCueAction; + SkelAnime_InitFlex(play, &this->skelAnime, &gCowSkel, &gCowMooAnim, this->jointTable, this->morphTable, + COW_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gCowMooAnim); + } +} + +void EnInvadepohDemo_CowTail_WaitForObject(EnInvadepohDemo* this, PlayState* play) { + s32 pad[2]; + + if (Object_IsLoaded(&play->objectCtx, this->objectIndex)) { + this->actor.objBankIndex = this->objectIndex; + Actor_SetObjectDependency(play, &this->actor); + this->drawFlags |= DRAW_FLAG_SHOULD_DRAW; + this->actionFunc = EnInvadepohDemo_CowTail_Idle; + SkelAnime_InitFlex(play, &this->skelAnime, &gCowTailSkel, &gCowTailSwishAnim, this->jointTable, + this->morphTable, COW_TAIL_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gCowTailSwishAnim); + } +} + +void EnInvadepohDemo_Ufo_UpdateMatrixTranslation(Vec3f* translation) { + MtxF* currentMatrix = Matrix_GetCurrent(); + + currentMatrix->xw = translation->x; + currentMatrix->yw = translation->y; + currentMatrix->zw = translation->z; +} + +s32 EnInvadepohDemo_Ufo_ShouldDrawLensFlare(PlayState* play, Vec3f* pos) { + Vec3f projectedPos; + f32 invW; + + Actor_GetProjectedPos(play, pos, &projectedPos, &invW); + if ((projectedPos.z > 1.0f) && (fabsf(projectedPos.x * invW) < 1.0f) && (fabsf(projectedPos.y * invW) < 1.0f)) { + f32 screenPosX = PROJECTED_TO_SCREEN_X(projectedPos, invW); + f32 screenPosY = PROJECTED_TO_SCREEN_Y(projectedPos, invW); + s32 wZ = (s32)(projectedPos.z * invW * 16352.0f) + 16352; + + if (wZ < SysCfb_GetZBufferInt(screenPosX, screenPosY)) { + return true; + } + } + + return false; +} + +void EnInvadepohDemo_Alien_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + if (limbIndex == ALIEN_LIMB_LEFT_EYE) { + Matrix_Push(); + Matrix_RotateZS(-0x53ED, MTXMODE_APPLY); + Matrix_RotateYS(-0x3830, MTXMODE_APPLY); + Matrix_Scale(1.0f, 1.0f, 1.5f, MTXMODE_APPLY); + Matrix_Get(&sAlienLeftEyeBeamMtxF); + Matrix_Pop(); + } else if (limbIndex == ALIEN_LIMB_RIGHT_EYE) { + Matrix_Push(); + Matrix_RotateZS(-0x53ED, MTXMODE_APPLY); + Matrix_RotateYS(-0x47D0, MTXMODE_APPLY); + Matrix_Scale(1.0f, 1.0f, 1.5f, MTXMODE_APPLY); + Matrix_Get(&sAlienRightEyeBeamMtxF); + Matrix_Pop(); + } +} + +void EnInvadepohDemo_Alien_Draw(EnInvadepohDemo* this, PlayState* play) { + s32 pad[2]; + Mtx* mtx; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + Gfx_SetupDL25_Opa(play->state.gfxCtx); + Matrix_Push(); + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(&gAlienEmptyTexAnim)); + Scene_SetRenderModeXlu(play, 0, 1); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); + POLY_OPA_DISP = + SkelAnime_DrawFlex(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, + EnInvadepohDemo_Alien_PostLimbDraw, &this->actor, POLY_OPA_DISP); + + // In EnInvadepoh, the eye beam alpha is controlled by an instance variable, and there is an if-block that checks + // to see if this variable is not zero. In this actor, the eye beam alpha is hardcoded, but this block is still + // necessary to prevent reordering; this is likely a result of copy-pasting from EnInvadepoh. + if (true) { + Gfx* gfx; + + AnimatedMat_Draw(play, Lib_SegmentedToVirtual(&gAlienEyeBeamTexAnim)); + + OPEN_DISPS(play->state.gfxCtx); + + gfx = POLY_XLU_DISP; + gDPPipeSync(gfx++); + gDPSetPrimColor(gfx++, 0, 0xFF, 240, 180, 100, 60); + gDPSetEnvColor(gfx++, 255, 255, 255, 150); + Matrix_Mult(&sAlienLeftEyeBeamMtxF, MTXMODE_NEW); + + mtx = Matrix_NewMtx(play->state.gfxCtx); + + if (mtx != NULL) { + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, gAlienEyeBeamDL); + Matrix_Mult(&sAlienRightEyeBeamMtxF, MTXMODE_NEW); + + mtx = Matrix_NewMtx(play->state.gfxCtx); + + if (mtx != NULL) { + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, gAlienEyeBeamDL); + POLY_XLU_DISP = gfx; + } + } + + CLOSE_DISPS(play->state.gfxCtx); + } + + CLOSE_DISPS(play->state.gfxCtx); + + // In EnInvadepoh, the code to draw the light flash checks an instance variable which is set to true if the actor + // should draw. In this actor, an equivalent variable is checked in EnInvadepohDemo_Draw, so it isn't checked here. + // However, this block is still necessary to prevent reordering; this is likely a result of copy-pasting from + // EnInvadepoh. Similarly, this function requires a lot of extra stack space for unused variables; the names and + // types of these variables are inferred from EnInvadepoh's version of this code. + if (true) { + Gfx* gfx; + Vec3f glowOffset; + Vec3f glowPos; // unused, inferred from EnInvadepoh + s32 glowAlpha; // unused, inferred from EnInvadepoh + + OPEN_DISPS(play->state.gfxCtx); + + gfx = POLY_XLU_DISP; + gfx = Gfx_SetupDL20_NoCD(gfx); + + gDPSetDither(gfx++, G_CD_NOISE); + gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, + 0); + Matrix_Mult(&play->billboardMtxF, MTXMODE_NEW); + Matrix_MultVecZ(90.0f, &glowOffset); + Matrix_Translate(this->actor.world.pos.x + glowOffset.x, this->actor.world.pos.y + glowOffset.y + 25.0f, + this->actor.world.pos.z + glowOffset.z, MTXMODE_NEW); + Matrix_Scale(0.15f, 0.15f, 0.15f, MTXMODE_APPLY); + gSPDisplayList(gfx++, gameplay_keep_DL_029CB0); + gDPSetPrimColor(gfx++, 0, 0, 240, 180, 100, 100); + + mtx = Matrix_NewMtx(play->state.gfxCtx); + + if (mtx != NULL) { + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, gameplay_keep_DL_029CF0); + POLY_XLU_DISP = gfx; + } + + CLOSE_DISPS(play->state.gfxCtx); + } + + Matrix_Pop(); +} + +void EnInvadepohDemo_Romani_Draw(EnInvadepohDemo* this, PlayState* play) { + s32 pad[2]; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Opa(play->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&gRomaniEyeSadTex)); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(&gRomaniMouthHangingOpenTex)); + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, + NULL, &this->actor); + + CLOSE_DISPS(play->state.gfxCtx); +} + +s32 EnInvadepohDemo_Cow_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + if (limbIndex == COW_LIMB_NOSE_RING) { + *dList = NULL; + } + + return false; +} + +void EnInvadepohDemo_Cow_Draw(EnInvadepohDemo* this, PlayState* play) { + Gfx_SetupDL37_Opa(play->state.gfxCtx); + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnInvadepohDemo_Cow_OverrideLimbDraw, NULL, &this->actor); +} + +void EnInvadepohDemo_Ufo_Draw(EnInvadepohDemo* this, PlayState* play) { + s32 pad[2]; + Vec3f flashPos = gZeroVec3f; + Mtx* mtx; + + flashPos.x = this->actor.world.pos.x; + flashPos.y = this->actor.world.pos.y; + flashPos.z = this->actor.world.pos.z; + EnInvadepohDemo_Ufo_UpdateMatrixTranslation(&flashPos); + Matrix_ReplaceRotation(&play->billboardMtxF); + Matrix_RotateZS(this->ufoRotZ, MTXMODE_APPLY); + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + mtx = Matrix_NewMtx(play->state.gfxCtx); + if (mtx != NULL) { + gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0xFF, 0x80, 255, 255, 0, 180); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 50, 0, 0); + gSPDisplayList(POLY_XLU_DISP++, gEffFlash1DL); + } + + CLOSE_DISPS(play->state.gfxCtx); + + if (EnInvadepohDemo_Ufo_ShouldDrawLensFlare(play, &flashPos)) { + func_800F9824(play, &play->envCtx, &play->view, play->state.gfxCtx, flashPos, 20.0f, 9.0f, 0, 0); + } +} + +void EnInvadepohDemo_CowTail_Draw(EnInvadepohDemo* this, PlayState* play) { + Gfx_SetupDL37_Opa(play->state.gfxCtx); + SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, + NULL, &this->actor); +} + +void EnInvadepohDemo_Init(Actor* thisx, PlayState* play) { + s32 pad; + EnInvadepohDemo* this = THIS; + + this->cueIdOffset = EN_INVADEPOH_DEMO_GET_CUEID_OFFSET(&this->actor); + this->type = EN_INVADEPOH_DEMO_GET_TYPE(&this->actor); + if ((this->type < EN_INVADEPOH_DEMO_TYPE_ALIEN) || (this->type > EN_INVADEPOH_DEMO_TYPE_COW_TAIL)) { + Actor_Kill(&this->actor); + return; + } + + if (this->type == EN_INVADEPOH_DEMO_TYPE_UFO) { + this->actor.world.rot.z = 0; + this->speed = EN_INVADEPOH_DEMO_GET_SPEED(&this->actor); + this->actor.shape.rot.z = this->actor.world.rot.z; + } else { + this->actor.world.rot.z = 0; + this->speed = EN_INVADEPOH_DEMO_GET_SPEED(&this->actor) / 10.0f; + this->actor.shape.rot.z = this->actor.world.rot.z; + } + + this->drawFlags = 0; + this->cueId = EN_INVADEPOH_DEMO_CUEID_NONE; + this->ufoRotZ = 0; + this->pathIndex = EN_INVADEPOH_DEMO_GET_PATH_INDEX(&this->actor); + this->pointIndex = 0; + this->objectIndex = -1; + sInitFuncs[this->type](this, play); +} + +void EnInvadepohDemo_Destroy(Actor* thisx, PlayState* play) { + s32 pad; + EnInvadepohDemo* this = THIS; + + sDestroyFuncs[this->type](this, play); +} + +void EnInvadepohDemo_Update(Actor* thisx, PlayState* play) { + s32 pad; + EnInvadepohDemo* this = THIS; + + this->actionFunc(this, play); +} + +void EnInvadepohDemo_Draw(Actor* thisx, PlayState* play) { + s32 pad; + EnInvadepohDemo* this = THIS; + + if ((this->cueId != EN_INVADEPOH_DEMO_CUEID_NONE) && (this->drawFlags & DRAW_FLAG_SHOULD_DRAW)) { + sDrawFuncs[this->type](this, play); + } +} diff --git a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h index ff13ca6686..ac93078ec3 100644 --- a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h +++ b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h @@ -2,15 +2,54 @@ #define Z_EN_INVADEPOH_DEMO_H #include "global.h" +#include "assets/objects/gameplay_keep/gameplay_keep.h" +#include "assets/objects/object_cow/object_cow.h" +#include "assets/objects/object_ma1/object_ma1.h" +#include "assets/objects/object_uch/object_uch.h" + +typedef enum { + /* 0 */ EN_INVADEPOH_DEMO_TYPE_ALIEN, + /* 1 */ EN_INVADEPOH_DEMO_TYPE_ROMANI, + /* 2 */ EN_INVADEPOH_DEMO_TYPE_COW, + /* 3 */ EN_INVADEPOH_DEMO_TYPE_UFO, + /* 4 */ EN_INVADEPOH_DEMO_TYPE_COW_TAIL, + /* 5 */ EN_INVADEPOH_DEMO_TYPE_MAX +} EnInvadepohDemoType; + +#define EN_INVADEPOH_DEMO_GET_TYPE(thisx) ((thisx)->params & 0xF) +#define EN_INVADEPOH_DEMO_GET_CUEID_OFFSET(thisx) (((thisx)->params >> 11) & 0x7) +#define EN_INVADEPOH_DEMO_GET_PATH_INDEX(thisx) (((thisx)->params >> 4) & 0x7F) +#define EN_INVADEPOH_DEMO_GET_SPEED(thisx) ((thisx)->shape.rot.z) struct EnInvadepohDemo; typedef void (*EnInvadepohDemoActionFunc)(struct EnInvadepohDemo*, PlayState*); +// This actor has multiple arrays of function pointers which are used for things like +// Init, Destroy, Draw, and something similar to an Update function. Some of these +// functions do not have any stack space for a recast temp, which means that they must +// take an EnInvadepohDemo pointer, not an Actor pointer. In other words, these +// functions are not ActorFuncs. This typedef is used for these arrays of function +// pointers to better distinguish them from "actual" action functions, even if they +// have the exact same signature. +typedef void (*EnInvadepohDemoFunc)(struct EnInvadepohDemo*, PlayState*); + typedef struct EnInvadepohDemo { /* 0x000 */ Actor actor; /* 0x144 */ EnInvadepohDemoActionFunc actionFunc; - /* 0x148 */ char unk_148[0x180]; + /* 0x148 */ s32 type; // "type" + /* 0x14C */ f32 speed; + /* 0x150 */ s32 cueChannel; + /* 0x154 */ s32 cueId; // "demo_mode" + /* 0x158 */ s32 pathIndex; + /* 0x15C */ s32 pointIndex; + /* 0x160 */ s32 objectIndex; + /* 0x164 */ s32 drawFlags; // Only has one flag to control whether or not to draw + /* 0x168 */ s32 cueIdOffset; + /* 0x16C */ s16 ufoRotZ; + /* 0x170 */ SkelAnime skelAnime; + /* 0x1B4 */ Vec3s jointTable[ROMANI_LIMB_MAX]; + /* 0x23E */ Vec3s morphTable[ROMANI_LIMB_MAX]; } EnInvadepohDemo; // size = 0x2C8 #endif // Z_EN_INVADEPOH_DEMO_H diff --git a/src/overlays/actors/ovl_En_Osk/z_en_osk.c b/src/overlays/actors/ovl_En_Osk/z_en_osk.c index c9828e0ff0..3a58ba62b0 100644 --- a/src/overlays/actors/ovl_En_Osk/z_en_osk.c +++ b/src/overlays/actors/ovl_En_Osk/z_en_osk.c @@ -542,12 +542,10 @@ void EnOsk_Draw(Actor* thisx, PlayState* play) { MTXMODE_APPLY); } - gfx = Gfx_SetupDL20_NoCD(POLY_XLU_DISP); + gfx = POLY_XLU_DISP; + gfx = Gfx_SetupDL20_NoCD(gfx); - gSPSetOtherMode(gfx++, G_SETOTHERMODE_H, 4, 4, 0x00000080); - if (1) {} - if (1) {} - if (1) {} + gDPSetDither(gfx++, G_CD_NOISE); gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0); gSPDisplayList(gfx++, gameplay_keep_DL_029CB0); gDPSetPrimColor(gfx++, 0, 0, 130, 0, 255, 100); diff --git a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c index 6625437745..6440493cf9 100644 --- a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c +++ b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c @@ -701,7 +701,7 @@ void func_80B32F04(Actor* thisx, PlayState* play) { gfx = POLY_XLU_DISP; gfx = Gfx_SetupDL20_NoCD(gfx); - gSPSetOtherMode(gfx++, G_SETOTHERMODE_H, 4, 4, 0x00000080); + gDPSetDither(gfx++, G_CD_NOISE); gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0); gSPDisplayList(gfx++, gameplay_keep_DL_029CB0); diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index d060d23e22..e146d804d0 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -16876,38 +16876,38 @@ 0x80C18E94:("EnAnd_Update",), 0x80C18ED0:("EnAnd_TransformLimbDraw",), 0x80C19084:("EnAnd_Draw",), - 0x80C192A0:("func_80C192A0",), - 0x80C192B0:("func_80C192B0",), - 0x80C19334:("func_80C19334",), - 0x80C193A8:("func_80C193A8",), - 0x80C19454:("func_80C19454",), - 0x80C19498:("func_80C19498",), - 0x80C1950C:("func_80C1950C",), - 0x80C19548:("func_80C19548",), - 0x80C19564:("func_80C19564",), - 0x80C19590:("func_80C19590",), - 0x80C1965C:("func_80C1965C",), - 0x80C19688:("func_80C19688",), - 0x80C19754:("func_80C19754",), - 0x80C1985C:("func_80C1985C",), - 0x80C1987C:("func_80C1987C",), - 0x80C199BC:("func_80C199BC",), - 0x80C199EC:("func_80C199EC",), - 0x80C19AB4:("func_80C19AB4",), - 0x80C19D00:("func_80C19D00",), - 0x80C19D48:("func_80C19D48",), - 0x80C19E04:("func_80C19E04",), - 0x80C19EC0:("func_80C19EC0",), - 0x80C19F7C:("func_80C19F7C",), - 0x80C1A038:("func_80C1A038",), - 0x80C1A070:("func_80C1A070",), - 0x80C1A168:("func_80C1A168",), - 0x80C1A244:("func_80C1A244",), - 0x80C1A590:("func_80C1A590",), - 0x80C1A650:("func_80C1A650",), - 0x80C1A670:("func_80C1A670",), - 0x80C1A6C8:("func_80C1A6C8",), - 0x80C1A854:("func_80C1A854",), + 0x80C192A0:("EnInvadepohDemo_DoNothing",), + 0x80C192B0:("EnInvadepohDemo_Alien_Init",), + 0x80C19334:("EnInvadepohDemo_Romani_Init",), + 0x80C193A8:("EnInvadepohDemo_Cow_Init",), + 0x80C19454:("EnInvadepohDemo_Ufo_Init",), + 0x80C19498:("EnInvadepohDemo_CowTail_Init",), + 0x80C1950C:("EnInvadepohDemo_Cow_Destroy",), + 0x80C19548:("EnInvadepohDemo_CowTail_Destroy",), + 0x80C19564:("EnInvadepohDemo_Alien_Idle",), + 0x80C19590:("EnInvadepohDemo_Alien_FollowPath",), + 0x80C1965C:("EnInvadepohDemo_Romani_Idle",), + 0x80C19688:("EnInvadepohDemo_Romani_FollowPath",), + 0x80C19754:("EnInvadepohDemo_Cow_UpdateCommon",), + 0x80C1985C:("EnInvadepohDemo_Cow_Idle",), + 0x80C1987C:("EnInvadepohDemo_Cow_FollowPath",), + 0x80C199BC:("EnInvadepohDemo_Ufo_Idle",), + 0x80C199EC:("EnInvadepohDemo_Ufo_FollowPath",), + 0x80C19AB4:("EnInvadepohDemo_SelectCueAction",), + 0x80C19D00:("EnInvadepohDemo_CowTail_Idle",), + 0x80C19D48:("EnInvadepohDemo_Alien_WaitForObject",), + 0x80C19E04:("EnInvadepohDemo_Romani_WaitForObject",), + 0x80C19EC0:("EnInvadepohDemo_Cow_WaitForObject",), + 0x80C19F7C:("EnInvadepohDemo_CowTail_WaitForObject",), + 0x80C1A038:("EnInvadepohDemo_Ufo_UpdateMatrixTranslation",), + 0x80C1A070:("EnInvadepohDemo_Ufo_ShouldDrawLensFlare",), + 0x80C1A168:("EnInvadepohDemo_Alien_PostLimbDraw",), + 0x80C1A244:("EnInvadepohDemo_Alien_Draw",), + 0x80C1A590:("EnInvadepohDemo_Romani_Draw",), + 0x80C1A650:("EnInvadepohDemo_Cow_OverrideLimbDraw",), + 0x80C1A670:("EnInvadepohDemo_Cow_Draw",), + 0x80C1A6C8:("EnInvadepohDemo_Ufo_Draw",), + 0x80C1A854:("EnInvadepohDemo_CowTail_Draw",), 0x80C1A8A4:("EnInvadepohDemo_Init",), 0x80C1A98C:("EnInvadepohDemo_Destroy",), 0x80C1A9C0:("EnInvadepohDemo_Update",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 5047e9804a..fc49a3b43f 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -16415,26 +16415,25 @@ 0x80C19218:("D_80C19218","UNK_TYPE4","",0x4), 0x80C19220:("D_80C19220","UNK_TYPE1","",0x1), 0x80C1AA40:("En_Invadepoh_Demo_InitVars","UNK_TYPE1","",0x1), - 0x80C1AA60:("D_80C1AA60","UNK_TYPE1","",0x1), - 0x80C1AA62:("D_80C1AA62","UNK_TYPE1","",0x1), - 0x80C1AA74:("D_80C1AA74","UNK_TYPE1","",0x1), - 0x80C1AA88:("D_80C1AA88","UNK_TYPE1","",0x1), - 0x80C1AAA0:("D_80C1AAA0","UNK_TYPE1","",0x1), - 0x80C1AAB0:("D_80C1AAB0","UNK_TYPE1","",0x1), - 0x80C1AAC8:("D_80C1AAC8","UNK_TYPE1","",0x1), - 0x80C1AAD8:("D_80C1AAD8","UNK_PTR","",0x4), - 0x80C1AAEC:("D_80C1AAEC","UNK_PTR","",0x4), - 0x80C1AB00:("D_80C1AB00","UNK_PTR","",0x4), - 0x80C1AB1C:("D_80C1AB1C","UNK_TYPE1","",0x1), - 0x80C1AB28:("D_80C1AB28","UNK_PTR","",0x4), - 0x80C1AB3C:("D_80C1AB3C","UNK_PTR","",0x4), - 0x80C1AB4C:("D_80C1AB4C","UNK_PTR","",0x4), + 0x80C1AA60:("sCueTypes","s32","[5]",0x14), + 0x80C1AA74:("sAlienInitChain","InitChainEntry","[5]",0x14), + 0x80C1AA88:("sRomaniInitChain","InitChainEntry","[6]",0x18), + 0x80C1AAA0:("sCowInitChain","InitChainEntry","[4]",0x10), + 0x80C1AAB0:("sUfoInitChain","InitChainEntry","[6]",0x18), + 0x80C1AAC8:("sCowTailInitChain","InitChainEntry","[4]",0x10), + 0x80C1AAD8:("sInitFuncs","UNK_PTR","[5]",0x14), + 0x80C1AAEC:("sDestroyFuncs","UNK_PTR","[5]",0x14), + 0x80C1AB00:("sAlienCueActionCsFuncs","UNK_PTR","[7]",0x1C), + 0x80C1AB1C:("sRomaniCueActionCsFuncs","UNK_TYPE1","[3]",0xC), + 0x80C1AB28:("sCowCueActionCsFuncs","UNK_PTR","[5]",0x14), + 0x80C1AB3C:("sUfoCueActionCsFuncs","UNK_PTR","[4]",0x10), + 0x80C1AB4C:("sDrawFuncs","UNK_PTR","[5]",0x14), 0x80C1AB60:("D_80C1AB60","f32","",0x4), 0x80C1AB64:("D_80C1AB64","f32","",0x4), 0x80C1AB68:("D_80C1AB68","f32","",0x4), 0x80C1AB6C:("D_80C1AB6C","f32","",0x4), - 0x80C1AD40:("D_80C1AD40","UNK_TYPE1","",0x1), - 0x80C1AD80:("D_80C1AD80","UNK_TYPE1","",0x1), + 0x80C1AD40:("sAlienLeftEyeBeamMtxF","MtxF","",0x40), + 0x80C1AD80:("sAlienRightEyeBeamMtxF","MtxF","",0x40), 0x80C1B520:("Obj_Danpeilift_InitVars","UNK_TYPE1","",0x1), 0x80C1B540:("D_80C1B540","UNK_TYPE1","",0x1), 0x80C1B550:("D_80C1B550","f32","",0x4), diff --git a/undefined_syms.txt b/undefined_syms.txt index 81f14ced86..a6a5bc8ae4 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -470,22 +470,6 @@ D_06015C28 = 0x06015C28; D_060156D8 = 0x060156D8; D_06016720 = 0x06016720; -// ovl_En_Invadepoh_Demo - -D_06000080 = 0x06000080; -D_06000550 = 0x06000550; -D_06000560 = 0x06000560; -D_06001D80 = 0x06001D80; -D_06004010 = 0x06004010; -D_06004264 = 0x06004264; -D_06004C30 = 0x06004C30; -D_06004E50 = 0x06004E50; -D_06004E98 = 0x06004E98; -D_06011FC8 = 0x06011FC8; -D_06012FC8 = 0x06012FC8; -D_06013928 = 0x06013928; -D_06016588 = 0x06016588; - // ovl_En_Jso D_060081F4 = 0x060081F4;