From 2025f02105b11d386eddbba7e049b5b0f6c67d8e Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 30 Jan 2021 16:18:10 +0100 Subject: [PATCH] Search for more game data directories. Also properly remove duplicate paths --- rpcs3/Emu/Cell/PPUThread.cpp | 25 +++++++++++------- rpcs3/Emu/System.cpp | 50 ++++++++++++++++++++++++++++++++++++ rpcs3/Emu/System.h | 3 +++ 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index ea65bf2600..2dcb8b79fb 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -5,6 +5,7 @@ #include "Crypto/unself.h" #include "Loader/ELF.h" #include "Loader/mself.hpp" +#include "Loader/PSF.h" #include "Emu/perf_meter.hpp" #include "Emu/Memory/vm_reservation.h" #include "Emu/Memory/vm_locking.h" @@ -2069,7 +2070,13 @@ extern void ppu_finalize(const ppu_module& info) extern void ppu_precompile(std::vector& dir_queue, std::vector* loaded_prx) { - // Remove duplicates + // Make sure we only have one '/' at the end and remove duplicates. + for (std::string& dir : dir_queue) + { + while (dir.back() == '/' || dir.back() == '\\') + dir.pop_back(); + dir += '/'; + } std::sort(dir_queue.begin(), dir_queue.end()); dir_queue.erase(std::unique(dir_queue.begin(), dir_queue.end()), dir_queue.end()); @@ -2230,6 +2237,9 @@ extern void ppu_precompile(std::vector& dir_queue, std::vector(utils::get_thread_count(), ::size32(file_queue)), [&] { + // Set low priority + thread_ctrl::scoped_priority low_prio(-1); + for (usz func_i = fnext++; func_i < file_queue.size(); func_i = fnext++, g_progr_fdone++) { if (Emu.IsStopped()) @@ -2265,7 +2275,7 @@ extern void ppu_precompile(std::vector& dir_queue, std::vector& dir_queue, std::vector dirs = Emu.GetGameDirs(); + dir_queue.insert(std::end(dir_queue), std::begin(dirs), std::end(dirs)); } ppu_precompile(dir_queue, &prx_list); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 5a071dd85d..1499371d6a 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -1110,6 +1110,10 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool } } + // Try to add all related directories + const std::set dirs = GetGameDirs(); + dir_queue.insert(std::end(dir_queue), std::begin(dirs), std::end(dirs)); + if (std::string path = m_path + "/USRDIR/EBOOT.BIN"; fs::is_file(path)) { // Compile EBOOT.BIN first @@ -2042,4 +2046,50 @@ void Emulator::ConfigurePPUCache() } } +std::set Emulator::GetGameDirs() const +{ + std::set dirs; + + // Add boot directory. + // For installed titles and disc titles with updates this is usually /dev_hdd0/game// + // For disc titles without updates this is /dev_bdvd/PS3_GAME/ + if (const std::string dir = vfs::get(GetDir()); !dir.empty()) + { + dirs.insert(dir + '/'); + } + + // Add more paths for disc titles. + if (const std::string dev_bdvd = vfs::get("/dev_bdvd/PS3_GAME"); + !dev_bdvd.empty() && !GetTitleID().empty()) + { + // Add the dev_bdvd dir if available. This is necessary for disc titles with installed updates. + dirs.insert(dev_bdvd + '/'); + + // Naive search for all matching game data dirs. + const std::string game_dir = vfs::get("/dev_hdd0/game/"); + for (auto&& entry : fs::dir(game_dir)) + { + if (entry.is_directory && entry.name.starts_with(GetTitleID())) + { + const std::string sfo_dir = game_dir + entry.name + '/'; + const fs::file sfo_file(sfo_dir + "PARAM.SFO"); + if (!sfo_file) + { + continue; + } + + const psf::registry psf = psf::load_object(sfo_file); + const std::string title_id = std::string(psf::get_string(psf, "TITLE_ID", "")); + + if (title_id == GetTitleID()) + { + dirs.insert(sfo_dir); + } + } + } + } + + return dirs; +} + Emulator Emu; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index a2ba4118f5..e833848f1d 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -6,6 +6,7 @@ #include #include #include +#include u64 get_system_time(); u64 get_guest_system_time(); @@ -242,6 +243,8 @@ public: void ConfigureLogs(); void ConfigurePPUCache(); + std::set GetGameDirs() const; + private: void LimitCacheSize(); };