summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2024-10-16 03:44:09 +0200
committerGitHub <noreply@github.com>2024-10-15 21:44:09 -0400
commitbf79fa17fbc106fd06c545732ad875275821376e (patch)
tree17249f9386cb4e6d174090772ac7fe2cb702a5d9 /src
parent40b04ad7247e1d60ac99f62698e7c04388bfcdfc (diff)
Untangle eggAudio a bit (#61)
* Untangle eggAudio a bit * eggAudioRmtSpeakerMgr with a regswap * Fix eggAudioRmtSpeakerMgr (thanks Cuyler!) * eggAudioUtility with two regswaps
Diffstat (limited to 'src')
-rw-r--r--src/egg/audio/eggAudioArcPlayerMgr.cpp291
-rw-r--r--src/egg/audio/eggAudioHeapMgr.cpp17
-rw-r--r--src/egg/audio/eggAudioMgr.cpp95
-rw-r--r--src/egg/audio/eggAudioRmtSpeakerMgr.cpp145
-rw-r--r--src/egg/audio/eggAudioSystem.cpp52
-rw-r--r--src/egg/audio/eggAudioUtility.cpp92
6 files changed, 686 insertions, 6 deletions
diff --git a/src/egg/audio/eggAudioArcPlayerMgr.cpp b/src/egg/audio/eggAudioArcPlayerMgr.cpp
index 89b4927c..176ac9db 100644
--- a/src/egg/audio/eggAudioArcPlayerMgr.cpp
+++ b/src/egg/audio/eggAudioArcPlayerMgr.cpp
@@ -1,3 +1,292 @@
#include <egg/audio/eggAudioArcPlayerMgr.h>
+#include <egg/audio/eggAudioMgr.h>
+#include <nw4r/snd/snd_SoundPlayer.h>
+#include <rvl/OS/OSCache.h>
-namespace EGG {} // namespace EGG
+namespace EGG {
+
+using namespace nw4r;
+
+ArcPlayer::ArcPlayer(snd::SoundArchivePlayer *player, snd::SoundHeap *heap)
+ : mIsOpeningArchive(false), mIsLoadingGroup(false), mLoadLabelStringData(true), mOpenSndArchive(NULL),
+ mActiveSndArchivePlayer(player), mSoundHeap(heap), mStorage(STORAGE_NONE), mSteamBlocks(1) {}
+
+ArcPlayer::~ArcPlayer() {}
+
+bool ArcPlayer::setSteamBlocks(u32 n) {
+ if (!mOpenSndArchive) {
+ mSteamBlocks = n;
+ return true;
+ }
+
+ return false;
+}
+
+UNKTYPE *ArcPlayer::openArchive(const char *name, snd::SoundHeap *heap, SARC_STORAGE storage) {
+ UNKTYPE *ret = NULL;
+
+ switch (storage) {
+ case STORAGE_DVD: ret = openDvdArchive(name, heap); break;
+
+ case STORAGE_NAND: ret = openNandArchive(name, heap); break;
+
+ default: break;
+ }
+
+ return ret;
+}
+
+UNKTYPE *ArcPlayer::openDvdArchive(const char *name, snd::SoundHeap *heap) {
+ u32 headerBufSize;
+
+ if (!heap) {
+ heap = mSoundHeap;
+ }
+
+ if (mOpenSndArchive) {
+ return mActiveSndArchivePlayer;
+ }
+
+ mOpenSndArchive = &mDvdSndArchive;
+
+ if (mDvdSndArchive.Open(name)) {
+ mIsOpeningArchive = true;
+
+ headerBufSize = mDvdSndArchive.GetHeaderSize();
+ mpHeaderBuf = heap->Alloc(headerBufSize, NULL, (void *)'ARCH');
+ if (!mDvdSndArchive.LoadHeader(mpHeaderBuf, headerBufSize)) {
+ mIsOpeningArchive = false;
+ return NULL;
+ }
+
+ if (mLoadLabelStringData) {
+ headerBufSize = mDvdSndArchive.GetLabelStringDataSize();
+ void *stringDataBuf = heap->Alloc(headerBufSize, NULL, (void *)'ARCL');
+ mDvdSndArchive.LoadLabelStringData(stringDataBuf, headerBufSize);
+ }
+
+ u32 setupBufSize = mActiveSndArchivePlayer->GetRequiredMemSize(mOpenSndArchive);
+ void *setupBuf = heap->Alloc(setupBufSize, NULL, (void *)'APLM');
+
+ u32 strmBufSize = mSteamBlocks * mActiveSndArchivePlayer->GetRequiredStrmBufferSize(mOpenSndArchive);
+ void *strmBuf = heap->Alloc(strmBufSize, NULL, (void *)'APLS');
+
+ if (!mActiveSndArchivePlayer->Setup(mOpenSndArchive, setupBuf, setupBufSize, strmBuf, strmBufSize)) {
+ mIsOpeningArchive = false;
+ return NULL;
+ }
+
+ mStorage = STORAGE_DVD;
+ mIsOpeningArchive = false;
+ return mActiveSndArchivePlayer;
+ }
+
+ return NULL;
+}
+
+UNKTYPE *ArcPlayer::openNandArchive(const char *name, snd::SoundHeap *heap) {
+ u32 headerBufSize;
+
+ if (!heap) {
+ heap = mSoundHeap;
+ }
+
+ if (mOpenSndArchive) {
+ return mActiveSndArchivePlayer;
+ }
+
+ mOpenSndArchive = &mNandSndArchive;
+
+ if (mNandSndArchive.Open(name)) {
+ mIsOpeningArchive = true;
+
+ headerBufSize = mNandSndArchive.GetHeaderSize();
+ void *headerBuf = heap->Alloc(headerBufSize, NULL, NULL);
+ if (!mNandSndArchive.LoadHeader(headerBuf, headerBufSize)) {
+ mIsOpeningArchive = false;
+ return NULL;
+ }
+
+ if (mLoadLabelStringData) {
+ headerBufSize = mNandSndArchive.GetLabelStringDataSize();
+ void *stringDataBuf = heap->Alloc(headerBufSize, NULL, NULL);
+ mNandSndArchive.LoadLabelStringData(stringDataBuf, headerBufSize);
+ }
+
+ u32 setupBufSize = mActiveSndArchivePlayer->GetRequiredMemSize(&mNandSndArchive);
+ void *setupBuf = heap->Alloc(setupBufSize, NULL, NULL);
+
+ u32 strmBufSize = mSteamBlocks * mActiveSndArchivePlayer->GetRequiredStrmBufferSize(&mNandSndArchive);
+ void *strmBuf = heap->Alloc(strmBufSize, NULL, NULL);
+
+ if (!mActiveSndArchivePlayer->Setup(&mNandSndArchive, setupBuf, setupBufSize, strmBuf, strmBufSize)) {
+ mIsOpeningArchive = false;
+ return NULL;
+ }
+
+ mStorage = STORAGE_NAND;
+ mIsOpeningArchive = false;
+ return mActiveSndArchivePlayer;
+ }
+
+ return NULL;
+}
+
+UNKTYPE *ArcPlayer::setupMemoryArchive(const void *work, snd::SoundHeap *heap) {
+ if (!heap) {
+ heap = mSoundHeap;
+ }
+
+ if (mOpenSndArchive) {
+ return mActiveSndArchivePlayer;
+ }
+
+ mOpenSndArchive = &mMemorySndArchive;
+
+ if (mMemorySndArchive.Setup(work)) {
+ mIsOpeningArchive = true;
+
+ u32 neededForMem = mActiveSndArchivePlayer->GetRequiredMemSize(&mMemorySndArchive);
+ void *memBuf = heap->Alloc(neededForMem, NULL, NULL);
+
+ u32 neededForStrm = mSteamBlocks * mActiveSndArchivePlayer->GetRequiredStrmBufferSize(&mMemorySndArchive);
+ void *strmBuf = heap->Alloc(neededForStrm, NULL, NULL);
+
+ if (!mActiveSndArchivePlayer->Setup(&mMemorySndArchive, memBuf, neededForMem, strmBuf, neededForStrm)) {
+ mIsOpeningArchive = false;
+ return NULL;
+ }
+
+ mStorage = STORAGE_MEM;
+ mIsOpeningArchive = false;
+ return mActiveSndArchivePlayer;
+ }
+
+ return NULL;
+}
+
+UNKTYPE ArcPlayer::closeArchive() {
+ if (!mOpenSndArchive) {
+ return;
+ }
+
+ switch (mStorage) {
+ case STORAGE_DVD: mDvdSndArchive.Close(); break;
+
+ case STORAGE_NAND: mNandSndArchive.Close(); break;
+
+ case STORAGE_CNT:
+ case STORAGE_MEM: mMemorySndArchive.Shutdown(); break;
+ }
+
+ mActiveSndArchivePlayer->Shutdown();
+
+ mStorage = STORAGE_NONE;
+ mOpenSndArchive = NULL;
+}
+
+bool ArcPlayer::loadGroup(unsigned int id, snd::SoundHeap *heap, u32 loadBlockSize) {
+ if (mStorage == STORAGE_NAND || mStorage == STORAGE_CNT) {
+ return true;
+ }
+
+ if (!heap) {
+ heap = mSoundHeap;
+ }
+
+ if (mIsOpeningArchive) {
+ return false;
+ } else {
+ if (!mActiveSndArchivePlayer->IsAvailable()) {
+ return false;
+ }
+
+ mIsLoadingGroup = true;
+ UNKWORD result = mActiveSndArchivePlayer->LoadGroup((u32)id, heap, loadBlockSize);
+ mIsLoadingGroup = false;
+ return (result != 0);
+ }
+}
+
+bool ArcPlayer::loadGroup(int id, snd::SoundHeap *heap, u32 loadBlockSize) {
+ if (mStorage == STORAGE_NAND || mStorage == STORAGE_CNT) {
+ return true;
+ }
+
+ if (!heap) {
+ heap = mSoundHeap;
+ }
+
+ if (mIsOpeningArchive) {
+ return false;
+ } else {
+ if (!mActiveSndArchivePlayer->IsAvailable()) {
+ return false;
+ }
+
+ mIsLoadingGroup = true;
+ UNKWORD result = mActiveSndArchivePlayer->LoadGroup((u32)id, heap, loadBlockSize);
+ mIsLoadingGroup = false;
+ return (result != 0);
+ }
+}
+
+bool ArcPlayer::loadGroup(u32 id, snd::SoundHeap *heap, u32 loadBlockSize) {
+ if (mStorage == STORAGE_NAND || mStorage == STORAGE_CNT) {
+ return true;
+ }
+
+ if (!heap) {
+ heap = mSoundHeap;
+ }
+
+ if (mIsOpeningArchive) {
+ return false;
+ } else {
+ if (!mActiveSndArchivePlayer->IsAvailable()) {
+ return false;
+ }
+
+ mIsLoadingGroup = true;
+ bool b = (mActiveSndArchivePlayer->LoadGroup(id, heap, loadBlockSize) != 0);
+ mIsLoadingGroup = false;
+ return b;
+ }
+}
+
+bool ArcPlayer::loadGroup(const char *name, snd::SoundHeap *heap, u32 loadBlockSize) {
+ if (mStorage == STORAGE_NAND || mStorage == STORAGE_CNT) {
+ return true;
+ }
+
+ if (!heap) {
+ heap = mSoundHeap;
+ }
+
+ if (mIsOpeningArchive) {
+ return false;
+ } else {
+ if (!mActiveSndArchivePlayer->IsAvailable()) {
+ return false;
+ }
+
+ mIsLoadingGroup = true;
+ bool b = (mActiveSndArchivePlayer->LoadGroup(name, heap, loadBlockSize) != 0);
+ mIsLoadingGroup = false;
+ return b;
+ }
+}
+
+void ArcPlayer::calc() {
+ if (!mIsOpeningArchive) {
+ mActiveSndArchivePlayer->Update();
+ }
+}
+
+void ArcPlayer::stopAllSound() {
+ for (int i = 0; i < mActiveSndArchivePlayer->GetSoundPlayerCount(); i++) {
+ mActiveSndArchivePlayer->GetSoundPlayer(i).StopAllSound(0);
+ }
+}
+
+} // namespace EGG
diff --git a/src/egg/audio/eggAudioHeapMgr.cpp b/src/egg/audio/eggAudioHeapMgr.cpp
index b9582070..5ca7c5d7 100644
--- a/src/egg/audio/eggAudioHeapMgr.cpp
+++ b/src/egg/audio/eggAudioHeapMgr.cpp
@@ -1,3 +1,18 @@
#include <egg/audio/eggAudioHeapMgr.h>
-namespace EGG {} // namespace EGG
+namespace EGG {
+
+void SoundHeapMgr::createSoundHeap(Allocator *allocator, u32 size) {
+ if (!mSoundHeap.IsValid()) {
+ void *ptr = allocator->alloc(size);
+ if (ptr != nullptr) {
+ mSoundHeap.Create(ptr, size);
+ }
+ }
+}
+
+void SoundHeapMgr::destroySoundHeap() {
+ mSoundHeap.Destroy();
+}
+
+} // namespace EGG
diff --git a/src/egg/audio/eggAudioMgr.cpp b/src/egg/audio/eggAudioMgr.cpp
index 02f2f40f..ab330146 100644
--- a/src/egg/audio/eggAudioMgr.cpp
+++ b/src/egg/audio/eggAudioMgr.cpp
@@ -1,3 +1,96 @@
#include <egg/audio/eggAudioMgr.h>
+#include <nw4r/snd/snd_SoundSystem.h>
+#include <rvl/AI.h>
+#include <rvl/AX.h>
-namespace EGG {} // namespace EGG
+namespace EGG {
+
+IAudioMgr::Arg::Arg() {
+ heap = nullptr;
+ sndThreadPriority = 4;
+ dvdThreadPriority = 3;
+ soundFileName = nullptr;
+ sndThreadStackSize = 0;
+ dvdThreadStackSize = 0;
+ blocks = 1;
+}
+
+SimpleAudioMgr::SimpleAudioMgrArg::SimpleAudioMgrArg() {
+ field_0x1C = 0x8CA000;
+ loadStringLabels = true;
+}
+
+SimpleAudioMgr::SimpleAudioMgr() : ArcPlayer(&mArchivePlayer, getSoundHeap()) {
+ init();
+}
+
+SimpleAudioMgr::~SimpleAudioMgr() {}
+
+void SimpleAudioMgr::initialize(EGG::IAudioMgr::Arg *arg) {
+ AIInit(nullptr);
+ AXInit();
+
+ if (arg->field_0x1C != 0 && arg->heap != nullptr) {
+ Allocator alloc(arg->heap, 0x20);
+ SoundHeapMgr::createSoundHeap(&alloc, arg->field_0x1C);
+ }
+
+ if (arg->sndThreadStackSize == 0 && arg->dvdThreadStackSize == 0) {
+ nw4r::snd::SoundSystem::InitSoundSystem(arg->sndThreadPriority, arg->dvdThreadPriority);
+ } else {
+ if (arg->sndThreadStackSize == 0) {
+ arg->sndThreadStackSize = 0x4000;
+ }
+ if (arg->dvdThreadStackSize == 0) {
+ arg->dvdThreadStackSize = 0x4000;
+ }
+
+ nw4r::snd::SoundSystem::SoundSystemParam param;
+ param.soundThreadPriority = arg->sndThreadPriority;
+ param.soundThreadStackSize = arg->sndThreadStackSize;
+ param.dvdThreadPriority = arg->dvdThreadPriority;
+ param.dvdThreadStackSize = arg->dvdThreadStackSize;
+ u32 size = nw4r::snd::SoundSystem::GetRequiredMemSize(param);
+ void *ptr = SoundHeapMgr::getSoundHeap()->Alloc(size, nullptr, (void*)'SYST');
+ nw4r::snd::SoundSystem::InitSoundSystem(param, ptr, size);
+ }
+ ArcPlayer::setSteamBlocks(arg->blocks);
+ setLoadStringLabels(arg->loadStringLabels);
+ IAudioMgr::field_0x04 = true;
+}
+
+void SimpleAudioMgr::calc() {
+ AudioSystem::calc();
+ if (AudioSystem::isField0x04Eq2()) {
+ ArcPlayer::stopAllSound();
+ }
+ ArcPlayer::calc();
+}
+
+UNKTYPE *SimpleAudioMgr::openDvdArchive(const char *name, nw4r::snd::SoundHeap *heap) {
+ return ArcPlayer::openDvdArchive(name, heap);
+}
+UNKTYPE *SimpleAudioMgr::openNandArchive(const char *name, nw4r::snd::SoundHeap *heap) {
+ return ArcPlayer::openNandArchive(name, heap);
+}
+UNKTYPE *SimpleAudioMgr::setupMemoryArchive(const void *name, nw4r::snd::SoundHeap *heap) {
+ return ArcPlayer::setupMemoryArchive(name, heap);
+}
+
+void SimpleAudioMgr::closeArchive() {
+ ArcPlayer::closeArchive();
+}
+bool SimpleAudioMgr::loadGroup(unsigned int arg, nw4r::snd::SoundHeap *heap, u32 arg2) {
+ return ArcPlayer::loadGroup(arg, heap, arg2);
+}
+bool SimpleAudioMgr::loadGroup(int arg, nw4r::snd::SoundHeap *heap, u32 arg2) {
+ return ArcPlayer::loadGroup(arg, heap, arg2);
+}
+bool SimpleAudioMgr::loadGroup(u32 arg, nw4r::snd::SoundHeap *heap, u32 arg2) {
+ return ArcPlayer::loadGroup(arg, heap, arg2);
+}
+bool SimpleAudioMgr::loadGroup(const char *arg, nw4r::snd::SoundHeap *heap, u32 arg2) {
+ return ArcPlayer::loadGroup(arg, heap, arg2);
+}
+
+} // namespace EGG
diff --git a/src/egg/audio/eggAudioRmtSpeakerMgr.cpp b/src/egg/audio/eggAudioRmtSpeakerMgr.cpp
index 62eeaa21..08695c8e 100644
--- a/src/egg/audio/eggAudioRmtSpeakerMgr.cpp
+++ b/src/egg/audio/eggAudioRmtSpeakerMgr.cpp
@@ -1,3 +1,146 @@
#include <egg/audio/eggAudioRmtSpeakerMgr.h>
+#include <nw4r/snd/snd_SoundSystem.h>
+#include <rvl/OS.h>
-namespace EGG {} // namespace EGG
+namespace EGG {
+
+bool AudioRmtSpeakerMgr::sAudioRmtSpeakerConnectCanncelSw;
+u32 AudioRmtSpeakerMgr::mTaskFinishCount;
+u32 AudioRmtSpeakerMgr::mTaskRequestCount;
+bool AudioRmtSpeakerMgr::sTask;
+
+u8 AudioRmtSpeakerMgr::sAudioRmtSpeakerWpadVolume = 0x58;
+
+AudioRmtSpeakerTask AudioRmtSpeakerMgr::sTasks[0x14];
+
+void AudioRmtSpeakerMgr::setupCallback(s32 arg1, s32 arg2) {
+ if (arg2 == 0) {
+ if (sTasks[mTaskFinishCount].mpCallback != nullptr) {
+ (sTasks[mTaskFinishCount].mpCallback)(arg1, arg2);
+ }
+ sAudioRmtSpeakerWpadVolume = WPADGetSpeakerVolume();
+ } else {
+ fn_804B6D80(arg1, sTasks[mTaskFinishCount].mpCallback);
+ }
+ sTasks[mTaskFinishCount].field_0x01 = true;
+}
+
+void AudioRmtSpeakerMgr::shutdownCallback(s32 arg1, s32 arg2) {
+ if ((u32)arg2 + 1 <= 1) {
+ if (sTasks[mTaskFinishCount].mpCallback != nullptr) {
+ (sTasks[mTaskFinishCount].mpCallback)(arg1, arg2);
+ }
+ } else {
+ fn_804B6DE0(arg1, sTasks[mTaskFinishCount].mpCallback);
+ }
+ sTasks[mTaskFinishCount].field_0x01 = true;
+}
+
+void AudioRmtSpeakerMgr::fn_804B6AF0(s32 i, WPADCallback *pCallback, bool enable) {
+ BOOL intr = OSDisableInterrupts();
+
+ u32 index = mTaskRequestCount;
+ sTasks[index].mChannel = i;
+ sTasks[index].field_0x00 = enable;
+ sTasks[index].mpCallback = pCallback;
+ sTasks[index].field_0x01 = false;
+ if (++mTaskRequestCount >= 0x14) {
+ mTaskRequestCount = 0;
+ }
+
+ OSRestoreInterrupts(intr);
+}
+
+void AudioRmtSpeakerMgr::fn_804B6B80(s32 i, WPADCallback *pCallback) {
+ if (!nw4r::snd::SoundSystem::GetRemoteSpeaker(i).Setup(pCallback)) {
+ fn_804B6AF0(i, pCallback, true);
+ sTasks[mTaskRequestCount].field_0x01 = true;
+ }
+}
+
+void AudioRmtSpeakerMgr::fn_804B6C00(s32 i, WPADCallback *pCallback) {
+ nw4r::snd::SoundSystem::GetRemoteSpeaker(i).Shutdown(pCallback);
+}
+
+void AudioRmtSpeakerMgr::calc() {
+ if (!sTask) {
+ if (mTaskRequestCount != mTaskFinishCount) {
+ if (sTasks[mTaskFinishCount].field_0x00) {
+ fn_804B6B80(sTasks[mTaskFinishCount].mChannel, setupCallback);
+ } else {
+ fn_804B6C00(sTasks[mTaskFinishCount].mChannel, shutdownCallback);
+ }
+ sTask = true;
+ }
+ } else if (sTasks[mTaskFinishCount].field_0x01) {
+ sTask = false;
+ mTaskFinishCount++;
+ if (mTaskFinishCount >= 0x14) {
+ mTaskFinishCount = 0;
+ }
+ }
+}
+
+void AudioRmtSpeakerMgr::setupCallbackDirect(s32 arg1, s32 arg2) {
+ if (arg2 == 0) {
+ sAudioRmtSpeakerWpadVolume = WPADGetSpeakerVolume();
+ } else {
+ fn_804B6B80(arg1, setupCallbackDirect);
+ }
+}
+
+void AudioRmtSpeakerMgr::shutdownCallbackDirect(s32 arg1, s32 arg2) {
+ if (arg2 == -1) {
+ return;
+ }
+ if (arg2 == 0) {
+ return;
+ }
+ fn_804B6C00(arg1, shutdownCallbackDirect);
+}
+
+void AudioRmtSpeakerMgr::fn_804B6D80(s32 i, WPADCallback *pCallback) {
+ WPADDeviceType ty;
+ if (!sAudioRmtSpeakerConnectCanncelSw && WPADProbe(i, &ty) != WPAD_ERR_NO_CONTROLLER) {
+ fn_804B6AF0(i, pCallback, true);
+ }
+}
+
+void AudioRmtSpeakerMgr::fn_804B6DE0(s32 i, WPADCallback *pCallback) {
+ WPADDeviceType ty;
+ if (!sAudioRmtSpeakerConnectCanncelSw) {
+ if (WPADProbe(i, &ty) == WPAD_ERR_NO_CONTROLLER) {
+ if (!nw4r::snd::SoundSystem::GetRemoteSpeaker(i).IsEnabledOutput()) {
+ return;
+ }
+ }
+ fn_804B6AF0(i, pCallback, false);
+ }
+}
+
+void AudioRmtSpeakerMgr::connectAllByForce() {
+ WPADDeviceType ty;
+ sAudioRmtSpeakerConnectCanncelSw = false;
+ for (int i = 0; i < 4; i++) {
+ if (WPADProbe(i, &ty) != WPAD_ERR_NO_CONTROLLER) {
+ fn_804B6B80(i, setupCallbackDirect);
+ }
+ }
+}
+
+void AudioRmtSpeakerMgr::disconnectAllByForce() {
+ WPADDeviceType ty;
+ for (int i = 0; i < 4; i++) {
+ WPADProbe(i, &ty); // ignoring result here
+ if (nw4r::snd::SoundSystem::GetRemoteSpeaker(i).IsAvailable()) {
+ fn_804B6C00(i, shutdownCallbackDirect);
+ }
+ }
+ sAudioRmtSpeakerConnectCanncelSw = true;
+}
+
+u8 AudioRmtSpeakerMgr::getWpadVolume() {
+ return sAudioRmtSpeakerWpadVolume;
+}
+
+} // namespace EGG
diff --git a/src/egg/audio/eggAudioSystem.cpp b/src/egg/audio/eggAudioSystem.cpp
index 12b88463..50d8634d 100644
--- a/src/egg/audio/eggAudioSystem.cpp
+++ b/src/egg/audio/eggAudioSystem.cpp
@@ -1,3 +1,53 @@
#include <egg/audio/eggAudioSystem.h>
+#include <nw4r/snd/snd_SoundSystem.h>
-namespace EGG {} // namespace EGG
+namespace EGG {
+
+AudioSystem *AudioSystem::sInstanse;
+
+AudioSystem::AudioSystem() {
+ field_0x00 = 1.0f;
+ field_0x08 = 0;
+ field_0x04 = 0;
+ sInstanse = this;
+}
+
+AudioSystem::~AudioSystem() {}
+
+void AudioSystem::fn_804B7270(s32 frame) {
+ if (field_0x08 == 0 && field_0x04 == 0) {
+ field_0x00 = nw4r::snd::SoundSystem::GetMasterVolume();
+ nw4r::snd::SoundSystem::SetMasterVolume(0.0f, frame * 16.666667f);
+ field_0x04 = 1;
+ }
+}
+
+void AudioSystem::fn_804B7370() {
+ if (field_0x08 == 0) {
+ nw4r::snd::SoundSystem::SetMasterVolume(field_0x00, 0);
+ field_0x04 = 0;
+ }
+}
+
+void AudioSystem::fn_804B73D0(s32 frame) {
+ if (field_0x08 == 0) {
+ field_0x08 = 1;
+ nw4r::snd::SoundSystem::SetMasterVolume(0.0f, frame * 16.666667f);
+ }
+}
+
+void AudioSystem::calc() {
+ f32 masterVolume = nw4r::snd::SoundSystem::GetMasterVolume();
+
+ if (field_0x08 == 1 && masterVolume == 0.0f) {
+ nw4r::snd::SoundSystem::PrepareReset();
+ nw4r::snd::SoundSystem::WaitForResetReady();
+ field_0x08 = 2;
+ }
+
+ if (field_0x08 != 2 && field_0x04 == 1 && masterVolume == 0.0f) {
+ field_0x04 = 2;
+ }
+}
+
+} // namespace EGG
diff --git a/src/egg/audio/eggAudioUtility.cpp b/src/egg/audio/eggAudioUtility.cpp
index 5fc52e30..95c2b0b9 100644
--- a/src/egg/audio/eggAudioUtility.cpp
+++ b/src/egg/audio/eggAudioUtility.cpp
@@ -1,3 +1,93 @@
+#include <egg/audio/eggAudioRmtSpeakerMgr.h>
#include <egg/audio/eggAudioUtility.h>
+#include <nw4r/snd/snd_SoundPlayer.h>
+#include <nw4r/snd/snd_SoundSystem.h>
-namespace EGG {} // namespace EGG
+namespace EGG {
+
+AudioUtility::MoveParamMgr AudioUtility::sMoveParamMgr;
+
+MultiArcSimpleAudioMgr *AudioUtility::HBM::sMultiArcSimpleAudioMgr;
+SimpleAudioMgr *AudioUtility::HBM::sSimpleAudioMgr;
+void (*AudioUtility::HBM::sHBMEffectRestCallback)();
+void (*AudioUtility::HBM::sHBMUserCallback)(s32, s32);
+u32 AudioUtility::HBM::sHBFadeframe = 0x12;
+
+AudioUtility::MoveParamMgr::MoveParamMgr() {
+ init();
+}
+
+void AudioUtility::MoveParamMgr::init() {
+ nw4r::ut::List_Init(&sMoveParamMgr.mList, 0x28);
+}
+
+void AudioUtility::HBM::init(SimpleAudioMgr *mgr, void (*userCallback)(), u32 frame) {
+ sSimpleAudioMgr = mgr;
+ sHBFadeframe = frame;
+ sHBMEffectRestCallback = userCallback;
+}
+
+void AudioUtility::HBM::enter() {
+ if (sHBMUserCallback != nullptr) {
+ (sHBMUserCallback)(0, 0);
+ }
+
+ // Regswaps
+ u32 i;
+ int j;
+
+ if (sSimpleAudioMgr != nullptr) {
+ for (i = 0; i < sSimpleAudioMgr->getPlayer()->GetSoundPlayerCount(); i++) {
+ sSimpleAudioMgr->getPlayer()->GetSoundPlayer(i).PauseAllSound(true, sHBFadeframe);
+ }
+ }
+
+ if (sMultiArcSimpleAudioMgr != nullptr) {
+ int max = sMultiArcSimpleAudioMgr->field_0x0FC;
+ for (j = 0; j < max; j++) {
+ for (i = 0; i < sMultiArcSimpleAudioMgr->getPlayer(j)->GetSoundPlayerCount(); i++) {
+ sMultiArcSimpleAudioMgr->getPlayer(j)->GetSoundPlayer(i).PauseAllSound(true, sHBFadeframe);
+ }
+ }
+ }
+
+ nw4r::snd::SoundSystem::ClearEffect(nw4r::snd::AUX_A, 0xFA);
+ nw4r::snd::SoundSystem::ClearEffect(nw4r::snd::AUX_B, 0xFA);
+ nw4r::snd::SoundSystem::ClearEffect(nw4r::snd::AUX_C, 0xFA);
+ AudioRmtSpeakerMgr::disconnectAllByForce();
+}
+
+void AudioUtility::HBM::exit(bool arg) {
+ if (sHBMUserCallback != nullptr) {
+ (sHBMUserCallback)(true, arg);
+ }
+
+ if (arg) {
+ // Regswaps
+ u32 i;
+ int j;
+
+ if (sSimpleAudioMgr != nullptr) {
+ for (i = 0; i < sSimpleAudioMgr->getPlayer()->GetSoundPlayerCount(); i++) {
+ sSimpleAudioMgr->getPlayer()->GetSoundPlayer(i).PauseAllSound(false, sHBFadeframe);
+ }
+ }
+
+ if (sMultiArcSimpleAudioMgr != nullptr) {
+ int max = sMultiArcSimpleAudioMgr->field_0x0FC;
+ for (j = 0; j < max; j++) {
+ for (i = 0; i < sMultiArcSimpleAudioMgr->getPlayer(j)->GetSoundPlayerCount(); i++) {
+ sMultiArcSimpleAudioMgr->getPlayer(j)->GetSoundPlayer(i).PauseAllSound(false, sHBFadeframe);
+ }
+ }
+ }
+ }
+
+ if (sHBMEffectRestCallback != nullptr) {
+ (sHBMEffectRestCallback)();
+ }
+
+ AudioRmtSpeakerMgr::connectAllByForce();
+}
+
+} // namespace EGG