mirror of https://github.com/AxioDL/metaforce.git
Working SFX playback
This commit is contained in:
parent
9701907a3a
commit
afd852f1a4
|
@ -82,4 +82,27 @@ void CAudioSys::SysRemoveGroupFromAmuse(const std::string& name)
|
||||||
RemoveAudioGroup(set->GetAudioGroupData());
|
RemoveAudioGroup(set->GetAudioGroupData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAudioSys::SysSetVolume(u8 volume)
|
||||||
|
{
|
||||||
|
GetAmuseEngine().setVolume(volume / 127.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static s16 s_VolumeScale = 0x7f;
|
||||||
|
static s16 s_DefaultVolumeScale = 0x7f;
|
||||||
|
|
||||||
|
s16 CAudioSys::GetDefaultVolumeScale()
|
||||||
|
{
|
||||||
|
return s_DefaultVolumeScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAudioSys::SetDefaultVolumeScale(s16 scale)
|
||||||
|
{
|
||||||
|
s_DefaultVolumeScale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAudioSys::SetVolumeScale(s16 scale)
|
||||||
|
{
|
||||||
|
s_VolumeScale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,6 @@ CFactoryFnReturn FAudioTranslationTableFactory(const SObjectTag& tag, CInputStre
|
||||||
|
|
||||||
class CAudioSys
|
class CAudioSys
|
||||||
{
|
{
|
||||||
static CAudioSys* g_SharedSys;
|
|
||||||
boo::IAudioVoiceEngine* m_voiceEngine;
|
|
||||||
amuse::Engine m_engine;
|
|
||||||
public:
|
public:
|
||||||
enum class ESurroundModes
|
enum class ESurroundModes
|
||||||
{
|
{
|
||||||
|
@ -30,6 +27,12 @@ public:
|
||||||
Surround
|
Surround
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static CAudioSys* g_SharedSys;
|
||||||
|
boo::IAudioVoiceEngine* m_voiceEngine;
|
||||||
|
amuse::Engine m_engine;
|
||||||
|
|
||||||
|
public:
|
||||||
struct C3DEmitterParmData
|
struct C3DEmitterParmData
|
||||||
{
|
{
|
||||||
zeus::CVector3f x0_pos;
|
zeus::CVector3f x0_pos;
|
||||||
|
@ -40,7 +43,8 @@ public:
|
||||||
u16 x24_sfxId;
|
u16 x24_sfxId;
|
||||||
float x26_maxVol;
|
float x26_maxVol;
|
||||||
float x27_minVol;
|
float x27_minVol;
|
||||||
u8 x28_extra[2];
|
u8 x28_;
|
||||||
|
u8 x29_;
|
||||||
};
|
};
|
||||||
CAudioSys(boo::IAudioVoiceEngine* voiceEngine,
|
CAudioSys(boo::IAudioVoiceEngine* voiceEngine,
|
||||||
amuse::IBackendVoiceAllocator& backend, u8,u8,u8,u8,u32)
|
amuse::IBackendVoiceAllocator& backend, u8,u8,u8,u8,u32)
|
||||||
|
@ -81,6 +85,11 @@ public:
|
||||||
static bool SysIsGroupSetLoaded(const std::string& name);
|
static bool SysIsGroupSetLoaded(const std::string& name);
|
||||||
static void SysAddGroupIntoAmuse(const std::string& name);
|
static void SysAddGroupIntoAmuse(const std::string& name);
|
||||||
static void SysRemoveGroupFromAmuse(const std::string& name);
|
static void SysRemoveGroupFromAmuse(const std::string& name);
|
||||||
|
static void SysSetVolume(u8 volume);
|
||||||
|
|
||||||
|
static s16 GetDefaultVolumeScale();
|
||||||
|
static void SetDefaultVolumeScale(s16 scale);
|
||||||
|
static void SetVolumeScale(s16 scale);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,16 @@ namespace urde
|
||||||
static TLockedToken<std::vector<s16>> mpSfxTranslationTableTok;
|
static TLockedToken<std::vector<s16>> mpSfxTranslationTableTok;
|
||||||
std::vector<s16>* CSfxManager::mpSfxTranslationTable = nullptr;
|
std::vector<s16>* CSfxManager::mpSfxTranslationTable = nullptr;
|
||||||
|
|
||||||
|
static amuse::EffectReverbHiInfo s_ReverbHiQueued;
|
||||||
|
static amuse::EffectChorusInfo s_ChorusQueued;
|
||||||
|
static amuse::EffectReverbStdInfo s_ReverbStdQueued;
|
||||||
|
static amuse::EffectDelayInfo s_DelayQueued;
|
||||||
|
|
||||||
|
static amuse::EffectReverbHi* s_ReverbHiState = nullptr;
|
||||||
|
static amuse::EffectChorus* s_ChorusState = nullptr;
|
||||||
|
static amuse::EffectReverbStd* s_ReverbStdState = nullptr;
|
||||||
|
static amuse::EffectDelay* s_DelayState = nullptr;
|
||||||
|
|
||||||
CFactoryFnReturn FAudioTranslationTableFactory(const SObjectTag& tag, CInputStream& in,
|
CFactoryFnReturn FAudioTranslationTableFactory(const SObjectTag& tag, CInputStream& in,
|
||||||
const CVParamTransfer& vparms,
|
const CVParamTransfer& vparms,
|
||||||
CObjectReference* selfRef)
|
CObjectReference* selfRef)
|
||||||
|
@ -20,14 +30,14 @@ CFactoryFnReturn FAudioTranslationTableFactory(const SObjectTag& tag, CInputStre
|
||||||
}
|
}
|
||||||
|
|
||||||
CSfxManager::CSfxChannel CSfxManager::m_channels[4];
|
CSfxManager::CSfxChannel CSfxManager::m_channels[4];
|
||||||
rstl::reserved_vector<std::shared_ptr<CSfxManager::CSfxEmitterWrapper>, 128> CSfxManager::m_emitterWrapperPool;
|
CSfxManager::ESfxChannels CSfxManager::m_currentChannel = CSfxManager::ESfxChannels::Default;
|
||||||
rstl::reserved_vector<std::shared_ptr<CSfxManager::CSfxWrapper>, 128> CSfxManager::m_wrapperPool;
|
|
||||||
CSfxManager::ESfxChannels CSfxManager::m_currentChannel;
|
|
||||||
bool CSfxManager::m_doUpdate;
|
bool CSfxManager::m_doUpdate;
|
||||||
void* CSfxManager::m_usedSounds;
|
void* CSfxManager::m_usedSounds;
|
||||||
bool CSfxManager::m_muted;
|
bool CSfxManager::m_muted;
|
||||||
bool CSfxManager::m_auxProcessingEnabled;
|
bool CSfxManager::m_auxProcessingEnabled = false;
|
||||||
float CSfxManager::m_reverbAmount = 1.f;
|
float CSfxManager::m_reverbAmount = 1.f;
|
||||||
|
CSfxManager::EAuxEffect CSfxManager::m_activeEffect = CSfxManager::EAuxEffect::None;
|
||||||
|
CSfxManager::EAuxEffect CSfxManager::m_nextEffect = CSfxManager::EAuxEffect::None;
|
||||||
|
|
||||||
u16 CSfxManager::kMaxPriority;
|
u16 CSfxManager::kMaxPriority;
|
||||||
u16 CSfxManager::kMedPriority;
|
u16 CSfxManager::kMedPriority;
|
||||||
|
@ -38,10 +48,10 @@ bool CSfxManager::LoadTranslationTable(CSimplePool* pool, const SObjectTag* tag)
|
||||||
{
|
{
|
||||||
if (!tag)
|
if (!tag)
|
||||||
return false;
|
return false;
|
||||||
|
mpSfxTranslationTable = nullptr;
|
||||||
mpSfxTranslationTableTok = pool->GetObj(*tag);
|
mpSfxTranslationTableTok = pool->GetObj(*tag);
|
||||||
if (!mpSfxTranslationTableTok)
|
if (!mpSfxTranslationTableTok)
|
||||||
return false;
|
return false;
|
||||||
mpSfxTranslationTable = mpSfxTranslationTableTok.GetObj();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +91,27 @@ bool CSfxManager::CSfxWrapper::Ready()
|
||||||
return x24_ready;
|
return x24_ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 CSfxManager::CSfxWrapper::GetSfxId() const
|
||||||
|
{
|
||||||
|
return x18_sfxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::CSfxWrapper::UpdateEmitterSilent()
|
||||||
|
{
|
||||||
|
x1c_voiceHandle->setVolume(1.f / 127.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::CSfxWrapper::UpdateEmitter()
|
||||||
|
{
|
||||||
|
x1c_voiceHandle->setVolume(x20_vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::CSfxWrapper::SetReverb(float rev)
|
||||||
|
{
|
||||||
|
if (IsAuxProcessingEnabled() && UseAcoustics())
|
||||||
|
x1c_voiceHandle->setReverbVol(rev);
|
||||||
|
}
|
||||||
|
|
||||||
bool CSfxManager::CSfxEmitterWrapper::IsPlaying() const
|
bool CSfxManager::CSfxEmitterWrapper::IsPlaying() const
|
||||||
{
|
{
|
||||||
if (IsLooped())
|
if (IsLooped())
|
||||||
|
@ -138,10 +169,86 @@ CSfxManager::ESfxAudibility CSfxManager::CSfxEmitterWrapper::GetAudible(const ze
|
||||||
return ESfxAudibility::Aud0;
|
return ESfxAudibility::Aud0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSfxManager::CSfxManager()
|
u16 CSfxManager::CSfxEmitterWrapper::GetSfxId() const
|
||||||
{
|
{
|
||||||
m_emitterWrapperPool.resize(128);
|
return x24_parmData.x24_sfxId;
|
||||||
m_wrapperPool.resize(128);
|
}
|
||||||
|
|
||||||
|
void CSfxManager::CSfxEmitterWrapper::UpdateEmitterSilent()
|
||||||
|
{
|
||||||
|
x50_emitterHandle->setPos(x24_parmData.x0_pos.v);
|
||||||
|
x50_emitterHandle->setDir(x24_parmData.xc_dir.v);
|
||||||
|
x50_emitterHandle->setMaxVol(1.f / 127.f);
|
||||||
|
x55_cachedMaxVol = x24_parmData.x26_maxVol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::CSfxEmitterWrapper::UpdateEmitter()
|
||||||
|
{
|
||||||
|
x50_emitterHandle->setPos(x24_parmData.x0_pos.v);
|
||||||
|
x50_emitterHandle->setDir(x24_parmData.xc_dir.v);
|
||||||
|
x50_emitterHandle->setMaxVol(x55_cachedMaxVol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::CSfxEmitterWrapper::SetReverb(float rev)
|
||||||
|
{
|
||||||
|
if (IsAuxProcessingEnabled() && UseAcoustics())
|
||||||
|
x1a_reverb = rev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::SetChannel(ESfxChannels chan)
|
||||||
|
{
|
||||||
|
if (m_currentChannel == chan)
|
||||||
|
return;
|
||||||
|
if (m_currentChannel != ESfxChannels::Invalid)
|
||||||
|
TurnOffChannel(m_currentChannel);
|
||||||
|
TurnOnChannel(chan);
|
||||||
|
m_currentChannel = chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::TurnOnChannel(ESfxChannels chan)
|
||||||
|
{
|
||||||
|
CSfxChannel& chanObj = m_channels[int(chan)];
|
||||||
|
m_currentChannel = chan;
|
||||||
|
m_doUpdate = true;
|
||||||
|
if (chanObj.x44_listenerActive)
|
||||||
|
{
|
||||||
|
for (const CSfxHandle& handle : chanObj.x48_handles)
|
||||||
|
{
|
||||||
|
handle->UpdateEmitter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::TurnOffChannel(ESfxChannels chan)
|
||||||
|
{
|
||||||
|
CSfxChannel& chanObj = m_channels[int(chan)];
|
||||||
|
for (auto it = chanObj.x48_handles.begin() ; it != chanObj.x48_handles.end() ;)
|
||||||
|
{
|
||||||
|
const CSfxHandle& handle = *it;
|
||||||
|
if (handle->IsLooped())
|
||||||
|
{
|
||||||
|
handle->UpdateEmitterSilent();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle->Stop();
|
||||||
|
it = chanObj.x48_handles.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = chanObj.x48_handles.begin() ; it != chanObj.x48_handles.end() ;)
|
||||||
|
{
|
||||||
|
const CSfxHandle& handle = *it;
|
||||||
|
if (!handle->IsLooped())
|
||||||
|
{
|
||||||
|
handle->Release();
|
||||||
|
it = chanObj.x48_handles.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSfxManager::AddListener(ESfxChannels,
|
void CSfxManager::AddListener(ESfxChannels,
|
||||||
|
@ -157,6 +264,47 @@ void CSfxManager::UpdateListener(const zeus::CVector3f& pos, const zeus::CVector
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s16 CSfxManager::GetRank(CBaseSfxWrapper* sfx)
|
||||||
|
{
|
||||||
|
CSfxChannel& chanObj = m_channels[int(m_currentChannel)];
|
||||||
|
if (!sfx->IsInArea())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
s16 rank = sfx->GetPriority() / 4;
|
||||||
|
if (sfx->IsPlaying())
|
||||||
|
++rank;
|
||||||
|
|
||||||
|
if (sfx->IsLooped())
|
||||||
|
rank -= 2;
|
||||||
|
|
||||||
|
if (sfx->Ready() && !sfx->IsPlaying())
|
||||||
|
rank += 3;
|
||||||
|
|
||||||
|
if (chanObj.x44_listenerActive)
|
||||||
|
{
|
||||||
|
ESfxAudibility aud = sfx->GetAudible(chanObj.x0_pos);
|
||||||
|
if (aud == ESfxAudibility::Aud0)
|
||||||
|
return 0;
|
||||||
|
rank += int(aud) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::ApplyReverb()
|
||||||
|
{
|
||||||
|
CSfxChannel& chanObj = m_channels[int(m_currentChannel)];
|
||||||
|
for (const CSfxHandle& handle : chanObj.x48_handles)
|
||||||
|
{
|
||||||
|
handle->SetReverb(m_reverbAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float CSfxManager::GetReverbAmount()
|
||||||
|
{
|
||||||
|
return m_reverbAmount;
|
||||||
|
}
|
||||||
|
|
||||||
u16 CSfxManager::TranslateSFXID(u16 id)
|
u16 CSfxManager::TranslateSFXID(u16 id)
|
||||||
{
|
{
|
||||||
if (mpSfxTranslationTable == nullptr)
|
if (mpSfxTranslationTable == nullptr)
|
||||||
|
@ -172,10 +320,19 @@ u16 CSfxManager::TranslateSFXID(u16 id)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSfxManager::StopSound(const CSfxHandle& handle)
|
||||||
|
{
|
||||||
|
m_doUpdate = true;
|
||||||
|
if (handle->IsPlaying())
|
||||||
|
handle->Stop();
|
||||||
|
handle->Release();
|
||||||
|
CSfxChannel& chanObj = m_channels[int(m_currentChannel)];
|
||||||
|
chanObj.x48_handles.erase(handle);
|
||||||
|
}
|
||||||
|
|
||||||
void CSfxManager::SfxStop(const CSfxHandle& handle)
|
void CSfxManager::SfxStop(const CSfxHandle& handle)
|
||||||
{
|
{
|
||||||
if (handle)
|
StopSound(handle);
|
||||||
handle->Stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CSfxHandle CSfxManager::SfxStart(u16 id, float vol, float pan, bool useAcoustics, s16 prio, bool looped, s32 areaId)
|
CSfxHandle CSfxManager::SfxStart(u16 id, float vol, float pan, bool useAcoustics, s16 prio, bool looped, s32 areaId)
|
||||||
|
@ -183,35 +340,226 @@ CSfxHandle CSfxManager::SfxStart(u16 id, float vol, float pan, bool useAcoustics
|
||||||
if (m_muted || id == 0xffff)
|
if (m_muted || id == 0xffff)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
std::shared_ptr<CSfxWrapper>* wrapper = AllocateCSfxWrapper();
|
m_doUpdate = true;
|
||||||
if (!wrapper)
|
CSfxHandle wrapper = std::make_shared<CSfxWrapper>(looped, prio, id, vol, pan, useAcoustics, areaId);
|
||||||
return {};
|
CSfxChannel& chanObj = m_channels[int(m_currentChannel)];
|
||||||
|
chanObj.x48_handles.insert(wrapper);
|
||||||
*wrapper = std::make_shared<CSfxWrapper>(looped, prio, id, vol, pan, useAcoustics, areaId);
|
return wrapper;
|
||||||
return std::static_pointer_cast<CBaseSfxWrapper>(*wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<CSfxManager::CSfxWrapper>* CSfxManager::AllocateCSfxWrapper()
|
|
||||||
{
|
|
||||||
for (std::shared_ptr<CSfxWrapper>& existing : m_wrapperPool)
|
|
||||||
if (!existing || existing->Available())
|
|
||||||
return &existing;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSfxManager::StopAndRemoveAllEmitters()
|
void CSfxManager::StopAndRemoveAllEmitters()
|
||||||
{
|
{
|
||||||
|
for (int i=0 ; i<4 ; ++i)
|
||||||
|
{
|
||||||
|
CSfxChannel& chanObj = m_channels[i];
|
||||||
|
for (auto it = chanObj.x48_handles.begin() ; it != chanObj.x48_handles.end() ;)
|
||||||
|
{
|
||||||
|
const CSfxHandle& handle = *it;
|
||||||
|
if (handle->IsPlaying())
|
||||||
|
handle->Stop();
|
||||||
|
handle->Release();
|
||||||
|
it = chanObj.x48_handles.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSfxManager::DisableAuxCallbacks()
|
void CSfxManager::EnableAuxCallback()
|
||||||
{
|
{
|
||||||
|
m_reverbAmount = 0.f;
|
||||||
|
ApplyReverb();
|
||||||
|
if (m_activeEffect != EAuxEffect::None)
|
||||||
|
DisableAuxCallback();
|
||||||
|
|
||||||
|
auto studio = CAudioSys::GetAmuseEngine().getDefaultStudio();
|
||||||
|
amuse::Submix& smix = studio->getAuxA();
|
||||||
|
|
||||||
|
m_activeEffect = m_nextEffect;
|
||||||
|
switch (m_activeEffect)
|
||||||
|
{
|
||||||
|
case EAuxEffect::ReverbHi:
|
||||||
|
s_ReverbHiState = &smix.makeReverbHi(s_ReverbHiQueued);
|
||||||
|
break;
|
||||||
|
case EAuxEffect::Chorus:
|
||||||
|
s_ChorusState = &smix.makeChorus(s_ChorusQueued);
|
||||||
|
break;
|
||||||
|
case EAuxEffect::ReverbStd:
|
||||||
|
s_ReverbStdState = &smix.makeReverbStd(s_ReverbStdQueued);
|
||||||
|
break;
|
||||||
|
case EAuxEffect::Delay:
|
||||||
|
s_DelayState = &smix.makeDelay(s_DelayQueued);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_auxProcessingEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSfxManager::Update()
|
void CSfxManager::PrepareDelayCallback(const amuse::EffectDelayInfo& info)
|
||||||
{
|
{
|
||||||
|
DisableAuxProcessing();
|
||||||
|
s_DelayQueued = info;
|
||||||
|
m_nextEffect = EAuxEffect::Delay;
|
||||||
|
if (m_reverbAmount == 0.f)
|
||||||
|
EnableAuxCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::PrepareReverbStdCallback(const amuse::EffectReverbStdInfo& info)
|
||||||
|
{
|
||||||
|
DisableAuxProcessing();
|
||||||
|
s_ReverbStdQueued = info;
|
||||||
|
m_nextEffect = EAuxEffect::ReverbStd;
|
||||||
|
if (m_reverbAmount == 0.f)
|
||||||
|
EnableAuxCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::PrepareChorusCallback(const amuse::EffectChorusInfo& info)
|
||||||
|
{
|
||||||
|
DisableAuxProcessing();
|
||||||
|
s_ChorusQueued = info;
|
||||||
|
m_nextEffect = EAuxEffect::Chorus;
|
||||||
|
if (m_reverbAmount == 0.f)
|
||||||
|
EnableAuxCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::PrepareReverbHiCallback(const amuse::EffectReverbHiInfo& info)
|
||||||
|
{
|
||||||
|
DisableAuxProcessing();
|
||||||
|
s_ReverbHiQueued = info;
|
||||||
|
m_nextEffect = EAuxEffect::ReverbHi;
|
||||||
|
if (m_reverbAmount == 0.f)
|
||||||
|
EnableAuxCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::DisableAuxCallback()
|
||||||
|
{
|
||||||
|
auto studio = CAudioSys::GetAmuseEngine().getDefaultStudio();
|
||||||
|
studio->getAuxA().clearEffects();
|
||||||
|
|
||||||
|
switch (m_activeEffect)
|
||||||
|
{
|
||||||
|
case EAuxEffect::ReverbHi:
|
||||||
|
s_ReverbHiState = nullptr;
|
||||||
|
break;
|
||||||
|
case EAuxEffect::Chorus:
|
||||||
|
s_ChorusState = nullptr;
|
||||||
|
break;
|
||||||
|
case EAuxEffect::ReverbStd:
|
||||||
|
s_ReverbStdState = nullptr;
|
||||||
|
break;
|
||||||
|
case EAuxEffect::Delay:
|
||||||
|
s_DelayState = nullptr;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_activeEffect = EAuxEffect::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::DisableAuxProcessing()
|
||||||
|
{
|
||||||
|
m_nextEffect = EAuxEffect::None;
|
||||||
|
m_auxProcessingEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSfxManager::Update(float dt)
|
||||||
|
{
|
||||||
|
CSfxChannel& chanObj = m_channels[int(m_currentChannel)];
|
||||||
|
|
||||||
|
for (auto it = chanObj.x48_handles.begin() ; it != chanObj.x48_handles.end() ;)
|
||||||
|
{
|
||||||
|
const CSfxHandle& handle = *it;
|
||||||
|
if (!handle->IsLooped())
|
||||||
|
{
|
||||||
|
float timeRem = handle->GetTimeRemaining();
|
||||||
|
handle->SetTimeRemaining(timeRem - dt);
|
||||||
|
if (timeRem < 0.f)
|
||||||
|
{
|
||||||
|
handle->Stop();
|
||||||
|
m_doUpdate = true;
|
||||||
|
it = chanObj.x48_handles.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_doUpdate)
|
||||||
|
{
|
||||||
|
std::vector<CSfxHandle> rankedSfx;
|
||||||
|
rankedSfx.reserve(chanObj.x48_handles.size());
|
||||||
|
for (const CSfxHandle& handle : chanObj.x48_handles)
|
||||||
|
{
|
||||||
|
rankedSfx.push_back(handle);
|
||||||
|
handle->SetRank(GetRank(handle.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(rankedSfx.begin(), rankedSfx.end(),
|
||||||
|
[](const CSfxHandle& a, const CSfxHandle& b) -> bool
|
||||||
|
{
|
||||||
|
return a->GetRank() < b->GetRank();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i=48 ; i<rankedSfx.size() ; ++i)
|
||||||
|
{
|
||||||
|
const CSfxHandle& handle = rankedSfx[i];
|
||||||
|
if (handle->IsPlaying())
|
||||||
|
{
|
||||||
|
handle->Stop();
|
||||||
|
chanObj.x48_handles.erase(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const CSfxHandle& handle : rankedSfx)
|
||||||
|
{
|
||||||
|
if (handle->IsPlaying() && !handle->IsInArea())
|
||||||
|
{
|
||||||
|
handle->Stop();
|
||||||
|
chanObj.x48_handles.erase(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const CSfxHandle& handle : chanObj.x48_handles)
|
||||||
|
{
|
||||||
|
if (handle->IsPlaying())
|
||||||
|
continue;
|
||||||
|
if (handle->Ready() && handle->IsInArea())
|
||||||
|
handle->Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_doUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = chanObj.x48_handles.begin() ; it != chanObj.x48_handles.end() ;)
|
||||||
|
{
|
||||||
|
const CSfxHandle& handle = *it;
|
||||||
|
if (!handle->IsPlaying() && !handle->IsLooped())
|
||||||
|
{
|
||||||
|
handle->Release();
|
||||||
|
m_doUpdate = true;
|
||||||
|
it = chanObj.x48_handles.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_auxProcessingEnabled && m_reverbAmount < 1.f)
|
||||||
|
{
|
||||||
|
m_reverbAmount = std::min(1.f, dt / 0.1f + m_reverbAmount);
|
||||||
|
ApplyReverb();
|
||||||
|
}
|
||||||
|
else if (!m_auxProcessingEnabled && m_reverbAmount > 0.f)
|
||||||
|
{
|
||||||
|
m_reverbAmount = std::max(0.f, m_reverbAmount - dt / (2.f * 0.1f));
|
||||||
|
ApplyReverb();
|
||||||
|
if (m_reverbAmount == 0.f)
|
||||||
|
{
|
||||||
|
DisableAuxCallback();
|
||||||
|
EnableAuxCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mpSfxTranslationTableTok.IsLoaded() && !mpSfxTranslationTable)
|
||||||
|
mpSfxTranslationTable = mpSfxTranslationTableTok.GetObj();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSfxManager::Shutdown()
|
void CSfxManager::Shutdown()
|
||||||
|
@ -219,7 +567,7 @@ void CSfxManager::Shutdown()
|
||||||
mpSfxTranslationTable = nullptr;
|
mpSfxTranslationTable = nullptr;
|
||||||
mpSfxTranslationTableTok = TLockedToken<std::vector<s16>>{};
|
mpSfxTranslationTableTok = TLockedToken<std::vector<s16>>{};
|
||||||
StopAndRemoveAllEmitters();
|
StopAndRemoveAllEmitters();
|
||||||
DisableAuxCallbacks();
|
DisableAuxCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,13 @@ class CSfxManager
|
||||||
{
|
{
|
||||||
static std::vector<s16>* mpSfxTranslationTable;
|
static std::vector<s16>* mpSfxTranslationTable;
|
||||||
public:
|
public:
|
||||||
CSfxManager();
|
|
||||||
|
|
||||||
enum class ESfxChannels
|
enum class ESfxChannels
|
||||||
{
|
{
|
||||||
Zero,
|
Invalid = -1,
|
||||||
One
|
Default = 0,
|
||||||
|
Game,
|
||||||
|
PauseScreen
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ESfxAudibility
|
enum class ESfxAudibility
|
||||||
|
@ -29,16 +30,37 @@ public:
|
||||||
Aud3
|
Aud3
|
||||||
};
|
};
|
||||||
|
|
||||||
class CSfxChannel
|
enum class EAuxEffect
|
||||||
{
|
{
|
||||||
|
None = -1,
|
||||||
|
ReverbHi = 0,
|
||||||
|
Chorus,
|
||||||
|
ReverbStd,
|
||||||
|
Delay
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBaseSfxWrapper;
|
class CBaseSfxWrapper;
|
||||||
using CSfxHandle = std::shared_ptr<CBaseSfxWrapper>;
|
using CSfxHandle = std::shared_ptr<CBaseSfxWrapper>;
|
||||||
|
|
||||||
|
class CSfxChannel
|
||||||
|
{
|
||||||
|
friend class CSfxManager;
|
||||||
|
zeus::CVector3f x0_pos;
|
||||||
|
zeus::CVector3f xc_;
|
||||||
|
zeus::CVector3f x18_;
|
||||||
|
zeus::CVector3f x24_;
|
||||||
|
float x30_ = 0.f;
|
||||||
|
float x34_ = 0.f;
|
||||||
|
float x38_ = 0.f;
|
||||||
|
u32 x3c_ = 0;
|
||||||
|
bool x40_ = false;
|
||||||
|
bool x44_listenerActive = false;
|
||||||
|
std::unordered_set<CSfxHandle> x48_handles;
|
||||||
|
};
|
||||||
|
|
||||||
class CBaseSfxWrapper : public std::enable_shared_from_this<CBaseSfxWrapper>
|
class CBaseSfxWrapper : public std::enable_shared_from_this<CBaseSfxWrapper>
|
||||||
{
|
{
|
||||||
float x4_ = 15.f;
|
float x4_timeRemaining = 15.f;
|
||||||
s16 x8_rank = 0;
|
s16 x8_rank = 0;
|
||||||
s16 xa_prio;
|
s16 xa_prio;
|
||||||
//CSfxHandle xc_handle;
|
//CSfxHandle xc_handle;
|
||||||
|
@ -76,10 +98,17 @@ public:
|
||||||
virtual bool Ready()=0;
|
virtual bool Ready()=0;
|
||||||
virtual ESfxAudibility GetAudible(const zeus::CVector3f&)=0;
|
virtual ESfxAudibility GetAudible(const zeus::CVector3f&)=0;
|
||||||
virtual const std::shared_ptr<amuse::Voice>& GetVoice() const=0;
|
virtual const std::shared_ptr<amuse::Voice>& GetVoice() const=0;
|
||||||
|
virtual u16 GetSfxId() const=0;
|
||||||
|
virtual void UpdateEmitterSilent()=0;
|
||||||
|
virtual void UpdateEmitter()=0;
|
||||||
|
virtual void SetReverb(float rev)=0;
|
||||||
|
|
||||||
void Release() { x14_28_available = true; }
|
void Release() { x14_28_available = true; x4_timeRemaining = 15.f; }
|
||||||
bool Available() const { return x14_28_available; }
|
bool Available() const { return x14_28_available; }
|
||||||
|
|
||||||
|
float GetTimeRemaining() const { return x4_timeRemaining; }
|
||||||
|
void SetTimeRemaining(float t) { x4_timeRemaining = t; }
|
||||||
|
|
||||||
CBaseSfxWrapper(bool looped, s16 prio, /*const CSfxHandle& handle,*/ bool useAcoustics, TAreaId area)
|
CBaseSfxWrapper(bool looped, s16 prio, /*const CSfxHandle& handle,*/ bool useAcoustics, TAreaId area)
|
||||||
: x8_rank(0), xa_prio(prio), /*xc_handle(handle),*/ x10_area(area), x14_24_isActive(true), x14_25_isPlaying(false),
|
: x8_rank(0), xa_prio(prio), /*xc_handle(handle),*/ x10_area(area), x14_24_isActive(true), x14_25_isPlaying(false),
|
||||||
x14_26_looped(looped), x14_27_inArea(true), x14_28_available(false), x14_29_useAcoustics(useAcoustics) {}
|
x14_26_looped(looped), x14_27_inArea(true), x14_28_available(false), x14_29_useAcoustics(useAcoustics) {}
|
||||||
|
@ -91,6 +120,7 @@ public:
|
||||||
CAudioSys::C3DEmitterParmData x24_parmData;
|
CAudioSys::C3DEmitterParmData x24_parmData;
|
||||||
std::shared_ptr<amuse::Emitter> x50_emitterHandle;
|
std::shared_ptr<amuse::Emitter> x50_emitterHandle;
|
||||||
bool x54_ready = true;
|
bool x54_ready = true;
|
||||||
|
float x55_cachedMaxVol;
|
||||||
public:
|
public:
|
||||||
bool IsPlaying() const;
|
bool IsPlaying() const;
|
||||||
void Play();
|
void Play();
|
||||||
|
@ -98,6 +128,10 @@ public:
|
||||||
bool Ready();
|
bool Ready();
|
||||||
ESfxAudibility GetAudible(const zeus::CVector3f&);
|
ESfxAudibility GetAudible(const zeus::CVector3f&);
|
||||||
const std::shared_ptr<amuse::Voice>& GetVoice() const { return x50_emitterHandle->getVoice(); }
|
const std::shared_ptr<amuse::Voice>& GetVoice() const { return x50_emitterHandle->getVoice(); }
|
||||||
|
u16 GetSfxId() const;
|
||||||
|
void UpdateEmitterSilent();
|
||||||
|
void UpdateEmitter();
|
||||||
|
void SetReverb(float rev);
|
||||||
|
|
||||||
const std::shared_ptr<amuse::Emitter>& GetHandle() const { return x50_emitterHandle; }
|
const std::shared_ptr<amuse::Emitter>& GetHandle() const { return x50_emitterHandle; }
|
||||||
|
|
||||||
|
@ -120,6 +154,10 @@ public:
|
||||||
bool Ready();
|
bool Ready();
|
||||||
ESfxAudibility GetAudible(const zeus::CVector3f&) { return ESfxAudibility::Aud3; }
|
ESfxAudibility GetAudible(const zeus::CVector3f&) { return ESfxAudibility::Aud3; }
|
||||||
const std::shared_ptr<amuse::Voice>& GetVoice() const { return x1c_voiceHandle; }
|
const std::shared_ptr<amuse::Voice>& GetVoice() const { return x1c_voiceHandle; }
|
||||||
|
u16 GetSfxId() const;
|
||||||
|
void UpdateEmitterSilent();
|
||||||
|
void UpdateEmitter();
|
||||||
|
void SetReverb(float rev);
|
||||||
|
|
||||||
void SetVolume(s16 vol) { x20_vol = vol; }
|
void SetVolume(s16 vol) { x20_vol = vol; }
|
||||||
|
|
||||||
|
@ -130,14 +168,14 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
static CSfxChannel m_channels[4];
|
static CSfxChannel m_channels[4];
|
||||||
static rstl::reserved_vector<std::shared_ptr<CSfxEmitterWrapper>, 128> m_emitterWrapperPool;
|
|
||||||
static rstl::reserved_vector<std::shared_ptr<CSfxWrapper>, 128> m_wrapperPool;
|
|
||||||
static ESfxChannels m_currentChannel;
|
static ESfxChannels m_currentChannel;
|
||||||
static bool m_doUpdate;
|
static bool m_doUpdate;
|
||||||
static void* m_usedSounds;
|
static void* m_usedSounds;
|
||||||
static bool m_muted;
|
static bool m_muted;
|
||||||
static bool m_auxProcessingEnabled;
|
static bool m_auxProcessingEnabled;
|
||||||
static float m_reverbAmount;
|
static float m_reverbAmount;
|
||||||
|
static EAuxEffect m_activeEffect;
|
||||||
|
static EAuxEffect m_nextEffect;
|
||||||
|
|
||||||
static u16 kMaxPriority;
|
static u16 kMaxPriority;
|
||||||
static u16 kMedPriority;
|
static u16 kMedPriority;
|
||||||
|
@ -146,9 +184,10 @@ public:
|
||||||
|
|
||||||
static bool LoadTranslationTable(CSimplePool* pool, const SObjectTag* tag);
|
static bool LoadTranslationTable(CSimplePool* pool, const SObjectTag* tag);
|
||||||
static bool IsAuxProcessingEnabled() { return m_auxProcessingEnabled; }
|
static bool IsAuxProcessingEnabled() { return m_auxProcessingEnabled; }
|
||||||
static void SetChannel(ESfxChannels) {}
|
static void SetChannel(ESfxChannels);
|
||||||
static void KillAll(ESfxChannels) {}
|
static void KillAll(ESfxChannels) {}
|
||||||
static void TurnOnChannel(ESfxChannels) {}
|
static void TurnOnChannel(ESfxChannels);
|
||||||
|
static void TurnOffChannel(ESfxChannels);
|
||||||
static ESfxChannels GetCurrentChannel() {return m_currentChannel;}
|
static ESfxChannels GetCurrentChannel() {return m_currentChannel;}
|
||||||
static void AddListener(ESfxChannels,
|
static void AddListener(ESfxChannels,
|
||||||
const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||||
|
@ -159,19 +198,26 @@ public:
|
||||||
const zeus::CVector3f& heading, const zeus::CVector3f& up,
|
const zeus::CVector3f& heading, const zeus::CVector3f& up,
|
||||||
u8 vol);
|
u8 vol);
|
||||||
|
|
||||||
|
static void StopSound(const CSfxHandle& handle);
|
||||||
|
static s16 GetRank(CBaseSfxWrapper* sfx);
|
||||||
|
static void ApplyReverb();
|
||||||
|
static float GetReverbAmount();
|
||||||
static void RemoveEmitter(const CSfxHandle&) {}
|
static void RemoveEmitter(const CSfxHandle&) {}
|
||||||
static void PitchBend(const CSfxHandle&, s32) {}
|
static void PitchBend(const CSfxHandle&, s32) {}
|
||||||
static u16 TranslateSFXID(u16);
|
static u16 TranslateSFXID(u16);
|
||||||
static void SfxStop(const CSfxHandle& handle);
|
static void SfxStop(const CSfxHandle& handle);
|
||||||
static CSfxHandle SfxStart(u16 id, float vol, float pan, bool useAcoustics, s16 prio, bool looped, s32 areaId);
|
static CSfxHandle SfxStart(u16 id, float vol, float pan, bool useAcoustics, s16 prio, bool looped, s32 areaId);
|
||||||
static void StopAndRemoveAllEmitters();
|
static void StopAndRemoveAllEmitters();
|
||||||
static void DisableAuxCallbacks();
|
static void DisableAuxCallback();
|
||||||
|
static void EnableAuxCallback();
|
||||||
|
static void PrepareDelayCallback(const amuse::EffectDelayInfo& info);
|
||||||
|
static void PrepareReverbStdCallback(const amuse::EffectReverbStdInfo& info);
|
||||||
|
static void PrepareChorusCallback(const amuse::EffectChorusInfo& info);
|
||||||
|
static void PrepareReverbHiCallback(const amuse::EffectReverbHiInfo& info);
|
||||||
|
static void DisableAuxProcessing();
|
||||||
|
|
||||||
static void Update();
|
static void Update(float dt);
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
private:
|
|
||||||
static std::shared_ptr<CSfxWrapper>* AllocateCSfxWrapper();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using CSfxHandle = CSfxManager::CSfxHandle;
|
using CSfxHandle = CSfxManager::CSfxHandle;
|
||||||
|
|
|
@ -24,7 +24,7 @@ float CCameraManager::sThirdPersonFOV = 60.f;
|
||||||
|
|
||||||
CCameraManager::CCameraManager(TUniqueId curCameraId) : x0_curCameraId(curCameraId)
|
CCameraManager::CCameraManager(TUniqueId curCameraId) : x0_curCameraId(curCameraId)
|
||||||
{
|
{
|
||||||
CSfxManager::AddListener(CSfxManager::ESfxChannels::One, zeus::CVector3f::skZero, zeus::CVector3f::skZero,
|
CSfxManager::AddListener(CSfxManager::ESfxChannels::Game, zeus::CVector3f::skZero, zeus::CVector3f::skZero,
|
||||||
{1.f, 0.f, 0.f}, {0.f, 0.f, 1.f}, 50.f, 50.f, 1000.f, 1, 0x7f);
|
{1.f, 0.f, 0.f}, {0.f, 0.f, 1.f}, 50.f, 50.f, 1000.f, 1, 0x7f);
|
||||||
sAspect = float(gViewport.x8_width / gViewport.xc_height);
|
sAspect = float(gViewport.x8_width / gViewport.xc_height);
|
||||||
sFirstPersonFOV = g_tweakGame->GetFirstPersonFOV();
|
sFirstPersonFOV = g_tweakGame->GetFirstPersonFOV();
|
||||||
|
|
|
@ -18,16 +18,16 @@ CIOWin::EMessageReturn CAudioStateWin::OnMessage(const CArchitectureMessage& msg
|
||||||
const EArchMsgType msgType = msg.GetType();
|
const EArchMsgType msgType = msg.GetType();
|
||||||
if (msgType == EArchMsgType::SetGameState)
|
if (msgType == EArchMsgType::SetGameState)
|
||||||
{
|
{
|
||||||
CSfxManager::KillAll(CSfxManager::ESfxChannels::One);
|
CSfxManager::KillAll(CSfxManager::ESfxChannels::Game);
|
||||||
CSfxManager::TurnOnChannel(CSfxManager::ESfxChannels::One);
|
CSfxManager::TurnOnChannel(CSfxManager::ESfxChannels::Game);
|
||||||
}
|
}
|
||||||
else if (msgType == EArchMsgType::QuitGameplay)
|
else if (msgType == EArchMsgType::QuitGameplay)
|
||||||
{
|
{
|
||||||
if (g_GameState->GetWorldTransitionManager()->GetTransType() == CWorldTransManager::ETransType::Disabled ||
|
if (g_GameState->GetWorldTransitionManager()->GetTransType() == CWorldTransManager::ETransType::Disabled ||
|
||||||
m->GetFlowState() != EFlowState::Zero)
|
m->GetFlowState() != EFlowState::Zero)
|
||||||
{
|
{
|
||||||
CSfxManager::SetChannel(CSfxManager::ESfxChannels::Zero);
|
CSfxManager::SetChannel(CSfxManager::ESfxChannels::Default);
|
||||||
CSfxManager::KillAll(CSfxManager::ESfxChannels::One);
|
CSfxManager::KillAll(CSfxManager::ESfxChannels::Game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return EMessageReturn::Normal;
|
return EMessageReturn::Normal;
|
||||||
|
|
|
@ -39,6 +39,10 @@ CGameArchitectureSupport::CGameArchitectureSupport(CMain& parent, boo::IAudioVoi
|
||||||
|
|
||||||
g_GuiSys = &x44_guiSys;
|
g_GuiSys = &x44_guiSys;
|
||||||
x30_inputGenerator.startScanning();
|
x30_inputGenerator.startScanning();
|
||||||
|
|
||||||
|
CAudioSys::SysSetVolume(0x7f);
|
||||||
|
CAudioSys::SetDefaultVolumeScale(0x75);
|
||||||
|
CAudioSys::SetVolumeScale(CAudioSys::GetDefaultVolumeScale());
|
||||||
CStreamAudioManager::Initialize();
|
CStreamAudioManager::Initialize();
|
||||||
m->ResetGameState();
|
m->ResetGameState();
|
||||||
|
|
||||||
|
@ -267,6 +271,7 @@ bool CMain::Proc()
|
||||||
CGBASupport::GlobalPoll();
|
CGBASupport::GlobalPoll();
|
||||||
x164_archSupport->UpdateTicks();
|
x164_archSupport->UpdateTicks();
|
||||||
x164_archSupport->Update();
|
x164_archSupport->Update();
|
||||||
|
CSfxManager::Update(1.f / 60.f);
|
||||||
CStreamAudioManager::Update(1.f / 60.f);
|
CStreamAudioManager::Update(1.f / 60.f);
|
||||||
return x160_24_finished;
|
return x160_24_finished;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,7 @@ set(WORLD_SOURCES
|
||||||
CScriptMazeNode.hpp CScriptMazeNode.cpp
|
CScriptMazeNode.hpp CScriptMazeNode.cpp
|
||||||
CScriptShadowProjector.hpp CScriptShadowProjector.cpp
|
CScriptShadowProjector.hpp CScriptShadowProjector.cpp
|
||||||
CScriptStreamedMusic.hpp CScriptStreamedMusic.cpp
|
CScriptStreamedMusic.hpp CScriptStreamedMusic.cpp
|
||||||
|
CScriptRoomAcoustics.hpp CScriptRoomAcoustics.cpp
|
||||||
CGrappleParameters.hpp
|
CGrappleParameters.hpp
|
||||||
CActorParameters.hpp
|
CActorParameters.hpp
|
||||||
CLightParameters.hpp
|
CLightParameters.hpp
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
#include "CScriptRoomAcoustics.hpp"
|
||||||
|
#include "TCastTo.hpp"
|
||||||
|
#include "Audio/CSfxManager.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
static TAreaId s_ActiveAcousticsAreaId = kInvalidAreaId;
|
||||||
|
|
||||||
|
CScriptRoomAcoustics::CScriptRoomAcoustics(TUniqueId uid, const std::string& name,
|
||||||
|
const CEntityInfo& info, bool active, u32 volScale,
|
||||||
|
bool revHi, bool revHiDis, float revHiColoration, float revHiMix,
|
||||||
|
float revHiTime, float revHiDamping, float revHiPreDelay, float revHiCrosstalk,
|
||||||
|
bool chorus, float baseDelay, float variation, float period,
|
||||||
|
bool revStd, bool revStdDis, float revStdColoration, float revStdMix,
|
||||||
|
float revStdTime, float revStdDamping, float revStdPreDelay,
|
||||||
|
bool delay, u32 delayL, u32 delayR, u32 delayS,
|
||||||
|
u32 feedbackL, u32 feedbackR, u32 feedbackS,
|
||||||
|
u32 outputL, u32 outputR, u32 outputS)
|
||||||
|
: CEntity(uid, info, active, name), x34_volumeScale(volScale),
|
||||||
|
x38_revHi(revHi), x39_revHiDis(revHiDis),
|
||||||
|
x3c_revHiInfo(revHiColoration, revHiMix, revHiTime, revHiDamping, revHiPreDelay, revHiCrosstalk),
|
||||||
|
x54_chorus(chorus), x58_chorusInfo(baseDelay, variation, period),
|
||||||
|
x64_revStd(revStd), x65_revStdDis(revStdDis),
|
||||||
|
x68_revStdInfo(revStdColoration, revStdMix, revStdTime, revStdDamping, revStdPreDelay),
|
||||||
|
x7c_delay(delay), x80_delayInfo(delayL, delayR, delayS, feedbackL, feedbackR, feedbackS, outputL, outputR, outputS)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CScriptRoomAcoustics::DisableAuxCallbacks()
|
||||||
|
{
|
||||||
|
CSfxManager::DisableAuxProcessing();
|
||||||
|
s_ActiveAcousticsAreaId = kInvalidAreaId;
|
||||||
|
CAudioSys::SetVolumeScale(CAudioSys::GetDefaultVolumeScale());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptRoomAcoustics::EnableAuxCallbacks()
|
||||||
|
{
|
||||||
|
if (!x30_24_active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool applied = true;
|
||||||
|
if (x38_revHi)
|
||||||
|
CSfxManager::PrepareReverbHiCallback(x3c_revHiInfo);
|
||||||
|
else if (x54_chorus)
|
||||||
|
CSfxManager::PrepareChorusCallback(x58_chorusInfo);
|
||||||
|
else if (x64_revStd)
|
||||||
|
CSfxManager::PrepareReverbStdCallback(x68_revStdInfo);
|
||||||
|
else if (x7c_delay)
|
||||||
|
CSfxManager::PrepareDelayCallback(x80_delayInfo);
|
||||||
|
else
|
||||||
|
applied = false;
|
||||||
|
|
||||||
|
if (applied)
|
||||||
|
CAudioSys::SetVolumeScale(x34_volumeScale);
|
||||||
|
s_ActiveAcousticsAreaId = x4_areaId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptRoomAcoustics::Think(float dt, CStateManager& stateMgr)
|
||||||
|
{
|
||||||
|
/* Intentionally empty */
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptRoomAcoustics::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr)
|
||||||
|
{
|
||||||
|
CEntity::AcceptScriptMsg(msg, objId, stateMgr);
|
||||||
|
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case EScriptObjectMessage::Activate:
|
||||||
|
EnableAuxCallbacks();
|
||||||
|
break;
|
||||||
|
case EScriptObjectMessage::Deactivate:
|
||||||
|
if (s_ActiveAcousticsAreaId == x4_areaId)
|
||||||
|
{
|
||||||
|
s_ActiveAcousticsAreaId = kInvalidAreaId;
|
||||||
|
CSfxManager::DisableAuxProcessing();
|
||||||
|
CAudioSys::SetVolumeScale(CAudioSys::GetDefaultVolumeScale());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptRoomAcoustics::Accept(IVisitor& visitor)
|
||||||
|
{
|
||||||
|
visitor.Visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef __URDE_CSCRIPTROOMACOUSTICS_HPP__
|
||||||
|
#define __URDE_CSCRIPTROOMACOUSTICS_HPP__
|
||||||
|
|
||||||
|
#include "CEntity.hpp"
|
||||||
|
#include "amuse/EffectChorus.hpp"
|
||||||
|
#include "amuse/EffectDelay.hpp"
|
||||||
|
#include "amuse/EffectReverb.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
class CScriptRoomAcoustics : public CEntity
|
||||||
|
{
|
||||||
|
u32 x34_volumeScale;
|
||||||
|
|
||||||
|
bool x38_revHi, x39_revHiDis;
|
||||||
|
amuse::EffectReverbHiInfo x3c_revHiInfo;
|
||||||
|
|
||||||
|
bool x54_chorus;
|
||||||
|
amuse::EffectChorusInfo x58_chorusInfo;
|
||||||
|
|
||||||
|
bool x64_revStd, x65_revStdDis;
|
||||||
|
amuse::EffectReverbStdInfo x68_revStdInfo;
|
||||||
|
|
||||||
|
bool x7c_delay;
|
||||||
|
amuse::EffectDelayInfo x80_delayInfo;
|
||||||
|
|
||||||
|
void EnableAuxCallbacks();
|
||||||
|
|
||||||
|
public:
|
||||||
|
CScriptRoomAcoustics(TUniqueId uid, const std::string& name,
|
||||||
|
const CEntityInfo& info, bool active, u32 volScale,
|
||||||
|
bool revHi, bool revHiDis, float revHiColoration, float revHiMix,
|
||||||
|
float revHiTime, float revHiDamping, float revHiPreDelay, float revHiCrosstalk,
|
||||||
|
bool chorus, float baseDelay, float variation, float period,
|
||||||
|
bool revStd, bool revStdDis, float revStdColoration, float revStdMix,
|
||||||
|
float revStdTime, float revStdDamping, float revStdPreDelay,
|
||||||
|
bool delay, u32 delayL, u32 delayR, u32 delayS,
|
||||||
|
u32 feedbackL, u32 feedbackR, u32 feedbackS,
|
||||||
|
u32 outputL, u32 outputR, u32 outputS);
|
||||||
|
void Think(float dt, CStateManager& stateMgr);
|
||||||
|
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr);
|
||||||
|
void Accept(IVisitor& visitor);
|
||||||
|
|
||||||
|
static void DisableAuxCallbacks();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __URDE_CSCRIPTROOMACOUSTICS_HPP__
|
|
@ -61,6 +61,7 @@
|
||||||
#include "MP1/CSpacePirate.hpp"
|
#include "MP1/CSpacePirate.hpp"
|
||||||
#include "CScriptShadowProjector.hpp"
|
#include "CScriptShadowProjector.hpp"
|
||||||
#include "CScriptStreamedMusic.hpp"
|
#include "CScriptStreamedMusic.hpp"
|
||||||
|
#include "CScriptRoomAcoustics.hpp"
|
||||||
#include "CPatternedInfo.hpp"
|
#include "CPatternedInfo.hpp"
|
||||||
#include "CSimplePool.hpp"
|
#include "CSimplePool.hpp"
|
||||||
#include "Collision/CCollidableOBBTreeGroup.hpp"
|
#include "Collision/CCollidableOBBTreeGroup.hpp"
|
||||||
|
@ -1761,7 +1762,44 @@ CEntity* ScriptLoader::LoadFlaahgraTentacle(CStateManager& mgr, CInputStream& in
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadRoomAcoustics(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
CEntity* ScriptLoader::LoadRoomAcoustics(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
||||||
{
|
{
|
||||||
return nullptr;
|
if (!EnsurePropertyCount(propCount, 32, "RoomAcoustics"))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
std::string name = mgr.HashInstanceName(in);
|
||||||
|
bool a = in.readBool();
|
||||||
|
u32 b = in.readUint32Big();
|
||||||
|
bool c = in.readBool();
|
||||||
|
bool d = in.readBool();
|
||||||
|
float e = in.readFloatBig();
|
||||||
|
float f = in.readFloatBig();
|
||||||
|
float g = in.readFloatBig();
|
||||||
|
float h = in.readFloatBig();
|
||||||
|
float i = in.readFloatBig();
|
||||||
|
float j = in.readFloatBig();
|
||||||
|
bool k = in.readBool();
|
||||||
|
float l = in.readFloatBig();
|
||||||
|
float m = in.readFloatBig();
|
||||||
|
float n = in.readFloatBig();
|
||||||
|
bool o = in.readBool();
|
||||||
|
bool p = in.readBool();
|
||||||
|
float q = in.readFloatBig();
|
||||||
|
float r = in.readFloatBig();
|
||||||
|
float s = in.readFloatBig();
|
||||||
|
float t = in.readFloatBig();
|
||||||
|
float u = in.readFloatBig();
|
||||||
|
bool v = in.readBool();
|
||||||
|
u32 w = in.readUint32Big();
|
||||||
|
u32 x = in.readUint32Big();
|
||||||
|
u32 y = in.readUint32Big();
|
||||||
|
u32 z = in.readUint32Big();
|
||||||
|
u32 _a = in.readUint32Big();
|
||||||
|
u32 _b = in.readUint32Big();
|
||||||
|
u32 _c = in.readUint32Big();
|
||||||
|
u32 _d = in.readUint32Big();
|
||||||
|
u32 _e = in.readUint32Big();
|
||||||
|
|
||||||
|
return new CScriptRoomAcoustics(mgr.AllocateUniqueId(), name, info, a, b, c, d, e, f, g, h, i, j,
|
||||||
|
k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, _a, _b, _c, _d, _e);
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadColorModulate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
CEntity* ScriptLoader::LoadColorModulate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
||||||
|
|
2
amuse
2
amuse
|
@ -1 +1 @@
|
||||||
Subproject commit ecd990e94e4b0e6da071cb5f0ada4f65953dda44
|
Subproject commit 2e7345f11d73219d77d345f3c7a039ab68be0e57
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit e84a639ed1c213fa9e50f4f15ea43f8eb391986e
|
Subproject commit df935c31c1f5c21519ed432c128dd7b1541cd972
|
Loading…
Reference in New Issue