summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar liamwhite2023-09-06 09:12:49 -0400
committerGravatar GitHub2023-09-06 09:12:49 -0400
commit70790711d24ec212048841f8f5367832ab00b789 (patch)
tree28dd932a9813426124e15ce6d7ce8a7266e6ce55
parentMerge pull request #11451 from german77/mob_mii (diff)
parentqt: measure romfs dump completion by bytes read (diff)
downloadyuzu-70790711d24ec212048841f8f5367832ab00b789.tar.gz
yuzu-70790711d24ec212048841f8f5367832ab00b789.tar.xz
yuzu-70790711d24ec212048841f8f5367832ab00b789.zip
Merge pull request #11437 from liamwhite/dump-shenanigans
qt: measure romfs dump completion by bytes read
-rw-r--r--src/yuzu/main.cpp76
1 files changed, 50 insertions, 26 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f2e6c03f0..4e435c7e2 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2275,40 +2275,62 @@ void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
2275 QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path)); 2275 QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
2276} 2276}
2277 2277
2278static std::size_t CalculateRomFSEntrySize(const FileSys::VirtualDir& dir, bool full) { 2278static bool RomFSRawCopy(size_t total_size, size_t& read_size, QProgressDialog& dialog,
2279 std::size_t out = 0; 2279 const FileSys::VirtualDir& src, const FileSys::VirtualDir& dest,
2280 2280 bool full) {
2281 for (const auto& subdir : dir->GetSubdirectories()) {
2282 out += 1 + CalculateRomFSEntrySize(subdir, full);
2283 }
2284
2285 return out + (full ? dir->GetFiles().size() : 0);
2286}
2287
2288static bool RomFSRawCopy(QProgressDialog& dialog, const FileSys::VirtualDir& src,
2289 const FileSys::VirtualDir& dest, std::size_t block_size, bool full) {
2290 if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable()) 2281 if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable())
2291 return false; 2282 return false;
2292 if (dialog.wasCanceled()) 2283 if (dialog.wasCanceled())
2293 return false; 2284 return false;
2294 2285
2286 std::vector<u8> buffer(CopyBufferSize);
2287 auto last_timestamp = std::chrono::steady_clock::now();
2288
2289 const auto QtRawCopy = [&](const FileSys::VirtualFile& src_file,
2290 const FileSys::VirtualFile& dest_file) {
2291 if (src_file == nullptr || dest_file == nullptr) {
2292 return false;
2293 }
2294 if (!dest_file->Resize(src_file->GetSize())) {
2295 return false;
2296 }
2297
2298 for (std::size_t i = 0; i < src_file->GetSize(); i += buffer.size()) {
2299 if (dialog.wasCanceled()) {
2300 dest_file->Resize(0);
2301 return false;
2302 }
2303
2304 using namespace std::literals::chrono_literals;
2305 const auto new_timestamp = std::chrono::steady_clock::now();
2306
2307 if ((new_timestamp - last_timestamp) > 33ms) {
2308 last_timestamp = new_timestamp;
2309 dialog.setValue(
2310 static_cast<int>(std::min(read_size, total_size) * 100 / total_size));
2311 QCoreApplication::processEvents();
2312 }
2313
2314 const auto read = src_file->Read(buffer.data(), buffer.size(), i);
2315 dest_file->Write(buffer.data(), read, i);
2316
2317 read_size += read;
2318 }
2319
2320 return true;
2321 };
2322
2295 if (full) { 2323 if (full) {
2296 for (const auto& file : src->GetFiles()) { 2324 for (const auto& file : src->GetFiles()) {
2297 const auto out = VfsDirectoryCreateFileWrapper(dest, file->GetName()); 2325 const auto out = VfsDirectoryCreateFileWrapper(dest, file->GetName());
2298 if (!FileSys::VfsRawCopy(file, out, block_size)) 2326 if (!QtRawCopy(file, out))
2299 return false;
2300 dialog.setValue(dialog.value() + 1);
2301 if (dialog.wasCanceled())
2302 return false; 2327 return false;
2303 } 2328 }
2304 } 2329 }
2305 2330
2306 for (const auto& dir : src->GetSubdirectories()) { 2331 for (const auto& dir : src->GetSubdirectories()) {
2307 const auto out = dest->CreateSubdirectory(dir->GetName()); 2332 const auto out = dest->CreateSubdirectory(dir->GetName());
2308 if (!RomFSRawCopy(dialog, dir, out, block_size, full)) 2333 if (!RomFSRawCopy(total_size, read_size, dialog, dir, out, full))
2309 return false;
2310 dialog.setValue(dialog.value() + 1);
2311 if (dialog.wasCanceled())
2312 return false; 2334 return false;
2313 } 2335 }
2314 2336
@@ -2653,10 +2675,9 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
2653 } 2675 }
2654 2676
2655 const auto full = res == selections.constFirst(); 2677 const auto full = res == selections.constFirst();
2656 const auto entry_size = CalculateRomFSEntrySize(extracted, full);
2657 2678
2658 // The minimum required space is the size of the extracted RomFS + 1 GiB 2679 // The expected required space is the size of the RomFS + 1 GiB
2659 const auto minimum_free_space = extracted->GetSize() + 0x40000000; 2680 const auto minimum_free_space = romfs->GetSize() + 0x40000000;
2660 2681
2661 if (full && Common::FS::GetFreeSpaceSize(path) < minimum_free_space) { 2682 if (full && Common::FS::GetFreeSpaceSize(path) < minimum_free_space) {
2662 QMessageBox::warning(this, tr("RomFS Extraction Failed!"), 2683 QMessageBox::warning(this, tr("RomFS Extraction Failed!"),
@@ -2667,12 +2688,15 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
2667 return; 2688 return;
2668 } 2689 }
2669 2690
2670 QProgressDialog progress(tr("Extracting RomFS..."), tr("Cancel"), 0, 2691 QProgressDialog progress(tr("Extracting RomFS..."), tr("Cancel"), 0, 100, this);
2671 static_cast<s32>(entry_size), this);
2672 progress.setWindowModality(Qt::WindowModal); 2692 progress.setWindowModality(Qt::WindowModal);
2673 progress.setMinimumDuration(100); 2693 progress.setMinimumDuration(100);
2694 progress.setAutoClose(false);
2695 progress.setAutoReset(false);
2696
2697 size_t read_size = 0;
2674 2698
2675 if (RomFSRawCopy(progress, extracted, out, 0x400000, full)) { 2699 if (RomFSRawCopy(romfs->GetSize(), read_size, progress, extracted, out, full)) {
2676 progress.close(); 2700 progress.close();
2677 QMessageBox::information(this, tr("RomFS Extraction Succeeded!"), 2701 QMessageBox::information(this, tr("RomFS Extraction Succeeded!"),
2678 tr("The operation completed successfully.")); 2702 tr("The operation completed successfully."));