From 674bd550a4e2e9003a9e9b0d7b169da9af1b8cef Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Sun, 10 Dec 2017 20:01:11 -0500
Subject: [PATCH] HLE/APT: Stubbed FinishPreloadingLibraryApplet.

An applet is considered "loaded" when the parent application calls this function.
---
 src/core/hle/service/apt/apt.cpp   | 21 ++++++++++++++++++++-
 src/core/hle/service/apt/apt.h     | 11 +++++++++++
 src/core/hle/service/apt/apt_s.cpp |  2 +-
 src/core/hle/service/apt/apt_u.cpp |  2 +-
 4 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index b5a0f7d03..4a4276e70 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -76,6 +76,7 @@ struct AppletSlotData {
     AppletId applet_id;
     AppletSlot slot;
     bool registered;
+    bool loaded;
     AppletAttributes attributes;
     Kernel::SharedPtr<Kernel::Event> notification_event;
     Kernel::SharedPtr<Kernel::Event> parameter_event;
@@ -507,7 +508,7 @@ void IsRegistered(Service::Interface* self) {
     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
     rb.Push(RESULT_SUCCESS); // No error
 
-    auto* const slot_data = GetAppletSlotData(app_id);
+    const auto* slot_data = GetAppletSlotData(app_id);
 
     // Check if an LLE applet was registered first, then fallback to HLE applets
     bool is_registered = slot_data && slot_data->registered;
@@ -887,6 +888,20 @@ void PreloadLibraryApplet(Service::Interface* self) {
     }
 }
 
+void FinishPreloadingLibraryApplet(Service::Interface* self) {
+    IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x17, 1, 0); // 0x00170040
+    AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
+
+    // TODO(Subv): This function should fail depending on the applet preparation state.
+    auto& slot = applet_slots[static_cast<size_t>(AppletSlot::LibraryApplet)];
+    slot.loaded = true;
+
+    IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
+    rb.Push(RESULT_SUCCESS);
+
+    LOG_WARNING(Service_APT, "(STUBBED) called applet_id=%03X", static_cast<u32>(applet_id));
+}
+
 void StartLibraryApplet(Service::Interface* self) {
     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1E, 2, 4); // 0x1E0084
     AppletId applet_id = static_cast<AppletId>(rp.Pop<u32>());
@@ -1158,6 +1173,7 @@ void Init() {
         slot_data.applet_id = AppletId::None;
         slot_data.attributes.raw = 0;
         slot_data.registered = false;
+        slot_data.loaded = false;
         slot_data.notification_event =
             Kernel::Event::Create(Kernel::ResetType::OneShot, "APT:Notification");
         slot_data.parameter_event =
@@ -1175,6 +1191,9 @@ void Shutdown() {
         slot.registered = false;
         slot.notification_event = nullptr;
         slot.parameter_event = nullptr;
+        slot.loaded = false;
+        slot.attributes.raw = 0;
+        slot.applet_id = AppletId::None;
     }
 
     next_parameter = boost::none;
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
index 7b79e1f3e..ef3911ace 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -440,6 +440,17 @@ void PrepareToStartNewestHomeMenu(Service::Interface* self);
  */
 void PreloadLibraryApplet(Service::Interface* self);
 
+/**
+ * APT::FinishPreloadingLibraryApplet service function
+ *  Inputs:
+ *      0 : Command header [0x00170040]
+ *      1 : Id of the applet
+ *  Outputs:
+ *      0 : Return header
+ *      1 : Result of function, 0 on success, otherwise error code
+ */
+void FinishPreloadingLibraryApplet(Service::Interface* self);
+
 /**
  * APT::StartLibraryApplet service function
  *  Inputs:
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp
index bb78ee7d7..eb15f82f4 100644
--- a/src/core/hle/service/apt/apt_s.cpp
+++ b/src/core/hle/service/apt/apt_s.cpp
@@ -31,7 +31,7 @@ const Interface::FunctionInfo FunctionTable[] = {
     {0x00140040, nullptr, "SetPreparationState"},
     {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
     {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
-    {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
+    {0x00170040, FinishPreloadingLibraryApplet, "FinishPreloadingLibraryApplet"},
     {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
     {0x00190040, nullptr, "PrepareToStartSystemApplet"},
     {0x001A0000, PrepareToStartNewestHomeMenu, "PrepareToStartNewestHomeMenu"},
diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp
index 9dd002590..12eb206ca 100644
--- a/src/core/hle/service/apt/apt_u.cpp
+++ b/src/core/hle/service/apt/apt_u.cpp
@@ -31,7 +31,7 @@ const Interface::FunctionInfo FunctionTable[] = {
     {0x00140040, nullptr, "SetPreparationState"},
     {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"},
     {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"},
-    {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
+    {0x00170040, FinishPreloadingLibraryApplet, "FinishPreloadingLibraryApplet"},
     {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"},
     {0x00190040, nullptr, "PrepareToStartSystemApplet"},
     {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},