Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
472119c8da | ||
|
1865ea87e5 | ||
|
18b61aff59 | ||
|
cb22629ac1 | ||
|
6f0f99ee2b |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Something doesn't work correctly in Ryujinx. Note that game-specific issues should be instead posted on the Game Compatibility List at https://github.com/Ryujinx/Ryujinx-Games-List, unless it is a provable regression.
|
||||
about: Something doesn't work correctly in Ryujinx. Game-specific issues should be posted at https://github.com/Ryujinx/Ryujinx-Games-List instead, unless it is a provable regression.
|
||||
#assignees:
|
||||
---
|
||||
|
||||
|
@@ -15,12 +15,12 @@ using static Ryujinx.Ava.Ui.Controls.Win32NativeInterop;
|
||||
|
||||
namespace Ryujinx.Ava.Ui.Controls
|
||||
{
|
||||
public unsafe class EmbeddedWindow : NativeControlHost
|
||||
public class EmbeddedWindow : NativeControlHost
|
||||
{
|
||||
private WindowProc _wndProcDelegate;
|
||||
private string _className;
|
||||
|
||||
protected GLXWindow X11Window { get; private set; }
|
||||
protected GLXWindow X11Window { get; set; }
|
||||
protected IntPtr WindowHandle { get; set; }
|
||||
protected IntPtr X11Display { get; set; }
|
||||
|
||||
@@ -94,21 +94,17 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
IPlatformHandle CreateLinux(IPlatformHandle parent)
|
||||
protected virtual IPlatformHandle CreateLinux(IPlatformHandle parent)
|
||||
{
|
||||
X11Window = new GLXWindow(new NativeHandle(X11.DefaultDisplay), new NativeHandle(parent.Handle));
|
||||
|
||||
X11Window = PlatformHelper.CreateOpenGLWindow(FramebufferFormat.Default, 0, 0, 100, 100) as GLXWindow;
|
||||
WindowHandle = X11Window.WindowHandle.RawHandle;
|
||||
|
||||
X11Display = X11Window.DisplayHandle.RawHandle;
|
||||
|
||||
X11Window.Hide();
|
||||
X11Display = X11Window.DisplayHandle.RawHandle;
|
||||
|
||||
return new PlatformHandle(WindowHandle, "X11");
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
unsafe IPlatformHandle CreateWin32(IPlatformHandle parent)
|
||||
IPlatformHandle CreateWin32(IPlatformHandle parent)
|
||||
{
|
||||
_className = "NativeWindow-" + Guid.NewGuid();
|
||||
_wndProcDelegate = WndProc;
|
||||
@@ -144,7 +140,7 @@ namespace Ryujinx.Ava.Ui.Controls
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal IntPtr WndProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam)
|
||||
IntPtr WndProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
var point = new Point((long)lParam & 0xFFFF, ((long)lParam >> 16) & 0xFFFF);
|
||||
var root = VisualRoot as Window;
|
||||
|
@@ -1,10 +1,13 @@
|
||||
using Avalonia.Platform;
|
||||
using Ryujinx.Ava.Ui.Controls;
|
||||
using Silk.NET.Vulkan;
|
||||
using SPB.Graphics.Vulkan;
|
||||
using SPB.Platform.GLX;
|
||||
using SPB.Platform.Win32;
|
||||
using SPB.Platform.X11;
|
||||
using SPB.Windowing;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.Ava.Ui
|
||||
{
|
||||
@@ -12,6 +15,18 @@ namespace Ryujinx.Ava.Ui
|
||||
{
|
||||
private NativeWindowBase _window;
|
||||
|
||||
[SupportedOSPlatform("linux")]
|
||||
protected override IPlatformHandle CreateLinux(IPlatformHandle parent)
|
||||
{
|
||||
X11Window = new GLXWindow(new NativeHandle(X11.DefaultDisplay), new NativeHandle(parent.Handle));
|
||||
WindowHandle = X11Window.WindowHandle.RawHandle;
|
||||
X11Display = X11Window.DisplayHandle.RawHandle;
|
||||
|
||||
X11Window.Hide();
|
||||
|
||||
return new PlatformHandle(WindowHandle, "X11");
|
||||
}
|
||||
|
||||
public SurfaceKHR CreateSurface(Instance instance)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
|
@@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Ptm.Psm
|
||||
{
|
||||
if (_stateChangeEventHandle == -1)
|
||||
{
|
||||
KernelResult resultCode = context.Process.HandleTable.GenerateHandle(_stateChangeEvent.ReadableEvent, out int stateChangeEventHandle);
|
||||
KernelResult resultCode = context.Process.HandleTable.GenerateHandle(_stateChangeEvent.ReadableEvent, out _stateChangeEventHandle);
|
||||
|
||||
if (resultCode != KernelResult.Success)
|
||||
{
|
||||
|
@@ -315,6 +315,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
}
|
||||
}
|
||||
|
||||
if (updateCount > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// If we are here, that mean nothing was availaible, sleep for 50ms
|
||||
context.Device.System.KernelContext.Syscall.SleepThread(50 * 1000000);
|
||||
}
|
||||
@@ -972,11 +977,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
}
|
||||
|
||||
[CommandHipc(31)] // 7.0.0+
|
||||
// EventFd(u64 initval, nn::socket::EventFdFlags flags) -> (i32 ret, u32 bsd_errno)
|
||||
// EventFd(nn::socket::EventFdFlags flags, u64 initval) -> (i32 ret, u32 bsd_errno)
|
||||
public ResultCode EventFd(ServiceCtx context)
|
||||
{
|
||||
ulong initialValue = context.RequestData.ReadUInt64();
|
||||
EventFdFlags flags = (EventFdFlags)context.RequestData.ReadUInt32();
|
||||
context.RequestData.BaseStream.Position += 4; // Padding
|
||||
ulong initialValue = context.RequestData.ReadUInt64();
|
||||
|
||||
EventFileDescriptor newEventFile = new EventFileDescriptor(initialValue, flags);
|
||||
|
||||
|
@@ -26,8 +26,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
_value = value;
|
||||
_flags = flags;
|
||||
|
||||
WriteEvent = new ManualResetEvent(true);
|
||||
ReadEvent = new ManualResetEvent(true);
|
||||
WriteEvent = new ManualResetEvent(false);
|
||||
ReadEvent = new ManualResetEvent(false);
|
||||
UpdateEventStates();
|
||||
}
|
||||
|
||||
public int Refcount { get; set; }
|
||||
@@ -38,6 +39,25 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
ReadEvent.Dispose();
|
||||
}
|
||||
|
||||
private void ResetEventStates()
|
||||
{
|
||||
WriteEvent.Reset();
|
||||
ReadEvent.Reset();
|
||||
}
|
||||
|
||||
private void UpdateEventStates()
|
||||
{
|
||||
if (_value > 0)
|
||||
{
|
||||
ReadEvent.Set();
|
||||
}
|
||||
|
||||
if (_value != uint.MaxValue - 1)
|
||||
{
|
||||
WriteEvent.Set();
|
||||
}
|
||||
}
|
||||
|
||||
public LinuxError Read(out int readSize, Span<byte> buffer)
|
||||
{
|
||||
if (buffer.Length < sizeof(ulong))
|
||||
@@ -47,10 +67,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
return LinuxError.EINVAL;
|
||||
}
|
||||
|
||||
ReadEvent.Reset();
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
ResetEventStates();
|
||||
|
||||
ref ulong count = ref MemoryMarshal.Cast<byte, ulong>(buffer)[0];
|
||||
|
||||
if (_value == 0)
|
||||
@@ -66,6 +86,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
{
|
||||
readSize = 0;
|
||||
|
||||
UpdateEventStates();
|
||||
return LinuxError.EAGAIN;
|
||||
}
|
||||
}
|
||||
@@ -85,8 +106,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
ReadEvent.Set();
|
||||
|
||||
UpdateEventStates();
|
||||
return LinuxError.SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -100,10 +120,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
return LinuxError.EINVAL;
|
||||
}
|
||||
|
||||
WriteEvent.Reset();
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
ResetEventStates();
|
||||
|
||||
if (_value > _value + count)
|
||||
{
|
||||
if (Blocking)
|
||||
@@ -114,6 +134,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
{
|
||||
writeSize = 0;
|
||||
|
||||
UpdateEventStates();
|
||||
return LinuxError.EAGAIN;
|
||||
}
|
||||
}
|
||||
@@ -123,8 +144,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
_value += count;
|
||||
Monitor.Pulse(_lock);
|
||||
|
||||
WriteEvent.Set();
|
||||
|
||||
UpdateEventStates();
|
||||
return LinuxError.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@@ -68,20 +68,37 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
|
||||
{
|
||||
for (int i = 0; i < events.Count; i++)
|
||||
{
|
||||
PollEventTypeMask outputEvents = 0;
|
||||
|
||||
PollEvent evnt = events[i];
|
||||
|
||||
EventFileDescriptor socket = (EventFileDescriptor)evnt.FileDescriptor;
|
||||
|
||||
if ((evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Input) ||
|
||||
evnt.Data.InputEvents.HasFlag(PollEventTypeMask.UrgentInput))
|
||||
&& socket.ReadEvent.WaitOne(0))
|
||||
if (socket.ReadEvent.WaitOne(0))
|
||||
{
|
||||
waiters.Add(socket.ReadEvent);
|
||||
if (evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Input))
|
||||
{
|
||||
outputEvents |= PollEventTypeMask.Input;
|
||||
}
|
||||
|
||||
if (evnt.Data.InputEvents.HasFlag(PollEventTypeMask.UrgentInput))
|
||||
{
|
||||
outputEvents |= PollEventTypeMask.UrgentInput;
|
||||
}
|
||||
}
|
||||
|
||||
if ((evnt.Data.InputEvents.HasFlag(PollEventTypeMask.Output))
|
||||
&& socket.WriteEvent.WaitOne(0))
|
||||
{
|
||||
waiters.Add(socket.WriteEvent);
|
||||
outputEvents |= PollEventTypeMask.Output;
|
||||
}
|
||||
|
||||
|
||||
if (outputEvents != 0)
|
||||
{
|
||||
evnt.Data.OutputEvents = outputEvents;
|
||||
|
||||
updatedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -566,7 +566,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||
|
||||
private static List<AddrInfoSerialized> DeserializeAddrInfos(IVirtualMemoryManager memory, ulong address, ulong size)
|
||||
{
|
||||
List<AddrInfoSerialized> result = new List<AddrInfoSerialized>();
|
||||
List<AddrInfoSerialized> result = new();
|
||||
|
||||
ReadOnlySpan<byte> data = memory.GetSpan(address, (int)size);
|
||||
|
||||
@@ -606,9 +606,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
|
||||
}
|
||||
|
||||
// NOTE: 0 = Any
|
||||
AddrInfoSerializedHeader header = new AddrInfoSerializedHeader(ip, 0);
|
||||
AddrInfo4 addr = new AddrInfo4(ip, (short)port);
|
||||
AddrInfoSerialized info = new AddrInfoSerialized(header, addr, null, hostEntry.HostName);
|
||||
AddrInfoSerializedHeader header = new(ip, 0);
|
||||
AddrInfo4 addr = new(ip, (short)port);
|
||||
AddrInfoSerialized info = new(header, addr, null, hostEntry.HostName);
|
||||
|
||||
data = info.Write(data);
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
|
||||
public byte Family;
|
||||
public short Port;
|
||||
public Array4<byte> Address;
|
||||
public Array8<byte> Padding;
|
||||
|
||||
public AddrInfo4(IPAddress address, short port)
|
||||
{
|
||||
|
@@ -35,7 +35,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
|
||||
|
||||
AddrInfo4? socketAddress = null;
|
||||
Array4<byte>? rawIPv4Address = null;
|
||||
string canonicalName = null;
|
||||
string canonicalName;
|
||||
|
||||
buffer = buffer[Unsafe.SizeOf<AddrInfoSerializedHeader>()..];
|
||||
|
||||
@@ -50,6 +50,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
|
||||
|
||||
Debug.Assert(header.Magic == SfdnsresContants.AddrInfoMagic);
|
||||
|
||||
if (header.AddressLength == 0)
|
||||
{
|
||||
rest = buffer;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (header.Family == (int)AddressFamily.InterNetwork)
|
||||
{
|
||||
socketAddress = MemoryMarshal.Read<AddrInfo4>(buffer);
|
||||
|
Reference in New Issue
Block a user