mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-16 07:10:40 +00:00
Simulate BSD FS for file order presentation in savedata
This commit is contained in:
parent
aaae437ca3
commit
8de1239132
@ -813,6 +813,13 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
|
||||
lv2_sleep(ppu, 250);
|
||||
|
||||
// Check if RPCS3_BLIST section exist in PARAM.SFO
|
||||
// This section contains the list of files in the save ordered as they would be in BSD filesystem
|
||||
std::vector<std::string> blist;
|
||||
|
||||
if (psf.count("RPCS3_BLIST"))
|
||||
blist = fmt::split(psf.at("RPCS3_BLIST").as_string(), {"/"}, false);
|
||||
|
||||
// Get save stats
|
||||
{
|
||||
fs::stat_t dir_info{};
|
||||
@ -849,11 +856,12 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
|
||||
u32 size_kbytes = 0;
|
||||
|
||||
std::vector<fs::dir_entry> files_sorted;
|
||||
|
||||
for (auto&& entry : fs::dir(dir_path))
|
||||
{
|
||||
entry.name = vfs::unescape(entry.name);
|
||||
|
||||
// only files, system files ignored, fileNum is limited by setBuf->fileListMax
|
||||
if (!entry.is_directory)
|
||||
{
|
||||
if (entry.name == "PARAM.SFO" || entry.name == "PARAM.PFD")
|
||||
@ -861,6 +869,29 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
continue; // system files are not included in the file list
|
||||
}
|
||||
|
||||
files_sorted.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
std::sort(files_sorted.begin(), files_sorted.end(), [&](const fs::dir_entry& a, const fs::dir_entry& b) -> bool
|
||||
{
|
||||
const auto a_it = std::find(blist.begin(), blist.end(), a.name);
|
||||
const auto b_it = std::find(blist.begin(), blist.end(), b.name);
|
||||
|
||||
if (a_it == blist.end() && b_it == blist.end())
|
||||
{
|
||||
// Order alphabetically for old saves
|
||||
return a.name.compare(b.name);
|
||||
}
|
||||
|
||||
return a_it < b_it;
|
||||
});
|
||||
// clang-format on
|
||||
|
||||
for (auto&& entry : files_sorted)
|
||||
{
|
||||
{
|
||||
statGet->fileNum++;
|
||||
|
||||
size_kbytes += (entry.size + 1023) / 1024; // firmware rounds this value up
|
||||
@ -1135,6 +1166,25 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
|
||||
const u32 access_size = std::min<u32>(fileSet->fileSize, fileSet->fileBufSize);
|
||||
|
||||
// clang-format off
|
||||
auto add_to_blist = [&](const std::string& to_add)
|
||||
{
|
||||
if (std::find(blist.begin(), blist.end(), to_add) == blist.end())
|
||||
{
|
||||
if(auto it = std::find(blist.begin(), blist.end(), ""); it != blist.end())
|
||||
*it = to_add;
|
||||
else
|
||||
blist.push_back(to_add);
|
||||
}
|
||||
};
|
||||
|
||||
auto del_from_blist = [&](const std::string& to_del)
|
||||
{
|
||||
if (auto it = std::find(blist.begin(), blist.end(), to_del); it != blist.end())
|
||||
*it = "";
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
switch (const u32 op = fileSet->fileOperation)
|
||||
{
|
||||
case CELL_SAVEDATA_FILEOP_READ:
|
||||
@ -1184,6 +1234,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
file.trunc(sr + wr);
|
||||
fileGet->excSize = ::narrow<u32>(wr);
|
||||
all_times.erase(file_path);
|
||||
add_to_blist(file_path);
|
||||
has_modified = true;
|
||||
break;
|
||||
}
|
||||
@ -1195,6 +1246,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
psf.erase("*" + file_path);
|
||||
fileGet->excSize = 0;
|
||||
all_times.erase(file_path);
|
||||
del_from_blist(file_path);
|
||||
has_modified = true;
|
||||
break;
|
||||
}
|
||||
@ -1213,6 +1265,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
const u64 wr = file.write(fileSet->fileBuf.get_ptr(), access_size);
|
||||
fileGet->excSize = ::narrow<u32>(wr);
|
||||
all_times.erase(file_path);
|
||||
add_to_blist(file_path);
|
||||
has_modified = true;
|
||||
break;
|
||||
}
|
||||
@ -1238,6 +1291,11 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||
fmt::throw_exception("Failed to create directory %s (%s)", new_path, fs::g_tls_error);
|
||||
}
|
||||
|
||||
// add file list per FS order to PARAM.SFO
|
||||
std::string final_blist;
|
||||
final_blist = fmt::merge(blist, "/");
|
||||
psf::assign(psf, "RPCS3_BLIST", psf::string(final_blist.size(), final_blist));
|
||||
|
||||
// Write all files in temporary directory
|
||||
auto& fsfo = all_files["PARAM.SFO"];
|
||||
fsfo = fs::make_stream<std::vector<uchar>>();
|
||||
|
Loading…
Reference in New Issue
Block a user