From 9fb2f26f1b76e0ce7f2126e8b140448506d0ca07 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Tue, 5 Mar 2024 22:21:15 -0500 Subject: [PATCH] tts: use `RawJson` resource + add `SpeechLogger` (#3998) * moved `tts.cpp` away from using `LoadFileRaw` by creating a new `RawJson` resource type * added `SpeechLogger` --- .../speechsynthesizer/SpeechLogger.cpp | 16 +++++++++ .../speechsynthesizer/SpeechLogger.h | 17 +++++++++ .../speechsynthesizer/SpeechSynthesizer.h | 2 ++ soh/soh/Enhancements/tts/tts.cpp | 35 +++++++++---------- soh/soh/OTRGlobals.cpp | 5 +++ soh/soh/resource/importer/RawJsonFactory.cpp | 19 ++++++++++ soh/soh/resource/importer/RawJsonFactory.h | 11 ++++++ soh/soh/resource/type/RawJson.cpp | 14 ++++++++ soh/soh/resource/type/RawJson.h | 20 +++++++++++ soh/soh/resource/type/SohResourceType.h | 1 + 10 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 soh/soh/Enhancements/speechsynthesizer/SpeechLogger.cpp create mode 100644 soh/soh/Enhancements/speechsynthesizer/SpeechLogger.h create mode 100644 soh/soh/resource/importer/RawJsonFactory.cpp create mode 100644 soh/soh/resource/importer/RawJsonFactory.h create mode 100644 soh/soh/resource/type/RawJson.cpp create mode 100644 soh/soh/resource/type/RawJson.h diff --git a/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.cpp b/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.cpp new file mode 100644 index 000000000..a47a61d62 --- /dev/null +++ b/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.cpp @@ -0,0 +1,16 @@ +#include "SpeechLogger.h" +#include + +SpeechLogger::SpeechLogger() { +} + +void SpeechLogger::Speak(const char* text, const char* language) { + lusprintf(__FILE__, __LINE__, 2, "Spoken Text (%s): %s", language, text); +} + +bool SpeechLogger::DoInit() { + return true; +} + +void SpeechLogger::DoUninitialize() { +} diff --git a/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.h b/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.h new file mode 100644 index 000000000..3be27945f --- /dev/null +++ b/soh/soh/Enhancements/speechsynthesizer/SpeechLogger.h @@ -0,0 +1,17 @@ +#ifndef SOHSpeechLogger_h +#define SOHSpeechLogger_h + +#include "SpeechSynthesizer.h" + +class SpeechLogger : public SpeechSynthesizer { + public: + SpeechLogger(); + + void Speak(const char* text, const char* language); + + protected: + bool DoInit(void); + void DoUninitialize(void); +}; + +#endif diff --git a/soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h b/soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h index b08aab05c..29d209b5f 100644 --- a/soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h +++ b/soh/soh/Enhancements/speechsynthesizer/SpeechSynthesizer.h @@ -36,3 +36,5 @@ class SpeechSynthesizer { #elif defined(__APPLE__) #include "DarwinSpeechSynthesizer.h" #endif + +#include "SpeechLogger.h" diff --git a/soh/soh/Enhancements/tts/tts.cpp b/soh/soh/Enhancements/tts/tts.cpp index ff78fd0ab..f4b498815 100644 --- a/soh/soh/Enhancements/tts/tts.cpp +++ b/soh/soh/Enhancements/tts/tts.cpp @@ -11,6 +11,8 @@ #include "message_data_static.h" #include "overlays/gamestates/ovl_file_choose/file_choose.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/resource/type/SohResourceType.h" +#include "soh/resource/type/RawJson.h" extern "C" { extern MapData* gMapData; @@ -1037,25 +1039,22 @@ void InitTTSBank() { break; } - auto sceneFile = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw("accessibility/texts/scenes" + languageSuffix); - if (sceneFile != nullptr) { - sceneMap = nlohmann::json::parse(*sceneFile->Buffer.get(), nullptr, true, true); - } + auto initData = std::make_shared(); + initData->Format = RESOURCE_FORMAT_BINARY; + initData->Type = static_cast(SOH::ResourceType::SOH_RawJson); + initData->ResourceVersion = 0; - auto miscFile = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw("accessibility/texts/misc" + languageSuffix); - if (miscFile != nullptr) { - miscMap = nlohmann::json::parse(*miscFile->Buffer.get(), nullptr, true, true); - } - - auto kaleidoFile = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw("accessibility/texts/kaleidoscope" + languageSuffix); - if (kaleidoFile != nullptr) { - kaleidoMap = nlohmann::json::parse(*kaleidoFile->Buffer.get(), nullptr, true, true); - } - - auto fileChooseFile = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw("accessibility/texts/filechoose" + languageSuffix); - if (fileChooseFile != nullptr) { - fileChooseMap = nlohmann::json::parse(*fileChooseFile->Buffer.get(), nullptr, true, true); - } + sceneMap = std::static_pointer_cast( + LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/scenes" + languageSuffix, true, initData))->Data; + + miscMap = std::static_pointer_cast( + LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/misc" + languageSuffix, true, initData))->Data; + + kaleidoMap = std::static_pointer_cast( + LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/kaleidoscope" + languageSuffix, true, initData))->Data; + + fileChooseMap = std::static_pointer_cast( + LUS::Context::GetInstance()->GetResourceManager()->LoadResource("accessibility/texts/filechoose" + languageSuffix, true, initData))->Data; } void RegisterOnSetGameLanguageHook() { diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 61f0e2b93..405335738 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -118,6 +118,7 @@ GameInteractorSail* GameInteractorSail::Instance; #include "soh/resource/importer/SkeletonLimbFactory.h" #include "soh/resource/importer/TextFactory.h" #include "soh/resource/importer/BackgroundFactory.h" +#include "soh/resource/importer/RawJsonFactory.h" #include "soh/config/ConfigUpdaters.h" @@ -341,6 +342,7 @@ OTRGlobals::OTRGlobals() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "AudioSoundFont", static_cast(SOH::ResourceType::SOH_AudioSoundFont), 2); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "AudioSequence", static_cast(SOH::ResourceType::SOH_AudioSequence), 2); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Background", static_cast(SOH::ResourceType::SOH_Background), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "RawJson", static_cast(SOH::ResourceType::SOH_RawJson), 0); gSaveStateMgr = std::make_shared(); gRandomizer = std::make_shared(); @@ -1109,6 +1111,9 @@ extern "C" void InitOTR() { #elif defined(_WIN32) SpeechSynthesizer::Instance = new SAPISpeechSynthesizer(); SpeechSynthesizer::Instance->Init(); +#else + SpeechSynthesizer::Instance = new SpeechLogger(); + SpeechSynthesizer::Instance->Init(); #endif #ifdef ENABLE_REMOTE_CONTROL diff --git a/soh/soh/resource/importer/RawJsonFactory.cpp b/soh/soh/resource/importer/RawJsonFactory.cpp new file mode 100644 index 000000000..4978f6f96 --- /dev/null +++ b/soh/soh/resource/importer/RawJsonFactory.cpp @@ -0,0 +1,19 @@ +#include "soh/resource/importer/RawJsonFactory.h" +#include "soh/resource/type/RawJson.h" +#include "spdlog/spdlog.h" + +namespace SOH { +std::shared_ptr ResourceFactoryBinaryRawJsonV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto rawJson = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + rawJson->DataSize = file->Buffer->size(); + rawJson->Data = nlohmann::json::parse(reader->ReadCString(), nullptr, true, true); + + return rawJson; +} +} // namespace SOH diff --git a/soh/soh/resource/importer/RawJsonFactory.h b/soh/soh/resource/importer/RawJsonFactory.h new file mode 100644 index 000000000..d5fa656b6 --- /dev/null +++ b/soh/soh/resource/importer/RawJsonFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "resource/Resource.h" +#include "resource/ResourceFactoryBinary.h" + +namespace SOH { +class ResourceFactoryBinaryRawJsonV0 : public LUS::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +}; // namespace SOH diff --git a/soh/soh/resource/type/RawJson.cpp b/soh/soh/resource/type/RawJson.cpp new file mode 100644 index 000000000..3022a67ef --- /dev/null +++ b/soh/soh/resource/type/RawJson.cpp @@ -0,0 +1,14 @@ +#include "RawJson.h" + +namespace SOH { +RawJson::RawJson() : Resource(std::shared_ptr()) { +} + +void* RawJson::GetPointer() { + return &Data; +} + +size_t RawJson::GetPointerSize() { + return DataSize * sizeof(char); +} +} // namespace SOH diff --git a/soh/soh/resource/type/RawJson.h b/soh/soh/resource/type/RawJson.h new file mode 100644 index 000000000..47e0323cc --- /dev/null +++ b/soh/soh/resource/type/RawJson.h @@ -0,0 +1,20 @@ +#pragma once + +#include "resource/Resource.h" +#include + +namespace SOH { + +class RawJson : public LUS::Resource { + public: + using Resource::Resource; + + RawJson(); + + void* GetPointer() override; + size_t GetPointerSize() override; + + nlohmann::json Data; + size_t DataSize; +}; +}; // namespace SOH diff --git a/soh/soh/resource/type/SohResourceType.h b/soh/soh/resource/type/SohResourceType.h index fdf39031e..3ef4163fe 100644 --- a/soh/soh/resource/type/SohResourceType.h +++ b/soh/soh/resource/type/SohResourceType.h @@ -17,5 +17,6 @@ enum class ResourceType { SOH_AudioSequence = 0x4F534551, // OSEQ SOH_Background = 0x4F424749, // OBGI SOH_SceneCommand = 0x4F52434D, // ORCM + SOH_RawJson = 0x4A534F4E, // JSON }; } // namespace SOH