summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/yuzu/main.cpp113
-rw-r--r--src/yuzu/main.h3
2 files changed, 65 insertions, 51 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 33c9fd0af..81dfbca22 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2573,50 +2573,41 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
2573 return; 2573 return;
2574 } 2574 }
2575 2575
2576 FileSys::VirtualFile base_romfs; 2576 FileSys::VirtualFile packed_update_raw{};
2577 if (loader->ReadRomFS(base_romfs) != Loader::ResultStatus::Success) { 2577 loader->ReadUpdateRaw(packed_update_raw);
2578 failed();
2579 return;
2580 }
2581 2578
2582 const auto& installed = system->GetContentProvider(); 2579 const auto& installed = system->GetContentProvider();
2583 const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
2584 2580
2585 if (!romfs_title_id) { 2581 u64 title_id{};
2582 u8 raw_type{};
2583 if (!SelectRomFSDumpTarget(installed, program_id, &title_id, &raw_type)) {
2586 failed(); 2584 failed();
2587 return; 2585 return;
2588 } 2586 }
2589 2587
2590 const auto type = *romfs_title_id == program_id ? FileSys::ContentRecordType::Program 2588 const auto type = static_cast<FileSys::ContentRecordType>(raw_type);
2591 : FileSys::ContentRecordType::Data; 2589 const auto base_nca = installed.GetEntry(title_id, type);
2592 const auto base_nca = installed.GetEntry(*romfs_title_id, type);
2593 if (!base_nca) { 2590 if (!base_nca) {
2594 failed(); 2591 failed();
2595 return; 2592 return;
2596 } 2593 }
2597 2594
2595 const auto base_romfs = base_nca->GetRomFS();
2596 if (!base_romfs) {
2597 failed();
2598 return;
2599 }
2600
2598 const auto dump_dir = 2601 const auto dump_dir =
2599 target == DumpRomFSTarget::Normal 2602 target == DumpRomFSTarget::Normal
2600 ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir) 2603 ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)
2601 : Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "atmosphere" / "contents"; 2604 : Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "atmosphere" / "contents";
2602 const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id); 2605 const auto romfs_dir = fmt::format("{:016X}/romfs", title_id);
2603 2606
2604 const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir); 2607 const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir);
2605 2608
2606 FileSys::VirtualFile romfs; 2609 const FileSys::PatchManager pm{title_id, system->GetFileSystemController(), installed};
2607 2610 auto romfs = pm.PatchRomFS(base_nca.get(), base_romfs, type, packed_update_raw, false);
2608 if (*romfs_title_id == program_id) {
2609 const FileSys::PatchManager pm{program_id, system->GetFileSystemController(), installed};
2610 romfs = pm.PatchRomFS(base_nca.get(), base_romfs, type, nullptr, false);
2611 } else {
2612 romfs = installed.GetEntry(*romfs_title_id, type)->GetRomFS();
2613 }
2614
2615 const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full);
2616 if (extracted == nullptr) {
2617 failed();
2618 return;
2619 }
2620 2611
2621 const auto out = VfsFilesystemCreateDirectoryWrapper(vfs, path, FileSys::Mode::ReadWrite); 2612 const auto out = VfsFilesystemCreateDirectoryWrapper(vfs, path, FileSys::Mode::ReadWrite);
2622 2613
@@ -2640,6 +2631,12 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
2640 return; 2631 return;
2641 } 2632 }
2642 2633
2634 const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full);
2635 if (extracted == nullptr) {
2636 failed();
2637 return;
2638 }
2639
2643 const auto full = res == selections.constFirst(); 2640 const auto full = res == selections.constFirst();
2644 const auto entry_size = CalculateRomFSEntrySize(extracted, full); 2641 const auto entry_size = CalculateRomFSEntrySize(extracted, full);
2645 2642
@@ -4350,28 +4347,41 @@ bool GMainWindow::CheckSystemArchiveDecryption() {
4350 return mii_nca->GetRomFS().get() != nullptr; 4347 return mii_nca->GetRomFS().get() != nullptr;
4351} 4348}
4352 4349
4353std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, 4350bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id,
4354 u64 program_id) { 4351 u64* selected_title_id, u8* selected_content_record_type) {
4355 const auto dlc_entries = 4352 using ContentInfo = std::pair<FileSys::TitleType, FileSys::ContentRecordType>;
4356 installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); 4353 boost::container::flat_map<u64, ContentInfo> available_title_ids;
4357 std::vector<FileSys::ContentProviderEntry> dlc_match; 4354
4358 dlc_match.reserve(dlc_entries.size()); 4355 const auto RetrieveEntries = [&](FileSys::TitleType title_type,
4359 std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match), 4356 FileSys::ContentRecordType record_type) {
4360 [&program_id, &installed](const FileSys::ContentProviderEntry& entry) { 4357 const auto entries = installed.ListEntriesFilter(title_type, record_type);
4361 return FileSys::GetBaseTitleID(entry.title_id) == program_id && 4358 for (const auto& entry : entries) {
4362 installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success; 4359 if (FileSys::GetBaseTitleID(entry.title_id) == program_id &&
4363 }); 4360 installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success) {
4364 4361 available_title_ids[entry.title_id] = {title_type, record_type};
4365 std::vector<u64> romfs_tids; 4362 }
4366 romfs_tids.push_back(program_id); 4363 }
4367 for (const auto& entry : dlc_match) { 4364 };
4368 romfs_tids.push_back(entry.title_id); 4365
4369 } 4366 RetrieveEntries(FileSys::TitleType::Application, FileSys::ContentRecordType::Program);
4370 4367 RetrieveEntries(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
4371 if (romfs_tids.size() > 1) { 4368
4372 QStringList list{QStringLiteral("Base")}; 4369 if (available_title_ids.empty()) {
4373 for (std::size_t i = 1; i < romfs_tids.size(); ++i) { 4370 return false;
4374 list.push_back(QStringLiteral("DLC %1").arg(romfs_tids[i] & 0x7FF)); 4371 }
4372
4373 size_t title_index = 0;
4374
4375 if (available_title_ids.size() > 1) {
4376 QStringList list;
4377 for (auto& [title_id, content_info] : available_title_ids) {
4378 const auto hex_title_id = QString::fromStdString(fmt::format("{:X}", title_id));
4379 if (content_info.first == FileSys::TitleType::Application) {
4380 list.push_back(QStringLiteral("Application [%1]").arg(hex_title_id));
4381 } else {
4382 list.push_back(
4383 QStringLiteral("DLC %1 [%2]").arg(title_id & 0x7FF).arg(hex_title_id));
4384 }
4375 } 4385 }
4376 4386
4377 bool ok; 4387 bool ok;
@@ -4379,13 +4389,16 @@ std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProv
4379 this, tr("Select RomFS Dump Target"), 4389 this, tr("Select RomFS Dump Target"),
4380 tr("Please select which RomFS you would like to dump."), list, 0, false, &ok); 4390 tr("Please select which RomFS you would like to dump."), list, 0, false, &ok);
4381 if (!ok) { 4391 if (!ok) {
4382 return {}; 4392 return false;
4383 } 4393 }
4384 4394
4385 return romfs_tids[list.indexOf(res)]; 4395 title_index = list.indexOf(res);
4386 } 4396 }
4387 4397
4388 return program_id; 4398 const auto selected_info = available_title_ids.nth(title_index);
4399 *selected_title_id = selected_info->first;
4400 *selected_content_record_type = static_cast<u8>(selected_info->second.second);
4401 return true;
4389} 4402}
4390 4403
4391bool GMainWindow::ConfirmClose() { 4404bool GMainWindow::ConfirmClose() {
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 1b7055122..668dbc3b1 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -375,7 +375,8 @@ private:
375 void RemoveAllTransferableShaderCaches(u64 program_id); 375 void RemoveAllTransferableShaderCaches(u64 program_id);
376 void RemoveCustomConfiguration(u64 program_id, const std::string& game_path); 376 void RemoveCustomConfiguration(u64 program_id, const std::string& game_path);
377 void RemoveCacheStorage(u64 program_id); 377 void RemoveCacheStorage(u64 program_id);
378 std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id); 378 bool SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id,
379 u64* selected_title_id, u8* selected_content_record_type);
379 InstallResult InstallNSPXCI(const QString& filename); 380 InstallResult InstallNSPXCI(const QString& filename);
380 InstallResult InstallNCA(const QString& filename); 381 InstallResult InstallNCA(const QString& filename);
381 void MigrateConfigFiles(); 382 void MigrateConfigFiles();