diff options
| -rw-r--r-- | src/core/hle/service/apt/apt.cpp | 25 |
1 files 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 { | |||
| 65 | u32 raw; | 65 | u32 raw; |
| 66 | 66 | ||
| 67 | BitField<0, 3, u32> applet_pos; | 67 | BitField<0, 3, u32> applet_pos; |
| 68 | BitField<29, 1, u32> is_home_menu; | ||
| 68 | 69 | ||
| 69 | AppletAttributes() : raw(0) {} | 70 | AppletAttributes() : raw(0) {} |
| 70 | AppletAttributes(u32 attributes) : raw(attributes) {} | 71 | AppletAttributes(u32 attributes) : raw(attributes) {} |
| @@ -158,6 +159,11 @@ static AppletSlotData* GetAppletSlotData(AppletAttributes attributes) { | |||
| 158 | if (slot == AppletSlot::Error) | 159 | if (slot == AppletSlot::Error) |
| 159 | return nullptr; | 160 | return nullptr; |
| 160 | 161 | ||
| 162 | // The Home Menu is a system applet, however, it has its own applet slot so that it can run | ||
| 163 | // concurrently with other system applets. | ||
| 164 | if (slot == AppletSlot::SystemApplet && attributes.is_home_menu) | ||
| 165 | return &applet_slots[static_cast<size_t>(AppletSlot::HomeMenu)]; | ||
| 166 | |||
| 161 | return &applet_slots[static_cast<size_t>(slot)]; | 167 | return &applet_slots[static_cast<size_t>(slot)]; |
| 162 | } | 168 | } |
| 163 | 169 | ||
| @@ -197,6 +203,19 @@ void Initialize(Service::Interface* self) { | |||
| 197 | rb.Push(RESULT_SUCCESS); | 203 | rb.Push(RESULT_SUCCESS); |
| 198 | rb.PushCopyHandles(Kernel::g_handle_table.Create(slot_data->notification_event).Unwrap(), | 204 | rb.PushCopyHandles(Kernel::g_handle_table.Create(slot_data->notification_event).Unwrap(), |
| 199 | Kernel::g_handle_table.Create(slot_data->parameter_event).Unwrap()); | 205 | Kernel::g_handle_table.Create(slot_data->parameter_event).Unwrap()); |
| 206 | |||
| 207 | if (slot_data->applet_id == AppletId::Application || | ||
| 208 | slot_data->applet_id == AppletId::HomeMenu) { | ||
| 209 | // Initialize the APT parameter to wake up the application. | ||
| 210 | next_parameter.emplace(); | ||
| 211 | next_parameter->signal = static_cast<u32>(SignalType::Wakeup); | ||
| 212 | next_parameter->sender_id = static_cast<u32>(AppletId::None); | ||
| 213 | next_parameter->destination_id = app_id; | ||
| 214 | // Not signaling the parameter event will cause the application (or Home Menu) to hang | ||
| 215 | // during startup. In the real console, it is usually the Kernel and Home Menu who cause NS | ||
| 216 | // to signal the HomeMenu and Application parameter events, respectively. | ||
| 217 | slot_data->parameter_event->Signal(); | ||
| 218 | } | ||
| 200 | } | 219 | } |
| 201 | 220 | ||
| 202 | static u32 DecompressLZ11(const u8* in, u8* out) { | 221 | static u32 DecompressLZ11(const u8* in, u8* out) { |
| @@ -1041,12 +1060,6 @@ void Init() { | |||
| 1041 | slot_data.parameter_event = | 1060 | slot_data.parameter_event = |
| 1042 | Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter"); | 1061 | Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Parameter"); |
| 1043 | } | 1062 | } |
| 1044 | |||
| 1045 | // Initialize the parameter to wake up the application. | ||
| 1046 | next_parameter.emplace(); | ||
| 1047 | next_parameter->signal = static_cast<u32>(SignalType::Wakeup); | ||
| 1048 | next_parameter->destination_id = static_cast<u32>(AppletId::Application); | ||
| 1049 | applet_slots[static_cast<size_t>(AppletSlot::Application)].parameter_event->Signal(); | ||
| 1050 | } | 1063 | } |
| 1051 | 1064 | ||
| 1052 | void Shutdown() { | 1065 | void Shutdown() { |