diff --git a/Ryujinx.Core/OsHle/Horizon.cs b/Ryujinx.Core/OsHle/Horizon.cs index 803d3d67..3b31bfc6 100644 --- a/Ryujinx.Core/OsHle/Horizon.cs +++ b/Ryujinx.Core/OsHle/Horizon.cs @@ -12,17 +12,19 @@ namespace Ryujinx.Core.OsHle internal const int HidSize = 0x40000; internal const int FontSize = 0x50; + private Switch Ns; + private KProcessScheduler Scheduler; private ConcurrentDictionary Processes; + internal SystemStateMgr SystemState { get; private set; } + internal HSharedMem HidSharedMem { get; private set; } internal HSharedMem FontSharedMem { get; private set; } internal KEvent VsyncEvent { get; private set; } - private Switch Ns; - public Horizon(Switch Ns) { this.Ns = Ns; @@ -31,6 +33,8 @@ namespace Ryujinx.Core.OsHle Processes = new ConcurrentDictionary(); + SystemState = new SystemStateMgr(); + HidSharedMem = new HSharedMem(); FontSharedMem = new HSharedMem(); diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs index 3ccb8612..8ce86a0b 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioDevice.cs @@ -34,21 +34,23 @@ namespace Ryujinx.Core.OsHle.Services.Aud public long ListAudioDeviceName(ServiceCtx Context) { - string[] Names = new string[] { "FIXME" }; + string[] DeviceNames = SystemStateMgr.AudioOutputs; - Context.ResponseData.Write(Names.Length); + Context.ResponseData.Write(DeviceNames.Length); long Position = Context.Request.ReceiveBuff[0].Position; long Size = Context.Request.ReceiveBuff[0].Size; long BasePosition = Position; - foreach (string Name in Names) + foreach (string Name in DeviceNames) { - byte[] Buffer = Encoding.ASCII.GetBytes(Name + '\0'); + byte[] Buffer = Encoding.UTF8.GetBytes(Name + '\0'); if ((Position - BasePosition) + Buffer.Length > Size) { + Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!"); + break; } @@ -67,7 +69,9 @@ namespace Ryujinx.Core.OsHle.Services.Aud long Position = Context.Request.SendBuff[0].Position; long Size = Context.Request.SendBuff[0].Size; - string Name = AMemoryHelper.ReadAsciiString(Context.Memory, Position, Size); + byte[] DeviceNameBuffer = AMemoryHelper.ReadBytes(Context.Memory, Position, Size); + + string DeviceName = Encoding.UTF8.GetString(DeviceNameBuffer); Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); @@ -76,14 +80,21 @@ namespace Ryujinx.Core.OsHle.Services.Aud public long GetActiveAudioDeviceName(ServiceCtx Context) { - string Name = "FIXME"; + string Name = Context.Ns.Os.SystemState.ActiveAudioOutput; long Position = Context.Request.ReceiveBuff[0].Position; long Size = Context.Request.ReceiveBuff[0].Size; - byte[] Buffer = Encoding.ASCII.GetBytes(Name + '\0'); + byte[] DeviceNameBuffer = Encoding.UTF8.GetBytes(Name + '\0'); - AMemoryHelper.WriteBytes(Context.Memory, Position, Buffer); + if ((ulong)DeviceNameBuffer.Length <= (ulong)Size) + { + AMemoryHelper.WriteBytes(Context.Memory, Position, DeviceNameBuffer); + } + else + { + Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!"); + } return 0; } diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs index b1d20fbe..3bf154f3 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs @@ -1,5 +1,6 @@ using ChocolArm64.Memory; using Ryujinx.Audio; +using Ryujinx.Core.Logging; using Ryujinx.Core.OsHle.Handles; using Ryujinx.Core.OsHle.Ipc; using System.Collections.Generic; @@ -9,6 +10,8 @@ namespace Ryujinx.Core.OsHle.Services.Aud { class IAudioOutManager : IpcService { + private const string DefaultAudioOutput = "DeviceOut"; + private Dictionary m_Commands; public override IReadOnlyDictionary Commands => m_Commands; @@ -25,10 +28,24 @@ namespace Ryujinx.Core.OsHle.Services.Aud public long ListAudioOuts(ServiceCtx Context) { long Position = Context.Request.ReceiveBuff[0].Position; + long Size = Context.Request.ReceiveBuff[0].Size; - AMemoryHelper.WriteBytes(Context.Memory, Position, Encoding.ASCII.GetBytes("iface")); + int NameCount = 0; - Context.ResponseData.Write(1); + byte[] DeviceNameBuffer = Encoding.UTF8.GetBytes(DefaultAudioOutput); + + if ((ulong)DeviceNameBuffer.Length <= (ulong)Size) + { + AMemoryHelper.WriteBytes(Context.Memory, Position, DeviceNameBuffer); + + NameCount++; + } + else + { + Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!"); + } + + Context.ResponseData.Write(NameCount); return 0; } @@ -44,17 +61,21 @@ namespace Ryujinx.Core.OsHle.Services.Aud if (DeviceName == string.Empty) { - DeviceName = "FIXME"; + DeviceName = DefaultAudioOutput; } - long DeviceNamePosition = Context.Request.ReceiveBuff[0].Position; - long DeviceNameSize = Context.Request.ReceiveBuff[0].Size; + long Position = Context.Request.ReceiveBuff[0].Position; + long Size = Context.Request.ReceiveBuff[0].Size; - byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(DeviceName); + byte[] DeviceNameBuffer = Encoding.UTF8.GetBytes(DeviceName); - if (DeviceName.Length <= DeviceNameSize) + if ((ulong)DeviceNameBuffer.Length <= (ulong)Size) { - AMemoryHelper.WriteBytes(Context.Memory, DeviceNamePosition, DeviceNameBuffer); + AMemoryHelper.WriteBytes(Context.Memory, Position, DeviceNameBuffer); + } + else + { + Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!"); } int SampleRate = Context.RequestData.ReadInt32(); diff --git a/Ryujinx.Core/OsHle/SystemStateMgr.cs b/Ryujinx.Core/OsHle/SystemStateMgr.cs new file mode 100644 index 00000000..3223abfb --- /dev/null +++ b/Ryujinx.Core/OsHle/SystemStateMgr.cs @@ -0,0 +1,34 @@ +namespace Ryujinx.Core.OsHle +{ + class SystemStateMgr + { + internal static string[] AudioOutputs = new string[] + { + "AudioTvOutput", + "AudioStereoJackOutput", + "AudioBuiltInSpeakerOutput" + }; + + public string ActiveAudioOutput { get; private set; } + + public SystemStateMgr() + { + SetAudioOutputAsBuiltInSpeaker(); + } + + public void SetAudioOutputAsTv() + { + ActiveAudioOutput = AudioOutputs[0]; + } + + public void SetAudioOutputAsStereoJack() + { + ActiveAudioOutput = AudioOutputs[1]; + } + + public void SetAudioOutputAsBuiltInSpeaker() + { + ActiveAudioOutput = AudioOutputs[2]; + } + } +} \ No newline at end of file