EnInvadepohDemo (Aliens cutscene actors) OK and documented (#1363)

* EnInvadepohDemo (Aliens cutscene actors) OK and documented

* Make bss variables non-static

* Provide type to Actor_SpawnAsChild

* Respond to hensldm's review

* Introduce obvious misformat

* Format again, see if that fixes it?

* Push the misformat up so I can see how Jenkins complains

* Fix formatting on my end (again)

* Apparently I had to merge master to fix the formatting issue??????

* Respond to engineer's review
This commit is contained in:
Tom Overton 2023-09-13 18:29:30 -07:00 committed by GitHub
parent 190b78549e
commit 17068dadef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 826 additions and 162 deletions

4
spec
View File

@ -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

View File

@ -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;
}

View File

@ -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,

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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",),

View File

@ -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),

View File

@ -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;