diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml
index 8357f3f3f0..1e42a845f1 100644
--- a/assets/xml/objects/gameplay_keep.xml
+++ b/assets/xml/objects/gameplay_keep.xml
@@ -1043,7 +1043,7 @@
-
+
diff --git a/spec b/spec
index e467349236..53b6cbf8f3 100644
--- a/spec
+++ b/spec
@@ -1787,8 +1787,7 @@ beginseg
name "ovl_Effect_Ss_G_Spk"
compress
include "build/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.o"
- include "build/data/ovl_Effect_Ss_G_Spk/ovl_Effect_Ss_G_Spk.data.o"
- include "build/data/ovl_Effect_Ss_G_Spk/ovl_Effect_Ss_G_Spk.reloc.o"
+ include "build/src/overlays/effects/ovl_Effect_Ss_G_Spk/ovl_Effect_Ss_G_Spk_reloc.o"
endseg
beginseg
diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c
index 60a15c3ccb..b6a5c46fa0 100644
--- a/src/code/z_effect_soft_sprite_old_init.c
+++ b/src/code/z_effect_soft_sprite_old_init.c
@@ -335,7 +335,7 @@ void EffectSsGSpk_SpawnAccel(PlayState* play, Actor* actor, Vec3f* pos, Vec3f* v
initParams.actor = actor;
initParams.scale = scale;
initParams.scaleStep = scaleStep;
- initParams.updateMode = 0;
+ initParams.updateMode = GSPK_UPDATEMODE_NORMAL;
EffectSs_Spawn(play, EFFECT_SS_G_SPK, 128, &initParams);
}
@@ -353,7 +353,7 @@ void EffectSsGSpk_SpawnNoAccel(PlayState* play, Actor* actor, Vec3f* pos, Vec3f*
initParams.actor = actor;
initParams.scale = scale;
initParams.scaleStep = scaleStep;
- initParams.updateMode = 1;
+ initParams.updateMode = GSPK_UPDATEMODE_NO_ACCEL;
EffectSs_Spawn(play, EFFECT_SS_G_SPK, 128, &initParams);
}
diff --git a/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c b/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c
index d465e082e7..260541b511 100644
--- a/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c
+++ b/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.c
@@ -1,30 +1,145 @@
/*
* File: z_eff_ss_g_spk.c
* Overlay: ovl_Effect_Ss_G_Spk
- * Description:
+ * Description: Sparks
*/
#include "z_eff_ss_g_spk.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
+
+#define rPrimColorR regs[0]
+#define rPrimColorG regs[1]
+#define rPrimColorB regs[2]
+#define rPrimColorA regs[3]
+#define rEnvColorR regs[4]
+#define rEnvColorG regs[5]
+#define rEnvColorB regs[6]
+#define rEnvColorA regs[7]
+#define rTexIndex regs[8]
+#define rScale regs[9]
+#define rScaleStep regs[10]
#define PARAMS ((EffectSsGSpkInitParams*)initParamsx)
-s32 EffectSsGSpk_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx);
-void func_80978F40(PlayState* play, u32 index, EffectSs* this);
-void func_80979068(PlayState* play, u32 index, EffectSs* this);
+u32 EffectSsGSpk_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx);
+void EffectSsGSpk_Update(PlayState* play, u32 index, EffectSs* this);
+void EffectSsGSpk_UpdateNoAccel(PlayState* play, u32 index, EffectSs* this);
void EffectSsGSpk_Draw(PlayState* play, u32 index, EffectSs* this);
-#if 0
const EffectSsInit Effect_Ss_G_Spk_InitVars = {
EFFECT_SS_G_SPK,
EffectSsGSpk_Init,
};
-#endif
+static TexturePtr sSparkTextures[] = {
+ gElectricSpark1Tex,
+ gElectricSpark2Tex,
+ gElectricSpark3Tex,
+ gElectricSpark4Tex,
+};
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_G_Spk/EffectSsGSpk_Init.s")
+u32 EffectSsGSpk_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx) {
+ EffectSsGSpkInitParams* initParams = PARAMS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_G_Spk/EffectSsGSpk_Draw.s")
+ Math_Vec3f_Copy(&this->pos, &initParams->pos);
+ Math_Vec3f_Copy(&this->velocity, &initParams->velocity);
+ Math_Vec3f_Copy(&this->accel, &initParams->accel);
+ this->gfx = gEffSparkDL;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_G_Spk/func_80978F40.s")
+ if (initParams->updateMode == GSPK_UPDATEMODE_NORMAL) {
+ this->life = 10;
+ this->vec.x = initParams->pos.x - initParams->actor->world.pos.x;
+ this->vec.y = initParams->pos.y - initParams->actor->world.pos.y;
+ this->vec.z = initParams->pos.z - initParams->actor->world.pos.z;
+ this->update = EffectSsGSpk_Update;
+ } else {
+ this->life = 5;
+ this->update = EffectSsGSpk_UpdateNoAccel;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_G_Spk/func_80979068.s")
+ this->draw = EffectSsGSpk_Draw;
+ this->rPrimColorR = initParams->primColor.r;
+ this->rPrimColorG = initParams->primColor.g;
+ this->rPrimColorB = initParams->primColor.b;
+ this->rPrimColorA = initParams->primColor.a;
+ this->rEnvColorR = initParams->envColor.r;
+ this->rEnvColorG = initParams->envColor.g;
+ this->rEnvColorB = initParams->envColor.b;
+ this->rEnvColorA = initParams->envColor.a;
+ this->rTexIndex = 0;
+ this->rScale = initParams->scale;
+ this->rScaleStep = initParams->scaleStep;
+ this->actor = initParams->actor;
+
+ return 1;
+}
+
+void EffectSsGSpk_Draw(PlayState* play, u32 index, EffectSs* this) {
+ s32 pad;
+ MtxF mfTrans;
+ MtxF mfScale;
+ MtxF mfResult;
+ MtxF mfTransBillboard;
+ Mtx* mtx;
+ f32 scale;
+ GraphicsContext* gfxCtx = play->state.gfxCtx;
+
+ OPEN_DISPS(gfxCtx);
+
+ scale = this->rScale * 0.0025f;
+ SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z);
+ SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f);
+ SkinMatrix_MtxFMtxFMult(&mfTrans, &play->billboardMtxF, &mfTransBillboard);
+ SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfScale, &mfResult);
+
+ mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult);
+
+ if (mtx != NULL) {
+ gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(sSparkTextures[this->rTexIndex]));
+ func_8012C974(gfxCtx);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, 255);
+ gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, this->rEnvColorA);
+ gSPDisplayList(POLY_XLU_DISP++, this->gfx);
+ }
+
+ CLOSE_DISPS(gfxCtx);
+}
+
+void EffectSsGSpk_Update(PlayState* play, u32 index, EffectSs* this) {
+ this->accel.x = (Rand_ZeroOne() - 0.5f) * 3.0f;
+ this->accel.z = (Rand_ZeroOne() - 0.5f) * 3.0f;
+
+ if (this->actor != NULL) {
+ if ((this->actor->category == ACTORCAT_EXPLOSIVES) && (this->actor->update != NULL)) {
+ this->pos.x = this->actor->world.pos.x + this->vec.x;
+ this->pos.y = this->actor->world.pos.y + this->vec.y;
+ this->pos.z = this->actor->world.pos.z + this->vec.z;
+ if (this->actor->depthInWater >= 20.0f) {
+ this->life = 0;
+ }
+ }
+ }
+
+ this->vec.x += this->accel.x;
+ this->vec.z += this->accel.z;
+
+ this->rTexIndex++;
+ this->rTexIndex &= 3;
+ this->rScale += this->rScaleStep;
+}
+
+// this update mode is unused in the original game
+// with this update mode, the sparks dont move randomly in the xz plane, appearing to be on top of each other
+void EffectSsGSpk_UpdateNoAccel(PlayState* play, u32 index, EffectSs* this) {
+ if (this->actor != NULL) {
+ if ((this->actor->category == ACTORCAT_EXPLOSIVES) && (this->actor->update != NULL)) {
+ this->pos.x += (Math_SinS(this->actor->world.rot.y) * this->actor->speedXZ);
+ this->pos.z += (Math_CosS(this->actor->world.rot.y) * this->actor->speedXZ);
+ }
+ }
+
+ this->rTexIndex++;
+ this->rTexIndex &= 3;
+ this->rScale += this->rScaleStep;
+}
diff --git a/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.h b/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.h
index 1d970d3d24..c44bb91686 100644
--- a/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.h
+++ b/src/overlays/effects/ovl_Effect_Ss_G_Spk/z_eff_ss_g_spk.h
@@ -3,6 +3,11 @@
#include "global.h"
+typedef enum EffectSsGSpkUpdatemode {
+ /* 0 */ GSPK_UPDATEMODE_NORMAL,
+ /* 1 */ GSPK_UPDATEMODE_NO_ACCEL
+} EffectSsGSpkUpdatemode;
+
typedef struct {
/* 0x00 */ Actor* actor;
/* 0x04 */ Vec3f pos;
diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt
index 63db13c513..79eacb3264 100644
--- a/tools/disasm/functions.txt
+++ b/tools/disasm/functions.txt
@@ -8145,8 +8145,8 @@
0x80978B68:("EffectSsBlast_Update",),
0x80978C30:("EffectSsGSpk_Init",),
0x80978D70:("EffectSsGSpk_Draw",),
- 0x80978F40:("func_80978F40",),
- 0x80979068:("func_80979068",),
+ 0x80978F40:("EffectSsGSpk_Update",),
+ 0x80979068:("EffectSsGSpk_UpdateNoAccel",),
0x809791B0:("func_809791B0",),
0x80979228:("EffectSsDFire_Init",),
0x8097930C:("EffectSsDFire_Draw",),