Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loader: Improve just-in-time installation of disc game files #10719

Merged
merged 3 commits into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions rpcs3/Emu/RSX/RSXThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,17 +1010,17 @@ namespace rsx
{
u32 offset_color[] =
{
rsx::method_registers.surface_a_offset(),
rsx::method_registers.surface_b_offset(),
rsx::method_registers.surface_c_offset(),
rsx::method_registers.surface_d_offset(),
rsx::method_registers.surface_offset(0),
rsx::method_registers.surface_offset(1),
rsx::method_registers.surface_offset(2),
rsx::method_registers.surface_offset(3),
};
u32 context_dma_color[] =
{
rsx::method_registers.surface_a_dma(),
rsx::method_registers.surface_b_dma(),
rsx::method_registers.surface_c_dma(),
rsx::method_registers.surface_d_dma(),
rsx::method_registers.surface_dma(0),
rsx::method_registers.surface_dma(1),
rsx::method_registers.surface_dma(2),
rsx::method_registers.surface_dma(3),
};
return
{
Expand Down Expand Up @@ -1064,10 +1064,10 @@ namespace rsx
layout.zeta_pitch = rsx::method_registers.surface_z_pitch();
layout.color_pitch =
{
rsx::method_registers.surface_a_pitch(),
rsx::method_registers.surface_b_pitch(),
rsx::method_registers.surface_c_pitch(),
rsx::method_registers.surface_d_pitch(),
rsx::method_registers.surface_pitch(0),
rsx::method_registers.surface_pitch(1),
rsx::method_registers.surface_pitch(2),
rsx::method_registers.surface_pitch(3),
};

layout.color_format = rsx::method_registers.surface_color();
Expand Down
75 changes: 24 additions & 51 deletions rpcs3/Emu/RSX/rsx_methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -1106,64 +1106,37 @@ namespace rsx
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();
}

u32 surface_b_offset() const
{
return decode<NV4097_SET_SURFACE_COLOR_BOFFSET>().surface_b_offset();
}

u32 surface_c_offset() const
{
return decode<NV4097_SET_SURFACE_COLOR_COFFSET>().surface_c_offset();
}

u32 surface_d_offset() const
{
return decode<NV4097_SET_SURFACE_COLOR_DOFFSET>().surface_d_offset();
}

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();
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_c_dma() const
u32 surface_pitch(u32 index) const
{
return decode<NV4097_SET_CONTEXT_DMA_COLOR_C>().dma_surface_c();
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_d_dma() const
u32 surface_dma(u32 index) const
{
return decode<NV4097_SET_CONTEXT_DMA_COLOR_D>().dma_surface_d();
switch (index)
{
case 0: return decode<NV4097_SET_CONTEXT_DMA_COLOR_A>().dma_surface_a();
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();
default: return decode<NV4097_SET_CONTEXT_DMA_COLOR_D>().dma_surface_d();
}
}

u32 surface_z_offset() const
Expand Down
54 changes: 38 additions & 16 deletions rpcs3/Emu/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ void Emulator::Init(bool add_only)
make_path_verbose(dev_hdd0 + "game/");
make_path_verbose(dev_hdd0 + "game/TEST12345/");
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/"));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@elad335
The dollar sign seems wrong.
Shouldn't be $ than $?
then no need the u8 cast.

Copy link
Contributor Author

@elad335 elad335 Aug 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some VFS trick to hide files from emulation.

make_path_verbose(dev_hdd0 + "home/");
make_path_verbose(dev_hdd0 + "home/" + m_usr + "/");
make_path_verbose(dev_hdd0 + "home/" + m_usr + "/exdata/");
Expand Down Expand Up @@ -1015,21 +1015,40 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
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
if (!bdvd_dir.empty())
{
const std::string ins_dir = vfs::get("/dev_bdvd/PS3_GAME/INSDIR/");
const 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 ins_dir = vfs::get("/dev_bdvd/PS3_GAME/INSDIR/");
std::string pkg_dir = vfs::get("/dev_bdvd/PS3_GAME/PKGDIR/");
std::string extra_dir = vfs::get("/dev_bdvd/PS3_GAME/PS3_EXTRA/");
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
lock_file.open(hdd0_game + ".locks/" + m_title_id, fs::read + fs::create + fs::excl);
if (!fs::is_dir(*path_ptr))
{
path_ptr->clear();
}
}

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 && fs::is_dir(ins_dir))
if (!lock_file && !ins_dir.empty())
{
sys_log.notice("Found INSDIR: %s", ins_dir);

Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -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
Expand All @@ -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);
}

// Set title to actual disc title if necessary
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))
if (!disc_psf_obj.empty())
{
const auto psf_obj = psf::load_object(fs::file{ disc_sfo_dir });
const auto bdvd_title = psf::get_string(psf_obj, "TITLE");
const auto bdvd_title = psf::get_string(disc_psf_obj, "TITLE");

if (!bdvd_title.empty() && bdvd_title != m_title)
{
Expand Down