diff --git a/assets/xml/overlays/ovl_Oceff_Spot.xml b/assets/xml/overlays/ovl_Oceff_Spot.xml new file mode 100644 index 0000000000..f4e9beea75 --- /dev/null +++ b/assets/xml/overlays/ovl_Oceff_Spot.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/spec b/spec index 5f0500cf3b..1135ac9210 100644 --- a/spec +++ b/spec @@ -1694,8 +1694,7 @@ beginseg name "ovl_Oceff_Spot" compress include "build/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.o" - include "build/data/ovl_Oceff_Spot/ovl_Oceff_Spot.data.o" - include "build/data/ovl_Oceff_Spot/ovl_Oceff_Spot.reloc.o" + include "build/src/overlays/actors/ovl_Oceff_Spot/ovl_Oceff_Spot_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c index 91a5d3e661..504a2815ab 100644 --- a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c +++ b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c @@ -10,17 +10,17 @@ #define THIS ((OceffSpot*)thisx) -void OceffSpot_Init(Actor* thisx, PlayState* play); -void OceffSpot_Destroy(Actor* thisx, PlayState* play); +void OceffSpot_Init(Actor* thisx, PlayState* play2); +void OceffSpot_Destroy(Actor* thisx, PlayState* play2); void OceffSpot_Update(Actor* thisx, PlayState* play); void OceffSpot_Draw(Actor* thisx, PlayState* play); -void func_809728F8(OceffSpot* this, PlayState* play); -void func_80972934(OceffSpot* this, PlayState* play); +void OceffSpot_Wait(OceffSpot* this, PlayState* play); +void OceffSpot_GrowCylinder(OceffSpot* this, PlayState* play); +void OceffSpot_End(OceffSpot* this, PlayState* play); void OceffSpot_SetupAction(OceffSpot* this, OceffSpotActionFunc actionFunc); -#if 0 const ActorInit Oceff_Spot_InitVars = { ACTOR_OCEFF_SPOT, ACTORCAT_ITEMACTION, @@ -33,28 +33,140 @@ const ActorInit Oceff_Spot_InitVars = { (ActorFunc)OceffSpot_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80973478[] = { +#include "assets/overlays/ovl_Oceff_Spot/ovl_Oceff_Spot.c" + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 0, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1500, ICHAIN_STOP), }; -#endif +void OceffSpot_SetupAction(OceffSpot* this, OceffSpotActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern InitChainEntry D_80973478[]; +void OceffSpot_Init(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + OceffSpot* this = THIS; + Player* player = GET_PLAYER(play); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_SetupAction.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + OceffSpot_SetupAction(this, OceffSpot_GrowCylinder); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_Init.s") + Lights_PointNoGlowSetInfo(&this->lightInfo1, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, 0); + this->lightNode1 = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_Destroy.s") + Lights_PointNoGlowSetInfo(&this->lightInfo2, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, 0); + this->lightNode2 = LightContext_InsertLight(play, &play->lightCtx, &this->lightInfo2); + this->actor.scale.y = 0.3f; + this->unk16C = 0.0f; + this->actor.world.pos.y = player->actor.world.pos.y; + this->actor.world.pos.x = player->bodyPartsPos[0].x; + this->actor.world.pos.z = player->bodyPartsPos[0].z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/func_80972844.s") +void OceffSpot_Destroy(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + OceffSpot* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/func_809728F8.s") + LightContext_RemoveLight(play, &play->lightCtx, this->lightNode1); + LightContext_RemoveLight(play, &play->lightCtx, this->lightNode2); + func_80115D5C(&play->state); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/func_80972934.s") +void OceffSpot_End(OceffSpot* this, PlayState* play) { + if (this->unk16C > 0.0f) { + this->unk16C -= 0.05f; + } else { + Actor_MarkForDeath(&this->actor); + if ((REG(15) != 0x190) && (play->msgCtx.unk12046 == 0)) { + if ((play->msgCtx.ocarinaAction != 0x39) || (play->msgCtx.ocarinaMode != 0xA)) { + gSaveContext.sunsSongState = SUNSSONG_START; + } + } else { + play->msgCtx.ocarinaMode = 4; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_Update.s") +void OceffSpot_Wait(OceffSpot* this, PlayState* play) { + if (this->timer > 0) { + this->timer--; + } else { + OceffSpot_SetupAction(this, OceffSpot_End); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Spot/OceffSpot_Draw.s") +void OceffSpot_GrowCylinder(OceffSpot* this, PlayState* play) { + if (this->unk16C < 1.0f) { + this->unk16C += 0.05f; + } else { + OceffSpot_SetupAction(this, OceffSpot_Wait); + this->timer = 60; + } +} + +void OceffSpot_Update(Actor* thisx, PlayState* play) { + f32 scale; + s32 pad; + Player* player = GET_PLAYER(play); + f32 temp; + OceffSpot* this = THIS; + + temp = (1.0f - cosf(this->unk16C * M_PI)) * 0.5f; + this->actionFunc(this, play); + + switch (gSaveContext.save.playerForm) { + default: + scale = 1.0f; + break; + + case PLAYER_FORM_DEKU: + scale = 1.3f; + break; + + case PLAYER_FORM_ZORA: + scale = 1.2f; + break; + + case PLAYER_FORM_GORON: + scale = 2.0f; + break; + } + + this->actor.scale.z = (scale * 0.42f) * temp; + this->actor.scale.x = (scale * 0.42f) * temp; + + this->actor.world.pos = player->actor.world.pos; + this->actor.world.pos.y = this->actor.world.pos.y + 5.0f; + + temp = (2.0f - this->unk16C) * this->unk16C; + + func_800FD2B4(play, temp * 0.5f, 880.0f, 0.2f, 0.9f); + + Lights_PointNoGlowSetInfo(&this->lightInfo1, this->actor.world.pos.x, this->actor.world.pos.y + 55.0f, + this->actor.world.pos.z, (s32)(255.0f * temp), (s32)(255.0f * temp), (s32)(200.0f * temp), + 100.0f * temp); + Lights_PointNoGlowSetInfo( + &this->lightInfo2, this->actor.world.pos.x + (Math_SinS(player->actor.shape.rot.y) * 20.0f), + this->actor.world.pos.y + 20.0f, this->actor.world.pos.z + (Math_CosS(player->actor.shape.rot.y) * 20.0f), + (s32)(255.0f * temp), (s32)(255.0f * temp), (s32)(200.0f * temp), 100.0f * temp); +} + +void OceffSpot_Draw(Actor* thisx, PlayState* play) { + OceffSpot* this = THIS; + u32 scroll = play->state.frames & 0xFFFF; + + OPEN_DISPS(play->state.gfxCtx); + + func_8012C2DC(play->state.gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &sSunSongEffectCylinderMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(play->state.gfxCtx, 0, scroll * 2, scroll * -2, 0x20, 0x20, 1, 0, + scroll * -8, 0x20, 0x20)); + gSPDisplayList(POLY_XLU_DISP++, &sSunSongEffectCylinderModelDL); + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h index 922b1f89b8..0a770ee9d3 100644 --- a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h +++ b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.h @@ -9,7 +9,12 @@ typedef void (*OceffSpotActionFunc)(struct OceffSpot*, PlayState*); typedef struct OceffSpot { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x30]; + /* 0x144 */ LightNode* lightNode1; + /* 0x148 */ LightInfo lightInfo1; + /* 0x158 */ LightNode* lightNode2; + /* 0x15C */ LightInfo lightInfo2; + /* 0x16C */ f32 unk16C; + /* 0x170 */ u16 timer; /* 0x174 */ OceffSpotActionFunc actionFunc; } OceffSpot; // size = 0x178 diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 20fb6c0c27..dc205b344f 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -8057,9 +8057,9 @@ 0x80972680:("OceffSpot_SetupAction",), 0x8097268C:("OceffSpot_Init",), 0x809727EC:("OceffSpot_Destroy",), - 0x80972844:("func_80972844",), - 0x809728F8:("func_809728F8",), - 0x80972934:("func_80972934",), + 0x80972844:("OceffSpot_End",), + 0x809728F8:("OceffSpot_Wait",), + 0x80972934:("OceffSpot_GrowCylinder",), 0x80972998:("OceffSpot_Update",), 0x80972C54:("OceffSpot_Draw",), 0x80973550:("EnTorch_Init",),