From df1c902e447c2d85581209d6689e69f8f6497f32 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 20 Nov 2018 17:49:09 -0500 Subject: settings: Add option to dump ExeFS of games upon launch When enabled, all exefs(es) will be copied to yuzu/dump//exefs. --- src/core/file_sys/patch_manager.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (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 8d062eb3e3..f56b1c773e 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -57,6 +57,15 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { if (exefs == nullptr) return exefs; + if (Settings::values.dump_exefs) { + LOG_INFO(Loader, "Dumping ExeFS for title_id={:016X}", title_id); + const auto dump_dir = Service::FileSystem::GetModificationDumpRoot(title_id); + if (dump_dir != nullptr) { + const auto exefs_dir = GetOrCreateDirectoryRelative(dump_dir, "/exefs"); + VfsRawCopyD(exefs, exefs_dir); + } + } + const auto installed = Service::FileSystem::GetUnionContents(); // Game Updates -- cgit v1.2.3 From 67e33e8866983e9a1854ff7bc771b2a5ea0c3438 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 20 Nov 2018 17:51:00 -0500 Subject: patch_manager: Apply LayeredExeFS patches This will scan the /exefs dir for all files and then layer those on top of the game's exefs and use this as the new exefs. This allows for overriding of the compressed NSOs or adding new files. This does use the same dir as IPS/IPSwitch patch, but since the loader will not look for those they are ignored. --- src/core/file_sys/patch_manager.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (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 f56b1c773e..ccc4f3061b 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -79,6 +79,31 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { exefs = update->GetExeFS(); } + // LayeredExeFS + const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); + if (load_dir != nullptr && load_dir->GetSize() > 0) { + + auto patch_dirs = load_dir->GetSubdirectories(); + std::sort( + patch_dirs.begin(), patch_dirs.end(), + [](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); }); + + std::vector layers; + layers.reserve(patch_dirs.size() + 1); + for (const auto& subdir : patch_dirs) { + auto exefs_dir = subdir->GetSubdirectory("exefs"); + if (exefs_dir != nullptr) + layers.push_back(std::move(exefs_dir)); + } + layers.push_back(exefs); + + auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers)); + if (layered != nullptr) { + LOG_INFO(Loader, " ExeFS: LayeredExeFS patches applied successfully"); + exefs = std::move(layered); + } + } + return exefs; } -- cgit v1.2.3 From 91921418227e578448a3b72fc1c14b721130fdef Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 20 Nov 2018 19:22:26 -0500 Subject: patch_manager: Show LayeredExeFS patch in add-ons column The decision was made to name them LayeredExeFS instead of just LayeredFS to differentiate from normal RomFS-based mods. The name may be long/unweildy, but conveys the meaning well. --- src/core/file_sys/patch_manager.cpp | 17 ++++++++++++++--- src/yuzu/configuration/configure_debug.ui | 2 +- 2 files changed, 15 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 ccc4f3061b..e8df087242 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -26,6 +26,11 @@ namespace FileSys { constexpr u64 SINGLE_BYTE_MODULUS = 0x100; constexpr u64 DLC_BASE_TITLE_ID_MASK = 0xFFFFFFFFFFFFE000; +constexpr std::array EXEFS_FILE_NAMES{ + "main", "main.npdm", "rtld", "sdk", "subsdk0", "subsdk1", "subsdk2", + "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", "subsdk8", "subsdk9", +}; + struct NSOBuildHeader { u32_le magic; INSERT_PADDING_BYTES(0x3C); @@ -82,7 +87,6 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const { // LayeredExeFS const auto load_dir = Service::FileSystem::GetModificationLoadRoot(title_id); if (load_dir != nullptr && load_dir->GetSize() > 0) { - auto patch_dirs = load_dir->GetSubdirectories(); std::sort( patch_dirs.begin(), patch_dirs.end(), @@ -348,18 +352,25 @@ std::map> PatchManager::GetPatchVersionNam if (IsDirValidAndNonEmpty(exefs_dir)) { bool ips = false; bool ipswitch = false; + bool layeredfs = false; for (const auto& file : exefs_dir->GetFiles()) { - if (file->GetExtension() == "ips") + if (file->GetExtension() == "ips") { ips = true; - else if (file->GetExtension() == "pchtxt") + } else if (file->GetExtension() == "pchtxt") { ipswitch = true; + } else if (std::find(EXEFS_FILE_NAMES.begin(), EXEFS_FILE_NAMES.end(), + file->GetName()) != EXEFS_FILE_NAMES.end()) { + layeredfs = true; + } } if (ips) AppendCommaIfNotEmpty(types, "IPS"); if (ipswitch) AppendCommaIfNotEmpty(types, "IPSwitch"); + if (layeredfs) + AppendCommaIfNotEmpty(types, "LayeredExeFS"); } if (IsDirValidAndNonEmpty(mod->GetSubdirectory("romfs"))) AppendCommaIfNotEmpty(types, "LayeredFS"); diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index f51f8702b4..758a92335b 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui @@ -148,7 +148,7 @@ - When checked, any game that yuzu loads will have its ExeFS dumped + When checked, any game that yuzu loads will have its ExeFS dumped to the yuzu/dump directory. Dump ExeFS -- cgit v1.2.3