From 4f56cf70e959f535756761dd391c2de03d9348f9 Mon Sep 17 00:00:00 2001 From: Kiwi <49212064+kiwi515@users.noreply.github.com> Date: Sat, 24 Jan 2026 12:59:05 -0500 Subject: [PATCH 1/6] temp --- include/Pack/RPAudio.h | 1 + include/Pack/RPAudio/RPSndStaticMgr.h | 63 ++++++++++++++++++++++++ src/Pack/RPAudio/RPSndHomeMenuArcMgr.cpp | 2 +- src/Pack/RPAudio/RPSndStaticMgr.cpp | 44 +++++++++++++++++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 include/Pack/RPAudio/RPSndStaticMgr.h create mode 100644 src/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/RPSndStaticMgr.h b/include/Pack/RPAudio/RPSndStaticMgr.h new file mode 100644 index 00000000..8b3a8368 --- /dev/null +++ b/include/Pack/RPAudio/RPSndStaticMgr.h @@ -0,0 +1,63 @@ +#ifndef RP_AUDIO_SND_STATIC_MGR_H +#define RP_AUDIO_SND_STATIC_MGR_H +#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(); + + void startSe(u32 id, s32 player); + +private: + struct Info { + u8 unk0; + u16 unk2; + u16 unk4; + u32 unk8; + u32 unkC; + u32 unk10; + }; + +private: + //! Active sound handle + nw4r::snd::SoundHandle mSoundHandle; // at 0x5B4 + + Info mInfo[WPAD_MAX_CONTROLLERS]; // at 0x5B8 + + //! Static sound archive asset + 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/RPSndStaticMgr.cpp b/src/Pack/RPAudio/RPSndStaticMgr.cpp new file mode 100644 index 00000000..520e639d --- /dev/null +++ b/src/Pack/RPAudio/RPSndStaticMgr.cpp @@ -0,0 +1,44 @@ +#include + +// asset generated by dtk +#include + +/** + * @brief Constructor + */ +RPSndStaticMgr::RPSndStaticMgr() : EGG::ArcPlayer(NULL) { + for (int i = 0; i < WPAD_MAX_CONTROLLERS; i++) { + mInfo[i].unk0 = 0; + } +} + +/** + * @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() { +// if (!mIsInitialized) { +// return; +// } + +// EGG::ArcPlayer::calc(); +// } From 7c555d094fc0160e23275d37f556ed80bc4082f1 Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sat, 24 Jan 2026 14:41:53 -0500 Subject: [PATCH 2/6] matching --- config/RSPE01_01/symbols.txt | 12 ++-- configure.py | 2 +- include/Pack/RPAudio/RPSndSpeakerMgr.h | 4 +- include/Pack/RPAudio/RPSndStaticMgr.h | 42 +++++++++--- src/Pack/RPAudio/RPSndSpeakerMgr.cpp | 6 +- src/Pack/RPAudio/RPSndStaticMgr.cpp | 95 +++++++++++++++++++++++--- 6 files changed, 130 insertions(+), 31 deletions(-) diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index bc071ac8..4ba1a857 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -8190,11 +8190,11 @@ __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 +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 @@ -18727,7 +18727,7 @@ __vt__14RPSndMoveParam = .data:0x803BAA70; // type:object size:0x18 lbl_803BAA88 = .data:0x803BAA88; // type:object size:0x10 __vt__19RPSndHomeMenuArcMgr = .data:0x803BAA98; // type:object size:0x88 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:0x60 lbl_803C1720 = .data:0x803C1720; // type:object size:0x28 lbl_803C1748 = .data:0x803C1748; // type:object size:0x18 lbl_803C1760 = .data:0x803C1760; // type:object size:0x34 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/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 index 8b3a8368..18b0905b 100644 --- a/include/Pack/RPAudio/RPSndStaticMgr.h +++ b/include/Pack/RPAudio/RPSndStaticMgr.h @@ -36,25 +36,51 @@ class RPSndStaticMgr : public EGG::ArcPlayer { */ 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: - struct Info { - u8 unk0; - u16 unk2; + /** + * @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; - u32 unk8; + //! Player output line flag + u32 playerFlag; // at 0x8 u32 unkC; - u32 unk10; + //! 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 - Info mInfo[WPAD_MAX_CONTROLLERS]; // at 0x5B8 - - //! Static sound archive asset + //! Static sound archive binary (generated by dtk) static u8 sStaticSoundArchive[]; }; diff --git a/src/Pack/RPAudio/RPSndSpeakerMgr.cpp b/src/Pack/RPAudio/RPSndSpeakerMgr.cpp index 11dc8c45..2a0874c0 100644 --- a/src/Pack/RPAudio/RPSndSpeakerMgr.cpp +++ b/src/Pack/RPAudio/RPSndSpeakerMgr.cpp @@ -111,13 +111,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 +129,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 index 520e639d..fb923f10 100644 --- a/src/Pack/RPAudio/RPSndStaticMgr.cpp +++ b/src/Pack/RPAudio/RPSndStaticMgr.cpp @@ -1,6 +1,8 @@ #include -// asset generated by dtk +#include + +// generated by dtk #include /** @@ -8,7 +10,7 @@ */ RPSndStaticMgr::RPSndStaticMgr() : EGG::ArcPlayer(NULL) { for (int i = 0; i < WPAD_MAX_CONTROLLERS; i++) { - mInfo[i].unk0 = 0; + mStartTasks[i].valid = false; } } @@ -32,13 +34,84 @@ bool RPSndStaticMgr::setupArchive() { return success; } -// /** -// * @brief Updates the state of the sound player -// */ -// void RPSndStaticMgr::calc() { -// if (!mIsInitialized) { -// return; -// } +/** + * @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(); -// EGG::ArcPlayer::calc(); -// } + 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()); + + // Remote send configuration is stored in userdata + 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); +} From 9ca25e639707530a20040936ca282d5ecbbc2916 Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sat, 24 Jan 2026 14:42:14 -0500 Subject: [PATCH 3/6] Update symbols.txt --- config/RSPE01_01/symbols.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index 4ba1a857..b2ed5600 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -8188,8 +8188,8 @@ 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 +@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 @@ -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 -__vt__14RPSndStaticMgr = .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 From bb21649b0a03b093f5766590449779e7b3b53ef9 Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sat, 24 Jan 2026 14:44:01 -0500 Subject: [PATCH 4/6] Update RPSndStaticMgr.cpp --- src/Pack/RPAudio/RPSndStaticMgr.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Pack/RPAudio/RPSndStaticMgr.cpp b/src/Pack/RPAudio/RPSndStaticMgr.cpp index fb923f10..cc417318 100644 --- a/src/Pack/RPAudio/RPSndStaticMgr.cpp +++ b/src/Pack/RPAudio/RPSndStaticMgr.cpp @@ -100,8 +100,6 @@ void RPSndStaticMgr::setRemoteSend(u32 playerFlag) { } u32 param = getSoundArchive().GetSoundUserParam(mSoundHandle.GetId()); - - // Remote send configuration is stored in userdata if (!(param & 0xFFFF0000)) { return; } From 2efaf6e3b0cf95f853a00467f3253f6fa7079aaa Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sat, 24 Jan 2026 14:45:00 -0500 Subject: [PATCH 5/6] Update RPSndStaticMgr.cpp --- src/Pack/RPAudio/RPSndStaticMgr.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Pack/RPAudio/RPSndStaticMgr.cpp b/src/Pack/RPAudio/RPSndStaticMgr.cpp index cc417318..9d11ec6f 100644 --- a/src/Pack/RPAudio/RPSndStaticMgr.cpp +++ b/src/Pack/RPAudio/RPSndStaticMgr.cpp @@ -2,6 +2,8 @@ #include +#include + // generated by dtk #include From 678b16864ae062ac7d88122d7ecc98edb707cb25 Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Sat, 24 Jan 2026 14:46:07 -0500 Subject: [PATCH 6/6] fix includes --- include/Pack/RPAudio/RPSndStaticMgr.h | 2 ++ src/Pack/RPAudio/RPSndSpeakerMgr.cpp | 2 ++ src/Pack/RPAudio/RPSndStaticMgr.cpp | 3 +++ 3 files changed, 7 insertions(+) diff --git a/include/Pack/RPAudio/RPSndStaticMgr.h b/include/Pack/RPAudio/RPSndStaticMgr.h index 18b0905b..52ba850d 100644 --- a/include/Pack/RPAudio/RPSndStaticMgr.h +++ b/include/Pack/RPAudio/RPSndStaticMgr.h @@ -4,6 +4,8 @@ #include +#include + #include //! @addtogroup rp_audio diff --git a/src/Pack/RPAudio/RPSndSpeakerMgr.cpp b/src/Pack/RPAudio/RPSndSpeakerMgr.cpp index 2a0874c0..985de535 100644 --- a/src/Pack/RPAudio/RPSndSpeakerMgr.cpp +++ b/src/Pack/RPAudio/RPSndSpeakerMgr.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include diff --git a/src/Pack/RPAudio/RPSndStaticMgr.cpp b/src/Pack/RPAudio/RPSndStaticMgr.cpp index 9d11ec6f..78e9bd7b 100644 --- a/src/Pack/RPAudio/RPSndStaticMgr.cpp +++ b/src/Pack/RPAudio/RPSndStaticMgr.cpp @@ -1,5 +1,8 @@ #include +#include +#include + #include #include