diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index 54cb04fc..fdb460d6 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -38,6 +38,7 @@ set(SWA_KERNEL_CXX_SOURCES "kernel/xdm.cpp" "kernel/heap.cpp" "kernel/memory.cpp" + "kernel/platform.cpp" "kernel/xam.cpp" "kernel/io/file_system.cpp" ) diff --git a/UnleashedRecomp/framework.h b/UnleashedRecomp/framework.h index a8a87599..e870fec3 100644 --- a/UnleashedRecomp/framework.h +++ b/UnleashedRecomp/framework.h @@ -14,6 +14,13 @@ #define SWA_API extern "C" SWA_DLLIMPORT #endif +#define PROC_ADDRESS(libraryName, procName) \ + GetProcAddress(LoadLibrary(TEXT(libraryName)), procName) + +#define LIB_FUNCTION(returnType, libraryName, procName, ...) \ + typedef returnType _##procName(__VA_ARGS__); \ + _##procName* procName = (_##procName*)PROC_ADDRESS(libraryName, #procName); + template void ByteSwap(T& value) { @@ -66,4 +73,4 @@ constexpr size_t FirstBitLow(TValue value) } return 0; -} \ No newline at end of file +} diff --git a/UnleashedRecomp/kernel/platform.cpp b/UnleashedRecomp/kernel/platform.cpp new file mode 100644 index 00000000..97c072f4 --- /dev/null +++ b/UnleashedRecomp/kernel/platform.cpp @@ -0,0 +1,24 @@ +#include + +#if _WIN32 +LIB_FUNCTION(LONG, "ntdll.dll", RtlGetVersion, PRTL_OSVERSIONINFOW); +#endif + +PlatformVersion GetPlatformVersion() +{ + auto result = PlatformVersion{}; + +#if _WIN32 + OSVERSIONINFOEXW osvi = { 0 }; + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); + + if (RtlGetVersion((PRTL_OSVERSIONINFOW)&osvi) != 0) + return result; + + result.Major = osvi.dwMajorVersion; + result.Minor = osvi.dwMinorVersion; + result.Build = osvi.dwBuildNumber; +#endif + + return result; +} diff --git a/UnleashedRecomp/kernel/platform.h b/UnleashedRecomp/kernel/platform.h new file mode 100644 index 00000000..a03379a1 --- /dev/null +++ b/UnleashedRecomp/kernel/platform.h @@ -0,0 +1,11 @@ +#pragma once + +struct PlatformVersion +{ +public: + uint32_t Major{}; + uint32_t Minor{}; + uint32_t Build{}; +}; + +extern PlatformVersion GetPlatformVersion(); diff --git a/UnleashedRecomp/locale/config_locale.h b/UnleashedRecomp/locale/config_locale.h index 49c644c4..541b0f5e 100644 --- a/UnleashedRecomp/locale/config_locale.h +++ b/UnleashedRecomp/locale/config_locale.h @@ -157,7 +157,7 @@ CONFIG_DEFINE_LOCALE(SEVolume) CONFIG_DEFINE_LOCALE(MusicAttenuation) { - { ELanguage::English, { "Music Attenuation", "Fade out the game's music when external media is playing.\n\nRequires Windows 10 or later." } } + { ELanguage::English, { "Music Attenuation", "Fade out the game's music when external media is playing." } } }; CONFIG_DEFINE_LOCALE(VoiceLanguage) diff --git a/UnleashedRecomp/locale/locale.h b/UnleashedRecomp/locale/locale.h index 220796ea..012b8e11 100644 --- a/UnleashedRecomp/locale/locale.h +++ b/UnleashedRecomp/locale/locale.h @@ -41,6 +41,12 @@ inline static std::unordered_map #include #include +#include #include #if _WIN32 @@ -37,6 +38,8 @@ bool IsExternalAudioPlaying() return session.GetPlaybackInfo().PlaybackStatus() == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing; } + +int AudioPatches::m_isAttenuationSupported = -1; #endif be* GetVolume(bool isMusic = true) @@ -50,6 +53,22 @@ be* GetVolume(bool isMusic = true) return (be*)g_memory.Translate(4 * ((int)isMusic + 0x1C) + ((be*)g_memory.Translate(ppUnkClass->get() + 4))->get()); } +bool AudioPatches::CanAttenuate() +{ +#if _WIN32 + if (m_isAttenuationSupported >= 0) + return m_isAttenuationSupported; + + auto version = GetPlatformVersion(); + + m_isAttenuationSupported = version.Major == 10 && version.Build >= 17763; + + return m_isAttenuationSupported; +#else + return false; +#endif +} + void AudioPatches::Update(float deltaTime) { auto pMusicVolume = GetVolume(); @@ -59,7 +78,7 @@ void AudioPatches::Update(float deltaTime) return; #if _WIN32 - if (Config::MusicAttenuation) + if (Config::MusicAttenuation && CanAttenuate()) { auto time = 1.0f - expf(2.5f * -deltaTime); diff --git a/UnleashedRecomp/patches/audio_patches.h b/UnleashedRecomp/patches/audio_patches.h index 4397c391..e28ec90e 100644 --- a/UnleashedRecomp/patches/audio_patches.h +++ b/UnleashedRecomp/patches/audio_patches.h @@ -2,6 +2,10 @@ class AudioPatches { +protected: + static int m_isAttenuationSupported; + public: + static bool CanAttenuate(); static void Update(float deltaTime); }; diff --git a/UnleashedRecomp/ui/options_menu.cpp b/UnleashedRecomp/ui/options_menu.cpp index cdec9d73..7df3dd5d 100644 --- a/UnleashedRecomp/ui/options_menu.cpp +++ b/UnleashedRecomp/ui/options_menu.cpp @@ -8,6 +8,8 @@ #include #include +#include + constexpr float COMMON_PADDING_POS_Y = 118.0f; constexpr float COMMON_PADDING_POS_X = 30.0f; constexpr float INFO_CONTAINER_POS_X = 870.0f; @@ -859,7 +861,7 @@ static void DrawConfigOptions() DrawConfigOption(rowCount++, yOffset, &Config::SEVolume, true); DrawConfigOption(rowCount++, yOffset, &Config::VoiceLanguage, true); DrawConfigOption(rowCount++, yOffset, &Config::Subtitles, true); - DrawConfigOption(rowCount++, yOffset, &Config::MusicAttenuation, true); // TODO: grey this out for non-Windows platforms. + DrawConfigOption(rowCount++, yOffset, &Config::MusicAttenuation, AudioPatches::CanAttenuate(), &Localise("Options_Desc_OSNotSupported")); DrawConfigOption(rowCount++, yOffset, &Config::WerehogBattleMusic, true); break; case 3: // VIDEO