From b8d1d7cdf18a0545b5745cea9be902141a0270b1 Mon Sep 17 00:00:00 2001 From: Antonino Di Guardo <64427768+digant73@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:14:54 +0200 Subject: [PATCH] Fix game list update for auto-detection VFS games folder (#17051) --- rpcs3/Emu/System.cpp | 25 +++++++++++++++++++++++++ rpcs3/Emu/System.h | 1 + rpcs3/rpcs3qt/game_list_frame.cpp | 19 +++---------------- rpcs3/rpcs3qt/vfs_dialog.cpp | 12 ++++++++++++ 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 77f98c4798..1e994d829a 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -4139,6 +4139,31 @@ game_boot_result Emulator::AddGameToYml(const std::string& path) return game_boot_result::invalid_file_or_folder; } +u32 Emulator::RemoveGamesFromDir(const std::string& games_dir, const std::vector& serials_to_remove_from_yml, bool save_on_disk) +{ + // List of serials (title id) to remove in "games.yml" file (if any) + std::vector serials_to_remove = serials_to_remove_from_yml; // Initialize the list with the specified serials (if any) + + if (!games_dir.empty()) // Skip an empty folder, otherwise we'll remove all games (which is not the intention) + { + // Scan game list to detect the titles belonging to auto-detection "games_dir" folder + for (const auto& [serial, path] : Emu.GetGamesConfig().get_games()) // Loop on game list file + { + // NOTE: Used starts_with(games_dir) instead of Emu.IsPathInsideDir(path, games_dir) due the latter would check + // also the existence of the paths + // + if (path.starts_with(games_dir)) // If game path belongs to auto-detection "games_dir" folder, add the serial to the removal list + { + serials_to_remove.push_back(serial); + } + } + } + + // Remove the specified and detected serials (title id) belonging to "games_dir" from the game list in memory + // or also in "games.yml" file according to the value of "save_on_disk" + return RemoveGames(serials_to_remove, save_on_disk); +} + u32 Emulator::RemoveGames(const std::vector& title_id_list, bool save_on_disk) { if (title_id_list.empty()) diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 4306fe9658..036215870f 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -454,6 +454,7 @@ public: u32 AddGamesFromDir(const std::string& path); game_boot_result AddGame(const std::string& path); game_boot_result AddGameToYml(const std::string& path); + u32 RemoveGamesFromDir(const std::string& games_dir, const std::vector& serials_to_remove_from_yml = {}, bool save_on_disk = true); u32 RemoveGames(const std::vector& title_id_list, bool save_on_disk = true); game_boot_result RemoveGameFromYml(const std::string& title_id); diff --git a/rpcs3/rpcs3qt/game_list_frame.cpp b/rpcs3/rpcs3qt/game_list_frame.cpp index 4399137600..58430bc3b1 100644 --- a/rpcs3/rpcs3qt/game_list_frame.cpp +++ b/rpcs3/rpcs3qt/game_list_frame.cpp @@ -419,22 +419,9 @@ void game_list_frame::Refresh(const bool from_drive, const std::vector serials_to_remove = serials_to_remove_from_yml; // Initialize the list with the specified serials (if any) - - // Scan game list to detect the titles belonging to auto-detection "games" folder - for (const auto& [serial, path] : Emu.GetGamesConfig().get_games()) // Loop on game list file - { - // NOTE: Used starts_with(games_dir) instead of Emu.IsPathInsideDir(path, games_dir) due the latter would check also the existence of the paths - // - if (path.starts_with(games_dir)) // If game path belongs to auto-detection "games" folder, add the serial to the removal list - { - serials_to_remove.push_back(serial); - } - } - - // Remove the specified and detected serials (title id) only from the game list in memory (not yet in "games.yml" file) - Emu.RemoveGames(serials_to_remove, false); + // Remove the specified and detected serials (title id) belonging to "games_dir" folder only from the game list in memory + // (not yet in "games.yml" file) + Emu.RemoveGamesFromDir(games_dir, serials_to_remove_from_yml, false); // Scan auto-detection "games" folder adding the detected titles to the game list plus flushing also all the other changes in "games.yml" file if (const u32 games_added = Emu.AddGamesFromDir(games_dir); games_added != 0) diff --git a/rpcs3/rpcs3qt/vfs_dialog.cpp b/rpcs3/rpcs3qt/vfs_dialog.cpp index 5a79e2fe8b..9a22017437 100644 --- a/rpcs3/rpcs3qt/vfs_dialog.cpp +++ b/rpcs3/rpcs3qt/vfs_dialog.cpp @@ -10,6 +10,7 @@ #include #include "Emu/System.h" +#include "Emu/system_utils.hpp" #include "Emu/vfs_config.h" vfs_dialog::vfs_dialog(std::shared_ptr _gui_settings, QWidget* parent) @@ -76,6 +77,17 @@ vfs_dialog::vfs_dialog(std::shared_ptr _gui_settings, QWidget* par { static_cast(tabs->widget(i))->set_settings(); } + else if (tabs->tabText(i) == "games") + { + // Check if the games folder changed. If changed, reconciliate the game list for the old folder before setting the new one + if (const std::string games_dir = rpcs3::utils::get_games_dir(); games_dir != static_cast(tabs->widget(i))->get_selected_path()) + { + // Remove the detected serials (title id) belonging to old folder from the game list in memory and also in "games.yml" file + Emu.RemoveGamesFromDir(games_dir); + } + + static_cast(tabs->widget(i))->set_settings(); // set new folder + } else { static_cast(tabs->widget(i))->set_settings();