From 92d7c286136e77e84927b23fa2dab7c60628cb6a Mon Sep 17 00:00:00 2001 From: ReimousTH <51449880+ReimousTH@users.noreply.github.com> Date: Mon, 11 Aug 2025 04:14:11 +0300 Subject: [PATCH 1/6] SoundConfig --- MarathonRecomp/api/Marathon.h | 2 + .../api/Sonicteam/AudioEngineXenon.h | 31 +++++++++++ MarathonRecomp/api/Sonicteam/DocMarathonImp.h | 53 ++++++++++++++++++- .../api/Sonicteam/SoX/Audio/IAudioEngine.h | 13 +++++ MarathonRecomp/app.cpp | 4 ++ 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 MarathonRecomp/api/Sonicteam/AudioEngineXenon.h create mode 100644 MarathonRecomp/api/Sonicteam/SoX/Audio/IAudioEngine.h diff --git a/MarathonRecomp/api/Marathon.h b/MarathonRecomp/api/Marathon.h index ebdf1f766..e98ba3f31 100644 --- a/MarathonRecomp/api/Marathon.h +++ b/MarathonRecomp/api/Marathon.h @@ -17,6 +17,7 @@ #include "CSD/Platform/csdTexList.h" #include "Sonicteam/Actor.h" #include "Sonicteam/AppMarathon.h" +#include "Sonicteam/AudioEngineXenon.h" #include "Sonicteam/Camera/CameraMode.h" #include "Sonicteam/Camera/Cameraman.h" #include "Sonicteam/Camera/SonicCamera.h" @@ -48,6 +49,7 @@ #include "Sonicteam/Player/State/Object2.h" #include "Sonicteam/Player/State/TailsContext.h" #include "Sonicteam/SoX/AI/StateMachine.h" +#include "Sonicteam/SoX/Audio/IAudioEngine.h" #include "Sonicteam/SoX/Component.h" #include "Sonicteam/SoX/Engine/Doc.h" #include "Sonicteam/SoX/Engine/DocMode.h" diff --git a/MarathonRecomp/api/Sonicteam/AudioEngineXenon.h b/MarathonRecomp/api/Sonicteam/AudioEngineXenon.h new file mode 100644 index 000000000..68eadd6ea --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/AudioEngineXenon.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include +#include + +namespace Sonicteam +{ + + class AudioEngineXenon : public SoX::Audio::IAudioEngine + { + public: + MARATHON_INSERT_PADDING(8); + be m_Audio; + be m_SoundEffects; + MARATHON_INSERT_PADDING(0x14); + + //Singleton> + static AudioEngineXenon* GetAudioEngine() + { + auto ppAudio = (xpointer*)g_memory.Translate(0x82D37AC8); + if (!ppAudio->ptr.get()) + { + auto pAudio = GuestToHostFunction(sub_824A5C78); + *ppAudio = pAudio; + } + return *ppAudio; + }; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/DocMarathonImp.h b/MarathonRecomp/api/Sonicteam/DocMarathonImp.h index 75b0b6e73..8271b64d3 100644 --- a/MarathonRecomp/api/Sonicteam/DocMarathonImp.h +++ b/MarathonRecomp/api/Sonicteam/DocMarathonImp.h @@ -5,10 +5,61 @@ namespace Sonicteam { + + struct DocSaveFile + { + public: + enum EPISODE + { + EPISODE_SONIC, + EPISODE_SHADOW, + EPISODE_SILVER + //... + }; + static const uint32_t EPISODE_COUNT = 32; + static const uint32_t TRIAL_COUNT = 512; + static const uint32_t GLOBALFLAG_COUNT = 0x2800; + static const uint32_t STRING_SIZE = 0x100; + static const uint32_t STRING_SIZE_SHORT = 0x42; + + MARATHON_INSERT_PADDING(4); + be m_Episode_Lives[EPISODE_COUNT]; + be m_Episode_Rings[EPISODE_COUNT]; + be m_GlobalFlags[GLOBALFLAG_COUNT]; + char m_Episode_Lua[EPISODE_COUNT * STRING_SIZE]; + MARATHON_INSERT_PADDING(EPISODE_COUNT * 0x80); + char m_Episode_Objective[EPISODE_COUNT * STRING_SIZE]; + char m_Episode_Area[EPISODE_COUNT * STRING_SIZE]; + char m_Episode_Terrain[EPISODE_COUNT * STRING_SIZE]; + char m_Episode_SET[EPISODE_COUNT * STRING_SIZE]; + char m_Episode_PATH[EPISODE_COUNT * STRING_SIZE]; + MARATHON_INSERT_PADDING(EPISODE_COUNT * 0x500); + char m_Episode_MST[EPISODE_COUNT * STRING_SIZE]; + MARATHON_INSERT_PADDING(EPISODE_COUNT * 0x24C); + be m_Episode_Progress[EPISODE_COUNT]; + be m_Episode_Year[EPISODE_COUNT]; + uint8_t m_Episode_Month[EPISODE_COUNT]; + uint8_t m_Episode_Day[EPISODE_COUNT]; + uint8_t m_Episode_Hour[EPISODE_COUNT]; + uint8_t m_Episode_Minute[EPISODE_COUNT]; + char m_Episode_Location[EPISODE_COUNT * STRING_SIZE_SHORT]; + be m_Trial_ID[TRIAL_COUNT]; + be m_Trial_Rank[TRIAL_COUNT]; + be m_Trial_Time[TRIAL_COUNT]; + be m_Trial_Score[TRIAL_COUNT]; + be m_Trial_Rings[TRIAL_COUNT]; + bool m_Option_Subtitles; + be m_Option_Music; + be m_Option_Effects; + }; + class DocMarathonImp : public SoX::Engine::Doc { public: MARATHON_INSERT_PADDING(0x74); bool m_VFrame; + MARATHON_INSERT_PADDING(0X2E8); + DocSaveFile m_SaveIn; + DocSaveFile m_SaveOut; }; -} +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Audio/IAudioEngine.h b/MarathonRecomp/api/Sonicteam/SoX/Audio/IAudioEngine.h new file mode 100644 index 000000000..3c2d91732 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Audio/IAudioEngine.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace Sonicteam::SoX::Audio +{ + + class IAudioEngine + { + public: + xpointer m_pVftable; + }; +} diff --git a/MarathonRecomp/app.cpp b/MarathonRecomp/app.cpp index 272522297..47f4fe0d0 100644 --- a/MarathonRecomp/app.cpp +++ b/MarathonRecomp/app.cpp @@ -48,6 +48,10 @@ PPC_FUNC(sub_8262A568) cfg->Width = Video::s_viewportWidth; cfg->Height = Video::s_viewportHeight; + auto pAudio = Sonicteam::AudioEngineXenon::GetAudioEngine(); + pAudio->m_Audio = Config::MasterVolume * Config::MusicVolume; + pAudio->m_SoundEffects = Config::MasterVolume * Config::EffectsVolume; + LOGFN_UTILITY("Changed resolution: {}x{}", cfg->Width.get(), cfg->Height.get()); __imp__sub_8262A568(ctx, base); From eab4863376d5237139b2997f61e1415c5023d669 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 11 Aug 2025 05:38:55 +0100 Subject: [PATCH 2/6] Implement Sonicteam::System::Singleton --- MarathonRecomp/api/Marathon.h | 2 ++ .../api/Sonicteam/AudioEngineXenon.h | 22 +++++-------------- .../api/Sonicteam/SoX/Audio/IAudioEngine.h | 1 - .../api/Sonicteam/System/CreateStatic.h | 14 ++++++++++++ .../api/Sonicteam/System/Singleton.h | 21 ++++++++++++++++++ MarathonRecomp/app.cpp | 6 ++--- 6 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 MarathonRecomp/api/Sonicteam/System/CreateStatic.h create mode 100644 MarathonRecomp/api/Sonicteam/System/Singleton.h diff --git a/MarathonRecomp/api/Marathon.h b/MarathonRecomp/api/Marathon.h index e98ba3f31..ec5ec14c8 100644 --- a/MarathonRecomp/api/Marathon.h +++ b/MarathonRecomp/api/Marathon.h @@ -56,6 +56,8 @@ #include "Sonicteam/SoX/Engine/Task.h" #include "Sonicteam/SoX/MessageReceiver.h" #include "Sonicteam/SoX/Object.h" +#include "Sonicteam/System/CreateStatic.h" +#include "Sonicteam/System/Singleton.h" #include "Sonicteam/TitleTask.h" #include "boost/smart_ptr/make_shared_object.h" #include "boost/smart_ptr/shared_ptr.h" diff --git a/MarathonRecomp/api/Sonicteam/AudioEngineXenon.h b/MarathonRecomp/api/Sonicteam/AudioEngineXenon.h index 68eadd6ea..f8354eb0f 100644 --- a/MarathonRecomp/api/Sonicteam/AudioEngineXenon.h +++ b/MarathonRecomp/api/Sonicteam/AudioEngineXenon.h @@ -3,29 +3,17 @@ #include #include #include -#include +#include +#include namespace Sonicteam { - - class AudioEngineXenon : public SoX::Audio::IAudioEngine + class AudioEngineXenon : public SoX::Audio::IAudioEngine, public System::Singleton> { public: MARATHON_INSERT_PADDING(8); - be m_Audio; - be m_SoundEffects; + be m_MusicVolume; + be m_EffectsVolume; MARATHON_INSERT_PADDING(0x14); - - //Singleton> - static AudioEngineXenon* GetAudioEngine() - { - auto ppAudio = (xpointer*)g_memory.Translate(0x82D37AC8); - if (!ppAudio->ptr.get()) - { - auto pAudio = GuestToHostFunction(sub_824A5C78); - *ppAudio = pAudio; - } - return *ppAudio; - }; }; } diff --git a/MarathonRecomp/api/Sonicteam/SoX/Audio/IAudioEngine.h b/MarathonRecomp/api/Sonicteam/SoX/Audio/IAudioEngine.h index 3c2d91732..78775fa23 100644 --- a/MarathonRecomp/api/Sonicteam/SoX/Audio/IAudioEngine.h +++ b/MarathonRecomp/api/Sonicteam/SoX/Audio/IAudioEngine.h @@ -4,7 +4,6 @@ namespace Sonicteam::SoX::Audio { - class IAudioEngine { public: diff --git a/MarathonRecomp/api/Sonicteam/System/CreateStatic.h b/MarathonRecomp/api/Sonicteam/System/CreateStatic.h new file mode 100644 index 000000000..76b99ed34 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/System/CreateStatic.h @@ -0,0 +1,14 @@ +#pragma once + +namespace Sonicteam::System +{ + template + class CreateStatic + { + public: + static T* Create() + { + return GuestToHostFunction(TCreator); + } + }; +} diff --git a/MarathonRecomp/api/Sonicteam/System/Singleton.h b/MarathonRecomp/api/Sonicteam/System/Singleton.h new file mode 100644 index 000000000..d20ca4cfb --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/System/Singleton.h @@ -0,0 +1,21 @@ +#pragma once + +namespace Sonicteam::System +{ + template + class Singleton + { + inline static TCreator m_Creator{}; + + public: + static T* GetInstance() + { + auto pInstance = (xpointer*)g_memory.Translate(Ptr); + + if (!pInstance->ptr.get()) + *pInstance = m_Creator.Create(); + + return *pInstance; + } + }; +} diff --git a/MarathonRecomp/app.cpp b/MarathonRecomp/app.cpp index 47f4fe0d0..80b0a7970 100644 --- a/MarathonRecomp/app.cpp +++ b/MarathonRecomp/app.cpp @@ -48,9 +48,9 @@ PPC_FUNC(sub_8262A568) cfg->Width = Video::s_viewportWidth; cfg->Height = Video::s_viewportHeight; - auto pAudio = Sonicteam::AudioEngineXenon::GetAudioEngine(); - pAudio->m_Audio = Config::MasterVolume * Config::MusicVolume; - pAudio->m_SoundEffects = Config::MasterVolume * Config::EffectsVolume; + auto pAudioEngine = Sonicteam::AudioEngineXenon::GetInstance(); + pAudioEngine->m_MusicVolume = Config::MusicVolume * Config::MasterVolume; + pAudioEngine->m_EffectsVolume = Config::EffectsVolume * Config::MasterVolume; LOGFN_UTILITY("Changed resolution: {}x{}", cfg->Width.get(), cfg->Height.get()); From 847213fd68061242a5003abad13e6192b313c393 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 11 Aug 2025 06:11:12 +0100 Subject: [PATCH 3/6] Remove save data struct Not relevant to the PR and doesn't seem to be mapped correctly. --- MarathonRecomp/api/Sonicteam/DocMarathonImp.h | 53 +------------------ 1 file changed, 1 insertion(+), 52 deletions(-) diff --git a/MarathonRecomp/api/Sonicteam/DocMarathonImp.h b/MarathonRecomp/api/Sonicteam/DocMarathonImp.h index 8271b64d3..75b0b6e73 100644 --- a/MarathonRecomp/api/Sonicteam/DocMarathonImp.h +++ b/MarathonRecomp/api/Sonicteam/DocMarathonImp.h @@ -5,61 +5,10 @@ namespace Sonicteam { - - struct DocSaveFile - { - public: - enum EPISODE - { - EPISODE_SONIC, - EPISODE_SHADOW, - EPISODE_SILVER - //... - }; - static const uint32_t EPISODE_COUNT = 32; - static const uint32_t TRIAL_COUNT = 512; - static const uint32_t GLOBALFLAG_COUNT = 0x2800; - static const uint32_t STRING_SIZE = 0x100; - static const uint32_t STRING_SIZE_SHORT = 0x42; - - MARATHON_INSERT_PADDING(4); - be m_Episode_Lives[EPISODE_COUNT]; - be m_Episode_Rings[EPISODE_COUNT]; - be m_GlobalFlags[GLOBALFLAG_COUNT]; - char m_Episode_Lua[EPISODE_COUNT * STRING_SIZE]; - MARATHON_INSERT_PADDING(EPISODE_COUNT * 0x80); - char m_Episode_Objective[EPISODE_COUNT * STRING_SIZE]; - char m_Episode_Area[EPISODE_COUNT * STRING_SIZE]; - char m_Episode_Terrain[EPISODE_COUNT * STRING_SIZE]; - char m_Episode_SET[EPISODE_COUNT * STRING_SIZE]; - char m_Episode_PATH[EPISODE_COUNT * STRING_SIZE]; - MARATHON_INSERT_PADDING(EPISODE_COUNT * 0x500); - char m_Episode_MST[EPISODE_COUNT * STRING_SIZE]; - MARATHON_INSERT_PADDING(EPISODE_COUNT * 0x24C); - be m_Episode_Progress[EPISODE_COUNT]; - be m_Episode_Year[EPISODE_COUNT]; - uint8_t m_Episode_Month[EPISODE_COUNT]; - uint8_t m_Episode_Day[EPISODE_COUNT]; - uint8_t m_Episode_Hour[EPISODE_COUNT]; - uint8_t m_Episode_Minute[EPISODE_COUNT]; - char m_Episode_Location[EPISODE_COUNT * STRING_SIZE_SHORT]; - be m_Trial_ID[TRIAL_COUNT]; - be m_Trial_Rank[TRIAL_COUNT]; - be m_Trial_Time[TRIAL_COUNT]; - be m_Trial_Score[TRIAL_COUNT]; - be m_Trial_Rings[TRIAL_COUNT]; - bool m_Option_Subtitles; - be m_Option_Music; - be m_Option_Effects; - }; - class DocMarathonImp : public SoX::Engine::Doc { public: MARATHON_INSERT_PADDING(0x74); bool m_VFrame; - MARATHON_INSERT_PADDING(0X2E8); - DocSaveFile m_SaveIn; - DocSaveFile m_SaveOut; }; -} +} From 16dd5ec69fafd0f3dccc267ed7e871356b585a06 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 11 Aug 2025 06:18:42 +0100 Subject: [PATCH 4/6] Save audio settings to config on exit --- MarathonRecomp/app.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/MarathonRecomp/app.cpp b/MarathonRecomp/app.cpp index 80b0a7970..857359be1 100644 --- a/MarathonRecomp/app.cpp +++ b/MarathonRecomp/app.cpp @@ -19,6 +19,13 @@ void App::Restart(std::vector restartArgs) void App::Exit() { + // TODO (Hyper): remove this once the new options menu is implemented. + if (auto pAudioEngine = Sonicteam::AudioEngineXenon::GetInstance()) + { + Config::MusicVolume = pAudioEngine->m_MusicVolume; + Config::EffectsVolume = pAudioEngine->m_EffectsVolume; + } + Config::Save(); #ifdef _WIN32 @@ -44,15 +51,15 @@ PPC_FUNC(sub_8262A568) be Height; }; - auto cfg = reinterpret_cast(g_memory.Translate(ctx.r4.u32)); - cfg->Width = Video::s_viewportWidth; - cfg->Height = Video::s_viewportHeight; + auto pRenderConfig = reinterpret_cast(g_memory.Translate(ctx.r4.u32)); + pRenderConfig->Width = Video::s_viewportWidth; + pRenderConfig->Height = Video::s_viewportHeight; auto pAudioEngine = Sonicteam::AudioEngineXenon::GetInstance(); pAudioEngine->m_MusicVolume = Config::MusicVolume * Config::MasterVolume; pAudioEngine->m_EffectsVolume = Config::EffectsVolume * Config::MasterVolume; - LOGFN_UTILITY("Changed resolution: {}x{}", cfg->Width.get(), cfg->Height.get()); + LOGFN_UTILITY("Changed resolution: {}x{}", pRenderConfig->Width.get(), pRenderConfig->Height.get()); __imp__sub_8262A568(ctx, base); From a084c88d58bc63936ebc44cdbc1f6140a97c434b Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 11 Aug 2025 06:19:54 +0100 Subject: [PATCH 5/6] Use original game defaults for volume settings --- MarathonRecomp/user/config_def.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MarathonRecomp/user/config_def.h b/MarathonRecomp/user/config_def.h index d001c4688..0e4371f2e 100644 --- a/MarathonRecomp/user/config_def.h +++ b/MarathonRecomp/user/config_def.h @@ -39,8 +39,8 @@ CONFIG_DEFINE_ENUM("Bindings", SDL_Scancode, Key_RightStickLeft, SDL_SCANCODE_UN CONFIG_DEFINE_ENUM("Bindings", SDL_Scancode, Key_RightStickRight, SDL_SCANCODE_UNKNOWN); CONFIG_DEFINE_LOCALISED("Audio", float, MasterVolume, 1.0f); -CONFIG_DEFINE_LOCALISED("Audio", float, MusicVolume, 1.0f); -CONFIG_DEFINE_LOCALISED("Audio", float, EffectsVolume, 1.0f); +CONFIG_DEFINE_LOCALISED("Audio", float, MusicVolume, 0.6f); +CONFIG_DEFINE_LOCALISED("Audio", float, EffectsVolume, 0.6f); CONFIG_DEFINE_ENUM_LOCALISED("Audio", EChannelConfiguration, ChannelConfiguration, EChannelConfiguration::Stereo); CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false); From 5606864046b2810a9b15bb79ee0f02cbc6416328 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 11 Aug 2025 06:33:19 +0100 Subject: [PATCH 6/6] Fix naming convention --- MarathonRecomp/api/Sonicteam/System/Singleton.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MarathonRecomp/api/Sonicteam/System/Singleton.h b/MarathonRecomp/api/Sonicteam/System/Singleton.h index d20ca4cfb..336e58c18 100644 --- a/MarathonRecomp/api/Sonicteam/System/Singleton.h +++ b/MarathonRecomp/api/Sonicteam/System/Singleton.h @@ -5,7 +5,7 @@ namespace Sonicteam::System template class Singleton { - inline static TCreator m_Creator{}; + inline static TCreator ms_Creator{}; public: static T* GetInstance() @@ -13,7 +13,7 @@ namespace Sonicteam::System auto pInstance = (xpointer*)g_memory.Translate(Ptr); if (!pInstance->ptr.get()) - *pInstance = m_Creator.Create(); + *pInstance = ms_Creator.Create(); return *pInstance; }