From c0056546e72b148ccc561eba7b8daa6a78f484ae Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 26 Dec 2021 10:48:18 -0300 Subject: [PATCH 1/9] Fix bug causing an audio buffer to be enqueued more than once (#2940) --- Ryujinx.Audio/Common/AudioDeviceSession.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ryujinx.Audio/Common/AudioDeviceSession.cs b/Ryujinx.Audio/Common/AudioDeviceSession.cs index 511f39057..820e51039 100644 --- a/Ryujinx.Audio/Common/AudioDeviceSession.cs +++ b/Ryujinx.Audio/Common/AudioDeviceSession.cs @@ -175,7 +175,7 @@ namespace Ryujinx.Audio.Common for (int i = 0; i < buffersToFlush.Length; i++) { - buffersToFlush[i] = _buffers[_hardwareBufferIndex]; + buffersToFlush[i] = _buffers[hardwareBufferIndex]; _bufferAppendedCount--; _bufferRegisteredCount++; From 0b1185284c311510d08eb4a3442823356a785e24 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 26 Dec 2021 11:17:13 -0300 Subject: [PATCH 2/9] Fix GetAddrInfoWithOptions and some sockets issues (#2936) * Fix GetAddrInfoWithOptions and some sockets issues * Was not supposed to remove this log --- Ryujinx.HLE/HLEConfiguration.cs | 9 +- .../Services/Nifm/StaticService/IRequest.cs | 13 +- .../HOS/Services/Sockets/Bsd/IClient.cs | 178 ++++++++++-------- .../Sockets/Bsd/Types/BsdSocketFlags.cs | 24 +++ .../Services/Sockets/Sfdnsres/IResolver.cs | 30 ++- .../Sockets/Sfdnsres/Types/AddrInfo4.cs | 6 +- Ryujinx.HLE/Switch.cs | 2 +- Ryujinx.Headless.SDL2/Options.cs | 3 + Ryujinx.Headless.SDL2/Program.cs | 1 + .../Configuration/ConfigurationFileFormat.cs | 16 +- Ryujinx/Configuration/ConfigurationState.cs | 21 ++- Ryujinx/Ui/MainWindow.cs | 15 +- Ryujinx/Ui/Windows/SettingsWindow.cs | 7 + Ryujinx/Ui/Windows/SettingsWindow.glade | 20 +- 14 files changed, 237 insertions(+), 108 deletions(-) create mode 100644 Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs diff --git a/Ryujinx.HLE/HLEConfiguration.cs b/Ryujinx.HLE/HLEConfiguration.cs index bba21435b..70706f0f6 100644 --- a/Ryujinx.HLE/HLEConfiguration.cs +++ b/Ryujinx.HLE/HLEConfiguration.cs @@ -98,6 +98,11 @@ namespace Ryujinx.HLE /// internal readonly bool EnablePtc; + /// + /// Control if the guest application should be told that there is a Internet connection available. + /// + internal readonly bool EnableInternetAccess; + /// /// Control LibHac's integrity check level. /// @@ -122,8 +127,8 @@ namespace Ryujinx.HLE /// This cannot be changed after instantiation. internal readonly string TimeZone; - /// + /// Type of the memory manager used on CPU emulation. /// public MemoryManagerMode MemoryManagerMode { internal get; set; } @@ -163,6 +168,7 @@ namespace Ryujinx.HLE bool enableVsync, bool enableDockedMode, bool enablePtc, + bool enableInternetAccess, IntegrityCheckLevel fsIntegrityCheckLevel, int fsGlobalAccessLogMode, long systemTimeOffset, @@ -186,6 +192,7 @@ namespace Ryujinx.HLE EnableVsync = enableVsync; EnableDockedMode = enableDockedMode; EnablePtc = enablePtc; + EnableInternetAccess = enableInternetAccess; FsIntegrityCheckLevel = fsIntegrityCheckLevel; FsGlobalAccessLogMode = fsGlobalAccessLogMode; SystemTimeOffset = systemTimeOffset; diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs index a1c40aebc..7a3fdabd0 100644 --- a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs @@ -8,6 +8,13 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService { class IRequest : IpcService { + private enum RequestState + { + Error = 1, + OnHold = 2, + Available = 3 + } + private KEvent _event0; private KEvent _event1; @@ -28,7 +35,11 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService // GetRequestState() -> u32 public ResultCode GetRequestState(ServiceCtx context) { - context.ResponseData.Write(1); + RequestState requestState = context.Device.Configuration.EnableInternetAccess + ? RequestState.Available + : RequestState.Error; + + context.ResponseData.Write((int)requestState); Logger.Stub?.PrintStub(LogClass.ServiceNifm); diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs index 355ef8647..43c7ee7d9 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs @@ -106,7 +106,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd _isPrivileged = isPrivileged; } - private LinuxError ConvertError(WsaError errorCode) + private static LinuxError ConvertError(WsaError errorCode) { if (!_errorMap.TryGetValue(errorCode, out LinuxError errno)) { @@ -116,6 +116,56 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return errno; } + private static SocketFlags ConvertBsdSocketFlags(BsdSocketFlags bsdSocketFlags) + { + BsdSocketFlags SupportedFlags = + BsdSocketFlags.Oob | + BsdSocketFlags.Peek | + BsdSocketFlags.DontRoute | + BsdSocketFlags.Trunc | + BsdSocketFlags.CTrunc; + + SocketFlags socketFlags = SocketFlags.None; + + if (bsdSocketFlags.HasFlag(BsdSocketFlags.Oob)) + { + socketFlags |= SocketFlags.OutOfBand; + } + + if (bsdSocketFlags.HasFlag(BsdSocketFlags.Peek)) + { + socketFlags |= SocketFlags.Peek; + } + + if (bsdSocketFlags.HasFlag(BsdSocketFlags.DontRoute)) + { + socketFlags |= SocketFlags.DontRoute; + } + + if (bsdSocketFlags.HasFlag(BsdSocketFlags.Trunc)) + { + socketFlags |= SocketFlags.Truncated; + } + + if (bsdSocketFlags.HasFlag(BsdSocketFlags.CTrunc)) + { + socketFlags |= SocketFlags.ControlDataTruncated; + } + + bsdSocketFlags &= ~(BsdSocketFlags.Oob | + BsdSocketFlags.Peek | + BsdSocketFlags.DontRoute | + BsdSocketFlags.Trunc | + BsdSocketFlags.CTrunc); + + if (bsdSocketFlags != BsdSocketFlags.None) + { + Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported socket flags: {bsdSocketFlags}"); + } + + return socketFlags; + } + private ResultCode WriteWinSock2Error(ServiceCtx context, WsaError errorCode) { return WriteBsdResult(context, -1, ConvertError(errorCode)); @@ -463,8 +513,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd // Recv(u32 socket, u32 flags) -> (i32 ret, u32 bsd_errno, array message) public ResultCode Recv(ServiceCtx context) { - int socketFd = context.RequestData.ReadInt32(); - SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32(); + int socketFd = context.RequestData.ReadInt32(); + BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32(); (ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22(); @@ -474,18 +524,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd if (socket != null) { - if (socketFlags != SocketFlags.None && (socketFlags & SocketFlags.OutOfBand) == 0 - && (socketFlags & SocketFlags.Peek) == 0) - { - Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Recv flags: {socketFlags}"); - return WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP); - } - byte[] receivedBuffer = new byte[receiveLength]; try { - result = socket.Handle.Receive(receivedBuffer, socketFlags); + result = socket.Handle.Receive(receivedBuffer, ConvertBsdSocketFlags(socketFlags)); errno = SetResultErrno(socket.Handle, result); context.Memory.Write(receivePosition, receivedBuffer); @@ -503,8 +546,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd // RecvFrom(u32 sock, u32 flags) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer message, buffer) public ResultCode RecvFrom(ServiceCtx context) { - int socketFd = context.RequestData.ReadInt32(); - SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32(); + int socketFd = context.RequestData.ReadInt32(); + BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32(); (ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22(); (ulong sockAddrOutPosition, ulong sockAddrOutSize) = context.Request.GetBufferType0x22(1); @@ -515,20 +558,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd if (socket != null) { - if (socketFlags != SocketFlags.None && (socketFlags & SocketFlags.OutOfBand) == 0 - && (socketFlags & SocketFlags.Peek) == 0) - { - Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Recv flags: {socketFlags}"); - - return WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP); - } - byte[] receivedBuffer = new byte[receiveLength]; EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); try { - result = socket.Handle.ReceiveFrom(receivedBuffer, receivedBuffer.Length, socketFlags, ref endPoint); + result = socket.Handle.ReceiveFrom(receivedBuffer, receivedBuffer.Length, ConvertBsdSocketFlags(socketFlags), ref endPoint); errno = SetResultErrno(socket.Handle, result); context.Memory.Write(receivePosition, receivedBuffer); @@ -547,8 +582,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd // Send(u32 socket, u32 flags, buffer) -> (i32 ret, u32 bsd_errno) public ResultCode Send(ServiceCtx context) { - int socketFd = context.RequestData.ReadInt32(); - SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32(); + int socketFd = context.RequestData.ReadInt32(); + BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32(); (ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21(); @@ -558,21 +593,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd if (socket != null) { - if (socketFlags != SocketFlags.None && socketFlags != SocketFlags.OutOfBand - && socketFlags != SocketFlags.Peek && socketFlags != SocketFlags.DontRoute) - { - Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Send flags: {socketFlags}"); - - return WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP); - } - byte[] sendBuffer = new byte[sendSize]; context.Memory.Read(sendPosition, sendBuffer); try { - result = socket.Handle.Send(sendBuffer, socketFlags); + result = socket.Handle.Send(sendBuffer, ConvertBsdSocketFlags(socketFlags)); errno = SetResultErrno(socket.Handle, result); } catch (SocketException exception) @@ -589,8 +616,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd // SendTo(u32 socket, u32 flags, buffer, buffer) -> (i32 ret, u32 bsd_errno) public ResultCode SendTo(ServiceCtx context) { - int socketFd = context.RequestData.ReadInt32(); - SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32(); + int socketFd = context.RequestData.ReadInt32(); + BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32(); (ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21(); (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(1); @@ -601,14 +628,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd if (socket != null) { - if (socketFlags != SocketFlags.None && socketFlags != SocketFlags.OutOfBand - && socketFlags != SocketFlags.Peek && socketFlags != SocketFlags.DontRoute) - { - Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Send flags: {socketFlags}"); - - return WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP); - } - byte[] sendBuffer = new byte[sendSize]; context.Memory.Read(sendPosition, sendBuffer); @@ -617,7 +636,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd try { - result = socket.Handle.SendTo(sendBuffer, sendBuffer.Length, socketFlags, endPoint); + result = socket.Handle.SendTo(sendBuffer, sendBuffer.Length, ConvertBsdSocketFlags(socketFlags), endPoint); errno = SetResultErrno(socket.Handle, result); } catch (SocketException exception) @@ -737,7 +756,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd } catch (SocketException exception) { - errno = ConvertError((WsaError)exception.ErrorCode); + if (!socket.Handle.Blocking && exception.ErrorCode == (int)WsaError.WSAEWOULDBLOCK) + { + errno = LinuxError.EINPROGRESS; + } + else + { + errno = ConvertError((WsaError)exception.ErrorCode); + } } } @@ -794,9 +820,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd // GetSockOpt(u32 socket, u32 level, u32 option_name) -> (i32 ret, u32 bsd_errno, u32, buffer) public ResultCode GetSockOpt(ServiceCtx context) { - int socketFd = context.RequestData.ReadInt32(); - int level = context.RequestData.ReadInt32(); - int optionName = context.RequestData.ReadInt32(); + int socketFd = context.RequestData.ReadInt32(); + SocketOptionLevel level = (SocketOptionLevel)context.RequestData.ReadInt32(); + SocketOptionName optionName = (SocketOptionName)context.RequestData.ReadInt32(); (ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x22(); @@ -805,16 +831,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd if (socket != null) { - errno = LinuxError.ENOPROTOOPT; - - if (level == 0xFFFF) - { - errno = HandleGetSocketOption(context, socket, (SocketOptionName)optionName, bufferPosition, bufferSize); - } - else - { - Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported GetSockOpt Level: {(SocketOptionLevel)level}"); - } + errno = HandleGetSocketOption(context, socket, optionName, level, bufferPosition, bufferSize); } return WriteBsdResult(context, 0, errno); @@ -916,7 +933,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return WriteBsdResult(context, result, errno); } - private LinuxError HandleGetSocketOption(ServiceCtx context, BsdSocket socket, SocketOptionName optionName, ulong optionValuePosition, ulong optionValueSize) + private static LinuxError HandleGetSocketOption( + ServiceCtx context, + BsdSocket socket, + SocketOptionName optionName, + SocketOptionLevel level, + ulong optionValuePosition, + ulong optionValueSize) { try { @@ -936,19 +959,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd case SocketOptionName.SendTimeout: case SocketOptionName.Type: case SocketOptionName.Linger: - socket.Handle.GetSocketOption(SocketOptionLevel.Socket, optionName, optionValue); + socket.Handle.GetSocketOption(level, optionName, optionValue); context.Memory.Write(optionValuePosition, optionValue); return LinuxError.SUCCESS; case (SocketOptionName)0x200: - socket.Handle.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, optionValue); + socket.Handle.GetSocketOption(level, SocketOptionName.ReuseAddress, optionValue); context.Memory.Write(optionValuePosition, optionValue); return LinuxError.SUCCESS; default: - Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported SetSockOpt OptionName: {optionName}"); + Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported GetSockOpt OptionName: {optionName}"); return LinuxError.EOPNOTSUPP; } @@ -959,7 +982,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd } } - private LinuxError HandleSetSocketOption(ServiceCtx context, BsdSocket socket, SocketOptionName optionName, ulong optionValuePosition, ulong optionValueSize) + private static LinuxError HandleSetSocketOption( + ServiceCtx context, + BsdSocket socket, + SocketOptionName optionName, + SocketOptionLevel level, + ulong optionValuePosition, + ulong optionValueSize) { try { @@ -977,17 +1006,17 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd case SocketOptionName.SendTimeout: case SocketOptionName.Type: case SocketOptionName.ReuseAddress: - socket.Handle.SetSocketOption(SocketOptionLevel.Socket, optionName, context.Memory.Read((ulong)optionValuePosition)); + socket.Handle.SetSocketOption(level, optionName, context.Memory.Read((ulong)optionValuePosition)); return LinuxError.SUCCESS; case (SocketOptionName)0x200: - socket.Handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, context.Memory.Read((ulong)optionValuePosition)); + socket.Handle.SetSocketOption(level, SocketOptionName.ReuseAddress, context.Memory.Read((ulong)optionValuePosition)); return LinuxError.SUCCESS; case SocketOptionName.Linger: - socket.Handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, + socket.Handle.SetSocketOption(level, SocketOptionName.Linger, new LingerOption(context.Memory.Read((ulong)optionValuePosition) != 0, context.Memory.Read((ulong)optionValuePosition + 4))); return LinuxError.SUCCESS; @@ -1008,9 +1037,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd // SetSockOpt(u32 socket, u32 level, u32 option_name, buffer option_value) -> (i32 ret, u32 bsd_errno) public ResultCode SetSockOpt(ServiceCtx context) { - int socketFd = context.RequestData.ReadInt32(); - int level = context.RequestData.ReadInt32(); - int optionName = context.RequestData.ReadInt32(); + int socketFd = context.RequestData.ReadInt32(); + SocketOptionLevel level = (SocketOptionLevel)context.RequestData.ReadInt32(); + SocketOptionName optionName = (SocketOptionName)context.RequestData.ReadInt32(); (ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x21(); @@ -1019,16 +1048,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd if (socket != null) { - errno = LinuxError.ENOPROTOOPT; - - if (level == 0xFFFF) - { - errno = HandleSetSocketOption(context, socket, (SocketOptionName)optionName, bufferPos, bufferSize); - } - else - { - Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported SetSockOpt Level: {(SocketOptionLevel)level}"); - } + errno = HandleSetSocketOption(context, socket, optionName, level, bufferPos, bufferSize); } return WriteBsdResult(context, 0, errno); diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs new file mode 100644 index 000000000..4dc56356d --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs @@ -0,0 +1,24 @@ +using System.Net.Sockets; + +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +{ + enum BsdSocketFlags + { + None = 0, + Oob = 0x1, + Peek = 0x2, + DontRoute = 0x4, + Eor = 0x8, + Trunc = 0x10, + CTrunc = 0x20, + WaitAll = 0x40, + DontWait = 0x80, + Eof = 0x100, + Notification = 0x2000, + Nbio = 0x4000, + Compat = 0x8000, + SoCallbck = 0x10000, + NoSignal = 0x20000, + CMsgCloExec = 0x40000 + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs index 06df4d134..f5ae3818a 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs @@ -155,7 +155,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres ulong responseBufferPosition = context.Request.ReceiveBuff[0].Position; ulong responseBufferSize = context.Request.ReceiveBuff[0].Size; - return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, 0, 0); + return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, false, 0, 0); } [CommandHipc(8)] @@ -213,7 +213,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres (ulong responseBufferPosition, ulong responseBufferSize) = context.Request.GetBufferType0x22(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); - return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, optionsBufferPosition, optionsBufferSize); + return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, true, optionsBufferPosition, optionsBufferSize); } private ResultCode GetHostByNameRequestImpl(ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) @@ -391,7 +391,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres return bufferPosition - originalBufferPosition; } - private ResultCode GetAddrInfoRequestImpl(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) + private ResultCode GetAddrInfoRequestImpl( + ServiceCtx context, + ulong responseBufferPosition, + ulong responseBufferSize, + bool withOptions, + ulong optionsBufferPosition, + ulong optionsBufferSize) { bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; uint cancelHandle = context.RequestData.ReadUInt32(); @@ -402,7 +408,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // NOTE: We ignore hints for now. DeserializeAddrInfos(context.Memory, (ulong)context.Request.SendBuff[2].Position, (ulong)context.Request.SendBuff[2].Size); - if (optionsBufferSize > 0) + if (withOptions) { // TODO: Find unknown, Parse and use options. uint unknown = context.RequestData.ReadUInt32(); @@ -457,9 +463,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port); } - context.ResponseData.Write((int)netDbErrorCode); - context.ResponseData.Write((int)errno); - context.ResponseData.Write(serializedSize); + if (withOptions) + { + context.ResponseData.Write(serializedSize); + context.ResponseData.Write((int)errno); + context.ResponseData.Write((int)netDbErrorCode); + context.ResponseData.Write(0); + } + else + { + context.ResponseData.Write((int)netDbErrorCode); + context.ResponseData.Write((int)errno); + context.ResponseData.Write(serializedSize); + } return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs index 515d8649d..0e1d3aaeb 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs @@ -21,9 +21,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types Port = port; Address = default; - address.GetAddressBytes().AsSpan().CopyTo(Address.ToSpan()); - - Address.ToSpan().Reverse(); + Span outAddress = Address.ToSpan(); + address.TryWriteBytes(outAddress, out _); + outAddress.Reverse(); } } } \ No newline at end of file diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs index 29d2ddd44..ac7d46112 100644 --- a/Ryujinx.HLE/Switch.cs +++ b/Ryujinx.HLE/Switch.cs @@ -49,7 +49,7 @@ namespace Ryujinx.HLE throw new ArgumentNullException(nameof(configuration.AudioDeviceDriver)); } - if (configuration.UserChannelPersistence== null) + if (configuration.UserChannelPersistence == null) { throw new ArgumentNullException(nameof(configuration.UserChannelPersistence)); } diff --git a/Ryujinx.Headless.SDL2/Options.cs b/Ryujinx.Headless.SDL2/Options.cs index 2c635a596..c8829d064 100644 --- a/Ryujinx.Headless.SDL2/Options.cs +++ b/Ryujinx.Headless.SDL2/Options.cs @@ -79,6 +79,9 @@ namespace Ryujinx.Headless.SDL2 [Option("enable-ptc", Required = false, Default = true, HelpText = "Enables profiled translation cache persistency.")] public bool? EnablePtc { get; set; } + [Option("enable-internet-connection", Required = false, Default = false, HelpText = "Enables guest Internet connection.")] + public bool? EnableInternetAccess { get; set; } + [Option("enable-fs-integrity-checks", Required = false, Default = true, HelpText = "Enables integrity checks on Game content files.")] public bool? EnableFsIntegrityChecks { get; set; } diff --git a/Ryujinx.Headless.SDL2/Program.cs b/Ryujinx.Headless.SDL2/Program.cs index eddf93518..2b169478e 100644 --- a/Ryujinx.Headless.SDL2/Program.cs +++ b/Ryujinx.Headless.SDL2/Program.cs @@ -459,6 +459,7 @@ namespace Ryujinx.Headless.SDL2 (bool)options.EnableVsync, (bool)options.EnableDockedMode, (bool)options.EnablePtc, + (bool)options.EnableInternetAccess, (bool)options.EnableFsIntegrityChecks ? LibHac.FsSystem.IntegrityCheckLevel.ErrorOnInvalid : LibHac.FsSystem.IntegrityCheckLevel.None, options.FsGlobalAccessLogMode, options.SystemTimeOffset, diff --git a/Ryujinx/Configuration/ConfigurationFileFormat.cs b/Ryujinx/Configuration/ConfigurationFileFormat.cs index 648004d5f..b06e04e0d 100644 --- a/Ryujinx/Configuration/ConfigurationFileFormat.cs +++ b/Ryujinx/Configuration/ConfigurationFileFormat.cs @@ -14,8 +14,11 @@ namespace Ryujinx.Configuration /// /// The current version of the file format /// - public const int CurrentVersion = 33; + public const int CurrentVersion = 34; + /// + /// Version of the configuration file format + /// public int Version { get; set; } /// @@ -98,7 +101,6 @@ namespace Ryujinx.Configuration /// public GraphicsDebugLevel LoggingGraphicsDebugLevel { get; set; } - /// /// Change System Language /// @@ -154,16 +156,16 @@ namespace Ryujinx.Configuration /// public bool EnableShaderCache { get; set; } - /// - /// Enables or disables multi-core scheduling of threads - /// - public bool EnableMulticoreScheduling { get; set; } - /// /// Enables or disables profiled translation cache persistency /// public bool EnablePtc { get; set; } + /// + /// Enables or disables guest Internet access + /// + public bool EnableInternetAccess { get; set; } + /// /// Enables integrity checks on Game content files /// diff --git a/Ryujinx/Configuration/ConfigurationState.cs b/Ryujinx/Configuration/ConfigurationState.cs index 02136591d..b0b01771a 100644 --- a/Ryujinx/Configuration/ConfigurationState.cs +++ b/Ryujinx/Configuration/ConfigurationState.cs @@ -205,6 +205,11 @@ namespace Ryujinx.Configuration /// public ReactiveObject EnablePtc { get; private set; } + /// + /// Enables or disables guest Internet access + /// + public ReactiveObject EnableInternetAccess { get; private set; } + /// /// Enables integrity checks on Game content files /// @@ -250,6 +255,8 @@ namespace Ryujinx.Configuration EnableDockedMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableDockedMode)); EnablePtc = new ReactiveObject(); EnablePtc.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnablePtc)); + EnableInternetAccess = new ReactiveObject(); + EnableInternetAccess.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableInternetAccess)); EnableFsIntegrityChecks = new ReactiveObject(); EnableFsIntegrityChecks.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableFsIntegrityChecks)); FsGlobalAccessLogMode = new ReactiveObject(); @@ -276,7 +283,7 @@ namespace Ryujinx.Configuration /// Enable or disable keyboard support (Independent from controllers binding) /// public ReactiveObject EnableKeyboard { get; private set; } - + /// /// Enable or disable mouse support (Independent from controllers binding) /// @@ -464,6 +471,7 @@ namespace Ryujinx.Configuration EnableVsync = Graphics.EnableVsync, EnableShaderCache = Graphics.EnableShaderCache, EnablePtc = System.EnablePtc, + EnableInternetAccess = System.EnableInternetAccess, EnableFsIntegrityChecks = System.EnableFsIntegrityChecks, FsGlobalAccessLogMode = System.FsGlobalAccessLogMode, AudioBackend = System.AudioBackend, @@ -534,6 +542,7 @@ namespace Ryujinx.Configuration Graphics.EnableVsync.Value = true; Graphics.EnableShaderCache.Value = true; System.EnablePtc.Value = true; + System.EnableInternetAccess.Value = false; System.EnableFsIntegrityChecks.Value = true; System.FsGlobalAccessLogMode.Value = 0; System.AudioBackend.Value = AudioBackend.SDL2; @@ -956,6 +965,15 @@ namespace Ryujinx.Configuration configurationFileUpdated = true; } + if (configurationFileFormat.Version < 34) + { + Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 34."); + + configurationFileFormat.EnableInternetAccess = false; + + configurationFileUpdated = true; + } + Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog; Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading; Graphics.ResScale.Value = configurationFileFormat.ResScale; @@ -984,6 +1002,7 @@ namespace Ryujinx.Configuration Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync; Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache; System.EnablePtc.Value = configurationFileFormat.EnablePtc; + System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess; System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks; System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode; System.AudioBackend.Value = configurationFileFormat.AudioBackend; diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index 51a09a319..e78d1a46d 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -206,7 +206,7 @@ namespace Ryujinx.Ui ConfigurationState.Instance.System.IgnoreMissingServices.Event += UpdateIgnoreMissingServicesState; ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState; ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState; - ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState; + ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState; if (ConfigurationState.Instance.Ui.StartFullscreen) { @@ -434,7 +434,7 @@ namespace Ryujinx.Ui else { Logger.Warning?.Print(LogClass.Audio, "SDL2 is not supported, trying to fall back to OpenAL."); - + if (OpenALHardwareDeviceDriver.IsSupported) { Logger.Warning?.Print(LogClass.Audio, "Found OpenAL, changing configuration."); @@ -447,7 +447,7 @@ namespace Ryujinx.Ui else { Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, trying to fall back to SoundIO."); - + if (SoundIoHardwareDeviceDriver.IsSupported) { Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration."); @@ -460,8 +460,8 @@ namespace Ryujinx.Ui else { Logger.Warning?.Print(LogClass.Audio, "SoundIO is not supported, falling back to dummy audio out."); - } - } + } + } } } else if (ConfigurationState.Instance.System.AudioBackend.Value == AudioBackend.SoundIo) @@ -499,7 +499,7 @@ namespace Ryujinx.Ui else { Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, falling back to dummy audio out."); - } + } } } } @@ -525,7 +525,7 @@ namespace Ryujinx.Ui else { Logger.Warning?.Print(LogClass.Audio, "SDL2 is not supported, trying to fall back to SoundIO."); - + if (SoundIoHardwareDeviceDriver.IsSupported) { Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration."); @@ -563,6 +563,7 @@ namespace Ryujinx.Ui ConfigurationState.Instance.Graphics.EnableVsync, ConfigurationState.Instance.System.EnableDockedMode, ConfigurationState.Instance.System.EnablePtc, + ConfigurationState.Instance.System.EnableInternetAccess, fsIntegrityCheckLevel, ConfigurationState.Instance.System.FsGlobalAccessLogMode, ConfigurationState.Instance.System.SystemTimeOffset, diff --git a/Ryujinx/Ui/Windows/SettingsWindow.cs b/Ryujinx/Ui/Windows/SettingsWindow.cs index c5aeebdaa..1b9796386 100644 --- a/Ryujinx/Ui/Windows/SettingsWindow.cs +++ b/Ryujinx/Ui/Windows/SettingsWindow.cs @@ -52,6 +52,7 @@ namespace Ryujinx.Ui.Windows [GUI] CheckButton _vSyncToggle; [GUI] CheckButton _shaderCacheToggle; [GUI] CheckButton _ptcToggle; + [GUI] CheckButton _internetToggle; [GUI] CheckButton _fsicToggle; [GUI] RadioButton _mmSoftware; [GUI] RadioButton _mmHost; @@ -226,6 +227,11 @@ namespace Ryujinx.Ui.Windows _ptcToggle.Click(); } + if (ConfigurationState.Instance.System.EnableInternetAccess) + { + _internetToggle.Click(); + } + if (ConfigurationState.Instance.System.EnableFsIntegrityChecks) { _fsicToggle.Click(); @@ -496,6 +502,7 @@ namespace Ryujinx.Ui.Windows ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active; ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active; ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active; + ConfigurationState.Instance.System.EnableInternetAccess.Value = _internetToggle.Active; ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active; ConfigurationState.Instance.System.MemoryManagerMode.Value = memoryMode; ConfigurationState.Instance.System.ExpandRam.Value = _expandRamToggle.Active; diff --git a/Ryujinx/Ui/Windows/SettingsWindow.glade b/Ryujinx/Ui/Windows/SettingsWindow.glade index fa544edb2..d9b36daf6 100644 --- a/Ryujinx/Ui/Windows/SettingsWindow.glade +++ b/Ryujinx/Ui/Windows/SettingsWindow.glade @@ -1507,6 +1507,24 @@ 6 + + + Enable guest Internet access + True + True + False + Enables guest Internet access. If enabled, the application will behave as if the emulated Switch console was connected to the Internet. Note that in some cases, applications may still access the Internet even with this option disabled + start + 5 + 5 + True + + + False + True + 7 + + Enable FS Integrity Checks @@ -1522,7 +1540,7 @@ False True - 7 + 8 From 451673ada576ecd7b8e98fb03e063b5d37152c39 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 26 Dec 2021 12:39:07 -0300 Subject: [PATCH 3/9] Fix I2M texture copies when line length is not a multiple of 4 (#2938) * Fix I2M texture copies when line length is not a multiple of 4 * Do not copy padding bytes for 1D copies * Nit --- .../Engine/InlineToMemory/InlineToMemoryClass.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs b/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs index 9649841f2..c09390579 100644 --- a/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs +++ b/Ryujinx.Graphics.Gpu/Engine/InlineToMemory/InlineToMemoryClass.cs @@ -99,9 +99,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory _isLinear = (argument & 1) != 0; _offset = 0; - _size = (int)(state.LineLengthIn * state.LineCount); + _size = (int)(BitUtils.AlignUp(state.LineLengthIn, 4) * state.LineCount); - int count = BitUtils.DivRoundUp(_size, 4); + int count = _size / 4; if (_buffer == null || _buffer.Length < count) { @@ -171,7 +171,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory if (_isLinear && _lineCount == 1) { - memoryManager.WriteTrackedResource(_dstGpuVa, data); + memoryManager.WriteTrackedResource(_dstGpuVa, data.Slice(0, _lineLengthIn)); _context.AdvanceSequence(); } else @@ -224,6 +224,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory memoryManager.Write(dstAddress, data[srcOffset]); } + + // All lines must be aligned to 4 bytes, as the data is pushed one word at a time. + // If our copy length is not a multiple of 4, then we need to skip the padding bytes here. + int misalignment = _lineLengthIn & 3; + + if (misalignment != 0) + { + srcOffset += 4 - misalignment; + } } _context.AdvanceSequence(); From 7c7bf30ad38d0d80ed9c125b7c894eba2293df66 Mon Sep 17 00:00:00 2001 From: sharmander Date: Sun, 26 Dec 2021 10:54:26 -0500 Subject: [PATCH 4/9] Fix missing default value of audio volume. (#2939) --- Ryujinx/Configuration/ConfigurationState.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Ryujinx/Configuration/ConfigurationState.cs b/Ryujinx/Configuration/ConfigurationState.cs index b0b01771a..90fb3f6f5 100644 --- a/Ryujinx/Configuration/ConfigurationState.cs +++ b/Ryujinx/Configuration/ConfigurationState.cs @@ -546,6 +546,7 @@ namespace Ryujinx.Configuration System.EnableFsIntegrityChecks.Value = true; System.FsGlobalAccessLogMode.Value = 0; System.AudioBackend.Value = AudioBackend.SDL2; + System.AudioVolume.Value = 1; System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe; System.ExpandRam.Value = false; System.IgnoreMissingServices.Value = false; From a87f7f202973d2ab0db088f97b3538ae724bbe69 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 26 Dec 2021 13:05:26 -0300 Subject: [PATCH 5/9] Fix DMA copy fast path line size when xCount < stride (#2942) --- Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs | 1 + Ryujinx.Graphics.Gpu/Image/Texture.cs | 1 + Ryujinx.Graphics.Texture/LayoutConverter.cs | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs b/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs index 856d52a9a..c00e2bef6 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs @@ -222,6 +222,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma target.Info.Height, 1, 1, + xCount * srcBpp, srcStride, target.Info.FormatInfo.BytesPerPixel, srcSpan); diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs index a13edc691..590356e34 100644 --- a/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -760,6 +760,7 @@ namespace Ryujinx.Graphics.Gpu.Image Info.FormatInfo.BlockWidth, Info.FormatInfo.BlockHeight, Info.Stride, + Info.Stride, Info.FormatInfo.BytesPerPixel, data); } diff --git a/Ryujinx.Graphics.Texture/LayoutConverter.cs b/Ryujinx.Graphics.Texture/LayoutConverter.cs index 970d08cb4..1039ea26a 100644 --- a/Ryujinx.Graphics.Texture/LayoutConverter.cs +++ b/Ryujinx.Graphics.Texture/LayoutConverter.cs @@ -248,6 +248,7 @@ namespace Ryujinx.Graphics.Texture int height, int blockWidth, int blockHeight, + int lineSize, int stride, int bytesPerPixel, ReadOnlySpan data) @@ -256,7 +257,7 @@ namespace Ryujinx.Graphics.Texture int h = BitUtils.DivRoundUp(height, blockHeight); int outStride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment); - int lineSize = Math.Min(stride, outStride); + lineSize = Math.Min(lineSize, outStride); Span output = new byte[h * outStride]; From ac57dd5d75bd59b73471685c1f76c61f5ad5eae8 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 27 Dec 2021 18:10:49 -0300 Subject: [PATCH 6/9] Fix wrong title language (#2933) * Fix wrong title language * Sort --- Ryujinx/Ui/App/ApplicationLibrary.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Ryujinx/Ui/App/ApplicationLibrary.cs b/Ryujinx/Ui/App/ApplicationLibrary.cs index 00c09cac3..e96f336d4 100644 --- a/Ryujinx/Ui/App/ApplicationLibrary.cs +++ b/Ryujinx/Ui/App/ApplicationLibrary.cs @@ -10,6 +10,7 @@ using Ryujinx.Common.Logging; using Ryujinx.Configuration.System; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS; +using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.Loaders.Npdm; using System; using System.Collections.Generic; @@ -125,7 +126,7 @@ namespace Ryujinx.Ui.App foreach (string appDir in appDirs) { - + if (!Directory.Exists(appDir)) { Logger.Warning?.Print(LogClass.Application, $"The \"game_dirs\" section in \"Config.json\" contains an invalid directory: \"{appDir}\""); @@ -552,7 +553,7 @@ namespace Ryujinx.Ui.App private void GetNameIdDeveloper(ref ApplicationControlProperty controlData, out string titleName, out string titleId, out string publisher) { - _ = Enum.TryParse(_desiredTitleLanguage.ToString(), out LibHac.Settings.Language desiredTitleLanguage); + _ = Enum.TryParse(_desiredTitleLanguage.ToString(), out TitleLanguage desiredTitleLanguage); if (controlData.Titles.Length > (int)desiredTitleLanguage) { From f65d01b5d35b2339d2b5afaa0f85cdcf832b4636 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 27 Dec 2021 18:25:21 -0300 Subject: [PATCH 7/9] Use minimum stream sample count on SDL2 audio backend (#2948) --- Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs b/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs index 33e1632dd..b39f196ac 100644 --- a/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs +++ b/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs @@ -42,11 +42,13 @@ namespace Ryujinx.Audio.Backends.SDL2 private void EnsureAudioStreamSetup(AudioBuffer buffer) { - bool needAudioSetup = _outputStream == 0 || ((uint)GetSampleCount(buffer) % _sampleCount) != 0; + uint bufferSampleCount = (uint)GetSampleCount(buffer); + bool needAudioSetup = _outputStream == 0 || + (bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount); if (needAudioSetup) { - _sampleCount = Math.Max(Constants.TargetSampleCount, (uint)GetSampleCount(buffer)); + _sampleCount = Math.Max(Constants.TargetSampleCount, bufferSampleCount); uint newOutputStream = SDL2HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate); From 6dacc4c577ed4ea81581e6d376630d0f6cc8250b Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 28 Dec 2021 08:22:58 -0300 Subject: [PATCH 8/9] Fix GetHostByNameRequestWithOptions and GetHostByAddrRequestWithOptions (#2943) --- .../Services/Sockets/Sfdnsres/IResolver.cs | 128 +++++++++++------- 1 file changed, 76 insertions(+), 52 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs index f5ae3818a..c569915f6 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs @@ -57,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position; ulong outputBufferSize = context.Request.ReceiveBuff[0].Size; - return GetHostByNameRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, 0, 0); + return GetHostByNameRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, false, 0, 0); } [CommandHipc(3)] @@ -70,7 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position; ulong outputBufferSize = context.Request.ReceiveBuff[0].Size; - return GetHostByAddrRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, 0, 0); + return GetHostByAddrRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, false, 0, 0); } [CommandHipc(4)] @@ -192,7 +192,15 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); - return GetHostByNameRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, optionsBufferPosition, optionsBufferSize); + return GetHostByNameRequestImpl( + context, + inputBufferPosition, + inputBufferSize, + outputBufferPosition, + outputBufferSize, + true, + optionsBufferPosition, + optionsBufferSize); } [CommandHipc(11)] // 5.0.0+ @@ -203,20 +211,36 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); - return GetHostByAddrRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, optionsBufferPosition, optionsBufferSize); + return GetHostByAddrRequestImpl( + context, + inputBufferPosition, + inputBufferSize, + outputBufferPosition, + outputBufferSize, + true, + optionsBufferPosition, + optionsBufferSize); } [CommandHipc(12)] // 5.0.0+ // GetAddrInfoRequestWithOptions(bool enable_nsd_resolve, u32, u64 pid_placeholder, pid, buffer host, buffer service, buffer hints, buffer) -> (i32 ret, u32 bsd_errno, u32 unknown, u32 packed_addrinfo_size, buffer response) public ResultCode GetAddrInfoRequestWithOptions(ServiceCtx context) { - (ulong responseBufferPosition, ulong responseBufferSize) = context.Request.GetBufferType0x22(); - (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); + (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); + (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); - return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, true, optionsBufferPosition, optionsBufferSize); + return GetAddrInfoRequestImpl(context, outputBufferPosition, outputBufferSize, true, optionsBufferPosition, optionsBufferSize); } - private ResultCode GetHostByNameRequestImpl(ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) + private static ResultCode GetHostByNameRequestImpl( + ServiceCtx context, + ulong inputBufferPosition, + ulong inputBufferSize, + ulong outputBufferPosition, + ulong outputBufferSize, + bool withOptions, + ulong optionsBufferPosition, + ulong optionsBufferSize) { string name = MemoryHelper.ReadAsciiString(context.Memory, inputBufferPosition, (int)inputBufferSize); @@ -225,7 +249,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); - if (optionsBufferSize > 0) + if (withOptions) { // TODO: Parse and use options. } @@ -283,14 +307,20 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres } } - context.ResponseData.Write((int)netDbErrorCode); - context.ResponseData.Write((int)errno); - context.ResponseData.Write(serializedSize); + WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode); return ResultCode.Success; } - private ResultCode GetHostByAddrRequestImpl(ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) + private static ResultCode GetHostByAddrRequestImpl( + ServiceCtx context, + ulong inputBufferPosition, + ulong inputBufferSize, + ulong outputBufferPosition, + ulong outputBufferSize, + bool withOptions, + ulong optionsBufferPosition, + ulong optionsBufferSize) { byte[] rawIp = new byte[inputBufferSize]; @@ -302,7 +332,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); - if (optionsBufferSize > 0) + if (withOptions) { // TODO: Parse and use options. } @@ -338,14 +368,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, GetIpv4Addresses(hostEntry)); } - context.ResponseData.Write((int)netDbErrorCode); - context.ResponseData.Write((int)errno); - context.ResponseData.Write(serializedSize); + WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode); return ResultCode.Success; } - private ulong SerializeHostEntries(ServiceCtx context, ulong outputBufferPosition, ulong outputBufferSize, IPHostEntry hostEntry, IEnumerable addresses = null) + private static ulong SerializeHostEntries(ServiceCtx context, ulong outputBufferPosition, ulong outputBufferSize, IPHostEntry hostEntry, IEnumerable addresses = null) { ulong originalBufferPosition = outputBufferPosition; ulong bufferPosition = originalBufferPosition; @@ -391,7 +419,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres return bufferPosition - originalBufferPosition; } - private ResultCode GetAddrInfoRequestImpl( + private static ResultCode GetAddrInfoRequestImpl( ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, @@ -416,8 +444,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres ulong pidPlaceHolder = context.RequestData.ReadUInt64(); - Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { enableNsdResolve, cancelHandle, pidPlaceHolder, host, service }); - IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; @@ -463,24 +489,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port); } - if (withOptions) - { - context.ResponseData.Write(serializedSize); - context.ResponseData.Write((int)errno); - context.ResponseData.Write((int)netDbErrorCode); - context.ResponseData.Write(0); - } - else - { - context.ResponseData.Write((int)netDbErrorCode); - context.ResponseData.Write((int)errno); - context.ResponseData.Write(serializedSize); - } + WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode); return ResultCode.Success; } - private void DeserializeAddrInfos(IVirtualMemoryManager memory, ulong address, ulong size) + private static void DeserializeAddrInfos(IVirtualMemoryManager memory, ulong address, ulong size) { ulong endAddress = address + size; @@ -496,23 +510,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres address += (ulong)Unsafe.SizeOf() + header.AddressLength; // ai_canonname - string canonname = string.Empty; - - while (true) - { - byte chr = memory.Read(address++); - - if (chr == 0) - { - break; - } - - canonname += (char)chr; - } + string canonname = MemoryHelper.ReadAsciiString(memory, address); } } - private ulong SerializeAddrInfos(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, IPHostEntry hostEntry, int port) + private static ulong SerializeAddrInfos(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, IPHostEntry hostEntry, int port) { ulong originalBufferPosition = (ulong)responseBufferPosition; ulong bufferPosition = originalBufferPosition; @@ -550,12 +552,34 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres return bufferPosition - originalBufferPosition; } - private IEnumerable GetIpv4Addresses(IPHostEntry hostEntry) + private static void WriteResponse( + ServiceCtx context, + bool withOptions, + ulong serializedSize, + GaiError errno, + NetDbError netDbErrorCode) + { + if (withOptions) + { + context.ResponseData.Write((int)serializedSize); + context.ResponseData.Write((int)errno); + context.ResponseData.Write((int)netDbErrorCode); + context.ResponseData.Write(0); + } + else + { + context.ResponseData.Write((int)netDbErrorCode); + context.ResponseData.Write((int)errno); + context.ResponseData.Write((int)serializedSize); + } + } + + private static IEnumerable GetIpv4Addresses(IPHostEntry hostEntry) { return hostEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork); } - private NetDbError ConvertSocketErrorCodeToNetDbError(int errorCode) + private static NetDbError ConvertSocketErrorCodeToNetDbError(int errorCode) { return errorCode switch { @@ -567,7 +591,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres }; } - private GaiError ConvertSocketErrorCodeToGaiError(int errorCode, GaiError errno) + private static GaiError ConvertSocketErrorCodeToGaiError(int errorCode, GaiError errno) { return errorCode switch { From ef39b2ebddb3d0f4c1d50a8dbffc6c434591b2dc Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 28 Dec 2021 08:37:23 -0300 Subject: [PATCH 9/9] Flip scissor box when the YNegate bit is set (#2941) * Flip scissor box when the YNegate bit is set * Flip scissor based on screen scissor state, account for negative scissor Y * No need for abs when we already know the value is negative --- .../Engine/Threed/StateUpdater.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs index cf74f649e..9f6ee17ce 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs @@ -64,7 +64,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed nameof(ThreedClassState.ShaderState)), new StateUpdateCallbackEntry(UpdateRasterizerState, nameof(ThreedClassState.RasterizeEnable)), - new StateUpdateCallbackEntry(UpdateScissorState, nameof(ThreedClassState.ScissorState)), + + new StateUpdateCallbackEntry(UpdateScissorState, + nameof(ThreedClassState.ScissorState), + nameof(ThreedClassState.ScreenScissorState)), new StateUpdateCallbackEntry(UpdateVertexBufferState, nameof(ThreedClassState.VertexBufferDrawState), @@ -426,6 +429,18 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed int width = scissor.X2 - x; int height = scissor.Y2 - y; + if (_state.State.YControl.HasFlag(YControl.NegateY)) + { + ref var screenScissor = ref _state.State.ScreenScissorState; + y = screenScissor.Height - height - y; + + if (y < 0) + { + height += y; + y = 0; + } + } + float scale = _channel.TextureManager.RenderTargetScale; if (scale != 1f) {