From ee8fb18a0ff054345ee5c8ad32eafbac2078afe7 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 15 Mar 2018 12:59:23 -0300 Subject: [PATCH 1/9] Fix CPU instruction Ld/St (single structure) with index != 0 --- ChocolArm64/Decoder/AOpCodeSimdMemSs.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/ChocolArm64/Decoder/AOpCodeSimdMemSs.cs b/ChocolArm64/Decoder/AOpCodeSimdMemSs.cs index be4a8cd98b..6938c77d32 100644 --- a/ChocolArm64/Decoder/AOpCodeSimdMemSs.cs +++ b/ChocolArm64/Decoder/AOpCodeSimdMemSs.cs @@ -82,6 +82,7 @@ namespace ChocolArm64.Decoder } } + this.Index = Index; this.SElems = SElems; this.Size = Scale; From 92f47d535e7c3b350c25499dec5e91d8be5544bc Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 15 Mar 2018 18:14:22 -0300 Subject: [PATCH 2/9] Fix crc32 instruction with size greater than a byte --- ChocolArm64/Instruction/ASoftFallback.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ChocolArm64/Instruction/ASoftFallback.cs b/ChocolArm64/Instruction/ASoftFallback.cs index f79628ad03..705ca4a296 100644 --- a/ChocolArm64/Instruction/ASoftFallback.cs +++ b/ChocolArm64/Instruction/ASoftFallback.cs @@ -41,15 +41,15 @@ namespace ChocolArm64.Instruction private const uint Crc32RevPoly = 0xedb88320; private const uint Crc32cRevPoly = 0x82f63b78; - public static uint Crc32b(uint Crc, byte Val) => Crc32 (Crc, Crc32RevPoly, Val); - public static uint Crc32h(uint Crc, byte Val) => Crc32h(Crc, Crc32RevPoly, Val); - public static uint Crc32w(uint Crc, byte Val) => Crc32w(Crc, Crc32RevPoly, Val); - public static uint Crc32x(uint Crc, byte Val) => Crc32x(Crc, Crc32RevPoly, Val); + public static uint Crc32b(uint Crc, byte Val) => Crc32 (Crc, Crc32RevPoly, Val); + public static uint Crc32h(uint Crc, ushort Val) => Crc32h(Crc, Crc32RevPoly, Val); + public static uint Crc32w(uint Crc, uint Val) => Crc32w(Crc, Crc32RevPoly, Val); + public static uint Crc32x(uint Crc, ulong Val) => Crc32x(Crc, Crc32RevPoly, Val); - public static uint Crc32cb(uint Crc, byte Val) => Crc32 (Crc, Crc32cRevPoly, Val); - public static uint Crc32ch(uint Crc, byte Val) => Crc32h(Crc, Crc32cRevPoly, Val); - public static uint Crc32cw(uint Crc, byte Val) => Crc32w(Crc, Crc32cRevPoly, Val); - public static uint Crc32cx(uint Crc, byte Val) => Crc32x(Crc, Crc32cRevPoly, Val); + public static uint Crc32cb(uint Crc, byte Val) => Crc32 (Crc, Crc32cRevPoly, Val); + public static uint Crc32ch(uint Crc, ushort Val) => Crc32h(Crc, Crc32cRevPoly, Val); + public static uint Crc32cw(uint Crc, uint Val) => Crc32w(Crc, Crc32cRevPoly, Val); + public static uint Crc32cx(uint Crc, ulong Val) => Crc32x(Crc, Crc32cRevPoly, Val); private static uint Crc32h(uint Crc, uint Poly, ushort Val) { From 79a59397349b40758fc75cd2e19c67726a77e975 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 15 Mar 2018 21:06:24 -0300 Subject: [PATCH 3/9] Improvements to audout (#58) * Some audout refactoring and improvements * More audio improvements * Change ReadAsciiString to use long for the Size, avoids some casting --- ChocolArm64/Memory/AMemoryHelper.cs | 38 ++- Ryujinx.Audio/AudioFormat.cs | 13 + Ryujinx.Audio/IAalOutput.cs | 18 ++ Ryujinx.Audio/OpenAL/OpenALAudioOut.cs | 283 ++++++++++++++++++ Ryujinx.Audio/PlaybackState.cs | 8 + Ryujinx.Audio/Ryujinx.Audio.csproj | 11 + Ryujinx.Core/OsHle/Homebrew.cs | 2 +- Ryujinx.Core/OsHle/Ipc/IpcPtrBuffDesc.cs | 4 +- Ryujinx.Core/OsHle/ServiceMgr.cs | 22 +- .../OsHle/Services/Aud/AudioOutData.cs | 14 + .../OsHle/Services/Aud/IAudioDevice.cs | 2 +- Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs | 177 ++++------- .../OsHle/Services/Aud/ServiceAudOut.cs | 61 +++- Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs | 12 +- Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs | 2 +- Ryujinx.Core/OsHle/Services/Lm/ILogger.cs | 2 +- .../OsHle/Services/Vi/IHOSBinderDriver.cs | 6 +- Ryujinx.Core/OsHle/Svc/SvcSystem.cs | 6 +- Ryujinx.Core/Ryujinx.Core.csproj | 1 + .../Settings/{SetSys.cs => SystemSettings.cs} | 2 +- Ryujinx.Core/Switch.cs | 47 ++- .../{VirtualFs.cs => VirtualFileSystem.cs} | 2 +- Ryujinx.Graphics/Gpu/NsGpuPGraph.cs | 2 +- Ryujinx/Ryujinx.csproj | 1 + Ryujinx/Ui/Program.cs | 8 +- 25 files changed, 567 insertions(+), 177 deletions(-) create mode 100644 Ryujinx.Audio/AudioFormat.cs create mode 100644 Ryujinx.Audio/IAalOutput.cs create mode 100644 Ryujinx.Audio/OpenAL/OpenALAudioOut.cs create mode 100644 Ryujinx.Audio/PlaybackState.cs create mode 100644 Ryujinx.Audio/Ryujinx.Audio.csproj create mode 100644 Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs rename Ryujinx.Core/Settings/{SetSys.cs => SystemSettings.cs} (72%) rename Ryujinx.Core/{VirtualFs.cs => VirtualFileSystem.cs} (98%) diff --git a/ChocolArm64/Memory/AMemoryHelper.cs b/ChocolArm64/Memory/AMemoryHelper.cs index 219aeebf9e..1e3462985b 100644 --- a/ChocolArm64/Memory/AMemoryHelper.cs +++ b/ChocolArm64/Memory/AMemoryHelper.cs @@ -1,4 +1,6 @@ +using System; using System.IO; +using System.Runtime.InteropServices; using System.Text; namespace ChocolArm64.Memory @@ -20,11 +22,11 @@ namespace ChocolArm64.Memory } } - public static byte[] ReadBytes(AMemory Memory, long Position, int Size) + public static byte[] ReadBytes(AMemory Memory, long Position, long Size) { byte[] Data = new byte[Size]; - for (int Offs = 0; Offs < Size; Offs++) + for (long Offs = 0; Offs < Size; Offs++) { Data[Offs] = (byte)Memory.ReadByte(Position + Offs); } @@ -40,11 +42,39 @@ namespace ChocolArm64.Memory } } - public static string ReadAsciiString(AMemory Memory, long Position, int MaxSize = -1) + public unsafe static T Read(AMemory Memory, long Position) where T : struct + { + long Size = Marshal.SizeOf(); + + if ((ulong)(Position + Size) > AMemoryMgr.AddrSize) + { + throw new ArgumentOutOfRangeException(nameof(Position)); + } + + IntPtr Ptr = new IntPtr((byte*)Memory.Ram + Position); + + return Marshal.PtrToStructure(Ptr); + } + + public unsafe static void Write(AMemory Memory, long Position, T Value) where T : struct + { + long Size = Marshal.SizeOf(); + + if ((ulong)(Position + Size) > AMemoryMgr.AddrSize) + { + throw new ArgumentOutOfRangeException(nameof(Position)); + } + + IntPtr Ptr = new IntPtr((byte*)Memory.Ram + Position); + + Marshal.StructureToPtr(Value, Ptr, false); + } + + public static string ReadAsciiString(AMemory Memory, long Position, long MaxSize = -1) { using (MemoryStream MS = new MemoryStream()) { - for (int Offs = 0; Offs < MaxSize || MaxSize == -1; Offs++) + for (long Offs = 0; Offs < MaxSize || MaxSize == -1; Offs++) { byte Value = (byte)Memory.ReadByte(Position + Offs); diff --git a/Ryujinx.Audio/AudioFormat.cs b/Ryujinx.Audio/AudioFormat.cs new file mode 100644 index 0000000000..8250d1368e --- /dev/null +++ b/Ryujinx.Audio/AudioFormat.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.Audio +{ + public enum AudioFormat + { + Invalid = 0, + PcmInt8 = 1, + PcmInt16 = 2, + PcmImt24 = 3, + PcmImt32 = 4, + PcmFloat = 5, + Adpcm = 6 + } +} \ No newline at end of file diff --git a/Ryujinx.Audio/IAalOutput.cs b/Ryujinx.Audio/IAalOutput.cs new file mode 100644 index 0000000000..7ed0e0b6bc --- /dev/null +++ b/Ryujinx.Audio/IAalOutput.cs @@ -0,0 +1,18 @@ +namespace Ryujinx.Audio +{ + public interface IAalOutput + { + int OpenTrack(int SampleRate, int Channels, out AudioFormat Format); + void CloseTrack(int Track); + + void AppendBuffer(int Track, long Tag, byte[] Buffer); + bool ContainsBuffer(int Track, long Tag); + + long[] GetReleasedBuffers(int Track); + + void Start(int Track); + void Stop(int Track); + + PlaybackState GetState(int Track); + } +} \ No newline at end of file diff --git a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs new file mode 100644 index 0000000000..7cf30c1822 --- /dev/null +++ b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs @@ -0,0 +1,283 @@ +using OpenTK.Audio; +using OpenTK.Audio.OpenAL; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; + +namespace Ryujinx.Audio.OpenAL +{ + public class OpenALAudioOut : IAalOutput + { + private const int MaxTracks = 256; + + private AudioContext Context; + + private class Track : IDisposable + { + public int SourceId { get; private set; } + + public int SampleRate { get; private set; } + + public ALFormat Format { get; private set; } + + public PlaybackState State { get; set; } + + private ConcurrentDictionary Buffers; + + private Queue QueuedTagsQueue; + + private bool Disposed; + + public Track(int SampleRate, ALFormat Format) + { + this.SampleRate = SampleRate; + this.Format = Format; + + State = PlaybackState.Stopped; + + SourceId = AL.GenSource(); + + Buffers = new ConcurrentDictionary(); + + QueuedTagsQueue = new Queue(); + } + + public int GetBufferId(long Tag) + { + if (Disposed) + { + throw new ObjectDisposedException(nameof(Track)); + } + + int Id = AL.GenBuffer(); + + Buffers.AddOrUpdate(Tag, Id, (Key, OldId) => + { + AL.DeleteBuffer(OldId); + + return Id; + }); + + QueuedTagsQueue.Enqueue(Tag); + + return Id; + } + + public long[] GetReleasedBuffers() + { + ClearReleased(); + + List Tags = new List(); + + foreach (long Tag in Buffers.Keys) + { + if (!ContainsBuffer(Tag)) + { + Tags.Add(Tag); + } + } + + return Tags.ToArray(); + } + + public void ClearReleased() + { + SyncQueuedTags(); + + AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount); + + if (ReleasedCount > 0) + { + AL.SourceUnqueueBuffers(SourceId, ReleasedCount); + } + } + + public bool ContainsBuffer(long Tag) + { + SyncQueuedTags(); + + foreach (long QueuedTag in QueuedTagsQueue) + { + if (QueuedTag == Tag) + { + return true; + } + } + + return false; + } + + private void SyncQueuedTags() + { + AL.GetSource(SourceId, ALGetSourcei.BuffersQueued, out int QueuedCount); + AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount); + + QueuedCount -= ReleasedCount; + + while (QueuedTagsQueue.Count > QueuedCount) + { + QueuedTagsQueue.Dequeue(); + } + } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing && !Disposed) + { + Disposed = true; + + AL.DeleteSource(SourceId); + + foreach (int Id in Buffers.Values) + { + AL.DeleteBuffer(Id); + } + } + } + } + + private ConcurrentDictionary Tracks; + + public OpenALAudioOut() + { + Context = new AudioContext(); + + Tracks = new ConcurrentDictionary(); + } + + public int OpenTrack(int SampleRate, int Channels, out AudioFormat Format) + { + Format = AudioFormat.PcmInt16; + + Track Td = new Track(SampleRate, GetALFormat(Channels, Format)); + + for (int Id = 0; Id < MaxTracks; Id++) + { + if (Tracks.TryAdd(Id, Td)) + { + return Id; + } + } + + return -1; + } + + private ALFormat GetALFormat(int Channels, AudioFormat Format) + { + if (Channels < 1 || Channels > 2) + { + throw new ArgumentOutOfRangeException(nameof(Channels)); + } + + if (Channels == 1) + { + switch (Format) + { + case AudioFormat.PcmInt8: return ALFormat.Mono8; + case AudioFormat.PcmInt16: return ALFormat.Mono16; + } + } + else /* if (Channels == 2) */ + { + switch (Format) + { + case AudioFormat.PcmInt8: return ALFormat.Stereo8; + case AudioFormat.PcmInt16: return ALFormat.Stereo16; + } + } + + throw new ArgumentException(nameof(Format)); + } + + public void CloseTrack(int Track) + { + if (Tracks.TryRemove(Track, out Track Td)) + { + Td.Dispose(); + } + } + + public void AppendBuffer(int Track, long Tag, byte[] Buffer) + { + if (Tracks.TryGetValue(Track, out Track Td)) + { + int BufferId = Td.GetBufferId(Tag); + + AL.BufferData(BufferId, Td.Format, Buffer, Buffer.Length, Td.SampleRate); + + AL.SourceQueueBuffer(Td.SourceId, BufferId); + + StartPlaybackIfNeeded(Td); + } + } + + public bool ContainsBuffer(int Track, long Tag) + { + if (Tracks.TryGetValue(Track, out Track Td)) + { + return Td.ContainsBuffer(Tag); + } + + return false; + } + + public long[] GetReleasedBuffers(int Track) + { + if (Tracks.TryGetValue(Track, out Track Td)) + { + return Td.GetReleasedBuffers(); + } + + return null; + } + + public void Start(int Track) + { + if (Tracks.TryGetValue(Track, out Track Td)) + { + Td.State = PlaybackState.Playing; + + StartPlaybackIfNeeded(Td); + } + } + + private void StartPlaybackIfNeeded(Track Td) + { + AL.GetSource(Td.SourceId, ALGetSourcei.SourceState, out int StateInt); + + ALSourceState State = (ALSourceState)StateInt; + + if (State != ALSourceState.Playing && Td.State == PlaybackState.Playing) + { + Td.ClearReleased(); + + AL.SourcePlay(Td.SourceId); + } + } + + public void Stop(int Track) + { + if (Tracks.TryGetValue(Track, out Track Td)) + { + Td.State = PlaybackState.Stopped; + + AL.SourceStop(Td.SourceId); + } + } + + public PlaybackState GetState(int Track) + { + if (Tracks.TryGetValue(Track, out Track Td)) + { + return Td.State; + } + + return PlaybackState.Stopped; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Audio/PlaybackState.cs b/Ryujinx.Audio/PlaybackState.cs new file mode 100644 index 0000000000..8b53128aaf --- /dev/null +++ b/Ryujinx.Audio/PlaybackState.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Audio +{ + public enum PlaybackState + { + Playing = 0, + Stopped = 1 + } +} \ No newline at end of file diff --git a/Ryujinx.Audio/Ryujinx.Audio.csproj b/Ryujinx.Audio/Ryujinx.Audio.csproj new file mode 100644 index 0000000000..2e7c86fa01 --- /dev/null +++ b/Ryujinx.Audio/Ryujinx.Audio.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp2.0 + + + + + + + diff --git a/Ryujinx.Core/OsHle/Homebrew.cs b/Ryujinx.Core/OsHle/Homebrew.cs index 2a717ca738..873dda0255 100644 --- a/Ryujinx.Core/OsHle/Homebrew.cs +++ b/Ryujinx.Core/OsHle/Homebrew.cs @@ -51,7 +51,7 @@ namespace Ryujinx.Core.OsHle long Value0 = Memory.ReadInt64(Position + 0x08); long Value1 = Memory.ReadInt64(Position + 0x10); - FileName = AMemoryHelper.ReadAsciiString(Memory, Value0, (int)(Value1 - Value0)); + FileName = AMemoryHelper.ReadAsciiString(Memory, Value0, Value1 - Value0); break; } diff --git a/Ryujinx.Core/OsHle/Ipc/IpcPtrBuffDesc.cs b/Ryujinx.Core/OsHle/Ipc/IpcPtrBuffDesc.cs index d39f78db81..4eb15b9d75 100644 --- a/Ryujinx.Core/OsHle/Ipc/IpcPtrBuffDesc.cs +++ b/Ryujinx.Core/OsHle/Ipc/IpcPtrBuffDesc.cs @@ -6,7 +6,7 @@ namespace Ryujinx.Core.OsHle.Ipc { public long Position { get; private set; } public int Index { get; private set; } - public short Size { get; private set; } + public long Size { get; private set; } public IpcPtrBuffDesc(BinaryReader Reader) { @@ -20,7 +20,7 @@ namespace Ryujinx.Core.OsHle.Ipc Index = ((int)Word0 >> 0) & 0x03f; Index |= ((int)Word0 >> 3) & 0x1c0; - Size = (short)(Word0 >> 16); + Size = (ushort)(Word0 >> 16); } } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/ServiceMgr.cs b/Ryujinx.Core/OsHle/ServiceMgr.cs index f59647afef..39f6236859 100644 --- a/Ryujinx.Core/OsHle/ServiceMgr.cs +++ b/Ryujinx.Core/OsHle/ServiceMgr.cs @@ -37,7 +37,25 @@ namespace Ryujinx.Core.OsHle { lock (Services) { - if (!Services.TryGetValue(Name, out IIpcService Service)) + string LookUpName; + + //Same service with different privileges. + if (Name.EndsWith(":a") || + Name.EndsWith(":m") || + Name.EndsWith(":s") || + Name.EndsWith(":su") || + Name.EndsWith(":u") || + Name.EndsWith(":u0") || + Name.EndsWith(":u1")) + { + LookUpName = Name.Substring(0, Name.IndexOf(':')); + } + else + { + LookUpName = Name; + } + + if (!Services.TryGetValue(LookUpName, out IIpcService Service)) { switch (Name) { @@ -76,7 +94,7 @@ namespace Ryujinx.Core.OsHle throw new NotImplementedException(Name); } - Services.Add(Name, Service); + Services.Add(LookUpName, Service); } return Service; diff --git a/Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs b/Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs new file mode 100644 index 0000000000..6b27f5291f --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs @@ -0,0 +1,14 @@ +using System.Runtime.InteropServices; + +namespace Ryujinx.Core.OsHle.IpcServices.Aud +{ + [StructLayout(LayoutKind.Sequential)] + struct AudioOutData + { + public long NextBufferPtr; + public long SampleBufferPtr; + public long SampleBufferCapacity; + public long SampleBufferSize; + public long SampleBufferInnerOffset; + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs index 9ebf140a26..863c9a27f6 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs @@ -55,7 +55,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud long Position = Context.Request.SendBuff[0].Position; long Size = Context.Request.SendBuff[0].Size; - string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position, (int)Size); + string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position, Size); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs index 2312920f6c..d0528a6d3e 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs @@ -1,11 +1,9 @@ using ChocolArm64.Memory; +using Ryujinx.Audio; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; -using OpenTK.Audio; -using OpenTK.Audio.OpenAL; using System; using System.Collections.Generic; -using System.IO; namespace Ryujinx.Core.OsHle.IpcServices.Aud { @@ -15,124 +13,64 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud public IReadOnlyDictionary Commands => m_Commands; - public IAudioOut() + private IAalOutput AudioOut; + + private int Track; + + public IAudioOut(IAalOutput AudioOut, int Track) { m_Commands = new Dictionary() { - { 0, GetAudioOutState }, - { 1, StartAudioOut }, - { 2, StopAudioOut }, - { 3, AppendAudioOutBuffer }, - { 4, RegisterBufferEvent }, - { 5, GetReleasedAudioOutBuffer }, - { 6, ContainsAudioOutBuffer }, - { 7, AppendAudioOutBuffer_ex }, - { 8, GetReleasedAudioOutBuffer_ex } + { 0, GetAudioOutState }, + { 1, StartAudioOut }, + { 2, StopAudioOut }, + { 3, AppendAudioOutBuffer }, + { 4, RegisterBufferEvent }, + { 5, GetReleasedAudioOutBuffer }, + { 6, ContainsAudioOutBuffer }, + { 7, AppendAudioOutBufferEx }, + { 8, GetReleasedAudioOutBufferEx } }; + + this.AudioOut = AudioOut; + this.Track = Track; } - enum AudioOutState - { - Started, - Stopped - }; - - //IAudioOut - private AudioOutState State = AudioOutState.Stopped; - private Queue BufferIdQueue = new Queue(); - - //OpenAL - private bool OpenALInstalled = true; - private AudioContext AudioCtx; - private int Source; - private int Buffer; - - //Return State of IAudioOut public long GetAudioOutState(ServiceCtx Context) { - Context.ResponseData.Write((int)State); + Context.ResponseData.Write((int)AudioOut.GetState(Track)); return 0; } public long StartAudioOut(ServiceCtx Context) { - if (State == AudioOutState.Stopped) - { - State = AudioOutState.Started; - - try - { - AudioCtx = new AudioContext(); //Create the audio context - } - catch (Exception) - { - Logging.Warn("OpenAL Error! PS: Install OpenAL Core SDK!"); - OpenALInstalled = false; - } - - if (OpenALInstalled) AL.Listener(ALListenerf.Gain, 8.0f); //Add more gain to it - } + AudioOut.Start(Track); return 0; } public 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); - AL.DeleteBuffers(1, ref Buffer); - } - State = AudioOutState.Stopped; - } + AudioOut.Stop(Track); return 0; } public long AppendAudioOutBuffer(ServiceCtx Context) { - long BufferId = Context.RequestData.ReadInt64(); + long Tag = Context.RequestData.ReadInt64(); - byte[] AudioOutBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[0].Position, sizeof(long) * 5); + AudioOutData Data = AMemoryHelper.Read( + Context.Memory, + Context.Request.SendBuff[0].Position); + + byte[] Buffer = AMemoryHelper.ReadBytes( + Context.Memory, + Data.SampleBufferPtr, + Data.SampleBufferSize); - using (MemoryStream MS = new MemoryStream(AudioOutBuffer)) - { - BinaryReader Reader = new BinaryReader(MS); - long PointerNextBuffer = Reader.ReadInt64(); - long PointerSampleBuffer = Reader.ReadInt64(); - long CapacitySampleBuffer = Reader.ReadInt64(); - long SizeDataInSampleBuffer = Reader.ReadInt64(); - long OffsetDataInSampleBuffer = Reader.ReadInt64(); - - if (SizeDataInSampleBuffer > 0) - { - BufferIdQueue.Enqueue(BufferId); - - byte[] AudioSampleBuffer = AMemoryHelper.ReadBytes(Context.Memory, PointerSampleBuffer + OffsetDataInSampleBuffer, (int)SizeDataInSampleBuffer); - - if (OpenALInstalled) - { - if (AudioCtx == null) //Needed to call the instance of AudioContext() - return 0; - - EnsureAudioFinalized(); - - Source = AL.GenSource(); - Buffer = AL.GenBuffer(); - - AL.BufferData(Buffer, ALFormat.Stereo16, AudioSampleBuffer, AudioSampleBuffer.Length, 48000); - AL.SourceQueueBuffer(Source, Buffer); - AL.SourcePlay(Source); - } - } - } + AudioOut.AppendBuffer(Track, Tag, Buffer); return 0; } @@ -148,62 +86,63 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud public long GetReleasedAudioOutBuffer(ServiceCtx Context) { - int ReleasedBuffersCount = 0; + long Position = Context.Request.ReceiveBuff[0].Position; + long Size = Context.Request.ReceiveBuff[0].Size; - for(int i = 0; i < BufferIdQueue.Count; i++) + uint Count = (uint)((ulong)Size >> 3); + + long[] ReleasedBuffers = AudioOut.GetReleasedBuffers(Track); + + for (uint Index = 0; Index < Count; Index++) { - long BufferId = BufferIdQueue.Dequeue(); + long Tag = 0; - AMemoryHelper.WriteBytes(Context.Memory, Context.Request.ReceiveBuff[0].Position + (8 * i), BitConverter.GetBytes(BufferId)); + if (Index < ReleasedBuffers.Length) + { + Tag = ReleasedBuffers[Index]; + } - ReleasedBuffersCount++; + Context.Memory.WriteInt64(Position + Index * 8, Tag); } - Context.ResponseData.Write(ReleasedBuffersCount); + Context.ResponseData.Write(ReleasedBuffers.Length); return 0; } public long ContainsAudioOutBuffer(ServiceCtx Context) { + long Tag = Context.RequestData.ReadInt64(); + + Context.ResponseData.Write(AudioOut.ContainsBuffer(Track, Tag) ? 1 : 0); + return 0; } - public long AppendAudioOutBuffer_ex(ServiceCtx Context) + public long AppendAudioOutBufferEx(ServiceCtx Context) { + Logging.Warn("Not implemented!"); + return 0; } - public long GetReleasedAudioOutBuffer_ex(ServiceCtx Context) + public long GetReleasedAudioOutBufferEx(ServiceCtx Context) { + Logging.Warn("Not implemented!"); + return 0; } - private void EnsureAudioFinalized() - { - if (Source != 0 || - Buffer != 0) - { - AL.SourceStop(Source); - AL.SourceUnqueueBuffer(Buffer); - AL.DeleteSource(Source); - AL.DeleteBuffers(1, ref Buffer); - - Source = 0; - Buffer = 0; - } - } - public void Dispose() { Dispose(true); } - protected virtual void Dispose(bool disposing) + protected virtual void Dispose(bool Disposing) { - if (disposing) + if (Disposing) { - EnsureAudioFinalized(); + AudioOut.CloseTrack(Track); } } } diff --git a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs index eb923562bf..19f23d1c7c 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.Audio; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.Text; @@ -18,7 +19,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud m_Commands = new Dictionary() { { 0, ListAudioOuts }, - { 1, OpenAudioOut }, + { 1, OpenAudioOut } }; } @@ -35,21 +36,51 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud public long OpenAudioOut(ServiceCtx Context) { - MakeObject(Context, new IAudioOut()); + IAalOutput AudioOut = Context.Ns.AudioOut; - 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 + string DeviceName = AMemoryHelper.ReadAsciiString( + Context.Memory, + Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size); + + if (DeviceName == string.Empty) + { + DeviceName = "FIXME"; + } + + long DeviceNamePosition = Context.Request.ReceiveBuff[0].Position; + long DeviceNameSize = Context.Request.ReceiveBuff[0].Size; + + byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(DeviceName); + + if (DeviceName.Length <= DeviceNameSize) + { + AMemoryHelper.WriteBytes(Context.Memory, DeviceNamePosition, DeviceNameBuffer); + } + + int SampleRate = Context.RequestData.ReadInt32(); + int Channels = Context.RequestData.ReadInt32(); + + Channels = (ushort)(Channels >> 16); + + if (SampleRate == 0) + { + SampleRate = 48000; + } + + if (Channels < 1 || Channels > 2) + { + Channels = 2; + } + + int Track = AudioOut.OpenTrack(SampleRate, Channels, out AudioFormat Format); + + MakeObject(Context, new IAudioOut(AudioOut, Track)); + + Context.ResponseData.Write(SampleRate); + Context.ResponseData.Write(Channels); + Context.ResponseData.Write((int)Format); + Context.ResponseData.Write((int)PlaybackState.Stopped); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs b/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs index da1e51e17c..680e8405cf 100644 --- a/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs +++ b/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs @@ -151,7 +151,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Bsd byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[0].Position, - (int)Context.Request.SendBuff[0].Size); + Context.Request.SendBuff[0].Size); int SocketId = Get32(SentBuffer, 0); short RequestedEvents = (short)Get16(SentBuffer, 4); short ReturnedEvents = (short)Get16(SentBuffer, 6); @@ -197,7 +197,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Bsd int SocketFlags = Context.RequestData.ReadInt32(); byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[0].Position, - (int)Context.Request.SendBuff[0].Size); + Context.Request.SendBuff[0].Size); try { @@ -224,10 +224,10 @@ namespace Ryujinx.Core.OsHle.IpcServices.Bsd int SocketFlags = Context.RequestData.ReadInt32(); byte[] SentBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[0].Position, - (int)Context.Request.SendBuff[0].Size); + Context.Request.SendBuff[0].Size); byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[1].Position, - (int)Context.Request.SendBuff[1].Size); + Context.Request.SendBuff[1].Size); if (!Sockets[SocketId].Handle.Connected) { @@ -333,7 +333,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Bsd byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[0].Position, - (int)Context.Request.SendBuff[0].Size); + Context.Request.SendBuff[0].Size); try { @@ -358,7 +358,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Bsd byte[] AddressBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[0].Position, - (int)Context.Request.SendBuff[0].Size); + Context.Request.SendBuff[0].Size); try { diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs index ac2100f29e..b997306122 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs @@ -62,7 +62,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.FspSrv long Offset = Context.RequestData.ReadInt64(); long Size = Context.RequestData.ReadInt64(); - byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, Position, (int)Size); + byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, Position, Size); BaseStream.Seek(Offset, SeekOrigin.Begin); BaseStream.Write(Data, 0, (int)Size); diff --git a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs index 5ee097b6f9..8ef9f3c6dd 100644 --- a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs +++ b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs @@ -54,7 +54,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Lm long BufferPosition = Context.Request.PtrBuff[0].Position; long BufferLen = Context.Request.PtrBuff[0].Size; - byte[] LogBuffer = AMemoryHelper.ReadBytes(Context.Memory, BufferPosition, (int)BufferLen); + byte[] LogBuffer = AMemoryHelper.ReadBytes(Context.Memory, BufferPosition, BufferLen); MemoryStream LogMessage = new MemoryStream(LogBuffer); BinaryReader bReader = new BinaryReader(LogMessage); diff --git a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs index b24a773bfe..beccbe7d3f 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs @@ -35,7 +35,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi long DataPos = Context.Request.SendBuff[0].Position; long DataSize = Context.Request.SendBuff[0].Size; - byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, DataPos, (int)DataSize); + byte[] Data = AMemoryHelper.ReadBytes(Context.Memory, DataPos, DataSize); Data = Parcel.GetParcelData(Data); @@ -66,9 +66,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi Dispose(true); } - protected virtual void Dispose(bool disposing) + protected virtual void Dispose(bool Disposing) { - if (disposing) + if (Disposing) { Flinger.Dispose(); } diff --git a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs index 671a32d361..9417473cf5 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs @@ -118,7 +118,7 @@ namespace Ryujinx.Core.OsHle.Svc Process.Scheduler.Suspend(CurrThread.ProcessorId); - byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size); + byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, Size); HSession Session = Process.HandleTable.GetData(Handle); @@ -136,7 +136,7 @@ namespace Ryujinx.Core.OsHle.Svc CmdPtr, Handle); - byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size); + byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, Size); ThreadState.X0 = 0; } @@ -164,7 +164,7 @@ namespace Ryujinx.Core.OsHle.Svc long Position = (long)ThreadState.X0; long Size = (long)ThreadState.X1; - string Str = AMemoryHelper.ReadAsciiString(Memory, Position, (int)Size); + string Str = AMemoryHelper.ReadAsciiString(Memory, Position, Size); Logging.Info($"SvcOutputDebugString: {Str}"); diff --git a/Ryujinx.Core/Ryujinx.Core.csproj b/Ryujinx.Core/Ryujinx.Core.csproj index 7d5ad71853..b9374af1db 100644 --- a/Ryujinx.Core/Ryujinx.Core.csproj +++ b/Ryujinx.Core/Ryujinx.Core.csproj @@ -14,6 +14,7 @@ + diff --git a/Ryujinx.Core/Settings/SetSys.cs b/Ryujinx.Core/Settings/SystemSettings.cs similarity index 72% rename from Ryujinx.Core/Settings/SetSys.cs rename to Ryujinx.Core/Settings/SystemSettings.cs index d8b6eb6ef5..0f56ef3ae3 100644 --- a/Ryujinx.Core/Settings/SetSys.cs +++ b/Ryujinx.Core/Settings/SystemSettings.cs @@ -1,6 +1,6 @@ namespace Ryujinx.Core.Settings { - public class SetSys + public class SystemSettings { public ColorSet ThemeColor; } diff --git a/Ryujinx.Core/Switch.cs b/Ryujinx.Core/Switch.cs index 487f3bdb99..92d78f4536 100644 --- a/Ryujinx.Core/Switch.cs +++ b/Ryujinx.Core/Switch.cs @@ -1,3 +1,4 @@ +using Ryujinx.Audio; using Ryujinx.Core.Input; using Ryujinx.Core.OsHle; using Ryujinx.Core.Settings; @@ -9,32 +10,50 @@ namespace Ryujinx.Core { public class Switch : IDisposable { - internal NsGpu Gpu { get; private set; } - internal Horizon Os { get; private set; } - internal VirtualFs VFs { get; private set; } + internal IAalOutput AudioOut { get; private set; } + + internal NsGpu Gpu { get; private set; } + + internal Horizon Os { get; private set; } + + internal VirtualFileSystem VFs { get; private set; } + + public SystemSettings Settings { get; private set; } - public Hid Hid { get; private set; } - public SetSys Settings { get; private set; } public PerformanceStatistics Statistics { get; private set; } + public Hid Hid { get; private set; } + public event EventHandler Finish; - public Switch(IGalRenderer Renderer) + public Switch(IGalRenderer Renderer, IAalOutput AudioOut) { + if (Renderer == null) + { + throw new ArgumentNullException(nameof(Renderer)); + } + + if (AudioOut == null) + { + throw new ArgumentNullException(nameof(AudioOut)); + } + + this.AudioOut = AudioOut; + Gpu = new NsGpu(Renderer); - VFs = new VirtualFs(); - - Hid = new Hid(); - - Statistics = new PerformanceStatistics(); - Os = new Horizon(this); + VFs = new VirtualFileSystem(); + + Settings = new SystemSettings(); + + Statistics = new PerformanceStatistics(); + + Hid = new Hid(); + Os.HidSharedMem.MemoryMapped += Hid.ShMemMap; Os.HidSharedMem.MemoryUnmapped += Hid.ShMemUnmap; - - Settings = new SetSys(); } public void LoadCart(string ExeFsDir, string RomFsFile = null) diff --git a/Ryujinx.Core/VirtualFs.cs b/Ryujinx.Core/VirtualFileSystem.cs similarity index 98% rename from Ryujinx.Core/VirtualFs.cs rename to Ryujinx.Core/VirtualFileSystem.cs index c0858e0ee6..1c717b2ca7 100644 --- a/Ryujinx.Core/VirtualFs.cs +++ b/Ryujinx.Core/VirtualFileSystem.cs @@ -3,7 +3,7 @@ using System.IO; namespace Ryujinx.Core { - class VirtualFs : IDisposable + class VirtualFileSystem : IDisposable { private const string BasePath = "RyuFs"; private const string NandPath = "nand"; diff --git a/Ryujinx.Graphics/Gpu/NsGpuPGraph.cs b/Ryujinx.Graphics/Gpu/NsGpuPGraph.cs index eb893f74c6..6543b1d1d8 100644 --- a/Ryujinx.Graphics/Gpu/NsGpuPGraph.cs +++ b/Ryujinx.Graphics/Gpu/NsGpuPGraph.cs @@ -117,7 +117,7 @@ namespace Ryujinx.Graphics.Gpu if (Position != -1) { - byte[] Buffer = AMemoryHelper.ReadBytes(Memory, Position, (int)Size); + byte[] Buffer = AMemoryHelper.ReadBytes(Memory, Position, Size); int Stride = GetRegister(NsGpuRegister._3dVertexArray0Fetch) & 0xfff; diff --git a/Ryujinx/Ryujinx.csproj b/Ryujinx/Ryujinx.csproj index bc5dbe0423..f2d9cafe9d 100644 --- a/Ryujinx/Ryujinx.csproj +++ b/Ryujinx/Ryujinx.csproj @@ -11,6 +11,7 @@ + diff --git a/Ryujinx/Ui/Program.cs b/Ryujinx/Ui/Program.cs index b67e52bdc3..062e8bade9 100644 --- a/Ryujinx/Ui/Program.cs +++ b/Ryujinx/Ui/Program.cs @@ -1,4 +1,6 @@ -using Ryujinx.Core; +using Ryujinx.Audio; +using Ryujinx.Audio.OpenAL; +using Ryujinx.Core; using Ryujinx.Graphics.Gal; using Ryujinx.Graphics.Gal.OpenGL; using System; @@ -18,7 +20,9 @@ namespace Ryujinx IGalRenderer Renderer = new OpenGLRenderer(); - Switch Ns = new Switch(Renderer); + IAalOutput AudioOut = new OpenALAudioOut(); + + Switch Ns = new Switch(Renderer, AudioOut); if (args.Length == 1) { From 88c6160c62b000d155a829b23e6207d78b7dccfa Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 15 Mar 2018 22:36:47 -0300 Subject: [PATCH 4/9] Add MLA (vector by element), fixes some cases of MUL (vector by element)? --- ChocolArm64/AOpCodeTable.cs | 1 + ChocolArm64/Decoder/AOpCodeSimdRegElem.cs | 5 ++--- ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 9 +++++++++ ChocolArm64/Instruction/AInstEmitSimdHelper.cs | 7 +++++-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index d32bd9cd24..9240c0a7a9 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/AOpCodeTable.cs @@ -228,6 +228,7 @@ namespace ChocolArm64 Set("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemReg)); Set("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit, typeof(AOpCodeSimdMemLit)); Set("0x001110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V, typeof(AOpCodeSimdReg)); + Set("0x101111xxxxxxxx0000x0xxxxxxxxxx", AInstEmit.Mla_Ve, typeof(AOpCodeSimdRegElem)); Set("0x101110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mls_V, typeof(AOpCodeSimdReg)); Set("0x00111100000xxx0xx001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); Set("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); diff --git a/ChocolArm64/Decoder/AOpCodeSimdRegElem.cs b/ChocolArm64/Decoder/AOpCodeSimdRegElem.cs index 721da88faa..d6dc4bd231 100644 --- a/ChocolArm64/Decoder/AOpCodeSimdRegElem.cs +++ b/ChocolArm64/Decoder/AOpCodeSimdRegElem.cs @@ -11,9 +11,8 @@ namespace ChocolArm64.Decoder switch (Size) { case 1: - Index = (OpCode >> 21) & 1 | - (OpCode >> 10) & 2 | - (OpCode >> 18) & 4; + Index = (OpCode >> 20) & 3 | + (OpCode >> 9) & 4; Rm &= 0xf; diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index bf980a581e..989b470ea4 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -335,6 +335,15 @@ namespace ChocolArm64.Instruction }); } + public static void Mla_Ve(AILEmitterCtx Context) + { + EmitVectorTernaryOpByElemZx(Context, () => + { + Context.Emit(OpCodes.Mul); + Context.Emit(OpCodes.Add); + }); + } + public static void Mls_V(AILEmitterCtx Context) { EmitVectorTernaryOpZx(Context, () => diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs index 4e45a11d6a..d8642e99a8 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs @@ -381,13 +381,16 @@ namespace ChocolArm64.Instruction } EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed); - EmitVectorExtract(Context, Op.Rm, Index, Op.Size, Signed); + EmitVectorExtract(Context, Op.Rm, Elem, Op.Size, Signed); Emit(); - EmitVectorInsert(Context, Op.Rd, Index, Op.Size); + EmitVectorInsertTmp(Context, Index, Op.Size); } + Context.EmitLdvectmp(); + Context.EmitStvec(Op.Rd); + if (Op.RegisterSize == ARegisterSize.SIMD64) { EmitVectorZeroUpper(Context, Op.Rd); From 4940cf0ea58c77c8666d76abdfc35c6380efed4c Mon Sep 17 00:00:00 2001 From: gdkchan Date: Fri, 16 Mar 2018 00:42:44 -0300 Subject: [PATCH 5/9] Add BFI instruction, even more audout fixes --- ChocolArm64/AOpCodeTable.cs | 1 + .../Instruction/AInstEmitSimdLogical.cs | 30 +++++ Ryujinx.Audio/IAalOutput.cs | 6 +- Ryujinx.Audio/OpenAL/OpenALAudioOut.cs | 113 ++++++++++-------- Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs | 2 +- 5 files changed, 99 insertions(+), 53 deletions(-) diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index 9240c0a7a9..c28abe5cd7 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/AOpCodeTable.cs @@ -139,6 +139,7 @@ namespace ChocolArm64 Set("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V, typeof(AOpCodeSimdReg)); Set("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V, typeof(AOpCodeSimdReg)); Set("0x10111100000xxx<101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg)); Set("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd)); diff --git a/ChocolArm64/Instruction/AInstEmitSimdLogical.cs b/ChocolArm64/Instruction/AInstEmitSimdLogical.cs index 5b71a0bbb8..8fd8ea4d10 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdLogical.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdLogical.cs @@ -32,6 +32,36 @@ namespace ChocolArm64.Instruction }); } + public static void Bif_V(AILEmitterCtx Context) + { + AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; + + int Bytes = Context.CurrOp.GetBitsCount() >> 3; + + for (int Index = 0; Index < (Bytes >> Op.Size); Index++) + { + EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size); + EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size); + + Context.Emit(OpCodes.Xor); + + EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size); + + Context.Emit(OpCodes.And); + + EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size); + + Context.Emit(OpCodes.Xor); + + EmitVectorInsert(Context, Op.Rd, Index, Op.Size); + } + + if (Op.RegisterSize == ARegisterSize.SIMD64) + { + EmitVectorZeroUpper(Context, Op.Rd); + } + } + public static void Bsl_V(AILEmitterCtx Context) { EmitVectorTernaryOpZx(Context, () => diff --git a/Ryujinx.Audio/IAalOutput.cs b/Ryujinx.Audio/IAalOutput.cs index 7ed0e0b6bc..5ffeebdd84 100644 --- a/Ryujinx.Audio/IAalOutput.cs +++ b/Ryujinx.Audio/IAalOutput.cs @@ -3,12 +3,14 @@ namespace Ryujinx.Audio public interface IAalOutput { int OpenTrack(int SampleRate, int Channels, out AudioFormat Format); + void CloseTrack(int Track); - void AppendBuffer(int Track, long Tag, byte[] Buffer); bool ContainsBuffer(int Track, long Tag); - long[] GetReleasedBuffers(int Track); + long[] GetReleasedBuffers(int Track, int MaxCount); + + void AppendBuffer(int Track, long Tag, byte[] Buffer); void Start(int Track); void Stop(int Track); diff --git a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs index 7cf30c1822..48dcd19919 100644 --- a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs +++ b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs @@ -10,6 +10,8 @@ namespace Ryujinx.Audio.OpenAL { private const int MaxTracks = 256; + private const int MaxReleased = 32; + private AudioContext Context; private class Track : IDisposable @@ -26,6 +28,8 @@ namespace Ryujinx.Audio.OpenAL private Queue QueuedTagsQueue; + private Queue ReleasedTagsQueue; + private bool Disposed; public Track(int SampleRate, ALFormat Format) @@ -40,9 +44,45 @@ namespace Ryujinx.Audio.OpenAL Buffers = new ConcurrentDictionary(); QueuedTagsQueue = new Queue(); + + ReleasedTagsQueue = new Queue(); } - public int GetBufferId(long Tag) + public bool ContainsBuffer(long Tag) + { + SyncQueuedTags(); + + foreach (long QueuedTag in QueuedTagsQueue) + { + if (QueuedTag == Tag) + { + return true; + } + } + + return false; + } + + public long[] GetReleasedBuffers(int MaxCount) + { + ClearReleased(); + + List Tags = new List(); + + HashSet Unique = new HashSet(); + + while (MaxCount-- > 0 && ReleasedTagsQueue.TryDequeue(out long Tag)) + { + if (Unique.Add(Tag)) + { + Tags.Add(Tag); + } + } + + return Tags.ToArray(); + } + + public int AppendBuffer(long Tag) { if (Disposed) { @@ -63,23 +103,6 @@ namespace Ryujinx.Audio.OpenAL return Id; } - public long[] GetReleasedBuffers() - { - ClearReleased(); - - List Tags = new List(); - - foreach (long Tag in Buffers.Keys) - { - if (!ContainsBuffer(Tag)) - { - Tags.Add(Tag); - } - } - - return Tags.ToArray(); - } - public void ClearReleased() { SyncQueuedTags(); @@ -91,21 +114,6 @@ namespace Ryujinx.Audio.OpenAL AL.SourceUnqueueBuffers(SourceId, ReleasedCount); } } - - public bool ContainsBuffer(long Tag) - { - SyncQueuedTags(); - - foreach (long QueuedTag in QueuedTagsQueue) - { - if (QueuedTag == Tag) - { - return true; - } - } - - return false; - } private void SyncQueuedTags() { @@ -116,7 +124,12 @@ namespace Ryujinx.Audio.OpenAL while (QueuedTagsQueue.Count > QueuedCount) { - QueuedTagsQueue.Dequeue(); + ReleasedTagsQueue.Enqueue(QueuedTagsQueue.Dequeue()); + } + + while (ReleasedTagsQueue.Count > MaxReleased) + { + ReleasedTagsQueue.Dequeue(); } } @@ -202,20 +215,6 @@ namespace Ryujinx.Audio.OpenAL } } - public void AppendBuffer(int Track, long Tag, byte[] Buffer) - { - if (Tracks.TryGetValue(Track, out Track Td)) - { - int BufferId = Td.GetBufferId(Tag); - - AL.BufferData(BufferId, Td.Format, Buffer, Buffer.Length, Td.SampleRate); - - AL.SourceQueueBuffer(Td.SourceId, BufferId); - - StartPlaybackIfNeeded(Td); - } - } - public bool ContainsBuffer(int Track, long Tag) { if (Tracks.TryGetValue(Track, out Track Td)) @@ -226,16 +225,30 @@ namespace Ryujinx.Audio.OpenAL return false; } - public long[] GetReleasedBuffers(int Track) + public long[] GetReleasedBuffers(int Track, int MaxCount) { if (Tracks.TryGetValue(Track, out Track Td)) { - return Td.GetReleasedBuffers(); + return Td.GetReleasedBuffers(MaxCount); } return null; } + public void AppendBuffer(int Track, long Tag, byte[] Buffer) + { + if (Tracks.TryGetValue(Track, out Track Td)) + { + int BufferId = Td.AppendBuffer(Tag); + + AL.BufferData(BufferId, Td.Format, Buffer, Buffer.Length, Td.SampleRate); + + AL.SourceQueueBuffer(Td.SourceId, BufferId); + + StartPlaybackIfNeeded(Td); + } + } + public void Start(int Track) { if (Tracks.TryGetValue(Track, out Track Td)) diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs index d0528a6d3e..8cd013f8b9 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs @@ -91,7 +91,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud uint Count = (uint)((ulong)Size >> 3); - long[] ReleasedBuffers = AudioOut.GetReleasedBuffers(Track); + long[] ReleasedBuffers = AudioOut.GetReleasedBuffers(Track, (int)Count); for (uint Index = 0; Index < Count; Index++) { From 4314a8f3e5b76bbf2143f701c06e9354de712027 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 19 Mar 2018 15:58:46 -0300 Subject: [PATCH 6/9] [WIP] Add support for events (#60) * Add support for events, move concept of domains to IpcService * Support waiting for KThread, remove some test code, other tweaks * Use move handle on NIFM since I can't test that now, it's better to leave it how it was --- Ryujinx.Audio/IAalOutput.cs | 6 +- Ryujinx.Audio/OpenAL/OpenALAudioOut.cs | 75 ++++++++- Ryujinx.Audio/ReleaseCallback.cs | 4 + Ryujinx.Core/OsHle/AppletStateMgr.cs | 62 +++++++ Ryujinx.Core/OsHle/CondVar.cs | 8 +- Ryujinx.Core/OsHle/FileDesc.cs | 12 -- Ryujinx.Core/OsHle/GlobalStateTable.cs | 62 +++++++ Ryujinx.Core/OsHle/Handles/HDomain.cs | 48 ------ Ryujinx.Core/OsHle/Handles/HEvent.cs | 7 - Ryujinx.Core/OsHle/Handles/HSession.cs | 29 ---- Ryujinx.Core/OsHle/Handles/HSessionObj.cs | 30 ---- Ryujinx.Core/OsHle/Handles/KEvent.cs | 4 + .../OsHle/Handles/KProcessHandleTable.cs | 39 +---- .../OsHle/Handles/KProcessScheduler.cs | 26 +-- Ryujinx.Core/OsHle/Handles/KSession.cs | 28 ++++ .../OsHle/Handles/KSynchronizationObject.cs | 28 ++++ .../OsHle/Handles/{HThread.cs => KThread.cs} | 4 +- Ryujinx.Core/OsHle/Horizon.cs | 19 ++- Ryujinx.Core/OsHle/IdDictionary.cs | 37 ++--- Ryujinx.Core/OsHle/Ipc/IpcDomCmd.cs | 8 - Ryujinx.Core/OsHle/Ipc/IpcHandler.cs | 117 +++----------- Ryujinx.Core/OsHle/Ipc/IpcLog.cs | 3 +- Ryujinx.Core/OsHle/Ipc/IpcMagic.cs | 8 + Ryujinx.Core/OsHle/Ipc/IpcMessage.cs | 48 +----- Ryujinx.Core/OsHle/KernelErr.cs | 1 - Ryujinx.Core/OsHle/Mutex.cs | 10 +- Ryujinx.Core/OsHle/Process.cs | 47 ++++-- Ryujinx.Core/OsHle/ServiceCtx.cs | 4 +- Ryujinx.Core/OsHle/ServiceMgr.cs | 128 --------------- .../Services/Acc/IManagerForApplication.cs | 4 +- Ryujinx.Core/OsHle/Services/Acc/IProfile.cs | 4 +- Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs | 6 +- Ryujinx.Core/OsHle/Services/Am/AmErr.cs | 7 + Ryujinx.Core/OsHle/Services/Am/FocusState.cs | 8 + .../Services/Am/IApplicationFunctions.cs | 6 +- .../OsHle/Services/Am/IApplicationProxy.cs | 6 +- .../OsHle/Services/Am/IAudioController.cs | 4 +- .../OsHle/Services/Am/ICommonStateGetter.cs | 41 +++-- .../OsHle/Services/Am/IDebugFunctions.cs | 4 +- .../OsHle/Services/Am/IDisplayController.cs | 4 +- .../Services/Am/ILibraryAppletCreator.cs | 4 +- .../OsHle/Services/Am/ISelfController.cs | 4 +- Ryujinx.Core/OsHle/Services/Am/IStorage.cs | 6 +- .../OsHle/Services/Am/IStorageAccessor.cs | 4 +- .../OsHle/Services/Am/IWindowController.cs | 4 +- Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs | 9 ++ .../OsHle/Services/Am/OperationMode.cs | 8 + .../OsHle/Services/Am/ServiceAppletOE.cs | 6 +- Ryujinx.Core/OsHle/Services/Apm/ISession.cs | 4 +- Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs | 6 +- .../OsHle/Services/Aud/IAudioDevice.cs | 4 +- Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs | 17 +- .../OsHle/Services/Aud/IAudioRenderer.cs | 27 +++- .../OsHle/Services/Aud/ServiceAudOut.cs | 18 ++- .../OsHle/Services/Aud/ServiceAudRen.cs | 6 +- Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs | 4 +- .../OsHle/Services/Friend/IFriendService.cs | 4 +- .../OsHle/Services/Friend/ServiceFriend.cs | 6 +- .../OsHle/Services/FspSrv/IDirectory.cs | 4 +- Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs | 4 +- .../OsHle/Services/FspSrv/IFileSystem.cs | 5 +- .../OsHle/Services/FspSrv/IStorage.cs | 4 +- .../OsHle/Services/FspSrv/ServiceFspSrv.cs | 6 +- .../Hid/IActiveVibrationDeviceList.cs | 4 +- .../OsHle/Services/Hid/IAppletResource.cs | 4 +- Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs | 6 +- Ryujinx.Core/OsHle/Services/IpcService.cs | 151 ++++++++++++++++++ Ryujinx.Core/OsHle/Services/Lm/ILogger.cs | 4 +- Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs | 8 +- .../OsHle/Services/Nifm/IGeneralService.cs | 6 +- Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs | 29 +++- .../OsHle/Services/Nifm/ServiceNifm.cs | 6 +- Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs | 4 +- .../OsHle/Services/Nv/ServiceNvDrv.cs | 63 +++++--- Ryujinx.Core/OsHle/Services/ObjHelper.cs | 24 --- .../Services/Pctl/IParentalControlService.cs | 4 +- .../OsHle/Services/Pctl/ServicePctl.cs | 6 +- Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs | 4 +- Ryujinx.Core/OsHle/Services/ServiceFactory.cs | 119 ++++++++++++++ Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs | 4 +- .../OsHle/Services/Set/ServiceSetSys.cs | 4 +- .../Services/Sfdnsres/ServiceSfdnsres.cs | 4 +- Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs | 12 +- Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs | 4 +- .../OsHle/Services/Time/ISteadyClock.cs | 4 +- .../OsHle/Services/Time/ISystemClock.cs | 4 +- .../OsHle/Services/Time/ITimeZoneService.cs | 4 +- .../OsHle/Services/Time/ServiceTime.cs | 6 +- .../Services/Vi/IApplicationDisplayService.cs | 8 +- .../OsHle/Services/Vi/IHOSBinderDriver.cs | 17 +- .../Services/Vi/IManagerDisplayService.cs | 4 +- .../Services/Vi/ISystemDisplayService.cs | 4 +- Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs | 22 ++- Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs | 6 +- Ryujinx.Core/OsHle/Svc/SvcSystem.cs | 151 ++++++++++++------ Ryujinx.Core/OsHle/Svc/SvcThread.cs | 18 ++- Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs | 6 +- Ryujinx.Core/Switch.cs | 10 +- Ryujinx.Graphics/Gpu/NsGpuPGraph.cs | 59 +++++-- Ryujinx.Graphics/Gpu/NsGpuRegister.cs | 1 + Ryujinx/Ui/GLScreen.cs | 2 + 101 files changed, 1120 insertions(+), 836 deletions(-) create mode 100644 Ryujinx.Audio/ReleaseCallback.cs create mode 100644 Ryujinx.Core/OsHle/AppletStateMgr.cs delete mode 100644 Ryujinx.Core/OsHle/FileDesc.cs create mode 100644 Ryujinx.Core/OsHle/GlobalStateTable.cs delete mode 100644 Ryujinx.Core/OsHle/Handles/HDomain.cs delete mode 100644 Ryujinx.Core/OsHle/Handles/HEvent.cs delete mode 100644 Ryujinx.Core/OsHle/Handles/HSession.cs delete mode 100644 Ryujinx.Core/OsHle/Handles/HSessionObj.cs create mode 100644 Ryujinx.Core/OsHle/Handles/KEvent.cs create mode 100644 Ryujinx.Core/OsHle/Handles/KSession.cs create mode 100644 Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs rename Ryujinx.Core/OsHle/Handles/{HThread.cs => KThread.cs} (79%) delete mode 100644 Ryujinx.Core/OsHle/Ipc/IpcDomCmd.cs create mode 100644 Ryujinx.Core/OsHle/Ipc/IpcMagic.cs delete mode 100644 Ryujinx.Core/OsHle/ServiceMgr.cs create mode 100644 Ryujinx.Core/OsHle/Services/Am/AmErr.cs create mode 100644 Ryujinx.Core/OsHle/Services/Am/FocusState.cs create mode 100644 Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs create mode 100644 Ryujinx.Core/OsHle/Services/Am/OperationMode.cs create mode 100644 Ryujinx.Core/OsHle/Services/IpcService.cs delete mode 100644 Ryujinx.Core/OsHle/Services/ObjHelper.cs create mode 100644 Ryujinx.Core/OsHle/Services/ServiceFactory.cs diff --git a/Ryujinx.Audio/IAalOutput.cs b/Ryujinx.Audio/IAalOutput.cs index 5ffeebdd84..f9978ee4d9 100644 --- a/Ryujinx.Audio/IAalOutput.cs +++ b/Ryujinx.Audio/IAalOutput.cs @@ -2,7 +2,11 @@ namespace Ryujinx.Audio { public interface IAalOutput { - int OpenTrack(int SampleRate, int Channels, out AudioFormat Format); + int OpenTrack( + int SampleRate, + int Channels, + ReleaseCallback Callback, + out AudioFormat Format); void CloseTrack(int Track); diff --git a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs index 48dcd19919..f574b46f38 100644 --- a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs +++ b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs @@ -3,6 +3,7 @@ using OpenTK.Audio.OpenAL; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Threading; namespace Ryujinx.Audio.OpenAL { @@ -22,20 +23,27 @@ namespace Ryujinx.Audio.OpenAL public ALFormat Format { get; private set; } + private ReleaseCallback Callback; + public PlaybackState State { get; set; } + private bool ShouldCallReleaseCallback; + private ConcurrentDictionary Buffers; private Queue QueuedTagsQueue; private Queue ReleasedTagsQueue; + private int LastReleasedCount; + private bool Disposed; - public Track(int SampleRate, ALFormat Format) + public Track(int SampleRate, ALFormat Format, ReleaseCallback Callback) { this.SampleRate = SampleRate; this.Format = Format; + this.Callback = Callback; State = PlaybackState.Stopped; @@ -109,11 +117,42 @@ namespace Ryujinx.Audio.OpenAL AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount); + CheckReleaseChanges(ReleasedCount); + if (ReleasedCount > 0) { AL.SourceUnqueueBuffers(SourceId, ReleasedCount); } } + + public void CallReleaseCallbackIfNeeded() + { + CheckReleaseChanges(); + + if (ShouldCallReleaseCallback) + { + ShouldCallReleaseCallback = false; + + Callback(); + } + } + + private void CheckReleaseChanges() + { + AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount); + + CheckReleaseChanges(ReleasedCount); + } + + private void CheckReleaseChanges(int NewReleasedCount) + { + if (LastReleasedCount != NewReleasedCount) + { + LastReleasedCount = NewReleasedCount; + + ShouldCallReleaseCallback = true; + } + } private void SyncQueuedTags() { @@ -156,18 +195,46 @@ namespace Ryujinx.Audio.OpenAL private ConcurrentDictionary Tracks; + private Thread AudioPollerThread; + + private bool KeepPolling; + public OpenALAudioOut() { Context = new AudioContext(); Tracks = new ConcurrentDictionary(); + + KeepPolling = true; + + AudioPollerThread = new Thread(AudioPollerWork); + + AudioPollerThread.Start(); } - public int OpenTrack(int SampleRate, int Channels, out AudioFormat Format) + private void AudioPollerWork() + { + do + { + foreach (Track Td in Tracks.Values) + { + Td.CallReleaseCallbackIfNeeded(); + } + + Thread.Yield(); + } + while (KeepPolling); + } + + public int OpenTrack( + int SampleRate, + int Channels, + ReleaseCallback Callback, + out AudioFormat Format) { Format = AudioFormat.PcmInt16; - Track Td = new Track(SampleRate, GetALFormat(Channels, Format)); + Track Td = new Track(SampleRate, GetALFormat(Channels, Format), Callback); for (int Id = 0; Id < MaxTracks; Id++) { @@ -292,5 +359,7 @@ namespace Ryujinx.Audio.OpenAL return PlaybackState.Stopped; } + + } } \ No newline at end of file diff --git a/Ryujinx.Audio/ReleaseCallback.cs b/Ryujinx.Audio/ReleaseCallback.cs new file mode 100644 index 0000000000..f534e02cdd --- /dev/null +++ b/Ryujinx.Audio/ReleaseCallback.cs @@ -0,0 +1,4 @@ +namespace Ryujinx.Audio +{ + public delegate void ReleaseCallback(); +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/AppletStateMgr.cs b/Ryujinx.Core/OsHle/AppletStateMgr.cs new file mode 100644 index 0000000000..cd168b77a8 --- /dev/null +++ b/Ryujinx.Core/OsHle/AppletStateMgr.cs @@ -0,0 +1,62 @@ +using Ryujinx.Core.OsHle.IpcServices.Am; +using Ryujinx.Core.OsHle.Handles; +using System; +using System.Collections.Concurrent; + +namespace Ryujinx.Core.OsHle +{ + class AppletStateMgr : IDisposable + { + private ConcurrentQueue Messages; + + public FocusState FocusState { get; private set; } + + public KEvent MessageEvent { get; private set; } + + public AppletStateMgr() + { + Messages = new ConcurrentQueue(); + + MessageEvent = new KEvent(); + } + + public void SetFocus(bool IsFocused) + { + FocusState = IsFocused + ? FocusState.InFocus + : FocusState.OutOfFocus; + + EnqueueMessage(MessageInfo.FocusStateChanged); + } + + public void EnqueueMessage(MessageInfo Message) + { + Messages.Enqueue(Message); + + MessageEvent.Handle.Set(); + } + + public bool TryDequeueMessage(out MessageInfo Message) + { + if (Messages.Count < 2) + { + MessageEvent.Handle.Reset(); + } + + return Messages.TryDequeue(out Message); + } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing) + { + MessageEvent.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/CondVar.cs b/Ryujinx.Core/OsHle/CondVar.cs index f5fe3d292e..f1b846d08c 100644 --- a/Ryujinx.Core/OsHle/CondVar.cs +++ b/Ryujinx.Core/OsHle/CondVar.cs @@ -13,7 +13,7 @@ namespace Ryujinx.Core.OsHle private bool OwnsCondVarValue; - private List WaitingThreads; + private List WaitingThreads; public CondVar(Process Process, long CondVarAddress, long Timeout) { @@ -21,10 +21,10 @@ namespace Ryujinx.Core.OsHle this.CondVarAddress = CondVarAddress; this.Timeout = Timeout; - WaitingThreads = new List(); + WaitingThreads = new List(); } - public bool WaitForSignal(HThread Thread) + public bool WaitForSignal(KThread Thread) { int Count = Process.Memory.ReadInt32(CondVarAddress); @@ -66,7 +66,7 @@ namespace Ryujinx.Core.OsHle return true; } - public void SetSignal(HThread Thread, int Count) + public void SetSignal(KThread Thread, int Count) { lock (WaitingThreads) { diff --git a/Ryujinx.Core/OsHle/FileDesc.cs b/Ryujinx.Core/OsHle/FileDesc.cs deleted file mode 100644 index 4be83bb07f..0000000000 --- a/Ryujinx.Core/OsHle/FileDesc.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Core.OsHle -{ - class FileDesc - { - public string Name { get; private set; } - - public FileDesc(string Name) - { - this.Name = Name; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/GlobalStateTable.cs b/Ryujinx.Core/OsHle/GlobalStateTable.cs new file mode 100644 index 0000000000..ffc9f26270 --- /dev/null +++ b/Ryujinx.Core/OsHle/GlobalStateTable.cs @@ -0,0 +1,62 @@ +using System.Collections.Concurrent; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle +{ + class GlobalStateTable + { + private ConcurrentDictionary DictByProcess; + + public GlobalStateTable() + { + DictByProcess = new ConcurrentDictionary(); + } + + public int Add(Process Process, object Obj) + { + IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary()); + + return Dict.Add(Obj); + } + + public object GetData(Process Process, int Id) + { + if (DictByProcess.TryGetValue(Process, out IdDictionary Dict)) + { + return Dict.GetData(Id); + } + + return null; + } + + public T GetData(Process Process, int Id) + { + if (DictByProcess.TryGetValue(Process, out IdDictionary Dict)) + { + return Dict.GetData(Id); + } + + return default(T); + } + + public object Delete(Process Process, int Id) + { + if (DictByProcess.TryGetValue(Process, out IdDictionary Dict)) + { + return Dict.Delete(Id); + } + + return null; + } + + public ICollection DeleteProcess(Process Process) + { + if (DictByProcess.TryRemove(Process, out IdDictionary Dict)) + { + return Dict.Clear(); + } + + return null; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/HDomain.cs b/Ryujinx.Core/OsHle/Handles/HDomain.cs deleted file mode 100644 index 26c604554f..0000000000 --- a/Ryujinx.Core/OsHle/Handles/HDomain.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; - -namespace Ryujinx.Core.OsHle.Handles -{ - class HDomain : HSession, IDisposable - { - private IdDictionary Objects; - - public HDomain(HSession Session) : base(Session) - { - Objects = new IdDictionary(); - } - - public int Add(object Obj) - { - return Objects.Add(Obj); - } - - public bool Delete(int Id) - { - return Objects.Delete(Id); - } - - public object GetObject(int Id) - { - return Objects.GetData(Id); - } - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool Disposing) - { - if (Disposing) - { - foreach (object Obj in Objects) - { - if (Obj != this && Obj is IDisposable DisposableObj) - { - DisposableObj.Dispose(); - } - } - } - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/HEvent.cs b/Ryujinx.Core/OsHle/Handles/HEvent.cs deleted file mode 100644 index 4e881ca249..0000000000 --- a/Ryujinx.Core/OsHle/Handles/HEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.Core.OsHle.Handles -{ - class HEvent - { - - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/HSession.cs b/Ryujinx.Core/OsHle/Handles/HSession.cs deleted file mode 100644 index f30e91f98d..0000000000 --- a/Ryujinx.Core/OsHle/Handles/HSession.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Ryujinx.Core.OsHle.IpcServices; - -namespace Ryujinx.Core.OsHle.Handles -{ - class HSession - { - public IIpcService Service { get; private set; } - - public bool IsInitialized { get; private set; } - - public int State { get; set; } - - public HSession(IIpcService Service) - { - this.Service = Service; - } - - public HSession(HSession Session) - { - Service = Session.Service; - IsInitialized = Session.IsInitialized; - } - - public void Initialize() - { - IsInitialized = true; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/HSessionObj.cs b/Ryujinx.Core/OsHle/Handles/HSessionObj.cs deleted file mode 100644 index ed0530f74c..0000000000 --- a/Ryujinx.Core/OsHle/Handles/HSessionObj.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; - -namespace Ryujinx.Core.OsHle.Handles -{ - class HSessionObj : HSession, IDisposable - { - public object Obj { get; private set; } - - public HSessionObj(HSession Session, object Obj) : base(Session) - { - this.Obj = Obj; - } - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool Disposing) - { - if (Disposing && Obj != null) - { - if (Obj is IDisposable DisposableObj) - { - DisposableObj.Dispose(); - } - } - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/KEvent.cs b/Ryujinx.Core/OsHle/Handles/KEvent.cs new file mode 100644 index 0000000000..96ff01f7ff --- /dev/null +++ b/Ryujinx.Core/OsHle/Handles/KEvent.cs @@ -0,0 +1,4 @@ +namespace Ryujinx.Core.OsHle.Handles +{ + class KEvent : KSynchronizationObject { } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/KProcessHandleTable.cs b/Ryujinx.Core/OsHle/Handles/KProcessHandleTable.cs index 1156e035fd..2c8098834e 100644 --- a/Ryujinx.Core/OsHle/Handles/KProcessHandleTable.cs +++ b/Ryujinx.Core/OsHle/Handles/KProcessHandleTable.cs @@ -1,8 +1,8 @@ -using System; +using System.Collections.Generic; namespace Ryujinx.Core.OsHle.Handles { - class KProcessHandleTable : IDisposable + class KProcessHandleTable { private IdDictionary Handles; @@ -21,43 +21,14 @@ namespace Ryujinx.Core.OsHle.Handles return Handles.GetData(Handle); } - public bool ReplaceData(int Id, object Data) + public object CloseHandle(int Handle) { - return Handles.ReplaceData(Id, Data); - } - - public bool CloseHandle(int Handle) - { - object Data = Handles.GetData(Handle); - - if (Data is HTransferMem TMem) - { - TMem.Memory.Manager.Reprotect( - TMem.Position, - TMem.Size, - TMem.Perm); - } - return Handles.Delete(Handle); } - public void Dispose() + public ICollection Clear() { - Dispose(true); - } - - protected virtual void Dispose(bool Disposing) - { - if (Disposing) - { - foreach (object Obj in Handles) - { - if (Obj is IDisposable DisposableObj) - { - DisposableObj.Dispose(); - } - } - } + return Handles.Clear(); } } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs index b111607811..9575429838 100644 --- a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs +++ b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs @@ -5,15 +5,15 @@ using System.Threading; namespace Ryujinx.Core.OsHle.Handles { - public class KProcessScheduler : IDisposable + class KProcessScheduler : IDisposable { private class SchedulerThread : IDisposable { - public HThread Thread { get; private set; } + public KThread Thread { get; private set; } public AutoResetEvent WaitEvent { get; private set; } - public SchedulerThread(HThread Thread) + public SchedulerThread(KThread Thread) { this.Thread = Thread; @@ -95,7 +95,7 @@ namespace Ryujinx.Core.OsHle.Handles } } - private ConcurrentDictionary AllThreads; + private ConcurrentDictionary AllThreads; private ThreadQueue[] WaitingToRun; @@ -105,7 +105,7 @@ namespace Ryujinx.Core.OsHle.Handles public KProcessScheduler() { - AllThreads = new ConcurrentDictionary(); + AllThreads = new ConcurrentDictionary(); WaitingToRun = new ThreadQueue[4]; @@ -119,7 +119,7 @@ namespace Ryujinx.Core.OsHle.Handles SchedLock = new object(); } - public void StartThread(HThread Thread) + public void StartThread(KThread Thread) { lock (SchedLock) { @@ -164,7 +164,7 @@ namespace Ryujinx.Core.OsHle.Handles } } - public void Resume(HThread CurrThread) + public void Resume(KThread CurrThread) { SchedulerThread SchedThread; @@ -183,7 +183,7 @@ namespace Ryujinx.Core.OsHle.Handles TryResumingExecution(SchedThread); } - public bool WaitForSignal(HThread Thread, int Timeout = -1) + public bool WaitForSignal(KThread Thread, int Timeout = -1) { SchedulerThread SchedThread; @@ -230,7 +230,7 @@ namespace Ryujinx.Core.OsHle.Handles private void TryResumingExecution(SchedulerThread SchedThread) { - HThread Thread = SchedThread.Thread; + KThread Thread = SchedThread.Thread; lock (SchedLock) { @@ -249,7 +249,7 @@ namespace Ryujinx.Core.OsHle.Handles Logging.Debug($"{GetDbgThreadInfo(Thread)} resuming execution..."); } - public void Yield(HThread Thread) + public void Yield(KThread Thread) { SchedulerThread SchedThread; @@ -295,11 +295,11 @@ namespace Ryujinx.Core.OsHle.Handles } } - public void Signal(params HThread[] Threads) + public void Signal(params KThread[] Threads) { lock (SchedLock) { - foreach (HThread Thread in Threads) + foreach (KThread Thread in Threads) { if (AllThreads.TryGetValue(Thread, out SchedulerThread SchedThread)) { @@ -314,7 +314,7 @@ namespace Ryujinx.Core.OsHle.Handles } } - private string GetDbgThreadInfo(HThread Thread) + private string GetDbgThreadInfo(KThread Thread) { return $"Thread {Thread.ThreadId} (core {Thread.ProcessorId}) prio {Thread.Priority}"; } diff --git a/Ryujinx.Core/OsHle/Handles/KSession.cs b/Ryujinx.Core/OsHle/Handles/KSession.cs new file mode 100644 index 0000000000..6934e52259 --- /dev/null +++ b/Ryujinx.Core/OsHle/Handles/KSession.cs @@ -0,0 +1,28 @@ +using Ryujinx.Core.OsHle.IpcServices; +using System; + +namespace Ryujinx.Core.OsHle.Handles +{ + class KSession : IDisposable + { + public IpcService Service { get; private set; } + + public KSession(IpcService Service) + { + this.Service = Service; + } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing && Service is IDisposable DisposableService) + { + DisposableService.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs b/Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs new file mode 100644 index 0000000000..015b814a42 --- /dev/null +++ b/Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs @@ -0,0 +1,28 @@ +using System; +using System.Threading; + +namespace Ryujinx.Core.OsHle.Handles +{ + class KSynchronizationObject : IDisposable + { + public ManualResetEvent Handle { get; private set; } + + public KSynchronizationObject() + { + Handle = new ManualResetEvent(false); + } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing) + { + Handle.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Handles/HThread.cs b/Ryujinx.Core/OsHle/Handles/KThread.cs similarity index 79% rename from Ryujinx.Core/OsHle/Handles/HThread.cs rename to Ryujinx.Core/OsHle/Handles/KThread.cs index c631cedc6c..aa1b27bede 100644 --- a/Ryujinx.Core/OsHle/Handles/HThread.cs +++ b/Ryujinx.Core/OsHle/Handles/KThread.cs @@ -2,7 +2,7 @@ using ChocolArm64; namespace Ryujinx.Core.OsHle.Handles { - public class HThread + class KThread : KSynchronizationObject { public AThread Thread { get; private set; } @@ -11,7 +11,7 @@ namespace Ryujinx.Core.OsHle.Handles public int ThreadId => Thread.ThreadId; - public HThread(AThread Thread, int ProcessorId, int Priority) + public KThread(AThread Thread, int ProcessorId, int Priority) { this.Thread = Thread; this.ProcessorId = ProcessorId; diff --git a/Ryujinx.Core/OsHle/Horizon.cs b/Ryujinx.Core/OsHle/Horizon.cs index c3f8cd8b00..240c08dbd9 100644 --- a/Ryujinx.Core/OsHle/Horizon.cs +++ b/Ryujinx.Core/OsHle/Horizon.cs @@ -16,8 +16,10 @@ namespace Ryujinx.Core.OsHle private ConcurrentDictionary Processes; - internal HSharedMem HidSharedMem; - internal HSharedMem FontSharedMem; + internal HSharedMem HidSharedMem { get; private set; } + internal HSharedMem FontSharedMem { get; private set; } + + internal KEvent VsyncEvent { get; private set; } private Switch Ns; @@ -32,6 +34,8 @@ namespace Ryujinx.Core.OsHle HidSharedMem = new HSharedMem(); FontSharedMem = new HSharedMem(); + + VsyncEvent = new KEvent(); } public void LoadCart(string ExeFsDir, string RomFsFile = null) @@ -91,6 +95,8 @@ namespace Ryujinx.Core.OsHle MainProcess.Run(IsNro); } + public void SignalVsync() => VsyncEvent.Handle.Set(); + private Process MakeProcess() { Process Process; @@ -109,9 +115,16 @@ namespace Ryujinx.Core.OsHle Processes.TryAdd(ProcessId, Process); } + InitializeProcess(Process); + return Process; } + private void InitializeProcess(Process Process) + { + Process.AppletState.SetFocus(true); + } + internal void ExitProcess(int ProcessId) { if (Processes.TryGetValue(ProcessId, out Process Process) && Process.NeedsHbAbi) @@ -171,6 +184,8 @@ namespace Ryujinx.Core.OsHle Process.StopAllThreadsAsync(); Process.Dispose(); } + + VsyncEvent.Dispose(); } } } diff --git a/Ryujinx.Core/OsHle/IdDictionary.cs b/Ryujinx.Core/OsHle/IdDictionary.cs index 0b90924616..0746ae81b1 100644 --- a/Ryujinx.Core/OsHle/IdDictionary.cs +++ b/Ryujinx.Core/OsHle/IdDictionary.cs @@ -1,11 +1,10 @@ using System; -using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; namespace Ryujinx.Core.OsHle { - class IdDictionary : IEnumerable + class IdDictionary { private ConcurrentDictionary Objs; @@ -39,18 +38,6 @@ namespace Ryujinx.Core.OsHle throw new InvalidOperationException(); } - public bool ReplaceData(int Id, object Data) - { - if (Objs.ContainsKey(Id)) - { - Objs[Id] = Data; - - return true; - } - - return false; - } - public object GetData(int Id) { if (Objs.TryGetValue(Id, out object Data)) @@ -71,31 +58,25 @@ namespace Ryujinx.Core.OsHle return default(T); } - public bool Delete(int Id) + public object Delete(int Id) { if (Objs.TryRemove(Id, out object Obj)) { - if (Obj is IDisposable DisposableObj) - { - DisposableObj.Dispose(); - } - FreeIdHint = Id; - return true; + return Obj; } - return false; + return null; } - IEnumerator IEnumerable.GetEnumerator() + public ICollection Clear() { - return Objs.Values.GetEnumerator(); - } + ICollection Values = Objs.Values; - IEnumerator IEnumerable.GetEnumerator() - { - return Objs.Values.GetEnumerator(); + Objs.Clear(); + + return Values; } } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Ipc/IpcDomCmd.cs b/Ryujinx.Core/OsHle/Ipc/IpcDomCmd.cs deleted file mode 100644 index 1ef0c40823..0000000000 --- a/Ryujinx.Core/OsHle/Ipc/IpcDomCmd.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.Core.OsHle.Ipc -{ - enum IpcDomCmd - { - SendMsg = 1, - DeleteObj = 2 - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Ipc/IpcHandler.cs b/Ryujinx.Core/OsHle/Ipc/IpcHandler.cs index f2179a962c..35a2535bee 100644 --- a/Ryujinx.Core/OsHle/Ipc/IpcHandler.cs +++ b/Ryujinx.Core/OsHle/Ipc/IpcHandler.cs @@ -1,6 +1,5 @@ using ChocolArm64.Memory; using Ryujinx.Core.OsHle.Handles; -using Ryujinx.Core.OsHle.IpcServices; using System; using System.IO; @@ -8,20 +7,15 @@ namespace Ryujinx.Core.OsHle.Ipc { static class IpcHandler { - private const long SfciMagic = 'S' << 0 | 'F' << 8 | 'C' << 16 | 'I' << 24; - private const long SfcoMagic = 'S' << 0 | 'F' << 8 | 'C' << 16 | 'O' << 24; - public static void IpcCall( Switch Ns, Process Process, AMemory Memory, - HSession Session, + KSession Session, IpcMessage Request, - int ThreadId, - long CmdPtr, - int HndId) + long CmdPtr) { - IpcMessage Response = new IpcMessage(Request.IsDomain && Request.Type == IpcMessageType.Request); + IpcMessage Response = new IpcMessage(); using (MemoryStream Raw = new MemoryStream(Request.RawData)) { @@ -29,94 +23,25 @@ namespace Ryujinx.Core.OsHle.Ipc if (Request.Type == IpcMessageType.Request) { - string ServiceName = Session.Service.GetType().Name; + Response.Type = IpcMessageType.Response; - ServiceProcessRequest ProcReq = null; - - bool IgnoreNullPR = false; - - string DbgServiceName = string.Empty; - - if (Session is HDomain Dom) + using (MemoryStream ResMS = new MemoryStream()) { - if (Request.DomCmd == IpcDomCmd.SendMsg) - { - long Magic = ReqReader.ReadInt64(); - int CmdId = (int)ReqReader.ReadInt64(); + BinaryWriter ResWriter = new BinaryWriter(ResMS); - object Obj = Dom.GetObject(Request.DomObjId); + ServiceCtx Context = new ServiceCtx( + Ns, + Process, + Memory, + Session, + Request, + Response, + ReqReader, + ResWriter); - if (Obj is HDomain) - { - Session.Service.Commands.TryGetValue(CmdId, out ProcReq); + Session.Service.CallMethod(Context); - DbgServiceName = $"{ProcReq?.Method.Name ?? CmdId.ToString()}"; - } - else if (Obj != null) - { - ((IIpcService)Obj).Commands.TryGetValue(CmdId, out ProcReq); - - DbgServiceName = $"{Obj.GetType().Name} {ProcReq?.Method.Name ?? CmdId.ToString()}"; - } - } - else if (Request.DomCmd == IpcDomCmd.DeleteObj) - { - Dom.Delete(Request.DomObjId); - - Response = FillResponse(Response, 0); - - IgnoreNullPR = true; - } - } - else - { - long Magic = ReqReader.ReadInt64(); - int CmdId = (int)ReqReader.ReadInt64(); - - if (Session is HSessionObj) - { - object Obj = ((HSessionObj)Session).Obj; - - ((IIpcService)Obj).Commands.TryGetValue(CmdId, out ProcReq); - - DbgServiceName = $"{Obj.GetType().Name} {ProcReq?.Method.Name ?? CmdId.ToString()}"; - } - else - { - Session.Service.Commands.TryGetValue(CmdId, out ProcReq); - - DbgServiceName = $"{ProcReq?.Method.Name ?? CmdId.ToString()}"; - } - } - - DbgServiceName = $"Tid {ThreadId} {ServiceName} {DbgServiceName}"; - - Logging.Debug($"IpcMessage: {DbgServiceName}"); - - if (ProcReq != null) - { - using (MemoryStream ResMS = new MemoryStream()) - { - BinaryWriter ResWriter = new BinaryWriter(ResMS); - - ServiceCtx Context = new ServiceCtx( - Ns, - Process, - Memory, - Session, - Request, - Response, - ReqReader, - ResWriter); - - long Result = ProcReq(Context); - - Response = FillResponse(Response, Result, ResMS.ToArray()); - } - } - else if (!IgnoreNullPR) - { - throw new NotImplementedException(DbgServiceName); + Response.RawData = ResMS.ToArray(); } } else if (Request.Type == IpcMessageType.Control) @@ -128,11 +53,7 @@ namespace Ryujinx.Core.OsHle.Ipc { case 0: { - HDomain Dom = new HDomain(Session); - - Process.HandleTable.ReplaceData(HndId, Dom); - - Request = FillResponse(Response, 0, Dom.Add(Dom)); + Request = FillResponse(Response, 0, Session.Service.ConvertToDomain()); break; } @@ -198,7 +119,7 @@ namespace Ryujinx.Core.OsHle.Ipc { BinaryWriter Writer = new BinaryWriter(MS); - Writer.Write(SfcoMagic); + Writer.Write(IpcMagic.Sfco); Writer.Write(Result); if (Data != null) diff --git a/Ryujinx.Core/OsHle/Ipc/IpcLog.cs b/Ryujinx.Core/OsHle/Ipc/IpcLog.cs index dfec7ccfd4..01915d91a4 100644 --- a/Ryujinx.Core/OsHle/Ipc/IpcLog.cs +++ b/Ryujinx.Core/OsHle/Ipc/IpcLog.cs @@ -125,8 +125,7 @@ namespace Ryujinx.Core.OsHle.Ipc Reader.ReadInt64(); //Padding - IpcMessage += Environment.NewLine + $" Domain:" + Environment.NewLine + - $" DomCmd: {Enum.GetName(typeof(IpcDomCmd), DomCmd)}" + Environment.NewLine + + IpcMessage += Environment.NewLine + $" Domain:" + Environment.NewLine + Environment.NewLine + $" DomObjId: {DomObjId.ToString()}" + Environment.NewLine; } diff --git a/Ryujinx.Core/OsHle/Ipc/IpcMagic.cs b/Ryujinx.Core/OsHle/Ipc/IpcMagic.cs new file mode 100644 index 0000000000..e3b8c74eb2 --- /dev/null +++ b/Ryujinx.Core/OsHle/Ipc/IpcMagic.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Core.OsHle.Ipc +{ + abstract class IpcMagic + { + public const long Sfci = 'S' << 0 | 'F' << 8 | 'C' << 16 | 'I' << 24; + public const long Sfco = 'S' << 0 | 'F' << 8 | 'C' << 16 | 'O' << 24; + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs index ebb3dbca04..a992424655 100644 --- a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs +++ b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs @@ -17,10 +17,6 @@ namespace Ryujinx.Core.OsHle.Ipc public List ResponseObjIds { get; private set; } - public bool IsDomain { get; private set; } - public IpcDomCmd DomCmd { get; private set; } - public int DomObjId { get; private set; } - public byte[] RawData { get; set; } public IpcMessage() @@ -34,27 +30,18 @@ namespace Ryujinx.Core.OsHle.Ipc ResponseObjIds = new List(); } - public IpcMessage(bool Domain) : this() + public IpcMessage(byte[] Data, long CmdPtr) : this() { - IsDomain = Domain; - } - - public IpcMessage(byte[] Data, long CmdPtr, bool Domain) : this() - { - Logging.Ipc(Data, CmdPtr, Domain); - using (MemoryStream MS = new MemoryStream(Data)) { BinaryReader Reader = new BinaryReader(MS); - Initialize(Reader, CmdPtr, Domain); + Initialize(Reader, CmdPtr); } } - private void Initialize(BinaryReader Reader, long CmdPtr, bool Domain) + private void Initialize(BinaryReader Reader, long CmdPtr) { - IsDomain = Domain; - int Word0 = Reader.ReadInt32(); int Word1 = Reader.ReadInt32(); @@ -110,19 +97,6 @@ namespace Ryujinx.Core.OsHle.Ipc RecvListCount = 0; } - if (Domain && Type == IpcMessageType.Request) - { - int DomWord0 = Reader.ReadInt32(); - - DomCmd = (IpcDomCmd)(DomWord0 & 0xff); - - RawDataSize = (DomWord0 >> 16) & 0xffff; - - DomObjId = Reader.ReadInt32(); - - Reader.ReadInt64(); //Padding - } - RawData = Reader.ReadBytes(RawDataSize); Reader.BaseStream.Seek(RecvListPos, SeekOrigin.Begin); @@ -165,9 +139,7 @@ namespace Ryujinx.Core.OsHle.Ipc //This is the weirdest padding I've seen so far... int Pad1 = 0x10 - Pad0; - DataLength = (DataLength + Pad0 + Pad1 + (IsDomain ? 0x10 : 0)) / 4; - - DataLength += ResponseObjIds.Count; + DataLength = (DataLength + Pad0 + Pad1) / 4; Word1 = DataLength & 0x3ff; @@ -182,23 +154,11 @@ namespace Ryujinx.Core.OsHle.Ipc MS.Seek(Pad0, SeekOrigin.Current); - if (IsDomain) - { - Writer.Write(ResponseObjIds.Count); - Writer.Write(0); - Writer.Write(0L); - } - if (RawData != null) { Writer.Write(RawData); } - foreach (int Id in ResponseObjIds) - { - Writer.Write(Id); - } - Writer.Write(new byte[Pad1]); return MS.ToArray(); diff --git a/Ryujinx.Core/OsHle/KernelErr.cs b/Ryujinx.Core/OsHle/KernelErr.cs index 19983af19d..e476f631fd 100644 --- a/Ryujinx.Core/OsHle/KernelErr.cs +++ b/Ryujinx.Core/OsHle/KernelErr.cs @@ -6,6 +6,5 @@ namespace Ryujinx.Core.OsHle public const int InvalidHandle = 114; public const int Timeout = 117; public const int InvalidInfo = 120; - public const int InvalidIpcReq = 123; } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Mutex.cs b/Ryujinx.Core/OsHle/Mutex.cs index c619e12174..7a0e8b6cf5 100644 --- a/Ryujinx.Core/OsHle/Mutex.cs +++ b/Ryujinx.Core/OsHle/Mutex.cs @@ -16,7 +16,7 @@ namespace Ryujinx.Core.OsHle private object EnterWaitLock; - private ConcurrentQueue WaitingThreads; + private ConcurrentQueue WaitingThreads; public Mutex(Process Process, long MutexAddress, int OwnerThreadHandle) { @@ -27,10 +27,10 @@ namespace Ryujinx.Core.OsHle EnterWaitLock = new object(); - WaitingThreads = new ConcurrentQueue(); + WaitingThreads = new ConcurrentQueue(); } - public void WaitForLock(HThread RequestingThread, int RequestingThreadHandle) + public void WaitForLock(KThread RequestingThread, int RequestingThreadHandle) { AcquireMutexValue(); @@ -83,11 +83,11 @@ namespace Ryujinx.Core.OsHle ReleaseMutexValue(); - HThread[] UnlockedThreads = new HThread[WaitingThreads.Count]; + KThread[] UnlockedThreads = new KThread[WaitingThreads.Count]; int Index = 0; - while (WaitingThreads.TryDequeue(out HThread Thread)) + while (WaitingThreads.TryDequeue(out KThread Thread)) { UnlockedThreads[Index++] = Thread; } diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs index 239b198039..1846e576d3 100644 --- a/Ryujinx.Core/OsHle/Process.cs +++ b/Ryujinx.Core/OsHle/Process.cs @@ -5,6 +5,7 @@ using Ryujinx.Core.Loaders; using Ryujinx.Core.Loaders.Executables; using Ryujinx.Core.OsHle.Exceptions; using Ryujinx.Core.OsHle.Handles; +using Ryujinx.Core.OsHle.IpcServices.NvServices; using Ryujinx.Core.OsHle.Svc; using System; using System.Collections.Concurrent; @@ -31,21 +32,21 @@ namespace Ryujinx.Core.OsHle public AMemory Memory { get; private set; } - public ServiceMgr Services { get; private set; } - public KProcessScheduler Scheduler { get; private set; } public KProcessHandleTable HandleTable { get; private set; } + public AppletStateMgr AppletState { get; private set; } + private SvcHandler SvcHandler; private ConcurrentDictionary TlsSlots; - private ConcurrentDictionary ThreadsByTpidr; + private ConcurrentDictionary ThreadsByTpidr; private List Executables; - private HThread MainThread; + private KThread MainThread; private long ImageBase; @@ -60,17 +61,17 @@ namespace Ryujinx.Core.OsHle Memory = new AMemory(); - Services = new ServiceMgr(); - HandleTable = new KProcessHandleTable(); - Scheduler = new KProcessScheduler(); + Scheduler = new KProcessScheduler(); + + AppletState = new AppletStateMgr(); SvcHandler = new SvcHandler(Ns, this); TlsSlots = new ConcurrentDictionary(); - ThreadsByTpidr = new ConcurrentDictionary(); + ThreadsByTpidr = new ConcurrentDictionary(); Executables = new List(); @@ -132,7 +133,7 @@ namespace Ryujinx.Core.OsHle return false; } - MainThread = HandleTable.GetData(Handle); + MainThread = HandleTable.GetData(Handle); if (NeedsHbAbi) { @@ -186,7 +187,7 @@ namespace Ryujinx.Core.OsHle AThread Thread = new AThread(GetTranslator(), Memory, EntryPoint); - HThread ThreadHnd = new HThread(Thread, ProcessorId, Priority); + KThread ThreadHnd = new KThread(Thread, ProcessorId, Priority); int Handle = HandleTable.OpenHandle(ThreadHnd); @@ -311,9 +312,9 @@ namespace Ryujinx.Core.OsHle return (int)((Position - MemoryRegions.TlsPagesAddress) / TlsSize); } - public HThread GetThread(long Tpidr) + public KThread GetThread(long Tpidr) { - if (!ThreadsByTpidr.TryGetValue(Tpidr, out HThread Thread)) + if (!ThreadsByTpidr.TryGetValue(Tpidr, out KThread Thread)) { Logging.Error($"Thread with TPIDR 0x{Tpidr:x16} not found!"); } @@ -344,11 +345,27 @@ namespace Ryujinx.Core.OsHle } Disposed = true; - - Services.Dispose(); - HandleTable.Dispose(); + + foreach (object Obj in HandleTable.Clear()) + { + if (Obj is KSession Session) + { + Session.Dispose(); + } + } + + ServiceNvDrv.Fds.DeleteProcess(this); + + ServiceNvDrv.NvMaps.DeleteProcess(this); + + ServiceNvDrv.NvMapsById.DeleteProcess(this); + Scheduler.Dispose(); + + AppletState.Dispose(); + SvcHandler.Dispose(); + Memory.Dispose(); Logging.Info($"Process {ProcessId} exiting..."); diff --git a/Ryujinx.Core/OsHle/ServiceCtx.cs b/Ryujinx.Core/OsHle/ServiceCtx.cs index 60c378d5a7..7716507fe8 100644 --- a/Ryujinx.Core/OsHle/ServiceCtx.cs +++ b/Ryujinx.Core/OsHle/ServiceCtx.cs @@ -10,7 +10,7 @@ namespace Ryujinx.Core.OsHle public Switch Ns { get; private set; } public Process Process { get; private set; } public AMemory Memory { get; private set; } - public HSession Session { get; private set; } + public KSession Session { get; private set; } public IpcMessage Request { get; private set; } public IpcMessage Response { get; private set; } public BinaryReader RequestData { get; private set; } @@ -20,7 +20,7 @@ namespace Ryujinx.Core.OsHle Switch Ns, Process Process, AMemory Memory, - HSession Session, + KSession Session, IpcMessage Request, IpcMessage Response, BinaryReader RequestData, diff --git a/Ryujinx.Core/OsHle/ServiceMgr.cs b/Ryujinx.Core/OsHle/ServiceMgr.cs deleted file mode 100644 index 39f6236859..0000000000 --- a/Ryujinx.Core/OsHle/ServiceMgr.cs +++ /dev/null @@ -1,128 +0,0 @@ -using Ryujinx.Core.OsHle.IpcServices; -using Ryujinx.Core.OsHle.IpcServices.Acc; -using Ryujinx.Core.OsHle.IpcServices.Am; -using Ryujinx.Core.OsHle.IpcServices.Apm; -using Ryujinx.Core.OsHle.IpcServices.Aud; -using Ryujinx.Core.OsHle.IpcServices.Bsd; -using Ryujinx.Core.OsHle.IpcServices.Friend; -using Ryujinx.Core.OsHle.IpcServices.FspSrv; -using Ryujinx.Core.OsHle.IpcServices.Hid; -using Ryujinx.Core.OsHle.IpcServices.Lm; -using Ryujinx.Core.OsHle.IpcServices.Nifm; -using Ryujinx.Core.OsHle.IpcServices.Ns; -using Ryujinx.Core.OsHle.IpcServices.NvServices; -using Ryujinx.Core.OsHle.IpcServices.Pctl; -using Ryujinx.Core.OsHle.IpcServices.Pl; -using Ryujinx.Core.OsHle.IpcServices.Set; -using Ryujinx.Core.OsHle.IpcServices.Sfdnsres; -using Ryujinx.Core.OsHle.IpcServices.Sm; -using Ryujinx.Core.OsHle.IpcServices.Ssl; -using Ryujinx.Core.OsHle.IpcServices.Time; -using Ryujinx.Core.OsHle.IpcServices.Vi; -using System; -using System.Collections.Generic; - -namespace Ryujinx.Core.OsHle -{ - class ServiceMgr : IDisposable - { - private Dictionary Services; - - public ServiceMgr() - { - Services = new Dictionary(); - } - - public IIpcService GetService(string Name) - { - lock (Services) - { - string LookUpName; - - //Same service with different privileges. - if (Name.EndsWith(":a") || - Name.EndsWith(":m") || - Name.EndsWith(":s") || - Name.EndsWith(":su") || - Name.EndsWith(":u") || - Name.EndsWith(":u0") || - Name.EndsWith(":u1")) - { - LookUpName = Name.Substring(0, Name.IndexOf(':')); - } - else - { - LookUpName = Name; - } - - if (!Services.TryGetValue(LookUpName, out IIpcService Service)) - { - switch (Name) - { - case "acc:u0": Service = new ServiceAcc(); break; - case "aoc:u": Service = new ServiceNs(); break; - case "apm": Service = new ServiceApm(); break; - case "apm:p": Service = new ServiceApm(); break; - case "appletOE": Service = new ServiceAppletOE(); break; - case "audout:u": Service = new ServiceAudOut(); break; - case "audren:u": Service = new ServiceAudRen(); break; - case "bsd:s": Service = new ServiceBsd(); break; - case "bsd:u": Service = new ServiceBsd(); break; - case "friend:a": Service = new ServiceFriend(); break; - case "fsp-srv": Service = new ServiceFspSrv(); break; - case "hid": Service = new ServiceHid(); break; - case "lm": Service = new ServiceLm(); break; - case "nifm:u": Service = new ServiceNifm(); break; - case "nvdrv": Service = new ServiceNvDrv(); break; - case "nvdrv:a": Service = new ServiceNvDrv(); break; - case "pctl:a": Service = new ServicePctl(); break; - case "pl:u": Service = new ServicePl(); break; - case "set": Service = new ServiceSet(); break; - case "set:sys": Service = new ServiceSetSys(); break; - case "sfdnsres": Service = new ServiceSfdnsres(); break; - case "sm:": Service = new ServiceSm(); break; - case "ssl": Service = new ServiceSsl(); break; - case "time:s": Service = new ServiceTime(); break; - case "time:u": Service = new ServiceTime(); break; - case "vi:m": Service = new ServiceVi(); break; - case "vi:s": Service = new ServiceVi(); break; - case "vi:u": Service = new ServiceVi(); break; - } - - if (Service == null) - { - throw new NotImplementedException(Name); - } - - Services.Add(LookUpName, Service); - } - - return Service; - } - } - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool Disposing) - { - if (Disposing) - { - lock (Services) - { - foreach (IIpcService Service in Services.Values) - { - if (Service is IDisposable DisposableSrv) - { - DisposableSrv.Dispose(); - } - } - - Services.Clear(); - } - } - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs b/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs index ab491eac79..9e309142c9 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Acc { - class IManagerForApplication : IIpcService + class IManagerForApplication : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IManagerForApplication() { diff --git a/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs b/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs index 77fe2b48cb..bdeadfe88b 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Acc { - class IProfile : IIpcService + class IProfile : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IProfile() { diff --git a/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs b/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs index 8844bb5d1c..8b0a99d9de 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Acc { - class ServiceAcc : IIpcService + class ServiceAcc : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceAcc() { diff --git a/Ryujinx.Core/OsHle/Services/Am/AmErr.cs b/Ryujinx.Core/OsHle/Services/Am/AmErr.cs new file mode 100644 index 0000000000..be1658742b --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Am/AmErr.cs @@ -0,0 +1,7 @@ +namespace Ryujinx.Core.OsHle.IpcServices.Am +{ + static class AmErr + { + public const int NoMessages = 3; + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Am/FocusState.cs b/Ryujinx.Core/OsHle/Services/Am/FocusState.cs new file mode 100644 index 0000000000..08dffe3b69 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Am/FocusState.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Core.OsHle.IpcServices.Am +{ + enum FocusState + { + InFocus = 1, + OutOfFocus = 2 + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs index c989cdd449..685a748235 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs @@ -2,15 +2,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.IO; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Am { - class IApplicationFunctions : IIpcService + class IApplicationFunctions : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IApplicationFunctions() { diff --git a/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs index 5417d7f045..81bb2711a9 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Am { - class IApplicationProxy : IIpcService + class IApplicationProxy : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IApplicationProxy() { diff --git a/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs b/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs index 1212f1e241..aa927d601a 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Am { - class IAudioController : IIpcService + class IAudioController : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IAudioController() { diff --git a/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs index 2999bbbae7..ec1fc7746b 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs @@ -1,13 +1,16 @@ +using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; +using static Ryujinx.Core.OsHle.ErrorCode; + namespace Ryujinx.Core.OsHle.IpcServices.Am { - class ICommonStateGetter : IIpcService + class ICommonStateGetter : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ICommonStateGetter() { @@ -17,37 +20,31 @@ namespace Ryujinx.Core.OsHle.IpcServices.Am { 1, ReceiveMessage }, { 5, GetOperationMode }, { 6, GetPerformanceMode }, - { 9, GetCurrentFocusState }, + { 9, GetCurrentFocusState } }; } - private enum FocusState - { - InFocus = 1, - OutOfFocus = 2 - } - - private enum OperationMode - { - Handheld = 0, - Docked = 1 - } - public long GetEventHandle(ServiceCtx Context) { - Context.ResponseData.Write(0L); + KEvent Event = Context.Process.AppletState.MessageEvent; + + int Handle = Context.Process.HandleTable.OpenHandle(Event); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); return 0; } public long ReceiveMessage(ServiceCtx Context) { - //Program expects 0xF at 0x17ae70 on puyo sdk, - //otherwise runs on a infinite loop until it reads said value. - //What it means is still unknown. - Context.ResponseData.Write(0xfL); + if (!Context.Process.AppletState.TryDequeueMessage(out MessageInfo Message)) + { + return MakeError(ErrorModule.Am, AmErr.NoMessages); + } - return 0; //0x680; + Context.ResponseData.Write((int)Message); + + return 0; } public long GetOperationMode(ServiceCtx Context) @@ -66,7 +63,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Am public long GetCurrentFocusState(ServiceCtx Context) { - Context.ResponseData.Write((byte)FocusState.InFocus); + Context.ResponseData.Write((byte)Context.Process.AppletState.FocusState); return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs index 944e58d81e..445b57e28a 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Am { - class IDebugFunctions : IIpcService + class IDebugFunctions : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IDebugFunctions() { diff --git a/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs b/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs index 979e842a69..599562424e 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Am { - class IDisplayController : IIpcService + class IDisplayController : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IDisplayController() { diff --git a/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs b/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs index 9f5b5e69c1..02da315619 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Am { - class ILibraryAppletCreator : IIpcService + class ILibraryAppletCreator : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ILibraryAppletCreator() { diff --git a/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs index 403e4072d3..c5865009fb 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Am { - class ISelfController : IIpcService + class ISelfController : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ISelfController() { diff --git a/Ryujinx.Core/OsHle/Services/Am/IStorage.cs b/Ryujinx.Core/OsHle/Services/Am/IStorage.cs index 375b960b1b..8f99ea7d03 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IStorage.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IStorage.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Am { - class IStorage : IIpcService + class IStorage : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public byte[] Data { get; private set; } diff --git a/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs index 6d83e6f94f..096183ed2c 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs @@ -5,11 +5,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Am { - class IStorageAccessor : IIpcService + class IStorageAccessor : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private IStorage Storage; diff --git a/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs b/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs index ddc73bced0..a830f2635a 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Am { - class IWindowController : IIpcService + class IWindowController : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IWindowController() { diff --git a/Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs b/Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs new file mode 100644 index 0000000000..4c91e54a04 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs @@ -0,0 +1,9 @@ +namespace Ryujinx.Core.OsHle.IpcServices.Am +{ + enum MessageInfo + { + FocusStateChanged = 0xf, + OperationModeChanged = 0x1e, + PerformanceModeChanged = 0x1f + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Am/OperationMode.cs b/Ryujinx.Core/OsHle/Services/Am/OperationMode.cs new file mode 100644 index 0000000000..7103742f25 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Am/OperationMode.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Core.OsHle.IpcServices.Am +{ + enum OperationMode + { + Handheld = 0, + Docked = 1 + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs b/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs index b60c93dd5e..255f74e62a 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Am { - class ServiceAppletOE : IIpcService + class ServiceAppletOE : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceAppletOE() { diff --git a/Ryujinx.Core/OsHle/Services/Apm/ISession.cs b/Ryujinx.Core/OsHle/Services/Apm/ISession.cs index 500f7596cd..dd06e2c9da 100644 --- a/Ryujinx.Core/OsHle/Services/Apm/ISession.cs +++ b/Ryujinx.Core/OsHle/Services/Apm/ISession.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Apm { - class ISession : IIpcService + class ISession : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ISession() { diff --git a/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs b/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs index d6c0400acf..d75262160c 100644 --- a/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs +++ b/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Apm { - class ServiceApm : IIpcService + class ServiceApm : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceApm() { diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs index 863c9a27f6..b8aa0a6eaf 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs @@ -5,11 +5,11 @@ using System.Text; namespace Ryujinx.Core.OsHle.IpcServices.Aud { - class IAudioDevice : IIpcService + class IAudioDevice : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IAudioDevice() { diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs index 8cd013f8b9..9549eb5710 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs @@ -7,17 +7,19 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Aud { - class IAudioOut : IIpcService, IDisposable + class IAudioOut : IpcService, IDisposable { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private IAalOutput AudioOut; + private KEvent ReleaseEvent; + private int Track; - public IAudioOut(IAalOutput AudioOut, int Track) + public IAudioOut(IAalOutput AudioOut, KEvent ReleaseEvent, int Track) { m_Commands = new Dictionary() { @@ -32,8 +34,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud { 8, GetReleasedAudioOutBufferEx } }; - this.AudioOut = AudioOut; - this.Track = Track; + this.AudioOut = AudioOut; + this.ReleaseEvent = ReleaseEvent; + this.Track = Track; } public long GetAudioOutState(ServiceCtx Context) @@ -77,7 +80,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud public long RegisterBufferEvent(ServiceCtx Context) { - int Handle = Context.Process.HandleTable.OpenHandle(new HEvent()); + int Handle = Context.Process.HandleTable.OpenHandle(ReleaseEvent); Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); @@ -143,6 +146,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud if (Disposing) { AudioOut.CloseTrack(Track); + + ReleaseEvent.Dispose(); } } } diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs index 4d29371fbd..68fe0f4cdf 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs @@ -1,14 +1,17 @@ using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; +using System; using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Aud { - class IAudioRenderer : IIpcService + class IAudioRenderer : IpcService, IDisposable { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; + + private KEvent UpdateEvent; public IAudioRenderer() { @@ -19,6 +22,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud { 6, StopAudioRenderer }, { 7, QuerySystemEvent } }; + + UpdateEvent = new KEvent(); } public long RequestUpdateAudioRenderer(ServiceCtx Context) @@ -41,6 +46,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud Context.Memory.WriteInt32(Position + Offset, 5); } + //TODO: We shouldn't be signaling this here. + UpdateEvent.Handle.Set(); + return 0; } @@ -56,11 +64,24 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud public long QuerySystemEvent(ServiceCtx Context) { - int Handle = Context.Process.HandleTable.OpenHandle(new HEvent()); + int Handle = Context.Process.HandleTable.OpenHandle(UpdateEvent); Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); return 0; } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing) + { + UpdateEvent.Dispose(); + } + } } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs index 19f23d1c7c..5064398c92 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs @@ -1,18 +1,17 @@ using ChocolArm64.Memory; using Ryujinx.Audio; +using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.Text; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Aud { - class ServiceAudOut : IIpcService + class ServiceAudOut : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceAudOut() { @@ -73,9 +72,16 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud Channels = 2; } - int Track = AudioOut.OpenTrack(SampleRate, Channels, out AudioFormat Format); + KEvent ReleaseEvent = new KEvent(); - MakeObject(Context, new IAudioOut(AudioOut, Track)); + ReleaseCallback Callback = () => + { + ReleaseEvent.Handle.Set(); + }; + + int Track = AudioOut.OpenTrack(SampleRate, Channels, Callback, out AudioFormat Format); + + MakeObject(Context, new IAudioOut(AudioOut, ReleaseEvent, Track)); Context.ResponseData.Write(SampleRate); Context.ResponseData.Write(Channels); diff --git a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs index c3a0a8b436..8c7d95257c 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Aud { - class ServiceAudRen : IIpcService + class ServiceAudRen : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceAudRen() { diff --git a/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs b/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs index 680e8405cf..825b3b2717 100644 --- a/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs +++ b/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs @@ -51,11 +51,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.Bsd public Socket Handle; } - class ServiceBsd : IIpcService + class ServiceBsd : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private List Sockets = new List(); diff --git a/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs b/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs index e3e03da855..f5497f38d4 100644 --- a/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs +++ b/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Friend { - class IFriendService : IIpcService + class IFriendService : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IFriendService() { diff --git a/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs b/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs index 674877f67f..43baf8bb23 100644 --- a/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs +++ b/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Friend { - class ServiceFriend : IIpcService + class ServiceFriend : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceFriend() { diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs index 54dbec746b..6563c6aa13 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs @@ -7,13 +7,13 @@ using System.Text; namespace Ryujinx.Core.OsHle.IpcServices.FspSrv { - class IDirectory : IIpcService, IDisposable + class IDirectory : IpcService, IDisposable { private const int DirectoryEntrySize = 0x310; private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private List DirectoryEntries; diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs index b997306122..7d01b22f81 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs @@ -6,11 +6,11 @@ using System.IO; namespace Ryujinx.Core.OsHle.IpcServices.FspSrv { - class IFile : IIpcService, IDisposable + class IFile : IpcService, IDisposable { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private Stream BaseStream; diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs index 62bcb8e8b2..d5c2766e3d 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs @@ -5,15 +5,14 @@ using System.IO; using System.Text; using static Ryujinx.Core.OsHle.ErrorCode; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; namespace Ryujinx.Core.OsHle.IpcServices.FspSrv { - class IFileSystem : IIpcService + class IFileSystem : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private HashSet OpenPaths; diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs index 297461a047..d0f40333d4 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs @@ -5,11 +5,11 @@ using System.IO; namespace Ryujinx.Core.OsHle.IpcServices.FspSrv { - class IStorage : IIpcService + class IStorage : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private Stream BaseStream; diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs b/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs index 991f40272d..c6f23005a7 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.FspSrv { - class ServiceFspSrv : IIpcService + class ServiceFspSrv : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceFspSrv() { diff --git a/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs b/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs index f6596f4296..ff8291727a 100644 --- a/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs +++ b/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Hid { - class IActiveApplicationDeviceList : IIpcService + class IActiveApplicationDeviceList : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IActiveApplicationDeviceList() { diff --git a/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs b/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs index ef437c022f..2b7e934e0c 100644 --- a/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs +++ b/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs @@ -4,11 +4,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Hid { - class IAppletResource : IIpcService + class IAppletResource : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private HSharedMem HidSharedMem; diff --git a/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs b/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs index 6735c6ad2c..f15cbcfc34 100644 --- a/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs +++ b/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs @@ -2,15 +2,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using Ryujinx.Core.Input; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Hid { - class ServiceHid : IIpcService + class ServiceHid : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceHid() { diff --git a/Ryujinx.Core/OsHle/Services/IpcService.cs b/Ryujinx.Core/OsHle/Services/IpcService.cs new file mode 100644 index 0000000000..9dca811483 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/IpcService.cs @@ -0,0 +1,151 @@ +using Ryujinx.Core.OsHle.Ipc; +using Ryujinx.Core.OsHle.Handles; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Ryujinx.Core.OsHle.IpcServices +{ + abstract class IpcService : IIpcService + { + public abstract IReadOnlyDictionary Commands { get; } + + private IdDictionary DomainObjects; + + private int SelfId; + + private bool IsDomain; + + public IpcService() + { + DomainObjects = new IdDictionary(); + + SelfId = -1; + } + + public int ConvertToDomain() + { + if (SelfId == -1) + { + SelfId = DomainObjects.Add(this); + } + + IsDomain = true; + + return SelfId; + } + + public void ConvertToSession() + { + IsDomain = false; + } + + public void CallMethod(ServiceCtx Context) + { + IIpcService Service = this; + + if (IsDomain) + { + int DomainWord0 = Context.RequestData.ReadInt32(); + int DomainObjId = Context.RequestData.ReadInt32(); + + long Padding = Context.RequestData.ReadInt64(); + + int DomainCmd = DomainWord0 & 0xff; + + if (DomainCmd == 1) + { + Service = GetObject(DomainObjId); + + Context.ResponseData.Write(0L); + Context.ResponseData.Write(0L); + } + else if (DomainCmd == 2) + { + Delete(DomainObjId); + + Context.ResponseData.Write(0L); + + return; + } + else + { + throw new NotImplementedException($"Domain command: {DomainCmd}"); + } + } + + long SfciMagic = Context.RequestData.ReadInt64(); + int CommandId = (int)Context.RequestData.ReadInt64(); + + if (Service.Commands.TryGetValue(CommandId, out ServiceProcessRequest ProcessRequest)) + { + Context.ResponseData.BaseStream.Seek(IsDomain ? 0x20 : 0x10, SeekOrigin.Begin); + + Logging.Trace($"{Service.GetType().Name}: {ProcessRequest.Method.Name}"); + + long Result = ProcessRequest(Context); + + if (IsDomain) + { + foreach (int Id in Context.Response.ResponseObjIds) + { + Context.ResponseData.Write(Id); + } + + Context.ResponseData.BaseStream.Seek(0, SeekOrigin.Begin); + + Context.ResponseData.Write(Context.Response.ResponseObjIds.Count); + } + + Context.ResponseData.BaseStream.Seek(IsDomain ? 0x10 : 0, SeekOrigin.Begin); + + Context.ResponseData.Write(IpcMagic.Sfco); + Context.ResponseData.Write(Result); + } + else + { + throw new NotImplementedException($"{Service.GetType().Name}: {CommandId}"); + } + } + + protected static void MakeObject(ServiceCtx Context, IpcService Obj) + { + IpcService Service = Context.Session.Service; + + if (Service.IsDomain) + { + Context.Response.ResponseObjIds.Add(Service.Add(Obj)); + } + else + { + KSession Session = new KSession(Obj); + + int Handle = Context.Process.HandleTable.OpenHandle(Session); + + Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); + } + } + + private int Add(IIpcService Obj) + { + return DomainObjects.Add(Obj); + } + + private bool Delete(int Id) + { + object Obj = DomainObjects.Delete(Id); + + if (Obj is IDisposable DisposableObj) + { + DisposableObj.Dispose(); + } + + return Obj != null; + } + + private IIpcService GetObject(int Id) + { + return DomainObjects.GetData(Id); + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs index 8ef9f3c6dd..c3f5b035ac 100644 --- a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs +++ b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs @@ -7,11 +7,11 @@ using System.Text; namespace Ryujinx.Core.OsHle.IpcServices.Lm { - class ILogger : IIpcService + class ILogger : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ILogger() { diff --git a/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs b/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs index ca3fe35e83..e23ff56595 100644 --- a/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs +++ b/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Lm { - class ServiceLm : IIpcService + class ServiceLm : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceLm() { @@ -21,8 +19,6 @@ namespace Ryujinx.Core.OsHle.IpcServices.Lm public long Initialize(ServiceCtx Context) { - Context.Session.Initialize(); - MakeObject(Context, new ILogger()); return 0; diff --git a/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs b/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs index c31ee36b20..abd1cc20fc 100644 --- a/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs +++ b/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Nifm { - class IGeneralService : IIpcService + class IGeneralService : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IGeneralService() { diff --git a/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs b/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs index 6110e5fbe2..1e1f13e68f 100644 --- a/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs +++ b/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs @@ -1,13 +1,17 @@ +using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; +using System; using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Nifm { - class IRequest : IIpcService + class IRequest : IpcService, IDisposable { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; + + private KEvent Event; public IRequest() { @@ -17,9 +21,10 @@ namespace Ryujinx.Core.OsHle.IpcServices.Nifm { 1, GetResult }, { 2, GetSystemEventReadableHandles } }; + + Event = new KEvent(); } - // -> i32 public long GetRequestState(ServiceCtx Context) { Context.ResponseData.Write(0); @@ -39,11 +44,25 @@ namespace Ryujinx.Core.OsHle.IpcServices.Nifm //GetSystemEventReadableHandles() -> (KObject, KObject) public long GetSystemEventReadableHandles(ServiceCtx Context) { - Context.Response.HandleDesc = IpcHandleDesc.MakeMove(0xbadcafe); + //FIXME: Is this supposed to return 2 events? + int Handle = Context.Process.HandleTable.OpenHandle(Event); - //Todo: Stub + Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); return 0; } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing) + { + Event.Dispose(); + } + } } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs b/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs index 7e183389b2..b3602e9c49 100644 --- a/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs +++ b/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Nifm { - class ServiceNifm : IIpcService + class ServiceNifm : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceNifm() { diff --git a/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs index 720baa6ec2..acdb92cf13 100644 --- a/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs +++ b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Ns { - class ServiceNs : IIpcService + class ServiceNs : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceNs() { diff --git a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs index 67ad44919a..ef223772f5 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using Ryujinx.Core.OsHle.Utilities; using Ryujinx.Graphics.Gpu; @@ -7,20 +8,22 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.NvServices { - class ServiceNvDrv : IIpcService + class ServiceNvDrv : IpcService, IDisposable { private delegate long ServiceProcessIoctl(ServiceCtx Context); private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private Dictionary<(string, int), ServiceProcessIoctl> IoctlCmds; - private IdDictionary Fds; + public static GlobalStateTable Fds { get; private set; } - private IdDictionary NvMaps; - private IdDictionary NvMapsById; + public static GlobalStateTable NvMaps { get; private set; } + public static GlobalStateTable NvMapsById { get; private set; } + + private KEvent Event; public ServiceNvDrv() { @@ -64,10 +67,15 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices { ("/dev/nvmap", 0x010e), NvMapIocGetId }, }; - Fds = new IdDictionary(); + Event = new KEvent(); + } - NvMaps = new IdDictionary(); - NvMapsById = new IdDictionary(); + static ServiceNvDrv() + { + Fds = new GlobalStateTable(); + + NvMaps = new GlobalStateTable(); + NvMapsById = new GlobalStateTable(); } public long Open(ServiceCtx Context) @@ -76,7 +84,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices string Name = AMemoryHelper.ReadAsciiString(Context.Memory, NamePtr); - int Fd = Fds.Add(new NvFd(Name)); + int Fd = Fds.Add(Context.Process, new NvFd(Name)); Context.ResponseData.Write(Fd); Context.ResponseData.Write(0); @@ -89,7 +97,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices int Fd = Context.RequestData.ReadInt32(); int Cmd = Context.RequestData.ReadInt32() & 0xffff; - NvFd FdData = Fds.GetData(Fd); + NvFd FdData = Fds.GetData(Context.Process, Fd); long Position = Context.Request.GetSendBuffPtr(); @@ -109,7 +117,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices { int Fd = Context.RequestData.ReadInt32(); - Fds.Delete(Fd); + Fds.Delete(Context.Process, Fd); Context.ResponseData.Write(0); @@ -131,7 +139,10 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices int Fd = Context.RequestData.ReadInt32(); int EventId = Context.RequestData.ReadInt32(); - Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(0xcafe); + //TODO: Use Fd/EventId, different channels have different events. + int Handle = Context.Process.HandleTable.OpenHandle(Event); + + Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); Context.ResponseData.Write(0); @@ -203,7 +214,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices return 0; } - NvMap Map = NvMaps.GetData(Handle); + NvMap Map = NvMaps.GetData(Context.Process, Handle); if (Map == null) { @@ -550,9 +561,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices NvMap Map = new NvMap() { Size = Size }; - Map.Handle = NvMaps.Add(Map); + Map.Handle = NvMaps.Add(Context.Process, Map); - Map.Id = NvMapsById.Add(Map); + Map.Id = NvMapsById.Add(Context.Process, Map); Context.Memory.WriteInt32(Position + 4, Map.Handle); @@ -567,7 +578,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices int Id = Context.Memory.ReadInt32(Position); - NvMap Map = NvMapsById.GetData(Id); + NvMap Map = NvMapsById.GetData(Context.Process, Id); if (Map == null) { @@ -594,7 +605,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices byte Kind = (byte)Reader.ReadInt64(); long Addr = Reader.ReadInt64(); - NvMap Map = NvMaps.GetData(Handle); + NvMap Map = NvMaps.GetData(Context.Process, Handle); if (Map == null) { @@ -620,7 +631,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices int Handle = Reader.ReadInt32(); int Padding = Reader.ReadInt32(); - NvMap Map = NvMaps.GetData(Handle); + NvMap Map = NvMaps.GetData(Context.Process, Handle); if (Map == null) { @@ -645,7 +656,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices int Handle = Reader.ReadInt32(); int Param = Reader.ReadInt32(); - NvMap Map = NvMaps.GetData(Handle); + NvMap Map = NvMaps.GetData(Context.Process, Handle); if (Map == null) { @@ -675,7 +686,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices int Handle = Context.Memory.ReadInt32(Position + 4); - NvMap Map = NvMaps.GetData(Handle); + NvMap Map = NvMaps.GetData(Context.Process, Handle); if (Map == null) { @@ -689,9 +700,17 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices return 0; } - public NvMap GetNvMap(int Handle) + public void Dispose() { - return NvMaps.GetData(Handle); + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing) + { + Event.Dispose(); + } } } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/ObjHelper.cs b/Ryujinx.Core/OsHle/Services/ObjHelper.cs deleted file mode 100644 index 89d986aeb0..0000000000 --- a/Ryujinx.Core/OsHle/Services/ObjHelper.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Ryujinx.Core.OsHle.Handles; -using Ryujinx.Core.OsHle.Ipc; - -namespace Ryujinx.Core.OsHle.IpcServices -{ - static class ObjHelper - { - public static void MakeObject(ServiceCtx Context, object Obj) - { - if (Context.Session is HDomain Dom) - { - Context.Response.ResponseObjIds.Add(Dom.Add(Obj)); - } - else - { - HSessionObj HndData = new HSessionObj(Context.Session, Obj); - - int VHandle = Context.Process.HandleTable.OpenHandle(HndData); - - Context.Response.HandleDesc = IpcHandleDesc.MakeMove(VHandle); - } - } - } -} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs b/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs index 4eb92d31d5..45216864d2 100644 --- a/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs +++ b/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Pctl { - class IParentalControlService : IIpcService + class IParentalControlService : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IParentalControlService() { diff --git a/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs b/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs index 2d5e22a462..b648d184c8 100644 --- a/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs +++ b/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Pctl { - class ServicePctl : IIpcService + class ServicePctl : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServicePctl() { diff --git a/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs b/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs index 9a61779934..55637eac19 100644 --- a/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs +++ b/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Pl { - class ServicePl : IIpcService + class ServicePl : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServicePl() { diff --git a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs new file mode 100644 index 0000000000..9f43cdf003 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs @@ -0,0 +1,119 @@ +using Ryujinx.Core.OsHle.IpcServices.Acc; +using Ryujinx.Core.OsHle.IpcServices.Am; +using Ryujinx.Core.OsHle.IpcServices.Apm; +using Ryujinx.Core.OsHle.IpcServices.Aud; +using Ryujinx.Core.OsHle.IpcServices.Bsd; +using Ryujinx.Core.OsHle.IpcServices.Friend; +using Ryujinx.Core.OsHle.IpcServices.FspSrv; +using Ryujinx.Core.OsHle.IpcServices.Hid; +using Ryujinx.Core.OsHle.IpcServices.Lm; +using Ryujinx.Core.OsHle.IpcServices.Nifm; +using Ryujinx.Core.OsHle.IpcServices.Ns; +using Ryujinx.Core.OsHle.IpcServices.NvServices; +using Ryujinx.Core.OsHle.IpcServices.Pctl; +using Ryujinx.Core.OsHle.IpcServices.Pl; +using Ryujinx.Core.OsHle.IpcServices.Set; +using Ryujinx.Core.OsHle.IpcServices.Sfdnsres; +using Ryujinx.Core.OsHle.IpcServices.Sm; +using Ryujinx.Core.OsHle.IpcServices.Ssl; +using Ryujinx.Core.OsHle.IpcServices.Time; +using Ryujinx.Core.OsHle.IpcServices.Vi; +using System; + +namespace Ryujinx.Core.OsHle.IpcServices +{ + static class ServiceFactory + { + public static IpcService MakeService(string Name) + { + switch (Name) + { + case "acc:u0": + return new ServiceAcc(); + + case "aoc:u": + return new ServiceNs(); + + case "apm": + return new ServiceApm(); + + case "apm:p": + return new ServiceApm(); + + case "appletOE": + return new ServiceAppletOE(); + + case "audout:u": + return new ServiceAudOut(); + + case "audren:u": + return new ServiceAudRen(); + + case "bsd:s": + return new ServiceBsd(); + + case "bsd:u": + return new ServiceBsd(); + + case "friend:a": + return new ServiceFriend(); + + case "fsp-srv": + return new ServiceFspSrv(); + + case "hid": + return new ServiceHid(); + + case "lm": + return new ServiceLm(); + + case "nifm:u": + return new ServiceNifm(); + + case "nvdrv": + return new ServiceNvDrv(); + + case "nvdrv:a": + return new ServiceNvDrv(); + + case "pctl:a": + return new ServicePctl(); + + case "pl:u": + return new ServicePl(); + + case "set": + return new ServiceSet(); + + case "set:sys": + return new ServiceSetSys(); + + case "sfdnsres": + return new ServiceSfdnsres(); + + case "sm:": + return new ServiceSm(); + + case "ssl": + return new ServiceSsl(); + + case "time:s": + return new ServiceTime(); + + case "time:u": + return new ServiceTime(); + + case "vi:m": + return new ServiceVi(); + + case "vi:s": + return new ServiceVi(); + + case "vi:u": + return new ServiceVi(); + } + + throw new NotImplementedException(Name); + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs b/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs index c60e1712aa..558243578a 100644 --- a/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs +++ b/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs @@ -5,11 +5,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Set { - class ServiceSet : IIpcService + class ServiceSet : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceSet() { diff --git a/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs b/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs index dee6573d35..1d6afc4fc5 100644 --- a/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs +++ b/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Set { - class ServiceSetSys : IIpcService + class ServiceSetSys : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceSetSys() { diff --git a/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs b/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs index f110ae736f..1f68558ed6 100644 --- a/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs +++ b/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Sfdnsres { - class ServiceSfdnsres : IIpcService + class ServiceSfdnsres : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceSfdnsres() { diff --git a/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs b/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs index cb745e3738..770227d52d 100644 --- a/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs +++ b/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs @@ -4,11 +4,13 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Sm { - class ServiceSm : IIpcService + class ServiceSm : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; + + private bool IsInitialized; public ServiceSm() { @@ -23,7 +25,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Sm public long Initialize(ServiceCtx Context) { - Context.Session.Initialize(); + IsInitialized = true; return 0; } @@ -31,7 +33,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Sm public long GetService(ServiceCtx Context) { //Only for kernel version > 3.0.0. - if (!Context.Session.IsInitialized) + if (!IsInitialized) { //return SmNotInitialized; } @@ -55,7 +57,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Sm return 0; } - HSession Session = new HSession(Context.Process.Services.GetService(Name)); + KSession Session = new KSession(ServiceFactory.MakeService(Name)); int Handle = Context.Process.HandleTable.OpenHandle(Session); diff --git a/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs b/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs index 23934b1405..b9513a864a 100644 --- a/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs +++ b/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Ssl { - class ServiceSsl : IIpcService + class ServiceSsl : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceSsl() { diff --git a/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs b/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs index d20e4378ad..91d78664af 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Time { - class ISteadyClock : IIpcService + class ISteadyClock : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ISteadyClock() { diff --git a/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs b/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs index 4d4493dad4..f7f710c8e2 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs @@ -4,11 +4,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Time { - class ISystemClock : IIpcService + class ISystemClock : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); diff --git a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs index d220824c56..63329ada79 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs @@ -4,11 +4,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Time { - class ITimeZoneService : IIpcService + class ITimeZoneService : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local); diff --git a/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs b/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs index 43f28bb80b..1f94793985 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Time { - class ServiceTime : IIpcService + class ServiceTime : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceTime() { diff --git a/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs index 0ff1f90993..62db23b408 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs @@ -1,19 +1,17 @@ using ChocolArm64.Memory; -using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.IO; using static Ryujinx.Core.OsHle.IpcServices.Android.Parcel; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; namespace Ryujinx.Core.OsHle.IpcServices.Vi { - class IApplicationDisplayService : IIpcService + class IApplicationDisplayService : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; private IdDictionary Displays; @@ -145,7 +143,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi { string Name = GetDisplayName(Context); - int Handle = Context.Process.HandleTable.OpenHandle(new HEvent()); + int Handle = Context.Process.HandleTable.OpenHandle(Context.Ns.Os.VsyncEvent); Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle); diff --git a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs index beccbe7d3f..4c34200609 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using Ryujinx.Core.OsHle.IpcServices.Android; using Ryujinx.Graphics.Gal; @@ -7,11 +8,13 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Vi { - class IHOSBinderDriver : IIpcService, IDisposable + class IHOSBinderDriver : IpcService, IDisposable { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; + + private KEvent ReleaseEvent; private NvFlinger Flinger; @@ -24,7 +27,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi { 2, GetNativeHandle } }; - Flinger = new NvFlinger(Renderer); + ReleaseEvent = new KEvent(); + + Flinger = new NvFlinger(Renderer, ReleaseEvent); } public long TransactParcel(ServiceCtx Context) @@ -56,7 +61,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi int Id = Context.RequestData.ReadInt32(); uint Unk = Context.RequestData.ReadUInt32(); - Context.Response.HandleDesc = IpcHandleDesc.MakeMove(0xbadcafe); + int Handle = Context.Process.HandleTable.OpenHandle(ReleaseEvent); + + Context.Response.HandleDesc = IpcHandleDesc.MakeMove(Handle); return 0; } @@ -70,6 +77,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Vi { if (Disposing) { + ReleaseEvent.Dispose(); + Flinger.Dispose(); } } diff --git a/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs index 69dbff47a9..6c7f36ff1d 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Vi { - class IManagerDisplayService : IIpcService + class IManagerDisplayService : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public IManagerDisplayService() { diff --git a/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs index d87fcbf6ec..814ed7d1b8 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; namespace Ryujinx.Core.OsHle.IpcServices.Vi { - class ISystemDisplayService : IIpcService + class ISystemDisplayService : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ISystemDisplayService() { diff --git a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs index 5309dcabb7..3a7a2ee62d 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs @@ -1,4 +1,5 @@ using ChocolArm64.Memory; +using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.IpcServices.NvServices; using Ryujinx.Graphics.Gal; using System; @@ -17,6 +18,10 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android private Dictionary<(string, int), ServiceProcessParcel> Commands; + private KEvent ReleaseEvent; + + private IGalRenderer Renderer; + private const int BufferQueueCount = 0x40; private const int BufferQueueMask = BufferQueueCount - 1; @@ -55,8 +60,6 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android public GbpBuffer Data; } - private IGalRenderer Renderer; - private BufferEntry[] BufferQueue; private ManualResetEvent WaitBufferFree; @@ -69,7 +72,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android private bool KeepRunning; - public NvFlinger(IGalRenderer Renderer) + public NvFlinger(IGalRenderer Renderer, KEvent ReleaseEvent) { Commands = new Dictionary<(string, int), ServiceProcessParcel>() { @@ -83,8 +86,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android { ("android.gui.IGraphicBufferProducer", 0xb), GbpDisconnect }, { ("android.gui.IGraphicBufferProducer", 0xe), GbpPreallocBuffer } }; - - this.Renderer = Renderer; + + this.Renderer = Renderer; + this.ReleaseEvent = ReleaseEvent; BufferQueue = new BufferEntry[0x40]; @@ -293,6 +297,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android BufferQueue[Slot].State = BufferState.Free; + ReleaseEvent.Handle.Set(); + WaitBufferFree.Set(); return; @@ -377,6 +383,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android Interlocked.Decrement(ref RenderQueueCount); + ReleaseEvent.Handle.Set(); + lock (WaitBufferFree) { WaitBufferFree.Set(); @@ -397,9 +405,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android NvMapHandle = BitConverter.ToInt32(RawValue, 0); } - ServiceNvDrv NvDrv = (ServiceNvDrv)Context.Process.Services.GetService("nvdrv"); - - return NvDrv.GetNvMap(NvMapHandle); + return ServiceNvDrv.NvMaps.GetData(Context.Process, NvMapHandle); } private int GetFreeSlotBlocking(int Width, int Height) diff --git a/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs b/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs index 2c3dd2a3c8..360cb6fafe 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs @@ -1,15 +1,13 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using static Ryujinx.Core.OsHle.IpcServices.ObjHelper; - namespace Ryujinx.Core.OsHle.IpcServices.Vi { - class ServiceVi : IIpcService + class ServiceVi : IpcService { private Dictionary m_Commands; - public IReadOnlyDictionary Commands => m_Commands; + public override IReadOnlyDictionary Commands => m_Commands; public ServiceVi() { diff --git a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs index 9417473cf5..96bef5e474 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs @@ -3,6 +3,7 @@ using ChocolArm64.State; using Ryujinx.Core.OsHle.Exceptions; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; +using Ryujinx.Core.OsHle.IpcServices; using System; using System.Threading; @@ -34,7 +35,28 @@ namespace Ryujinx.Core.OsHle.Svc { int Handle = (int)ThreadState.X0; - Process.HandleTable.CloseHandle(Handle); + object Obj = Process.HandleTable.CloseHandle(Handle); + + if (Obj == null) + { + Logging.Warn($"Tried to CloseHandle on invalid handle 0x{Handle:x8}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); + + return; + } + + if (Obj is KSession Session) + { + Session.Dispose(); + } + else if (Obj is HTransferMem TMem) + { + TMem.Memory.Manager.Reprotect( + TMem.Position, + TMem.Size, + TMem.Perm); + } ThreadState.X0 = 0; } @@ -43,25 +65,78 @@ namespace Ryujinx.Core.OsHle.Svc { int Handle = (int)ThreadState.X0; - //TODO: Implement events. + KEvent Event = Process.HandleTable.GetData(Handle); - ThreadState.X0 = 0; + if (Event != null) + { + Event.Handle.Reset(); + + ThreadState.X0 = 0; + } + else + { + Logging.Warn($"Tried to ResetSignal on invalid event handle 0x{Handle:x8}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); + } } private void SvcWaitSynchronization(AThreadState ThreadState) { - long HandlesPtr = (long)ThreadState.X0; + long HandlesPtr = (long)ThreadState.X1; int HandlesCount = (int)ThreadState.X2; long Timeout = (long)ThreadState.X3; - //TODO: Implement events. + KThread CurrThread = Process.GetThread(ThreadState.Tpidr); - HThread CurrThread = Process.GetThread(ThreadState.Tpidr); + WaitHandle[] Handles = new WaitHandle[HandlesCount]; + + for (int Index = 0; Index < HandlesCount; Index++) + { + int Handle = Memory.ReadInt32(HandlesPtr + Index * 4); + + KSynchronizationObject SyncObj = Process.HandleTable.GetData(Handle); + + if (SyncObj == null) + { + Logging.Warn($"Tried to WaitSynchronization on invalid handle 0x{Handle:x8}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); + + return; + } + + Handles[Index] = SyncObj.Handle; + } Process.Scheduler.Suspend(CurrThread.ProcessorId); + + int HandleIndex; + + ulong Result = 0; + + if (Timeout != -1) + { + HandleIndex = WaitHandle.WaitAny(Handles, (int)(Timeout / 1000000)); + + if (HandleIndex == WaitHandle.WaitTimeout) + { + Result = MakeError(ErrorModule.Kernel, KernelErr.Timeout); + } + } + else + { + HandleIndex = WaitHandle.WaitAny(Handles); + } + Process.Scheduler.Resume(CurrThread); - ThreadState.X0 = 0; + ThreadState.X0 = Result; + + if (Result == 0) + { + ThreadState.X1 = (ulong)HandleIndex; + } } private void SvcGetSystemTick(AThreadState ThreadState) @@ -78,8 +153,7 @@ namespace Ryujinx.Core.OsHle.Svc //TODO: Validate that app has perms to access the service, and that the service //actually exists, return error codes otherwise. - - HSession Session = new HSession(Process.Services.GetService(Name)); + KSession Session = new KSession(ServiceFactory.MakeService(Name)); ulong Handle = (ulong)Process.HandleTable.OpenHandle(Session); @@ -89,65 +163,46 @@ namespace Ryujinx.Core.OsHle.Svc private void SvcSendSyncRequest(AThreadState ThreadState) { - SendSyncRequest(ThreadState, false); + SendSyncRequest(ThreadState, ThreadState.Tpidr, 0x100, (int)ThreadState.X0); } private void SvcSendSyncRequestWithUserBuffer(AThreadState ThreadState) { - SendSyncRequest(ThreadState, true); + SendSyncRequest( + ThreadState, + (long)ThreadState.X0, + (long)ThreadState.X1, + (int)ThreadState.X2); } - private void SendSyncRequest(AThreadState ThreadState, bool UserBuffer) + private void SendSyncRequest(AThreadState ThreadState, long CmdPtr, long Size, int Handle) { - long CmdPtr = ThreadState.Tpidr; - long Size = 0x100; - int Handle = 0; - - if (UserBuffer) - { - CmdPtr = (long)ThreadState.X0; - Size = (long)ThreadState.X1; - Handle = (int)ThreadState.X2; - } - else - { - Handle = (int)ThreadState.X0; - } - - HThread CurrThread = Process.GetThread(ThreadState.Tpidr); - - Process.Scheduler.Suspend(CurrThread.ProcessorId); + KThread CurrThread = Process.GetThread(ThreadState.Tpidr); byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, Size); - HSession Session = Process.HandleTable.GetData(Handle); - - IpcMessage Cmd = new IpcMessage(CmdData, CmdPtr, Session is HDomain); + KSession Session = Process.HandleTable.GetData(Handle); if (Session != null) { - IpcHandler.IpcCall( - Ns, - Process, - Memory, - Session, - Cmd, - ThreadState.ThreadId, - CmdPtr, - Handle); + Process.Scheduler.Suspend(CurrThread.ProcessorId); - byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, Size); + IpcMessage Cmd = new IpcMessage(CmdData, CmdPtr); + + IpcHandler.IpcCall(Ns, Process, Memory, Session, Cmd, CmdPtr); + + Thread.Yield(); + + Process.Scheduler.Resume(CurrThread); ThreadState.X0 = 0; } else { - ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidIpcReq); + Logging.Warn($"Tried to SendSyncRequest on invalid session handle 0x{Handle:x8}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle); } - - Thread.Yield(); - - Process.Scheduler.Resume(CurrThread); } private void SvcBreak(AThreadState ThreadState) diff --git a/Ryujinx.Core/OsHle/Svc/SvcThread.cs b/Ryujinx.Core/OsHle/Svc/SvcThread.cs index 231ee2a237..77cef44cc7 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcThread.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcThread.cs @@ -39,7 +39,7 @@ namespace Ryujinx.Core.OsHle.Svc { int Handle = (int)ThreadState.X0; - HThread Thread = Process.HandleTable.GetData(Handle); + KThread Thread = Process.HandleTable.GetData(Handle); if (Thread != null) { @@ -53,16 +53,18 @@ namespace Ryujinx.Core.OsHle.Svc private void SvcExitThread(AThreadState ThreadState) { - HThread CurrThread = Process.GetThread(ThreadState.Tpidr); - + KThread CurrThread = Process.GetThread(ThreadState.Tpidr); + CurrThread.Thread.StopExecution(); + + CurrThread.Handle.Set(); } private void SvcSleepThread(AThreadState ThreadState) { ulong NanoSecs = ThreadState.X0; - HThread CurrThread = Process.GetThread(ThreadState.Tpidr); + KThread CurrThread = Process.GetThread(ThreadState.Tpidr); if (NanoSecs == 0) { @@ -78,7 +80,7 @@ namespace Ryujinx.Core.OsHle.Svc { int Handle = (int)ThreadState.X1; - HThread Thread = Process.HandleTable.GetData(Handle); + KThread Thread = Process.HandleTable.GetData(Handle); if (Thread != null) { @@ -91,10 +93,10 @@ namespace Ryujinx.Core.OsHle.Svc private void SvcSetThreadPriority(AThreadState ThreadState) { + int Prio = (int)ThreadState.X0; int Handle = (int)ThreadState.X1; - int Prio = (int)ThreadState.X0; - HThread Thread = Process.HandleTable.GetData(Handle); + KThread Thread = Process.HandleTable.GetData(Handle); if (Thread != null) { @@ -117,7 +119,7 @@ namespace Ryujinx.Core.OsHle.Svc { int Handle = (int)ThreadState.X0; - HThread Thread = Process.HandleTable.GetData(Handle); + KThread Thread = Process.HandleTable.GetData(Handle); if (Thread != null) { diff --git a/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs b/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs index 38356073e6..318688b853 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs @@ -13,7 +13,7 @@ namespace Ryujinx.Core.OsHle.Svc long MutexAddress = (long)ThreadState.X1; int RequestingThreadHandle = (int)ThreadState.X2; - HThread RequestingThread = Process.HandleTable.GetData(RequestingThreadHandle); + KThread RequestingThread = Process.HandleTable.GetData(RequestingThreadHandle); Mutex M = new Mutex(Process, MutexAddress, OwnerThreadHandle); @@ -43,7 +43,7 @@ namespace Ryujinx.Core.OsHle.Svc int ThreadHandle = (int)ThreadState.X2; long Timeout = (long)ThreadState.X3; - HThread Thread = Process.HandleTable.GetData(ThreadHandle); + KThread Thread = Process.HandleTable.GetData(ThreadHandle); Mutex M = new Mutex(Process, MutexAddress, ThreadHandle); @@ -72,7 +72,7 @@ namespace Ryujinx.Core.OsHle.Svc long CondVarAddress = (long)ThreadState.X0; int Count = (int)ThreadState.X1; - HThread CurrThread = Process.GetThread(ThreadState.Tpidr); + KThread CurrThread = Process.GetThread(ThreadState.Tpidr); if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv)) { diff --git a/Ryujinx.Core/Switch.cs b/Ryujinx.Core/Switch.cs index 92d78f4536..0df8b12602 100644 --- a/Ryujinx.Core/Switch.cs +++ b/Ryujinx.Core/Switch.cs @@ -14,10 +14,10 @@ namespace Ryujinx.Core internal NsGpu Gpu { get; private set; } - internal Horizon Os { get; private set; } - internal VirtualFileSystem VFs { get; private set; } + public Horizon Os { get; private set; } + public SystemSettings Settings { get; private set; } public PerformanceStatistics Statistics { get; private set; } @@ -40,12 +40,12 @@ namespace Ryujinx.Core this.AudioOut = AudioOut; - Gpu = new NsGpu(Renderer); - - Os = new Horizon(this); + Gpu = new NsGpu(Renderer); VFs = new VirtualFileSystem(); + Os = new Horizon(this); + Settings = new SystemSettings(); Statistics = new PerformanceStatistics(); diff --git a/Ryujinx.Graphics/Gpu/NsGpuPGraph.cs b/Ryujinx.Graphics/Gpu/NsGpuPGraph.cs index 6543b1d1d8..652f3e7517 100644 --- a/Ryujinx.Graphics/Gpu/NsGpuPGraph.cs +++ b/Ryujinx.Graphics/Gpu/NsGpuPGraph.cs @@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gpu { private NsGpu Gpu; - private int[] Registers; + private uint[] Registers; public NsGpuEngine[] SubChannels; @@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Gpu { this.Gpu = Gpu; - Registers = new int[0x1000]; + Registers = new uint[0x1000]; SubChannels = new NsGpuEngine[8]; @@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Gpu { if (Entry.Arguments.Count == 1) { - SetRegister(Entry.Register, Entry.Arguments[0]); + SetRegister(Entry.Register, (uint)Entry.Arguments[0]); } switch (Entry.Register) @@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Gpu case NsGpuRegister._3dVertexArray0Fetch: SendVertexBuffers(Memory); break; - + case NsGpuRegister._3dCbData0: if (GetRegister(NsGpuRegister._3dCbPos) == 0x20) { @@ -62,6 +62,22 @@ namespace Ryujinx.Graphics.Gpu case NsGpuRegister._3dQueryGet: HasQuery = true; break; + + case NsGpuRegister._3dSetShader: + uint ShaderPrg = (uint)Entry.Arguments[0]; + uint ShaderId = (uint)Entry.Arguments[1]; + uint CodeAddr = (uint)Entry.Arguments[2]; + uint ShaderType = (uint)Entry.Arguments[3]; + uint CodeEnd = (uint)Entry.Arguments[4]; + + SendShader( + Memory, + ShaderPrg, + ShaderId, + CodeAddr, + ShaderType, + CodeEnd); + break; } } @@ -71,10 +87,10 @@ namespace Ryujinx.Graphics.Gpu (long)GetRegister(NsGpuRegister._3dQueryAddressHigh) << 32 | (long)GetRegister(NsGpuRegister._3dQueryAddressLow) << 0; - int Seq = GetRegister(NsGpuRegister._3dQuerySequence); - int Get = GetRegister(NsGpuRegister._3dQueryGet); + uint Seq = GetRegister(NsGpuRegister._3dQuerySequence); + uint Get = GetRegister(NsGpuRegister._3dQueryGet); - int Mode = Get & 3; + uint Mode = Get & 3; if (Mode == 0) { @@ -85,7 +101,7 @@ namespace Ryujinx.Graphics.Gpu { Gpu.Renderer.QueueAction(delegate() { - Memory.WriteInt32(Position, Seq); + Memory.WriteUInt32(Position, Seq); }); } } @@ -119,13 +135,13 @@ namespace Ryujinx.Graphics.Gpu { byte[] Buffer = AMemoryHelper.ReadBytes(Memory, Position, Size); - int Stride = GetRegister(NsGpuRegister._3dVertexArray0Fetch) & 0xfff; + int Stride = (int)GetRegister(NsGpuRegister._3dVertexArray0Fetch) & 0xfff; List Attribs = new List(); for (int Attr = 0; Attr < 16; Attr++) { - int Packed = GetRegister(NsGpuRegister._3dVertexAttrib0Format + Attr * 4); + int Packed = (int)GetRegister(NsGpuRegister._3dVertexAttrib0Format + Attr * 4); GalVertexAttrib Attrib = new GalVertexAttrib(Attr, (Packed >> 0) & 0x1f, @@ -154,10 +170,10 @@ namespace Ryujinx.Graphics.Gpu long TicPos = (long)GetRegister(NsGpuRegister._3dTicAddressHigh) << 32 | (long)GetRegister(NsGpuRegister._3dTicAddressLow) << 0; - int CbData = GetRegister(NsGpuRegister._3dCbData0); + uint CbData = GetRegister(NsGpuRegister._3dCbData0); - int TicIndex = (CbData >> 0) & 0xfffff; - int TscIndex = (CbData >> 20) & 0xfff; //I guess? + uint TicIndex = (CbData >> 0) & 0xfffff; + uint TscIndex = (CbData >> 20) & 0xfff; //I guess? TicPos = Gpu.MemoryMgr.GetCpuAddr(TicPos + TicIndex * 0x20); @@ -198,6 +214,19 @@ namespace Ryujinx.Graphics.Gpu } } + private void SendShader( + AMemory Memory, + uint ShaderPrg, + uint ShaderId, + uint CodeAddr, + uint ShaderType, + uint CodeEnd) + { + long CodePos = Gpu.MemoryMgr.GetCpuAddr(CodeAddr); + + byte[] Data = AMemoryHelper.ReadBytes(Memory, CodePos, 0x300); + } + private static byte[] GetDecodedTexture( AMemory Memory, NsGpuTextureFormat Format, @@ -263,12 +292,12 @@ namespace Ryujinx.Graphics.Gpu return Data; } - public int GetRegister(NsGpuRegister Register) + public uint GetRegister(NsGpuRegister Register) { return Registers[((int)Register >> 2) & 0xfff]; } - public void SetRegister(NsGpuRegister Register, int Value) + public void SetRegister(NsGpuRegister Register, uint Value) { Registers[((int)Register >> 2) & 0xfff] = Value; } diff --git a/Ryujinx.Graphics/Gpu/NsGpuRegister.cs b/Ryujinx.Graphics/Gpu/NsGpuRegister.cs index 319e2c01f6..4642e68d67 100644 --- a/Ryujinx.Graphics/Gpu/NsGpuRegister.cs +++ b/Ryujinx.Graphics/Gpu/NsGpuRegister.cs @@ -89,5 +89,6 @@ namespace Ryujinx.Graphics.Gpu _3dCbData13 = 0x23c4, _3dCbData14 = 0x23c8, _3dCbData15 = 0x23cc, + _3dSetShader = 0x3890 } } \ No newline at end of file diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs index b0dca81b77..3bcef92183 100644 --- a/Ryujinx/Ui/GLScreen.cs +++ b/Ryujinx/Ui/GLScreen.cs @@ -181,6 +181,8 @@ namespace Ryujinx SwapBuffers(); Ns.Statistics.EndSystemFrame(); + + Ns.Os.SignalVsync(); } protected override void OnResize(EventArgs e) From 1bd99e559785ecf6a40e1bcb4a717642014c078f Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 20 Mar 2018 12:18:25 -0300 Subject: [PATCH 7/9] Support different framebuffer offsets (fixes #59) --- Ryujinx.Core/OsHle/GlobalStateTable.cs | 11 ++++- Ryujinx.Core/OsHle/IdDictionary.cs | 5 +++ Ryujinx.Core/OsHle/Process.cs | 4 +- Ryujinx.Core/OsHle/Services/Nv/NvMap.cs | 2 +- Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs | 40 +++++++++++++++++++ .../OsHle/Services/Nv/ServiceNvDrv.cs | 17 +++++--- Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs | 17 ++++++-- 7 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs diff --git a/Ryujinx.Core/OsHle/GlobalStateTable.cs b/Ryujinx.Core/OsHle/GlobalStateTable.cs index ffc9f26270..2a5714ad09 100644 --- a/Ryujinx.Core/OsHle/GlobalStateTable.cs +++ b/Ryujinx.Core/OsHle/GlobalStateTable.cs @@ -12,11 +12,18 @@ namespace Ryujinx.Core.OsHle DictByProcess = new ConcurrentDictionary(); } - public int Add(Process Process, object Obj) + public bool Add(Process Process, int Id, object Data) { IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary()); - return Dict.Add(Obj); + return Dict.Add(Id, Data); + } + + public int Add(Process Process, object Data) + { + IdDictionary Dict = DictByProcess.GetOrAdd(Process, (Key) => new IdDictionary()); + + return Dict.Add(Data); } public object GetData(Process Process, int Id) diff --git a/Ryujinx.Core/OsHle/IdDictionary.cs b/Ryujinx.Core/OsHle/IdDictionary.cs index 0746ae81b1..2a498e7f67 100644 --- a/Ryujinx.Core/OsHle/IdDictionary.cs +++ b/Ryujinx.Core/OsHle/IdDictionary.cs @@ -15,6 +15,11 @@ namespace Ryujinx.Core.OsHle Objs = new ConcurrentDictionary(); } + public bool Add(int Id, object Data) + { + return Objs.TryAdd(Id, Data); + } + public int Add(object Data) { if (Objs.TryAdd(FreeIdHint, Data)) diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs index 1846e576d3..25c10a4353 100644 --- a/Ryujinx.Core/OsHle/Process.cs +++ b/Ryujinx.Core/OsHle/Process.cs @@ -356,9 +356,9 @@ namespace Ryujinx.Core.OsHle ServiceNvDrv.Fds.DeleteProcess(this); - ServiceNvDrv.NvMaps.DeleteProcess(this); - + ServiceNvDrv.NvMaps .DeleteProcess(this); ServiceNvDrv.NvMapsById.DeleteProcess(this); + ServiceNvDrv.NvMapsFb .DeleteProcess(this); Scheduler.Dispose(); diff --git a/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs b/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs index ca844f9f28..d5a5a80082 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs @@ -7,6 +7,6 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices public int Size; public int Align; public int Kind; - public long Address; + public long CpuAddress; } } \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs b/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs new file mode 100644 index 0000000000..1066cc9530 --- /dev/null +++ b/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; + +namespace Ryujinx.Core.OsHle.IpcServices.NvServices +{ + class NvMapFb + { + private List BufferOffs; + + public NvMapFb() + { + BufferOffs = new List(); + } + + public void AddBufferOffset(long Offset) + { + BufferOffs.Add(Offset); + } + + public bool HasBufferOffset(int Index) + { + if ((uint)Index >= BufferOffs.Count) + { + return false; + } + + return true; + } + + public long GetBufferOffset(int Index) + { + if ((uint)Index >= BufferOffs.Count) + { + throw new ArgumentOutOfRangeException(nameof(Index)); + } + + return BufferOffs[Index]; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs index ef223772f5..a1e0e5321a 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs @@ -22,6 +22,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices public static GlobalStateTable NvMaps { get; private set; } public static GlobalStateTable NvMapsById { get; private set; } + public static GlobalStateTable NvMapsFb { get; private set; } private KEvent Event; @@ -76,6 +77,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices NvMaps = new GlobalStateTable(); NvMapsById = new GlobalStateTable(); + NvMapsFb = new GlobalStateTable(); } public long Open(ServiceCtx Context) @@ -131,6 +133,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices Context.ResponseData.Write(0); + NvMapsFb.Add(Context.Process, 0, new NvMapFb()); + return 0; } @@ -209,8 +213,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices if (Handle == 0) { - //Handle 0 is valid here, but it refers to something else. - //TODO: Figure out what, for now just return success. + //This is used to store offsets for the Framebuffer(s); + NvMapFb MapFb = (NvMapFb)NvMapsFb.GetData(Context.Process, 0); + + MapFb.AddBufferOffset(BuffAddr); + return 0; } @@ -225,11 +232,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices if ((Flags & 1) != 0) { - Offset = Context.Ns.Gpu.MapMemory(Map.Address, Offset, Map.Size); + Offset = Context.Ns.Gpu.MapMemory(Map.CpuAddress, Offset, Map.Size); } else { - Offset = Context.Ns.Gpu.MapMemory(Map.Address, Map.Size); + Offset = Context.Ns.Gpu.MapMemory(Map.CpuAddress, Map.Size); } Context.Memory.WriteInt64(Position + 0x20, Offset); @@ -614,7 +621,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices return -1; //TODO: Corrent error code. } - Map.Address = Addr; + Map.CpuAddress = Addr; Map.Align = Align; Map.Kind = Kind; diff --git a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs index 3a7a2ee62d..550260bb8e 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs @@ -289,11 +289,20 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android long FbSize = (uint)FbWidth * FbHeight * 4; - NvMap NvMap = GetNvMap(Context, Slot); + NvMap Map = GetNvMap(Context, Slot); - if ((ulong)(NvMap.Address + FbSize) > AMemoryMgr.AddrSize) + NvMapFb MapFb = (NvMapFb)ServiceNvDrv.NvMapsFb.GetData(Context.Process, 0); + + long Address = Map.CpuAddress; + + if (MapFb.HasBufferOffset(Slot)) { - Logging.Error($"Frame buffer address {NvMap.Address:x16} is invalid!"); + Address += MapFb.GetBufferOffset(Slot); + } + + if ((ulong)(Address + FbSize) > AMemoryMgr.AddrSize) + { + Logging.Error($"Frame buffer address {Address:x16} is invalid!"); BufferQueue[Slot].State = BufferState.Free; @@ -365,7 +374,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android Interlocked.Increment(ref RenderQueueCount); } - byte* Fb = (byte*)Context.Memory.Ram + NvMap.Address; + byte* Fb = (byte*)Context.Memory.Ram + Address; Context.Ns.Gpu.Renderer.QueueAction(delegate() { From e922c3627a789a86747fda6f42425b40c56182df Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 20 Mar 2018 17:00:00 -0300 Subject: [PATCH 8/9] Rename IpcServices -> Services --- ChocolArm64/Translation/ILGeneratorEx.cs | 2 +- Ryujinx.Core/OsHle/AppletStateMgr.cs | 2 +- Ryujinx.Core/OsHle/Handles/KSession.cs | 2 +- Ryujinx.Core/OsHle/Process.cs | 2 +- .../Services/Acc/IManagerForApplication.cs | 2 +- Ryujinx.Core/OsHle/Services/Acc/IProfile.cs | 2 +- Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs | 2 +- Ryujinx.Core/OsHle/Services/Am/AmErr.cs | 2 +- Ryujinx.Core/OsHle/Services/Am/FocusState.cs | 2 +- .../Services/Am/IApplicationFunctions.cs | 2 +- .../OsHle/Services/Am/IApplicationProxy.cs | 2 +- .../OsHle/Services/Am/IAudioController.cs | 2 +- .../OsHle/Services/Am/ICommonStateGetter.cs | 2 +- .../OsHle/Services/Am/IDebugFunctions.cs | 2 +- .../OsHle/Services/Am/IDisplayController.cs | 2 +- .../Services/Am/ILibraryAppletCreator.cs | 2 +- .../OsHle/Services/Am/ISelfController.cs | 2 +- Ryujinx.Core/OsHle/Services/Am/IStorage.cs | 2 +- .../OsHle/Services/Am/IStorageAccessor.cs | 2 +- .../OsHle/Services/Am/IWindowController.cs | 2 +- Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs | 2 +- .../OsHle/Services/Am/OperationMode.cs | 2 +- .../OsHle/Services/Am/ServiceAppletOE.cs | 2 +- Ryujinx.Core/OsHle/Services/Apm/ISession.cs | 2 +- Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs | 2 +- .../OsHle/Services/Aud/AudioOutData.cs | 2 +- .../OsHle/Services/Aud/IAudioDevice.cs | 2 +- Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs | 2 +- .../OsHle/Services/Aud/IAudioRenderer.cs | 2 +- .../OsHle/Services/Aud/ServiceAudOut.cs | 2 +- .../OsHle/Services/Aud/ServiceAudRen.cs | 2 +- Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs | 2 +- .../OsHle/Services/Friend/IFriendService.cs | 2 +- .../OsHle/Services/Friend/ServiceFriend.cs | 2 +- Ryujinx.Core/OsHle/Services/FspSrv/FsErr.cs | 2 +- .../OsHle/Services/FspSrv/IDirectory.cs | 2 +- Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs | 2 +- .../OsHle/Services/FspSrv/IFileSystem.cs | 2 +- .../OsHle/Services/FspSrv/IStorage.cs | 2 +- .../OsHle/Services/FspSrv/ServiceFspSrv.cs | 2 +- .../Hid/IActiveVibrationDeviceList.cs | 2 +- .../OsHle/Services/Hid/IAppletResource.cs | 2 +- Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs | 4 +- Ryujinx.Core/OsHle/Services/IIpcService.cs | 2 +- Ryujinx.Core/OsHle/Services/IpcService.cs | 4 +- Ryujinx.Core/OsHle/Services/Lm/ILogger.cs | 2 +- Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs | 2 +- .../OsHle/Services/Nifm/IGeneralService.cs | 2 +- Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs | 2 +- .../OsHle/Services/Nifm/ServiceNifm.cs | 2 +- Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs | 2 +- Ryujinx.Core/OsHle/Services/Nv/NvFd.cs | 2 +- Ryujinx.Core/OsHle/Services/Nv/NvMap.cs | 2 +- Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs | 2 +- .../OsHle/Services/Nv/ServiceNvDrv.cs | 2 +- .../Services/Pctl/IParentalControlService.cs | 2 +- .../OsHle/Services/Pctl/ServicePctl.cs | 2 +- Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs | 2 +- .../OsHle/Services/Pl/SharedFontType.cs | 2 +- Ryujinx.Core/OsHle/Services/ServiceFactory.cs | 42 +++++++++---------- Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs | 2 +- .../OsHle/Services/Set/ServiceSetSys.cs | 2 +- .../Services/Sfdnsres/ServiceSfdnsres.cs | 2 +- Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs | 2 +- Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs | 2 +- .../OsHle/Services/Time/ISteadyClock.cs | 2 +- .../OsHle/Services/Time/ISystemClock.cs | 2 +- .../OsHle/Services/Time/ITimeZoneService.cs | 2 +- .../OsHle/Services/Time/ServiceTime.cs | 2 +- .../OsHle/Services/Time/SystemClockType.cs | 2 +- Ryujinx.Core/OsHle/Services/Vi/Display.cs | 2 +- Ryujinx.Core/OsHle/Services/Vi/GbpBuffer.cs | 2 +- .../Services/Vi/IApplicationDisplayService.cs | 4 +- .../OsHle/Services/Vi/IHOSBinderDriver.cs | 4 +- .../Services/Vi/IManagerDisplayService.cs | 2 +- .../Services/Vi/ISystemDisplayService.cs | 2 +- Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs | 9 ++-- Ryujinx.Core/OsHle/Services/Vi/Parcel.cs | 2 +- Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs | 2 +- Ryujinx.Core/OsHle/Svc/SvcSystem.cs | 2 +- Ryujinx.sln | 12 ++++-- 81 files changed, 116 insertions(+), 111 deletions(-) diff --git a/ChocolArm64/Translation/ILGeneratorEx.cs b/ChocolArm64/Translation/ILGeneratorEx.cs index abb35ec3f1..612993088c 100644 --- a/ChocolArm64/Translation/ILGeneratorEx.cs +++ b/ChocolArm64/Translation/ILGeneratorEx.cs @@ -3,7 +3,7 @@ using System; namespace ChocolArm64 { using System.Reflection.Emit; - + static class ILGeneratorEx { public static void EmitLdc_I4(this ILGenerator Generator,int Value) diff --git a/Ryujinx.Core/OsHle/AppletStateMgr.cs b/Ryujinx.Core/OsHle/AppletStateMgr.cs index cd168b77a8..25f56c63fb 100644 --- a/Ryujinx.Core/OsHle/AppletStateMgr.cs +++ b/Ryujinx.Core/OsHle/AppletStateMgr.cs @@ -1,5 +1,5 @@ -using Ryujinx.Core.OsHle.IpcServices.Am; using Ryujinx.Core.OsHle.Handles; +using Ryujinx.Core.OsHle.Services.Am; using System; using System.Collections.Concurrent; diff --git a/Ryujinx.Core/OsHle/Handles/KSession.cs b/Ryujinx.Core/OsHle/Handles/KSession.cs index 6934e52259..86ce5ccc06 100644 --- a/Ryujinx.Core/OsHle/Handles/KSession.cs +++ b/Ryujinx.Core/OsHle/Handles/KSession.cs @@ -1,4 +1,4 @@ -using Ryujinx.Core.OsHle.IpcServices; +using Ryujinx.Core.OsHle.Services; using System; namespace Ryujinx.Core.OsHle.Handles diff --git a/Ryujinx.Core/OsHle/Process.cs b/Ryujinx.Core/OsHle/Process.cs index 25c10a4353..1c31d3e05c 100644 --- a/Ryujinx.Core/OsHle/Process.cs +++ b/Ryujinx.Core/OsHle/Process.cs @@ -5,7 +5,7 @@ using Ryujinx.Core.Loaders; using Ryujinx.Core.Loaders.Executables; using Ryujinx.Core.OsHle.Exceptions; using Ryujinx.Core.OsHle.Handles; -using Ryujinx.Core.OsHle.IpcServices.NvServices; +using Ryujinx.Core.OsHle.Services.Nv; using Ryujinx.Core.OsHle.Svc; using System; using System.Collections.Concurrent; diff --git a/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs b/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs index 9e309142c9..57f6895fda 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/IManagerForApplication.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Acc +namespace Ryujinx.Core.OsHle.Services.Acc { class IManagerForApplication : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs b/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs index bdeadfe88b..92e73f7881 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/IProfile.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Acc +namespace Ryujinx.Core.OsHle.Services.Acc { class IProfile : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs b/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs index 8b0a99d9de..59f4e47f05 100644 --- a/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs +++ b/Ryujinx.Core/OsHle/Services/Acc/ServiceAcc.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Acc +namespace Ryujinx.Core.OsHle.Services.Acc { class ServiceAcc : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/AmErr.cs b/Ryujinx.Core/OsHle/Services/Am/AmErr.cs index be1658742b..cb41c2d0f6 100644 --- a/Ryujinx.Core/OsHle/Services/Am/AmErr.cs +++ b/Ryujinx.Core/OsHle/Services/Am/AmErr.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { static class AmErr { diff --git a/Ryujinx.Core/OsHle/Services/Am/FocusState.cs b/Ryujinx.Core/OsHle/Services/Am/FocusState.cs index 08dffe3b69..2585cf2cc1 100644 --- a/Ryujinx.Core/OsHle/Services/Am/FocusState.cs +++ b/Ryujinx.Core/OsHle/Services/Am/FocusState.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { enum FocusState { diff --git a/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs index 685a748235..29e363be8d 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationFunctions.cs @@ -2,7 +2,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.IO; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class IApplicationFunctions : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs index 81bb2711a9..d9d91600e9 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IApplicationProxy.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class IApplicationProxy : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs b/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs index aa927d601a..8ef71e7e30 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IAudioController.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class IAudioController : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs index ec1fc7746b..7ce98ef859 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ICommonStateGetter.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using static Ryujinx.Core.OsHle.ErrorCode; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class ICommonStateGetter : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs b/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs index 445b57e28a..b7c7e9cf68 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IDebugFunctions.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class IDebugFunctions : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs b/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs index 599562424e..a56d171304 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IDisplayController.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class IDisplayController : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs b/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs index 02da315619..7b3e12cc6a 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ILibraryAppletCreator.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class ILibraryAppletCreator : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs index c5865009fb..28047159f5 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ISelfController.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class ISelfController : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/IStorage.cs b/Ryujinx.Core/OsHle/Services/Am/IStorage.cs index 8f99ea7d03..fef4a237ed 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IStorage.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IStorage.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class IStorage : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs index 096183ed2c..1e17d9ba67 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IStorageAccessor.cs @@ -3,7 +3,7 @@ using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class IStorageAccessor : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs b/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs index a830f2635a..1c10fb9218 100644 --- a/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs +++ b/Ryujinx.Core/OsHle/Services/Am/IWindowController.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class IWindowController : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs b/Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs index 4c91e54a04..45bf4326f5 100644 --- a/Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs +++ b/Ryujinx.Core/OsHle/Services/Am/MessageInfo.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { enum MessageInfo { diff --git a/Ryujinx.Core/OsHle/Services/Am/OperationMode.cs b/Ryujinx.Core/OsHle/Services/Am/OperationMode.cs index 7103742f25..f82a825b47 100644 --- a/Ryujinx.Core/OsHle/Services/Am/OperationMode.cs +++ b/Ryujinx.Core/OsHle/Services/Am/OperationMode.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { enum OperationMode { diff --git a/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs b/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs index 255f74e62a..65cdad4212 100644 --- a/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs +++ b/Ryujinx.Core/OsHle/Services/Am/ServiceAppletOE.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Am +namespace Ryujinx.Core.OsHle.Services.Am { class ServiceAppletOE : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Apm/ISession.cs b/Ryujinx.Core/OsHle/Services/Apm/ISession.cs index dd06e2c9da..a2faa01a4d 100644 --- a/Ryujinx.Core/OsHle/Services/Apm/ISession.cs +++ b/Ryujinx.Core/OsHle/Services/Apm/ISession.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Apm +namespace Ryujinx.Core.OsHle.Services.Apm { class ISession : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs b/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs index d75262160c..fcd64a2faa 100644 --- a/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs +++ b/Ryujinx.Core/OsHle/Services/Apm/ServiceApm.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Apm +namespace Ryujinx.Core.OsHle.Services.Apm { class ServiceApm : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs b/Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs index 6b27f5291f..9ba9354147 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs @@ -1,6 +1,6 @@ using System.Runtime.InteropServices; -namespace Ryujinx.Core.OsHle.IpcServices.Aud +namespace Ryujinx.Core.OsHle.Services.Aud { [StructLayout(LayoutKind.Sequential)] struct AudioOutData diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs index b8aa0a6eaf..546c9ebab0 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs @@ -3,7 +3,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.Text; -namespace Ryujinx.Core.OsHle.IpcServices.Aud +namespace Ryujinx.Core.OsHle.Services.Aud { class IAudioDevice : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs index 9549eb5710..b194e76c7a 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs @@ -5,7 +5,7 @@ using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Aud +namespace Ryujinx.Core.OsHle.Services.Aud { class IAudioOut : IpcService, IDisposable { diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs index 68fe0f4cdf..54c1e41f87 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioRenderer.cs @@ -3,7 +3,7 @@ using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Aud +namespace Ryujinx.Core.OsHle.Services.Aud { class IAudioRenderer : IpcService, IDisposable { diff --git a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs index 5064398c92..dd362c1565 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudOut.cs @@ -5,7 +5,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.Text; -namespace Ryujinx.Core.OsHle.IpcServices.Aud +namespace Ryujinx.Core.OsHle.Services.Aud { class ServiceAudOut : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs index 8c7d95257c..245d85d8b4 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/ServiceAudRen.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Aud +namespace Ryujinx.Core.OsHle.Services.Aud { class ServiceAudRen : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs b/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs index 825b3b2717..94d3370d18 100644 --- a/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs +++ b/Ryujinx.Core/OsHle/Services/Bsd/ServiceBsd.cs @@ -8,7 +8,7 @@ using System.Net; using System.Net.Sockets; using System.Threading.Tasks; -namespace Ryujinx.Core.OsHle.IpcServices.Bsd +namespace Ryujinx.Core.OsHle.Services.Bsd { //bsd_errno == (SocketException.ErrorCode - 10000) diff --git a/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs b/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs index f5497f38d4..c6e29f8608 100644 --- a/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs +++ b/Ryujinx.Core/OsHle/Services/Friend/IFriendService.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Friend +namespace Ryujinx.Core.OsHle.Services.Friend { class IFriendService : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs b/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs index 43baf8bb23..1b87d22b6c 100644 --- a/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs +++ b/Ryujinx.Core/OsHle/Services/Friend/ServiceFriend.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Friend +namespace Ryujinx.Core.OsHle.Services.Friend { class ServiceFriend : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/FsErr.cs b/Ryujinx.Core/OsHle/Services/FspSrv/FsErr.cs index 656d529f2c..762f655112 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/FsErr.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/FsErr.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.FspSrv +namespace Ryujinx.Core.OsHle.Services.FspSrv { static class FsErr { diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs index 6563c6aa13..fab8c676d6 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IDirectory.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Text; -namespace Ryujinx.Core.OsHle.IpcServices.FspSrv +namespace Ryujinx.Core.OsHle.Services.FspSrv { class IDirectory : IpcService, IDisposable { diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs index 7d01b22f81..bd7d138fd5 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFile.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.IO; -namespace Ryujinx.Core.OsHle.IpcServices.FspSrv +namespace Ryujinx.Core.OsHle.Services.FspSrv { class IFile : IpcService, IDisposable { diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs index d5c2766e3d..f65b89ef60 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IFileSystem.cs @@ -6,7 +6,7 @@ using System.Text; using static Ryujinx.Core.OsHle.ErrorCode; -namespace Ryujinx.Core.OsHle.IpcServices.FspSrv +namespace Ryujinx.Core.OsHle.Services.FspSrv { class IFileSystem : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs b/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs index d0f40333d4..05181c649b 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/IStorage.cs @@ -3,7 +3,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.IO; -namespace Ryujinx.Core.OsHle.IpcServices.FspSrv +namespace Ryujinx.Core.OsHle.Services.FspSrv { class IStorage : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs b/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs index c6f23005a7..49b7dd23c9 100644 --- a/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs +++ b/Ryujinx.Core/OsHle/Services/FspSrv/ServiceFspSrv.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.FspSrv +namespace Ryujinx.Core.OsHle.Services.FspSrv { class ServiceFspSrv : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs b/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs index ff8291727a..d02fa17e72 100644 --- a/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs +++ b/Ryujinx.Core/OsHle/Services/Hid/IActiveVibrationDeviceList.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Hid +namespace Ryujinx.Core.OsHle.Services.Hid { class IActiveApplicationDeviceList : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs b/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs index 2b7e934e0c..23dfd7a22e 100644 --- a/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs +++ b/Ryujinx.Core/OsHle/Services/Hid/IAppletResource.cs @@ -2,7 +2,7 @@ using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Hid +namespace Ryujinx.Core.OsHle.Services.Hid { class IAppletResource : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs b/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs index f15cbcfc34..46c868aab0 100644 --- a/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs +++ b/Ryujinx.Core/OsHle/Services/Hid/ServiceHid.cs @@ -1,8 +1,8 @@ +using Ryujinx.Core.Input; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -using Ryujinx.Core.Input; -namespace Ryujinx.Core.OsHle.IpcServices.Hid +namespace Ryujinx.Core.OsHle.Services.Hid { class ServiceHid : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/IIpcService.cs b/Ryujinx.Core/OsHle/Services/IIpcService.cs index eebcdfbe56..98b5c23903 100644 --- a/Ryujinx.Core/OsHle/Services/IIpcService.cs +++ b/Ryujinx.Core/OsHle/Services/IIpcService.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices +namespace Ryujinx.Core.OsHle.Services { interface IIpcService { diff --git a/Ryujinx.Core/OsHle/Services/IpcService.cs b/Ryujinx.Core/OsHle/Services/IpcService.cs index 9dca811483..33300dec95 100644 --- a/Ryujinx.Core/OsHle/Services/IpcService.cs +++ b/Ryujinx.Core/OsHle/Services/IpcService.cs @@ -1,10 +1,10 @@ -using Ryujinx.Core.OsHle.Ipc; using Ryujinx.Core.OsHle.Handles; +using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; using System.IO; -namespace Ryujinx.Core.OsHle.IpcServices +namespace Ryujinx.Core.OsHle.Services { abstract class IpcService : IIpcService { diff --git a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs index c3f5b035ac..9a0b1aa3fb 100644 --- a/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs +++ b/Ryujinx.Core/OsHle/Services/Lm/ILogger.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Text; -namespace Ryujinx.Core.OsHle.IpcServices.Lm +namespace Ryujinx.Core.OsHle.Services.Lm { class ILogger : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs b/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs index e23ff56595..f1c2204e30 100644 --- a/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs +++ b/Ryujinx.Core/OsHle/Services/Lm/ServiceLm.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Lm +namespace Ryujinx.Core.OsHle.Services.Lm { class ServiceLm : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs b/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs index abd1cc20fc..bda307699f 100644 --- a/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs +++ b/Ryujinx.Core/OsHle/Services/Nifm/IGeneralService.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Nifm +namespace Ryujinx.Core.OsHle.Services.Nifm { class IGeneralService : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs b/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs index 1e1f13e68f..307da1d67b 100644 --- a/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs +++ b/Ryujinx.Core/OsHle/Services/Nifm/IRequest.cs @@ -3,7 +3,7 @@ using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Nifm +namespace Ryujinx.Core.OsHle.Services.Nifm { class IRequest : IpcService, IDisposable { diff --git a/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs b/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs index b3602e9c49..7e5ecacd54 100644 --- a/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs +++ b/Ryujinx.Core/OsHle/Services/Nifm/ServiceNifm.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Nifm +namespace Ryujinx.Core.OsHle.Services.Nifm { class ServiceNifm : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs index acdb92cf13..7f8faaa5f3 100644 --- a/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs +++ b/Ryujinx.Core/OsHle/Services/Ns/ServiceNs.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Ns +namespace Ryujinx.Core.OsHle.Services.Ns { class ServiceNs : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Nv/NvFd.cs b/Ryujinx.Core/OsHle/Services/Nv/NvFd.cs index dbce74adfc..1fdbd1a17f 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/NvFd.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/NvFd.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.NvServices +namespace Ryujinx.Core.OsHle.Services.Nv { class NvFd { diff --git a/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs b/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs index d5a5a80082..9ef703196a 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/NvMap.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.NvServices +namespace Ryujinx.Core.OsHle.Services.Nv { class NvMap { diff --git a/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs b/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs index 1066cc9530..d8a47418b9 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/NvMapFb.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.NvServices +namespace Ryujinx.Core.OsHle.Services.Nv { class NvMapFb { diff --git a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs index a1e0e5321a..2c909b3ac7 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs @@ -6,7 +6,7 @@ using Ryujinx.Graphics.Gpu; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.NvServices +namespace Ryujinx.Core.OsHle.Services.Nv { class ServiceNvDrv : IpcService, IDisposable { diff --git a/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs b/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs index 45216864d2..28b35b0a30 100644 --- a/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs +++ b/Ryujinx.Core/OsHle/Services/Pctl/IParentalControlService.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Pctl +namespace Ryujinx.Core.OsHle.Services.Pctl { class IParentalControlService : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs b/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs index b648d184c8..0eb4cb87d5 100644 --- a/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs +++ b/Ryujinx.Core/OsHle/Services/Pctl/ServicePctl.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Pctl +namespace Ryujinx.Core.OsHle.Services.Pctl { class ServicePctl : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs b/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs index 55637eac19..8deaa5f4a1 100644 --- a/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs +++ b/Ryujinx.Core/OsHle/Services/Pl/ServicePl.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Pl +namespace Ryujinx.Core.OsHle.Services.Pl { class ServicePl : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Pl/SharedFontType.cs b/Ryujinx.Core/OsHle/Services/Pl/SharedFontType.cs index 29fe02b8a4..2318b17295 100644 --- a/Ryujinx.Core/OsHle/Services/Pl/SharedFontType.cs +++ b/Ryujinx.Core/OsHle/Services/Pl/SharedFontType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.Pl +namespace Ryujinx.Core.OsHle.Services.Pl { enum SharedFontType { diff --git a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs index 9f43cdf003..e001a3b06d 100644 --- a/Ryujinx.Core/OsHle/Services/ServiceFactory.cs +++ b/Ryujinx.Core/OsHle/Services/ServiceFactory.cs @@ -1,26 +1,26 @@ -using Ryujinx.Core.OsHle.IpcServices.Acc; -using Ryujinx.Core.OsHle.IpcServices.Am; -using Ryujinx.Core.OsHle.IpcServices.Apm; -using Ryujinx.Core.OsHle.IpcServices.Aud; -using Ryujinx.Core.OsHle.IpcServices.Bsd; -using Ryujinx.Core.OsHle.IpcServices.Friend; -using Ryujinx.Core.OsHle.IpcServices.FspSrv; -using Ryujinx.Core.OsHle.IpcServices.Hid; -using Ryujinx.Core.OsHle.IpcServices.Lm; -using Ryujinx.Core.OsHle.IpcServices.Nifm; -using Ryujinx.Core.OsHle.IpcServices.Ns; -using Ryujinx.Core.OsHle.IpcServices.NvServices; -using Ryujinx.Core.OsHle.IpcServices.Pctl; -using Ryujinx.Core.OsHle.IpcServices.Pl; -using Ryujinx.Core.OsHle.IpcServices.Set; -using Ryujinx.Core.OsHle.IpcServices.Sfdnsres; -using Ryujinx.Core.OsHle.IpcServices.Sm; -using Ryujinx.Core.OsHle.IpcServices.Ssl; -using Ryujinx.Core.OsHle.IpcServices.Time; -using Ryujinx.Core.OsHle.IpcServices.Vi; +using Ryujinx.Core.OsHle.Services.Acc; +using Ryujinx.Core.OsHle.Services.Am; +using Ryujinx.Core.OsHle.Services.Apm; +using Ryujinx.Core.OsHle.Services.Aud; +using Ryujinx.Core.OsHle.Services.Bsd; +using Ryujinx.Core.OsHle.Services.Friend; +using Ryujinx.Core.OsHle.Services.FspSrv; +using Ryujinx.Core.OsHle.Services.Hid; +using Ryujinx.Core.OsHle.Services.Lm; +using Ryujinx.Core.OsHle.Services.Nifm; +using Ryujinx.Core.OsHle.Services.Ns; +using Ryujinx.Core.OsHle.Services.Nv; +using Ryujinx.Core.OsHle.Services.Pctl; +using Ryujinx.Core.OsHle.Services.Pl; +using Ryujinx.Core.OsHle.Services.Set; +using Ryujinx.Core.OsHle.Services.Sfdnsres; +using Ryujinx.Core.OsHle.Services.Sm; +using Ryujinx.Core.OsHle.Services.Ssl; +using Ryujinx.Core.OsHle.Services.Time; +using Ryujinx.Core.OsHle.Services.Vi; using System; -namespace Ryujinx.Core.OsHle.IpcServices +namespace Ryujinx.Core.OsHle.Services { static class ServiceFactory { diff --git a/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs b/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs index 558243578a..ab4e040a62 100644 --- a/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs +++ b/Ryujinx.Core/OsHle/Services/Set/ServiceSet.cs @@ -3,7 +3,7 @@ using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Set +namespace Ryujinx.Core.OsHle.Services.Set { class ServiceSet : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs b/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs index 1d6afc4fc5..e4fcafcc84 100644 --- a/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs +++ b/Ryujinx.Core/OsHle/Services/Set/ServiceSetSys.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Set +namespace Ryujinx.Core.OsHle.Services.Set { class ServiceSetSys : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs b/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs index 1f68558ed6..1ef80829e5 100644 --- a/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs +++ b/Ryujinx.Core/OsHle/Services/Sfdnsres/ServiceSfdnsres.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Sfdnsres +namespace Ryujinx.Core.OsHle.Services.Sfdnsres { class ServiceSfdnsres : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs b/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs index 770227d52d..e7fd4a105d 100644 --- a/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs +++ b/Ryujinx.Core/OsHle/Services/Sm/ServiceSm.cs @@ -2,7 +2,7 @@ using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Sm +namespace Ryujinx.Core.OsHle.Services.Sm { class ServiceSm : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs b/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs index b9513a864a..e23811e036 100644 --- a/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs +++ b/Ryujinx.Core/OsHle/Services/Ssl/ServiceSsl.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Ssl +namespace Ryujinx.Core.OsHle.Services.Ssl { class ServiceSsl : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs b/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs index 91d78664af..187d7a063d 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ISteadyClock.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Time +namespace Ryujinx.Core.OsHle.Services.Time { class ISteadyClock : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs b/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs index f7f710c8e2..82075ee36f 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ISystemClock.cs @@ -2,7 +2,7 @@ using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Time +namespace Ryujinx.Core.OsHle.Services.Time { class ISystemClock : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs index 63329ada79..c162d98c18 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ITimeZoneService.cs @@ -2,7 +2,7 @@ using Ryujinx.Core.OsHle.Ipc; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Time +namespace Ryujinx.Core.OsHle.Services.Time { class ITimeZoneService : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs b/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs index 1f94793985..00defb987b 100644 --- a/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs +++ b/Ryujinx.Core/OsHle/Services/Time/ServiceTime.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Time +namespace Ryujinx.Core.OsHle.Services.Time { class ServiceTime : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Time/SystemClockType.cs b/Ryujinx.Core/OsHle/Services/Time/SystemClockType.cs index 2314942a3b..7b5074ba7d 100644 --- a/Ryujinx.Core/OsHle/Services/Time/SystemClockType.cs +++ b/Ryujinx.Core/OsHle/Services/Time/SystemClockType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.Time +namespace Ryujinx.Core.OsHle.Services.Time { enum SystemClockType { diff --git a/Ryujinx.Core/OsHle/Services/Vi/Display.cs b/Ryujinx.Core/OsHle/Services/Vi/Display.cs index ceadc39311..0dbb2eda03 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/Display.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/Display.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.Core.OsHle.IpcServices.Vi +namespace Ryujinx.Core.OsHle.Services.Vi { class Display { diff --git a/Ryujinx.Core/OsHle/Services/Vi/GbpBuffer.cs b/Ryujinx.Core/OsHle/Services/Vi/GbpBuffer.cs index 5fe585d068..cae310544a 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/GbpBuffer.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/GbpBuffer.cs @@ -1,6 +1,6 @@ using System.IO; -namespace Ryujinx.Core.OsHle.IpcServices.Android +namespace Ryujinx.Core.OsHle.Services.Android { struct GbpBuffer { diff --git a/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs index 62db23b408..c7e7524c10 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IApplicationDisplayService.cs @@ -3,9 +3,9 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; using System.IO; -using static Ryujinx.Core.OsHle.IpcServices.Android.Parcel; +using static Ryujinx.Core.OsHle.Services.Android.Parcel; -namespace Ryujinx.Core.OsHle.IpcServices.Vi +namespace Ryujinx.Core.OsHle.Services.Vi { class IApplicationDisplayService : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs index 4c34200609..b1b7a26828 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IHOSBinderDriver.cs @@ -1,12 +1,12 @@ using ChocolArm64.Memory; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; -using Ryujinx.Core.OsHle.IpcServices.Android; +using Ryujinx.Core.OsHle.Services.Android; using Ryujinx.Graphics.Gal; using System; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Vi +namespace Ryujinx.Core.OsHle.Services.Vi { class IHOSBinderDriver : IpcService, IDisposable { diff --git a/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs index 6c7f36ff1d..3c79250102 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/IManagerDisplayService.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Vi +namespace Ryujinx.Core.OsHle.Services.Vi { class IManagerDisplayService : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs b/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs index 814ed7d1b8..02aafebb24 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/ISystemDisplayService.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Vi +namespace Ryujinx.Core.OsHle.Services.Vi { class ISystemDisplayService : IpcService { diff --git a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs index 550260bb8e..36030d20f8 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/NvFlinger.cs @@ -1,16 +1,15 @@ using ChocolArm64.Memory; using Ryujinx.Core.OsHle.Handles; -using Ryujinx.Core.OsHle.IpcServices.NvServices; +using Ryujinx.Core.OsHle.Services.Nv; using Ryujinx.Graphics.Gal; using System; -using System.IO; using System.Collections.Generic; +using System.IO; using System.Text; using System.Threading; +using static Ryujinx.Core.OsHle.Services.Android.Parcel; -using static Ryujinx.Core.OsHle.IpcServices.Android.Parcel; - -namespace Ryujinx.Core.OsHle.IpcServices.Android +namespace Ryujinx.Core.OsHle.Services.Android { class NvFlinger : IDisposable { diff --git a/Ryujinx.Core/OsHle/Services/Vi/Parcel.cs b/Ryujinx.Core/OsHle/Services/Vi/Parcel.cs index 3404c227ef..1300a741dd 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/Parcel.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/Parcel.cs @@ -1,7 +1,7 @@ using System; using System.IO; -namespace Ryujinx.Core.OsHle.IpcServices.Android +namespace Ryujinx.Core.OsHle.Services.Android { static class Parcel { diff --git a/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs b/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs index 360cb6fafe..f9f6beefd5 100644 --- a/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs +++ b/Ryujinx.Core/OsHle/Services/Vi/ServiceVi.cs @@ -1,7 +1,7 @@ using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; -namespace Ryujinx.Core.OsHle.IpcServices.Vi +namespace Ryujinx.Core.OsHle.Services.Vi { class ServiceVi : IpcService { diff --git a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs index 96bef5e474..8813514fa6 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcSystem.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcSystem.cs @@ -3,7 +3,7 @@ using ChocolArm64.State; using Ryujinx.Core.OsHle.Exceptions; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; -using Ryujinx.Core.OsHle.IpcServices; +using Ryujinx.Core.OsHle.Services; using System; using System.Threading; diff --git a/Ryujinx.sln b/Ryujinx.sln index 34a5f48873..036421f903 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27130.2027 +VisualStudioVersion = 15.0.26730.8 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "Ryujinx\Ryujinx.csproj", "{074045D4-3ED2-4711-9169-E385F2BFB5A0}" EndProject @@ -9,9 +9,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Tests", "Ryujinx.Te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Core", "Ryujinx.Core\Ryujinx.Core.csproj", "{CB92CFF9-1D62-4D4F-9E88-8130EF61E351}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChocolArm64", "ChocolArm64\ChocolArm64.csproj", "{2345A1A7-8DEF-419B-9AFB-4DFD41D20D05}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChocolArm64", "ChocolArm64\ChocolArm64.csproj", "{2345A1A7-8DEF-419B-9AFB-4DFD41D20D05}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics", "Ryujinx.Graphics\Ryujinx.Graphics.csproj", "{EAAE36AF-7781-4578-A7E0-F0EFD2025569}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics", "Ryujinx.Graphics\Ryujinx.Graphics.csproj", "{EAAE36AF-7781-4578-A7E0-F0EFD2025569}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio", "Ryujinx.Audio\Ryujinx.Audio.csproj", "{5C1D818E-682A-46A5-9D54-30006E26C270}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -39,6 +41,10 @@ Global {EAAE36AF-7781-4578-A7E0-F0EFD2025569}.Debug|Any CPU.Build.0 = Debug|Any CPU {EAAE36AF-7781-4578-A7E0-F0EFD2025569}.Release|Any CPU.ActiveCfg = Release|Any CPU {EAAE36AF-7781-4578-A7E0-F0EFD2025569}.Release|Any CPU.Build.0 = Release|Any CPU + {5C1D818E-682A-46A5-9D54-30006E26C270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5C1D818E-682A-46A5-9D54-30006E26C270}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5C1D818E-682A-46A5-9D54-30006E26C270}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5C1D818E-682A-46A5-9D54-30006E26C270}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From d4a3e8267bddc5bf8ad2eb1e76b2ef15d4cbda2c Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 20 Mar 2018 18:42:13 -0300 Subject: [PATCH 9/9] Allow enabling/disabling memory checks on config file --- Ryujinx.Core/Config.cs | 2 ++ Ryujinx/Ryujinx.conf | 19 +++++++++++-------- Ryujinx/Ui/Program.cs | 4 ++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Ryujinx.Core/Config.cs b/Ryujinx.Core/Config.cs index c9a76de343..1e1cb3c733 100644 --- a/Ryujinx.Core/Config.cs +++ b/Ryujinx.Core/Config.cs @@ -9,6 +9,7 @@ namespace Ryujinx.Core { public static class Config { + public static bool EnableMemoryChecks { get; private set; } public static bool LoggingEnableInfo { get; private set; } public static bool LoggingEnableTrace { get; private set; } public static bool LoggingEnableDebug { get; private set; } @@ -26,6 +27,7 @@ namespace Ryujinx.Core var iniPath = Path.Combine(iniFolder, "Ryujinx.conf"); IniParser Parser = new IniParser(iniPath); + EnableMemoryChecks = Convert.ToBoolean(Parser.Value("Enable_Memory_Checks")); LoggingEnableInfo = Convert.ToBoolean(Parser.Value("Logging_Enable_Info")); LoggingEnableTrace = Convert.ToBoolean(Parser.Value("Logging_Enable_Trace")); LoggingEnableDebug = Convert.ToBoolean(Parser.Value("Logging_Enable_Debug")); diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf index e8effac1d0..00f0da5e4f 100644 --- a/Ryujinx/Ryujinx.conf +++ b/Ryujinx/Ryujinx.conf @@ -1,25 +1,28 @@ -#Enabled print informations logs +#Enable cpu memory checks (slow) +Enable_Memory_Checks = false + +#Enable print informations logs Logging_Enable_Info = true -#Enabled print trace logs +#Enable print trace logs Logging_Enable_Trace = false -#Enabled print debug logs +#Enable print debug logs Logging_Enable_Debug = false -#Enabled print warning logs +#Enable print warning logs Logging_Enable_Warn = true -#Enabled print error logs +#Enable print error logs Logging_Enable_Error = true -#Enabled print fatal logs +#Enable print fatal logs Logging_Enable_Fatal = true -#Enabled print Ipc logs +#Enable print Ipc logs Logging_Enable_Ipc = false -#Saved logs into Ryujinx.log +#Save logs into Ryujinx.log Logging_Enable_LogFile = false #https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs diff --git a/Ryujinx/Ui/Program.cs b/Ryujinx/Ui/Program.cs index 062e8bade9..bfd07433cc 100644 --- a/Ryujinx/Ui/Program.cs +++ b/Ryujinx/Ui/Program.cs @@ -12,10 +12,10 @@ namespace Ryujinx { static void Main(string[] args) { - AOptimizations.DisableMemoryChecks = true; - Config.Read(); + AOptimizations.DisableMemoryChecks = !Config.EnableMemoryChecks; + Console.Title = "Ryujinx Console"; IGalRenderer Renderer = new OpenGLRenderer();