mirror of
https://github.com/zeldaret/ss
synced 2026-06-04 02:46:25 -04:00
1248 lines
40 KiB
C++
1248 lines
40 KiB
C++
#include "d/snd/d_snd_state_mgr.h"
|
|
|
|
#include "common.h"
|
|
#include "d/a/d_a_player.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"
|
|
#include "d/snd/d_snd_checkers.h"
|
|
#include "d/snd/d_snd_control_player_mgr.h"
|
|
#include "d/snd/d_snd_event.h"
|
|
#include "d/snd/d_snd_harp_song_mgr.h"
|
|
#include "d/snd/d_snd_mgr.h"
|
|
#include "d/snd/d_snd_player_mgr.h"
|
|
#include "d/snd/d_snd_small_effect_mgr.h"
|
|
#include "d/snd/d_snd_source_mgr.h"
|
|
#include "d/snd/d_snd_stage_data.h"
|
|
#include "d/snd/d_snd_util.h"
|
|
#include "d/snd/d_snd_wzsound.h"
|
|
#include "d/t/d_t_sound_area_mgr.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"
|
|
#include "toBeSorted/event_manager.h"
|
|
|
|
#include <cstring>
|
|
|
|
SndEventCallback dSndStateMgr_c::sEventExecuteCallback;
|
|
SND_DISPOSER_DEFINE(dSndStateMgr_c);
|
|
|
|
dSndStateMgr_c::dSndStateMgr_c()
|
|
: field_0x010(0),
|
|
field_0x014(0),
|
|
field_0x018(0),
|
|
field_0x03C(0),
|
|
mStageId(0xAC),
|
|
mPreviousStageId(0xAC),
|
|
mStageTypeFlags(0),
|
|
mLayer(0),
|
|
mRoomId(-1),
|
|
mCheckRoomIdCooldown(0),
|
|
field_0x064(false),
|
|
field_0x065(false),
|
|
mHasChangedTgSndAreaFlags(false),
|
|
mHasChangedTgSndAreaMgFlags(false),
|
|
mSavedTgSndAreaFlags(-1),
|
|
mSavedTgSndAreaMgFlags(-1),
|
|
mpUnkCallback(nullptr),
|
|
field_0x074(0),
|
|
mpOnEventStartCallback(nullptr),
|
|
field_0x07C(0),
|
|
mpTgSndAreaFlagsChangeCallback(nullptr),
|
|
mpTgSndAreaMgFlagsChangeCallback(nullptr),
|
|
field_0x088(0),
|
|
mSoundEventId(SND_EVENT_0x89),
|
|
mCameraCutCounter(0),
|
|
mEventFlags(0),
|
|
mpStbEventName(nullptr),
|
|
mFrameCounter(0),
|
|
mCameraCutFrameCounter(0),
|
|
mMsgFrameCounter(0),
|
|
mSeLvSoundId(-1),
|
|
field_0x22C(0),
|
|
mpSoundEventDef(nullptr),
|
|
field_0x238(-1),
|
|
field_0x23C(0),
|
|
field_0x23D(0),
|
|
field_0x240(0),
|
|
field_0x244(0),
|
|
field_0x248(0),
|
|
mMsgCounter(-1),
|
|
mMsgWaitSelectCounter(0),
|
|
field_0x254(0),
|
|
field_0x258(0),
|
|
field_0x48C(0),
|
|
mFxSend3DDefault(0.02f),
|
|
mFxSend3DOverride(-1.0f),
|
|
mFxSend3DNext(-1.0f),
|
|
mFxSend3D(0.02f),
|
|
mFxSend3DTarget(0.02f),
|
|
mPrevStageGroup(-1),
|
|
field_0x4A8(0),
|
|
mNeedsGroupsReload(false) {}
|
|
|
|
extern "C" void fn_803665B0(nw4r::snd::detail::FxReverbStdParam &, int);
|
|
|
|
void dSndStateMgr_c::setup(EGG::Heap *pHeap) {
|
|
u32 max = 0;
|
|
for (int i = 0; i < 5; i++) {
|
|
nw4r::snd::detail::FxReverbStdParam param;
|
|
fn_803665B0(param, i);
|
|
mFx.SetParam(param);
|
|
u32 thisSize = mFx.GetRequiredMemSize();
|
|
if (max < thisSize) {
|
|
max = thisSize;
|
|
}
|
|
}
|
|
void *mem = pHeap->alloc(max, 4);
|
|
mFx.AssignWorkBuffer(mem, max);
|
|
resetEventName();
|
|
}
|
|
|
|
void dSndStateMgr_c::onStageOrLayerUpdate() {
|
|
if (dSndPlayerMgr_c::GetInstance()->checkFlag(dSndPlayerMgr_c::MGR_CAUTION)) {
|
|
dSndPlayerMgr_c::GetInstance()->leaveCaution();
|
|
}
|
|
|
|
bool unk_0x065 = field_0x065;
|
|
|
|
onFlag0x10(FLAG0x10_0x02);
|
|
field_0x064 = false;
|
|
|
|
if (!streq(mStageName, dScGame_c::currentSpawnInfo.getStageName())) {
|
|
mNeedsGroupsReload = true;
|
|
mStageName = dScGame_c::currentSpawnInfo.getStageName();
|
|
}
|
|
|
|
if (!mNeedsGroupsReload && dScGame_c::currentSpawnInfo.layer != mLayer) {
|
|
mNeedsGroupsReload = true;
|
|
}
|
|
|
|
mLayer = dScGame_c::currentSpawnInfo.layer;
|
|
u32 newStageId = getStageId(dScGame_c::currentSpawnInfo.getStageName(), dScGame_c::currentSpawnInfo.layer);
|
|
mPreviousStageId = mStageId;
|
|
field_0x044 = getStageUnk2(newStageId);
|
|
mStageId = newStageId;
|
|
|
|
if (unk_0x065) {
|
|
setCallbacksForStage();
|
|
}
|
|
}
|
|
|
|
inline bool checkStagePrefix(const char *stageName, const char *prefix) {
|
|
return !std::strncmp(prefix, stageName, 2);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getStageTypeFlags(const char *stageName) const {
|
|
u32 flags = 0;
|
|
if (checkStagePrefix(stageName, "F0")) {
|
|
flags |= STAGE_SKY | STAGE_FIELD;
|
|
} else if (checkStagePrefix(stageName, "D0")) {
|
|
flags |= STAGE_SKY | STAGE_DUNGEON;
|
|
} else if (checkStagePrefix(stageName, "B0")) {
|
|
flags |= STAGE_SKY | STAGE_BOSS;
|
|
} else if (checkStagePrefix(stageName, "S0")) {
|
|
flags |= STAGE_SKY | STAGE_SILENT_REALM;
|
|
} else if (checkStagePrefix(stageName, "F1")) {
|
|
flags |= STAGE_FOREST | STAGE_FIELD;
|
|
} else if (checkStagePrefix(stageName, "D1")) {
|
|
flags |= STAGE_FOREST | STAGE_DUNGEON;
|
|
} else if (checkStagePrefix(stageName, "B1")) {
|
|
flags |= STAGE_FOREST | STAGE_BOSS;
|
|
} else if (checkStagePrefix(stageName, "S1")) {
|
|
flags |= STAGE_FOREST | STAGE_SILENT_REALM;
|
|
} else if (checkStagePrefix(stageName, "F2")) {
|
|
flags |= STAGE_MOUNTAIN | STAGE_FIELD;
|
|
} else if (checkStagePrefix(stageName, "D2")) {
|
|
flags |= STAGE_MOUNTAIN | STAGE_DUNGEON;
|
|
} else if (checkStagePrefix(stageName, "B2")) {
|
|
flags |= STAGE_MOUNTAIN | STAGE_BOSS;
|
|
} else if (checkStagePrefix(stageName, "S2")) {
|
|
flags |= STAGE_MOUNTAIN | STAGE_SILENT_REALM;
|
|
} else if (checkStagePrefix(stageName, "F3")) {
|
|
flags |= STAGE_DESERT | STAGE_FIELD;
|
|
} else if (checkStagePrefix(stageName, "D3")) {
|
|
flags |= STAGE_DESERT | STAGE_DUNGEON;
|
|
} else if (checkStagePrefix(stageName, "B3")) {
|
|
flags |= STAGE_DESERT | STAGE_BOSS;
|
|
} else if (checkStagePrefix(stageName, "S3")) {
|
|
flags |= STAGE_DESERT | STAGE_SILENT_REALM;
|
|
} else if (checkStagePrefix(stageName, "F4")) {
|
|
flags |= STAGE_SILENT_GROUNDS | STAGE_FIELD;
|
|
} else if (checkStagePrefix(stageName, "D4")) {
|
|
flags |= STAGE_SILENT_GROUNDS | STAGE_DUNGEON;
|
|
} else if (checkStagePrefix(stageName, "B4")) {
|
|
flags |= STAGE_SILENT_GROUNDS | STAGE_BOSS;
|
|
}
|
|
|
|
if ((flags & STAGE_SKY) != 0 && std::strstr(stageName, "r") != nullptr) {
|
|
flags |= STAGE_ROOM;
|
|
}
|
|
|
|
return flags;
|
|
}
|
|
|
|
bool dSndStateMgr_c::isVolcanicDungeon(u32 stageId) {
|
|
u32 base = getStageUnk2(stageId);
|
|
switch (base) {
|
|
case SND_STAGE_D200:
|
|
case SND_STAGE_D201:
|
|
case SND_STAGE_D201_1:
|
|
case SND_STAGE_D003_0:
|
|
case SND_STAGE_D003_1: return true;
|
|
default: return false;
|
|
}
|
|
}
|
|
|
|
bool dSndStateMgr_c::isSeekerStoneStage(const char *stageName, s32 layer) {
|
|
if (streq(stageName, "F000") && layer == 22) {
|
|
// Skyloft hint stone
|
|
return true;
|
|
}
|
|
|
|
if (streq(stageName, "F202") && layer == 10) {
|
|
// Boko base hint stone
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool dSndStateMgr_c::isSomeSkyloftRoom() const {
|
|
switch (field_0x044) {
|
|
case SND_STAGE_F001r:
|
|
case SND_STAGE_F002r:
|
|
case SND_STAGE_F011r:
|
|
case SND_STAGE_F005r:
|
|
case SND_STAGE_F006r:
|
|
case SND_STAGE_F007r:
|
|
case SND_STAGE_F013r:
|
|
case SND_STAGE_F014r:
|
|
case SND_STAGE_F015r:
|
|
case SND_STAGE_F016r:
|
|
case SND_STAGE_F017r:
|
|
case SND_STAGE_F018r: return true;
|
|
default: return false;
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::onRestartScene(s32 fadeFrames) {
|
|
if (field_0x064) {
|
|
return;
|
|
}
|
|
|
|
s32 nextLayer = dScGame_c::nextSpawnInfo.layer;
|
|
// This combines next stage with current layer, so this effectively checks if you're leaving the Hint Movie scene
|
|
if (isSeekerStoneStage(mStageName, dScGame_c::currentSpawnInfo.layer)) {
|
|
dSndBgmMgr_c::GetInstance()->stopAllBgm(fadeFrames);
|
|
} else if (mLayer != nextLayer) {
|
|
if (isSeekerStoneStage(mStageName, nextLayer)) {
|
|
dSndBgmMgr_c::GetInstance()->stopAllBgm(fadeFrames);
|
|
dSndBgmMgr_c::GetInstance()->prepareBgm(BGM_HINT_SELECT, 0);
|
|
dSndBgmMgr_c::GetInstance()->setOverrideBgmId(BGM_HINT_SELECT);
|
|
dSndBgmMgr_c::GetInstance()->activateOverrideBgmId();
|
|
dSndAreaSoundEffectMgr_c::GetInstance()->stopSounds(fadeFrames);
|
|
} else {
|
|
onGotoStage(fadeFrames);
|
|
onFlag0x10(FLAG0x10_0x01);
|
|
return;
|
|
}
|
|
}
|
|
|
|
dSndSmallEffectMgr_c::GetInstance()->stopAllSoundExceptEvent(fadeFrames);
|
|
dSndBgmMgr_c::GetInstance()->prepareBgm();
|
|
dSndHarpSongMgr_c::GetInstance()->deactivate();
|
|
onFlag0x10(FLAG0x10_0x01);
|
|
dSndBgmMgr_c::GetInstance()->setField_0x306(1);
|
|
offFlag0x10(FLAG0x10_0x04);
|
|
offFlag0x10(FLAG0x10_0x10);
|
|
}
|
|
|
|
void dSndStateMgr_c::loadStageSound() {
|
|
loadStageSound(false);
|
|
}
|
|
|
|
void dSndStateMgr_c::loadStageSound(bool force) {
|
|
if (!force && !mNeedsGroupsReload) {
|
|
return;
|
|
}
|
|
|
|
bool demo = isInDemo();
|
|
if (!checkFlag0x18(0x40)) {
|
|
for (int i = 0; i < dSndControlPlayerMgr_c::sNumPlayers; i++) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setLpfFreq(i, 0.0f, 0);
|
|
dSndControlPlayerMgr_c::GetInstance()->setFxSend(i, 0.0f, 0);
|
|
}
|
|
}
|
|
|
|
if (checkEventFlag(EVENT_0x800)) {
|
|
if (!dSndBgmMgr_c::GetInstance()->isPlayingBgmSound()) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setupPlayerControlsStage();
|
|
offEventFlag(EVENT_0x800);
|
|
} else {
|
|
dSndControlPlayerMgr_c::GetInstance()->setupPlayerControlsStageBgm();
|
|
}
|
|
} else {
|
|
if (dSndBgmMgr_c::GetInstance()->isPlayingBgmSound()) {
|
|
dSndControlPlayerMgr_c::GetInstance()->setupPlayerControlsStageBgm();
|
|
onEventFlag(EVENT_0x800);
|
|
} else {
|
|
dSndControlPlayerMgr_c::GetInstance()->setupPlayerControlsStage();
|
|
}
|
|
}
|
|
|
|
dSndControlPlayerMgr_c::GetInstance()->muteScenePlayers(0);
|
|
dSndPlayerMgr_c::GetInstance()->shutdownDemo();
|
|
field_0x4A8 = 1;
|
|
bool bHasState1 = false;
|
|
|
|
if (isSomeSkyloftRoom()) {
|
|
u32 id = dSndMgr_c::GetInstance()->getArchive()->ConvertLabelStringToGroupId("GRP_FAN_TIMECHANGE");
|
|
if (dSndMgr_c::GetInstance()->getPlayer().IsLoadedGroup(id)) {
|
|
bHasState1 = true;
|
|
} else {
|
|
dSndPlayerMgr_c::GetInstance()->popToState0();
|
|
if (dSndMgr_c::GetInstance()->loadGroup(id, nullptr, 0)) {
|
|
dSndPlayerMgr_c::GetInstance()->saveState1();
|
|
bHasState1 = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
const dSndStageInfo *info = &dSndStageInfo::sInfos[mStageId];
|
|
|
|
u32 id = -1;
|
|
int round = 1;
|
|
|
|
bool canReuseStageState = false;
|
|
SizedString<64> label;
|
|
|
|
if (info->unk4 == mStageId) {
|
|
const char *stageName = getStageName(info->unk4);
|
|
label.sprintf("GRP_A_%s_L%d", stageName, mLayer);
|
|
round = 2;
|
|
} else {
|
|
const char *stageName = getCurrentStageName4();
|
|
label.sprintf("GRP_A_%s", stageName);
|
|
}
|
|
|
|
for (; round > 0; round--) {
|
|
id = dSndMgr_c::GetInstance()->getArchive()->ConvertLabelStringToGroupId(label);
|
|
if (mPrevStageGroup == id && mPrevStageGroup != -1) {
|
|
canReuseStageState = true;
|
|
break;
|
|
}
|
|
|
|
if (id != -1) {
|
|
if (bHasState1) {
|
|
dSndPlayerMgr_c::GetInstance()->popToState1();
|
|
} else {
|
|
dSndPlayerMgr_c::GetInstance()->popToState0();
|
|
}
|
|
if (dSndMgr_c::GetInstance()->loadGroup(id, nullptr, 0)) {
|
|
mPrevStageGroup = id;
|
|
dSndPlayerMgr_c::GetInstance()->saveState2();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (round == 2) {
|
|
// we tried layer variant, now try variant without layer
|
|
const char *stageName = getCurrentStageName4();
|
|
label.sprintf("GRP_A_%s", stageName);
|
|
}
|
|
}
|
|
|
|
if (canReuseStageState) {
|
|
dSndPlayerMgr_c::GetInstance()->popToState2();
|
|
} else if (id == -1) {
|
|
if (bHasState1) {
|
|
dSndPlayerMgr_c::GetInstance()->popToState1();
|
|
} else {
|
|
dSndPlayerMgr_c::GetInstance()->popToState0();
|
|
}
|
|
dSndPlayerMgr_c::GetInstance()->saveState2();
|
|
mPrevStageGroup = -1;
|
|
}
|
|
|
|
if (!demo && (field_0x03C != 2 || field_0x065)) {
|
|
if (field_0x065) {
|
|
id = GRP_SIREN;
|
|
} else if (checkStageTypeFlag(STAGE_ROOM)) {
|
|
id = GRP_INDOOR;
|
|
} else if (checkStageTypeFlag(STAGE_FIELD)) {
|
|
id = GRP_FIELD;
|
|
} else if (checkStageTypeFlag(STAGE_DUNGEON)) {
|
|
if (isVolcanicDungeon(mStageId)) {
|
|
id = GRP_DUNGEON_BATTLE_ROOM;
|
|
} else {
|
|
id = GRP_DUNGEON;
|
|
}
|
|
} else if (checkStageTypeFlag(STAGE_BOSS)) {
|
|
id = GRP_BOSS;
|
|
} else {
|
|
id = GRP_DEFAULT;
|
|
}
|
|
|
|
if (id != -1) {
|
|
dSndMgr_c::GetInstance()->loadGroup(id, nullptr, 0);
|
|
}
|
|
}
|
|
|
|
if (!field_0x065) {
|
|
id = -1;
|
|
if (!demo) {
|
|
if (field_0x03C == 2) {
|
|
id = GRP_SKY;
|
|
} else if (checkStageTypeFlag(STAGE_FOREST)) {
|
|
id = GRP_FOREST;
|
|
} else if (checkStageTypeFlag(STAGE_MOUNTAIN)) {
|
|
id = GRP_MOUNTAIN;
|
|
} else if (checkStageTypeFlag(STAGE_DESERT)) {
|
|
id = GRP_DESERT;
|
|
}
|
|
|
|
if (id != -1) {
|
|
dSndMgr_c::GetInstance()->loadGroup(id, nullptr, 0);
|
|
}
|
|
}
|
|
|
|
SizedString<64> label;
|
|
label.sprintf("GRP_%s_L%d", &mStageName, mLayer);
|
|
id = dSndMgr_c::GetInstance()->getArchive()->ConvertLabelStringToGroupId(label);
|
|
if (id == -1) {
|
|
label.sprintf("GRP_%s", &mStageName);
|
|
id = dSndMgr_c::GetInstance()->getArchive()->ConvertLabelStringToGroupId(label);
|
|
}
|
|
|
|
if (id != -1) {
|
|
dSndMgr_c::GetInstance()->loadGroup(id, nullptr, 0);
|
|
}
|
|
|
|
if (demo) {
|
|
// REGSWAP
|
|
if (dSndPlayerMgr_c::GetInstance()->loadDemoArchive(getCurrentStageMusicDemoName())) {
|
|
for (u32 i = dSndPlayerMgr_c::PLAYER_LINK_BODY; i <= dSndPlayerMgr_c::PLAYER_EVENT; i++) {
|
|
dSndControlPlayerMgr_c::GetInstance()->getPlayer1(i)->StopAllSound(0);
|
|
}
|
|
dSndControlPlayerMgr_c::GetInstance()->setupPlayerControlsDemo();
|
|
}
|
|
}
|
|
}
|
|
|
|
field_0x4A8 = 0;
|
|
dSndBgmMgr_c::GetInstance()->loadStageSound();
|
|
f32 volume = -1.0f;
|
|
dSndAreaSoundEffectMgr_c::GetInstance()->loadStageSound(&volume);
|
|
if (volume > 0.0f) {
|
|
mFxSend3DDefault = volume;
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::calcEvent() {
|
|
if (!isInEvent()) {
|
|
return;
|
|
}
|
|
|
|
bool b = false;
|
|
if (dSndPlayerMgr_c::GetInstance()->checkFlag(dSndPlayerMgr_c::MGR_CAUTION) ||
|
|
dSndPlayerMgr_c::GetInstance()->checkFlag(dSndPlayerMgr_c::MGR_MAP) ||
|
|
dSndPlayerMgr_c::GetInstance()->checkFlag(dSndPlayerMgr_c::MGR_MSG_WAIT)) {
|
|
b = true;
|
|
}
|
|
|
|
if (mpSoundEventDef != nullptr && sEventExecuteCallback != nullptr) {
|
|
(sEventExecuteCallback)();
|
|
}
|
|
|
|
if (!b) {
|
|
if (EventManager::getCurrentEventName() == nullptr) {
|
|
if (!checkEventFlag(EVENT_0x800)) {
|
|
endEvent(false);
|
|
}
|
|
} else {
|
|
if (mSeLvSoundId != -1) {
|
|
dSndMgr_c::GetInstance()->holdSound(&mSeLvSoundHandle, mSeLvSoundId);
|
|
}
|
|
calcBgm();
|
|
calcSe();
|
|
calcCmd();
|
|
mFrameCounter++;
|
|
mCameraCutFrameCounter++;
|
|
mMsgFrameCounter++;
|
|
nw4r::snd::SeqSoundHandle::WriteGlobalVariable(2, mCameraCutFrameCounter);
|
|
}
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::setEvent(const char *eventName) {
|
|
if (eventName == nullptr) {
|
|
return;
|
|
}
|
|
|
|
if (dSndPlayerMgr_c::GetInstance()->checkFlag(dSndPlayerMgr_c::MGR_CAUTION)) {
|
|
dSndPlayerMgr_c::GetInstance()->leaveCaution();
|
|
}
|
|
|
|
if (!field_0x064) {
|
|
if (streq(mEventName, "DefaultSkip")) {
|
|
onSkipEvent();
|
|
mPrevEventName = mEventName;
|
|
return;
|
|
}
|
|
|
|
if (!checkFlag0x18(0x20) || !checkFlag0x10(FLAG0x10_0x04)) {
|
|
SizedString<64> prevEvent = mEventName;
|
|
if (isInEvent()) {
|
|
field_0x23C = 1;
|
|
finalizeEvent(false);
|
|
} else {
|
|
field_0x23C = 0;
|
|
}
|
|
|
|
// TODO - constness or direct access
|
|
if (checkEventFlag(EVENT_0x04)) {
|
|
offEventFlag(EVENT_0x04);
|
|
}
|
|
mEventName = eventName;
|
|
mPrevEventName = prevEvent;
|
|
resetEventVars();
|
|
field_0x23D = 0;
|
|
field_0x238 = -1;
|
|
|
|
if (streq(mEventName, "STB")) {
|
|
if (mpStbEventName != nullptr) {
|
|
mEventName = mpStbEventName;
|
|
}
|
|
onEventFlag(EVENT_DEMO);
|
|
} else {
|
|
mpStbEventName = nullptr;
|
|
}
|
|
|
|
if (!checkFlag0x10(FLAG0x10_0x04)) {
|
|
if (mpUnkCallback != nullptr) {
|
|
mpUnkCallback();
|
|
}
|
|
field_0x23D = 1;
|
|
dSndBgmMgr_c::GetInstance()->setField_0x306(1);
|
|
dSndBgmMgr_c::GetInstance()->prepareBgm();
|
|
onEventFlag(EVENT_0x04);
|
|
onFlag0x10(FLAG0x10_0x04);
|
|
dSndControlPlayerMgr_c::GetInstance()->unmuteScenePlayers(30);
|
|
}
|
|
bool b2 = checkEventFlag(EVENT_0x800) && dSndBgmMgr_c::GetInstance()->isPlayingBgmSound();
|
|
if (checkEventFlag(EVENT_0x800) && !field_0x064) {
|
|
// TODO - constness or direct access
|
|
offEventFlag(0x800);
|
|
}
|
|
|
|
mSoundEventId = SND_EVENT_0x89;
|
|
initializeEventCallbacks(mEventName);
|
|
s32 i3 = 0;
|
|
SizedString<64> eventLabel;
|
|
if (mSoundEventId == SND_EVENT_JMAP) {
|
|
s32 eventRoomId = EventManager::getCurrentEventRoomId();
|
|
// UB: Cannot pass object of non-POD type 'SizedString<32>' through variadic method
|
|
eventLabel.sprintf("%s_R%d_JMAP_%d", mStageName, mRoomId, eventRoomId);
|
|
} else if (mSoundEventId == SND_EVENT_JMAPAllMove) {
|
|
s32 eventRoomId = EventManager::getCurrentEventRoomId();
|
|
// UB: Cannot pass object of non-POD type 'SizedString<32>' through variadic method
|
|
eventLabel.sprintf("%s_R%d_JMAPAllMove_%d", mStageName, mRoomId, eventRoomId);
|
|
} else {
|
|
eventLabel.sprintf("%s", &mEventName);
|
|
}
|
|
|
|
if (checkEventFlag(EVENT_DEMO)) {
|
|
mBgmName.sprintf("BGM_%s", &eventLabel);
|
|
mFanName.sprintf("FAN_%s", &eventLabel);
|
|
mSeName.sprintf("SE_%s", &eventLabel);
|
|
mCmdName.sprintf("CMD_%s", &eventLabel);
|
|
} else {
|
|
mBgmName.sprintf("BGM_EVENT_%s", &eventLabel);
|
|
mFanName.sprintf("FAN_EVENT_%s", &eventLabel);
|
|
mSeName.sprintf("SE_EVENT_%s", &eventLabel);
|
|
mCmdName.sprintf("CMD_EVENT_%s", &eventLabel);
|
|
}
|
|
|
|
if (checkEventFlag(EVENT_0x04)) {
|
|
field_0x238 = getBgmLabelSoundId();
|
|
if (b2 && field_0x238 == -1) {
|
|
field_0x23D = 0;
|
|
}
|
|
} else {
|
|
i3 = playFanOrBgm(getBgmLabelSoundId());
|
|
if (i3) {
|
|
field_0x23D = 0;
|
|
}
|
|
}
|
|
|
|
handleFan();
|
|
handleSe();
|
|
handleSeLv();
|
|
handleCmd();
|
|
|
|
if (mSoundEventId != SND_EVENT_0x89) {
|
|
onEventFlag(EVENT_IN_EVENT);
|
|
mFrameCounter = 0;
|
|
mCameraCutFrameCounter = 0;
|
|
mMsgFrameCounter = 0;
|
|
if (mpOnEventStartCallback != nullptr) {
|
|
(mpOnEventStartCallback)(mSoundEventId, mEventFlags);
|
|
}
|
|
if (field_0x238 == -1) {
|
|
dSndBgmMgr_c::GetInstance()->onEventStart(mEventName, mSoundEventId, i3);
|
|
}
|
|
dSndAreaSoundEffectMgr_c::GetInstance()->onEventStart();
|
|
dSndSourceMgr_c::GetInstance()->onEventStart();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool dSndStateMgr_c::isInStage(const char *stageName) {
|
|
return !std::strcmp(dScGame_c::currentSpawnInfo.getStageName(), stageName);
|
|
}
|
|
|
|
void dSndStateMgr_c::initializeEventCallbacks(const char *name) {
|
|
if (name == nullptr) {
|
|
return;
|
|
}
|
|
|
|
mpSoundEventDef = nullptr;
|
|
sEventExecuteCallback = nullptr;
|
|
resetOverrides();
|
|
|
|
if (checkEventFlag(EVENT_DEMO)) {
|
|
handleDemoEvent(name);
|
|
return;
|
|
}
|
|
|
|
if (mSoundEventId == SND_EVENT_0x87) {
|
|
return;
|
|
}
|
|
|
|
if (!handleStageEvent(name)) {
|
|
handleGlobalEvent(name);
|
|
}
|
|
|
|
if (mSoundEventId == SND_EVENT_0x89) {
|
|
if (strstr(name, "Intro")) {
|
|
mSoundEventId = SND_EVENT_0x88;
|
|
} else {
|
|
mSoundEventId = SND_EVENT_0x86;
|
|
cbUnkNoop();
|
|
}
|
|
}
|
|
}
|
|
|
|
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(getCameraFmt(), &mSeName, mCameraCutCounter, mCameraCutFrameCounter);
|
|
return convertSeLabelToSoundId(label);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getSeMsgWaitId() {
|
|
SizedString<64> label;
|
|
label.sprintf(getMsgWaitFmt(), &mSeName, mMsgCounter, mMsgWaitSelectCounter, mMsgFrameCounter);
|
|
return convertSeLabelToSoundId(label);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getSeFrameCountId() {
|
|
SizedString<64> label;
|
|
label.sprintf(getFrameFmt(), &mSeName, mFrameCounter);
|
|
return convertSeLabelToSoundId(label);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getBgmCameraId() {
|
|
SizedString<64> label;
|
|
label.sprintf(getCameraFmt(), &mBgmName, mCameraCutCounter, mCameraCutFrameCounter);
|
|
return convertBgmLabelToSoundId(label);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getBgmMsgWaitId() {
|
|
SizedString<64> label;
|
|
label.sprintf(getMsgWaitFmt(), &mBgmName, mMsgCounter, mMsgWaitSelectCounter, mMsgFrameCounter);
|
|
return convertBgmLabelToSoundId(label);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getBgmFrameCountId() {
|
|
SizedString<64> label;
|
|
label.sprintf(getFrameFmt(), &mBgmName, mFrameCounter);
|
|
return convertBgmLabelToSoundId(label);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getCmdCameraId() {
|
|
SizedString<64> label;
|
|
label.sprintf(getCameraFmt(), &mCmdName, mCameraCutCounter, mCameraCutFrameCounter);
|
|
return convertCmdLabelToSoundId(label);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getCmdMsgWaitId() {
|
|
SizedString<64> label;
|
|
label.sprintf(getMsgWaitFmt(), &mCmdName, mMsgCounter, mMsgWaitSelectCounter, mMsgFrameCounter);
|
|
return convertCmdLabelToSoundId(label);
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getCmdFrameCountId() {
|
|
SizedString<64> label;
|
|
label.sprintf(getFrameFmt(), &mCmdName, mFrameCounter);
|
|
return convertCmdLabelToSoundId(label);
|
|
}
|
|
|
|
void dSndStateMgr_c::clearEventExecuteCallback() {
|
|
sEventExecuteCallback = nullptr;
|
|
}
|
|
|
|
bool dSndStateMgr_c::calcBgm() {
|
|
bool ok = playFanOrBgm(getBgmCameraId());
|
|
if (!ok) {
|
|
ok = playFanOrBgm(getBgmMsgWaitId());
|
|
}
|
|
if (!ok) {
|
|
// @bug (?) shouldn't this assign to ok? Maybe a shadowing redeclaration...
|
|
(void)playFanOrBgm(getBgmFrameCountId());
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
void dSndStateMgr_c::calcSe() {
|
|
playSe(getSeCameraId());
|
|
playSe(getSeMsgWaitId());
|
|
playSe(getSeFrameCountId());
|
|
}
|
|
|
|
void dSndStateMgr_c::handleSeLv() {
|
|
SizedString<0x40> name = mSeName;
|
|
name += "_LV";
|
|
u32 soundId = convertSeLabelToSoundId(name);
|
|
if (soundId != -1) {
|
|
mSeLvSoundId = soundId;
|
|
if (dSndMgr_c::GetInstance()->holdSound(&mSeLvSoundHandle, soundId)) {
|
|
u32 id = dSndPlayerMgr_c::GetInstance()->getDemoArchive()->GetSoundUserParam(soundId);
|
|
if ((dSndPlayerMgr_c::sEventMuteFlagsMask & id & 0x2000000) == 0) {
|
|
mSeLvSoundHandle.SetFxSend(nw4r::snd::AUX_A, mFxSend3D);
|
|
}
|
|
}
|
|
} else {
|
|
mSeLvSoundId = -1;
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::calcCmd() {
|
|
playCmd(getCmdCameraId());
|
|
playCmd(getCmdMsgWaitId());
|
|
playCmd(getCmdFrameCountId());
|
|
}
|
|
|
|
bool dSndStateMgr_c::finalizeEvent(bool skipped) {
|
|
dSndPlayerMgr_c *mgr = dSndPlayerMgr_c::GetInstance();
|
|
if (mgr->checkFlag(dSndPlayerMgr_c::MGR_CAUTION)) {
|
|
mgr->leaveCaution();
|
|
}
|
|
if (!isInEvent()) {
|
|
return false;
|
|
}
|
|
|
|
if (mpSoundEventDef != nullptr && mpSoundEventDef->finalizeCb) {
|
|
mpSoundEventDef->finalizeCb(skipped);
|
|
}
|
|
|
|
if (!isInDemo()) {
|
|
nw4r::snd::SoundPlayer *p = dSndControlPlayerMgr_c::GetInstance()->getPlayer1(dSndPlayerMgr_c::PLAYER_EVENT);
|
|
SoundStopperIfParamFlag20 stopper;
|
|
p->ForEachSound(stopper, false);
|
|
}
|
|
|
|
SizedString<64> label;
|
|
label.sprintf("%s_FIN", &mSeName);
|
|
playSe(dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(label));
|
|
label.sprintf("%s_FIN", &mBgmName);
|
|
doBgm(label);
|
|
label.sprintf("%s_FIN", &mCmdName);
|
|
doCmd(label);
|
|
|
|
return dSndBgmMgr_c::GetInstance()->onEventFinalize(mEventName, mSoundEventId, skipped);
|
|
}
|
|
|
|
// 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%d_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%d_WE%d", mMsgCounter, mMsgWaitSelectCounter);
|
|
doLabelSuffix(label);
|
|
}
|
|
|
|
void dSndStateMgr_c::onLinkDie() {
|
|
if (!checkFlag0x10(FLAG0x10_0x08)) {
|
|
onFlag0x10(FLAG0x10_0x08);
|
|
dSndBgmMgr_c::GetInstance()->stopAllBgm(15);
|
|
dSndSmallEffectMgr_c::GetInstance()->stopAllSoundExceptEffectOrLink(15);
|
|
if (field_0x065 == 0) {
|
|
dSndBgmMgr_c::GetInstance()->prepareFanSound(FAN_GAMEOVER);
|
|
}
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::setStbEventName(const char *eventName) {
|
|
mpStbEventName = eventName;
|
|
}
|
|
|
|
void dSndStateMgr_c::calcRoomId() {
|
|
if (checkFlag0x10(FLAG0x10_0x04)) {
|
|
if (mCheckRoomIdCooldown > 0) {
|
|
mCheckRoomIdCooldown--;
|
|
} else {
|
|
if (mRoomId == -1) {
|
|
mCheckRoomIdCooldown = 30;
|
|
}
|
|
s32 newRoom = dSndSourceMgr_c::GetInstance()->getPlayerSourceRoomId();
|
|
if (mRoomId != newRoom) {
|
|
setRoomId(newRoom);
|
|
} else if (newRoom != -1 && !checkFlag0x10(FLAG0x10_0x10)) {
|
|
setRoomId(newRoom);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::setRoomId(s32 roomId) {
|
|
// ...
|
|
}
|
|
|
|
void dSndStateMgr_c::calcTgSnd() {
|
|
mHasChangedTgSndAreaFlags = false;
|
|
mHasChangedTgSndAreaMgFlags = false;
|
|
dAcPy_c *link = dAcPy_c::GetLinkM();
|
|
if (link != nullptr && dTgSndMg_c::GetInstance() != nullptr) {
|
|
u32 flags = dTgSndMg_c::GetInstance()->getSndFlags();
|
|
if (flags != mSavedTgSndAreaMgFlags) {
|
|
mHasChangedTgSndAreaMgFlags = true;
|
|
if (mpTgSndAreaMgFlagsChangeCallback != nullptr) {
|
|
(mpTgSndAreaMgFlagsChangeCallback)(flags, mSavedTgSndAreaMgFlags);
|
|
}
|
|
dSndBgmMgr_c::GetInstance()->onTgSndAreaMgFlagsChange(flags, mSavedTgSndAreaMgFlags);
|
|
mSavedTgSndAreaMgFlags = flags;
|
|
}
|
|
|
|
if (dSndSourceMgr_c::getBoomerangSource() != nullptr) {
|
|
flags = mSavedTgSndAreaMgFlags;
|
|
} else {
|
|
flags = link->mTgSndAreaFlags;
|
|
}
|
|
if (flags != mSavedTgSndAreaFlags) {
|
|
mHasChangedTgSndAreaFlags = true;
|
|
if (mpTgSndAreaFlagsChangeCallback != nullptr) {
|
|
(mpTgSndAreaFlagsChangeCallback)(flags, mSavedTgSndAreaFlags);
|
|
}
|
|
mFxSend3DNext = getUserParamVolume(flags);
|
|
dSndBgmMgr_c::GetInstance()->onTgSndAreaFlagsChange(flags, mSavedTgSndAreaFlags);
|
|
mSavedTgSndAreaFlags = flags;
|
|
}
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::calcFilters() {
|
|
dCamera_c *cam = dScGame_c::getCamera(0);
|
|
if (cam != nullptr && !checkFlag0x258(0x2)) {
|
|
if (cam->isUnderwater()) {
|
|
if (!checkFlag0x258(0x1)) {
|
|
resetFlag0x258();
|
|
onFlag0x258(1);
|
|
setFiltersIfUnderwater();
|
|
}
|
|
f32 depth = cam->getUnderwaterDepth();
|
|
dSndAreaSoundEffectMgr_c::GetInstance()->holdInWaterLvSound(depth);
|
|
f32 maxDepth = isInStage("F103") ? 5000.0f : 1000.0f;
|
|
f32 unk = isInStage("F103") ? 0.5f : 0.3f;
|
|
if (depth < maxDepth) {
|
|
f32 tmp = (1.0f - unk);
|
|
f32 tmp2 = (depth / maxDepth);
|
|
unk = 1.0f - tmp2 * tmp;
|
|
}
|
|
dSndBgmMgr_c::GetInstance()->updateField_0x2F4(unk);
|
|
} else {
|
|
if (checkFlag0x258(0x1)) {
|
|
offFlag0x258(1);
|
|
resetLpfAndFxSend();
|
|
}
|
|
|
|
if (dAcPy_c::GetLink()->checkActionFlagsCont(0x400000)) {
|
|
if (!checkFlag0x258(0x4)) {
|
|
resetFlag0x258();
|
|
onFlag0x258(0x4);
|
|
setBgmAndStageEffectLpf();
|
|
dSndBgmMgr_c::GetInstance()->setField_0x307(0);
|
|
}
|
|
} else {
|
|
if (checkFlag0x258(0x4)) {
|
|
offFlag0x258(0x4);
|
|
resetBgmAndStageEffectLpf();
|
|
if (dSndBgmMgr_c::GetInstance()->getField_0x308() != 0) {
|
|
dSndBgmMgr_c::GetInstance()->setField_0x307(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::calcFxSend3D() {
|
|
if (mFxSend3D > mFxSend3DTarget) {
|
|
mFxSend3D -= 0.02f;
|
|
if (mFxSend3D < mFxSend3DTarget) {
|
|
mFxSend3D = mFxSend3DTarget;
|
|
}
|
|
} else if (mFxSend3D < mFxSend3DTarget) {
|
|
mFxSend3D += 0.02f;
|
|
if (mFxSend3D > mFxSend3DTarget) {
|
|
mFxSend3D = mFxSend3DTarget;
|
|
}
|
|
}
|
|
}
|
|
|
|
void dSndStateMgr_c::setFxSend3DTarget() {
|
|
// TODO - weird control flow
|
|
f32 target = mFxSend3DDefault;
|
|
if (mFxSend3DNext > 0.0f) {
|
|
target = mFxSend3DNext;
|
|
} else if (mFxSend3DOverride > 0.0f) {
|
|
target = mFxSend3DOverride;
|
|
}
|
|
|
|
if (target < 0.02f) {
|
|
target = 0.02f;
|
|
} else if (target > 0.3f) {
|
|
target = 0.3f;
|
|
}
|
|
mFxSend3DTarget = target;
|
|
}
|
|
|
|
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";
|
|
}
|
|
return dSndStageInfo::sInfos[id].stageName;
|
|
}
|
|
|
|
const char *dSndStateMgr_c::getStageName4(s32 id) {
|
|
if (id >= SND_STAGE_MAX) {
|
|
return "NULL";
|
|
}
|
|
return dSndStageInfo::sInfos[getSndStageId4(id)].stageName;
|
|
}
|
|
|
|
const char *dSndStateMgr_c::getCurrentStageName4() {
|
|
return getStageName(dSndStageInfo::sInfos[mStageId].unk4);
|
|
}
|
|
|
|
s32 dSndStateMgr_c::getSndStageId(const char *stageName, s32 layer) {
|
|
if (stageName != nullptr) {
|
|
for (s32 idx = 0; idx < dSndStageInfo::sNumStageInfos; idx++) {
|
|
if (streq(stageName, dSndStageInfo::sInfos[idx].stageName)) {
|
|
if (dSndStageInfo::sInfos[idx].layer == -1) {
|
|
return dSndStageInfo::sInfos[idx].unk1;
|
|
}
|
|
if (dSndStageInfo::sInfos[idx].layer == layer) {
|
|
return dSndStageInfo::sInfos[idx].unk1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return SND_STAGE_MAX;
|
|
}
|
|
|
|
s32 dSndStateMgr_c::getSndStageId3(const char *stageName, s32 layer) {
|
|
if (stageName != nullptr) {
|
|
for (s32 idx = 0; idx < dSndStageInfo::sNumStageInfos; idx++) {
|
|
if (streq(stageName, dSndStageInfo::sInfos[idx].stageName)) {
|
|
if (dSndStageInfo::sInfos[idx].layer == -1 || dSndStageInfo::sInfos[idx].layer == layer) {
|
|
return dSndStageInfo::sInfos[idx].unk3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return SND_STAGE_MAX;
|
|
}
|
|
|
|
s32 dSndStateMgr_c::getSndStageId4(const char *stageName, s32 layer) {
|
|
if (stageName != nullptr) {
|
|
for (s32 idx = 0; idx < dSndStageInfo::sNumStageInfos; idx++) {
|
|
if (streq(stageName, dSndStageInfo::sInfos[idx].stageName)) {
|
|
if (dSndStageInfo::sInfos[idx].layer == -1 || dSndStageInfo::sInfos[idx].layer == layer) {
|
|
return dSndStageInfo::sInfos[idx].unk4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return SND_STAGE_MAX;
|
|
}
|
|
|
|
s32 dSndStateMgr_c::getSndStageId2(s32 id) {
|
|
if (id >= SND_STAGE_MAX) {
|
|
return SND_STAGE_MAX;
|
|
}
|
|
return dSndStageInfo::sInfos[id].unk2;
|
|
}
|
|
|
|
s32 dSndStateMgr_c::getSndStageId4(s32 id) {
|
|
if (id >= SND_STAGE_MAX) {
|
|
return SND_STAGE_MAX;
|
|
}
|
|
return dSndStageInfo::sInfos[id].unk4;
|
|
}
|
|
|
|
s32 dSndStateMgr_c::getNextSndStageId(s32 id) {
|
|
return getSndStageId(dScGame_c::nextSpawnInfo.getStageName(), dScGame_c::nextSpawnInfo.layer);
|
|
}
|
|
|
|
bool dSndStateMgr_c::specialLayerVersionExists(const char *stageName, s32 layer) {
|
|
if (stageName != nullptr && layer > 0) {
|
|
return getSndStageId(stageName, layer) != getSndStageId(stageName, 0);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
u32 dSndStateMgr_c::getSoundIdForStageAndLayer(SoundIdLookup_e lookup, const char *stageName, s32 layer, s32 stageId) {
|
|
// Ternary causes regswaps...
|
|
const char *prefix = "BGM_";
|
|
if (lookup == LOOKUP_SE_A) {
|
|
prefix = "SE_A_";
|
|
}
|
|
SizedString<64> label;
|
|
|
|
u32 soundId = -1;
|
|
s32 round = 3;
|
|
|
|
bool hasSpecialLayerVersion = false;
|
|
if (layer > 0) {
|
|
hasSpecialLayerVersion = specialLayerVersionExists(stageName, layer);
|
|
}
|
|
|
|
if (hasSpecialLayerVersion) {
|
|
label.sprintf("%s%s_L%d", prefix, stageName, layer);
|
|
} else if (layer > 0) {
|
|
label.sprintf("%s%s_L%d", prefix, stageName, layer);
|
|
} else {
|
|
label.sprintf("%s%s", prefix, stageName);
|
|
// We didn't bother with a _L layer variant, so we're going
|
|
// in with the base variant
|
|
round = 2;
|
|
}
|
|
|
|
while (round > 0) {
|
|
if (lookup == LOOKUP_BGM_MAIN) {
|
|
label += "_MAIN";
|
|
}
|
|
|
|
soundId = dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(label);
|
|
if (soundId != -1) {
|
|
break;
|
|
}
|
|
|
|
if (round == 3) {
|
|
// If _L layer variant didn't exist, try the one without a layer...
|
|
label.sprintf("%s%s", prefix, stageName);
|
|
} else if (round == 2) {
|
|
if (lookup == LOOKUP_BGM) {
|
|
// If the one without a layer doesn't exist, continue with the one referenced
|
|
// in field 3, unless it's the same as the original one
|
|
s32 otherStageId = getSndStageId3(stageName, layer);
|
|
if (stageId != otherStageId) {
|
|
label.sprintf("%s%s", prefix, getStageName(otherStageId));
|
|
} else {
|
|
// break to prevent infinite loop
|
|
round = 0;
|
|
}
|
|
} else if (lookup == LOOKUP_SE_A) {
|
|
// If the one without a layer doesn't exist, continue with the one referenced
|
|
// in field 4, unless it's the same as the original one
|
|
s32 otherStageId = getSndStageId4(stageName, layer);
|
|
if (stageId != otherStageId) {
|
|
label.sprintf("%s%s", prefix, getStageName(otherStageId));
|
|
} else {
|
|
// break to prevent infinite loop
|
|
break;
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
round--;
|
|
}
|
|
|
|
return soundId;
|
|
}
|