diff options
| author | 2021-06-14 21:41:25 -0400 | |
|---|---|---|
| committer | 2021-06-28 10:08:07 -0400 | |
| commit | 1664c74a6c5a02640bb5f2204b661f94e825d906 (patch) | |
| tree | 76e64c8defb6dc833a1e419aacc7f04370f5354d /src | |
| parent | yuzu qt: Add option to dump to SDMC directory (diff) | |
| download | yuzu-1664c74a6c5a02640bb5f2204b661f94e825d906.tar.gz yuzu-1664c74a6c5a02640bb5f2204b661f94e825d906.tar.xz yuzu-1664c74a6c5a02640bb5f2204b661f94e825d906.zip | |
core: Support LayeredFS mod from SDMC directory
Enables loading a mod directly from `[yuzu data
directory]/sdmc/atmosphere/contents/[title_id]`. For use with some
homebrew mod managers.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/file_sys/patch_manager.cpp | 31 | ||||
| -rw-r--r-- | src/core/file_sys/sdmc_factory.cpp | 7 | ||||
| -rw-r--r-- | src/core/file_sys/sdmc_factory.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.h | 1 |
5 files changed, 47 insertions, 2 deletions
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 53b8b7ca0..6f5aa6da2 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 | ||
| @@ -524,6 +529,28 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u | |||
| 524 | } | 529 | } |
| 525 | } | 530 | } |
| 526 | 531 | ||
| 532 | // SDMC mod directory (LayeredFS) | ||
| 533 | const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); | ||
| 534 | if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0) { | ||
| 535 | std::string types; | ||
| 536 | |||
| 537 | const auto exefs_dir = FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"); | ||
| 538 | if (IsDirValidAndNonEmpty(exefs_dir)) { | ||
| 539 | bool layeredfs = false; | ||
| 540 | |||
| 541 | if (layeredfs) | ||
| 542 | AppendCommaIfNotEmpty(types, "LayeredExeFS"); | ||
| 543 | } | ||
| 544 | if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs"))) | ||
| 545 | AppendCommaIfNotEmpty(types, "LayeredFS"); | ||
| 546 | |||
| 547 | if (!types.empty()) { | ||
| 548 | const auto mod_disabled = | ||
| 549 | std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end(); | ||
| 550 | out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", types); | ||
| 551 | } | ||
| 552 | } | ||
| 553 | |||
| 527 | // DLC | 554 | // DLC |
| 528 | const auto dlc_entries = | 555 | const auto dlc_entries = |
| 529 | content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); | 556 | content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); |
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index cb56d8f2d..f4dba8f16 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp | |||
| @@ -27,6 +27,13 @@ ResultVal<VirtualDir> SDMCFactory::Open() const { | |||
| 27 | return MakeResult<VirtualDir>(dir); | 27 | return MakeResult<VirtualDir>(dir); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | VirtualDir SDMCFactory::GetSDMCModificationLoadRoot(u64 title_id) const { | ||
| 31 | // LayeredFS doesn't work on updates and title id-less homebrew | ||
| 32 | if (title_id == 0 || (title_id & 0xFFF) == 0x800) | ||
| 33 | return nullptr; | ||
| 34 | return GetOrCreateDirectoryRelative(dir, fmt::format("/atmosphere/contents/{:016X}", title_id)); | ||
| 35 | } | ||
| 36 | |||
| 30 | VirtualDir SDMCFactory::GetSDMCContentDirectory() const { | 37 | VirtualDir SDMCFactory::GetSDMCContentDirectory() const { |
| 31 | return GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents"); | 38 | return GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents"); |
| 32 | } | 39 | } |
diff --git a/src/core/file_sys/sdmc_factory.h b/src/core/file_sys/sdmc_factory.h index 2bb92ba93..c57514938 100644 --- a/src/core/file_sys/sdmc_factory.h +++ b/src/core/file_sys/sdmc_factory.h | |||
| @@ -21,6 +21,7 @@ public: | |||
| 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; |
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 3c16fe6c7..9191f19fe 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -703,6 +703,15 @@ 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 | return sdmc_factory->GetSDMCModificationLoadRoot(title_id); | ||
| 713 | } | ||
| 714 | |||
| 706 | FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const { | 715 | FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const { |
| 707 | LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id); | 716 | LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id); |
| 708 | 717 | ||
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 | ||