diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 8ff37c4d..c6f0c7b8 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -91,7 +91,7 @@ toBeSorted/blur_and_palette_manager.cpp: toBeSorted/d_effects_1.cpp: .text start:0x800268B0 end:0x8002B99C align:16 .ctors start:0x804DB660 end:0x804DB664 - .data start:0x80500E98 end:0x80501500 + .data start:0x80500E98 end:0x805014C0 .sdata start:0x805718A8 end:0x80571920 .sdata2 start:0x80576C18 end:0x80576C68 .bss start:0x80594FA0 end:0x80597020 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 6a13be60..174957ca 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -929,7 +929,7 @@ execute__13EffectsStructFv = .text:0x80027930; // type:function size:0x130 getOwnerPolyAttrs__13EffectsStructFPlPl = .text:0x80027A60; // type:function size:0x44 realizeAlpha__13EffectsStructFv = .text:0x80027AB0; // type:function size:0x6C setFading__13EffectsStructFUc = .text:0x80027B20; // type:function size:0x24 -create__18dParticleFogProc_cFlllP16mHeapAllocator_c = .text:0x80027B50; // type:function size:0x80 +create__18dParticleFogProc_cFUlllP16mHeapAllocator_c = .text:0x80027B50; // type:function size:0x80 doDraw__18dParticleFogProc_cFv = .text:0x80027BD0; // type:function size:0xD8 draw__11dEffect2D_cFv = .text:0x80027CB0; // type:function size:0x100 create__11dEffect2D_cFUlUc = .text:0x80027DB0; // type:function size:0xC @@ -948,8 +948,8 @@ remove__17dMassObjEmitter_cFv = .text:0x800288C0; // type:function size:0x38 getGroupId__14dEmitterBase_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 -fn_80028F90 = .text:0x80028F90; // type:function size:0xE0 -vt_0x20__18dEmitterCallback_cFP14JPABaseEmitter = .text:0x80029070; // type:function size:0x4 +doCustomSkywardSwordThing__14dJEffManager_cFff = .text:0x80028F90; // type:function size:0xE0 +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 @@ -963,12 +963,12 @@ spawnEffectInternal__14dJEffManager_cFUsRC6mMtx_cPC8_GXColorPC8_GXColorll = .tex spawnEffect__14dJEffManager_cFUsRC7mVec3_cPC7mAng3_cPC7mVec3_cPC8_GXColorPC8_GXColorll = .text:0x800298B0; // type:function size:0x4 spawnUIEffect__14dJEffManager_cFUsRC7mVec3_cPC7mAng3_cPC7mVec3_cPC8_GXColorPC8_GXColor = .text:0x800298C0; // type:function size:0x4C spawnEffect__14dJEffManager_cFUsRC6mMtx_cPC8_GXColorPC8_GXColorll = .text:0x80029910; // type:function size:0x4 -fn_80029920 = .text:0x80029920; // type:function size:0x54 -fn_80029980__13EffectsStructFUsP7mVec3_cP7mAng3_cP7mVec3_cPvPv = .text:0x80029980; // type:function size:0x64 -fn_800299F0__13EffectsStructFUsP6mMtx_cPvPv = .text:0x800299F0; // type:function size:0x20 -fn_80029A10__13EffectsStructFUsP7mVec3_cP7mAng3_cP7mVec3_cPvPv = .text:0x80029A10; // type:function size:0x54 -fn_80029A70__13EffectsStructFUsP7mVec3_cP7mAng3_cP7mVec3_cPvPv = .text:0x80029A70; // type:function size:0x64 -fn_80029AE0 = .text:0x80029AE0; // type:function size:0x20 +createEffect__13EffectsStructFUsRC7mVec3_cPC7mAng3_cPC7mVec3_cPC8_GXColorPC8_GXColor = .text:0x80029920; // type:function size:0x54 +createUIEffect__13EffectsStructFUsRC7mVec3_cPC7mAng3_cPC7mVec3_cPC8_GXColorPC8_GXColor = .text:0x80029980; // type:function size:0x64 +createEffect__13EffectsStructFUsRC6mMtx_cPC8_GXColorPC8_GXColor = .text:0x800299F0; // type:function size:0x20 +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 loadColors__14dEmitterBase_cFP14JPABaseEmitterPC8_GXColorPC8_GXColorll = .text:0x80029BE0; // type:function size:0x43C removeFromActiveEmittersList__13EffectsStructFv = .text:0x8002A020; // type:function size:0xA4 @@ -29910,7 +29910,7 @@ __vt__21CommonEmitterCallback = .data:0x8050131C; // type:object size:0x1C __vt__13dShpEmitter_c = .data:0x80501338; // type:object size:0x14 __vt__15dShpEmitterProc = .data:0x8050134C; // type:object size:0x2C __vt__11dEffect2D_c = .data:0x80501378; // type:object size:0x10 -__vt__18dParticleFogProc_c = .data:0x80501388; // type:object size:0x30 +__vt__18dParticleFogProc_c = .data:0x80501388; // type:object size:0x2C __vt__19dParticleCallback_c = .data:0x805013B8; // type:object size:0x18 __vt__18dEmitterCallback_c = .data:0x805013D0; // type:object size:0x24 __vt__13EffectsStruct = .data:0x805013F4; // type:object size:0xC diff --git a/include/toBeSorted/effects_struct.h b/include/toBeSorted/effects_struct.h index a61d7dab..d9c8365b 100644 --- a/include/toBeSorted/effects_struct.h +++ b/include/toBeSorted/effects_struct.h @@ -5,7 +5,6 @@ #include "JSystem/JParticle/JPAEmitter.h" #include "JSystem/JParticle/JPAParticle.h" #include "common.h" -#include "d/a/d_a_base.h" #include "d/a/obj/d_a_obj_base.h" #include "d/d_base.h" #include "m/m2d.h" @@ -36,6 +35,10 @@ public: const GXColor *c2, s32 idx1, s32 idx2 ); + dEmitterCallback_c *getEmitterCallback() const { + return mpEmitterCallback; + } + protected: void deactivateEmitters(); void stopCalcEmitters(); @@ -108,16 +111,25 @@ public: void setFading(u8 lifetime); void remove(bool bForceDeleteEmitters); - void fn_80029920(u16 effect, mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, void *, void *); - void fn_80029980(u16 effect, mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, void *, void *); - void fn_800299F0(u16 effect, mMtx_c *mtx, void *, void *); - void fn_80029A10(u16 effect, mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, void *, void *); - void fn_80029A70(u16 effect, mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, void *, void *); + + // 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 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 mMtx_c &transform, const GXColor *c1, const GXColor *c2); bool hasEmitters() const { return mpEmitterHead != 0; } + u8 getGroupId() const { + return mpEmitterHead->getGroupID(); + } + bool checkFlag(u32 flag) const { return mFlags & flag; } @@ -201,7 +213,7 @@ class dEmitterCallback_c : public JPAEmitterCallBack { public: virtual ~dEmitterCallback_c(); virtual void create(JPABaseEmitter *) {} - virtual void vt_0x20(JPABaseEmitter *) {} + virtual void vt_0x20(f32, f32) {} void remove(dEmitterBase_c *emitter); @@ -225,6 +237,7 @@ public: class dParticleFogProc_c : public d3d::UnkProc { public: + dParticleFogProc_c() {} virtual ~dParticleFogProc_c() {} virtual void drawOpa() override { doDraw(); @@ -361,6 +374,7 @@ public: static void draw(const JPADrawInfo *info, u32 groupId); static void draw(); static void execute(); + static void doCustomSkywardSwordThing(f32 x, f32 y); static void setupEffects(); static dEmitterBase_c *spawnEffect( u16 effectResourceId, const mVec3_c &position, const mAng3_c *rot, const mVec3_c *scale, const GXColor *c1, diff --git a/src/REL/d/a/obj/d_a_obj_dungeon_ship.cpp b/src/REL/d/a/obj/d_a_obj_dungeon_ship.cpp index e49d456d..9e16849e 100644 --- a/src/REL/d/a/obj/d_a_obj_dungeon_ship.cpp +++ b/src/REL/d/a/obj/d_a_obj_dungeon_ship.cpp @@ -196,7 +196,7 @@ int dAcODungeonShip_c::actorExecute() { mAnmMatClr.play(); mMdl.calc(false); if (field_0x8D8) { - mEffects[0].fn_80029A10(PARTICLE_RESOURCE_ID_MAPPING_682_, &position, &rotation, nullptr, nullptr, nullptr); + mEffects[0].createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_682_, position, &rotation, nullptr, nullptr, nullptr); } if (field_0x8D9) { @@ -205,7 +205,7 @@ int dAcODungeonShip_c::actorExecute() { if (mEffects[1].hasEmitters()) { mEffects[1].setTransform(tmpMtx); } else if (field_0x8DA == 0) { - mEffects[1].fn_800299F0(PARTICLE_RESOURCE_ID_MAPPING_683_, &tmpMtx, nullptr, nullptr); + mEffects[1].createEffect(PARTICLE_RESOURCE_ID_MAPPING_683_, tmpMtx, nullptr, nullptr); field_0x8DA = 1; } } diff --git a/src/REL/d/a/obj/d_a_obj_seat_sword.cpp b/src/REL/d/a/obj/d_a_obj_seat_sword.cpp index 36b16ea1..a889ad49 100644 --- a/src/REL/d/a/obj/d_a_obj_seat_sword.cpp +++ b/src/REL/d/a/obj/d_a_obj_seat_sword.cpp @@ -231,7 +231,7 @@ void dAcOSeatSword_c::actorExecuteCommon() { mEffPos += player->position; mEffPos.y = position.y; - mEff.fn_80029A10(PARTICLE_RESOURCE_ID_MAPPING_76_, &mEffPos, &rotation, &mScale, nullptr, nullptr); + mEff.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_76_, mEffPos, &rotation, &mScale, nullptr, nullptr); mEff.setGlobalAlpha(mField_0x7E4); } diff --git a/src/REL/d/a/obj/d_a_obj_tower_gearD101.cpp b/src/REL/d/a/obj/d_a_obj_tower_gearD101.cpp index cbf4a29c..eac5d5a1 100644 --- a/src/REL/d/a/obj/d_a_obj_tower_gearD101.cpp +++ b/src/REL/d/a/obj/d_a_obj_tower_gearD101.cpp @@ -10,6 +10,7 @@ #include "f/f_profile_name.h" #include "m/m_vec.h" #include "nw4r/g3d/res/g3d_resmdl.h" +#include "toBeSorted/small_sound_mgr.h" SPECIAL_ACTOR_PROFILE(OBJ_TOWER_GEAR_D101, dAcOTowerGearD101_c, fProfile::OBJ_TOWER_GEAR_D101, 0x17E, 0, 7); @@ -92,9 +93,9 @@ void dAcOTowerGearD101_c::executeState_Wait() { mAng newRotation = diff * scale5 / 2400.0f; if (newRotation != mCurrRotation) { if (mPreviousTurnSpeed == 0) { - playSound(0xBF8); + playSound(SE_TGrD101_ROLL_START); } else { - playSoundEffect1(0xBF9); + playSoundEffect1(SE_TGrD101_ROLL_LV); playVisualEffect(); } } @@ -128,5 +129,5 @@ void dAcOTowerGearD101_c::initTransform() { extern "C" const u16 PARTICLE_RESOURCE_ID_MAPPING_585_; void dAcOTowerGearD101_c::playVisualEffect() { - mEffects.fn_80029A10(PARTICLE_RESOURCE_ID_MAPPING_585_, &field_0x3F4, &rotation, nullptr, nullptr, nullptr); + mEffects.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_585_, field_0x3F4, &rotation, nullptr, nullptr, nullptr); } diff --git a/src/REL/d/a/obj/d_a_obj_tower_hand_D101.cpp b/src/REL/d/a/obj/d_a_obj_tower_hand_D101.cpp index f4c0fdf2..2c584c5d 100644 --- a/src/REL/d/a/obj/d_a_obj_tower_hand_D101.cpp +++ b/src/REL/d/a/obj/d_a_obj_tower_hand_D101.cpp @@ -597,7 +597,7 @@ extern "C" const u16 PARTICLE_RESOURCE_ID_MAPPING_573; void dAcOTowerHandD101_c::initializeState_Close() { mMdl.getAnm().setPlayState(m3d::PLAY_MODE_1); mMdl.setRate(getCloseRate()); - mEffects.fn_80029920(PARTICLE_RESOURCE_ID_MAPPING_573, &position, nullptr, nullptr, nullptr, nullptr); + mEffects.createEffect(PARTICLE_RESOURCE_ID_MAPPING_573, position, nullptr, nullptr, nullptr, nullptr); playSound(0xC0C); } void dAcOTowerHandD101_c::executeState_Close() { diff --git a/src/REL/d/a/obj/d_a_obj_triforce.cpp b/src/REL/d/a/obj/d_a_obj_triforce.cpp index f09ee010..6b967253 100644 --- a/src/REL/d/a/obj/d_a_obj_triforce.cpp +++ b/src/REL/d/a/obj/d_a_obj_triforce.cpp @@ -56,7 +56,6 @@ int dAcOtriforce_c::doDelete() { } extern const u16 PARTICLE_RESOURCE_ID_MAPPING_967_; -extern "C" void fn_80029AE0(EffectsStruct *, u16, mMtx_c *, void *, void *); int dAcOtriforce_c::actorExecute() { int zero = 0; @@ -73,7 +72,7 @@ int dAcOtriforce_c::actorExecute() { PSMTXConcat(mWorldMtx.m, m, mWorldMtx.m); mMdl.setLocalMtx(mWorldMtx); mAnm.play(); - fn_80029AE0(&mEffects, PARTICLE_RESOURCE_ID_MAPPING_967_, &mWorldMtx, nullptr, nullptr); + mEffects.createContinuousEffect(PARTICLE_RESOURCE_ID_MAPPING_967_, mWorldMtx, nullptr, nullptr); return 1; } 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 b47ba004..1eaae5ee 100644 --- a/src/d/lyt/meter/d_lyt_meter_item_select.cpp +++ b/src/d/lyt/meter/d_lyt_meter_item_select.cpp @@ -2242,7 +2242,7 @@ void dLytMeterItemSelect_c::fn_800EF580() { nw4r::math::MTX34 mtx = mpPanes[11]->GetGlobalMtx(); mVec3_c pos(mtx._03, mtx._13, 0.0f); mVec3_c scale(mEffectScale, mEffectScale, mEffectScale); - mEffects.fn_80029A70(PARTICLE_RESOURCE_ID_MAPPING_717_, &pos, nullptr, &scale, nullptr, nullptr); + mEffects.createContinuousUIEffect(PARTICLE_RESOURCE_ID_MAPPING_717_, pos, nullptr, &scale, nullptr, nullptr); if (field_0x57C0 != 0) { mEffects.stopDrawParticles(); diff --git a/src/d/lyt/meter/d_lyt_meter_minus_btn.cpp b/src/d/lyt/meter/d_lyt_meter_minus_btn.cpp index fb71a501..b1f600fd 100644 --- a/src/d/lyt/meter/d_lyt_meter_minus_btn.cpp +++ b/src/d/lyt/meter/d_lyt_meter_minus_btn.cpp @@ -626,8 +626,8 @@ void dLytMeterMinusBtn_c::initializeState_DemoMove() { nw4r::math::MTX34 mtx = mpPanes[i + MINUS_BTN_PANE_ITEM_OFFSET]->GetGlobalMtx(); mVec3_c pos(mtx._03, mtx._13, 0.0f); mSlotForEffect[numPlayingEffects] = i; - mEffects[numPlayingEffects].fn_80029980( - PARTICLE_RESOURCE_ID_MAPPING_971_, &pos, &mEffectsRot[numPlayingEffects], nullptr, nullptr, nullptr + mEffects[numPlayingEffects].createUIEffect( + PARTICLE_RESOURCE_ID_MAPPING_971_, pos, &mEffectsRot[numPlayingEffects], nullptr, nullptr, nullptr ); numPlayingEffects++; } @@ -665,8 +665,8 @@ void dLytMeterMinusBtn_c::executeState_DemoMove() { nw4r::math::MTX34 mtx = getPaneByIndex(mSlotToDemo + MINUS_BTN_PANE_ITEM_OFFSET)->GetGlobalMtx(); mVec3_c pos(mtx._03, mtx._13, 0.0f); mSlotForEffect[0] = mSlotToDemo; - mEffects[0].fn_80029980( - PARTICLE_RESOURCE_ID_MAPPING_971_, &pos, &mEffectsRot[0], nullptr, nullptr, nullptr + mEffects[0].createUIEffect( + PARTICLE_RESOURCE_ID_MAPPING_971_, pos, &mEffectsRot[0], nullptr, nullptr, nullptr ); } } else if (mDemoFrame > 0) { diff --git a/src/toBeSorted/d_effects_1.cpp b/src/toBeSorted/d_effects_1.cpp index 7d462859..c4d37d08 100644 --- a/src/toBeSorted/d_effects_1.cpp +++ b/src/toBeSorted/d_effects_1.cpp @@ -1,3 +1,10 @@ +// clang-format off +// vtable order +#include "JSystem/JParticle/JPAEmitter.h" +#include "JSystem/JParticle/JPAParticle.h" +#include "toBeSorted/d_d3d.h" +// clang-format on + #include "JSystem/JParticle/JPADrawInfo.h" #include "JSystem/JParticle/JPAEmitter.h" #include "c/c_math.h" @@ -36,8 +43,9 @@ #include "rvl/GX.h" #include "rvl/MTX.h" -// TODO: This file suffers from vtable and weak function order problems, big time. -// Some of what we think are weak functions may not be weak functions? +// There's a data gap at 0x805013b4 (right after dParticleFogProc_c's vtable) +// so maybe that's a data split. Unsure how to get all those vtables to appear +// there though... void float_ordering_1(s32 a) { (f32) a; @@ -684,6 +692,20 @@ void dJEffManager_c::removeEffManagers() { } } +void dJEffManager_c::doCustomSkywardSwordThing(f32 x, f32 y) { + EffectsList::Iterator it = sPlayingEffectsList.GetBeginIter(); + while (it != sPlayingEffectsList.GetEndIter()) { + if (it->getEmitterCallback() != nullptr && it->hasEmitters() && it->getGroupId() < 12) { + it->getEmitterCallback()->vt_0x20(x, y); + } + ++it; + } + + for (s32 i = 0; i < 12; i++) { + dParticle::mgr_c::GetInstance()->doCustomSkywardSwordThing(i, x, 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}; @@ -858,6 +880,32 @@ 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) { + 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) { + mVec3_c adjustedPosition(pos.x * getlbl_80571C50(), pos.y, pos.z); + return createEffect(true, resourceId, adjustedPosition, rot, scale, c1, c2); +} + +bool EffectsStruct::createEffect(u16 resourceId, const mMtx_c &transform, const GXColor *c1, const GXColor *c2) { + 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) { + 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) { + 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) { + return createEffect(false, resourceId, transform, c1, c2); +} + void dEmitterBase_c::loadColors( JPABaseEmitter *emitter, const GXColor *color1, const GXColor *color2, s32 plltIdx1, s32 plltIdx2 ) { @@ -1051,7 +1099,7 @@ void dWaterEffect_c::execute(f32 water, f32 ground) { // Spawn effect upon leaving water mVec3_c pos(ac->position.x, water, ac->position.z); mVec3_c scale(mScale, mScale, mScale); - mEff.fn_80029A10(PARTICLE_RESOURCE_ID_MAPPING_127_, &pos, nullptr, &scale, nullptr, nullptr); + mEff.createEffect(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);