diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index d481d933..272d4257 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -119,8 +119,10 @@ toBeSorted/d_emitter.cpp: .sdata2 start:0x80576C18 end:0x80576C68 .bss start:0x80594FA0 end:0x80597020 -toBeSorted/d_effects_2.cpp: +toBeSorted/d_emitter_callbacks.cpp: .text start:0x8002B9A0 end:0x8002C128 align:16 + .data start:0x805014C0 end:0x80501528 + .sdata2 start:0x80576C68 end:0x80576C88 toBeSorted/sound_info.cpp: .text start:0x8002C130 end:0x8002C3A0 align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index cf9a02e4..fe4451f5 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -1009,18 +1009,18 @@ __ct__18dParticleFogProc_cFv = .text:0x8002B8F0; // type:function size:0x44 __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 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 -fn_8002BD10 = .text:0x8002BD10; // type:function size:0x28 -fn_8002BD40 = .text:0x8002BD40; // type:function size:0x34 +__ct__29dEmitterCallbackCursorTrail_cFUlf = .text:0x8002B9A0; // type:function size:0x30 +fn_8002B9D0__FR7mVec3_cRC7mVec3_cRC7mVec3_cRC7mVec3_cRC7mVec3_cf = .text:0x8002B9D0; // type:function size:0x10C +executeAfter__29dEmitterCallbackCursorTrail_cFP14JPABaseEmitter = .text:0x8002BAE0; // type:function size:0x228 +create__29dEmitterCallbackCursorTrail_cFP14JPABaseEmitter = .text:0x8002BD10; // type:function size:0x28 +vt_0x20__29dEmitterCallbackCursorTrail_cFff = .text:0x8002BD40; // type:function size:0x34 fn_8002BD80 = .text:0x8002BD80; // type:function size:0x1C4 fn_8002BF50 = .text:0x8002BF50; // type:function size:0x40 fn_8002BF90 = .text:0x8002BF90; // type:function size:0x1C fn_8002BFB0 = .text:0x8002BFB0; // type:function size:0x54 fn_8002C010 = .text:0x8002C010; // type:function size:0x58 fn_8002C070 = .text:0x8002C070; // type:function size:0x58 -fn_8002C0D0 = .text:0x8002C0D0; // type:function size:0x58 +__dt__29dEmitterCallbackCursorTrail_cFv = .text:0x8002C0D0; // type:function size:0x58 __ct__9SoundInfoFP9dAcBase_c = .text:0x8002C130; // type:function size:0x24 __dt__16dSoundSourceIf_cFv = .text:0x8002C160; // type:function size:0x40 scope:weak __dt__9SoundInfoFv = .text:0x8002C1A0; // type:function size:0xB0 @@ -11274,8 +11274,8 @@ __dt__40sFState_cFv = .text:0x801BD960; // type:f __dt__43sFStateFct_cFv = .text:0x801BD9C0; // type:function size:0x6C __dt__96sStateMgr_cFv = .text:0x801BDA30; // type:function size:0xA0 __dt__66sFStateMgr_cFv = .text:0x801BDAD0; // type:function size:0xA4 -fn_801BDB80 = .text:0x801BDB80; // type:function size:0x40 -fn_801BDBC0 = .text:0x801BDBC0; // type:function size:0x6C +__dt__Q23d2d9AnmGroupsFv = .text:0x801BDB80; // type:function size:0x40 +__dt__18dCsGameAnmGroups_cFv = .text:0x801BDBC0; // type:function size:0x6C __dt__53sFState_cFv = .text:0x801BDC30; // type:function size:0x58 __dt__56sFStateFct_cFv = .text:0x801BDC90; // type:function size:0x6C __dt__109sStateMgr_cFv = .text:0x801BDD00; // type:function size:0xA0 @@ -30003,7 +30003,7 @@ __vt__14dEmitterBase_c = .data:0x80501400; // type:object size:0xC lbl_8050140C = .data:0x8050140C; // type:object size:0xB4 lbl_805014C0 = .data:0x805014C0; // type:object size:0x28 lbl_805014E8 = .data:0x805014E8; // type:object size:0x18 -lbl_80501500 = .data:0x80501500; // type:object size:0x28 +__vt__29dEmitterCallbackCursorTrail_c = .data:0x80501500; // type:object size:0x28 __vt__9SoundInfo = .data:0x80501528; // type:object size:0xC @19465 = .data:0x80501538; // type:object size:0xC data:string __vt__9dAcBase_c = .data:0x80501544; // type:object size:0x74 @@ -35847,7 +35847,7 @@ lbl_8052EDB0 = .data:0x8052EDB0; // type:object size:0x10 lbl_8052EDC0 = .data:0x8052EDC0; // type:object size:0x84 lbl_8052EE44 = .data:0x8052EE44; // type:object size:0xC __vt__9dCsGame_c = .data:0x8052EE50; // type:object size:0x4C -CsGame__lytItemCursor__vtable = .data:0x8052EE9C; // type:object size:0x2C +__vt__Q29dCsGame_c15lytItemCursor_c = .data:0x8052EE9C; // type:object size:0x2C lbl_8052EEC8 = .data:0x8052EEC8; // type:object size:0x10 __vt__66sFStateMgr_c = .data:0x8052EED8; // type:object size:0x30 __vt__96sStateMgr_c = .data:0x8052EF08; // type:object size:0x30 diff --git a/configure.py b/configure.py index 7a46e2e2..9670be23 100644 --- a/configure.py +++ b/configure.py @@ -410,7 +410,7 @@ config.libs = [ Object(NonMatching, "toBeSorted/d_unk_mdl_stuff_2.cpp"), Object(Matching, "d/d_light_env.cpp"), Object(NonMatching, "toBeSorted/d_emitter.cpp"), - Object(NonMatching, "toBeSorted/d_effects_2.cpp"), + Object(NonMatching, "toBeSorted/d_emitter_callbacks.cpp"), Object(Matching, "toBeSorted/sound_info.cpp"), Object(NonMatching, "d/a/d_a_base.cpp"), Object(NonMatching, "d/a/obj/d_a_obj_base.cpp"), diff --git a/include/d/d_cs_game.h b/include/d/d_cs_game.h index 861a4a04..2b5980be 100644 --- a/include/d/d_cs_game.h +++ b/include/d/d_cs_game.h @@ -10,6 +10,7 @@ #include "s/s_State.hpp" #include "s/s_StateID.hpp" #include "toBeSorted/d_emitter.h" +#include "toBeSorted/d_emitter_callbacks.h" struct dCsGame_HIO_c { dCsGame_HIO_c(); @@ -35,15 +36,7 @@ struct dCsGame_HIO_c { /* 0x42 */ u8 field_0x42; }; -class EffectRelatedTmp { -public: - EffectRelatedTmp(); - virtual ~EffectRelatedTmp(); - - void doSomething(EffectsStruct *s); -}; - -class EffectRelated : public EffectRelatedTmp { +class EffectRelated : public dEmitterCallback_c { public: EffectRelated(u32 x = 0x28, f32 y = 3.5f); virtual ~EffectRelated() {} @@ -130,8 +123,6 @@ public: return sInstance; } - void setSomething(int); - bool fn_801BF5E0() const; bool fn_801BF630() const; @@ -141,6 +132,7 @@ public: public: enum CursorType_e { + NONE = 0, BOW = 6, }; @@ -342,8 +334,8 @@ public: /* 0x00C */ UI_STATE_MGR_DECLARE(lytItemCursor_c); /* 0x048 */ EffectsStruct mEffects; - /* 0x07C */ EffectRelated mEffectRelated; - /* 0x080 */ u8 field_0x80[0xC8 - 0x80]; + /* 0x07C */ dEmitterCallbackCursorTrail_c mTrailCb; + /* 0x0B0 */ u8 field_0xB0[0xC8 - 0xB0]; /* 0x0C8 */ m2d::ResAccIf_c *mpResAcc; /* 0x0CC */ d2d::LytBase_c mLyt; /* 0x15C */ dCsGameAnmGroups_c mAnmGroups; diff --git a/include/toBeSorted/d_emitter.h b/include/toBeSorted/d_emitter.h index 82b11202..3a741dc0 100644 --- a/include/toBeSorted/d_emitter.h +++ b/include/toBeSorted/d_emitter.h @@ -43,15 +43,15 @@ public: return mpEmitterCallback; } + void setEmitterCallback(dEmitterCallback_c *cb); + void setParticleCallback(dParticleCallback_c *cb); + protected: void deactivateEmitters(); void stopCalcEmitters(); void playCalcEmitters(); static void loadColors(JPABaseEmitter *emitter, const GXColor *c1, const GXColor *c2, s32 idx1, s32 idx2); - void setEmitterCallback(dEmitterCallback_c *cb); - void setParticleCallback(dParticleCallback_c *cb); - void setImmortal(); static JPABaseEmitter *GetNextEmitter(JPABaseEmitter *head); diff --git a/include/toBeSorted/d_emitter_callbacks.h b/include/toBeSorted/d_emitter_callbacks.h new file mode 100644 index 00000000..710eb0bb --- /dev/null +++ b/include/toBeSorted/d_emitter_callbacks.h @@ -0,0 +1,28 @@ +#ifndef D_EMITTER_CALLBACKS_H +#define D_EMITTER_CALLBACKS_H + +#include "m/m_vec.h" +#include "toBeSorted/d_emitter.h" + +/** + * A callback responsible for emitting the trail left by the red item cursor dot. + * Used by Bow, Gust Bellows, Clawshots, Slingshot. + */ +class dEmitterCallbackCursorTrail_c : public dEmitterCallback_c { +public: + dEmitterCallbackCursorTrail_c(u32 x = 0x28, f32 y = 3.5f); + virtual ~dEmitterCallbackCursorTrail_c() {} + + virtual void executeAfter(JPABaseEmitter *) override; + virtual void create(JPABaseEmitter *) override; + virtual void vt_0x20(f32, f32) override; + +private: + /* 0x10 */ f32 field_0x10; + /* 0x14 */ u16 field_0x14; + /* 0x16 */ u8 _0x16[0x1C - 0x16]; + /* 0x1C */ mVec3_c posNMinus1; + /* 0x28 */ mVec3_c posNMinus2; +}; + +#endif diff --git a/src/d/d_cs_game.cpp b/src/d/d_cs_game.cpp index 7163184a..f9f7518c 100644 --- a/src/d/d_cs_game.cpp +++ b/src/d/d_cs_game.cpp @@ -143,7 +143,7 @@ int dCsGame_c::create() { mCursor.setResAcc(&mMain2DResAcc); mCursor.init(); - setSomething(0); + setNextCursorType(lytItemCursor_c::NONE); mCursorType = 0; mCursor.setField0x9A0(0); @@ -255,7 +255,8 @@ bool dCsGame_c::lytItemCursor_c::doInit() { mVacuum.init(); mAnmGroups.tmp.mAnmGroups[MAIN_ANIM_VACUUM_LOCK].setAnimEnable(false); - mEffectRelated.doSomething(&mEffects); + mEffects.setEmitterCallback(&mTrailCb); + mLyt.setPriority(0x88); mLyt.calc(); @@ -551,6 +552,27 @@ void dCsGame_c::lytItemCursor_c::lytCrawShotCsr_c::initializeState_ToNormal() {} void dCsGame_c::lytItemCursor_c::lytCrawShotCsr_c::executeState_ToNormal() {} void dCsGame_c::lytItemCursor_c::lytCrawShotCsr_c::finalizeState_ToNormal() {} +void dCsGame_c::lytItemCursor_c::lytCrawShotCsr_c::enter() { + mAnm[MAIN_ANIM_CURSOR].setFrame(4.0f); + mAnm[MAIN_ANIM_HOOK_FIX].setAnimEnable(true); + mAnm[MAIN_ANIM_HOOK_FIX].setFrame(0.0f); + mAnm[MAIN_ANIM_LOCK_LOOP].setAnimEnable(false); + mpLyt->getLayout()->Animate(0); + mpLyt->calc(); + mAnm[MAIN_ANIM_HOOK_FIX].setAnimEnable(false); + mStateMgr.changeState(StateID_Normal); +} + +void dCsGame_c::lytItemCursor_c::lytCrawShotCsr_c::init() { + enter(); + mStateMgr.changeState(StateID_Normal); +} + +void dCsGame_c::lytItemCursor_c::lytCrawShotCsr_c::execute() { + mStateMgr.executeState(); +} + + void dCsGame_c::lytItemCursor_c::lytVacuumCsr_c::initializeState_Normal() { mAnm[MAIN_ANIM_LOOP].setAnimEnable(true); } diff --git a/src/toBeSorted/d_emitter_callbacks.cpp b/src/toBeSorted/d_emitter_callbacks.cpp new file mode 100644 index 00000000..b7c9d116 --- /dev/null +++ b/src/toBeSorted/d_emitter_callbacks.cpp @@ -0,0 +1,61 @@ +#include "toBeSorted/d_emitter_callbacks.h" +#include "JSystem/JParticle/JPAEmitter.h" +#include "common.h" +#include "m/m_vec.h" + +dEmitterCallbackCursorTrail_c::dEmitterCallbackCursorTrail_c(u32 a, f32 b) : field_0x10(b), field_0x14(a) { + // TODO - TList +} + +static void fn_8002B9D0(mVec3_c &newPos, const mVec3_c&, const mVec3_c&, const mVec3_c&, const mVec3_c&, f32) { + // TODO - ... + // Probably cubic B-Spline interpolation? +} + +void dEmitterCallbackCursorTrail_c::executeAfter(JPABaseEmitter *emitter) { + mVec3_c newPos; + mVec3_c pos; + mVec3_c v2; + mVec3_c v1; + + emitter->getGlobalTranslation(pos); + + if (!emitter->checkStatus(JPAEmtrStts_StopCalc) && emitter->mMaxFrame == 0) { + v1 = (pos - posNMinus1) * 0.5f; + v2 = (posNMinus1 - posNMinus2) * 0.5f; + f32 dist = pos.distance(posNMinus1); + dist = dist * 0.1f * field_0x10; + if (field_0x14 != 0 && dist > field_0x14) { + dist = field_0x14; + } + + if (dist > 1.0f) { + f32 f, step; + step = 1.0f / dist; + for (f = step; f < 1.0f; f += step) { + fn_8002B9D0(newPos, posNMinus1, v2, v1, pos, f); + JPABaseParticle *ptc = emitter->createParticle(); + if (ptc != nullptr) { + ptc->setOffsetPosition(newPos); + } + } + } + } + + if (emitter->getUserWork() == 0) { + posNMinus2 = posNMinus1; + posNMinus1 = pos; + } +} + +void dEmitterCallbackCursorTrail_c::create(JPABaseEmitter *emitter) { + emitter->getGlobalTranslation(posNMinus1); + posNMinus2 = posNMinus1; +} + +void dEmitterCallbackCursorTrail_c::vt_0x20(f32 x, f32 y) { + posNMinus2.x += x; + posNMinus2.z += y; + posNMinus1.x += x; + posNMinus1.z += y; +}