mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2024-11-30 13:24:16 +01:00
Merge pull request #2946 from Subv/home_menu_apt
Implement PrepareToStartNewestHomeMenu and fixed an APT regression.
This commit is contained in:
commit
7056b9c46a
@ -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)];
|
||||
}
|
||||
|
||||
@ -197,6 +203,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) {
|
||||
@ -757,6 +776,20 @@ void PrepareToStartLibraryApplet(Service::Interface* self) {
|
||||
LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id);
|
||||
}
|
||||
|
||||
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>());
|
||||
@ -1041,12 +1074,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() {
|
||||
|
@ -419,6 +419,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:
|
||||
|
@ -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, nullptr, "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"},
|
||||
|
Loading…
Reference in New Issue
Block a user