mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
Loader: Improve just-in-time installation of disc game files (#10719)
* rsx: Indexed access to surface attributes
This commit is contained in:
parent
c13a46b07b
commit
fcfeac818f
3 changed files with 74 additions and 79 deletions
|
@ -1010,17 +1010,17 @@ namespace rsx
|
||||||
{
|
{
|
||||||
u32 offset_color[] =
|
u32 offset_color[] =
|
||||||
{
|
{
|
||||||
rsx::method_registers.surface_a_offset(),
|
rsx::method_registers.surface_offset(0),
|
||||||
rsx::method_registers.surface_b_offset(),
|
rsx::method_registers.surface_offset(1),
|
||||||
rsx::method_registers.surface_c_offset(),
|
rsx::method_registers.surface_offset(2),
|
||||||
rsx::method_registers.surface_d_offset(),
|
rsx::method_registers.surface_offset(3),
|
||||||
};
|
};
|
||||||
u32 context_dma_color[] =
|
u32 context_dma_color[] =
|
||||||
{
|
{
|
||||||
rsx::method_registers.surface_a_dma(),
|
rsx::method_registers.surface_dma(0),
|
||||||
rsx::method_registers.surface_b_dma(),
|
rsx::method_registers.surface_dma(1),
|
||||||
rsx::method_registers.surface_c_dma(),
|
rsx::method_registers.surface_dma(2),
|
||||||
rsx::method_registers.surface_d_dma(),
|
rsx::method_registers.surface_dma(3),
|
||||||
};
|
};
|
||||||
return
|
return
|
||||||
{
|
{
|
||||||
|
@ -1064,10 +1064,10 @@ namespace rsx
|
||||||
layout.zeta_pitch = rsx::method_registers.surface_z_pitch();
|
layout.zeta_pitch = rsx::method_registers.surface_z_pitch();
|
||||||
layout.color_pitch =
|
layout.color_pitch =
|
||||||
{
|
{
|
||||||
rsx::method_registers.surface_a_pitch(),
|
rsx::method_registers.surface_pitch(0),
|
||||||
rsx::method_registers.surface_b_pitch(),
|
rsx::method_registers.surface_pitch(1),
|
||||||
rsx::method_registers.surface_c_pitch(),
|
rsx::method_registers.surface_pitch(2),
|
||||||
rsx::method_registers.surface_d_pitch(),
|
rsx::method_registers.surface_pitch(3),
|
||||||
};
|
};
|
||||||
|
|
||||||
layout.color_format = rsx::method_registers.surface_color();
|
layout.color_format = rsx::method_registers.surface_color();
|
||||||
|
|
|
@ -1106,64 +1106,37 @@ namespace rsx
|
||||||
return decode<NV4097_SET_SURFACE_CLIP_VERTICAL>().height();
|
return decode<NV4097_SET_SURFACE_CLIP_VERTICAL>().height();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 surface_a_offset() const
|
u32 surface_offset(u32 index) const
|
||||||
{
|
{
|
||||||
return decode<NV4097_SET_SURFACE_COLOR_AOFFSET>().surface_a_offset();
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return decode<NV4097_SET_SURFACE_COLOR_AOFFSET>().surface_a_offset();
|
||||||
|
case 1: return decode<NV4097_SET_SURFACE_COLOR_BOFFSET>().surface_b_offset();
|
||||||
|
case 2: return decode<NV4097_SET_SURFACE_COLOR_COFFSET>().surface_c_offset();
|
||||||
|
default: return decode<NV4097_SET_SURFACE_COLOR_DOFFSET>().surface_d_offset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 surface_b_offset() const
|
u32 surface_pitch(u32 index) const
|
||||||
{
|
{
|
||||||
return decode<NV4097_SET_SURFACE_COLOR_BOFFSET>().surface_b_offset();
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return decode<NV4097_SET_SURFACE_PITCH_A>().surface_a_pitch();
|
||||||
|
case 1: return decode<NV4097_SET_SURFACE_PITCH_B>().surface_b_pitch();
|
||||||
|
case 2: return decode<NV4097_SET_SURFACE_PITCH_C>().surface_c_pitch();
|
||||||
|
default: return decode<NV4097_SET_SURFACE_PITCH_D>().surface_d_pitch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 surface_c_offset() const
|
u32 surface_dma(u32 index) const
|
||||||
{
|
{
|
||||||
return decode<NV4097_SET_SURFACE_COLOR_COFFSET>().surface_c_offset();
|
switch (index)
|
||||||
}
|
{
|
||||||
|
case 0: return decode<NV4097_SET_CONTEXT_DMA_COLOR_A>().dma_surface_a();
|
||||||
u32 surface_d_offset() const
|
case 1: return decode<NV4097_SET_CONTEXT_DMA_COLOR_B>().dma_surface_b();
|
||||||
{
|
case 2: return decode<NV4097_SET_CONTEXT_DMA_COLOR_C>().dma_surface_c();
|
||||||
return decode<NV4097_SET_SURFACE_COLOR_DOFFSET>().surface_d_offset();
|
default: return decode<NV4097_SET_CONTEXT_DMA_COLOR_D>().dma_surface_d();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 surface_a_pitch() const
|
|
||||||
{
|
|
||||||
return decode<NV4097_SET_SURFACE_PITCH_A>().surface_a_pitch();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 surface_b_pitch() const
|
|
||||||
{
|
|
||||||
return decode<NV4097_SET_SURFACE_PITCH_B>().surface_b_pitch();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 surface_c_pitch() const
|
|
||||||
{
|
|
||||||
return decode<NV4097_SET_SURFACE_PITCH_C>().surface_c_pitch();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 surface_d_pitch() const
|
|
||||||
{
|
|
||||||
return decode<NV4097_SET_SURFACE_PITCH_D>().surface_d_pitch();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 surface_a_dma() const
|
|
||||||
{
|
|
||||||
return decode<NV4097_SET_CONTEXT_DMA_COLOR_A>().dma_surface_a();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 surface_b_dma() const
|
|
||||||
{
|
|
||||||
return decode<NV4097_SET_CONTEXT_DMA_COLOR_B>().dma_surface_b();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 surface_c_dma() const
|
|
||||||
{
|
|
||||||
return decode<NV4097_SET_CONTEXT_DMA_COLOR_C>().dma_surface_c();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 surface_d_dma() const
|
|
||||||
{
|
|
||||||
return decode<NV4097_SET_CONTEXT_DMA_COLOR_D>().dma_surface_d();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 surface_z_offset() const
|
u32 surface_z_offset() const
|
||||||
|
|
|
@ -205,7 +205,7 @@ void Emulator::Init(bool add_only)
|
||||||
make_path_verbose(dev_hdd0 + "game/");
|
make_path_verbose(dev_hdd0 + "game/");
|
||||||
make_path_verbose(dev_hdd0 + "game/TEST12345/");
|
make_path_verbose(dev_hdd0 + "game/TEST12345/");
|
||||||
make_path_verbose(dev_hdd0 + "game/TEST12345/USRDIR/");
|
make_path_verbose(dev_hdd0 + "game/TEST12345/USRDIR/");
|
||||||
make_path_verbose(dev_hdd0 + "game/.locks/");
|
make_path_verbose(dev_hdd0 + reinterpret_cast<const char*>(u8"game/$locks/"));
|
||||||
make_path_verbose(dev_hdd0 + "home/");
|
make_path_verbose(dev_hdd0 + "home/");
|
||||||
make_path_verbose(dev_hdd0 + "home/" + m_usr + "/");
|
make_path_verbose(dev_hdd0 + "home/" + m_usr + "/");
|
||||||
make_path_verbose(dev_hdd0 + "home/" + m_usr + "/exdata/");
|
make_path_verbose(dev_hdd0 + "home/" + m_usr + "/exdata/");
|
||||||
|
@ -1015,21 +1015,40 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||||
return game_boot_result::no_errors;
|
return game_boot_result::no_errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set title to actual disc title if necessary
|
||||||
|
const std::string disc_sfo_dir = vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO");
|
||||||
|
|
||||||
|
const auto disc_psf_obj = psf::load_object(fs::file{ disc_sfo_dir });
|
||||||
|
|
||||||
// Install PKGDIR, INSDIR, PS3_EXTRA
|
// Install PKGDIR, INSDIR, PS3_EXTRA
|
||||||
if (!bdvd_dir.empty())
|
if (!bdvd_dir.empty())
|
||||||
{
|
{
|
||||||
const std::string ins_dir = vfs::get("/dev_bdvd/PS3_GAME/INSDIR/");
|
std::string ins_dir = vfs::get("/dev_bdvd/PS3_GAME/INSDIR/");
|
||||||
const std::string pkg_dir = vfs::get("/dev_bdvd/PS3_GAME/PKGDIR/");
|
std::string pkg_dir = vfs::get("/dev_bdvd/PS3_GAME/PKGDIR/");
|
||||||
const std::string extra_dir = vfs::get("/dev_bdvd/PS3_GAME/PS3_EXTRA/");
|
std::string extra_dir = vfs::get("/dev_bdvd/PS3_GAME/PS3_EXTRA/");
|
||||||
fs::file lock_file;
|
fs::file lock_file;
|
||||||
|
|
||||||
if (fs::is_dir(ins_dir) || fs::is_dir(pkg_dir) || fs::is_dir(extra_dir))
|
for (const auto path_ptr : {&ins_dir, &pkg_dir, &extra_dir})
|
||||||
{
|
{
|
||||||
// Create lock file to prevent double installation
|
if (!fs::is_dir(*path_ptr))
|
||||||
lock_file.open(hdd0_game + ".locks/" + m_title_id, fs::read + fs::create + fs::excl);
|
{
|
||||||
|
path_ptr->clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock_file && fs::is_dir(ins_dir))
|
const std::string lock_file_path = fmt::format("%s%s%s_v%s", hdd0_game, u8"$locks/", m_title_id, psf::get_string(disc_psf_obj, "APP_VER"));
|
||||||
|
|
||||||
|
if (!ins_dir.empty() || !pkg_dir.empty() || !extra_dir.empty())
|
||||||
|
{
|
||||||
|
// For backwards compatibility
|
||||||
|
if (!lock_file.open(hdd0_game + ".locks/" + m_title_id))
|
||||||
|
{
|
||||||
|
// Check if already installed
|
||||||
|
lock_file.open(lock_file_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lock_file && !ins_dir.empty())
|
||||||
{
|
{
|
||||||
sys_log.notice("Found INSDIR: %s", ins_dir);
|
sys_log.notice("Found INSDIR: %s", ins_dir);
|
||||||
|
|
||||||
|
@ -1044,7 +1063,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock_file && fs::is_dir(pkg_dir))
|
if (!lock_file && !pkg_dir.empty())
|
||||||
{
|
{
|
||||||
sys_log.notice("Found PKGDIR: %s", pkg_dir);
|
sys_log.notice("Found PKGDIR: %s", pkg_dir);
|
||||||
|
|
||||||
|
@ -1063,7 +1082,7 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock_file && fs::is_dir(extra_dir))
|
if (!lock_file && !extra_dir.empty())
|
||||||
{
|
{
|
||||||
sys_log.notice("Found PS3_EXTRA: %s", extra_dir);
|
sys_log.notice("Found PS3_EXTRA: %s", extra_dir);
|
||||||
|
|
||||||
|
@ -1081,6 +1100,13 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!lock_file)
|
||||||
|
{
|
||||||
|
// Create lock file to prevent double installation
|
||||||
|
// Do it after installation to prevent false positives when RPCS3 closed in the middle of the operation
|
||||||
|
lock_file.open(lock_file_path, fs::read + fs::create + fs::excl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check game updates
|
// Check game updates
|
||||||
|
@ -1093,13 +1119,9 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
|
||||||
return m_path = hdd0_boot, Load(m_title_id, false, force_global_config, true);
|
return m_path = hdd0_boot, Load(m_title_id, false, force_global_config, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set title to actual disc title if necessary
|
if (!disc_psf_obj.empty())
|
||||||
const std::string disc_sfo_dir = vfs::get("/dev_bdvd/PS3_GAME/PARAM.SFO");
|
|
||||||
|
|
||||||
if (!disc_sfo_dir.empty() && fs::is_file(disc_sfo_dir))
|
|
||||||
{
|
{
|
||||||
const auto psf_obj = psf::load_object(fs::file{ disc_sfo_dir });
|
const auto bdvd_title = psf::get_string(disc_psf_obj, "TITLE");
|
||||||
const auto bdvd_title = psf::get_string(psf_obj, "TITLE");
|
|
||||||
|
|
||||||
if (!bdvd_title.empty() && bdvd_title != m_title)
|
if (!bdvd_title.empty() && bdvd_title != m_title)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue