mirror of
https://github.com/zeldaret/ss
synced 2026-07-08 22:04:41 -04:00
1316 lines
39 KiB
C++
1316 lines
39 KiB
C++
#include "d/snd/d_snd_source.h"
|
|
|
|
#include "common.h"
|
|
#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_anim_sound.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_id_mappers.h"
|
|
#include "d/snd/d_snd_mgr.h"
|
|
#include "d/snd/d_snd_player_mgr.h"
|
|
#include "d/snd/d_snd_se_sound.h"
|
|
#include "d/snd/d_snd_se_sound_1.h"
|
|
#include "d/snd/d_snd_se_sound_2.h"
|
|
#include "d/snd/d_snd_se_sound_pool.h"
|
|
#include "d/snd/d_snd_source_enums.h"
|
|
#include "d/snd/d_snd_source_group.h"
|
|
#include "d/snd/d_snd_source_mgr.h"
|
|
#include "d/snd/d_snd_stage_data.h"
|
|
#include "d/snd/d_snd_state_mgr.h"
|
|
#include "d/snd/d_snd_wzsound.h"
|
|
#include "egg/audio/eggAudioRmtSpeakerMgr.h"
|
|
#include "m/m_vec.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"
|
|
#include "toBeSorted/time_area_mgr.h"
|
|
|
|
static dSndSoundCtxParam sCtxParams;
|
|
bool dSoundSource_c::sIsStartingBaseSound;
|
|
|
|
dSoundSource_c *dSoundSource_c::create(u32 id, dAcBase_c *actor, const char *name, u8 subtype) {
|
|
return dSndSourceMgr_c::createSource(id, actor, name, subtype);
|
|
}
|
|
|
|
dSoundSource_c::dSoundSource_c(u8 sourceType, dAcBase_c *actor, const char *name, dSndSourceGroup_c *pOwnerGroup)
|
|
: dSnd3DActor_c(pOwnerGroup->getAmbientParam(), sourceType),
|
|
mpName(name),
|
|
field_0x0F4(0),
|
|
mpActor(actor),
|
|
mSourceType(sourceType),
|
|
mSubtype(0),
|
|
mIsSetup(false),
|
|
field_0x100(0),
|
|
field_0x101(0),
|
|
field_0x102(0),
|
|
field_0x104(0),
|
|
field_0x108(0),
|
|
mpCtxParam(nullptr),
|
|
field_0x11C(0),
|
|
mpOwnerGroup(pOwnerGroup),
|
|
field_0x154(0),
|
|
mPolyAttr0(-1),
|
|
mPolyAttr1(-1) {
|
|
mSourceCategory = dSndSourceMgr_c::getSourceCategoryForSourceType(sourceType, name);
|
|
// TODO: Offsetof
|
|
nw4r::ut::List_Init(&mDistantSoundList, 0xEC);
|
|
nw4r::ut::List_Init(&mHandleType1List, 0x04);
|
|
nw4r::ut::List_Init(&mHandleType2List, 0x04);
|
|
pOwnerGroup->registerSource(this);
|
|
}
|
|
|
|
dSoundSource_c::~dSoundSource_c() {
|
|
SetUserParam(0);
|
|
shutdown();
|
|
removeAllSeHandles();
|
|
detachAllDistantSounds();
|
|
dSndSourceMgr_c::GetInstance()->unregisterSource(this);
|
|
mpOwnerGroup->unregisterSource(this);
|
|
}
|
|
|
|
void dSoundSource_c::setup() {
|
|
if (mIsSetup) {
|
|
return;
|
|
}
|
|
SetPosition(mpActor->position);
|
|
resetCachedRelativePositions();
|
|
initVolumeFade();
|
|
if (mSourceCategory == SND_SOURCE_CATEGORY_PLAYER) {
|
|
mPositionRelativeToPlayer.x = 0.0f;
|
|
mPositionRelativeToPlayer.y = 0.0f;
|
|
mPositionRelativeToPlayer.z = 0.0f;
|
|
}
|
|
mIsPaused = false;
|
|
field_0x102 = 0;
|
|
switch (mSourceCategory) {
|
|
case SND_SOURCE_CATEGORY_ENEMY:
|
|
case SND_SOURCE_CATEGORY_OBJECT:
|
|
case SND_SOURCE_CATEGORY_NPC:
|
|
case SND_SOURCE_CATEGORY_TG_SOUND:
|
|
case SND_SOURCE_CATEGORY_6:
|
|
if (dSndSourceMgr_c::GetInstance()->getField_0x0013() != 0 && mSourceType != SND_SOURCE_SHUTTER) {
|
|
field_0x101 = 1;
|
|
} else {
|
|
field_0x101 = 0;
|
|
}
|
|
}
|
|
|
|
postSetup();
|
|
dSndSourceMgr_c::GetInstance()->registerSource(this);
|
|
s32 id = dSndStateMgr_c::GetInstance()->getStageId_0x040();
|
|
if (SND_STAGE_F000_L26 <= id && id <= SND_STAGE_F000_L27) {
|
|
setVolumeFade(0.0f, 0);
|
|
}
|
|
field_0x100 = dSndSourceMgr_c::isSwOrEOc(mpName);
|
|
mIsSetup = true;
|
|
}
|
|
|
|
void dSoundSource_c::shutdown() {
|
|
if (!mIsDisabled) {
|
|
if (getAnimSound() != nullptr) {
|
|
getAnimSound()->shutdown();
|
|
}
|
|
if (mIsPaused) {
|
|
stopAllSound(1);
|
|
}
|
|
dSndSourceMgr_c::GetInstance()->onShutdownSource(this);
|
|
mIsDisabled = true;
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::stopAllPlaySounds(s32 fadeFrames) {
|
|
dSndSeSound1_c *sound = getHandleType1First();
|
|
while (sound != nullptr) {
|
|
sound->getHandle()->Stop(fadeFrames);
|
|
sound = getHandleType1Next(sound);
|
|
}
|
|
}
|
|
|
|
const nw4r::math::VEC3 &dSoundSource_c::getListenerPosition() const {
|
|
return dSnd3DManager_c::GetInstance()->getSndListenerPos();
|
|
}
|
|
|
|
void dSoundSource_c::calc(const nw4r::math::VEC3 &pos) {
|
|
preCalc();
|
|
setPosition(pos);
|
|
calcHandles();
|
|
calcVolumeFade();
|
|
postCalc();
|
|
field_0x108 = 0;
|
|
}
|
|
|
|
void dSoundSource_c::preCalc() {
|
|
if (field_0x100 != 0) {
|
|
return;
|
|
}
|
|
|
|
if (dSndSourceMgr_c::GetInstance()->getField_0x0012() != 0) {
|
|
return;
|
|
}
|
|
|
|
if (!mIsPaused && !mpActor->isBasePropertyFlag(dBase_c::BASE_PROP_0x4)) {
|
|
setPause(true, 3);
|
|
} else if (mIsPaused && mpActor->isBasePropertyFlag(dBase_c::BASE_PROP_0x4)) {
|
|
setPause(false, 3);
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::postCalc() {
|
|
// noop
|
|
}
|
|
|
|
bool dSoundSource_c::hasPlayingSounds() const {
|
|
return dSnd3DActor_c::hasPlayingSounds();
|
|
}
|
|
|
|
bool dSoundSource_c::isPlayingSound(u32 soundId) {
|
|
return dSnd3DActor_c::isPlayingSound(soundId);
|
|
}
|
|
|
|
bool dSoundSource_c::isPlayingSound(const char *soundId) {
|
|
return isPlayingSound(soundLabelToSoundId(soundId));
|
|
}
|
|
|
|
void dSoundSource_c::initVolumeFade() {
|
|
mVolumeFadeTarget = 1.0f;
|
|
mVolumeFadeStepSize = 0.0f;
|
|
}
|
|
|
|
void dSoundSource_c::setVolumeFade(f32 volume, u32 fadeFrames) {
|
|
// @bug not actually clamped
|
|
(void)nw4r::ut::Clamp(volume, 0.0f, 2.0f);
|
|
if (fadeFrames == 0) {
|
|
SoundActor::SetVolume(volume);
|
|
mVolumeFadeTarget = volume;
|
|
mVolumeFadeStepSize = 0.0f;
|
|
return;
|
|
}
|
|
f32 currVolume = SoundActor::GetVolume();
|
|
if (currVolume == volume) {
|
|
mVolumeFadeTarget = volume;
|
|
mVolumeFadeStepSize = 0.0f;
|
|
} else {
|
|
mVolumeFadeTarget = volume;
|
|
mVolumeFadeStepSize = (volume - currVolume) / fadeFrames;
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::calcVolumeFade() {
|
|
if (mIsPaused) {
|
|
return;
|
|
}
|
|
|
|
if (mVolumeFadeStepSize == 0.0f) {
|
|
return;
|
|
}
|
|
|
|
f32 nextVolume = SoundActor::GetVolume();
|
|
nextVolume += mVolumeFadeStepSize;
|
|
if (mVolumeFadeStepSize > 0.0f) {
|
|
if (nextVolume >= mVolumeFadeTarget) {
|
|
nextVolume = mVolumeFadeTarget;
|
|
mVolumeFadeStepSize = 0.0f;
|
|
}
|
|
} else {
|
|
if (nextVolume <= mVolumeFadeTarget) {
|
|
nextVolume = mVolumeFadeTarget;
|
|
mVolumeFadeStepSize = 0.0f;
|
|
}
|
|
}
|
|
|
|
SoundActor::SetVolume(nextVolume);
|
|
}
|
|
|
|
void dSoundSource_c::setCtxInt(s32 value) {
|
|
sCtxParams.intParam = value;
|
|
setCtxParam(&sCtxParams);
|
|
}
|
|
|
|
void dSoundSource_c::setCtxFloat(f32 value) {
|
|
sCtxParams.floatParam = value;
|
|
setCtxParam(&sCtxParams);
|
|
}
|
|
|
|
bool dSoundSource_c::isInaudibleInternal() {
|
|
if (field_0x102 != 0) {
|
|
return true;
|
|
}
|
|
|
|
return dSnd3DActor_c::getDistanceToCameraTarget() >= mpSourceParam->getField0x10();
|
|
}
|
|
|
|
bool dSoundSource_c::d_s_vt_0x190() const {
|
|
if (field_0x101 != 0) {
|
|
return true;
|
|
}
|
|
if (mIsDisabled) {
|
|
return true;
|
|
}
|
|
return dSndStateMgr_c::GetInstance()->getField_0x14() > 0;
|
|
}
|
|
|
|
void dSoundSource_c::setPause(bool flag, int fadeFrames) {
|
|
if (!flag) {
|
|
PauseAllSound(flag, fadeFrames);
|
|
pauseAllDistantSounds(flag, fadeFrames);
|
|
mIsPaused = false;
|
|
} else if (!mIsDisabled) {
|
|
PauseAllSound(flag, fadeFrames);
|
|
pauseAllDistantSounds(flag, fadeFrames);
|
|
mIsPaused = true;
|
|
}
|
|
}
|
|
|
|
bool dSoundSource_c::startSound(u32 soundId) {
|
|
return startSound(soundId, nullptr);
|
|
}
|
|
|
|
bool dSoundSource_c::startSound(const char *label) {
|
|
return startSound(soundLabelToSoundId(label));
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundWithIntParam(u32 soundId, s32 value) {
|
|
setCtxInt(value);
|
|
return startSound(soundId, nullptr) != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundWithIntParam(const char *label, s32 value) {
|
|
u32 soundId = soundLabelToSoundId(label);
|
|
return startSoundWithIntParam(soundId, value);
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundWithFloatParam(u32 soundId, f32 value) {
|
|
setCtxFloat(value);
|
|
return startSound(soundId, nullptr) != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundWithFloatParam(const char *label, f32 value) {
|
|
u32 soundId = soundLabelToSoundId(label);
|
|
return startSoundWithFloatParam(soundId, value);
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundWithParams(u32 soundId, f32 fValue, s32 value) {
|
|
setCtxInt(value);
|
|
setCtxFloat(fValue);
|
|
return startSound(soundId, nullptr) != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundWithParams(const char *label, f32 fValue, s32 value) {
|
|
u32 soundId = soundLabelToSoundId(label);
|
|
return startSoundWithParams(soundId, fValue, value);
|
|
}
|
|
|
|
bool dSoundSource_c::maybeUnusedEnemyDeath() {
|
|
if (mSourceCategory == SND_SOURCE_CATEGORY_ENEMY) {
|
|
dSndSourceMgr_c::GetInstance()->onShutdownSource(this);
|
|
if (getAnimSound() != nullptr) {
|
|
getAnimSound()->shutdown();
|
|
}
|
|
return startSound(SE_E_DISAPPEAR);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
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) {
|
|
resetTempParams();
|
|
return START_ERR_USER;
|
|
}
|
|
|
|
seHandle->shiftParam(mpCtxParam);
|
|
if (handle != nullptr) {
|
|
seHandle->setHandle(handle);
|
|
} else {
|
|
handle = seHandle->getHandle();
|
|
}
|
|
|
|
field_0x11C |= 0x80000000;
|
|
result = StartSoundReturnStatus(handle, soundId, nullptr);
|
|
if (result == START_SUCCESS) {
|
|
addSeHandleType1(seHandle);
|
|
postStartSound(*handle, seHandle, soundId);
|
|
postSetupSound(handle->GetId(), soundId, seHandle);
|
|
seHandle->onStart(this);
|
|
seHandle->onCalc(this);
|
|
} else {
|
|
dSndSeSoundPool_c::GetInstance()->releaseSoundType1(seHandle, true);
|
|
handle = nullptr;
|
|
}
|
|
resetTempParams();
|
|
if (pOutHandle != nullptr) {
|
|
*pOutHandle = handle;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundAtPosition(u32 soundId, const nw4r::math::VEC3 *position) {
|
|
if (!d_s_vt_0x1AC(soundId)) {
|
|
return false;
|
|
}
|
|
|
|
u32 actualSoundId = soundId;
|
|
if (!sIsStartingBaseSound) {
|
|
actualSoundId = overrideStartSoundId(soundId);
|
|
if (actualSoundId == -1) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
}
|
|
dSndDistantSoundActor_c *ac = startSoundAtPosition(actualSoundId, position, nullptr);
|
|
|
|
if (ac != nullptr) {
|
|
if (ac->getHandle() != nullptr) {
|
|
actualSoundId = ac->getHandle()->GetId();
|
|
}
|
|
f32 volume = getBaseSoundVolume(actualSoundId, soundId);
|
|
startBaseSoundAtPosition(soundId, position, volume);
|
|
}
|
|
return ac != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundAtPosition(const char *label, const nw4r::math::VEC3 *position) {
|
|
return startSoundAtPosition(soundLabelToSoundId(label), position);
|
|
}
|
|
|
|
bool dSoundSource_c::startObjHitSound(u32 baseSoundId, dSoundSourceIf_c *source, const nw4r::math::VEC3 *position) {
|
|
if (source == nullptr) {
|
|
return startSoundAtPosition(baseSoundId, position);
|
|
}
|
|
|
|
if (!d_s_vt_0x1AC(baseSoundId)) {
|
|
return false;
|
|
}
|
|
|
|
u32 soundId = baseSoundId;
|
|
if (!sIsStartingBaseSound) {
|
|
u32 tmp = overrideStartSoundId(soundId);
|
|
if (tmp == -1) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
soundId = overrideHitObjSoundId(tmp, static_cast<dSoundSource_c *>(source));
|
|
if (soundId == -1) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
}
|
|
dSndDistantSoundActor_c *ac = startSoundAtPosition(soundId, position, nullptr);
|
|
if (ac != nullptr) {
|
|
if (ac->getHandle() != nullptr) {
|
|
soundId = ac->getHandle()->GetId();
|
|
}
|
|
f32 volume = getBaseSoundVolume(soundId, baseSoundId);
|
|
startBaseSoundAtPosition(baseSoundId, position, volume);
|
|
}
|
|
return ac != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::startObjHitSound(const char *label, dSoundSourceIf_c *source, const nw4r::math::VEC3 *position) {
|
|
return startObjHitSound(soundLabelToSoundId(label), source, position);
|
|
}
|
|
|
|
bool dSoundSource_c::startBgHitSound(u32 baseSoundId, u32 polyAttr0, u32 polyAttr1, const nw4r::math::VEC3 *position) {
|
|
if (!d_s_vt_0x1AC(baseSoundId)) {
|
|
return false;
|
|
}
|
|
|
|
u32 soundId = baseSoundId;
|
|
if (!sIsStartingBaseSound) {
|
|
u32 tmp = overrideStartSoundId(soundId);
|
|
if (tmp == -1) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
soundId = specializeBgHitSoundId(tmp, polyAttr0, polyAttr1);
|
|
if (soundId == -1) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
}
|
|
dSndDistantSoundActor_c *ac = startSoundAtPosition(soundId, position, nullptr);
|
|
if (ac != nullptr) {
|
|
if (ac->getHandle() != nullptr) {
|
|
soundId = ac->getHandle()->GetId();
|
|
}
|
|
f32 volume = getBaseSoundVolume(soundId, baseSoundId);
|
|
startBaseSoundAtPosition(baseSoundId, position, volume);
|
|
}
|
|
return ac != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::startBgHitSound(
|
|
const char *label, u32 polyAttr0, u32 polyAttr1, const nw4r::math::VEC3 *position
|
|
) {
|
|
return startBgHitSound(soundLabelToSoundId(label), polyAttr0, polyAttr1, position);
|
|
}
|
|
|
|
// exact copy of startSoundAtPosition - used only for when the hookshot
|
|
// hits the water level
|
|
bool dSoundSource_c::startSoundAtPosition2(u32 soundId, const nw4r::math::VEC3 *position) {
|
|
if (!d_s_vt_0x1AC(soundId)) {
|
|
return false;
|
|
}
|
|
|
|
u32 actualSoundId = soundId;
|
|
if (!sIsStartingBaseSound) {
|
|
actualSoundId = overrideStartSoundId(soundId);
|
|
if (actualSoundId == -1) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
}
|
|
dSndDistantSoundActor_c *ac = startSoundAtPosition(actualSoundId, position, nullptr);
|
|
|
|
if (ac != nullptr) {
|
|
if (ac->getHandle() != nullptr) {
|
|
actualSoundId = ac->getHandle()->GetId();
|
|
}
|
|
f32 volume = getBaseSoundVolume(actualSoundId, soundId);
|
|
startBaseSoundAtPosition(soundId, position, volume);
|
|
}
|
|
return ac != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::startSoundAtPosition2(const char *label, const nw4r::math::VEC3 *position) {
|
|
return startSoundAtPosition2(soundLabelToSoundId(label), position);
|
|
}
|
|
|
|
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) {
|
|
resetTempParams();
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
dSndDistantSoundActor_c *ac = dSndDistantSoundActorPool_c::GetInstance()->acquireActor(soundId, position, this);
|
|
if (ac == nullptr) {
|
|
resetTempParams();
|
|
return nullptr;
|
|
}
|
|
|
|
seHandle->setAcquiredMaybe(true);
|
|
seHandle->shiftParam(mpCtxParam);
|
|
if (handle != nullptr) {
|
|
seHandle->setHandle(handle);
|
|
} else {
|
|
handle = seHandle->getHandle();
|
|
}
|
|
|
|
if (ac->startSound(soundId, *position, handle)) {
|
|
addSeHandleType1(seHandle);
|
|
seHandle->setInUseMaybe(true);
|
|
ac->postStartSound(*handle, seHandle, soundId);
|
|
postSetupSound(handle->GetId(), soundId, seHandle);
|
|
seHandle->onStart(this);
|
|
seHandle->onCalc(this);
|
|
} else {
|
|
dSndSeSoundPool_c::GetInstance()->releaseSoundType1(seHandle, true);
|
|
ac = nullptr;
|
|
}
|
|
resetTempParams();
|
|
return ac;
|
|
}
|
|
|
|
u32 dSoundSource_c::overrideHitObjSoundId(u32 soundId, dSoundSource_c *source) {
|
|
if (source == nullptr) {
|
|
return soundId;
|
|
}
|
|
if (checkUserParamMask(soundId, 0x200)) {
|
|
return modifySoundId(soundId, source);
|
|
}
|
|
return soundId;
|
|
}
|
|
|
|
void dSoundSource_c::handleRemoCon(nw4r::snd::SoundHandle *pHandle, u32 baseId) {
|
|
u32 userParam = getSomeUserParam(baseId);
|
|
if ((userParam & 0x8) != 0) {
|
|
if (EGG::AudioRmtSpeakerMgr::getWpadVolume() != 0) {
|
|
pHandle->SetOutputLineFlag(nw4r::snd::OUTPUT_LINE_REMOTE_1);
|
|
}
|
|
} else if ((userParam & 0x4) != 0) {
|
|
pHandle->SetOutputLineFlag(nw4r::snd::OUTPUT_LINE_MAIN | nw4r::snd::OUTPUT_LINE_REMOTE_1);
|
|
}
|
|
|
|
if ((userParam & 0x10) != 0) {
|
|
if (EGG::AudioRmtSpeakerMgr::getWpadVolume() != 0) {
|
|
u32 variant = getRemoConSoundVariant(baseId);
|
|
if (variant != -1) {
|
|
startRemoConSound(variant);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool dSoundSource_c::startVoiceLine(const char *label) {
|
|
return startVoiceLine(soundLabelToSoundId(label));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
bool dSoundSource_c::holdSoundWithIntParam(u32 soundId, s32 value) {
|
|
setCtxInt(value);
|
|
return holdSound(soundId, nullptr) != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::holdSoundWithIntParam(const char *label, s32 value) {
|
|
u32 soundId = soundLabelToSoundId(label);
|
|
return holdSoundWithIntParam(soundId, value);
|
|
}
|
|
|
|
bool dSoundSource_c::holdSoundWithFloatParam(u32 soundId, f32 value) {
|
|
setCtxFloat(value);
|
|
return holdSound(soundId, nullptr) != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::holdSoundWithFloatParam(const char *label, f32 value) {
|
|
u32 soundId = soundLabelToSoundId(label);
|
|
return holdSoundWithFloatParam(soundId, value);
|
|
}
|
|
|
|
bool dSoundSource_c::holdSoundWithParams(u32 soundId, f32 fValue, s32 value) {
|
|
setCtxInt(value);
|
|
setCtxFloat(fValue);
|
|
return holdSound(soundId, nullptr) != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::holdSoundWithParams(const char *label, f32 fValue, s32 value) {
|
|
u32 soundId = soundLabelToSoundId(label);
|
|
return holdSoundWithParams(soundId, fValue, value);
|
|
}
|
|
|
|
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) {
|
|
resetTempParams();
|
|
return nullptr;
|
|
}
|
|
|
|
seHandle->shiftParam(mpCtxParam);
|
|
|
|
if (handle != nullptr) {
|
|
seHandle->setHandle(handle);
|
|
} else {
|
|
handle = seHandle->getHandle();
|
|
}
|
|
|
|
field_0x11C |= 0x80000000;
|
|
if (HoldSound(handle, soundId)) {
|
|
addSeHandleType2(seHandle);
|
|
postHoldSound(*handle, seHandle, soundId, 0);
|
|
postSetupSound(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);
|
|
}
|
|
resetTempParams();
|
|
|
|
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)) {
|
|
resetTempParams();
|
|
return nullptr;
|
|
}
|
|
|
|
u32 actualSoundId = soundId;
|
|
if (!sIsStartingBaseSound) {
|
|
actualSoundId = d_s_vt_0x1A0(soundId, 0);
|
|
if (actualSoundId == -1) {
|
|
resetTempParams();
|
|
return nullptr;
|
|
}
|
|
actualSoundId = d_s_vt_0x1E8(actualSoundId);
|
|
if (actualSoundId == -1) {
|
|
resetTempParams();
|
|
return nullptr;
|
|
}
|
|
}
|
|
nw4r::snd::SoundHandle *handle = seHandle->getHandle();
|
|
seHandle->shiftParam(mpCtxParam);
|
|
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);
|
|
postHoldSound(*handle, seHandle, soundId, 0);
|
|
} else {
|
|
handle = nullptr;
|
|
}
|
|
resetTempParams();
|
|
return handle;
|
|
}
|
|
|
|
bool dSoundSource_c::holdSoundAtPosition(u32 soundId, const nw4r::math::VEC3 *position) {
|
|
dSndSeSound2_c *seHandle;
|
|
nw4r::snd::SoundHandle *handle;
|
|
|
|
if (position != nullptr) {
|
|
dSndDistantSoundActor_c *actor = dSndDistantSoundActorPool_c::GetInstance()->findActiveActor(soundId, this);
|
|
if (actor != nullptr) {
|
|
seHandle = actor->getHoldSoundHandle();
|
|
seHandle->setAcquiredMaybe(1);
|
|
handle = continueHoldingSound(seHandle, soundId, actor, position);
|
|
} else {
|
|
if (d_s_vt_0x190()) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
if (isInaudibleInternal()) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
actor = dSndDistantSoundActorPool_c::GetInstance()->acquireActor(soundId, position, this);
|
|
if (actor == nullptr) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
seHandle = dSndSeSoundPool_c::GetInstance()->acquireSoundType2(this, soundId);
|
|
if (seHandle == nullptr) {
|
|
resetTempParams();
|
|
return false;
|
|
}
|
|
seHandle->shiftParam(mpCtxParam);
|
|
handle = seHandle->getHandle();
|
|
if (actor->holdSound(soundId, *position, handle)) {
|
|
addSeHandleType2(seHandle);
|
|
postHoldSound(*handle, seHandle, soundId, 0);
|
|
postSetupSound(handle->GetId(), soundId, seHandle);
|
|
seHandle->onStart(this);
|
|
seHandle->onCalc(this);
|
|
actor->setHoldSoundHandle(seHandle);
|
|
} else {
|
|
dSndSeSoundPool_c::GetInstance()->releaseSoundType2(seHandle);
|
|
handle = nullptr;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
handle = holdSound(soundId, nullptr);
|
|
}
|
|
resetTempParams();
|
|
return handle != nullptr;
|
|
}
|
|
|
|
bool dSoundSource_c::holdSoundAtPosition(const char *label, const nw4r::math::VEC3 *position) {
|
|
return holdSoundAtPosition(soundLabelToSoundId(label), position);
|
|
}
|
|
|
|
nw4r::snd::SoundStartable::StartResult
|
|
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();
|
|
}
|
|
}
|
|
|
|
bool dSoundSource_c::d_s_vt_0x1AC(u32 soundId) {
|
|
if (soundId == -1) {
|
|
return false;
|
|
}
|
|
|
|
if (d_s_vt_0x190()) {
|
|
return false;
|
|
}
|
|
|
|
if (isInaudibleInternal()) {
|
|
return false;
|
|
}
|
|
|
|
if (checkUserParamMask(soundId, 0x80000000)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
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 = overrideStartSoundId(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);
|
|
resetTempParams();
|
|
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);
|
|
}
|
|
resetTempParams();
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
void dSoundSource_c::resetTempParams() {
|
|
mpCtxParam = nullptr;
|
|
sCtxParams.floatParam = 0.0f;
|
|
sCtxParams.intParam = 0;
|
|
field_0x11C = 0;
|
|
field_0x154 = 0;
|
|
}
|
|
|
|
nw4r::snd::SoundStartable::StartResult dSoundSource_c::onSetupError() {
|
|
resetTempParams();
|
|
return START_ERR_USER;
|
|
}
|
|
|
|
u32 dSoundSource_c::overrideStartSoundId(u32 soundId) {
|
|
return soundId;
|
|
}
|
|
|
|
void dSoundSource_c::postStartSound(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id) {
|
|
// noop
|
|
}
|
|
|
|
u32 dSoundSource_c::d_s_vt_0x1A0(u32 soundId, UNKWORD) {
|
|
return soundId;
|
|
}
|
|
|
|
void dSoundSource_c::postHoldSound(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id, UNKWORD) {
|
|
// noop
|
|
}
|
|
|
|
void dSoundSource_c::attachDistantSound(dSndDistantSoundActor_c *sound) {
|
|
if (sound != nullptr) {
|
|
sound->setSourceDirectly(this);
|
|
appendDistantSound(sound);
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::detachDistantSound(dSndDistantSoundActor_c *sound) {
|
|
if (sound != nullptr && sound->isAttachedSource(this)) {
|
|
sound->setSourceDirectly(nullptr);
|
|
removeDistantSound(sound);
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::detachAllDistantSounds() {
|
|
dSndDistantSoundActor_c *it = getDistantSoundFirst();
|
|
while (it != nullptr) {
|
|
it->setSourceDirectly(nullptr);
|
|
removeDistantSound(it);
|
|
it = getDistantSoundFirst();
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::pauseAllDistantSounds(bool flag, int fadeFrames) {
|
|
for (dSndDistantSoundActor_c *it = getDistantSoundFirst(); it != nullptr; it = getDistantSoundNext(it)) {
|
|
it->PauseAllSound(flag, fadeFrames);
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::addSeHandleType1(dSndSeSound1_c *handle) {
|
|
if (handle == nullptr) {
|
|
return;
|
|
}
|
|
if (handle->isAttachedSource()) {
|
|
return;
|
|
}
|
|
handle->attachSource(this);
|
|
appendHandleType1(handle);
|
|
}
|
|
|
|
void dSoundSource_c::addSeHandleType2(dSndSeSound2_c *handle) {
|
|
if (handle == nullptr) {
|
|
return;
|
|
}
|
|
if (handle->isAttachedSource()) {
|
|
return;
|
|
}
|
|
handle->attachSource(this);
|
|
appendHandleType2(handle);
|
|
}
|
|
|
|
void dSoundSource_c::removeSeHandleType1(dSndSeSound1_c *handle, bool stop) {
|
|
if (handle == nullptr) {
|
|
return;
|
|
}
|
|
if (!handle->isAttachedSource()) {
|
|
return;
|
|
}
|
|
removeHandleType1(handle);
|
|
dSndSeSoundPool_c::GetInstance()->releaseSoundType1(handle, stop);
|
|
}
|
|
|
|
void dSoundSource_c::removeSeHandleType2(dSndSeSound2_c *handle) {
|
|
if (handle == nullptr) {
|
|
return;
|
|
}
|
|
if (!handle->isAttachedSource()) {
|
|
return;
|
|
}
|
|
removeHandleType2(handle);
|
|
dSndSeSoundPool_c::GetInstance()->releaseSoundType2(handle);
|
|
}
|
|
|
|
void dSoundSource_c::removeAllSeHandles() {
|
|
removeAllSeHandlesType1();
|
|
removeAllSeHandlesType2();
|
|
}
|
|
|
|
void dSoundSource_c::removeAllSeHandlesType1() {
|
|
dSndSeSound1_c *sound = getHandleType1First();
|
|
while (sound != nullptr) {
|
|
removeSeHandleType1(sound, sound->unkRemovalCheck());
|
|
sound = getHandleType1First();
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::removeAllSeHandlesType2() {
|
|
dSndSeSound2_c *sound = getHandleType2First();
|
|
while (sound != nullptr) {
|
|
removeSeHandleType2(sound);
|
|
sound = getHandleType2First();
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::calcHandles() {
|
|
calcHandlesType1();
|
|
calcHandlesType2();
|
|
}
|
|
|
|
void dSoundSource_c::calcHandlesType1() {
|
|
dSndSeSound1_c *next, *it;
|
|
it = getHandleType1First();
|
|
while (it != nullptr) {
|
|
next = getHandleType1Next(it);
|
|
if (it->isAttachedSound()) {
|
|
it->calc(this);
|
|
} else {
|
|
removeSeHandleType1(it, true);
|
|
}
|
|
it = next;
|
|
}
|
|
}
|
|
|
|
void dSoundSource_c::calcHandlesType2() {
|
|
dSndSeSound2_c *next, *it;
|
|
it = getHandleType2First();
|
|
while (it != nullptr) {
|
|
next = getHandleType2Next(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 = getHandleType1First();
|
|
while (sound != nullptr) {
|
|
if (sound->isSoundId(soundId) || sound->getHandle()->GetId() == soundId) {
|
|
return sound;
|
|
}
|
|
sound = getHandleType1Next(sound);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
dSndSeSound1_c *dSoundSource_c::getHandleType1ForSoundHandle(nw4r::snd::SoundHandle *handle) {
|
|
dSndSeSound1_c *sound = getHandleType1First();
|
|
while (sound != nullptr) {
|
|
if (sound->getHandle() == handle) {
|
|
return sound;
|
|
}
|
|
sound = getHandleType1Next(sound);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
dSndSeSound2_c *dSoundSource_c::getHandleType2ForSoundId(u32 soundId) {
|
|
dSndSeSound2_c *sound = getHandleType2First();
|
|
while (sound != nullptr) {
|
|
if (sound->isSoundId(soundId) || sound->getHandle()->GetId() == soundId) {
|
|
return sound;
|
|
}
|
|
sound = getHandleType2Next(sound);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
dSndSeSound1_c *dSoundSource_c::getHandleType1ForSoundHandle_Dupe(nw4r::snd::SoundHandle *pHandle) {
|
|
dSndSeSound1_c *sound = getHandleType1First();
|
|
while (sound != nullptr) {
|
|
if (sound->getHandle() == pHandle) {
|
|
return sound;
|
|
}
|
|
sound = getHandleType1Next(sound);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
dSndSeSound2_c *dSoundSource_c::getHandleType2ForSoundHandle_Dupe(nw4r::snd::SoundHandle *pHandle) {
|
|
dSndSeSound2_c *sound = getHandleType2First();
|
|
while (sound != nullptr) {
|
|
if (sound->getHandle() == pHandle) {
|
|
return sound;
|
|
}
|
|
sound = getHandleType2Next(sound);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void dSoundSource_c::stopSoundHandles(u32 soundId, s32 fadeFrames) {
|
|
{
|
|
dSndSeSound1_c *next, *it;
|
|
it = getHandleType1First();
|
|
while (it != nullptr) {
|
|
next = getHandleType1Next(it);
|
|
if (it->isSoundId(soundId) || it->getHandle()->GetId() == soundId) {
|
|
it->getHandle()->Stop(fadeFrames);
|
|
removeSeHandleType1(it, true);
|
|
}
|
|
it = next;
|
|
}
|
|
}
|
|
|
|
{
|
|
dSndSeSound2_c *next, *it;
|
|
it = getHandleType2First();
|
|
while (it != nullptr) {
|
|
next = getHandleType2Next(it);
|
|
if (it->isSoundId(soundId) || it->getHandle()->GetId() == soundId) {
|
|
it->getHandle()->Stop(fadeFrames);
|
|
removeSeHandleType2(it);
|
|
}
|
|
it = next;
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma push
|
|
#pragma optimize_tail_call off
|
|
bool dSoundSource_c::isInaudible() {
|
|
return isInaudibleInternal();
|
|
}
|
|
#pragma pop
|
|
|
|
void dSoundSource_c::setPolyAttrs(u8 polyAttr0, u8 polyAttr1) {
|
|
mPolyAttr0 = polyAttr0;
|
|
mPolyAttr1 = polyAttr1;
|
|
}
|
|
|
|
void dSoundSource_c::d_s_vt_0x1E4_noop() {
|
|
// never used, never overridden
|
|
}
|
|
|
|
u32 dSoundSource_c::modifySoundId(u32 baseSoundId) {
|
|
if (baseSoundId != -1) {
|
|
SizedString<64> label;
|
|
|
|
const char *baseLabel = dSndMgr_c::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;
|
|
|
|
const char *baseLabel = dSndMgr_c::getSoundLabelString(baseSoundId);
|
|
const char *charLabel = source->getName();
|
|
label.sprintf("%s_%s", baseLabel, charLabel);
|
|
u32 newLabel = dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(label);
|
|
if (newLabel != -1) {
|
|
return newLabel;
|
|
}
|
|
}
|
|
return baseSoundId;
|
|
}
|
|
|
|
u32 dSoundSource_c::specializeBgHitSoundId(u32 soundId, u32 polyAttr0, u32 polyAttr1) {
|
|
if (checkUserParamMask(soundId, 0x100)) {
|
|
if (polyAttr0 >= SND_MAT_NONE + 1 && polyAttr0 <= SND_MAT_MAX - 1) {
|
|
const char *baseLabel = dSndMgr_c::getSoundLabelString(soundId);
|
|
SizedString<64> label;
|
|
label.sprintf("%s_%s_%d", baseLabel, getHitEffectName(polyAttr0), polyAttr1);
|
|
u32 newId = dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(label);
|
|
if (newId == -1) {
|
|
SizedString<64> label;
|
|
label.sprintf("%s_%s", baseLabel, getHitEffectName(polyAttr0));
|
|
newId = dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(label);
|
|
}
|
|
if (newId != -1) {
|
|
return newId;
|
|
}
|
|
}
|
|
}
|
|
return soundId;
|
|
}
|
|
|
|
u32 dSoundSource_c::d_s_vt_0x1E8(u32 soundId) {
|
|
return soundId;
|
|
}
|
|
|
|
u32 dSoundSource_c::getRemoConSoundVariant(u32 soundId) const {
|
|
const char *label = soundIdToSoundLabel(soundId);
|
|
SizedString<64> str;
|
|
str.sprintf("%s_RC", label);
|
|
return soundLabelToSoundId(str);
|
|
}
|
|
|
|
f32 dSoundSource_c::timeAreaCheck() {
|
|
bool check = !dTimeAreaMgr_c::GetInstance()->fn_800B9B60(getRoomId(), GetPosition());
|
|
if (check) {
|
|
return 0.0f;
|
|
}
|
|
f32 tmp = dTimeAreaMgr_c::GetInstance()->fn_800B9CE0(GetPosition());
|
|
if (tmp > 0.0f) {
|
|
tmp = tmp / 500.0f;
|
|
if (tmp > 1.0f) {
|
|
tmp = 1.0f;
|
|
}
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
nw4r::snd::SoundStartable::StartResult
|
|
dSoundSource_c::setupSoundCommon(nw4r::snd::SoundHandle *pHandle, u32 soundId, const StartInfo *pStartInfo, void *arg) {
|
|
bool holdFlag = *(bool *)arg;
|
|
if (!d_s_vt_0x1AC(soundId)) {
|
|
return onSetupError();
|
|
}
|
|
|
|
dSndSeSound_c *seHandle = nullptr;
|
|
bool freshSeSound = false;
|
|
if ((field_0x11C & 0x80000000) == 0) {
|
|
if (holdFlag) {
|
|
seHandle = getHandleType2ForSoundHandle_Dupe(pHandle);
|
|
} else {
|
|
seHandle = getHandleType1ForSoundHandle_Dupe(pHandle);
|
|
}
|
|
|
|
if (seHandle == nullptr) {
|
|
if (holdFlag) {
|
|
seHandle = dSndSeSoundPool_c::GetInstance()->acquireSoundType2(this, soundId);
|
|
} else {
|
|
seHandle = dSndSeSoundPool_c::GetInstance()->acquireSoundType1(this, soundId);
|
|
}
|
|
freshSeSound = true;
|
|
}
|
|
|
|
if (seHandle == nullptr) {
|
|
return onSetupError();
|
|
}
|
|
|
|
if (pHandle != nullptr) {
|
|
seHandle->setHandle(pHandle);
|
|
} else {
|
|
pHandle = seHandle->getHandle();
|
|
}
|
|
}
|
|
|
|
StartResult res = setupSound(pHandle, soundId, pStartInfo, arg, holdFlag);
|
|
if (res == START_SUCCESS) {
|
|
if (seHandle != nullptr) {
|
|
if (!holdFlag) {
|
|
if (freshSeSound) {
|
|
addSeHandleType1(static_cast<dSndSeSound1_c *>(seHandle));
|
|
}
|
|
postStartSound(*pHandle, seHandle, soundId);
|
|
} else {
|
|
if (freshSeSound) {
|
|
addSeHandleType2(static_cast<dSndSeSound2_c *>(seHandle));
|
|
}
|
|
postHoldSound(*pHandle, seHandle, soundId, 1);
|
|
}
|
|
postSetupSound(pHandle->GetId(), soundId, seHandle);
|
|
seHandle->onStart(this);
|
|
seHandle->onCalc(this);
|
|
}
|
|
} else if (freshSeSound) {
|
|
if (seHandle->getHandleType() == dSndSeSound_c::SE_HANDLE_TYPE_1) {
|
|
dSndSeSoundPool_c::GetInstance()->releaseSoundType1(static_cast<dSndSeSound1_c *>(seHandle), true);
|
|
} else {
|
|
dSndSeSoundPool_c::GetInstance()->releaseSoundType2(static_cast<dSndSeSound2_c *>(seHandle));
|
|
}
|
|
}
|
|
return res;
|
|
}
|