diff options
Diffstat (limited to 'src/core/hle/service/apt')
-rw-r--r-- | src/core/hle/service/apt/apt.cpp | 43 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt.h | 10 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt_s.cpp | 4 |
3 files changed, 47 insertions, 10 deletions
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index c36775473..59ea9823d 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -65,6 +65,7 @@ union AppletAttributes { u32 raw; BitField<0, 3, u32> applet_pos; + BitField<29, 1, u32> is_home_menu; AppletAttributes() : raw(0) {} AppletAttributes(u32 attributes) : raw(attributes) {} @@ -158,6 +159,11 @@ static AppletSlotData* GetAppletSlotData(AppletAttributes attributes) { if (slot == AppletSlot::Error) return nullptr; + // The Home Menu is a system applet, however, it has its own applet slot so that it can run + // concurrently with other system applets. + if (slot == AppletSlot::SystemApplet && attributes.is_home_menu) + return &applet_slots[static_cast<size_t>(AppletSlot::HomeMenu)]; + return &applet_slots[static_cast<size_t>(slot)]; } @@ -201,6 +207,19 @@ void Initialize(Service::Interface* self) { rb.Push(RESULT_SUCCESS); rb.PushCopyHandles(Kernel::g_handle_table.Create(slot_data->notification_event).Unwrap(), Kernel::g_handle_table.Create(slot_data->parameter_event).Unwrap()); + + if (slot_data->applet_id == AppletId::Application || + slot_data->applet_id == AppletId::HomeMenu) { + // Initialize the APT parameter to wake up the application. + next_parameter.emplace(); + next_parameter->signal = static_cast<u32>(SignalType::Wakeup); + next_parameter->sender_id = static_cast<u32>(AppletId::None); + next_parameter->destination_id = app_id; + // Not signaling the parameter event will cause the application (or Home Menu) to hang + // during startup. In the real console, it is usually the Kernel and Home Menu who cause NS + // to signal the HomeMenu and Application parameter events, respectively. + slot_data->parameter_event->Signal(); + } } static u32 DecompressLZ11(const u8* in, u8* out) { @@ -563,7 +582,7 @@ void ReceiveParameter(Service::Interface* self) { ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap() : 0); - rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0); + rb.PushStaticBuffer(buffer, next_parameter->buffer.size(), 0); Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size()); @@ -611,7 +630,7 @@ void GlanceParameter(Service::Interface* self) { ? Kernel::g_handle_table.Create(next_parameter->object).Unwrap() : 0); - rb.PushStaticBuffer(buffer, static_cast<u32>(next_parameter->buffer.size()), 0); + rb.PushStaticBuffer(buffer, next_parameter->buffer.size(), 0); Memory::WriteBlock(buffer, next_parameter->buffer.data(), next_parameter->buffer.size()); @@ -763,6 +782,20 @@ void PrepareToStartLibraryApplet(Service::Interface* self) { } } +void PrepareToStartNewestHomeMenu(Service::Interface* self) { + IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1A, 0, 0); // 0x1A0000 + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + + // TODO(Subv): This command can only be called by a System Applet (return 0xC8A0CC04 otherwise). + + // This command must return an error when called, otherwise the Home Menu will try to reboot the + // system. + rb.Push(ResultCode(ErrorDescription::AlreadyExists, ErrorModule::Applet, + ErrorSummary::InvalidState, ErrorLevel::Status)); + + LOG_DEBUG(Service_APT, "called"); +} + void PreloadLibraryApplet(Service::Interface* self) { IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x16, 1, 0); // 0x160040 AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>()); @@ -1058,12 +1091,6 @@ void Init() { slot_data.parameter_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter"); } - - // Initialize the parameter to wake up the application. - next_parameter.emplace(); - next_parameter->signal = static_cast<u32>(SignalType::Wakeup); - next_parameter->destination_id = static_cast<u32>(AppletId::Application); - applet_slots[static_cast<size_t>(AppletSlot::Application)].parameter_event->Signal(); } void Shutdown() { diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 96b28b438..7b79e1f3e 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -420,6 +420,16 @@ void GetAppCpuTimeLimit(Service::Interface* self); void PrepareToStartLibraryApplet(Service::Interface* self); /** + * APT::PrepareToStartNewestHomeMenu service function + * Inputs: + * 0 : Command header [0x001A0000] + * Outputs: + * 0 : Return header + * 1 : Result of function + */ +void PrepareToStartNewestHomeMenu(Service::Interface* self); + +/** * APT::PreloadLibraryApplet service function * Inputs: * 0 : Command header [0x00160040] diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index cf74c2a36..bb78ee7d7 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -17,7 +17,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00060040, GetAppletInfo, "GetAppletInfo"}, {0x00070000, nullptr, "GetLastSignaledAppletId"}, {0x00080000, nullptr, "CountRegisteredApplet"}, - {0x00090040, nullptr, "IsRegistered"}, + {0x00090040, IsRegistered, "IsRegistered"}, {0x000A0040, nullptr, "GetAttribute"}, {0x000B0040, InquireNotification, "InquireNotification"}, {0x000C0104, SendParameter, "SendParameter"}, @@ -34,7 +34,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, {0x00190040, nullptr, "PrepareToStartSystemApplet"}, - {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, + {0x001A0000, PrepareToStartNewestHomeMenu, "PrepareToStartNewestHomeMenu"}, {0x001B00C4, nullptr, "StartApplication"}, {0x001C0000, nullptr, "WakeupApplication"}, {0x001D0000, nullptr, "CancelApplication"}, |