From 329398cd41d0826dfca1f89c440c71055f57cbe8 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Mon, 14 Jun 2021 21:41:25 -0400 Subject: 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. --- src/core/file_sys/patch_manager.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'src/core/file_sys/patch_manager.cpp') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 53b8b7ca0d..6f5aa6da29 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -345,8 +345,10 @@ std::vector PatchManager::CreateCheatList( static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type, const Service::FileSystem::FileSystemController& fs_controller) { const auto load_dir = fs_controller.GetModificationLoadRoot(title_id); + const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); if ((type != ContentRecordType::Program && type != ContentRecordType::Data) || - load_dir == nullptr || load_dir->GetSize() <= 0) { + ((load_dir == nullptr || load_dir->GetSize() <= 0) && + (sdmc_load_dir == nullptr || sdmc_load_dir->GetSize() <= 0))) { return; } @@ -356,7 +358,10 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t } const auto& disabled = Settings::values.disabled_addons[title_id]; - auto patch_dirs = load_dir->GetSubdirectories(); + std::vector patch_dirs = load_dir->GetSubdirectories(); + if (std::find(disabled.cbegin(), disabled.cend(), "SDMC") == disabled.cend()) { + patch_dirs.push_back(sdmc_load_dir); + } std::sort(patch_dirs.begin(), patch_dirs.end(), [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); @@ -524,6 +529,28 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u } } + // SDMC mod directory (LayeredFS) + const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); + if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0) { + std::string types; + + const auto exefs_dir = FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"); + if (IsDirValidAndNonEmpty(exefs_dir)) { + bool layeredfs = false; + + if (layeredfs) + AppendCommaIfNotEmpty(types, "LayeredExeFS"); + } + if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs"))) + AppendCommaIfNotEmpty(types, "LayeredFS"); + + if (!types.empty()) { + const auto mod_disabled = + std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end(); + out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", types); + } + } + // DLC const auto dlc_entries = content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data); -- cgit v1.2.3 From bc4dc2135e9065fdc246e36bf7256b036a9cc644 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Tue, 15 Jun 2021 19:59:10 -0400 Subject: core: Simplify SDMC mod loading If someone else wants to support other mod formats in the SDMC directory, that can be added later. For now, just allow RomFS modding here and force people to do other types of mods the old way. Addresses review comments. Co-authored-by: LC --- src/core/file_sys/patch_manager.cpp | 25 ++++++------------------- src/core/file_sys/sdmc_factory.cpp | 3 ++- src/core/hle/service/filesystem/filesystem.cpp | 3 ++- 3 files changed, 10 insertions(+), 21 deletions(-) (limited to 'src/core/file_sys/patch_manager.cpp') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 6f5aa6da29..13d294ad87 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -529,26 +529,13 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u } } - // SDMC mod directory (LayeredFS) + // SDMC mod directory (RomFS LayeredFS) const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id); - if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0) { - std::string types; - - const auto exefs_dir = FindSubdirectoryCaseless(sdmc_mod_dir, "exefs"); - if (IsDirValidAndNonEmpty(exefs_dir)) { - bool layeredfs = false; - - if (layeredfs) - AppendCommaIfNotEmpty(types, "LayeredExeFS"); - } - if (IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs"))) - AppendCommaIfNotEmpty(types, "LayeredFS"); - - if (!types.empty()) { - const auto mod_disabled = - std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end(); - out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", types); - } + if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0 && + IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs"))) { + const auto mod_disabled = + std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end(); + out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", "LayeredFS"); } // DLC diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index f4dba8f163..7e878123c5 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp @@ -29,8 +29,9 @@ ResultVal SDMCFactory::Open() const { VirtualDir SDMCFactory::GetSDMCModificationLoadRoot(u64 title_id) const { // LayeredFS doesn't work on updates and title id-less homebrew - if (title_id == 0 || (title_id & 0xFFF) == 0x800) + if (title_id == 0 || (title_id & 0xFFF) == 0x800) { return nullptr; + } return GetOrCreateDirectoryRelative(dir, fmt::format("/atmosphere/contents/{:016X}", title_id)); } diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 9191f19fe8..d66e74d3a8 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -706,8 +706,9 @@ FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id) FileSys::VirtualDir FileSystemController::GetSDMCModificationLoadRoot(u64 title_id) const { LOG_TRACE(Service_FS, "Opening SDMC mod load root for tid={:016X}", title_id); - if (sdmc_factory == nullptr) + if (sdmc_factory == nullptr) { return nullptr; + } return sdmc_factory->GetSDMCModificationLoadRoot(title_id); } -- cgit v1.2.3 From 263495a5d57962c627abb9def4309f7fcfb4e288 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Mon, 28 Jun 2021 10:07:40 -0400 Subject: patch_manager: Do not apply LayeredFS mods when dumping We should not apply any mods when dumping a game's RomFS. --- src/core/file_sys/patch_manager.cpp | 6 ++++-- src/core/file_sys/patch_manager.h | 3 ++- src/yuzu/main.cpp | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/core/file_sys/patch_manager.cpp') diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 13d294ad87..7c0950bb01 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -407,7 +407,7 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t } VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type, - VirtualFile update_raw) const { + VirtualFile update_raw, bool apply_layeredfs) const { const auto log_string = fmt::format("Patching RomFS for title_id={:016X}, type={:02X}", title_id, static_cast(type)); @@ -447,7 +447,9 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content } // LayeredFS - ApplyLayeredFS(romfs, title_id, type, fs_controller); + if (apply_layeredfs) { + ApplyLayeredFS(romfs, title_id, type, fs_controller); + } return romfs; } diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index fb18530355..3be871f35d 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -64,7 +64,8 @@ public: // - LayeredFS [[nodiscard]] VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset, ContentRecordType type = ContentRecordType::Program, - VirtualFile update_raw = nullptr) const; + VirtualFile update_raw = nullptr, + bool apply_layeredfs = true) const; // Returns a vector of pairs between patch names and patch versions. // i.e. Update 3.2.2 will return {"Update", "3.2.2"} diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 08128effb0..ece169a38a 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1922,7 +1922,8 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa if (*romfs_title_id == program_id) { const u64 ivfc_offset = loader->ReadRomFSIVFCOffset(); const FileSys::PatchManager pm{program_id, system.GetFileSystemController(), installed}; - romfs = pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program); + romfs = + pm.PatchRomFS(file, ivfc_offset, FileSys::ContentRecordType::Program, nullptr, false); } else { romfs = installed.GetEntry(*romfs_title_id, FileSys::ContentRecordType::Data)->GetRomFS(); } -- cgit v1.2.3