From f7dc637a616fd202f213a1a8eac4888167462825 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Mon, 15 Jan 2018 15:43:46 -0500
Subject: [PATCH] AppletOE: Stub a bunch of functions required by libnx
 homebrew.

---
 src/core/hle/service/am/applet_oe.cpp | 66 +++++++++++++++++++++++++--
 1 file changed, 62 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index b629ac509b..ff0390b58a 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -71,6 +71,15 @@ private:
         // Takes 3 input u8s with each field located immediately after the previous u8, these are
         // bool flags. No output.
 
+        IPC::RequestParser rp{ctx};
+
+        struct FocusHandlingModeParams {
+            u8 unknown0;
+            u8 unknown1;
+            u8 unknown2;
+        };
+        auto flags = rp.PopRaw<FocusHandlingModeParams>();
+
         IPC::RequestBuilder rb{ctx, 2};
         rb.Push(RESULT_SUCCESS);
 
@@ -85,27 +94,38 @@ private:
     }
 
     void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
+        IPC::RequestParser rp{ctx};
+
+        bool flag = rp.Pop<bool>();
+
         IPC::RequestBuilder rb{ctx, 2};
         rb.Push(RESULT_SUCCESS);
 
-        LOG_WARNING(Service, "(STUBBED) called");
+        LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
     }
 
     void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
+        IPC::RequestParser rp{ctx};
+
+        bool flag = rp.Pop<bool>();
+
         IPC::RequestBuilder rb{ctx, 2};
         rb.Push(RESULT_SUCCESS);
 
-        LOG_WARNING(Service, "(STUBBED) called");
+        LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
     }
 
     void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
         // Takes 3 input u8s with each field located immediately after the previous u8, these are
         // bool flags. No output.
+        IPC::RequestParser rp{ctx};
+
+        bool enabled = rp.Pop<bool>();
 
         IPC::RequestBuilder rb{ctx, 2};
         rb.Push(RESULT_SUCCESS);
 
-        LOG_WARNING(Service, "(STUBBED) called");
+        LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
     }
 };
 
@@ -115,6 +135,8 @@ public:
         static const FunctionInfo functions[] = {
             {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
             {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
+            {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
+            {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
             {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
         };
         RegisterHandlers(functions);
@@ -123,6 +145,16 @@ public:
     }
 
 private:
+    enum class FocusState : u8 {
+        InFocus = 1,
+        NotInFocus = 2,
+    };
+
+    enum class OperationMode : u8 {
+        Handheld = 0,
+        Docked = 1,
+    };
+
     void GetEventHandle(Kernel::HLERequestContext& ctx) {
         event->Signal();
 
@@ -144,7 +176,23 @@ private:
     void GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
         IPC::RequestBuilder rb{ctx, 3};
         rb.Push(RESULT_SUCCESS);
-        rb.Push<u32>(1); // 1: In focus, 2/3: Out of focus(running in "background")
+        rb.Push(static_cast<u8>(FocusState::InFocus));
+
+        LOG_WARNING(Service, "(STUBBED) called");
+    }
+
+    void GetOperationMode(Kernel::HLERequestContext& ctx) {
+        IPC::RequestBuilder rb{ctx, 3};
+        rb.Push(RESULT_SUCCESS);
+        rb.Push(static_cast<u8>(OperationMode::Handheld));
+
+        LOG_WARNING(Service, "(STUBBED) called");
+    }
+
+    void GetPerformanceMode(Kernel::HLERequestContext& ctx) {
+        IPC::RequestBuilder rb{ctx, 3};
+        rb.Push(RESULT_SUCCESS);
+        rb.Push<u32>(0);
 
         LOG_WARNING(Service, "(STUBBED) called");
     }
@@ -160,6 +208,7 @@ public:
             {66, &IApplicationFunctions::InitializeGamePlayRecording,
              "InitializeGamePlayRecording"},
             {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
+            {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
         };
         RegisterHandlers(functions);
     }
@@ -187,6 +236,15 @@ private:
     void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
         IPC::RequestBuilder rb{ctx, 2};
         rb.Push(RESULT_SUCCESS);
+
+        LOG_WARNING(Service, "(STUBBED) called");
+    }
+
+    void NotifyRunning(Kernel::HLERequestContext& ctx) {
+        IPC::RequestBuilder rb{ctx, 3};
+        rb.Push(RESULT_SUCCESS);
+        rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
+
         LOG_WARNING(Service, "(STUBBED) called");
     }
 };
-- 
GitLab