From 0aa41b305dd8964e4575dbefc5608bfe4fe0948c Mon Sep 17 00:00:00 2001 From: sukibaby <163092272+sukibaby@users.noreply.github.com> Date: Sun, 22 Sep 2024 04:19:06 -0700 Subject: [PATCH] Make static vectors of default driver lists Currently we are storing the default driver lists as a macro, and splitting them into RString vectors every time they are needed. This commit changes the macros in `arch_default.h` into vectors of RStrings, so that they do not need to be split each time. I have updated all references where the default driver lists are being called so that the vector is used directly. A new function is added to RageUtil to make a compatible vector of RStrings from user input which may be separated with a comma. RageSoundDriver was refactored to check user input in Preferences.ini against the default driver list, and in case of incorrect spelling or failure, provides a detailed error message (including a list of valid options) in logs so the user can resolve the problem. `fix_bogus_sound_driver_pref` is no longer needed, since we are now telling the user what their valid options are if the user provides an incorrect entry for the `SoundDrivers` preference, instead of silently attempting to guess what the user wanted. Since I think it's rare that someone wants to specify a driver to begin with, we should let them know their exact options if they put something wrong here, instead of silently failing or using an unwanted driver. I tested this on Windows by specifying `DirectSound-sw` in Preferences.ini, and it worked as expected. I also tried putting an unusable value in, and got the error in logs letting me know what my valid driver options were. Of course, input and movies all work as expected too. --- src/GameSoundManager.cpp | 3 +- src/RageSoundManager.cpp | 5 --- src/RageSoundManager.h | 1 - src/RageUtil.cpp | 8 ++++ src/RageUtil.h | 1 + src/arch/InputHandler/InputHandler.cpp | 21 +++++---- src/arch/MovieTexture/MovieTexture.cpp | 13 ++++-- src/arch/Sound/RageSoundDriver.cpp | 60 +++++++++++++++++--------- src/arch/Sound/RageSoundDriver.h | 2 +- src/arch/arch_default.h | 59 ++++++++++++++++++++----- 10 files changed, 118 insertions(+), 55 deletions(-) diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp index fb9ee7cefb..1f4e27938b 100644 --- a/src/GameSoundManager.cpp +++ b/src/GameSoundManager.cpp @@ -913,8 +913,7 @@ LUA_REGISTER_CLASS(GameSoundManager); int LuaFunc_get_sound_driver_list(lua_State* L); int LuaFunc_get_sound_driver_list(lua_State* L) { - std::vector driver_names; - split(RageSoundDriver::GetDefaultSoundDriverList(), ",", driver_names, true); + std::vector driver_names = RageSoundDriver::GetSoundDriverList(); lua_createtable(L, driver_names.size(), 0); for(std::size_t n= 0; n < driver_names.size(); ++n) { diff --git a/src/RageSoundManager.cpp b/src/RageSoundManager.cpp index 42533b4ee8..4080a735bf 100644 --- a/src/RageSoundManager.cpp +++ b/src/RageSoundManager.cpp @@ -63,11 +63,6 @@ void RageSoundManager::low_sample_count_workaround() m_pDriver->low_sample_count_workaround(); } -void RageSoundManager::fix_bogus_sound_driver_pref(RString const& valid_setting) -{ - g_sSoundDrivers.Set(valid_setting); -} - /* * Previously, we went to some lengths to shut down sounds before exiting threads. * The only other thread that actually starts sounds is SOUND. Doing this was ugly; diff --git a/src/RageSoundManager.h b/src/RageSoundManager.h index 72b58ebefe..891222246d 100644 --- a/src/RageSoundManager.h +++ b/src/RageSoundManager.h @@ -46,7 +46,6 @@ public: RageSoundReader *GetLoadedSound( const RString &sPath ); void AddLoadedSound( const RString &sPath, RageSoundReader_Preload *pSound ); - void fix_bogus_sound_driver_pref(RString const& valid_setting); void low_sample_count_workaround(); private: diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index 68ab34d8be..8b196ab11c 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -863,6 +863,14 @@ void split( const std::wstring &sSource, const std::wstring &sDelimitor, std::ve do_split( sSource, sDelimitor, asAddIt, bIgnoreEmpty ); } +std::vector split( const RString& sSource, const char delimiter, const bool bIgnoreEmpty ) +{ + std::vector result; + RString sDelimiter(1, delimiter); // Create an RString from the char delimiter + split(sSource, sDelimiter, result, bIgnoreEmpty); + return result; +} + /* Use: RString str="a,b,c"; diff --git a/src/RageUtil.h b/src/RageUtil.h index 899106867a..8d48641526 100644 --- a/src/RageUtil.h +++ b/src/RageUtil.h @@ -407,6 +407,7 @@ RString GetLanguageNameFromISO639Code( RString sName ); // Splits a RString into an std::vector according the Delimitor. void split( const RString &sSource, const RString &sDelimitor, std::vector& asAddIt, const bool bIgnoreEmpty = true ); void split( const std::wstring &sSource, const std::wstring &sDelimitor, std::vector &asAddIt, const bool bIgnoreEmpty = true ); +std::vector split( const RString &sSource, const char delimiter, const bool bIgnoreEmpty = true ); /* In-place split. */ void split( const RString &sSource, const RString &sDelimitor, int &iBegin, int &iSize, const bool bIgnoreEmpty = true ); diff --git a/src/arch/InputHandler/InputHandler.cpp b/src/arch/InputHandler/InputHandler.cpp index 6a8a9cb371..60d7901db2 100644 --- a/src/arch/InputHandler/InputHandler.cpp +++ b/src/arch/InputHandler/InputHandler.cpp @@ -173,16 +173,16 @@ RString InputHandler::GetLocalizedInputString( const DeviceInput &di ) DriverList InputHandler::m_pDriverList; static LocalizedString INPUT_HANDLERS_EMPTY( "Arch", "Input Handlers cannot be empty." ); -void InputHandler::Create( const RString &drivers_, std::vector &Add ) +void InputHandler::Create( const RString &drivers_, std::vector &add ) { - const RString drivers = drivers_.empty()? RString(DEFAULT_INPUT_DRIVER_LIST):drivers_; - std::vector DriversToTry; - split( drivers, ",", DriversToTry, true ); + const std::vector& driversToTry = drivers_.empty() ? GetDefaultInputDriverList() : split(drivers_, ',', true); - if( DriversToTry.empty() ) - RageException::Throw( "%s", INPUT_HANDLERS_EMPTY.GetValue().c_str() ); + if (driversToTry.empty()) + { + RageException::Throw("%s", INPUT_HANDLERS_EMPTY.GetValue().c_str()); + } - for (RString const &s : DriversToTry) + for (const RString &s : driversToTry) { RageDriver *pDriver = InputHandler::m_pDriverList.Create( s ); if( pDriver == nullptr ) @@ -193,15 +193,14 @@ void InputHandler::Create( const RString &drivers_, std::vector InputHandler *ret = dynamic_cast( pDriver ); DEBUG_ASSERT( ret ); - Add.push_back( ret ); + add.push_back( ret ); } // Always add - Add.push_back( new InputHandler_MonkeyKeyboard ); -// Add.push_back( new InputHandler_NSEvent ); + add.push_back(new InputHandler_MonkeyKeyboard); +// add.push_back(new InputHandler_NSEvent); } - /* * (c) 2003-2004 Glenn Maynard * All rights reserved. diff --git a/src/arch/MovieTexture/MovieTexture.cpp b/src/arch/MovieTexture/MovieTexture.cpp index 157d7176d4..8ac6fa3975 100644 --- a/src/arch/MovieTexture/MovieTexture.cpp +++ b/src/arch/MovieTexture/MovieTexture.cpp @@ -86,11 +86,16 @@ RageMovieTexture *RageMovieTexture::Create( RageTextureID ID ) DumpAVIDebugInfo( ID.filename ); RString sDrivers = g_sMovieDrivers; - if( sDrivers.empty() ) - sDrivers = DEFAULT_MOVIE_DRIVER_LIST; - std::vector DriversToTry; - split( sDrivers, ",", DriversToTry, true ); + + if (sDrivers.empty()) + { + DriversToTry = GetDefaultMovieDriverList(); + } + else + { + DriversToTry = split(sDrivers, ','); + } if( DriversToTry.empty() ) RageException::Throw( "%s", MOVIE_DRIVERS_EMPTY.GetValue().c_str() ); diff --git a/src/arch/Sound/RageSoundDriver.cpp b/src/arch/Sound/RageSoundDriver.cpp index 3591c47e40..ee78024b79 100644 --- a/src/arch/Sound/RageSoundDriver.cpp +++ b/src/arch/Sound/RageSoundDriver.cpp @@ -9,46 +9,66 @@ #include #include +namespace +{ + void WarnUserAboutBadSoundDriverEntry() + { + #if defined(_WIN32) + LOG->Trace(" - Valid sound drivers for your OS are: WaveOut, DirectSound-sw, WDMKS, Null"); + #elif defined(MACOSX) + LOG->Trace(" - Valid sound drivers for your OS are: AudioUnit, Null"); + #else // assume linux/unix if we reach this point + LOG->Trace(" - Valid sound drivers for your OS are: ALSA-sw, OSS, JACK, Pulse, Null"); + #endif + LOG->Trace(" - Make sure the driver entry is spelled correctly, and is supported on your OS."); + } +} // namespace DriverList RageSoundDriver::m_pDriverList; RageSoundDriver *RageSoundDriver::Create( const RString& drivers ) { - std::vector drivers_to_try; + std::vector driversToTry; if(drivers.empty()) { - split(DEFAULT_SOUND_DRIVER_LIST, ",", drivers_to_try); + driversToTry = GetDefaultSoundDriverList(); } else { - split(drivers, ",", drivers_to_try); - std::size_t to_try= 0; - bool had_to_erase= false; - while(to_try < drivers_to_try.size()) + std::size_t start = 0; + std::size_t end = drivers.find(','); + + while (end != RString::npos) { - if(m_pDriverList.m_pRegistrees->find(istring(drivers_to_try[to_try])) - == m_pDriverList.m_pRegistrees->end()) + driversToTry.emplace_back(drivers.substr(start, end - start)); + start = end + 1; + end = drivers.find(',', start); + } + + driversToTry.emplace_back(drivers.substr(start)); + + std::size_t to_try = 0; + + while (to_try < driversToTry.size()) + { + if (std::find(GetDefaultSoundDriverList().begin(), GetDefaultSoundDriverList().end(), driversToTry[to_try]) == GetDefaultSoundDriverList().end()) { - LOG->Warn("Removed unusable sound driver %s", drivers_to_try[to_try].c_str()); - drivers_to_try.erase(drivers_to_try.begin() + to_try); - had_to_erase= true; + LOG->Warn("Removed unusable sound driver %s", driversToTry[to_try].c_str()); + WarnUserAboutBadSoundDriverEntry(); + driversToTry.erase(driversToTry.begin() + to_try); } else { ++to_try; } } - if(had_to_erase) + if(driversToTry.empty()) { - SOUNDMAN->fix_bogus_sound_driver_pref(join(",", drivers_to_try)); - } - if(drivers_to_try.empty()) - { - split(DEFAULT_SOUND_DRIVER_LIST, ",", drivers_to_try); + driversToTry = GetDefaultSoundDriverList(); } } - for (RString const &Driver : drivers_to_try) + for (RString const &Driver : driversToTry) { RageDriver *pDriver = m_pDriverList.Create( Driver ); char const *driverString = Driver.c_str(); @@ -73,9 +93,9 @@ RageSoundDriver *RageSoundDriver::Create( const RString& drivers ) return nullptr; } -RString RageSoundDriver::GetDefaultSoundDriverList() +std::vector RageSoundDriver::GetSoundDriverList() { - return DEFAULT_SOUND_DRIVER_LIST; + return GetDefaultSoundDriverList(); } /* diff --git a/src/arch/Sound/RageSoundDriver.h b/src/arch/Sound/RageSoundDriver.h index 461e583f95..54a7caf5e5 100644 --- a/src/arch/Sound/RageSoundDriver.h +++ b/src/arch/Sound/RageSoundDriver.h @@ -20,7 +20,7 @@ public: /* Pass an empty string to get the default sound driver list. */ static RageSoundDriver *Create( const RString &sDrivers ); static DriverList m_pDriverList; - static RString GetDefaultSoundDriverList(); + static std::vector GetSoundDriverList(); friend class RageSoundManager; diff --git a/src/arch/arch_default.h b/src/arch/arch_default.h index 6287b07746..8d3fab9f18 100644 --- a/src/arch/arch_default.h +++ b/src/arch/arch_default.h @@ -1,26 +1,50 @@ #ifndef ARCH_DEFAULT_H #define ARCH_DEFAULT_H +#include + /* Define the default driver sets. */ #if defined(WINDOWS) #include "ArchHooks/ArchHooks_Win32.h" #include "LoadingWindow/LoadingWindow_Win32.h" #include "LowLevelWindow/LowLevelWindow_Win32.h" #include "MemoryCard/MemoryCardDriverThreaded_Windows.h" -#define DEFAULT_INPUT_DRIVER_LIST "DirectInput,Pump,Para" -#define DEFAULT_MOVIE_DRIVER_LIST "FFMpeg,Null" -#define DEFAULT_SOUND_DRIVER_LIST "WaveOut,DirectSound-sw,WDMKS,Null" +inline const std::vector& GetDefaultInputDriverList() { + static const std::vector inputDriverList = { "DirectInput", "Pump", "Para" }; + return inputDriverList; +} + +inline const std::vector& GetDefaultMovieDriverList() { + static const std::vector movieDriverList = { "FFMpeg", "Null" }; + return movieDriverList; +} + +inline const std::vector& GetDefaultSoundDriverList() { + static const std::vector soundDriverList = { "WaveOut", "DirectSound-sw", "WDMKS", "Null" }; + return soundDriverList; +} #elif defined(MACOSX) #include "ArchHooks/ArchHooks_MacOSX.h" #include "LoadingWindow/LoadingWindow_MacOSX.h" #include "LowLevelWindow/LowLevelWindow_MacOSX.h" #include "MemoryCard/MemoryCardDriverThreaded_MacOSX.h" -#define DEFAULT_INPUT_DRIVER_LIST "HID" -#define DEFAULT_MOVIE_DRIVER_LIST "FFMpeg,Null" -#define DEFAULT_SOUND_DRIVER_LIST "AudioUnit,Null" +inline const std::vector& GetDefaultInputDriverList() { + static const std::vector inputDriverList = { "HID" }; + return inputDriverList; +} + +inline const std::vector& GetDefaultMovieDriverList() { + static const std::vector movieDriverList = { "FFMpeg", "Null" }; + return movieDriverList; +} + +inline const std::vector& GetDefaultSoundDriverList() { + static const std::vector soundDriverList = { "AudioUnit", "Null" }; + return soundDriverList; +} #elif defined(UNIX) #include "ArchHooks/ArchHooks_Unix.h" @@ -33,12 +57,22 @@ #if defined(HAVE_GTK) #include "LoadingWindow/LoadingWindow_Gtk.h" #endif + #if defined(LINUX) -#define DEFAULT_INPUT_DRIVER_LIST "X11,LinuxEvent,LinuxJoystick" +inline const std::vector& GetDefaultInputDriverList() { + static const std::vector inputDriverList = { "X11", "LinuxEvent", "LinuxJoystick" }; + return inputDriverList; +} #else -#define DEFAULT_INPUT_DRIVER_LIST "X11" +inline const std::vector& GetDefaultInputDriverList() { + static const std::vector inputDriverList = { "X11" }; + return inputDriverList; +} #endif -#define DEFAULT_MOVIE_DRIVER_LIST "FFMpeg,Null" +inline const std::vector& GetDefaultMovieDriverList() { + static const std::vector movieDriverList = { "FFMpeg", "Null" }; + return movieDriverList; +} // PulseAudio is the preferred Unix driver since it allows the gives non // exclusive access to the audio device, unlike ALSA. // Use ALSA next because it is the lowest latency. @@ -47,7 +81,10 @@ // JACK gives us an explicit option to NOT start a daemon, so try it last, // as PulseAudio will successfully Init() but not actually work if the // PulseAudio daemon has been suspended by/for jackd. -#define DEFAULT_SOUND_DRIVER_LIST "Pulse,ALSA-sw,OSS,JACK,Null" +inline const std::vector& GetDefaultSoundDriverList() { + static const std::vector soundDriverList = { "Pulse", "ALSA-sw", "OSS", "JACK", "Null" }; + return soundDriverList; +} #else #error Which arch? #endif @@ -57,7 +94,7 @@ #include "MemoryCard/MemoryCardDriver_Null.h" #include "MemoryCard/MemoryCardDriverThreaded_Folder.h" -#endif +#endif // ARCH_DEFAULT_H /* * (c) 2002-2006 Glenn Maynard, Ben Anderson, Steve Checkoway