diff options
| author | 2023-09-06 09:12:49 -0400 | |
|---|---|---|
| committer | 2023-09-06 09:12:49 -0400 | |
| commit | 70790711d24ec212048841f8f5367832ab00b789 (patch) | |
| tree | 28dd932a9813426124e15ce6d7ce8a7266e6ce55 | |
| parent | Merge pull request #11451 from german77/mob_mii (diff) | |
| parent | qt: measure romfs dump completion by bytes read (diff) | |
| download | yuzu-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.cpp | 76 |
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 | ||
| 2278 | static std::size_t CalculateRomFSEntrySize(const FileSys::VirtualDir& dir, bool full) { | 2278 | static 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 | |||
| 2288 | static 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.")); |