diff --git a/ARMeilleure/Signal/UnixSignalHandlerRegistration.cs b/ARMeilleure/Signal/UnixSignalHandlerRegistration.cs index 12bda3de2..945a01dae 100644 --- a/ARMeilleure/Signal/UnixSignalHandlerRegistration.cs +++ b/ARMeilleure/Signal/UnixSignalHandlerRegistration.cs @@ -18,17 +18,17 @@ namespace ARMeilleure.Signal public IntPtr sa_restorer; } - static class UnixSignalHandlerRegistration + static partial class UnixSignalHandlerRegistration { private const int SIGSEGV = 11; private const int SIGBUS = 10; private const int SA_SIGINFO = 0x00000004; - [DllImport("libc", SetLastError = true)] - private static extern int sigaction(int signum, ref SigAction sigAction, out SigAction oldAction); + [LibraryImport("libc", SetLastError = true)] + private static partial int sigaction(int signum, ref SigAction sigAction, out SigAction oldAction); - [DllImport("libc", SetLastError = true)] - private static extern int sigemptyset(ref SigSet set); + [LibraryImport("libc", SetLastError = true)] + private static partial int sigemptyset(ref SigSet set); public static SigAction RegisterExceptionHandler(IntPtr action) { diff --git a/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs b/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs index b74f1098b..3219e015d 100644 --- a/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs +++ b/ARMeilleure/Signal/WindowsSignalHandlerRegistration.cs @@ -3,19 +3,19 @@ using System.Runtime.InteropServices; namespace ARMeilleure.Signal { - unsafe class WindowsSignalHandlerRegistration + unsafe partial class WindowsSignalHandlerRegistration { - [DllImport("kernel32.dll")] - private static extern IntPtr AddVectoredExceptionHandler(uint first, IntPtr handler); + [LibraryImport("kernel32.dll")] + private static partial IntPtr AddVectoredExceptionHandler(uint first, IntPtr handler); - [DllImport("kernel32.dll")] - private static extern ulong RemoveVectoredExceptionHandler(IntPtr handle); + [LibraryImport("kernel32.dll")] + private static partial ulong RemoveVectoredExceptionHandler(IntPtr handle); - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)] - static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); + [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "LoadLibraryA")] + private static partial IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); - [DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] - private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); + [LibraryImport("kernel32.dll", SetLastError = true)] + private static partial IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName); private static IntPtr _getCurrentThreadIdPtr; diff --git a/ARMeilleure/Translation/Cache/JitUnwindWindows.cs b/ARMeilleure/Translation/Cache/JitUnwindWindows.cs index 072c0f51b..77727bf16 100644 --- a/ARMeilleure/Translation/Cache/JitUnwindWindows.cs +++ b/ARMeilleure/Translation/Cache/JitUnwindWindows.cs @@ -7,7 +7,7 @@ using System.Runtime.InteropServices; namespace ARMeilleure.Translation.Cache { - static class JitUnwindWindows + static partial class JitUnwindWindows { private const int MaxUnwindCodesArraySize = 32; // Must be an even value. @@ -42,14 +42,15 @@ namespace ARMeilleure.Translation.Cache private unsafe delegate RuntimeFunction* GetRuntimeFunctionCallback(ulong controlPc, IntPtr context); - [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - private static unsafe extern bool RtlInstallFunctionTableCallback( + [LibraryImport("kernel32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static unsafe partial bool RtlInstallFunctionTableCallback( ulong tableIdentifier, ulong baseAddress, uint length, GetRuntimeFunctionCallback callback, IntPtr context, - string outOfProcessCallbackDll); + [MarshalAs(UnmanagedType.LPWStr)] string outOfProcessCallbackDll); private static GetRuntimeFunctionCallback _getRuntimeFunctionCallback; diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..10a26484d --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,54 @@ + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj b/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj index 9736c348e..115a37601 100644 --- a/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj +++ b/Ryujinx.Audio.Backends.OpenAL/Ryujinx.Audio.Backends.OpenAL.csproj @@ -1,11 +1,11 @@ - + net7.0 - + diff --git a/Ryujinx.Ava/AppHost.cs b/Ryujinx.Ava/AppHost.cs index 0cb3bd138..c1b3355a4 100644 --- a/Ryujinx.Ava/AppHost.cs +++ b/Ryujinx.Ava/AppHost.cs @@ -17,7 +17,7 @@ using Ryujinx.Ava.Ui.Windows; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; -using Ryujinx.Common.System; +using Ryujinx.Common.SystemInterop; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.Gpu; diff --git a/Ryujinx.Ava/Assets/Locales/en_US.json b/Ryujinx.Ava/Assets/Locales/en_US.json index 5778fd0c2..115dd27c4 100644 --- a/Ryujinx.Ava/Assets/Locales/en_US.json +++ b/Ryujinx.Ava/Assets/Locales/en_US.json @@ -280,7 +280,7 @@ "ControllerSettingsRemoveProfileToolTip": "Remove Profile", "ControllerSettingsSaveProfileToolTip": "Save Profile", "MenuBarFileToolsTakeScreenshot": "Take Screenshot", - "MenuBarFileToolsHideUi": "Hide Ui", + "MenuBarFileToolsHideUi": "Hide UI", "GameListContextMenuToggleFavorite": "Toggle Favorite", "GameListContextMenuToggleFavoriteToolTip": "Toggle Favorite status of Game", "SettingsTabGeneralTheme": "Theme", diff --git a/Ryujinx.Ava/Helper/MetalHelper.cs b/Ryujinx.Ava/Helper/MetalHelper.cs index ae07ce69b..2d4d828b8 100644 --- a/Ryujinx.Ava/Helper/MetalHelper.cs +++ b/Ryujinx.Ava/Helper/MetalHelper.cs @@ -8,7 +8,7 @@ namespace Ryujinx.Ava.Ui.Helper public delegate void UpdateBoundsCallbackDelegate(Rect rect); [SupportedOSPlatform("macos")] - static class MetalHelper + static partial class MetalHelper { private const string LibObjCImport = "/usr/lib/libobjc.A.dylib"; @@ -100,28 +100,28 @@ namespace Ryujinx.Ava.Ui.Helper // TODO } - [DllImport(LibObjCImport)] - private static unsafe extern IntPtr sel_registerName(byte* data); + [LibraryImport(LibObjCImport)] + private static unsafe partial IntPtr sel_registerName(byte* data); - [DllImport(LibObjCImport)] - private static unsafe extern IntPtr objc_getClass(byte* data); + [LibraryImport(LibObjCImport)] + private static unsafe partial IntPtr objc_getClass(byte* data); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector, byte value); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector, byte value); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector, NSRect point); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector, NSRect point); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector, double value); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value); - [DllImport(LibObjCImport, EntryPoint = "objc_msgSend")] - private static extern IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector); + [LibraryImport(LibObjCImport, EntryPoint = "objc_msgSend")] + private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector); } } \ No newline at end of file diff --git a/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs b/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs index 8400ddad6..0cc04d0a9 100644 --- a/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs +++ b/Ryujinx.Ava/Input/AvaloniaKeyboardMappingHelper.cs @@ -7,8 +7,7 @@ namespace Ryujinx.Ava.Input { internal static class AvaloniaKeyboardMappingHelper { - private static readonly AvaKey[] _keyMapping = new AvaKey[(int)Key.Count] - { + private static readonly AvaKey[] _keyMapping = { // NOTE: Invalid AvaKey.None, @@ -151,16 +150,16 @@ namespace Ryujinx.Ava.Input static AvaloniaKeyboardMappingHelper() { - var inputKeys = Enum.GetValues(typeof(Key)); + var inputKeys = Enum.GetValues(); // NOTE: Avalonia.Input.Key is not contiguous and quite large, so use a dictionary instead of an array. _avaKeyMapping = new Dictionary(); foreach (var key in inputKeys) { - if (TryGetAvaKey((Key)key, out var index)) + if (TryGetAvaKey(key, out var index)) { - _avaKeyMapping[index] = (Key)key; + _avaKeyMapping[index] = key; } } } diff --git a/Ryujinx.Ava/Modules/Updater/Updater.cs b/Ryujinx.Ava/Modules/Updater/Updater.cs index a48156c4d..b3a1ef30c 100644 --- a/Ryujinx.Ava/Modules/Updater/Updater.cs +++ b/Ryujinx.Ava/Modules/Updater/Updater.cs @@ -11,6 +11,7 @@ using Ryujinx.Ava.Ui.Controls; using Ryujinx.Ava.Ui.Windows; using Ryujinx.Common; using Ryujinx.Common.Logging; +using Ryujinx.Ui.Common.Helper; using System; using System.Collections.Generic; using System.Diagnostics; @@ -278,14 +279,15 @@ namespace Ryujinx.Modules { string ryuName = Path.GetFileName(Environment.ProcessPath); string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName); - var ryuArg = Environment.GetCommandLineArgs().Skip(1); - if (!OperatingSystem.IsWindows()) + if (!Path.Exists(ryuExe)) { - chmod(ryuExe, Convert.ToUInt32("0777", 8)); + ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx"); } - Process.Start(ryuExe, ryuArg); + SetFileExecutable(ryuExe); + + Process.Start(ryuExe, CommandLineState.Arguments); Environment.Exit(0); } @@ -456,16 +458,19 @@ namespace Ryujinx.Modules worker.Start(); } - [DllImport("libc", SetLastError = true)] - private static extern int chmod(string path, uint mode); - - private static void SetUnixPermissions() + private static void SetFileExecutable(string path) { - string ryuBin = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx"); + const UnixFileMode ExecutableFileMode = UnixFileMode.UserExecute | + UnixFileMode.UserWrite | + UnixFileMode.UserRead | + UnixFileMode.GroupRead | + UnixFileMode.GroupWrite | + UnixFileMode.OtherRead | + UnixFileMode.OtherWrite; - if (!OperatingSystem.IsWindows()) + if (!OperatingSystem.IsWindows() && File.Exists(path)) { - chmod(ryuBin, 493); + File.SetUnixFileMode(path, ExecutableFileMode); } } @@ -586,7 +591,7 @@ namespace Ryujinx.Modules Directory.Delete(UpdateDir, true); - SetUnixPermissions(); + SetFileExecutable(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx")); UpdateSuccessful = true; diff --git a/Ryujinx.Ava/Program.cs b/Ryujinx.Ava/Program.cs index ba10a4599..023e31df3 100644 --- a/Ryujinx.Ava/Program.cs +++ b/Ryujinx.Ava/Program.cs @@ -6,7 +6,7 @@ using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.Logging; -using Ryujinx.Common.System; +using Ryujinx.Common.SystemInterop; using Ryujinx.Common.SystemInfo; using Ryujinx.Modules; using Ryujinx.SDL2.Common; @@ -20,7 +20,7 @@ using System.Threading.Tasks; namespace Ryujinx.Ava { - internal class Program + internal partial class Program { public static double WindowScaleFactor { get; set; } public static double DesktopScaleFactor { get; set; } = 1.0; @@ -28,8 +28,8 @@ namespace Ryujinx.Ava public static string ConfigurationPath { get; private set; } public static bool PreviewerDetached { get; private set; } - [DllImport("user32.dll", SetLastError = true)] - public static extern int MessageBoxA(IntPtr hWnd, string text, string caption, uint type); + [LibraryImport("user32.dll", SetLastError = true)] + public static partial int MessageBoxA(IntPtr hWnd, [MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string caption, uint type); private const uint MB_ICONWARNING = 0x30; diff --git a/Ryujinx.Ava/Ryujinx.Ava.csproj b/Ryujinx.Ava/Ryujinx.Ava.csproj index a16641ac4..6da118491 100644 --- a/Ryujinx.Ava/Ryujinx.Ava.csproj +++ b/Ryujinx.Ava/Ryujinx.Ava.csproj @@ -1,4 +1,4 @@ - + net7.0 win10-x64;osx-x64;linux-x64 @@ -18,31 +18,31 @@ - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - + diff --git a/Ryujinx.Ava/Ui/Applet/SwkbdAppletDialog.axaml.cs b/Ryujinx.Ava/Ui/Applet/SwkbdAppletDialog.axaml.cs index e4ddba966..ee329bc29 100644 --- a/Ryujinx.Ava/Ui/Applet/SwkbdAppletDialog.axaml.cs +++ b/Ryujinx.Ava/Ui/Applet/SwkbdAppletDialog.axaml.cs @@ -111,7 +111,7 @@ namespace Ryujinx.Ava.Ui.Controls overlay.Position = window.PointToScreen(new Point()); - await contentDialog.ShowAsync(); + await contentDialog.ShowAsync(overlay); contentDialog.Closed -= handler; overlay.Close(); }; diff --git a/Ryujinx.Ava/Ui/Controls/EmbeddedWindow.cs b/Ryujinx.Ava/Ui/Controls/EmbeddedWindow.cs index 260075911..05b2cc5bd 100644 --- a/Ryujinx.Ava/Ui/Controls/EmbeddedWindow.cs +++ b/Ryujinx.Ava/Ui/Controls/EmbeddedWindow.cs @@ -125,9 +125,9 @@ namespace Ryujinx.Ava.Ui.Controls { cbSize = Marshal.SizeOf(), hInstance = GetModuleHandle(null), - lpfnWndProc = _wndProcDelegate, + lpfnWndProc = Marshal.GetFunctionPointerForDelegate(_wndProcDelegate), style = ClassStyles.CS_OWNDC, - lpszClassName = _className, + lpszClassName = Marshal.StringToHGlobalUni(_className), hCursor = LoadCursor(IntPtr.Zero, (IntPtr)Cursors.IDC_ARROW) }; @@ -148,7 +148,9 @@ namespace Ryujinx.Ava.Ui.Controls IntPtr.Zero); WindowHandle = handle; - + + Marshal.FreeHGlobal(wndClassEx.lpszClassName); + return new PlatformHandle(WindowHandle, "HWND"); } diff --git a/Ryujinx.Ava/Ui/Controls/Win32NativeInterop.cs b/Ryujinx.Ava/Ui/Controls/Win32NativeInterop.cs index 124536d99..81e2fee90 100644 --- a/Ryujinx.Ava/Ui/Controls/Win32NativeInterop.cs +++ b/Ryujinx.Ava/Ui/Controls/Win32NativeInterop.cs @@ -5,7 +5,7 @@ using System.Runtime.Versioning; namespace Ryujinx.Ava.Ui.Controls { [SupportedOSPlatform("windows")] - internal class Win32NativeInterop + internal partial class Win32NativeInterop { [Flags] public enum ClassStyles : uint @@ -48,58 +48,52 @@ namespace Ryujinx.Ava.Ui.Controls [UnmanagedFunctionPointer(CallingConvention.Winapi)] internal delegate IntPtr WindowProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam); - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + [StructLayout(LayoutKind.Sequential)] public struct WNDCLASSEX { public int cbSize; public ClassStyles style; - [MarshalAs(UnmanagedType.FunctionPtr)] - public WindowProc lpfnWndProc; // not WndProc + public IntPtr lpfnWndProc; // not WndProc public int cbClsExtra; public int cbWndExtra; public IntPtr hInstance; public IntPtr hIcon; public IntPtr hCursor; public IntPtr hbrBackground; - [MarshalAs(UnmanagedType.LPWStr)] - public string lpszMenuName; - [MarshalAs(UnmanagedType.LPWStr)] - public string lpszClassName; + public IntPtr lpszMenuName; + public IntPtr lpszClassName; public IntPtr hIconSm; - public static WNDCLASSEX Create() + public WNDCLASSEX() { - return new WNDCLASSEX - { - cbSize = Marshal.SizeOf() - }; + cbSize = Marshal.SizeOf(); } } - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern ushort RegisterClassEx(ref WNDCLASSEX param); + [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "RegisterClassExW")] + public static partial ushort RegisterClassEx(ref WNDCLASSEX param); - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern short UnregisterClass([MarshalAs(UnmanagedType.LPWStr)] string lpClassName, IntPtr instance); + [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "UnregisterClassW")] + public static partial short UnregisterClass([MarshalAs(UnmanagedType.LPWStr)] string lpClassName, IntPtr instance); - [DllImport("user32.dll", CharSet = CharSet.Unicode)] - public static extern IntPtr DefWindowProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam); + [LibraryImport("user32.dll", EntryPoint = "DefWindowProcW")] + public static partial IntPtr DefWindowProc(IntPtr hWnd, WindowsMessages msg, IntPtr wParam, IntPtr lParam); - [DllImport("kernel32.dll")] - public static extern IntPtr GetModuleHandle(string lpModuleName); + [LibraryImport("kernel32.dll", EntryPoint = "GetModuleHandleA")] + public static partial IntPtr GetModuleHandle([MarshalAs(UnmanagedType.LPStr)] string lpModuleName); - [DllImport("user32.dll", SetLastError = true)] + [LibraryImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool DestroyWindow(IntPtr hwnd); + public static partial bool DestroyWindow(IntPtr hwnd); - [DllImport("user32.dll", SetLastError = true)] - public static extern IntPtr LoadCursor(IntPtr hInstance, IntPtr lpCursorName); + [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "LoadCursorA")] + public static partial IntPtr LoadCursor(IntPtr hInstance, IntPtr lpCursorName); - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr CreateWindowEx( + [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowExW")] + public static partial IntPtr CreateWindowEx( uint dwExStyle, - string lpClassName, - string lpWindowName, + [MarshalAs(UnmanagedType.LPWStr)] string lpClassName, + [MarshalAs(UnmanagedType.LPWStr)] string lpWindowName, WindowStyles dwStyle, int x, int y, diff --git a/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs b/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs index ad2236310..c5be6e376 100644 --- a/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs +++ b/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs @@ -5,7 +5,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.Common.GraphicsDriver { - static class NVThreadedOptimization + static partial class NVThreadedOptimization { private const string ProfileName = "Ryujinx Nvidia Profile"; @@ -19,8 +19,8 @@ namespace Ryujinx.Common.GraphicsDriver private const uint NvAPI_DRS_SaveSettings_ID = 0xFCBC7E14; private const uint NvAPI_DRS_DestroySession_ID = 0x0DAD9CFF8; - [DllImport("nvapi64")] - private static extern IntPtr nvapi_QueryInterface(uint id); + [LibraryImport("nvapi64")] + private static partial IntPtr nvapi_QueryInterface(uint id); private delegate int NvAPI_InitializeDelegate(); private static NvAPI_InitializeDelegate NvAPI_Initialize; @@ -152,7 +152,7 @@ namespace Ryujinx.Common.GraphicsDriver if (ptr != IntPtr.Zero) { - return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T; + return Marshal.GetDelegateForFunctionPointer(ptr); } else { diff --git a/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs b/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs index 7a14e616f..3463d06cf 100644 --- a/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs +++ b/Ryujinx.Common/Memory/PartialUnmaps/PartialUnmapState.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; using System.Runtime.Versioning; using System.Threading; @@ -12,7 +13,7 @@ namespace Ryujinx.Common.Memory.PartialUnmaps /// State for partial unmaps. Intended to be used on Windows. /// [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct PartialUnmapState + public partial struct PartialUnmapState { public NativeReaderWriterLock PartialUnmapLock; public int PartialUnmapsCount; @@ -25,20 +26,22 @@ namespace Ryujinx.Common.Memory.PartialUnmaps public readonly static IntPtr GlobalState; [SupportedOSPlatform("windows")] - [DllImport("kernel32.dll")] - public static extern int GetCurrentThreadId(); + [LibraryImport("kernel32.dll")] + public static partial int GetCurrentThreadId(); [SupportedOSPlatform("windows")] - [DllImport("kernel32.dll", SetLastError = true)] - static extern IntPtr OpenThread(int dwDesiredAccess, bool bInheritHandle, uint dwThreadId); + [LibraryImport("kernel32.dll", SetLastError = true)] + private static partial IntPtr OpenThread(int dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwThreadId); [SupportedOSPlatform("windows")] - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool CloseHandle(IntPtr hObject); + [LibraryImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs (UnmanagedType.Bool)] + public static partial bool CloseHandle(IntPtr hObject); [SupportedOSPlatform("windows")] - [DllImport("kernel32.dll", SetLastError = true)] - static extern bool GetExitCodeThread(IntPtr hThread, out uint lpExitCode); + [LibraryImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool GetExitCodeThread(IntPtr hThread, out uint lpExitCode); /// /// Creates a global static PartialUnmapState and populates the field offsets. diff --git a/Ryujinx.Common/Ryujinx.Common.csproj b/Ryujinx.Common/Ryujinx.Common.csproj index 9a83c2b4b..ca5de76a6 100644 --- a/Ryujinx.Common/Ryujinx.Common.csproj +++ b/Ryujinx.Common/Ryujinx.Common.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs b/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs index 3fcb1a253..ad022bdf0 100644 --- a/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs +++ b/Ryujinx.Common/SystemInfo/MacOSSystemInfo.cs @@ -8,7 +8,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.Common.SystemInfo { [SupportedOSPlatform("macos")] - class MacOSSystemInfo : SystemInfo + partial class MacOSSystemInfo : SystemInfo { internal MacOSSystemInfo() { @@ -60,8 +60,8 @@ namespace Ryujinx.Common.SystemInfo private const string SystemLibraryName = "libSystem.dylib"; - [DllImport(SystemLibraryName, CharSet = CharSet.Ansi, SetLastError = true)] - private static extern int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize); + [LibraryImport(SystemLibraryName, SetLastError = true)] + private static partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, IntPtr oldValue, ref ulong oldSize, IntPtr newValue, ulong newValueSize); private static int sysctlbyname(string name, IntPtr oldValue, ref ulong oldSize) { @@ -116,11 +116,11 @@ namespace Ryujinx.Common.SystemInfo return res; } - [DllImport(SystemLibraryName, CharSet = CharSet.Ansi, SetLastError = true)] - private static extern uint mach_host_self(); + [LibraryImport(SystemLibraryName, SetLastError = true)] + private static partial uint mach_host_self(); - [DllImport(SystemLibraryName, CharSet = CharSet.Ansi, SetLastError = true)] - private static extern int host_page_size(uint host, ref uint out_page_size); + [LibraryImport(SystemLibraryName, SetLastError = true)] + private static partial int host_page_size(uint host, ref uint out_page_size); [StructLayout(LayoutKind.Sequential, Pack = 8)] struct VMStatistics64 @@ -151,7 +151,7 @@ namespace Ryujinx.Common.SystemInfo public ulong TotalUncompressedPagesInCompressor; } - [DllImport(SystemLibraryName, CharSet = CharSet.Ansi, SetLastError = true)] - private static extern int host_statistics64(uint host_priv, int host_flavor, ref VMStatistics64 host_info64_out, ref uint host_info64_outCnt); + [LibraryImport(SystemLibraryName, SetLastError = true)] + private static partial int host_statistics64(uint host_priv, int host_flavor, ref VMStatistics64 host_info64_out, ref uint host_info64_outCnt); } } \ No newline at end of file diff --git a/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs index ed301e021..11f0785e6 100644 --- a/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs +++ b/Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs @@ -7,7 +7,7 @@ using Ryujinx.Common.Logging; namespace Ryujinx.Common.SystemInfo { [SupportedOSPlatform("windows")] - class WindowsSystemInfo : SystemInfo + partial class WindowsSystemInfo : SystemInfo { internal WindowsSystemInfo() { @@ -18,7 +18,7 @@ namespace Ryujinx.Common.SystemInfo private static (ulong Total, ulong Available) GetMemoryStats() { MemoryStatusEx memStatus = new MemoryStatusEx(); - if (GlobalMemoryStatusEx(memStatus)) + if (GlobalMemoryStatusEx(ref memStatus)) { return (memStatus.TotalPhys, memStatus.AvailPhys); // Bytes } @@ -45,8 +45,8 @@ namespace Ryujinx.Common.SystemInfo return Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER").Trim(); } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - private class MemoryStatusEx + [StructLayout(LayoutKind.Sequential)] + private struct MemoryStatusEx { public uint Length; public uint MemoryLoad; @@ -60,13 +60,13 @@ namespace Ryujinx.Common.SystemInfo public MemoryStatusEx() { - Length = (uint)Marshal.SizeOf(typeof(MemoryStatusEx)); + Length = (uint)Marshal.SizeOf(); } } + [LibraryImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern bool GlobalMemoryStatusEx([In, Out] MemoryStatusEx lpBuffer); + private static partial bool GlobalMemoryStatusEx(ref MemoryStatusEx lpBuffer); private static ManagementObjectCollection GetWMIObjects(string scope, string query) { diff --git a/Ryujinx.Common/System/DisplaySleep.cs b/Ryujinx.Common/SystemInterop/DisplaySleep.cs similarity index 76% rename from Ryujinx.Common/System/DisplaySleep.cs rename to Ryujinx.Common/SystemInterop/DisplaySleep.cs index bad964b9d..5a1f66f50 100644 --- a/Ryujinx.Common/System/DisplaySleep.cs +++ b/Ryujinx.Common/SystemInterop/DisplaySleep.cs @@ -1,9 +1,9 @@ using System; using System.Runtime.InteropServices; -namespace Ryujinx.Common.System +namespace Ryujinx.Common.SystemInterop { - public class DisplaySleep + public partial class DisplaySleep { [Flags] enum EXECUTION_STATE : uint @@ -13,8 +13,8 @@ namespace Ryujinx.Common.System ES_SYSTEM_REQUIRED = 0x00000001 } - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); + [LibraryImport("kernel32.dll", SetLastError = true)] + private static partial EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); static public void Prevent() { diff --git a/Ryujinx.Common/System/ForceDpiAware.cs b/Ryujinx.Common/SystemInterop/ForceDpiAware.cs similarity index 75% rename from Ryujinx.Common/System/ForceDpiAware.cs rename to Ryujinx.Common/SystemInterop/ForceDpiAware.cs index 8d19876e8..f17612a6d 100644 --- a/Ryujinx.Common/System/ForceDpiAware.cs +++ b/Ryujinx.Common/SystemInterop/ForceDpiAware.cs @@ -3,29 +3,30 @@ using System; using System.Globalization; using System.Runtime.InteropServices; -namespace Ryujinx.Common.System +namespace Ryujinx.Common.SystemInterop { - public static class ForceDpiAware + public static partial class ForceDpiAware { - [DllImport("user32.dll")] - private static extern bool SetProcessDPIAware(); + [LibraryImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool SetProcessDPIAware(); private const string X11LibraryName = "libX11.so.6"; - [DllImport(X11LibraryName)] - private static extern IntPtr XOpenDisplay(string display); + [LibraryImport(X11LibraryName)] + private static partial IntPtr XOpenDisplay([MarshalAs(UnmanagedType.LPStr)] string display); - [DllImport(X11LibraryName)] - private static extern IntPtr XGetDefault(IntPtr display, string program, string option); + [LibraryImport(X11LibraryName)] + private static partial IntPtr XGetDefault(IntPtr display, [MarshalAs(UnmanagedType.LPStr)] string program, [MarshalAs(UnmanagedType.LPStr)] string option); - [DllImport(X11LibraryName)] - private static extern int XDisplayWidth(IntPtr display, int screenNumber); + [LibraryImport(X11LibraryName)] + private static partial int XDisplayWidth(IntPtr display, int screenNumber); - [DllImport(X11LibraryName)] - private static extern int XDisplayWidthMM(IntPtr display, int screenNumber); + [LibraryImport(X11LibraryName)] + private static partial int XDisplayWidthMM(IntPtr display, int screenNumber); - [DllImport(X11LibraryName)] - private static extern int XCloseDisplay(IntPtr display); + [LibraryImport(X11LibraryName)] + private static partial int XCloseDisplay(IntPtr display); private static readonly double _standardDpiScale = 96.0; private static readonly double _maxScaleFactor = 1.25; diff --git a/Ryujinx.Common/System/GdiPlusHelper.cs b/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs similarity index 74% rename from Ryujinx.Common/System/GdiPlusHelper.cs rename to Ryujinx.Common/SystemInterop/GdiPlusHelper.cs index c084c6510..1001424df 100644 --- a/Ryujinx.Common/System/GdiPlusHelper.cs +++ b/Ryujinx.Common/SystemInterop/GdiPlusHelper.cs @@ -2,10 +2,10 @@ using System.Runtime.InteropServices; using System.Runtime.Versioning; -namespace Ryujinx.Common.System +namespace Ryujinx.Common.SystemInterop { [SupportedOSPlatform("windows")] - public static class GdiPlusHelper + public static partial class GdiPlusHelper { private const string LibraryName = "gdiplus.dll"; @@ -52,17 +52,17 @@ namespace Ryujinx.Common.System public IntPtr NotificationUnhook; } - [DllImport(LibraryName)] - private static extern int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output); + [LibraryImport(LibraryName)] + private static partial int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output); - [DllImport(LibraryName)] - private static extern int GdipCreateFromHWND(IntPtr hwnd, out IntPtr graphics); + [LibraryImport(LibraryName)] + private static partial int GdipCreateFromHWND(IntPtr hwnd, out IntPtr graphics); - [DllImport(LibraryName)] - private static extern int GdipDeleteGraphics(IntPtr graphics); + [LibraryImport(LibraryName)] + private static partial int GdipDeleteGraphics(IntPtr graphics); - [DllImport(LibraryName)] - private static extern int GdipGetDpiX(IntPtr graphics, out float dpi); + [LibraryImport(LibraryName)] + private static partial int GdipGetDpiX(IntPtr graphics, out float dpi); public static float GetDpiX(IntPtr hwnd) { diff --git a/Ryujinx.Common/System/WindowsMultimediaTimerResolution.cs b/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs similarity index 84% rename from Ryujinx.Common/System/WindowsMultimediaTimerResolution.cs rename to Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs index d19fbe73d..a4fbf0bd4 100644 --- a/Ryujinx.Common/System/WindowsMultimediaTimerResolution.cs +++ b/Ryujinx.Common/SystemInterop/WindowsMultimediaTimerResolution.cs @@ -4,13 +4,13 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; -namespace Ryujinx.Common.System +namespace Ryujinx.Common.SystemInterop { /// /// Handle Windows Multimedia timer resolution. /// [SupportedOSPlatform("windows")] - public class WindowsMultimediaTimerResolution : IDisposable + public partial class WindowsMultimediaTimerResolution : IDisposable { [StructLayout(LayoutKind.Sequential)] public struct TimeCaps @@ -19,14 +19,14 @@ namespace Ryujinx.Common.System public uint wPeriodMax; }; - [DllImport("winmm.dll", EntryPoint = "timeGetDevCaps", SetLastError = true)] - private static extern uint TimeGetDevCaps(ref TimeCaps timeCaps, uint sizeTimeCaps); + [LibraryImport("winmm.dll", EntryPoint = "timeGetDevCaps", SetLastError = true)] + private static partial uint TimeGetDevCaps(ref TimeCaps timeCaps, uint sizeTimeCaps); - [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")] - private static extern uint TimeBeginPeriod(uint uMilliseconds); + [LibraryImport("winmm.dll", EntryPoint = "timeBeginPeriod")] + private static partial uint TimeBeginPeriod(uint uMilliseconds); - [DllImport("winmm.dll", EntryPoint = "timeEndPeriod")] - private static extern uint TimeEndPeriod(uint uMilliseconds); + [LibraryImport("winmm.dll", EntryPoint = "timeEndPeriod")] + private static partial uint TimeEndPeriod(uint uMilliseconds); private uint _targetResolutionInMilliseconds; private bool _isActive; diff --git a/Ryujinx.Graphics.Device/DeviceState.cs b/Ryujinx.Graphics.Device/DeviceState.cs index 181005715..a9b446e18 100644 --- a/Ryujinx.Graphics.Device/DeviceState.cs +++ b/Ryujinx.Graphics.Device/DeviceState.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Device { - public class DeviceState : IDeviceState where TState : unmanaged + public class DeviceState<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TState> : IDeviceState where TState : unmanaged { private const int RegisterSize = sizeof(int); diff --git a/Ryujinx.Graphics.Gpu/Engine/DeviceStateWithShadow.cs b/Ryujinx.Graphics.Gpu/Engine/DeviceStateWithShadow.cs index 3a06bc2a6..74a9aa049 100644 --- a/Ryujinx.Graphics.Gpu/Engine/DeviceStateWithShadow.cs +++ b/Ryujinx.Graphics.Gpu/Engine/DeviceStateWithShadow.cs @@ -2,6 +2,7 @@ using Ryujinx.Graphics.Device; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Ryujinx.Graphics.Gpu.Engine @@ -21,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Engine /// Represents a device's state, with a additional shadow state. /// /// Type of the state - class DeviceStateWithShadow : IDeviceState where TState : unmanaged, IShadowState + class DeviceStateWithShadow<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TState> : IDeviceState where TState : unmanaged, IShadowState { private readonly DeviceState _state; private readonly DeviceState _shadowState; diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs index 5a659f555..cd14259a6 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs @@ -98,7 +98,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// Method call argument public void DrawEnd(ThreedClass engine, int argument) { - DrawEnd(engine, _state.State.IndexBufferState.First, (int)_state.State.IndexBufferCount); + DrawEnd( + engine, + _state.State.IndexBufferState.First, + (int)_state.State.IndexBufferCount, + _state.State.VertexBufferDrawState.First, + _state.State.VertexBufferDrawState.Count); } /// @@ -108,7 +113,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// 3D engine where this method is being called /// Index of the first index buffer element used on the draw /// Number of index buffer elements used on the draw - private void DrawEnd(ThreedClass engine, int firstIndex, int indexCount) + /// Index of the first vertex used on the draw + /// Number of vertices used on the draw + private void DrawEnd(ThreedClass engine, int firstIndex, int indexCount, int drawFirstVertex, int drawVertexCount) { ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable( _context, @@ -195,7 +202,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed { var drawState = _state.State.VertexBufferDrawState; - _context.Renderer.Pipeline.Draw(drawState.Count, 1, drawState.First, firstInstance); + _context.Renderer.Pipeline.Draw(drawVertexCount, 1, drawFirstVertex, firstInstance); } _drawState.DrawIndexed = false; @@ -216,16 +223,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed bool incrementInstance = (argument & (1 << 26)) != 0; bool resetInstance = (argument & (1 << 27)) == 0; - if (_state.State.PrimitiveTypeOverrideEnable) - { - PrimitiveTypeOverride typeOverride = _state.State.PrimitiveTypeOverride; - DrawBegin(incrementInstance, resetInstance, typeOverride.Convert()); - } - else - { - PrimitiveType type = (PrimitiveType)(argument & 0xffff); - DrawBegin(incrementInstance, resetInstance, type.Convert()); - } + PrimitiveType type = (PrimitiveType)(argument & 0xffff); + DrawBegin(incrementInstance, resetInstance, type); } /// @@ -234,8 +233,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// /// Indicates if the current instance should be incremented /// Indicates if the current instance should be set to zero - /// Primitive topology - private void DrawBegin(bool incrementInstance, bool resetInstance, PrimitiveTopology topology) + /// Primitive type + private void DrawBegin(bool incrementInstance, bool resetInstance, PrimitiveType primitiveType) { if (incrementInstance) { @@ -248,6 +247,18 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _instanceIndex = 0; } + PrimitiveTopology topology; + + if (_state.State.PrimitiveTypeOverrideEnable) + { + PrimitiveTypeOverride typeOverride = _state.State.PrimitiveTypeOverride; + topology = typeOverride.Convert(); + } + else + { + topology = primitiveType.Convert(); + } + UpdateTopology(topology); } @@ -276,46 +287,70 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _drawState.DrawIndexed = true; } + // TODO: Verify if the index type is implied from the method that is called, + // or if it uses the state index type on hardware. + /// - /// Performs a indexed draw with a low number of index buffer elements. + /// Performs a indexed draw with 8-bit index buffer elements. /// /// 3D engine where this method is being called /// Method call argument - public void DrawIndexedSmall(ThreedClass engine, int argument) + public void DrawIndexBuffer8BeginEndInstanceFirst(ThreedClass engine, int argument) { - DrawIndexedSmall(engine, argument, false); + DrawIndexBufferBeginEndInstance(engine, argument, false); } /// - /// Performs a indexed draw with a low number of index buffer elements. + /// Performs a indexed draw with 16-bit index buffer elements. /// /// 3D engine where this method is being called /// Method call argument - public void DrawIndexedSmall2(ThreedClass engine, int argument) + public void DrawIndexBuffer16BeginEndInstanceFirst(ThreedClass engine, int argument) { - DrawIndexedSmall(engine, argument); + DrawIndexBufferBeginEndInstance(engine, argument, false); } /// - /// Performs a indexed draw with a low number of index buffer elements, + /// Performs a indexed draw with 32-bit index buffer elements. + /// + /// 3D engine where this method is being called + /// Method call argument + public void DrawIndexBuffer32BeginEndInstanceFirst(ThreedClass engine, int argument) + { + DrawIndexBufferBeginEndInstance(engine, argument, false); + } + + /// + /// Performs a indexed draw with 8-bit index buffer elements, /// while also pre-incrementing the current instance value. /// /// 3D engine where this method is being called /// Method call argument - public void DrawIndexedSmallIncInstance(ThreedClass engine, int argument) + public void DrawIndexBuffer8BeginEndInstanceSubsequent(ThreedClass engine, int argument) { - DrawIndexedSmall(engine, argument, true); + DrawIndexBufferBeginEndInstance(engine, argument, true); } /// - /// Performs a indexed draw with a low number of index buffer elements, + /// Performs a indexed draw with 16-bit index buffer elements, /// while also pre-incrementing the current instance value. /// /// 3D engine where this method is being called /// Method call argument - public void DrawIndexedSmallIncInstance2(ThreedClass engine, int argument) + public void DrawIndexBuffer16BeginEndInstanceSubsequent(ThreedClass engine, int argument) { - DrawIndexedSmallIncInstance(engine, argument); + DrawIndexBufferBeginEndInstance(engine, argument, true); + } + + /// + /// Performs a indexed draw with 32-bit index buffer elements, + /// while also pre-incrementing the current instance value. + /// + /// 3D engine where this method is being called + /// Method call argument + public void DrawIndexBuffer32BeginEndInstanceSubsequent(ThreedClass engine, int argument) + { + DrawIndexBufferBeginEndInstance(engine, argument, true); } /// @@ -325,11 +360,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// 3D engine where this method is being called /// Method call argument /// True to increment the current instance value, false otherwise - private void DrawIndexedSmall(ThreedClass engine, int argument, bool instanced) + private void DrawIndexBufferBeginEndInstance(ThreedClass engine, int argument, bool instanced) { - PrimitiveTypeOverride typeOverride = _state.State.PrimitiveTypeOverride; - - DrawBegin(instanced, !instanced, typeOverride.Convert()); + DrawBegin(instanced, !instanced, (PrimitiveType)((argument >> 28) & 0xf)); int firstIndex = argument & 0xffff; int indexCount = (argument >> 16) & 0xfff; @@ -339,7 +372,51 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _drawState.DrawIndexed = true; engine.ForceStateDirty(IndexBufferCountMethodOffset * 4); - DrawEnd(engine, firstIndex, indexCount); + DrawEnd(engine, firstIndex, indexCount, 0, 0); + + _drawState.DrawIndexed = oldDrawIndexed; + } + + /// + /// Performs a non-indexed draw with the specified topology, index and count. + /// + /// 3D engine where this method is being called + /// Method call argument + public void DrawVertexArrayBeginEndInstanceFirst(ThreedClass engine, int argument) + { + DrawVertexArrayBeginEndInstance(engine, argument, false); + } + + /// + /// Performs a non-indexed draw with the specified topology, index and count, + /// while incrementing the current instance. + /// + /// 3D engine where this method is being called + /// Method call argument + public void DrawVertexArrayBeginEndInstanceSubsequent(ThreedClass engine, int argument) + { + DrawVertexArrayBeginEndInstance(engine, argument, true); + } + + /// + /// Performs a indexed draw with a low number of index buffer elements, + /// while optionally also pre-incrementing the current instance value. + /// + /// 3D engine where this method is being called + /// Method call argument + /// True to increment the current instance value, false otherwise + private void DrawVertexArrayBeginEndInstance(ThreedClass engine, int argument, bool instanced) + { + DrawBegin(instanced, !instanced, (PrimitiveType)((argument >> 28) & 0xf)); + + int firstVertex = argument & 0xffff; + int vertexCount = (argument >> 16) & 0xfff; + + bool oldDrawIndexed = _drawState.DrawIndexed; + + _drawState.DrawIndexed = false; + + DrawEnd(engine, 0, 0, firstVertex, vertexCount); _drawState.DrawIndexed = oldDrawIndexed; } diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs index 628eb46a7..3ed5607a4 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -39,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// GPU state update tracker. /// /// State type - class StateUpdateTracker + class StateUpdateTracker<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TState> { private const int BlockSize = 0xe00; private const int RegisterSize = sizeof(uint); diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs index 572f7fb01..014a17398 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs @@ -1,7 +1,5 @@ using Ryujinx.Common.Logging; -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Gpu.Engine.GPFifo; using Ryujinx.Graphics.Gpu.Engine.Types; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Shader; @@ -1295,7 +1293,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++) { - _currentProgramInfo[stageIndex] = gs.Shaders[stageIndex + 1]?.Info; + ShaderProgramInfo info = gs.Shaders[stageIndex + 1]?.Info; + + if (info?.UsesRtLayer == true) + { + _vtgWritesRtLayer = true; + } + + _currentProgramInfo[stageIndex] = info; } _context.Renderer.Pipeline.SetProgram(gs.HostProgram); diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs index b254e95e0..87dd1d8ee 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs @@ -42,6 +42,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed { nameof(ThreedClassState.TextureBarrier), new RwCallback(TextureBarrier, null) }, { nameof(ThreedClassState.TextureBarrierTiled), new RwCallback(TextureBarrierTiled, null) }, { nameof(ThreedClassState.DrawTextureSrcY), new RwCallback(DrawTexture, null) }, + { nameof(ThreedClassState.DrawVertexArrayBeginEndInstanceFirst), new RwCallback(DrawVertexArrayBeginEndInstanceFirst, null) }, + { nameof(ThreedClassState.DrawVertexArrayBeginEndInstanceSubsequent), new RwCallback(DrawVertexArrayBeginEndInstanceSubsequent, null) }, { nameof(ThreedClassState.VbElementU8), new RwCallback(VbElementU8, null) }, { nameof(ThreedClassState.VbElementU16), new RwCallback(VbElementU16, null) }, { nameof(ThreedClassState.VbElementU32), new RwCallback(VbElementU32, null) }, @@ -49,10 +51,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed { nameof(ThreedClassState.RenderEnableCondition), new RwCallback(null, Zero) }, { nameof(ThreedClassState.DrawEnd), new RwCallback(DrawEnd, null) }, { nameof(ThreedClassState.DrawBegin), new RwCallback(DrawBegin, null) }, - { nameof(ThreedClassState.DrawIndexedSmall), new RwCallback(DrawIndexedSmall, null) }, - { nameof(ThreedClassState.DrawIndexedSmall2), new RwCallback(DrawIndexedSmall2, null) }, - { nameof(ThreedClassState.DrawIndexedSmallIncInstance), new RwCallback(DrawIndexedSmallIncInstance, null) }, - { nameof(ThreedClassState.DrawIndexedSmallIncInstance2), new RwCallback(DrawIndexedSmallIncInstance2, null) }, + { nameof(ThreedClassState.DrawIndexBuffer32BeginEndInstanceFirst), new RwCallback(DrawIndexBuffer32BeginEndInstanceFirst, null) }, + { nameof(ThreedClassState.DrawIndexBuffer16BeginEndInstanceFirst), new RwCallback(DrawIndexBuffer16BeginEndInstanceFirst, null) }, + { nameof(ThreedClassState.DrawIndexBuffer8BeginEndInstanceFirst), new RwCallback(DrawIndexBuffer8BeginEndInstanceFirst, null) }, + { nameof(ThreedClassState.DrawIndexBuffer32BeginEndInstanceSubsequent), new RwCallback(DrawIndexBuffer32BeginEndInstanceSubsequent, null) }, + { nameof(ThreedClassState.DrawIndexBuffer16BeginEndInstanceSubsequent), new RwCallback(DrawIndexBuffer16BeginEndInstanceSubsequent, null) }, + { nameof(ThreedClassState.DrawIndexBuffer8BeginEndInstanceSubsequent), new RwCallback(DrawIndexBuffer8BeginEndInstanceSubsequent, null) }, { nameof(ThreedClassState.IndexBufferCount), new RwCallback(SetIndexBufferCount, null) }, { nameof(ThreedClassState.Clear), new RwCallback(Clear, null) }, { nameof(ThreedClassState.SemaphoreControl), new RwCallback(Report, null) }, @@ -303,6 +307,25 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _drawManager.DrawTexture(this, argument); } + /// + /// Performs a non-indexed draw with the specified topology, index and count. + /// + /// Method call argument + private void DrawVertexArrayBeginEndInstanceFirst(int argument) + { + _drawManager.DrawVertexArrayBeginEndInstanceFirst(this, argument); + } + + /// + /// Performs a non-indexed draw with the specified topology, index and count, + /// while incrementing the current instance. + /// + /// Method call argument + private void DrawVertexArrayBeginEndInstanceSubsequent(int argument) + { + _drawManager.DrawVertexArrayBeginEndInstanceSubsequent(this, argument); + } + /// /// Pushes four 8-bit index buffer elements. /// @@ -370,41 +393,60 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed } /// - /// Performs a indexed draw with a low number of index buffer elements. + /// Performs a indexed draw with 8-bit index buffer elements. /// /// Method call argument - private void DrawIndexedSmall(int argument) + private void DrawIndexBuffer8BeginEndInstanceFirst(int argument) { - _drawManager.DrawIndexedSmall(this, argument); + _drawManager.DrawIndexBuffer8BeginEndInstanceFirst(this, argument); } /// - /// Performs a indexed draw with a low number of index buffer elements. + /// Performs a indexed draw with 16-bit index buffer elements. /// /// Method call argument - private void DrawIndexedSmall2(int argument) + private void DrawIndexBuffer16BeginEndInstanceFirst(int argument) { - _drawManager.DrawIndexedSmall2(this, argument); + _drawManager.DrawIndexBuffer16BeginEndInstanceFirst(this, argument); } /// - /// Performs a indexed draw with a low number of index buffer elements, + /// Performs a indexed draw with 32-bit index buffer elements. + /// + /// Method call argument + private void DrawIndexBuffer32BeginEndInstanceFirst(int argument) + { + _drawManager.DrawIndexBuffer32BeginEndInstanceFirst(this, argument); + } + + /// + /// Performs a indexed draw with 8-bit index buffer elements, /// while also pre-incrementing the current instance value. /// /// Method call argument - private void DrawIndexedSmallIncInstance(int argument) + private void DrawIndexBuffer8BeginEndInstanceSubsequent(int argument) { - _drawManager.DrawIndexedSmallIncInstance(this, argument); + _drawManager.DrawIndexBuffer8BeginEndInstanceSubsequent(this, argument); } /// - /// Performs a indexed draw with a low number of index buffer elements, + /// Performs a indexed draw with 16-bit index buffer elements, /// while also pre-incrementing the current instance value. /// /// Method call argument - private void DrawIndexedSmallIncInstance2(int argument) + private void DrawIndexBuffer16BeginEndInstanceSubsequent(int argument) { - _drawManager.DrawIndexedSmallIncInstance2(this, argument); + _drawManager.DrawIndexBuffer16BeginEndInstanceSubsequent(this, argument); + } + + /// + /// Performs a indexed draw with 32-bit index buffer elements, + /// while also pre-incrementing the current instance value. + /// + /// Method call argument + private void DrawIndexBuffer32BeginEndInstanceSubsequent(int argument) + { + _drawManager.DrawIndexBuffer32BeginEndInstanceSubsequent(this, argument); } /// diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs index e416cd583..1498e27ba 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs @@ -813,7 +813,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed public uint ClearFlags; public fixed uint Reserved10FC[25]; public Array32 VertexAttribState; - public fixed uint Reserved11E0[15]; + public fixed uint Reserved11E0[13]; + public uint DrawVertexArrayBeginEndInstanceFirst; + public uint DrawVertexArrayBeginEndInstanceSubsequent; public RtControl RtControl; public fixed uint Reserved1220[2]; public Size3D RtDepthStencilSize; @@ -888,12 +890,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed public fixed uint Reserved164C[95]; public IndexBufferState IndexBufferState; public uint IndexBufferCount; - public uint DrawIndexedSmall; - public uint DrawIndexedSmall2; - public uint Reserved17EC; - public uint DrawIndexedSmallIncInstance; - public uint DrawIndexedSmallIncInstance2; - public fixed uint Reserved17F8[33]; + public uint DrawIndexBuffer32BeginEndInstanceFirst; + public uint DrawIndexBuffer16BeginEndInstanceFirst; + public uint DrawIndexBuffer8BeginEndInstanceFirst; + public uint DrawIndexBuffer32BeginEndInstanceSubsequent; + public uint DrawIndexBuffer16BeginEndInstanceSubsequent; + public uint DrawIndexBuffer8BeginEndInstanceSubsequent; + public fixed uint Reserved17FC[32]; public float DepthBiasClamp; public Array16 VertexBufferInstanced; public fixed uint Reserved18C0[20]; diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index e337dd9c0..bdc6f4d66 100644 --- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMinor = 2; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; - private const uint CodeGenVersion = 4069; + private const uint CodeGenVersion = 4106; private const string SharedTocFileName = "shared.toc"; private const string SharedDataFileName = "shared.data"; diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/ShaderBinarySerializer.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/ShaderBinarySerializer.cs index 0e5ce292c..5b430e1af 100644 --- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/ShaderBinarySerializer.cs +++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/ShaderBinarySerializer.cs @@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache { CachedShaderStage currentStage = stages[i]; - if (currentStage != null && currentStage.Info.Stage == stage && currentStage.Info != null) + if (currentStage?.Info != null && currentStage.Info.Stage == stage) { return ShaderCache.GetBindings(currentStage.Info); } diff --git a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs index 9bf71778b..d173a4129 100644 --- a/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs +++ b/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs @@ -5,7 +5,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { - static class FFmpegApi + static partial class FFmpegApi { public const string AvCodecLibraryName = "avcodec"; public const string AvUtilLibraryName = "avutil"; @@ -78,52 +78,52 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native public unsafe delegate void av_log_set_callback_callback(void* a0, AVLog level, [MarshalAs(UnmanagedType.LPUTF8Str)] string a2, byte* a3); - [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern AVFrame* av_frame_alloc(); + [LibraryImport(AvUtilLibraryName)] + internal static unsafe partial AVFrame* av_frame_alloc(); - [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern void av_frame_unref(AVFrame* frame); + [LibraryImport(AvUtilLibraryName)] + internal static unsafe partial void av_frame_unref(AVFrame* frame); - [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern void av_free(AVFrame* frame); + [LibraryImport(AvUtilLibraryName)] + internal static unsafe partial void av_free(AVFrame* frame); - [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern void av_log_set_level(AVLog level); + [LibraryImport(AvUtilLibraryName)] + internal static unsafe partial void av_log_set_level(AVLog level); - [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern void av_log_set_callback(av_log_set_callback_callback callback); + [LibraryImport(AvUtilLibraryName)] + internal static unsafe partial void av_log_set_callback(av_log_set_callback_callback callback); - [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern AVLog av_log_get_level(); + [LibraryImport(AvUtilLibraryName)] + internal static unsafe partial AVLog av_log_get_level(); - [DllImport(AvUtilLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern void av_log_format_line(void* ptr, AVLog level, [MarshalAs(UnmanagedType.LPUTF8Str)] string fmt, byte* vl, byte* line, int lineSize, int* printPrefix); + [LibraryImport(AvUtilLibraryName)] + internal static unsafe partial void av_log_format_line(void* ptr, AVLog level, [MarshalAs(UnmanagedType.LPUTF8Str)] string fmt, byte* vl, byte* line, int lineSize, int* printPrefix); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern AVCodec* avcodec_find_decoder(AVCodecID id); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial AVCodec* avcodec_find_decoder(AVCodecID id); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern AVCodecContext* avcodec_alloc_context3(AVCodec* codec); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial AVCodecContext* avcodec_alloc_context3(AVCodec* codec); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern int avcodec_open2(AVCodecContext* avctx, AVCodec* codec, void **options); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial int avcodec_open2(AVCodecContext* avctx, AVCodec* codec, void **options); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern int avcodec_close(AVCodecContext* avctx); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial int avcodec_close(AVCodecContext* avctx); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern void avcodec_free_context(AVCodecContext** avctx); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial void avcodec_free_context(AVCodecContext** avctx); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern AVPacket* av_packet_alloc(); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial AVPacket* av_packet_alloc(); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern void av_packet_unref(AVPacket* pkt); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial void av_packet_unref(AVPacket* pkt); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern void av_packet_free(AVPacket** pkt); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial void av_packet_free(AVPacket** pkt); - [DllImport(AvCodecLibraryName, CallingConvention = CallingConvention.Cdecl)] - internal static unsafe extern int avcodec_version(); + [LibraryImport(AvCodecLibraryName)] + internal static unsafe partial int avcodec_version(); } } diff --git a/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs b/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs index 7cc39708d..963549463 100644 --- a/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs +++ b/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs @@ -5,7 +5,7 @@ using System.Runtime.Versioning; namespace Ryujinx.Graphics.OpenGL.Helper { [SupportedOSPlatform("linux")] - internal static class GLXHelper + internal static partial class GLXHelper { private const string LibraryName = "glx.dll"; @@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.OpenGL.Helper }); } - [DllImport(LibraryName, EntryPoint = "glXGetCurrentContext")] - public static extern IntPtr GetCurrentContext(); + [LibraryImport(LibraryName, EntryPoint = "glXGetCurrentContext")] + public static partial IntPtr GetCurrentContext(); } } diff --git a/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs b/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs index b37134eb5..df497ae24 100644 --- a/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs +++ b/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs @@ -5,11 +5,11 @@ using System.Runtime.Versioning; namespace Ryujinx.Graphics.OpenGL.Helper { [SupportedOSPlatform("windows")] - internal static class WGLHelper + internal static partial class WGLHelper { private const string LibraryName = "OPENGL32.DLL"; - [DllImport(LibraryName, EntryPoint = "wglGetCurrentContext")] - public extern static IntPtr GetCurrentContext(); + [LibraryImport(LibraryName, EntryPoint = "wglGetCurrentContext")] + public static partial IntPtr GetCurrentContext(); } } diff --git a/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj b/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj index 9a4869cec..9fd2c48a5 100644 --- a/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj +++ b/Ryujinx.Graphics.OpenGL/Ryujinx.Graphics.OpenGL.csproj @@ -6,7 +6,7 @@ - + diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/ConstantFolding.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/ConstantFolding.cs index 092e52a98..ab33da195 100644 --- a/Ryujinx.Graphics.Shader/Translation/Optimizations/ConstantFolding.cs +++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/ConstantFolding.cs @@ -262,7 +262,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations value = (value >> operation.Index * 16) & 0xffff; - operation.TurnIntoCopy(ConstF(HalfConversion.HalfToSingle(value))); + operation.TurnIntoCopy(ConstF((float)BitConverter.UInt16BitsToHalf((ushort)value))); } private static void FPNegate(Operation operation) diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/HalfConversion.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/HalfConversion.cs deleted file mode 100644 index 960602726..000000000 --- a/Ryujinx.Graphics.Shader/Translation/Optimizations/HalfConversion.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.Translation.Optimizations -{ - static class HalfConversion - { - public static float HalfToSingle(int value) - { - int mantissa = (value >> 0) & 0x3ff; - int exponent = (value >> 10) & 0x1f; - int sign = (value >> 15) & 0x1; - - if (exponent == 0x1f) - { - // NaN or Infinity. - mantissa <<= 13; - exponent = 0xff; - } - else if (exponent != 0 || mantissa != 0 ) - { - if (exponent == 0) - { - // Denormal. - int e = -1; - int m = mantissa; - - do - { - e++; - m <<= 1; - } - while ((m & 0x400) == 0); - - mantissa = m & 0x3ff; - exponent = e; - } - - mantissa <<= 13; - exponent = 127 - 15 + exponent; - } - - int output = (sign << 31) | (exponent << 23) | mantissa; - - return BitConverter.Int32BitsToSingle(output); - } - } -} \ No newline at end of file diff --git a/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj b/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj index e4e199e96..87f14a6ab 100644 --- a/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj +++ b/Ryujinx.Graphics.Vulkan/Ryujinx.Graphics.Vulkan.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -13,14 +13,14 @@ - - - - - - - - + + + + + + + + diff --git a/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs b/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs index 942970c27..68462825f 100644 --- a/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs +++ b/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs @@ -374,7 +374,24 @@ namespace Ryujinx.Graphics.Vulkan api.GetPhysicalDeviceProperties(physicalDevice, out var properties); bool useRobustBufferAccess = VendorUtils.FromId(properties.VendorID) == Vendor.Nvidia; - var supportedFeatures = api.GetPhysicalDeviceFeature(physicalDevice); + PhysicalDeviceFeatures2 features2 = new PhysicalDeviceFeatures2() + { + SType = StructureType.PhysicalDeviceFeatures2 + }; + + PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColorSupported = new PhysicalDeviceCustomBorderColorFeaturesEXT() + { + SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt + }; + + if (supportedExtensions.Contains("VK_EXT_custom_border_color")) + { + features2.PNext = &featuresCustomBorderColorSupported; + } + + api.GetPhysicalDeviceFeatures2(physicalDevice, &features2); + + var supportedFeatures = features2.Features; var features = new PhysicalDeviceFeatures() { @@ -491,6 +508,23 @@ namespace Ryujinx.Graphics.Vulkan pExtendedFeatures = &featuresSubgroupSizeControl; } + PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColor; + + if (supportedExtensions.Contains("VK_EXT_custom_border_color") && + featuresCustomBorderColorSupported.CustomBorderColors && + featuresCustomBorderColorSupported.CustomBorderColorWithoutFormat) + { + featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT() + { + SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt, + PNext = pExtendedFeatures, + CustomBorderColors = true, + CustomBorderColorWithoutFormat = true, + }; + + pExtendedFeatures = &featuresCustomBorderColor; + } + var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray(); IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length]; diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index e94720672..fa9d4cb0c 100644 --- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -177,6 +177,11 @@ namespace Ryujinx.Graphics.Vulkan SType = StructureType.PhysicalDeviceShaderFloat16Int8Features }; + PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT() + { + SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt + }; + if (supportedExtensions.Contains("VK_EXT_robustness2")) { features2.PNext = &featuresRobustness2; @@ -188,8 +193,18 @@ namespace Ryujinx.Graphics.Vulkan features2.PNext = &featuresShaderInt8; } + if (supportedExtensions.Contains("VK_EXT_custom_border_color")) + { + featuresCustomBorderColor.PNext = features2.PNext; + features2.PNext = &featuresCustomBorderColor; + } + Api.GetPhysicalDeviceFeatures2(_physicalDevice, &features2); + bool customBorderColorSupported = supportedExtensions.Contains("VK_EXT_custom_border_color") && + featuresCustomBorderColor.CustomBorderColors && + featuresCustomBorderColor.CustomBorderColorWithoutFormat; + ref var properties = ref properties2.Properties; SampleCountFlags supportedSampleCounts = @@ -199,7 +214,7 @@ namespace Ryujinx.Graphics.Vulkan Capabilities = new HardwareCapabilities( supportedExtensions.Contains("VK_EXT_index_type_uint8"), - supportedExtensions.Contains("VK_EXT_custom_border_color"), + customBorderColorSupported, supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName), supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"), supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"), diff --git a/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs index bd321f6fe..ba7efbd7d 100644 --- a/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs +++ b/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs @@ -47,7 +47,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error _errorStorage = _normalSession.Pop(); _errorCommonHeader = IApplet.ReadStruct(_errorStorage); - _errorStorage = _errorStorage.Skip(Marshal.SizeOf(typeof(ErrorCommonHeader))).ToArray(); + _errorStorage = _errorStorage.Skip(Marshal.SizeOf()).ToArray(); switch (_errorCommonHeader.Type) { diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs index 74073420f..4077ad420 100644 --- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs +++ b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs @@ -9,6 +9,7 @@ using Ryujinx.HLE.Ui.Input; using Ryujinx.Memory; using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -797,7 +798,7 @@ namespace Ryujinx.HLE.HOS.Applets return sb.ToString(); } - private static T ReadStruct(byte[] data) + private static T ReadStruct<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(byte[] data) where T : struct { GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); diff --git a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs index fc0c06479..f4ad03661 100644 --- a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs +++ b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/NfpManager/INfp.cs @@ -589,9 +589,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp ulong outputPosition = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(TagInfo))); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf()); - MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(TagInfo))); + MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf()); uint deviceHandle = (uint)context.RequestData.ReadUInt64(); @@ -665,9 +665,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp ulong outputPosition = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(RegisterInfo))); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf()); - MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(RegisterInfo))); + MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf()); uint deviceHandle = (uint)context.RequestData.ReadUInt64(); @@ -728,9 +728,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp ulong outputPosition = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(CommonInfo))); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf()); - MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(CommonInfo))); + MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf()); uint deviceHandle = (uint)context.RequestData.ReadUInt64(); @@ -788,9 +788,9 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp ulong outputPosition = context.Request.RecvListBuff[0].Position; - context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf(typeof(ModelInfo))); + context.Response.PtrBuff[0] = context.Response.PtrBuff[0].WithSize((uint)Marshal.SizeOf()); - MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf(typeof(ModelInfo))); + MemoryHelper.FillWithZeros(context.Memory, outputPosition, Marshal.SizeOf()); uint deviceHandle = (uint)context.RequestData.ReadUInt64(); diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs index cd78af78b..a93f176a5 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/BsdContext.cs @@ -1,5 +1,8 @@ -using System.Collections.Concurrent; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using System; +using System.Collections.Concurrent; using System.Collections.Generic; +using System.Numerics; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { @@ -41,6 +44,27 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return null; } + public List RetrieveFileDescriptorsFromMask(ReadOnlySpan mask) + { + List fds = new(); + + for (int i = 0; i < mask.Length; i++) + { + byte current = mask[i]; + + while (current != 0) + { + int bit = BitOperations.TrailingZeroCount(current); + current &= (byte)~(1 << bit); + int fd = i * 8 + bit; + + fds.Add(RetrieveFileDescriptor(fd)); + } + } + + return fds; + } + public int RegisterFileDescriptor(IFileDescriptor file) { lock (_lock) @@ -61,6 +85,16 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd } } + public void BuildMask(List fds, Span mask) + { + foreach (IFileDescriptor descriptor in fds) + { + int fd = _fds.IndexOf(descriptor); + + mask[fd >> 3] |= (byte)(1 << (fd & 7)); + } + } + public int DuplicateFileDescriptor(int fd) { IFileDescriptor oldFile = RetrieveFileDescriptor(fd); @@ -147,4 +181,4 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return processContext; } } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs index ece5375b9..eaf65e4cc 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs @@ -1,10 +1,13 @@ using Ryujinx.Common; using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using Ryujinx.Memory; using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; +using System.Numerics; using System.Runtime.CompilerServices; using System.Text; @@ -202,12 +205,122 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd } [CommandHipc(5)] - // Select(u32 nfds, nn::socket::timeout timeout, buffer readfds_in, buffer writefds_in, buffer errorfds_in) -> (i32 ret, u32 bsd_errno, buffer readfds_out, buffer writefds_out, buffer errorfds_out) + // Select(u32 nfds, nn::socket::timeval timeout, buffer readfds_in, buffer writefds_in, buffer errorfds_in) + // -> (i32 ret, u32 bsd_errno, buffer readfds_out, buffer writefds_out, buffer errorfds_out) public ResultCode Select(ServiceCtx context) { - WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP); + int fdsCount = context.RequestData.ReadInt32(); + int timeout = context.RequestData.ReadInt32(); - Logger.Stub?.PrintStub(LogClass.ServiceBsd); + (ulong readFdsInBufferPosition, ulong readFdsInBufferSize) = context.Request.GetBufferType0x21(0); + (ulong writeFdsInBufferPosition, ulong writeFdsInBufferSize) = context.Request.GetBufferType0x21(1); + (ulong errorFdsInBufferPosition, ulong errorFdsInBufferSize) = context.Request.GetBufferType0x21(2); + + (ulong readFdsOutBufferPosition, ulong readFdsOutBufferSize) = context.Request.GetBufferType0x22(0); + (ulong writeFdsOutBufferPosition, ulong writeFdsOutBufferSize) = context.Request.GetBufferType0x22(1); + (ulong errorFdsOutBufferPosition, ulong errorFdsOutBufferSize) = context.Request.GetBufferType0x22(2); + + List readFds = _context.RetrieveFileDescriptorsFromMask(context.Memory.GetSpan(readFdsInBufferPosition, (int)readFdsInBufferSize)); + List writeFds = _context.RetrieveFileDescriptorsFromMask(context.Memory.GetSpan(writeFdsInBufferPosition, (int)writeFdsInBufferSize)); + List errorFds = _context.RetrieveFileDescriptorsFromMask(context.Memory.GetSpan(errorFdsInBufferPosition, (int)errorFdsInBufferSize)); + + int actualFdsCount = readFds.Count + writeFds.Count + errorFds.Count; + + if (fdsCount == 0 || actualFdsCount == 0) + { + WriteBsdResult(context, 0); + + return ResultCode.Success; + } + + PollEvent[] events = new PollEvent[actualFdsCount]; + + int index = 0; + + foreach (IFileDescriptor fd in readFds) + { + events[index] = new PollEvent(new PollEventData { InputEvents = PollEventTypeMask.Input }, fd); + + index++; + } + + foreach (IFileDescriptor fd in writeFds) + { + events[index] = new PollEvent(new PollEventData { InputEvents = PollEventTypeMask.Output }, fd); + + index++; + } + + foreach (IFileDescriptor fd in errorFds) + { + events[index] = new PollEvent(new PollEventData { InputEvents = PollEventTypeMask.Error }, fd); + + index++; + } + + List[] eventsByPollManager = new List[_pollManagers.Count]; + + for (int i = 0; i < eventsByPollManager.Length; i++) + { + eventsByPollManager[i] = new List(); + + foreach (PollEvent evnt in events) + { + if (_pollManagers[i].IsCompatible(evnt)) + { + eventsByPollManager[i].Add(evnt); + } + } + } + + int updatedCount = 0; + + for (int i = 0; i < _pollManagers.Count; i++) + { + if (eventsByPollManager[i].Count > 0) + { + _pollManagers[i].Select(eventsByPollManager[i], timeout, out int updatedPollCount); + updatedCount += updatedPollCount; + } + } + + readFds.Clear(); + writeFds.Clear(); + errorFds.Clear(); + + foreach (PollEvent pollEvent in events) + { + for (int i = 0; i < _pollManagers.Count; i++) + { + if (eventsByPollManager[i].Contains(pollEvent)) + { + if (pollEvent.Data.OutputEvents.HasFlag(PollEventTypeMask.Input)) + { + readFds.Add(pollEvent.FileDescriptor); + } + + if (pollEvent.Data.OutputEvents.HasFlag(PollEventTypeMask.Output)) + { + writeFds.Add(pollEvent.FileDescriptor); + } + + if (pollEvent.Data.OutputEvents.HasFlag(PollEventTypeMask.Error)) + { + errorFds.Add(pollEvent.FileDescriptor); + } + } + } + } + + using var readFdsOut = context.Memory.GetWritableRegion(readFdsOutBufferPosition, (int)readFdsOutBufferSize); + using var writeFdsOut = context.Memory.GetWritableRegion(writeFdsOutBufferPosition, (int)writeFdsOutBufferSize); + using var errorFdsOut = context.Memory.GetWritableRegion(errorFdsOutBufferPosition, (int)errorFdsOutBufferSize); + + _context.BuildMask(readFds, readFdsOut.Memory.Span); + _context.BuildMask(writeFds, writeFdsOut.Memory.Span); + _context.BuildMask(errorFds, errorFdsOut.Memory.Span); + + WriteBsdResult(context, updatedCount); return ResultCode.Success; } @@ -320,14 +433,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd break; } - // If we are here, that mean nothing was availaible, sleep for 50ms + // If we are here, that mean nothing was available, sleep for 50ms context.Device.System.KernelContext.Syscall.SleepThread(50 * 1000000); } while (PerformanceCounter.ElapsedMilliseconds < budgetLeftMilliseconds); } else if (timeout == -1) { - // FIXME: If we get a timeout of -1 and there is no fds to wait on, this should kill the KProces. (need to check that with re) + // FIXME: If we get a timeout of -1 and there is no fds to wait on, this should kill the KProcess. (need to check that with re) throw new InvalidOperationException(); } else @@ -998,4 +1111,4 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return WriteBsdResult(context, newSockFd, errno); } } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IFileDescriptor.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IFileDescriptor.cs index 56f67539b..9d4f81ce2 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IFileDescriptor.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IFileDescriptor.cs @@ -1,4 +1,5 @@ -using System; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using System; namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd { @@ -11,4 +12,4 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd LinuxError Write(out int writeSize, ReadOnlySpan buffer); } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs index b4f2bff19..058748685 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/ISocket.cs @@ -1,4 +1,5 @@ -using System; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using System; using System.Net; using System.Net.Sockets; diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs index f84e9b93b..6514d4855 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptor.cs @@ -1,8 +1,9 @@ -using System; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using System; using System.Runtime.InteropServices; using System.Threading; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl { class EventFileDescriptor : IFileDescriptor { @@ -149,4 +150,4 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd } } } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptorPollManager.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptorPollManager.cs index 6501d1117..e0ab68c62 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptorPollManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/EventFileDescriptorPollManager.cs @@ -1,8 +1,9 @@ using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System.Collections.Generic; using System.Threading; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl { class EventFileDescriptorPollManager : IPollManager { @@ -109,5 +110,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return LinuxError.SUCCESS; } + + public LinuxError Select(List events, int timeout, out int updatedCount) + { + // TODO: Implement Select for event file descriptors + updatedCount = 0; + + return LinuxError.EOPNOTSUPP; + } } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocket.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocket.cs index 3db7c2223..75efc49a1 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocket.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocket.cs @@ -1,4 +1,5 @@ using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System; using System.Collections.Generic; using System.Diagnostics; @@ -6,7 +7,7 @@ using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl { class ManagedSocket : ISocket { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocketPollManager.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocketPollManager.cs index 31d93cadf..1b305dfb7 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocketPollManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/ManagedSocketPollManager.cs @@ -1,8 +1,9 @@ using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; using System.Collections.Generic; using System.Net.Sockets; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl { class ManagedSocketPollManager : IPollManager { @@ -117,5 +118,60 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return LinuxError.SUCCESS; } + + public LinuxError Select(List events, int timeout, out int updatedCount) + { + List readEvents = new(); + List writeEvents = new(); + List errorEvents = new(); + + updatedCount = 0; + + foreach (PollEvent pollEvent in events) + { + ManagedSocket socket = (ManagedSocket)pollEvent.FileDescriptor; + + if (pollEvent.Data.InputEvents.HasFlag(PollEventTypeMask.Input)) + { + readEvents.Add(socket.Socket); + } + + if (pollEvent.Data.InputEvents.HasFlag(PollEventTypeMask.Output)) + { + writeEvents.Add(socket.Socket); + } + + if (pollEvent.Data.InputEvents.HasFlag(PollEventTypeMask.Error)) + { + errorEvents.Add(socket.Socket); + } + } + + Socket.Select(readEvents, writeEvents, errorEvents, timeout); + + updatedCount = readEvents.Count + writeEvents.Count + errorEvents.Count; + + foreach (PollEvent pollEvent in events) + { + ManagedSocket socket = (ManagedSocket)pollEvent.FileDescriptor; + + if (readEvents.Contains(socket.Socket)) + { + pollEvent.Data.OutputEvents |= PollEventTypeMask.Input; + } + + if (writeEvents.Contains(socket.Socket)) + { + pollEvent.Data.OutputEvents |= PollEventTypeMask.Output; + } + + if (errorEvents.Contains(socket.Socket)) + { + pollEvent.Data.OutputEvents |= PollEventTypeMask.Error; + } + } + + return LinuxError.SUCCESS; + } } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WSAError.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WSAError.cs index d87e72d82..0f24a57f5 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WSAError.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WSAError.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl { [SuppressMessage("ReSharper", "InconsistentNaming")] enum WsaError diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WinSockHelper.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WinSockHelper.cs index ad12745e8..48439d7d3 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WinSockHelper.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WinSockHelper.cs @@ -1,7 +1,8 @@ -using System.Collections.Generic; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using System.Collections.Generic; using System.Net.Sockets; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl { static class WinSockHelper { @@ -162,4 +163,4 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd return table.TryGetValue(option, out name); } } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdAddressFamily.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdAddressFamily.cs index dcc9f0fd7..37461bb25 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdAddressFamily.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdAddressFamily.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdAddressFamily : uint { @@ -8,4 +8,4 @@ Unknown = uint.MaxValue } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdIoctl.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdIoctl.cs index 421a255cc..1dfa5a5f9 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdIoctl.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdIoctl.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdIoctl { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMMsgHdr.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMMsgHdr.cs index bfcc92cd8..f97b8f5be 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMMsgHdr.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMMsgHdr.cs @@ -1,6 +1,6 @@ using System; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { class BsdMMsgHdr { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMsgHdr.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMsgHdr.cs index bb620375c..07c97182c 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMsgHdr.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdMsgHdr.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { class BsdMsgHdr { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSockAddr.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSockAddr.cs index 71926ceba..67c11e54d 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSockAddr.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSockAddr.cs @@ -3,7 +3,7 @@ using System; using System.Net; using System.Runtime.InteropServices; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x10)] struct BsdSockAddr diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketCreationFlags.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketCreationFlags.cs index 77718800d..be5991ff6 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketCreationFlags.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketCreationFlags.cs @@ -1,6 +1,6 @@ using System; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { [Flags] enum BsdSocketCreationFlags diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs index ca464c09e..4408c89af 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdSocketFlags { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketOption.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketOption.cs index 726e4111e..4d0d1dcf3 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketOption.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketOption.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdSocketOption { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketShutdownFlags.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketShutdownFlags.cs index 2588376bb..13230ac39 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketShutdownFlags.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketShutdownFlags.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdSocketShutdownFlags { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketType.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketType.cs index 9b13e669a..b54c78863 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketType.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketType.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { enum BsdSocketType { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/EventFdFlags.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/EventFdFlags.cs index 7d08fb24a..e01d82267 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/EventFdFlags.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/EventFdFlags.cs @@ -1,6 +1,6 @@ using System; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { [Flags] enum EventFdFlags : uint diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/IPollManager.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/IPollManager.cs index 8b0959fd0..d36638784 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/IPollManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/IPollManager.cs @@ -1,11 +1,13 @@ using System.Collections.Generic; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { interface IPollManager { bool IsCompatible(PollEvent evnt); LinuxError Poll(List events, int timeoutMilliseconds, out int updatedCount); + + LinuxError Select(List events, int timeout, out int updatedCount); } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/LinuxError.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/LinuxError.cs index b13269852..96602830b 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/LinuxError.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/LinuxError.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { [SuppressMessage("ReSharper", "InconsistentNaming")] enum LinuxError diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEvent.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEvent.cs index 8056e7a87..8b77a6c2f 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEvent.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEvent.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { class PollEvent { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventData.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventData.cs index df084ff4a..546b738ee 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventData.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventData.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { struct PollEventData { @@ -8,4 +8,4 @@ #pragma warning restore CS0649 public PollEventTypeMask OutputEvents; } -} +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventTypeMask.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventTypeMask.cs index 899072bf0..f434fa032 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventTypeMask.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/PollEventTypeMask.cs @@ -1,6 +1,6 @@ using System; -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { [Flags] enum PollEventTypeMask : ushort diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/TimeVal.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/TimeVal.cs index c57766023..690a63aeb 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/TimeVal.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/TimeVal.cs @@ -1,4 +1,4 @@ -namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd +namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types { public struct TimeVal { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs index 80339b4ac..13c5597fd 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs @@ -18,7 +18,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres [Service("sfdnsres")] class IResolver : IpcService { - public IResolver(ServiceCtx context) { } + public IResolver(ServiceCtx context) + { + DnsMitmResolver.Instance.ReloadEntries(context); + } [CommandHipc(0)] // SetDnsAddressesPrivateRequest(u32, buffer) @@ -259,6 +262,16 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres return ResultCode.Success; } + // Atmosphère extension for dns_mitm + [CommandHipc(65000)] + // AtmosphereReloadHostsFile() + public ResultCode AtmosphereReloadHostsFile(ServiceCtx context) + { + DnsMitmResolver.Instance.ReloadEntries(context); + + return ResultCode.Success; + } + private static ResultCode GetHostByNameRequestImpl( ServiceCtx context, ulong inputBufferPosition, @@ -321,7 +334,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres try { - hostEntry = Dns.GetHostEntry(targetHost); + hostEntry = DnsMitmResolver.Instance.ResolveAddress(targetHost); } catch (SocketException exception) { @@ -537,7 +550,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres try { - hostEntry = Dns.GetHostEntry(targetHost); + hostEntry = DnsMitmResolver.Instance.ResolveAddress(targetHost); } catch (SocketException exception) { diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsMitmResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsMitmResolver.cs new file mode 100644 index 000000000..8eece5ea0 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsMitmResolver.cs @@ -0,0 +1,106 @@ +using Ryujinx.Common.Logging; +using Ryujinx.HLE.HOS.Services.Sockets.Nsd; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Enumeration; +using System.Net; + +namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy +{ + class DnsMitmResolver + { + private const string HostsFilePath = "/atmosphere/hosts/default.txt"; + + private static DnsMitmResolver _instance; + public static DnsMitmResolver Instance => _instance ??= new DnsMitmResolver(); + + private readonly Dictionary _mitmHostEntries = new(); + + public void ReloadEntries(ServiceCtx context) + { + string sdPath = context.Device.Configuration.VirtualFileSystem.GetSdCardPath(); + string filePath = context.Device.Configuration.VirtualFileSystem.GetFullPath(sdPath, HostsFilePath); + + _mitmHostEntries.Clear(); + + if (File.Exists(filePath)) + { + using FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read); + using StreamReader reader = new(fileStream); + + while (!reader.EndOfStream) + { + string line = reader.ReadLine(); + + if (line == null) + { + break; + } + + // Ignore comments and empty lines + if (line.StartsWith("#") || line.Trim().Length == 0) + { + continue; + } + + string[] entry = line.Split(new[] { ' ', '\t' }, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); + + // Hosts file example entry: + // 127.0.0.1 localhost loopback + + // 0. Check the size of the array + if (entry.Length < 2) + { + Logger.Warning?.PrintMsg(LogClass.ServiceBsd, $"Invalid entry in hosts file: {line}"); + + continue; + } + + // 1. Parse the address + if (!IPAddress.TryParse(entry[0], out IPAddress address)) + { + Logger.Warning?.PrintMsg(LogClass.ServiceBsd, $"Failed to parse IP address in hosts file: {entry[0]}"); + + continue; + } + + // 2. Check for AMS hosts file extension: "%" + for (int i = 1; i < entry.Length; i++) + { + entry[i] = entry[i].Replace("%", IManager.NsdSettings.Environment); + } + + // 3. Add hostname to entry dictionary (updating duplicate entries) + foreach (string hostname in entry[1..]) + { + _mitmHostEntries[hostname] = address; + } + } + } + } + + public IPHostEntry ResolveAddress(string host) + { + foreach (var hostEntry in _mitmHostEntries) + { + // Check for AMS hosts file extension: "*" + // NOTE: MatchesSimpleExpression also allows "?" as a wildcard + if (FileSystemName.MatchesSimpleExpression(hostEntry.Key, host)) + { + Logger.Info?.PrintMsg(LogClass.ServiceBsd, $"Redirecting '{host}' to: {hostEntry.Value}"); + + return new IPHostEntry + { + AddressList = new[] { hostEntry.Value }, + HostName = hostEntry.Key, + Aliases = Array.Empty() + }; + } + } + + // No match has been found, resolve the host using regular dns + return Dns.GetHostEntry(host); + } + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Ssl/SslService/SslManagedSocketConnection.cs b/Ryujinx.HLE/HOS/Services/Ssl/SslService/SslManagedSocketConnection.cs index 56bfa709b..47d3eddbe 100644 --- a/Ryujinx.HLE/HOS/Services/Ssl/SslService/SslManagedSocketConnection.cs +++ b/Ryujinx.HLE/HOS/Services/Ssl/SslService/SslManagedSocketConnection.cs @@ -1,4 +1,5 @@ using Ryujinx.HLE.HOS.Services.Sockets.Bsd; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl; using Ryujinx.HLE.HOS.Services.Ssl.Types; using System; using System.IO; diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj index ec5d26807..1e814ca98 100644 --- a/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -21,12 +21,12 @@ - - - - - - + + + + + + diff --git a/Ryujinx.Headless.SDL2/Program.cs b/Ryujinx.Headless.SDL2/Program.cs index 50a90763f..9a082b6d0 100644 --- a/Ryujinx.Headless.SDL2/Program.cs +++ b/Ryujinx.Headless.SDL2/Program.cs @@ -10,7 +10,7 @@ using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller.Motion; using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Logging; -using Ryujinx.Common.System; +using Ryujinx.Common.SystemInterop; using Ryujinx.Common.Utilities; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; diff --git a/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj b/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj index 6a8b38f7b..44a162051 100644 --- a/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj +++ b/Ryujinx.Headless.SDL2/Ryujinx.Headless.SDL2.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -11,8 +11,8 @@ - - + + @@ -28,7 +28,7 @@ - + diff --git a/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj b/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj index 0fd79794f..67fab2d55 100644 --- a/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj +++ b/Ryujinx.Horizon.Generators/Ryujinx.Horizon.Generators.csproj @@ -5,11 +5,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Ryujinx.Input/Ryujinx.Input.csproj b/Ryujinx.Input/Ryujinx.Input.csproj index 55111f77f..40b82246c 100644 --- a/Ryujinx.Input/Ryujinx.Input.csproj +++ b/Ryujinx.Input/Ryujinx.Input.csproj @@ -6,7 +6,7 @@ - + diff --git a/Ryujinx.Memory.Tests/Ryujinx.Memory.Tests.csproj b/Ryujinx.Memory.Tests/Ryujinx.Memory.Tests.csproj index 46478c61d..4dcb69623 100644 --- a/Ryujinx.Memory.Tests/Ryujinx.Memory.Tests.csproj +++ b/Ryujinx.Memory.Tests/Ryujinx.Memory.Tests.csproj @@ -6,9 +6,9 @@ - - - + + + diff --git a/Ryujinx.Memory/MemoryManagerUnixHelper.cs b/Ryujinx.Memory/MemoryManagerUnixHelper.cs index dd31c328b..87a81a79b 100644 --- a/Ryujinx.Memory/MemoryManagerUnixHelper.cs +++ b/Ryujinx.Memory/MemoryManagerUnixHelper.cs @@ -3,7 +3,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.Memory { - public static class MemoryManagerUnixHelper + public static partial class MemoryManagerUnixHelper { [Flags] public enum MmapProts : uint @@ -51,38 +51,38 @@ namespace Ryujinx.Memory public const int MADV_DONTNEED = 4; public const int MADV_REMOVE = 9; - [DllImport("libc", EntryPoint = "mmap", SetLastError = true)] - private static extern IntPtr Internal_mmap(IntPtr address, ulong length, MmapProts prot, int flags, int fd, long offset); + [LibraryImport("libc", EntryPoint = "mmap", SetLastError = true)] + private static partial IntPtr Internal_mmap(IntPtr address, ulong length, MmapProts prot, int flags, int fd, long offset); - [DllImport("libc", SetLastError = true)] - public static extern int mprotect(IntPtr address, ulong length, MmapProts prot); + [LibraryImport("libc", SetLastError = true)] + public static partial int mprotect(IntPtr address, ulong length, MmapProts prot); - [DllImport("libc", SetLastError = true)] - public static extern int munmap(IntPtr address, ulong length); + [LibraryImport("libc", SetLastError = true)] + public static partial int munmap(IntPtr address, ulong length); - [DllImport("libc", SetLastError = true)] - public static extern IntPtr mremap(IntPtr old_address, ulong old_size, ulong new_size, int flags, IntPtr new_address); + [LibraryImport("libc", SetLastError = true)] + public static partial IntPtr mremap(IntPtr old_address, ulong old_size, ulong new_size, int flags, IntPtr new_address); - [DllImport("libc", SetLastError = true)] - public static extern int madvise(IntPtr address, ulong size, int advice); + [LibraryImport("libc", SetLastError = true)] + public static partial int madvise(IntPtr address, ulong size, int advice); - [DllImport("libc", SetLastError = true)] - public static extern int mkstemp(IntPtr template); + [LibraryImport("libc", SetLastError = true)] + public static partial int mkstemp(IntPtr template); - [DllImport("libc", SetLastError = true)] - public static extern int unlink(IntPtr pathname); + [LibraryImport("libc", SetLastError = true)] + public static partial int unlink(IntPtr pathname); - [DllImport("libc", SetLastError = true)] - public static extern int ftruncate(int fildes, IntPtr length); + [LibraryImport("libc", SetLastError = true)] + public static partial int ftruncate(int fildes, IntPtr length); - [DllImport("libc", SetLastError = true)] - public static extern int close(int fd); + [LibraryImport("libc", SetLastError = true)] + public static partial int close(int fd); - [DllImport("libc", SetLastError = true)] - public static extern int shm_open(IntPtr name, int oflag, uint mode); + [LibraryImport("libc", SetLastError = true)] + public static partial int shm_open(IntPtr name, int oflag, uint mode); - [DllImport("libc", SetLastError = true)] - public static extern int shm_unlink(IntPtr name); + [LibraryImport("libc", SetLastError = true)] + public static partial int shm_unlink(IntPtr name); private static int MmapFlagsToSystemFlags(MmapFlags flags) { diff --git a/Ryujinx.Memory/WindowsShared/WindowsApi.cs b/Ryujinx.Memory/WindowsShared/WindowsApi.cs index cbb7d99e6..67e704ea4 100644 --- a/Ryujinx.Memory/WindowsShared/WindowsApi.cs +++ b/Ryujinx.Memory/WindowsShared/WindowsApi.cs @@ -3,20 +3,20 @@ using System.Runtime.InteropServices; namespace Ryujinx.Memory.WindowsShared { - static class WindowsApi + static partial class WindowsApi { public static readonly IntPtr InvalidHandleValue = new IntPtr(-1); public static readonly IntPtr CurrentProcessHandle = new IntPtr(-1); - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr VirtualAlloc( + [LibraryImport("kernel32.dll", SetLastError = true)] + public static partial IntPtr VirtualAlloc( IntPtr lpAddress, IntPtr dwSize, AllocationType flAllocationType, MemoryProtection flProtect); - [DllImport("KernelBase.dll", SetLastError = true)] - public static extern IntPtr VirtualAlloc2( + [LibraryImport("KernelBase.dll", SetLastError = true)] + public static partial IntPtr VirtualAlloc2( IntPtr process, IntPtr lpAddress, IntPtr dwSize, @@ -25,18 +25,20 @@ namespace Ryujinx.Memory.WindowsShared IntPtr extendedParameters, ulong parameterCount); - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool VirtualProtect( + [LibraryImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool VirtualProtect( IntPtr lpAddress, IntPtr dwSize, MemoryProtection flNewProtect, out MemoryProtection lpflOldProtect); - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool VirtualFree(IntPtr lpAddress, IntPtr dwSize, AllocationType dwFreeType); + [LibraryImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool VirtualFree(IntPtr lpAddress, IntPtr dwSize, AllocationType dwFreeType); - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr CreateFileMapping( + [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "CreateFileMappingW")] + public static partial IntPtr CreateFileMapping( IntPtr hFile, IntPtr lpFileMappingAttributes, FileMapProtection flProtect, @@ -44,19 +46,20 @@ namespace Ryujinx.Memory.WindowsShared uint dwMaximumSizeLow, [MarshalAs(UnmanagedType.LPWStr)] string lpName); - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool CloseHandle(IntPtr hObject); + [LibraryImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool CloseHandle(IntPtr hObject); - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr MapViewOfFile( + [LibraryImport("kernel32.dll", SetLastError = true)] + public static partial IntPtr MapViewOfFile( IntPtr hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, IntPtr dwNumberOfBytesToMap); - [DllImport("KernelBase.dll", SetLastError = true)] - public static extern IntPtr MapViewOfFile3( + [LibraryImport("KernelBase.dll", SetLastError = true)] + public static partial IntPtr MapViewOfFile3( IntPtr hFileMappingObject, IntPtr process, IntPtr baseAddress, @@ -67,17 +70,19 @@ namespace Ryujinx.Memory.WindowsShared IntPtr extendedParameters, ulong parameterCount); - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress); + [LibraryImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool UnmapViewOfFile(IntPtr lpBaseAddress); - [DllImport("KernelBase.dll", SetLastError = true)] - public static extern bool UnmapViewOfFile2(IntPtr process, IntPtr lpBaseAddress, ulong unmapFlags); + [LibraryImport("KernelBase.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static partial bool UnmapViewOfFile2(IntPtr process, IntPtr lpBaseAddress, ulong unmapFlags); - [DllImport("kernel32.dll")] - public static extern uint GetLastError(); + [LibraryImport("kernel32.dll")] + public static partial uint GetLastError(); - [DllImport("kernel32.dll")] - public static extern int GetCurrentThreadId(); + [LibraryImport("kernel32.dll")] + public static partial int GetCurrentThreadId(); public static MemoryProtection GetProtection(MemoryPermission permission) { diff --git a/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj b/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj index 96bebac0a..955e6d3f1 100644 --- a/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj +++ b/Ryujinx.SDL2.Common/Ryujinx.SDL2.Common.csproj @@ -5,7 +5,7 @@ - + diff --git a/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj b/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj index 5c6ca6fb9..74b4ec2f7 100644 --- a/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj +++ b/Ryujinx.ShaderTools/Ryujinx.ShaderTools.csproj @@ -11,7 +11,7 @@ - + diff --git a/Ryujinx.Tests.Unicorn/Native/Interface.cs b/Ryujinx.Tests.Unicorn/Native/Interface.cs index 0ecda22ea..4e34ee8b3 100644 --- a/Ryujinx.Tests.Unicorn/Native/Interface.cs +++ b/Ryujinx.Tests.Unicorn/Native/Interface.cs @@ -1,12 +1,14 @@ using Ryujinx.Tests.Unicorn.Native.Const; using System; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Ryujinx.Tests.Unicorn.Native { - public static class Interface + public static partial class Interface { public static bool IsUnicornAvailable { get; private set; } = true; @@ -43,9 +45,9 @@ namespace Ryujinx.Tests.Unicorn.Native } } - public static void MarshalArrayOf(IntPtr input, int length, out T[] output) + public static void MarshalArrayOf<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(IntPtr input, int length, out T[] output) { - int size = Marshal.SizeOf(typeof(T)); + int size = Marshal.SizeOf(); output = new T[length]; @@ -57,43 +59,43 @@ namespace Ryujinx.Tests.Unicorn.Native } } - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern uint uc_version(out uint major, out uint minor); + [LibraryImport("unicorn")] + public static partial uint uc_version(out uint major, out uint minor); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_open(Arch arch, Mode mode, out IntPtr uc); + [LibraryImport("unicorn")] + public static partial Error uc_open(Arch arch, Mode mode, out IntPtr uc); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_close(IntPtr uc); + [LibraryImport("unicorn")] + public static partial Error uc_close(IntPtr uc); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr uc_strerror(Error err); + [LibraryImport("unicorn")] + public static partial IntPtr uc_strerror(Error err); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_reg_write(IntPtr uc, int regid, byte[] value); + [LibraryImport("unicorn")] + public static partial Error uc_reg_write(IntPtr uc, int regid, byte[] value); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_reg_read(IntPtr uc, int regid, byte[] value); + [LibraryImport("unicorn")] + public static partial Error uc_reg_read(IntPtr uc, int regid, byte[] value); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_mem_write(IntPtr uc, ulong address, byte[] bytes, ulong size); + [LibraryImport("unicorn")] + public static partial Error uc_mem_write(IntPtr uc, ulong address, byte[] bytes, ulong size); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_mem_read(IntPtr uc, ulong address, byte[] bytes, ulong size); + [LibraryImport("unicorn")] + public static partial Error uc_mem_read(IntPtr uc, ulong address, byte[] bytes, ulong size); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_emu_start(IntPtr uc, ulong begin, ulong until, ulong timeout, ulong count); + [LibraryImport("unicorn")] + public static partial Error uc_emu_start(IntPtr uc, ulong begin, ulong until, ulong timeout, ulong count); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_mem_map(IntPtr uc, ulong address, ulong size, uint perms); + [LibraryImport("unicorn")] + public static partial Error uc_mem_map(IntPtr uc, ulong address, ulong size, uint perms); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_mem_unmap(IntPtr uc, ulong address, ulong size); + [LibraryImport("unicorn")] + public static partial Error uc_mem_unmap(IntPtr uc, ulong address, ulong size); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_mem_protect(IntPtr uc, ulong address, ulong size, uint perms); + [LibraryImport("unicorn")] + public static partial Error uc_mem_protect(IntPtr uc, ulong address, ulong size, uint perms); - [DllImport("unicorn", CallingConvention = CallingConvention.Cdecl)] - public static extern Error uc_mem_regions(IntPtr uc, out IntPtr regions, out uint count); + [LibraryImport("unicorn")] + public static partial Error uc_mem_regions(IntPtr uc, out IntPtr regions, out uint count); } } \ No newline at end of file diff --git a/Ryujinx.Tests/Ryujinx.Tests.csproj b/Ryujinx.Tests/Ryujinx.Tests.csproj index e85c4f1cd..5976e998b 100644 --- a/Ryujinx.Tests/Ryujinx.Tests.csproj +++ b/Ryujinx.Tests/Ryujinx.Tests.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -18,9 +18,9 @@ - - - + + + @@ -35,14 +35,14 @@ - + - + diff --git a/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs b/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs index d85a8121b..4eb3b79c1 100644 --- a/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs +++ b/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs @@ -5,7 +5,7 @@ using System.Runtime.Versioning; namespace Ryujinx.Ui.Common.Helper { - public static class ConsoleHelper + public static partial class ConsoleHelper { public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows(); @@ -39,11 +39,12 @@ namespace Ryujinx.Ui.Common.Helper } [SupportedOSPlatform("windows")] - [DllImport("kernel32")] - static extern IntPtr GetConsoleWindow(); + [LibraryImport("kernel32")] + private static partial IntPtr GetConsoleWindow(); [SupportedOSPlatform("windows")] - [DllImport("user32")] - static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + [LibraryImport("user32")] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool ShowWindow(IntPtr hWnd, int nCmdShow); } } \ No newline at end of file diff --git a/Ryujinx.Ui.Common/Ryujinx.Ui.Common.csproj b/Ryujinx.Ui.Common/Ryujinx.Ui.Common.csproj index ed89e08de..3a1cd1250 100644 --- a/Ryujinx.Ui.Common/Ryujinx.Ui.Common.csproj +++ b/Ryujinx.Ui.Common/Ryujinx.Ui.Common.csproj @@ -2,6 +2,7 @@ net7.0 + true @@ -41,7 +42,7 @@ - + diff --git a/Ryujinx.sln b/Ryujinx.sln index 1332e129b..0915ef987 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -34,6 +34,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + Directory.Packages.props = Directory.Packages.props EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Memory", "Ryujinx.Memory\Ryujinx.Memory.csproj", "{A5E6C691-9E22-4263-8F40-42F002CE66BE}" diff --git a/Ryujinx/Modules/Updater/Updater.cs b/Ryujinx/Modules/Updater/Updater.cs index 194d35e53..0a1cb53bc 100644 --- a/Ryujinx/Modules/Updater/Updater.cs +++ b/Ryujinx/Modules/Updater/Updater.cs @@ -387,16 +387,19 @@ namespace Ryujinx.Modules worker.Start(); } - [DllImport("libc", SetLastError = true)] - private static extern int chmod(string path, uint mode); - - private static void SetUnixPermissions() + private static void SetFileExecutable(string path) { - string ryuBin = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx"); + const UnixFileMode ExecutableFileMode = UnixFileMode.UserExecute | + UnixFileMode.UserWrite | + UnixFileMode.UserRead | + UnixFileMode.GroupRead | + UnixFileMode.GroupWrite | + UnixFileMode.OtherRead | + UnixFileMode.OtherWrite; - if (!OperatingSystem.IsWindows()) + if (!OperatingSystem.IsWindows() && File.Exists(path)) { - chmod(ryuBin, 493); + File.SetUnixFileMode(path, ExecutableFileMode); } } @@ -519,7 +522,7 @@ namespace Ryujinx.Modules Directory.Delete(UpdateDir, true); - SetUnixPermissions(); + SetFileExecutable(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx")); updateDialog.MainText.Text = "Update Complete!"; updateDialog.SecondaryText.Text = "Do you want to restart Ryujinx now?"; diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs index 403dde300..e27c4ae94 100644 --- a/Ryujinx/Program.cs +++ b/Ryujinx/Program.cs @@ -4,7 +4,7 @@ using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.Logging; -using Ryujinx.Common.System; +using Ryujinx.Common.SystemInterop; using Ryujinx.Common.SystemInfo; using Ryujinx.Modules; using Ryujinx.SDL2.Common; @@ -23,7 +23,7 @@ using System.Threading.Tasks; namespace Ryujinx { - class Program + partial class Program { public static double WindowScaleFactor { get; private set; } @@ -35,17 +35,17 @@ namespace Ryujinx private const string X11LibraryName = "libX11"; - [DllImport(X11LibraryName)] - private extern static int XInitThreads(); + [LibraryImport(X11LibraryName)] + private static partial int XInitThreads(); - [DllImport("user32.dll", SetLastError = true)] - public static extern int MessageBoxA(IntPtr hWnd, string text, string caption, uint type); + [LibraryImport("user32.dll", SetLastError = true)] + public static partial int MessageBoxA(IntPtr hWnd, [MarshalAs(UnmanagedType.LPStr)] string text, [MarshalAs(UnmanagedType.LPStr)] string caption, uint type); - [DllImport("libc", SetLastError = true)] - static extern int setenv(string name, string value, int overwrite); + [LibraryImport("libc", SetLastError = true)] + private static partial int setenv([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string value, int overwrite); - [DllImport("libc")] - static extern IntPtr getenv(string name); + [LibraryImport("libc")] + private static partial IntPtr getenv([MarshalAs(UnmanagedType.LPStr)] string name); private const uint MB_ICONWARNING = 0x30; diff --git a/Ryujinx/Ryujinx.csproj b/Ryujinx/Ryujinx.csproj index b4cc05162..d8176ee35 100644 --- a/Ryujinx/Ryujinx.csproj +++ b/Ryujinx/Ryujinx.csproj @@ -1,4 +1,4 @@ - + net7.0 @@ -19,17 +19,17 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs index 06d414edc..5804ed181 100644 --- a/Ryujinx/Ui/GLRenderer.cs +++ b/Ryujinx/Ui/GLRenderer.cs @@ -13,7 +13,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.Ui { - public class GlRenderer : RendererWidgetBase + public partial class GlRenderer : RendererWidgetBase { private GraphicsDebugLevel _glLogLevel; @@ -74,14 +74,14 @@ namespace Ryujinx.Ui throw new NotImplementedException(); } - [DllImport("libgdk-3-0.dll")] - private static extern IntPtr gdk_win32_window_get_handle(IntPtr d); + [LibraryImport("libgdk-3-0.dll")] + private static partial IntPtr gdk_win32_window_get_handle(IntPtr d); - [DllImport("libgdk-3.so.0")] - private static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr gdkDisplay); + [LibraryImport("libgdk-3.so.0")] + private static partial IntPtr gdk_x11_display_get_xdisplay(IntPtr gdkDisplay); - [DllImport("libgdk-3.so.0")] - private static extern IntPtr gdk_x11_window_get_xid(IntPtr gdkWindow); + [LibraryImport("libgdk-3.so.0")] + private static partial IntPtr gdk_x11_window_get_xid(IntPtr gdkWindow); private static FramebufferFormat GetGraphicsMode() { diff --git a/Ryujinx/Ui/Helper/MetalHelper.cs b/Ryujinx/Ui/Helper/MetalHelper.cs index 62ca29301..1e10eb05a 100644 --- a/Ryujinx/Ui/Helper/MetalHelper.cs +++ b/Ryujinx/Ui/Helper/MetalHelper.cs @@ -8,7 +8,7 @@ namespace Ryujinx.Ui.Helper public delegate void UpdateBoundsCallbackDelegate(Window window); [SupportedOSPlatform("macos")] - static class MetalHelper + static partial class MetalHelper { private const string LibObjCImport = "/usr/lib/libobjc.A.dylib"; @@ -104,31 +104,31 @@ namespace Ryujinx.Ui.Helper return metalLayer; } - [DllImport(LibObjCImport)] - private static unsafe extern IntPtr sel_registerName(byte* data); + [LibraryImport(LibObjCImport)] + private static unsafe partial IntPtr sel_registerName(byte* data); - [DllImport(LibObjCImport)] - private static unsafe extern IntPtr objc_getClass(byte* data); + [LibraryImport(LibObjCImport)] + private static unsafe partial IntPtr objc_getClass(byte* data); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector, byte value); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector, byte value); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector, NSRect point); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector, NSRect point); - [DllImport(LibObjCImport)] - private static extern void objc_msgSend(IntPtr receiver, Selector selector, double value); + [LibraryImport(LibObjCImport)] + private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value); - [DllImport(LibObjCImport, EntryPoint = "objc_msgSend")] - private static extern IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector); + [LibraryImport(LibObjCImport, EntryPoint = "objc_msgSend")] + private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector); - [DllImport("libgdk-3.0.dylib")] - private static extern IntPtr gdk_quartz_window_get_nsview(IntPtr gdkWindow); + [LibraryImport("libgdk-3.0.dylib")] + private static partial IntPtr gdk_quartz_window_get_nsview(IntPtr gdkWindow); } } \ No newline at end of file diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index 3a5b7723d..0e7e4d625 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -15,7 +15,7 @@ using Ryujinx.Audio.Integration; using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; -using Ryujinx.Common.System; +using Ryujinx.Common.SystemInterop; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.OpenGL; diff --git a/Ryujinx/Ui/VKRenderer.cs b/Ryujinx/Ui/VKRenderer.cs index 63d0d0a62..e49b30c3b 100644 --- a/Ryujinx/Ui/VKRenderer.cs +++ b/Ryujinx/Ui/VKRenderer.cs @@ -12,7 +12,7 @@ using System.Runtime.InteropServices; namespace Ryujinx.Ui { - public class VKRenderer : RendererWidgetBase + public partial class VKRenderer : RendererWidgetBase { public NativeWindowBase NativeWindow { get; private set; } private UpdateBoundsCallbackDelegate _updateBoundsCallback; @@ -44,14 +44,14 @@ namespace Ryujinx.Ui throw new NotImplementedException(); } - [DllImport("libgdk-3-0.dll")] - private static extern IntPtr gdk_win32_window_get_handle(IntPtr d); + [LibraryImport("libgdk-3-0.dll")] + private static partial IntPtr gdk_win32_window_get_handle(IntPtr d); - [DllImport("libgdk-3.so.0")] - private static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr gdkDisplay); + [LibraryImport("libgdk-3.so.0")] + private static partial IntPtr gdk_x11_display_get_xdisplay(IntPtr gdkDisplay); - [DllImport("libgdk-3.so.0")] - private static extern IntPtr gdk_x11_window_get_xid(IntPtr gdkWindow); + [LibraryImport("libgdk-3.so.0")] + private static partial IntPtr gdk_x11_window_get_xid(IntPtr gdkWindow); protected override bool OnConfigureEvent(EventConfigure evnt) {