mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-10 01:59:41 +00:00
Simulate BSD FS for file order presentation in savedata
This commit is contained in:
parent
aaae437ca3
commit
8de1239132
1 changed files with 59 additions and 1 deletions
|
@ -813,6 +813,13 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||||
|
|
||||||
lv2_sleep(ppu, 250);
|
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
|
// Get save stats
|
||||||
{
|
{
|
||||||
fs::stat_t dir_info{};
|
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;
|
u32 size_kbytes = 0;
|
||||||
|
|
||||||
|
std::vector<fs::dir_entry> files_sorted;
|
||||||
|
|
||||||
for (auto&& entry : fs::dir(dir_path))
|
for (auto&& entry : fs::dir(dir_path))
|
||||||
{
|
{
|
||||||
entry.name = vfs::unescape(entry.name);
|
entry.name = vfs::unescape(entry.name);
|
||||||
|
|
||||||
// only files, system files ignored, fileNum is limited by setBuf->fileListMax
|
|
||||||
if (!entry.is_directory)
|
if (!entry.is_directory)
|
||||||
{
|
{
|
||||||
if (entry.name == "PARAM.SFO" || entry.name == "PARAM.PFD")
|
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
|
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++;
|
statGet->fileNum++;
|
||||||
|
|
||||||
size_kbytes += (entry.size + 1023) / 1024; // firmware rounds this value up
|
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);
|
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)
|
switch (const u32 op = fileSet->fileOperation)
|
||||||
{
|
{
|
||||||
case CELL_SAVEDATA_FILEOP_READ:
|
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);
|
file.trunc(sr + wr);
|
||||||
fileGet->excSize = ::narrow<u32>(wr);
|
fileGet->excSize = ::narrow<u32>(wr);
|
||||||
all_times.erase(file_path);
|
all_times.erase(file_path);
|
||||||
|
add_to_blist(file_path);
|
||||||
has_modified = true;
|
has_modified = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1195,6 +1246,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||||
psf.erase("*" + file_path);
|
psf.erase("*" + file_path);
|
||||||
fileGet->excSize = 0;
|
fileGet->excSize = 0;
|
||||||
all_times.erase(file_path);
|
all_times.erase(file_path);
|
||||||
|
del_from_blist(file_path);
|
||||||
has_modified = true;
|
has_modified = true;
|
||||||
break;
|
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);
|
const u64 wr = file.write(fileSet->fileBuf.get_ptr(), access_size);
|
||||||
fileGet->excSize = ::narrow<u32>(wr);
|
fileGet->excSize = ::narrow<u32>(wr);
|
||||||
all_times.erase(file_path);
|
all_times.erase(file_path);
|
||||||
|
add_to_blist(file_path);
|
||||||
has_modified = true;
|
has_modified = true;
|
||||||
break;
|
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);
|
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
|
// Write all files in temporary directory
|
||||||
auto& fsfo = all_files["PARAM.SFO"];
|
auto& fsfo = all_files["PARAM.SFO"];
|
||||||
fsfo = fs::make_stream<std::vector<uchar>>();
|
fsfo = fs::make_stream<std::vector<uchar>>();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue