From b57d58c0dc94857d28a3ef197d9656f0fbad8e08 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 23 Sep 2017 13:59:07 -0500 Subject: HLE/APT: Prepare the APT Wakeup parameter when the game calls Initialize We need to know what is being run so we can set the APT parameter destination AppId correctly. Delaying the preparation of the parameter until we know which AppId is running lets us support booting both the Home Menu and normal game Applications. --- src/core/hle/service/apt/apt.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 8c0ba73f2..ea964bab1 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(AppletSlot::HomeMenu)]; + return &applet_slots[static_cast(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(SignalType::Wakeup); + next_parameter->sender_id = static_cast(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) { @@ -1041,12 +1060,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(SignalType::Wakeup); - next_parameter->destination_id = static_cast(AppletId::Application); - applet_slots[static_cast(AppletSlot::Application)].parameter_event->Signal(); } void Shutdown() { -- cgit v1.2.3