mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-13 06:26:28 +02:00
Move solution and projects to src
This commit is contained in:
parent
cd124bda58
commit
cee7121058
3466 changed files with 55 additions and 55 deletions
16
src/Ryujinx.Common/Configuration/AntiAliasing.cs
Normal file
16
src/Ryujinx.Common/Configuration/AntiAliasing.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<AntiAliasing>))]
|
||||
public enum AntiAliasing
|
||||
{
|
||||
None,
|
||||
Fxaa,
|
||||
SmaaLow,
|
||||
SmaaMedium,
|
||||
SmaaHigh,
|
||||
SmaaUltra
|
||||
}
|
||||
}
|
149
src/Ryujinx.Common/Configuration/AppDataManager.cs
Normal file
149
src/Ryujinx.Common/Configuration/AppDataManager.cs
Normal file
|
@ -0,0 +1,149 @@
|
|||
using Ryujinx.Common.Logging;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
public static class AppDataManager
|
||||
{
|
||||
public const string DefaultBaseDir = "Ryujinx";
|
||||
public const string DefaultPortableDir = "portable";
|
||||
|
||||
// The following 3 are always part of Base Directory
|
||||
private const string GamesDir = "games";
|
||||
private const string ProfilesDir = "profiles";
|
||||
private const string KeysDir = "system";
|
||||
|
||||
public enum LaunchMode
|
||||
{
|
||||
UserProfile,
|
||||
Portable,
|
||||
Custom
|
||||
}
|
||||
|
||||
public static LaunchMode Mode { get; private set; }
|
||||
|
||||
public static string BaseDirPath { get; private set; }
|
||||
public static string GamesDirPath { get; private set; }
|
||||
public static string ProfilesDirPath { get; private set; }
|
||||
public static string KeysDirPath { get; private set; }
|
||||
public static string KeysDirPathUser { get; }
|
||||
|
||||
public const string DefaultNandDir = "bis";
|
||||
public const string DefaultSdcardDir = "sdcard";
|
||||
private const string DefaultModsDir = "mods";
|
||||
|
||||
public static string CustomModsPath { get; set; }
|
||||
public static string CustomSdModsPath {get; set; }
|
||||
public static string CustomNandPath { get; set; } // TODO: Actually implement this into VFS
|
||||
public static string CustomSdCardPath { get; set; } // TODO: Actually implement this into VFS
|
||||
|
||||
static AppDataManager()
|
||||
{
|
||||
KeysDirPathUser = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch");
|
||||
}
|
||||
|
||||
public static void Initialize(string baseDirPath)
|
||||
{
|
||||
string appDataPath;
|
||||
if (OperatingSystem.IsMacOS())
|
||||
{
|
||||
appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library", "Application Support");
|
||||
}
|
||||
else
|
||||
{
|
||||
appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
}
|
||||
|
||||
if (appDataPath.Length == 0)
|
||||
{
|
||||
appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
}
|
||||
|
||||
string userProfilePath = Path.Combine(appDataPath, DefaultBaseDir);
|
||||
string portablePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DefaultPortableDir);
|
||||
|
||||
if (Directory.Exists(portablePath))
|
||||
{
|
||||
BaseDirPath = portablePath;
|
||||
Mode = LaunchMode.Portable;
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseDirPath = userProfilePath;
|
||||
Mode = LaunchMode.UserProfile;
|
||||
}
|
||||
|
||||
if (baseDirPath != null && baseDirPath != userProfilePath)
|
||||
{
|
||||
if (!Directory.Exists(baseDirPath))
|
||||
{
|
||||
Logger.Error?.Print(LogClass.Application, $"Custom Data Directory '{baseDirPath}' does not exist. Falling back to {Mode}...");
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseDirPath = baseDirPath;
|
||||
Mode = LaunchMode.Custom;
|
||||
}
|
||||
}
|
||||
|
||||
BaseDirPath = Path.GetFullPath(BaseDirPath); // convert relative paths
|
||||
|
||||
// NOTE: Moves the Ryujinx folder in `~/.config` to `~/Library/Application Support` if one is found
|
||||
// and a Ryujinx folder does not already exist in Application Support.
|
||||
// Also creates a symlink from `~/.config/Ryujinx` to `~/Library/Application Support/Ryujinx` to preserve backwards compatibility.
|
||||
// This should be removed in the future.
|
||||
if (OperatingSystem.IsMacOS() && Mode == LaunchMode.UserProfile)
|
||||
{
|
||||
string oldConfigPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir);
|
||||
if (Path.Exists(oldConfigPath) && !Path.Exists(BaseDirPath))
|
||||
{
|
||||
CopyDirectory(oldConfigPath, BaseDirPath);
|
||||
Directory.Delete(oldConfigPath, true);
|
||||
Directory.CreateSymbolicLink(oldConfigPath, BaseDirPath);
|
||||
}
|
||||
}
|
||||
|
||||
SetupBasePaths();
|
||||
}
|
||||
|
||||
private static void SetupBasePaths()
|
||||
{
|
||||
Directory.CreateDirectory(BaseDirPath);
|
||||
Directory.CreateDirectory(GamesDirPath = Path.Combine(BaseDirPath, GamesDir));
|
||||
Directory.CreateDirectory(ProfilesDirPath = Path.Combine(BaseDirPath, ProfilesDir));
|
||||
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));
|
||||
}
|
||||
|
||||
private static void CopyDirectory(string sourceDir, string destinationDir)
|
||||
{
|
||||
var dir = new DirectoryInfo(sourceDir);
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");
|
||||
}
|
||||
|
||||
DirectoryInfo[] subDirs = dir.GetDirectories();
|
||||
Directory.CreateDirectory(destinationDir);
|
||||
|
||||
foreach (FileInfo file in dir.GetFiles())
|
||||
{
|
||||
if (file.Name == ".DS_Store")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
file.CopyTo(Path.Combine(destinationDir, file.Name));
|
||||
}
|
||||
|
||||
foreach (DirectoryInfo subDir in subDirs)
|
||||
{
|
||||
CopyDirectory(subDir.FullName, Path.Combine(destinationDir, subDir.Name));
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetModsPath() => CustomModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultModsDir)).FullName;
|
||||
public static string GetSdModsPath() => CustomSdModsPath ?? Directory.CreateDirectory(Path.Combine(BaseDirPath, DefaultSdcardDir, "atmosphere")).FullName;
|
||||
}
|
||||
}
|
63
src/Ryujinx.Common/Configuration/AspectRatioExtensions.cs
Normal file
63
src/Ryujinx.Common/Configuration/AspectRatioExtensions.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<AspectRatio>))]
|
||||
public enum AspectRatio
|
||||
{
|
||||
Fixed4x3,
|
||||
Fixed16x9,
|
||||
Fixed16x10,
|
||||
Fixed21x9,
|
||||
Fixed32x9,
|
||||
Stretched
|
||||
}
|
||||
|
||||
public static class AspectRatioExtensions
|
||||
{
|
||||
public static float ToFloat(this AspectRatio aspectRatio)
|
||||
{
|
||||
return aspectRatio.ToFloatX() / aspectRatio.ToFloatY();
|
||||
}
|
||||
|
||||
public static float ToFloatX(this AspectRatio aspectRatio)
|
||||
{
|
||||
return aspectRatio switch
|
||||
{
|
||||
AspectRatio.Fixed4x3 => 4.0f,
|
||||
AspectRatio.Fixed16x9 => 16.0f,
|
||||
AspectRatio.Fixed16x10 => 16.0f,
|
||||
AspectRatio.Fixed21x9 => 21.0f,
|
||||
AspectRatio.Fixed32x9 => 32.0f,
|
||||
_ => 16.0f
|
||||
};
|
||||
}
|
||||
|
||||
public static float ToFloatY(this AspectRatio aspectRatio)
|
||||
{
|
||||
return aspectRatio switch
|
||||
{
|
||||
AspectRatio.Fixed4x3 => 3.0f,
|
||||
AspectRatio.Fixed16x9 => 9.0f,
|
||||
AspectRatio.Fixed16x10 => 10.0f,
|
||||
AspectRatio.Fixed21x9 => 9.0f,
|
||||
AspectRatio.Fixed32x9 => 9.0f,
|
||||
_ => 9.0f
|
||||
};
|
||||
}
|
||||
|
||||
public static string ToText(this AspectRatio aspectRatio)
|
||||
{
|
||||
return aspectRatio switch
|
||||
{
|
||||
AspectRatio.Fixed4x3 => "4:3",
|
||||
AspectRatio.Fixed16x9 => "16:9",
|
||||
AspectRatio.Fixed16x10 => "16:10",
|
||||
AspectRatio.Fixed21x9 => "21:9",
|
||||
AspectRatio.Fixed32x9 => "32:9",
|
||||
_ => "Stretched"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
13
src/Ryujinx.Common/Configuration/BackendThreading.cs
Normal file
13
src/Ryujinx.Common/Configuration/BackendThreading.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<BackendThreading>))]
|
||||
public enum BackendThreading
|
||||
{
|
||||
Auto,
|
||||
Off,
|
||||
On
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
public struct DownloadableContentContainer
|
||||
{
|
||||
[JsonPropertyName("path")]
|
||||
public string ContainerPath { get; set; }
|
||||
[JsonPropertyName("dlc_nca_list")]
|
||||
public List<DownloadableContentNca> DownloadableContentNcaList { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(List<DownloadableContentContainer>))]
|
||||
public partial class DownloadableContentJsonSerializerContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
}
|
14
src/Ryujinx.Common/Configuration/DownloadableContentNca.cs
Normal file
14
src/Ryujinx.Common/Configuration/DownloadableContentNca.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
public struct DownloadableContentNca
|
||||
{
|
||||
[JsonPropertyName("path")]
|
||||
public string FullPath { get; set; }
|
||||
[JsonPropertyName("title_id")]
|
||||
public ulong TitleId { get; set; }
|
||||
[JsonPropertyName("is_enabled")]
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
}
|
12
src/Ryujinx.Common/Configuration/GraphicsBackend.cs
Normal file
12
src/Ryujinx.Common/Configuration/GraphicsBackend.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<GraphicsBackend>))]
|
||||
public enum GraphicsBackend
|
||||
{
|
||||
Vulkan,
|
||||
OpenGl
|
||||
}
|
||||
}
|
14
src/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs
Normal file
14
src/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<GraphicsDebugLevel>))]
|
||||
public enum GraphicsDebugLevel
|
||||
{
|
||||
None,
|
||||
Error,
|
||||
Slowdowns,
|
||||
All
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<GamepadInputId>))]
|
||||
public enum GamepadInputId : byte
|
||||
{
|
||||
Unbound,
|
||||
A,
|
||||
B,
|
||||
X,
|
||||
Y,
|
||||
LeftStick,
|
||||
RightStick,
|
||||
LeftShoulder,
|
||||
RightShoulder,
|
||||
|
||||
// Likely axis
|
||||
LeftTrigger,
|
||||
// Likely axis
|
||||
RightTrigger,
|
||||
|
||||
DpadUp,
|
||||
DpadDown,
|
||||
DpadLeft,
|
||||
DpadRight,
|
||||
|
||||
// Special buttons
|
||||
|
||||
Minus,
|
||||
Plus,
|
||||
|
||||
Back = Minus,
|
||||
Start = Plus,
|
||||
|
||||
Guide,
|
||||
Misc1,
|
||||
|
||||
// Xbox Elite paddle
|
||||
Paddle1,
|
||||
Paddle2,
|
||||
Paddle3,
|
||||
Paddle4,
|
||||
|
||||
// PS5 touchpad button
|
||||
Touchpad,
|
||||
|
||||
// Virtual buttons for single joycon
|
||||
SingleLeftTrigger0,
|
||||
SingleRightTrigger0,
|
||||
|
||||
SingleLeftTrigger1,
|
||||
SingleRightTrigger1,
|
||||
|
||||
Count
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
using Ryujinx.Common.Configuration.Hid.Controller.Motion;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
{
|
||||
public class GenericControllerInputConfig<Button, Stick> : GenericInputConfigurationCommon<Button> where Button : unmanaged where Stick : unmanaged
|
||||
{
|
||||
[JsonIgnore]
|
||||
private float _deadzoneLeft;
|
||||
[JsonIgnore]
|
||||
private float _deadzoneRight;
|
||||
[JsonIgnore]
|
||||
private float _triggerThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// Left JoyCon Controller Stick Bindings
|
||||
/// </summary>
|
||||
public JoyconConfigControllerStick<Button, Stick> LeftJoyconStick { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Right JoyCon Controller Stick Bindings
|
||||
/// </summary>
|
||||
public JoyconConfigControllerStick<Button, Stick> RightJoyconStick { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller Left Analog Stick Deadzone
|
||||
/// </summary>
|
||||
public float DeadzoneLeft
|
||||
{
|
||||
get => _deadzoneLeft; set
|
||||
{
|
||||
_deadzoneLeft = MathF.Round(value, 3);
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controller Right Analog Stick Deadzone
|
||||
/// </summary>
|
||||
public float DeadzoneRight
|
||||
{
|
||||
get => _deadzoneRight; set
|
||||
{
|
||||
_deadzoneRight = MathF.Round(value, 3);
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controller Left Analog Stick Range
|
||||
/// </summary>
|
||||
public float RangeLeft { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller Right Analog Stick Range
|
||||
/// </summary>
|
||||
public float RangeRight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller Trigger Threshold
|
||||
/// </summary>
|
||||
public float TriggerThreshold
|
||||
{
|
||||
get => _triggerThreshold; set
|
||||
{
|
||||
_triggerThreshold = MathF.Round(value, 3);
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Controller Motion Settings
|
||||
/// </summary>
|
||||
public MotionConfigController Motion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller Rumble Settings
|
||||
/// </summary>
|
||||
public RumbleConfigController Rumble { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
{
|
||||
public class JoyconConfigControllerStick<Button, Stick> where Button: unmanaged where Stick: unmanaged
|
||||
{
|
||||
public Stick Joystick { get; set; }
|
||||
public bool InvertStickX { get; set; }
|
||||
public bool InvertStickY { get; set; }
|
||||
public bool Rotate90CW { get; set; }
|
||||
public Button StickButton { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
|
||||
{
|
||||
public class CemuHookMotionConfigController : MotionConfigController
|
||||
{
|
||||
/// <summary>
|
||||
/// Motion Controller Slot
|
||||
/// </summary>
|
||||
public int Slot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Motion Controller Alternative Slot, for RightJoyCon in Pair mode
|
||||
/// </summary>
|
||||
public int AltSlot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Mirror motion input in Pair mode
|
||||
/// </summary>
|
||||
public bool MirrorInput { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Host address of the DSU Server
|
||||
/// </summary>
|
||||
public string DsuServerHost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Port of the DSU Server
|
||||
/// </summary>
|
||||
public int DsuServerPort { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
|
||||
{
|
||||
class JsonMotionConfigControllerConverter : JsonConverter<MotionConfigController>
|
||||
{
|
||||
private static readonly MotionConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||
|
||||
private static MotionInputBackendType GetMotionInputBackendType(ref Utf8JsonReader reader)
|
||||
{
|
||||
// Temporary reader to get the backend type
|
||||
Utf8JsonReader tempReader = reader;
|
||||
|
||||
MotionInputBackendType result = MotionInputBackendType.Invalid;
|
||||
|
||||
while (tempReader.Read())
|
||||
{
|
||||
// NOTE: We scan all properties ignoring the depth entirely on purpose.
|
||||
// The reason behind this is that we cannot track in a reliable way the depth of the object because Utf8JsonReader never emit the first TokenType == StartObject if the json start with an object.
|
||||
// As such, this code will try to parse very field named "motion_backend" to the correct enum.
|
||||
if (tempReader.TokenType == JsonTokenType.PropertyName)
|
||||
{
|
||||
string propertyName = tempReader.GetString();
|
||||
|
||||
if (propertyName.Equals("motion_backend"))
|
||||
{
|
||||
tempReader.Read();
|
||||
|
||||
if (tempReader.TokenType == JsonTokenType.String)
|
||||
{
|
||||
string backendTypeRaw = tempReader.GetString();
|
||||
|
||||
if (!Enum.TryParse(backendTypeRaw, out result))
|
||||
{
|
||||
result = MotionInputBackendType.Invalid;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override MotionConfigController Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
MotionInputBackendType motionBackendType = GetMotionInputBackendType(ref reader);
|
||||
|
||||
return motionBackendType switch
|
||||
{
|
||||
MotionInputBackendType.GamepadDriver => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardMotionConfigController),
|
||||
MotionInputBackendType.CemuHook => JsonSerializer.Deserialize(ref reader, SerializerContext.CemuHookMotionConfigController),
|
||||
_ => throw new InvalidOperationException($"Unknown backend type {motionBackendType}"),
|
||||
};
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, MotionConfigController value, JsonSerializerOptions options)
|
||||
{
|
||||
switch (value.MotionBackend)
|
||||
{
|
||||
case MotionInputBackendType.GamepadDriver:
|
||||
JsonSerializer.Serialize(writer, value as StandardMotionConfigController, SerializerContext.StandardMotionConfigController);
|
||||
break;
|
||||
case MotionInputBackendType.CemuHook:
|
||||
JsonSerializer.Serialize(writer, value as CemuHookMotionConfigController, SerializerContext.CemuHookMotionConfigController);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException($"Unknown motion backend type {value.MotionBackend}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
|
||||
{
|
||||
[JsonConverter(typeof(JsonMotionConfigControllerConverter))]
|
||||
public class MotionConfigController
|
||||
{
|
||||
public MotionInputBackendType MotionBackend { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gyro Sensitivity
|
||||
/// </summary>
|
||||
public int Sensitivity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gyro Deadzone
|
||||
/// </summary>
|
||||
public double GyroDeadzone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable Motion Controls
|
||||
/// </summary>
|
||||
public bool EnableMotion { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
|
||||
{
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(MotionConfigController))]
|
||||
[JsonSerializable(typeof(CemuHookMotionConfigController))]
|
||||
[JsonSerializable(typeof(StandardMotionConfigController))]
|
||||
public partial class MotionConfigJsonSerializerContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<MotionInputBackendType>))]
|
||||
public enum MotionInputBackendType : byte
|
||||
{
|
||||
Invalid,
|
||||
GamepadDriver,
|
||||
CemuHook
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
|
||||
{
|
||||
public class StandardMotionConfigController : MotionConfigController { }
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
{
|
||||
public class RumbleConfigController
|
||||
{
|
||||
/// <summary>
|
||||
/// Controller Strong Rumble Multiplier
|
||||
/// </summary>
|
||||
public float StrongRumble { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller Weak Rumble Multiplier
|
||||
/// </summary>
|
||||
public float WeakRumble { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable Rumble
|
||||
/// </summary>
|
||||
public bool EnableRumble { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
{
|
||||
public class StandardControllerInputConfig : GenericControllerInputConfig<GamepadInputId, StickInputId> { }
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<StickInputId>))]
|
||||
public enum StickInputId : byte
|
||||
{
|
||||
Unbound,
|
||||
Left,
|
||||
Right,
|
||||
|
||||
Count
|
||||
}
|
||||
}
|
23
src/Ryujinx.Common/Configuration/Hid/ControllerType.cs
Normal file
23
src/Ryujinx.Common/Configuration/Hid/ControllerType.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||
[Flags]
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<ControllerType>))]
|
||||
public enum ControllerType : int
|
||||
{
|
||||
None,
|
||||
ProController = 1 << 0,
|
||||
Handheld = 1 << 1,
|
||||
JoyconPair = 1 << 2,
|
||||
JoyconLeft = 1 << 3,
|
||||
JoyconRight = 1 << 4,
|
||||
Invalid = 1 << 5,
|
||||
Pokeball = 1 << 6,
|
||||
SystemExternal = 1 << 29,
|
||||
System = 1 << 30
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
public class GenericInputConfigurationCommon<Button> : InputConfig where Button : unmanaged
|
||||
{
|
||||
/// <summary>
|
||||
/// Left JoyCon Controller Bindings
|
||||
/// </summary>
|
||||
public LeftJoyconCommonConfig<Button> LeftJoycon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Right JoyCon Controller Bindings
|
||||
/// </summary>
|
||||
public RightJoyconCommonConfig<Button> RightJoycon { get; set; }
|
||||
}
|
||||
}
|
13
src/Ryujinx.Common/Configuration/Hid/InputBackendType.cs
Normal file
13
src/Ryujinx.Common/Configuration/Hid/InputBackendType.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<InputBackendType>))]
|
||||
public enum InputBackendType
|
||||
{
|
||||
Invalid,
|
||||
WindowKeyboard,
|
||||
GamepadSDL2,
|
||||
}
|
||||
}
|
41
src/Ryujinx.Common/Configuration/Hid/InputConfig.cs
Normal file
41
src/Ryujinx.Common/Configuration/Hid/InputConfig.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
[JsonConverter(typeof(JsonInputConfigConverter))]
|
||||
public class InputConfig : INotifyPropertyChanged
|
||||
{
|
||||
/// <summary>
|
||||
/// The current version of the input file format
|
||||
/// </summary>
|
||||
public const int CurrentVersion = 1;
|
||||
|
||||
public int Version { get; set; }
|
||||
|
||||
public InputBackendType Backend { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller id
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controller's Type
|
||||
/// </summary>
|
||||
public ControllerType ControllerType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Player's Index for the controller
|
||||
/// </summary>
|
||||
public PlayerIndex PlayerIndex { get; set; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(InputConfig))]
|
||||
[JsonSerializable(typeof(StandardKeyboardInputConfig))]
|
||||
[JsonSerializable(typeof(StandardControllerInputConfig))]
|
||||
public partial class InputConfigJsonSerializerContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||
using Ryujinx.Common.Utilities;
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
public class JsonInputConfigConverter : JsonConverter<InputConfig>
|
||||
{
|
||||
private static readonly InputConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||
|
||||
private static InputBackendType GetInputBackendType(ref Utf8JsonReader reader)
|
||||
{
|
||||
// Temporary reader to get the backend type
|
||||
Utf8JsonReader tempReader = reader;
|
||||
|
||||
InputBackendType result = InputBackendType.Invalid;
|
||||
|
||||
while (tempReader.Read())
|
||||
{
|
||||
// NOTE: We scan all properties ignoring the depth entirely on purpose.
|
||||
// The reason behind this is that we cannot track in a reliable way the depth of the object because Utf8JsonReader never emit the first TokenType == StartObject if the json start with an object.
|
||||
// As such, this code will try to parse very field named "backend" to the correct enum.
|
||||
if (tempReader.TokenType == JsonTokenType.PropertyName)
|
||||
{
|
||||
string propertyName = tempReader.GetString();
|
||||
|
||||
if (propertyName.Equals("backend"))
|
||||
{
|
||||
tempReader.Read();
|
||||
|
||||
if (tempReader.TokenType == JsonTokenType.String)
|
||||
{
|
||||
string backendTypeRaw = tempReader.GetString();
|
||||
|
||||
if (!Enum.TryParse(backendTypeRaw, out result))
|
||||
{
|
||||
result = InputBackendType.Invalid;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override InputConfig Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
InputBackendType backendType = GetInputBackendType(ref reader);
|
||||
|
||||
return backendType switch
|
||||
{
|
||||
InputBackendType.WindowKeyboard => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardKeyboardInputConfig),
|
||||
InputBackendType.GamepadSDL2 => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardControllerInputConfig),
|
||||
_ => throw new InvalidOperationException($"Unknown backend type {backendType}"),
|
||||
};
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, InputConfig value, JsonSerializerOptions options)
|
||||
{
|
||||
switch (value.Backend)
|
||||
{
|
||||
case InputBackendType.WindowKeyboard:
|
||||
JsonSerializer.Serialize(writer, value as StandardKeyboardInputConfig, SerializerContext.StandardKeyboardInputConfig);
|
||||
break;
|
||||
case InputBackendType.GamepadSDL2:
|
||||
JsonSerializer.Serialize(writer, value as StandardControllerInputConfig, SerializerContext.StandardControllerInputConfig);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException($"Unknown backend type {value.Backend}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
143
src/Ryujinx.Common/Configuration/Hid/Key.cs
Normal file
143
src/Ryujinx.Common/Configuration/Hid/Key.cs
Normal file
|
@ -0,0 +1,143 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<Key>))]
|
||||
public enum Key
|
||||
{
|
||||
Unknown,
|
||||
ShiftLeft,
|
||||
ShiftRight,
|
||||
ControlLeft,
|
||||
ControlRight,
|
||||
AltLeft,
|
||||
AltRight,
|
||||
WinLeft,
|
||||
WinRight,
|
||||
Menu,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
F11,
|
||||
F12,
|
||||
F13,
|
||||
F14,
|
||||
F15,
|
||||
F16,
|
||||
F17,
|
||||
F18,
|
||||
F19,
|
||||
F20,
|
||||
F21,
|
||||
F22,
|
||||
F23,
|
||||
F24,
|
||||
F25,
|
||||
F26,
|
||||
F27,
|
||||
F28,
|
||||
F29,
|
||||
F30,
|
||||
F31,
|
||||
F32,
|
||||
F33,
|
||||
F34,
|
||||
F35,
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
Enter,
|
||||
Escape,
|
||||
Space,
|
||||
Tab,
|
||||
BackSpace,
|
||||
Insert,
|
||||
Delete,
|
||||
PageUp,
|
||||
PageDown,
|
||||
Home,
|
||||
End,
|
||||
CapsLock,
|
||||
ScrollLock,
|
||||
PrintScreen,
|
||||
Pause,
|
||||
NumLock,
|
||||
Clear,
|
||||
Keypad0,
|
||||
Keypad1,
|
||||
Keypad2,
|
||||
Keypad3,
|
||||
Keypad4,
|
||||
Keypad5,
|
||||
Keypad6,
|
||||
Keypad7,
|
||||
Keypad8,
|
||||
Keypad9,
|
||||
KeypadDivide,
|
||||
KeypadMultiply,
|
||||
KeypadSubtract,
|
||||
KeypadAdd,
|
||||
KeypadDecimal,
|
||||
KeypadEnter,
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
K,
|
||||
L,
|
||||
M,
|
||||
N,
|
||||
O,
|
||||
P,
|
||||
Q,
|
||||
R,
|
||||
S,
|
||||
T,
|
||||
U,
|
||||
V,
|
||||
W,
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
Number0,
|
||||
Number1,
|
||||
Number2,
|
||||
Number3,
|
||||
Number4,
|
||||
Number5,
|
||||
Number6,
|
||||
Number7,
|
||||
Number8,
|
||||
Number9,
|
||||
Tilde,
|
||||
Grave,
|
||||
Minus,
|
||||
Plus,
|
||||
BracketLeft,
|
||||
BracketRight,
|
||||
Semicolon,
|
||||
Quote,
|
||||
Comma,
|
||||
Period,
|
||||
Slash,
|
||||
BackSlash,
|
||||
Unbound,
|
||||
|
||||
Count
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid.Keyboard
|
||||
{
|
||||
public class GenericKeyboardInputConfig<Key> : GenericInputConfigurationCommon<Key> where Key : unmanaged
|
||||
{
|
||||
/// <summary>
|
||||
/// Left JoyCon Controller Stick Bindings
|
||||
/// </summary>
|
||||
public JoyconConfigKeyboardStick<Key> LeftJoyconStick { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Right JoyCon Controller Stick Bindings
|
||||
/// </summary>
|
||||
public JoyconConfigKeyboardStick<Key> RightJoyconStick { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid.Keyboard
|
||||
{
|
||||
public class JoyconConfigKeyboardStick<Key> where Key: unmanaged
|
||||
{
|
||||
public Key StickUp { get; set; }
|
||||
public Key StickDown { get; set; }
|
||||
public Key StickLeft { get; set; }
|
||||
public Key StickRight { get; set; }
|
||||
public Key StickButton { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid.Keyboard
|
||||
{
|
||||
public class StandardKeyboardInputConfig : GenericKeyboardInputConfig<Key> { }
|
||||
}
|
17
src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
Normal file
17
src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
// NOTE: Please don't change this to struct.
|
||||
// This breaks Avalonia's TwoWay binding, which makes us unable to save new KeyboardHotkeys.
|
||||
public class KeyboardHotkeys
|
||||
{
|
||||
public Key ToggleVsync { get; set; }
|
||||
public Key Screenshot { get; set; }
|
||||
public Key ShowUi { get; set; }
|
||||
public Key Pause { get; set; }
|
||||
public Key ToggleMute { get; set; }
|
||||
public Key ResScaleUp { get; set; }
|
||||
public Key ResScaleDown { get; set; }
|
||||
public Key VolumeUp { get; set; }
|
||||
public Key VolumeDown { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
public class LeftJoyconCommonConfig<Button>
|
||||
{
|
||||
public Button ButtonMinus { get; set; }
|
||||
public Button ButtonL { get; set; }
|
||||
public Button ButtonZl { get; set; }
|
||||
public Button ButtonSl { get; set; }
|
||||
public Button ButtonSr { get; set; }
|
||||
public Button DpadUp { get; set; }
|
||||
public Button DpadDown { get; set; }
|
||||
public Button DpadLeft { get; set; }
|
||||
public Button DpadRight { get; set; }
|
||||
}
|
||||
}
|
22
src/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
Normal file
22
src/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<PlayerIndex>))]
|
||||
public enum PlayerIndex : int
|
||||
{
|
||||
Player1 = 0,
|
||||
Player2 = 1,
|
||||
Player3 = 2,
|
||||
Player4 = 3,
|
||||
Player5 = 4,
|
||||
Player6 = 5,
|
||||
Player7 = 6,
|
||||
Player8 = 7,
|
||||
Handheld = 8,
|
||||
Unknown = 9,
|
||||
Auto = 10 // Shouldn't be used directly
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
namespace Ryujinx.Common.Configuration.Hid
|
||||
{
|
||||
public class RightJoyconCommonConfig<Button>
|
||||
{
|
||||
public Button ButtonPlus { get; set; }
|
||||
public Button ButtonR { get; set; }
|
||||
public Button ButtonZr { get; set; }
|
||||
public Button ButtonSl { get; set; }
|
||||
public Button ButtonSr { get; set; }
|
||||
public Button ButtonX { get; set; }
|
||||
public Button ButtonB { get; set; }
|
||||
public Button ButtonY { get; set; }
|
||||
public Button ButtonA { get; set; }
|
||||
}
|
||||
}
|
13
src/Ryujinx.Common/Configuration/MemoryManagerMode.cs
Normal file
13
src/Ryujinx.Common/Configuration/MemoryManagerMode.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<MemoryManagerMode>))]
|
||||
public enum MemoryManagerMode : byte
|
||||
{
|
||||
SoftwarePageTable,
|
||||
HostMapped,
|
||||
HostMappedUnsafe
|
||||
}
|
||||
}
|
13
src/Ryujinx.Common/Configuration/ScalingFilter.cs
Normal file
13
src/Ryujinx.Common/Configuration/ScalingFilter.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using Ryujinx.Common.Utilities;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonConverter(typeof(TypedStringEnumConverter<ScalingFilter>))]
|
||||
public enum ScalingFilter
|
||||
{
|
||||
Bilinear,
|
||||
Nearest,
|
||||
Fsr
|
||||
}
|
||||
}
|
10
src/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs
Normal file
10
src/Ryujinx.Common/Configuration/TitleUpdateMetadata.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
public struct TitleUpdateMetadata
|
||||
{
|
||||
public string Selected { get; set; }
|
||||
public List<string> Paths { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Ryujinx.Common.Configuration
|
||||
{
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(TitleUpdateMetadata))]
|
||||
public partial class TitleUpdateMetadataJsonSerializerContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue