diff --git a/scripts/run_regression_tests.py b/scripts/run_regression_tests.py index 5c7a6a022..d55ae50b8 100644 --- a/scripts/run_regression_tests.py +++ b/scripts/run_regression_tests.py @@ -26,8 +26,9 @@ def run_regression_test(runner, destdir, dump_interval, frames, renderer, cargs, args += cargs args += ["--", gamepath] - print("Running '%s'" % (" ".join(args))) + #print("Running '%s'" % (" ".join(args))) subprocess.run(args) + return os.path.basename(gamepath) def run_regression_tests(runner, gamedir, destdir, dump_interval, frames, parallel, renderer, cargs): @@ -50,6 +51,11 @@ def run_regression_tests(runner, gamedir, destdir, dump_interval, frames, parall print("Processing %u games on %u processors" % (len(gamepaths), parallel)) func = partial(run_regression_test, runner, destdir, dump_interval, frames, renderer, cargs) pool = multiprocessing.Pool(parallel) + completed = 0 + for filename in pool.imap_unordered(func, gamepaths, chunksize=1): + completed += 1 + print("[%u%% %u/%u] %s" % ((completed * 100) // len(gamepaths), completed, len(gamepaths), filename)) + pool.map(func, gamepaths, chunksize=1) pool.close() diff --git a/src/core/host.cpp b/src/core/host.cpp index 3d6335717..1d26548be 100644 --- a/src/core/host.cpp +++ b/src/core/host.cpp @@ -18,6 +18,7 @@ #include "common/assert.h" #include "common/error.h" +#include "common/file_system.h" #include "common/layered_settings_interface.h" #include "common/log.h" #include "common/path.h" @@ -26,8 +27,14 @@ #include "fmt/format.h" #include +#include #include +#ifdef _WIN32 +#include "common/windows_headers.h" +#include +#endif + LOG_CHANNEL(Host); namespace Host { @@ -35,6 +42,71 @@ static std::mutex s_settings_mutex; static LayeredSettingsInterface s_layered_settings_interface; } // namespace Host +bool Host::Internal::ShouldUsePortableMode() +{ +#ifndef __ANDROID__ + // Check whether portable.ini exists in the program directory. + return (FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "portable.txt").c_str()) || + FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "settings.ini").c_str())); +#else + return false; +#endif +} + +std::string Host::Internal::ComputeDataDirectory() +{ + std::string ret; + + if (ShouldUsePortableMode()) + { + ret = EmuFolders::AppRoot; + return ret; + } + +#if defined(_WIN32) + // On Windows, use My Documents\DuckStation. + PWSTR documents_directory; + if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &documents_directory))) + { + if (std::wcslen(documents_directory) > 0) + ret = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "DuckStation"); + CoTaskMemFree(documents_directory); + } +#elif (defined(__linux__) || defined(__FreeBSD__)) && !defined(__ANDROID__) + // Use $XDG_CONFIG_HOME/duckstation if it exists. + const char* xdg_config_home = getenv("XDG_CONFIG_HOME"); + if (xdg_config_home && Path::IsAbsolute(xdg_config_home)) + { + ret = Path::RealPath(Path::Combine(xdg_config_home, "duckstation")); + } + else + { + // Use ~/.local/share/duckstation otherwise. + const char* home_dir = getenv("HOME"); + if (home_dir) + { + // ~/.local/share should exist, but just in case it doesn't and this is a fresh profile.. + const std::string local_dir(Path::Combine(home_dir, ".local")); + const std::string share_dir(Path::Combine(local_dir, "share")); + FileSystem::EnsureDirectoryExists(local_dir.c_str(), false); + FileSystem::EnsureDirectoryExists(share_dir.c_str(), false); + ret = Path::RealPath(Path::Combine(share_dir, "duckstation")); + } + } +#elif defined(__APPLE__) + static constexpr char MAC_DATA_DIR[] = "Library/Application Support/DuckStation"; + const char* home_dir = getenv("HOME"); + if (home_dir) + ret = Path::RealPath(Path::Combine(home_dir, MAC_DATA_DIR)); +#endif + + // Couldn't find anything? Fall back to portable. + if (ret.empty()) + ret = EmuFolders::AppRoot; + + return ret; +} + std::unique_lock Host::GetSettingsLock() { return std::unique_lock(s_settings_mutex); diff --git a/src/core/host.h b/src/core/host.h index 260255143..41896a522 100644 --- a/src/core/host.h +++ b/src/core/host.h @@ -112,6 +112,13 @@ void ReleaseGPUDevice(); void FrameDone(); namespace Internal { + +/// Returns true if the host should use portable mode. +bool ShouldUsePortableMode(); + +/// Based on the current configuration, determines what the data directory is. +std::string ComputeDataDirectory(); + /// Retrieves the base settings layer. Must call with lock held. SettingsInterface* GetBaseSettingsLayer(); @@ -129,5 +136,7 @@ void SetGameSettingsLayer(SettingsInterface* sif, std::unique_lock& /// Sets the input profile settings layer. Called by VMManager when the game changes. void SetInputSettingsLayer(SettingsInterface* sif, std::unique_lock& lock); + } // namespace Internal + } // namespace Host diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index a6f08febc..a7d9e0584 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -71,11 +71,6 @@ LOG_CHANNEL(Host); -#ifdef _WIN32 -#include "common/windows_headers.h" -#include -#endif - static constexpr u32 SETTINGS_VERSION = 3; static constexpr u32 SETTINGS_SAVE_DELAY = 1000; @@ -96,7 +91,6 @@ static bool PerformEarlyHardwareChecks(); static bool EarlyProcessStartup(); static void RegisterTypes(); static bool InitializeConfig(std::string settings_filename); -static bool ShouldUsePortableMode(); static void SetAppRoot(); static void SetResourcesDirectory(); static bool SetDataDirectory(); @@ -516,13 +510,6 @@ bool QtHost::SetCriticalFolders() return true; } -bool QtHost::ShouldUsePortableMode() -{ - // Check whether portable.ini exists in the program directory. - return (FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "portable.txt").c_str()) || - FileSystem::FileExists(Path::Combine(EmuFolders::AppRoot, "settings.ini").c_str())); -} - void QtHost::SetAppRoot() { const std::string program_path = FileSystem::GetProgramPath(); @@ -545,54 +532,11 @@ void QtHost::SetResourcesDirectory() bool QtHost::SetDataDirectory() { // Already set, e.g. by -portable. - if (!EmuFolders::DataRoot.empty()) - return true; - - if (ShouldUsePortableMode()) - { - EmuFolders::DataRoot = EmuFolders::AppRoot; - return true; - } - -#if defined(_WIN32) - // On Windows, use My Documents\DuckStation. - PWSTR documents_directory; - if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &documents_directory))) - { - if (std::wcslen(documents_directory) > 0) - EmuFolders::DataRoot = Path::Combine(StringUtil::WideStringToUTF8String(documents_directory), "DuckStation"); - CoTaskMemFree(documents_directory); - } -#elif defined(__linux__) || defined(__FreeBSD__) - // Use $XDG_CONFIG_HOME/duckstation if it exists. - const char* xdg_config_home = getenv("XDG_CONFIG_HOME"); - if (xdg_config_home && Path::IsAbsolute(xdg_config_home)) - { - EmuFolders::DataRoot = Path::RealPath(Path::Combine(xdg_config_home, "duckstation")); - } - else - { - // Use ~/.local/share/duckstation otherwise. - const char* home_dir = getenv("HOME"); - if (home_dir) - { - // ~/.local/share should exist, but just in case it doesn't and this is a fresh profile.. - const std::string local_dir(Path::Combine(home_dir, ".local")); - const std::string share_dir(Path::Combine(local_dir, "share")); - FileSystem::EnsureDirectoryExists(local_dir.c_str(), false); - FileSystem::EnsureDirectoryExists(share_dir.c_str(), false); - EmuFolders::DataRoot = Path::RealPath(Path::Combine(share_dir, "duckstation")); - } - } -#elif defined(__APPLE__) - static constexpr char MAC_DATA_DIR[] = "Library/Application Support/DuckStation"; - const char* home_dir = getenv("HOME"); - if (home_dir) - EmuFolders::DataRoot = Path::RealPath(Path::Combine(home_dir, MAC_DATA_DIR)); -#endif + if (EmuFolders::DataRoot.empty()) + EmuFolders::DataRoot = Host::Internal::ComputeDataDirectory(); // make sure it exists - if (!EmuFolders::DataRoot.empty() && !FileSystem::DirectoryExists(EmuFolders::DataRoot.c_str())) + if (!FileSystem::DirectoryExists(EmuFolders::DataRoot.c_str())) { // we're in trouble if we fail to create this directory... but try to hobble on with portable Error error; @@ -610,10 +554,6 @@ bool QtHost::SetDataDirectory() } } - // couldn't determine the data directory? fallback to portable. - if (EmuFolders::DataRoot.empty()) - EmuFolders::DataRoot = EmuFolders::AppRoot; - return true; } diff --git a/src/duckstation-regtest/regtest_host.cpp b/src/duckstation-regtest/regtest_host.cpp index baf1e5a66..5f60d1a7e 100644 --- a/src/duckstation-regtest/regtest_host.cpp +++ b/src/duckstation-regtest/regtest_host.cpp @@ -34,7 +34,7 @@ #include #include -LOG_CHANNEL(RegTestHost); +LOG_CHANNEL(Host); namespace RegTestHost { static bool ParseCommandLineParameters(int argc, char* argv[], std::optional& autoboot); @@ -58,19 +58,10 @@ static std::string s_dump_base_directory; bool RegTestHost::SetFolders() { std::string program_path(FileSystem::GetProgramPath()); - INFO_LOG("Program Path: {}", program_path); + DEV_LOG("Program Path: {}", program_path); EmuFolders::AppRoot = Path::Canonicalize(Path::GetDirectory(program_path)); - EmuFolders::DataRoot = EmuFolders::AppRoot; - -#ifdef __APPLE__ - static constexpr char MAC_DATA_DIR[] = "Library/Application Support/DuckStation"; - const char* home_dir = getenv("HOME"); - if (home_dir) - EmuFolders::DataRoot = Path::Combine(home_dir, MAC_DATA_DIR); -#endif - - // On Windows/Linux, these are in the binary directory. + EmuFolders::DataRoot = Host::Internal::ComputeDataDirectory(); EmuFolders::Resources = Path::Combine(EmuFolders::AppRoot, "resources"); DEV_LOG("AppRoot Directory: {}", EmuFolders::AppRoot); @@ -87,6 +78,12 @@ bool RegTestHost::SetFolders() return false; } + if (EmuFolders::DataRoot.empty() || !FileSystem::EnsureDirectoryExists(EmuFolders::DataRoot.c_str(), false)) + { + ERROR_LOG("Failed to create data directory '{}'", EmuFolders::DataRoot); + return false; + } + return true; } @@ -500,7 +497,10 @@ void RegTestHost::InitializeEarlyConsole() { const bool was_console_enabled = Log::IsConsoleOutputEnabled(); if (!was_console_enabled) + { Log::SetConsoleOutputParams(true); + Log::SetLogLevel(Log::Level::Info); + } } void RegTestHost::PrintCommandLineVersion() @@ -723,9 +723,7 @@ bool RegTestHost::SetNewDataRoot(const std::string& filename) EmuFolders::DataRoot = std::move(dump_directory); s_base_settings_interface->SetBoolValue("Logging", "LogToFile", true); s_base_settings_interface->SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(Log::Level::Dev)); - g_settings.log_to_file = true; - g_settings.log_level = Log::Level::Dev; - g_settings.UpdateLogSettings(); + Settings::UpdateLogConfig(*s_base_settings_interface); } return true;