summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/am
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/am')
-rw-r--r--src/core/hle/service/am/am.cpp376
-rw-r--r--src/core/hle/service/am/am.h50
-rw-r--r--src/core/hle/service/am/applet_ae.cpp48
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.h11
-rw-r--r--src/core/hle/service/am/applets/applet_general_backend.cpp6
-rw-r--r--src/core/hle/service/am/applets/applet_mii_edit.cpp52
-rw-r--r--src/core/hle/service/am/applets/applet_mii_edit.h7
-rw-r--r--src/core/hle/service/am/applets/applets.cpp16
-rw-r--r--src/core/hle/service/am/applets/applets.h49
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;
};