summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSubv <subv2112@gmail.com>2017-09-23 13:59:07 -0500
committerSubv <subv2112@gmail.com>2017-09-24 08:59:30 -0500
commitb57d58c0dc94857d28a3ef197d9656f0fbad8e08 (patch)
treeee63fba3ff78cc6dc35d2eb280dd84858fabf043 /src
parenta7758b0b36f50b0d0f20149134551f4dfee01442 (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/apt/apt.cpp25
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 {
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) {
@@ -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<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() {