From 79893db26d654bdbae0507008b9648afc3e01dde Mon Sep 17 00:00:00 2001 From: Kiwi <49212064+kiwi515@users.noreply.github.com> Date: Sat, 24 Jan 2026 14:46:35 -0500 Subject: [PATCH] RPSndStaticMgr OK (#19) * temp * matching * Update symbols.txt * Update RPSndStaticMgr.cpp * Update RPSndStaticMgr.cpp * fix includes --- config/RSPE01_01/symbols.txt | 22 ++--- configure.py | 2 +- include/Pack/RPAudio.h | 1 + include/Pack/RPAudio/RPSndSpeakerMgr.h | 4 +- include/Pack/RPAudio/RPSndStaticMgr.h | 91 +++++++++++++++++ src/Pack/RPAudio/RPSndHomeMenuArcMgr.cpp | 2 +- src/Pack/RPAudio/RPSndSpeakerMgr.cpp | 8 +- src/Pack/RPAudio/RPSndStaticMgr.cpp | 120 +++++++++++++++++++++++ 8 files changed, 232 insertions(+), 18 deletions(-) create mode 100644 include/Pack/RPAudio/RPSndStaticMgr.h create mode 100644 src/Pack/RPAudio/RPSndStaticMgr.cpp diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index bc071ac8..b2ed5600 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -8188,13 +8188,13 @@ calc__19RPSndHomeMenuArcMgrFv = .text:0x801B93A0; // type:function size:0x18 setupArchive__19RPSndHomeMenuArcMgrFPCv = .text:0x801B93B8; // type:function size:0x54 __dt__19RPSndHomeMenuArcMgrFv = .text:0x801B940C; // type:function size:0x90 __ct__19RPSndHomeMenuArcMgrFv = .text:0x801B949C; // type:function size:0x9C -@240@calc__19RPSndHomeMenuArcMgrFv = .text:0x801B9538; // type:function size:0x8 -@240@__dt__19RPSndHomeMenuArcMgrFv = .text:0x801B9540; // type:function size:0x8 -fn_801B9548 = .text:0x801B9548; // type:function size:0x148 -fn_801B9690 = .text:0x801B9690; // type:function size:0x16C -fn_801B97FC = .text:0x801B97FC; // type:function size:0x54 -fn_801B9850 = .text:0x801B9850; // type:function size:0x68 -fn_801B98B8 = .text:0x801B98B8; // type:function size:0x58 +@240@calc__19RPSndHomeMenuArcMgrFv = .text:0x801B9538; // type:function size:0x8 scope:weak +@240@__dt__19RPSndHomeMenuArcMgrFv = .text:0x801B9540; // type:function size:0x8 scope:weak +startSe__14RPSndStaticMgrFUll = .text:0x801B9548; // type:function size:0x148 +calc__14RPSndStaticMgrFv = .text:0x801B9690; // type:function size:0x16C +setupArchive__14RPSndStaticMgrFv = .text:0x801B97FC; // type:function size:0x54 +__dt__14RPSndStaticMgrFv = .text:0x801B9850; // type:function size:0x68 +__ct__14RPSndStaticMgrFv = .text:0x801B98B8; // type:function size:0x58 fn_801B9910 = .text:0x801B9910; // type:function size:0x1FC fn_801B9B0C = .text:0x801B9B0C; // type:function size:0x298 fn_801B9DA4 = .text:0x801B9DA4; // type:function size:0x11C @@ -18725,9 +18725,9 @@ lbl_803BAA50 = .data:0x803BAA50; // type:object size:0x10 data:string __vt__15RPSndSpeakerMgr = .data:0x803BAA60; // type:object size:0xC __vt__14RPSndMoveParam = .data:0x803BAA70; // type:object size:0x18 lbl_803BAA88 = .data:0x803BAA88; // type:object size:0x10 -__vt__19RPSndHomeMenuArcMgr = .data:0x803BAA98; // type:object size:0x88 +__vt__19RPSndHomeMenuArcMgr = .data:0x803BAA98; // type:object size:0x78 sStaticSoundArchive__14RPSndStaticMgr = .data:0x803BAB20; // type:object size:0x6BA0 align:32 noreloc -lbl_803C16C0 = .data:0x803C16C0; // type:object size:0x60 +__vt__14RPSndStaticMgr = .data:0x803C16C0; // type:object size:0x5C lbl_803C1720 = .data:0x803C1720; // type:object size:0x28 lbl_803C1748 = .data:0x803C1748; // type:object size:0x18 lbl_803C1760 = .data:0x803C1760; // type:object size:0x34 @@ -23733,9 +23733,9 @@ lbl_804C1960 = .sdata2:0x804C1960; // type:object size:0x8 align:8 data:double @10672 = .sdata2:0x804C197C; // type:object size:0x4 scope:local align:4 data:float lbl_804C1980 = .sdata2:0x804C1980; // type:object size:0x8 align:8 data:double lbl_804C1988 = .sdata2:0x804C1988; // type:object size:0x8 align:4 data:float -lbl_804C1990 = .sdata2:0x804C1990; // type:object size:0x4 align:4 data:float +@10717 = .sdata2:0x804C1990; // type:object size:0x4 scope:local align:4 data:float gap_12_804C1994_sdata2 = .sdata2:0x804C1994; // type:object size:0x4 scope:global -lbl_804C1998 = .sdata2:0x804C1998; // type:object size:0x8 align:8 data:double +@10720 = .sdata2:0x804C1998; // type:object size:0x8 scope:local align:8 data:double lbl_804C19A0 = .sdata2:0x804C19A0; // type:object size:0x4 align:4 data:float lbl_804C19A4 = .sdata2:0x804C19A4; // type:object size:0x4 align:4 data:float lbl_804C19A8 = .sdata2:0x804C19A8; // type:object size:0x4 align:4 data:float diff --git a/configure.py b/configure.py index 29ce1bf0..a75f47cd 100755 --- a/configure.py +++ b/configure.py @@ -1221,7 +1221,7 @@ def MatchingFor(*versions): Object(Matching, "Pack/RPAudio/RPSndUtility.cpp"), Object(NonMatching, "Pack/RPAudio/RPSndMoveParam.cpp"), Object(Matching, "Pack/RPAudio/RPSndHomeMenuArcMgr.cpp"), - Object(NonMatching, "Pack/RPAudio/RPSndStaticMgr.cpp"), + Object(Matching, "Pack/RPAudio/RPSndStaticMgr.cpp"), ], }, { diff --git a/include/Pack/RPAudio.h b/include/Pack/RPAudio.h index fcac58f4..27843272 100644 --- a/include/Pack/RPAudio.h +++ b/include/Pack/RPAudio.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #endif diff --git a/include/Pack/RPAudio/RPSndSpeakerMgr.h b/include/Pack/RPAudio/RPSndSpeakerMgr.h index 55301b44..455a8f8b 100644 --- a/include/Pack/RPAudio/RPSndSpeakerMgr.h +++ b/include/Pack/RPAudio/RPSndSpeakerMgr.h @@ -52,12 +52,12 @@ class RPSndSpeakerMgr : public EGG::Disposer { * sound handle * * @param pHandle Sound handle - * @param channelFlag Remote channel output line flags + * @param playerFlag Player output line flags * @param mainOut Main output volume * @param remoteOut Remote output volume * @param muteOut Main output volume when the remote speaker is muted */ - void setRemoteSend(nw4r::snd::SoundHandle* pHandle, u32 channelFlag, + void setRemoteSend(nw4r::snd::SoundHandle* pHandle, u32 playerFlag, f32 mainOut, f32 remoteOut, f32 muteOut); /** diff --git a/include/Pack/RPAudio/RPSndStaticMgr.h b/include/Pack/RPAudio/RPSndStaticMgr.h new file mode 100644 index 00000000..52ba850d --- /dev/null +++ b/include/Pack/RPAudio/RPSndStaticMgr.h @@ -0,0 +1,91 @@ +#ifndef RP_AUDIO_SND_STATIC_MGR_H +#define RP_AUDIO_SND_STATIC_MGR_H +#include + +#include + +#include + +#include + +//! @addtogroup rp_audio +//! @{ + +/** + * @brief Static-lifetime sound archive manager + */ +class RPSndStaticMgr : public EGG::ArcPlayer { +public: + /** + * @brief Constructor + */ + RPSndStaticMgr(); + + /** + * @brief Destructor + */ + virtual ~RPSndStaticMgr(); // at 0x8 + + /** + * @brief Updates the state of the sound player + */ + virtual void calc(); // at 0x34 + + /** + * @brief Mounts the static sound archive + * + * @return Success + */ + bool setupArchive(); + + /** + * @brief Starts a sound effect through the main output and the specified + * player's remote output + * + * @param id Sound effect ID + * @param player Player index + */ + void startSe(u32 id, s32 player); + +private: + /** + * @brief Sound start task + */ + struct StartTask { + //! Whether this task structure is in use + bool valid; // at 0x0 + //! Time-out threshold + u16 timeOut; // at 0x2 + u16 unk4; + //! Player output line flag + u32 playerFlag; // at 0x8 + u32 unkC; + //! Sound ID + u32 id; // at 0x10 + }; + + //! Task time-out threshold + static const int TIMEOUT = 120; + +private: + /** + * @brief Configures the main and remote output volumes for the specified + * sound + * + * @param playerFlag Player output line flags + */ + void setRemoteSend(u32 playerFlag); + +private: + //! Active sound handle + nw4r::snd::SoundHandle mSoundHandle; // at 0x5B4 + //! Sound effect tasks + StartTask mStartTasks[WPAD_MAX_CONTROLLERS]; // at 0x5B8 + + //! Static sound archive binary (generated by dtk) + static u8 sStaticSoundArchive[]; +}; + +//! @} + +#endif diff --git a/src/Pack/RPAudio/RPSndHomeMenuArcMgr.cpp b/src/Pack/RPAudio/RPSndHomeMenuArcMgr.cpp index 1f1d88a1..5599accc 100644 --- a/src/Pack/RPAudio/RPSndHomeMenuArcMgr.cpp +++ b/src/Pack/RPAudio/RPSndHomeMenuArcMgr.cpp @@ -4,7 +4,7 @@ * @brief Constructor */ RPSndHomeMenuArcMgr::RPSndHomeMenuArcMgr() - : EGG::ArcPlayer(&getSoundHeap()), mSoundHandle(), mIsInitialized(false) {} + : EGG::ArcPlayer(&getSoundHeap()), mIsInitialized(false) {} /** * @brief Destructor diff --git a/src/Pack/RPAudio/RPSndSpeakerMgr.cpp b/src/Pack/RPAudio/RPSndSpeakerMgr.cpp index 11dc8c45..985de535 100644 --- a/src/Pack/RPAudio/RPSndSpeakerMgr.cpp +++ b/src/Pack/RPAudio/RPSndSpeakerMgr.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -111,13 +113,13 @@ bool RPSndSpeakerMgr::setEnableSw(s32 chan, bool enable) { * sound handle * * @param pHandle Sound handle - * @param channelFlag Remote channel output line flags + * @param playerFlag Player output line flags * @param mainOut Main output volume * @param remoteOut Remote output volume * @param muteOut Main output volume when the remote speaker is muted */ void RPSndSpeakerMgr::setRemoteSend(nw4r::snd::SoundHandle* pHandle, - u32 channelFlag, f32 mainOut, f32 remoteOut, + u32 playerFlag, f32 mainOut, f32 remoteOut, f32 muteOut) { if (pHandle == NULL) { return; @@ -129,7 +131,7 @@ void RPSndSpeakerMgr::setRemoteSend(nw4r::snd::SoundHandle* pHandle, } u32 remoteOutFlag = - channelFlag == 0 ? 0 : changeBitPlayerToChannel(channelFlag); + playerFlag == 0 ? 0 : changeBitPlayerToChannel(playerFlag); u32 outputFlag = 0; u32 mainOutFlag = 0; diff --git a/src/Pack/RPAudio/RPSndStaticMgr.cpp b/src/Pack/RPAudio/RPSndStaticMgr.cpp new file mode 100644 index 00000000..78e9bd7b --- /dev/null +++ b/src/Pack/RPAudio/RPSndStaticMgr.cpp @@ -0,0 +1,120 @@ +#include + +#include +#include + +#include + +#include + +// generated by dtk +#include + +/** + * @brief Constructor + */ +RPSndStaticMgr::RPSndStaticMgr() : EGG::ArcPlayer(NULL) { + for (int i = 0; i < WPAD_MAX_CONTROLLERS; i++) { + mStartTasks[i].valid = false; + } +} + +/** + * @brief Destructor + */ +RPSndStaticMgr::~RPSndStaticMgr() {} + +/** + * @brief Mounts the static sound archive + * + * @return Success + */ +bool RPSndStaticMgr::setupArchive() { + mSoundHeap = &RP_GET_INSTANCE(RPSndAudioMgr)->getSoundHeap(); + + bool success = setupMemoryArchive( + sStaticSoundArchive, + &RP_GET_INSTANCE(RPSndAudioMgr)->getSoundHeap()) != NULL; + + return success; +} + +/** + * @brief Updates the state of the sound player + */ +void RPSndStaticMgr::calc() { + for (int i = 0; i < WPAD_MAX_CONTROLLERS; i++) { + StartTask& rTask = mStartTasks[i]; + if (!rTask.valid) { + continue; + } + + if (!nw4r::snd::SoundSystem::GetRemoteSpeaker(i).IsEnabledOutput()) { + if (--rTask.timeOut == 0) { + rTask.valid = false; + } + + continue; + } + + getPlayer().StartSound(&mSoundHandle, rTask.id); + setRemoteSend(rTask.playerFlag); + + rTask.valid = false; + } + + EGG::ArcPlayer::calc(); +} + +/** + * @brief Starts a sound effect through the main output and the specified + * player's remote output + * + * @param id Sound effect ID + * @param player Player index + */ +void RPSndStaticMgr::startSe(u32 id, s32 player) { + s32 chan = EGG_GET_INSTANCE(EGG::CoreControllerMgr) + ->getNthController(player) + ->getChannelID(); + + u32 playerFlag = 1 << player; + + if (nw4r::snd::SoundSystem::GetRemoteSpeaker(chan).IsAvailable()) { + getPlayer().StartSound(&mSoundHandle, id); + setRemoteSend(playerFlag); + } else { + mStartTasks[chan].valid = true; + mStartTasks[chan].timeOut = TIMEOUT; + mStartTasks[chan].id = id; + mStartTasks[chan].playerFlag = playerFlag; + mStartTasks[chan].unkC = 60; + mStartTasks[chan].unk4 = 0; + } +} + +/** + * @brief Configures the main and remote output volumes for the specified + * sound + * + * @param playerFlag Player output line flags + */ +void RPSndStaticMgr::setRemoteSend(u32 playerFlag) { + if (!mSoundHandle.IsAttachedSound()) { + return; + } + + u32 param = getSoundArchive().GetSoundUserParam(mSoundHandle.GetId()); + if (!(param & 0xFFFF0000)) { + return; + } + + // clang-format off + f32 mainOut = static_cast(param >> 16 & 0x7F) / WPAD_MAX_SPEAKER_VOLUME; + f32 muteOut = static_cast(param >> 8 & 0x7F) / WPAD_MAX_SPEAKER_VOLUME; + f32 remoteOut = static_cast(param >> 24) / WPAD_MAX_SPEAKER_VOLUME; + // clang-format on + + RP_GET_INSTANCE(RPSndSpeakerMgr) + ->setRemoteSend(&mSoundHandle, playerFlag, mainOut, remoteOut, muteOut); +}