diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index c6f0c7b8..2875ba0f 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -88,7 +88,7 @@ toBeSorted/blur_and_palette_manager.cpp: .sdata2 start:0x80576BA0 end:0x80576C18 .bss start:0x8058F210 end:0x80594FA0 -toBeSorted/d_effects_1.cpp: +toBeSorted/d_emitter.cpp: .text start:0x800268B0 end:0x8002B99C align:16 .ctors start:0x804DB660 end:0x804DB664 .data start:0x80500E98 end:0x805014C0 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 174957ca..b0d41679 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -939,13 +939,13 @@ init__13dShpEmitter_cFPCcPCcb = .text:0x80028080; // type:function size:0x100 clear__13dShpEmitter_cFv = .text:0x80028180; // type:function size:0x10 draw__13dShpEmitter_cFP14JPABaseEmitterP15JPABaseParticle = .text:0x80028190; // type:function size:0x270 draw__21CommonEmitterCallbackFP14JPABaseEmitter = .text:0x80028400; // type:function size:0x18 -fn_80028420 = .text:0x80028420; // type:function size:0x58 +start__25dMassObjEmitterCallback_cFRC7mVec3_cP12dAcObjBase_c = .text:0x80028420; // type:function size:0x58 executeAfter__25dMassObjEmitterCallback_cFP14JPABaseEmitter = .text:0x80028480; // type:function size:0x170 execute__25dMassObjEmitterCallback_cFv = .text:0x800285F0; // type:function size:0x19C -fn_80028790 = .text:0x80028790; // type:function size:0x88 +clear__25dMassObjEmitterCallback_cFv = .text:0x80028790; // type:function size:0x88 create__17dMassObjEmitter_cFUs = .text:0x80028820; // type:function size:0x9C remove__17dMassObjEmitter_cFv = .text:0x800288C0; // type:function size:0x38 -getGroupId__14dEmitterBase_cFUs = .text:0x80028900; // type:function size:0x180 +getGroupId__14dJEffManager_cFUs = .text:0x80028900; // type:function size:0x180 setupEffects__14dJEffManager_cFv = .text:0x80028A80; // type:function size:0x434 removeEffManagers__14dJEffManager_cFv = .text:0x80028EC0; // type:function size:0xCC doCustomSkywardSwordThing__14dJEffManager_cFff = .text:0x80028F90; // type:function size:0xE0 @@ -953,7 +953,7 @@ vt_0x20__18dEmitterCallback_cFff = .text:0x80029070; // type:function size:0x4 execute__14dJEffManager_cFv = .text:0x80029080; // type:function size:0x1A8 draw__14dJEffManager_cFv = .text:0x80029230; // type:function size:0xB0 draw__14dJEffManager_cFPC11JPADrawInfoUl = .text:0x800292E0; // type:function size:0x18 -shouldBePaused__13EffectsStructFP7dBase_c = .text:0x80029300; // type:function size:0x94 +shouldBePaused__14dJEffManager_cFP7dBase_c = .text:0x80029300; // type:function size:0x94 createEffManagers__14dJEffManager_cFv = .text:0x800293A0; // type:function size:0x1EC __ct__17dMassObjEmitter_cFv = .text:0x80029590; // type:function size:0xC8 __dt__25dMassObjEmitterCallback_cFv = .text:0x80029660; // type:function size:0x90 @@ -969,7 +969,7 @@ createEffect__13EffectsStructFUsRC6mMtx_cPC8_GXColorPC8_GXColor = .text:0x800299 createContinuousEffect__13EffectsStructFUsRC7mVec3_cPC7mAng3_cPC7mVec3_cPC8_GXColorPC8_GXColor = .text:0x80029A10; // type:function size:0x54 createContinuousUIEffect__13EffectsStructFUsRC7mVec3_cPC7mAng3_cPC7mVec3_cPC8_GXColorPC8_GXColor = .text:0x80029A70; // type:function size:0x64 createContinuousEffect__13EffectsStructFUsRC6mMtx_cPC8_GXColorPC8_GXColor = .text:0x80029AE0; // type:function size:0x20 -fn_80029B00 = .text:0x80029B00; // type:function size:0xD8 +createMassObjEffect__14dJEffManager_cFUsRC7mVec3_cP12dAcObjBase_cPC6mColor = .text:0x80029B00; // type:function size:0xD8 loadColors__14dEmitterBase_cFP14JPABaseEmitterPC8_GXColorPC8_GXColorll = .text:0x80029BE0; // type:function size:0x43C removeFromActiveEmittersList__13EffectsStructFv = .text:0x8002A020; // type:function size:0xA4 createEffect__13EffectsStructFbUsRC7mVec3_cPC7mAng3_cPC7mVec3_cPC8_GXColorPC8_GXColor = .text:0x8002A0D0; // type:function size:0x15C @@ -1000,15 +1000,15 @@ drawOpa__18dParticleFogProc_cFv = .text:0x8002B670; // type:function size:0x4 draw__19JPAParticleCallBackFP14JPABaseEmitterP15JPABaseParticle = .text:0x8002B680; // type:function size:0x4 drawXlu__11dShpProc1_cFv = .text:0x8002B690; // type:function size:0x4 drawOpa__11dShpProc1_cFv = .text:0x8002B6A0; // type:function size:0x4 -__sinit_\d_effects_1_cpp = .text:0x8002B6B0; // type:function size:0x158 +__sinit_\d_emitter_cpp = .text:0x8002B6B0; // type:function size:0x158 scope:local __ct__21CommonEmitterCallbackFv = .text:0x8002B810; // type:function size:0x18 -__arraydtor$9497 = .text:0x8002B830; // type:function size:0x1C +__arraydtor$9497 = .text:0x8002B830; // type:function size:0x1C scope:local __ct__13dShpEmitter_cFv = .text:0x8002B850; // type:function size:0x78 -__arraydtor$9499 = .text:0x8002B8D0; // type:function size:0x1C +__arraydtor$9499 = .text:0x8002B8D0; // type:function size:0x1C scope:local __ct__18dParticleFogProc_cFv = .text:0x8002B8F0; // type:function size:0x44 -__arraydtor$9502 = .text:0x8002B940; // type:function size:0x1C +__arraydtor$9502 = .text:0x8002B940; // type:function size:0x1C scope:local __ct__11dEffect2D_cFv = .text:0x8002B960; // type:function size:0x18 -__arraydtor$9504 = .text:0x8002B980; // type:function size:0x1C +__arraydtor$9504 = .text:0x8002B980; // type:function size:0x1C scope:local fn_8002B9A0 = .text:0x8002B9A0; // type:function size:0x30 fn_8002B9D0 = .text:0x8002B9D0; // type:function size:0x10C fn_8002BAE0 = .text:0x8002BAE0; // type:function size:0x228 @@ -39892,7 +39892,7 @@ lbl_80575058 = .sbss:0x80575058; // type:object size:0x8 data:byte lbl_80575060 = .sbss:0x80575060; // type:object size:0x1 data:byte lbl_80575064 = .sbss:0x80575064; // type:object size:0x4 data:4byte sPInstance__21BlurAndPaletteManager = .sbss:0x80575068; // type:object size:0x8 data:4byte -sManagers__14dJEffManager_c = .sbss:0x80575070; // type:object size:0x4 data:4byte +sMassObjEmitters__14dJEffManager_c = .sbss:0x80575070; // type:object size:0x4 data:4byte CURRENT_EFFECT_MANAGER_INIT = .sbss:0x80575074; // type:object size:0x4 data:4byte ms_allocator__14dJEffManager_c = .sbss:0x80575078; // type:object size:0x4 data:4byte lbl_8057507C = .sbss:0x8057507C; // type:object size:0x1 data:byte @@ -44209,7 +44209,7 @@ PARTICLE_RESOURCE_ID_MAPPING_991_ = .sdata2:0x8057AB6E; // type:object size:0x2 PARTICLE_RESOURCE_ID_MAPPING_992_ = .sdata2:0x8057AB70; // type:object size:0x2 data:2byte lbl_8057AB72 = .sdata2:0x8057AB72; // type:object size:0x2 data:2byte lbl_8057AB74 = .sdata2:0x8057AB74; // type:object size:0x2 data:2byte -sNumberOfMgrs = .sdata2:0x8057AB78; // type:object size:0x8 data:4byte +sNumMassObjEmitters = .sdata2:0x8057AB78; // type:object size:0x8 data:4byte lbl_8057AB80 = .sdata2:0x8057AB80; // type:object size:0x8 data:byte lbl_8057AB88 = .sdata2:0x8057AB88; // type:object size:0x4 data:float lbl_8057AB8C = .sdata2:0x8057AB8C; // type:object size:0x4 data:float diff --git a/configure.py b/configure.py index 061881a6..da64f42f 100644 --- a/configure.py +++ b/configure.py @@ -389,7 +389,7 @@ config.libs = [ Object(NonMatching, "toBeSorted/d_unk_mdl_stuff_1.cpp"), Object(NonMatching, "toBeSorted/d_unk_mdl_stuff_2.cpp"), Object(NonMatching, "toBeSorted/blur_and_palette_manager.cpp"), - Object(NonMatching, "toBeSorted/d_effects_1.cpp"), + Object(NonMatching, "toBeSorted/d_emitter.cpp"), Object(NonMatching, "toBeSorted/d_effects_2.cpp"), Object(NonMatching, "toBeSorted/sound_info.cpp"), Object(NonMatching, "d/a/d_a_base.cpp"), diff --git a/include/d/a/d_a_item.h b/include/d/a/d_a_item.h index 983b701f..b897bdf1 100644 --- a/include/d/a/d_a_item.h +++ b/include/d/a/d_a_item.h @@ -17,7 +17,7 @@ #include "s/s_State.hpp" #include "toBeSorted/actor_event.h" #include "toBeSorted/dowsing_target.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" class dAcItem_0xB34 { public: diff --git a/include/d/a/obj/d_a_obj_arrow.h b/include/d/a/obj/d_a_obj_arrow.h index 8bedda03..6e2d1a17 100644 --- a/include/d/a/obj/d_a_obj_arrow.h +++ b/include/d/a/obj/d_a_obj_arrow.h @@ -9,7 +9,7 @@ #include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateID.hpp" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" class dAcArrow_c : public dAcObjBase_c { public: diff --git a/include/d/a/obj/d_a_obj_bomb.h b/include/d/a/obj/d_a_obj_bomb.h index e82b3743..c5cd71d2 100644 --- a/include/d/a/obj/d_a_obj_bomb.h +++ b/include/d/a/obj/d_a_obj_bomb.h @@ -13,7 +13,7 @@ #include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" #include "s/s_StateID.hpp" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" // This may need its own file and could be independent of a bomb class UnkBombColInfo : public cBgS_PolyInfo { diff --git a/include/d/a/obj/d_a_obj_dungeon_ship.h b/include/d/a/obj/d_a_obj_dungeon_ship.h index 18fbdb31..d8106eb8 100644 --- a/include/d/a/obj/d_a_obj_dungeon_ship.h +++ b/include/d/a/obj/d_a_obj_dungeon_ship.h @@ -13,7 +13,7 @@ #include "toBeSorted/actor_event.h" #include "toBeSorted/actor_on_rail.h" #include "toBeSorted/dowsing_target.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/time_proc.h" class dAcODungeonShip_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_seat_sword.h b/include/d/a/obj/d_a_obj_seat_sword.h index ec74ab45..cedbf9db 100644 --- a/include/d/a/obj/d_a_obj_seat_sword.h +++ b/include/d/a/obj/d_a_obj_seat_sword.h @@ -17,7 +17,7 @@ #include "s/s_StateMgr.hpp" #include "toBeSorted/actor_event.h" #include "toBeSorted/attention.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" class dAcOSeatSword_c : public dAcObjBase_c { public: diff --git a/include/d/a/obj/d_a_obj_tower_gearD101.h b/include/d/a/obj/d_a_obj_tower_gearD101.h index d77b665a..bcc98e7d 100644 --- a/include/d/a/obj/d_a_obj_tower_gearD101.h +++ b/include/d/a/obj/d_a_obj_tower_gearD101.h @@ -9,7 +9,7 @@ #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" /** * A callback implementation that controls the button node in the switch model. diff --git a/include/d/a/obj/d_a_obj_tower_hand_D101.h b/include/d/a/obj/d_a_obj_tower_hand_D101.h index 3dcca5fc..ae945915 100644 --- a/include/d/a/obj/d_a_obj_tower_hand_D101.h +++ b/include/d/a/obj/d_a_obj_tower_hand_D101.h @@ -13,7 +13,7 @@ #include "s/s_State.hpp" #include "s/s_StateMgr.hpp" #include "toBeSorted/actor_event.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" class dAcOTowerHandD101_c : public dAcObjBase_c { diff --git a/include/d/a/obj/d_a_obj_triforce.h b/include/d/a/obj/d_a_obj_triforce.h index ac134bef..eefc90fe 100644 --- a/include/d/a/obj/d_a_obj_triforce.h +++ b/include/d/a/obj/d_a_obj_triforce.h @@ -8,7 +8,7 @@ #include "m/m3d/m_smdl.h" #include "m/m_angle.h" #include "nw4r/g3d/res/g3d_resfile.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" class dAcOtriforce_c : public dAcObjBase_c { public: diff --git a/include/d/a/obj/d_a_obj_tubo.h b/include/d/a/obj/d_a_obj_tubo.h index 4e8e8c27..fe8fed49 100644 --- a/include/d/a/obj/d_a_obj_tubo.h +++ b/include/d/a/obj/d_a_obj_tubo.h @@ -15,7 +15,7 @@ #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_State.hpp" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" class dAcOtubo_c : public dAcObjBase_c { public: diff --git a/include/d/d_cs_game.h b/include/d/d_cs_game.h index a090bf97..4050fddf 100644 --- a/include/d/d_cs_game.h +++ b/include/d/d_cs_game.h @@ -9,7 +9,7 @@ #include "s/s_FStateID.hpp" #include "s/s_State.hpp" #include "s/s_StateID.hpp" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" struct CsGameConfigMaybe { CsGameConfigMaybe(); diff --git a/include/d/lyt/meter/d_lyt_meter_item_select.h b/include/d/lyt/meter/d_lyt_meter_item_select.h index ae097d41..d64e7eae 100644 --- a/include/d/lyt/meter/d_lyt_meter_item_select.h +++ b/include/d/lyt/meter/d_lyt_meter_item_select.h @@ -8,7 +8,7 @@ #include "d/lyt/d_window.h" #include "nw4r/lyt/lyt_pane.h" #include "s/s_State.hpp" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" class dLytMeterItemSelectIcon_c { public: diff --git a/include/d/lyt/meter/d_lyt_meter_minus_btn.h b/include/d/lyt/meter/d_lyt_meter_minus_btn.h index 7478aea3..30fb1830 100644 --- a/include/d/lyt/meter/d_lyt_meter_minus_btn.h +++ b/include/d/lyt/meter/d_lyt_meter_minus_btn.h @@ -7,7 +7,7 @@ #include "d/lyt/d_window.h" #include "nw4r/lyt/lyt_pane.h" #include "s/s_State.hpp" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" // At 0x8, [8], size 0x48 class dLytMeterMinusBtnMenuIcon_c { diff --git a/include/toBeSorted/attention.h b/include/toBeSorted/attention.h index 69a9044b..96a8ed3e 100644 --- a/include/toBeSorted/attention.h +++ b/include/toBeSorted/attention.h @@ -8,7 +8,7 @@ #include "m/m3d/m_anmtexpat.h" #include "m/m3d/m_smdl.h" #include "m/m_allocator.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/raii_ptr.h" static const u32 OFF = 'off '; diff --git a/include/toBeSorted/effects_struct.h b/include/toBeSorted/d_emitter.h similarity index 87% rename from include/toBeSorted/effects_struct.h rename to include/toBeSorted/d_emitter.h index d9c8365b..56026645 100644 --- a/include/toBeSorted/effects_struct.h +++ b/include/toBeSorted/d_emitter.h @@ -13,6 +13,7 @@ #include "m/m_color.h" #include "m/m_mtx.h" #include "m/m_vec.h" +#include "rvl/GX/GXTypes.h" #include "toBeSorted/d_d3d.h" #include "toBeSorted/d_unk_mdl_stuff_2.h" #include "toBeSorted/tlist.h" @@ -43,7 +44,6 @@ protected: void deactivateEmitters(); void stopCalcEmitters(); void playCalcEmitters(); - static s32 getGroupId(u16); static void loadColors(JPABaseEmitter *emitter, const GXColor *c1, const GXColor *c2, s32 idx1, s32 idx2); void setEmitterCallback(dEmitterCallback_c *cb); @@ -114,12 +114,24 @@ public: // TODO maybe reconsider the naming here - the observation here is that a "continous" effect // is typically called every frame, while the others are one-shot calls - bool createContinuousEffect(u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2); - bool createContinuousUIEffect(u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2); + bool createContinuousEffect( + u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, + const GXColor *c2 + ); + bool createContinuousUIEffect( + u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, + const GXColor *c2 + ); bool createContinuousEffect(u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2); - bool createEffect(u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2); - bool createUIEffect(u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2); + bool createEffect( + u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, + const GXColor *c2 + ); + bool createUIEffect( + u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, + const GXColor *c2 + ); bool createEffect(u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2); bool hasEmitters() const { @@ -155,8 +167,6 @@ protected: const GXColor *c2 ); bool createEffect(bool bFlags, u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2); - - static bool shouldBePaused(dBase_c *owner); bool getOwnerPolyAttrs(s32 *pOut1, s32 *pOut2); public: @@ -335,10 +345,17 @@ public: virtual void executeAfter(JPABaseEmitter *) override; void execute(); + void clear(); + bool start(const mVec3_c &v1, dAcObjBase_c *owner); - /* 0x010 */ mVec3_c field_0x010[0x32]; - /* 0x268 */ mVec3_c field_0x268[0x32]; - /* 0x4C0 */ u8 _0x4C0[0x650 - 0x4C0]; +private: + /* 0x010 */ mVec3_c field_0x010[50]; + /* 0x268 */ mVec3_c field_0x268[50]; + /* 0x4C0 */ dAcObjBase_c *field_0x4C0[50]; + /* 0x588 */ dAcObjBase_c *field_0x588[50]; + /* 0x650 */ mColor field_0x650; + /* 0x654 */ u32 field_0x654; + /* 0x658 */ u32 field_0x658; // TODO unclear structure boundary }; @@ -350,20 +367,36 @@ public: } void create(u16 resourceId); + bool start(const mVec3_c &v1, dAcObjBase_c *owner) { + return mCallback.start(v1, owner); + } void remove(); mColor getField_0x67C() const { return field_0x67C; } + void setField_0x67C(GXColor clr) { + field_0x67C.r = clr.r; + field_0x67C.g = clr.g; + field_0x67C.b = clr.b; + field_0x67C.a = clr.a; + } + + + void setField_0x67C(mColor clr) { + field_0x67C.r = clr.r; + field_0x67C.g = clr.g; + field_0x67C.b = clr.b; + field_0x67C.a = clr.a; + } + void execute() { mCallback.execute(); } private: /* 0x020 */ dMassObjEmitterCallback_c mCallback; - /* 0x670 */ mColor field_0x670; - /* 0x674 */ u8 _0x674[0x67C - 0x674]; /* 0x67C */ mColor field_0x67C; }; @@ -388,6 +421,12 @@ public: u16 effectResourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2, s32 idx1, s32 idx2 ); + // "mass obj" = grass, fire + static bool createMassObjEffect(u16 effectResourceId, const mVec3_c &v1, dAcObjBase_c *owner, const mColor *color); + + static s32 getGroupId(u16); + static bool shouldBePaused(dBase_c *owner); + enum Fx_e { TsuboA, TsuboB, @@ -456,7 +495,9 @@ private: ); static mHeapAllocator_c *ms_allocator; - static dMassObjEmitter_c *sManagers; + static dMassObjEmitter_c *sMassObjEmitters; + static u32 sInts[]; + static u32 sInts2[]; }; #endif diff --git a/src/REL/d/a/d_a_t_wood_area.cpp b/src/REL/d/a/d_a_t_wood_area.cpp index 88ef72d8..044826bf 100644 --- a/src/REL/d/a/d_a_t_wood_area.cpp +++ b/src/REL/d/a/d_a_t_wood_area.cpp @@ -2,7 +2,7 @@ #include "common.h" #include "d/a/d_a_player.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" const f32 dAcTWoodArea_c::scaleX = 100.0f; const f32 dAcTWoodArea_c::scaleY = 100.0f; diff --git a/src/REL/d/a/obj/d_a_obj_tubo.cpp b/src/REL/d/a/obj/d_a_obj_tubo.cpp index 16361da0..a21885eb 100644 --- a/src/REL/d/a/obj/d_a_obj_tubo.cpp +++ b/src/REL/d/a/obj/d_a_obj_tubo.cpp @@ -31,7 +31,7 @@ #include "s/s_Math.h" #include "toBeSorted/attention.h" #include "toBeSorted/blur_and_palette_manager.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/event_manager.h" #include "toBeSorted/small_sound_mgr.h" #include "toBeSorted/special_item_drop_mgr.h" diff --git a/src/REL/d/a/obj/d_a_obj_tumble_weed.cpp b/src/REL/d/a/obj/d_a_obj_tumble_weed.cpp index 110ef752..367f48e2 100644 --- a/src/REL/d/a/obj/d_a_obj_tumble_weed.cpp +++ b/src/REL/d/a/obj/d_a_obj_tumble_weed.cpp @@ -19,7 +19,7 @@ #include "s/s_Math.h" #include "toBeSorted/blur_and_palette_manager.h" #include "toBeSorted/dowsing_target.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/small_sound_mgr.h" void float_ordering() { diff --git a/src/d/a/d_a_insect.cpp b/src/d/a/d_a_insect.cpp index b7dc69da..56c29de0 100644 --- a/src/d/a/d_a_insect.cpp +++ b/src/d/a/d_a_insect.cpp @@ -14,7 +14,7 @@ #include "m/m_mtx.h" #include "m/m_vec.h" #include "toBeSorted/attention.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/small_sound_mgr.h" extern "C" const u16 PARTICLE_RESOURCE_ID_MAPPING_394_; diff --git a/src/d/a/obj/d_a_obj_switch.cpp b/src/d/a/obj/d_a_obj_switch.cpp index 8103d7a7..3bedebf6 100644 --- a/src/d/a/obj/d_a_obj_switch.cpp +++ b/src/d/a/obj/d_a_obj_switch.cpp @@ -6,7 +6,7 @@ #include "d/flag/sceneflag_manager.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "s/s_Math.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/small_sound_mgr.h" SPECIAL_ACTOR_PROFILE(OBJ_SW, dAcOsw_c, fProfile::OBJ_SW, 0x12B, 0, 0x1002); diff --git a/src/d/a/obj/d_a_obj_water_spout.cpp b/src/d/a/obj/d_a_obj_water_spout.cpp index 32f2f4ac..b86b6f09 100644 --- a/src/d/a/obj/d_a_obj_water_spout.cpp +++ b/src/d/a/obj/d_a_obj_water_spout.cpp @@ -9,7 +9,7 @@ #include "nw4r/g3d/res/g3d_resfile.h" #include "nw4r/g3d/res/g3d_resmdl.h" #include "s/s_State.hpp" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" SPECIAL_ACTOR_PROFILE(OBJ_WATER_SPOUT, dAcOwaterSpout_c, fProfile::OBJ_WATER_SPOUT, 0x1DA, 0, 6); diff --git a/src/d/lyt/meter/d_lyt_meter_dowsing.cpp b/src/d/lyt/meter/d_lyt_meter_dowsing.cpp index 736cdc1b..f7850755 100644 --- a/src/d/lyt/meter/d_lyt_meter_dowsing.cpp +++ b/src/d/lyt/meter/d_lyt_meter_dowsing.cpp @@ -15,7 +15,7 @@ #include "nw4r/math/math_types.h" #include "sized_string.h" #include "toBeSorted/dowsing_target.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/file_manager.h" #include "toBeSorted/small_sound_mgr.h" diff --git a/src/d/lyt/meter/d_lyt_meter_heart.cpp b/src/d/lyt/meter/d_lyt_meter_heart.cpp index 6b11a4c0..7ee24c48 100644 --- a/src/d/lyt/meter/d_lyt_meter_heart.cpp +++ b/src/d/lyt/meter/d_lyt_meter_heart.cpp @@ -6,7 +6,7 @@ #include "d/lyt/d2d.h" #include "d/lyt/d_lyt_game_over.h" #include "nw4r/math/math_types.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/event_manager.h" #include "toBeSorted/file_manager.h" #include "toBeSorted/small_sound_mgr.h" diff --git a/src/d/lyt/meter/d_lyt_meter_item_select.cpp b/src/d/lyt/meter/d_lyt_meter_item_select.cpp index 1eaae5ee..7055a566 100644 --- a/src/d/lyt/meter/d_lyt_meter_item_select.cpp +++ b/src/d/lyt/meter/d_lyt_meter_item_select.cpp @@ -18,7 +18,7 @@ #include "nw4r/math/math_types.h" #include "s/s_Math.h" #include "sized_string.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/event_manager.h" #include "toBeSorted/minigame_mgr.h" #include "toBeSorted/small_sound_mgr.h" diff --git a/src/d/lyt/meter/d_lyt_meter_timer.cpp b/src/d/lyt/meter/d_lyt_meter_timer.cpp index a67f92b9..085479cf 100644 --- a/src/d/lyt/meter/d_lyt_meter_timer.cpp +++ b/src/d/lyt/meter/d_lyt_meter_timer.cpp @@ -14,7 +14,7 @@ #include "m/m_vec.h" #include "nw4r/lyt/lyt_pane.h" #include "nw4r/math/math_types.h" -#include "toBeSorted/effects_struct.h" +#include "toBeSorted/d_emitter.h" #include "toBeSorted/event_manager.h" #include "toBeSorted/small_sound_mgr.h" diff --git a/src/toBeSorted/d_effects_1.cpp b/src/toBeSorted/d_emitter.cpp similarity index 86% rename from src/toBeSorted/d_effects_1.cpp rename to src/toBeSorted/d_emitter.cpp index c4d37d08..e1e63501 100644 --- a/src/toBeSorted/d_effects_1.cpp +++ b/src/toBeSorted/d_emitter.cpp @@ -2,9 +2,12 @@ // vtable order #include "JSystem/JParticle/JPAEmitter.h" #include "JSystem/JParticle/JPAParticle.h" +#include "rvl/GX/GXTypes.h" #include "toBeSorted/d_d3d.h" // clang-format on +#include "toBeSorted/d_emitter.h" + #include "JSystem/JParticle/JPADrawInfo.h" #include "JSystem/JParticle/JPAEmitter.h" #include "c/c_math.h" @@ -36,7 +39,6 @@ #include "toBeSorted/blur_and_palette_manager.h" #include "toBeSorted/d_d3d.h" #include "toBeSorted/d_particle.h" -#include "toBeSorted/effects_struct.h" #include "toBeSorted/event_manager.h" #include "toBeSorted/lyt_related_floats.h" @@ -129,7 +131,9 @@ bool dEmitterBase_c::createEmitters( JPABaseEmitter *head = nullptr; JPABaseEmitter *last; for (; iter != 0xFFFF; iter = dParticle::mgr_c::GetInstance()->getJpnData(iter)) { - last = dParticle::mgr_c::GetInstance()->createEmitter(iter, getGroupId(iter), position, rot, scale); + last = dParticle::mgr_c::GetInstance()->createEmitter( + iter, dJEffManager_c::getGroupId(iter), position, rot, scale + ); if (last != nullptr) { if (head != nullptr) { head->setUserWork(reinterpret_cast(last)); @@ -375,7 +379,7 @@ void EffectsStruct::execute() { if (mpOwner != nullptr && (mpOwner->delete_request || mpOwner->lifecycle_state == fBase_c::TO_BE_DELETED)) { mpOwner = nullptr; } - if (shouldBePaused(mpOwner)) { + if (dJEffManager_c::shouldBePaused(mpOwner)) { if (!checkFlag(EMITTER_0x10)) { stopCalcEmitters(); if (mpOwner != nullptr && !mpOwner->isBasePropertyFlag(0x100)) { @@ -484,7 +488,95 @@ void dEffect2D_c::create(u32 groupId, u8 prio) { setPriority(prio); } -void dMassObjEmitterCallback_c::executeAfter(JPABaseEmitter *) {} +bool dMassObjEmitterCallback_c::start(const mVec3_c &v1, dAcObjBase_c *owner) { + if (field_0x658 >= 50) { + return false; + } + + field_0x010[field_0x658] = v1; + field_0x4C0[field_0x658] = owner; + + field_0x658++; + return true; +} + +void dMassObjEmitterCallback_c::executeAfter(JPABaseEmitter *emitter) { + s32 createNumber = emitter->getCurrentCreateNumber(); + if (createNumber > 0) { + s32 i = 0; + mVec3_c translate; + emitter->getLocalTranslation(translate); + if (field_0x654 != 0) { + for (; i < field_0x654; i++) { + mVec3_c newTranslate = mVec3_c(field_0x268[i] + translate); + emitter->setGlobalTranslation(newTranslate); + for (s32 j = 0; j < createNumber; j++) { + JPABaseParticle *p = emitter->createParticle(); + if (p != nullptr) { + p->setOffsetPosition(newTranslate); + } + } + } + } + } +} + +void dMassObjEmitterCallback_c::execute() { + for (s32 i = field_0x654 - 1; i >= 0; i--) { + if (field_0x588[i] != nullptr) { + if (!dJEffManager_c::shouldBePaused(field_0x588[i]) || field_0x588[i]->delete_request || + field_0x588[i]->lifecycle_state == fBase_c::TO_BE_DELETED) { + if (field_0x654 != 0 && i != field_0x654 - 1) { + field_0x588[i] = field_0x588[field_0x654 - 1]; + field_0x268[i] = field_0x268[field_0x654 - 1]; + } else { + field_0x588[i] = nullptr; + } + field_0x654--; + } + } else { + field_0x654--; + } + } + if (field_0x658 + field_0x654 > 50) { + field_0x658 = 50 - field_0x654; + } + + for (u32 i = 0; i < field_0x658; i++) { + field_0x588[field_0x654] = field_0x4C0[i]; + field_0x268[field_0x654] = field_0x010[i]; + field_0x654++; + } + field_0x658 = 0; +} + +#pragma opt_unroll_loops off +void dMassObjEmitterCallback_c::clear() { + // TODO: this unrolls the entire loops, + // but the original code uses an unroll + // factor of 10 (5 iterations). 2D arrays + // work here but are probably fake. + field_0x654 = 0; + for (u32 i = 0; i < 50; i++) { + field_0x588[i] = nullptr; + } + field_0x658 = 0; + for (u32 i = 0; i < 50; i++) { + field_0x4C0[i] = nullptr; + } +} +#pragma opt_unroll_loops reset + +void dMassObjEmitter_c::create(u16 resourceId) { + setEmitterCallback(&mCallback); + if (createEmitters(resourceId, mVec3_c::Zero, nullptr, nullptr, nullptr, nullptr, 0, 0)) { + for (JPABaseEmitter *emitter = mpEmitterHead; emitter != nullptr; emitter = GetNextEmitter(emitter)) { + emitter->setStatus(JPAEmtrStts_Immortal); + emitter->setStatus(JPAEmtrStts_StopEmit); + } + mCallback.clear(); + } +} void dShpEmitterProc::doDraw() { mMtx_c viewMtx; @@ -611,16 +703,45 @@ void dMassObjEmitter_c::remove() { mpEmitterHead = nullptr; } -extern "C" u32 sNumberOfMgrs; // should be const? +extern "C" u32 sNumMassObjEmitters; // should be const? extern "C" const u16 PARTICLE_RESOURCE_ID_MAPPING_119_; extern "C" dMassObjEmitter_c *CURRENT_EFFECT_MANAGER_INIT; +s32 dJEffManager_c::getGroupId(u16 resourceId) { + u32 mask = dParticle::mgr_c::GetInstance()->getResUserWork(resourceId); + s32 bit = 1; + for (int i = 0; i < 10; i++) { + if ((mask & (1 << i)) != 0) { + bit = i; + break; + } + } + + int i = sInts[bit]; + // TODO explain this + if ((mask & 0x8000) != 0) { + if (i == 3) { + i = 2; + } else if (i == 5) { + i = 4; + } else if (i == 7) { + i = 6; + } else if (i == 1) { + i = 0; + } else if (i == 11) { + i = 10; + } + } + + return i; +} + // various grasses being cut extern const u16 sEffectResourceIds[]; void dJEffManager_c::setupEffects() { - for (s32 idx = 0; idx < sNumberOfMgrs; idx++) { - sManagers[idx].create(sEffectResourceIds[idx]); + for (s32 idx = 0; idx < sNumMassObjEmitters; idx++) { + sMassObjEmitters[idx].create(sEffectResourceIds[idx]); } sShpEmitters[TsuboA].init("FX_TsuboA", "Tubo", false); @@ -672,9 +793,12 @@ void dJEffManager_c::setupEffects() { sShpEmitters[BWallF210].init("FX_BWallF210", "BWallF210", true); } +u32 dJEffManager_c::sInts[] = {0x28, 0x29, 0x87, 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x91, 0x86, 0x1, 0x2}; +u32 dJEffManager_c::sInts2[] = {0x2, 0x87, 0x8B}; + void dJEffManager_c::removeEffManagers() { - for (s32 i = 0; i < sNumberOfMgrs; i++) { - sManagers[i].remove(); + for (s32 i = 0; i < sNumMassObjEmitters; i++) { + sMassObjEmitters[i].remove(); } // TODO @@ -706,39 +830,6 @@ void dJEffManager_c::doCustomSkywardSwordThing(f32 x, f32 y) { } } -// TODO explain this -static u32 sInts[] = {0x28, 0x29, 0x87, 0x88, 0x89, 0x8A, 0x8C, 0x8D, 0x91, 0x86, 0x1, 0x2}; -static u32 sInts2[] = {0x2, 0x87, 0x8B}; - -s32 dEmitterBase_c::getGroupId(u16 resourceId) { - u32 mask = dParticle::mgr_c::GetInstance()->getResUserWork(resourceId); - s32 bit = 1; - for (int i = 0; i < 10; i++) { - if ((mask & (1 << i)) != 0) { - bit = i; - break; - } - } - - int i = sInts[bit]; - // TODO explain this - if ((mask & 0x8000) != 0) { - if (i == 3) { - i = 2; - } else if (i == 5) { - i = 4; - } else if (i == 7) { - i = 6; - } else if (i == 1) { - i = 0; - } else if (i == 11) { - i = 10; - } - } - - return i; -} - void dJEffManager_c::execute() { for (EffectsList::Iterator it = sPlayingEffectsList.GetBeginIter(); it != sPlayingEffectsList.GetEndIter();) { EffectsList::Iterator itNext = it; @@ -763,10 +854,10 @@ void dJEffManager_c::execute() { CURRENT_EFFECT_MANAGER_INIT->setGlobalAlpha(dStageMgr_c::GetInstance()->getGlobalAlpha()); } - for (s32 i = 0; i < sNumberOfMgrs; i++) { - mColor c = sManagers[i].getField_0x67C(); - sManagers[i].loadColors(&c, nullptr, 0, 0); - sManagers[i].execute(); + for (s32 i = 0; i < sNumMassObjEmitters; i++) { + mColor c = sMassObjEmitters[i].getField_0x67C(); + sMassObjEmitters[i].loadColors(&c, nullptr, 0, 0); + sMassObjEmitters[i].execute(); } if ((dBase_c::s_ExecuteControlFlags & 0x6F9) == 0) { @@ -796,22 +887,26 @@ void dJEffManager_c::draw() { } } -bool EffectsStruct::shouldBePaused(dBase_c *owner) { +bool dJEffManager_c::shouldBePaused(dBase_c *owner) { return owner != nullptr && !owner->isBasePropertyFlag(dBase_c::BASE_PROP_0x4) && (EventManager::isInEvent() || owner->isProcControlFlag(fBase_c::DISABLE_EXECUTE) || // TODO execute control flags (owner->s_ExecuteControlFlags & 0x6fb)); } +void dJEffManager_c::draw(const JPADrawInfo *info, u32 groupId) { + dParticle::mgr_c::GetInstance()->draw(info, groupId); +} + bool dJEffManager_c::createEffManagers() { EGG::Heap *heap = dHeap::work1Heap.heap; ms_allocator = new (heap, 4) mHeapAllocator_c(); - sManagers = new (heap, 4) dMassObjEmitter_c[sNumberOfMgrs]; + sMassObjEmitters = new (heap, 4) dMassObjEmitter_c[sNumMassObjEmitters]; - for (s32 idx = 0; idx < sNumberOfMgrs; idx++) { + for (s32 idx = 0; idx < sNumMassObjEmitters; idx++) { // TODO explain this if (sEffectResourceIds[idx] == PARTICLE_RESOURCE_ID_MAPPING_119_) { - CURRENT_EFFECT_MANAGER_INIT = &sManagers[idx]; + CURRENT_EFFECT_MANAGER_INIT = &sMassObjEmitters[idx]; break; } } @@ -880,11 +975,15 @@ dEmitterBase_c *dJEffManager_c::spawnEffect( return spawnEffectInternal(effectResourceId, transform, c1, c2, idx1, idx2); } -bool EffectsStruct::createEffect(u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2) { +bool EffectsStruct::createEffect( + u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2 +) { return createEffect(true, resourceId, pos, rot, scale, c1, c2); } -bool EffectsStruct::createUIEffect(u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2) { +bool EffectsStruct::createUIEffect( + u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2 +) { mVec3_c adjustedPosition(pos.x * getlbl_80571C50(), pos.y, pos.z); return createEffect(true, resourceId, adjustedPosition, rot, scale, c1, c2); } @@ -893,19 +992,42 @@ bool EffectsStruct::createEffect(u16 resourceId, const mMtx_c &transform, const return createEffect(true, resourceId, transform, c1, c2); } -bool EffectsStruct::createContinuousEffect(u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2) { +bool EffectsStruct::createContinuousEffect( + u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2 +) { return createEffect(false, resourceId, pos, rot, scale, c1, c2); } -bool EffectsStruct::createContinuousUIEffect(u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2) { +bool EffectsStruct::createContinuousUIEffect( + u16 resourceId, const mVec3_c &pos, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, const GXColor *c2 +) { mVec3_c adjustedPosition(pos.x * getlbl_80571C50(), pos.y, pos.z); return createEffect(false, resourceId, adjustedPosition, rot, scale, c1, c2); } -bool EffectsStruct::createContinuousEffect(u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2) { +bool EffectsStruct::createContinuousEffect( + u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2 +) { return createEffect(false, resourceId, transform, c1, c2); } +bool dJEffManager_c::createMassObjEffect( + u16 effectResourceId, const mVec3_c &v1, dAcObjBase_c *owner, const mColor *color +) { + for (s32 i = 0; i < sNumMassObjEmitters; i++) { + if (effectResourceId == sEffectResourceIds[i]) { + if (color != nullptr) { + sMassObjEmitters[i].setField_0x67C(*color); + } else { + sMassObjEmitters[i].setField_0x67C(mColor(0xFF, 0xFF, 0xFF, 0xFF)); + } + return sMassObjEmitters[i].start(v1, owner); + } + } + + return false; +} + void dEmitterBase_c::loadColors( JPABaseEmitter *emitter, const GXColor *color1, const GXColor *color2, s32 plltIdx1, s32 plltIdx2 ) { @@ -1096,10 +1218,10 @@ void dWaterEffect_c::execute(f32 water, f32 ground) { } if (mIsInWater && getActorCeilPos(ac) > water) { - // Spawn effect upon leaving water + // Spawn effect while in water mVec3_c pos(ac->position.x, water, ac->position.z); mVec3_c scale(mScale, mScale, mScale); - mEff.createEffect(PARTICLE_RESOURCE_ID_MAPPING_127_, pos, nullptr, &scale, nullptr, nullptr); + mEff.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_127_, pos, nullptr, &scale, nullptr, nullptr); f32 rate = nw4r::math::FAbs(ac->forwardSpeed) * 0.02f; rate = rate > 0.95f ? 0.95f : rate; mEff.setRate(rate + 0.05f);