From c50d4e9820735c2dc508c123c2830f1ef8bbedb0 Mon Sep 17 00:00:00 2001 From: smiRaphi Date: Tue, 7 Apr 2026 20:23:59 +0200 Subject: [PATCH] [hle/service] Implement/Stub various debug functions --- src/common/fs/fs_paths.h | 3 +- src/common/fs/path_util.cpp | 1 + src/common/fs/path_util.h | 3 +- src/core/CMakeLists.txt | 2 + src/core/file_sys/host_factory.cpp | 18 +++++++++ src/core/file_sys/host_factory.h | 21 ++++++++++ .../am/service/application_functions.cpp | 38 ++++++++++++++++++- .../am/service/application_functions.h | 1 + .../hle/service/filesystem/filesystem.cpp | 23 +++++++++++ src/core/hle/service/filesystem/filesystem.h | 3 ++ .../hle/service/filesystem/fsp/fsp_srv.cpp | 22 ++++++++++- src/core/hle/service/filesystem/fsp/fsp_srv.h | 2 + .../vi/application_display_service.cpp | 22 ++++++++++- .../service/vi/application_display_service.h | 6 +++ 14 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 src/core/file_sys/host_factory.cpp create mode 100644 src/core/file_sys/host_factory.h diff --git a/src/common/fs/fs_paths.h b/src/common/fs/fs_paths.h index 640a83c44b..986d8223c0 100644 --- a/src/common/fs/fs_paths.h +++ b/src/common/fs/fs_paths.h @@ -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 2021 yuzu Emulator Project @@ -17,6 +17,7 @@ #define CONFIG_DIR "config" #define CRASH_DUMPS_DIR "crash_dumps" #define DUMP_DIR "dump" +#define HOST_DIR "host" #define KEYS_DIR "keys" #define LOAD_DIR "load" #define LOG_DIR "log" diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp index 714e393293..56ddafa56f 100644 --- a/src/common/fs/path_util.cpp +++ b/src/common/fs/path_util.cpp @@ -155,6 +155,7 @@ public: GenerateEdenPath(EdenPath::ConfigDir, eden_path_config); GenerateEdenPath(EdenPath::CrashDumpsDir, eden_path / CRASH_DUMPS_DIR); GenerateEdenPath(EdenPath::DumpDir, eden_path / DUMP_DIR); + GenerateEdenPath(EdenPath::HostDir, eden_path / HOST_DIR); GenerateEdenPath(EdenPath::KeysDir, eden_path / KEYS_DIR); GenerateEdenPath(EdenPath::LoadDir, eden_path / LOAD_DIR); GenerateEdenPath(EdenPath::LogDir, eden_path / LOG_DIR); diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h index 9f597232a5..8324796105 100644 --- a/src/common/fs/path_util.h +++ b/src/common/fs/path_util.h @@ -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 2021 yuzu Emulator Project @@ -20,6 +20,7 @@ enum class EdenPath { ConfigDir, // Where config files are stored. CrashDumpsDir, // Where crash dumps are stored. DumpDir, // Where dumped data is stored. + HostDir, // Where the game has access to the host system. KeysDir, // Where key files are stored. LoadDir, // Where cheat/mod files are stored. LogDir, // Where log files are stored. diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 0ce6b405cd..f542a8275b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -114,6 +114,8 @@ add_library(core STATIC file_sys/fssystem/fssystem_switch_storage.h file_sys/fssystem/fssystem_utility.cpp file_sys/fssystem/fssystem_utility.h + file_sys/host_factory.cpp + file_sys/host_factory.h file_sys/ips_layer.cpp file_sys/ips_layer.h file_sys/kernel_executable.cpp diff --git a/src/core/file_sys/host_factory.cpp b/src/core/file_sys/host_factory.cpp new file mode 100644 index 0000000000..f1b764c8ac --- /dev/null +++ b/src/core/file_sys/host_factory.cpp @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "core/file_sys/host_factory.h" +#include "core/file_sys/vfs/vfs.h" + +namespace FileSys { + +HostFactory::HostFactory(VirtualDir host_dir_) + : host_dir(std::move(host_dir_)) {} + +HostFactory::~HostFactory() = default; + +VirtualDir HostFactory::Open() const { + return host_dir; +} + +} // namespace FileSys diff --git a/src/core/file_sys/host_factory.h b/src/core/file_sys/host_factory.h new file mode 100644 index 0000000000..d7b2224e57 --- /dev/null +++ b/src/core/file_sys/host_factory.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/file_sys/vfs/vfs_types.h" + +namespace FileSys { + +class HostFactory { +public: + explicit HostFactory(VirtualDir host_dir_); + ~HostFactory(); + + VirtualDir Open() const; + +private: + VirtualDir host_dir; +}; + +} // namespace FileSys diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index 9ab343e59e..62f07a0de3 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp @@ -25,6 +25,30 @@ namespace Service::AM { +namespace { + +FileSys::StorageId GetStorageIdForFrontendSlot( + std::optional slot) { + if (!slot.has_value()) { + return FileSys::StorageId::None; + } + + switch (*slot) { + case FileSys::ContentProviderUnionSlot::UserNAND: + return FileSys::StorageId::NandUser; + case FileSys::ContentProviderUnionSlot::SysNAND: + return FileSys::StorageId::NandSystem; + case FileSys::ContentProviderUnionSlot::SDMC: + return FileSys::StorageId::SdCard; + case FileSys::ContentProviderUnionSlot::FrontendManual: + return FileSys::StorageId::Host; + default: + return FileSys::StorageId::None; + } +} + +} // Anonymous namespace + IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr applet) : ServiceFramework{system_, "IApplicationFunctions"}, m_applet{std::move(applet)} { // clang-format off @@ -40,7 +64,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ {21, D<&IApplicationFunctions::GetDesiredLanguage>, "GetDesiredLanguage"}, {22, D<&IApplicationFunctions::SetTerminateResult>, "SetTerminateResult"}, {23, D<&IApplicationFunctions::GetDisplayVersion>, "GetDisplayVersion"}, - {24, nullptr, "GetLaunchStorageInfoForDebug"}, + {24, D<&IApplicationFunctions::GetLaunchStorageInfoForDebug>, "GetLaunchStorageInfoForDebug"}, {25, D<&IApplicationFunctions::ExtendSaveData>, "ExtendSaveData"}, {26, D<&IApplicationFunctions::GetSaveDataSize>, "GetSaveDataSize"}, {27, D<&IApplicationFunctions::CreateCacheStorage>, "CreateCacheStorage"}, @@ -231,6 +255,18 @@ Result IApplicationFunctions::GetDisplayVersion(Out out_display_ R_SUCCEED(); } +Result IApplicationFunctions::GetLaunchStorageInfoForDebug(Out out_app_storage, + Out out_app_storage_update) { + LOG_DEBUG(Service_AM, "called"); + + auto& storage = system.GetContentProviderUnion(); + *out_app_storage = static_cast(GetStorageIdForFrontendSlot( + storage.GetSlotForEntry(m_applet->program_id, FileSys::ContentRecordType::Program))); + *out_app_storage_update = static_cast(GetStorageIdForFrontendSlot(storage.GetSlotForEntry( + FileSys::GetUpdateTitleID(m_applet->program_id), FileSys::ContentRecordType::Program))); + R_SUCCEED(); +} + Result IApplicationFunctions::ExtendSaveData(Out out_required_size, FileSys::SaveDataType type, Common::UUID user_id, u64 normal_size, u64 journal_size) { diff --git a/src/core/hle/service/am/service/application_functions.h b/src/core/hle/service/am/service/application_functions.h index abee2f9d47..7aacb35efe 100644 --- a/src/core/hle/service/am/service/application_functions.h +++ b/src/core/hle/service/am/service/application_functions.h @@ -36,6 +36,7 @@ private: Result GetDesiredLanguage(Out out_language_code); Result SetTerminateResult(Result terminate_result); Result GetDisplayVersion(Out out_display_version); + Result GetLaunchStorageInfoForDebug(Out out_app_storage, Out out_app_storage_update); Result ExtendSaveData(Out out_required_size, FileSys::SaveDataType type, Common::UUID user_id, u64 normal_size, u64 journal_size); Result GetSaveDataSize(Out out_normal_size, Out out_journal_size, diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index c192fea454..335058b83c 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -16,6 +16,7 @@ #include "core/file_sys/card_image.h" #include "core/file_sys/control_metadata.h" #include "core/file_sys/errors.h" +#include "core/file_sys/host_factory.h" #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs_factory.h" @@ -360,6 +361,22 @@ std::shared_ptr FileSystemController::CreateSaveDataFa std::move(save_directory)); } +Result FileSystemController::OpenHost(FileSys::VirtualDir* out_host) const { + LOG_TRACE(Service_FS, "Opening host"); + + if (host_factory == nullptr) { + return FileSys::ResultTargetNotFound; + } + + auto host = host_factory->Open(); + if (host == nullptr) { + return FileSys::ResultTargetNotFound; + } + + *out_host = host; + return ResultSuccess; +} + Result FileSystemController::OpenSDMC(FileSys::VirtualDir* out_sdmc) const { LOG_TRACE(Service_FS, "Opening SDMC"); @@ -697,6 +714,8 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove const auto sdmc_load_dir_path = sdmc_dir_path / "atmosphere/contents"; const auto rw_mode = FileSys::OpenMode::ReadWrite; + auto host_directory = + vfs.OpenDirectory(Common::FS::GetEdenPathString(EdenPath::HostDir), rw_mode); auto nand_directory = vfs.OpenDirectory(Common::FS::GetEdenPathString(EdenPath::NANDDir), rw_mode); auto sd_directory = vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_dir_path), rw_mode); @@ -716,6 +735,10 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove bis_factory->GetUserNANDContents()); } + if (host_factory == nullptr) { + host_factory = std::make_unique(host_directory); + } + if (sdmc_factory == nullptr) { sdmc_factory = std::make_unique(std::move(sd_directory), std::move(sd_load_directory)); diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index ef45aec627..d9de71b82b 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -21,6 +21,7 @@ class System; namespace FileSys { class BISFactory; class ExternalContentProvider; +class HostFactory; class NCA; class RegisteredCache; class RegisteredCacheUnion; @@ -80,6 +81,7 @@ public: std::shared_ptr OpenSaveDataController(); + Result OpenHost(FileSys::VirtualDir* out_host) const; Result OpenSDMC(FileSys::VirtualDir* out_sdmc) const; Result OpenBISPartition(FileSys::VirtualDir* out_bis_partition, FileSys::BisPartitionId id) const; @@ -141,6 +143,7 @@ private: std::mutex registration_lock; std::map registrations; + std::unique_ptr host_factory; std::unique_ptr sdmc_factory; std::unique_ptr bis_factory; diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp index 0ee68c0332..dfdb18050c 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp @@ -61,7 +61,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) {11, nullptr, "OpenBisFileSystem"}, {12, nullptr, "OpenBisStorage"}, {13, nullptr, "InvalidateBisCache"}, - {17, nullptr, "OpenHostFileSystem"}, + {17, D<&FSP_SRV::OpenHostFileSystem>, "OpenHostFileSystem"}, {18, D<&FSP_SRV::OpenSdCardFileSystem>, "OpenSdCardFileSystem"}, {19, nullptr, "FormatSdCardFileSystem"}, {21, nullptr, "DeleteSaveDataFileSystem"}, @@ -155,7 +155,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) {810, nullptr, "RegisterProgramIndexMapInfo"}, {1000, nullptr, "SetBisRootForHost"}, {1001, nullptr, "SetSaveDataSize"}, - {1002, nullptr, "SetSaveDataRootPath"}, + {1002, D<&FSP_SRV::SetSaveDataRootPath>, "SetSaveDataRootPath"}, {1003, D<&FSP_SRV::DisableAutoSaveDataCreation>, "DisableAutoSaveDataCreation"}, {1004, D<&FSP_SRV::SetGlobalAccessLogMode>, "SetGlobalAccessLogMode"}, {1005, D<&FSP_SRV::GetGlobalAccessLogMode>, "GetGlobalAccessLogMode"}, @@ -217,6 +217,18 @@ Result FSP_SRV::OpenFileSystemWithPatch(OutInterface out_interface, R_SUCCEED(); } +Result FSP_SRV::OpenHostFileSystem(OutInterface out_interface) { + LOG_DEBUG(Service_FS, "called"); + + FileSys::VirtualDir host_dir{}; + fsc.OpenHost(&host_dir); + + *out_interface = std::make_shared(system, host_dir, + SizeGetter::FromStorageId(fsc, FileSys::StorageId::Host)); + + R_SUCCEED(); +} + Result FSP_SRV::OpenSdCardFileSystem(OutInterface out_interface) { LOG_DEBUG(Service_FS, "called"); @@ -532,6 +544,12 @@ Result FSP_SRV::IsSdCardAccessible(Out out_is_accessible) { R_SUCCEED(); } +Result FSP_SRV::SetSaveDataRootPath(InBuffer path) { + LOG_WARNING(Service_FS, "(STUBBED) called, path_size={}", path.size()); + + R_SUCCEED(); +} + Result FSP_SRV::DisableAutoSaveDataCreation() { LOG_DEBUG(Service_FS, "called"); diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.h b/src/core/hle/service/filesystem/fsp/fsp_srv.h index 0ea41903e4..584696046e 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.h @@ -53,6 +53,7 @@ private: Result SetCurrentProcess(ClientProcessId pid); Result OpenFileSystemWithPatch(OutInterface out_interface, FileSystemProxyType type, u64 open_program_id); + Result OpenHostFileSystem(OutInterface out_interface); Result OpenSdCardFileSystem(OutInterface out_interface); Result CreateSaveDataFileSystem(FileSys::SaveDataCreationInfo save_create_struct, FileSys::SaveDataAttribute save_struct, u128 uid); @@ -102,6 +103,7 @@ private: FileSys::StorageId storage_id, u64 title_id); Result OpenDataStorageWithProgramIndex(OutInterface out_interface, u8 program_index); Result IsSdCardAccessible(Out out_is_accessible); + Result SetSaveDataRootPath(InBuffer path); Result DisableAutoSaveDataCreation(); Result SetGlobalAccessLogMode(AccessLogMode access_log_mode_); Result GetGlobalAccessLogMode(Out out_access_log_mode); diff --git a/src/core/hle/service/vi/application_display_service.cpp b/src/core/hle/service/vi/application_display_service.cpp index 969c86f53b..f42c662cbc 100644 --- a/src/core/hle/service/vi/application_display_service.cpp +++ b/src/core/hle/service/vi/application_display_service.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 2024 yuzu Emulator Project @@ -42,7 +42,7 @@ IApplicationDisplayService::IApplicationDisplayService(Core::System& system_, {2451, nullptr, "GetIndirectLayerImageCropMap"}, {2460, C<&IApplicationDisplayService::GetIndirectLayerImageRequiredMemoryInfo>, "GetIndirectLayerImageRequiredMemoryInfo"}, {5202, C<&IApplicationDisplayService::GetDisplayVsyncEvent>, "GetDisplayVsyncEvent"}, - {5203, nullptr, "GetDisplayVsyncEventForDebug"}, + {5203, C<&IApplicationDisplayService::GetDisplayVsyncEventForDebug>, "GetDisplayVsyncEventForDebug"}, }; // clang-format on @@ -53,6 +53,9 @@ IApplicationDisplayService::~IApplicationDisplayService() { for (auto& [display_id, event] : m_display_vsync_events) { m_container->UnlinkVsyncEvent(display_id, &event); } + for (auto& [display_id, event] : m_display_vsync_events_debug) { + m_container->UnlinkVsyncEvent(display_id, &event); + } for (const auto layer_id : m_open_layer_ids) { m_container->CloseLayer(layer_id); } @@ -263,6 +266,21 @@ Result IApplicationDisplayService::GetDisplayVsyncEvent( R_SUCCEED(); } +Result IApplicationDisplayService::GetDisplayVsyncEventForDebug( + OutCopyHandle out_vsync_event, u64 display_id) { + LOG_DEBUG(Service_VI, "called. display_id={}", display_id); + + std::scoped_lock lk{m_lock}; + + auto [it, created] = m_display_vsync_events_debug.emplace(display_id, m_context); + R_UNLESS(created, VI::ResultPermissionDenied); + + m_container->LinkVsyncEvent(display_id, &it->second); + *out_vsync_event = it->second.GetHandle(); + + R_SUCCEED(); +} + Result IApplicationDisplayService::ConvertScalingMode(Out out_scaling_mode, NintendoScaleMode mode) { LOG_DEBUG(Service_VI, "called mode={}", mode); diff --git a/src/core/hle/service/vi/application_display_service.h b/src/core/hle/service/vi/application_display_service.h index 1bdeb8f845..66a14d1efb 100644 --- a/src/core/hle/service/vi/application_display_service.h +++ b/src/core/hle/service/vi/application_display_service.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -58,6 +61,8 @@ public: Result DestroyStrayLayer(u64 layer_id); Result GetDisplayVsyncEvent(OutCopyHandle out_vsync_event, u64 display_id); + Result GetDisplayVsyncEventForDebug(OutCopyHandle out_vsync_event, + u64 display_id); Result ConvertScalingMode(Out out_scaling_mode, NintendoScaleMode mode); Result GetIndirectLayerImageMap( Out out_size, Out out_stride, @@ -75,6 +80,7 @@ private: std::set m_open_layer_ids{}; std::set m_stray_layer_ids{}; std::map m_display_vsync_events{}; + std::map m_display_vsync_events_debug{}; bool m_vsync_event_fetched{false}; };