forked from MeloNX/MeloNX
move unmanaged methods to separate file and expose more api
(cherry picked from commit 4a6b7ffbe55da614ca1a8b8dd693f60e17e99cb0)
This commit is contained in:
parent
235a90aed8
commit
c90b78499b
@ -12,36 +12,6 @@ namespace LibRyujinx
|
|||||||
{
|
{
|
||||||
public static partial class LibRyujinx
|
public static partial class LibRyujinx
|
||||||
{
|
{
|
||||||
[UnmanagedCallersOnly(EntryPoint = "device_initialize")]
|
|
||||||
public static bool InitializeDeviceNative(bool isHostMapped,
|
|
||||||
bool useHypervisor,
|
|
||||||
SystemLanguage systemLanguage,
|
|
||||||
RegionCode regionCode,
|
|
||||||
bool enableVsync,
|
|
||||||
bool enableDockedMode,
|
|
||||||
bool enablePtc,
|
|
||||||
bool enableInternetAccess,
|
|
||||||
IntPtr timeZone,
|
|
||||||
bool ignoreMissingServices)
|
|
||||||
{
|
|
||||||
return InitializeDevice(isHostMapped,
|
|
||||||
useHypervisor,
|
|
||||||
systemLanguage,
|
|
||||||
regionCode,
|
|
||||||
enableVsync,
|
|
||||||
enableDockedMode,
|
|
||||||
enablePtc,
|
|
||||||
enableInternetAccess,
|
|
||||||
Marshal.PtrToStringAnsi(timeZone),
|
|
||||||
ignoreMissingServices);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "device_reloadFilesystem")]
|
|
||||||
public static void ReloadFileSystem()
|
|
||||||
{
|
|
||||||
SwitchDevice?.ReloadFileSystem();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool InitializeDevice(bool isHostMapped,
|
public static bool InitializeDevice(bool isHostMapped,
|
||||||
bool useHypervisor,
|
bool useHypervisor,
|
||||||
SystemLanguage systemLanguage,
|
SystemLanguage systemLanguage,
|
||||||
@ -70,34 +40,6 @@ namespace LibRyujinx
|
|||||||
ignoreMissingServices);
|
ignoreMissingServices);
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "device_load")]
|
|
||||||
public static bool LoadApplicationNative(IntPtr pathPtr)
|
|
||||||
{
|
|
||||||
if(SwitchDevice?.EmulationContext == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var path = Marshal.PtrToStringAnsi(pathPtr);
|
|
||||||
|
|
||||||
return LoadApplication(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "device_install_firmware")]
|
|
||||||
public static void InstallFirmwareNative(int descriptor, bool isXci)
|
|
||||||
{
|
|
||||||
var stream = OpenFile(descriptor);
|
|
||||||
|
|
||||||
InstallFirmware(stream, isXci);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "device_get_installed_firmware_version")]
|
|
||||||
public static IntPtr GetInstalledFirmwareVersionNative()
|
|
||||||
{
|
|
||||||
var result = GetInstalledFirmwareVersion();
|
|
||||||
return Marshal.StringToHGlobalAnsi(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void InstallFirmware(Stream stream, bool isXci)
|
public static void InstallFirmware(Stream stream, bool isXci)
|
||||||
{
|
{
|
||||||
SwitchDevice?.ContentManager.InstallFirmware(stream, isXci);
|
SwitchDevice?.ContentManager.InstallFirmware(stream, isXci);
|
||||||
|
@ -32,12 +32,6 @@ namespace LibRyujinx
|
|||||||
|
|
||||||
public static IRenderer? Renderer { get; set; }
|
public static IRenderer? Renderer { get; set; }
|
||||||
public static GraphicsConfiguration GraphicsConfiguration { get; private set; }
|
public static GraphicsConfiguration GraphicsConfiguration { get; private set; }
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "graphics_initialize")]
|
|
||||||
public static bool InitializeGraphicsNative(GraphicsConfiguration graphicsConfiguration)
|
|
||||||
{
|
|
||||||
return InitializeGraphics(graphicsConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool InitializeGraphics(GraphicsConfiguration graphicsConfiguration)
|
public static bool InitializeGraphics(GraphicsConfiguration graphicsConfiguration)
|
||||||
{
|
{
|
||||||
@ -55,30 +49,7 @@ namespace LibRyujinx
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "graphics_initialize_renderer")]
|
public static bool InitializeGraphicsRenderer(GraphicsBackend graphicsBackend, CreateSurface? createSurfaceFunc, string?[] requiredExtensions)
|
||||||
public unsafe static bool InitializeGraphicsRendererNative(GraphicsBackend graphicsBackend, NativeGraphicsInterop nativeGraphicsInterop)
|
|
||||||
{
|
|
||||||
_nativeGraphicsInterop = nativeGraphicsInterop;
|
|
||||||
if (Renderer != null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<string> extensions = new List<string>();
|
|
||||||
var size = Marshal.SizeOf<IntPtr>();
|
|
||||||
var extPtr = (IntPtr*)nativeGraphicsInterop.VkRequiredExtensions;
|
|
||||||
for (int i = 0; i < nativeGraphicsInterop.VkRequiredExtensionsCount; i++)
|
|
||||||
{
|
|
||||||
var ptr = extPtr[i];
|
|
||||||
extensions.Add(Marshal.PtrToStringAnsi(ptr) ?? string.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateSurface createSurfaceFunc = nativeGraphicsInterop.VkCreateSurface == IntPtr.Zero ? default : Marshal.GetDelegateForFunctionPointer<CreateSurface>(nativeGraphicsInterop.VkCreateSurface);
|
|
||||||
|
|
||||||
return InitializeGraphicsRenderer(graphicsBackend, createSurfaceFunc, extensions.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool InitializeGraphicsRenderer(GraphicsBackend graphicsBackend, CreateSurface createSurfaceFunc, string?[] requiredExtensions)
|
|
||||||
{
|
{
|
||||||
if (Renderer != null)
|
if (Renderer != null)
|
||||||
{
|
{
|
||||||
@ -91,7 +62,7 @@ namespace LibRyujinx
|
|||||||
}
|
}
|
||||||
else if (graphicsBackend == GraphicsBackend.Vulkan)
|
else if (graphicsBackend == GraphicsBackend.Vulkan)
|
||||||
{
|
{
|
||||||
Renderer = new VulkanRenderer(Vk.GetApi(), (instance, vk) => new SurfaceKHR((ulong?)createSurfaceFunc(instance.Handle)),
|
Renderer = new VulkanRenderer(Vk.GetApi(), (instance, vk) => new SurfaceKHR(createSurfaceFunc == null ? null : (ulong?)createSurfaceFunc(instance.Handle)),
|
||||||
() => requiredExtensions,
|
() => requiredExtensions,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
@ -103,35 +74,11 @@ namespace LibRyujinx
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_size")]
|
|
||||||
public static void SetRendererSizeNative(int width, int height)
|
|
||||||
{
|
|
||||||
SetRendererSize(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetRendererSize(int width, int height)
|
public static void SetRendererSize(int width, int height)
|
||||||
{
|
{
|
||||||
Renderer?.Window?.SetSize(width, height);
|
Renderer?.Window?.SetSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_run_loop")]
|
|
||||||
public static void RunLoopNative()
|
|
||||||
{
|
|
||||||
if (Renderer is OpenGLRenderer)
|
|
||||||
{
|
|
||||||
var proc = Marshal.GetDelegateForFunctionPointer<GetProcAddress>(_nativeGraphicsInterop.GlGetProcAddress);
|
|
||||||
GL.LoadBindings(new OpenTKBindingsContext(x => proc!.Invoke(x)));
|
|
||||||
}
|
|
||||||
RunLoop();
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_vsync")]
|
|
||||||
public static void SetVsyncStateNative(bool enabled)
|
|
||||||
{
|
|
||||||
SetVsyncState(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetVsyncState(bool enabled)
|
public static void SetVsyncState(bool enabled)
|
||||||
{
|
{
|
||||||
var device = SwitchDevice!.EmulationContext!;
|
var device = SwitchDevice!.EmulationContext!;
|
||||||
@ -248,12 +195,6 @@ namespace LibRyujinx
|
|||||||
throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}");
|
throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_swap_buffer_callback")]
|
|
||||||
public static void SetSwapBuffersCallbackNative(IntPtr swapBuffersCallback)
|
|
||||||
{
|
|
||||||
_swapBuffersCallback = Marshal.GetDelegateForFunctionPointer<SwapBuffersCallback>(swapBuffersCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetSwapBuffersCallback(SwapBuffersCallback swapBuffersCallback)
|
public static void SetSwapBuffersCallback(SwapBuffersCallback swapBuffersCallback)
|
||||||
{
|
{
|
||||||
|
@ -191,76 +191,6 @@ namespace LibRyujinx
|
|||||||
SwitchDevice!.EmulationContext?.Hid.Touchscreen.Update();
|
SwitchDevice!.EmulationContext?.Hid.Touchscreen.Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Native Methods
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_initialize")]
|
|
||||||
public static void InitializeInputNative(int width, int height)
|
|
||||||
{
|
|
||||||
InitializeInput(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_set_client_size")]
|
|
||||||
public static void SetClientSizeNative(int width, int height)
|
|
||||||
{
|
|
||||||
SetClientSize(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_set_touch_point")]
|
|
||||||
public static void SetTouchPointNative(int x, int y)
|
|
||||||
{
|
|
||||||
SetTouchPoint(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_release_touch_point")]
|
|
||||||
public static void ReleaseTouchPointNative()
|
|
||||||
{
|
|
||||||
ReleaseTouchPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_update")]
|
|
||||||
public static void UpdateInputNative()
|
|
||||||
{
|
|
||||||
UpdateInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_set_button_pressed")]
|
|
||||||
public static void SetButtonPressedNative(GamepadButtonInputId button, int id)
|
|
||||||
{
|
|
||||||
SetButtonPressed(button, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_set_button_released")]
|
|
||||||
public static void SetButtonReleasedNative(GamepadButtonInputId button, int id)
|
|
||||||
{
|
|
||||||
SetButtonReleased(button, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_set_accelerometer_data")]
|
|
||||||
public static void SetAccelerometerDataNative(Vector3 accel, int id)
|
|
||||||
{
|
|
||||||
SetAccelerometerData(accel, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_set_gyro_data")]
|
|
||||||
public static void SetGryoDataNatuve(Vector3 gyro, int id)
|
|
||||||
{
|
|
||||||
SetGryoData(gyro, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_set_stick_axis")]
|
|
||||||
public static void SetStickAxisNative(StickInputId stick, Vector2 axes, int id)
|
|
||||||
{
|
|
||||||
SetStickAxis(stick, axes, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "input_connect_gamepad")]
|
|
||||||
public static IntPtr ConnectGamepadNative(int index)
|
|
||||||
{
|
|
||||||
return ConnectGamepad(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VirtualTouchScreen : IMouse
|
public class VirtualTouchScreen : IMouse
|
||||||
|
450
src/LibRyujinx/LibRyujinx.Native.cs
Normal file
450
src/LibRyujinx/LibRyujinx.Native.cs
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
using LibRyujinx.Shared;
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
using Ryujinx.Common.Configuration;
|
||||||
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Graphics.OpenGL;
|
||||||
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
|
using Ryujinx.Input;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace LibRyujinx
|
||||||
|
{
|
||||||
|
public static partial class LibRyujinx
|
||||||
|
{
|
||||||
|
private unsafe static IntPtr CreateStringArray(List<string> strings)
|
||||||
|
{
|
||||||
|
uint size = (uint)(Marshal.SizeOf<IntPtr>() * (strings.Count + 1));
|
||||||
|
var array = (char**)Marshal.AllocHGlobal((int)size);
|
||||||
|
Unsafe.InitBlockUnaligned(array, 0, size);
|
||||||
|
|
||||||
|
for (int i = 0; i < strings.Count; i++)
|
||||||
|
{
|
||||||
|
array[i] = (char*)Marshal.StringToHGlobalAnsi(strings[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (nint)array;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_initialize")]
|
||||||
|
public static bool InitializeDeviceNative(bool isHostMapped,
|
||||||
|
bool useHypervisor,
|
||||||
|
SystemLanguage systemLanguage,
|
||||||
|
RegionCode regionCode,
|
||||||
|
bool enableVsync,
|
||||||
|
bool enableDockedMode,
|
||||||
|
bool enablePtc,
|
||||||
|
bool enableInternetAccess,
|
||||||
|
IntPtr timeZone,
|
||||||
|
bool ignoreMissingServices)
|
||||||
|
{
|
||||||
|
return InitializeDevice(isHostMapped,
|
||||||
|
useHypervisor,
|
||||||
|
systemLanguage,
|
||||||
|
regionCode,
|
||||||
|
enableVsync,
|
||||||
|
enableDockedMode,
|
||||||
|
enablePtc,
|
||||||
|
enableInternetAccess,
|
||||||
|
Marshal.PtrToStringAnsi(timeZone),
|
||||||
|
ignoreMissingServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_reload_file_system")]
|
||||||
|
public static void ReloadFileSystemNative()
|
||||||
|
{
|
||||||
|
SwitchDevice?.ReloadFileSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_load")]
|
||||||
|
public static bool LoadApplicationNative(IntPtr pathPtr)
|
||||||
|
{
|
||||||
|
if (SwitchDevice?.EmulationContext == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = Marshal.PtrToStringAnsi(pathPtr);
|
||||||
|
|
||||||
|
return LoadApplication(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_install_firmware")]
|
||||||
|
public static void InstallFirmwareNative(int descriptor, bool isXci)
|
||||||
|
{
|
||||||
|
var stream = OpenFile(descriptor);
|
||||||
|
|
||||||
|
InstallFirmware(stream, isXci);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_get_installed_firmware_version")]
|
||||||
|
public static IntPtr GetInstalledFirmwareVersionNative()
|
||||||
|
{
|
||||||
|
var result = GetInstalledFirmwareVersion();
|
||||||
|
return Marshal.StringToHGlobalAnsi(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "initialize")]
|
||||||
|
public static bool InitializeNative(IntPtr basePathPtr)
|
||||||
|
{
|
||||||
|
var path = Marshal.PtrToStringAnsi(basePathPtr);
|
||||||
|
|
||||||
|
var res = Initialize(path);
|
||||||
|
|
||||||
|
InitializeAudio();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "graphics_initialize")]
|
||||||
|
public static bool InitializeGraphicsNative(GraphicsConfiguration graphicsConfiguration)
|
||||||
|
{
|
||||||
|
return InitializeGraphics(graphicsConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "graphics_initialize_renderer")]
|
||||||
|
public unsafe static bool InitializeGraphicsRendererNative(GraphicsBackend graphicsBackend, NativeGraphicsInterop nativeGraphicsInterop)
|
||||||
|
{
|
||||||
|
_nativeGraphicsInterop = nativeGraphicsInterop;
|
||||||
|
if (Renderer != null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> extensions = new List<string>();
|
||||||
|
var size = Marshal.SizeOf<IntPtr>();
|
||||||
|
var extPtr = (IntPtr*)nativeGraphicsInterop.VkRequiredExtensions;
|
||||||
|
for (int i = 0; i < nativeGraphicsInterop.VkRequiredExtensionsCount; i++)
|
||||||
|
{
|
||||||
|
var ptr = extPtr[i];
|
||||||
|
extensions.Add(Marshal.PtrToStringAnsi(ptr) ?? string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateSurface? createSurfaceFunc = nativeGraphicsInterop.VkCreateSurface == IntPtr.Zero ? default : Marshal.GetDelegateForFunctionPointer<CreateSurface>(nativeGraphicsInterop.VkCreateSurface);
|
||||||
|
|
||||||
|
return InitializeGraphicsRenderer(graphicsBackend, createSurfaceFunc, extensions.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_size")]
|
||||||
|
public static void SetRendererSizeNative(int width, int height)
|
||||||
|
{
|
||||||
|
SetRendererSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_run_loop")]
|
||||||
|
public static void RunLoopNative()
|
||||||
|
{
|
||||||
|
if (Renderer is OpenGLRenderer)
|
||||||
|
{
|
||||||
|
var proc = Marshal.GetDelegateForFunctionPointer<GetProcAddress>(_nativeGraphicsInterop.GlGetProcAddress);
|
||||||
|
GL.LoadBindings(new OpenTKBindingsContext(x => proc!.Invoke(x)));
|
||||||
|
}
|
||||||
|
RunLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_vsync")]
|
||||||
|
public static void SetVsyncStateNative(bool enabled)
|
||||||
|
{
|
||||||
|
SetVsyncState(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "graphics_renderer_set_swap_buffer_callback")]
|
||||||
|
public static void SetSwapBuffersCallbackNative(IntPtr swapBuffersCallback)
|
||||||
|
{
|
||||||
|
_swapBuffersCallback = Marshal.GetDelegateForFunctionPointer<SwapBuffersCallback>(swapBuffersCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "get_game_info")]
|
||||||
|
public static GameInfoNative GetGameInfoNative(int descriptor, IntPtr extensionPtr)
|
||||||
|
{
|
||||||
|
var extension = Marshal.PtrToStringAnsi(extensionPtr);
|
||||||
|
var stream = OpenFile(descriptor);
|
||||||
|
|
||||||
|
var gameInfo = GetGameInfo(stream, extension ?? "");
|
||||||
|
|
||||||
|
return gameInfo == null ? default : new GameInfoNative(gameInfo.FileSize, gameInfo.TitleName, gameInfo.TitleId, gameInfo.Developer, gameInfo.Version, gameInfo.Icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_initialize")]
|
||||||
|
public static void InitializeInputNative(int width, int height)
|
||||||
|
{
|
||||||
|
InitializeInput(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_set_client_size")]
|
||||||
|
public static void SetClientSizeNative(int width, int height)
|
||||||
|
{
|
||||||
|
SetClientSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_set_touch_point")]
|
||||||
|
public static void SetTouchPointNative(int x, int y)
|
||||||
|
{
|
||||||
|
SetTouchPoint(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_release_touch_point")]
|
||||||
|
public static void ReleaseTouchPointNative()
|
||||||
|
{
|
||||||
|
ReleaseTouchPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_update")]
|
||||||
|
public static void UpdateInputNative()
|
||||||
|
{
|
||||||
|
UpdateInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_set_button_pressed")]
|
||||||
|
public static void SetButtonPressedNative(GamepadButtonInputId button, int id)
|
||||||
|
{
|
||||||
|
SetButtonPressed(button, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_set_button_released")]
|
||||||
|
public static void SetButtonReleasedNative(GamepadButtonInputId button, int id)
|
||||||
|
{
|
||||||
|
SetButtonReleased(button, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_set_accelerometer_data")]
|
||||||
|
public static void SetAccelerometerDataNative(Vector3 accel, int id)
|
||||||
|
{
|
||||||
|
SetAccelerometerData(accel, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_set_gyro_data")]
|
||||||
|
public static void SetGryoDataNative(Vector3 gyro, int id)
|
||||||
|
{
|
||||||
|
SetGryoData(gyro, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_set_stick_axis")]
|
||||||
|
public static void SetStickAxisNative(StickInputId stick, Vector2 axes, int id)
|
||||||
|
{
|
||||||
|
SetStickAxis(stick, axes, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "input_connect_gamepad")]
|
||||||
|
public static IntPtr ConnectGamepadNative(int index)
|
||||||
|
{
|
||||||
|
return ConnectGamepad(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_get_game_fifo")]
|
||||||
|
public static double GetGameInfoNative()
|
||||||
|
{
|
||||||
|
var stats = SwitchDevice?.EmulationContext?.Statistics.GetFifoPercent() ?? 0;
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_get_game_frame_time")]
|
||||||
|
public static double GetGameFrameTimeNative()
|
||||||
|
{
|
||||||
|
var stats = SwitchDevice?.EmulationContext?.Statistics.GetGameFrameTime() ?? 0;
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_get_game_frame_rate")]
|
||||||
|
public static double GetGameFrameRateNative()
|
||||||
|
{
|
||||||
|
var stats = SwitchDevice?.EmulationContext?.Statistics.GetGameFrameRate() ?? 0;
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_launch_mii_editor")]
|
||||||
|
public static bool LaunchMiiEditAppletNative()
|
||||||
|
{
|
||||||
|
if (SwitchDevice?.EmulationContext == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LaunchMiiEditApplet();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_get_dlc_content_list")]
|
||||||
|
public static IntPtr GetDlcContentListNative(IntPtr pathPtr, long titleId)
|
||||||
|
{
|
||||||
|
var list = GetDlcContentList(Marshal.PtrToStringAnsi(pathPtr) ?? "", (ulong)titleId);
|
||||||
|
|
||||||
|
return CreateStringArray(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_get_dlc_title_id")]
|
||||||
|
public static long GetDlcTitleIdNative(IntPtr pathPtr, IntPtr ncaPath)
|
||||||
|
{
|
||||||
|
return Marshal.StringToHGlobalAnsi(GetDlcTitleId(Marshal.PtrToStringAnsi(pathPtr) ?? "", Marshal.PtrToStringAnsi(ncaPath) ?? ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_signal_emulation_close")]
|
||||||
|
public static void SignalEmulationCloseNative()
|
||||||
|
{
|
||||||
|
SignalEmulationClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_close_emulation")]
|
||||||
|
public static void CloseEmulationNative()
|
||||||
|
{
|
||||||
|
CloseEmulation();
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_load_descriptor")]
|
||||||
|
public static bool LoadApplicationNative(int descriptor, int type, int updateDescriptor)
|
||||||
|
{
|
||||||
|
if (SwitchDevice?.EmulationContext == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stream = OpenFile(descriptor);
|
||||||
|
var update = updateDescriptor == -1 ? null : OpenFile(updateDescriptor);
|
||||||
|
|
||||||
|
return LoadApplication(stream, (FileType)type, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_verify_firmware")]
|
||||||
|
public static IntPtr VerifyFirmwareNative(int descriptor, bool isXci)
|
||||||
|
{
|
||||||
|
var stream = OpenFile(descriptor);
|
||||||
|
|
||||||
|
IntPtr stringHandle = 0;
|
||||||
|
string? version = "0.0";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
version = VerifyFirmware(stream, isXci)?.VersionString;
|
||||||
|
}
|
||||||
|
catch (Exception _)
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Service, $"Unable to verify firmware. Exception: {_}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != null)
|
||||||
|
{
|
||||||
|
stringHandle = Marshal.StringToHGlobalAnsi(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "logging_set_enabled")]
|
||||||
|
public static void SetLoggingEnabledNative(int logLevel, bool enabled)
|
||||||
|
{
|
||||||
|
Logger.SetEnable((LogLevel)logLevel, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "logging_enabled_graphics_log")]
|
||||||
|
public static void SetLoggingEnabledGraphicsLogNative(bool enabled)
|
||||||
|
{
|
||||||
|
_enableGraphicsLogging = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "device_get_game_info")]
|
||||||
|
public unsafe static void GetGameInfoNative(int fileDescriptor, IntPtr extension, IntPtr infoPtr)
|
||||||
|
{
|
||||||
|
using var stream = OpenFile(fileDescriptor);
|
||||||
|
var ext = Marshal.PtrToStringAnsi(extension);
|
||||||
|
var info = GetGameInfo(stream, ext.ToLower()) ?? GetDefaultInfo(stream);
|
||||||
|
var i = (GameInfoNative*)infoPtr;
|
||||||
|
var n = new GameInfoNative(info);
|
||||||
|
i->TitleId = n.TitleId;
|
||||||
|
i->TitleName = n.TitleName;
|
||||||
|
i->Version = n.Version;
|
||||||
|
i->FileSize = n.FileSize;
|
||||||
|
i->Icon = n.Icon;
|
||||||
|
i->Version = n.Version;
|
||||||
|
i->Developer = n.Developer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_get_opened_user")]
|
||||||
|
public static IntPtr GetOpenedUserNative()
|
||||||
|
{
|
||||||
|
var userId = GetOpenedUser();
|
||||||
|
var ptr = Marshal.StringToHGlobalAnsi(userId);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_get_user_picture")]
|
||||||
|
public static IntPtr GetUserPictureNative(IntPtr userIdPtr)
|
||||||
|
{
|
||||||
|
var userId = Marshal.PtrToStringAnsi(userIdPtr) ?? "";
|
||||||
|
|
||||||
|
return Marshal.StringToHGlobalAnsi(GetUserPicture(userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_set_user_picture")]
|
||||||
|
public static void SetUserPictureNative(IntPtr userIdPtr, IntPtr picturePtr)
|
||||||
|
{
|
||||||
|
var userId = Marshal.PtrToStringAnsi(userIdPtr) ?? "";
|
||||||
|
var picture = Marshal.PtrToStringAnsi(picturePtr) ?? "";
|
||||||
|
|
||||||
|
SetUserPicture(userId, picture);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_get_user_name")]
|
||||||
|
public static IntPtr GetUserNameNative(IntPtr userIdPtr)
|
||||||
|
{
|
||||||
|
var userId = Marshal.PtrToStringAnsi(userIdPtr) ?? "";
|
||||||
|
|
||||||
|
return Marshal.StringToHGlobalAnsi(GetUserName(userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_set_user_name")]
|
||||||
|
public static void SetUserNameNative(IntPtr userIdPtr, IntPtr userNamePtr)
|
||||||
|
{
|
||||||
|
var userId = Marshal.PtrToStringAnsi(userIdPtr) ?? "";
|
||||||
|
var userName = Marshal.PtrToStringAnsi(userNamePtr) ?? "";
|
||||||
|
|
||||||
|
SetUserName(userId, userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_get_all_users")]
|
||||||
|
public static IntPtr GetAllUsersNative()
|
||||||
|
{
|
||||||
|
var users = GetAllUsers();
|
||||||
|
|
||||||
|
return CreateStringArray(users.ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_add_user")]
|
||||||
|
public static void AddUserNative(IntPtr userNamePtr, IntPtr picturePtr)
|
||||||
|
{
|
||||||
|
var userName = Marshal.PtrToStringAnsi(userNamePtr) ?? "";
|
||||||
|
var picture = Marshal.PtrToStringAnsi(picturePtr) ?? "";
|
||||||
|
|
||||||
|
AddUser(userName, picture);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_delete_user")]
|
||||||
|
public static void DeleteUserNative(IntPtr userIdPtr)
|
||||||
|
{
|
||||||
|
var userId = Marshal.PtrToStringAnsi(userIdPtr) ?? "";
|
||||||
|
|
||||||
|
DeleteUser(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_open_user")]
|
||||||
|
public static void OpenUserNative(IntPtr userIdPtr)
|
||||||
|
{
|
||||||
|
var userId = Marshal.PtrToStringAnsi(userIdPtr) ?? "";
|
||||||
|
|
||||||
|
OpenUser(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly(EntryPoint = "user_close_user")]
|
||||||
|
public static void CloseUserNative(IntPtr userIdPtr)
|
||||||
|
{
|
||||||
|
var userId = Marshal.PtrToStringAnsi(userIdPtr) ?? "";
|
||||||
|
|
||||||
|
CloseUser(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -44,18 +44,6 @@ namespace LibRyujinx
|
|||||||
private static readonly TitleUpdateMetadataJsonSerializerContext _titleSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
private static readonly TitleUpdateMetadataJsonSerializerContext _titleSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||||
public static SwitchDevice? SwitchDevice { get; set; }
|
public static SwitchDevice? SwitchDevice { get; set; }
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "initialize")]
|
|
||||||
public static bool Initialize(IntPtr basePathPtr)
|
|
||||||
{
|
|
||||||
var path = Marshal.PtrToStringAnsi(basePathPtr);
|
|
||||||
|
|
||||||
var res = Initialize(path);
|
|
||||||
|
|
||||||
InitializeAudio();
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool Initialize(string? basePath)
|
public static bool Initialize(string? basePath)
|
||||||
{
|
{
|
||||||
if (SwitchDevice != null)
|
if (SwitchDevice != null)
|
||||||
@ -85,6 +73,8 @@ namespace LibRyujinx
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.SetEnable(LogLevel.Trace, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,17 +113,6 @@ namespace LibRyujinx
|
|||||||
return GetGameInfo(stream, new FileInfo(file).Extension.Remove('.'));
|
return GetGameInfo(stream, new FileInfo(file).Extension.Remove('.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly(EntryPoint = "get_game_info")]
|
|
||||||
public static GameInfoNative GetGameInfoNative(int descriptor, IntPtr extensionPtr)
|
|
||||||
{
|
|
||||||
var extension = Marshal.PtrToStringAnsi(extensionPtr);
|
|
||||||
var stream = OpenFile(descriptor);
|
|
||||||
|
|
||||||
var gameInfo = GetGameInfo(stream, extension);
|
|
||||||
|
|
||||||
return new GameInfoNative(gameInfo.FileSize, gameInfo.TitleName, gameInfo.TitleId, gameInfo.Developer, gameInfo.Version, gameInfo.Icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GameInfo? GetGameInfo(Stream gameStream, string extension)
|
public static GameInfo? GetGameInfo(Stream gameStream, string extension)
|
||||||
{
|
{
|
||||||
if (SwitchDevice == null)
|
if (SwitchDevice == null)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user