summaryrefslogtreecommitdiff
path: root/src/port/Engine.cpp
diff options
context:
space:
mode:
authorKiritoDv <kiritodev01@gmail.com>2024-11-29 11:00:09 -0600
committerKiritoDv <kiritodev01@gmail.com>2024-11-29 11:00:09 -0600
commit78754246074a7377a5d163856caf99eb9dc93539 (patch)
tree515396180dba03581d92d91161426322fa8a8730 /src/port/Engine.cpp
parenta4a03820b4bf2689a945068d736cbe60210baf0b (diff)
Audio is now compiling but crashing yay
Diffstat (limited to 'src/port/Engine.cpp')
-rw-r--r--src/port/Engine.cpp204
1 files changed, 186 insertions, 18 deletions
diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp
index 66b8cd2c3..ed85998c4 100644
--- a/src/port/Engine.cpp
+++ b/src/port/Engine.cpp
@@ -5,6 +5,9 @@
#include "libultraship/src/Context.h"
#include "resource/type/ResourceType.h"
#include "resource/importers/GenericArrayFactory.h"
+#include "resource/importers/AudioBankFactory.h"
+#include "resource/importers/AudioSampleFactory.h"
+#include "resource/importers/AudioSequenceFactory.h"
#include "resource/importers/Vec3fFactory.h"
#include "resource/importers/Vec3sFactory.h"
#include "resource/importers/KartAIFactory.h"
@@ -31,6 +34,8 @@ float gInterpolationStep = 0.0f;
#include <BlobFactory.h>
#include <VertexFactory.h>
#include <LightFactory.h>
+#include "audio/internal.h"
+#include "audio/GameAudio.h"
}
GameEngine* GameEngine::Instance;
@@ -57,7 +62,7 @@ GameEngine::GameEngine() {
}
}
- this->context = Ship::Context::CreateInstance("Spaghettify", "skart64", "spaghettify.cfg.json", OTRFiles, {}, 3);
+ this->context = Ship::Context::CreateInstance("Spaghettify", "skart64", "spaghettify.cfg.json", OTRFiles, {}, 3, {32000, 1024, 2480});
auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
@@ -65,13 +70,18 @@ GameEngine::GameEngine() {
this->context->InitGfxDebugger();
auto loader = context->GetResourceManager()->GetResourceLoader();
+ loader->RegisterResourceFactory(std::make_shared<SM64::AudioBankFactoryV0>(), RESOURCE_FORMAT_BINARY,
+ "AudioBank", static_cast<uint32_t>(SF64::ResourceType::Bank), 0);
+ loader->RegisterResourceFactory(std::make_shared<SM64::AudioSampleFactoryV0>(), RESOURCE_FORMAT_BINARY,
+ "AudioSample", static_cast<uint32_t>(SF64::ResourceType::Sample), 0);
+ loader->RegisterResourceFactory(std::make_shared<SM64::AudioSequenceFactoryV0>(), RESOURCE_FORMAT_BINARY,
+ "AudioSequence", static_cast<uint32_t>(SF64::ResourceType::Sequence), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryVec3fV0>(), RESOURCE_FORMAT_BINARY,
"Vec3f", static_cast<uint32_t>(SF64::ResourceType::Vec3f), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryVec3sV0>(), RESOURCE_FORMAT_BINARY,
"Vec3s", static_cast<uint32_t>(SF64::ResourceType::Vec3s), 0);
- loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryGenericArrayV0>(),
- RESOURCE_FORMAT_BINARY, "GenericArray",
- static_cast<uint32_t>(SF64::ResourceType::GenericArray), 0);
+ loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryGenericArrayV0>(), RESOURCE_FORMAT_BINARY,
+ "GenericArray", static_cast<uint32_t>(SF64::ResourceType::GenericArray), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryTextureV0>(), RESOURCE_FORMAT_BINARY,
"Texture", static_cast<uint32_t>(LUS::ResourceType::Texture), 0);
loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryTextureV1>(), RESOURCE_FORMAT_BINARY,
@@ -92,29 +102,27 @@ GameEngine::GameEngine() {
"KartAI", static_cast<uint32_t>(MK64::ResourceType::KartAI), 0);
loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryCourseVtxV0>(), RESOURCE_FORMAT_BINARY,
"CourseVtx", static_cast<uint32_t>(MK64::ResourceType::CourseVertex), 0);
- loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackSectionsV0>(),
- RESOURCE_FORMAT_BINARY, "TrackSections",
- static_cast<uint32_t>(MK64::ResourceType::TrackSection), 0);
- loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackWaypointsV0>(),
- RESOURCE_FORMAT_BINARY, "Waypoints",
- static_cast<uint32_t>(MK64::ResourceType::Waypoints), 0);
- loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryActorSpawnDataV0>(),
- RESOURCE_FORMAT_BINARY, "SpawnData",
- static_cast<uint32_t>(MK64::ResourceType::SpawnData), 0);
- loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryUnkActorSpawnDataV0>(),
- RESOURCE_FORMAT_BINARY, "UnkSpawnData",
- static_cast<uint32_t>(MK64::ResourceType::UnkSpawnData), 0);
+ loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackSectionsV0>(), RESOURCE_FORMAT_BINARY,
+ "TrackSections", static_cast<uint32_t>(MK64::ResourceType::TrackSection), 0);
+ loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackWaypointsV0>(), RESOURCE_FORMAT_BINARY,
+ "Waypoints", static_cast<uint32_t>(MK64::ResourceType::Waypoints), 0);
+ loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryActorSpawnDataV0>(), RESOURCE_FORMAT_BINARY,
+ "SpawnData", static_cast<uint32_t>(MK64::ResourceType::SpawnData), 0);
+ loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryUnkActorSpawnDataV0>(), RESOURCE_FORMAT_BINARY,
+ "UnkSpawnData", static_cast<uint32_t>(MK64::ResourceType::UnkSpawnData), 0);
}
void GameEngine::Create() {
const auto instance = Instance = new GameEngine();
+ instance->AudioInit();
GameUI::SetupGuiElements();
#if defined(__SWITCH__) || defined(__WIIU__)
CVarRegisterInteger("gControlNav", 1); // always enable controller nav on switch/wii u
#endif
}
-void GameEngine::Destroy() {
+void GameEngine::Destroy(){
+ AudioExit();
}
bool ShouldClearTextureCacheAtEndOfFrame = false;
@@ -161,6 +169,106 @@ void GameEngine::ProcessGfxCommands(Gfx* commands) {
}
}
+// Audio
+
+void GameEngine::HandleAudioThread(){
+ while (audio.running) {
+ {
+ std::unique_lock<std::mutex> Lock(audio.mutex);
+ while (!audio.processing && audio.running) {
+ audio.cv_to_thread.wait(Lock);
+ }
+
+ if (!audio.running) {
+ break;
+ }
+ }
+ std::unique_lock<std::mutex> Lock(audio.mutex);
+
+ int samples_left = AudioPlayerBuffered();
+ u32 num_audio_samples = samples_left < AudioPlayerGetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
+
+ s16 audio_buffer[SAMPLES_PER_FRAME];
+ for (int i = 0; i < NUM_AUDIO_CHANNELS; i++) {
+ create_next_audio_buffer(audio_buffer + i * (num_audio_samples * 2), num_audio_samples);
+ }
+
+ AudioPlayerPlayFrame((u8 *) audio_buffer, 2 * num_audio_samples * 4);
+
+ audio.processing = false;
+ audio.cv_from_thread.notify_one();
+ }
+}
+
+void GameEngine::StartAudioFrame(){
+ {
+ std::unique_lock<std::mutex> Lock(audio.mutex);
+ audio.processing = true;
+ }
+
+ audio.cv_to_thread.notify_one();
+}
+
+void GameEngine::EndAudioFrame(){
+ {
+ std::unique_lock<std::mutex> Lock(audio.mutex);
+ while (audio.processing) {
+ audio.cv_from_thread.wait(Lock);
+ }
+ }
+}
+
+void GameEngine::AudioInit() {
+ const auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager();
+ resourceMgr->LoadDirectory("sound");
+ const auto banksFiles = resourceMgr->GetArchiveManager()->ListFiles("sound/banks/*");
+ const auto sequences_files = resourceMgr->GetArchiveManager()->ListFiles("sound/sequences/*");
+
+ Instance->sequenceTable.resize(512);
+ Instance->audioSequenceTable.resize(512);
+ Instance->banksTable.resize(512);
+
+ for(auto& bank : *banksFiles){
+ auto path = "__OTR__" + bank;
+ const auto ctl = static_cast<CtlEntry *>(ResourceGetDataByName(path.c_str()));
+ this->bankMapTable[bank] = ctl->bankId;
+ SPDLOG_INFO("Loaded bank: {}", bank);
+ }
+
+ for(auto& sequence : *sequences_files){
+ auto path = "__OTR__" + sequence;
+ auto seq = static_cast<AudioSequenceData *>(ResourceGetDataByName(path.c_str()));
+ Instance->sequenceTable[seq->id] = path;
+ SPDLOG_INFO("Loaded sequence: {}", sequence);
+ }
+
+ if (!audio.running) {
+ audio.running = true;
+ audio.thread = std::thread(HandleAudioThread);
+ SPDLOG_INFO("Audio thread started");
+ }
+}
+
+void GameEngine::AudioExit() {
+ {
+ std::unique_lock lock(audio.mutex);
+ audio.running = false;
+ }
+ audio.cv_to_thread.notify_all();
+
+ // Wait until the audio thread quit
+ audio.thread.join();
+}
+
+uint8_t GameEngine::GetBankIdByName(const std::string& name) {
+ if(Instance->bankMapTable.contains(name)){
+ return Instance->bankMapTable[name];
+ }
+ return 0;
+}
+
+// End
+
extern "C" uint32_t GameEngine_GetSampleRate() {
auto player = Ship::Context::GetInstance()->GetAudio()->GetAudioPlayer();
if (player == nullptr) {
@@ -178,7 +286,67 @@ extern "C" uint32_t GameEngine_GetSamplesPerFrame() {
return SAMPLES_PER_FRAME;
}
-// End
+extern "C" CtlEntry* GameEngine_LoadBank(const uint8_t bankId) {
+ const auto engine = GameEngine::Instance;
+
+ if(bankId >= engine->bankMapTable.size()){
+ return nullptr;
+ }
+
+ if(engine->banksTable[bankId] != nullptr){
+ return engine->banksTable[bankId];
+ }
+
+ for(auto& bank : engine->bankMapTable){
+ if(bank.second == bankId){
+ const auto ctl = static_cast<CtlEntry *>(ResourceGetDataByName(("__OTR__" + bank.first).c_str()));
+ engine->banksTable[bankId] = ctl;
+ return ctl;
+ }
+ }
+ return nullptr;
+}
+
+extern "C" uint8_t GameEngine_IsBankLoaded(const uint8_t bankId) {
+ const auto engine = GameEngine::Instance;
+ GameEngine_LoadBank(bankId);
+ return engine->banksTable[bankId] != nullptr;
+}
+
+extern "C" void GameEngine_UnloadBank(const uint8_t bankId) {
+ const auto engine = GameEngine::Instance;
+ engine->banksTable[bankId] = nullptr;
+}
+
+extern "C" AudioSequenceData* GameEngine_LoadSequence(const uint8_t seqId) {
+ auto engine = GameEngine::Instance;
+
+ if(engine->sequenceTable[seqId].empty()){
+ return nullptr;
+ }
+
+ if(engine->audioSequenceTable[seqId] != nullptr){
+ return engine->audioSequenceTable[seqId];
+ }
+
+ auto sequences = static_cast<AudioSequenceData *>(ResourceGetDataByName(engine->sequenceTable[seqId].c_str()));
+ engine->audioSequenceTable[seqId] = sequences;
+ return sequences;
+}
+
+extern "C" uint32_t GameEngine_GetSequenceCount(){
+ auto engine = GameEngine::Instance;
+ return engine->sequenceTable.size();
+}
+
+extern "C" uint8_t GameEngine_IsSequenceLoaded(const uint8_t seqId) {
+ return GameEngine_LoadSequence(seqId) != nullptr;
+}
+
+extern "C" void GameEngine_UnloadSequence(const uint8_t seqId) {
+ const auto engine = GameEngine::Instance;
+ engine->audioSequenceTable[seqId] = nullptr;
+}
extern "C" float GameEngine_GetAspectRatio() {
return gfx_current_dimensions.aspect_ratio;