summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-06-14 16:40:55 +0200
committerrobojumper <robojumper@gmail.com>2025-09-13 10:49:07 +0200
commitcb8c482c3b7e955f1ca274601567ed3785c3996b (patch)
tree2024a87c430bc8447def892bf265e9113fa6f94b /src
parentf730fa82862d9abef8c6745fdfea81f2bfcb957c (diff)
Getting somewhere
Diffstat (limited to 'src')
-rw-r--r--src/d/snd/d_snd_bgm_mgr.cpp1
-rw-r--r--src/d/snd/d_snd_distant_sound_actor.cpp14
-rw-r--r--src/d/snd/d_snd_distant_sound_actor_pool.cpp58
-rw-r--r--src/d/snd/d_snd_se_sound.cpp4
-rw-r--r--src/d/snd/d_snd_se_sound_pool.cpp4
-rw-r--r--src/d/snd/d_snd_small_effect_mgr.cpp2
-rw-r--r--src/d/snd/d_snd_source.cpp540
-rw-r--r--src/d/snd/d_snd_state_mgr.cpp2
-rw-r--r--src/nw4r/snd/snd_BasicPlayer.cpp2
-rw-r--r--src/nw4r/snd/snd_BasicSound.cpp2
-rw-r--r--src/nw4r/snd/snd_Channel.cpp2
-rw-r--r--src/nw4r/snd/snd_SoundPlayer.cpp2
-rw-r--r--src/nw4r/snd/snd_Voice.cpp6
13 files changed, 613 insertions, 26 deletions
diff --git a/src/d/snd/d_snd_bgm_mgr.cpp b/src/d/snd/d_snd_bgm_mgr.cpp
index 9305808f..020350c4 100644
--- a/src/d/snd/d_snd_bgm_mgr.cpp
+++ b/src/d/snd/d_snd_bgm_mgr.cpp
@@ -66,6 +66,7 @@ dSndBgmMgr_c::dSndBgmMgr_c()
void dSndBgmMgr_c::calcLists() {
// TODO ...
+ // TODO: Weird declaration order required for regswaps
dSndBgmSound_c *next, *it;
for (it = getFirstInBgmSoundList(BGM_LIST_PLAYING); it != nullptr; it = next) {
diff --git a/src/d/snd/d_snd_distant_sound_actor.cpp b/src/d/snd/d_snd_distant_sound_actor.cpp
index c06c96af..c7c94d26 100644
--- a/src/d/snd/d_snd_distant_sound_actor.cpp
+++ b/src/d/snd/d_snd_distant_sound_actor.cpp
@@ -13,7 +13,7 @@ dSndDistantSoundActor_c::dSndDistantSoundActor_c()
field_0x0F4(0),
mpSoundSource(nullptr),
mpSoundHandle(&mSoundHandle),
- field_0x104(0),
+ mIsActive(false),
mUseSourcePosition(false) {}
void dSndDistantSoundActor_c::initSource(dSoundSource_c *pSource) {
@@ -38,6 +38,18 @@ void dSndDistantSoundActor_c::updatePosition() {
}
}
+void dSndDistantSoundActor_c::d_vt_0x58(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id) {
+ if (mpSoundSource != nullptr) {
+ mpSoundSource->d_vt_0x58(handle, pSound, id);
+ }
+}
+
+void dSndDistantSoundActor_c::d_vt_0x5C(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id, UNKWORD arg) {
+ if (mpSoundSource != nullptr) {
+ mpSoundSource->d_vt_0x5C(handle, pSound, id, arg);
+ }
+}
+
bool dSndDistantSoundActor_c::startSound(
u32 soundId, const nw4r::math::VEC3 &position, nw4r::snd::SoundHandle *pHandle
) {
diff --git a/src/d/snd/d_snd_distant_sound_actor_pool.cpp b/src/d/snd/d_snd_distant_sound_actor_pool.cpp
index 4cd6530b..d8ffa83e 100644
--- a/src/d/snd/d_snd_distant_sound_actor_pool.cpp
+++ b/src/d/snd/d_snd_distant_sound_actor_pool.cpp
@@ -1,11 +1,13 @@
#include "d/snd/d_snd_distant_sound_actor_pool.h"
+#include "common.h"
+#include "d/snd/d_snd_distant_sound_actor.h"
+#include "d/snd/d_snd_source.h"
#include "m/m_vec.h"
#include "nw4r/ut/ut_list.h"
#include <cmath>
-
SND_DISPOSER_DEFINE(dSndDistantSoundActorPool_c);
dSndSourceParam dSndDistantSoundActorPool_c::sParam;
@@ -13,10 +15,62 @@ dSndSourceParam dSndDistantSoundActorPool_c::sParam;
dSndDistantSoundActorPool_c::dSndDistantSoundActorPool_c() {
field_0x4210 = 0;
// TODO offsetof
- nw4r::ut::List_Init(&mList, 0xE4);
+ nw4r::ut::List_Init(&mActiveActors, 0xE4);
sParam.reset(INFINITY);
}
+dSndDistantSoundActor_c *
+dSndDistantSoundActorPool_c::acquireActor(u32 soundId, const nw4r::math::VEC3 *position, dSoundSource_c *source) {
+ if (soundId == -1) {
+ return nullptr;
+ }
+
+ dSndDistantSoundActor_c *ac = nullptr;
+ int i = 0;
+ while (ac == nullptr) {
+ ac = &mSounds[field_0x4210];
+ field_0x4210++;
+ if (field_0x4210 >= POOL_SIZE) {
+ field_0x4210 = 0;
+ }
+ if (ac->isActive()) {
+ i++;
+ ac = nullptr;
+ if (i >= POOL_SIZE) {
+ break;
+ }
+ }
+ }
+
+ if (ac != nullptr) {
+ if (source != nullptr) {
+ ac->initSource(source);
+ source->attachDistantSound(ac);
+ } else {
+ ac->loadDefaultParam();
+ ac->setSource(nullptr);
+ }
+ ac->SetPosition(*position);
+ ac->updateListenerParameters();
+ ac->updateCameraTargetParameters();
+
+ addToActiveList(ac, soundId);
+
+ return ac;
+ }
+ return nullptr;
+}
+
+void dSndDistantSoundActorPool_c::addToActiveList(dSndDistantSoundActor_c *actor, u32 id) {
+ if (actor == nullptr) {
+ return;
+ }
+ if (actor->isActive()) {
+ return;
+ }
+ nw4r::ut::List_Append(&mActiveActors, actor);
+ actor->setActive(true);
+}
void dSndDistantSoundActorPool_c::onChangeStage() {
mVec3_c v(INFINITY, INFINITY, INFINITY);
diff --git a/src/d/snd/d_snd_se_sound.cpp b/src/d/snd/d_snd_se_sound.cpp
index 7454da81..3ab0a0ff 100644
--- a/src/d/snd/d_snd_se_sound.cpp
+++ b/src/d/snd/d_snd_se_sound.cpp
@@ -4,7 +4,7 @@
#include "d/snd/d_snd_source.h"
dSndSeSound_c::dSndSeSound_c()
- : field_0x014(0),
+ : mpSource(nullptr),
mpSoundHandle(&mSound),
mHandleType(SE_HANDLE_TYPE_1),
mSoundId(-1),
@@ -40,7 +40,7 @@ void dSndSeSound_c::setSource(dSoundSource_c *source, u32 soundId) {
void dSndSeSound_c::clear() {
field_0x114 = -1;
- field_0x014 = 0;
+ mpSource = nullptr;
mpCalcCallback = nullptr;
mpStartCallback = nullptr;
mpSoundHandle = &mSound;
diff --git a/src/d/snd/d_snd_se_sound_pool.cpp b/src/d/snd/d_snd_se_sound_pool.cpp
index 450b3e3a..9c5cfc70 100644
--- a/src/d/snd/d_snd_se_sound_pool.cpp
+++ b/src/d/snd/d_snd_se_sound_pool.cpp
@@ -66,13 +66,13 @@ dSndSeSound2_c *dSndSeSoundPool_c::acquireSoundType2(dSoundSource_c *source, u32
return nullptr;
}
-void dSndSeSoundPool_c::releaseSoundType1(dSndSeSound1_c *sound, bool arg) {
+void dSndSeSoundPool_c::releaseSoundType1(dSndSeSound1_c *sound, bool stop) {
if (sound == nullptr) {
return;
}
if (sound->isAttachedSound()) {
- if (arg) {
+ if (stop) {
sound->stop(0);
sound->clear();
nw4r::ut::List_Append(&mFreeType1List, sound);
diff --git a/src/d/snd/d_snd_small_effect_mgr.cpp b/src/d/snd/d_snd_small_effect_mgr.cpp
index 1dca1655..ba048d90 100644
--- a/src/d/snd/d_snd_small_effect_mgr.cpp
+++ b/src/d/snd/d_snd_small_effect_mgr.cpp
@@ -185,7 +185,7 @@ void dSndSmallEffectMgr_c::resetButtonPressSound() {
void dSndSmallEffectMgr_c::setButtonPressSound(dSoundSource_c *source) {
resetButtonPressSound();
if (source != nullptr) {
- mTextboxAdvanceSound = dSoundSource_c::getCharacterTalkSoundId(SE_S_TALK_CHAR, source);
+ mTextboxAdvanceSound = dSoundSource_c::modifySoundId(SE_S_TALK_CHAR, source);
if (mTextboxAdvanceSound == SE_S_TALK_CHAR) {
resetButtonPressSound();
}
diff --git a/src/d/snd/d_snd_source.cpp b/src/d/snd/d_snd_source.cpp
index 7085108e..d0de9e6c 100644
--- a/src/d/snd/d_snd_source.cpp
+++ b/src/d/snd/d_snd_source.cpp
@@ -4,12 +4,18 @@
#include "d/a/d_a_base.h"
#include "d/snd/d_snd_3d_actor.h"
#include "d/snd/d_snd_3d_manager.h"
+#include "d/snd/d_snd_checkers.h"
#include "d/snd/d_snd_distant_sound_actor.h"
+#include "d/snd/d_snd_distant_sound_actor_pool.h"
#include "d/snd/d_snd_mgr.h"
#include "d/snd/d_snd_player_mgr.h"
+#include "d/snd/d_snd_se_sound_pool.h"
#include "d/snd/d_snd_source_group.h"
#include "d/snd/d_snd_source_mgr.h"
+#include "egg/audio/eggAudioRmtSpeakerMgr.h"
+#include "nw4r/snd/snd_SoundHandle.h"
#include "nw4r/snd/snd_SoundStartable.h"
+#include "nw4r/snd/snd_global.h"
#include "nw4r/ut/ut_list.h"
#include "sized_string.h"
@@ -39,7 +45,7 @@ dSoundSource_c::dSoundSource_c(u8 sourceType, dAcBase_c *actor, const char *name
field_0x102(0),
field_0x104(0),
field_0x108(0),
- field_0x10C(0),
+ mpUnkSe(nullptr),
field_0x11C(0),
mpOwnerGroup(pOwnerGroup),
field_0x154(0),
@@ -48,14 +54,15 @@ dSoundSource_c::dSoundSource_c(u8 sourceType, dAcBase_c *actor, const char *name
mSourceCategory = dSndSourceMgr_c::getSourceCategoryForSourceType(sourceType, name);
// TODO: Offsetof
nw4r::ut::List_Init(&mDistantSoundList, 0xEC);
- nw4r::ut::List_Init(&field_0x120, 0x04);
- nw4r::ut::List_Init(&field_0x12C, 0x04);
+ nw4r::ut::List_Init(&mHandleType1List, 0x04);
+ nw4r::ut::List_Init(&mHandleType2List, 0x04);
pOwnerGroup->registerSource(this);
}
dSoundSource_c::~dSoundSource_c() {
SetUserParam(0);
vt_0x44();
+ removeAllSeHandles();
detachAllDistantSounds();
dSndSourceMgr_c::GetInstance()->unregisterSource(this);
mpOwnerGroup->unregisterSource(this);
@@ -89,21 +96,347 @@ void dSoundSource_c::setPause(bool flag, int fadeFrames) {
}
}
+bool dSoundSource_c::startSound(u32 soundId) {
+ return startSound(soundId, nullptr);
+}
+
+bool dSoundSource_c::startSound(const char *label) {
+ return startSound(soundLabelToSoundId(label));
+}
+
+bool dSoundSource_c::startRemoConSound(u32 soundId) {
+ nw4r::snd::SoundHandle *outHandle = nullptr;
+ StartResult result = startSound(soundId, nullptr, &outHandle);
+ if (result == START_SUCCESS && EGG::AudioRmtSpeakerMgr::getWpadVolume() != 0) {
+ outHandle->SetOutputLineFlag(nw4r::snd::OUTPUT_LINE_REMOTE_1);
+ }
+ return result == START_SUCCESS;
+}
+
+nw4r::snd::SoundHandle *dSoundSource_c::startSound(u32 soundId, nw4r::snd::SoundHandle *handle) {
+ nw4r::snd::SoundHandle *outHandle = nullptr;
+ StartResult result = startSound(soundId, handle, &outHandle);
+ if (result == START_SUCCESS) {
+ return outHandle;
+ }
+ return nullptr;
+}
+
+nw4r::snd::SoundStartable::StartResult
+dSoundSource_c::startSound(u32 soundId, nw4r::snd::SoundHandle *handle, nw4r::snd::SoundHandle **pOutHandle) {
+ StartResult result;
+
+ dSndSeSound1_c *seHandle = dSndSeSoundPool_c::GetInstance()->acquireSoundType1(this, soundId);
+ if (seHandle == nullptr) {
+ d_s_vt_0x1C8();
+ return START_ERR_USER;
+ }
+
+ seHandle->shiftPair(mpUnkSe);
+ if (handle != nullptr) {
+ seHandle->setHandle(handle);
+ } else {
+ handle = seHandle->getHandle();
+ }
+
+ field_0x11C |= 0x80000000;
+ result = detail_StartSound(handle, soundId, nullptr);
+ if (result == START_SUCCESS) {
+ addSeHandleType1(seHandle);
+ d_vt_0x58(*handle, seHandle, soundId);
+ d_s_vt_0x1CC(handle->GetId(), soundId, seHandle);
+ seHandle->onStart(this);
+ seHandle->onCalc(this);
+ } else {
+ dSndSeSoundPool_c::GetInstance()->releaseSoundType1(seHandle, true);
+ handle = nullptr;
+ }
+ d_s_vt_0x1C8();
+ if (pOutHandle != nullptr) {
+ *pOutHandle = handle;
+ }
+ return result;
+}
+
+dSndDistantSoundActor_c *
+dSoundSource_c::startSoundAtPosition(u32 soundId, const nw4r::math::VEC3 *position, nw4r::snd::SoundHandle *handle) {
+ if (position == nullptr) {
+ position = &GetPosition();
+ }
+ dSndSeSound1_c *seHandle = nullptr;
+ if (handle != nullptr) {
+ seHandle = getHandleType1ForSoundHandle(handle);
+ }
+ if (seHandle == nullptr) {
+ seHandle = dSndSeSoundPool_c::GetInstance()->acquireSoundType1(this, soundId);
+ if (seHandle == nullptr) {
+ d_s_vt_0x1C8();
+ return nullptr;
+ }
+ }
+
+ dSndDistantSoundActor_c *ac = dSndDistantSoundActorPool_c::GetInstance()->acquireActor(soundId, position, this);
+ if (ac == nullptr) {
+ d_s_vt_0x1C8();
+ return nullptr;
+ }
+
+ seHandle->setAcquiredMaybe(true);
+ seHandle->shiftPair(mpUnkSe);
+ if (handle != nullptr) {
+ seHandle->setHandle(handle);
+ } else {
+ handle = seHandle->getHandle();
+ }
+
+ if (ac->startSound(soundId, *position, handle)) {
+ addSeHandleType1(seHandle);
+ seHandle->setInUseMaybe(true);
+ ac->d_vt_0x58(*handle, seHandle, soundId);
+ d_s_vt_0x1CC(handle->GetId(), soundId, seHandle);
+ seHandle->onStart(this);
+ seHandle->onCalc(this);
+ } else {
+ dSndSeSoundPool_c::GetInstance()->releaseSoundType1(seHandle, true);
+ ac = nullptr;
+ }
+ d_s_vt_0x1C8();
+ return ac;
+}
+
s32 dSoundSource_c::getRoomId() const {
return mpActor->roomid;
}
+void dSoundSource_c::stopSounds(u32 soundId, s32 fadeFrames) {
+ SoundStopper handler(soundId, fadeFrames);
+ ForEachSound(handler, false);
+}
+
+void dSoundSource_c::stopSounds(const char *label, s32 fadeFrames) {
+ stopSounds(soundLabelToSoundId(label), fadeFrames);
+}
+
+bool dSoundSource_c::holdSound(u32 soundId) {
+ return holdSound(soundId, nullptr);
+}
+
+bool dSoundSource_c::holdSound(const char *label) {
+ return holdSound(soundLabelToSoundId(label));
+}
+
+nw4r::snd::SoundHandle *dSoundSource_c::holdSound(u32 soundId, nw4r::snd::SoundHandle *handle) {
+ if (soundId == -1) {
+ return nullptr;
+ }
+
+ dSndSeSound2_c *seHandle = getHandleType2ForSoundId(soundId);
+ if (seHandle == nullptr) {
+ seHandle = dSndSeSoundPool_c::GetInstance()->acquireSoundType2(this, soundId);
+ if (seHandle == nullptr) {
+ d_s_vt_0x1C8();
+ return nullptr;
+ }
+
+ seHandle->shiftPair(mpUnkSe);
+
+ if (handle != nullptr) {
+ seHandle->setHandle(handle);
+ } else {
+ handle = seHandle->getHandle();
+ }
+
+ field_0x11C |= 0x80000000;
+ if (HoldSound(handle, soundId)) {
+ addSeHandleType2(seHandle);
+ d_vt_0x5C(*handle, seHandle, soundId, 0);
+ d_s_vt_0x1CC(handle->GetId(), soundId, seHandle);
+ seHandle->onStart(this);
+ seHandle->onCalc(this);
+ } else {
+ dSndSeSoundPool_c::GetInstance()->releaseSoundType2(seHandle);
+ handle = nullptr;
+ }
+ } else {
+ handle = continueHoldingSound(seHandle, soundId, nullptr, nullptr);
+ }
+ d_s_vt_0x1C8();
+
+ return handle;
+}
+
+nw4r::snd::SoundHandle *dSoundSource_c::continueHoldingSound(
+ dSndSeSound2_c *seHandle, u32 soundId, dSndDistantSoundActor_c *distant, const nw4r::math::VEC3 *position
+) {
+ if (!d_s_vt_0x1AC(soundId)) {
+ d_s_vt_0x1C8();
+ return nullptr;
+ }
+
+ u32 actualSoundId = soundId;
+ if (!sIsStartingBaseSound) {
+ actualSoundId = d_s_vt_0x1A0(soundId, 0);
+ if (actualSoundId == -1) {
+ d_s_vt_0x1C8();
+ return nullptr;
+ }
+ actualSoundId = d_s_vt_0x1E8(actualSoundId);
+ if (actualSoundId == -1) {
+ d_s_vt_0x1C8();
+ return nullptr;
+ }
+ }
+ nw4r::snd::SoundHandle *handle = seHandle->getHandle();
+ seHandle->shiftPair(mpUnkSe);
+ field_0x11C |= 0x80000000;
+ bool ok;
+ if (distant != nullptr && position != nullptr) {
+ // not sure why we're using the original ID here
+ ok = distant->holdSound(soundId, *position, handle);
+ } else {
+ ok = HoldSound(handle, actualSoundId);
+ }
+ field_0x11C = 0;
+ field_0x154 = 0;
+ if (ok) {
+ seHandle->setField0x130(1);
+ d_vt_0x5C(*handle, seHandle, soundId, 0);
+ } else {
+ handle = nullptr;
+ }
+ d_s_vt_0x1C8();
+ return handle;
+}
+
nw4r::snd::SoundStartable::StartResult
-dSoundSource_c::SetupSound(nw4r::snd::SoundHandle *pHandle, u32 soundId, const StartInfo *pStartInfo, void *) {
- // TODO
- return START_SUCCESS;
+dSoundSource_c::SetupSound(nw4r::snd::SoundHandle *pHandle, u32 soundId, const StartInfo *pStartInfo, void *arg) {
+ bool holdFlag = *(bool *)arg;
+ if (!d_s_vt_0x1AC(soundId)) {
+ return onSetupError();
+ } else if ((field_0x11C & 0x80000000) != 0) {
+ return setupSound(pHandle, soundId, pStartInfo, arg, holdFlag);
+ } else {
+ return onSetupError();
+ }
+}
+
+nw4r::snd::SoundStartable::StartResult dSoundSource_c::setupSound(
+ nw4r::snd::SoundHandle *pHandle, u32 soundId, const StartInfo *pStartInfo, void *arg, bool holdFlag
+) {
+ u32 userParam = getSomeUserParam(soundId);
+ if (userParam & 0x2) {
+ // maybe a flag for not allowing duplicates
+ if (getHandleType1ForSoundId(soundId) != nullptr) {
+ return onSetupError();
+ }
+ } else if (userParam & 0x1) {
+ // maybe a flag for stopping other copies
+ stopSoundHandles(soundId, 2);
+ }
+
+ u32 variantSoundId = soundId;
+ if (!sIsStartingBaseSound) {
+ u32 anotherSoundId;
+ if (holdFlag) {
+ anotherSoundId = d_s_vt_0x1A0(soundId, 1);
+ } else {
+ anotherSoundId = d_s_vt_0x194(soundId);
+ }
+ if (anotherSoundId == -1) {
+ return onSetupError();
+ }
+
+ if (userParam & 0x800) {
+ anotherSoundId = modifySoundId(anotherSoundId);
+ if (anotherSoundId == -1) {
+ return onSetupError();
+ }
+ }
+ variantSoundId = d_s_vt_0x1E8(anotherSoundId);
+ if (variantSoundId == -1) {
+ return onSetupError();
+ }
+ }
+
+ if (!holdFlag && (userParam & 0x1C000000) != 0) {
+ dSndDistantSoundActor_c *ac = startSoundAtPosition(variantSoundId, &GetPosition(), nullptr);
+ f32 volume = 0.0f;
+ if (ac != nullptr) {
+ if ((userParam & 0x10000000) != 0 && (userParam & 0xC000000) == 0) {
+ ac->setUseSourcePosition(true);
+ }
+ // unnecessary double check
+ if (!holdFlag) {
+ volume = getBaseSoundVolume(variantSoundId, soundId);
+ }
+ }
+ startBaseSoundAtPosition(soundId, &GetPosition(), volume);
+ d_s_vt_0x1C8();
+ return onSetupError();
+ } else {
+ StartResult result = dSnd3DActor_c::SetupSound(pHandle, variantSoundId, pStartInfo, arg);
+ if (result == START_SUCCESS && !holdFlag) {
+ f32 volume = getBaseSoundVolume(variantSoundId, soundId);
+ startBaseSound(soundId, volume);
+ }
+ d_s_vt_0x1C8();
+ return result;
+ }
+}
+
+f32 dSoundSource_c::getBaseSoundVolume(u32 variantSoundId, u32 baseSoundId) {
+ if (variantSoundId == baseSoundId) {
+ return 0.0f;
+ } else if (sIsStartingBaseSound) {
+ return 0.0f;
+ }
+
+ u32 volume = (dSndPlayerMgr_c::GetInstance()->getSomeUserParam(variantSoundId) >> 16) & 0xFF;
+ if (volume > 100) {
+ volume = 100;
+ }
+ return volume / 100.0f;
}
-void dSoundSource_c::d_vt_0x58() {
+nw4r::snd::SoundHandle *dSoundSource_c::startBaseSound(u32 baseSoundId, f32 volume) {
+ if (volume <= 0.0f) {
+ return nullptr;
+ }
+
+ sIsStartingBaseSound = true;
+ nw4r::snd::SoundHandle *handle = startSound(baseSoundId, nullptr);
+ sIsStartingBaseSound = false;
+ if (handle != nullptr) {
+ handle->SetVolume(volume, 0);
+ }
+ return handle;
+}
+
+dSndDistantSoundActor_c *
+dSoundSource_c::startBaseSoundAtPosition(u32 baseSoundId, const nw4r::math::VEC3 *position, f32 volume) {
+ if (volume <= 0.0f) {
+ return nullptr;
+ }
+
+ sIsStartingBaseSound = true;
+ dSndDistantSoundActor_c *handle = startSoundAtPosition(baseSoundId, position, nullptr);
+ sIsStartingBaseSound = false;
+ if (handle != nullptr) {
+ handle->getHandle()->SetVolume(volume, 0);
+ }
+ return handle;
+}
+
+nw4r::snd::SoundStartable::StartResult dSoundSource_c::onSetupError() {
+ d_s_vt_0x1C8();
+ return START_ERR_USER;
+}
+
+void dSoundSource_c::d_vt_0x58(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id) {
// noop
}
-void dSoundSource_c::d_vt_0x5C() {
+void dSoundSource_c::d_vt_0x5C(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id, UNKWORD) {
// noop
}
@@ -131,13 +464,200 @@ void dSoundSource_c::detachAllDistantSounds() {
}
void dSoundSource_c::pauseAllDistantSounds(bool flag, int fadeFrames) {
- for (dSndDistantSoundActor_c *it = static_cast<dSndDistantSoundActor_c *>(nw4r::ut::List_GetFirst(&mDistantSoundList));
+ for (dSndDistantSoundActor_c *it =
+ static_cast<dSndDistantSoundActor_c *>(nw4r::ut::List_GetFirst(&mDistantSoundList));
it != nullptr; it = static_cast<dSndDistantSoundActor_c *>(nw4r::ut::List_GetNext(&mDistantSoundList, it))) {
it->PauseAllSound(flag, fadeFrames);
}
}
-u32 dSoundSource_c::getCharacterTalkSoundId(u32 baseSoundId, dSoundSource_c *source) {
+void dSoundSource_c::addSeHandleType1(dSndSeSound1_c *handle) {
+ if (handle == nullptr) {
+ return;
+ }
+ if (handle->isAttachedSource()) {
+ return;
+ }
+ handle->attachSource(this);
+ nw4r::ut::List_Append(&mHandleType1List, handle);
+}
+
+void dSoundSource_c::addSeHandleType2(dSndSeSound2_c *handle) {
+ if (handle == nullptr) {
+ return;
+ }
+ if (handle->isAttachedSource()) {
+ return;
+ }
+ handle->attachSource(this);
+ nw4r::ut::List_Append(&mHandleType2List, handle);
+}
+
+void dSoundSource_c::removeSeHandleType1(dSndSeSound1_c *handle, bool stop) {
+ if (handle == nullptr) {
+ return;
+ }
+ if (!handle->isAttachedSource()) {
+ return;
+ }
+ nw4r::ut::List_Remove(&mHandleType1List, handle);
+ dSndSeSoundPool_c::GetInstance()->releaseSoundType1(handle, stop);
+}
+
+void dSoundSource_c::removeSeHandleType2(dSndSeSound2_c *handle) {
+ if (handle == nullptr) {
+ return;
+ }
+ if (!handle->isAttachedSource()) {
+ return;
+ }
+ nw4r::ut::List_Remove(&mHandleType2List, handle);
+ dSndSeSoundPool_c::GetInstance()->releaseSoundType2(handle);
+}
+
+void dSoundSource_c::removeAllSeHandles() {
+ removeAllSeHandlesType1();
+ removeAllSeHandlesType2();
+}
+
+void dSoundSource_c::removeAllSeHandlesType1() {
+ dSndSeSound1_c *sound = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetFirst(&mHandleType1List));
+ while (sound != nullptr) {
+ removeSeHandleType1(sound, sound->unkRemovalCheck());
+ sound = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetFirst(&mHandleType1List));
+ }
+}
+
+void dSoundSource_c::removeAllSeHandlesType2() {
+ dSndSeSound2_c *sound = static_cast<dSndSeSound2_c *>(nw4r::ut::List_GetFirst(&mHandleType2List));
+ while (sound != nullptr) {
+ removeSeHandleType2(sound);
+ sound = static_cast<dSndSeSound2_c *>(nw4r::ut::List_GetFirst(&mHandleType2List));
+ }
+}
+
+void dSoundSource_c::calcHandles() {
+ calcHandlesType1();
+ calcHandlesType2();
+}
+
+void dSoundSource_c::calcHandlesType1() {
+ dSndSeSound1_c *next, *it;
+ it = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetFirst(&mHandleType1List));
+ while (it != nullptr) {
+ next = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetNext(&mHandleType1List, it));
+ if (it->isAttachedSound()) {
+ it->calc(this);
+ } else {
+ removeSeHandleType1(it, true);
+ }
+ it = next;
+ }
+}
+
+void dSoundSource_c::calcHandlesType2() {
+ dSndSeSound2_c *next, *it;
+ it = static_cast<dSndSeSound2_c *>(nw4r::ut::List_GetFirst(&mHandleType2List));
+ while (it != nullptr) {
+ next = static_cast<dSndSeSound2_c *>(nw4r::ut::List_GetNext(&mHandleType2List, it));
+ if (it->isAttachedSound()) {
+ if (it->calcTimer()) {
+ continueHoldingSound(it, it->getHandle()->GetId(), nullptr, nullptr);
+ }
+ it->calc(this);
+ } else {
+ removeSeHandleType2(it);
+ }
+ it = next;
+ }
+}
+
+dSndSeSound1_c *dSoundSource_c::getHandleType1ForSoundId(u32 soundId) {
+ dSndSeSound1_c *sound = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetFirst(&mHandleType1List));
+ while (sound != nullptr) {
+ if (sound->isSoundId(soundId) || sound->getHandle()->GetId() == soundId) {
+ return sound;
+ }
+ sound = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetNext(&mHandleType1List, sound));
+ }
+
+ return nullptr;
+}
+
+dSndSeSound1_c *dSoundSource_c::getHandleType1ForSoundHandle(nw4r::snd::SoundHandle *handle) {
+ dSndSeSound1_c *sound = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetFirst(&mHandleType1List));
+ while (sound != nullptr) {
+ if (sound->getHandle() == handle) {
+ return sound;
+ }
+ sound = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetNext(&mHandleType1List, sound));
+ }
+
+ return nullptr;
+}
+
+dSndSeSound2_c *dSoundSource_c::getHandleType2ForSoundId(u32 soundId) {
+ dSndSeSound2_c *sound = static_cast<dSndSeSound2_c *>(nw4r::ut::List_GetFirst(&mHandleType2List));
+ while (sound != nullptr) {
+ if (sound->isSoundId(soundId) || sound->getHandle()->GetId() == soundId) {
+ return sound;
+ }
+ sound = static_cast<dSndSeSound2_c *>(nw4r::ut::List_GetNext(&mHandleType2List, sound));
+ }
+
+ return nullptr;
+}
+
+void dSoundSource_c::stopSoundHandles(u32 soundId, s32 fadeFrames) {
+ // TODO: Weird declaration order required for regswaps
+ {
+ dSndSeSound1_c *next, *it;
+ it = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetFirst(&mHandleType1List));
+ while (it != nullptr) {
+ next = static_cast<dSndSeSound1_c *>(nw4r::ut::List_GetNext(&mHandleType1List, it));
+ if (it->isSoundId(soundId) || it->getHandle()->GetId() == soundId) {
+ it->getHandle()->Stop(fadeFrames);
+ removeSeHandleType1(it, true);
+ }
+ it = next;
+ }
+ }
+
+ {
+ dSndSeSound2_c *it, *next;
+ it = static_cast<dSndSeSound2_c *>(nw4r::ut::List_GetFirst(&mHandleType2List));
+ while (it != nullptr) {
+ next = static_cast<dSndSeSound2_c *>(nw4r::ut::List_GetNext(&mHandleType2List, it));
+ if (it->isSoundId(soundId) || it->getHandle()->GetId() == soundId) {
+ it->getHandle()->Stop(fadeFrames);
+ removeSeHandleType2(it);
+ }
+ it = next;
+ }
+ }
+}
+
+u32 dSoundSource_c::modifySoundId(u32 baseSoundId) {
+ if (baseSoundId != -1) {
+ SizedString<64> label;
+
+ // maybe an inline
+ const char *baseLabel = nullptr;
+ if (dSndMgr_c::GetInstance()->getArchive() != nullptr) {
+ baseLabel = dSndMgr_c::GetInstance()->getArchive()->GetSoundLabelString(baseSoundId);
+ }
+
+ const char *charLabel = getName();
+ label.sprintf("%s_%s", baseLabel, charLabel);
+ u32 newLabel = dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(label);
+ if (newLabel != -1) {
+ return newLabel;
+ }
+ }
+ return baseSoundId;
+}
+
+u32 dSoundSource_c::modifySoundId(u32 baseSoundId, dSoundSource_c *source) {
if (baseSoundId != -1 && source != nullptr) {
SizedString<64> label;
diff --git a/src/d/snd/d_snd_state_mgr.cpp b/src/d/snd/d_snd_state_mgr.cpp
index 5f7909ab..e62ad85b 100644
--- a/src/d/snd/d_snd_state_mgr.cpp
+++ b/src/d/snd/d_snd_state_mgr.cpp
@@ -199,6 +199,6 @@ bool dSndStateMgr_c::isSeekerStoneStage(const char *stageName, s32 layer) {
return false;
}
-bool isInStage(const char *stageName) {
+bool dSndStateMgr_c::isInStage(const char *stageName) {
return !std::strcmp(dScGame_c::currentSpawnInfo.getStageName(), stageName);
}
diff --git a/src/nw4r/snd/snd_BasicPlayer.cpp b/src/nw4r/snd/snd_BasicPlayer.cpp
index 4045f4b8..6b8cba05 100644
--- a/src/nw4r/snd/snd_BasicPlayer.cpp
+++ b/src/nw4r/snd/snd_BasicPlayer.cpp
@@ -32,7 +32,7 @@ void PlayerParamSet::Init()
biquadType = 0;
biquadValue = 0.0f;
remoteFilter = 0;
- outputLineFlag = 1;
+ outputLineFlag = OUTPUT_LINE_MAIN;
mainOutVolume = 1.0f;
mainSend = 0.0f;
panMode = PAN_MODE_DUAL;
diff --git a/src/nw4r/snd/snd_BasicSound.cpp b/src/nw4r/snd/snd_BasicSound.cpp
index d6e29c09..f2b7931b 100644
--- a/src/nw4r/snd/snd_BasicSound.cpp
+++ b/src/nw4r/snd/snd_BasicSound.cpp
@@ -100,7 +100,7 @@ void BasicSound::InitParam()
mLpfFreq = 0.0f;
mBiquadFilterType = 0;
mBiquadFilterValue = 0.0f;
- mOutputLineFlag = mSoundPlayer ? mSoundPlayer->GetDefaultOutputLine() : 1;
+ mOutputLineFlag = mSoundPlayer ? mSoundPlayer->GetDefaultOutputLine() : OUTPUT_LINE_MAIN;
mMainOutVolume = 1.0f;
mMainSend = 0.0f;
// clang-format on
diff --git a/src/nw4r/snd/snd_Channel.cpp b/src/nw4r/snd/snd_Channel.cpp
index 3d3456d8..1c92348b 100644
--- a/src/nw4r/snd/snd_Channel.cpp
+++ b/src/nw4r/snd/snd_Channel.cpp
@@ -143,7 +143,7 @@ void Channel::InitParam(Callback *callback, u32 callbackData)
mBiquadType = 0;
mBiquadValue = 0.0f;
mRemoteFilter = 0;
- mOutputLineFlag = 1;
+ mOutputLineFlag = OUTPUT_LINE_MAIN;
mMainOutVolume = 1.0f;
mMainSend = 0.0f;
diff --git a/src/nw4r/snd/snd_SoundPlayer.cpp b/src/nw4r/snd/snd_SoundPlayer.cpp
index 112135ec..a991dad2 100644
--- a/src/nw4r/snd/snd_SoundPlayer.cpp
+++ b/src/nw4r/snd/snd_SoundPlayer.cpp
@@ -34,7 +34,7 @@ SoundPlayer::SoundPlayer() :
mPlayableLimit (INT_MAX),
mVolume (1.0f),
mLpfFreq (0.0f),
- mOutputLineFlag (1),
+ mOutputLineFlag (OUTPUT_LINE_MAIN),
mMainOutVolume (1.0f),
mBiquadType (0),
mBiquadValue (0.0f),
diff --git a/src/nw4r/snd/snd_Voice.cpp b/src/nw4r/snd/snd_Voice.cpp
index b422b842..dd19828c 100644
--- a/src/nw4r/snd/snd_Voice.cpp
+++ b/src/nw4r/snd/snd_Voice.cpp
@@ -129,7 +129,7 @@ void Voice::InitParam(int channelCount, int voiceOutCount, Callback *callback,
mBiquadValue = 0.0f;
mPan = 0.0f;
mSurroundPan = 0.0f;
- mOutputLineFlag = 1;
+ mOutputLineFlag = OUTPUT_LINE_MAIN;
mMainOutVolume = 1.0f;
mMainSend = 1.0f;
@@ -873,7 +873,7 @@ bool Voice::CalcAxMix()
CalcMixParam(channelIndex, voiceOutIndex, &mix, &rmtmix);
nextUpdateFlag |= axVoice->SetMix(mix);
- if (mOutputLineFlag == 0 || mOutputLineFlag == 1) {
+ if (mOutputLineFlag == 0 || mOutputLineFlag == OUTPUT_LINE_MAIN) {
axVoice->EnableRemote(false);
} else {
axVoice->EnableRemote(true);
@@ -1077,7 +1077,7 @@ void Voice::CalcMixParam(int channelIndex, int voiceOutIndex,
f32 fxSendB = 0.0f;
f32 fxSendC = 0.0f;
- if (mOutputLineFlag & 1) // OUTPUT_LINE_MAIN
+ if (mOutputLineFlag & OUTPUT_LINE_MAIN)
{
mainVolume = mMainOutVolume;
mainSend = mMainSend;