diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index d1812de216..457fe4ba28 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include "Utilities/JIT.h" @@ -112,6 +113,7 @@ void fmt_class_string::format(std::string& out, u64 arg) case game_boot_result::nothing_to_boot: return "Nothing to boot"; case game_boot_result::wrong_disc_location: return "Wrong disc location"; case game_boot_result::invalid_file_or_folder: return "Invalid file or folder"; + case game_boot_result::invalid_bdvd_folder: return "Invalid dev_bdvd folder"; case game_boot_result::install_failed: return "Game install failed"; case game_boot_result::decryption_error: return "Failed to decrypt content"; case game_boot_result::file_creation_error: return "Could not create important files"; @@ -239,6 +241,7 @@ void Emulator::Init(bool add_only) // Mount all devices const std::string emu_dir = rpcs3::utils::get_emu_dir(); const std::string elf_dir = fs::get_parent_dir(m_path); + const std::string dev_bdvd = g_cfg_vfs.get(g_cfg_vfs.dev_bdvd, emu_dir); // Only used for make_path const std::string dev_hdd0 = g_cfg_vfs.get(g_cfg_vfs.dev_hdd0, emu_dir); const std::string dev_hdd1 = g_cfg_vfs.get(g_cfg_vfs.dev_hdd1, emu_dir); const std::string dev_flsh = g_cfg_vfs.get_dev_flash(); @@ -344,6 +347,7 @@ void Emulator::Init(bool add_only) if (g_cfg.vfs.init_dirs) { + make_path_verbose(dev_bdvd); make_path_verbose(dev_hdd0); make_path_verbose(dev_hdd1); make_path_verbose(dev_flsh); @@ -933,7 +937,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool const std::string elf_dir = fs::get_parent_dir(m_path); - // Mount /app_home + // Mount /app_home again since m_path might have changed due to savestates. vfs::mount("/app_home", g_cfg_vfs.app_home.to_string().empty() ? elf_dir + '/' : g_cfg_vfs.get(g_cfg_vfs.app_home, rpcs3::utils::get_emu_dir())); // Load PARAM.SFO (TODO) @@ -1103,18 +1107,27 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool if (!add_only) { - bdvd_dir = g_cfg_vfs.dev_bdvd; + bdvd_dir = g_cfg_vfs.get(g_cfg_vfs.dev_bdvd, rpcs3::utils::get_emu_dir()); - if (!bdvd_dir.empty() && bdvd_dir.back() != fs::delim[0] && bdvd_dir.back() != fs::delim[1]) + if (!bdvd_dir.empty()) { - bdvd_dir.push_back('/'); - } + if (bdvd_dir.back() != fs::delim[0] && bdvd_dir.back() != fs::delim[1]) + { + bdvd_dir.push_back('/'); + } - if (!bdvd_dir.empty() && !fs::is_file(bdvd_dir + "PS3_DISC.SFB")) - { - // Unuse if invalid - sys_log.error("Failed to use custom BDVD directory: '%s'", bdvd_dir); - bdvd_dir.clear(); + if (fs::is_dir(bdvd_dir) && std::filesystem::is_empty(bdvd_dir)) + { + // Ignore empty dir. We will need it later for disc games in dev_hdd0. + bdvd_dir.clear(); + sys_log.notice("Ignoring empty vfs BDVD directory: '%s'", bdvd_dir); + } + else if (!fs::is_file(bdvd_dir + "PS3_DISC.SFB")) + { + // Unuse if invalid + sys_log.error("Failed to use custom BDVD directory: '%s'", bdvd_dir); + bdvd_dir.clear(); + } } } @@ -1403,6 +1416,15 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool else if (m_cat == "DG" && from_hdd0_game && disc.empty()) { // Disc game located in dev_hdd0/game + bdvd_dir = g_cfg_vfs.get(g_cfg_vfs.dev_bdvd, rpcs3::utils::get_emu_dir()); + + if (!fs::is_dir(bdvd_dir) || !std::filesystem::is_empty(bdvd_dir)) + { + sys_log.error("Failed to load disc game from dev_hdd0. The virtual bdvd_dir path does not exist or the directory is not empty: '%s'", bdvd_dir); + return game_boot_result::invalid_bdvd_folder; + } + + vfs::mount("/dev_bdvd", bdvd_dir); vfs::mount("/dev_bdvd/PS3_GAME", hdd0_game + m_path.substr(hdd0_game.size(), 10)); sys_log.notice("Game: %s", vfs::get("/dev_bdvd/PS3_GAME")); } diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index f45b9dab62..831eeb17f8 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -40,6 +40,7 @@ enum class game_boot_result : u32 nothing_to_boot, wrong_disc_location, invalid_file_or_folder, + invalid_bdvd_folder, install_failed, decryption_error, file_creation_error, diff --git a/rpcs3/Emu/vfs_config.h b/rpcs3/Emu/vfs_config.h index 86d965e6ea..74a0f0d880 100644 --- a/rpcs3/Emu/vfs_config.h +++ b/rpcs3/Emu/vfs_config.h @@ -15,7 +15,7 @@ struct cfg_vfs : cfg::node cfg::string dev_flash{ this, "/dev_flash/", "$(EmulatorDir)dev_flash/" }; cfg::string dev_flash2{ this, "/dev_flash2/", "$(EmulatorDir)dev_flash2/" }; cfg::string dev_flash3{ this, "/dev_flash3/", "$(EmulatorDir)dev_flash3/" }; - cfg::string dev_bdvd{ this, "/dev_bdvd/" }; // Not mounted + cfg::string dev_bdvd{ this, "/dev_bdvd/", "$(EmulatorDir)dev_bdvd/" }; // Only mounted in some special cases cfg::string app_home{ this, "/app_home/" }; // Not mounted cfg::device_entry dev_usb{ this, "/dev_usb***/", diff --git a/rpcs3/rpcs3qt/gui_settings.h b/rpcs3/rpcs3qt/gui_settings.h index 59d9680f62..49f2a1471f 100644 --- a/rpcs3/rpcs3qt/gui_settings.h +++ b/rpcs3/rpcs3qt/gui_settings.h @@ -183,6 +183,7 @@ namespace gui const gui_save fs_dev_flash_list = gui_save(fs, "dev_flash_list", QStringList()); const gui_save fs_dev_flash2_list = gui_save(fs, "dev_flash2_list", QStringList()); const gui_save fs_dev_flash3_list = gui_save(fs, "dev_flash3_list", QStringList()); + const gui_save fs_dev_bdvd_list = gui_save(fs, "dev_bdvd_list", QStringList()); const gui_save fs_dev_usb_list = gui_save(fs, "dev_usb00X_list", QStringList()); // Used as a template for all usb paths const gui_save l_tty = gui_save(logger, "TTY", true); diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index db7cd6a087..39f7161c8b 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -376,6 +376,9 @@ void main_window::show_boot_error(game_boot_result status) case game_boot_result::invalid_file_or_folder: message = tr("The selected file or folder is invalid or corrupted."); break; + case game_boot_result::invalid_bdvd_folder: + message = tr("The virtual dev_bdvd folder does not exist or is not empty."); + break; case game_boot_result::install_failed: message = tr("Additional content could not be installed."); break; diff --git a/rpcs3/rpcs3qt/vfs_dialog.cpp b/rpcs3/rpcs3qt/vfs_dialog.cpp index c5ca2c454c..b9b6693bd3 100644 --- a/rpcs3/rpcs3qt/vfs_dialog.cpp +++ b/rpcs3/rpcs3qt/vfs_dialog.cpp @@ -32,6 +32,7 @@ vfs_dialog::vfs_dialog(std::shared_ptr _gui_settings, QWidget* par vfs_dialog_tab* dev_flash_tab = new vfs_dialog_tab("dev_flash", gui::fs_dev_flash_list, &g_cfg_vfs.dev_flash, m_gui_settings, this); vfs_dialog_tab* dev_flash2_tab = new vfs_dialog_tab("dev_flash2", gui::fs_dev_flash2_list, &g_cfg_vfs.dev_flash2, m_gui_settings, this); vfs_dialog_tab* dev_flash3_tab = new vfs_dialog_tab("dev_flash3", gui::fs_dev_flash3_list, &g_cfg_vfs.dev_flash3, m_gui_settings, this); + vfs_dialog_tab* dev_bdvd_tab = new vfs_dialog_tab("dev_bdvd", gui::fs_dev_bdvd_list, &g_cfg_vfs.dev_bdvd, m_gui_settings, this); vfs_dialog_usb_tab* dev_usb_tab = new vfs_dialog_usb_tab(&g_cfg_vfs.dev_usb, m_gui_settings, this); tabs->addTab(emulator_tab, "$(EmulatorDir)"); @@ -40,6 +41,7 @@ vfs_dialog::vfs_dialog(std::shared_ptr _gui_settings, QWidget* par tabs->addTab(dev_flash_tab, "dev_flash"); tabs->addTab(dev_flash2_tab, "dev_flash2"); tabs->addTab(dev_flash3_tab, "dev_flash3"); + tabs->addTab(dev_bdvd_tab, "dev_bdvd"); tabs->addTab(dev_usb_tab, "dev_usb"); // Create buttons