mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-07 01:59:42 +00:00
Merge branch 'Ryujinx:master' into master
This commit is contained in:
commit
a8a4e44179
22 changed files with 339 additions and 155 deletions
|
@ -42,11 +42,13 @@ namespace Ryujinx.Audio.Backends.SDL2
|
||||||
|
|
||||||
private void EnsureAudioStreamSetup(AudioBuffer buffer)
|
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)
|
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);
|
uint newOutputStream = SDL2HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate);
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ namespace Ryujinx.Audio.Common
|
||||||
|
|
||||||
for (int i = 0; i < buffersToFlush.Length; i++)
|
for (int i = 0; i < buffersToFlush.Length; i++)
|
||||||
{
|
{
|
||||||
buffersToFlush[i] = _buffers[_hardwareBufferIndex];
|
buffersToFlush[i] = _buffers[hardwareBufferIndex];
|
||||||
|
|
||||||
_bufferAppendedCount--;
|
_bufferAppendedCount--;
|
||||||
_bufferRegisteredCount++;
|
_bufferRegisteredCount++;
|
||||||
|
|
|
@ -222,6 +222,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||||
target.Info.Height,
|
target.Info.Height,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
|
xCount * srcBpp,
|
||||||
srcStride,
|
srcStride,
|
||||||
target.Info.FormatInfo.BytesPerPixel,
|
target.Info.FormatInfo.BytesPerPixel,
|
||||||
srcSpan);
|
srcSpan);
|
||||||
|
|
|
@ -99,9 +99,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||||
_isLinear = (argument & 1) != 0;
|
_isLinear = (argument & 1) != 0;
|
||||||
|
|
||||||
_offset = 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)
|
if (_buffer == null || _buffer.Length < count)
|
||||||
{
|
{
|
||||||
|
@ -171,7 +171,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||||
|
|
||||||
if (_isLinear && _lineCount == 1)
|
if (_isLinear && _lineCount == 1)
|
||||||
{
|
{
|
||||||
memoryManager.WriteTrackedResource(_dstGpuVa, data);
|
memoryManager.WriteTrackedResource(_dstGpuVa, data.Slice(0, _lineLengthIn));
|
||||||
_context.AdvanceSequence();
|
_context.AdvanceSequence();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -224,6 +224,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||||
|
|
||||||
memoryManager.Write(dstAddress, data[srcOffset]);
|
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();
|
_context.AdvanceSequence();
|
||||||
|
|
|
@ -64,7 +64,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
nameof(ThreedClassState.ShaderState)),
|
nameof(ThreedClassState.ShaderState)),
|
||||||
|
|
||||||
new StateUpdateCallbackEntry(UpdateRasterizerState, nameof(ThreedClassState.RasterizeEnable)),
|
new StateUpdateCallbackEntry(UpdateRasterizerState, nameof(ThreedClassState.RasterizeEnable)),
|
||||||
new StateUpdateCallbackEntry(UpdateScissorState, nameof(ThreedClassState.ScissorState)),
|
|
||||||
|
new StateUpdateCallbackEntry(UpdateScissorState,
|
||||||
|
nameof(ThreedClassState.ScissorState),
|
||||||
|
nameof(ThreedClassState.ScreenScissorState)),
|
||||||
|
|
||||||
new StateUpdateCallbackEntry(UpdateVertexBufferState,
|
new StateUpdateCallbackEntry(UpdateVertexBufferState,
|
||||||
nameof(ThreedClassState.VertexBufferDrawState),
|
nameof(ThreedClassState.VertexBufferDrawState),
|
||||||
|
@ -426,6 +429,18 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
int width = scissor.X2 - x;
|
int width = scissor.X2 - x;
|
||||||
int height = scissor.Y2 - y;
|
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;
|
float scale = _channel.TextureManager.RenderTargetScale;
|
||||||
if (scale != 1f)
|
if (scale != 1f)
|
||||||
{
|
{
|
||||||
|
|
|
@ -760,6 +760,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
Info.FormatInfo.BlockWidth,
|
Info.FormatInfo.BlockWidth,
|
||||||
Info.FormatInfo.BlockHeight,
|
Info.FormatInfo.BlockHeight,
|
||||||
Info.Stride,
|
Info.Stride,
|
||||||
|
Info.Stride,
|
||||||
Info.FormatInfo.BytesPerPixel,
|
Info.FormatInfo.BytesPerPixel,
|
||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,6 +248,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
int height,
|
int height,
|
||||||
int blockWidth,
|
int blockWidth,
|
||||||
int blockHeight,
|
int blockHeight,
|
||||||
|
int lineSize,
|
||||||
int stride,
|
int stride,
|
||||||
int bytesPerPixel,
|
int bytesPerPixel,
|
||||||
ReadOnlySpan<byte> data)
|
ReadOnlySpan<byte> data)
|
||||||
|
@ -256,7 +257,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
int h = BitUtils.DivRoundUp(height, blockHeight);
|
int h = BitUtils.DivRoundUp(height, blockHeight);
|
||||||
|
|
||||||
int outStride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment);
|
int outStride = BitUtils.AlignUp(w * bytesPerPixel, HostStrideAlignment);
|
||||||
int lineSize = Math.Min(stride, outStride);
|
lineSize = Math.Min(lineSize, outStride);
|
||||||
|
|
||||||
Span<byte> output = new byte[h * outStride];
|
Span<byte> output = new byte[h * outStride];
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,11 @@ namespace Ryujinx.HLE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal readonly bool EnablePtc;
|
internal readonly bool EnablePtc;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Control if the guest application should be told that there is a Internet connection available.
|
||||||
|
/// </summary>
|
||||||
|
internal readonly bool EnableInternetAccess;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Control LibHac's integrity check level.
|
/// Control LibHac's integrity check level.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -122,8 +127,8 @@ namespace Ryujinx.HLE
|
||||||
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
|
||||||
internal readonly string TimeZone;
|
internal readonly string TimeZone;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Type of the memory manager used on CPU emulation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MemoryManagerMode MemoryManagerMode { internal get; set; }
|
public MemoryManagerMode MemoryManagerMode { internal get; set; }
|
||||||
|
|
||||||
|
@ -163,6 +168,7 @@ namespace Ryujinx.HLE
|
||||||
bool enableVsync,
|
bool enableVsync,
|
||||||
bool enableDockedMode,
|
bool enableDockedMode,
|
||||||
bool enablePtc,
|
bool enablePtc,
|
||||||
|
bool enableInternetAccess,
|
||||||
IntegrityCheckLevel fsIntegrityCheckLevel,
|
IntegrityCheckLevel fsIntegrityCheckLevel,
|
||||||
int fsGlobalAccessLogMode,
|
int fsGlobalAccessLogMode,
|
||||||
long systemTimeOffset,
|
long systemTimeOffset,
|
||||||
|
@ -186,6 +192,7 @@ namespace Ryujinx.HLE
|
||||||
EnableVsync = enableVsync;
|
EnableVsync = enableVsync;
|
||||||
EnableDockedMode = enableDockedMode;
|
EnableDockedMode = enableDockedMode;
|
||||||
EnablePtc = enablePtc;
|
EnablePtc = enablePtc;
|
||||||
|
EnableInternetAccess = enableInternetAccess;
|
||||||
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
|
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
|
||||||
FsGlobalAccessLogMode = fsGlobalAccessLogMode;
|
FsGlobalAccessLogMode = fsGlobalAccessLogMode;
|
||||||
SystemTimeOffset = systemTimeOffset;
|
SystemTimeOffset = systemTimeOffset;
|
||||||
|
|
|
@ -8,6 +8,13 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||||
{
|
{
|
||||||
class IRequest : IpcService
|
class IRequest : IpcService
|
||||||
{
|
{
|
||||||
|
private enum RequestState
|
||||||
|
{
|
||||||
|
Error = 1,
|
||||||
|
OnHold = 2,
|
||||||
|
Available = 3
|
||||||
|
}
|
||||||
|
|
||||||
private KEvent _event0;
|
private KEvent _event0;
|
||||||
private KEvent _event1;
|
private KEvent _event1;
|
||||||
|
|
||||||
|
@ -28,7 +35,11 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
|
||||||
// GetRequestState() -> u32
|
// GetRequestState() -> u32
|
||||||
public ResultCode GetRequestState(ServiceCtx context)
|
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);
|
Logger.Stub?.PrintStub(LogClass.ServiceNifm);
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
_isPrivileged = isPrivileged;
|
_isPrivileged = isPrivileged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinuxError ConvertError(WsaError errorCode)
|
private static LinuxError ConvertError(WsaError errorCode)
|
||||||
{
|
{
|
||||||
if (!_errorMap.TryGetValue(errorCode, out LinuxError errno))
|
if (!_errorMap.TryGetValue(errorCode, out LinuxError errno))
|
||||||
{
|
{
|
||||||
|
@ -116,6 +116,56 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
return errno;
|
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)
|
private ResultCode WriteWinSock2Error(ServiceCtx context, WsaError errorCode)
|
||||||
{
|
{
|
||||||
return WriteBsdResult(context, -1, ConvertError(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<i8, 0x22> message)
|
// Recv(u32 socket, u32 flags) -> (i32 ret, u32 bsd_errno, array<i8, 0x22> message)
|
||||||
public ResultCode Recv(ServiceCtx context)
|
public ResultCode Recv(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int socketFd = context.RequestData.ReadInt32();
|
int socketFd = context.RequestData.ReadInt32();
|
||||||
SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32();
|
BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
(ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22();
|
(ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22();
|
||||||
|
|
||||||
|
@ -474,18 +524,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
|
|
||||||
if (socket != null)
|
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];
|
byte[] receivedBuffer = new byte[receiveLength];
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = socket.Handle.Receive(receivedBuffer, socketFlags);
|
result = socket.Handle.Receive(receivedBuffer, ConvertBsdSocketFlags(socketFlags));
|
||||||
errno = SetResultErrno(socket.Handle, result);
|
errno = SetResultErrno(socket.Handle, result);
|
||||||
|
|
||||||
context.Memory.Write(receivePosition, receivedBuffer);
|
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<i8, 0x22, 0> message, buffer<nn::socket::sockaddr_in, 0x22, 0x10>)
|
// RecvFrom(u32 sock, u32 flags) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<i8, 0x22, 0> message, buffer<nn::socket::sockaddr_in, 0x22, 0x10>)
|
||||||
public ResultCode RecvFrom(ServiceCtx context)
|
public ResultCode RecvFrom(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int socketFd = context.RequestData.ReadInt32();
|
int socketFd = context.RequestData.ReadInt32();
|
||||||
SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32();
|
BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
(ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22();
|
(ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22();
|
||||||
(ulong sockAddrOutPosition, ulong sockAddrOutSize) = context.Request.GetBufferType0x22(1);
|
(ulong sockAddrOutPosition, ulong sockAddrOutSize) = context.Request.GetBufferType0x22(1);
|
||||||
|
@ -515,20 +558,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
|
|
||||||
if (socket != null)
|
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];
|
byte[] receivedBuffer = new byte[receiveLength];
|
||||||
EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
|
EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||||
|
|
||||||
try
|
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);
|
errno = SetResultErrno(socket.Handle, result);
|
||||||
|
|
||||||
context.Memory.Write(receivePosition, receivedBuffer);
|
context.Memory.Write(receivePosition, receivedBuffer);
|
||||||
|
@ -547,8 +582,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
// Send(u32 socket, u32 flags, buffer<i8, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
|
// Send(u32 socket, u32 flags, buffer<i8, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
|
||||||
public ResultCode Send(ServiceCtx context)
|
public ResultCode Send(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int socketFd = context.RequestData.ReadInt32();
|
int socketFd = context.RequestData.ReadInt32();
|
||||||
SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32();
|
BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
(ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21();
|
(ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21();
|
||||||
|
|
||||||
|
@ -558,21 +593,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
|
|
||||||
if (socket != null)
|
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];
|
byte[] sendBuffer = new byte[sendSize];
|
||||||
|
|
||||||
context.Memory.Read(sendPosition, sendBuffer);
|
context.Memory.Read(sendPosition, sendBuffer);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = socket.Handle.Send(sendBuffer, socketFlags);
|
result = socket.Handle.Send(sendBuffer, ConvertBsdSocketFlags(socketFlags));
|
||||||
errno = SetResultErrno(socket.Handle, result);
|
errno = SetResultErrno(socket.Handle, result);
|
||||||
}
|
}
|
||||||
catch (SocketException exception)
|
catch (SocketException exception)
|
||||||
|
@ -589,8 +616,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
// SendTo(u32 socket, u32 flags, buffer<i8, 0x21, 0>, buffer<nn::socket::sockaddr_in, 0x21, 0x10>) -> (i32 ret, u32 bsd_errno)
|
// SendTo(u32 socket, u32 flags, buffer<i8, 0x21, 0>, buffer<nn::socket::sockaddr_in, 0x21, 0x10>) -> (i32 ret, u32 bsd_errno)
|
||||||
public ResultCode SendTo(ServiceCtx context)
|
public ResultCode SendTo(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int socketFd = context.RequestData.ReadInt32();
|
int socketFd = context.RequestData.ReadInt32();
|
||||||
SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32();
|
BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
(ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21();
|
(ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21();
|
||||||
(ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(1);
|
(ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(1);
|
||||||
|
@ -601,14 +628,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
|
|
||||||
if (socket != null)
|
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];
|
byte[] sendBuffer = new byte[sendSize];
|
||||||
|
|
||||||
context.Memory.Read(sendPosition, sendBuffer);
|
context.Memory.Read(sendPosition, sendBuffer);
|
||||||
|
@ -617,7 +636,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
|
|
||||||
try
|
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);
|
errno = SetResultErrno(socket.Handle, result);
|
||||||
}
|
}
|
||||||
catch (SocketException exception)
|
catch (SocketException exception)
|
||||||
|
@ -737,7 +756,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
}
|
}
|
||||||
catch (SocketException exception)
|
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<unknown, 0x22, 0>)
|
// GetSockOpt(u32 socket, u32 level, u32 option_name) -> (i32 ret, u32 bsd_errno, u32, buffer<unknown, 0x22, 0>)
|
||||||
public ResultCode GetSockOpt(ServiceCtx context)
|
public ResultCode GetSockOpt(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int socketFd = context.RequestData.ReadInt32();
|
int socketFd = context.RequestData.ReadInt32();
|
||||||
int level = context.RequestData.ReadInt32();
|
SocketOptionLevel level = (SocketOptionLevel)context.RequestData.ReadInt32();
|
||||||
int optionName = context.RequestData.ReadInt32();
|
SocketOptionName optionName = (SocketOptionName)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
(ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x22();
|
(ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x22();
|
||||||
|
|
||||||
|
@ -805,16 +831,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
|
|
||||||
if (socket != null)
|
if (socket != null)
|
||||||
{
|
{
|
||||||
errno = LinuxError.ENOPROTOOPT;
|
errno = HandleGetSocketOption(context, socket, optionName, level, bufferPosition, bufferSize);
|
||||||
|
|
||||||
if (level == 0xFFFF)
|
|
||||||
{
|
|
||||||
errno = HandleGetSocketOption(context, socket, (SocketOptionName)optionName, bufferPosition, bufferSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported GetSockOpt Level: {(SocketOptionLevel)level}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteBsdResult(context, 0, errno);
|
return WriteBsdResult(context, 0, errno);
|
||||||
|
@ -916,7 +933,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
return WriteBsdResult(context, result, errno);
|
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
|
try
|
||||||
{
|
{
|
||||||
|
@ -936,19 +959,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
case SocketOptionName.SendTimeout:
|
case SocketOptionName.SendTimeout:
|
||||||
case SocketOptionName.Type:
|
case SocketOptionName.Type:
|
||||||
case SocketOptionName.Linger:
|
case SocketOptionName.Linger:
|
||||||
socket.Handle.GetSocketOption(SocketOptionLevel.Socket, optionName, optionValue);
|
socket.Handle.GetSocketOption(level, optionName, optionValue);
|
||||||
context.Memory.Write(optionValuePosition, optionValue);
|
context.Memory.Write(optionValuePosition, optionValue);
|
||||||
|
|
||||||
return LinuxError.SUCCESS;
|
return LinuxError.SUCCESS;
|
||||||
|
|
||||||
case (SocketOptionName)0x200:
|
case (SocketOptionName)0x200:
|
||||||
socket.Handle.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, optionValue);
|
socket.Handle.GetSocketOption(level, SocketOptionName.ReuseAddress, optionValue);
|
||||||
context.Memory.Write(optionValuePosition, optionValue);
|
context.Memory.Write(optionValuePosition, optionValue);
|
||||||
|
|
||||||
return LinuxError.SUCCESS;
|
return LinuxError.SUCCESS;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported SetSockOpt OptionName: {optionName}");
|
Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported GetSockOpt OptionName: {optionName}");
|
||||||
|
|
||||||
return LinuxError.EOPNOTSUPP;
|
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
|
try
|
||||||
{
|
{
|
||||||
|
@ -977,17 +1006,17 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
case SocketOptionName.SendTimeout:
|
case SocketOptionName.SendTimeout:
|
||||||
case SocketOptionName.Type:
|
case SocketOptionName.Type:
|
||||||
case SocketOptionName.ReuseAddress:
|
case SocketOptionName.ReuseAddress:
|
||||||
socket.Handle.SetSocketOption(SocketOptionLevel.Socket, optionName, context.Memory.Read<int>((ulong)optionValuePosition));
|
socket.Handle.SetSocketOption(level, optionName, context.Memory.Read<int>((ulong)optionValuePosition));
|
||||||
|
|
||||||
return LinuxError.SUCCESS;
|
return LinuxError.SUCCESS;
|
||||||
|
|
||||||
case (SocketOptionName)0x200:
|
case (SocketOptionName)0x200:
|
||||||
socket.Handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, context.Memory.Read<int>((ulong)optionValuePosition));
|
socket.Handle.SetSocketOption(level, SocketOptionName.ReuseAddress, context.Memory.Read<int>((ulong)optionValuePosition));
|
||||||
|
|
||||||
return LinuxError.SUCCESS;
|
return LinuxError.SUCCESS;
|
||||||
|
|
||||||
case SocketOptionName.Linger:
|
case SocketOptionName.Linger:
|
||||||
socket.Handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger,
|
socket.Handle.SetSocketOption(level, SocketOptionName.Linger,
|
||||||
new LingerOption(context.Memory.Read<int>((ulong)optionValuePosition) != 0, context.Memory.Read<int>((ulong)optionValuePosition + 4)));
|
new LingerOption(context.Memory.Read<int>((ulong)optionValuePosition) != 0, context.Memory.Read<int>((ulong)optionValuePosition + 4)));
|
||||||
|
|
||||||
return LinuxError.SUCCESS;
|
return LinuxError.SUCCESS;
|
||||||
|
@ -1008,9 +1037,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
// SetSockOpt(u32 socket, u32 level, u32 option_name, buffer<unknown, 0x21, 0> option_value) -> (i32 ret, u32 bsd_errno)
|
// SetSockOpt(u32 socket, u32 level, u32 option_name, buffer<unknown, 0x21, 0> option_value) -> (i32 ret, u32 bsd_errno)
|
||||||
public ResultCode SetSockOpt(ServiceCtx context)
|
public ResultCode SetSockOpt(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int socketFd = context.RequestData.ReadInt32();
|
int socketFd = context.RequestData.ReadInt32();
|
||||||
int level = context.RequestData.ReadInt32();
|
SocketOptionLevel level = (SocketOptionLevel)context.RequestData.ReadInt32();
|
||||||
int optionName = context.RequestData.ReadInt32();
|
SocketOptionName optionName = (SocketOptionName)context.RequestData.ReadInt32();
|
||||||
|
|
||||||
(ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x21();
|
(ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x21();
|
||||||
|
|
||||||
|
@ -1019,16 +1048,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||||
|
|
||||||
if (socket != null)
|
if (socket != null)
|
||||||
{
|
{
|
||||||
errno = LinuxError.ENOPROTOOPT;
|
errno = HandleSetSocketOption(context, socket, optionName, level, bufferPos, bufferSize);
|
||||||
|
|
||||||
if (level == 0xFFFF)
|
|
||||||
{
|
|
||||||
errno = HandleSetSocketOption(context, socket, (SocketOptionName)optionName, bufferPos, bufferSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported SetSockOpt Level: {(SocketOptionLevel)level}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return WriteBsdResult(context, 0, errno);
|
return WriteBsdResult(context, 0, errno);
|
||||||
|
|
24
Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs
Normal file
24
Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs
Normal file
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position;
|
ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position;
|
||||||
ulong outputBufferSize = context.Request.ReceiveBuff[0].Size;
|
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)]
|
[CommandHipc(3)]
|
||||||
|
@ -70,7 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position;
|
ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position;
|
||||||
ulong outputBufferSize = context.Request.ReceiveBuff[0].Size;
|
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)]
|
[CommandHipc(4)]
|
||||||
|
@ -155,7 +155,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
ulong responseBufferPosition = context.Request.ReceiveBuff[0].Position;
|
ulong responseBufferPosition = context.Request.ReceiveBuff[0].Position;
|
||||||
ulong responseBufferSize = context.Request.ReceiveBuff[0].Size;
|
ulong responseBufferSize = context.Request.ReceiveBuff[0].Size;
|
||||||
|
|
||||||
return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, 0, 0);
|
return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, false, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHipc(8)]
|
[CommandHipc(8)]
|
||||||
|
@ -192,7 +192,15 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
(ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22();
|
(ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22();
|
||||||
(ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21();
|
(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+
|
[CommandHipc(11)] // 5.0.0+
|
||||||
|
@ -203,20 +211,36 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
(ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22();
|
(ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22();
|
||||||
(ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21();
|
(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+
|
[CommandHipc(12)] // 5.0.0+
|
||||||
// GetAddrInfoRequestWithOptions(bool enable_nsd_resolve, u32, u64 pid_placeholder, pid, buffer<i8, 5, 0> host, buffer<i8, 5, 0> service, buffer<packed_addrinfo, 5, 0> hints, buffer<unknown, 21, 0>) -> (i32 ret, u32 bsd_errno, u32 unknown, u32 packed_addrinfo_size, buffer<packed_addrinfo, 22, 0> response)
|
// GetAddrInfoRequestWithOptions(bool enable_nsd_resolve, u32, u64 pid_placeholder, pid, buffer<i8, 5, 0> host, buffer<i8, 5, 0> service, buffer<packed_addrinfo, 5, 0> hints, buffer<unknown, 21, 0>) -> (i32 ret, u32 bsd_errno, u32 unknown, u32 packed_addrinfo_size, buffer<packed_addrinfo, 22, 0> response)
|
||||||
public ResultCode GetAddrInfoRequestWithOptions(ServiceCtx context)
|
public ResultCode GetAddrInfoRequestWithOptions(ServiceCtx context)
|
||||||
{
|
{
|
||||||
(ulong responseBufferPosition, ulong responseBufferSize) = context.Request.GetBufferType0x22();
|
(ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22();
|
||||||
(ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21();
|
(ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21();
|
||||||
|
|
||||||
return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, 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);
|
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();
|
int timeOut = context.RequestData.ReadInt32();
|
||||||
ulong pidPlaceholder = context.RequestData.ReadUInt64();
|
ulong pidPlaceholder = context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
if (optionsBufferSize > 0)
|
if (withOptions)
|
||||||
{
|
{
|
||||||
// TODO: Parse and use options.
|
// TODO: Parse and use options.
|
||||||
}
|
}
|
||||||
|
@ -283,14 +307,20 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.ResponseData.Write((int)netDbErrorCode);
|
WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode);
|
||||||
context.ResponseData.Write((int)errno);
|
|
||||||
context.ResponseData.Write(serializedSize);
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
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];
|
byte[] rawIp = new byte[inputBufferSize];
|
||||||
|
|
||||||
|
@ -302,7 +332,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
int timeOut = context.RequestData.ReadInt32();
|
int timeOut = context.RequestData.ReadInt32();
|
||||||
ulong pidPlaceholder = context.RequestData.ReadUInt64();
|
ulong pidPlaceholder = context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
if (optionsBufferSize > 0)
|
if (withOptions)
|
||||||
{
|
{
|
||||||
// TODO: Parse and use options.
|
// TODO: Parse and use options.
|
||||||
}
|
}
|
||||||
|
@ -338,14 +368,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, GetIpv4Addresses(hostEntry));
|
serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, GetIpv4Addresses(hostEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
context.ResponseData.Write((int)netDbErrorCode);
|
WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode);
|
||||||
context.ResponseData.Write((int)errno);
|
|
||||||
context.ResponseData.Write(serializedSize);
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong SerializeHostEntries(ServiceCtx context, ulong outputBufferPosition, ulong outputBufferSize, IPHostEntry hostEntry, IEnumerable<IPAddress> addresses = null)
|
private static ulong SerializeHostEntries(ServiceCtx context, ulong outputBufferPosition, ulong outputBufferSize, IPHostEntry hostEntry, IEnumerable<IPAddress> addresses = null)
|
||||||
{
|
{
|
||||||
ulong originalBufferPosition = outputBufferPosition;
|
ulong originalBufferPosition = outputBufferPosition;
|
||||||
ulong bufferPosition = originalBufferPosition;
|
ulong bufferPosition = originalBufferPosition;
|
||||||
|
@ -391,7 +419,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
return bufferPosition - originalBufferPosition;
|
return bufferPosition - originalBufferPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultCode GetAddrInfoRequestImpl(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize)
|
private static ResultCode GetAddrInfoRequestImpl(
|
||||||
|
ServiceCtx context,
|
||||||
|
ulong responseBufferPosition,
|
||||||
|
ulong responseBufferSize,
|
||||||
|
bool withOptions,
|
||||||
|
ulong optionsBufferPosition,
|
||||||
|
ulong optionsBufferSize)
|
||||||
{
|
{
|
||||||
bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0;
|
bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0;
|
||||||
uint cancelHandle = context.RequestData.ReadUInt32();
|
uint cancelHandle = context.RequestData.ReadUInt32();
|
||||||
|
@ -402,7 +436,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
// NOTE: We ignore hints for now.
|
// NOTE: We ignore hints for now.
|
||||||
DeserializeAddrInfos(context.Memory, (ulong)context.Request.SendBuff[2].Position, (ulong)context.Request.SendBuff[2].Size);
|
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.
|
// TODO: Find unknown, Parse and use options.
|
||||||
uint unknown = context.RequestData.ReadUInt32();
|
uint unknown = context.RequestData.ReadUInt32();
|
||||||
|
@ -410,8 +444,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
|
|
||||||
ulong pidPlaceHolder = context.RequestData.ReadUInt64();
|
ulong pidPlaceHolder = context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { enableNsdResolve, cancelHandle, pidPlaceHolder, host, service });
|
|
||||||
|
|
||||||
IPHostEntry hostEntry = null;
|
IPHostEntry hostEntry = null;
|
||||||
|
|
||||||
NetDbError netDbErrorCode = NetDbError.Success;
|
NetDbError netDbErrorCode = NetDbError.Success;
|
||||||
|
@ -457,14 +489,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port);
|
serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.ResponseData.Write((int)netDbErrorCode);
|
WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode);
|
||||||
context.ResponseData.Write((int)errno);
|
|
||||||
context.ResponseData.Write(serializedSize);
|
|
||||||
|
|
||||||
return ResultCode.Success;
|
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;
|
ulong endAddress = address + size;
|
||||||
|
|
||||||
|
@ -480,23 +510,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
address += (ulong)Unsafe.SizeOf<AddrInfoSerializedHeader>() + header.AddressLength;
|
address += (ulong)Unsafe.SizeOf<AddrInfoSerializedHeader>() + header.AddressLength;
|
||||||
|
|
||||||
// ai_canonname
|
// ai_canonname
|
||||||
string canonname = string.Empty;
|
string canonname = MemoryHelper.ReadAsciiString(memory, address);
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
byte chr = memory.Read<byte>(address++);
|
|
||||||
|
|
||||||
if (chr == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
canonname += (char)chr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 originalBufferPosition = (ulong)responseBufferPosition;
|
||||||
ulong bufferPosition = originalBufferPosition;
|
ulong bufferPosition = originalBufferPosition;
|
||||||
|
@ -534,12 +552,34 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||||
return bufferPosition - originalBufferPosition;
|
return bufferPosition - originalBufferPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IPAddress> 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<IPAddress> GetIpv4Addresses(IPHostEntry hostEntry)
|
||||||
{
|
{
|
||||||
return hostEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork);
|
return hostEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NetDbError ConvertSocketErrorCodeToNetDbError(int errorCode)
|
private static NetDbError ConvertSocketErrorCodeToNetDbError(int errorCode)
|
||||||
{
|
{
|
||||||
return errorCode switch
|
return errorCode switch
|
||||||
{
|
{
|
||||||
|
@ -551,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
|
return errorCode switch
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,9 +21,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
|
||||||
Port = port;
|
Port = port;
|
||||||
Address = default;
|
Address = default;
|
||||||
|
|
||||||
address.GetAddressBytes().AsSpan().CopyTo(Address.ToSpan());
|
Span<byte> outAddress = Address.ToSpan();
|
||||||
|
address.TryWriteBytes(outAddress, out _);
|
||||||
Address.ToSpan().Reverse();
|
outAddress.Reverse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -49,7 +49,7 @@ namespace Ryujinx.HLE
|
||||||
throw new ArgumentNullException(nameof(configuration.AudioDeviceDriver));
|
throw new ArgumentNullException(nameof(configuration.AudioDeviceDriver));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.UserChannelPersistence== null)
|
if (configuration.UserChannelPersistence == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(configuration.UserChannelPersistence));
|
throw new ArgumentNullException(nameof(configuration.UserChannelPersistence));
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,9 @@ namespace Ryujinx.Headless.SDL2
|
||||||
[Option("enable-ptc", Required = false, Default = true, HelpText = "Enables profiled translation cache persistency.")]
|
[Option("enable-ptc", Required = false, Default = true, HelpText = "Enables profiled translation cache persistency.")]
|
||||||
public bool? EnablePtc { get; set; }
|
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.")]
|
[Option("enable-fs-integrity-checks", Required = false, Default = true, HelpText = "Enables integrity checks on Game content files.")]
|
||||||
public bool? EnableFsIntegrityChecks { get; set; }
|
public bool? EnableFsIntegrityChecks { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -459,6 +459,7 @@ namespace Ryujinx.Headless.SDL2
|
||||||
(bool)options.EnableVsync,
|
(bool)options.EnableVsync,
|
||||||
(bool)options.EnableDockedMode,
|
(bool)options.EnableDockedMode,
|
||||||
(bool)options.EnablePtc,
|
(bool)options.EnablePtc,
|
||||||
|
(bool)options.EnableInternetAccess,
|
||||||
(bool)options.EnableFsIntegrityChecks ? LibHac.FsSystem.IntegrityCheckLevel.ErrorOnInvalid : LibHac.FsSystem.IntegrityCheckLevel.None,
|
(bool)options.EnableFsIntegrityChecks ? LibHac.FsSystem.IntegrityCheckLevel.ErrorOnInvalid : LibHac.FsSystem.IntegrityCheckLevel.None,
|
||||||
options.FsGlobalAccessLogMode,
|
options.FsGlobalAccessLogMode,
|
||||||
options.SystemTimeOffset,
|
options.SystemTimeOffset,
|
||||||
|
|
|
@ -14,8 +14,11 @@ namespace Ryujinx.Configuration
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 33;
|
public const int CurrentVersion = 34;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Version of the configuration file format
|
||||||
|
/// </summary>
|
||||||
public int Version { get; set; }
|
public int Version { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -98,7 +101,6 @@ namespace Ryujinx.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GraphicsDebugLevel LoggingGraphicsDebugLevel { get; set; }
|
public GraphicsDebugLevel LoggingGraphicsDebugLevel { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Change System Language
|
/// Change System Language
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -154,16 +156,16 @@ namespace Ryujinx.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool EnableShaderCache { get; set; }
|
public bool EnableShaderCache { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enables or disables multi-core scheduling of threads
|
|
||||||
/// </summary>
|
|
||||||
public bool EnableMulticoreScheduling { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables profiled translation cache persistency
|
/// Enables or disables profiled translation cache persistency
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool EnablePtc { get; set; }
|
public bool EnablePtc { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables guest Internet access
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableInternetAccess { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables integrity checks on Game content files
|
/// Enables integrity checks on Game content files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -205,6 +205,11 @@ namespace Ryujinx.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> EnablePtc { get; private set; }
|
public ReactiveObject<bool> EnablePtc { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables guest Internet access
|
||||||
|
/// </summary>
|
||||||
|
public ReactiveObject<bool> EnableInternetAccess { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables integrity checks on Game content files
|
/// Enables integrity checks on Game content files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -250,6 +255,8 @@ namespace Ryujinx.Configuration
|
||||||
EnableDockedMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableDockedMode));
|
EnableDockedMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableDockedMode));
|
||||||
EnablePtc = new ReactiveObject<bool>();
|
EnablePtc = new ReactiveObject<bool>();
|
||||||
EnablePtc.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnablePtc));
|
EnablePtc.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnablePtc));
|
||||||
|
EnableInternetAccess = new ReactiveObject<bool>();
|
||||||
|
EnableInternetAccess.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableInternetAccess));
|
||||||
EnableFsIntegrityChecks = new ReactiveObject<bool>();
|
EnableFsIntegrityChecks = new ReactiveObject<bool>();
|
||||||
EnableFsIntegrityChecks.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableFsIntegrityChecks));
|
EnableFsIntegrityChecks.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableFsIntegrityChecks));
|
||||||
FsGlobalAccessLogMode = new ReactiveObject<int>();
|
FsGlobalAccessLogMode = new ReactiveObject<int>();
|
||||||
|
@ -276,7 +283,7 @@ namespace Ryujinx.Configuration
|
||||||
/// Enable or disable keyboard support (Independent from controllers binding)
|
/// Enable or disable keyboard support (Independent from controllers binding)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> EnableKeyboard { get; private set; }
|
public ReactiveObject<bool> EnableKeyboard { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enable or disable mouse support (Independent from controllers binding)
|
/// Enable or disable mouse support (Independent from controllers binding)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -464,6 +471,7 @@ namespace Ryujinx.Configuration
|
||||||
EnableVsync = Graphics.EnableVsync,
|
EnableVsync = Graphics.EnableVsync,
|
||||||
EnableShaderCache = Graphics.EnableShaderCache,
|
EnableShaderCache = Graphics.EnableShaderCache,
|
||||||
EnablePtc = System.EnablePtc,
|
EnablePtc = System.EnablePtc,
|
||||||
|
EnableInternetAccess = System.EnableInternetAccess,
|
||||||
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
|
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
|
||||||
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
|
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
|
||||||
AudioBackend = System.AudioBackend,
|
AudioBackend = System.AudioBackend,
|
||||||
|
@ -534,9 +542,11 @@ namespace Ryujinx.Configuration
|
||||||
Graphics.EnableVsync.Value = true;
|
Graphics.EnableVsync.Value = true;
|
||||||
Graphics.EnableShaderCache.Value = true;
|
Graphics.EnableShaderCache.Value = true;
|
||||||
System.EnablePtc.Value = true;
|
System.EnablePtc.Value = true;
|
||||||
|
System.EnableInternetAccess.Value = false;
|
||||||
System.EnableFsIntegrityChecks.Value = true;
|
System.EnableFsIntegrityChecks.Value = true;
|
||||||
System.FsGlobalAccessLogMode.Value = 0;
|
System.FsGlobalAccessLogMode.Value = 0;
|
||||||
System.AudioBackend.Value = AudioBackend.SDL2;
|
System.AudioBackend.Value = AudioBackend.SDL2;
|
||||||
|
System.AudioVolume.Value = 1;
|
||||||
System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe;
|
System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe;
|
||||||
System.ExpandRam.Value = false;
|
System.ExpandRam.Value = false;
|
||||||
System.IgnoreMissingServices.Value = false;
|
System.IgnoreMissingServices.Value = false;
|
||||||
|
@ -956,6 +966,15 @@ namespace Ryujinx.Configuration
|
||||||
configurationFileUpdated = true;
|
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;
|
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||||
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
|
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
|
||||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||||
|
@ -984,6 +1003,7 @@ namespace Ryujinx.Configuration
|
||||||
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
|
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
|
||||||
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
|
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
|
||||||
System.EnablePtc.Value = configurationFileFormat.EnablePtc;
|
System.EnablePtc.Value = configurationFileFormat.EnablePtc;
|
||||||
|
System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
|
||||||
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
|
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
|
||||||
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
|
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
|
||||||
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
|
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
|
||||||
|
|
|
@ -10,6 +10,7 @@ using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Configuration.System;
|
using Ryujinx.Configuration.System;
|
||||||
using Ryujinx.HLE.FileSystem;
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.HLE.Loaders.Npdm;
|
using Ryujinx.HLE.Loaders.Npdm;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -125,7 +126,7 @@ namespace Ryujinx.Ui.App
|
||||||
|
|
||||||
foreach (string appDir in appDirs)
|
foreach (string appDir in appDirs)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!Directory.Exists(appDir))
|
if (!Directory.Exists(appDir))
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Application, $"The \"game_dirs\" section in \"Config.json\" contains an invalid directory: \"{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)
|
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)
|
if (controlData.Titles.Length > (int)desiredTitleLanguage)
|
||||||
{
|
{
|
||||||
|
|
|
@ -206,7 +206,7 @@ namespace Ryujinx.Ui
|
||||||
ConfigurationState.Instance.System.IgnoreMissingServices.Event += UpdateIgnoreMissingServicesState;
|
ConfigurationState.Instance.System.IgnoreMissingServices.Event += UpdateIgnoreMissingServicesState;
|
||||||
ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState;
|
ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState;
|
||||||
ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState;
|
ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState;
|
||||||
ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState;
|
ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState;
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Ui.StartFullscreen)
|
if (ConfigurationState.Instance.Ui.StartFullscreen)
|
||||||
{
|
{
|
||||||
|
@ -434,7 +434,7 @@ namespace Ryujinx.Ui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Audio, "SDL2 is not supported, trying to fall back to OpenAL.");
|
Logger.Warning?.Print(LogClass.Audio, "SDL2 is not supported, trying to fall back to OpenAL.");
|
||||||
|
|
||||||
if (OpenALHardwareDeviceDriver.IsSupported)
|
if (OpenALHardwareDeviceDriver.IsSupported)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Audio, "Found OpenAL, changing configuration.");
|
Logger.Warning?.Print(LogClass.Audio, "Found OpenAL, changing configuration.");
|
||||||
|
@ -447,7 +447,7 @@ namespace Ryujinx.Ui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, trying to fall back to SoundIO.");
|
Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, trying to fall back to SoundIO.");
|
||||||
|
|
||||||
if (SoundIoHardwareDeviceDriver.IsSupported)
|
if (SoundIoHardwareDeviceDriver.IsSupported)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration.");
|
Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration.");
|
||||||
|
@ -460,8 +460,8 @@ namespace Ryujinx.Ui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Audio, "SoundIO is not supported, falling back to dummy audio out.");
|
Logger.Warning?.Print(LogClass.Audio, "SoundIO is not supported, falling back to dummy audio out.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ConfigurationState.Instance.System.AudioBackend.Value == AudioBackend.SoundIo)
|
else if (ConfigurationState.Instance.System.AudioBackend.Value == AudioBackend.SoundIo)
|
||||||
|
@ -499,7 +499,7 @@ namespace Ryujinx.Ui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, falling back to dummy audio out.");
|
Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, falling back to dummy audio out.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,7 @@ namespace Ryujinx.Ui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Audio, "SDL2 is not supported, trying to fall back to SoundIO.");
|
Logger.Warning?.Print(LogClass.Audio, "SDL2 is not supported, trying to fall back to SoundIO.");
|
||||||
|
|
||||||
if (SoundIoHardwareDeviceDriver.IsSupported)
|
if (SoundIoHardwareDeviceDriver.IsSupported)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration.");
|
Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration.");
|
||||||
|
@ -563,6 +563,7 @@ namespace Ryujinx.Ui
|
||||||
ConfigurationState.Instance.Graphics.EnableVsync,
|
ConfigurationState.Instance.Graphics.EnableVsync,
|
||||||
ConfigurationState.Instance.System.EnableDockedMode,
|
ConfigurationState.Instance.System.EnableDockedMode,
|
||||||
ConfigurationState.Instance.System.EnablePtc,
|
ConfigurationState.Instance.System.EnablePtc,
|
||||||
|
ConfigurationState.Instance.System.EnableInternetAccess,
|
||||||
fsIntegrityCheckLevel,
|
fsIntegrityCheckLevel,
|
||||||
ConfigurationState.Instance.System.FsGlobalAccessLogMode,
|
ConfigurationState.Instance.System.FsGlobalAccessLogMode,
|
||||||
ConfigurationState.Instance.System.SystemTimeOffset,
|
ConfigurationState.Instance.System.SystemTimeOffset,
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace Ryujinx.Ui.Windows
|
||||||
[GUI] CheckButton _vSyncToggle;
|
[GUI] CheckButton _vSyncToggle;
|
||||||
[GUI] CheckButton _shaderCacheToggle;
|
[GUI] CheckButton _shaderCacheToggle;
|
||||||
[GUI] CheckButton _ptcToggle;
|
[GUI] CheckButton _ptcToggle;
|
||||||
|
[GUI] CheckButton _internetToggle;
|
||||||
[GUI] CheckButton _fsicToggle;
|
[GUI] CheckButton _fsicToggle;
|
||||||
[GUI] RadioButton _mmSoftware;
|
[GUI] RadioButton _mmSoftware;
|
||||||
[GUI] RadioButton _mmHost;
|
[GUI] RadioButton _mmHost;
|
||||||
|
@ -226,6 +227,11 @@ namespace Ryujinx.Ui.Windows
|
||||||
_ptcToggle.Click();
|
_ptcToggle.Click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.System.EnableInternetAccess)
|
||||||
|
{
|
||||||
|
_internetToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
if (ConfigurationState.Instance.System.EnableFsIntegrityChecks)
|
if (ConfigurationState.Instance.System.EnableFsIntegrityChecks)
|
||||||
{
|
{
|
||||||
_fsicToggle.Click();
|
_fsicToggle.Click();
|
||||||
|
@ -496,6 +502,7 @@ namespace Ryujinx.Ui.Windows
|
||||||
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
|
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
|
||||||
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active;
|
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active;
|
||||||
ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.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.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
|
||||||
ConfigurationState.Instance.System.MemoryManagerMode.Value = memoryMode;
|
ConfigurationState.Instance.System.MemoryManagerMode.Value = memoryMode;
|
||||||
ConfigurationState.Instance.System.ExpandRam.Value = _expandRamToggle.Active;
|
ConfigurationState.Instance.System.ExpandRam.Value = _expandRamToggle.Active;
|
||||||
|
|
|
@ -1507,6 +1507,24 @@
|
||||||
<property name="position">6</property>
|
<property name="position">6</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCheckButton" id="_internetToggle">
|
||||||
|
<property name="label" translatable="yes">Enable guest Internet access</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can-focus">True</property>
|
||||||
|
<property name="receives-default">False</property>
|
||||||
|
<property name="tooltip-text" translatable="yes">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</property>
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="margin-top">5</property>
|
||||||
|
<property name="margin-bottom">5</property>
|
||||||
|
<property name="draw-indicator">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">7</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="_fsicToggle">
|
<object class="GtkCheckButton" id="_fsicToggle">
|
||||||
<property name="label" translatable="yes">Enable FS Integrity Checks</property>
|
<property name="label" translatable="yes">Enable FS Integrity Checks</property>
|
||||||
|
@ -1522,7 +1540,7 @@
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">7</property>
|
<property name="position">8</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|
Loading…
Reference in a new issue