diff options
| author | 2021-06-29 00:10:31 -0400 | |
|---|---|---|
| committer | 2021-06-29 00:10:31 -0400 | |
| commit | 39be4c302630e6e11a4ee08587d69bc41ce44caf (patch) | |
| tree | 5fc6e24ea6ed777e48489260925684964c154381 /src/core | |
| parent | Merge pull request #6502 from ameerj/vendor-title (diff) | |
| parent | patch_manager: Do not apply LayeredFS mods when dumping (diff) | |
| download | yuzu-39be4c302630e6e11a4ee08587d69bc41ce44caf.tar.gz yuzu-39be4c302630e6e11a4ee08587d69bc41ce44caf.tar.xz yuzu-39be4c302630e6e11a4ee08587d69bc41ce44caf.zip | |
Merge pull request #6471 from lat9nq/dump-as-mod
yuzu qt, core: Support LayeredFS mods from SDMC directory
Diffstat (limited to 'src/core')
| -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 |
6 files changed, 66 insertions, 23 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 | ||