summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/yuzu/main.cpp120
-rw-r--r--src/yuzu/main.h3
2 files changed, 72 insertions, 51 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 9ee7a5ee4..f2e6c03f0 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2581,50 +2581,48 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
2581 return; 2581 return;
2582 } 2582 }
2583 2583
2584 FileSys::VirtualFile base_romfs; 2584 FileSys::VirtualFile packed_update_raw{};
2585 if (loader->ReadRomFS(base_romfs) != Loader::ResultStatus::Success) { 2585 loader->ReadUpdateRaw(packed_update_raw);
2586 failed();
2587 return;
2588 }
2589 2586
2590 const auto& installed = system->GetContentProvider(); 2587 const auto& installed = system->GetContentProvider();
2591 const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
2592 2588
2593 if (!romfs_title_id) { 2589 u64 title_id{};
2590 u8 raw_type{};
2591 if (!SelectRomFSDumpTarget(installed, program_id, &title_id, &raw_type)) {
2594 failed(); 2592 failed();
2595 return; 2593 return;
2596 } 2594 }
2597 2595
2598 const auto type = *romfs_title_id == program_id ? FileSys::ContentRecordType::Program 2596 const auto type = static_cast<FileSys::ContentRecordType>(raw_type);
2599 : FileSys::ContentRecordType::Data; 2597 const auto base_nca = installed.GetEntry(title_id, type);
2600 const auto base_nca = installed.GetEntry(*romfs_title_id, type);
2601 if (!base_nca) { 2598 if (!base_nca) {
2602 failed(); 2599 failed();
2603 return; 2600 return;
2604 } 2601 }
2605 2602
2603 const FileSys::NCA update_nca{packed_update_raw, nullptr};
2604 if (type != FileSys::ContentRecordType::Program ||
2605 update_nca.GetStatus() != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS ||
2606 update_nca.GetTitleId() != FileSys::GetUpdateTitleID(title_id)) {
2607 packed_update_raw = {};
2608 }
2609
2610 const auto base_romfs = base_nca->GetRomFS();
2611 if (!base_romfs) {
2612 failed();
2613 return;
2614 }
2615
2606 const auto dump_dir = 2616 const auto dump_dir =
2607 target == DumpRomFSTarget::Normal 2617 target == DumpRomFSTarget::Normal
2608 ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir) 2618 ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)
2609 : Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "atmosphere" / "contents"; 2619 : Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "atmosphere" / "contents";
2610 const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id); 2620 const auto romfs_dir = fmt::format("{:016X}/romfs", title_id);
2611 2621
2612 const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir); 2622 const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir);
2613 2623
2614 FileSys::VirtualFile romfs; 2624 const FileSys::PatchManager pm{title_id, system->GetFileSystemController(), installed};
2615 2625 auto romfs = pm.PatchRomFS(base_nca.get(), base_romfs, type, packed_update_raw, false);
2616 if (*romfs_title_id == program_id) {
2617 const FileSys::PatchManager pm{program_id, system->GetFileSystemController(), installed};
2618 romfs = pm.PatchRomFS(base_nca.get(), base_romfs, type, nullptr, false);
2619 } else {
2620 romfs = installed.GetEntry(*romfs_title_id, type)->GetRomFS();
2621 }
2622
2623 const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full);
2624 if (extracted == nullptr) {
2625 failed();
2626 return;
2627 }
2628 2626
2629 const auto out = VfsFilesystemCreateDirectoryWrapper(vfs, path, FileSys::Mode::ReadWrite); 2627 const auto out = VfsFilesystemCreateDirectoryWrapper(vfs, path, FileSys::Mode::ReadWrite);
2630 2628
@@ -2648,6 +2646,12 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
2648 return; 2646 return;
2649 } 2647 }
2650 2648
2649 const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full);
2650 if (extracted == nullptr) {
2651 failed();
2652 return;
2653 }
2654
2651 const auto full = res == selections.constFirst(); 2655 const auto full = res == selections.constFirst();
2652 const auto entry_size = CalculateRomFSEntrySize(extracted, full); 2656 const auto entry_size = CalculateRomFSEntrySize(extracted, full);
2653 2657
@@ -4358,28 +4362,41 @@ bool GMainWindow::CheckSystemArchiveDecryption() {
4358 return mii_nca->GetRomFS().get() != nullptr; 4362 return mii_nca->GetRomFS().get() != nullptr;
4359} 4363}
4360 4364
4361std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, 4365bool GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed, u64 program_id,
4362 u64 program_id) { 4366 u64* selected_title_id, u8* selected_content_record_type) {
4363 const auto dlc_entries = 4367 using ContentInfo = std::pair<FileSys::TitleType, FileSys::ContentRecordType>;
4364 installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); 4368 boost::container::flat_map<u64, ContentInfo> available_title_ids;
4365 std::vector<FileSys::ContentProviderEntry> dlc_match; 4369
4366 dlc_match.reserve(dlc_entries.size()); 4370 const auto RetrieveEntries = [&](FileSys::TitleType title_type,
4367 std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match), 4371 FileSys::ContentRecordType record_type) {
4368 [&program_id, &installed](const FileSys::ContentProviderEntry& entry) { 4372 const auto entries = installed.ListEntriesFilter(title_type, record_type);
4369 return FileSys::GetBaseTitleID(entry.title_id) == program_id && 4373 for (const auto& entry : entries) {
4370 installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success; 4374 if (FileSys::GetBaseTitleID(entry.title_id) == program_id &&
4371 }); 4375 installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success) {
4372 4376 available_title_ids[entry.title_id] = {title_type, record_type};
4373 std::vector<u64> romfs_tids; 4377 }
4374 romfs_tids.push_back(program_id); 4378 }
4375 for (const auto& entry : dlc_match) { 4379 };
4376 romfs_tids.push_back(entry.title_id); 4380
4377 } 4381 RetrieveEntries(FileSys::TitleType::Application, FileSys::ContentRecordType::Program);
4378 4382 RetrieveEntries(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
4379 if (romfs_tids.size() > 1) { 4383
4380 QStringList list{QStringLiteral("Base")}; 4384 if (available_title_ids.empty()) {
4381 for (std::size_t i = 1; i < romfs_tids.size(); ++i) { 4385 return false;
4382 list.push_back(QStringLiteral("DLC %1").arg(romfs_tids[i] & 0x7FF)); 4386 }
4387
4388 size_t title_index = 0;
4389
4390 if (available_title_ids.size() > 1) {
4391 QStringList list;
4392 for (auto& [title_id, content_info] : available_title_ids) {
4393 const auto hex_title_id = QString::fromStdString(fmt::format("{:X}", title_id));
4394 if (content_info.first == FileSys::TitleType::Application) {
4395 list.push_back(QStringLiteral("Application [%1]").arg(hex_title_id));
4396 } else {
4397 list.push_back(
4398 QStringLiteral("DLC %1 [%2]").arg(title_id & 0x7FF).arg(hex_title_id));
4399 }
4383 } 4400 }
4384 4401
4385 bool ok; 4402 bool ok;
@@ -4387,13 +4404,16 @@ std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProv
4387 this, tr("Select RomFS Dump Target"), 4404 this, tr("Select RomFS Dump Target"),
4388 tr("Please select which RomFS you would like to dump."), list, 0, false, &ok); 4405 tr("Please select which RomFS you would like to dump."), list, 0, false, &ok);
4389 if (!ok) { 4406 if (!ok) {
4390 return {}; 4407 return false;
4391 } 4408 }
4392 4409
4393 return romfs_tids[list.indexOf(res)]; 4410 title_index = list.indexOf(res);
4394 } 4411 }
4395 4412
4396 return program_id; 4413 const auto selected_info = available_title_ids.nth(title_index);
4414 *selected_title_id = selected_info->first;
4415 *selected_content_record_type = static_cast<u8>(selected_info->second.second);
4416 return true;
4397} 4417}
4398 4418
4399bool GMainWindow::ConfirmClose() { 4419bool 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();