From c0dc8f9d2567bd2a7f0bbd0bf4a5f42194bbb102 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sun, 5 Jul 2020 06:26:07 -0400
Subject: [PATCH] AM/ISelfController: Stub CreateManagedDisplaySeparableLayer

Stub this by sending 1 layer id instead of 2 as yuzu does not support multiple layers per display.
No adverse side effects have been observed.
- Used by Animal Crossing: New Horizons Update 1.3.0
---
 src/core/hle/service/am/am.cpp | 20 +++++++++++++++++++-
 src/core/hle/service/am/am.h   |  1 +
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 1bb544dd87..2642c24cc1 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -271,7 +271,7 @@ ISelfController::ISelfController(Core::System& system,
         {41, nullptr, "IsSystemBufferSharingEnabled"},
         {42, nullptr, "GetSystemSharedLayerHandle"},
         {43, nullptr, "GetSystemSharedBufferHandle"},
-        {44, nullptr, "CreateManagedDisplaySeparableLayer"},
+        {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"},
         {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
         {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
         {51, nullptr, "ApproveToDisplay"},
@@ -461,6 +461,24 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx)
     rb.Push(*layer_id);
 }
 
+void ISelfController::CreateManagedDisplaySeparableLayer(Kernel::HLERequestContext& ctx) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    // TODO(Subv): Find out how AM determines the display to use, for now just
+    // create the layer in the Default display.
+    // This calls nn::vi::CreateRecordingLayer() which creates another layer.
+    // Currently we do not support more than 1 layer per display, output 1 layer id for now.
+    // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse
+    // side effects.
+    // TODO: Support multiple layers
+    const auto display_id = nvflinger->OpenDisplay("Default");
+    const auto layer_id = nvflinger->CreateLayer(*display_id);
+
+    IPC::ResponseBuilder rb{ctx, 4};
+    rb.Push(RESULT_SUCCESS);
+    rb.Push(*layer_id);
+}
+
 void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 2f69466ece..6cfb11b480 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -140,6 +140,7 @@ private:
     void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx);
     void SetAlbumImageOrientation(Kernel::HLERequestContext& ctx);
     void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx);
+    void CreateManagedDisplaySeparableLayer(Kernel::HLERequestContext& ctx);
     void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx);
     void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
     void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);