RegTest: Support using global data directory
This commit is contained in:
parent
a854ed2da1
commit
88e14dd3ff
|
@ -26,8 +26,9 @@ def run_regression_test(runner, destdir, dump_interval, frames, renderer, cargs,
|
||||||
args += cargs
|
args += cargs
|
||||||
args += ["--", gamepath]
|
args += ["--", gamepath]
|
||||||
|
|
||||||
print("Running '%s'" % (" ".join(args)))
|
#print("Running '%s'" % (" ".join(args)))
|
||||||
subprocess.run(args)
|
subprocess.run(args)
|
||||||
|
return os.path.basename(gamepath)
|
||||||
|
|
||||||
|
|
||||||
def run_regression_tests(runner, gamedir, destdir, dump_interval, frames, parallel, renderer, cargs):
|
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))
|
print("Processing %u games on %u processors" % (len(gamepaths), parallel))
|
||||||
func = partial(run_regression_test, runner, destdir, dump_interval, frames, renderer, cargs)
|
func = partial(run_regression_test, runner, destdir, dump_interval, frames, renderer, cargs)
|
||||||
pool = multiprocessing.Pool(parallel)
|
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.map(func, gamepaths, chunksize=1)
|
||||||
pool.close()
|
pool.close()
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
|
#include "common/file_system.h"
|
||||||
#include "common/layered_settings_interface.h"
|
#include "common/layered_settings_interface.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/path.h"
|
#include "common/path.h"
|
||||||
|
@ -26,8 +27,14 @@
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
#include <cstdlib>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "common/windows_headers.h"
|
||||||
|
#include <ShlObj.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG_CHANNEL(Host);
|
LOG_CHANNEL(Host);
|
||||||
|
|
||||||
namespace Host {
|
namespace Host {
|
||||||
|
@ -35,6 +42,71 @@ static std::mutex s_settings_mutex;
|
||||||
static LayeredSettingsInterface s_layered_settings_interface;
|
static LayeredSettingsInterface s_layered_settings_interface;
|
||||||
} // namespace Host
|
} // 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<std::mutex> Host::GetSettingsLock()
|
std::unique_lock<std::mutex> Host::GetSettingsLock()
|
||||||
{
|
{
|
||||||
return std::unique_lock<std::mutex>(s_settings_mutex);
|
return std::unique_lock<std::mutex>(s_settings_mutex);
|
||||||
|
|
|
@ -112,6 +112,13 @@ void ReleaseGPUDevice();
|
||||||
void FrameDone();
|
void FrameDone();
|
||||||
|
|
||||||
namespace Internal {
|
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.
|
/// Retrieves the base settings layer. Must call with lock held.
|
||||||
SettingsInterface* GetBaseSettingsLayer();
|
SettingsInterface* GetBaseSettingsLayer();
|
||||||
|
|
||||||
|
@ -129,5 +136,7 @@ void SetGameSettingsLayer(SettingsInterface* sif, std::unique_lock<std::mutex>&
|
||||||
|
|
||||||
/// Sets the input profile settings layer. Called by VMManager when the game changes.
|
/// Sets the input profile settings layer. Called by VMManager when the game changes.
|
||||||
void SetInputSettingsLayer(SettingsInterface* sif, std::unique_lock<std::mutex>& lock);
|
void SetInputSettingsLayer(SettingsInterface* sif, std::unique_lock<std::mutex>& lock);
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|
||||||
} // namespace Host
|
} // namespace Host
|
||||||
|
|
|
@ -71,11 +71,6 @@
|
||||||
|
|
||||||
LOG_CHANNEL(Host);
|
LOG_CHANNEL(Host);
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include "common/windows_headers.h"
|
|
||||||
#include <ShlObj.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static constexpr u32 SETTINGS_VERSION = 3;
|
static constexpr u32 SETTINGS_VERSION = 3;
|
||||||
static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
|
static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
|
||||||
|
|
||||||
|
@ -96,7 +91,6 @@ static bool PerformEarlyHardwareChecks();
|
||||||
static bool EarlyProcessStartup();
|
static bool EarlyProcessStartup();
|
||||||
static void RegisterTypes();
|
static void RegisterTypes();
|
||||||
static bool InitializeConfig(std::string settings_filename);
|
static bool InitializeConfig(std::string settings_filename);
|
||||||
static bool ShouldUsePortableMode();
|
|
||||||
static void SetAppRoot();
|
static void SetAppRoot();
|
||||||
static void SetResourcesDirectory();
|
static void SetResourcesDirectory();
|
||||||
static bool SetDataDirectory();
|
static bool SetDataDirectory();
|
||||||
|
@ -516,13 +510,6 @@ bool QtHost::SetCriticalFolders()
|
||||||
return true;
|
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()
|
void QtHost::SetAppRoot()
|
||||||
{
|
{
|
||||||
const std::string program_path = FileSystem::GetProgramPath();
|
const std::string program_path = FileSystem::GetProgramPath();
|
||||||
|
@ -545,54 +532,11 @@ void QtHost::SetResourcesDirectory()
|
||||||
bool QtHost::SetDataDirectory()
|
bool QtHost::SetDataDirectory()
|
||||||
{
|
{
|
||||||
// Already set, e.g. by -portable.
|
// Already set, e.g. by -portable.
|
||||||
if (!EmuFolders::DataRoot.empty())
|
if (EmuFolders::DataRoot.empty())
|
||||||
return true;
|
EmuFolders::DataRoot = Host::Internal::ComputeDataDirectory();
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
// make sure it exists
|
// 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
|
// we're in trouble if we fail to create this directory... but try to hobble on with portable
|
||||||
Error error;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
LOG_CHANNEL(RegTestHost);
|
LOG_CHANNEL(Host);
|
||||||
|
|
||||||
namespace RegTestHost {
|
namespace RegTestHost {
|
||||||
static bool ParseCommandLineParameters(int argc, char* argv[], std::optional<SystemBootParameters>& autoboot);
|
static bool ParseCommandLineParameters(int argc, char* argv[], std::optional<SystemBootParameters>& autoboot);
|
||||||
|
@ -58,19 +58,10 @@ static std::string s_dump_base_directory;
|
||||||
bool RegTestHost::SetFolders()
|
bool RegTestHost::SetFolders()
|
||||||
{
|
{
|
||||||
std::string program_path(FileSystem::GetProgramPath());
|
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::AppRoot = Path::Canonicalize(Path::GetDirectory(program_path));
|
||||||
EmuFolders::DataRoot = EmuFolders::AppRoot;
|
EmuFolders::DataRoot = Host::Internal::ComputeDataDirectory();
|
||||||
|
|
||||||
#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::Resources = Path::Combine(EmuFolders::AppRoot, "resources");
|
EmuFolders::Resources = Path::Combine(EmuFolders::AppRoot, "resources");
|
||||||
|
|
||||||
DEV_LOG("AppRoot Directory: {}", EmuFolders::AppRoot);
|
DEV_LOG("AppRoot Directory: {}", EmuFolders::AppRoot);
|
||||||
|
@ -87,6 +78,12 @@ bool RegTestHost::SetFolders()
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +497,10 @@ void RegTestHost::InitializeEarlyConsole()
|
||||||
{
|
{
|
||||||
const bool was_console_enabled = Log::IsConsoleOutputEnabled();
|
const bool was_console_enabled = Log::IsConsoleOutputEnabled();
|
||||||
if (!was_console_enabled)
|
if (!was_console_enabled)
|
||||||
|
{
|
||||||
Log::SetConsoleOutputParams(true);
|
Log::SetConsoleOutputParams(true);
|
||||||
|
Log::SetLogLevel(Log::Level::Info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegTestHost::PrintCommandLineVersion()
|
void RegTestHost::PrintCommandLineVersion()
|
||||||
|
@ -723,9 +723,7 @@ bool RegTestHost::SetNewDataRoot(const std::string& filename)
|
||||||
EmuFolders::DataRoot = std::move(dump_directory);
|
EmuFolders::DataRoot = std::move(dump_directory);
|
||||||
s_base_settings_interface->SetBoolValue("Logging", "LogToFile", true);
|
s_base_settings_interface->SetBoolValue("Logging", "LogToFile", true);
|
||||||
s_base_settings_interface->SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(Log::Level::Dev));
|
s_base_settings_interface->SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(Log::Level::Dev));
|
||||||
g_settings.log_to_file = true;
|
Settings::UpdateLogConfig(*s_base_settings_interface);
|
||||||
g_settings.log_level = Log::Level::Dev;
|
|
||||||
g_settings.UpdateLogSettings();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue