From 7d4aaef0cdd1e6a0e4720d82c2fcbe7a2c275fbe Mon Sep 17 00:00:00 2001 From: louist103 <35883445+louist103@users.noreply.github.com> Date: Fri, 25 Mar 2022 22:51:41 -0400 Subject: [PATCH] Fire and Light arrows (#710) * fire arrow OK * Light arrows OK * Format * Assets * Mtx Mode * PR fixes * pr fixes * Update src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c * Update src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c --- assets/xml/overlays/ovl_Arrow_Ice.xml | 4 +- assets/xml/overlays/ovl_Arrow_Light.xml | 13 + assets/xml/overlays/ovl_Arrow_fire.xml | 12 + spec | 8 +- .../actors/ovl_Arrow_Fire/z_arrow_fire.c | 279 ++++++++++++++++-- .../actors/ovl_Arrow_Fire/z_arrow_fire.h | 15 +- .../actors/ovl_Arrow_Ice/z_arrow_ice.c | 8 +- .../actors/ovl_Arrow_Light/z_arrow_light.c | 205 +++++++++++-- .../actors/ovl_Arrow_Light/z_arrow_light.h | 12 +- tools/disasm/functions.txt | 16 +- tools/disasm/variables.txt | 17 +- 11 files changed, 505 insertions(+), 84 deletions(-) create mode 100644 assets/xml/overlays/ovl_Arrow_Light.xml create mode 100644 assets/xml/overlays/ovl_Arrow_fire.xml diff --git a/assets/xml/overlays/ovl_Arrow_Ice.xml b/assets/xml/overlays/ovl_Arrow_Ice.xml index 9ac5d04e07..bec512600b 100644 --- a/assets/xml/overlays/ovl_Arrow_Ice.xml +++ b/assets/xml/overlays/ovl_Arrow_Ice.xml @@ -1,8 +1,8 @@ - - + + diff --git a/assets/xml/overlays/ovl_Arrow_Light.xml b/assets/xml/overlays/ovl_Arrow_Light.xml new file mode 100644 index 0000000000..3d5ae87b84 --- /dev/null +++ b/assets/xml/overlays/ovl_Arrow_Light.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_Arrow_fire.xml b/assets/xml/overlays/ovl_Arrow_fire.xml new file mode 100644 index 0000000000..893f335d0d --- /dev/null +++ b/assets/xml/overlays/ovl_Arrow_fire.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/spec b/spec index c6faa6511e..3cb2716e3a 100644 --- a/spec +++ b/spec @@ -1369,9 +1369,7 @@ beginseg name "ovl_Arrow_Fire" compress include "build/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.o" - include "build/data/ovl_Arrow_Fire/ovl_Arrow_Fire.data.o" - include "build/data/ovl_Arrow_Fire/ovl_Arrow_Fire.bss.o" - include "build/data/ovl_Arrow_Fire/ovl_Arrow_Fire.reloc.o" + include "build/src/overlays/actors/ovl_Arrow_Fire/ovl_Arrow_Fire_reloc.o" endseg beginseg @@ -1385,9 +1383,7 @@ beginseg name "ovl_Arrow_Light" compress include "build/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.o" - include "build/data/ovl_Arrow_Light/ovl_Arrow_Light.data.o" - include "build/data/ovl_Arrow_Light/ovl_Arrow_Light.bss.o" - include "build/data/ovl_Arrow_Light/ovl_Arrow_Light.reloc.o" + include "build/src/overlays/actors/ovl_Arrow_Light/ovl_Arrow_Light_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c index e85e3791ad..0b9bedbb8e 100644 --- a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c +++ b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c @@ -5,6 +5,7 @@ */ #include "z_arrow_fire.h" +#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) @@ -15,19 +16,10 @@ void ArrowFire_Destroy(Actor* thisx, GlobalContext* globalCtx); void ArrowFire_Update(Actor* thisx, GlobalContext* globalCtx); void ArrowFire_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80920440(ArrowFire* this, GlobalContext* globalCtx); -void func_8092058C(ArrowFire* this, GlobalContext* globalCtx); -void func_809207A0(ArrowFire* this, GlobalContext* globalCtx); +void FireArrow_ChargeAndWait(ArrowFire* this, GlobalContext* globalCtx); +void FireArrow_Fly(ArrowFire* this, GlobalContext* globalCtx); -void ArrowFire_SetupAction(ArrowFire* this, ArrowFireActionFunc actionFunc); - -#if 0 -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_80922230 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_TYPE_PLAYER, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK0, { 0x08000000, 0x00, 0x02 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, - { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, -}; +#include "overlays/ovl_Arrow_fire/ovl_Arrow_Fire.c" const ActorInit Arrow_Fire_InitVars = { ACTOR_ARROW_FIRE, @@ -41,29 +33,264 @@ const ActorInit Arrow_Fire_InitVars = { (ActorFunc)ArrowFire_Draw, }; -#endif +static ColliderQuadInit sQuadInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_NONE, + OC1_NONE, + OC2_TYPE_PLAYER, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0x08000000, 0x00, 0x02 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, + { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, +}; -extern ColliderQuadInit D_80922230; +static InitChainEntry sInitChain[] = { + ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_STOP), +}; -// there are uses of D_0E000000.fillRect (appearing as D_0E0002E0) in this file -extern GfxMasterList D_0E000000; +s32 sUnused; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_SetupAction.s") +void ArrowFire_SetupAction(ArrowFire* this, ArrowFireActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_Init.s") +void ArrowFire_Init(Actor* thisx, GlobalContext* globalCtx) { + ArrowFire* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_Destroy.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->radius = 0; + this->height = 1.0f; + ArrowFire_SetupAction(this, FireArrow_ChargeAndWait); + Actor_SetScale(&this->actor, 0.01f); + this->alpha = 160; + this->timer = 0; + this->screenFillIntensity = 0.0f; + Collider_InitAndSetQuad(globalCtx, &this->collider1, &this->actor, &sQuadInit); + Collider_InitAndSetQuad(globalCtx, &this->collider2, &this->actor, &sQuadInit); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/func_80920440.s") +void ArrowFire_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ArrowFire* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/FireArrow_Lerp.s") + func_80115D5C(&globalCtx->state); + Collider_DestroyQuad(globalCtx, &this->collider1); + Collider_DestroyQuad(globalCtx, &this->collider2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/func_8092058C.s") +void FireArrow_ChargeAndWait(ArrowFire* this, GlobalContext* globalCtx) { + EnArrow* arrow = (EnArrow*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/func_809207A0.s") + if ((arrow == NULL) || (arrow->actor.update == NULL)) { + Actor_MarkForDeath(&this->actor); + return; + } + if (this->radius < 10) { + this->radius++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_Update.s") + this->actor.world.pos = arrow->actor.world.pos; + this->actor.shape.rot = arrow->actor.shape.rot; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/func_80920948.s") + func_800B9010(&this->actor, NA_SE_PL_ARROW_CHARGE_FIRE - SFX_FLAG); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_Draw.s") + // if arrow has no parent, player has fired the arrow + if (arrow->actor.parent == NULL) { + this->firedPos = this->actor.world.pos; + this->radius = 10; + ArrowFire_SetupAction(this, FireArrow_Fly); + this->alpha = 255; + } +} + +void FireArrow_Lerp(Vec3f* firedPos, Vec3f* pos, f32 scale) { + VEC3F_LERPIMPDST(firedPos, firedPos, pos, scale); +} + +void FireArrow_Hit(ArrowFire* this, GlobalContext* globalCtx) { + f32 offset; + f32 scale; + u16 timer; + + if (this->actor.projectedW < 50.0f) { + scale = 10.0f; + } else if (this->actor.projectedW > 950.0f) { + scale = 310.0f; + } else { + scale = this->actor.projectedW; + scale = ((scale - 50.0f) * (1.0f / 3.0f)) + 10.0f; + } + + timer = this->timer; + if (timer != 0) { + this->timer--; + if (this->timer >= 8) { + offset = (this->timer - 8) * (1.0f / 24.0f); + offset = SQ(offset); + this->radius = (((1.0f - offset) * scale) + 10.0f); + this->height = F32_LERPIMP(this->height, 2.0f, 0.1f); + if (this->timer < 16) { + this->alpha = (this->timer * 35) - 280; + } + } + } + if (this->timer >= 9) { + if (this->screenFillIntensity < 1.0f) { + this->screenFillIntensity += 0.25f; + } + } else { + if (this->screenFillIntensity > 0.0f) { + this->screenFillIntensity -= 0.125f; + } + } + if (this->timer < 8) { + this->alpha = 0; + } + if (this->timer == 0) { + this->timer = 255; + Actor_MarkForDeath(&this->actor); + return; + } + if (this->timer >= 13) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } +} + +void FireArrow_Fly(ArrowFire* this, GlobalContext* globalCtx) { + EnArrow* arrow = (EnArrow*)this->actor.parent; + s32 pad; + s32 pad2; + + if ((arrow == NULL) || (arrow->actor.update == NULL)) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->actor.world.pos = arrow->actor.world.pos; + this->actor.shape.rot = arrow->actor.shape.rot; + + this->height = Math_Vec3f_DistXYZ(&this->firedPos, &this->actor.world.pos) * (1.0f / 24.0f); + + if (this->height < 1.0f) { + this->height = 1.0f; + } + + FireArrow_Lerp(&this->firedPos, &this->actor.world.pos, 0.05f); + if (arrow->unk_261 & 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_EXPLOSION_FRAME); + ArrowFire_SetupAction(this, FireArrow_Hit); + this->timer = 32; + this->alpha = 255; + return; + } + if (arrow->unk_260 < 34) { + if (this->alpha < 35) { + Actor_MarkForDeath(&this->actor); + return; + } + this->alpha -= 25; + } +} + +void ArrowFire_Update(Actor* thisx, GlobalContext* globalCtx) { + ArrowFire* this = (ArrowFire*)thisx; + + if ((globalCtx->msgCtx.msgMode == 0xE) || (globalCtx->msgCtx.msgMode == 0x12)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actionFunc(this, globalCtx); +} + +void FireArrow_SetQuadVerticies(ArrowFire* this) { + static Vec3f D_80922284 = { 100.0f, 700.0f, 0.0f }; + static Vec3f D_80922290 = { 400.0f, 27.0f, 0.0f }; + static Vec3f D_8092229C = { -100.0f, 700.0f, 0.0f }; + static Vec3f D_809222A8 = { -400, 27.0f, 0.0f }; + static Vec3f D_809222B4 = { 0.0f, 700.0f, 100.0f }; + static Vec3f D_809222C0 = { 0.0f, 27.0f, 400.0f }; + static Vec3f D_809222CC = { 0.0f, 700.0f, -100.0f }; + static Vec3f D_809222D8 = { 0.0f, 27.0f, -400.0f }; + Vec3f sp44; + Vec3f sp38; + Vec3f sp2C; + Vec3f sp20; + + Matrix_MultiplyVector3fByState(&D_80922284, &sp44); + Matrix_MultiplyVector3fByState(&D_80922290, &sp38); + Matrix_MultiplyVector3fByState(&D_8092229C, &sp2C); + Matrix_MultiplyVector3fByState(&D_809222A8, &sp20); + Collider_SetQuadVertices(&this->collider1, &sp44, &sp38, &sp2C, &sp20); + Matrix_MultiplyVector3fByState(&D_809222B4, &sp44); + Matrix_MultiplyVector3fByState(&D_809222C0, &sp38); + Matrix_MultiplyVector3fByState(&D_809222CC, &sp2C); + Matrix_MultiplyVector3fByState(&D_809222D8, &sp20); + Collider_SetQuadVertices(&this->collider2, &sp44, &sp38, &sp2C, &sp20); +} + +void ArrowFire_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnArrow* arrow; + ArrowFire* this = THIS; + u32 frames = globalCtx->state.frames; + s32 pad; + + arrow = (EnArrow*)this->actor.parent; + + if ((arrow != NULL) && (arrow->actor.update != NULL) && (this->timer < 255)) { + Actor* transform = (arrow->unk_261 & 2) ? &this->actor : &arrow->actor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + Matrix_InsertTranslation(transform->world.pos.x, transform->world.pos.y, transform->world.pos.z, MTXMODE_NEW); + Matrix_RotateY(transform->shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(transform->shape.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(transform->shape.rot.z, MTXMODE_APPLY); + + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + if (this->screenFillIntensity > 0.0f) { + POLY_XLU_DISP = func_8012BFC4(POLY_XLU_DISP); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s32)(this->screenFillIntensity * 40.0f) & 0xFF, 0, 0, + (s32)(150.0f * this->screenFillIntensity) & 0xFF); + + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE); + + gSPDisplayList(POLY_XLU_DISP++, D_0E000000.fillRect); + } + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 200, 0, this->alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128); + + Matrix_InsertRotation(0x4000, 0, 0, MTXMODE_APPLY); + + if (this->timer != 0) { + Matrix_InsertTranslation(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } else { + Matrix_InsertTranslation(0.0f, 1500.0f, 0.0f, MTXMODE_APPLY); + } + + Matrix_Scale(this->radius * 0.2f, this->height * 4.0f, this->radius * 0.2f, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, -700.0f, 0.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + FireArrow_SetQuadVerticies(this); + gSPDisplayList(POLY_XLU_DISP++, gFireArrowMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 255 - ((frames * 2) % 256), 0, 64, 32, 1, + 255 - (frames % 256), 511 - ((frames * 10) % 512), 64, 64)); + gSPDisplayList(POLY_XLU_DISP++, gFireArrowModelDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.h b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.h index bf1143cd9d..5f9617c65f 100644 --- a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.h +++ b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.h @@ -8,12 +8,19 @@ struct ArrowFire; typedef void (*ArrowFireActionFunc)(struct ArrowFire*, GlobalContext*); typedef struct ArrowFire { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x114]; - /* 0x0258 */ ArrowFireActionFunc actionFunc; - /* 0x025C */ char unk_25C[0x8]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderQuad collider1; + /* 0x1C4 */ ColliderQuad collider2; + /* 0x244 */ Vec3f firedPos; + /* 0x250 */ f32 height; + /* 0x254 */ f32 screenFillIntensity; + /* 0x258 */ ArrowFireActionFunc actionFunc; + /* 0x25C */ s16 radius; + /* 0x25E */ u16 timer; + /* 0x260 */ u8 alpha; } ArrowFire; // size = 0x264 + extern const ActorInit Arrow_Fire_InitVars; #endif // Z_ARROW_FIRE_H diff --git a/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c b/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c index 8f1d75ddee..8a402dfbe4 100644 --- a/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c +++ b/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c @@ -17,7 +17,6 @@ void ArrowIce_Update(Actor* thisx, GlobalContext* globalCtx); void ArrowIce_Draw(Actor* thisx, GlobalContext* globalCtx); void ArrowIce_Charge(ArrowIce* this, GlobalContext* globalCtx); -void ArrowIce_Hit(ArrowIce* this, GlobalContext* globalCtx); void ArrowIce_Fly(ArrowIce* this, GlobalContext* globalCtx); #include "overlays/ovl_Arrow_Ice/ovl_Arrow_Ice.c" @@ -94,7 +93,6 @@ void ArrowIce_LerpFiredPosition(Vec3f* firedPos, Vec3f* icePos, f32 scale) { void ArrowIce_Hit(ArrowIce* this, GlobalContext* globalCtx) { f32 scale; - f32 offset; u16 timer; if (this->actor.projectedW < 50.0f) { @@ -111,12 +109,12 @@ void ArrowIce_Hit(ArrowIce* this, GlobalContext* globalCtx) { this->timer--; if (this->timer >= 8) { - offset = ((this->timer - 8) * (1.0f / 24.0f)); + f32 offset = ((this->timer - 8) * (1.0f / 24.0f)); + offset = SQ(offset); this->radius = (((1.0f - offset) * scale) + 10.0f); - this->height += ((2.0f - this->height) * 0.1f); + this->height = F32_LERPIMP(this->height, 2.0f, 0.1f); if (this->timer < 16) { - if (1) {} this->alpha = ((this->timer * 35) - 280); } } diff --git a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c index 7d81b05a58..ac8eb1ae92 100644 --- a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c +++ b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c @@ -5,6 +5,7 @@ */ #include "z_arrow_light.h" +#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) @@ -15,13 +16,11 @@ void ArrowLight_Destroy(Actor* thisx, GlobalContext* globalCtx); void ArrowLight_Update(Actor* thisx, GlobalContext* globalCtx); void ArrowLight_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_809243AC(ArrowLight* this, GlobalContext* globalCtx); -void func_809244F8(ArrowLight* this, GlobalContext* globalCtx); -void func_809246C4(ArrowLight* this, GlobalContext* globalCtx); +void ArrowLight_Charge(ArrowLight* this, GlobalContext* globalCtx); +void ArrowLight_Fly(ArrowLight* this, GlobalContext* globalCtx); -void ArrowLight_SetupAction(ArrowLight* this, ArrowLightActionFunc actionFunc); +#include "overlays/ovl_Arrow_Light/ovl_Arrow_Light.c" -#if 0 const ActorInit Arrow_Light_InitVars = { ACTOR_ARROW_LIGHT, ACTORCAT_ITEMACTION, @@ -34,34 +33,198 @@ const ActorInit Arrow_Light_InitVars = { (ActorFunc)ArrowLight_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809260A0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_STOP), }; -#endif +static s32 sUnused; -extern InitChainEntry D_809260A0[]; +void ArrowLight_SetupAction(ArrowLight* this, ArrowLightActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -// there are uses of D_0E000000.fillRect (appearing as D_0E0002E0) in this file -extern GfxMasterList D_0E000000; +void ArrowLight_Init(Actor* thisx, GlobalContext* globalCtx) { + ArrowLight* this = (ArrowLight*)thisx; + Actor_ProcessInitChain(&this->actor, sInitChain); + this->radius = 0; + this->height = 1.0f; + ArrowLight_SetupAction(this, ArrowLight_Charge); + Actor_SetScale(&this->actor, 0.01f); + this->alpha = 130; + this->timer = 0; + this->screenFillIntensity = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/D_809260B0.s") +void ArrowLight_Destroy(Actor* thisx, GlobalContext* globalCtx) { + func_80115D5C(&globalCtx->state); + (void)"消滅"; // Unreferenced in retail, means "Disappearance" +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_SetupAction.s") +void ArrowLight_Charge(ArrowLight* this, GlobalContext* globalCtx) { + EnArrow* arrow = (EnArrow*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_Init.s") + if ((arrow == NULL) || (arrow->actor.update == NULL)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_Destroy.s") + if (this->radius < 10) { + this->radius++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/func_809243AC.s") + this->actor.world.pos = arrow->actor.world.pos; + this->actor.shape.rot = arrow->actor.shape.rot; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/func_809244A0.s") + func_800B9010(&this->actor, NA_SE_PL_ARROW_CHARGE_LIGHT - SFX_FLAG); + if (arrow->actor.parent == NULL) { + this->firedPos = this->actor.world.pos; + this->radius = 10; + ArrowLight_SetupAction(this, ArrowLight_Fly); + this->alpha = 255; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/func_809244F8.s") +void ArrowLight_Lerp(Vec3f* firedPos, Vec3f* pos, f32 scale) { + VEC3F_LERPIMPDST(firedPos, firedPos, pos, scale); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/func_809246C4.s") +void ArrowLight_Hit(ArrowLight* this, GlobalContext* globalCtx) { + f32 scale; + u16 timer; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_Update.s") + if (this->actor.projectedW < 50.0f) { + scale = 10.0f; + } else if (this->actor.projectedW > 950.0f) { + scale = 310.0f; + } else { + scale = this->actor.projectedW; + scale = ((scale - 50.0f) * (1.0f / 3.0f)) + 10.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_Draw.s") + timer = this->timer; + if (timer != 0) { + this->timer--; + if (this->timer >= 8) { + f32 offset = (this->timer - 8) * (1.0f / 24.0f); + + offset = SQ(offset); + this->radius = (((1.0f - offset) * scale) + 10.0f); + this->height = F32_LERPIMP(this->height, 2.0f, 0.1f); + if (this->timer < 16) { + this->alpha = (this->timer * 35) - 280; + } + } + } + if (this->timer >= 9) { + if (this->screenFillIntensity < 1.0f) { + this->screenFillIntensity += 0.25f; + } + } else { + if (this->screenFillIntensity > 0.0f) { + this->screenFillIntensity -= 0.125f; + } + } + if (this->timer < 8) { + this->alpha = 0; + } + if (this->timer == 0) { + this->timer = 255; + Actor_MarkForDeath(&this->actor); + return; + } +} + +void ArrowLight_Fly(ArrowLight* this, GlobalContext* globalCtx) { + EnArrow* arrow = (EnArrow*)this->actor.parent; + s32 pad[2]; + + if ((arrow == NULL) || (arrow->actor.update == NULL)) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->actor.world.pos = arrow->actor.world.pos; + this->actor.shape.rot = arrow->actor.shape.rot; + + this->height = Math_Vec3f_DistXYZ(&this->firedPos, &this->actor.world.pos) * (1.0f / 24.0f); + if (this->height < 1.0f) { + this->height = 1.0f; + } + + ArrowLight_Lerp(&this->firedPos, &this->actor.world.pos, 0.05f); + + if (arrow->unk_261 & 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_EXPLOSION_LIGHT); + ArrowLight_SetupAction(this, ArrowLight_Hit); + this->timer = 32; + this->alpha = 255; + return; + } + if (arrow->unk_260 < 34) { + if (this->alpha < 35) { + Actor_MarkForDeath(&this->actor); + return; + } + this->alpha -= 25; + } +} + +void ArrowLight_Update(Actor* thisx, GlobalContext* globalCtx) { + ArrowLight* this = THIS; + + if ((globalCtx->msgCtx.msgMode == 0xE) || (globalCtx->msgCtx.msgMode == 0x12)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actionFunc(this, globalCtx); +} + +void ArrowLight_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ArrowLight* this = (ArrowLight*)thisx; + u32 frames = globalCtx->state.frames; + EnArrow* arrow = (EnArrow*)this->actor.parent; + + if ((arrow != NULL) && (arrow->actor.update != NULL) && (this->timer < 255)) { + Actor* transform = (arrow->unk_261 & 2) ? &this->actor : &arrow->actor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_InsertTranslation(transform->world.pos.x, transform->world.pos.y, transform->world.pos.z, MTXMODE_NEW); + Matrix_RotateY(transform->shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(transform->shape.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(transform->shape.rot.z, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + if (this->screenFillIntensity > 0.0f) { + POLY_XLU_DISP = func_8012BFC4(POLY_XLU_DISP); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s32)(this->screenFillIntensity * 30.0f) & 0xFF, + (s32)(40.0f * this->screenFillIntensity) & 0xFF, 0, + (s32)(150.0f * this->screenFillIntensity) & 0xFF); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE); + gSPDisplayList(POLY_XLU_DISP++, D_0E000000.fillRect); + } + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 170, this->alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 0, 128); + + Matrix_InsertRotation(0x4000, 0, 0, MTXMODE_APPLY); + if (this->timer != 0) { + Matrix_InsertTranslation(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } else { + Matrix_InsertTranslation(0.0f, 1500.0f, 0.0f, MTXMODE_APPLY); + } + Matrix_Scale(this->radius * 0.2f, this->height * 4.0f, this->radius * 0.2f, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, -700.0f, 0.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gLightArrowMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 511 - ((frames * 5) % 512), 0, 4, 32, 1, + 511 - ((frames * 10) % 512), 511 - ((frames * 30) % 512), 8, 16)); + gSPDisplayList(POLY_XLU_DISP++, gLightArrowModelDL); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.h b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.h index ef462cfde2..7b3f3088f9 100644 --- a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.h +++ b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.h @@ -8,11 +8,17 @@ struct ArrowLight; typedef void (*ArrowLightActionFunc)(struct ArrowLight*, GlobalContext*); typedef struct ArrowLight { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; - /* 0x0160 */ ArrowLightActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ s16 radius; + /* 0x146 */ u16 timer; + /* 0x148 */ u8 alpha; + /* 0x14C */ Vec3f firedPos; + /* 0x158 */ f32 height; + /* 0x15C */ f32 screenFillIntensity; + /* 0x160 */ ArrowLightActionFunc actionFunc; } ArrowLight; // size = 0x164 + extern const ActorInit Arrow_Light_InitVars; #endif // Z_ARROW_LIGHT_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 26cff71a91..8b40e2a919 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -7000,12 +7000,12 @@ 0x80920340:("ArrowFire_SetupAction",), 0x8092034C:("ArrowFire_Init",), 0x809203F8:("ArrowFire_Destroy",), - 0x80920440:("func_80920440",), + 0x80920440:("FireArrow_ChargeAndWait",), 0x80920534:("FireArrow_Lerp",), - 0x8092058C:("func_8092058C",), - 0x809207A0:("func_809207A0",), + 0x8092058C:("FireArrow_Hit",), + 0x809207A0:("FireArrow_Fly",), 0x809208F4:("ArrowFire_Update",), - 0x80920948:("func_80920948",), + 0x80920948:("FireArrow_SetQuadVerticies",), 0x80920A24:("ArrowFire_Draw",), 0x80922430:("ArrowIce_SetupAction",), 0x8092243C:("ArrowIce_Init",), @@ -7019,10 +7019,10 @@ 0x80924300:("ArrowLight_SetupAction",), 0x8092430C:("ArrowLight_Init",), 0x80924388:("ArrowLight_Destroy",), - 0x809243AC:("func_809243AC",), - 0x809244A0:("func_809244A0",), - 0x809244F8:("func_809244F8",), - 0x809246C4:("func_809246C4",), + 0x809243AC:("ArrowLight_Charge",), + 0x809244A0:("ArrowLight_Lerp",), + 0x809244F8:("ArrowLight_Hit",), + 0x809246C4:("ArrowLight_Fly",), 0x80924818:("ArrowLight_Update",), 0x8092486C:("ArrowLight_Draw",), 0x809261B0:("ObjKibako_SpawnCollectible",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index f509fff707..d578b0544a 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -7992,15 +7992,14 @@ 0x8092024C:("D_8092024C","UNK_TYPE1","",0x1), 0x80920268:("D_80920268","UNK_TYPE1","",0x1), 0x80920290:("jtbl_80920290","UNK_PTR","",0x4), - 0x80920DF0:("arrowFireTexture1","u8","[2048]",0x800), - 0x809215F0:("arrowFireTexture2","u8","[2048]",0x800), - 0x80921DF0:("arrowFireVertices","F3DVertex","[43]",0x2b0), - 0x80921FF0:("D_80921FF0","UNK_TYPE1","",0x1), - 0x809220A0:("D_809220A0","Gfx","[22]",0xb0), - 0x80922150:("D_80922150","Gfx","[24]",0xc0), + 0x80920DF0:("gFireArrowTex","u8","[2048]",0x800), + 0x809215F0:("gFireArrowMaskTex","u8","[2048]",0x800), + 0x80921DF0:("gFireArrowVtx","F3DVertex","[43]",0x2b0), + 0x809220A0:("gIceArrowMaterialDL","Gfx","[22]",0xb0), + 0x80922150:("gIceArrowModelDL","Gfx","[24]",0xc0), 0x80922210:("Arrow_Fire_InitVars","ActorInit","",0x20), - 0x80922230:("D_80922230","UNK_TYPE1","",0x1), - 0x80922280:("fireArrowActorInitVars","ActorInitVar","[1]",0x4), + 0x80922230:("sQuadInit","UNK_TYPE1","",0x1), + 0x80922280:("sInitChain","ActorInitVar","[1]",0x4), 0x80922284:("D_80922284","Vec3f","",0xc), 0x80922290:("D_80922290","Vec3f","",0xc), 0x8092229C:("D_8092229C","Vec3f","",0xc), @@ -8041,7 +8040,7 @@ 0x80925F10:("D_80925F10","UNK_TYPE1","",0x1), 0x80925FC0:("D_80925FC0","UNK_TYPE1","",0x1), 0x80926080:("Arrow_Light_InitVars","UNK_TYPE1","",0x1), - 0x809260A0:("D_809260A0","UNK_TYPE1","",0x1), + 0x809260A0:("sInitChain","UNK_TYPE1","",0x1), 0x809260B0:("D_809260B0","char","[]",0x1), 0x809260B8:("D_809260B8","f32","",0x4), 0x809260BC:("D_809260BC","f32","",0x4),