diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml index 86f48d61dd..22626d302f 100644 --- a/assets/xml/objects/gameplay_keep.xml +++ b/assets/xml/objects/gameplay_keep.xml @@ -1287,27 +1287,27 @@ - + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - + + + + + diff --git a/include/z64effect.h b/include/z64effect.h index d9211ef5e1..0b848a478f 100644 --- a/include/z64effect.h +++ b/include/z64effect.h @@ -257,6 +257,7 @@ typedef struct { /* 0x18 */ u8 unk18; // Always 1? } EffectSsOverlay; // size = 0x1C +//! TODO: Review reuse of vec/gfx/actor fields across all effects typedef struct EffectSs { /* 0x00 */ Vec3f pos; /* 0x0C */ Vec3f velocity; diff --git a/spec b/spec index 9fc8e73276..3a3d2f8ff8 100644 --- a/spec +++ b/spec @@ -3411,8 +3411,7 @@ beginseg name "ovl_Effect_Ss_Sbn" compress include "build/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.o" - include "build/data/ovl_Effect_Ss_Sbn/ovl_Effect_Ss_Sbn.data.o" - include "build/data/ovl_Effect_Ss_Sbn/ovl_Effect_Ss_Sbn.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Sbn/ovl_Effect_Ss_Sbn_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c index d3286f5451..f1dc5c6f6a 100644 --- a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c +++ b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c @@ -357,10 +357,10 @@ void func_8088ACE0(EnArrow* this, GlobalContext* globalCtx) { if ((this->unk_262 != 0) && (this->actor.wallBgId == BG_ACTOR_MAX)) { - Math_Vec3f_Copy(&sp84.unk_00, &this->actor.world.pos); - sp84.unk_0C = this->actor.wallPoly; - sp84.unk_10 = this->bubble.unk_144; - EffectSs_Spawn(globalCtx, EFFECT_SS_SBN, 128, &sp84.unk_00); + Math_Vec3f_Copy(&sp84.pos, &this->actor.world.pos); + sp84.colPoly = this->actor.wallPoly; + sp84.scale = this->bubble.unk_144; + EffectSs_Spawn(globalCtx, EFFECT_SS_SBN, 128, &sp84); } } Actor_MarkForDeath(&this->actor); diff --git a/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.c b/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.c index b09dca0142..26901bac56 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.c +++ b/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.c @@ -1,30 +1,208 @@ /* * File: z_eff_ss_sbn.c * Overlay: ovl_Effect_Ss_Sbn - * Description: + * Description: Popped Deku Bubble + * + * Note: The gfx field is used to store the colPoly, not anything gfx related + * This is not a problem since gfx is already void* */ #include "z_eff_ss_sbn.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define rScrollStep regs[0] +#define rScroll regs[1] +#define rTexIndex regs[2] +#define rAlpha regs[3] +#define rReg4 regs[4] +#define rReg4Step regs[5] +#define rRotAngle regs[6] +#define rScale regs[7] +#define rReg8 regs[8] #define PARAMS ((EffectSsSbnInitParams*)initParamsx) -s32 EffectSsSbn_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsSbn_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsSbn_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); -void func_80AC8ECC(GlobalContext* globalCtx, u32 index, EffectSs* this); -void func_80AC9164(GlobalContext* globalCtx, u32 index, EffectSs* this); +void EffectSsSbn_DrawSliding(GlobalContext* globalCtx, u32 index, EffectSs* this); +void EffectSsSbn_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_Ss_Sbn_InitVars = { EFFECT_SS_SBN, EffectSsSbn_Init, }; -#endif +static TexturePtr sSlidingTextures[] = { + gEffPoppedDekuBubbleSliding1Tex, gEffPoppedDekuBubbleSliding2Tex, gEffPoppedDekuBubbleSliding3Tex, + gEffPoppedDekuBubbleSliding4Tex, gEffPoppedDekuBubbleSliding5Tex, gEffPoppedDekuBubbleSliding6Tex, + gEffPoppedDekuBubbleSliding7Tex, gEffPoppedDekuBubbleSliding8Tex, gEffPoppedDekuBubbleSliding9Tex, + gEffPoppedDekuBubbleSliding10Tex, gEffPoppedDekuBubbleSliding11Tex, gEffPoppedDekuBubbleSliding12Tex, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sbn/EffectSsSbn_Init.s") +static TexturePtr sTextures[] = { + gEffPoppedDekuBubble1Tex, gEffPoppedDekuBubble2Tex, gEffPoppedDekuBubble3Tex, + gEffPoppedDekuBubble4Tex, gEffPoppedDekuBubble5Tex, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sbn/func_80AC8ECC.s") +u32 EffectSsSbn_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsSbnInitParams* initParams = PARAMS; + CollisionPoly* colPoly; + MtxF mtx; + Vec3f normal; + Vec3f colPolyVec; + Vec3f bubbleVec; + f32 angle; + f32 opposite; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sbn/func_80AC9164.s") + Math_Vec3f_Copy(&this->pos, &initParams->pos); + Math_Vec3f_Copy(&this->velocity, &gZeroVec3f); + Math_Vec3f_Copy(&this->accel, &gZeroVec3f); + this->flags = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sbn/EffectSsSbn_Update.s") + this->gfx = initParams->colPoly; + + this->rScroll = 0; + this->rScrollStep = 7; + this->rTexIndex = 0; + this->rAlpha = 200; + this->rReg4 = 250; + this->rReg4Step = 30; + + this->rScale = randPlusMinusPoint5Scaled(100.0f) + (initParams->scale * 120.0f); + if (this->rScale < 600) { + this->rScale = 600; + } else if (this->rScale > 1500) { + this->rScale = 1500; + } + + this->rReg8 = 1000; + this->rRotAngle = 0; + this->life = 93; + this->draw = EffectSsSbn_DrawSliding; + this->update = EffectSsSbn_Update; + + if (this->gfx != NULL) { + colPoly = this->gfx; + func_800C0094(colPoly, this->pos.x, this->pos.y, this->pos.z, &mtx); + normal.x = COLPOLY_GET_NORMAL(colPoly->normal.x); + normal.y = COLPOLY_GET_NORMAL(colPoly->normal.y); + normal.z = COLPOLY_GET_NORMAL(colPoly->normal.z); + if ((normal.y > 0.95f) || (normal.y < -0.95f)) { + this->draw = EffectSsSbn_Draw; + return 1; + } + if (normal.y > 0.05f) { + colPolyVec.x = normal.x * 10.0f; + colPolyVec.y = (-(SQ(normal.x) + SQ(normal.z)) * 10.0f) / normal.y; + colPolyVec.z = normal.z * 10.0f; + } else if (normal.y < -0.05f) { + colPolyVec.x = -normal.x * 10.0f; + colPolyVec.y = (-(SQ(normal.x) + SQ(normal.z)) * 10.0f) / -normal.y; + colPolyVec.z = -normal.z * 10.0f; + } else { + colPolyVec.x = 0.0f; + colPolyVec.y = -10.0f; + colPolyVec.z = 0.0f; + } + bubbleVec.x = -mtx.mf[2][0] * 10.0f; + bubbleVec.y = -mtx.mf[2][1] * 10.0f; + bubbleVec.z = -mtx.mf[2][2] * 10.0f; + Math3D_AngleBetweenVectors(&colPolyVec, &bubbleVec, &angle); + + opposite = (SQ(angle) >= 1.0f) ? 0.0f : sqrtf(1.0f - SQ(angle)); + if (((mtx.mf[0][0] * colPolyVec.x) + (mtx.mf[0][1] * colPolyVec.y) + (mtx.mf[0][2] * colPolyVec.z)) < 0.0f) { + this->rRotAngle = Math_FAtan2F(angle, opposite); + } else { + this->rRotAngle = -Math_FAtan2F(angle, opposite); + } + } + + return 1; +} + +void EffectSsSbn_DrawSliding(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + MtxF mtx; + f32 scale = this->rScale * 0.001f; + s32 pad; + + func_800C0094(this->gfx, this->pos.x, this->pos.y, this->pos.z, &mtx); + SkinMatrix_MulYRotation(&mtx, this->rRotAngle); + Matrix_InsertMatrix(&mtx, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_Scale(0.05f, 0.05f, 0.05f, MTXMODE_APPLY); + + OPEN_DISPS(gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(gfxCtx); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_DECAL2); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, this->rAlpha); + + if (this->rTexIndex < ARRAY_COUNT(sSlidingTextures)) { + { + TexturePtr tex = sSlidingTextures[this->rTexIndex]; + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(tex)); + } + this->rTexIndex++; + this->rScroll += this->rScrollStep; + } else { + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffPoppedDekuBubbleSliding12Tex)); + if ((this->rScrollStep >= 2) && ((globalCtx->state.frames % 2) == 0)) { + this->rScrollStep--; + } + this->rScroll += this->rScrollStep; + } + gSPSegment(POLY_XLU_DISP++, 0x09, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, this->rScroll, 0x20, 0x20)); + gSPDisplayList(POLY_XLU_DISP++, gEffPoppedDekuBubbleSlidingDL); + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsSbn_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + MtxF mtx; + f32 scale = this->rScale * 0.001f; + + func_800C0094(this->gfx, this->pos.x, this->pos.y, this->pos.z, &mtx); + SkinMatrix_MulYRotation(&mtx, this->rRotAngle); + Matrix_InsertMatrix(&mtx, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_Scale(0.05f, 0.05f, 0.05f, MTXMODE_APPLY); + + OPEN_DISPS(gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(gfxCtx); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_DECAL2); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, this->rAlpha); + + if (this->rTexIndex < ARRAY_COUNT(sTextures)) { + { + TexturePtr tex = sTextures[this->rTexIndex]; + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(tex)); + } + this->rTexIndex++; + } else { + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffPoppedDekuBubble5Tex)); + } + gSPDisplayList(POLY_XLU_DISP++, gEffPoppedDekuBubbleDL); + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsSbn_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + if (this->life < 10) { + this->rAlpha -= 20; + } else if (this->life >= 45) { + if (this->life < 85) { + this->rReg8 += 12; + this->rReg4 -= this->rReg4Step; + } else { + this->rReg8 = 1000; + } + } +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h b/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h index ba2355d232..439ef88a01 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h +++ b/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h @@ -4,11 +4,10 @@ #include "global.h" typedef struct { - /* 0x00 */ Vec3f unk_00; - /* 0x0C */ CollisionPoly* unk_0C; - /* 0x10 */ f32 unk_10; - /* 0x14 */ char unk_14[UNK_SIZE]; -} EffectSsSbnInitParams; // size = ? + /* 0x00 */ Vec3f pos; + /* 0x0C */ CollisionPoly* colPoly; + /* 0x10 */ f32 scale; +} EffectSsSbnInitParams; // size = 0x14 extern const EffectSsInit Effect_Ss_Sbn_InitVars; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 73c959b32b..6a7b926838 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -11997,8 +11997,8 @@ 0x80AC8A94:("TransitionWipe5_SetColor",), 0x80AC8AA0:("TransitionWipe5_SetEnvColor",), 0x80AC8B50:("EffectSsSbn_Init",), - 0x80AC8ECC:("func_80AC8ECC",), - 0x80AC9164:("func_80AC9164",), + 0x80AC8ECC:("EffectSsSbn_DrawSliding",), + 0x80AC9164:("EffectSsSbn_Draw",), 0x80AC933C:("EffectSsSbn_Update",), 0x80AC94C0:("func_80AC94C0",), 0x80AC94FC:("ObjOcarinalift_Init",), diff --git a/undefined_syms.txt b/undefined_syms.txt index ca9dfd0a8e..296d6273e8 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -470,10 +470,6 @@ D_0406F380 = 0x0406F380; D_0406F9F0 = 0x0406F9F0; D_0406FAE0 = 0x0406FAE0; D_040706E0 = 0x040706E0; -D_04071230 = 0x04071230; -D_04073F00 = 0x04073F00; -D_04074330 = 0x04074330; -D_04075400 = 0x04075400; D_04075A40 = 0x04075A40; D_04076BC0 = 0x04076BC0; D_04079B10 = 0x04079B10;