diff --git a/config/GM8E01_00/splits.txt b/config/GM8E01_00/splits.txt index 861b7b16..843179fb 100644 --- a/config/GM8E01_00/splits.txt +++ b/config/GM8E01_00/splits.txt @@ -4305,9 +4305,6 @@ musyx/runtime/hw_dolphin.c: .bss start:0x805678A0 end:0x80569900 .sbss start:0x805A9B70 end:0x805A9B98 -Dolphin/dummy.c: - .bss start:0x80569900 end:0x80569908 - musyx/runtime/hw_memory.c: .text start:0x803B5134 end:0x803B5188 diff --git a/configure.py b/configure.py index 8e311174..bf3cfcf4 100755 --- a/configure.py +++ b/configure.py @@ -1288,12 +1288,6 @@ config.libs = [ Object(Matching, "musyx/runtime/profile.c"), ], ), - DolphinLib( - "Dummy", - [ - Object(Matching, "Dolphin/dummy.c"), - ], - ), DolphinLib( "dtk", [ diff --git a/include/MetroidPrime/ScriptObjects/CScriptSound.hpp b/include/MetroidPrime/ScriptObjects/CScriptSound.hpp new file mode 100644 index 00000000..b3619e75 --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptSound.hpp @@ -0,0 +1,62 @@ +#ifndef _CSCRIPTSOUND +#define _CSCRIPTSOUND + +#include + +class CScriptSound : public CActor { +public: + CScriptSound(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, const ushort soundId, bool active, const float maxDist, + const float distComp, const float startDelay, const uint minVol, const uint vol, + const uint w3, const uint prio, const uint pan, const uint w6, const bool looped, + const bool nonEmitter, const bool autoStart, const bool occlusionTest, + const bool acoustics, const bool worldSfx, const bool allowDuplicates, + const int pitch); + ~CScriptSound(); + + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; + void PreThink(float dt, CStateManager& mgr) override; + void Think(float dt, CStateManager&) override; + void AddToRenderer(const CFrustumPlanes& planes, CStateManager& mgr); + void Accept(IVisitor& visitor); + + void PlaySound(CStateManager& mgr); + void StopSound(CStateManager& mgr); + + static float GetOccludedVolumeAmount(const CVector3f& pos, const CStateManager& mgr); + + ushort GetSoundId() const { return x100_soundId; } + +private: + static bool sFirstInFrame; + + float xe8_occUpdateTimer; + CSfxHandle xec_sfxHandle; + short xf0_maxVol; + short xf2_maxVolUpd; + short xf4_maxVolUpdDelta; + float xf8_updateTimer; + float xfc_startDelay; + ushort x100_soundId; + float x104_maxDist; + float x108_distComp; + short x10c_minVol; + short x10e_vol; + short x110_; + short x112_prio; + ushort x114_pan; + short x116_; + uint x118_pitch; + bool x11c_24_playRequested : 1; + bool x11c_25_looped : 1; + bool x11c_26_nonEmitter : 1; + bool x11c_27_autoStart : 1; + bool x11c_28_occlusionTest : 1; + bool x11c_29_acoustics : 1; + bool x11c_30_worldSfx : 1; + bool x11c_31_selfFree : 1; + bool x11d_24_allowDuplicates : 1; + bool x11d_25_processedThisFrame : 1; +}; + +#endif // _CSCRIPTSOUND diff --git a/src/MetroidPrime/ScriptObjects/CScriptSound.cpp b/src/MetroidPrime/ScriptObjects/CScriptSound.cpp new file mode 100644 index 00000000..36d33602 --- /dev/null +++ b/src/MetroidPrime/ScriptObjects/CScriptSound.cpp @@ -0,0 +1,180 @@ +#include "Kyoto/Math/CFrustumPlanes.hpp" +#include "MetroidPrime/CActor.hpp" +#include "MetroidPrime/CEntityInfo.hpp" +#include "rstl/math.hpp" +#include + +#include +#include +#include + +#include + +#include + +bool CScriptSound::sFirstInFrame = false; + +CScriptSound::CScriptSound(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, const ushort soundId, bool active, + const float maxDist, const float distComp, const float startDelay, + const uint minVol, const uint vol, const uint w3, const uint prio, + const uint pan, const uint w6, const bool looped, const bool nonEmitter, + const bool autoStart, const bool occlusionTest, const bool acoustics, + const bool worldSfx, const bool allowDuplicates, const int pitch) +: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(kMT_NoStepLogic), + CActorParameters::None(), kInvalidUniqueId) +, xe8_occUpdateTimer(0.f) +, xf0_maxVol(0) +, xf4_maxVolUpdDelta(0) +, xf8_updateTimer(0.f) +, xfc_startDelay(startDelay) +, x100_soundId(CSfxManager::TranslateSFXID(soundId)) +, x104_maxDist(maxDist) +, x108_distComp(distComp) +, x10c_minVol(minVol) +, x10e_vol(vol) +, x110_(w3) +, x112_prio(prio) +, x114_pan(pan) +, x116_(w6) +, x118_pitch(pitch + 8192) +, x11c_24_playRequested(false) +, x11c_25_looped(looped) +, x11c_26_nonEmitter(nonEmitter) +, x11c_27_autoStart(autoStart) +, x11c_28_occlusionTest(occlusionTest) +, x11c_29_acoustics(acoustics) +, x11c_30_worldSfx(worldSfx) +, x11c_31_selfFree(false) +, x11d_24_allowDuplicates(allowDuplicates) +, x11d_25_processedThisFrame(false) { + if (x11c_30_worldSfx && !x11c_26_nonEmitter) { + x11c_30_worldSfx = false; + } + + if (x11c_30_worldSfx && !x11c_25_looped) { + x11c_30_worldSfx = false; + } +} + +void CScriptSound::PreThink(float dt, CStateManager& mgr) { + CEntity::PreThink(dt, mgr); + sFirstInFrame = true; + x11d_25_processedThisFrame = false; +} + +CScriptSound::~CScriptSound() {} + +void CScriptSound::Think(float dt, CStateManager& mgr) { + if (x11c_31_selfFree && (!GetActive() || x11c_25_looped || !x11c_27_autoStart)) { + mgr.DeleteObjectRequest(GetUniqueId()); + return; + } + + if (!GetActive()) { + return; + } + + if (!x11c_25_looped && x11c_27_autoStart && !x11c_24_playRequested && xec_sfxHandle && + !CSfxManager::IsPlaying(xec_sfxHandle)) { + mgr.DeleteObjectRequest(GetUniqueId()); + } + + if (!x11c_26_nonEmitter && xec_sfxHandle) { + if (xf8_updateTimer <= 0.f) { + xf8_updateTimer = 0.25f; + char updateDelta = xf2_maxVolUpd; + CSfxManager::UpdateEmitter(xec_sfxHandle, GetTranslation(), CVector3f::Zero(), updateDelta); + } else { + xf8_updateTimer -= dt; + } + } + + if (xec_sfxHandle && !x11c_26_nonEmitter && x11c_28_occlusionTest) { + if (xe8_occUpdateTimer <= 0.f && sFirstInFrame) { + sFirstInFrame = false; + const float occVol = GetOccludedVolumeAmount(GetTranslation(), mgr); + const short newMaxVol = rstl::max_val(static_cast< short >(occVol * x10e_vol), x10c_minVol); + if (newMaxVol != xf0_maxVol) { + xf0_maxVol = newMaxVol; + const int delta = xf0_maxVol - xf2_maxVolUpd; + xf4_maxVolUpdDelta = delta / 10.5f; + if (xf4_maxVolUpdDelta == 0) { + if (xf2_maxVolUpd < xf0_maxVol) { + xf4_maxVolUpdDelta = 1; + } else { + xf4_maxVolUpdDelta = -1; + } + } + } + } + } +} + +void CScriptSound::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) { + CActor::AcceptScriptMsg(msg, uid, mgr); + + switch (msg) { + case kSM_Registered: { + if (GetActive() && x11c_27_autoStart) { + x11c_24_playRequested = true; + } + x11c_31_selfFree = mgr.IsGeneratingObject(); + } break; + case kSM_Play: { + if (GetActive()) { + PlaySound(mgr); + } + } break; + case kSM_Stop: { + if (GetActive()) { + StopSound(mgr); + } + } break; + case kSM_Deactivate: { + StopSound(mgr); + } break; + case kSM_Activate: { + if (x11c_27_autoStart) { + x11c_24_playRequested = true; + } + } break; + case kSM_Deleted: { + if (!x11c_30_worldSfx) { + StopSound(mgr); + } + } + } +} + +void CScriptSound::PlaySound(CStateManager& mgr) { + TAreaId areaId = GetCurrentAreaId(); + if (!x11d_24_allowDuplicates && xec_sfxHandle) { + if (CSfxManager::IsValidHandle(xec_sfxHandle)) { + return; + } + } + + if (x11d_25_processedThisFrame) { + return; + } + x11d_25_processedThisFrame = true; + if (!x11c_26_nonEmitter) { + const float volume = x11c_30_worldSfx ? 1.f : GetOccludedVolumeAmount(GetTranslation(), mgr); + } +} + +void CScriptSound::StopSound(CStateManager& mgr) { + x11c_24_playRequested = false; + if (x11c_30_worldSfx && x11c_26_nonEmitter) { + mgr.World()->StopGlobalSound(GetSoundId()); + xec_sfxHandle.Clear(); + } else if (xec_sfxHandle) { + CSfxManager::RemoveEmitter(xec_sfxHandle); + xec_sfxHandle.Clear(); + } +} + +void CScriptSound::AddToRenderer(const CFrustumPlanes& planes, CStateManager& mgr) {} + +void CScriptSound::Accept(IVisitor& visitor) { visitor.Visit(*this); }