From 4983aa7d72df0c3ff56b0c45a64a65bceb264724 Mon Sep 17 00:00:00 2001 From: Maufeat Date: Fri, 12 Dec 2025 02:28:01 +0100 Subject: [PATCH] add overlay show logo (nintendo logo, etc.) --- .../service/am/service/overlay_functions.cpp | 32 +++++++++++- .../service/am/service/overlay_functions.h | 1 + .../ns/application_manager_interface.cpp | 51 ++++++++++++++++++- .../ns/application_manager_interface.h | 4 ++ 4 files changed, 85 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/am/service/overlay_functions.cpp b/src/core/hle/service/am/service/overlay_functions.cpp index 8af037734a..41f2e5c008 100644 --- a/src/core/hle/service/am/service/overlay_functions.cpp +++ b/src/core/hle/service/am/service/overlay_functions.cpp @@ -24,7 +24,7 @@ namespace Service::AM { {20, D<&IOverlayFunctions::SetHandlingHomeButtonShortPressedEnabled>, "SetHandlingHomeButtonShortPressedEnabled"}, {21, nullptr, "SetHandlingTouchScreenInputEnabled"}, {30, nullptr, "SetHealthWarningShowingState"}, - {31, nullptr, "IsHealthWarningRequired"}, + {31, D<&IOverlayFunctions::IsHealthWarningRequired>, "IsHealthWarningRequired"}, {40, nullptr, "GetApplicationNintendoLogo"}, {41, nullptr, "GetApplicationStartupMovie"}, {50, nullptr, "SetGpuTimeSliceBoostForApplication"}, @@ -69,12 +69,33 @@ namespace Service::AM { Result IOverlayFunctions::GetApplicationIdForLogo(Out out_application_id) { LOG_DEBUG(Service_AM, "called"); - // Prefer explicit application_id if available, else fall back to program_id + std::shared_ptr target_applet; + + auto* window_system = system.GetAppletManager().GetWindowSystem(); + if (window_system) { + target_applet = window_system->GetMainApplet(); + if (target_applet) { + std::scoped_lock lk{target_applet->lock}; + LOG_DEBUG(Service_AM, "applet_id={}, program_id={:016X}, type={}", + static_cast(target_applet->applet_id), target_applet->program_id, + static_cast(target_applet->type)); + + u64 id = target_applet->screen_shot_identity.application_id; + if (id == 0) { + id = target_applet->program_id; + } + LOG_DEBUG(Service_AM, "application_id={:016X}", id); + *out_application_id = id; + R_SUCCEED(); + } + } + std::scoped_lock lk{m_applet->lock}; u64 id = m_applet->screen_shot_identity.application_id; if (id == 0) { id = m_applet->program_id; } + LOG_DEBUG(Service_AM, "application_id={:016X} (fallback)", id); *out_application_id = id; R_SUCCEED(); } @@ -86,6 +107,13 @@ namespace Service::AM { R_SUCCEED(); } + Result IOverlayFunctions::IsHealthWarningRequired(Out is_required) { + LOG_DEBUG(Service_AM, "called"); + std::scoped_lock lk{m_applet->lock}; + *is_required = false; + R_SUCCEED(); + } + Result IOverlayFunctions::SetHandlingHomeButtonShortPressedEnabled(bool enabled) { LOG_DEBUG(Service_AM, "called, enabled={}", enabled); std::scoped_lock lk{m_applet->lock}; diff --git a/src/core/hle/service/am/service/overlay_functions.h b/src/core/hle/service/am/service/overlay_functions.h index 26c5cc0c88..870f5eae9c 100644 --- a/src/core/hle/service/am/service/overlay_functions.h +++ b/src/core/hle/service/am/service/overlay_functions.h @@ -18,6 +18,7 @@ namespace Service::AM { Result EndToWatchShortHomeButtonMessage(); Result GetApplicationIdForLogo(Out out_application_id); Result SetAutoSleepTimeAndDimmingTimeEnabled(bool enabled); + Result IsHealthWarningRequired(Out is_required); Result SetHandlingHomeButtonShortPressedEnabled(bool enabled); Result Unknown70(); diff --git a/src/core/hle/service/ns/application_manager_interface.cpp b/src/core/hle/service/ns/application_manager_interface.cpp index 81f42f0937..3e56b7752d 100644 --- a/src/core/hle/service/ns/application_manager_interface.cpp +++ b/src/core/hle/service/ns/application_manager_interface.cpp @@ -10,6 +10,8 @@ #include "core/hle/service/cmif_serialization.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/ns/application_manager_interface.h" + +#include "core/file_sys/content_archive.h" #include "core/hle/service/ns/content_management_interface.h" #include "core/hle/service/ns/read_only_application_control_data_interface.h" #include "core/file_sys/patch_manager.h" @@ -53,7 +55,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_ {37, nullptr, "ListRequiredVersion"}, {38, D<&IApplicationManagerInterface::CheckApplicationLaunchVersion>, "CheckApplicationLaunchVersion"}, {39, nullptr, "CheckApplicationLaunchRights"}, - {40, nullptr, "GetApplicationLogoData"}, + {40, D<&IApplicationManagerInterface::GetApplicationLogoData>, "GetApplicationLogoData"}, {41, nullptr, "CalculateApplicationDownloadRequiredSize"}, {42, nullptr, "CleanupSdCard"}, {43, D<&IApplicationManagerInterface::CheckSdCardMountStatus>, "CheckSdCardMountStatus"}, @@ -330,6 +332,53 @@ Result IApplicationManagerInterface::UnregisterNetworkServiceAccountWithUserSave LOG_DEBUG(Service_NS, "called, user_id={}", user_id.FormattedString()); R_SUCCEED(); } + +Result IApplicationManagerInterface::GetApplicationLogoData( + Out out_size, OutBuffer out_buffer, u64 application_id, + InBuffer logo_path_buffer) { + const std::string path_view{reinterpret_cast(logo_path_buffer.data()), + logo_path_buffer.size()}; + + // Find null terminator and trim the path + auto null_pos = path_view.find('\0'); + std::string path = (null_pos != std::string::npos) ? path_view.substr(0, null_pos) : path_view; + + LOG_DEBUG(Service_NS, "called, application_id={:016X}, logo_path={}", application_id, path); + + auto& content_provider = system.GetContentProviderUnion(); + + auto program = content_provider.GetEntry(application_id, FileSys::ContentRecordType::Program); + if (!program) { + LOG_WARNING(Service_NS, "Application program not found for id={:016X}", application_id); + R_RETURN(ResultUnknown); + } + + const auto logo_dir = program->GetLogoPartition(); + if (!logo_dir) { + LOG_WARNING(Service_NS, "Logo partition not found for id={:016X}", application_id); + R_RETURN(ResultUnknown); + } + + const auto file = logo_dir->GetFile(path); + if (!file) { + LOG_WARNING(Service_NS, "Logo path not found: {} for id={:016X}", path, + application_id); + R_RETURN(ResultUnknown); + } + + const auto data = file->ReadAllBytes(); + if (data.size() > out_buffer.size()) { + LOG_WARNING(Service_NS, "Logo buffer too small: have={}, need={}", out_buffer.size(), + data.size()); + R_RETURN(ResultUnknown); + } + + std::memcpy(out_buffer.data(), data.data(), data.size()); + *out_size = static_cast(data.size()); + + R_SUCCEED(); +} + Result IApplicationManagerInterface::GetApplicationControlData( OutBuffer out_buffer, Out out_actual_size, ApplicationControlSource application_control_source, u64 application_id) { diff --git a/src/core/hle/service/ns/application_manager_interface.h b/src/core/hle/service/ns/application_manager_interface.h index 9c36939257..03ca82fc29 100644 --- a/src/core/hle/service/ns/application_manager_interface.h +++ b/src/core/hle/service/ns/application_manager_interface.h @@ -59,6 +59,10 @@ public: u64 application_id); Result CheckApplicationLaunchVersion(u64 application_id); Result GetApplicationTerminateResult(Out out_result, u64 application_id); + Result GetApplicationLogoData(Out out_size, + OutBuffer out_buffer, + u64 application_id, + InBuffer logo_path_buffer); Result Unknown4022(OutCopyHandle out_event); Result Unknown4023(Out out_result); Result Unknown4053();