diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 80e00be5..b7216957 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -10721,7 +10721,7 @@ fn_8019D890 = .text:0x8019D890; // type:function size:0x2E8 fn_8019DB80 = .text:0x8019DB80; // type:function size:0x158 fn_8019DCE0 = .text:0x8019DCE0; // type:function size:0x140 fn_8019DE20 = .text:0x8019DE20; // type:function size:0x3C -dCamera__someShift6_0x1 = .text:0x8019DE60; // type:function size:0xC +isUnderwater__9dCamera_cCFv = .text:0x8019DE60; // type:function size:0xC fn_8019DE70 = .text:0x8019DE70; // type:function size:0x2A4 fn_8019E120 = .text:0x8019E120; // type:function size:0xC4 fn_8019E1F0 = .text:0x8019E1F0; // type:function size:0x10 @@ -20073,12 +20073,12 @@ fn_80362730 = .text:0x80362730; // type:function size:0x8 fn_80362740 = .text:0x80362740; // type:function size:0x59C EnemySoundMgr__update = .text:0x80362CE0; // type:function size:0xFC EnemySoundMgr__enemyMusicRelated = .text:0x80362DE0; // type:function size:0x154 -fn_80362F40 = .text:0x80362F40; // type:function size:0x770 +setEvent__14dSndStateMgr_cFPCc = .text:0x80362F40; // type:function size:0x770 initializeEventCallbacks__14dSndStateMgr_cFPCc = .text:0x803636B0; // type:function size:0xCC convertSeLabelToSoundId__14dSndStateMgr_cFPCc = .text:0x80363780; // type:function size:0xCC fn_80363850 = .text:0x80363850; // type:function size:0xA8 fn_80363900 = .text:0x80363900; // type:function size:0xA8 -fn_803639B0 = .text:0x803639B0; // type:function size:0xA8 +doLabelSuffix__14dSndStateMgr_cFPCc = .text:0x803639B0; // type:function size:0xA8 fn_80363A60 = .text:0x80363A60; // type:function size:0x5C fn_80363AC0 = .text:0x80363AC0; // type:function size:0x60 fn_80363B20 = .text:0x80363B20; // type:function size:0x54 @@ -20090,13 +20090,13 @@ fn_80363D00 = .text:0x80363D00; // type:function size:0x60 fn_80363D60 = .text:0x80363D60; // type:function size:0x54 fn_80363DC0 = .text:0x80363DC0; // type:function size:0xC fn_80363DD0 = .text:0x80363DD0; // type:function size:0x1AC -fn_80363F80 = .text:0x80363F80; // type:function size:0x48 +doSe__14dSndStateMgr_cFPCc = .text:0x80363F80; // type:function size:0x48 fn_80363FD0 = .text:0x80363FD0; // type:function size:0x24C fn_80364220 = .text:0x80364220; // type:function size:0x9C playFanOrBgm__14dSndStateMgr_cFUl = .text:0x803642C0; // type:function size:0x84 -fn_80364350 = .text:0x80364350; // type:function size:0x48 +doBgm__14dSndStateMgr_cFPCc = .text:0x80364350; // type:function size:0x48 fn_803643A0 = .text:0x803643A0; // type:function size:0x130 -fn_803644D0 = .text:0x803644D0; // type:function size:0x40 +doCmd__14dSndStateMgr_cFPCc = .text:0x803644D0; // type:function size:0x40 fn_80364510 = .text:0x80364510; // type:function size:0x60 handleSe__14dSndStateMgr_cFv = .text:0x80364570; // type:function size:0x8 handleSeLv__14dSndStateMgr_cFv = .text:0x80364580; // type:function size:0x1C4 @@ -20110,13 +20110,13 @@ __cl__25SoundStopperIfParamFlag20FRQ34nw4r3snd11SoundHandle = .text:0x80364A40; fn_80364AE0 = .text:0x80364AE0; // type:function size:0x8C fn_80364B70 = .text:0x80364B70; // type:function size:0xD0 resetEventVars__14dSndStateMgr_cFv = .text:0x80364C40; // type:function size:0xBC -fn_80364D00 = .text:0x80364D00; // type:function size:0x94 -isInEvent__14dSndStateMgr_cCFv = .text:0x80364DA0; // type:function size:0xC +onCameraCut__14dSndStateMgr_cFl = .text:0x80364D00; // type:function size:0x94 +isInEvent__14dSndStateMgr_cFv = .text:0x80364DA0; // type:function size:0xC isInEvent__14dSndStateMgr_cFPCc = .text:0x80364DB0; // type:function size:0x2C -doMsgStart__14dSndStateMgr_cFl = .text:0x80364DE0; // type:function size:0x7C -doMsgEnd__14dSndStateMgr_cFv = .text:0x80364E60; // type:function size:0x54 -doMsgWaitStart__14dSndStateMgr_cFv = .text:0x80364EC0; // type:function size:0x90 -doMsgWaitEnd__14dSndStateMgr_cFv = .text:0x80364F50; // type:function size:0x7C +onMsgStart__14dSndStateMgr_cFl = .text:0x80364DE0; // type:function size:0x7C +onMsgEnd__14dSndStateMgr_cFv = .text:0x80364E60; // type:function size:0x54 +onMsgWaitStart__14dSndStateMgr_cFv = .text:0x80364EC0; // type:function size:0x90 +onMsgWaitEnd__14dSndStateMgr_cFv = .text:0x80364F50; // type:function size:0x7C setFlowEvent__14dSndStateMgr_cFUl = .text:0x80364FD0; // type:function size:0x50 onSkipEvent__14dSndStateMgr_cCFv = .text:0x80365020; // type:function size:0x84 fn_803650B0 = .text:0x803650B0; // type:function size:0x6C @@ -20128,19 +20128,19 @@ fn_803651A0 = .text:0x803651A0; // type:function size:0xA0 fn_80365240 = .text:0x80365240; // type:function size:0x1F8 fn_80365440 = .text:0x80365440; // type:function size:0x10C fn_80365550 = .text:0x80365550; // type:function size:0x1A8 -setUnderwaterLpfFreq = .text:0x80365700; // type:function size:0xCC -fn_803657D0 = .text:0x803657D0; // type:function size:0x78 -fn_80365850 = .text:0x80365850; // type:function size:0x70 -fn_803658C0 = .text:0x803658C0; // type:function size:0x5C -fn_80365920 = .text:0x80365920; // type:function size:0x4C -fn_80365970 = .text:0x80365970; // type:function size:0x8 -fn_80365980 = .text:0x80365980; // type:function size:0x54 -resetBgmAndStageEffectLpfFreq = .text:0x803659E0; // type:function size:0x4C -resetBgmLpfFreq = .text:0x80365A30; // type:function size:0x48 +setFiltersIfUnderwater__14dSndStateMgr_cFv = .text:0x80365700; // type:function size:0xCC +setBgmLpfAndFxSendIfUnderwater__14dSndStateMgr_cFv = .text:0x803657D0; // type:function size:0x78 +resetLpfAndFxSend__14dSndStateMgr_cFv = .text:0x80365850; // type:function size:0x70 +resetBgmLpfAndFxSend__14dSndStateMgr_cFv = .text:0x803658C0; // type:function size:0x5C +setBgmAndStageEffectLpf__14dSndStateMgr_cFv = .text:0x80365920; // type:function size:0x4C +setBgmLpf__14dSndStateMgr_cFv = .text:0x80365970; // type:function size:0x8 +setBgmLpf__14dSndStateMgr_cFl = .text:0x80365980; // type:function size:0x54 +resetBgmAndStageEffectLpf__14dSndStateMgr_cFv = .text:0x803659E0; // type:function size:0x4C +resetBgmLpf__14dSndStateMgr_cFv = .text:0x80365A30; // type:function size:0x48 fn_80365A80 = .text:0x80365A80; // type:function size:0x4C restoreEffects__14dSndStateMgr_cFv = .text:0x80365AD0; // type:function size:0xA8 fn_80365B80 = .text:0x80365B80; // type:function size:0x5C -fn_80365BE0 = .text:0x80365BE0; // type:function size:0x70 +getUserParamVolume__14dSndStateMgr_cFUl = .text:0x80365BE0; // type:function size:0x70 fn_80365C50 = .text:0x80365C50; // type:function size:0xC8 fn_80365D20 = .text:0x80365D20; // type:function size:0x3C getStageName__14dSndStateMgr_cFl = .text:0x80365D60; // type:function size:0x24 @@ -20341,14 +20341,14 @@ remove__42SndMgrDisposer<24dSndAreaSoundEffectMgr_c>Fv = .text:0x8036A480; // ty __ct__24dSndAreaSoundEffectMgr_cFv = .text:0x8036A490; // type:function size:0x88 __dt__15dSndAreaSound_cFv = .text:0x8036A520; // type:function size:0x58 calc__24dSndAreaSoundEffectMgr_cFv = .text:0x8036A580; // type:function size:0x74 -fn_8036A600 = .text:0x8036A600; // type:function size:0x88 -fn_8036A690 = .text:0x8036A690; // type:function size:0x9C +calcPlayerVolume__24dSndAreaSoundEffectMgr_cFv = .text:0x8036A600; // type:function size:0x88 +calcActorVolume__24dSndAreaSoundEffectMgr_cFv = .text:0x8036A690; // type:function size:0x9C startSound__24dSndAreaSoundEffectMgr_cFUlUl = .text:0x8036A730; // type:function size:0xEC fn_8036A820 = .text:0x8036A820; // type:function size:0x328 fn_8036AB50 = .text:0x8036AB50; // type:function size:0x20 onEventStart__24dSndAreaSoundEffectMgr_cFv = .text:0x8036AB70; // type:function size:0x4 onEventEnd__24dSndAreaSoundEffectMgr_cFv = .text:0x8036AB80; // type:function size:0x4 -fn_8036AB90 = .text:0x8036AB90; // type:function size:0xFC +holdInWaterLvSound__24dSndAreaSoundEffectMgr_cFf = .text:0x8036AB90; // type:function size:0xFC stopSounds__24dSndAreaSoundEffectMgr_cFl = .text:0x8036AC90; // type:function size:0x68 fn_8036AD00 = .text:0x8036AD00; // type:function size:0xB0 isPlayingAnySound__24dSndAreaSoundEffectMgr_cCFv = .text:0x8036ADB0; // type:function size:0x44 @@ -20362,8 +20362,8 @@ fn_8036B3E0 = .text:0x8036B3E0; // type:function size:0xA4 fn_8036B490 = .text:0x8036B490; // type:function size:0x124 pauseAllSounds__24dSndAreaSoundEffectMgr_cFv = .text:0x8036B5C0; // type:function size:0x6C fn_8036B630 = .text:0x8036B630; // type:function size:0x170 -fn_8036B7A0 = .text:0x8036B7A0; // type:function size:0x110 -fn_8036B8B0 = .text:0x8036B8B0; // type:function size:0x20 +setTgSoundVolume__24dSndAreaSoundEffectMgr_cFfl = .text:0x8036B7A0; // type:function size:0x110 +__cl__17SoundVolumeSetterFRQ34nw4r3snd11SoundHandle = .text:0x8036B8B0; // type:function size:0x20 __ct__15dSndAreaSound_cFv = .text:0x8036B8D0; // type:function size:0x54 cancel__15dSndAreaSound_cFv = .text:0x8036B930; // type:function size:0x34 calc__15dSndAreaSound_cFv = .text:0x8036B970; // type:function size:0xC4 @@ -38009,7 +38009,7 @@ lbl_80548AF0 = .data:0x80548AF0; // type:object size:0xC lbl_80548AFC = .data:0x80548AFC; // type:object size:0xC lbl_80548B08 = .data:0x80548B08; // type:object size:0x14 lbl_80548B1C = .data:0x80548B1C; // type:object size:0x10 -lbl_80548B2C = .data:0x80548B2C; // type:object size:0xC +__vt__17SoundVolumeSetter = .data:0x80548B2C; // type:object size:0xC __vt__42SndMgrDisposer<24dSndAreaSoundEffectMgr_c> = .data:0x80548B38; // type:object size:0x10 lbl_80548B48 = .data:0x80548B48; // type:object size:0x30 __vt__33dSndControlSoundStrmTrackVolume_c = .data:0x80548B78; // type:object size:0x20 diff --git a/include/d/d_camera.h b/include/d/d_camera.h index f57fb520..6ad2ef47 100644 --- a/include/d/d_camera.h +++ b/include/d/d_camera.h @@ -33,6 +33,8 @@ public: mScreenShakeIntensity = val; } + bool isUnderwater() const; + private: /* 0x068 */ u8 _0x068[0x6C - 0x068]; /* 0x06C */ mVec3_c mPositionMaybe; diff --git a/include/d/snd/d_snd_area_sound_effect_mgr.h b/include/d/snd/d_snd_area_sound_effect_mgr.h index 2e450743..69696810 100644 --- a/include/d/snd/d_snd_area_sound_effect_mgr.h +++ b/include/d/snd/d_snd_area_sound_effect_mgr.h @@ -5,6 +5,7 @@ #include "d/snd/d_snd_actor.h" #include "d/snd/d_snd_area_sound.h" #include "d/snd/d_snd_util.h" +#include "nw4r/snd/snd_SoundHandle.h" SND_DISPOSER_FORWARD_DECL(dSndAreaSoundEffectMgr_c); @@ -25,19 +26,23 @@ public: void stopSounds(s32 fadeFrames); void pauseAllSounds(); + bool holdInWaterLvSound(f32 depth); void onEventStart(); void onEventEnd(); private: + void calcPlayerVolume(); + void calcActorVolume(); bool isPlayingAnySound() const; bool isPlayingSound(u32 soundId) const; + void setTgSoundVolume(f32 volume, s32 fadeFrames); /* 0x010 */ dSndAreaSound_c mSounds[3]; - /* 0x328 */ UNKWORD field_0x328; + /* 0x328 */ nw4r::snd::SoundHandle mInWaterLvHandle; /* 0x32C */ f32 field_0x32C; /* 0x330 */ f32 field_0x330; /* 0x334 */ dSndActor_c mActor; - /* 0x388 */ f32 field_0x388; + /* 0x388 */ f32 mTargetVolume; }; #endif diff --git a/include/d/snd/d_snd_checkers.h b/include/d/snd/d_snd_checkers.h index 880d65e3..22a56097 100644 --- a/include/d/snd/d_snd_checkers.h +++ b/include/d/snd/d_snd_checkers.h @@ -9,7 +9,15 @@ 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) {} + 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; @@ -125,4 +133,18 @@ public: private: }; +class SoundVolumeSetter { +public: + SoundVolumeSetter() {} + ~SoundVolumeSetter() {} + + virtual void operator()(nw4r::snd::SoundHandle &pHandle) { + pHandle.SetVolume(mVolume, mFadeFrames); + } + +public: + /* 0x04 */ f32 mVolume; + /* 0x08 */ s32 mFadeFrames; +}; + #endif diff --git a/include/d/snd/d_snd_event.h b/include/d/snd/d_snd_event.h index 2c394869..5f3ad071 100644 --- a/include/d/snd/d_snd_event.h +++ b/include/d/snd/d_snd_event.h @@ -5,6 +5,7 @@ typedef void (*SndEventCallback)(void); typedef void (*SndEventFinalizeCallback)(bool skipped); +typedef void (*SndEventMsgWaitCallback)(u32 msgWaitSelectCounter); struct SndEventDef { /* 0x00 */ const char *eventName; @@ -12,7 +13,8 @@ struct SndEventDef { /* 0x08 */ SndEventCallback initializeCb; /* 0x0C */ SndEventCallback executeCb; /* 0x10 */ SndEventFinalizeCallback finalizeCb; - /* 0x14 */ u8 _0x14[0x1C - 0x14]; // always zero + /* 0x14 */ SndEventMsgWaitCallback msgWaitStartCb; // always null + /* 0x18 */ SndEventMsgWaitCallback msgWaitEndCb; // always null }; enum SndEvent_e { diff --git a/include/d/snd/d_snd_state_mgr.h b/include/d/snd/d_snd_state_mgr.h index a164d78c..75d279ed 100644 --- a/include/d/snd/d_snd_state_mgr.h +++ b/include/d/snd/d_snd_state_mgr.h @@ -73,8 +73,8 @@ public: return field_0x058; } - u32 getField_0x11C() const { - return field_0x11C; + u32 getFrameCounter() const { + return mFrameCounter; } f32 getField_0x49C() const { @@ -87,6 +87,10 @@ public: bool checkFlag0x18(u32 mask); + bool checkFlag0x258(u32 mask) const { + return field_0x258 & mask; + } + bool checkFlag0x10(u32 mask) const { return field_0x010 & mask; } @@ -122,14 +126,16 @@ public: // not sure, subtype is unused bool isActiveDemoMaybe(s32 subtype) const; bool isInEvent(const char *eventName); - bool isInEvent() const; + bool isInEvent(); bool onSkipEvent() const; - void doMsgStart(s32 idx); - void doMsgEnd(); + void onMsgStart(s32 idx); + void onMsgEnd(); - void doMsgWaitStart(); - void doMsgWaitEnd(); + void onMsgWaitStart(); + void onMsgWaitEnd(); + + f32 getUserParamVolume(u32 userParam); // TODO better names static const char *getStageName(s32 id); @@ -154,6 +160,18 @@ public: u32 getSoundIdForStageAndLayer(SoundIdLookup_e lookup, const char *stageName, s32 layer, s32 stageId); + void setFiltersIfUnderwater(); + void setBgmLpfAndFxSendIfUnderwater(); + void resetLpfAndFxSend(); + void resetBgmLpfAndFxSend(); + void setBgmAndStageEffectLpf(); + void setBgmLpf(); + void setBgmLpf(s32 fadeFrames); + void resetBgmAndStageEffectLpf(); + void resetBgmLpf(); + + void onCameraCut(s32 cutIdx); + private: void resetOverrides(); void initializeEventCallbacks(const char *name); @@ -167,6 +185,13 @@ private: u32 getBgmLabelSoundId(); bool playFanOrBgm(u32 soundId); + void doBgm(const char *label); + void doSe(const char *label); + void doCmd(const char *label); + + void doLabelSuffix(const char *suffix); + u32 getSeCameraId(); + void handleFan(); void handleSe(); void handleCmd(); @@ -221,14 +246,14 @@ private: /* 0x084 */ UNKWORD field_0x084; /* 0x088 */ UNKWORD field_0x088; /* 0x08C */ s32 mSoundEventId; - /* 0x090 */ UNKWORD field_0x090; + /* 0x090 */ s32 mCameraCutCounter; /* 0x094 */ u32 mEventFlags; /* 0x098 */ SizedString<64> mEventName; /* 0x0D8 */ SizedString<64> mPrevEventName; /* 0x118 */ const char *field_0x118; - /* 0x11C */ u32 field_0x11C; - /* 0x120 */ UNKWORD field_0x120; - /* 0x124 */ UNKWORD field_0x124; + /* 0x11C */ u32 mFrameCounter; + /* 0x120 */ u32 mCameraCutFrameCounter; + /* 0x124 */ u32 mMsgFrameCounter; /* 0x128 */ u32 mSeLvSoundId; /* 0x12C */ SizedString<64> mSeName; /* 0x16C */ SizedString<64> mBgmName; @@ -243,10 +268,10 @@ private: /* 0x240 */ UNKWORD field_0x240; /* 0x244 */ UNKWORD field_0x244; /* 0x248 */ UNKWORD field_0x248; - /* 0x24C */ UNKWORD field_0x24C; - /* 0x250 */ UNKWORD field_0x250; + /* 0x24C */ s32 mMsgCounter; + /* 0x250 */ s32 mMsgWaitSelectCounter; /* 0x254 */ u8 field_0x254; - /* 0x258 */ UNKWORD field_0x258; + /* 0x258 */ u32 field_0x258; /* 0x25C */ nw4r::snd::FxReverbStdDpl2 mFx; /* 0x48C */ UNKWORD field_0x48C; /* 0x490 */ f32 field_0x490; diff --git a/include/toBeSorted/music_mgrs.h b/include/toBeSorted/music_mgrs.h index ef62b8b2..d0a9ca56 100644 --- a/include/toBeSorted/music_mgrs.h +++ b/include/toBeSorted/music_mgrs.h @@ -24,6 +24,5 @@ extern "C" void fn_80362730(dSndStateMgr_c *); extern "C" void fn_80365D20(dSndStateMgr_c *); extern "C" void fn_803624F0(dSndStateMgr_c *); extern "C" void fn_80365020(dSndStateMgr_c *); -extern "C" void fn_80364D00(dSndStateMgr_c *, s32); #endif diff --git a/src/d/snd/d_snd_3d_manager.cpp b/src/d/snd/d_snd_3d_manager.cpp index 07a14b51..cf4e6a37 100644 --- a/src/d/snd/d_snd_3d_manager.cpp +++ b/src/d/snd/d_snd_3d_manager.cpp @@ -81,7 +81,7 @@ void dSnd3DManager_c::updateFromCamera(EGG::LookAtCamera &camera) { f32 prevCameraPosSqVelocity = mCameraPosSqVelocity; mCameraAtSqVelocity = VECSquareDistance(camera.mAt, mCamera.mAt); mCameraPosSqVelocity = VECSquareDistance(camera.mPos, mCamera.mPos); - if (dSndStateMgr_c::GetInstance()->getField_0x11C() > 30) { + if (dSndStateMgr_c::GetInstance()->getFrameCounter() > 30) { bool bigMovement = false; bool hugeMovement = false; if (mTimer > 0) { @@ -116,7 +116,7 @@ void dSnd3DManager_c::updateFromCamera(EGG::LookAtCamera &camera) { } if (bigMovement) { - fn_80364D00(ENEMY_SOUND_MGR, -1); + dSndStateMgr_c::GetInstance()->onCameraCut(-1); mTimer = 30; } } diff --git a/src/d/snd/d_snd_area_sound_effect_mgr.cpp b/src/d/snd/d_snd_area_sound_effect_mgr.cpp index 691aa918..e574175d 100644 --- a/src/d/snd/d_snd_area_sound_effect_mgr.cpp +++ b/src/d/snd/d_snd_area_sound_effect_mgr.cpp @@ -2,24 +2,65 @@ #include "common.h" #include "d/d_sc_game.h" +#include "d/snd/d_snd_checkers.h" +#include "d/snd/d_snd_control_player_mgr.h" #include "d/snd/d_snd_mgr.h" #include "d/snd/d_snd_player_mgr.h" +#include "d/snd/d_snd_state_mgr.h" #include "d/snd/d_snd_util.h" +#include "d/snd/d_snd_wzsound.h" +#include "nw4r/snd/snd_SoundPlayer.h" #include "nw4r/snd/snd_SoundStartable.h" SND_DISPOSER_DEFINE(dSndAreaSoundEffectMgr_c); dSndAreaSoundEffectMgr_c::dSndAreaSoundEffectMgr_c() - : field_0x328(0), - field_0x32C(1.0f), - field_0x330(1.0f), - mActor(dSndMgr_c::GetInstance()->getPlayer()), - field_0x388(1.0f) {} + : field_0x32C(1.0f), field_0x330(1.0f), mActor(dSndMgr_c::GetInstance()->getPlayer()), mTargetVolume(1.0f) {} void dSndAreaSoundEffectMgr_c::calc() { for (int i = 0; i < 3; i++) { mSounds[i].calc(); } + calcPlayerVolume(); + calcActorVolume(); +} + +void dSndAreaSoundEffectMgr_c::calcPlayerVolume() { + if (dSndStateMgr_c::GetInstance()->checkEventFlag(dSndStateMgr_c::EVENT_MUTE_STAGE_EFFECTS_FULL)) { + dSndControlPlayerMgr_c::GetInstance()->setStageEffectsMuteVolume(0.0f); + } else if (dSndStateMgr_c::GetInstance()->checkEventFlag(dSndStateMgr_c::EVENT_MUTE_STAGE_EFFECTS_PARTIAL)) { + dSndControlPlayerMgr_c::GetInstance()->setStageEffectsMuteVolume(0.3f); + } + + if (dSndPlayerMgr_c::GetInstance()->checkFlag(dSndPlayerMgr_c::MGR_PAUSE)) { + dSndControlPlayerMgr_c::GetInstance()->setStageEffectsMuteVolume(0.3f); + } + + if (dSndStateMgr_c::GetInstance()->checkFlag0x258(0x04)) { + dSndControlPlayerMgr_c::GetInstance()->setStageEffectsMuteVolume(0.3f); + } +} + +void dSndAreaSoundEffectMgr_c::calcActorVolume() { + // TODO - FPR regswap + f32 volume = mActor.GetVolume(); + f32 target = mTargetVolume; + if (volume != target) { + if (volume - target > 0.05f) { + volume -= 0.05f; + } else if (target - volume > 0.05f) { + volume += 0.05f; + } + + if (volume < 0.0f) { + volume = 0.0f; + } else if (volume > 2.0f) { + volume = 2.0f; + } + mActor.SetVolume(volume); + setTgSoundVolume(volume, 0); + } + mTargetVolume = 1.0f; } bool dSndAreaSoundEffectMgr_c::startSound(u32 soundId, u32 handleIdx) { @@ -50,6 +91,33 @@ bool dSndAreaSoundEffectMgr_c::startSound(u32 soundId, u32 handleIdx) { return res; } +bool dSndAreaSoundEffectMgr_c::holdInWaterLvSound(f32 depth) { + if (depth <= 0) { + return false; + } + + // TODO: Ugh, maybe convert the enums to unsigned ints? + bool ret = dSndMgr_c::GetInstance()->holdSound(&mInWaterLvHandle, (unsigned int)SE_A_IN_WATER_LV); + if (ret) { + f32 volume = 1.0f; + if (depth < 600.0f) { + volume = (depth / 600.0f) * 0.5f + 0.5f; + } + mInWaterLvHandle.SetVolume(volume, 0); + } + + f32 otherVolume = 0.0f; + if (depth < 300.0f) { + otherVolume = (depth * -0.7f) / 300.0f + 0.7f; + if (otherVolume < 0.0f) { + otherVolume = 0.0f; + } + } + mTargetVolume *= otherVolume; + + return ret; +} + void dSndAreaSoundEffectMgr_c::onEventStart() { // no-op } @@ -81,3 +149,18 @@ bool dSndAreaSoundEffectMgr_c::isPlayingSound(u32 soundId) const { } return false; } + +void dSndAreaSoundEffectMgr_c::setTgSoundVolume(f32 volume, s32 fadeFrames) { + nw4r::snd::SoundPlayer *player = + dSndControlPlayerMgr_c::GetInstance()->getPlayer1(dSndPlayerMgr_c::PLAYER_TG_SOUND); + SoundVolumeSetter setter; + setter.mFadeFrames = fadeFrames; + if (volume > 1.0f) { + volume = 1.0f; + } else if (volume < 0.0f) { + volume = 0.0f; + } + setter.mVolume = volume; + + player->ForEachSound(setter, false); +} diff --git a/src/d/snd/d_snd_player_mgr.cpp b/src/d/snd/d_snd_player_mgr.cpp index 741690e1..9e1cd08f 100644 --- a/src/d/snd/d_snd_player_mgr.cpp +++ b/src/d/snd/d_snd_player_mgr.cpp @@ -211,23 +211,23 @@ void dSndPlayerMgr_c::setMsgActor(s32 msgIdx, dAcBase_c *actor) { } else { dSndSmallEffectMgr_c::GetInstance()->resetButtonPressSound(); } - dSndStateMgr_c::GetInstance()->doMsgStart(msgIdx); + dSndStateMgr_c::GetInstance()->onMsgStart(msgIdx); } void dSndPlayerMgr_c::unsetMsgActor() { - dSndStateMgr_c::GetInstance()->doMsgEnd(); + dSndStateMgr_c::GetInstance()->onMsgEnd(); dSndSmallEffectMgr_c::GetInstance()->resetButtonPressSound(); dSndSourceMgr_c::GetInstance()->setMsgSource(nullptr); } void dSndPlayerMgr_c::enterMsgWait() { onFlag(MGR_MSG_WAIT); - dSndStateMgr_c::GetInstance()->doMsgWaitStart(); + dSndStateMgr_c::GetInstance()->onMsgWaitStart(); } void dSndPlayerMgr_c::leaveMsgWait() { offFlag(MGR_MSG_WAIT); - dSndStateMgr_c::GetInstance()->doMsgWaitEnd(); + dSndStateMgr_c::GetInstance()->onMsgWaitEnd(); } nw4r::snd::SoundStartable::StartResult dSndPlayerMgr_c::startSound( diff --git a/src/d/snd/d_snd_state_mgr.cpp b/src/d/snd/d_snd_state_mgr.cpp index 8dd9ff4d..ca5bb01e 100644 --- a/src/d/snd/d_snd_state_mgr.cpp +++ b/src/d/snd/d_snd_state_mgr.cpp @@ -1,6 +1,7 @@ #include "d/snd/d_snd_state_mgr.h" #include "common.h" +#include "d/d_camera.h" #include "d/d_sc_game.h" #include "d/snd/d_snd_area_sound_effect_mgr.h" #include "d/snd/d_snd_bgm_mgr.h" @@ -14,6 +15,7 @@ #include "d/snd/d_snd_util.h" #include "egg/core/eggHeap.h" #include "nw4r/snd/snd_FxReverbStdDpl2.h" +#include "nw4r/snd/snd_SeqSoundHandle.h" #include "nw4r/snd/snd_SoundPlayer.h" #include "nw4r/snd/snd_global.h" #include "sized_string.h" @@ -49,12 +51,12 @@ dSndStateMgr_c::dSndStateMgr_c() field_0x084(0), field_0x088(0), mSoundEventId(SND_EVENT_0x89), - field_0x090(0), + mCameraCutCounter(0), mEventFlags(0), field_0x118(nullptr), - field_0x11C(0), - field_0x120(0), - field_0x124(0), + mFrameCounter(0), + mCameraCutFrameCounter(0), + mMsgFrameCounter(0), mSeLvSoundId(-1), field_0x22C(0), mpSoundEventDef(nullptr), @@ -64,8 +66,8 @@ dSndStateMgr_c::dSndStateMgr_c() field_0x240(0), field_0x244(0), field_0x248(0), - field_0x24C(-1), - field_0x250(0), + mMsgCounter(-1), + mMsgWaitSelectCounter(0), field_0x254(0), field_0x258(0), field_0x48C(0), @@ -313,9 +315,9 @@ void dSndStateMgr_c::setEvent(const char *eventName) { if (mSoundEventId != SND_EVENT_0x89) { onEventFlag(EVENT_IN_EVENT); - field_0x11C = 0; - field_0x120 = 0; - field_0x124 = 0; + mFrameCounter = 0; + mCameraCutFrameCounter = 0; + mMsgFrameCounter = 0; if (mpOnEventStartCallback != nullptr) { (mpOnEventStartCallback)(mSoundEventId, mEventFlags); } @@ -365,6 +367,22 @@ void dSndStateMgr_c::initializeEventCallbacks(const char *name) { } } +void dSndStateMgr_c::doLabelSuffix(const char *suffix) { + SizedString<64> label; + label.sprintf("%s%s", &mBgmName, suffix); + doBgm(label); + label.sprintf("%s%s", &mSeName, suffix); + doSe(label); + label.sprintf("%s%s", &mCmdName, suffix); + doCmd(label); +} + +u32 dSndStateMgr_c::getSeCameraId() { + SizedString<64> label; + label.sprintf("%s_C%d_%d", &mSeName, mCameraCutCounter, mCameraCutFrameCounter); + return convertSeLabelToSoundId(label); +} + void dSndStateMgr_c::handleSeLv() { SizedString<0x40> name = mSeName; name += "_LV"; @@ -405,6 +423,168 @@ bool dSndStateMgr_c::finalizeEvent(bool skipped) { return false; } +// TODO - the whole "camera cut" thing seems plausible but I haven't confirmed it yet +void dSndStateMgr_c::onCameraCut(s32 cutIdx) { + if (cutIdx <= 0) { + mCameraCutCounter++; + } else { + mCameraCutCounter = cutIdx; + } + mCameraCutFrameCounter = 0; + nw4r::snd::SeqSoundHandle::WriteGlobalVariable(1, mCameraCutCounter); + nw4r::snd::SeqSoundHandle::WriteGlobalVariable(2, 0); + SizedString<64> suffix; + suffix.sprintf("_C%d", mCameraCutCounter); + doLabelSuffix(suffix); +} + +bool dSndStateMgr_c::isInEvent() { + return checkEventFlag(EVENT_IN_EVENT); +} + +bool dSndStateMgr_c::isInEvent(const char *eventName) { + return streq(mEventName, eventName); +} + +void dSndStateMgr_c::onMsgStart(s32 idx) { + if (idx >= 0) { + mMsgCounter = idx; + } else { + mMsgCounter++; + } + field_0x254 = 1; + mMsgWaitSelectCounter = 0; + mMsgFrameCounter = 0; + SizedString<64> label; + label.sprintf("_MS%d", mMsgCounter); + doLabelSuffix(label); +} + +void dSndStateMgr_c::onMsgEnd() { + field_0x254 = 0; + SizedString<64> label; + label.sprintf("_ME%d", mMsgCounter); + doLabelSuffix(label); +} + +void dSndStateMgr_c::onMsgWaitStart() { + mMsgFrameCounter = 0; + mMsgWaitSelectCounter++; + + if (mpSoundEventDef != nullptr && mpSoundEventDef->msgWaitStartCb != nullptr) { + mpSoundEventDef->msgWaitStartCb(mMsgWaitSelectCounter); + } + + SizedString<64> label; + label.sprintf("_%M_WS%d", mMsgCounter, mMsgWaitSelectCounter); + doLabelSuffix(label); +} + +void dSndStateMgr_c::onMsgWaitEnd() { + if (mpSoundEventDef != nullptr && mpSoundEventDef->msgWaitEndCb != nullptr) { + mpSoundEventDef->msgWaitEndCb(mMsgWaitSelectCounter); + } + + SizedString<64> label; + label.sprintf("_%M_WE%d", mMsgCounter, mMsgWaitSelectCounter); + doLabelSuffix(label); +} + +void dSndStateMgr_c::setFiltersIfUnderwater() { + dCamera_c *cam = dScGame_c::getCamera(0); + if (cam == nullptr || cam->isUnderwater()) { + setBgmLpfAndFxSendIfUnderwater(); + for (u32 id = dSndPlayerMgr_c::PLAYER_LINK_BODY; id < dSndPlayerMgr_c::PLAYER_LINK_EQUIPMENT + 1; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, -0.45f, 15); + } + + for (u32 id = dSndPlayerMgr_c::PLAYER_ENEMY; id < dSndPlayerMgr_c::PLAYER_AREA + 1; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, -0.41f, 15); + } + + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(dSndPlayerMgr_c::PLAYER_AREA_IN_WATER_LV, -0.3f, 15); + + for (u32 id = dSndPlayerMgr_c::PLAYER_ENEMY; id <= dSndPlayerMgr_c::PLAYER_AREA_IN_WATER_LV; id++) { + dSndControlPlayerMgr_c::GetInstance()->setFxSend(id, 0.14f, 15); + } + } +} + +void dSndStateMgr_c::setBgmLpfAndFxSendIfUnderwater() { + dCamera_c *cam = dScGame_c::getCamera(0); + if (cam == nullptr || cam->isUnderwater()) { + for (u32 id = dSndPlayerMgr_c::PLAYER_BGM; id < dSndPlayerMgr_c::PLAYER_BGM_BATTLE + 1; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, -0.55f, 15); + dSndControlPlayerMgr_c::GetInstance()->setFxSend(id, 0.2f, 15); + } + } +} + +void dSndStateMgr_c::resetLpfAndFxSend() { + resetBgmLpfAndFxSend(); + for (u32 id = dSndPlayerMgr_c::PLAYER_LINK_BODY; id <= dSndPlayerMgr_c::PLAYER_AREA_IN_WATER_LV; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, 0.0f, 15); + } + + for (u32 id = dSndPlayerMgr_c::PLAYER_LINK_BODY; id <= dSndPlayerMgr_c::PLAYER_AREA_IN_WATER_LV; id++) { + dSndControlPlayerMgr_c::GetInstance()->setFxSend(id, 0.0f, 15); + } +} + +void dSndStateMgr_c::resetBgmLpfAndFxSend() { + for (u32 id = dSndPlayerMgr_c::PLAYER_BGM; id < dSndPlayerMgr_c::PLAYER_BGM_BATTLE + 1; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, 0.0f, 15); + dSndControlPlayerMgr_c::GetInstance()->setFxSend(id, 0.0f, 15); + } +} + +void dSndStateMgr_c::setBgmAndStageEffectLpf() { + setBgmLpf(); + for (u32 id = dSndPlayerMgr_c::PLAYER_TG_SOUND; id < dSndPlayerMgr_c::PLAYER_AREA + 1; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, -0.55f, 15); + } +} + +void dSndStateMgr_c::setBgmLpf() { + setBgmLpf(15); +} + +void dSndStateMgr_c::setBgmLpf(s32 fadeFrames) { + for (u32 id = dSndPlayerMgr_c::PLAYER_BGM; id < dSndPlayerMgr_c::PLAYER_BGM_BATTLE + 1; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, -0.55f, fadeFrames); + } +} + +void dSndStateMgr_c::resetBgmAndStageEffectLpf() { + resetBgmLpf(); + for (u32 id = dSndPlayerMgr_c::PLAYER_TG_SOUND; id < dSndPlayerMgr_c::PLAYER_AREA + 1; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, 0.0f, 15); + } +} + +void dSndStateMgr_c::resetBgmLpf() { + for (u32 id = dSndPlayerMgr_c::PLAYER_BGM; id < dSndPlayerMgr_c::PLAYER_BGM_BATTLE + 1; id++) { + dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(id, 0.0f, 15); + } +} + +f32 dSndStateMgr_c::getUserParamVolume(u32 userParam) { + s32 bit = 31; + for (int i = 0; i < 4; i++) { + if (((1 << bit) & userParam) != 0) { + switch (bit) { + case 31: return 0.3f; + case 30: return 0.2f; + case 29: return 0.1f; + case 28: return 0.02f; + } + } + + bit--; + } + return 0.0f; +} + const char *dSndStateMgr_c::getStageName(s32 id) { if (id >= SND_STAGE_MAX) { return "NULL";