From 1f8e45c2baac964a2c6b4dea1d7908d9c30a2a29 Mon Sep 17 00:00:00 2001
From: Ac_K <Acoustik666@gmail.com>
Date: Wed, 13 May 2020 07:29:16 +0200
Subject: [PATCH] nvdrv: Partially implementation of GetStatus (#1215)

* nvdrv: Partially implementation of GetStatus

This implement GetStatus call according to RE.
Since we don't handle tranfert memory on the initialize of the service, it's fine sets fields at 0 for now.
Tested on Undertale.

Fix #635

* Fix struct
---
 Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs | 29 ++++++++++++++++++-
 Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs | 15 ++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100644 Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs

diff --git a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
index 6e45375fa..ce7314f4a 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/INvDrvServices.cs
@@ -43,6 +43,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv
 
         private KProcess _owner;
 
+        private bool _transferMemInitialized = false;
+
         public INvDrvServices(ServiceCtx context)
         {
             _owner = null;
@@ -315,6 +317,9 @@ namespace Ryujinx.HLE.HOS.Services.Nv
             long transferMemSize   = context.RequestData.ReadInt64();
             int  transferMemHandle = context.Request.HandleDesc.ToCopy[0];
 
+            // TODO: When transfer memory will be implemented, this could be removed.
+            _transferMemInitialized = true;
+
             _owner = context.Process;
 
             context.ResponseData.Write((uint)NvResult.Success);
@@ -389,7 +394,29 @@ namespace Ryujinx.HLE.HOS.Services.Nv
         // GetStatus() -> (unknown<0x20>, u32 error_code)
         public ResultCode GetStatus(ServiceCtx context)
         {
-            throw new ServiceNotImplementedException(context);
+            // TODO: When transfer memory will be implemented, check if it's mapped instead.
+            if (_transferMemInitialized)
+            {
+                // TODO: Populate values when more RE will be done.
+                NvStatus nvStatus = new NvStatus
+                {
+                    MemoryValue1 = 0, // GetMemStats(transfer_memory + 0x60, 3)
+                    MemoryValue2 = 0, // GetMemStats(transfer_memory + 0x60, 5)
+                    MemoryValue3 = 0, // transfer_memory + 0x78
+                    MemoryValue4 = 0  // transfer_memory + 0x80
+                };
+
+                context.ResponseData.WriteStruct(nvStatus);
+                context.ResponseData.Write((uint)NvResult.Success);
+
+                Logger.PrintStub(LogClass.ServiceNv);
+            }
+            else
+            {
+                context.ResponseData.Write((uint)NvResult.NotInitialized);
+            }
+
+            return ResultCode.Success;
         }
 
         [Command(7)]
diff --git a/Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs b/Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs
new file mode 100644
index 000000000..d5c35265a
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Nv/Types/NvStatus.cs
@@ -0,0 +1,15 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Nv.Types
+{
+    [StructLayout(LayoutKind.Sequential, Size = 0x20)]
+    struct NvStatus
+    {
+        public uint MemoryValue1;
+        public uint MemoryValue2;
+        public uint MemoryValue3;
+        public uint MemoryValue4;
+        public long Padding1;
+        public long Padding2;
+    }
+}
\ No newline at end of file