From d88b5c762143d42367b9cbcdb48337db482dbed3 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Mon, 12 Mar 2018 16:29:06 -0300
Subject: [PATCH] Fix GetAudioRenderersProcessMasterVolume which was totally
 wrong

---
 ChocolArm64/Instruction/AInstEmitSystem.cs    | 10 ++-
 .../OsHle/Services/Aud/IAudioDeviceService.cs | 63 +++++++++++++++++++
 .../OsHle/Services/Aud/ServiceAudRen.cs       | 13 ++--
 3 files changed, 80 insertions(+), 6 deletions(-)
 create mode 100644 Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs

diff --git a/ChocolArm64/Instruction/AInstEmitSystem.cs b/ChocolArm64/Instruction/AInstEmitSystem.cs
index f9d18602..80b56604 100644
--- a/ChocolArm64/Instruction/AInstEmitSystem.cs
+++ b/ChocolArm64/Instruction/AInstEmitSystem.cs
@@ -89,6 +89,9 @@ namespace ChocolArm64.Instruction
             //We treat it as no-op here since we don't have any cache being emulated anyway.
             AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
 
+            //TODO: We should throw on unimplemented sys instructions here,
+            //since it causing some problems when the programs expects some values
+            //that never return.
             switch (GetPackedId(Op))
             {
                 case 0b11_011_0111_0100_001:
@@ -97,7 +100,7 @@ namespace ChocolArm64.Instruction
                     for (int Offs = 0; Offs < (4 << AThreadState.DczSizeLog2); Offs += 8)
                     {
                         Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
-                        Context.EmitLdint(Op.Rt);
+                        Context.EmitLdintzr(Op.Rt);
                         Context.EmitLdc_I(Offs);
 
                         Context.Emit(OpCodes.Add);
@@ -106,8 +109,13 @@ namespace ChocolArm64.Instruction
 
                         AInstEmitMemoryHelper.EmitWriteCall(Context, 3);
                     }
+
                     break;
                 }
+
+                //No-op
+                case 0b11_011_0111_1110_001: //DC CIVAC
+                    break;
             }
         }
 
diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs
new file mode 100644
index 00000000..9ebf140a
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDeviceService.cs
@@ -0,0 +1,63 @@
+using ChocolArm64.Memory;
+using Ryujinx.Core.OsHle.Ipc;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Ryujinx.Core.OsHle.IpcServices.Aud
+{
+    class IAudioDevice : IIpcService
+    {
+        private Dictionary<int, ServiceProcessRequest> m_Commands;
+
+        public IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
+
+        public IAudioDevice()
+        {
+            m_Commands = new Dictionary<int, ServiceProcessRequest>()
+            {
+                { 0, ListAudioDeviceName        },
+                { 1, SetAudioDeviceOutputVolume },
+            };
+        }
+
+        public long ListAudioDeviceName(ServiceCtx Context)
+        {
+            string[] Names = new string[] { "FIXME" };
+
+            Context.ResponseData.Write(Names.Length);
+
+            long Position = Context.Request.ReceiveBuff[0].Position;
+            long Size     = Context.Request.ReceiveBuff[0].Size;
+
+            long BasePosition = Position;
+
+            foreach (string Name in Names)
+            {
+                byte[] Buffer = Encoding.ASCII.GetBytes(Name + '\0');
+
+                if ((Position - BasePosition) + Buffer.Length > Size)
+                {
+                    break;
+                }
+
+                AMemoryHelper.WriteBytes(Context.Memory, Position, Buffer);
+
+                Position += Buffer.Length;
+            }
+
+            return 0;
+        }
+
+        public long SetAudioDeviceOutputVolume(ServiceCtx Context)
+        {
+            float Volume = Context.RequestData.ReadSingle();
+
+            long Position = Context.Request.SendBuff[0].Position;
+            long Size     = Context.Request.SendBuff[0].Size;
+
+            string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position, (int)Size);
+
+            return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs
index 15bda04c..155d0425 100644
--- a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs
+++ b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Core.OsHle.Handles;
 using Ryujinx.Core.OsHle.Ipc;
 using System.Collections.Generic;
 
@@ -15,9 +16,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                { 0, OpenAudioRenderer                    },
-                { 1, GetAudioRendererWorkBufferSize       },
-                { 2, GetAudioRenderersProcessMasterVolume }
+                { 0, OpenAudioRenderer              },
+                { 1, GetAudioRendererWorkBufferSize },
+                { 2, GetAudioDevice                 }
             };
         }
 
@@ -49,9 +50,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
             return 0;
         }
 
-        public long GetAudioRenderersProcessMasterVolume(ServiceCtx Context)
+        public long GetAudioDevice(ServiceCtx Context)
         {
-            Context.ResponseData.Write(0);
+            long UserId = Context.RequestData.ReadInt64();
+
+            MakeObject(Context, new IAudioDevice());
 
             return 0;
         }