mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-08-02 01:47:09 +02:00
Improvements to audout (#58)
* Some audout refactoring and improvements * More audio improvements * Change ReadAsciiString to use long for the Size, avoids some casting
This commit is contained in:
parent
af7683c6ad
commit
d79cab48ae
25 changed files with 567 additions and 177 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
14
Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs
Normal file
14
Ryujinx.Core/OsHle/Services/Aud/AudioOutData.cs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<int, ServiceProcessRequest> Commands => m_Commands;
|
||||
|
||||
public IAudioOut()
|
||||
private IAalOutput AudioOut;
|
||||
|
||||
private int Track;
|
||||
|
||||
public IAudioOut(IAalOutput AudioOut, int Track)
|
||||
{
|
||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||
{
|
||||
{ 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<long> BufferIdQueue = new Queue<long>();
|
||||
|
||||
//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<AudioOutData>(
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<int, ServiceProcessRequest>()
|
||||
{
|
||||
{ 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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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<HSession>(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}");
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ChocolArm64\ChocolArm64.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Audio\Ryujinx.Audio.csproj" />
|
||||
<ProjectReference Include="..\Ryujinx.Graphics\Ryujinx.Graphics.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.Core.Settings
|
||||
{
|
||||
public class SetSys
|
||||
public class SystemSettings
|
||||
{
|
||||
public ColorSet ThemeColor;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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";
|
Loading…
Add table
Add a link
Reference in a new issue