aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--Ryujinx/Cpu/AOpCodeTable.cs8
-rw-r--r--Ryujinx/Cpu/Decoder/AOpCodeSimdReg.cs6
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitAlu.cs54
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitScalar.cs45
-rw-r--r--Ryujinx/Cpu/Instruction/AInstEmitSimd.cs2
-rw-r--r--Ryujinx/OsHle/Ipc/IpcHandler.cs12
-rw-r--r--Ryujinx/OsHle/Objects/AudIAudioOut.cs166
-rw-r--r--Ryujinx/OsHle/Objects/AudIAudioRenderer.cs20
-rw-r--r--Ryujinx/OsHle/Services/ServiceAud.cs19
10 files changed, 324 insertions, 11 deletions
diff --git a/README.md b/README.md
index 1c8850de..857ba680 100644
--- a/README.md
+++ b/README.md
@@ -8,3 +8,6 @@ Contributions are always welcome.
To run this emulator, you need the .NET Core 2.0 (or higher) SDK.
Run `dotnet run -c Release -- game.nro` inside the Ryujinx solution folder.
+
+Audio is partially supported (glitched) on Windows, you need to install the OpenAL Core SDK :
+https://openal.org/downloads/OpenAL11CoreSDK.zip
diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs
index 1f770c6a..a7deb2c7 100644
--- a/Ryujinx/Cpu/AOpCodeTable.cs
+++ b/Ryujinx/Cpu/AOpCodeTable.cs
@@ -10,6 +10,7 @@ namespace ChocolArm64
{
#region "OpCode Table"
//Integer
+ Set("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc, typeof(AOpCodeAluRs));
Set("x0010001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm));
Set("x0001011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs));
Set("x0001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRx));
@@ -85,6 +86,7 @@ namespace ChocolArm64
Set("x101101011000000000010xxxxxxxxxx", AInstEmit.Rev32, typeof(AOpCodeAlu));
Set("1101101011000000000011xxxxxxxxxx", AInstEmit.Rev64, typeof(AOpCodeAlu));
Set("x0011010110xxxxx001011xxxxxxxxxx", AInstEmit.Rorv, typeof(AOpCodeAluRs));
+ Set("x1011010000xxxxx000000xxxxxxxxxx", AInstEmit.Sbc, typeof(AOpCodeAluRs));
Set("x00100110xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sbfm, typeof(AOpCodeBfm));
Set("x0011010110xxxxx000011xxxxxxxxxx", AInstEmit.Sdiv, typeof(AOpCodeAluRs));
Set("10011011001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Smaddl, typeof(AOpCodeMul));
@@ -144,6 +146,7 @@ namespace ChocolArm64
Set("0x0011100x1xxxxx110101xxxxxxxxxx", AInstEmit.Fadd_V, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxxxxxx01xxxxx0xxxx", AInstEmit.Fccmp_S, typeof(AOpCodeSimdFcond));
Set("00011110xx1xxxxx001000xxxxx0x000", AInstEmit.Fcmp_S, typeof(AOpCodeSimdReg));
+ Set("00011110xx1xxxxx001000xxxxx1x000", AInstEmit.Fcmpe_S, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxxxxxx11xxxxxxxxxx", AInstEmit.Fcsel_S, typeof(AOpCodeSimdFcond));
Set("00011110xx10001xx10000xxxxxxxxxx", AInstEmit.Fcvt_S, typeof(AOpCodeSimd));
Set("x0011110xx110000000000xxxxxxxxxx", AInstEmit.Fcvtms_S, typeof(AOpCodeSimdCvt));
@@ -156,18 +159,21 @@ namespace ChocolArm64
Set("x0011110xx011000xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzs_Fix, typeof(AOpCodeSimdCvt));
Set("x0011110xx011001xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzu_Fix, typeof(AOpCodeSimdCvt));
Set("00011110xx1xxxxx000110xxxxxxxxxx", AInstEmit.Fdiv_S, typeof(AOpCodeSimdReg));
+ Set("00011111xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Fmadd_S, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxx010010xxxxxxxxxx", AInstEmit.Fmax_S, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxx011010xxxxxxxxxx", AInstEmit.Fmaxnm_S, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxx010110xxxxxxxxxx", AInstEmit.Fmin_S, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxx011110xxxxxxxxxx", AInstEmit.Fminnm_S, typeof(AOpCodeSimdReg));
Set("0x0011100x1xxxxx110011xxxxxxxxxx", AInstEmit.Fmla_V, typeof(AOpCodeSimdReg));
Set("0x0011111<<xxxxx0001x0xxxxxxxxxx", AInstEmit.Fmla_Vs, typeof(AOpCodeSimdRegElem));
- Set("00011110xx1xxxxxxxx100xxxxxxxxxx", AInstEmit.Fmov_S, typeof(AOpCodeSimdFmov));
+ Set("00011110xx100000010000xxxxxxxxxx", AInstEmit.Fmov_S, typeof(AOpCodeSimd));
+ Set("00011110xx1xxxxxxxx100xxxxxxxxxx", AInstEmit.Fmov_Si, typeof(AOpCodeSimdFmov));
Set("0xx0111100000xxx111101xxxxxxxxxx", AInstEmit.Fmov_V, typeof(AOpCodeSimdImm));
Set("x0011110xx100110000000xxxxxxxxxx", AInstEmit.Fmov_Ftoi, typeof(AOpCodeSimdCvt));
Set("x0011110xx100111000000xxxxxxxxxx", AInstEmit.Fmov_Itof, typeof(AOpCodeSimdCvt));
Set("x0011110xx101110000000xxxxxxxxxx", AInstEmit.Fmov_Ftoi1, typeof(AOpCodeSimdCvt));
Set("x0011110xx101111000000xxxxxxxxxx", AInstEmit.Fmov_Itof1, typeof(AOpCodeSimdCvt));
+ Set("00011111xx0xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Fmsub_S, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxx000010xxxxxxxxxx", AInstEmit.Fmul_S, typeof(AOpCodeSimdReg));
Set("0x1011100x1xxxxx110111xxxxxxxxxx", AInstEmit.Fmul_V, typeof(AOpCodeSimdReg));
Set("0x0011111<<xxxxx1001x0xxxxxxxxxx", AInstEmit.Fmul_Vs, typeof(AOpCodeSimdRegElem));
diff --git a/Ryujinx/Cpu/Decoder/AOpCodeSimdReg.cs b/Ryujinx/Cpu/Decoder/AOpCodeSimdReg.cs
index d3a8b76a..10a4aff8 100644
--- a/Ryujinx/Cpu/Decoder/AOpCodeSimdReg.cs
+++ b/Ryujinx/Cpu/Decoder/AOpCodeSimdReg.cs
@@ -4,13 +4,15 @@ namespace ChocolArm64.Decoder
{
class AOpCodeSimdReg : AOpCodeSimd
{
- public int Rm { get; private set; }
public bool Bit3 { get; private set; }
+ public int Ra { get; private set; }
+ public int Rm { get; private set; }
public AOpCodeSimdReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
{
- Rm = (OpCode >> 16) & 0x1f;
Bit3 = ((OpCode >> 3) & 0x1) != 0;
+ Ra = (OpCode >> 10) & 0x1f;
+ Rm = (OpCode >> 16) & 0x1f;
}
}
} \ No newline at end of file
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs b/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
index f963f6f7..ac9c43c3 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitAlu.cs
@@ -1,6 +1,8 @@
using ChocolArm64.Decoder;
using ChocolArm64.State;
using ChocolArm64.Translation;
+using System;
+using System.Reflection;
using System.Reflection.Emit;
using static ChocolArm64.Instruction.AInstEmitAluHelper;
@@ -9,6 +11,30 @@ namespace ChocolArm64.Instruction
{
static partial class AInstEmit
{
+ public static void Adc(AILEmitterCtx Context)
+ {
+ EmitDataLoadOpers(Context);
+
+ Context.Emit(OpCodes.Add);
+
+ Context.EmitLdflg((int)APState.CBit);
+
+ Type[] MthdTypes = new Type[] { typeof(bool) };
+
+ MethodInfo MthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), MthdTypes);
+
+ Context.EmitCall(MthdInfo);
+
+ if (Context.CurrOp.RegisterSize != ARegisterSize.Int32)
+ {
+ Context.Emit(OpCodes.Conv_I8);
+ }
+
+ Context.Emit(OpCodes.Add);
+
+ EmitDataStore(Context);
+ }
+
public static void Add(AILEmitterCtx Context) => EmitDataOp(Context, OpCodes.Add);
public static void Adds(AILEmitterCtx Context)
@@ -105,6 +131,34 @@ namespace ChocolArm64.Instruction
public static void Lslv(AILEmitterCtx Context) => EmitDataOpShift(Context, OpCodes.Shl);
public static void Lsrv(AILEmitterCtx Context) => EmitDataOpShift(Context, OpCodes.Shr_Un);
+ public static void Sbc(AILEmitterCtx Context)
+ {
+ EmitDataLoadOpers(Context);
+
+ Context.Emit(OpCodes.Sub);
+
+ Context.EmitLdflg((int)APState.CBit);
+
+ Type[] MthdTypes = new Type[] { typeof(bool) };
+
+ MethodInfo MthdInfo = typeof(Convert).GetMethod(nameof(Convert.ToInt32), MthdTypes);
+
+ Context.EmitCall(MthdInfo);
+
+ Context.EmitLdc_I4(1);
+
+ Context.Emit(OpCodes.Xor);
+
+ if (Context.CurrOp.RegisterSize != ARegisterSize.Int32)
+ {
+ Context.Emit(OpCodes.Conv_I8);
+ }
+
+ Context.Emit(OpCodes.Sub);
+
+ EmitDataStore(Context);
+ }
+
public static void Sub(AILEmitterCtx Context) => EmitDataOp(Context, OpCodes.Sub);
public static void Subs(AILEmitterCtx Context)
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitScalar.cs b/Ryujinx/Cpu/Instruction/AInstEmitScalar.cs
index 5085c224..ab4c2fd2 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitScalar.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitScalar.cs
@@ -169,6 +169,12 @@ namespace ChocolArm64.Instruction
Context.MarkLabel(LblNotNaN);
}
+ public static void Fcmpe_S(AILEmitterCtx Context)
+ {
+ //TODO: Raise exception if value is NaN, how to handle exceptions?
+ Fcmp_S(Context);
+ }
+
public static void Fcsel_S(AILEmitterCtx Context)
{
AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp;
@@ -252,6 +258,20 @@ namespace ChocolArm64.Instruction
public static void Fdiv_S(AILEmitterCtx Context) => EmitScalarOp(Context, OpCodes.Div);
+ public static void Fmadd_S(AILEmitterCtx Context)
+ {
+ AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+ Context.EmitLdvecsf(Op.Ra);
+ Context.EmitLdvecsf(Op.Rn);
+ Context.EmitLdvecsf(Op.Rm);
+
+ Context.Emit(OpCodes.Mul);
+ Context.Emit(OpCodes.Add);
+
+ Context.EmitStvecsf(Op.Rd);
+ }
+
public static void Fmax_S(AILEmitterCtx Context) => EmitMathOp3(Context, nameof(Math.Max));
public static void Fmin_S(AILEmitterCtx Context) => EmitMathOp3(Context, nameof(Math.Min));
@@ -260,6 +280,14 @@ namespace ChocolArm64.Instruction
public static void Fmov_S(AILEmitterCtx Context)
{
+ AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
+
+ Context.EmitLdvecsf(Op.Rn);
+ Context.EmitStvecsf(Op.Rd);
+ }
+
+ public static void Fmov_Si(AILEmitterCtx Context)
+ {
AOpCodeSimdFmov Op = (AOpCodeSimdFmov)Context.CurrOp;
Context.EmitLdc_I8(Op.Imm);
@@ -313,6 +341,23 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
+ public static void Fmsub_S(AILEmitterCtx Context)
+ {
+ AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+ Context.EmitLdvecsf(Op.Ra);
+ Context.EmitLdvecsf(Op.Rn);
+
+ Context.Emit(OpCodes.Neg);
+
+ Context.EmitLdvecsf(Op.Rm);
+
+ Context.Emit(OpCodes.Mul);
+ Context.Emit(OpCodes.Sub);
+
+ Context.EmitStvecsf(Op.Rd);
+ }
+
public static void Fmul_S(AILEmitterCtx Context) => EmitScalarOp(Context, OpCodes.Mul);
public static void Fneg_S(AILEmitterCtx Context) => EmitScalarOp(Context, OpCodes.Neg);
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
index ccf0e357..8d4ade3a 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
@@ -273,7 +273,7 @@ namespace ChocolArm64.Instruction
AOpCodeSimdIns Op = (AOpCodeSimdIns)Context.CurrOp;
Context.EmitLdvec(Op.Rd);
- Context.EmitLdintzr(Op.Rn);
+ Context.EmitLdvec(Op.Rn);
Context.EmitLdc_I4(Op.SrcIndex);
Context.EmitLdc_I4(Op.DstIndex);
Context.EmitLdc_I4(Op.Size);
diff --git a/Ryujinx/OsHle/Ipc/IpcHandler.cs b/Ryujinx/OsHle/Ipc/IpcHandler.cs
index 50968014..4e57889a 100644
--- a/Ryujinx/OsHle/Ipc/IpcHandler.cs
+++ b/Ryujinx/OsHle/Ipc/IpcHandler.cs
@@ -127,8 +127,20 @@ namespace Ryujinx.OsHle.Ipc
//IAudioRenderer
{ (typeof(AudIAudioRenderer), 4), AudIAudioRenderer.RequestUpdateAudioRenderer },
{ (typeof(AudIAudioRenderer), 5), AudIAudioRenderer.StartAudioRenderer },
+ { (typeof(AudIAudioRenderer), 6), AudIAudioRenderer.StopAudioRenderer },
{ (typeof(AudIAudioRenderer), 7), AudIAudioRenderer.QuerySystemEvent },
+ //IAudioOut
+ { (typeof(AudIAudioOut), 0), AudIAudioOut.GetAudioOutState },
+ { (typeof(AudIAudioOut), 1), AudIAudioOut.StartAudioOut },
+ { (typeof(AudIAudioOut), 2), AudIAudioOut.StopAudioOut },
+ { (typeof(AudIAudioOut), 3), AudIAudioOut.AppendAudioOutBuffer },
+ { (typeof(AudIAudioOut), 4), AudIAudioOut.RegisterBufferEvent },
+ { (typeof(AudIAudioOut), 5), AudIAudioOut.GetReleasedAudioOutBuffer },
+ { (typeof(AudIAudioOut), 6), AudIAudioOut.ContainsAudioOutBuffer },
+ { (typeof(AudIAudioOut), 7), AudIAudioOut.AppendAudioOutBuffer_ex },
+ { (typeof(AudIAudioOut), 8), AudIAudioOut.GetReleasedAudioOutBuffer_ex },
+
//IFile
{ (typeof(FspSrvIFile), 0), FspSrvIFile.Read },
{ (typeof(FspSrvIFile), 1), FspSrvIFile.Write },
diff --git a/Ryujinx/OsHle/Objects/AudIAudioOut.cs b/Ryujinx/OsHle/Objects/AudIAudioOut.cs
new file mode 100644
index 00000000..965e840d
--- /dev/null
+++ b/Ryujinx/OsHle/Objects/AudIAudioOut.cs
@@ -0,0 +1,166 @@
+using ChocolArm64.Memory;
+using Ryujinx.OsHle.Handles;
+using Ryujinx.OsHle.Ipc;
+using static Ryujinx.OsHle.Objects.ObjHelper;
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+using OpenTK.Audio;
+using OpenTK.Audio.OpenAL;
+
+namespace Ryujinx.OsHle.Objects
+{
+ class AudIAudioOut
+ {
+ enum AudioOutState
+ {
+ Started,
+ Stopped
+ };
+
+ //IAudioOut
+ private static AudioOutState State = AudioOutState.Stopped;
+ private static List<long> KeysQueue = new List<long>();
+
+ //OpenAL
+ private static bool OpenALInstalled = true;
+ private static AudioContext AudioCtx;
+ private static int Source;
+ private static int Buffer;
+
+ //Return State of IAudioOut
+ public static long GetAudioOutState(ServiceCtx Context)
+ {
+ Context.ResponseData.Write((int)State);
+
+ return 0;
+ }
+
+ public static long StartAudioOut(ServiceCtx Context)
+ {
+ if (State == AudioOutState.Stopped)
+ {
+ State = AudioOutState.Started;
+
+ try
+ {
+ AudioCtx = new AudioContext(); //Create the audio context
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("OpenAL Error! PS: Install OpenAL Core SDK!");
+ OpenALInstalled = false;
+ }
+
+ if (OpenALInstalled) AL.Listener(ALListenerf.Gain, (float)8.0); //Add more gain to it
+ }
+
+ return 0;
+ }
+
+ public static long StopAudioOut(ServiceCtx Context)
+ {
+ if (State == AudioOutState.Started)
+ {
+ if (OpenALInstalled)
+ {
+ if (AudioCtx == null) //Needed to call the instance of AudioContext()
+ return 0;
+
+ AL.SourceStop(Source);
+ AL.DeleteSource(Source);
+ }
+ State = AudioOutState.Stopped;
+ }
+
+ return 0;
+ }
+
+ public static long AppendAudioOutBuffer(ServiceCtx Context)
+ {
+ long BufferId = Context.RequestData.ReadInt64();
+
+ KeysQueue.Insert(0, BufferId);
+
+ byte[] AudioOutBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[0].Position, 0x28);
+ using (MemoryStream MS = new MemoryStream(AudioOutBuffer))
+ {
+ BinaryReader Reader = new BinaryReader(MS);
+ long PointerToSampleDataPointer = Reader.ReadInt64();
+ long PointerToSampleData = Reader.ReadInt64();
+ long CapacitySampleBuffer = Reader.ReadInt64();
+ long SizeDataSampleBuffer = Reader.ReadInt64();
+ long Unknown = Reader.ReadInt64();
+
+ byte[] AudioSampleBuffer = AMemoryHelper.ReadBytes(Context.Memory, PointerToSampleData, (int)SizeDataSampleBuffer);
+
+ if (OpenALInstalled)
+ {
+ if (AudioCtx == null) //Needed to call the instance of AudioContext()
+ return 0;
+
+ Buffer = AL.GenBuffer();
+ AL.BufferData(Buffer, ALFormat.Stereo16, AudioSampleBuffer, AudioSampleBuffer.Length, 48000);
+
+ Source = AL.GenSource();
+ AL.SourceQueueBuffer(Source, Buffer);
+ }
+ }
+
+ return 0;
+ }
+
+ public static long RegisterBufferEvent(ServiceCtx Context)
+ {
+ int Handle = Context.Ns.Os.Handles.GenerateId(new HEvent());
+
+ Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
+
+ return 0;
+ }
+
+ public static long GetReleasedAudioOutBuffer(ServiceCtx Context)
+ {
+ long TempKey = 0;
+
+ if (KeysQueue.Count > 0)
+ {
+ TempKey = KeysQueue[KeysQueue.Count - 1];
+ KeysQueue.Remove(KeysQueue[KeysQueue.Count - 1]);
+ }
+
+ AMemoryHelper.WriteBytes(Context.Memory, Context.Request.ReceiveBuff[0].Position, System.BitConverter.GetBytes(TempKey));
+
+ Context.ResponseData.Write((int)TempKey);
+
+ if (OpenALInstalled)
+ {
+ if (AudioCtx == null) //Needed to call the instance of AudioContext()
+ return 0;
+
+ AL.SourcePlay(Source);
+ int[] FreeBuffers = AL.SourceUnqueueBuffers(Source, 1);
+ AL.DeleteBuffers(FreeBuffers);
+ }
+
+ return 0;
+ }
+
+ public static long ContainsAudioOutBuffer(ServiceCtx Context)
+ {
+ return 0;
+ }
+
+ public static long AppendAudioOutBuffer_ex(ServiceCtx Context)
+ {
+ return 0;
+ }
+
+ public static long GetReleasedAudioOutBuffer_ex(ServiceCtx Context)
+ {
+ return 0;
+ }
+ }
+}
diff --git a/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs b/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs
index 84ac4e04..35a5b82d 100644
--- a/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs
+++ b/Ryujinx/OsHle/Objects/AudIAudioRenderer.cs
@@ -1,15 +1,20 @@
+using Ryujinx.OsHle.Handles;
+using Ryujinx.OsHle.Ipc;
+
namespace Ryujinx.OsHle.Objects
{
class AudIAudioRenderer
{
public static long RequestUpdateAudioRenderer(ServiceCtx Context)
{
+ //buffer < unknown, 5, 0 >) -> (buffer < unknown, 6, 0 >, buffer < unknown, 6, 0 >
+
long Position = Context.Request.ReceiveBuff[0].Position;
//0x40 bytes header
- Context.Memory.WriteInt32(Position + 0x4, 0xb0); //Behavior Out State Size? (note: this is the last section)
- Context.Memory.WriteInt32(Position + 0x8, 0x18e0); //Memory Pool Out State Size?
- Context.Memory.WriteInt32(Position + 0xc, 0x600); //Voice Out State Size?
+ Context.Memory.WriteInt32(Position + 0x4, 0xb0); //Behavior Out State Size? (note: this is the last section)
+ Context.Memory.WriteInt32(Position + 0x8, 0x18e0); //Memory Pool Out State Size?
+ Context.Memory.WriteInt32(Position + 0xc, 0x600); //Voice Out State Size?
Context.Memory.WriteInt32(Position + 0x14, 0xe0); //Effect Out State Size?
Context.Memory.WriteInt32(Position + 0x1c, 0x20); //Sink Out State Size?
Context.Memory.WriteInt32(Position + 0x20, 0x10); //Performance Out State Size?
@@ -28,8 +33,17 @@ namespace Ryujinx.OsHle.Objects
return 0;
}
+ public static long StopAudioRenderer(ServiceCtx Context)
+ {
+ return 0;
+ }
+
public static long QuerySystemEvent(ServiceCtx Context)
{
+ int Handle = Context.Ns.Os.Handles.GenerateId(new HEvent());
+
+ Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
+
return 0;
}
}
diff --git a/Ryujinx/OsHle/Services/ServiceAud.cs b/Ryujinx/OsHle/Services/ServiceAud.cs
index 96e7e548..18401ae9 100644
--- a/Ryujinx/OsHle/Services/ServiceAud.cs
+++ b/Ryujinx/OsHle/Services/ServiceAud.cs
@@ -21,10 +21,21 @@ namespace Ryujinx.OsHle.Services
public static long AudOutOpenAudioOut(ServiceCtx Context)
{
- Context.ResponseData.Write(48000);
- Context.ResponseData.Write(2);
- Context.ResponseData.Write(2);
- Context.ResponseData.Write(0);
+ MakeObject(Context, new AudIAudioOut());
+
+ Context.ResponseData.Write(48000); //Sample Rate
+ Context.ResponseData.Write(2); //Channel Count
+ Context.ResponseData.Write(2); //PCM Format
+ /*
+ 0 - Invalid
+ 1 - INT8
+ 2 - INT16
+ 3 - INT24
+ 4 - INT32
+ 5 - PCM Float
+ 6 - ADPCM
+ */
+ Context.ResponseData.Write(0); //Unknown
return 0;
}