Merge pull request #11437 from liamwhite/dump-shenanigans

qt: measure romfs dump completion by bytes read
This commit is contained in:
liamwhite 2023-09-06 09:12:49 -04:00 committed by GitHub
commit 70790711d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2275,40 +2275,62 @@ void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path)); QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
} }
static std::size_t CalculateRomFSEntrySize(const FileSys::VirtualDir& dir, bool full) { static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& dialog,
std::size_t out = 0; const FileSys::VirtualDir& src, const FileSys::VirtualDir& dest,
bool full) {
for (const auto& subdir : dir->GetSubdirectories()) {
out += 1 + CalculateRomFSEntrySize(subdir, full);
}
return out + (full ? dir->GetFiles().size() : 0);
}
static bool RomFSRawCopy(QProgressDialog& dialog, const FileSys::VirtualDir& src,
const FileSys::VirtualDir& dest, std::size_t block_size, bool full) {
if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable()) if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable())
return false; return false;
if (dialog.wasCanceled()) if (dialog.wasCanceled())
return false; return false;
std::vector<u8> buffer(CopyBufferSize);
auto last_timestamp = std::chrono::steady_clock::now();
const auto QtRawCopy = [&](const FileSys::VirtualFile& src_file,
const FileSys::VirtualFile& dest_file) {
if (src_file == nullptr || dest_file == nullptr) {
return false;
}
if (!dest_file->Resize(src_file->GetSize())) {
return false;
}
for (std::size_t i = 0; i < src_file->GetSize(); i += buffer.size()) {
if (dialog.wasCanceled()) {
dest_file->Resize(0);
return false;
}
using namespace std::literals::chrono_literals;
const auto new_timestamp = std::chrono::steady_clock::now();
if ((new_timestamp - last_timestamp) > 33ms) {
last_timestamp = new_timestamp;
dialog.setValue(
static_cast<int>(std::min(read_size, total_size) * 100 / total_size));
QCoreApplication::processEvents();
}
const auto read = src_file->Read(buffer.data(), buffer.size(), i);
dest_file->Write(buffer.data(), read, i);
read_size += read;
}
return true;
};
if (full) { if (full) {
for (const auto& file : src->GetFiles()) { for (const auto& file : src->GetFiles()) {
const auto out = VfsDirectoryCreateFileWrapper(dest, file->GetName()); const auto out = VfsDirectoryCreateFileWrapper(dest, file->GetName());
if (!FileSys::VfsRawCopy(file, out, block_size)) if (!QtRawCopy(file, out))
return false;
dialog.setValue(dialog.value() + 1);
if (dialog.wasCanceled())
return false; return false;
} }
} }
for (const auto& dir : src->GetSubdirectories()) { for (const auto& dir : src->GetSubdirectories()) {
const auto out = dest->CreateSubdirectory(dir->GetName()); const auto out = dest->CreateSubdirectory(dir->GetName());
if (!RomFSRawCopy(dialog, dir, out, block_size, full)) if (!RomFSRawCopy(total_size, read_size, dialog, dir, out, full))
return false;
dialog.setValue(dialog.value() + 1);
if (dialog.wasCanceled())
return false; return false;
} }
@ -2653,10 +2675,9 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
} }
const auto full = res == selections.constFirst(); const auto full = res == selections.constFirst();
const auto entry_size = CalculateRomFSEntrySize(extracted, full);
// The minimum required space is the size of the extracted RomFS + 1 GiB // The expected required space is the size of the RomFS + 1 GiB
const auto minimum_free_space = extracted->GetSize() + 0x40000000; const auto minimum_free_space = romfs->GetSize() + 0x40000000;
if (full && Common::FS::GetFreeSpaceSize(path) < minimum_free_space) { if (full && Common::FS::GetFreeSpaceSize(path) < minimum_free_space) {
QMessageBox::warning(this, tr("RomFS Extraction Failed!"), QMessageBox::warning(this, tr("RomFS Extraction Failed!"),
@ -2667,12 +2688,15 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
return; return;
} }
QProgressDialog progress(tr("Extracting RomFS..."), tr("Cancel"), 0, QProgressDialog progress(tr("Extracting RomFS..."), tr("Cancel"), 0, 100, this);
static_cast<s32>(entry_size), this);
progress.setWindowModality(Qt::WindowModal); progress.setWindowModality(Qt::WindowModal);
progress.setMinimumDuration(100); progress.setMinimumDuration(100);
progress.setAutoClose(false);
progress.setAutoReset(false);
if (RomFSRawCopy(progress, extracted, out, 0x400000, full)) { size_t read_size = 0;
if (RomFSRawCopy(romfs->GetSize(), read_size, progress, extracted, out, full)) {
progress.close(); progress.close();
QMessageBox::information(this, tr("RomFS Extraction Succeeded!"), QMessageBox::information(this, tr("RomFS Extraction Succeeded!"),
tr("The operation completed successfully.")); tr("The operation completed successfully."));