This commit is contained in:
Vishrut Sachan 2026-04-21 10:17:30 +05:30 committed by GitHub
commit d9da050b33
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 56 additions and 16 deletions

View file

@ -9,6 +9,7 @@ struct GameInfo
std::string icon_path;
std::string movie_path;
std::string audio_path;
std::string game_dir;
std::string name;
std::string serial;

View file

@ -1492,9 +1492,9 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch,
// ISOs that are install discs will error if set to EBOOT.BIN
// so this should cover both of them
if (fs::exists(path + "PS3_GAME/USRDIR/EBOOT.BIN"))
if (fs::exists(path + m_game_dir + "/USRDIR/EBOOT.BIN"))
{
path = path + "PS3_GAME/USRDIR/EBOOT.BIN";
path = path + m_game_dir + "/USRDIR/EBOOT.BIN";
}
m_path_real = m_path;

View file

@ -215,6 +215,8 @@ public:
m_cb = std::move(cb);
}
void SetGameDir(const std::string& game_dir) { m_game_dir = game_dir; }
const auto& GetCallbacks() const
{
return m_cb;

View file

@ -142,6 +142,7 @@ public:
iso_archive(const std::string& path);
const std::string& path() const { return m_path; }
const iso_fs_node& root() const { return m_root; }
const std::shared_ptr<iso_file_decryption> get_dec() { return m_dec; }
iso_fs_node* retrieve(const std::string& path);

View file

@ -34,7 +34,7 @@ namespace
namespace iso_cache
{
bool load(const std::string& iso_path, iso_metadata_cache_entry& out_entry)
bool load(const std::string& iso_path, const std::string& cache_key, iso_metadata_cache_entry& out_entry)
{
fs::stat_t iso_stat{};
if (!fs::get_stat(iso_path, iso_stat) || iso_stat.is_directory)
@ -42,7 +42,7 @@ namespace iso_cache
return false;
}
const std::string stem = get_cache_stem(iso_path);
const std::string stem = get_cache_stem(cache_key);
const std::string dir = get_cache_dir();
const std::string yml_path = dir + stem + ".yml";
const std::string sfo_path = dir + stem + ".sfo";
@ -89,11 +89,9 @@ namespace iso_cache
return true;
}
void save(const std::string& iso_path, const iso_metadata_cache_entry& entry)
void save(const std::string& iso_path, const std::string& cache_key, const iso_metadata_cache_entry& entry)
{
iso_cache_log.notice("Saving cache for '%s'", iso_path);
const std::string stem = get_cache_stem(iso_path);
const std::string stem = get_cache_stem(cache_key);
const std::string dir = get_cache_dir();
const std::string yml_path = dir + stem + ".yml";
const std::string sfo_path = dir + stem + ".sfo";

View file

@ -22,10 +22,10 @@ struct iso_metadata_cache_entry
namespace iso_cache
{
// Returns false if no valid cache entry exists or mtime has changed.
bool load(const std::string& iso_path, iso_metadata_cache_entry& out_entry);
bool load(const std::string& iso_path, const std::string& cache_key, iso_metadata_cache_entry& out_entry);
// Persists a populated cache entry to disk.
void save(const std::string& iso_path, const iso_metadata_cache_entry& entry);
void save(const std::string& iso_path, const std::string& cache_key, const iso_metadata_cache_entry& entry);
// Remove cache entries for ISOs that are no longer in the scanned set.
void cleanup(const std::unordered_set<std::string>& valid_iso_paths);

View file

@ -546,17 +546,19 @@ void game_list_frame::OnParsingFinished()
const auto add_game = [this, localized_title, localized_icon, localized_movie, dev_flash, game_icon_path, _hdd,
cat_unknown_localized = localized.category.unknown.toStdString(), cat_unknown = cat::cat_unknown.toStdString(),
play_hover_movies = m_play_hover_movies, play_hover_music = m_play_hover_music, show_custom_icons = m_show_custom_icons]
(const std::string& dir_or_elf)
(const std::string& dir_or_elf, const std::string& game_dir = "PS3_GAME")
{
std::unique_ptr<iso_archive> archive;
iso_metadata_cache_entry cache_entry{};
const bool is_iso = is_file_iso(dir_or_elf);
std::string iso_cache_key;
if (is_iso)
{
const std::string iso_cache_key = (game_dir == "PS3_GAME") ? dir_or_elf : dir_or_elf + "|" + game_dir;
// Only construct iso_archive (which walks the full directory tree)
// when no valid cache entry exists for this ISO path + mtime.
if (!iso_cache::load(dir_or_elf, cache_entry))
if (!iso_cache::load(dir_or_elf, iso_cache_key, cache_entry))
{
archive = std::make_unique<iso_archive>(dir_or_elf);
}
@ -576,10 +578,11 @@ void game_list_frame::OnParsingFinished()
gui_game_info game{};
game.info.path = dir_or_elf;
game.info.game_dir = (game_dir == "PS3_GAME") ? "" : game_dir;
const Localized thread_localized;
const std::string sfo_dir = (archive || !cache_entry.psf_data.empty()) ? "PS3_GAME" : rpcs3::utils::get_sfo_dir_from_game_path(dir_or_elf);
const std::string sfo_dir = (archive || !cache_entry.psf_data.empty()) ? game_dir : rpcs3::utils::get_sfo_dir_from_game_path(dir_or_elf);
const std::string sfo_path = sfo_dir + "/PARAM.SFO";
// Load PSF: from archive on cache miss, rehydrate from cached SFO bytes on hit.
@ -762,7 +765,7 @@ void game_list_frame::OnParsingFinished()
}
}
iso_cache::save(dir_or_elf, cache_entry);
iso_cache::save(dir_or_elf, (game_dir == "PS3_GAME") ? dir_or_elf : dir_or_elf + "|" + game_dir, cache_entry);
}
}
@ -888,7 +891,38 @@ void game_list_frame::OnParsingFinished()
}
else if (is_file_iso(entry.path))
{
push_path(entry.path, legit_paths);
iso_archive archive(entry.path);
const iso_fs_node& root = archive.root();
const std::regex ps3_gm_regex("^PS3_GM[[:digit:]]{2}$");
bool found = false;
for (const auto& child : root.children)
{
if (m_refresh_watcher.isCanceled())
{
break;
}
if (!child->metadata.is_directory)
{
continue;
}
const std::string& name = child->metadata.name;
if (name == "PS3_GAME" || std::regex_match(name, ps3_gm_regex))
{
add_game(entry.path, name);
found = true;
}
}
if (!found)
{
add_game(entry.path);
}
return;
}
else
{

View file

@ -3685,6 +3685,10 @@ void main_window::CreateDockWindows()
connect(m_game_list_frame, &game_list_frame::RequestBoot, this, [this](const game_info& game, cfg_mode config_mode, const std::string& config_path, const std::string& savestate)
{
if (!game->info.game_dir.empty())
{
Emu.SetGameDir(game->info.game_dir);
}
Boot(savestate.empty() ? game->info.path : savestate, game->info.serial, false, false, config_mode, config_path);
});

View file

@ -712,7 +712,7 @@ namespace gui
// Check cache first — avoids constructing a full iso_archive just for the icon.
iso_metadata_cache_entry cache_entry{};
if (iso_cache::load(archive_path, cache_entry) && !cache_entry.icon_data.empty())
if (iso_cache::load(archive_path, archive_path, cache_entry) && !cache_entry.icon_data.empty())
{
const QByteArray data(reinterpret_cast<const char*>(cache_entry.icon_data.data()),
static_cast<qsizetype>(cache_entry.icon_data.size()));