diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 1cf38579..72569738 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2813,9 +2813,13 @@ d/snd/d_snd_sound_object_callbacks.cpp: d/snd/d_snd_sound_equipment_callbacks.cpp: .text start:0x80398430 end:0x80398AD4 align:16 + .sdata2 start:0x8057E528 end:0x8057E570 d/snd/d_snd_sound_npc_callbacks.cpp: .text start:0x80398AE0 end:0x80398E18 align:16 + .data start:0x8054D520 end:0x8054D730 + .sdata start:0x805748D8 end:0x805748E0 + .sdata2 start:0x8057E570 end:0x8057E598 d/snd/d_snd_sound_npc_2_callbacks.cpp: .text start:0x80398E20 end:0x80398FFC align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index ba74aa8b..05d3eee5 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -2609,7 +2609,7 @@ tryGrabItemWithWhip__17daPlayerActBase_cFv = .text:0x8005CCA0; // type:function isWhipOnObject__17daPlayerActBase_cFv = .text:0x8005CCB0; // type:function size:0x8 somethingWithWHip__17daPlayerActBase_cFv = .text:0x8005CCC0; // type:function size:0x8 anotherThingWithWhip__17daPlayerActBase_cFv = .text:0x8005CCD0; // type:function size:0x8 -isUsingWhip__17daPlayerActBase_cFv = .text:0x8005CCE0; // type:function size:0x8 +isUsingWhip__17daPlayerActBase_cCFv = .text:0x8005CCE0; // type:function size:0x8 finishPlayingHarp__17daPlayerActBase_cFv = .text:0x8005CCF0; // type:function size:0x4 isUsingHarp__17daPlayerActBase_cFv = .text:0x8005CD00; // type:function size:0x8 isPullingOutBomb__17daPlayerActBase_cFv = .text:0x8005CD10; // type:function size:0x8 @@ -20112,7 +20112,7 @@ fn_80364B70 = .text:0x80364B70; // type:function size:0xD0 fn_80364C40 = .text:0x80364C40; // type:function size:0xBC fn_80364D00 = .text:0x80364D00; // type:function size:0x94 fn_80364DA0 = .text:0x80364DA0; // type:function size:0xC -fn_80364DB0 = .text:0x80364DB0; // type:function size:0x2C +isInEvent__14dSndStateMgr_cFPCc = .text:0x80364DB0; // type:function size:0x2C fn_80364DE0 = .text:0x80364DE0; // type:function size:0x7C fn_80364E60 = .text:0x80364E60; // type:function size:0x54 fn_80364EC0 = .text:0x80364EC0; // type:function size:0x90 @@ -21171,7 +21171,7 @@ startBgHitSound__14dSoundSource_cFPCcUlUlPCQ34nw4r4math4VEC3 = .text:0x80389D50; startSoundAtPosition2__14dSoundSource_cFUlPCQ34nw4r4math4VEC3 = .text:0x80389DD0; // type:function size:0x11C startSoundAtPosition2__14dSoundSource_cFPCcPCQ34nw4r4math4VEC3 = .text:0x80389EF0; // type:function size:0x58 startSoundAtPosition__14dSoundSource_cFUlPCQ34nw4r4math4VEC3PQ34nw4r3snd11SoundHandle = .text:0x80389F50; // type:function size:0x208 -d_s_vt_0x19C__14dSoundSource_cFUlP14dSoundSource_c = .text:0x8038A160; // type:function size:0x6C +overrideHitObjSoundId__14dSoundSource_cFUlP14dSoundSource_c = .text:0x8038A160; // type:function size:0x6C handleRemoCon__14dSoundSource_cFPQ34nw4r3snd11SoundHandleUl = .text:0x8038A1D0; // type:function size:0xD8 startVoiceLine__14dSoundSource_cFPCc = .text:0x8038A2B0; // type:function size:0x48 getRoomId__14dSoundSource_cCFv = .text:0x8038A300; // type:function size:0x10 @@ -21197,7 +21197,7 @@ startBaseSound__14dSoundSource_cFUlf = .text:0x8038B1F0; // type:function size:0 startBaseSoundAtPosition__14dSoundSource_cFUlPCQ34nw4r4math4VEC3f = .text:0x8038B280; // type:function size:0x94 resetTempParams__14dSoundSource_cFv = .text:0x8038B320; // type:function size:0x24 onSetupError__14dSoundSource_cFv = .text:0x8038B350; // type:function size:0x30 -d_s_vt_0x194__14dSoundSource_cFUl = .text:0x8038B380; // type:function size:0x8 +overrideStartSoundId__14dSoundSource_cFUl = .text:0x8038B380; // type:function size:0x8 postStartSound__14dSoundSource_cFRQ34nw4r3snd11SoundHandleP13dSndSeSound_cUl = .text:0x8038B390; // type:function size:0x4 d_s_vt_0x1A0__14dSoundSource_cFUli = .text:0x8038B3A0; // type:function size:0x8 postHoldSound__14dSoundSource_cFRQ34nw4r3snd11SoundHandleP13dSndSeSound_cUli = .text:0x8038B3B0; // type:function size:0x4 @@ -21317,21 +21317,21 @@ fn_8038EAC0 = .text:0x8038EAC0; // type:function size:0x8 fn_8038EAD0 = .text:0x8038EAD0; // type:function size:0x8 tadtoneRelated = .text:0x8038EAE0; // type:function size:0xE4 fn_8038EBD0 = .text:0x8038EBD0; // type:function size:0x20 -fn_8038EBF0 = .text:0x8038EBF0; // type:function size:0x4C -fn_8038EC40 = .text:0x8038EC40; // type:function size:0x5C -fn_8038ECA0 = .text:0x8038ECA0; // type:function size:0x1F0 -fn_8038EE90 = .text:0x8038EE90; // type:function size:0x54 -fn_8038EEF0 = .text:0x8038EEF0; // type:function size:0x1D8 -fn_8038F0D0 = .text:0x8038F0D0; // type:function size:0x4C -fn_8038F120 = .text:0x8038F120; // type:function size:0x58 -fn_8038F180 = .text:0x8038F180; // type:function size:0x68 -fn_8038F1F0 = .text:0x8038F1F0; // type:function size:0xC -fn_8038F200 = .text:0x8038F200; // type:function size:0x5C -fn_8038F260 = .text:0x8038F260; // type:function size:0x8 -fn_8038F270 = .text:0x8038F270; // type:function size:0x8 -fn_8038F280 = .text:0x8038F280; // type:function size:0x8 -fn_8038F290 = .text:0x8038F290; // type:function size:0x8 -fn_8038F2A0 = .text:0x8038F2A0; // type:function size:0x8 +__ct__21dSndSourceEquipment_cFUcP9dAcBase_cPCcP17dSndSourceGroup_c = .text:0x8038EBF0; // type:function size:0x4C +shutdown__21dSndSourceEquipment_cFv = .text:0x8038EC40; // type:function size:0x5C +overrideStartSoundId__21dSndSourceEquipment_cFUl = .text:0x8038ECA0; // type:function size:0x1F0 +postStartSound__21dSndSourceEquipment_cFRQ34nw4r3snd11SoundHandleP13dSndSeSound_cUl = .text:0x8038EE90; // type:function size:0x54 +overrideHitObjSoundId__21dSndSourceEquipment_cFUlP14dSoundSource_c = .text:0x8038EEF0; // type:function size:0x1D8 +__ct__25dSndSourceEquipmentWhip_cFUcP9dAcBase_cPCcP17dSndSourceGroup_c = .text:0x8038F0D0; // type:function size:0x4C +__dt__21dSndSourceEquipment_cFv = .text:0x8038F120; // type:function size:0x58 scope:weak +postCalc__25dSndSourceEquipmentWhip_cFv = .text:0x8038F180; // type:function size:0x68 +d_s_vt_0x1E8__21dSndSourceEquipment_cFUl = .text:0x8038F1F0; // type:function size:0xC scope:weak +__dt__25dSndSourceEquipmentWhip_cFv = .text:0x8038F200; // type:function size:0x5C scope:weak +@88@__dt__21dSndSourceEquipment_cFv = .text:0x8038F260; // type:function size:0x8 scope:weak +@4@__dt__21dSndSourceEquipment_cFv = .text:0x8038F270; // type:function size:0x8 scope:weak +@88@__dt__25dSndSourceEquipmentWhip_cFv = .text:0x8038F280; // type:function size:0x8 scope:weak +@4@postStartSound__21dSndSourceEquipment_cFRQ34nw4r3snd11SoundHandleP13dSndSeSound_cUl = .text:0x8038F290; // type:function size:0x8 scope:weak +@4@__dt__25dSndSourceEquipmentWhip_cFv = .text:0x8038F2A0; // type:function size:0x8 scope:weak fn_8038F2B0 = .text:0x8038F2B0; // type:function size:0x7C fn_8038F330 = .text:0x8038F330; // type:function size:0x64 fn_8038F3A0 = .text:0x8038F3A0; // type:function size:0xD8 @@ -21580,17 +21580,17 @@ fn_80397C00 = .text:0x80397C00; // type:function size:0x60 fn_80397C60 = .text:0x80397C60; // type:function size:0xD8 fn_80397D40 = .text:0x80397D40; // type:function size:0x138 fn_80397E80 = .text:0x80397E80; // type:function size:0x5B0 -fn_80398430 = .text:0x80398430; // type:function size:0xC8 -fn_80398500 = .text:0x80398500; // type:function size:0x158 -fn_80398660 = .text:0x80398660; // type:function size:0x74 -fn_803986E0 = .text:0x803986E0; // type:function size:0x68 -fn_80398750 = .text:0x80398750; // type:function size:0x184 -fn_803988E0 = .text:0x803988E0; // type:function size:0x15C -fn_80398A40 = .text:0x80398A40; // type:function size:0x94 +cbBeFlyLv__21dSndSourceEquipment_cFP13dSndSeSound_cP14dSoundSource_cRQ34nw4r3snd11SoundHandle = .text:0x80398430; // type:function size:0xC8 +cbBeThrowRc__21dSndSourceEquipment_cFP13dSndSeSound_cP14dSoundSource_cRQ34nw4r3snd11SoundHandle = .text:0x80398500; // type:function size:0x158 +cbBmIgnitionLv__21dSndSourceEquipment_cFP13dSndSeSound_cP14dSoundSource_cRQ34nw4r3snd11SoundHandle = .text:0x80398660; // type:function size:0x74 +cbBmBound__21dSndSourceEquipment_cFP13dSndSeSound_cP14dSoundSource_cRQ34nw4r3snd11SoundHandle = .text:0x803986E0; // type:function size:0x68 +cbWiFxLv__21dSndSourceEquipment_cFP13dSndSeSound_cP14dSoundSource_cRQ34nw4r3snd11SoundHandle = .text:0x80398750; // type:function size:0x184 +cbPcHit__21dSndSourceEquipment_cFP13dSndSeSound_cP14dSoundSource_cRQ34nw4r3snd11SoundHandle = .text:0x803988E0; // type:function size:0x15C +postSetupSound__21dSndSourceEquipment_cFUlUlP13dSndSeSound_c = .text:0x80398A40; // type:function size:0x94 fn_80398AE0 = .text:0x80398AE0; // type:function size:0xC4 fn_80398BB0 = .text:0x80398BB0; // type:function size:0xCC fn_80398C80 = .text:0x80398C80; // type:function size:0x68 -fn_80398CF0 = .text:0x80398CF0; // type:function size:0x80 +cbPyBirdGlide__18dSndSourcePyBird_cFP13dSndSeSound_cP14dSoundSource_cRQ34nw4r3snd11SoundHandle = .text:0x80398CF0; // type:function size:0x80 fn_80398D70 = .text:0x80398D70; // type:function size:0x64 postSetupSound__18dSndSourcePyBird_cFUlUlP13dSndSeSound_c = .text:0x80398DE0; // type:function size:0x18 fn_80398E00 = .text:0x80398E00; // type:function size:0x8 @@ -38072,10 +38072,10 @@ lbl_8054B5A8 = .data:0x8054B5A8; // type:object size:0x1F0 lbl_8054B798 = .data:0x8054B798; // type:object size:0x1F0 lbl_8054B988 = .data:0x8054B988; // type:object size:0x1F0 lbl_8054BB78 = .data:0x8054BB78; // type:object size:0x48 -lbl_8054BBC0 = .data:0x8054BBC0; // type:object size:0x10 data:string -lbl_8054BBD0 = .data:0x8054BBD0; // type:object size:0x18 -lbl_8054BBE8 = .data:0x8054BBE8; // type:object size:0x1EC -lbl_8054BDD4 = .data:0x8054BDD4; // type:object size:0x1EC +@23983 = .data:0x8054BBC0; // type:object size:0x10 scope:local data:string +@23984 = .data:0x8054BBD0; // type:object size:0x15 scope:local data:string +__vt__25dSndSourceEquipmentWhip_c = .data:0x8054BBE8; // type:object size:0x1EC +__vt__21dSndSourceEquipment_c = .data:0x8054BDD4; // type:object size:0x1EC lbl_8054BFC0 = .data:0x8054BFC0; // type:object size:0x1F0 lbl_8054C1B0 = .data:0x8054C1B0; // type:object size:0x1F0 lbl_8054C3A0 = .data:0x8054C3A0; // type:object size:0x10 @@ -49530,23 +49530,23 @@ lbl_8057E514 = .sdata2:0x8057E514; // type:object size:0x4 align:4 data:float lbl_8057E518 = .sdata2:0x8057E518; // type:object size:0x4 align:4 data:float lbl_8057E51C = .sdata2:0x8057E51C; // type:object size:0x4 align:4 data:float lbl_8057E520 = .sdata2:0x8057E520; // type:object size:0x4 align:4 data:float -lbl_8057E528 = .sdata2:0x8057E528; // type:object size:0x4 align:4 data:float -lbl_8057E52C = .sdata2:0x8057E52C; // type:object size:0x4 align:4 data:float -lbl_8057E530 = .sdata2:0x8057E530; // type:object size:0x4 align:4 data:float -lbl_8057E534 = .sdata2:0x8057E534; // type:object size:0x4 align:4 data:float -lbl_8057E538 = .sdata2:0x8057E538; // type:object size:0x4 align:4 data:float -lbl_8057E53C = .sdata2:0x8057E53C; // type:object size:0x4 align:4 data:float -lbl_8057E540 = .sdata2:0x8057E540; // type:object size:0x4 align:4 data:float -lbl_8057E544 = .sdata2:0x8057E544; // type:object size:0x4 align:4 data:float -lbl_8057E548 = .sdata2:0x8057E548; // type:object size:0x4 align:4 data:float -lbl_8057E54C = .sdata2:0x8057E54C; // type:object size:0x4 align:4 data:float -lbl_8057E550 = .sdata2:0x8057E550; // type:object size:0x4 align:4 data:float -lbl_8057E554 = .sdata2:0x8057E554; // type:object size:0x4 align:4 data:float -lbl_8057E558 = .sdata2:0x8057E558; // type:object size:0x4 align:4 data:float -lbl_8057E55C = .sdata2:0x8057E55C; // type:object size:0x4 align:4 data:float -lbl_8057E560 = .sdata2:0x8057E560; // type:object size:0x4 align:4 data:float -lbl_8057E564 = .sdata2:0x8057E564; // type:object size:0x4 align:4 data:float -lbl_8057E568 = .sdata2:0x8057E568; // type:object size:0x4 align:4 data:float +@27751 = .sdata2:0x8057E528; // type:object size:0x4 scope:local align:4 data:float +@27752 = .sdata2:0x8057E52C; // type:object size:0x4 scope:local align:4 data:float +@27753 = .sdata2:0x8057E530; // type:object size:0x4 scope:local align:4 data:float +@27754 = .sdata2:0x8057E534; // type:object size:0x4 scope:local align:4 data:float +@27835 = .sdata2:0x8057E538; // type:object size:0x4 scope:local align:4 data:float +@27858 = .sdata2:0x8057E53C; // type:object size:0x4 scope:local align:4 data:float +@27859 = .sdata2:0x8057E540; // type:object size:0x4 scope:local align:4 data:float +@27860 = .sdata2:0x8057E544; // type:object size:0x4 scope:local align:4 data:float +@27925 = .sdata2:0x8057E548; // type:object size:0x4 scope:local align:4 data:float +@27926 = .sdata2:0x8057E54C; // type:object size:0x4 scope:local align:4 data:float +@27927 = .sdata2:0x8057E550; // type:object size:0x4 scope:local align:4 data:float +@27928 = .sdata2:0x8057E554; // type:object size:0x4 scope:local align:4 data:float +@27929 = .sdata2:0x8057E558; // type:object size:0x4 scope:local align:4 data:float +@27930 = .sdata2:0x8057E55C; // type:object size:0x4 scope:local align:4 data:float +@27931 = .sdata2:0x8057E560; // type:object size:0x4 scope:local align:4 data:float +@28140 = .sdata2:0x8057E564; // type:object size:0x4 scope:local align:4 data:float +@28141 = .sdata2:0x8057E568; // type:object size:0x4 scope:local align:4 data:float lbl_8057E570 = .sdata2:0x8057E570; // type:object size:0x4 align:4 data:float lbl_8057E574 = .sdata2:0x8057E574; // type:object size:0x4 align:4 data:float lbl_8057E578 = .sdata2:0x8057E578; // type:object size:0x4 align:4 data:float diff --git a/configure.py b/configure.py index 5cd5bf31..5a571079 100644 --- a/configure.py +++ b/configure.py @@ -770,7 +770,7 @@ config.libs = [ Object(NonMatching, "d/snd/d_snd_source_link_head.cpp"), Object(NonMatching, "d/snd/d_snd_source_enemy.cpp"), Object(NonMatching, "d/snd/d_snd_source_obj.cpp"), - Object(NonMatching, "d/snd/d_snd_source_equipment.cpp"), + Object(Matching, "d/snd/d_snd_source_equipment.cpp"), Object(NonMatching, "d/snd/d_snd_mgr_unk_8.cpp"), Object(NonMatching, "d/snd/d_snd_mgr_unk_9.cpp"), Object(Matching, "d/snd/d_snd_source_py_bird.cpp"), @@ -788,7 +788,7 @@ config.libs = [ Object(NonMatching, "d/snd/d_snd_sound_link_body_callbacks.cpp"), Object(NonMatching, "d/snd/d_snd_sound_enemy_callbacks.cpp"), Object(NonMatching, "d/snd/d_snd_sound_object_callbacks.cpp"), - Object(NonMatching, "d/snd/d_snd_sound_equipment_callbacks.cpp"), + Object(Matching, "d/snd/d_snd_sound_equipment_callbacks.cpp"), Object(NonMatching, "d/snd/d_snd_sound_npc_callbacks.cpp"), Object(NonMatching, "d/snd/d_snd_sound_npc_2_callbacks.cpp"), Object(NonMatching, "d/snd/d_snd_sound_tgsound_callbacks.cpp"), diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 7c272127..4e8b4b49 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -56,7 +56,7 @@ public: return false; } /* vt 0x0BC */ virtual void finishPlayingHarp() {} - /* vt 0x0C0 */ virtual bool isUsingWhip() { + /* vt 0x0C0 */ virtual bool isUsingWhip() const { return false; } /* vt 0x0C4 */ virtual bool anotherThingWithWhip() { @@ -611,6 +611,10 @@ public: return mAttackDirection != ATTACK_NONE; } + inline bool hasvt_0x1C0() const { + return vt_0x1C0() != nullptr; + } + static bool isInEvent(); bool isAttackingLeft() const; bool isAttackingRight() const; diff --git a/include/d/snd/d_snd_3d_actor.h b/include/d/snd/d_snd_3d_actor.h index fa00dca9..6e2ed11d 100644 --- a/include/d/snd/d_snd_3d_actor.h +++ b/include/d/snd/d_snd_3d_actor.h @@ -83,6 +83,14 @@ public: return mDistanceToListener; } + f32 getSpeed() { + if (!checkFlag(0x400)) { + mSpeed = VECMag(GetVelocity()); + setFlag(0x400); + } + return mSpeed; + } + f32 getDistanceToCameraTarget() { updateDistanceToCameraTarget(); return mDistanceToCameraTarget; @@ -111,7 +119,7 @@ protected: /* 0x90 */ f32 a_field_0x90; /* 0x94 */ f32 mDistanceToListener; /* 0x98 */ f32 mCameraDirectionDot; - /* 0x9C */ f32 a_field_0x9C; + /* 0x9C */ f32 mSpeed; /* 0xA0 */ nw4r::math::VEC3 mPositionRelativeToListener; /* 0xAC */ nw4r::math::VEC3 mPositionTransformedByListener; /* 0xB8 */ f32 mDistanceToCameraTarget; diff --git a/include/d/snd/d_snd_checkers.h b/include/d/snd/d_snd_checkers.h index 2b632d4f..e6bff0de 100644 --- a/include/d/snd/d_snd_checkers.h +++ b/include/d/snd/d_snd_checkers.h @@ -7,6 +7,8 @@ class SoundPropertiesChecker { public: + // @bug forgot to initialize mCounter4. see `dSndSourceEquipment_c::cbPcHit` for one consequence + SoundPropertiesChecker(u32 soundId) : mSoundId(soundId), mPlayCounter(0), mPauseCounter(0), mCounter3(0), mpPlayCounter(nullptr), mpPauseCounter(nullptr), mpCounter3(nullptr), mpCounter4(nullptr) {} virtual void operator()(nw4r::snd::SoundHandle &pHandle) { if (mSoundId != -1 && mSoundId != pHandle.GetId()) { return; @@ -61,16 +63,16 @@ public: } } -private: +public: /* 0x04 */ u32 mSoundId; - /* 0x08 */ u32 mPlayCounter; - /* 0x0C */ u32 mPauseCounter; - /* 0x10 */ u32 mCounter3; - /* 0x14 */ u32 mCounter4; - /* 0x18 */ u32 *mpPlayCounter; - /* 0x1C */ u32 *mpPauseCounter; - /* 0x20 */ u32 *mpCounter3; - /* 0x24 */ u32 *mpCounter4; + /* 0x08 */ s32 mPlayCounter; + /* 0x0C */ s32 mPauseCounter; + /* 0x10 */ s32 mCounter3; + /* 0x14 */ s32 mCounter4; + /* 0x18 */ s32 *mpPlayCounter; + /* 0x1C */ s32 *mpPauseCounter; + /* 0x20 */ s32 *mpCounter3; + /* 0x24 */ s32 *mpCounter4; }; // used at the very least when trying to finish Demise diff --git a/include/d/snd/d_snd_se_sound.h b/include/d/snd/d_snd_se_sound.h index 1d2b2f5c..6ed8e2c2 100644 --- a/include/d/snd/d_snd_se_sound.h +++ b/include/d/snd/d_snd_se_sound.h @@ -7,22 +7,6 @@ #include "nw4r/snd/snd_SoundHandle.h" #include "nw4r/ut/ut_list.h" -/** - * Examples: - * * Chandelier hold sound. Game code (dAcOChandelier_c::executeState_Wait) will - * push the current swing angle, callback (80397a40) will play additional sounds - * when chandelier swing speed exceeds certain values. - * * SE_L_ROPE_WIND_LV: callback (80228814) will read and write values to create a feedback - * loop for certain parameters. - */ -struct dSndSoundCtxParam { - dSndSoundCtxParam() : intParam(0), floatParam(0.0f) {} - ~dSndSoundCtxParam() {} - - /* 0x00 */ s32 intParam; - /* 0x04 */ f32 floatParam; -}; - /** * A sound effect handle. Typically acquired by sound sources from a pool. * This allows sound sources to play sounds with no pre-determined limit @@ -76,6 +60,14 @@ public: return mpSoundHandle; } + dSndSoundCtxParam *getCtxParams() const { + return mpCtxParam; + } + + s32 getField0x114() const { + return field_0x114; + } + void setHandle(nw4r::snd::SoundHandle *handle) { if (handle != nullptr) { mpSoundHandle = handle; @@ -110,6 +102,14 @@ public: field_0x11E = value; } + void setCallback1(Callback cb) { + mpStartCallback = cb; + } + + void setCallback2(Callback cb) { + mpCalcCallback = cb; + } + protected: /* 0x004 */ nw4r::ut::Node mSourceLink; /* 0x00C */ nw4r::ut::Node mPoolLink; @@ -119,7 +119,7 @@ protected: /* 0x10C */ Type_e mHandleType; /* 0x110 */ u32 mSoundId; /* 0x114 */ s32 field_0x114; - /* 0x118 */ dSndSoundCtxParam *mpUnk; + /* 0x118 */ dSndSoundCtxParam *mpCtxParam; /* 0x11C */ u8 field_0x11C; /* 0x11D */ u8 field_0x11D; /* 0x11E */ u8 field_0x11E; diff --git a/include/d/snd/d_snd_source.h b/include/d/snd/d_snd_source.h index 3b6c326b..4cc43ced 100644 --- a/include/d/snd/d_snd_source.h +++ b/include/d/snd/d_snd_source.h @@ -49,11 +49,11 @@ public: /* 0x188 */ virtual void postSetup() {} /* 0x18C */ virtual void postCalc(); /* 0x190 */ virtual bool d_s_vt_0x190() const; - /* 0x194 */ virtual u32 d_s_vt_0x194(u32 soundId); + /* 0x194 */ virtual u32 overrideStartSoundId(u32 soundId); /* 0x198 */ virtual void postStartSound(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id) override; - /* 0x19C */ virtual u32 d_s_vt_0x19C(u32 soundId, dSoundSource_c *source); + /* 0x19C */ virtual u32 overrideHitObjSoundId(u32 soundId, dSoundSource_c *source); /* 0x1A0 */ virtual u32 d_s_vt_0x1A0(u32 soundId, UNKWORD); /* 0x1A4 */ virtual void @@ -205,9 +205,10 @@ public: return false; } + dSndSeSound2_c *getHandleType2ForSoundId(u32 soundId); + protected: StartResult setupSoundCommon(nw4r::snd::SoundHandle *pHandle, u32 soundId, const StartInfo *pStartInfo, void *arg); - dSndSeSound2_c *getHandleType2ForSoundId(u32 soundId); private: /** @@ -260,7 +261,7 @@ private: // at 0x00: dSoundSourceIf_c vtable // at 0x04: dSnd3DActor_c sub-object // at 0x58: thunk-vtable - +protected: /* 0x0E8 */ nw4r::ut::Node mMgrLink; /* 0x0F0 */ const char *mpName; /* 0x0F4 */ UNKWORD field_0x0F4; diff --git a/include/d/snd/d_snd_source_equipment.h b/include/d/snd/d_snd_source_equipment.h new file mode 100644 index 00000000..f30d1c50 --- /dev/null +++ b/include/d/snd/d_snd_source_equipment.h @@ -0,0 +1,38 @@ +#ifndef D_SND_SOURCE_EQUIPMENT_H +#define D_SND_SOURCE_EQUIPMENT_H + +#include "d/snd/d_snd_source.h" + +class dSndSourceEquipment_c : public dSoundSource_c { +public: + dSndSourceEquipment_c(u8 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup); + + /* 0x040 */ virtual void shutdown() override; + /* 0x194 */ virtual u32 overrideStartSoundId(u32 soundId) override; + /* 0x198 */ virtual void postStartSound(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id) override; + /* 0x19C */ virtual u32 overrideHitObjSoundId(u32 soundId, dSoundSource_c *source) override; + + /* 0x1CC */ virtual void postSetupSound(u32 playingId, u32 requestedId, dSndSeSound_c *seSound) override; + + /* 0x1E8 */ virtual u32 d_s_vt_0x1E8(u32 soundId) override { + return specializeBgHitSoundId(soundId, mPolyAttr0, mPolyAttr1); + } + +private: + static void cbBeFlyLv(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle); + static void cbBeThrowRc(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle); + static void cbBmIgnitionLv(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle); + static void cbBmBound(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle); + static void cbWiFxLv(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle); + static void cbPcHit(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle); +}; + + +class dSndSourceEquipmentWhip_c : public dSndSourceEquipment_c { +public: + dSndSourceEquipmentWhip_c(u8 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup); + + /* 0x1CC */ virtual void postCalc() override; +}; + +#endif diff --git a/include/d/snd/d_snd_source_if.h b/include/d/snd/d_snd_source_if.h index acfa2f74..c79bb2e8 100644 --- a/include/d/snd/d_snd_source_if.h +++ b/include/d/snd/d_snd_source_if.h @@ -5,13 +5,29 @@ #include "nw4r/math/math_types.h" class dAcBase_c; -class dSndSoundCtxParam; + +/** + * Examples: + * * Chandelier hold sound. Game code (dAcOChandelier_c::executeState_Wait) will + * push the current swing angle, callback (80397a40) will play additional sounds + * when chandelier swing speed exceeds certain values. + * * SE_L_ROPE_WIND_LV: callback (80228814) will read and write values to create a feedback + * loop for certain parameters. + * * `dSndSourceEquipment_c::overrideStartSoundId` will directly read the parameter to customize shield + * sounds. + */ +struct dSndSoundCtxParam { + dSndSoundCtxParam() : intParam(0), floatParam(0.0f) {} + ~dSndSoundCtxParam() {} + + /* 0x00 */ s32 intParam; + /* 0x04 */ f32 floatParam; +}; /** An abstract interface for sound relating to a particular actor. */ class dSoundSourceIf_c { public: virtual ~dSoundSourceIf_c() {} -#define SOUNDSOURCE_VIRTUAL(offset) virtual void vt_##offset() = 0; /* 0x00C */ virtual void setup() = 0; /* 0x010 */ virtual s32 getCategory() const = 0; diff --git a/include/d/snd/d_snd_source_py_bird.h b/include/d/snd/d_snd_source_py_bird.h index 5da1e1c8..7a3c9405 100644 --- a/include/d/snd/d_snd_source_py_bird.h +++ b/include/d/snd/d_snd_source_py_bird.h @@ -15,6 +15,8 @@ public: /* 0x1CC */ virtual void postSetupSound(u32 playingId, u32 requestedId, dSndSeSound_c *seSound) override; private: + static void cbPyBirdGlide(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle); + /* 0x200 */ s32 mSeqVarValue; }; diff --git a/include/d/snd/d_snd_state_mgr.h b/include/d/snd/d_snd_state_mgr.h index 971e971a..0bf38ac3 100644 --- a/include/d/snd/d_snd_state_mgr.h +++ b/include/d/snd/d_snd_state_mgr.h @@ -79,6 +79,7 @@ public: bool isInDemo() const { return getCurrentStageMusicDemoName() != nullptr; } + bool isInEvent(const char *eventName); private: u32 getStageTypeFlags(const char *stageName) const; diff --git a/include/nw4r/snd/snd_Sound3DActor.h b/include/nw4r/snd/snd_Sound3DActor.h index 168fafa6..c0088339 100644 --- a/include/nw4r/snd/snd_Sound3DActor.h +++ b/include/nw4r/snd/snd_Sound3DActor.h @@ -24,6 +24,10 @@ public: const nw4r::math::VEC3 &GetPosition() const { return mPosition; } + + const nw4r::math::VEC3 &GetVelocity() const { + return mVelocity; + } void SetPosition(const math::VEC3 &rPosition); void SetUserParam(u32 userParam) { diff --git a/include/nw4r/snd/snd_SoundHandle.h b/include/nw4r/snd/snd_SoundHandle.h index ab6f5e71..a69b7999 100644 --- a/include/nw4r/snd/snd_SoundHandle.h +++ b/include/nw4r/snd/snd_SoundHandle.h @@ -69,6 +69,11 @@ namespace nw4r { namespace snd mSound->SetPan(pan); } + void SetLpfFreq(f32 lpfFreq) { + if (IsAttachedSound()) + mSound->SetLpfFreq(lpfFreq); + } + bool IsPause() const { return IsAttachedSound() && mSound->IsPause(); } diff --git a/src/d/snd/d_snd_3d_actor.cpp b/src/d/snd/d_snd_3d_actor.cpp index 0e7ad410..f5a216c3 100644 --- a/src/d/snd/d_snd_3d_actor.cpp +++ b/src/d/snd/d_snd_3d_actor.cpp @@ -25,7 +25,7 @@ dSnd3DActor_c::dSnd3DActor_c(dSndSourceParam *pSourceParam, u8 sourceType) a_field_0x90(INFINITY), mDistanceToListener(INFINITY), mCameraDirectionDot(0.0f), - a_field_0x9C(0.0f), + mSpeed(0.0f), mpSourceParam(pSourceParam), mFlags(0), mDistanceToPlayer(INFINITY), diff --git a/src/d/snd/d_snd_actor.cpp b/src/d/snd/d_snd_actor.cpp index 114bb03f..fdd30ddd 100644 --- a/src/d/snd/d_snd_actor.cpp +++ b/src/d/snd/d_snd_actor.cpp @@ -7,6 +7,6 @@ dSndActor_c::dSndActor_c(nw4r::snd::SoundArchivePlayer &rStartable) : nw4r::snd::SoundActor(rStartable) {} void dSndActor_c::doesSomethingWithForeachSound() { - SoundPropertiesChecker checker; + SoundPropertiesChecker checker(-1); ForEachSound(checker, false); } diff --git a/src/d/snd/d_snd_se_sound.cpp b/src/d/snd/d_snd_se_sound.cpp index 22620f31..45cb0977 100644 --- a/src/d/snd/d_snd_se_sound.cpp +++ b/src/d/snd/d_snd_se_sound.cpp @@ -14,19 +14,19 @@ dSndSeSound_c::dSndSeSound_c() field_0x11E(0), mpStartCallback(nullptr), mpCalcCallback(nullptr) { - mpUnk = new dSndSoundCtxParam[10]; + mpCtxParam = new dSndSoundCtxParam[10]; } dSndSeSound_c::~dSndSeSound_c() { - delete[] mpUnk; + delete[] mpCtxParam; } void dSndSeSound_c::setSource(dSoundSource_c *source, u32 soundId) { clear(); mSoundId = soundId; field_0x114 = 0; - dSndSoundCtxParam* s = mpUnk; - while (s < &mpUnk[10]) { + dSndSoundCtxParam* s = mpCtxParam; + while (s < &mpCtxParam[10]) { s->intParam = 0; s->floatParam = 0.0f; s++; @@ -57,22 +57,22 @@ void dSndSeSound_c::calc(dSoundSource_c *source) { field_0x114++; } -void dSndSeSound_c::shiftParam(const dSndSoundCtxParam *pUnk) { - if (pUnk == nullptr) { +void dSndSeSound_c::shiftParam(const dSndSoundCtxParam *pParam) { + if (pParam == nullptr) { return; } for (int i = 9; i > 0; i--) { - mpUnk[i] = mpUnk[i - 1]; + mpCtxParam[i] = mpCtxParam[i - 1]; } - mpUnk[0] = *pUnk; + mpCtxParam[0] = *pParam; } void dSndSeSound_c::shiftFloatParam(f32 value) { for (int i = 9; i > 0; i--) { - mpUnk[i].floatParam = mpUnk[i - 1].floatParam; + mpCtxParam[i].floatParam = mpCtxParam[i - 1].floatParam; } - mpUnk[0].floatParam = value; + mpCtxParam[0].floatParam = value; } void dSndSeSound_c::onStart(dSoundSource_c *source) { diff --git a/src/d/snd/d_snd_sound_equipment_callbacks.cpp b/src/d/snd/d_snd_sound_equipment_callbacks.cpp new file mode 100644 index 00000000..d5260734 --- /dev/null +++ b/src/d/snd/d_snd_sound_equipment_callbacks.cpp @@ -0,0 +1,156 @@ + +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/snd/d_snd_checkers.h" +#include "d/snd/d_snd_control_player_mgr.h" +#include "d/snd/d_snd_player_mgr.h" +#include "d/snd/d_snd_se_sound.h" +#include "d/snd/d_snd_se_sound_2.h" +#include "d/snd/d_snd_source_equipment.h" +#include "d/snd/d_snd_wzsound.h" +#include "nw4r/snd/snd_SeqSoundHandle.h" +#include "nw4r/snd/snd_SoundPlayer.h" + +void dSndSourceEquipment_c::cbBeFlyLv(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle) { + if (sound->getCtxParams()[0].floatParam > 0.0f) { + nw4r::snd::SeqSoundHandle seqHandle(&handle); + f32 volume = 0.6f; + f32 pitch = 1.0f; + if (sound->getCtxParams()[0].floatParam == 1.0f) { + volume = 1.0f; + pitch = 1.3f; + } + handle.SetVolume(volume, 0); + handle.SetPitch(pitch); + seqHandle.SetTempoRatio(pitch); + } +} + +void dSndSourceEquipment_c::cbBeThrowRc(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle) { + if (dAcPy_c::GetLink() != nullptr && !dAcPy_c::GetLink()->hasvt_0x1C0()) { + handle.Stop(10); + return; + } + + dSndSeSound2_c *flyHoldHandle = source->getHandleType2ForSoundId(SE_BE_FLY_LV); + if (flyHoldHandle == nullptr) { + if (sound->getField0x114() != 0) { + handle.Stop(3); + sound->setCallback2(nullptr); + } + return; + } + + nw4r::snd::SeqSoundHandle seqHandle(sound->getHandle()); + if (flyHoldHandle->getCtxParams()[0].floatParam > 0.0f) { + f32 volume = 0.6f; + f32 pitch = 1.0f; + if (flyHoldHandle->getCtxParams()[0].floatParam == 1.0f) { + volume = 1.0f; + pitch = 1.3f; + } + handle.SetVolume(volume, 0); + handle.SetPitch(pitch); + seqHandle.SetTempoRatio(pitch); + } +} + +void dSndSourceEquipment_c::cbBmIgnitionLv( + dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle +) { + // TODO how are these flags set + if (source->checkFlag(0x1)) { + handle.SetLpfFreq(-0.4f); + } else { + handle.SetLpfFreq(0.0f); + } +} + +void dSndSourceEquipment_c::cbBmBound(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle) { + f32 param = sound->getCtxParams()[0].floatParam; + if (param <= 2.0f) { + handle.Stop(0); + return; + } + // TODO what does this do? + f32 volume = param / 70.0f + 0.3f; + if (volume > 1.0f) { + volume = 1.0f; + } + handle.SetVolume(volume, 0); +} + +static const f32 beMinSpeed = 2.0f; +static const f32 beMaxSpeed = 40.0f; + +void dSndSourceEquipment_c::cbWiFxLv(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle) { + if (dAcPy_c::GetLink() == nullptr) { + return; + } + f32 volume = 1.0f; + f32 pitch = 1.0f; + if (dAcPy_c::GetLink()->checkCurrentAction(/* WHIP_LOCKED */ 0x8E)) { + volume = 0.9f; + } else { + if (dAcPy_c::GetLink()->checkCurrentAction(/* USE_WHIP */ 0x8D)) { + pitch = 1.2f; + } else if (dAcPy_c::GetLink()->isUsingWhip()) { + f32 speed = source->getSpeed(); + + if (speed <= beMinSpeed) { + volume = 0.2; + } else if (speed >= beMaxSpeed) { + volume = 0.8f; + } else { + volume = speed * 0.6f / 38.0f; + volume += 0.8f; + volume -= (beMaxSpeed * 0.6f / 38.0f); + // @bug not actually clamped + (void)nw4r::ut::Clamp(volume, 0.2f, 0.8f); + } + pitch = 0.9f; + } + } + // Save the current speed value... + sound->shiftFloatParam(pitch); + // And read the speed value from 4 frames earlier (~133ms) + f32 actualPitch = sound->getCtxParams()[5].floatParam; + handle.SetVolume(volume, 0); + handle.SetPitch(actualPitch); +} + +void dSndSourceEquipment_c::cbPcHit(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle) { + nw4r::snd::SoundPlayer *equipmentPlayer = + dSndControlPlayerMgr_c::GetInstance()->getPlayer2(dSndPlayerMgr_c::PLAYER_LINK_EQUIPMENT); + s32 result = 0; + SoundPropertiesChecker checker(handle.GetId()); + // due to a @bug in SoundPropertiesChecker's ctor, mCounter4 is uninitialized, + // so when MWCC creates a copy of `checker` for ForEachSound, + // it uses r3 to store the ininitialized field, which currently holds + // `equipmentPlayer`. So this behaves as if someone wrote: + // checker.mCounter4 = reinterpret_cast(equipmentPlayer); + // This is harmless here, since we never use the result. + checker.mpPlayCounter = &result; + + // The more equipment sounds are playing, the more + // the volume on SE_PC_HIT is reduced + equipmentPlayer->ForEachSound(checker, false); + if (result == 2) { + handle.SetVolume(0.7f, 0); + } else if (result == 3) { + handle.SetVolume(0.5f, 0); + } else if (result >= 4) { + handle.SetVolume(0.3f, 0); + } +} + +void dSndSourceEquipment_c::postSetupSound(u32 playingId, u32 requestedId, dSndSeSound_c *seSound) { + switch (requestedId) { + case SE_BE_FLY_LV: seSound->setCallback2(&cbBeFlyLv); break; + case SE_BE_THROW_RC: seSound->setCallback2(&cbBeThrowRc); break; + case SE_BM_IGNITION_LV: seSound->setCallback2(&cbBmIgnitionLv); break; + case SE_BM_BOUND: seSound->setCallback1(&cbBmBound); break; + case SE_WI_FX_LV: seSound->setCallback2(&cbWiFxLv); break; + case SE_PC_HIT: seSound->setCallback1(&cbPcHit); break; + } +} diff --git a/src/d/snd/d_snd_sound_npc_callbacks.cpp b/src/d/snd/d_snd_sound_npc_callbacks.cpp new file mode 100644 index 00000000..8f8e06de --- /dev/null +++ b/src/d/snd/d_snd_sound_npc_callbacks.cpp @@ -0,0 +1,21 @@ +#include "d/snd/d_snd_se_sound.h" +#include "d/snd/d_snd_source_py_bird.h" +#include "d/snd/d_snd_state_mgr.h" +#include "d/snd/d_snd_wzsound.h" +#include "nw4r/snd/snd_SeqSoundHandle.h" +#include "toBeSorted/music_mgrs.h" + +void dSndSourcePyBird_c::cbPyBirdGlide(dSndSeSound_c *sound, dSoundSource_c *source, nw4r::snd::SoundHandle &handle) { + s32 var = 0; + if (!fn_80364DA0(dSndStateMgr_c::GetInstance())) { + var = static_cast(source)->mSeqVarValue; + } + nw4r::snd::SeqSoundHandle seqHandle(&handle); + seqHandle.WriteVariable(10, var); +} + +void dSndSourcePyBird_c::postSetupSound(u32 playingId, u32 requestedId, dSndSeSound_c *seSound) { + if (requestedId == SE_PyBird_GLIDE) { + seSound->setCallback2(&cbPyBirdGlide); + } +} diff --git a/src/d/snd/d_snd_source.cpp b/src/d/snd/d_snd_source.cpp index 952387ca..643fb715 100644 --- a/src/d/snd/d_snd_source.cpp +++ b/src/d/snd/d_snd_source.cpp @@ -377,7 +377,7 @@ bool dSoundSource_c::startSoundAtPosition(u32 soundId, const nw4r::math::VEC3 *p u32 actualSoundId = soundId; if (!sIsStartingBaseSound) { - actualSoundId = d_s_vt_0x194(soundId); + actualSoundId = overrideStartSoundId(soundId); if (actualSoundId == -1) { resetTempParams(); return false; @@ -410,12 +410,12 @@ bool dSoundSource_c::startObjHitSound(u32 baseSoundId, dSoundSourceIf_c *source, u32 soundId = baseSoundId; if (!sIsStartingBaseSound) { - u32 tmp = d_s_vt_0x194(soundId); + u32 tmp = overrideStartSoundId(soundId); if (tmp == -1) { resetTempParams(); return false; } - soundId = d_s_vt_0x19C(tmp, static_cast(source)); + soundId = overrideHitObjSoundId(tmp, static_cast(source)); if (soundId == -1) { resetTempParams(); return false; @@ -443,7 +443,7 @@ bool dSoundSource_c::startBgHitSound(u32 baseSoundId, u32 polyAttr0, u32 polyAtt u32 soundId = baseSoundId; if (!sIsStartingBaseSound) { - u32 tmp = d_s_vt_0x194(soundId); + u32 tmp = overrideStartSoundId(soundId); if (tmp == -1) { resetTempParams(); return false; @@ -480,7 +480,7 @@ bool dSoundSource_c::startSoundAtPosition2(u32 soundId, const nw4r::math::VEC3 * u32 actualSoundId = soundId; if (!sIsStartingBaseSound) { - actualSoundId = d_s_vt_0x194(soundId); + actualSoundId = overrideStartSoundId(soundId); if (actualSoundId == -1) { resetTempParams(); return false; @@ -548,7 +548,7 @@ dSoundSource_c::startSoundAtPosition(u32 soundId, const nw4r::math::VEC3 *positi return ac; } -u32 dSoundSource_c::d_s_vt_0x19C(u32 soundId, dSoundSource_c *source) { +u32 dSoundSource_c::overrideHitObjSoundId(u32 soundId, dSoundSource_c *source) { if (source == nullptr) { return soundId; } @@ -824,7 +824,7 @@ nw4r::snd::SoundStartable::StartResult dSoundSource_c::setupSound( if (holdFlag) { anotherSoundId = d_s_vt_0x1A0(soundId, 1); } else { - anotherSoundId = d_s_vt_0x194(soundId); + anotherSoundId = overrideStartSoundId(soundId); } if (anotherSoundId == -1) { return onSetupError(); @@ -924,7 +924,7 @@ nw4r::snd::SoundStartable::StartResult dSoundSource_c::onSetupError() { return START_ERR_USER; } -u32 dSoundSource_c::d_s_vt_0x194(u32 soundId) { +u32 dSoundSource_c::overrideStartSoundId(u32 soundId) { return soundId; } diff --git a/src/d/snd/d_snd_source_equipment.cpp b/src/d/snd/d_snd_source_equipment.cpp new file mode 100644 index 00000000..d0c714df --- /dev/null +++ b/src/d/snd/d_snd_source_equipment.cpp @@ -0,0 +1,148 @@ +#include "d/snd/d_snd_source_equipment.h" + +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/snd/d_snd_source.h" +#include "d/snd/d_snd_source_enums.h" +#include "d/snd/d_snd_state_mgr.h" +#include "d/snd/d_snd_wzsound.h" + +dSndSourceEquipment_c::dSndSourceEquipment_c( + u8 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup +) + : dSoundSource_c(sourceType, ac, name, pOwnerGroup) {} + +void dSndSourceEquipment_c::shutdown() { + dSoundSource_c::shutdown(); + if (mSourceType == SND_SOURCE_ARROW && !mIsDisabled) { + stopAllSound(2); + } +} + +u32 dSndSourceEquipment_c::overrideStartSoundId(u32 soundId) { + switch (mSourceType) { + case SND_SOURCE_BLADE: + if (soundId == SE_SW_PUTIN && (dSndStateMgr_c::GetInstance()->isInEvent("ECaptain_c_dead") || + dSndStateMgr_c::GetInstance()->isInEvent("ECaptain_c_deadType2"))) { + // TODO: I guess there would be a distracting sword stow sound in the Scervo death sequence? + return -1; + } + break; + case SND_SOURCE_SHIELD: + switch (soundId) { + case SE_SH_GIRD_HIT: + if (mpCtxParam != nullptr) { + switch (mpCtxParam->intParam) { + case 1: soundId = SE_SH_GIRD_HIT_FIRE; break; + case 2: + case 4: soundId = SE_SH_GIRD_HIT_ELEC; break; + case 3: soundId = SE_SH_GIRD_HIT_CURSE; break; + } + } + break; + case SE_SH_GIRD_JUST: + if (mpCtxParam != nullptr) { + switch (mpCtxParam->intParam) { + case 1: soundId = SE_SH_GIRD_JUST_FIRE; break; + case 2: + case 4: soundId = SE_SH_GIRD_JUST_ELEC; break; + case 3: soundId = SE_SH_GIRD_JUST_CURSE; break; + } + } + break; + case SE_SH_BREAK: + // TODO enum + if (dAcPy_c::getCurrentlyEquippedShieldType() == 0) { + soundId = SE_SH_BREAK_WOOD; + break; + } + break; + } + break; + case SND_SOURCE_BOOMERANG: + if (soundId == SE_BE_HIT_DMG || soundId == SE_BE_COME_BACK) { + // Not sure if this override handler is the right place for a stop call + stopSounds(SE_BE_THROW_RC, 10); + } + break; + case SND_SOURCE_BOMB: + if (soundId == SE_BM_FALL_WATER) { + // Not sure if this override handler is the right place for a shutdown call + shutdown(); + } + break; + case SND_SOURCE_ARROW: + if (soundId != SE_AW_FLY) { + stopSounds(SE_AW_FLY, 1); + shutdown(); + } + } + return soundId; +} + +void dSndSourceEquipment_c::postStartSound(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id) { + dSoundSource_c::postStartSound(handle, pSound, id); + handleRemoCon(&handle, id); +} + +u32 dSndSourceEquipment_c::overrideHitObjSoundId(u32 soundId, dSoundSource_c *source) { + if (source == nullptr) { + return soundId; + } + u32 overrideId = soundId; + if (checkUserParamMask(soundId, 0x200)) { + overrideId = modifySoundId(soundId, source); + } + if (overrideId == soundId) { + switch (source->getCategory()) { + case SND_SOURCE_CATEGORY_OBJECT: + switch (soundId) { + case SE_SW_HIT: + if (source->getSourceType() == SND_SOURCE_ITEM || + source->getSourceType() == SND_SOURCE_BAMBOO) { + return -1; + } else { + overrideId = SE_SW_HIT_OBJ; + } + break; + case SE_SW_HIT_DMG: overrideId = SE_SW_HIT_OBJ; break; + case SE_SW_HIT_DMG_STAB: overrideId = SE_SW_HIT_OBJ; break; + case SE_SW_HIT_NO_DMG: overrideId = SE_SW_HIT_NO_DMG_OBJ; break; + case SE_SW_BEAM_HIT_DMG: overrideId = SE_SW_BEAM_HIT; break; + case SE_WI_HIT_DMG: overrideId = SE_WI_HIT; break; + case SE_HS_HIT_DMG: overrideId = SE_HS_REBOUND; break; + } + break; + case SND_SOURCE_CATEGORY_ENEMY: break; + case SND_SOURCE_CATEGORY_NPC: + if (source->getSourceType() != SND_SOURCE_INSECT) { + if (soundId == SE_BE_HIT) { + overrideId = SE_BE_HIT_NPC; + } else { + overrideId = -1; + } + } + break; + case SND_SOURCE_CATEGORY_EQUIPMENT: + if (source->getSourceType() == SND_SOURCE_BOMB && soundId == SE_BE_HIT_DMG) { + overrideId = SE_BE_HIT; + } else { + overrideId = -1; + } + break; + default: overrideId = -1; break; + } + } + return overrideId; +} + +dSndSourceEquipmentWhip_c::dSndSourceEquipmentWhip_c( + u8 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup +) + : dSndSourceEquipment_c(sourceType, ac, name, pOwnerGroup) {} + +void dSndSourceEquipmentWhip_c::postCalc() { + if (dAcPy_c::GetLink() != nullptr && dAcPy_c::GetLink()->isUsingWhip()) { + holdSound(SE_WI_FX_LV); + } +}