From 8f1dc7a2d46e12a22dfbfb8f2f843dc86ac7248b Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 22 Sep 2021 21:44:52 +0200 Subject: [PATCH] Fix VFS regression Implements cfg_mode --- rpcs3/Emu/Cell/lv2/sys_process.cpp | 2 +- rpcs3/Emu/System.cpp | 101 +++++++++++++++++++++-------- rpcs3/Emu/System.h | 18 +++-- rpcs3/main.cpp | 6 +- rpcs3/rpcs3qt/game_list_frame.cpp | 6 +- rpcs3/rpcs3qt/game_list_frame.h | 3 +- rpcs3/rpcs3qt/main_window.cpp | 9 ++- rpcs3/rpcs3qt/main_window.h | 3 +- 8 files changed, 100 insertions(+), 48 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_process.cpp b/rpcs3/Emu/Cell/lv2/sys_process.cpp index 746bcebe99..e9912ad522 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_process.cpp @@ -430,7 +430,7 @@ void _sys_process_exit2(ppu_thread& ppu, s32 status, vm::ptr ar Emu.SetForceBoot(true); - auto res = Emu.BootGame(path, "", true, false, old_config); + auto res = Emu.BootGame(path, "", true, false, cfg_mode::continuous, old_config); if (res != game_boot_result::no_errors) { diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 5916a71b4f..23b2140186 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -101,6 +101,24 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } +template<> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](cfg_mode value) + { + switch (value) + { + case cfg_mode::custom: return "custom config"; + case cfg_mode::custom_selection: return "custom config selection"; + case cfg_mode::global: return "global config"; + case cfg_mode::config_override: return "config override"; + case cfg_mode::continuous: return "continuous config"; + case cfg_mode::default_config: return "default config"; + } + return unknown; + }); +} + void Emulator::Init(bool add_only) { jit_runtime::initialize(); @@ -120,7 +138,7 @@ void Emulator::Init(bool add_only) // Reset defaults, cache them g_cfg.from_default(); - g_cfg.name = cfg_keys::_default; + g_cfg.name.clear(); // Not all renderers are known at compile time, so set a provided default if possible if (m_default_renderer == video_renderer::vulkan && !m_default_graphics_adapter.empty()) @@ -132,7 +150,7 @@ void Emulator::Init(bool add_only) g_cfg_defaults = g_cfg.to_string(); // Load config file - if (m_config_path.find_first_of(fs::delim) != umax) + if (m_config_mode == cfg_mode::config_override) { if (const fs::file cfg_file{m_config_path, fs::read + fs::create}) { @@ -141,7 +159,8 @@ void Emulator::Init(bool add_only) if (!g_cfg.from_string(cfg_file.to_string())) { sys_log.fatal("Failed to apply config: %s. Proceeding with regular configuration.", m_config_path); - m_config_path = cfg_keys::title_id; + m_config_path.clear(); + m_config_mode = cfg_mode::custom; } else { @@ -152,12 +171,13 @@ void Emulator::Init(bool add_only) else { sys_log.fatal("Failed to access config: %s (%s). Proceeding with regular configuration.", m_config_path, fs::g_tls_error); - m_config_path = cfg_keys::title_id; + m_config_path.clear(); + m_config_mode = cfg_mode::custom; } } // Reload global configuration - if (m_config_path == cfg_keys::global || m_config_path == cfg_keys::title_id) + if (m_config_mode != cfg_mode::config_override && m_config_mode != cfg_mode::default_config) { const auto cfg_path = fs::get_config_dir() + "/config.yml"; @@ -436,7 +456,7 @@ bool Emulator::BootRsxCapture(const std::string& path) return true; } -game_boot_result Emulator::BootGame(const std::string& path, const std::string& title_id, bool direct, bool add_only, const std::string& config_path) +game_boot_result Emulator::BootGame(const std::string& path, const std::string& title_id, bool direct, bool add_only, cfg_mode config_mode, const std::string& config_path) { if (!fs::exists(path)) { @@ -445,6 +465,7 @@ game_boot_result Emulator::BootGame(const std::string& path, const std::string& m_path_old = m_path; + m_config_mode = config_mode; m_config_path = config_path; if (direct || fs::is_file(path)) @@ -521,7 +542,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool m_title_id = title_id; } - sys_log.notice("Selected config: %s", m_config_path); + sys_log.notice("Selected config: mode=%s, path=\"%s\"", m_config_mode, m_config_path); { Init(add_only); @@ -607,39 +628,62 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool sys_log.notice("Category: %s", GetCat()); sys_log.notice("Version: APP_VER=%s VERSION=%s", version_app, version_disc); - if (!add_only && m_config_path == cfg_keys::title_id) + if (!add_only) { - const std::string config_path = rpcs3::utils::get_custom_config_path(m_title_id); - - // Load custom config-1 - if (fs::file cfg_file{ config_path }) + if (m_config_mode == cfg_mode::custom_selection || m_config_mode == cfg_mode::continuous) { - sys_log.notice("Applying custom config: %s", config_path); - - if (g_cfg.from_string(cfg_file.to_string())) + if (fs::file cfg_file{ m_config_path }) { - g_cfg.name = config_path; - m_config_path = config_path; + sys_log.notice("Applying %s: %s", m_config_mode, m_config_path); + + if (g_cfg.from_string(cfg_file.to_string())) + { + g_cfg.name = m_config_path; + } + else + { + sys_log.fatal("Failed to apply %s: %s", m_config_mode, m_config_path); + } } else { - sys_log.fatal("Failed to apply custom config: %s", config_path); + sys_log.fatal("Failed to access %s: %s", m_config_mode, m_config_path); } } - - // Load custom config-2 - if (fs::file cfg_file{ m_path + ".yml" }) + else if (m_config_mode == cfg_mode::custom) { - sys_log.notice("Applying custom config: %s.yml", m_path); + const std::string config_path = rpcs3::utils::get_custom_config_path(m_title_id); - if (g_cfg.from_string(cfg_file.to_string())) + // Load custom config-1 + if (fs::file cfg_file{ config_path }) { - g_cfg.name = m_path + ".yml"; - m_config_path = g_cfg.name; + sys_log.notice("Applying custom config: %s", config_path); + + if (g_cfg.from_string(cfg_file.to_string())) + { + g_cfg.name = config_path; + m_config_path = config_path; + } + else + { + sys_log.fatal("Failed to apply custom config: %s", config_path); + } } - else + + // Load custom config-2 + if (fs::file cfg_file{ m_path + ".yml" }) { - sys_log.fatal("Failed to apply custom config: %s.yml", m_path); + sys_log.notice("Applying custom config: %s.yml", m_path); + + if (g_cfg.from_string(cfg_file.to_string())) + { + g_cfg.name = m_path + ".yml"; + m_config_path = g_cfg.name; + } + else + { + sys_log.fatal("Failed to apply custom config: %s.yml", m_path); + } } } } @@ -1726,7 +1770,8 @@ void Emulator::Stop(bool restart) disc.clear(); klic.clear(); hdd1.clear(); - m_config_path = cfg_keys::global; + m_config_path.clear(); + m_config_mode == cfg_mode::custom; // Always Enable display sleep, not only if it was prevented. enable_display_sleep(); diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index c59b38fb24..f75ca57522 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -44,12 +44,15 @@ enum class game_boot_result : u32 unsupported_disc_type }; -namespace cfg_keys +enum class cfg_mode { - inline const std::string title_id = "title_id"; // No config override mode - inline const std::string global = "global"; // Force global config - inline const std::string _default = "default"; // Force virtual default constructed config.yml -} + custom, // Prefer regular custom config. Fall back to global config. + custom_selection, // Use user-selected custom config. Fall back to global config. + global, // Use global config. + config_override, // Use config override. This does not use the global VFS settings! Fall back to global config. + continuous, // Use same config as on last boot. Fall back to global config. + default_config // Use the default values of the config entries. +}; struct EmuCallbacks { @@ -90,7 +93,8 @@ class Emulator final video_renderer m_default_renderer; std::string m_default_graphics_adapter; - std::string m_config_path = cfg_keys::title_id; + cfg_mode m_config_mode = cfg_mode::custom; + std::string m_config_path; std::string m_path; std::string m_path_old; std::string m_title_id; @@ -227,7 +231,7 @@ public: return m_config_path; } - game_boot_result BootGame(const std::string& path, const std::string& title_id = "", bool direct = false, bool add_only = false, const std::string& config_path = cfg_keys::title_id); + game_boot_result BootGame(const std::string& path, const std::string& title_id = "", bool direct = false, bool add_only = false, cfg_mode config_mode = cfg_mode::custom, const std::string& config_path = ""); bool BootRsxCapture(const std::string& path); void SetForceBoot(bool force_boot); diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp index b5da751b83..fd9cd1efd0 100644 --- a/rpcs3/main.cpp +++ b/rpcs3/main.cpp @@ -920,7 +920,7 @@ int main(int argc, char** argv) } } - std::string config_path = cfg_keys::title_id; + std::string config_path; if (parser.isSet(arg_config)) { @@ -938,7 +938,9 @@ int main(int argc, char** argv) Emu.argv = std::move(rpcs3_argv); Emu.SetForceBoot(true); - if (const game_boot_result error = Emu.BootGame(path, "", false, false, config_path); error != game_boot_result::no_errors) + const cfg_mode config_mode = config_path.empty() ? cfg_mode::custom : cfg_mode::config_override; + + if (const game_boot_result error = Emu.BootGame(path, "", false, false, config_mode, config_path); error != game_boot_result::no_errors) { sys_log.error("Booting '%s' with cli argument failed: reason: %s", path, error); diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 63dba234f5..bedaa2bfdf 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -950,7 +950,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos) connect(boot_default, &QAction::triggered, [this, gameinfo] { sys_log.notice("Booting from gamelist per context menu..."); - Q_EMIT RequestBoot(gameinfo, cfg_keys::_default); + Q_EMIT RequestBoot(gameinfo, cfg_mode::default_config); }); QAction* boot_manual = menu.addAction(is_current_running_game @@ -962,7 +962,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos) if (std::string file_path = sstr(QFileDialog::getOpenFileName(this, "Select Config File", "", tr("Config Files (*.yml);;All files (*.*)"))); !file_path.empty()) { sys_log.notice("Booting from gamelist per context menu..."); - Q_EMIT RequestBoot(gameinfo, file_path); + Q_EMIT RequestBoot(gameinfo, cfg_mode::custom_selection, file_path); } else { @@ -1221,7 +1221,7 @@ void game_list_frame::ShowContextMenu(const QPoint &pos) connect(boot, &QAction::triggered, this, [this, gameinfo]() { sys_log.notice("Booting from gamelist per context menu..."); - Q_EMIT RequestBoot(gameinfo, cfg_keys::global); + Q_EMIT RequestBoot(gameinfo, cfg_mode::global); }); connect(configure, &QAction::triggered, this, [this, current_game, gameinfo]() { diff --git a/rpcs3/rpcs3qt/game_list_frame.h b/rpcs3/rpcs3qt/game_list_frame.h index 4a03f7e58a..18490191d6 100644 --- a/rpcs3/rpcs3qt/game_list_frame.h +++ b/rpcs3/rpcs3qt/game_list_frame.h @@ -4,6 +4,7 @@ #include "custom_dock_widget.h" #include "gui_save.h" #include "Utilities/lockless.h" +#include "Emu/System.h" #include #include @@ -83,7 +84,7 @@ private Q_SLOTS: Q_SIGNALS: void GameListFrameClosed(); void NotifyGameSelection(const game_info& game); - void RequestBoot(const game_info& game, const std::string& config_path = "title_id"); // "title_id" is cfg_keys::title_id + void RequestBoot(const game_info& game, cfg_mode config_mode = cfg_mode::custom, const std::string& config_path = ""); void RequestIconSizeChange(const int& val); void NotifyEmuSettingsChange(); protected: diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index b8872bbe71..c0bc48827a 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -40,7 +40,6 @@ #include #include "rpcs3_version.h" -#include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/VFS.h" #include "Emu/system_config.h" @@ -378,7 +377,7 @@ void main_window::show_boot_error(game_boot_result status) msg.exec(); } -void main_window::Boot(const std::string& path, const std::string& title_id, bool direct, bool add_only, const std::string& config_path) +void main_window::Boot(const std::string& path, const std::string& title_id, bool direct, bool add_only, cfg_mode config_mode, const std::string& config_path) { if (!m_gui_settings->GetBootConfirmation(this, gui::ib_confirm_boot)) { @@ -390,7 +389,7 @@ void main_window::Boot(const std::string& path, const std::string& title_id, boo Emu.SetForceBoot(true); Emu.Stop(); - if (const auto error = Emu.BootGame(path, title_id, direct, add_only, config_path); error != game_boot_result::no_errors) + if (const auto error = Emu.BootGame(path, title_id, direct, add_only, config_mode, config_path); error != game_boot_result::no_errors) { gui_log.error("Boot failed: reason: %s, path: %s", error, path); show_boot_error(error); @@ -2492,9 +2491,9 @@ void main_window::CreateDockWindows() m_selected_game = game; }); - connect(m_game_list_frame, &game_list_frame::RequestBoot, this, [this](const game_info& game, const std::string& config_path) + connect(m_game_list_frame, &game_list_frame::RequestBoot, this, [this](const game_info& game, cfg_mode config_mode, const std::string& config_path) { - Boot(game->info.path, game->info.serial, false, false, config_path); + Boot(game->info.path, game->info.serial, false, false, config_mode, config_path); }); connect(m_game_list_frame, &game_list_frame::NotifyEmuSettingsChange, this, &main_window::NotifyEmuSettingsChange); diff --git a/rpcs3/rpcs3qt/main_window.h b/rpcs3/rpcs3qt/main_window.h index 2babe2297c..121f8e540d 100644 --- a/rpcs3/rpcs3qt/main_window.h +++ b/rpcs3/rpcs3qt/main_window.h @@ -12,6 +12,7 @@ #include "update_manager.h" #include "settings.h" +#include "Emu/System.h" #include @@ -107,7 +108,7 @@ public Q_SLOTS: private Q_SLOTS: void OnPlayOrPause(); - void Boot(const std::string& path, const std::string& title_id = "", bool direct = false, bool add_only = false, const std::string& config_path = "title_id"); // "title_id" is cfg_keys::title_id + void Boot(const std::string& path, const std::string& title_id = "", bool direct = false, bool add_only = false, cfg_mode config_mode = cfg_mode::custom, const std::string& config_path = ""); void BootElf(); void BootGame(); void BootVSH();