From d79dad4c74946a1efd105e411a31fd40acab6d69 Mon Sep 17 00:00:00 2001 From: Fexty12573 Date: Fri, 2 Aug 2024 16:09:08 +0200 Subject: [PATCH] Document SPLEmitter_EmitChildren --- lib/spl/include/spl_internal.h | 2 +- lib/spl/include/spl_particle.h | 2 +- lib/spl/include/spl_resource.h | 24 +++--- lib/spl/meson.build | 2 +- lib/spl/src/{unk_020A05BC.c => spl_emit.c} | 95 ++++++++++------------ lib/spl/src/spl_emitter.c | 2 +- lib/spl/src/unk_0209DD54.c | 58 ++++++------- lib/spl/src/unk_020A19F0.c | 8 +- 8 files changed, 96 insertions(+), 97 deletions(-) rename lib/spl/src/{unk_020A05BC.c => spl_emit.c} (83%) diff --git a/lib/spl/include/spl_internal.h b/lib/spl/include/spl_internal.h index f41962ba13..b5dc674707 100644 --- a/lib/spl/include/spl_internal.h +++ b/lib/spl/include/spl_internal.h @@ -37,7 +37,7 @@ void sub_020A1A48(SPLParticle *ptcl, SPLResource *res, int lifeRate); // spl_chl void sub_020A19F0(SPLParticle *ptcl, SPLResource *res, int lifeRate); // spl_chld_alp_out void SPLEmitter_EmitParticles(SPLEmitter *emtr, SPLParticleList *list); -void sub_020A05BC(SPLParticle *ptcl, SPLEmitter *emtr, SPLList *list); +void SPLEmitter_EmitChildren(SPLParticle *ptcl, SPLEmitter *emtr, SPLParticleList *list); void SPLEmitter_Update(SPLManager *mgr, SPLEmitter *emtr); void SPLManager_DoDraw(SPLManager *mgr); diff --git a/lib/spl/include/spl_particle.h b/lib/spl/include/spl_particle.h index 115e0297c1..7effec4015 100644 --- a/lib/spl/include/spl_particle.h +++ b/lib/spl/include/spl_particle.h @@ -35,7 +35,7 @@ typedef struct SPLParticle { u16 currentPolygonID : 6; } visibility; fx32 baseScale; - fx16 unk_34; + fx16 animScale; GXRgb color; VecFx32 emitterPos; } SPLParticle; // size=0x44 diff --git a/lib/spl/include/spl_resource.h b/lib/spl/include/spl_resource.h index 0cb2f2f48b..ce4cb3b05d 100644 --- a/lib/spl/include/spl_resource.h +++ b/lib/spl/include/spl_resource.h @@ -27,6 +27,12 @@ enum SPLEmissionType { SPL_EMISSION_TYPE_HEMISPHERE, // Any point inside a hemisphere (direction specified by flags) }; +enum SPLChildRotationType { + SPL_CHILD_ROT_NONE = 0, + SPL_CHILD_ROT_INHERIT_ANGLE = 1, + SPL_CHILD_ROT_INHERIT_ANGLE_AND_VELOCITY = 2, +}; + typedef struct SPLArcHdr { u32 magic; u32 version; @@ -80,9 +86,9 @@ typedef union SPLChildResourceFlags { u16 usesBehaviors : 1; u16 hasScaleAnim : 1; u16 hasAlphaAnim : 1; - u16 unk_02_3 : 2; + u16 rotationType : 2; u16 followEmitter : 1; - u16 unk_02_6 : 1; + u16 useChildColor : 1; u16 drawType : 2; u16 unk_03_1 : 2; u16 unk_03_3 : 1; @@ -219,16 +225,14 @@ typedef struct SPLTexAnim { typedef struct SPLChildResource { SPLChildResourceFlags flags; - fx16 unk_02; + fx16 randomInitVelMag; // Randomization factor for the initial velocity magnitude (0 = no randomization) fx16 unk_04; - u16 unk_06; + u16 lifeTime; + u8 velocityRatio; // Ratio of the parent particle's velocity to inherit (255 = 100%) + u8 scaleRatio; // Ratio of the parent particle's scale to inherit (255 = 100%) + GXRgb color; struct { - u16 unk_00_0 : 8; - u16 unk_01_0 : 8; - } unk_08; - GXRgb unk_0A; - struct { - u32 unk_00_0 : 8; + u32 emissionCount : 8; // Number of particles to emit per emission interval u32 emissionDelay : 8; // Delay, as a fraction of the particle's lifetime, before the particle starts emitting u32 emissionInterval : 8; u32 textureIndex : 8; diff --git a/lib/spl/meson.build b/lib/spl/meson.build index 9e1ed1462a..248733776d 100644 --- a/lib/spl/meson.build +++ b/lib/spl/meson.build @@ -18,7 +18,7 @@ libspl_srcs = files( 'src/spl_manager.c', 'src/spl_emitter.c', 'src/unk_0209DD54.c', - 'src/unk_020A05BC.c', + 'src/spl_emit.c', 'src/unk_020A19F0.c', 'src/spl_behavior.c', 'src/spl_list.c', diff --git a/lib/spl/src/unk_020A05BC.c b/lib/spl/src/spl_emit.c similarity index 83% rename from lib/spl/src/unk_020A05BC.c rename to lib/spl/src/spl_emit.c index 896c91c69c..22419e8fad 100644 --- a/lib/spl/src/unk_020A05BC.c +++ b/lib/spl/src/spl_emit.c @@ -235,7 +235,7 @@ void SPLEmitter_EmitParticles(SPLEmitter *emtr, SPLParticleList *list) ptcl->emitterPos = emtr->position; ptcl->baseScale = SPLRandom_DoubleScaledRangeFX32(emtr->baseScale, header->randomAttenuation.baseScale); - ptcl->unk_34 = FX32_ONE; + ptcl->animScale = FX32_ONE; if (header->flags.hasColorAnim && res->colorAnim->unk_08.unk_00_0) { u16 clr[3]; @@ -285,76 +285,71 @@ void SPLEmitter_EmitParticles(SPLEmitter *emtr, SPLParticleList *list) } } -void sub_020A05BC(SPLParticle *ptcl, SPLEmitter *emtr, SPLList *list) +void SPLEmitter_EmitChildren(SPLParticle *ptcl, SPLEmitter *emtr, SPLParticleList *list) { - SPLParticle *chld; - fx32 velBase, velRand; - u32 rng; - int i; - SPLChildResource *chldRes = emtr->resource->childResource; - fx32 vel = FX_MUL((fx32)(chldRes->unk_08.unk_00_0 << FX32_SHIFT), FX32_CONST(1 / 256.0f)); + SPLParticle *child; - for (i = 0; i < chldRes->misc.unk_00_0; i++) { - chld = (SPLParticle *)SPLList_PopFront(list); - if (chld == NULL) { + SPLChildResource *childRes = emtr->resource->childResource; + fx32 velRatio = FX_MUL(childRes->velocityRatio * FX32_ONE, FX32_CONST(1 / 256.0f)); + + for (int i = 0; i < childRes->misc.emissionCount; i++) { + child = (SPLParticle *)SPLList_PopFront((SPLList *)list); // SPLParticleList_PopFront doesn't match here for some reason + if (child == NULL) { return; } - SPLList_PushFront((SPLList *)&emtr->childParticles, (SPLNode *)chld); - chld->position = ptcl->position; + SPLParticleList_PushFront(&emtr->childParticles, child); - velBase = FX_MUL(ptcl->velocity.x, vel); - velRand = SPLRandom_RangeFX32(chldRes->unk_02); - chld->velocity.x = velBase + velRand; + child->position = ptcl->position; - velBase = FX_MUL(ptcl->velocity.y, vel); - velRand = SPLRandom_RangeFX32(chldRes->unk_02); - chld->velocity.y = velBase + velRand; + fx32 velBase = FX_MUL(ptcl->velocity.x, velRatio); + fx32 velRand = SPLRandom_RangeFX32(childRes->randomInitVelMag); + child->velocity.x = velBase + velRand; - velBase = FX_MUL(ptcl->velocity.z, vel); - velRand = SPLRandom_RangeFX32(chldRes->unk_02); - chld->velocity.z = velBase + velRand; + velBase = FX_MUL(ptcl->velocity.y, velRatio); + velRand = SPLRandom_RangeFX32(childRes->randomInitVelMag); + child->velocity.y = velBase + velRand; - chld->emitterPos = ptcl->emitterPos; + velBase = FX_MUL(ptcl->velocity.z, velRatio); + velRand = SPLRandom_RangeFX32(childRes->randomInitVelMag); + child->velocity.z = velBase + velRand; - // `unk_08.unk_00_0` and `unk_08.unk_01_0` in `UnkSPLStruct14` - // could just be `u8 unk_08;` and `u8 unk_09;` - // instead of an inner struct - int idk = ptcl->baseScale * ptcl->unk_34 >> FX32_SHIFT; - chld->baseScale = idk * (chldRes->unk_08.unk_01_0 + 1) >> 6; + child->emitterPos = ptcl->emitterPos; - chld->unk_34 = FX32_ONE; + fx32 parentScale = ptcl->baseScale * ptcl->animScale >> FX32_SHIFT; + child->baseScale = parentScale * (childRes->scaleRatio + 1) >> 6; + child->animScale = FX32_ONE; - if (chldRes->flags.unk_02_6) { - chld->color = chldRes->unk_0A; + if (childRes->flags.useChildColor) { + child->color = childRes->color; } else { - chld->color = ptcl->color; + child->color = ptcl->color; } - chld->visibility.baseAlpha = (ptcl->visibility.baseAlpha * (ptcl->visibility.animAlpha + 1)) >> 5; - chld->visibility.animAlpha = 31; + child->visibility.baseAlpha = (ptcl->visibility.baseAlpha * (ptcl->visibility.animAlpha + 1)) >> 5; + child->visibility.animAlpha = 31; - switch (chldRes->flags.unk_02_3) { - case 0: - chld->rotation = 0; - chld->angularVelocity = 0; + switch (childRes->flags.rotationType) { + case SPL_CHILD_ROT_NONE: + child->rotation = 0; + child->angularVelocity = 0; break; - case 1: - chld->rotation = ptcl->rotation; - chld->angularVelocity = 0; + case SPL_CHILD_ROT_INHERIT_ANGLE: + child->rotation = ptcl->rotation; + child->angularVelocity = 0; break; - case 2: - chld->rotation = ptcl->rotation; - chld->angularVelocity = ptcl->angularVelocity; + case SPL_CHILD_ROT_INHERIT_ANGLE_AND_VELOCITY: + child->rotation = ptcl->rotation; + child->angularVelocity = ptcl->angularVelocity; break; } - chld->lifeTime = chldRes->unk_06; - chld->age = 0; - chld->misc.texture = chldRes->misc.textureIndex; + child->lifeTime = childRes->lifeTime; + child->age = 0; + child->misc.texture = childRes->misc.textureIndex; - chld->loopTimeFactor = 0xFFFF / (ptcl->lifeTime / 2); - chld->lifeTimeFactor = 0xFFFF / ptcl->lifeTime; - chld->misc.lifeRateOffset = 0; + child->loopTimeFactor = 0xFFFF / (ptcl->lifeTime / 2); + child->lifeTimeFactor = 0xFFFF / ptcl->lifeTime; + child->misc.lifeRateOffset = 0; } } diff --git a/lib/spl/src/spl_emitter.c b/lib/spl/src/spl_emitter.c index aa8956468a..788ed28827 100644 --- a/lib/spl/src/spl_emitter.c +++ b/lib/spl/src/spl_emitter.c @@ -225,7 +225,7 @@ void SPLEmitter_Update(SPLManager *mgr, SPLEmitter *emtr) if (diff >= 0) { if ((diff >> FX32_SHIFT) % child->misc.emissionInterval == 0) { - sub_020A05BC(ptcl, emtr, (SPLList *)&mgr->inactiveParticles); + SPLEmitter_EmitChildren(ptcl, emtr, &mgr->inactiveParticles); } } } diff --git a/lib/spl/src/unk_0209DD54.c b/lib/spl/src/unk_0209DD54.c index d9ec08a034..02531ebdd8 100644 --- a/lib/spl/src/unk_0209DD54.c +++ b/lib/spl/src/unk_0209DD54.c @@ -133,7 +133,7 @@ void sub_0209FF0C(SPLManager *mgr, SPLParticle *ptcl) cmr = mgr->renderState.viewMatrix; aspect = mgr->renderState.emitter->resource->header->unk_30; - animScale = ptcl->unk_34; + animScale = ptcl->animScale; ptclCol = ptcl->color; emtrCol = emtr->color; @@ -261,16 +261,16 @@ void sub_0209FAB8(SPLManager *mgr, SPLParticle *ptcl) switch (mgr->renderState.emitter->resource->header->misc.unk_07_4) { case 0: - sclX = FX_MUL(sclX, ptcl->unk_34); - sclY = FX_MUL(sclY, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); + sclY = FX_MUL(sclY, ptcl->animScale); break; case 1: - sclX = FX_MUL(sclX, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); break; case 2: - sclY = FX_MUL(sclY, ptcl->unk_34); + sclY = FX_MUL(sclY, ptcl->animScale); break; } @@ -372,16 +372,16 @@ void sub_0209F3D0(SPLManager *mgr, SPLParticle *ptcl) switch (mgr->renderState.emitter->resource->header->misc.unk_07_4) { case 0: - sclX = FX_MUL(sclX, ptcl->unk_34); - sclY = FX_MUL(sclY, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); + sclY = FX_MUL(sclY, ptcl->animScale); break; case 1: - sclX = FX_MUL(sclX, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); break; case 2: - sclY = FX_MUL(sclY, ptcl->unk_34); + sclY = FX_MUL(sclY, ptcl->animScale); break; } @@ -527,16 +527,16 @@ void sub_0209ECF0(SPLManager *mgr, SPLParticle *ptcl) switch (mgr->renderState.emitter->resource->header->misc.unk_07_4) { case 0: - sclX = FX_MUL(sclX, ptcl->unk_34); - sclY = FX_MUL(sclY, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); + sclY = FX_MUL(sclY, ptcl->animScale); break; case 1: - sclX = FX_MUL(sclX, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); break; case 2: - sclY = FX_MUL(sclY, ptcl->unk_34); + sclY = FX_MUL(sclY, ptcl->animScale); break; } @@ -680,16 +680,16 @@ void sub_0209E9A0(SPLManager *mgr, SPLParticle *ptcl) switch (resBase->misc.unk_07_4) { case 0: - sclX = FX_MUL(sclX, ptcl->unk_34); - sclY = FX_MUL(sclY, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); + sclY = FX_MUL(sclY, ptcl->animScale); break; case 1: - sclX = FX_MUL(sclX, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); break; case 2: - sclY = FX_MUL(sclY, ptcl->unk_34); + sclY = FX_MUL(sclY, ptcl->animScale); break; } @@ -763,16 +763,16 @@ void sub_0209E650(SPLManager *mgr, SPLParticle *ptcl) switch (resBase->misc.unk_07_4) { case 0: - sclX = FX_MUL(sclX, ptcl->unk_34); - sclY = FX_MUL(sclY, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); + sclY = FX_MUL(sclY, ptcl->animScale); break; case 1: - sclX = FX_MUL(sclX, ptcl->unk_34); + sclX = FX_MUL(sclX, ptcl->animScale); break; case 2: - sclY = FX_MUL(sclY, ptcl->unk_34); + sclY = FX_MUL(sclY, ptcl->animScale); break; } @@ -881,16 +881,16 @@ void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl) switch (resBase->misc.unk_07_4) { case 0: - scaleX = FX_MUL(scaleX, ptcl->unk_34); - scaleY = FX_MUL(scaleY, ptcl->unk_34); + scaleX = FX_MUL(scaleX, ptcl->animScale); + scaleY = FX_MUL(scaleY, ptcl->animScale); break; case 1: - scaleX = FX_MUL(scaleX, ptcl->unk_34); + scaleX = FX_MUL(scaleX, ptcl->animScale); break; case 2: - scaleY = FX_MUL(scaleY, ptcl->unk_34); + scaleY = FX_MUL(scaleY, ptcl->animScale); break; } @@ -999,16 +999,16 @@ void sub_0209DD54(SPLManager *mgr, SPLParticle *ptcl) switch (resBase->misc.unk_07_4) { case 0: - scaleX = FX_MUL(scaleX, ptcl->unk_34); - scaleY = FX_MUL(scaleY, ptcl->unk_34); + scaleX = FX_MUL(scaleX, ptcl->animScale); + scaleY = FX_MUL(scaleY, ptcl->animScale); break; case 1: - scaleX = FX_MUL(scaleX, ptcl->unk_34); + scaleX = FX_MUL(scaleX, ptcl->animScale); break; case 2: - scaleY = FX_MUL(scaleY, ptcl->unk_34); + scaleY = FX_MUL(scaleY, ptcl->animScale); break; } diff --git a/lib/spl/src/unk_020A19F0.c b/lib/spl/src/unk_020A19F0.c index 9288b1dde9..2d39af1178 100644 --- a/lib/spl/src/unk_020A19F0.c +++ b/lib/spl/src/unk_020A19F0.c @@ -18,13 +18,13 @@ void sub_020A1DA0(SPLParticle *ptcl, SPLResource *res, int lifeRate) if (lifeRate < in) { start = scaleAnim->unk_00; n = scaleAnim->unk_02; - ptcl->unk_34 = start + ((lifeRate * (n - start)) / in); + ptcl->animScale = start + ((lifeRate * (n - start)) / in); } else if (lifeRate >= out) { end = scaleAnim->unk_04; n = scaleAnim->unk_02; - ptcl->unk_34 = end + (((lifeRate - 255) * (end - n)) / (255 - out)); + ptcl->animScale = end + (((lifeRate - 255) * (end - n)) / (255 - out)); } else { - ptcl->unk_34 = scaleAnim->unk_02; + ptcl->animScale = scaleAnim->unk_02; } } @@ -124,7 +124,7 @@ void sub_020A1A94(SPLParticle *ptcl, SPLResource *res, int lifeRate) void sub_020A1A48(SPLParticle *ptcl, SPLResource *res, int lifeRate) { - ptcl->unk_34 = res->childResource->unk_04 + ((res->childResource->unk_04 - FX16_ONE) * (lifeRate - 255)) / 255; + ptcl->animScale = res->childResource->unk_04 + ((res->childResource->unk_04 - FX16_ONE) * (lifeRate - 255)) / 255; } void sub_020A19F0(SPLParticle *ptcl, SPLResource *res, int lifeRate)