From 70419d60448361cd9c0e14bc49cab37a40e428a1 Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Mon, 27 Dec 2021 17:26:06 -0800 Subject: [PATCH] En_Fall (the moon, Moon's Tear, and effects) OK and mostly documented (#476) * EnFall_Init OK * EnFall_Destroy OK * EnFall_Update OK * func_80A6C3AC and func_80A6C3FC OK * func_80A6BF90 OK * func_80A6CA9C OK * func_80A6CD38 OK * func_80A6CF60 OK * func_80A6C9A8 OK * Import data into C * func_80A6CB74 OK * func_80A6CD74 OK * func_80A6CF70 OK * func_80A6CECC OK * func_80A6D698 OK * func_80A6D220 OK * func_80A6D100 OK * func_80A6D75C OK * func_80A6D88C OK * func_80A6D98C OK * func_80A6DC20 OK * func_80A6DA7C OK * func_80A6DC40 OK * func_80A6DD3C OK * func_80A6E214 OK * func_80A6E37C OK * func_80A6C7C0 OK * func_80A6D444 OK * func_80A6C1DC OK * func_80A6D504 OK * func_80A6E07C OK * Move all statics to in-function * Migrate bss to C and use compiled reloc * Clean up UnkFallStruct * Initial documentation pass * Some more function names * Name some more unknowns * Name yet more unknowns * Name all struct variables and static data * Do one last documentation pass * Respond to engineer's style review * Respond to hensldm's review * This is a legacy PR, so using autogenned object symbols --- assets/xml/objects/object_fall.xml | 3 + spec | 4 +- src/overlays/actors/ovl_En_Fall/z_en_fall.c | 849 ++++++++++++++++++-- src/overlays/actors/ovl_En_Fall/z_en_fall.h | 46 +- tools/disasm/functions.txt | 56 +- tools/disasm/variables.txt | 7 +- undefined_syms.txt | 15 - 7 files changed, 875 insertions(+), 105 deletions(-) diff --git a/assets/xml/objects/object_fall.xml b/assets/xml/objects/object_fall.xml index f84ecffc5f..5a90c5a243 100644 --- a/assets/xml/objects/object_fall.xml +++ b/assets/xml/objects/object_fall.xml @@ -8,6 +8,9 @@ + + + diff --git a/spec b/spec index 6fa30a0201..b74852117e 100644 --- a/spec +++ b/spec @@ -3122,9 +3122,7 @@ beginseg name "ovl_En_Fall" compress include "build/src/overlays/actors/ovl_En_Fall/z_en_fall.o" - include "build/data/ovl_En_Fall/ovl_En_Fall.data.o" - include "build/data/ovl_En_Fall/ovl_En_Fall.bss.o" - include "build/data/ovl_En_Fall/ovl_En_Fall.reloc.o" + include "build/src/overlays/actors/ovl_En_Fall/ovl_En_Fall_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Fall/z_en_fall.c b/src/overlays/actors/ovl_En_Fall/z_en_fall.c index 43582bf264..155493dbd2 100644 --- a/src/overlays/actors/ovl_En_Fall/z_en_fall.c +++ b/src/overlays/actors/ovl_En_Fall/z_en_fall.c @@ -1,10 +1,24 @@ /* * File: z_en_fall.c * Overlay: ovl_En_Fall - * Description: The Moon and related effects + * Description: The moon and related effects, along with the Moon's Tear that falls from its eye. + * + * This actor handles mutliple types of moon as well as a variety of effects. Specifically, it handles: + * - A high-detail moon, used in Termina Field, the Clock Tower, and a few cutscenes + * - A high-detail open-mouthed moon, used in the cutscene prior to warping to the moon's interior. + * - An enlarged high-detail moon, used for when the moon is crashing. + * - A low-detail moon, used everywhere else. Its object file is named "Lodmoon". + * - The Moon's Tear that can be seen falling from the telescope, along with its associated fire trail. + * - The ball of fire that surrounds the moon when it is crashing. + * - The debris that rises from the ground as the moon is crashing. + * - The ring of fire that expands outward when the moon is almost done crashing. */ #include "z_en_fall.h" +#include "objects/object_fall/object_fall.h" +#include "objects/object_fall2/object_fall2.h" +#include "objects/object_lodmoon/object_lodmoon.h" +#include "objects/object_moonston/object_moonston.h" #define FLAGS 0x00000030 @@ -14,16 +28,34 @@ void EnFall_Init(Actor* thisx, GlobalContext* globalCtx); void EnFall_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFall_Update(Actor* thisx, GlobalContext* globalCtx); -void func_80A6C3FC(EnFall* this, GlobalContext* globalCtx); -void func_80A6C9A8(EnFall* this, GlobalContext* globalCtx); -void func_80A6CA9C(EnFall* this, GlobalContext* globalCtx); -void func_80A6CB74(EnFall* this, GlobalContext* globalCtx); -void func_80A6CD38(EnFall* this, GlobalContext* globalCtx); -void func_80A6CD74(EnFall* this, GlobalContext* globalCtx); -void func_80A6CF60(EnFall* this, GlobalContext* globalCtx); -void func_80A6CF70(EnFall* this, GlobalContext* globalCtx); +void EnFall_Setup(EnFall* this, GlobalContext* globalCtx); +void EnFall_CrashingMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_StoppedOpenMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_StoppedClosedMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_Moon_PerformDefaultActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_MoonsTear_Fall(EnFall* this, GlobalContext* globalCtx); +void EnFall_FireBall_Update(Actor* thisx, GlobalContext* globalCtx); +void EnFall_RisingDebris_Update(Actor* thisx, GlobalContext* globalCtx); +void EnFall_FireRing_Update(Actor* thisx, GlobalContext* globalCtx); +void EnFall_Moon_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_OpenMouthMoon_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_LodMoon_DrawWithoutLerp(Actor* thisx, GlobalContext* globalCtx); +void EnFall_LodMoon_DrawWithLerp(Actor* thisx, GlobalContext* globalCtx); +void EnFall_FireBall_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_RisingDebris_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_FireRing_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_MoonsTear_Draw(Actor* thisx, GlobalContext* globalCtx); + +typedef struct { + u8 dListIndex; + Vec3f pos; + Vec3f velocity; + Vec3s rot; +} EnFallDebrisParticle; + +EnFallDebrisParticle debrisParticles[50]; -#if 0 const ActorInit En_Fall_InitVars = { ACTOR_EN_FALL, ACTORCAT_ITEMACTION, @@ -36,75 +68,792 @@ const ActorInit En_Fall_InitVars = { (ActorFunc)NULL, }; -#endif +/** + * Sets the scale of the moon depending on the current day. On the Final Day, + * it also moves the moon closer to the ground depending on the current time. + */ +void EnFall_Moon_AdjustScaleAndPosition(EnFall* this, GlobalContext* globalCtx) { + u16 currentTime = gSaveContext.time; + u16 dayStartTime = this->dayStartTime; + f32 finalDayRelativeHeight; -extern UNK_TYPE D_06000198; -extern UNK_TYPE D_060004C0; -extern UNK_TYPE D_060010E0; -extern UNK_TYPE D_060011D0; -extern UNK_TYPE D_06001220; -extern UNK_TYPE D_06002970; -extern UNK_TYPE D_06004E38; -extern UNK_TYPE D_060077F0; + if (currentTime < dayStartTime) { + finalDayRelativeHeight = 1.0f - (((f32)dayStartTime - (f32)currentTime) * (1.0f / 0x10000)); + } else { + finalDayRelativeHeight = ((f32)currentTime - (f32)dayStartTime) * (1.0f / 0x10000); + } + switch (CURRENT_DAY) { + case 0: + Actor_SetScale(&this->actor, this->scale * 1.2f); + this->actor.world.pos.y = this->actor.home.pos.y; + break; + case 1: + Actor_SetScale(&this->actor, this->scale * 2.4f); + this->actor.world.pos.y = this->actor.home.pos.y; + break; + case 2: + Actor_SetScale(&this->actor, this->scale * 3.6f); + this->actor.world.pos.y = this->actor.home.pos.y; + break; + case 3: + Actor_SetScale(&this->actor, this->scale * 3.6f); + if (EN_FALL_TYPE(&this->actor) == EN_FALL_TYPE_LODMOON_INVERTED_STONE_TOWER) { + this->actor.world.pos.y = + this->actor.home.pos.y + (finalDayRelativeHeight * 6700.0f * (this->scale * 6.25f)); + } else { + this->actor.world.pos.y = + this->actor.home.pos.y - (finalDayRelativeHeight * 6700.0f * (this->scale * 6.25f)); + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6BF90.s") +void EnFall_RisingDebris_ResetParticles(EnFall* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C1DC.s") + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + debrisParticles[i].dListIndex = 3; + } + this->activeDebrisParticleCount = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/EnFall_Init.s") +void EnFall_Init(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + s32 objectIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/EnFall_Destroy.s") + this->eyeGlowIntensity = 0.0f; + this->flags = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C3AC.s") + // This system is basically never used in the final game; all instances + // of EnFall will use the default case. + switch (EN_FALL_SCALE(&this->actor)) { + case 1: + this->scale = 0.08f; + break; + case 2: + this->scale = 0.04f; + break; + case 3: + this->scale = 0.02f; + break; + case 4: + this->scale = 0.01f; + break; + default: + this->scale = 0.16f; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C3FC.s") + switch (EN_FALL_TYPE(&this->actor)) { + case EN_FALL_TYPE_LODMOON_NO_LERP: + case EN_FALL_TYPE_LODMOON: + case EN_FALL_TYPE_LODMOON_INVERTED_STONE_TOWER: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_LODMOON); + break; + case EN_FALL_TYPE_MOONS_TEAR: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MOONSTON); + break; + case EN_FALL_TYPE_STOPPED_MOON_OPEN_MOUTH: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_FALL2); + break; + default: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_FALL); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C7C0.s") + if (objectIndex < 0) { + Actor_MarkForDeath(&this->actor); + return; + } + this->objIndex = objectIndex; + this->actionFunc = EnFall_Setup; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C9A8.s") +void EnFall_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CA9C.s") +/** + * Finds the Termina Field moon so the Moon's Tear can spawn in the correct place. + */ +Actor* EnFall_MoonsTear_GetTerminaFieldMoon(GlobalContext* globalCtx) { + Actor* itemAction = globalCtx->actorCtx.actorList[ACTORCAT_ITEMACTION].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CB74.s") + while (itemAction != NULL) { + if (itemAction->id == ACTOR_EN_FALL && EN_FALL_TYPE(itemAction) == EN_FALL_TYPE_TERMINA_FIELD_MOON) { + return itemAction; + } + itemAction = itemAction->next; + } + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CD38.s") +void EnFall_Setup(EnFall* this, GlobalContext* globalCtx) { + Actor* moon; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CD74.s") + if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) { + this->actor.objBankIndex = this->objIndex; + this->actionFunc = EnFall_Moon_PerformDefaultActions; + switch (EN_FALL_TYPE(&this->actor)) { + case EN_FALL_TYPE_TITLE_SCREEN_MOON: + this->actor.draw = EnFall_Moon_Draw; + this->actionFunc = EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions; + Actor_SetScale(&this->actor, this->scale); + break; + case EN_FALL_TYPE_STOPPED_MOON_CLOSED_MOUTH: + this->actor.draw = EnFall_Moon_Draw; + this->actionFunc = EnFall_StoppedClosedMouthMoon_PerformCutsceneActions; + Actor_SetScale(&this->actor, this->scale * 3.0f); + if (!(gSaveContext.weekEventReg[0x19] & 2)) { + Actor_MarkForDeath(&this->actor); + } + break; + case EN_FALL_TYPE_CLOCK_TOWER_MOON: + this->actionFunc = EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions; + Actor_SetScale(&this->actor, this->scale * 3.0f); + this->actor.draw = EnFall_Moon_Draw; + if (gSaveContext.weekEventReg[0x19] & 2) { + Actor_MarkForDeath(&this->actor); + } + break; + case EN_FALL_TYPE_CRASHING_MOON: + this->actor.draw = EnFall_Moon_Draw; + Actor_SetScale(&this->actor, this->scale * 5.3999996f); + this->actionFunc = EnFall_CrashingMoon_PerformCutsceneActions; + break; + case EN_FALL_TYPE_CRASH_FIRE_BALL: + this->actor.update = EnFall_FireBall_Update; + this->actor.draw = EnFall_FireBall_Draw; + this->scale = 1.0f; + this->actor.shape.rot.z = 0; + this->fireBallIntensity = 0.0f; + this->fireBallAlpha = 100; + this->actor.shape.rot.x = this->actor.shape.rot.z; + break; + case EN_FALL_TYPE_CRASH_RISING_DEBRIS: + this->actor.update = EnFall_RisingDebris_Update; + this->actor.draw = EnFall_RisingDebris_Draw; + this->scale = 1.0f; + EnFall_RisingDebris_ResetParticles(this); + Actor_SetScale(&this->actor, 1.0f); + this->actor.shape.rot.x = 0; + break; + case EN_FALL_TYPE_LODMOON_NO_LERP: + this->actor.draw = EnFall_LodMoon_DrawWithoutLerp; + this->dayStartTime = CLOCK_TIME(6, 0); + this->currentDay = CURRENT_DAY; + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + break; + case EN_FALL_TYPE_LODMOON: + case EN_FALL_TYPE_LODMOON_INVERTED_STONE_TOWER: + this->actor.draw = EnFall_LodMoon_DrawWithLerp; + this->dayStartTime = CLOCK_TIME(6, 0); + this->currentDay = CURRENT_DAY; + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + break; + case EN_FALL_TYPE_MOONS_TEAR: + this->actor.update = EnFall_Update; + this->actor.draw = NULL; + this->actionFunc = EnFall_MoonsTear_Fall; + Actor_SetScale(&this->actor, 0.02f); + if (!(globalCtx->actorCtx.unk5 & 2)) { + Actor_MarkForDeath(&this->actor); + } + moon = EnFall_MoonsTear_GetTerminaFieldMoon(globalCtx); + this->actor.child = moon; + if (moon == NULL) { + Actor_MarkForDeath(&this->actor); + } + break; + case EN_FALL_TYPE_STOPPED_MOON_OPEN_MOUTH: + this->actor.draw = NULL; + this->actionFunc = EnFall_StoppedOpenMouthMoon_PerformCutsceneActions; + Actor_SetScale(&this->actor, this->scale * 3.0f); + break; + case EN_FALL_TYPE_CRASH_FIRE_RING: + this->actor.update = EnFall_FireRing_Update; + this->actor.draw = EnFall_FireRing_Draw; + Actor_SetScale(&this->actor, 0.2f); + break; + default: + this->actor.draw = EnFall_Moon_Draw; + this->dayStartTime = CLOCK_TIME(6, 0); + this->currentDay = CURRENT_DAY; + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CECC.s") +void EnFall_CrashingMoon_HandleGiantsCutscene(EnFall* this, GlobalContext* globalCtx) { + static s32 sGiantsCutsceneState = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CF60.s") + if (globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 1 && globalCtx->csCtx.unk_12 == 0) { + switch (sGiantsCutsceneState) { + case 0: + if (globalCtx->csCtx.state != 0) { + sGiantsCutsceneState += 2; + } + break; + case 2: + if (CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA) && CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT) && + CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG) && CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD)) { + if (gSaveContext.weekEventReg[0x5D] & 4) { + if (ActorCutscene_GetCanPlayNext(0xC)) { + ActorCutscene_Start(0xC, &this->actor); + sGiantsCutsceneState++; + } else { + ActorCutscene_SetIntentToPlay(0xC); + } + } else if (ActorCutscene_GetCanPlayNext(0xB)) { + ActorCutscene_Start(0xB, &this->actor); + gSaveContext.weekEventReg[0x5D] |= 4; + sGiantsCutsceneState++; + } else { + ActorCutscene_SetIntentToPlay(0xB); + } + } else if (globalCtx->csCtx.frames > 1600) { + globalCtx->nextEntranceIndex = 0x2C00; + gSaveContext.nextCutsceneIndex = 0xFFF2; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; + gSaveContext.nextTransition = 2; + sGiantsCutsceneState = 9; + } + break; + case 9: + globalCtx->csCtx.frames--; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CF70.s") +void EnFall_CrashingMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + EnFall_CrashingMoon_HandleGiantsCutscene(this, globalCtx); + if (func_800EE29C(globalCtx, 0x85)) { + if (func_800EE29C(globalCtx, 0x85) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0 == 1) { + this->actor.draw = NULL; + } else { + this->actor.draw = EnFall_Moon_Draw; + if (func_800EE29C(globalCtx, 0x85) && + globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0 == 2) { + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x85)); + } + } + } else { + this->actor.draw = NULL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/EnFall_Update.s") +void EnFall_StoppedOpenMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x85)) { + switch (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0) { + case 3: + if (this->eyeGlowIntensity == 0.0f) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_MOON_EYE_FLASH); + } + this->eyeGlowIntensity += 0.033333335f; + if (this->eyeGlowIntensity > 1.0f) { + this->eyeGlowIntensity = 1.0f; + } + break; + case 4: + this->actor.draw = EnFall_OpenMouthMoon_Draw; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D100.s") +void EnFall_StoppedClosedMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x85)) { + switch (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0) { + case 2: + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x85)); + break; + case 4: + this->actor.draw = NULL; + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D220.s") + if (globalCtx->sceneNum == SCENE_OKUJOU && gSaveContext.sceneSetupIndex == 2) { + switch (globalCtx->csCtx.unk_12) { + case 0: + switch (globalCtx->csCtx.frames) { + case 1060: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOON_SCREAM1); + break; + case 1089: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_MOON_CRY); + break; + case 1303: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_SLIP_MOON); + break; + } + if (globalCtx->csCtx.frames >= 1145) { + func_800B9010(&this->actor, NA_SE_EV_FALL_POWER - SFX_FLAG); + } + break; + case 1: + switch (globalCtx->csCtx.frames) { + case 561: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOON_SCREAM1); + break; + case 590: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_MOON_CRY); + break; + case 737: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_SLIP_MOON); + break; + } + if (globalCtx->csCtx.frames >= 650) { + func_800B9010(&this->actor, NA_SE_EV_FALL_POWER - SFX_FLAG); + } + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D444.s") +void EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state != 0 && globalCtx->sceneNum == SCENE_OKUJOU) { + func_800B9010(&this->actor, NA_SE_EV_MOON_FALL - SFX_FLAG); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D504.s") +/** + * This is rarely used in the final game. One example of where it *is* used + * is when the moon is crashing; there is a second, smaller moon hidden within + * the larger moon that uses this action function. + */ +void EnFall_Moon_PerformDefaultActions(EnFall* this, GlobalContext* globalCtx) { + u16 currentDay; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D698.s") + if (func_800EE29C(globalCtx, 0x85)) { + if (func_800EE29C(globalCtx, 0x85) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0 == 1) { + this->actor.draw = NULL; + } else { + Actor_SetScale(&this->actor, this->scale * 3.6f); + this->actor.draw = EnFall_Moon_Draw; + if (func_800EE29C(globalCtx, 0x85) && + globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0 == 2) { + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x85)); + } + } + } else { + if (this->actor.draw == NULL) { + this->actor.draw = EnFall_Moon_Draw; + } + currentDay = CURRENT_DAY; + if ((u16)this->currentDay != (u32)currentDay) { + this->currentDay = currentDay; + this->dayStartTime = gSaveContext.time; + } + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D75C.s") +void EnFall_MoonsTear_Initialize(EnFall* this) { + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D88C.s") + this->actor.draw = EnFall_MoonsTear_Draw; + if (this->actor.child != NULL) { + // The focus of the child needs to be shifted in EnFall_Moon_Draw first, + // otherwise the tear will spawn in the wrong place. + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.child->focus.pos); + } + this->actor.world.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); + this->actor.world.rot.x = Math_Vec3f_Pitch(&this->actor.world.pos, &this->actor.home.pos); + this->actor.speedXZ = Math_Vec3f_DistXYZ(&this->actor.world.pos, &this->actor.home.pos) / 82.0f; + this->actor.shape.rot.x = this->actor.world.rot.x; + this->actor.shape.rot.y = this->actor.world.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D98C.s") +void EnFall_DoNothing(EnFall* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DA7C.s") +void EnFall_MoonsTear_Fall(EnFall* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DC20.s") + if (func_800EE29C(globalCtx, 0x205) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x205)]->unk0 == 2 && + this->actor.draw == NULL) { + EnFall_MoonsTear_Initialize(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DC40.s") + if (this->actor.draw != NULL) { + if (Math_Vec3f_StepTo(&this->actor.world.pos, &this->actor.home.pos, this->actor.speedXZ) <= 0.0f) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_GORON_BOUND_1); + gSaveContext.weekEventReg[0x4A] |= 0x80; + gSaveContext.weekEventReg[0x4A] |= 0x20; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TEST, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, -2); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_EXPLOSION); + this->actor.draw = NULL; + this->actionFunc = EnFall_DoNothing; + } else { + func_800B9010(&this->actor, NA_SE_EV_MOONSTONE_FALL - SFX_FLAG); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DD3C.s") +void EnFall_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + this->actionFunc(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E07C.s") +/** + * Updates the alpha for every vertex in the fire ball so that some parts of + * the sphere are more transparent or opaque than others. + */ +void EnFall_FireBall_SetPerVertexAlpha(f32 fireBallAlpha) { + static u8 sAlphaTableIndex[] = { + 4, 4, 0, 1, 1, 1, 1, 1, 1, 3, 3, 0, 0, 3, 0, 1, 1, 1, 4, 0, 4, 0, 1, 1, 1, 3, 0, 3, 0, 1, 1, 1, 4, 4, 1, + 1, 0, 4, 4, 0, 1, 1, 1, 1, 1, 1, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 1, 1, 1, 4, 0, 4, 4, 0, 4, 4, 1, 1, 1, 1, + 1, 1, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 1, 1, 1, 1, 4, 4, 0, 4, 0, 1, 1, 1, 3, 0, 3, 3, 0, 0, 1, 1, 1, 1, 1, + 1, 4, 4, 0, 4, 4, 0, 1, 1, 1, 1, 1, 1, 3, 3, 0, 0, 0, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 0, 1, 1, 0, 0, 1, 0, + 2, 0, 0, 1, 0, 2, 0, 0, 2, 1, 2, 0, 1, 0, 1, 0, 0, 1, 2, 2, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, + 0, 0, 2, 0, 2, 2, 0, 1, 1, 0, 0, 1, 0, 0, 1, 2, 2, 0, 0, 0, 2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E214.s") + s32 pad; + u8 perVertexAlphaTable[5]; + Vtx* vertices = Lib_SegmentedToVirtual(&object_fall_Vtx_0004C0); + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E37C.s") + if (fireBallAlpha > 1.0f) { + fireBallAlpha = 1.0f; + } + perVertexAlphaTable[0] = 0; + perVertexAlphaTable[1] = (s8)(255.0f * fireBallAlpha); + perVertexAlphaTable[2] = (s8)(155.0f * fireBallAlpha); + perVertexAlphaTable[3] = (s8)(104.0f * fireBallAlpha); + perVertexAlphaTable[4] = (s8)(54.0f * fireBallAlpha); + + for (i = 0; i < ARRAY_COUNT(sAlphaTableIndex); i++, vertices++) { + vertices->v.cn[3] = perVertexAlphaTable[sAlphaTableIndex[i]]; + } +} + +void EnFall_FireBall_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + + if (globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 0 && globalCtx->csCtx.unk_12 == 2) { + globalCtx->skyboxCtx.rotY -= 0.05f; + } + + if (func_800EE29C(globalCtx, 0x1C2)) { + this->actor.draw = EnFall_FireBall_Draw; + if (this->flags & EN_FALL_FLAG_FIRE_BALL_INTENSIFIES) { + this->fireBallIntensity += 0.01f; + if (this->fireBallIntensity > 1.0f) { + this->fireBallIntensity = 1.0f; + } + } + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x1C2)); + + switch (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x1C2)]->unk0) { + default: + this->actor.draw = NULL; + this->fireBallAlpha = 0; + break; + case 2: + if (this->fireBallAlpha < 100) { + this->fireBallAlpha += 4; + } + if (this->fireBallAlpha > 100) { + this->fireBallAlpha = 100; + } + EnFall_FireBall_SetPerVertexAlpha(this->fireBallAlpha * 0.01f); + break; + case 3: + if (this->fireBallAlpha > 0) { + this->fireBallAlpha -= 2; + } + if (this->fireBallAlpha < 0) { + this->fireBallAlpha = 0; + } + EnFall_FireBall_SetPerVertexAlpha(this->fireBallAlpha * 0.01f); + break; + case 4: + this->flags |= EN_FALL_FLAG_FIRE_BALL_INTENSIFIES; + break; + case 5: + break; + } + } else { + this->actor.draw = NULL; + } + + if (func_800EE29C(globalCtx, 0x1C2) && this->fireBallAlpha > 0) { + func_8019F128(NA_SE_EV_MOON_FALL_LAST - SFX_FLAG); + } + Actor_SetScale(&this->actor, this->scale * 1.74f); +} + +void EnFall_RisingDebris_UpdateParticles(EnFall* this) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + if (debrisParticles[i].dListIndex < 3) { + debrisParticles[i].pos.x += debrisParticles[i].velocity.x; + debrisParticles[i].pos.y += debrisParticles[i].velocity.y; + debrisParticles[i].pos.z += debrisParticles[i].velocity.z; + debrisParticles[i].rot.x += 0x64; + debrisParticles[i].rot.y += 0xC8; + debrisParticles[i].rot.z += 0x12C; + if ((this->actor.world.pos.y + 3000.0f) < debrisParticles[i].pos.y) { + debrisParticles[i].dListIndex = 3; + this->activeDebrisParticleCount--; + } + } + } +} + +s32 EnFall_RisingDebris_InitializeParticles(EnFall* this) { + s16 angle; + s32 i; + f32 scale; + + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + if (debrisParticles[i].dListIndex >= 3) { + debrisParticles[i].dListIndex = (s32)Rand_ZeroFloat(3.0f); + debrisParticles[i].pos.x = this->actor.world.pos.x; + debrisParticles[i].pos.y = this->actor.world.pos.y; + debrisParticles[i].pos.z = this->actor.world.pos.z; + angle = randPlusMinusPoint5Scaled(0x10000); + scale = (1.0f - (Rand_ZeroFloat(1.0f) * Rand_ZeroFloat(1.0f))) * 3000.0f; + debrisParticles[i].pos.x += Math_SinS(angle) * scale; + debrisParticles[i].pos.z += Math_CosS(angle) * scale; + debrisParticles[i].velocity.x = 0.0f; + debrisParticles[i].velocity.z = 0.0f; + debrisParticles[i].velocity.y = 80.0f; + debrisParticles[i].rot.x = randPlusMinusPoint5Scaled(0x10000); + debrisParticles[i].rot.y = randPlusMinusPoint5Scaled(0x10000); + debrisParticles[i].rot.z = randPlusMinusPoint5Scaled(0x10000); + this->activeDebrisParticleCount++; + return true; + } + } + + return false; +} + +void EnFall_RisingDebris_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + + if (func_800EE29C(globalCtx, 0x1C3)) { + if (func_800EE29C(globalCtx, 0x1C3) && + globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x1C3)]->unk0 == 2) { + EnFall_RisingDebris_UpdateParticles(this); + EnFall_RisingDebris_InitializeParticles(this); + } else if (this->activeDebrisParticleCount != 0) { + EnFall_RisingDebris_ResetParticles(this); + } + } else if (thisx->home.rot.x != 0) { + EnFall_RisingDebris_UpdateParticles(this); + EnFall_RisingDebris_InitializeParticles(this); + } +} + +void EnFall_FireRing_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + + if (func_800EE29C(globalCtx, 0x1C2) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x1C2)]->unk0 == 5) { + if (!(this->flags & EN_FALL_FLAG_FIRE_RING_APPEARS)) { + Audio_PlayActorSound2(&this->actor, NA_SE_IT_DM_RING_EXPLOSION); + } + this->flags |= EN_FALL_FLAG_FIRE_RING_APPEARS; + } + if (this->flags & EN_FALL_FLAG_FIRE_RING_APPEARS) { + this->fireRingAlpha += 0.033333335f; + if (this->fireRingAlpha > 1.0f) { + this->fireRingAlpha = 1.0f; + } + if (this->actor.scale.x < 18.0f) { + this->actor.scale.x += 0.2f; + } + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = Math_SinS(this->fireWallYScale) * 5.0f; + if (this->fireWallYScale < 0x4000) { + this->fireWallYScale += 0x147; + } + } +} + +void EnFall_Moon_Draw(Actor* thisx, GlobalContext* globalCtx) { + // This offsets the moon's focus so that the Moon's Tear actually falls + // out of its eye when looking at it through the telescope. + static Vec3f sFocusOffset[] = { 1800.0f, 1000.0f, 4250.0f }; + EnFall* this = THIS; + s32 primColor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + Matrix_MultiplyVector3fByState(sFocusOffset, &this->actor.focus.pos); + primColor = (this->eyeGlowIntensity * 200.0f) + 40.0f; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, primColor, primColor, primColor, 255); + gSPDisplayList(POLY_OPA_DISP++, object_fall_DL_0077F0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_OpenMouthMoon_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + s32 primColor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + primColor = (this->eyeGlowIntensity * 200.0f) + 40.0f; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, primColor, primColor, primColor, 255); + gSPDisplayList(POLY_OPA_DISP++, object_fall2_DL_002970); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_LodMoon_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFall* this = THIS; + s32 primColor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 20, 25, 30, 0, 0x3E7, 0x3200); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_PASS, G_RM_AA_ZB_OPA_SURF2); + gSPLoadGeometryMode(POLY_OPA_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); + primColor = (this->eyeGlowIntensity * 200.0f) + 40.0f; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, primColor, primColor, primColor, 255); + gSPDisplayList(POLY_OPA_DISP++, object_lodmoon_DL_0010E0); + gSPLoadGeometryMode(POLY_OPA_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); + gSPDisplayList(POLY_OPA_DISP++, object_lodmoon_DL_001158); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_LodMoon_DrawWithoutLerp(Actor* thisx, GlobalContext* globalCtx) { + EnFall_LodMoon_Draw(thisx, globalCtx); +} + +/** + * If the moon is more than 9000 units away from the eye, this will lerp it + * to be 9000 units away before drawing it. + */ +void EnFall_LodMoon_DrawWithLerp(Actor* thisx, GlobalContext* globalCtx) { + f32 distanceToEye = Actor_DistanceToPoint(thisx, &globalCtx->view.eye); + f32 scale; + Vec3f translation; + + if (distanceToEye > 9000.0f) { + scale = 9000.0f / distanceToEye; + translation.x = (-(globalCtx->view.eye.x - thisx->world.pos.x) * scale) + globalCtx->view.eye.x; + translation.y = (-(globalCtx->view.eye.y - thisx->world.pos.y) * scale) + globalCtx->view.eye.y; + translation.z = (-(globalCtx->view.eye.z - thisx->world.pos.z) * scale) + globalCtx->view.eye.z; + Matrix_InsertTranslation(translation.x, translation.y, translation.z, MTXMODE_NEW); + Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY); + Matrix_RotateY(thisx->shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(thisx->shape.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(thisx->shape.rot.z, MTXMODE_APPLY); + } + EnFall_LodMoon_Draw(thisx, globalCtx); +} + +void EnFall_FireBall_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFall* this = THIS; + u32 gameplayFrames = globalCtx->gameplayFrames; + + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + this->fireBallYTexScroll1 += (s32)(4.0f + (this->fireBallIntensity * 12.0f)); + this->fireBallYTexScroll2 += (s32)(2.0f + (this->fireBallIntensity * 6.0f)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, + (s32)(((1.0f - this->fireBallIntensity) * 160.0f) + (255.0f * this->fireBallIntensity)), + (s32)((70.0f * (1.0f - this->fireBallIntensity)) + (255.0f * this->fireBallIntensity)), + (s32)(70.0f * (1.0f - this->fireBallIntensity)), 255); + gDPSetEnvColor( + POLY_XLU_DISP++, (s32)(((1.0f - this->fireBallIntensity) * 50.0f) + (200.0f * this->fireBallIntensity)), + (s32)(20.0f * (1.0f - this->fireBallIntensity)), (s32)(20.0f * (1.0f - this->fireBallIntensity)), 255); + + // Glowing sphere of fire + gSPSegment(POLY_XLU_DISP++, 0x09, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, gameplayFrames, -this->fireBallYTexScroll2, 64, 64, 1, + -gameplayFrames, -this->fireBallYTexScroll1, 64, 64)); + + // "Flecks" of fire + gSPSegment(POLY_XLU_DISP++, 0x0A, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, gameplayFrames * 2, -this->fireBallYTexScroll1, 64, 64, 1, + -gameplayFrames * 2, -this->fireBallYTexScroll1, 64, 64)); + + gDPSetColorDither(POLY_XLU_DISP++, G_CD_NOISE); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_NOISE); + gSPDisplayList(POLY_XLU_DISP++, object_fall_DL_0011D0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_RisingDebris_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Gfx* sDebrisDLists[] = { object_fall_DL_000220, object_fall_DL_000428, object_fall_DL_000498 }; + EnFall* this = THIS; + f32 scale = this->scale * 0.06f; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, object_fall_DL_000198); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + if (debrisParticles[i].dListIndex < 3) { + Matrix_InsertTranslation(debrisParticles[i].pos.x, debrisParticles[i].pos.y, debrisParticles[i].pos.z, + MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_InsertRotation(debrisParticles[i].rot.x, debrisParticles[i].rot.y, debrisParticles[i].rot.z, + MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, sDebrisDLists[debrisParticles[i].dListIndex]); + } + } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_FireRing_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFall* this = THIS; + + if (!(this->fireRingAlpha <= 0.0f)) { + if (this->fireRingAlpha > 1.0f) { + this->fireRingAlpha = 1.0f; + } + OPEN_DISPS(globalCtx->state.gfxCtx); + AnimatedMat_DrawXlu(globalCtx, Lib_SegmentedToVirtual(&object_fall_Matanimheader_004E38)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_NOISE); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_NOISE); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, (s32)(this->fireRingAlpha * 255.0f)); + gSPDisplayList(POLY_XLU_DISP++, object_fall_DL_003C30); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void EnFall_MoonsTear_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_moonston_Matanimheader_001220)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, object_moonston_DL_000400); + Matrix_Scale(3.0f, 3.0f, 6.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_XLU_DISP++, object_moonston_DL_0004C8); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Fall/z_en_fall.h b/src/overlays/actors/ovl_En_Fall/z_en_fall.h index fb149f7e54..0124087d95 100644 --- a/src/overlays/actors/ovl_En_Fall/z_en_fall.h +++ b/src/overlays/actors/ovl_En_Fall/z_en_fall.h @@ -3,14 +3,54 @@ #include "global.h" +#define EN_FALL_SCALE(thisx) ((thisx)->params & 0x7F) +#define EN_FALL_TYPE(thisx) (((thisx)->params & 0xF80) >> 7) + +#define EN_FALL_FLAG_FIRE_BALL_INTENSIFIES (1 << 0) +#define EN_FALL_FLAG_FIRE_RING_APPEARS (1 << 1) + +typedef enum { + /* 0 */ EN_FALL_TYPE_TERMINA_FIELD_MOON, + /* 1 */ EN_FALL_TYPE_TITLE_SCREEN_MOON, + /* 2 */ EN_FALL_TYPE_CRASHING_MOON, + /* 3 */ EN_FALL_TYPE_CRASH_FIRE_BALL, + /* 4 */ EN_FALL_TYPE_CRASH_RISING_DEBRIS, + /* 5 */ EN_FALL_TYPE_LODMOON_NO_LERP, // unused in final game + /* 6 */ EN_FALL_TYPE_LODMOON, + /* 7 */ EN_FALL_TYPE_STOPPED_MOON_CLOSED_MOUTH, + /* 8 */ EN_FALL_TYPE_MOONS_TEAR, + /* 9 */ EN_FALL_TYPE_CLOCK_TOWER_MOON, + /* 10 */ EN_FALL_TYPE_STOPPED_MOON_OPEN_MOUTH, + /* 11 */ EN_FALL_TYPE_CRASH_FIRE_RING, + /* 12 */ EN_FALL_TYPE_LODMOON_INVERTED_STONE_TOWER, +} EnFallType; + struct EnFall; typedef void (*EnFallActionFunc)(struct EnFall*, GlobalContext*); typedef struct EnFall { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; - /* 0x0160 */ EnFallActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ s16 dayStartTime; + /* 0x146 */ s16 currentDay; + /* 0x148 */ u8 objIndex; + /* 0x14C */ f32 scale; + /* 0x150 */ union { + f32 eyeGlowIntensity; + f32 fireBallIntensity; + f32 fireRingAlpha; + }; + /* 0x154 */ u16 flags; + /* 0x158 */ union { + s32 fireBallAlpha; + s32 activeDebrisParticleCount; + }; + /* 0x15C */ union { + s16 fireBallYTexScroll1; + s16 fireWallYScale; + }; + /* 0x15E */ s16 fireBallYTexScroll2; + /* 0x160 */ EnFallActionFunc actionFunc; } EnFall; // size = 0x164 extern const ActorInit En_Fall_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 2ac78bf859..6c7d5d38d7 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -10907,37 +10907,37 @@ 0x80A6B0D8:("func_80A6B0D8",), 0x80A6B3F8:("EnMushi2_Update",), 0x80A6B8D0:("EnMushi2_Draw",), - 0x80A6BF90:("func_80A6BF90",), - 0x80A6C1DC:("func_80A6C1DC",), + 0x80A6BF90:("EnFall_Moon_AdjustScaleAndPosition",), + 0x80A6C1DC:("EnFall_RisingDebris_ResetParticles",), 0x80A6C22C:("EnFall_Init",), 0x80A6C39C:("EnFall_Destroy",), - 0x80A6C3AC:("func_80A6C3AC",), - 0x80A6C3FC:("func_80A6C3FC",), - 0x80A6C7C0:("func_80A6C7C0",), - 0x80A6C9A8:("func_80A6C9A8",), - 0x80A6CA9C:("func_80A6CA9C",), - 0x80A6CB74:("func_80A6CB74",), - 0x80A6CD38:("func_80A6CD38",), - 0x80A6CD74:("func_80A6CD74",), - 0x80A6CECC:("func_80A6CECC",), - 0x80A6CF60:("func_80A6CF60",), - 0x80A6CF70:("func_80A6CF70",), + 0x80A6C3AC:("EnFall_MoonsTear_GetTerminaFieldMoon",), + 0x80A6C3FC:("EnFall_Setup",), + 0x80A6C7C0:("EnFall_CrashingMoon_HandleGiantsCutscene",), + 0x80A6C9A8:("EnFall_CrashingMoon_PerformCutsceneActions",), + 0x80A6CA9C:("EnFall_StoppedOpenMouthMoon_PerformCutsceneActions",), + 0x80A6CB74:("EnFall_StoppedClosedMouthMoon_PerformCutsceneActions",), + 0x80A6CD38:("EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions",), + 0x80A6CD74:("EnFall_Moon_PerformDefaultActions",), + 0x80A6CECC:("EnFall_MoonsTear_Initialize",), + 0x80A6CF60:("EnFall_DoNothing",), + 0x80A6CF70:("EnFall_MoonsTear_Fall",), 0x80A6D0DC:("EnFall_Update",), - 0x80A6D100:("func_80A6D100",), - 0x80A6D220:("func_80A6D220",), - 0x80A6D444:("func_80A6D444",), - 0x80A6D504:("func_80A6D504",), - 0x80A6D698:("func_80A6D698",), - 0x80A6D75C:("func_80A6D75C",), - 0x80A6D88C:("func_80A6D88C",), - 0x80A6D98C:("func_80A6D98C",), - 0x80A6DA7C:("func_80A6DA7C",), - 0x80A6DC20:("func_80A6DC20",), - 0x80A6DC40:("func_80A6DC40",), - 0x80A6DD3C:("func_80A6DD3C",), - 0x80A6E07C:("func_80A6E07C",), - 0x80A6E214:("func_80A6E214",), - 0x80A6E37C:("func_80A6E37C",), + 0x80A6D100:("EnFall_FireBall_SetPerVertexAlpha",), + 0x80A6D220:("EnFall_FireBall_Update",), + 0x80A6D444:("EnFall_RisingDebris_UpdateParticles",), + 0x80A6D504:("EnFall_RisingDebris_InitializeParticles",), + 0x80A6D698:("EnFall_RisingDebris_Update",), + 0x80A6D75C:("EnFall_FireRing_Update",), + 0x80A6D88C:("EnFall_Moon_Draw",), + 0x80A6D98C:("EnFall_OpenMouthMoon_Draw",), + 0x80A6DA7C:("EnFall_LodMoon_Draw",), + 0x80A6DC20:("EnFall_LodMoon_DrawWithoutLerp",), + 0x80A6DC40:("EnFall_LodMoon_DrawWithLerp",), + 0x80A6DD3C:("EnFall_FireBall_Draw",), + 0x80A6E07C:("EnFall_RisingDebris_Draw",), + 0x80A6E214:("EnFall_FireRing_Draw",), + 0x80A6E37C:("EnFall_MoonsTear_Draw",), 0x80A6F0A0:("EnMm3_Init",), 0x80A6F1EC:("EnMm3_Destroy",), 0x80A6F22C:("func_80A6F22C",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 44d1683d4f..c1653df0f8 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -12300,10 +12300,7 @@ 0x80A6BB00:("D_80A6BB00","f32","",0x4), 0x80A6E490:("En_Fall_InitVars","UNK_TYPE1","",0x1), 0x80A6E4B0:("D_80A6E4B0","UNK_TYPE4","",0x4), - 0x80A6E4B4:("D_80A6E4B4","UNK_TYPE1","",0x1), - 0x80A6E4B5:("D_80A6E4B5","UNK_TYPE1","",0x1), - 0x80A6E584:("D_80A6E584","UNK_TYPE1","",0x1), - 0x80A6E585:("D_80A6E585","UNK_TYPE1","",0x1), + 0x80A6E4B4:("D_80A6E4B4","s8","[0xD1]",0xD0), 0x80A6E588:("D_80A6E588","UNK_TYPE1","",0x1), 0x80A6E594:("D_80A6E594","UNK_TYPE1","",0x1), 0x80A6E5A0:("D_80A6E5A0","f32","",0x4), @@ -12335,8 +12332,6 @@ 0x80A6E650:("D_80A6E650","f32","",0x4), 0x80A6E654:("D_80A6E654","f32","",0x4), 0x80A6E990:("D_80A6E990","UNK_TYPE1","",0x1), - 0x80A6E9B4:("D_80A6E9B4","UNK_TYPE1","",0x1), - 0x80A6E9D8:("D_80A6E9D8","UNK_TYPE1","",0x1), 0x80A6F098:("D_80A6F098","UNK_TYPE1","",0x1), 0x80A703D0:("En_Mm3_InitVars","UNK_TYPE1","",0x1), 0x80A703F0:("D_80A703F0","UNK_TYPE1","",0x1), diff --git a/undefined_syms.txt b/undefined_syms.txt index cb1d8903a2..5dc1f16a91 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -2171,21 +2171,6 @@ D_0600A490 = 0x0600A490; D_06010240 = 0x06010240; -// ovl_En_Fall - -D_06000198 = 0x06000198; -D_06000400 = 0x06000400; -D_060004C0 = 0x060004C0; -D_060004C8 = 0x060004C8; -D_060010E0 = 0x060010E0; -D_06001158 = 0x06001158; -D_060011D0 = 0x060011D0; -D_06001220 = 0x06001220; -D_06002970 = 0x06002970; -D_06003C30 = 0x06003C30; -D_06004E38 = 0x06004E38; -D_060077F0 = 0x060077F0; - // ovl_En_Fall2 D_06005EF4 = 0x06005EF4;