diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 642fbb94..918049bc 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2377,6 +2377,7 @@ d/snd/d_snd_player_mgr.cpp: d/snd/d_snd_control_player_mgr.cpp: .text start:0x8035F050 end:0x80360C28 align:16 .ctors start:0x804DB914 end:0x804DB918 + .data start:0x805487A0 end:0x805487D0 .sbss start:0x80575D40 end:0x80575D58 .sdata2 start:0x8057D390 end:0x8057D3B8 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index fbd272c6..5ec7e144 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -20000,30 +20000,30 @@ fn_8035F610 = .text:0x8035F610; // type:function size:0x158 fn_8035F770 = .text:0x8035F770; // type:function size:0xDC calc__22dSndControlPlayerMgr_cFv = .text:0x8035F850; // type:function size:0x3C executeControls__22dSndControlPlayerMgr_cFv = .text:0x8035F890; // type:function size:0xAC -fn_8035F940 = .text:0x8035F940; // type:function size:0x168 +calcVolumes__22dSndControlPlayerMgr_cFv = .text:0x8035F940; // type:function size:0x168 fn_8035FAB0 = .text:0x8035FAB0; // type:function size:0x318 fn_8035FDD0 = .text:0x8035FDD0; // type:function size:0xE0 fn_8035FEB0 = .text:0x8035FEB0; // type:function size:0x11C fn_8035FFD0 = .text:0x8035FFD0; // type:function size:0xE0 -getPlayer1__22dSndControlPlayerMgr_cFl = .text:0x803600B0; // type:function size:0x70 -getPlayer2__22dSndControlPlayerMgr_cFl = .text:0x80360120; // type:function size:0x34 +getPlayer1__22dSndControlPlayerMgr_cCFUl = .text:0x803600B0; // type:function size:0x70 +getPlayer2__22dSndControlPlayerMgr_cCFUl = .text:0x80360120; // type:function size:0x34 fn_80360160 = .text:0x80360160; // type:function size:0xBC linkCtrl__22dSndControlPlayerMgr_cFP19dSndControlPlayer_c = .text:0x80360220; // type:function size:0x28 unlinkCtrl__22dSndControlPlayerMgr_cFP19dSndControlPlayer_c = .text:0x80360250; // type:function size:0x28 -fn_80360280 = .text:0x80360280; // type:function size:0x94 +setVolume__22dSndControlPlayerMgr_cFUlfl = .text:0x80360280; // type:function size:0x94 fn_80360320 = .text:0x80360320; // type:function size:0xC8 -fn_803603F0 = .text:0x803603F0; // type:function size:0xB0 -fn_803604A0 = .text:0x803604A0; // type:function size:0x48 +overrideVolume__22dSndControlPlayerMgr_cFUlfl = .text:0x803603F0; // type:function size:0xB0 +restoreVolume__22dSndControlPlayerMgr_cFUll = .text:0x803604A0; // type:function size:0x48 setLpfFreq__22dSndControlPlayerMgr_cFUlfl = .text:0x803604F0; // type:function size:0x20 setFxSend__22dSndControlPlayerMgr_cFUlfl = .text:0x80360510; // type:function size:0x20 -fn_80360530 = .text:0x80360530; // type:function size:0x38 +getAppliedPlayerVolume__22dSndControlPlayerMgr_cCFUl = .text:0x80360530; // type:function size:0x38 setControlValue__22dSndControlPlayerMgr_cFQ222dSndControlPlayerMgr_c12PlayerCtrl_eUlfl = .text:0x80360570; // type:function size:0xB0 resetControls__22dSndControlPlayerMgr_cFv = .text:0x80360620; // type:function size:0xAC getTargetValue__22dSndControlPlayerMgr_cCFQ222dSndControlPlayerMgr_c12PlayerCtrl_eUl = .text:0x803606D0; // type:function size:0x40 fn_80360710 = .text:0x80360710; // type:function size:0x78 fn_80360790 = .text:0x80360790; // type:function size:0x5C fn_803607F0 = .text:0x803607F0; // type:function size:0x60 -fn_80360850 = .text:0x80360850; // type:function size:0x2C +setShortParameterTo5__22dSndControlPlayerMgr_cFll = .text:0x80360850; // type:function size:0x2C fn_80360880 = .text:0x80360880; // type:function size:0x64 fn_803608F0 = .text:0x803608F0; // type:function size:0x50 fn_80360940 = .text:0x80360940; // type:function size:0x5C @@ -20395,8 +20395,8 @@ apply__32dSndControlSoundSeqTrackVolume_cFP11dSndSound_c = .text:0x8036C3A0; // apply__33dSndControlSoundStrmTrackVolume_cFP11dSndSound_c = .text:0x8036C3F0; // type:function size:0x54 __ct__29dSndControlPlayerVolumeBase_cFv = .text:0x8036C450; // type:function size:0x48 reset__19dSndControlPlayer_cFv = .text:0x8036C4A0; // type:function size:0x40 -setIndex1__19dSndControlPlayer_cFl = .text:0x8036C4E0; // type:function size:0x44 -setIndex2__19dSndControlPlayer_cFl = .text:0x8036C530; // type:function size:0x44 +setIndex1__19dSndControlPlayer_cFUl = .text:0x8036C4E0; // type:function size:0x44 +setIndex2__19dSndControlPlayer_cFUl = .text:0x8036C530; // type:function size:0x44 stop__19dSndControlPlayer_cFv = .text:0x8036C580; // type:function size:0x44 apply__25dSndControlPlayerVolume_cFv = .text:0x8036C5D0; // type:function size:0x10 getAppliedValue__25dSndControlPlayerVolume_cFv = .text:0x8036C5E0; // type:function size:0xC diff --git a/include/d/snd/d_snd_control_player.h b/include/d/snd/d_snd_control_player.h index 33f54205..c4bc4fe2 100644 --- a/include/d/snd/d_snd_control_player.h +++ b/include/d/snd/d_snd_control_player.h @@ -13,12 +13,12 @@ public: virtual void apply() = 0; // vt 0x1C virtual f32 getAppliedValue() = 0; // vt 0x20 - void setIndex1(s32 idx); - void setIndex2(s32 idx); + void setIndex1(u32 idx); + void setIndex2(u32 idx); protected: /* 0x30 */ nw4r::snd::SoundPlayer *mpPlayer; - /* 0x34 */ s32 mIndex; + /* 0x34 */ u32 mIndex; }; class dSndControlPlayerVolumeBase_c : public dSndControlPlayer_c { diff --git a/include/d/snd/d_snd_control_player_mgr.h b/include/d/snd/d_snd_control_player_mgr.h index ef9989e1..057f2e81 100644 --- a/include/d/snd/d_snd_control_player_mgr.h +++ b/include/d/snd/d_snd_control_player_mgr.h @@ -6,6 +6,32 @@ #include "nw4r/snd/snd_SoundPlayer.h" #include "nw4r/ut/ut_list.h" +/* +Num players: 0x15 = 21 +Notes on player groups: +0, 1 + +9, 10, 11 + +12, 13, 14, 16, 17 + +17, 18, 19, 20 + + +0: BGM + +3: UI Sfx, confirmation, pointer reset +4: UI SFX, get fruit +5, 7: Player walk +8: Player Equipment + +12: bomb explode, refresh fruit sprout +13: environmental sound effects (wind), bomb fuse +14: enemies/bugs + +17: TgSound +*/ + class dSndControlPlayerMgr_c; extern template class SndMgrDisposer; @@ -40,29 +66,37 @@ public: static const s32 sNumPlayers; - nw4r::snd::SoundPlayer *getPlayer1(s32); - nw4r::snd::SoundPlayer *getPlayer2(s32); + nw4r::snd::SoundPlayer *getPlayer1(u32) const; + nw4r::snd::SoundPlayer *getPlayer2(u32) const; + + void setVolume(u32 playerIdx, f32 value, s32 frames); void setLpfFreq(u32 playerIdx, f32 value, s32 frames); void setFxSend(u32 playerIdx, f32 value, s32 frames); + void overrideVolume(u32 playerIdx, f32 volume, s32 frames); + void restoreVolume(u32 playerIdx, s32 frames); + + void setShortParameterTo5(s32 idx1, s32 idx2); + private: void resetControls(); + void calcVolumes(); void executeControls(); void linkCtrl(dSndControlPlayer_c *); void unlinkCtrl(dSndControlPlayer_c *); void setControlValue(PlayerCtrl_e ctrlType, u32 playerIdx, f32 value, s32 frames); - - f32 getTargetValue(PlayerCtrl_e ctrlType, u32 playerIdx) const; + f32 getAppliedPlayerVolume(u32 playerIdx) const; + f32 getControlVolumeTarget(PlayerCtrl_e ctrlType, u32 playerIdx) const; /* 0x10 */ dSndControlPlayer_c *mpCtrls[CTRL_MAX]; - /* 0x1C */ void *field_0x1C; - /* 0x20 */ void *field_0x20; - /* 0x24 */ void *field_0x24; - /* 0x28 */ f32 *field_0x28; - /* 0x2C */ u32 mControlMask; + /* 0x1C */ f32 *mpTargetVolumes; + /* 0x20 */ f32 *mpMaxVolumeDecreases; + /* 0x24 */ f32 *mpMaxVolumeIncreases; + /* 0x28 */ f32 *mpSavedVolumes; + /* 0x2C */ u32 mOverrideVolumeMask; /* 0x30 */ nw4r::ut::List mActiveControls; - /* 0x3C */ s16 field_0x3C[8]; + /* 0x3C */ s16 field_0x3C[4][2]; }; #endif diff --git a/src/d/snd/d_snd_control_player.cpp b/src/d/snd/d_snd_control_player.cpp index a9a69a04..824f327a 100644 --- a/src/d/snd/d_snd_control_player.cpp +++ b/src/d/snd/d_snd_control_player.cpp @@ -16,12 +16,12 @@ void dSndControlPlayer_c::reset() { apply(); } -void dSndControlPlayer_c::setIndex1(s32 idx) { +void dSndControlPlayer_c::setIndex1(u32 idx) { mpPlayer = dSndControlPlayerMgr_c::GetInstance()->getPlayer1(idx); mIndex = idx; } -void dSndControlPlayer_c::setIndex2(s32 idx) { +void dSndControlPlayer_c::setIndex2(u32 idx) { mpPlayer = dSndControlPlayerMgr_c::GetInstance()->getPlayer2(idx); mIndex = idx; } diff --git a/src/d/snd/d_snd_control_player_mgr.cpp b/src/d/snd/d_snd_control_player_mgr.cpp index 44375f93..1f82c696 100644 --- a/src/d/snd/d_snd_control_player_mgr.cpp +++ b/src/d/snd/d_snd_control_player_mgr.cpp @@ -6,7 +6,7 @@ template class SndMgrDisposer; -dSndControlPlayerMgr_c::dSndControlPlayerMgr_c() : mControlMask(0) { +dSndControlPlayerMgr_c::dSndControlPlayerMgr_c() : mOverrideVolumeMask(0) { // TODO offsetof nw4r::ut::List_Init(&mActiveControls, 0x24); @@ -14,10 +14,10 @@ dSndControlPlayerMgr_c::dSndControlPlayerMgr_c() : mControlMask(0) { mpCtrls[CTRL_LPF_FREQ] = new dSndControlPlayerLpfFreq_c[sNumPlayers](); mpCtrls[CTRL_FX_SEND] = new dSndControlPlayerFxSend_c[sNumPlayers](); - field_0x28 = new f32[sNumPlayers]; - field_0x1C = new f32[sNumPlayers]; - field_0x20 = new f32[sNumPlayers]; - field_0x24 = new f32[sNumPlayers]; + mpSavedVolumes = new f32[sNumPlayers]; + mpTargetVolumes = new f32[sNumPlayers]; + mpMaxVolumeDecreases = new f32[sNumPlayers]; + mpMaxVolumeIncreases = new f32[sNumPlayers]; } void dSndControlPlayerMgr_c::calc() {} @@ -36,10 +36,40 @@ void dSndControlPlayerMgr_c::executeControls() { } } +void dSndControlPlayerMgr_c::calcVolumes() { + for (int i = 0; i < sNumPlayers; i++) { + if ((mOverrideVolumeMask & (1 << i)) != 0) { + // overridden volume + mpTargetVolumes[i] = mpSavedVolumes[i]; + } else { + // not overridden. The effect of this is that + // something will set the targetValue to a specific value + f32 currentVolume = getAppliedPlayerVolume(i); + f32 targetVolume = mpTargetVolumes[i]; + f32 maxVolumeDecrease = mpMaxVolumeDecreases[i]; + f32 maxVolumeIncrease = mpMaxVolumeDecreases[i]; + + if (currentVolume != targetVolume) { + if (currentVolume - targetVolume > maxVolumeDecrease) { + targetVolume = currentVolume - maxVolumeDecrease; + } else if (targetVolume - currentVolume > maxVolumeIncrease) { + targetVolume = currentVolume + maxVolumeIncrease; + } + // @bug not actually clamped + nw4r::ut::Clamp(targetVolume, 0.0f, 2.0f); + setVolume(i, targetVolume, 0); + } + mpTargetVolumes[i] = 1.0f; + mpMaxVolumeDecreases[i] = 0.1f; + mpMaxVolumeDecreases[i] = 0.025f; + } + } +} + void dSndControlPlayerMgr_c::linkCtrl(dSndControlPlayer_c *ctrl) { if (ctrl == nullptr) { return; - } + } if (ctrl->isLinked()) { return; } @@ -50,7 +80,7 @@ void dSndControlPlayerMgr_c::linkCtrl(dSndControlPlayer_c *ctrl) { void dSndControlPlayerMgr_c::unlinkCtrl(dSndControlPlayer_c *ctrl) { if (ctrl == nullptr) { return; - } + } if (!ctrl->isLinked()) { return; } @@ -58,6 +88,47 @@ void dSndControlPlayerMgr_c::unlinkCtrl(dSndControlPlayer_c *ctrl) { nw4r::ut::List_Remove(&mActiveControls, ctrl); } +void dSndControlPlayerMgr_c::setVolume(u32 playerIdx, f32 value, s32 frames) { + if (playerIdx >= sNumPlayers) { + return; + } + + u32 mask = (1 << playerIdx); + if ((mOverrideVolumeMask & mask) != 0) { + // Volume is overridden, set saved volume as to not interrupt override + mpSavedVolumes[playerIdx] = value; + + } else { + // Volume is not overridden, set volume normally + setControlValue(CTRL_VOLUME, playerIdx, value, frames); + mpSavedVolumes[playerIdx] = getControlVolumeTarget(CTRL_VOLUME, playerIdx); + } +} + +void dSndControlPlayerMgr_c::overrideVolume(u32 playerIdx, f32 volume, s32 frames) { + if (playerIdx >= sNumPlayers) { + return; + } + u32 mask = (1 << playerIdx); + if ((mOverrideVolumeMask & mask) == 0) { + mpSavedVolumes[playerIdx] = getControlVolumeTarget(CTRL_VOLUME, playerIdx); + mOverrideVolumeMask |= mask; + } + setControlValue(CTRL_VOLUME, playerIdx, volume, frames); +} + +void dSndControlPlayerMgr_c::restoreVolume(u32 playerIdx, s32 frames) { + if (playerIdx >= sNumPlayers) { + return; + } + u32 mask = (1 << playerIdx); + if ((mOverrideVolumeMask & mask) == 0) { + return; + } + mOverrideVolumeMask &= ~mask; + setControlValue(CTRL_VOLUME, playerIdx, mpSavedVolumes[playerIdx], frames); +} + void dSndControlPlayerMgr_c::setLpfFreq(u32 playerIdx, f32 value, s32 frames) { if (playerIdx < sNumPlayers) { setControlValue(CTRL_LPF_FREQ, playerIdx, value, frames); @@ -88,12 +159,19 @@ void dSndControlPlayerMgr_c::resetControls() { for (s32 ty = 0; ty < CTRL_MAX; ty++) { mpCtrls[ty][i].reset(); } - field_0x28[i] = 1.0f; + mpSavedVolumes[i] = 1.0f; } - mControlMask = 0; + mOverrideVolumeMask = 0; } -f32 dSndControlPlayerMgr_c::getTargetValue(PlayerCtrl_e ctrlType, u32 playerIdx) const { +f32 dSndControlPlayerMgr_c::getAppliedPlayerVolume(u32 playerIdx) const { + if (playerIdx >= sNumPlayers) { + return 0.0f; + } + return getPlayer1(playerIdx)->GetVolume(); +} + +f32 dSndControlPlayerMgr_c::getControlVolumeTarget(PlayerCtrl_e ctrlType, u32 playerIdx) const { if (ctrlType >= CTRL_MAX) { return 1.0f; } @@ -102,3 +180,15 @@ f32 dSndControlPlayerMgr_c::getTargetValue(PlayerCtrl_e ctrlType, u32 playerIdx) } return mpCtrls[ctrlType][playerIdx].getTargetValue(); } + +void dSndControlPlayerMgr_c::setShortParameterTo5(s32 idx1, s32 idx2) { + if (idx1 >= 4) { + return; + } + + if (idx2 >= 2) { + return; + } + + field_0x3C[idx1][idx2] = 5; +}