mirror of
https://github.com/zeldaret/ss
synced 2026-08-31 09:20:48 -04:00
405 lines
14 KiB
C++
405 lines
14 KiB
C++
#include "d/snd/d_snd_control_player_mgr.h"
|
|
|
|
#include "common.h"
|
|
#include "d/snd/d_snd_bgm_mgr.h"
|
|
#include "d/snd/d_snd_control_player.h"
|
|
#include "d/snd/d_snd_mgr.h"
|
|
#include "d/snd/d_snd_player_mgr.h"
|
|
#include "nw4r/snd/snd_SoundHandle.h"
|
|
#include "nw4r/ut/ut_list.h"
|
|
#include "toBeSorted/music_mgrs.h"
|
|
|
|
struct FanfareMuteFlagsApplier {
|
|
~FanfareMuteFlagsApplier() {}
|
|
virtual void operator()(nw4r::snd::SoundHandle &handle) {
|
|
// The logic here is inverted compared to the others - Fanfares seem to
|
|
// mute things by default unless otherwise speciefied
|
|
u32 id = handle.GetId();
|
|
if (dSndBgmMgr_c::GetInstance()->getSoundHandleCurrentlyPlayingFanSound(handle.GetId())) {
|
|
u32 userParam = dSndMgr_c::GetInstance()->getArchive()->GetSoundUserParam(id);
|
|
if (!(userParam & dSndPlayerMgr_c::FANFARE_UNMUTE_BGM)) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_BGM, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
dSndControlPlayerMgr_c::GetInstance()->setBgmVolumeDecreaseSpeed(0.2f);
|
|
}
|
|
|
|
if (fn_80364DA0(ENEMY_SOUND_MGR)) {
|
|
if (!(userParam & dSndPlayerMgr_c::FANFARE_UNMUTE_STAGE_EFFECTS)) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_STAGE_EFFECTS, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
}
|
|
if (!(userParam & dSndPlayerMgr_c::FANFARE_UNMUTE_ENEMY)) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_ENEMY, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
}
|
|
if (!(userParam & dSndPlayerMgr_c::FANFARE_UNMUTE_OBJECTS)) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_OBJECTS, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
struct SmallMuteFlagsApplier {
|
|
~SmallMuteFlagsApplier() {}
|
|
virtual void operator()(nw4r::snd::SoundHandle &handle) {
|
|
u32 userParam = dSndMgr_c::GetInstance()->getArchive()->GetSoundUserParam(handle.GetId());
|
|
|
|
if (userParam & dSndPlayerMgr_c::MUTE_BGM_FULL) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_BGM, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
} else if (userParam & dSndPlayerMgr_c::MUTE_BGM_PART) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_BGM, dSndControlPlayerMgr_c::MUTE_PARTIAL
|
|
);
|
|
}
|
|
|
|
if (userParam & dSndPlayerMgr_c::MUTE_STAGE_EFFECTS_FULL) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_STAGE_EFFECTS, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
} else if (userParam & dSndPlayerMgr_c::MUTE_STAGE_EFFECTS_PART) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_STAGE_EFFECTS, dSndControlPlayerMgr_c::MUTE_PARTIAL
|
|
);
|
|
}
|
|
|
|
if (userParam & dSndPlayerMgr_c::MUTE_ENEMY_FULL) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_ENEMY, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
} else if (userParam & dSndPlayerMgr_c::MUTE_ENEMY_PART) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_ENEMY, dSndControlPlayerMgr_c::MUTE_PARTIAL
|
|
);
|
|
}
|
|
|
|
if (userParam & dSndPlayerMgr_c::MUTE_OBJECTS_FULL) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_OBJECTS, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
} else if (userParam & dSndPlayerMgr_c::MUTE_OBJECTS_PART) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_OBJECTS, dSndControlPlayerMgr_c::MUTE_PARTIAL
|
|
);
|
|
}
|
|
};
|
|
};
|
|
|
|
struct EventMuteFlagsApplier {
|
|
~EventMuteFlagsApplier() {}
|
|
virtual void operator()(nw4r::snd::SoundHandle &handle) {
|
|
u32 userParam = dSndPlayerMgr_c::GetInstance()->getEventMuteMask(handle.GetId());
|
|
|
|
if (userParam & dSndPlayerMgr_c::MUTE_BGM_FULL) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_BGM, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
} else if (userParam & dSndPlayerMgr_c::MUTE_BGM_PART) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_BGM, dSndControlPlayerMgr_c::MUTE_PARTIAL
|
|
);
|
|
}
|
|
|
|
if (userParam & dSndPlayerMgr_c::MUTE_STAGE_EFFECTS_FULL) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_STAGE_EFFECTS, dSndControlPlayerMgr_c::MUTE_FULL
|
|
);
|
|
} else if (userParam & dSndPlayerMgr_c::MUTE_STAGE_EFFECTS_PART) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setGroupVolumeFlag(
|
|
dSndControlPlayerMgr_c::CTRL_GROUP_STAGE_EFFECTS, dSndControlPlayerMgr_c::MUTE_PARTIAL
|
|
);
|
|
}
|
|
};
|
|
};
|
|
|
|
static FanfareMuteFlagsApplier fanfareApplier;
|
|
static SmallMuteFlagsApplier smallApplier;
|
|
static EventMuteFlagsApplier eventApplier;
|
|
|
|
SND_DISPOSER_DEFINE(dSndControlPlayerMgr_c);
|
|
|
|
dSndControlPlayerMgr_c::dSndControlPlayerMgr_c() : mOverrideVolumeMask(0) {
|
|
// TODO offsetof
|
|
nw4r::ut::List_Init(&mActiveControls, 0x24);
|
|
|
|
mpCtrls[CTRL_VOLUME] = new dSndControlPlayerVolume_c[sNumPlayers]();
|
|
mpCtrls[CTRL_LPF_FREQ] = new dSndControlPlayerLpfFreq_c[sNumPlayers]();
|
|
mpCtrls[CTRL_FX_SEND] = new dSndControlPlayerFxSend_c[sNumPlayers]();
|
|
|
|
mpSavedVolumes = new f32[sNumPlayers];
|
|
mpTargetVolumes = new f32[sNumPlayers];
|
|
mpMaxVolumeDecreases = new f32[sNumPlayers];
|
|
mpMaxVolumeIncreases = new f32[sNumPlayers];
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::calc() {
|
|
calcMuteFlags();
|
|
calcVolumes();
|
|
executeControls();
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::executeControls() {
|
|
dSndControlPlayer_c *next;
|
|
dSndControlPlayer_c *iter = static_cast<dSndControlPlayer_c *>(nw4r::ut::List_GetFirst(&mActiveControls));
|
|
while (iter != nullptr) {
|
|
next = static_cast<dSndControlPlayer_c *>(nw4r::ut::List_GetNext(&mActiveControls, iter));
|
|
iter->calc();
|
|
iter->apply();
|
|
if (iter->isFinished()) {
|
|
unlinkCtrl(iter);
|
|
}
|
|
iter = next;
|
|
}
|
|
}
|
|
|
|
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.
|
|
f32 currentVolume = getAppliedPlayerVolume(i);
|
|
f32 targetVolume = mpTargetVolumes[i];
|
|
f32 maxVolumeDecrease = mpMaxVolumeDecreases[i];
|
|
f32 maxVolumeIncrease = mpMaxVolumeIncreases[i];
|
|
|
|
if (currentVolume != targetVolume) {
|
|
if (currentVolume - targetVolume > maxVolumeDecrease) {
|
|
targetVolume = currentVolume - maxVolumeDecrease;
|
|
} else if (targetVolume - currentVolume > maxVolumeIncrease) {
|
|
targetVolume = currentVolume + maxVolumeIncrease;
|
|
}
|
|
// @bug not actually clamped
|
|
(void)nw4r::ut::Clamp(targetVolume, 0.0f, 2.0f);
|
|
setVolume(i, targetVolume, 0);
|
|
}
|
|
mpTargetVolumes[i] = 1.0f;
|
|
mpMaxVolumeDecreases[i] = 0.1f;
|
|
mpMaxVolumeIncreases[i] = 0.025f;
|
|
}
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::calcMuteFlags() {
|
|
getPlayer1(dSndPlayerMgr_c::PLAYER_FAN)->ForEachSound(fanfareApplier, false);
|
|
getPlayer1(dSndPlayerMgr_c::PLAYER_SMALL_IMPORTANT)->ForEachSound(smallApplier, false);
|
|
getPlayer1(dSndPlayerMgr_c::PLAYER_SMALL_NORMAL)->ForEachSound(smallApplier, false);
|
|
getPlayer1(dSndPlayerMgr_c::PLAYER_EVENT)->ForEachSound(eventApplier, false);
|
|
|
|
f32 volumesByGroup[CTRL_GROUP_MAX];
|
|
for (int i = 0; i < CTRL_GROUP_MAX; i++) {
|
|
volumesByGroup[i] = 1.0f;
|
|
if (mTimersForGroupVolume[i][MUTE_PARTIAL] > 0) {
|
|
mTimersForGroupVolume[i][MUTE_PARTIAL]--;
|
|
volumesByGroup[i] = 0.3f;
|
|
}
|
|
|
|
if (mTimersForGroupVolume[i][MUTE_FULL] > 0) {
|
|
mTimersForGroupVolume[i][MUTE_FULL]--;
|
|
volumesByGroup[i] = 0.0f;
|
|
}
|
|
}
|
|
|
|
if (volumesByGroup[CTRL_GROUP_BGM] < 1.0f) {
|
|
setBgmMuteVolume(volumesByGroup[CTRL_GROUP_BGM]);
|
|
}
|
|
|
|
if (volumesByGroup[CTRL_GROUP_STAGE_EFFECTS] < 1.0f) {
|
|
setStageEffectsMuteVolume(volumesByGroup[CTRL_GROUP_STAGE_EFFECTS]);
|
|
}
|
|
|
|
if (volumesByGroup[CTRL_GROUP_ENEMY] < 1.0f) {
|
|
setEnemyMuteVolume(volumesByGroup[CTRL_GROUP_ENEMY]);
|
|
}
|
|
|
|
if (volumesByGroup[CTRL_GROUP_OBJECTS] < 1.0f) {
|
|
setObjectMuteVolume(volumesByGroup[CTRL_GROUP_OBJECTS]);
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::linkCtrl(dSndControlPlayer_c *ctrl) {
|
|
if (ctrl == nullptr) {
|
|
return;
|
|
}
|
|
if (ctrl->isLinked()) {
|
|
return;
|
|
}
|
|
ctrl->setLinked(true);
|
|
nw4r::ut::List_Append(&mActiveControls, ctrl);
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::unlinkCtrl(dSndControlPlayer_c *ctrl) {
|
|
if (ctrl == nullptr) {
|
|
return;
|
|
}
|
|
if (!ctrl->isLinked()) {
|
|
return;
|
|
}
|
|
ctrl->setLinked(false);
|
|
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;
|
|
setPlayerVolumeInternal(playerIdx, value);
|
|
} else {
|
|
// Volume is not overridden, set volume normally
|
|
setControlValue(CTRL_VOLUME, playerIdx, value, frames);
|
|
mpSavedVolumes[playerIdx] = getControlTarget(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] = getControlTarget(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);
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setFxSend(u32 playerIdx, f32 value, s32 frames) {
|
|
if (playerIdx < sNumPlayers) {
|
|
setControlValue(CTRL_FX_SEND, playerIdx, value, frames);
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setControlValue(PlayerCtrl_e ctrlType, u32 playerIdx, f32 value, s32 frames) {
|
|
if (ctrlType < CTRL_MAX && playerIdx < sNumPlayers) {
|
|
dSndControlPlayer_c *ctrl = &mpCtrls[ctrlType][playerIdx];
|
|
ctrl->set(value, frames);
|
|
if (ctrl->isFinished()) {
|
|
unlinkCtrl(ctrl);
|
|
} else {
|
|
linkCtrl(ctrl);
|
|
}
|
|
ctrl->apply();
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::resetControls() {
|
|
for (s32 i = 0; i < sNumPlayers; i++) {
|
|
for (s32 ty = 0; ty < CTRL_MAX; ty++) {
|
|
mpCtrls[ty][i].reset();
|
|
}
|
|
mpSavedVolumes[i] = 1.0f;
|
|
}
|
|
mOverrideVolumeMask = 0;
|
|
}
|
|
|
|
f32 dSndControlPlayerMgr_c::getAppliedPlayerVolume(u32 playerIdx) const {
|
|
if (playerIdx >= sNumPlayers) {
|
|
return 0.0f;
|
|
}
|
|
return getPlayer1(playerIdx)->GetVolume();
|
|
}
|
|
|
|
f32 dSndControlPlayerMgr_c::getControlTarget(PlayerCtrl_e ctrlType, u32 playerIdx) const {
|
|
if (ctrlType >= CTRL_MAX) {
|
|
return 1.0f;
|
|
}
|
|
if (playerIdx >= sNumPlayers) {
|
|
return 1.0f;
|
|
}
|
|
return mpCtrls[ctrlType][playerIdx].getTargetValue();
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setGroupVolumeFlag(VolumeControlGroup group, MuteLevel level) {
|
|
if (group >= CTRL_GROUP_MAX) {
|
|
return;
|
|
}
|
|
|
|
if (level >= MUTE_MAX) {
|
|
return;
|
|
}
|
|
|
|
mTimersForGroupVolume[group][level] = 5;
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setPlayerVolumeInternal(u32 playerIdx, f32 volume) {
|
|
if (playerIdx >= sNumPlayers) {
|
|
return;
|
|
}
|
|
// @bug not actually clamped
|
|
(void)nw4r::ut::Clamp(volume, 0.0f, 2.0f);
|
|
|
|
if (mpTargetVolumes[playerIdx] > volume) {
|
|
mpTargetVolumes[playerIdx] = volume;
|
|
}
|
|
|
|
u32 mask = (1 << playerIdx);
|
|
if ((mOverrideVolumeMask & mask) != 0) {
|
|
mpSavedVolumes[playerIdx] = mpTargetVolumes[playerIdx];
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setBgmMuteVolume(f32 volume) {
|
|
for (u32 i = dSndPlayerMgr_c::PLAYER_BGM; i < dSndPlayerMgr_c::PLAYER_BGM_BATTLE + 1; i++) {
|
|
setPlayerVolumeInternal(i, volume);
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setBgmVolumeDecreaseSpeed(f32 decrease) {}
|
|
|
|
void dSndControlPlayerMgr_c::setStageEffectsVolume(f32 volume, s32 fadeFrames) {
|
|
for (u32 i = dSndPlayerMgr_c::PLAYER_TG_SOUND; i <= dSndPlayerMgr_c::PLAYER_AREA_IN_WATER_LV; i++) {
|
|
setVolume(i, volume, fadeFrames);
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setStageEffectsMuteVolume(f32 volume) {
|
|
for (u32 i = dSndPlayerMgr_c::PLAYER_TG_SOUND; i <= dSndPlayerMgr_c::PLAYER_AREA_IN_WATER_LV; i++) {
|
|
setPlayerVolumeInternal(i, volume);
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setEnemyMuteVolume(f32 volume) {
|
|
for (u32 i = dSndPlayerMgr_c::PLAYER_ENEMY; i < dSndPlayerMgr_c::PLAYER_ENEMY_FOOTSTEP + 1; i++) {
|
|
setPlayerVolumeInternal(i, volume);
|
|
}
|
|
}
|
|
|
|
void dSndControlPlayerMgr_c::setObjectMuteVolume(f32 volume) {
|
|
for (u32 i = dSndPlayerMgr_c::PLAYER_OBJECT_1; i < dSndPlayerMgr_c::PLAYER_TG_SOUND + 1; i++) {
|
|
if (i != dSndPlayerMgr_c::PLAYER_NPC_VOICE) {
|
|
setPlayerVolumeInternal(i, volume);
|
|
}
|
|
}
|
|
}
|