From 7f5de6bcd651f8145e4746c76d0531b6560fd5e4 Mon Sep 17 00:00:00 2001 From: xbzk Date: Wed, 4 Mar 2026 22:51:35 +0100 Subject: [android/fs] external content loader + nca/xci patches (#3596) Foreword: WHY DON'T EVERYBODY USE ONE FOLDER FOR EACH GAME+CONTENTS? AIN'T THIS THE FORMAT GAMES COME WHEN YOU BUE THEM? DO YOU LIVE WITH ALL YOUR FRIENDS AND HAVE A 2ND HOUSE FOR ALL THE CHILDREN? Nice, i feel better now. This feat extends Maufeat's work on external content loading. It harmonically additions: "...also, if in each game folder X, you find a folder Y, and in this folder Y you detect ONLY a single game, then mount all external content for that game found in that folder Y and its subfolders." Permanent (not toggleable). External Content folders are supported equally. Also: -Reworked several routines for preserving single source of truth between android and other systems; -Fixed the annoying unknown format error for content files, by providing proper format detection. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3596 Reviewed-by: MaranBr Reviewed-by: Lizzie Co-authored-by: xbzk Co-committed-by: xbzk --- src/core/loader/loader.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'src/core/loader/loader.cpp') diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 4379634d03..b4d50227d3 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -9,11 +9,15 @@ #include #include #include +#include #include "common/concepts.h" #include "common/fs/path_util.h" #include "common/logging/log.h" #include "common/string_util.h" #include "core/core.h" +#include "core/file_sys/card_image.h" +#include "core/file_sys/common_funcs.h" +#include "core/file_sys/submission_package.h" #include "core/hle/kernel/k_process.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/kip.h" @@ -37,6 +41,49 @@ std::optional IdentifyFileLoader(FileSys::VirtualFile file) { return std::nullopt; } +std::shared_ptr OpenContainerAsNsp(FileSys::VirtualFile file, FileType type, + u64 program_id = 0, + std::size_t program_index = 0) { + if (!file) { + return nullptr; + } + + if (type == FileType::NSP) { + auto nsp = std::make_shared(file, program_id, program_index); + return nsp->GetStatus() == ResultStatus::Success ? nsp : nullptr; + } + + if (type == FileType::XCI) { + FileSys::XCI xci{file, program_id, program_index}; + if (xci.GetStatus() != ResultStatus::Success) { + return nullptr; + } + + auto secure_nsp = xci.GetSecurePartitionNSP(); + if (secure_nsp == nullptr || secure_nsp->GetStatus() != ResultStatus::Success) { + return nullptr; + } + + return secure_nsp; + } + + return nullptr; +} + +bool HasApplicationProgramContent(const std::shared_ptr& nsp) { + if (!nsp) { + return false; + } + + const auto& ncas = nsp->GetNCAs(); + return std::any_of(ncas.cbegin(), ncas.cend(), [](const auto& title_entry) { + const auto& nca_map = title_entry.second; + return nca_map.find( + {FileSys::TitleType::Application, FileSys::ContentRecordType::Program}) != + nca_map.end(); + }); +} + } // namespace FileType IdentifyFile(FileSys::VirtualFile file) { @@ -62,6 +109,27 @@ FileType IdentifyFile(FileSys::VirtualFile file) { } } +bool IsContainerType(FileType type) { + return type == FileType::NSP || type == FileType::XCI; +} + +bool IsBootableGameContainer(FileSys::VirtualFile file, FileType type, u64 program_id, + std::size_t program_index) { + if (!file) { + return false; + } + + if (type == FileType::Unknown) { + type = IdentifyFile(file); + } + + if (!IsContainerType(type)) { + return false; + } + + return HasApplicationProgramContent(OpenContainerAsNsp(file, type, program_id, program_index)); +} + FileType GuessFromFilename(const std::string& name) { if (name == "main") return FileType::DeconstructedRomDirectory; -- cgit v1.2.3