diff --git a/src/audio/load.c b/src/audio/load.c index c4d4fe2b..15ae6eb2 100644 --- a/src/audio/load.c +++ b/src/audio/load.c @@ -60,7 +60,6 @@ u8 sSampleDmaReuseQueueHead2; // sh: 0x803505E3 // bss correct up to here -u8 *gAlBankSets; u16 gSequenceCount; #if defined(VERSION_EU) @@ -399,16 +398,15 @@ out2: } uint8_t* load_sequence_immediate(s32 seqId, s32 arg1) { - return GameEngine_LoadSequence(seqId); + return GameEngine_LoadSequence(seqId)->data; } struct CtlEntry* load_banks_immediate(s32 seqId, u8 *outDefaultBank) { u32 bankId; - u16 offset = ((u16 *) gAlBankSets)[seqId]; + struct AudioSequenceData *seqData = ResourceGetDataByName(gSequenceTable[seqId]); struct CtlEntry *output; - for (u8 i = gAlBankSets[offset++]; i != 0; i--) { - bankId = gAlBankSets[offset++]; - output = GameEngine_LoadBank(bankId); + for(size_t i = 0; i < seqData->bankCount; i++) { + output = GameEngine_LoadBank(bankId = seqData->banks[i]); } *outDefaultBank = bankId; return output; @@ -555,8 +553,6 @@ void audio_init() { // Load headers for sounds and sequences gSequenceCount = sizeof(gSequenceTable) / sizeof(gSequenceTable[0]); - gAlBankSets = soundAlloc(&gAudioInitPool, 0xA0); - audio_dma_copy_immediate((uintptr_t) gBankTempData, gAlBankSets, 0xA0); init_sequence_players(); gAudioLoadLock = AUDIO_LOCK_NOT_LOADING; // Should probably contain the sizes of the data banks, but those aren't diff --git a/src/audio/load.h b/src/audio/load.h index 74bd0c11..caa28ded 100644 --- a/src/audio/load.h +++ b/src/audio/load.h @@ -30,7 +30,6 @@ extern struct NotePool gNoteFreeLists; extern OSMesgQueue gCurrAudioFrameDmaQueue; extern u32 gSampleDmaNumListItems; -extern u8 *gAlBankSets; #if defined(VERSION_EU) || defined(VERSION_SH) extern struct AudioBufferParametersEU gAudioBufferParameters; diff --git a/src/audio/seqplayer.c b/src/audio/seqplayer.c index fb053d11..b9d33c8b 100644 --- a/src/audio/seqplayer.c +++ b/src/audio/seqplayer.c @@ -954,6 +954,8 @@ u8 audioString107[] = "Error: Your assignchannel is stolen.\n"; #else // US/JP version with macros to simulate inlining by copt. Edit if you dare. #include "copt/seq_channel_layer_process_script_copt.inc.c" +#include "sequences_table.h" + #endif #ifdef VERSION_SH @@ -1782,9 +1784,8 @@ void sequence_channel_process_script(struct SequenceChannel *seqChannel) { loBits = *(sp38 + gAlBankSets); cmd = gAlBankSets[(s32)sp38 + loBits - cmd]; #else - sp5A = ((u16 *) gAlBankSets)[seqPlayer->seqId]; - loBits = *(sp5A + gAlBankSets); - cmd = gAlBankSets[sp5A + loBits - cmd]; + struct AudioSequenceData *sequence = ResourceGetDataByName(gSequenceTable[seqPlayer->seqId]); + cmd = sequence->banks[cmd]; #endif #ifdef VERSION_SH if (get_bank_or_seq(1, 2, cmd) != NULL) diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index e8ac9ce3..d0ba41bc 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -3,6 +3,7 @@ #include "port/importer/AnimationFactory.h" #include "port/importer/AudioBankFactory.h" #include "port/importer/AudioSampleFactory.h" +#include "port/importer/AudioSequenceFactory.h" #include "audio/internal.h" #include "banks_table.h" #include "sequences_table.h" @@ -22,6 +23,7 @@ GameEngine::GameEngine(){ this->context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::Anim, "Animation", std::make_shared()); this->context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::Bank, "Bank", std::make_shared()); this->context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::Sample, "Sample", std::make_shared()); + this->context->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(LUS::ResourceType::Sequence, "Sequence", std::make_shared()); } void GameEngine::Create(){ @@ -85,28 +87,28 @@ extern "C" void GameEngine_UnloadBank(uint8_t bankId) { } } -extern "C" uint8_t* GameEngine_LoadSequence(uint8_t seqId) { +extern "C" AudioSequenceData* GameEngine_LoadSequence(uint8_t seqId) { auto engine = GameEngine::Instance; if(seqId > (sizeof(gSequenceTable) / sizeof(gSequenceTable[0]))){ return nullptr; } - if(engine->samples.contains(seqId)){ - return engine->samples[seqId]; + if(engine->sequences.contains(seqId)){ + return engine->sequences[seqId]; } - auto sample = static_cast(ResourceGetDataByName(gSequenceTable[seqId])); - engine->samples[seqId] = sample; - return sample; + auto sequences = static_cast(ResourceGetDataByName(gSequenceTable[seqId])); + engine->sequences[seqId] = sequences; + return sequences; } extern "C" uint8_t GameEngine_IsSequenceLoaded(uint8_t seqId) { auto engine = GameEngine::Instance; GameEngine_LoadSequence(seqId); - return engine->samples.contains(seqId); + return engine->sequences.contains(seqId); } extern "C" void GameEngine_UnloadSequence(uint8_t seqId) { auto engine = GameEngine::Instance; - if(engine->samples.contains(seqId)){ - engine->samples.erase(seqId); + if(engine->sequences.contains(seqId)){ + engine->sequences.erase(seqId); } } \ No newline at end of file diff --git a/src/port/Engine.h b/src/port/Engine.h index cbff966c..689f558b 100644 --- a/src/port/Engine.h +++ b/src/port/Engine.h @@ -11,6 +11,7 @@ struct CtlEntry; struct AudioBankSample; +struct AudioSequenceData; class GameEngine { public: @@ -18,7 +19,7 @@ class GameEngine { std::shared_ptr context; std::unordered_map banks; - std::unordered_map samples; + std::unordered_map sequences; GameEngine(); static void Create(); @@ -32,7 +33,7 @@ float GameEngine_GetAspectRatio(); struct CtlEntry* GameEngine_LoadBank(uint8_t bankId); uint8_t GameEngine_IsBankLoaded(uint8_t bankId); void GameEngine_UnloadBank(uint8_t bankId); -struct AudioBankSample* GameEngine_LoadSequence(uint8_t seqId); +struct AudioSequenceData* GameEngine_LoadSequence(uint8_t seqId); uint8_t GameEngine_IsSequenceLoaded(uint8_t seqId); void GameEngine_UnloadSequence(uint8_t seqId); #endif \ No newline at end of file diff --git a/src/port/importer/AudioSequenceFactory.cpp b/src/port/importer/AudioSequenceFactory.cpp new file mode 100644 index 00000000..88496bf8 --- /dev/null +++ b/src/port/importer/AudioSequenceFactory.cpp @@ -0,0 +1,43 @@ +#include "AudioSequenceFactory.h" +#include "port/importer/types/AudioSequence.h" +#include "spdlog/spdlog.h" + +std::shared_ptr CubeOS::AudioSequenceFactory::ReadResource(std::shared_ptr initData, std::shared_ptr reader) { + auto resource = std::make_shared(initData); + std::shared_ptr factory = nullptr; + + switch (resource->GetInitData()->ResourceVersion) { + case 0: + factory = std::make_shared(); + break; + } + + if (factory == nullptr) { + SPDLOG_ERROR("Failed to load AudioBank with version {}", resource->GetInitData()->ResourceVersion); + return nullptr; + } + + factory->ParseFileBinary(reader, resource); + + return resource; +} + +void CubeOS::AudioSequenceFactoryV0::ParseFileBinary(std::shared_ptr reader, std::shared_ptr resource) { + std::shared_ptr bank = std::static_pointer_cast(resource); + + ResourceVersionFactory::ParseFileBinary(reader, bank); + + size_t bankCount = reader->ReadUInt32(); + for(size_t i = 0; i < bankCount; i++){ + bank->banks.push_back(reader->ReadUByte()); + } + + size_t sampleSize = reader->ReadUInt32(); + for(size_t i = 0; i < sampleSize; i++){ + bank->sampleData.push_back(reader->ReadUByte()); + } + + bank->mData.bankCount = bankCount; + bank->mData.banks = bank->banks.data(); + bank->mData.data = bank->sampleData.data(); +} \ No newline at end of file diff --git a/src/port/importer/AudioSequenceFactory.h b/src/port/importer/AudioSequenceFactory.h new file mode 100644 index 00000000..1944094c --- /dev/null +++ b/src/port/importer/AudioSequenceFactory.h @@ -0,0 +1,16 @@ +#pragma once + +#include "ResourceFactory.h" + +namespace CubeOS{ +class AudioSequenceFactory : public LUS::ResourceFactory { + public: + std::shared_ptr + ReadResource(std::shared_ptr initData, std::shared_ptr reader) override; +}; + +class AudioSequenceFactoryV0 : public LUS::ResourceVersionFactory { + public: + void ParseFileBinary(std::shared_ptr reader, std::shared_ptr resource) override; +}; +} diff --git a/src/port/importer/types/AudioSequence.cpp b/src/port/importer/types/AudioSequence.cpp new file mode 100644 index 00000000..6c781c9a --- /dev/null +++ b/src/port/importer/types/AudioSequence.cpp @@ -0,0 +1,11 @@ +#include "AudioSequence.h" + +namespace CubeOS { +AudioSequenceData* AudioSequence::GetPointer() { + return &mData; +} + +size_t AudioSequence::GetPointerSize() { + return sizeof(mData); +} +} \ No newline at end of file diff --git a/src/port/importer/types/AudioSequence.h b/src/port/importer/types/AudioSequence.h new file mode 100644 index 00000000..8f29c92b --- /dev/null +++ b/src/port/importer/types/AudioSequence.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +struct AudioSequenceData { + uint32_t bankCount; + uint8_t* banks; + uint8_t* data; +}; + +namespace CubeOS { + +class AudioSequence : public LUS::Resource { + public: + using Resource::Resource; + + AudioSequence() : Resource(std::shared_ptr()) {} + + AudioSequenceData* GetPointer(); + size_t GetPointerSize(); + + AudioSequenceData mData; + std::vector banks; + std::vector sampleData; +}; +} \ No newline at end of file