diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/core.cpp | 29 | ||||
-rw-r--r-- | src/core/core.h | 22 | ||||
-rw-r--r-- | src/core/file_sys/card_image.cpp | 5 | ||||
-rw-r--r-- | src/core/file_sys/card_image.h | 2 | ||||
-rw-r--r-- | src/core/file_sys/submission_package.cpp | 6 | ||||
-rw-r--r-- | src/core/file_sys/submission_package.h | 4 | ||||
-rw-r--r-- | src/core/hle/service/am/am.cpp | 34 | ||||
-rw-r--r-- | src/core/hle/service/am/am.h | 3 | ||||
-rw-r--r-- | src/core/loader/loader.cpp | 12 | ||||
-rw-r--r-- | src/core/loader/loader.h | 4 | ||||
-rw-r--r-- | src/core/loader/nsp.cpp | 5 | ||||
-rw-r--r-- | src/core/loader/nsp.h | 3 | ||||
-rw-r--r-- | src/core/loader/xci.cpp | 5 | ||||
-rw-r--r-- | src/core/loader/xci.h | 3 |
14 files changed, 108 insertions, 29 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 1aa477a29..7ca3652af 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -145,7 +145,7 @@ struct System::Impl { } ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) { - LOG_DEBUG(HW_Memory, "initialized OK"); + LOG_DEBUG(Core, "initialized OK"); device_memory = std::make_unique<Core::DeviceMemory>(); @@ -208,9 +208,11 @@ struct System::Impl { return ResultStatus::Success; } - ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, - const std::string& filepath) { - app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath)); + ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath, + std::size_t program_index) { + app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath), + program_index); + if (!app_loader) { LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); return ResultStatus::ErrorGetLoader; @@ -416,6 +418,8 @@ struct System::Impl { bool is_multicore{}; bool is_async_gpu{}; + ExecuteProgramCallback execute_program_callback; + std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_dynarmic{}; }; @@ -451,8 +455,9 @@ void System::Shutdown() { impl->Shutdown(); } -System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath) { - return impl->Load(*this, emu_window, filepath); +System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath, + std::size_t program_index) { + return impl->Load(*this, emu_window, filepath, program_index); } bool System::IsPoweredOn() const { @@ -789,4 +794,16 @@ bool System::IsMulticore() const { return impl->is_multicore; } +void System::RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback) { + impl->execute_program_callback = std::move(callback); +} + +void System::ExecuteProgram(std::size_t program_index) { + if (impl->execute_program_callback) { + impl->execute_program_callback(program_index); + } else { + LOG_CRITICAL(Core, "execute_program_callback must be initialized by the frontend"); + } +} + } // namespace Core diff --git a/src/core/core.h b/src/core/core.h index cd155625c..f642befc0 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -5,6 +5,7 @@ #pragma once #include <cstddef> +#include <functional> #include <memory> #include <string> #include <vector> @@ -173,9 +174,11 @@ public: * @param emu_window Reference to the host-system window used for video output and keyboard * input. * @param filepath String path to the executable application to load on the host file system. + * @param program_index Specifies the index within the container of the program to launch. * @returns ResultStatus code, indicating if the operation succeeded. */ - [[nodiscard]] ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath); + [[nodiscard]] ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath, + std::size_t program_index = 0); /** * Indicates if the emulated system is powered on (all subsystems initialized and able to run an @@ -385,6 +388,23 @@ public: /// Tells if system is running on multicore. [[nodiscard]] bool IsMulticore() const; + /// Type used for the frontend to designate a callback for System to re-launch the application + /// using a specified program index. + using ExecuteProgramCallback = std::function<void(std::size_t)>; + + /** + * Registers a callback from the frontend for System to re-launch the application using a + * specified program index. + * @param callback Callback from the frontend to relaunch the application. + */ + void RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback); + + /** + * Instructs the frontend to re-launch the application using the specified program_index. + * @param program_index Specifies the index within the application of the program to launch. + */ + void ExecuteProgram(std::size_t program_index); + private: System(); diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index 956da68f7..8dee5590b 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -29,7 +29,7 @@ constexpr std::array partition_names{ "logo", }; -XCI::XCI(VirtualFile file_) +XCI::XCI(VirtualFile file_, std::size_t program_index) : file(std::move(file_)), program_nca_status{Loader::ResultStatus::ErrorXCIMissingProgramNCA}, partitions(partition_names.size()), partitions_raw(partition_names.size()), keys{Core::Crypto::KeyManager::Instance()} { @@ -62,7 +62,8 @@ XCI::XCI(VirtualFile file_) } secure_partition = std::make_shared<NSP>( - main_hfs.GetFile(partition_names[static_cast<std::size_t>(XCIPartition::Secure)])); + main_hfs.GetFile(partition_names[static_cast<std::size_t>(XCIPartition::Secure)]), + program_index); ncas = secure_partition->GetNCAsCollapsed(); program = diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index 2d0a0f285..4960e90fe 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -78,7 +78,7 @@ enum class XCIPartition : u8 { Update, Normal, Secure, Logo }; class XCI : public ReadOnlyVfsDirectory { public: - explicit XCI(VirtualFile file); + explicit XCI(VirtualFile file, std::size_t program_index = 0); ~XCI() override; Loader::ResultStatus GetStatus() const; diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index 90641d23b..c05735ddd 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -20,8 +20,8 @@ namespace FileSys { -NSP::NSP(VirtualFile file_) - : file(std::move(file_)), status{Loader::ResultStatus::Success}, +NSP::NSP(VirtualFile file_, std::size_t program_index) + : file(std::move(file_)), program_index(program_index), status{Loader::ResultStatus::Success}, pfs(std::make_shared<PartitionFilesystem>(file)), keys{Core::Crypto::KeyManager::Instance()} { if (pfs->GetStatus() != Loader::ResultStatus::Success) { status = pfs->GetStatus(); @@ -146,7 +146,7 @@ std::shared_ptr<NCA> NSP::GetNCA(u64 title_id, ContentRecordType type, TitleType if (extracted) LOG_WARNING(Service_FS, "called on an NSP that is of type extracted."); - const auto title_id_iter = ncas.find(title_id); + const auto title_id_iter = ncas.find(title_id + program_index); if (title_id_iter == ncas.end()) return nullptr; diff --git a/src/core/file_sys/submission_package.h b/src/core/file_sys/submission_package.h index c70a11b5b..54581a6f3 100644 --- a/src/core/file_sys/submission_package.h +++ b/src/core/file_sys/submission_package.h @@ -27,7 +27,7 @@ enum class ContentRecordType : u8; class NSP : public ReadOnlyVfsDirectory { public: - explicit NSP(VirtualFile file); + explicit NSP(VirtualFile file, std::size_t program_index = 0); ~NSP() override; Loader::ResultStatus GetStatus() const; @@ -69,6 +69,8 @@ private: VirtualFile file; + const std::size_t program_index; + bool extracted = false; Loader::ResultStatus status; std::map<u64, Loader::ResultStatus> program_status; diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 55e428456..703a9b234 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1188,9 +1188,9 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"}, {110, &IApplicationFunctions::QueryApplicationPlayStatistics, "QueryApplicationPlayStatistics"}, {111, &IApplicationFunctions::QueryApplicationPlayStatisticsByUid, "QueryApplicationPlayStatisticsByUid"}, - {120, nullptr, "ExecuteProgram"}, - {121, nullptr, "ClearUserChannel"}, - {122, nullptr, "UnpopToUserChannel"}, + {120, &IApplicationFunctions::ExecuteProgram, "ExecuteProgram"}, + {121, &IApplicationFunctions::ClearUserChannel, "ClearUserChannel"}, + {122, &IApplicationFunctions::UnpopToUserChannel, "UnpopToUserChannel"}, {123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"}, {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, {130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"}, @@ -1561,6 +1561,34 @@ void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(Kernel::HLEReque rb.Push<u32>(0); } +void IApplicationFunctions::ExecuteProgram(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + [[maybe_unused]] const auto unk_1 = rp.Pop<u32>(); + [[maybe_unused]] const auto unk_2 = rp.Pop<u32>(); + const auto program_index = rp.Pop<u64>(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + + system.ExecuteProgram(program_index); +} + +void IApplicationFunctions::ClearUserChannel(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void IApplicationFunctions::UnpopToUserChannel(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + void IApplicationFunctions::GetPreviousProgramIndex(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 09c2d05bc..af97c303a 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -287,6 +287,9 @@ private: void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx); void QueryApplicationPlayStatistics(Kernel::HLERequestContext& ctx); void QueryApplicationPlayStatisticsByUid(Kernel::HLERequestContext& ctx); + void ExecuteProgram(Kernel::HLERequestContext& ctx); + void ClearUserChannel(Kernel::HLERequestContext& ctx); + void UnpopToUserChannel(Kernel::HLERequestContext& ctx); void GetPreviousProgramIndex(Kernel::HLERequestContext& ctx); void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); void GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx); diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index deffe7379..d91c15561 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -198,10 +198,11 @@ AppLoader::~AppLoader() = default; * @param system The system context to use. * @param file The file to retrieve the loader for * @param type The file type + * @param program_index Specifies the index within the container of the program to launch. * @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type */ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::VirtualFile file, - FileType type) { + FileType type, std::size_t program_index) { switch (type) { // Standard ELF file format. case FileType::ELF: @@ -222,7 +223,7 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V // NX XCI (nX Card Image) file format. case FileType::XCI: return std::make_unique<AppLoader_XCI>(std::move(file), system.GetFileSystemController(), - system.GetContentProvider()); + system.GetContentProvider(), program_index); // NX NAX (NintendoAesXts) file format. case FileType::NAX: @@ -231,7 +232,7 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V // NX NSP (Nintendo Submission Package) file format case FileType::NSP: return std::make_unique<AppLoader_NSP>(std::move(file), system.GetFileSystemController(), - system.GetContentProvider()); + system.GetContentProvider(), program_index); // NX KIP (Kernel Internal Process) file format case FileType::KIP: @@ -246,7 +247,8 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V } } -std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file) { +std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file, + std::size_t program_index) { FileType type = IdentifyFile(file); const FileType filename_type = GuessFromFilename(file->GetName()); @@ -260,7 +262,7 @@ std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile LOG_DEBUG(Loader, "Loading file {} as {}...", file->GetName(), GetFileTypeString(type)); - return GetFileLoader(system, std::move(file), type); + return GetFileLoader(system, std::move(file), type, program_index); } } // namespace Loader diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 8dc2d7615..36e79e71d 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -293,9 +293,11 @@ protected: * * @param system The system context. * @param file The bootable file. + * @param program_index Specifies the index within the container of the program to launch. * * @return the best loader for this file. */ -std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file); +std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file, + std::size_t program_index = 0); } // namespace Loader diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index e821937fd..928f64c8c 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -23,8 +23,9 @@ namespace Loader { AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file, const Service::FileSystem::FileSystemController& fsc, - const FileSys::ContentProvider& content_provider) - : AppLoader(file), nsp(std::make_unique<FileSys::NSP>(file)), + const FileSys::ContentProvider& content_provider, + std::size_t program_index) + : AppLoader(file), nsp(std::make_unique<FileSys::NSP>(file, program_index)), title_id(nsp->GetProgramTitleID()) { if (nsp->GetStatus() != ResultStatus::Success) { diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index 36e8e3533..f0518ac47 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -28,7 +28,8 @@ class AppLoader_NSP final : public AppLoader { public: explicit AppLoader_NSP(FileSys::VirtualFile file, const Service::FileSystem::FileSystemController& fsc, - const FileSys::ContentProvider& content_provider); + const FileSys::ContentProvider& content_provider, + std::size_t program_index); ~AppLoader_NSP() override; /** diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 536e721fc..aaa250cea 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -22,8 +22,9 @@ namespace Loader { AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file, const Service::FileSystem::FileSystemController& fsc, - const FileSys::ContentProvider& content_provider) - : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)), + const FileSys::ContentProvider& content_provider, + std::size_t program_index) + : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file, program_index)), nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { if (xci->GetStatus() != ResultStatus::Success) { return; diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 6dc1f9243..764dc8328 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -28,7 +28,8 @@ class AppLoader_XCI final : public AppLoader { public: explicit AppLoader_XCI(FileSys::VirtualFile file, const Service::FileSystem::FileSystemController& fsc, - const FileSys::ContentProvider& content_provider); + const FileSys::ContentProvider& content_provider, + std::size_t program_index); ~AppLoader_XCI() override; /** |