diff options
Diffstat (limited to 'src/core/hle/service/am')
-rw-r--r-- | src/core/hle/service/am/am.cpp | 376 | ||||
-rw-r--r-- | src/core/hle/service/am/am.h | 50 | ||||
-rw-r--r-- | src/core/hle/service/am/applet_ae.cpp | 48 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_cabinet.h | 11 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_general_backend.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_mii_edit.cpp | 52 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applet_mii_edit.h | 7 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applets.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applets.h | 49 |
9 files changed, 554 insertions, 61 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 8ffdd19e7..819dea6a7 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -8,6 +8,7 @@ #include "common/settings.h" #include "common/settings_enums.h" #include "core/core.h" +#include "core/core_timing.h" #include "core/file_sys/control_metadata.h" #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" @@ -19,6 +20,8 @@ #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" +#include "core/hle/service/am/applets/applet_cabinet.h" +#include "core/hle/service/am/applets/applet_mii_edit_types.h" #include "core/hle/service/am/applets/applet_profile_select.h" #include "core/hle/service/am/applets/applet_web_browser.h" #include "core/hle/service/am/applets/applets.h" @@ -32,11 +35,13 @@ #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ns/ns.h" +#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" #include "core/hle/service/nvnflinger/nvnflinger.h" #include "core/hle/service/pm/pm.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/sm/sm.h" #include "core/hle/service/vi/vi.h" +#include "core/hle/service/vi/vi_results.h" #include "core/memory.h" namespace Service::AM { @@ -189,8 +194,8 @@ IDisplayController::IDisplayController(Core::System& system_) {4, nullptr, "UpdateCallerAppletCaptureImage"}, {5, nullptr, "GetLastForegroundCaptureImageEx"}, {6, nullptr, "GetLastApplicationCaptureImageEx"}, - {7, nullptr, "GetCallerAppletCaptureImageEx"}, - {8, nullptr, "TakeScreenShotOfOwnLayer"}, + {7, &IDisplayController::GetCallerAppletCaptureImageEx, "GetCallerAppletCaptureImageEx"}, + {8, &IDisplayController::TakeScreenShotOfOwnLayer, "TakeScreenShotOfOwnLayer"}, {9, nullptr, "CopyBetweenCaptureBuffers"}, {10, nullptr, "AcquireLastApplicationCaptureBuffer"}, {11, nullptr, "ReleaseLastApplicationCaptureBuffer"}, @@ -207,8 +212,8 @@ IDisplayController::IDisplayController(Core::System& system_) {23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"}, {24, nullptr, "AcquireLastForegroundCaptureSharedBuffer"}, {25, nullptr, "ReleaseLastForegroundCaptureSharedBuffer"}, - {26, nullptr, "AcquireCallerAppletCaptureSharedBuffer"}, - {27, nullptr, "ReleaseCallerAppletCaptureSharedBuffer"}, + {26, &IDisplayController::AcquireCallerAppletCaptureSharedBuffer, "AcquireCallerAppletCaptureSharedBuffer"}, + {27, &IDisplayController::ReleaseCallerAppletCaptureSharedBuffer, "ReleaseCallerAppletCaptureSharedBuffer"}, {28, nullptr, "TakeScreenShotOfOwnLayerEx"}, }; // clang-format on @@ -218,6 +223,38 @@ IDisplayController::IDisplayController(Core::System& system_) IDisplayController::~IDisplayController() = default; +void IDisplayController::GetCallerAppletCaptureImageEx(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(1u); + rb.Push(0); +} + +void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IDisplayController::AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(1U); + rb.Push(0); +} + +void IDisplayController::ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + IDebugFunctions::IDebugFunctions(Core::System& system_) : ServiceFramework{system_, "IDebugFunctions"} { // clang-format off @@ -277,14 +314,14 @@ ISelfController::ISelfController(Core::System& system_, Nvnflinger::Nvnflinger& {20, nullptr, "SetDesirableKeyboardLayout"}, {21, nullptr, "GetScreenShotProgramId"}, {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"}, - {41, nullptr, "IsSystemBufferSharingEnabled"}, - {42, nullptr, "GetSystemSharedLayerHandle"}, - {43, nullptr, "GetSystemSharedBufferHandle"}, + {41, &ISelfController::IsSystemBufferSharingEnabled, "IsSystemBufferSharingEnabled"}, + {42, &ISelfController::GetSystemSharedLayerHandle, "GetSystemSharedLayerHandle"}, + {43, &ISelfController::GetSystemSharedBufferHandle, "GetSystemSharedBufferHandle"}, {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"}, {45, nullptr, "SetManagedDisplayLayerSeparationMode"}, {46, nullptr, "SetRecordingLayerCompositionEnabled"}, {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, - {51, nullptr, "ApproveToDisplay"}, + {51, &ISelfController::ApproveToDisplay, "ApproveToDisplay"}, {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"}, {61, nullptr, "SetMediaPlaybackState"}, {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"}, @@ -483,6 +520,50 @@ void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) { rb.Push(*layer_id); } +void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(this->EnsureBufferSharingEnabled()); +} + +void ISelfController::GetSystemSharedLayerHandle(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(this->EnsureBufferSharingEnabled()); + rb.Push<s64>(system_shared_buffer_id); + rb.Push<s64>(system_shared_layer_id); +} + +void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(this->EnsureBufferSharingEnabled()); + rb.Push<s64>(system_shared_buffer_id); +} + +Result ISelfController::EnsureBufferSharingEnabled() { + if (buffer_sharing_enabled) { + return ResultSuccess; + } + + if (system.GetAppletManager().GetCurrentAppletId() <= Applets::AppletId::Application) { + return VI::ResultOperationFailed; + } + + const auto display_id = nvnflinger.OpenDisplay("Default"); + const auto result = nvnflinger.GetSystemBufferManager().Initialize( + &system_shared_buffer_id, &system_shared_layer_id, *display_id); + + if (result.IsSuccess()) { + buffer_sharing_enabled = true; + } + + return result; +} + void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); @@ -508,6 +589,13 @@ void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) { rb.Push(ResultSuccess); } +void ISelfController::ApproveToDisplay(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; idle_time_detection_extension = rp.Pop<u32>(); @@ -678,7 +766,8 @@ void AppletMessageQueue::OperationModeChanged() { ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<AppletMessageQueue> msg_queue_) - : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} { + : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)}, + service_context{system_, "ICommonStateGetter"} { // clang-format off static const FunctionInfo functions[] = { {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, @@ -691,10 +780,10 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, {7, nullptr, "GetCradleStatus"}, {8, &ICommonStateGetter::GetBootMode, "GetBootMode"}, {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"}, - {10, nullptr, "RequestToAcquireSleepLock"}, + {10, &ICommonStateGetter::RequestToAcquireSleepLock, "RequestToAcquireSleepLock"}, {11, nullptr, "ReleaseSleepLock"}, {12, nullptr, "ReleaseSleepLockTransiently"}, - {13, nullptr, "GetAcquiredSleepLockEvent"}, + {13, &ICommonStateGetter::GetAcquiredSleepLockEvent, "GetAcquiredSleepLockEvent"}, {14, nullptr, "GetWakeupCount"}, {20, nullptr, "PushToGeneralChannel"}, {30, nullptr, "GetHomeButtonReaderLockAccessor"}, @@ -724,7 +813,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, {110, nullptr, "OpenMyGpuErrorHandler"}, {120, nullptr, "GetAppletLaunchedHistory"}, {200, nullptr, "GetOperationModeSystemInfo"}, - {300, nullptr, "GetSettingsPlatformRegion"}, + {300, &ICommonStateGetter::GetSettingsPlatformRegion, "GetSettingsPlatformRegion"}, {400, nullptr, "ActivateMigrationService"}, {401, nullptr, "DeactivateMigrationService"}, {500, nullptr, "DisableSleepTillShutdown"}, @@ -736,6 +825,12 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, // clang-format on RegisterHandlers(functions); + + sleep_lock_event = service_context.CreateEvent("ICommonStateGetter::SleepLockEvent"); + + // Configure applets to be in foreground state + msg_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); + msg_queue->PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); } ICommonStateGetter::~ICommonStateGetter() = default; @@ -781,6 +876,24 @@ void ICommonStateGetter::GetCurrentFocusState(HLERequestContext& ctx) { rb.Push(static_cast<u8>(FocusState::InFocus)); } +void ICommonStateGetter::RequestToAcquireSleepLock(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + // Sleep lock is acquired immediately. + sleep_lock_event->Signal(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ICommonStateGetter::GetAcquiredSleepLockEvent(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(sleep_lock_event->GetReadableEvent()); +} + void ICommonStateGetter::IsVrModeEnabled(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); @@ -867,6 +980,14 @@ void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(HLERequestContext& rb.Push(ResultSuccess); } +void ICommonStateGetter::GetSettingsPlatformRegion(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(SysPlatformRegion::Global); +} + void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled( HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); @@ -1324,18 +1445,19 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) { ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) : ServiceFramework{system_, "ILibraryAppletSelfAccessor"} { + // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "PopInData"}, - {1, nullptr, "PushOutData"}, + {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"}, + {1, &ILibraryAppletSelfAccessor::PushOutData, "PushOutData"}, {2, nullptr, "PopInteractiveInData"}, {3, nullptr, "PushInteractiveOutData"}, {5, nullptr, "GetPopInDataEvent"}, {6, nullptr, "GetPopInteractiveInDataEvent"}, - {10, nullptr, "ExitProcessAndReturn"}, - {11, nullptr, "GetLibraryAppletInfo"}, + {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"}, + {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"}, {12, nullptr, "GetMainAppletIdentityInfo"}, {13, nullptr, "CanUseApplicationCore"}, - {14, nullptr, "GetCallerAppletIdentityInfo"}, + {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"}, {15, nullptr, "GetMainAppletApplicationControlProperty"}, {16, nullptr, "GetMainAppletStorageId"}, {17, nullptr, "GetCallerAppletIdentityInfoStack"}, @@ -1361,10 +1483,180 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_) {140, nullptr, "SetApplicationMemoryReservation"}, {150, nullptr, "ShouldSetGpuTimeSliceManually"}, }; + // clang-format on RegisterHandlers(functions); + + switch (system.GetAppletManager().GetCurrentAppletId()) { + case Applets::AppletId::Cabinet: + PushInShowCabinetData(); + break; + case Applets::AppletId::MiiEdit: + PushInShowMiiEditData(); + break; + default: + break; + } } ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; +void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) { + LOG_INFO(Service_AM, "called"); + + if (queue_data.empty()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultNoDataInChannel); + return; + } + + auto data = queue_data.front(); + queue_data.pop_front(); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<IStorage>(system, std::move(data)); +} + +void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + system.Exit(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) { + struct LibraryAppletInfo { + Applets::AppletId applet_id; + Applets::LibraryAppletMode library_applet_mode; + }; + + LOG_WARNING(Service_AM, "(STUBBED) called"); + + const LibraryAppletInfo applet_info{ + .applet_id = system.GetAppletManager().GetCurrentAppletId(), + .library_applet_mode = Applets::LibraryAppletMode::AllForeground, + }; + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.PushRaw(applet_info); +} + +void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) { + struct AppletIdentityInfo { + Applets::AppletId applet_id; + INSERT_PADDING_BYTES(0x4); + u64 application_id; + }; + + LOG_WARNING(Service_AM, "(STUBBED) called"); + + const AppletIdentityInfo applet_info{ + .applet_id = Applets::AppletId::QLaunch, + .application_id = 0x0100000000001000ull, + }; + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(ResultSuccess); + rb.PushRaw(applet_info); +} + +void ILibraryAppletSelfAccessor::PushInShowCabinetData() { + const Applets::CommonArguments arguments{ + .arguments_version = Applets::CommonArgumentVersion::Version3, + .size = Applets::CommonArgumentSize::Version3, + .library_version = static_cast<u32>(Applets::CabinetAppletVersion::Version1), + .theme_color = Applets::ThemeColor::BasicBlack, + .play_startup_sound = true, + .system_tick = system.CoreTiming().GetClockTicks(), + }; + + const Applets::StartParamForAmiiboSettings amiibo_settings{ + .param_1 = 0, + .applet_mode = system.GetAppletManager().GetCabinetMode(), + .flags = Applets::CabinetFlags::None, + .amiibo_settings_1 = 0, + .device_handle = 0, + .tag_info{}, + .register_info{}, + .amiibo_settings_3{}, + }; + + std::vector<u8> argument_data(sizeof(arguments)); + std::vector<u8> settings_data(sizeof(amiibo_settings)); + std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); + std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings)); + queue_data.emplace_back(std::move(argument_data)); + queue_data.emplace_back(std::move(settings_data)); +} + +void ILibraryAppletSelfAccessor::PushInShowMiiEditData() { + struct MiiEditV3 { + Applets::MiiEditAppletInputCommon common; + Applets::MiiEditAppletInputV3 input; + }; + static_assert(sizeof(MiiEditV3) == 0x100, "MiiEditV3 has incorrect size."); + + MiiEditV3 mii_arguments{ + .common = + { + .version = Applets::MiiEditAppletVersion::Version3, + .applet_mode = Applets::MiiEditAppletMode::ShowMiiEdit, + }, + .input{}, + }; + + std::vector<u8> argument_data(sizeof(mii_arguments)); + std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments)); + + queue_data.emplace_back(std::move(argument_data)); +} + +IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_) + : ServiceFramework{system_, "IAppletCommonFunctions"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "SetTerminateResult"}, + {10, nullptr, "ReadThemeStorage"}, + {11, nullptr, "WriteThemeStorage"}, + {20, nullptr, "PushToAppletBoundChannel"}, + {21, nullptr, "TryPopFromAppletBoundChannel"}, + {40, nullptr, "GetDisplayLogicalResolution"}, + {42, nullptr, "SetDisplayMagnification"}, + {50, nullptr, "SetHomeButtonDoubleClickEnabled"}, + {51, nullptr, "GetHomeButtonDoubleClickEnabled"}, + {52, nullptr, "IsHomeButtonShortPressedBlocked"}, + {60, nullptr, "IsVrModeCurtainRequired"}, + {61, nullptr, "IsSleepRequiredByHighTemperature"}, + {62, nullptr, "IsSleepRequiredByLowBattery"}, + {70, &IAppletCommonFunctions::SetCpuBoostRequestPriority, "SetCpuBoostRequestPriority"}, + {80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"}, + {81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"}, + {90, nullptr, "OpenNamedChannelAsParent"}, + {91, nullptr, "OpenNamedChannelAsChild"}, + {100, nullptr, "SetApplicationCoreUsageMode"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IAppletCommonFunctions::~IAppletCommonFunctions() = default; + +void IAppletCommonFunctions::SetCpuBoostRequestPriority(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} IApplicationFunctions::IApplicationFunctions(Core::System& system_) : ServiceFramework{system_, "IApplicationFunctions"}, service_context{system, @@ -1941,9 +2233,6 @@ void IApplicationFunctions::PrepareForJit(HLERequestContext& ctx) { void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) { auto message_queue = std::make_shared<AppletMessageQueue>(system); - // Needed on game boot - message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); - auto server_manager = std::make_unique<ServerManager>(system); server_manager->RegisterNamedService( @@ -2049,8 +2338,8 @@ IProcessWindingController::IProcessWindingController(Core::System& system_) : ServiceFramework{system_, "IProcessWindingController"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "GetLaunchReason"}, - {11, nullptr, "OpenCallingLibraryApplet"}, + {0, &IProcessWindingController::GetLaunchReason, "GetLaunchReason"}, + {11, &IProcessWindingController::OpenCallingLibraryApplet, "OpenCallingLibraryApplet"}, {21, nullptr, "PushContext"}, {22, nullptr, "PopContext"}, {23, nullptr, "CancelWindingReservation"}, @@ -2064,4 +2353,47 @@ IProcessWindingController::IProcessWindingController(Core::System& system_) } IProcessWindingController::~IProcessWindingController() = default; + +void IProcessWindingController::GetLaunchReason(HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + struct AppletProcessLaunchReason { + u8 flag; + INSERT_PADDING_BYTES(3); + }; + static_assert(sizeof(AppletProcessLaunchReason) == 0x4, + "AppletProcessLaunchReason is an invalid size"); + + AppletProcessLaunchReason reason{ + .flag = 0, + }; + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(reason); +} + +void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) { + const auto applet_id = system.GetAppletManager().GetCurrentAppletId(); + const auto applet_mode = Applets::LibraryAppletMode::AllForeground; + + LOG_WARNING(Service_AM, "(STUBBED) called with applet_id={:08X}, applet_mode={:08X}", applet_id, + applet_mode); + + const auto& applet_manager{system.GetAppletManager()}; + const auto applet = applet_manager.GetApplet(applet_id, applet_mode); + + if (applet == nullptr) { + LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet); +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index f86841c60..349482dcc 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -120,6 +120,12 @@ class IDisplayController final : public ServiceFramework<IDisplayController> { public: explicit IDisplayController(Core::System& system_); ~IDisplayController() override; + +private: + void GetCallerAppletCaptureImageEx(HLERequestContext& ctx); + void TakeScreenShotOfOwnLayer(HLERequestContext& ctx); + void AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx); + void ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx); }; class IDebugFunctions final : public ServiceFramework<IDebugFunctions> { @@ -147,9 +153,13 @@ private: void SetRestartMessageEnabled(HLERequestContext& ctx); void SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx); void SetAlbumImageOrientation(HLERequestContext& ctx); + void IsSystemBufferSharingEnabled(HLERequestContext& ctx); + void GetSystemSharedBufferHandle(HLERequestContext& ctx); + void GetSystemSharedLayerHandle(HLERequestContext& ctx); void CreateManagedDisplayLayer(HLERequestContext& ctx); void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx); void SetHandlesRequestToDisplay(HLERequestContext& ctx); + void ApproveToDisplay(HLERequestContext& ctx); void SetIdleTimeDetectionExtension(HLERequestContext& ctx); void GetIdleTimeDetectionExtension(HLERequestContext& ctx); void ReportUserIsActive(HLERequestContext& ctx); @@ -161,6 +171,8 @@ private: void SaveCurrentScreenshot(HLERequestContext& ctx); void SetRecordVolumeMuted(HLERequestContext& ctx); + Result EnsureBufferSharingEnabled(); + enum class ScreenshotPermission : u32 { Inherit = 0, Enable = 1, @@ -176,7 +188,10 @@ private: u32 idle_time_detection_extension = 0; u64 num_fatal_sections_entered = 0; + u64 system_shared_buffer_id = 0; + u64 system_shared_layer_id = 0; bool is_auto_sleep_disabled = false; + bool buffer_sharing_enabled = false; ScreenshotPermission screenshot_permission = ScreenshotPermission::Inherit; }; @@ -212,9 +227,16 @@ private: CaptureButtonLongPressing, }; + enum class SysPlatformRegion : s32 { + Global = 1, + Terra = 2, + }; + void GetEventHandle(HLERequestContext& ctx); void ReceiveMessage(HLERequestContext& ctx); void GetCurrentFocusState(HLERequestContext& ctx); + void RequestToAcquireSleepLock(HLERequestContext& ctx); + void GetAcquiredSleepLockEvent(HLERequestContext& ctx); void GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx); void GetOperationMode(HLERequestContext& ctx); void GetPerformanceMode(HLERequestContext& ctx); @@ -227,10 +249,13 @@ private: void GetDefaultDisplayResolution(HLERequestContext& ctx); void SetCpuBoostMode(HLERequestContext& ctx); void PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx); + void GetSettingsPlatformRegion(HLERequestContext& ctx); void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx); std::shared_ptr<AppletMessageQueue> msg_queue; bool vr_mode_state{}; + Kernel::KEvent* sleep_lock_event; + KernelHelpers::ServiceContext service_context; }; class IStorageImpl { @@ -294,6 +319,27 @@ class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletS public: explicit ILibraryAppletSelfAccessor(Core::System& system_); ~ILibraryAppletSelfAccessor() override; + +private: + void PopInData(HLERequestContext& ctx); + void PushOutData(HLERequestContext& ctx); + void GetLibraryAppletInfo(HLERequestContext& ctx); + void ExitProcessAndReturn(HLERequestContext& ctx); + void GetCallerAppletIdentityInfo(HLERequestContext& ctx); + + void PushInShowCabinetData(); + void PushInShowMiiEditData(); + + std::deque<std::vector<u8>> queue_data; +}; + +class IAppletCommonFunctions final : public ServiceFramework<IAppletCommonFunctions> { +public: + explicit IAppletCommonFunctions(Core::System& system_); + ~IAppletCommonFunctions() override; + +private: + void SetCpuBoostRequestPriority(HLERequestContext& ctx); }; class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> { @@ -378,6 +424,10 @@ class IProcessWindingController final : public ServiceFramework<IProcessWindingC public: explicit IProcessWindingController(Core::System& system_); ~IProcessWindingController() override; + +private: + void GetLaunchReason(HLERequestContext& ctx); + void OpenCallingLibraryApplet(HLERequestContext& ctx); }; void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system); diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp index ee9d99a54..eb12312cc 100644 --- a/src/core/hle/service/am/applet_ae.cpp +++ b/src/core/hle/service/am/applet_ae.cpp @@ -27,7 +27,7 @@ public: {10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"}, {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"}, {20, &ILibraryAppletProxy::OpenLibraryAppletSelfAccessor, "OpenLibraryAppletSelfAccessor"}, - {21, nullptr, "GetAppletCommonFunctions"}, + {21, &ILibraryAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"}, {22, nullptr, "GetHomeMenuFunctions"}, {23, nullptr, "GetGlobalStateController"}, {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, @@ -86,28 +86,36 @@ private: rb.PushIpcInterface<IProcessWindingController>(system); } - void GetDebugFunctions(HLERequestContext& ctx) { + void GetLibraryAppletCreator(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<IDebugFunctions>(system); + rb.PushIpcInterface<ILibraryAppletCreator>(system); } - void GetLibraryAppletCreator(HLERequestContext& ctx) { + void OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<ILibraryAppletCreator>(system); + rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system); } - void OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) { + void GetAppletCommonFunctions(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system); + rb.PushIpcInterface<IAppletCommonFunctions>(system); + } + + void GetDebugFunctions(HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<IDebugFunctions>(system); } Nvnflinger::Nvnflinger& nvnflinger; @@ -133,7 +141,7 @@ public: {20, &ISystemAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"}, {21, &ISystemAppletProxy::GetGlobalStateController, "GetGlobalStateController"}, {22, &ISystemAppletProxy::GetApplicationCreator, "GetApplicationCreator"}, - {23, nullptr, "GetAppletCommonFunctions"}, + {23, &ISystemAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"}, {1000, &ISystemAppletProxy::GetDebugFunctions, "GetDebugFunctions"}, }; // clang-format on @@ -182,14 +190,6 @@ private: rb.PushIpcInterface<IDisplayController>(system); } - void GetDebugFunctions(HLERequestContext& ctx) { - LOG_DEBUG(Service_AM, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IDebugFunctions>(system); - } - void GetLibraryAppletCreator(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); @@ -222,6 +222,22 @@ private: rb.PushIpcInterface<IApplicationCreator>(system); } + void GetAppletCommonFunctions(HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<IAppletCommonFunctions>(system); + } + + void GetDebugFunctions(HLERequestContext& ctx) { + LOG_DEBUG(Service_AM, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<IDebugFunctions>(system); + } + Nvnflinger::Nvnflinger& nvnflinger; std::shared_ptr<AppletMessageQueue> msg_queue; }; diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h index b56427021..f498796f7 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.h +++ b/src/core/hle/service/am/applets/applet_cabinet.h @@ -29,6 +29,15 @@ enum class CabinetAppletVersion : u32 { Version1 = 0x1, }; +enum class CabinetFlags : u8 { + None = 0, + DeviceHandle = 1 << 0, + TagInfo = 1 << 1, + RegisterInfo = 1 << 2, + All = DeviceHandle | TagInfo | RegisterInfo, +}; +DECLARE_ENUM_FLAG_OPERATORS(CabinetFlags) + enum class CabinetResult : u8 { Cancel = 0, TagInfo = 1 << 1, @@ -51,7 +60,7 @@ static_assert(sizeof(AmiiboSettingsStartParam) == 0x30, struct StartParamForAmiiboSettings { u8 param_1; Service::NFP::CabinetMode applet_mode; - u8 flags; + CabinetFlags flags; u8 amiibo_settings_1; u64 device_handle; Service::NFP::TagInfo tag_info; diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp index 8b352020e..c0032f652 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.cpp +++ b/src/core/hle/service/am/applets/applet_general_backend.cpp @@ -223,9 +223,9 @@ void StubApplet::Initialize() { const auto data = broker.PeekDataToAppletForDebug(); system.GetReporter().SaveUnimplementedAppletReport( - static_cast<u32>(id), common_args.arguments_version, common_args.library_version, - common_args.theme_color, common_args.play_startup_sound, common_args.system_tick, - data.normal, data.interactive); + static_cast<u32>(id), static_cast<u32>(common_args.arguments_version), + common_args.library_version, static_cast<u32>(common_args.theme_color), + common_args.play_startup_sound, common_args.system_tick, data.normal, data.interactive); LogCurrentStorage(broker, "Initialize"); } diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index 350a90818..50adc7c02 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp @@ -7,7 +7,9 @@ #include "core/frontend/applets/mii_edit.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/applet_mii_edit.h" +#include "core/hle/service/mii/mii.h" #include "core/hle/service/mii/mii_manager.h" +#include "core/hle/service/sm/sm.h" namespace Service::AM::Applets { @@ -56,6 +58,12 @@ void MiiEdit::Initialize() { sizeof(MiiEditAppletInputV4)); break; } + + manager = system.ServiceManager().GetService<Mii::MiiDBModule>("mii:e")->GetMiiManager(); + if (manager == nullptr) { + manager = std::make_shared<Mii::MiiManager>(); + } + manager->Initialize(metadata); } bool MiiEdit::TransactionComplete() const { @@ -78,22 +86,46 @@ void MiiEdit::Execute() { // This is a default stub for each of the MiiEdit applet modes. switch (applet_input_common.applet_mode) { case MiiEditAppletMode::ShowMiiEdit: - case MiiEditAppletMode::AppendMii: case MiiEditAppletMode::AppendMiiImage: case MiiEditAppletMode::UpdateMiiImage: MiiEditOutput(MiiEditResult::Success, 0); break; - case MiiEditAppletMode::CreateMii: - case MiiEditAppletMode::EditMii: { - Mii::CharInfo char_info{}; + case MiiEditAppletMode::AppendMii: { Mii::StoreData store_data{}; - store_data.BuildBase(Mii::Gender::Male); - char_info.SetFromStoreData(store_data); + store_data.BuildRandom(Mii::Age::All, Mii::Gender::All, Mii::Race::All); + store_data.SetNickname({u'y', u'u', u'z', u'u'}); + store_data.SetChecksum(); + const auto result = manager->AddOrReplace(metadata, store_data); + + if (result.IsError()) { + MiiEditOutput(MiiEditResult::Cancel, 0); + break; + } + + s32 index = manager->FindIndex(store_data.GetCreateId(), false); + + if (index == -1) { + MiiEditOutput(MiiEditResult::Cancel, 0); + break; + } + + MiiEditOutput(MiiEditResult::Success, index); + break; + } + case MiiEditAppletMode::CreateMii: { + Mii::CharInfo char_info{}; + manager->BuildRandom(char_info, Mii::Age::All, Mii::Gender::All, Mii::Race::All); const MiiEditCharInfo edit_char_info{ - .mii_info{applet_input_common.applet_mode == MiiEditAppletMode::EditMii - ? applet_input_v4.char_info.mii_info - : char_info}, + .mii_info{char_info}, + }; + + MiiEditOutputForCharInfoEditing(MiiEditResult::Success, edit_char_info); + break; + } + case MiiEditAppletMode::EditMii: { + const MiiEditCharInfo edit_char_info{ + .mii_info{applet_input_v4.char_info.mii_info}, }; MiiEditOutputForCharInfoEditing(MiiEditResult::Success, edit_char_info); @@ -113,6 +145,8 @@ void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) { .index{index}, }; + LOG_INFO(Input, "called, result={}, index={}", result, index); + std::vector<u8> out_data(sizeof(MiiEditAppletOutput)); std::memcpy(out_data.data(), &applet_output, sizeof(MiiEditAppletOutput)); diff --git a/src/core/hle/service/am/applets/applet_mii_edit.h b/src/core/hle/service/am/applets/applet_mii_edit.h index 3f46fae1b..7ff34af49 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.h +++ b/src/core/hle/service/am/applets/applet_mii_edit.h @@ -11,6 +11,11 @@ namespace Core { class System; } // namespace Core +namespace Service::Mii { +struct DatabaseSessionMetadata; +class MiiManager; +} // namespace Service::Mii + namespace Service::AM::Applets { class MiiEdit final : public Applet { @@ -40,6 +45,8 @@ private: MiiEditAppletInputV4 applet_input_v4{}; bool is_complete{false}; + std::shared_ptr<Mii::MiiManager> manager = nullptr; + Mii::DatabaseSessionMetadata metadata{}; }; } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 10afbc2da..89d5434af 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -199,6 +199,14 @@ const AppletFrontendSet& AppletManager::GetAppletFrontendSet() const { return frontend; } +NFP::CabinetMode AppletManager::GetCabinetMode() const { + return cabinet_mode; +} + +AppletId AppletManager::GetCurrentAppletId() const { + return current_applet_id; +} + void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { if (set.cabinet != nullptr) { frontend.cabinet = std::move(set.cabinet); @@ -237,6 +245,14 @@ void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { } } +void AppletManager::SetCabinetMode(NFP::CabinetMode mode) { + cabinet_mode = mode; +} + +void AppletManager::SetCurrentAppletId(AppletId applet_id) { + current_applet_id = applet_id; +} + void AppletManager::SetDefaultAppletFrontendSet() { ClearAll(); SetDefaultAppletsIfMissing(); diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 12f374199..f02bbc450 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -34,6 +34,10 @@ class KEvent; class KReadableEvent; } // namespace Kernel +namespace Service::NFP { +enum class CabinetMode : u8; +} // namespace Service::NFP + namespace Service::AM { class IStorage; @@ -41,6 +45,8 @@ class IStorage; namespace Applets { enum class AppletId : u32 { + None = 0x00, + Application = 0x01, OverlayDisplay = 0x02, QLaunch = 0x03, Starter = 0x04, @@ -71,6 +77,32 @@ enum class LibraryAppletMode : u32 { AllForegroundInitiallyHidden = 4, }; +enum class CommonArgumentVersion : u32 { + Version0, + Version1, + Version2, + Version3, +}; + +enum class CommonArgumentSize : u32 { + Version3 = 0x20, +}; + +enum class ThemeColor : u32 { + BasicWhite = 0, + BasicBlack = 3, +}; + +struct CommonArguments { + CommonArgumentVersion arguments_version; + CommonArgumentSize size; + u32 library_version; + ThemeColor theme_color; + bool play_startup_sound; + u64_le system_tick; +}; +static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size."); + class AppletDataBroker final { public: explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_); @@ -161,16 +193,6 @@ public: } protected: - struct CommonArguments { - u32_le arguments_version; - u32_le size; - u32_le library_version; - u32_le theme_color; - bool play_startup_sound; - u64_le system_tick; - }; - static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size."); - CommonArguments common_args{}; AppletDataBroker broker; LibraryAppletMode applet_mode; @@ -219,8 +241,12 @@ public: ~AppletManager(); const AppletFrontendSet& GetAppletFrontendSet() const; + NFP::CabinetMode GetCabinetMode() const; + AppletId GetCurrentAppletId() const; void SetAppletFrontendSet(AppletFrontendSet set); + void SetCabinetMode(NFP::CabinetMode mode); + void SetCurrentAppletId(AppletId applet_id); void SetDefaultAppletFrontendSet(); void SetDefaultAppletsIfMissing(); void ClearAll(); @@ -228,6 +254,9 @@ public: std::shared_ptr<Applet> GetApplet(AppletId id, LibraryAppletMode mode) const; private: + AppletId current_applet_id{}; + NFP::CabinetMode cabinet_mode{}; + AppletFrontendSet frontend; Core::System& system; }; |