From 0b9f3ec2ca397713613c2aad0a0cf8cabc8d67a7 Mon Sep 17 00:00:00 2001 From: Fexty12573 Date: Thu, 1 Aug 2024 12:19:53 +0200 Subject: [PATCH] Document SPLEmitter Init and Update --- lib/spl/include/spl.h | 12 +- lib/spl/include/spl_emitter.h | 29 ++-- lib/spl/include/spl_internal.h | 4 +- lib/spl/include/spl_particle.h | 23 ++- lib/spl/include/spl_resource.h | 44 +++--- lib/spl/include/spl_texture.h | 10 +- lib/spl/src/spl_manager.c | 14 +- lib/spl/src/unk_0209CF00.c | 248 +++++++++++++++++---------------- lib/spl/src/unk_0209DD54.c | 152 ++++++++++---------- lib/spl/src/unk_020A05BC.c | 52 +++---- lib/spl/src/unk_020A19F0.c | 2 +- 11 files changed, 308 insertions(+), 282 deletions(-) diff --git a/lib/spl/include/spl.h b/lib/spl/include/spl.h index 717f2561a1..34ace30f13 100644 --- a/lib/spl/include/spl.h +++ b/lib/spl/include/spl.h @@ -6,24 +6,24 @@ static inline void SPL_UnkInline1 (SPLEmitter * param0, const VecFx32 * param1) { - param0->unk_98.x = param1->x + param0->resource->header->unk_04.x; - param0->unk_98.y = param1->y + param0->resource->header->unk_04.y; - param0->unk_98.z = param1->z + param0->resource->header->unk_04.z; + param0->position.x = param1->x + param0->resource->header->emitterBasePos.x; + param0->position.y = param1->y + param0->resource->header->emitterBasePos.y; + param0->position.z = param1->z + param0->resource->header->emitterBasePos.z; } static inline void SPL_UnkInline2 (SPLEmitter * param0, fx32 param1) { - param0->unk_98.x = param1 + param0->resource->header->unk_04.x; + param0->position.x = param1 + param0->resource->header->emitterBasePos.x; } static inline void SPL_UnkInline3 (SPLEmitter * param0, fx32 param1) { - param0->unk_98.y = param1 + param0->resource->header->unk_04.y; + param0->position.y = param1 + param0->resource->header->emitterBasePos.y; } static inline void SPL_UnkInline4 (SPLEmitter * param0, fx32 param1) { - param0->unk_98.z = param1 + param0->resource->header->unk_04.z; + param0->position.z = param1 + param0->resource->header->emitterBasePos.z; } static inline void SPL_UnkInline5 (SPLEmitter * param0, const VecFx16 * param1) diff --git a/lib/spl/include/spl_emitter.h b/lib/spl/include/spl_emitter.h index d93625b883..0a814bd511 100644 --- a/lib/spl/include/spl_emitter.h +++ b/lib/spl/include/spl_emitter.h @@ -6,6 +6,13 @@ #include "spl_particle.h" #include "spl_resource.h" +enum SPLUpdateCallbackType { + SPL_CALLBACK_PRE_UPDATE = 0, + SPL_CALLBACK_POST_UPDATE = 1, +}; + +typedef void(* SPLEmitterUpdateCallback)(struct SPLEmitter *emitter, enum SPLUpdateCallbackType type); + typedef struct UnkSPLStruct7 { union { @@ -13,12 +20,12 @@ typedef struct UnkSPLStruct7 { u8 padding_00[4]; struct { - u32 terminate:1; - u32 stop_generate:1; - u32 paused:1; - u32 renderingDisabled:1; + u32 terminate : 1; + u32 emissionPaused : 1; + u32 paused : 1; + u32 renderingDisabled : 1; u32 started: 1 ; - u32 reserved0:27; + u32 : 27; }; }; } UnkSPLStruct7; @@ -30,8 +37,8 @@ typedef struct SPLEmitter { SPLParticleList childParticles; SPLResource *resource; UnkSPLStruct7 state; - VecFx32 unk_98; - VecFx32 unk_A4; + VecFx32 position; + VecFx32 velocity; VecFx32 unk_B0; u16 age; fx16 unk_BE; @@ -43,22 +50,22 @@ typedef struct SPLEmitter { fx32 unk_D4; fx32 unk_D8; fx32 unk_DC; - u16 unk_E0; - GXRgb unk_E2; + u16 particleLifeTime; + GXRgb color; fx32 collisionPlaneHeight; fx16 unk_E8; fx16 unk_EA; fx16 unk_EC; fx16 unk_EE; struct { - u32 unk_00_0 : 8; + u32 emissionInterval : 8; // number of frames between particle emissions u32 unk_01_0 : 8; u32 updateCycle : 3; // 0 = every frame, 1 = cycle A, 2 = cycle B, cycles A and B alternate u32 unk_02_3 : 13; } misc; VecFx16 unk_F4; VecFx16 unk_FA; - void (* unk_100)(struct SPLEmitter *, unsigned int); + SPLEmitterUpdateCallback updateCallback; void * unk_104; union { u32 unk_108_val1; diff --git a/lib/spl/include/spl_internal.h b/lib/spl/include/spl_internal.h index aab749f798..14037cad16 100644 --- a/lib/spl/include/spl_internal.h +++ b/lib/spl/include/spl_internal.h @@ -39,9 +39,9 @@ void sub_020A19F0(SPLParticle *ptcl, SPLResource *res, int lifeRate); // spl_chl void sub_020A08DC(SPLEmitter *emtr, SPLList *list); void sub_020A05BC(SPLParticle *ptcl, SPLEmitter *emtr, SPLList *list); -void sub_0209D150(SPLManager *mgr, SPLEmitter *emtr); +void SPLEmitter_Update(SPLManager *mgr, SPLEmitter *emtr); void sub_0209CF00(SPLManager *mgr); -void sub_0209D998(SPLEmitter *emtr, SPLResource *res, const VecFx32 *pos); +void SPLEmitter_Init(SPLEmitter *emtr, SPLResource *res, const VecFx32 *pos); void spl_generate(SPLEmitter *emtr, SPLList *list); static inline void SPLParticleList_PushFront(SPLParticleList *list, SPLParticle *ptcl) diff --git a/lib/spl/include/spl_particle.h b/lib/spl/include/spl_particle.h index b3f1950a00..a478f8ff6b 100644 --- a/lib/spl/include/spl_particle.h +++ b/lib/spl/include/spl_particle.h @@ -10,20 +10,29 @@ typedef struct SPLParticle { struct SPLParticle *prev; VecFx32 position; VecFx32 velocity; - u16 unk_20; - s16 unk_22; + u16 rotation; + s16 angularVelocity; u16 lifeTime; u16 age; - u16 unk_28; - u16 unk_2A; + + // These two values are essentially 1.0f / lifeTime (or 1.0f / loopTime), represented as an integer + // They are used to map between age/lifeTime and a [0, 255] range + // Mainly just to lower the amount of divisions needed in the update functions + u16 loopTimeFactor; + u16 lifeTimeFactor; + struct { u16 unk_00 : 8; - u16 unk_01 : 8; - } unk_2C; + + // A value between 0 and 255 that is added to the life rate of the particle. + // This is used only for looping particles, so particles spawned at the same time + // don't have aren't all in sync (animation-wise) + u16 lifeRateOffset : 8; + } misc; struct { u16 unk_00_0 : 5; u16 unk_00_5 : 5; - u16 unk_01_2 : 6; + u16 currentPolygonID : 6; } unk_2E; fx32 unk_30; fx16 unk_34; diff --git a/lib/spl/include/spl_resource.h b/lib/spl/include/spl_resource.h index 9498aaefb7..887de03213 100644 --- a/lib/spl/include/spl_resource.h +++ b/lib/spl/include/spl_resource.h @@ -34,7 +34,7 @@ typedef union { // If set, the emitter will automatically terminate when it reaches the end of its life // and all of its particles have died u32 selfMaintaining : 1; - u32 unk_05_7 : 1; + u32 followEmitter : 1; u32 hasChildResource : 1; u32 unk_06_1 : 2; u32 unk_06_3 : 1; @@ -48,26 +48,26 @@ typedef union { u32 hasSpinBehavior : 1; u32 hasCollisionPlaneBehavior : 1; u32 hasConvergenceBehavior : 1; - u32 unk_07_6 : 1; - u32 unk_07_7 : 1; + u32 hasFixedPolygonID : 1; + u32 childHasFixedPolygonID : 1; }; } SPLResourceFlags; // size=0x4 typedef union { - u16 unk_00; + u16 all; struct { - u16 unk_02_0 : 1; - u16 unk_02_1 : 1; - u16 unk_02_2 : 1; + u16 usesBehaviors : 1; + u16 hasScaleAnim : 1; + u16 hasAlphaAnim : 1; u16 unk_02_3 : 2; - u16 unk_02_5 : 1; + u16 followEmitter : 1; u16 unk_02_6 : 1; u16 unk_02_7 : 2; u16 unk_03_1 : 2; u16 unk_03_3 : 1; u16 reserved_03_4 : 4; }; -} UnkSPLUnion2; // size=0x2 +} SPLChildResourceFlags; // size=0x2 typedef union { u16 val1; @@ -87,9 +87,9 @@ typedef union { }; } UnkSPLUnion4; // size=0x4 -typedef struct UnkSPLStruct9_t { +typedef struct SPLResourceHeader { SPLResourceFlags flags; - VecFx32 unk_04; + VecFx32 emitterBasePos; fx32 unk_10; fx32 unk_14; fx32 unk_18; @@ -116,7 +116,7 @@ typedef struct UnkSPLStruct9_t { struct { u32 unk_00_0 : 8; u32 unk_01_0 : 8; - u32 unk_02_0 : 8; + u32 airResistance : 8; u32 unk_03_0 : 8; u32 unk_04_0 : 8; u32 unk_05_0 : 16; @@ -128,7 +128,7 @@ typedef struct UnkSPLStruct9_t { u32 unk_08_1 : 1; u32 unk_08_2 : 3; u32 unk_08_5 : 27; - } unk_48; + } misc; fx16 unk_54; fx16 unk_56; struct { @@ -137,7 +137,7 @@ typedef struct UnkSPLStruct9_t { } unk_58; } SPLResourceHeader; // size=0x5C -typedef struct UnkSPLStruct10_t { +typedef struct SPLScaleAnim { fx16 unk_00; fx16 unk_02; fx16 unk_04; @@ -149,7 +149,7 @@ typedef struct UnkSPLStruct10_t { u16 reserved_0A; } SPLScaleAnim; // size=0xc -typedef struct UnkSPLStruct11_t { +typedef struct SPLColorAnim { GXRgb unk_00; GXRgb unk_02; UnkSPLUnion4 unk_04; @@ -162,7 +162,7 @@ typedef struct UnkSPLStruct11_t { u16 reserved_0A; } SPLColorAnim; -typedef struct UnkSPLStruct12_t { +typedef struct SPLAlphaAnim { union { u16 val1; struct { @@ -181,7 +181,7 @@ typedef struct UnkSPLStruct12_t { u16 reserved_06; } SPLAlphaAnim; // size=0x8 -typedef struct UnkSPLStruct13_t { +typedef struct SPLTexAnim { u8 unk_00[8]; struct { u32 unk_00_0 : 8; @@ -192,8 +192,8 @@ typedef struct UnkSPLStruct13_t { } unk_08; } SPLTexAnim; -typedef struct UnkSPLStruct14_t { - UnkSPLUnion2 unk_00; +typedef struct SPLChildResource { + SPLChildResourceFlags flags; fx16 unk_02; fx16 unk_04; u16 unk_06; @@ -204,8 +204,8 @@ typedef struct UnkSPLStruct14_t { GXRgb unk_0A; struct { u32 unk_00_0 : 8; - u32 unk_01_0 : 8; - u32 unk_02_0 : 8; + u32 emissionDelay : 8; // Delay, as a fraction of the particle's lifetime, before the particle starts emitting + u32 emissionInterval : 8; u32 unk_03_0 : 8; u32 unk_04_0 : 2; u32 unk_04_2 : 2; @@ -213,7 +213,7 @@ typedef struct UnkSPLStruct14_t { u32 unk_04_5 : 1; u32 unk_04_6 : 1; u32 reserved_04_7 : 25; - } unk_0C; + } misc; } SPLChildResource; typedef struct SPLResource { diff --git a/lib/spl/include/spl_texture.h b/lib/spl/include/spl_texture.h index 5d0cef34d1..83e87f3b51 100644 --- a/lib/spl/include/spl_texture.h +++ b/lib/spl/include/spl_texture.h @@ -8,11 +8,11 @@ typedef union SPLTextureParam { u32 all; struct { u32 format : 4; // Maps to GXTexFmt - u32 s : 4; - u32 t : 4; - u32 val2_01_4 : 2; - u32 val2_01_6 : 2; - u32 val2_02_0 : 1; + u32 s : 4; // Maps to GXTexSizeS + u32 t : 4; // Maps to GXTexSizeT + u32 repeat : 2; // Maps to GXTexRepeat + u32 flip : 2; // Maps to GXTexFlip + u32 palColor0 : 1; // Maps to GXTexPlttColor0 u32 val2_02_1 : 1; u32 sharedTexID : 8; u32 val2_03_2 : 6; diff --git a/lib/spl/src/spl_manager.c b/lib/spl/src/spl_manager.c index 6eb9863cd2..a01a7c9629 100644 --- a/lib/spl/src/spl_manager.c +++ b/lib/spl/src/spl_manager.c @@ -288,7 +288,7 @@ void SPLManager_Update(SPLManager *mgr) if (!emtr->state.paused) { if (emtr->misc.updateCycle == 0 || mgr->currentCycle == emtr->misc.updateCycle - 1) { - sub_0209D150(mgr, emtr); + SPLEmitter_Update(mgr, emtr); } } @@ -342,7 +342,7 @@ SPLEmitter *SPLManager_CreateEmitter(SPLManager *mgr, int resourceID, const VecF if (mgr->inactiveEmitters.first != NULL) { emtr = SPLEmitterList_PopFront(&mgr->inactiveEmitters); - sub_0209D998(emtr, mgr->resources + resourceID, pos); + SPLEmitter_Init(emtr, mgr->resources + resourceID, pos); SPLEmitterList_PushFront(&mgr->activeEmitters, emtr); if (emtr->resource->header->flags.selfMaintaining) { // Self-maintaining emitters are not returned to the user @@ -359,7 +359,7 @@ SPLEmitter *SPLManager_CreateEmitterWithCallback(SPLManager *mgr, int resourceID if (mgr->inactiveEmitters.first != NULL) { VecFx32 pos = { 0, 0, 0 }; emtr = SPLEmitterList_PopFront(&mgr->inactiveEmitters); - sub_0209D998(emtr, mgr->resources + resourceID, &pos); + SPLEmitter_Init(emtr, mgr->resources + resourceID, &pos); if (initCallback != NULL) { initCallback(emtr); @@ -380,7 +380,7 @@ SPLEmitter *SPLManager_CreateEmitterWithCallbackEx(SPLManager *mgr, int resource SPLEmitter *emtr = NULL; if (mgr->inactiveEmitters.first != NULL) { emtr = SPLEmitterList_PopFront(&mgr->inactiveEmitters); - sub_0209D998(emtr, mgr->resources + resourceID, pos); + SPLEmitter_Init(emtr, mgr->resources + resourceID, pos); if (initCallback != NULL) { initCallback(emtr, param); @@ -431,8 +431,8 @@ void SPL_Emit(SPLManager *mgr, SPLEmitter *emtr) void SPL_EmitAt(SPLManager *mgr, SPLEmitter *emtr, VecFx32 *pos) { - emtr->unk_98.x = pos->x + emtr->resource->header->unk_04.x; - emtr->unk_98.y = pos->y + emtr->resource->header->unk_04.y; - emtr->unk_98.z = pos->z + emtr->resource->header->unk_04.z; + emtr->position.x = pos->x + emtr->resource->header->emitterBasePos.x; + emtr->position.y = pos->y + emtr->resource->header->emitterBasePos.y; + emtr->position.z = pos->z + emtr->resource->header->emitterBasePos.z; spl_generate(emtr, (SPLList *)&mgr->inactiveParticles); } diff --git a/lib/spl/src/unk_0209CF00.c b/lib/spl/src/unk_0209CF00.c index ec769d72c1..bc4be40e37 100644 --- a/lib/spl/src/unk_0209CF00.c +++ b/lib/spl/src/unk_0209CF00.c @@ -10,6 +10,8 @@ #include "spl_internal.h" #include "spl_list.h" +#define ANIM_FUNC_NO_LOOP 0 +#define ANIM_FUNC_LOOP 1 typedef void(*DrawFunc)(SPLManager *mgr, SPLParticle *ptcl); typedef void(*SetTexFunc)(SPLTexture *tex); @@ -17,22 +19,22 @@ typedef void(*SetTexFunc)(SPLTexture *tex); typedef struct FieldFunc { void (*func)(SPLParticle *, SPLResource *, int); BOOL loop; -} FieldFunc; +} AnimFunc; typedef struct FieldFunc8 { void (*func)(SPLParticle *, SPLResource *, u8); BOOL loop; } FieldFunc8; -static void sub_0209DC68(SPLTexture *tex); // spl_set_tex -static void sub_0209DC64(SPLTexture *tex); // spl_set_tex_dummy +static void SPLUtil_SetTexture(SPLTexture *tex); // spl_set_tex +static void SPLUtil_SetTexture_Stub(SPLTexture *tex); // spl_set_tex_dummy static void sub_0209D064(SPLManager *mgr); static void sub_0209CF7C(SPLManager *mgr); -void sub_0209D998(SPLEmitter *emtr, SPLResource *res, const VecFx32 *param2); +void SPLEmitter_Init(SPLEmitter *emtr, SPLResource *res, const VecFx32 *param2); void sub_0209CF00(SPLManager *mgr); -void sub_0209D150(SPLManager *mgr, SPLEmitter *emtr); +void SPLEmitter_Update(SPLManager *mgr, SPLEmitter *emtr); -static void sub_0209DC68(SPLTexture *tex) +static void SPLUtil_SetTexture(SPLTexture *tex) { SPLTextureParam param = tex->param; @@ -41,9 +43,9 @@ static void sub_0209DC68(SPLTexture *tex) GX_TEXGEN_TEXCOORD, param.s, param.t, - param.val2_01_4, - param.val2_01_6, - param.val2_02_0, + param.repeat, + param.flip, + param.palColor0, tex->texAddr); G3_TexPlttBase(tex->palAddr, param.format); @@ -53,23 +55,23 @@ static void sub_0209DC68(SPLTexture *tex) G3_MtxMode(GX_MTXMODE_POSITION); } -static void sub_0209DC64(SPLTexture *tex) +static void SPLUtil_SetTexture_Stub(SPLTexture *tex) { } -void sub_0209D998(SPLEmitter *emtr, SPLResource *res, const VecFx32 *pos) +void SPLEmitter_Init(SPLEmitter *emtr, SPLResource *res, const VecFx32 *pos) { emtr->resource = res; emtr->state.all = 0; - emtr->unk_98.x = pos->x + emtr->resource->header->unk_04.x; - emtr->unk_98.y = pos->y + emtr->resource->header->unk_04.y; - emtr->unk_98.z = pos->z + emtr->resource->header->unk_04.z; + emtr->position.x = pos->x + emtr->resource->header->emitterBasePos.x; + emtr->position.y = pos->y + emtr->resource->header->emitterBasePos.y; + emtr->position.z = pos->z + emtr->resource->header->emitterBasePos.z; emtr->unk_B0.x = 0; emtr->unk_B0.y = 0; emtr->unk_B0.z = 0; - emtr->unk_A4.x = emtr->unk_A4.y = emtr->unk_A4.z = 0; + emtr->velocity.x = emtr->velocity.y = emtr->velocity.z = 0; emtr->age = 0; emtr->unk_BE = 0; @@ -82,34 +84,34 @@ void sub_0209D998(SPLEmitter *emtr, SPLResource *res, const VecFx32 *pos) emtr->unk_D4 = emtr->resource->header->unk_24; emtr->unk_D8 = emtr->resource->header->unk_28; emtr->unk_DC = emtr->resource->header->unk_2C; - emtr->unk_E0 = emtr->resource->header->particleLifeTime; + emtr->particleLifeTime = emtr->resource->header->particleLifeTime; - emtr->unk_E2 = GX_RGB(31, 31, 31); - emtr->misc.unk_00_0 = emtr->resource->header->unk_48.unk_00_0; - emtr->misc.unk_01_0 = emtr->resource->header->unk_48.unk_01_0; + emtr->color = GX_RGB(31, 31, 31); + emtr->misc.emissionInterval = emtr->resource->header->misc.unk_00_0; + emtr->misc.unk_01_0 = emtr->resource->header->misc.unk_01_0; emtr->misc.updateCycle = 0; emtr->misc.unk_02_3 = 0; emtr->collisionPlaneHeight = FX32_MIN; - emtr->unk_E8 = FX32_ONE << emtr->resource->header->unk_48.unk_07_0; - emtr->unk_EA = FX32_ONE << emtr->resource->header->unk_48.unk_07_2; + emtr->unk_E8 = FX32_ONE << emtr->resource->header->misc.unk_07_0; + emtr->unk_EA = FX32_ONE << emtr->resource->header->misc.unk_07_2; - if (emtr->resource->header->unk_48.unk_08_0) { + if (emtr->resource->header->misc.unk_08_0) { emtr->unk_E8 *= -1; } - if (emtr->resource->header->unk_48.unk_08_1) { + if (emtr->resource->header->misc.unk_08_1) { emtr->unk_EA *= -1; } if (emtr->resource->header->flags.hasChildResource) { - emtr->unk_EC = FX32_ONE << emtr->resource->childResource->unk_0C.unk_04_0; - emtr->unk_EE = FX32_ONE << emtr->resource->childResource->unk_0C.unk_04_2; + emtr->unk_EC = FX32_ONE << emtr->resource->childResource->misc.unk_04_0; + emtr->unk_EE = FX32_ONE << emtr->resource->childResource->misc.unk_04_2; - if (emtr->resource->childResource->unk_0C.unk_04_4) { + if (emtr->resource->childResource->misc.unk_04_4) { emtr->unk_EC *= -1; } - if (emtr->resource->childResource->unk_0C.unk_04_5) { + if (emtr->resource->childResource->misc.unk_04_5) { emtr->unk_EE *= -1; } } @@ -117,116 +119,121 @@ void sub_0209D998(SPLEmitter *emtr, SPLResource *res, const VecFx32 *pos) emtr->next = emtr->prev = NULL; emtr->particles.first = emtr->childParticles.first = NULL; emtr->particles.count = emtr->childParticles.count = 0; - emtr->unk_100 = NULL; + emtr->updateCallback = NULL; emtr->unk_104 = NULL; emtr->unk_108.unk_108_val1 = 0; } -void sub_0209D150(SPLManager *mgr, SPLEmitter *emtr) +void SPLEmitter_Update(SPLManager *mgr, SPLEmitter *emtr) { SPLParticle *ptcl; SPLParticle *next; SPLResource *res; - SPLResourceHeader *resBase; + SPLResourceHeader *header; SPLChildResource *child; SPLResourceFlags resFlags; - FieldFunc fieldFuncs[4]; - FieldFunc fieldFuncs2[4]; - int i, fieldIndex, fldNum; + AnimFunc animFuncs[4]; + AnimFunc childAnimFuncs[4]; + int i, animCount, behaviorCount; int airResistance; u8 lifeRates[2]; - VecFx32 vec; - int idx; + VecFx32 acc; res = emtr->resource; child = res->childResource; - fieldIndex = 0; - resBase = res->header; - resFlags = resBase->flags; - fldNum = res->behaviorCount; - airResistance = resBase->unk_48.unk_02_0 + 0x180; + animCount = 0; + header = res->header; + resFlags = header->flags; + behaviorCount = res->behaviorCount; + airResistance = header->misc.airResistance + FX32_CONST(0.09375); - if (emtr->unk_100) { - emtr->unk_100(emtr, FALSE); + if (emtr->updateCallback) { + emtr->updateCallback(emtr, SPL_CALLBACK_PRE_UPDATE); } - if (resBase->emitterLifeTime == 0 || emtr->age < resBase->emitterLifeTime) { - if (emtr->age % emtr->misc.unk_00_0 == 0) { - if (!emtr->state.terminate && !emtr->state.stop_generate && emtr->state.started) { + if (header->emitterLifeTime == 0 || emtr->age < header->emitterLifeTime) { + if (emtr->age % emtr->misc.emissionInterval == 0) { + if (!emtr->state.terminate && !emtr->state.emissionPaused && emtr->state.started) { sub_020A08DC(emtr, (SPLList *)(&mgr->inactiveParticles)); } } } if (resFlags.hasScaleAnim) { // ScaleAnim - fieldFuncs[fieldIndex].func = sub_020A1DA0; - fieldFuncs[fieldIndex++].loop = res->scaleAnim->unk_08.unk_00_0; + animFuncs[animCount].func = sub_020A1DA0; + animFuncs[animCount++].loop = res->scaleAnim->unk_08.unk_00_0; } if (resFlags.hasColorAnim && !res->colorAnim->unk_08.unk_00_0) { // ColorAnim - fieldFuncs[fieldIndex].func = sub_020A1BD4; - fieldFuncs[fieldIndex++].loop = res->colorAnim->unk_08.unk_00_1; + animFuncs[animCount].func = sub_020A1BD4; + animFuncs[animCount++].loop = res->colorAnim->unk_08.unk_00_1; } if (resFlags.hasAlphaAnim) { // AlphaAnim - fieldFuncs[fieldIndex].func = sub_020A1AF8; - fieldFuncs[fieldIndex++].loop = res->alphaAnim->unk_02.unk_01_0; + animFuncs[animCount].func = sub_020A1AF8; + animFuncs[animCount++].loop = res->alphaAnim->unk_02.unk_01_0; } if (resFlags.hasTexAnim && !res->texAnim->unk_08.unk_02_0) { // TexAnim - fieldFuncs[fieldIndex].func = sub_020A1A94; - fieldFuncs[fieldIndex++].loop = res->texAnim->unk_08.unk_02_1; + animFuncs[animCount].func = sub_020A1A94; + animFuncs[animCount++].loop = res->texAnim->unk_08.unk_02_1; } for (ptcl = emtr->particles.first; ptcl != NULL; ptcl = next) { next = ptcl->next; - lifeRates[0] = ptcl->unk_2A * ptcl->age >> 8; - lifeRates[1] = ptcl->unk_2C.unk_01 + (ptcl->unk_28 * ptcl->age >> 8); - for (i = 0; i < fieldIndex; i++) { - fieldFuncs[i].func(ptcl, res, lifeRates[fieldFuncs[i].loop]); + // For non-looping particles, "life rate" is a fraction of the particle's lifetime, represented as a u8. + // where 0 is the start of the particle's life and 255 is the end + // For looping particles, it's a fraction of the number of frames in the loop + // See the SPLParticle struct for more info + lifeRates[ANIM_FUNC_NO_LOOP] = (ptcl->lifeTimeFactor * ptcl->age) >> 8; + lifeRates[ANIM_FUNC_LOOP] = ptcl->misc.lifeRateOffset + ((ptcl->loopTimeFactor * ptcl->age) >> 8); + + for (i = 0; i < animCount; i++) { + animFuncs[i].func(ptcl, res, lifeRates[animFuncs[i].loop]); } - vec.x = vec.y = vec.z = 0; + acc.x = acc.y = acc.z = 0; - if (resFlags.unk_05_7) { - ptcl->emitterPos = emtr->unk_98; + if (resFlags.followEmitter) { + ptcl->emitterPos = emtr->position; } - for (i = 0; i < fldNum; i++) { - res->behaviors[i].apply(res->behaviors[i].object, ptcl, &vec, emtr); + for (i = 0; i < behaviorCount; i++) { + res->behaviors[i].apply(res->behaviors[i].object, ptcl, &acc, emtr); } - ptcl->unk_20 += ptcl->unk_22; + ptcl->rotation += ptcl->angularVelocity; - ptcl->velocity.x = (ptcl->velocity.x * airResistance >> 9); - ptcl->velocity.y = (ptcl->velocity.y * airResistance >> 9); - ptcl->velocity.z = (ptcl->velocity.z * airResistance >> 9); + ptcl->velocity.x = ptcl->velocity.x * airResistance >> 9; + ptcl->velocity.y = ptcl->velocity.y * airResistance >> 9; + ptcl->velocity.z = ptcl->velocity.z * airResistance >> 9; - ptcl->velocity.x += vec.x; - ptcl->velocity.y += vec.y; - ptcl->velocity.z += vec.z; + ptcl->velocity.x += acc.x; + ptcl->velocity.y += acc.y; + ptcl->velocity.z += acc.z; - ptcl->position.x += ptcl->velocity.x + emtr->unk_A4.x; - ptcl->position.y += ptcl->velocity.y + emtr->unk_A4.y; - ptcl->position.z += ptcl->velocity.z + emtr->unk_A4.z; + ptcl->position.x += ptcl->velocity.x + emtr->velocity.x; + ptcl->position.y += ptcl->velocity.y + emtr->velocity.y; + ptcl->position.z += ptcl->velocity.z + emtr->velocity.z; if (resFlags.hasChildResource) { - fx32 x = FX_MUL((fx32)ptcl->lifeTime << FX32_SHIFT, (fx32)child->unk_0C.unk_01_0 << FX32_SHIFT); - fx32 a = (fx32)ptcl->age * FX32_ONE; - fx32 diff = a - (x >> 8); + fx32 emissionDelay = FX_MUL((fx32)ptcl->lifeTime << FX32_SHIFT, (fx32)child->misc.emissionDelay << FX32_SHIFT); + + // The >> 8 here is a division by 256 because emissionDelay is a fraction of the particle's lifetime represented as a u8 + fx32 diff = ((fx32)ptcl->age * FX32_ONE) - (emissionDelay >> 8); if (diff >= 0) { - if ((diff >> FX32_SHIFT) % child->unk_0C.unk_02_0 == 0) { + if ((diff >> FX32_SHIFT) % child->misc.emissionInterval == 0) { sub_020A05BC(ptcl, emtr, (SPLList *)&mgr->inactiveParticles); } } } - if (emtr->resource->header->flags.unk_07_6) { - ptcl->unk_2E.unk_01_2 = mgr->polygonID.fix; + if (emtr->resource->header->flags.hasFixedPolygonID) { + ptcl->unk_2E.currentPolygonID = mgr->polygonID.fix; } else { - ptcl->unk_2E.unk_01_2 = mgr->polygonID.current; + ptcl->unk_2E.currentPolygonID = mgr->polygonID.current; mgr->polygonID.current += 1; if (mgr->polygonID.current > mgr->polygonID.max) { @@ -237,63 +244,65 @@ void sub_0209D150(SPLManager *mgr, SPLEmitter *emtr) ptcl->age += 1; if (ptcl->age > ptcl->lifeTime) { - SPLNode *node = SPLList_Erase((SPLList *)(&emtr->particles), (SPLNode *)ptcl); - SPLList_PushFront((SPLList *)&mgr->inactiveParticles, node); + SPLParticle *erased = SPLParticleList_Erase(&emtr->particles, ptcl); + SPLParticleList_PushFront(&mgr->inactiveParticles, erased); } } if (resFlags.hasChildResource) { - fieldIndex = 0; - if (child->unk_00.unk_02_1) { - fieldFuncs2[fieldIndex].func = sub_020A1A48; - fieldFuncs2[fieldIndex++].loop = FALSE; + animCount = 0; + if (child->flags.hasScaleAnim) { + childAnimFuncs[animCount].func = sub_020A1A48; + childAnimFuncs[animCount++].loop = FALSE; } - if (child->unk_00.unk_02_2) { - fieldFuncs2[fieldIndex].func = sub_020A19F0; - fieldFuncs2[fieldIndex++].loop = FALSE; + if (child->flags.hasAlphaAnim) { + childAnimFuncs[animCount].func = sub_020A19F0; + childAnimFuncs[animCount++].loop = FALSE; } - if (!child->unk_00.unk_02_0) { - fldNum = 0; + if (!child->flags.usesBehaviors) { + behaviorCount = 0; } for (ptcl = emtr->childParticles.first; ptcl != NULL; ptcl = next) { next = ptcl->next; + + // "life rate" is a fraction of the particle's lifetime, represented as a u8 + // where 0 is the start of the particle's life and 255 is the end lifeRates[0] = (ptcl->age << 8) / ptcl->lifeTime; - for (i = 0; i < fieldIndex; i++) { - u8 lifeRate = lifeRates[0]; - fieldFuncs2[i].func(ptcl, res, lifeRate); + for (i = 0; i < animCount; i++) { + childAnimFuncs[i].func(ptcl, res, lifeRates[0]); } - vec.x = vec.y = vec.z = 0; + acc.x = acc.y = acc.z = 0; - if (child->unk_00.unk_02_5) { - ptcl->emitterPos = emtr->unk_98; + if (child->flags.followEmitter) { + ptcl->emitterPos = emtr->position; } - for (i = 0; i < fldNum; i++) { - res->behaviors[i].apply(res->behaviors[i].object, ptcl, &vec, emtr); + for (i = 0; i < behaviorCount; i++) { + res->behaviors[i].apply(res->behaviors[i].object, ptcl, &acc, emtr); } - ptcl->unk_20 += ptcl->unk_22; + ptcl->rotation += ptcl->angularVelocity; ptcl->velocity.x = ptcl->velocity.x * airResistance >> 9; ptcl->velocity.y = ptcl->velocity.y * airResistance >> 9; ptcl->velocity.z = ptcl->velocity.z * airResistance >> 9; - ptcl->velocity.x += vec.x; - ptcl->velocity.y += vec.y; - ptcl->velocity.z += vec.z; + ptcl->velocity.x += acc.x; + ptcl->velocity.y += acc.y; + ptcl->velocity.z += acc.z; - ptcl->position.x += ptcl->velocity.x + emtr->unk_A4.x; - ptcl->position.y += ptcl->velocity.y + emtr->unk_A4.y; - ptcl->position.z += ptcl->velocity.z + emtr->unk_A4.z; + ptcl->position.x += ptcl->velocity.x + emtr->velocity.x; + ptcl->position.y += ptcl->velocity.y + emtr->velocity.y; + ptcl->position.z += ptcl->velocity.z + emtr->velocity.z; - if (emtr->resource->header->flags.unk_07_7) { - ptcl->unk_2E.unk_01_2 = mgr->polygonID.fix; + if (emtr->resource->header->flags.childHasFixedPolygonID) { + ptcl->unk_2E.currentPolygonID = mgr->polygonID.fix; } else { - ptcl->unk_2E.unk_01_2 = mgr->polygonID.current; + ptcl->unk_2E.currentPolygonID = mgr->polygonID.current; mgr->polygonID.current += 1; if (mgr->polygonID.current > mgr->polygonID.max) { @@ -304,15 +313,16 @@ void sub_0209D150(SPLManager *mgr, SPLEmitter *emtr) ptcl->age += 1; if (ptcl->age > ptcl->lifeTime) { - SPLList_PushFront((SPLList *)&mgr->inactiveParticles, SPLList_Erase((SPLList *)(&emtr->childParticles), (SPLNode *)ptcl)); + SPLParticle *erased = SPLParticleList_Erase(&emtr->childParticles, ptcl); + SPLParticleList_PushFront(&mgr->inactiveParticles, erased); } } } emtr->age += 1; - if (emtr->unk_100) { - emtr->unk_100(emtr, TRUE); + if (emtr->updateCallback) { + emtr->updateCallback(emtr, SPL_CALLBACK_POST_UPDATE); } } @@ -328,7 +338,7 @@ static void sub_0209D064(SPLManager *mgr) resBase = emtr->resource->header; drawFunc = NULL; - sub_0209DC68(mgr->textures + resBase->unk_48.unk_03_0); + SPLUtil_SetTexture(mgr->textures + resBase->misc.unk_03_0); switch (resBase->flags.unk_04_4) { case 0: @@ -348,11 +358,11 @@ static void sub_0209D064(SPLManager *mgr) break; } - setTexFunc = resBase->flags.hasTexAnim ? sub_0209DC68 : sub_0209DC64; + setTexFunc = resBase->flags.hasTexAnim ? SPLUtil_SetTexture : SPLUtil_SetTexture_Stub; ptcl = emtr->particles.first; while (ptcl != NULL) { - setTexFunc(mgr->textures + ptcl->unk_2C.unk_00); + setTexFunc(mgr->textures + ptcl->misc.unk_00); drawFunc(mgr, ptcl); ptcl = ptcl->next; } @@ -373,9 +383,9 @@ static void sub_0209CF7C(SPLManager *mgr) return; } - sub_0209DC68(mgr->textures + res->childResource->unk_0C.unk_03_0); + SPLUtil_SetTexture(mgr->textures + res->childResource->misc.unk_03_0); - switch (res->childResource->unk_00.unk_02_7) { + switch (res->childResource->flags.unk_02_7) { case 0: drawFunc = sub_0209FAB8; break; @@ -430,9 +440,9 @@ void SPL_Util_SetCylinderEmiterDirection(SPLEmitter *emtr, VecFx32 *p1, VecFx32 VecFx32 vex; if (emtr->resource->header->flags.unk_04_0 == 6 || emtr->resource->header->flags.unk_04_0 == 7) { - emtr->unk_98.x = (p2->x + p1->x) / 2; - emtr->unk_98.y = (p2->y + p1->y) / 2; - emtr->unk_98.z = (p2->z + p1->z) / 2; + emtr->position.x = (p2->x + p1->x) / 2; + emtr->position.y = (p2->y + p1->y) / 2; + emtr->position.z = (p2->z + p1->z) / 2; emtr->unk_D0 = VEC_Distance(p1, p2) / 2; vex.x = p2->x - p1->x; diff --git a/lib/spl/src/unk_0209DD54.c b/lib/spl/src/unk_0209DD54.c index a5e3233fde..fb923e835e 100644 --- a/lib/spl/src/unk_0209DD54.c +++ b/lib/spl/src/unk_0209DD54.c @@ -136,9 +136,9 @@ void sub_0209FF0C(SPLManager *mgr, SPLParticle *ptcl) animScale = ptcl->unk_34; ptclCol = ptcl->unk_36; - emtrCol = emtr->unk_E2; + emtrCol = emtr->color; - scaleAnimDirect = resBase->unk_48.unk_07_4; + scaleAnimDirect = resBase->misc.unk_07_4; fx32 alpha = ptcl->unk_2E.unk_00_0 * (ptcl->unk_2E.unk_00_5 + 1) >> 5; @@ -146,7 +146,7 @@ void sub_0209FF0C(SPLManager *mgr, SPLParticle *ptcl) GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, - ptcl->unk_2E.unk_01_2, + ptcl->unk_2E.currentPolygonID, alpha, mgr->unk_3C); @@ -174,8 +174,8 @@ void sub_0209FF0C(SPLManager *mgr, SPLParticle *ptcl) trs.z = ptcl->position.z + ptcl->emitterPos.z; MTX_MultVec43(&trs, cmr, &trs); - sin = FX_SinIdx(ptcl->unk_20); - fx32 cos = FX_CosIdx(ptcl->unk_20); + sin = FX_SinIdx(ptcl->rotation); + fx32 cos = FX_CosIdx(ptcl->rotation); load.m[0][0] = FX_MUL(cos, sclX); load.m[0][1] = FX_MUL(sin, sclX); load.m[0][2] = 0; @@ -192,13 +192,13 @@ void sub_0209FF0C(SPLManager *mgr, SPLParticle *ptcl) G3_Identity(); G3_MultMtx43(&load); } else { - trs.x = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->unk_04.x; - trs.y = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->unk_04.y; - trs.z = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->unk_04.z; + trs.x = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x; + trs.y = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y; + trs.z = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z; MTX_MultVec43(&trs, cmr, &trs); - sin = FX_SinIdx(ptcl->unk_20); - fx32 cos = FX_CosIdx(ptcl->unk_20); + sin = FX_SinIdx(ptcl->rotation); + fx32 cos = FX_CosIdx(ptcl->rotation); load.m[0][0] = FX_MUL(cos, sclX); load.m[0][1] = FX_MUL(sin, sclX); load.m[0][2] = 0; @@ -215,7 +215,7 @@ void sub_0209FF0C(SPLManager *mgr, SPLParticle *ptcl) G3_Identity(); SPLResourceHeader *resBase = mgr->renderState.emitter->resource->header; - G3_Translate(resBase->unk_04.x, resBase->unk_04.y, resBase->unk_04.z); + G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z); G3_MultMtx43(&load); } @@ -246,7 +246,7 @@ void sub_0209FAB8(SPLManager *mgr, SPLParticle *ptcl) GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, - ptcl->unk_2E.unk_01_2, + ptcl->unk_2E.currentPolygonID, alpha, mgr->unk_3C); @@ -259,7 +259,7 @@ void sub_0209FAB8(SPLManager *mgr, SPLParticle *ptcl) sclY = ptcl->unk_30; sclX = FX_MUL(sclY, aspect); - switch (mgr->renderState.emitter->resource->header->unk_48.unk_07_4) { + 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); @@ -280,8 +280,8 @@ void sub_0209FAB8(SPLManager *mgr, SPLParticle *ptcl) trs.z = ptcl->position.z + ptcl->emitterPos.z; MTX_MultVec43(&trs, cmr, &trs); - sin = FX_SinIdx(ptcl->unk_20); - fx32 cos = FX_CosIdx(ptcl->unk_20); + sin = FX_SinIdx(ptcl->rotation); + fx32 cos = FX_CosIdx(ptcl->rotation); load.m[0][0] = FX_MUL(cos, sclX); load.m[0][1] = FX_MUL(sin, sclX); load.m[0][2] = 0; @@ -298,13 +298,13 @@ void sub_0209FAB8(SPLManager *mgr, SPLParticle *ptcl) G3_Identity(); G3_MultMtx43(&load); } else { - trs.x = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->unk_04.x; - trs.y = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->unk_04.y; - trs.z = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->unk_04.z; + trs.x = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x; + trs.y = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y; + trs.z = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z; MTX_MultVec43(&trs, cmr, &trs); - sin = FX_SinIdx(ptcl->unk_20); - fx32 cos = FX_CosIdx(ptcl->unk_20); + sin = FX_SinIdx(ptcl->rotation); + fx32 cos = FX_CosIdx(ptcl->rotation); load.m[0][0] = FX_MUL(cos, sclX); load.m[0][1] = FX_MUL(sin, sclX); load.m[0][2] = 0; @@ -321,12 +321,12 @@ void sub_0209FAB8(SPLManager *mgr, SPLParticle *ptcl) G3_Identity(); SPLResourceHeader *resBase = mgr->renderState.emitter->resource->header; - G3_Translate(resBase->unk_04.x, resBase->unk_04.y, resBase->unk_04.z); + G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z); G3_MultMtx43(&load); } GXRgb colA = ptcl->unk_36; - GXRgb colB = mgr->renderState.emitter->unk_E2; + GXRgb colB = mgr->renderState.emitter->color; G3_Color(GX_RGB( GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5, GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15, @@ -357,7 +357,7 @@ void sub_0209F3D0(SPLManager *mgr, SPLParticle *ptcl) GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, - ptcl->unk_2E.unk_01_2, + ptcl->unk_2E.currentPolygonID, alpha, mgr->unk_3C); @@ -370,7 +370,7 @@ void sub_0209F3D0(SPLManager *mgr, SPLParticle *ptcl) sclY = ptcl->unk_30; sclX = FX_MUL(sclY, aspect); - switch (mgr->renderState.emitter->resource->header->unk_48.unk_07_4) { + 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); @@ -414,7 +414,7 @@ void sub_0209F3D0(SPLManager *mgr, SPLParticle *ptcl) dot = -dot; } - dot = FX_MUL(sclY, FX_MUL(FX32_ONE - dot, (fx32)mgr->renderState.emitter->resource->header->unk_48.unk_05_0) + FX32_ONE); + dot = FX_MUL(sclY, FX_MUL(FX32_ONE - dot, (fx32)mgr->renderState.emitter->resource->header->misc.unk_05_0) + FX32_ONE); load.m[0][0] = FX_MUL(dir.x, sclX); load.m[1][0] = FX_MUL(-dir.y, dot); load.m[3][0] = trs.x; @@ -431,9 +431,9 @@ void sub_0209F3D0(SPLManager *mgr, SPLParticle *ptcl) G3_Identity(); G3_MultMtx43(&load); } else { - trs.x = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->unk_04.x; - trs.y = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->unk_04.y; - trs.z = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->unk_04.z; + trs.x = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x; + trs.y = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y; + trs.z = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z; dir = ptcl->velocity; @@ -459,7 +459,7 @@ void sub_0209F3D0(SPLManager *mgr, SPLParticle *ptcl) dot = -dot; } - dot = FX_MUL(sclY, FX_MUL(FX32_ONE - dot, (fx32)mgr->renderState.emitter->resource->header->unk_48.unk_05_0) + FX32_ONE); + dot = FX_MUL(sclY, FX_MUL(FX32_ONE - dot, (fx32)mgr->renderState.emitter->resource->header->misc.unk_05_0) + FX32_ONE); load.m[0][0] = FX_MUL(dir.x, sclX); load.m[1][0] = FX_MUL(-dir.y, dot); load.m[2][0] = 0; @@ -476,12 +476,12 @@ void sub_0209F3D0(SPLManager *mgr, SPLParticle *ptcl) G3_Identity(); SPLResourceHeader *resBase = mgr->renderState.emitter->resource->header; - G3_Translate(resBase->unk_04.x, resBase->unk_04.y, resBase->unk_04.z); + G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z); G3_MultMtx43(&load); } GXRgb colA = ptcl->unk_36; - GXRgb colB = mgr->renderState.emitter->unk_E2; + GXRgb colB = mgr->renderState.emitter->color; G3_Color(GX_RGB( GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5, GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15, @@ -512,7 +512,7 @@ void sub_0209ECF0(SPLManager *mgr, SPLParticle *ptcl) GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, - ptcl->unk_2E.unk_01_2, + ptcl->unk_2E.currentPolygonID, alpha, mgr->unk_3C); @@ -525,7 +525,7 @@ void sub_0209ECF0(SPLManager *mgr, SPLParticle *ptcl) sclY = ptcl->unk_30; sclX = FX_MUL(sclY, aspect); - switch (mgr->renderState.emitter->resource->header->unk_48.unk_07_4) { + 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); @@ -569,7 +569,7 @@ void sub_0209ECF0(SPLManager *mgr, SPLParticle *ptcl) dot = -dot; } - dot = FX_MUL(sclY, FX_MUL(FX32_ONE - dot, (fx32)mgr->renderState.emitter->resource->header->unk_48.unk_05_0) + FX32_ONE); + dot = FX_MUL(sclY, FX_MUL(FX32_ONE - dot, (fx32)mgr->renderState.emitter->resource->header->misc.unk_05_0) + FX32_ONE); load.m[0][0] = FX_MUL(dir.x, sclX); load.m[1][0] = FX_MUL(-dir.y, dot); load.m[3][0] = trs.x; @@ -586,9 +586,9 @@ void sub_0209ECF0(SPLManager *mgr, SPLParticle *ptcl) G3_Identity(); G3_MultMtx43(&load); } else { - trs.x = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->unk_04.x; - trs.y = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->unk_04.y; - trs.z = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->unk_04.z; + trs.x = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x; + trs.y = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y; + trs.z = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z; dir = ptcl->velocity; @@ -614,7 +614,7 @@ void sub_0209ECF0(SPLManager *mgr, SPLParticle *ptcl) dot = -dot; } - dot = FX_MUL(sclY, FX_MUL(FX32_ONE - dot, (fx32)mgr->renderState.emitter->resource->header->unk_48.unk_05_0) + FX32_ONE); + dot = FX_MUL(sclY, FX_MUL(FX32_ONE - dot, (fx32)mgr->renderState.emitter->resource->header->misc.unk_05_0) + FX32_ONE); load.m[0][0] = FX_MUL(dir.x, sclX); load.m[1][0] = FX_MUL(-dir.y, dot); load.m[2][0] = 0; @@ -631,12 +631,12 @@ void sub_0209ECF0(SPLManager *mgr, SPLParticle *ptcl) G3_Identity(); SPLResourceHeader *resBase = mgr->renderState.emitter->resource->header; - G3_Translate(resBase->unk_04.x, resBase->unk_04.y, resBase->unk_04.z); + G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z); G3_MultMtx43(&load); } GXRgb colA = ptcl->unk_36; - GXRgb colB = mgr->renderState.emitter->unk_E2; + GXRgb colB = mgr->renderState.emitter->color; G3_Color(GX_RGB( GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5, GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15, @@ -662,7 +662,7 @@ void sub_0209E9A0(SPLManager *mgr, SPLParticle *ptcl) GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, - ptcl->unk_2E.unk_01_2, + ptcl->unk_2E.currentPolygonID, alpha, mgr->unk_3C); @@ -672,13 +672,13 @@ void sub_0209E9A0(SPLManager *mgr, SPLParticle *ptcl) return; } - Unk_02100DA8[mgr->renderState.emitter->resource->header->flags.unk_06_1](FX_SinIdx(ptcl->unk_20), FX_CosIdx(ptcl->unk_20), &rotMtx); + Unk_02100DA8[mgr->renderState.emitter->resource->header->flags.unk_06_1](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMtx); sclY = ptcl->unk_30; resBase = mgr->renderState.emitter->resource->header; sclX = FX_MUL(sclY, resBase->unk_30); - switch (resBase->unk_48.unk_07_4) { + switch (resBase->misc.unk_07_4) { case 0: sclX = FX_MUL(sclX, ptcl->unk_34); sclY = FX_MUL(sclY, ptcl->unk_34); @@ -704,21 +704,21 @@ void sub_0209E9A0(SPLManager *mgr, SPLParticle *ptcl) G3_LoadMtx43(mgr->renderState.viewMatrix); G3_MultMtx43(&load); } else { - load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->unk_04.x; - load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->unk_04.y; - load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->unk_04.z; + load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x; + load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y; + load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z; G3_Identity(); resBase = mgr->renderState.emitter->resource->header; - G3_Translate(resBase->unk_04.x, resBase->unk_04.y, resBase->unk_04.z); + G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z); G3_MultMtx43(mgr->renderState.viewMatrix); G3_MultMtx43(&load); } GXRgb colA = ptcl->unk_36; - GXRgb colB = mgr->renderState.emitter->unk_E2; + GXRgb colB = mgr->renderState.emitter->color; G3_Color(GX_RGB( GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5, GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15, @@ -745,7 +745,7 @@ void sub_0209E650(SPLManager *mgr, SPLParticle *ptcl) GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, - ptcl->unk_2E.unk_01_2, + ptcl->unk_2E.currentPolygonID, alpha, mgr->unk_3C); @@ -755,13 +755,13 @@ void sub_0209E650(SPLManager *mgr, SPLParticle *ptcl) return; } - Unk_02100DA8[mgr->renderState.emitter->resource->childResource->unk_00.unk_03_1](FX_SinIdx(ptcl->unk_20), FX_CosIdx(ptcl->unk_20), &rotMtx); + Unk_02100DA8[mgr->renderState.emitter->resource->childResource->flags.unk_03_1](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMtx); sclY = ptcl->unk_30; resBase = mgr->renderState.emitter->resource->header; sclX = FX_MUL(sclY, resBase->unk_30); - switch (resBase->unk_48.unk_07_4) { + switch (resBase->misc.unk_07_4) { case 0: sclX = FX_MUL(sclX, ptcl->unk_34); sclY = FX_MUL(sclY, ptcl->unk_34); @@ -786,27 +786,27 @@ void sub_0209E650(SPLManager *mgr, SPLParticle *ptcl) G3_LoadMtx43(mgr->renderState.viewMatrix); G3_MultMtx43(&load); } else { - load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->unk_04.x; - load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->unk_04.y; - load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->unk_04.z; + load.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - mgr->renderState.emitter->resource->header->emitterBasePos.x; + load.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y; + load.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z; G3_Identity(); resBase = mgr->renderState.emitter->resource->header; - G3_Translate(resBase->unk_04.x, resBase->unk_04.y, resBase->unk_04.z); + G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z); G3_MultMtx43(mgr->renderState.viewMatrix); G3_MultMtx43(&load); } GXRgb colA = ptcl->unk_36; - GXRgb colB = mgr->renderState.emitter->unk_E2; + GXRgb colB = mgr->renderState.emitter->color; G3_Color(GX_RGB( GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5, GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15, GX_RGB_B_(colA) * GX_RGB_B_(colB) >> 25)); SPLEmitter *emtr = mgr->renderState.emitter; - Unk_02100DA0[emtr->resource->childResource->unk_00.unk_03_3](emtr->unk_EC, emtr->unk_EE, 0, 0); + Unk_02100DA0[emtr->resource->childResource->flags.unk_03_3](emtr->unk_EC, emtr->unk_EE, 0, 0); } void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl) @@ -827,7 +827,7 @@ void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl) GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, - ptcl->unk_2E.unk_01_2, + ptcl->unk_2E.currentPolygonID, alpha, mgr->unk_3C); @@ -837,11 +837,11 @@ void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl) return; } - Unk_02100DA8[mgr->renderState.emitter->resource->header->flags.unk_06_1](FX_SinIdx(ptcl->unk_20), FX_CosIdx(ptcl->unk_20), &rotMat); + Unk_02100DA8[mgr->renderState.emitter->resource->header->flags.unk_06_1](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMat); MTX_Identity43(&mat); - if (!mgr->renderState.emitter->resource->header->unk_48.unk_07_7) { + if (!mgr->renderState.emitter->resource->header->misc.unk_07_7) { VEC_Normalize(&ptcl->velocity, &vec1); } else { VEC_Normalize(&ptcl->position, &vec1); @@ -879,7 +879,7 @@ void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl) scaleY = ptcl->unk_30; scaleX = FX_MUL(scaleY, resBase->unk_30); - switch (resBase->unk_48.unk_07_4) { + switch (resBase->misc.unk_07_4) { case 0: scaleX = FX_MUL(scaleX, ptcl->unk_34); scaleY = FX_MUL(scaleY, ptcl->unk_34); @@ -905,20 +905,20 @@ void sub_0209E1D4(SPLManager *mgr, SPLParticle *ptcl) G3_LoadMtx43(mgr->renderState.viewMatrix); G3_MultMtx43(&transform); } else { - transform.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - resBase->unk_04.x; - transform.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->unk_04.y; - transform.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->unk_04.z; + transform.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - resBase->emitterBasePos.x; + transform.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y; + transform.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z; G3_Identity(); resBase = mgr->renderState.emitter->resource->header; - G3_Translate(resBase->unk_04.x, resBase->unk_04.y, resBase->unk_04.z); + G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z); G3_MultMtx43(mgr->renderState.viewMatrix); G3_MultMtx43(&transform); } colA = ptcl->unk_36; - colB = mgr->renderState.emitter->unk_E2; + colB = mgr->renderState.emitter->color; G3_Color(GX_RGB( GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5, GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15, @@ -945,7 +945,7 @@ void sub_0209DD54(SPLManager *mgr, SPLParticle *ptcl) GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, - ptcl->unk_2E.unk_01_2, + ptcl->unk_2E.currentPolygonID, alpha, mgr->unk_3C); @@ -955,11 +955,11 @@ void sub_0209DD54(SPLManager *mgr, SPLParticle *ptcl) return; } - Unk_02100DA8[mgr->renderState.emitter->resource->childResource->unk_00.unk_03_1](FX_SinIdx(ptcl->unk_20), FX_CosIdx(ptcl->unk_20), &rotMtx); + Unk_02100DA8[mgr->renderState.emitter->resource->childResource->flags.unk_03_1](FX_SinIdx(ptcl->rotation), FX_CosIdx(ptcl->rotation), &rotMtx); MTX_Identity43(&mat); - if (!mgr->renderState.emitter->resource->childResource->unk_0C.unk_04_6) { + if (!mgr->renderState.emitter->resource->childResource->misc.unk_04_6) { VEC_Normalize(&ptcl->velocity, &vec1); } else { VEC_Normalize(&ptcl->position, &vec1); @@ -997,7 +997,7 @@ void sub_0209DD54(SPLManager *mgr, SPLParticle *ptcl) scaleY = ptcl->unk_30; scaleX = FX_MUL(scaleY, resBase->unk_30); - switch (resBase->unk_48.unk_07_4) { + switch (resBase->misc.unk_07_4) { case 0: scaleX = FX_MUL(scaleX, ptcl->unk_34); scaleY = FX_MUL(scaleY, ptcl->unk_34); @@ -1023,25 +1023,25 @@ void sub_0209DD54(SPLManager *mgr, SPLParticle *ptcl) G3_LoadMtx43(mgr->renderState.viewMatrix); G3_MultMtx43(&transform); } else { - transform.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - resBase->unk_04.x; - transform.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->unk_04.y; - transform.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->unk_04.z; + transform.m[3][0] = ptcl->position.x + ptcl->emitterPos.x - resBase->emitterBasePos.x; + transform.m[3][1] = ptcl->position.y + ptcl->emitterPos.y - mgr->renderState.emitter->resource->header->emitterBasePos.y; + transform.m[3][2] = ptcl->position.z + ptcl->emitterPos.z - mgr->renderState.emitter->resource->header->emitterBasePos.z; G3_Identity(); resBase = mgr->renderState.emitter->resource->header; - G3_Translate(resBase->unk_04.x, resBase->unk_04.y, resBase->unk_04.z); + G3_Translate(resBase->emitterBasePos.x, resBase->emitterBasePos.y, resBase->emitterBasePos.z); G3_MultMtx43(mgr->renderState.viewMatrix); G3_MultMtx43(&transform); } GXRgb colA = ptcl->unk_36; - GXRgb colB = mgr->renderState.emitter->unk_E2; + GXRgb colB = mgr->renderState.emitter->color; G3_Color(GX_RGB( GX_RGB_R_(colA) * GX_RGB_R_(colB) >> 5, GX_RGB_G_(colA) * GX_RGB_G_(colB) >> 15, GX_RGB_B_(colA) * GX_RGB_B_(colB) >> 25)); SPLEmitter *emtr = mgr->renderState.emitter; - Unk_02100DA0[emtr->resource->childResource->unk_00.unk_03_3](emtr->unk_EC, emtr->unk_EE, 0, 0); + Unk_02100DA0[emtr->resource->childResource->flags.unk_03_3](emtr->unk_EC, emtr->unk_EE, 0, 0); } diff --git a/lib/spl/src/unk_020A05BC.c b/lib/spl/src/unk_020A05BC.c index 88bf6d9d46..e600255b56 100644 --- a/lib/spl/src/unk_020A05BC.c +++ b/lib/spl/src/unk_020A05BC.c @@ -232,7 +232,7 @@ void sub_020A08DC(SPLEmitter *emtr, SPLList *list) ptcl->velocity.y = FX_MUL(posNorm.y, magPos) + FX_MUL(emtr->unk_C0.y, magAxis) + emtr->unk_B0.y; ptcl->velocity.z = FX_MUL(posNorm.z, magPos) + FX_MUL(emtr->unk_C0.z, magAxis) + emtr->unk_B0.z; - ptcl->emitterPos = emtr->unk_98; + ptcl->emitterPos = emtr->position; ptcl->unk_30 = SPLRandom_DoubleScaledRangeFX32(emtr->unk_DC, resBase->unk_44.unk_00_0); ptcl->unk_34 = FX32_ONE; @@ -252,35 +252,35 @@ void sub_020A08DC(SPLEmitter *emtr, SPLList *list) ptcl->unk_2E.unk_00_5 = 31; if (resBase->flags.unk_05_5) { - ptcl->unk_20 = SPLRandom_S32(32); + ptcl->rotation = SPLRandom_S32(32); } else { - ptcl->unk_20 = emtr->unk_C6; + ptcl->rotation = emtr->unk_C6; } if (resBase->flags.unk_05_4) { - ptcl->unk_22 = (u32)SPLRandom_BetweenFX32(resBase->unk_34, resBase->unk_36) >> FX32_SHIFT; + ptcl->angularVelocity = (u32)SPLRandom_BetweenFX32(resBase->unk_34, resBase->unk_36) >> FX32_SHIFT; } else { - ptcl->unk_22 = 0; + ptcl->angularVelocity = 0; } - ptcl->lifeTime = SPLRandom_ScaledRangeFX32(emtr->unk_E0, resBase->unk_44.unk_01_0) + 1; + ptcl->lifeTime = SPLRandom_ScaledRangeFX32(emtr->particleLifeTime, resBase->unk_44.unk_01_0) + 1; ptcl->age = 0; if (resBase->flags.hasTexAnim && res->texAnim->unk_08.unk_02_0) { - ptcl->unk_2C.unk_00 = res->texAnim->unk_00[SPLRandom_U32(12) % res->texAnim->unk_08.unk_00_0]; + ptcl->misc.unk_00 = res->texAnim->unk_00[SPLRandom_U32(12) % res->texAnim->unk_08.unk_00_0]; } else if (resBase->flags.hasTexAnim && !res->texAnim->unk_08.unk_02_0) { - ptcl->unk_2C.unk_00 = res->texAnim->unk_00[0]; + ptcl->misc.unk_00 = res->texAnim->unk_00[0]; } else { - ptcl->unk_2C.unk_00 = resBase->unk_48.unk_03_0; + ptcl->misc.unk_00 = resBase->misc.unk_03_0; } - ptcl->unk_28 = 0xFFFF / res->header->unk_48.unk_04_0; - ptcl->unk_2A = 0xFFFF / ptcl->lifeTime; + ptcl->loopTimeFactor = 0xFFFF / res->header->misc.unk_04_0; + ptcl->lifeTimeFactor = 0xFFFF / ptcl->lifeTime; - ptcl->unk_2C.unk_01 = 0; + ptcl->misc.lifeRateOffset = 0; if (resBase->flags.unk_06_4) { - ptcl->unk_2C.unk_01 = (u8)SPLRandom_S32(8); + ptcl->misc.lifeRateOffset = (u8)SPLRandom_S32(8); } i++; } while (i < curGenNum); @@ -296,7 +296,7 @@ void sub_020A05BC(SPLParticle *ptcl, SPLEmitter *emtr, SPLList *list) SPLChildResource *chldRes = emtr->resource->childResource; fx32 vel = FX_MUL((fx32)(chldRes->unk_08.unk_00_0 << FX32_SHIFT), FX32_CONST(1 / 256.0f)); - for (i = 0; i < chldRes->unk_0C.unk_00_0; i++) { + for (i = 0; i < chldRes->misc.unk_00_0; i++) { chld = (SPLParticle *)SPLList_PopFront(list); if (chld == NULL) { return; @@ -327,7 +327,7 @@ void sub_020A05BC(SPLParticle *ptcl, SPLEmitter *emtr, SPLList *list) chld->unk_34 = FX32_ONE; - if (chldRes->unk_00.unk_02_6) { + if (chldRes->flags.unk_02_6) { chld->unk_36 = chldRes->unk_0A; } else { chld->unk_36 = ptcl->unk_36; @@ -336,27 +336,27 @@ void sub_020A05BC(SPLParticle *ptcl, SPLEmitter *emtr, SPLList *list) chld->unk_2E.unk_00_0 = (ptcl->unk_2E.unk_00_0 * (ptcl->unk_2E.unk_00_5 + 1)) >> 5; chld->unk_2E.unk_00_5 = 31; - switch (chldRes->unk_00.unk_02_3) { + switch (chldRes->flags.unk_02_3) { case 0: - chld->unk_20 = 0; - chld->unk_22 = 0; + chld->rotation = 0; + chld->angularVelocity = 0; break; case 1: - chld->unk_20 = ptcl->unk_20; - chld->unk_22 = 0; + chld->rotation = ptcl->rotation; + chld->angularVelocity = 0; break; case 2: - chld->unk_20 = ptcl->unk_20; - chld->unk_22 = ptcl->unk_22; + chld->rotation = ptcl->rotation; + chld->angularVelocity = ptcl->angularVelocity; break; } chld->lifeTime = chldRes->unk_06; chld->age = 0; - chld->unk_2C.unk_00 = chldRes->unk_0C.unk_03_0; + chld->misc.unk_00 = chldRes->misc.unk_03_0; - chld->unk_28 = 0xFFFF / (ptcl->lifeTime / 2); - chld->unk_2A = 0xFFFF / ptcl->lifeTime; - chld->unk_2C.unk_01 = 0; + chld->loopTimeFactor = 0xFFFF / (ptcl->lifeTime / 2); + chld->lifeTimeFactor = 0xFFFF / ptcl->lifeTime; + chld->misc.lifeRateOffset = 0; } } diff --git a/lib/spl/src/unk_020A19F0.c b/lib/spl/src/unk_020A19F0.c index 9f746b00cf..07a6590bdb 100644 --- a/lib/spl/src/unk_020A19F0.c +++ b/lib/spl/src/unk_020A19F0.c @@ -116,7 +116,7 @@ void sub_020A1A94(SPLParticle *ptcl, SPLResource *res, int lifeRate) SPLTexAnim *texAnim = res->texAnim; for (int i = 0; i < texAnim->unk_08.unk_00_0; i++) { if (lifeRate < texAnim->unk_08.unk_01_0 * (i + 1)) { - ptcl->unk_2C.unk_00 = texAnim->unk_00[i]; + ptcl->misc.unk_00 = texAnim->unk_00[i]; return; } }