mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
Allow booting any ELF inside disc directory, not just ones at 'PS3_GAME/USRDIR/'
This commit is contained in:
parent
d63a712cc5
commit
ee7ed1fdc3
@ -896,7 +896,6 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
}
|
||||
|
||||
// Detect boot location
|
||||
constexpr usz game_dir_size = 8; // size of PS3_GAME and PS3_GMXX
|
||||
const std::string hdd0_game = vfs::get("/dev_hdd0/game/");
|
||||
const std::string hdd0_disc = vfs::get("/dev_hdd0/disc/");
|
||||
const bool from_hdd0_game = IsPathInsideDir(m_path, hdd0_game);
|
||||
@ -916,17 +915,38 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
// Mount /dev_bdvd/ if necessary
|
||||
if (bdvd_dir.empty() && disc.empty())
|
||||
{
|
||||
// Find /USRDIR position
|
||||
#ifdef _WIN32
|
||||
if (const usz usrdir_pos = std::max<usz>(elf_dir.rfind("/USRDIR"sv) + 1, elf_dir.rfind("\\USRDIR"sv) + 1) - 1; usrdir_pos != umax)
|
||||
#else
|
||||
if (const usz usrdir_pos = elf_dir.rfind("/USRDIR"); usrdir_pos != umax)
|
||||
#endif
|
||||
{
|
||||
const std::string main_dir = elf_dir.substr(0, usrdir_pos);
|
||||
// Find disc directory by searching a valid PS3_DISC.SFB closest to root directory
|
||||
std::string sfb_dir, main_dir;
|
||||
std::string_view main_dir_name;
|
||||
|
||||
if (const std::string sfb_dir = fs::get_parent_dir(main_dir);
|
||||
!sfb_dir.empty() && fs::is_file(sfb_dir + "/PS3_DISC.SFB"))
|
||||
for (std::string search_dir = elf_dir;;)
|
||||
{
|
||||
std::string parent_dir = fs::get_parent_dir(search_dir);
|
||||
|
||||
if (parent_dir.size() == search_dir.size())
|
||||
{
|
||||
// Keep looking until root directory is reached
|
||||
break;
|
||||
}
|
||||
|
||||
if (fs::file sfb_file{parent_dir + "/PS3_DISC.SFB"}; sfb_file && sfb_file.size() >= 4 && sfb_file.read<u32>() == ".SFB"_u32)
|
||||
{
|
||||
main_dir_name = std::string_view{search_dir}.substr(search_dir.find_last_of(fs::delim) + 1);
|
||||
|
||||
if (main_dir_name == "PS3_GAME" || std::regex_match(main_dir_name.begin(), main_dir_name.end(), std::regex("^PS3_GM[[:digit:]]{2}$")))
|
||||
{
|
||||
// Remember valid disc directory
|
||||
main_dir = search_dir;
|
||||
sfb_dir = parent_dir;
|
||||
main_dir_name = std::string_view{main_dir}.substr(main_dir.find_last_of(fs::delim) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
search_dir = std::move(parent_dir);
|
||||
}
|
||||
|
||||
if (!sfb_dir.empty())
|
||||
{
|
||||
{
|
||||
if (from_hdd0_game)
|
||||
{
|
||||
@ -948,19 +968,8 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
|
||||
bdvd_dir = sfb_dir + "/";
|
||||
|
||||
// Find game dir
|
||||
if (const std::string main_dir_name = main_dir.substr(main_dir.find_last_of(fs::delim) + 1);
|
||||
main_dir_name.size() == game_dir_size)
|
||||
{
|
||||
m_game_dir = main_dir_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show an error and reset game dir for now
|
||||
m_game_dir = "PS3_GAME";
|
||||
sys_log.error("Could not find proper game dir path for %s", elf_dir);
|
||||
return game_boot_result::unsupported_disc_type;
|
||||
}
|
||||
// Set game dir
|
||||
m_game_dir = std::string{main_dir_name};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1008,20 +1017,32 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
const auto game_psf = psf::load_object(fs::file{vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO")});
|
||||
const auto bdvd_title_id = psf::get_string(game_psf, "TITLE_ID");
|
||||
|
||||
if (bdvd_title_id != m_title_id)
|
||||
if (m_title_id.empty())
|
||||
{
|
||||
sys_log.error("Unexpected disc directory for the disc game %s (found %s)", m_title_id, bdvd_title_id);
|
||||
return game_boot_result::invalid_file_or_folder;
|
||||
// We are most likely booting a binary inside a disc directory
|
||||
sys_log.error("Booting binary without TITLE_ID inside disc dir of '%s'", bdvd_title_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bdvd_title_id != m_title_id)
|
||||
{
|
||||
// Not really an error just an odd situation
|
||||
sys_log.error("Unexpected PARAM.SFO found in disc directory '%s' (found '%s')", m_title_id, bdvd_title_id);
|
||||
}
|
||||
|
||||
// Store /dev_bdvd/ location
|
||||
games[m_title_id] = bdvd_dir;
|
||||
YAML::Emitter out;
|
||||
out << games;
|
||||
// Store /dev_bdvd/ location
|
||||
games[m_title_id] = bdvd_dir;
|
||||
YAML::Emitter out;
|
||||
out << games;
|
||||
|
||||
fs::pending_file temp(fs::get_config_dir() + "/games.yml");
|
||||
temp.file.write(out.c_str(), out.size());
|
||||
temp.commit();
|
||||
fs::pending_file temp(fs::get_config_dir() + "/games.yml");
|
||||
|
||||
// Do not update games.yml when TITLE_ID is empty
|
||||
if (!temp.file || temp.file.write(out.c_str(), out.size()), !temp.commit())
|
||||
{
|
||||
sys_log.error("Failed to save BDVD location of title '%s' (%s)", m_title_id, fs::g_tls_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_cat == "1P" && from_hdd0_game)
|
||||
{
|
||||
@ -1328,7 +1349,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||
{
|
||||
// Disc games are on /dev_bdvd/
|
||||
const usz pos = resolved_path.rfind(m_game_dir);
|
||||
argv[0] = "/dev_bdvd/PS3_GAME/" + unescape(resolved_path.substr(pos + game_dir_size + 1));
|
||||
argv[0] = "/dev_bdvd/PS3_GAME/" + unescape(resolved_path.substr(pos + m_game_dir.size() + 1));
|
||||
m_dir = "/dev_bdvd/PS3_GAME/";
|
||||
}
|
||||
else if (from_dev_flash)
|
||||
|
Loading…
Reference in New Issue
Block a user