diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/file_sys/patch_manager.cpp | 24 | ||||
| -rw-r--r-- | src/core/file_sys/patch_manager.h | 3 | ||||
| -rw-r--r-- | src/core/file_sys/sdmc_factory.cpp | 31 | ||||
| -rw-r--r-- | src/core/file_sys/sdmc_factory.h | 6 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.h | 1 | ||||
| -rw-r--r-- | src/yuzu/game_list.cpp | 12 | ||||
| -rw-r--r-- | src/yuzu/game_list.h | 7 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 11 | ||||
| -rw-r--r-- | src/yuzu/main.h | 3 |
10 files changed, 91 insertions, 31 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 53b8b7ca0..7c0950bb0 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -345,8 +345,10 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList( | |||
| 345 | static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type, | 345 | static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type, |
| 346 | const Service::FileSystem::FileSystemController& fs_controller) { | 346 | const Service::FileSystem::FileSystemController& fs_controller) { |
| 347 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); | 347 | const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); |
| 348 | const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); | ||
| 348 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || | 349 | if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || |
| 349 | load_dir == nullptr || load_dir->GetSize() <= 0) { | 350 | ((load_dir == nullptr || load_dir->GetSize() <= 0) && |
| 351 | (sdmc_load_dir == nullptr || sdmc_load_dir->GetSize() <= 0))) { | ||
| 350 | return; | 352 | return; |
| 351 | } | 353 | } |
| 352 | 354 | ||
| @@ -356,7 +358,10 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||
| 356 | } | 358 | } |
| 357 | 359 | ||
| 358 | const auto& disabled = Settings::values.disabled_addons[title_id]; | 360 | const auto& disabled = Settings::values.disabled_addons[title_id]; |
| 359 | auto patch_dirs = load_dir->GetSubdirectories(); | 361 | std::vector<VirtualDir> patch_dirs = load_dir->GetSubdirectories(); |
| 362 | if (std::find(disabled.cbegin(), disabled.cend(), "SDMC") == disabled.cend()) { | ||
| 363 | patch_dirs.push_back(sdmc_load_dir); | ||
| 364 | } | ||
| 360 | std::sort(patch_dirs.begin(), patch_dirs.end(), | 365 | std::sort(patch_dirs.begin(), patch_dirs.end(), |
| 361 | [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); | 366 | [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); |
| 362 | 367 | ||
| @@ -402,7 +407,7 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||
| 402 | } | 407 | } |
| 403 | 408 | ||
| 404 | VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type, | 409 | VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type, |
| 405 | VirtualFile update_raw) const { | 410 | VirtualFile update_raw, bool apply_layeredfs) const { |
| 406 | const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}", | 411 | const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}", |
| 407 | title_id, static_cast<u8>(type)); | 412 | title_id, static_cast<u8>(type)); |
| 408 | 413 | ||
| @@ -442,7 +447,9 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content | |||
| 442 | } | 447 | } |
| 443 | 448 | ||
| 444 | // LayeredFS | 449 | // LayeredFS |
| 445 | ApplyLayeredFS(romfs, title_id, type, fs_controller); | 450 | if (apply_layeredfs) { |
| 451 | ApplyLayeredFS(romfs, title_id, type, fs_controller); | ||
| 452 | } | ||
| 446 | 453 | ||
| 447 | return romfs; | 454 | return romfs; |
| 448 | } | 455 | } |
| @@ -524,6 +531,15 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 524 | } | 531 | } |
| 525 | } | 532 | } |
| 526 | 533 | ||
| 534 | // SDMC mod directory (RomFS LayeredFS) | ||
| 535 | const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); | ||
| 536 | if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0 && | ||
| 537 | IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs"))) { | ||
| 538 | const auto mod_disabled = | ||
| 539 | std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end(); | ||
| 540 | out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", "LayeredFS"); | ||
| 541 | } | ||
| 542 | |||
| 527 | // DLC | 543 | // DLC |
| 528 | const auto dlc_entries = | 544 | const auto dlc_entries = |
| 529 | content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); | 545 | content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); |
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index fb1853035..3be871f35 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h | |||
| @@ -64,7 +64,8 @@ public: | |||
| 64 | // - LayeredFS | 64 | // - LayeredFS |
| 65 | [[nodiscard]] VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, | 65 | [[nodiscard]] VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, |
| 66 | ContentRecordType type = ContentRecordType::Program, | 66 | ContentRecordType type = ContentRecordType::Program, |
| 67 | VirtualFile update_raw = nullptr) const; | 67 | VirtualFile update_raw = nullptr, |
| 68 | bool apply_layeredfs = true) const; | ||
| 68 | 69 | ||
| 69 | // Returns a vector of pairs between patch names and patch versions. | 70 | // Returns a vector of pairs between patch names and patch versions. |
| 70 | // i.e. Update 3.2.2 will return {"Update", "3.2.2"} | 71 | // i.e. Update 3.2.2 will return {"Update", "3.2.2"} |
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index cb56d8f2d..e5c72cd4d 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp | |||
| @@ -12,23 +12,32 @@ namespace FileSys { | |||
| 12 | 12 | ||
| 13 | constexpr u64 SDMC_TOTAL_SIZE = 0x10000000000; // 1 TiB | 13 | constexpr u64 SDMC_TOTAL_SIZE = 0x10000000000; // 1 TiB |
| 14 | 14 | ||
| 15 | SDMCFactory::SDMCFactory(VirtualDir dir_) | 15 | SDMCFactory::SDMCFactory(VirtualDir sd_dir_, VirtualDir sd_mod_dir_) |
| 16 | : dir(std::move(dir_)), contents(std::make_unique<RegisteredCache>( | 16 | : sd_dir(std::move(sd_dir_)), sd_mod_dir(std::move(sd_mod_dir_)), |
| 17 | GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/registered"), | 17 | contents(std::make_unique<RegisteredCache>( |
| 18 | [](const VirtualFile& file, const NcaID& id) { | 18 | GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Contents/registered"), |
| 19 | return NAX{file, id}.GetDecrypted(); | 19 | [](const VirtualFile& file, const NcaID& id) { |
| 20 | })), | 20 | return NAX{file, id}.GetDecrypted(); |
| 21 | })), | ||
| 21 | placeholder(std::make_unique<PlaceholderCache>( | 22 | placeholder(std::make_unique<PlaceholderCache>( |
| 22 | GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/placehld"))) {} | 23 | GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Contents/placehld"))) {} |
| 23 | 24 | ||
| 24 | SDMCFactory::~SDMCFactory() = default; | 25 | SDMCFactory::~SDMCFactory() = default; |
| 25 | 26 | ||
| 26 | ResultVal<VirtualDir> SDMCFactory::Open() const { | 27 | ResultVal<VirtualDir> SDMCFactory::Open() const { |
| 27 | return MakeResult<VirtualDir>(dir); | 28 | return MakeResult<VirtualDir>(sd_dir); |
| 29 | } | ||
| 30 | |||
| 31 | VirtualDir SDMCFactory::GetSDMCModificationLoadRoot(u64 title_id) const { | ||
| 32 | // LayeredFS doesn't work on updates and title id-less homebrew | ||
| 33 | if (title_id == 0 || (title_id & 0xFFF) == 0x800) { | ||
| 34 | return nullptr; | ||
| 35 | } | ||
| 36 | return GetOrCreateDirectoryRelative(sd_mod_dir, fmt::format("/{:016X}", title_id)); | ||
| 28 | } | 37 | } |
| 29 | 38 | ||
| 30 | VirtualDir SDMCFactory::GetSDMCContentDirectory() const { | 39 | VirtualDir SDMCFactory::GetSDMCContentDirectory() const { |
| 31 | return GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents"); | 40 | return GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Contents"); |
| 32 | } | 41 | } |
| 33 | 42 | ||
| 34 | RegisteredCache* SDMCFactory::GetSDMCContents() const { | 43 | RegisteredCache* SDMCFactory::GetSDMCContents() const { |
| @@ -40,11 +49,11 @@ PlaceholderCache* SDMCFactory::GetSDMCPlaceholder() const { | |||
| 40 | } | 49 | } |
| 41 | 50 | ||
| 42 | VirtualDir SDMCFactory::GetImageDirectory() const { | 51 | VirtualDir SDMCFactory::GetImageDirectory() const { |
| 43 | return GetOrCreateDirectoryRelative(dir, "/Nintendo/Album"); | 52 | return GetOrCreateDirectoryRelative(sd_dir, "/Nintendo/Album"); |
| 44 | } | 53 | } |
| 45 | 54 | ||
| 46 | u64 SDMCFactory::GetSDMCFreeSpace() const { | 55 | u64 SDMCFactory::GetSDMCFreeSpace() const { |
| 47 | return GetSDMCTotalSpace() - dir->GetSize(); | 56 | return GetSDMCTotalSpace() - sd_dir->GetSize(); |
| 48 | } | 57 | } |
| 49 | 58 | ||
| 50 | u64 SDMCFactory::GetSDMCTotalSpace() const { | 59 | u64 SDMCFactory::GetSDMCTotalSpace() const { |
diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index 2bb92ba93..3a3d11f3a 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h | |||
| @@ -16,11 +16,12 @@ class PlaceholderCache; | |||
| 16 | /// File system interface to the SDCard archive | 16 | /// File system interface to the SDCard archive |
| 17 | class SDMCFactory { | 17 | class SDMCFactory { |
| 18 | public: | 18 | public: |
| 19 | explicit SDMCFactory(VirtualDir dir); | 19 | explicit SDMCFactory(VirtualDir sd_dir_, VirtualDir sd_mod_dir_); |
| 20 | ~SDMCFactory(); | 20 | ~SDMCFactory(); |
| 21 | 21 | ||
| 22 | ResultVal<VirtualDir> Open() const; | 22 | ResultVal<VirtualDir> Open() const; |
| 23 | 23 | ||
| 24 | VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const; | ||
| 24 | VirtualDir GetSDMCContentDirectory() const; | 25 | VirtualDir GetSDMCContentDirectory() const; |
| 25 | 26 | ||
| 26 | RegisteredCache* GetSDMCContents() const; | 27 | RegisteredCache* GetSDMCContents() const; |
| @@ -32,7 +33,8 @@ public: | |||
| 32 | u64 GetSDMCTotalSpace() const; | 33 | u64 GetSDMCTotalSpace() const; |
| 33 | 34 | ||
| 34 | private: | 35 | private: |
| 35 | VirtualDir dir; | 36 | VirtualDir sd_dir; |
| 37 | VirtualDir sd_mod_dir; | ||
| 36 | 38 | ||
| 37 | std::unique_ptr<RegisteredCache> contents; | 39 | std::unique_ptr<RegisteredCache> contents; |
| 38 | std::unique_ptr<PlaceholderCache> placeholder; | 40 | std::unique_ptr<PlaceholderCache> placeholder; |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 3c16fe6c7..4a9b13e45 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -703,6 +703,16 @@ FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id) | |||
| 703 | return bis_factory->GetModificationLoadRoot(title_id); | 703 | return bis_factory->GetModificationLoadRoot(title_id); |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | FileSys::VirtualDir FileSystemController::GetSDMCModificationLoadRoot(u64 title_id) const { | ||
| 707 | LOG_TRACE(Service_FS, "Opening SDMC mod load root for tid={:016X}", title_id); | ||
| 708 | |||
| 709 | if (sdmc_factory == nullptr) { | ||
| 710 | return nullptr; | ||
| 711 | } | ||
| 712 | |||
| 713 | return sdmc_factory->GetSDMCModificationLoadRoot(title_id); | ||
| 714 | } | ||
| 715 | |||
| 706 | FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const { | 716 | FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const { |
| 707 | LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id); | 717 | LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id); |
| 708 | 718 | ||
| @@ -733,20 +743,23 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove | |||
| 733 | } | 743 | } |
| 734 | 744 | ||
| 735 | using YuzuPath = Common::FS::YuzuPath; | 745 | using YuzuPath = Common::FS::YuzuPath; |
| 746 | const auto sdmc_dir_path = Common::FS::GetYuzuPath(YuzuPath::SDMCDir); | ||
| 747 | const auto sdmc_load_dir_path = sdmc_dir_path / "atmosphere/contents"; | ||
| 736 | const auto rw_mode = FileSys::Mode::ReadWrite; | 748 | const auto rw_mode = FileSys::Mode::ReadWrite; |
| 737 | 749 | ||
| 738 | auto nand_directory = | 750 | auto nand_directory = |
| 739 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode); | 751 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode); |
| 740 | auto sd_directory = | 752 | auto sd_directory = vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_dir_path), rw_mode); |
| 741 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::SDMCDir), rw_mode); | ||
| 742 | auto load_directory = | 753 | auto load_directory = |
| 743 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), FileSys::Mode::Read); | 754 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), FileSys::Mode::Read); |
| 755 | auto sd_load_directory = | ||
| 756 | vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_load_dir_path), FileSys::Mode::Read); | ||
| 744 | auto dump_directory = | 757 | auto dump_directory = |
| 745 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode); | 758 | vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode); |
| 746 | 759 | ||
| 747 | if (bis_factory == nullptr) { | 760 | if (bis_factory == nullptr) { |
| 748 | bis_factory = | 761 | bis_factory = std::make_unique<FileSys::BISFactory>( |
| 749 | std::make_unique<FileSys::BISFactory>(nand_directory, load_directory, dump_directory); | 762 | nand_directory, std::move(load_directory), std::move(dump_directory)); |
| 750 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SysNAND, | 763 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SysNAND, |
| 751 | bis_factory->GetSystemNANDContents()); | 764 | bis_factory->GetSystemNANDContents()); |
| 752 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::UserNAND, | 765 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::UserNAND, |
| @@ -759,7 +772,8 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove | |||
| 759 | } | 772 | } |
| 760 | 773 | ||
| 761 | if (sdmc_factory == nullptr) { | 774 | if (sdmc_factory == nullptr) { |
| 762 | sdmc_factory = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory)); | 775 | sdmc_factory = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory), |
| 776 | std::move(sd_load_directory)); | ||
| 763 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SDMC, | 777 | system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SDMC, |
| 764 | sdmc_factory->GetSDMCContents()); | 778 | sdmc_factory->GetSDMCContents()); |
| 765 | } | 779 | } |
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index b6b1b9220..d387af3cb 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h | |||
| @@ -115,6 +115,7 @@ public: | |||
| 115 | FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const; | 115 | FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const; |
| 116 | FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const; | 116 | FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const; |
| 117 | 117 | ||
| 118 | FileSys::VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const; | ||
| 118 | FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const; | 119 | FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const; |
| 119 | FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const; | 120 | FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const; |
| 120 | 121 | ||
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index da956c99b..e44907be8 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -521,7 +521,9 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri | |||
| 521 | QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration")); | 521 | QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration")); |
| 522 | remove_menu->addSeparator(); | 522 | remove_menu->addSeparator(); |
| 523 | QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents")); | 523 | QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents")); |
| 524 | QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS")); | 524 | QMenu* dump_romfs_menu = context_menu.addMenu(tr("Dump RomFS")); |
| 525 | QAction* dump_romfs = dump_romfs_menu->addAction(tr("Dump RomFS")); | ||
| 526 | QAction* dump_romfs_sdmc = dump_romfs_menu->addAction(tr("Dump RomFS to SDMC")); | ||
| 525 | QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); | 527 | QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); |
| 526 | QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry")); | 528 | QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry")); |
| 527 | context_menu.addSeparator(); | 529 | context_menu.addSeparator(); |
| @@ -570,8 +572,12 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri | |||
| 570 | connect(remove_custom_config, &QAction::triggered, [this, program_id, path]() { | 572 | connect(remove_custom_config, &QAction::triggered, [this, program_id, path]() { |
| 571 | emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration, path); | 573 | emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration, path); |
| 572 | }); | 574 | }); |
| 573 | connect(dump_romfs, &QAction::triggered, | 575 | connect(dump_romfs, &QAction::triggered, [this, program_id, path]() { |
| 574 | [this, program_id, path]() { emit DumpRomFSRequested(program_id, path); }); | 576 | emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::Normal); |
| 577 | }); | ||
| 578 | connect(dump_romfs_sdmc, &QAction::triggered, [this, program_id, path]() { | ||
| 579 | emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::SDMC); | ||
| 580 | }); | ||
| 575 | connect(copy_tid, &QAction::triggered, | 581 | connect(copy_tid, &QAction::triggered, |
| 576 | [this, program_id]() { emit CopyTIDRequested(program_id); }); | 582 | [this, program_id]() { emit CopyTIDRequested(program_id); }); |
| 577 | connect(navigate_to_gamedb_entry, &QAction::triggered, [this, program_id]() { | 583 | connect(navigate_to_gamedb_entry, &QAction::triggered, [this, program_id]() { |
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index b630e34ff..50402da51 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h | |||
| @@ -45,6 +45,11 @@ enum class GameListRemoveTarget { | |||
| 45 | CustomConfiguration, | 45 | CustomConfiguration, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | enum class DumpRomFSTarget { | ||
| 49 | Normal, | ||
| 50 | SDMC, | ||
| 51 | }; | ||
| 52 | |||
| 48 | enum class InstalledEntryType { | 53 | enum class InstalledEntryType { |
| 49 | Game, | 54 | Game, |
| 50 | Update, | 55 | Update, |
| @@ -92,7 +97,7 @@ signals: | |||
| 92 | void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type); | 97 | void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type); |
| 93 | void RemoveFileRequested(u64 program_id, GameListRemoveTarget target, | 98 | void RemoveFileRequested(u64 program_id, GameListRemoveTarget target, |
| 94 | const std::string& game_path); | 99 | const std::string& game_path); |
| 95 | void DumpRomFSRequested(u64 program_id, const std::string& game_path); | 100 | void DumpRomFSRequested(u64 program_id, const std::string& game_path, DumpRomFSTarget target); |
| 96 | void CopyTIDRequested(u64 program_id); | 101 | void CopyTIDRequested(u64 program_id); |
| 97 | void NavigateToGamedbEntryRequested(u64 program_id, | 102 | void NavigateToGamedbEntryRequested(u64 program_id, |
| 98 | const CompatibilityList& compatibility_list); | 103 | const CompatibilityList& compatibility_list); |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 7063327e8..f462cd072 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1882,7 +1882,8 @@ void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& g | |||
| 1882 | } | 1882 | } |
| 1883 | } | 1883 | } |
| 1884 | 1884 | ||
| 1885 | void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path) { | 1885 | void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path, |
| 1886 | DumpRomFSTarget target) { | ||
| 1886 | const auto failed = [this] { | 1887 | const auto failed = [this] { |
| 1887 | QMessageBox::warning(this, tr("RomFS Extraction Failed!"), | 1888 | QMessageBox::warning(this, tr("RomFS Extraction Failed!"), |
| 1888 | tr("There was an error copying the RomFS files or the user " | 1889 | tr("There was an error copying the RomFS files or the user " |
| @@ -1910,7 +1911,10 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 1910 | return; | 1911 | return; |
| 1911 | } | 1912 | } |
| 1912 | 1913 | ||
| 1913 | const auto dump_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir); | 1914 | const auto dump_dir = |
| 1915 | target == DumpRomFSTarget::Normal | ||
| 1916 | ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir) | ||
| 1917 | : Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "atmosphere" / "contents"; | ||
| 1914 | const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id); | 1918 | const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id); |
| 1915 | 1919 | ||
| 1916 | const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir); | 1920 | const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir); |
| @@ -1920,7 +1924,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | |||
| 1920 | if (*romfs_title_id == program_id) { | 1924 | if (*romfs_title_id == program_id) { |
| 1921 | const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); | 1925 | const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); |
| 1922 | const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed}; | 1926 | const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed}; |
| 1923 | romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program); | 1927 | romfs = |
| 1928 | pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program, nullptr, false); | ||
| 1924 | } else { | 1929 | } else { |
| 1925 | romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); | 1930 | romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); |
| 1926 | } | 1931 | } |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 5c199155a..45c8310e1 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -34,6 +34,7 @@ class QProgressDialog; | |||
| 34 | class WaitTreeWidget; | 34 | class WaitTreeWidget; |
| 35 | enum class GameListOpenTarget; | 35 | enum class GameListOpenTarget; |
| 36 | enum class GameListRemoveTarget; | 36 | enum class GameListRemoveTarget; |
| 37 | enum class DumpRomFSTarget; | ||
| 37 | enum class InstalledEntryType; | 38 | enum class InstalledEntryType; |
| 38 | class GameListPlaceholder; | 39 | class GameListPlaceholder; |
| 39 | 40 | ||
| @@ -244,7 +245,7 @@ private slots: | |||
| 244 | void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type); | 245 | void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type); |
| 245 | void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target, | 246 | void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target, |
| 246 | const std::string& game_path); | 247 | const std::string& game_path); |
| 247 | void OnGameListDumpRomFS(u64 program_id, const std::string& game_path); | 248 | void OnGameListDumpRomFS(u64 program_id, const std::string& game_path, DumpRomFSTarget target); |
| 248 | void OnGameListCopyTID(u64 program_id); | 249 | void OnGameListCopyTID(u64 program_id); |
| 249 | void OnGameListNavigateToGamedbEntry(u64 program_id, | 250 | void OnGameListNavigateToGamedbEntry(u64 program_id, |
| 250 | const CompatibilityList& compatibility_list); | 251 | const CompatibilityList& compatibility_list); |