diff --git a/CONFIG.md b/CONFIG.md index eef7b68d99..003fc2408e 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -1,6 +1,6 @@ ## Config File -`Ryujinx.conf` should be present in executable folder (It's an *.ini file) following this format: +`Config.json` should be present in executable folder. The available settings follow: - `Logging_Enable_Info` *(bool)* diff --git a/README.md b/README.md index bdf8588ae1..2ec0ddfdbe 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ or just drag'n'drop the homebrew *.NRO / *.NSO or the game *.NSP / *.XCI on the - Controller Input is supported, see [CONFIG.md](CONFIG.md) - - Config File: `Ryujinx.conf` should be present in executable folder. + - Config File: `Config.json` should be present in executable folder. For more information [you can go here](CONFIG.md). **Help** diff --git a/Ryujinx.Common/StructIOExtension.cs b/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs similarity index 86% rename from Ryujinx.Common/StructIOExtension.cs rename to Ryujinx.Common/Extensions/BinaryReaderExtensions.cs index 8671b1920b..74385ae29a 100644 --- a/Ryujinx.Common/StructIOExtension.cs +++ b/Ryujinx.Common/Extensions/BinaryReaderExtensions.cs @@ -6,9 +6,10 @@ using System.Text; namespace Ryujinx.Common { - public static class StructIOExtension + public static class BinaryReaderExtensions { - public unsafe static T ReadStruct(this BinaryReader reader) where T : struct + public unsafe static T ReadStruct(this BinaryReader reader) + where T : struct { int size = Marshal.SizeOf(); @@ -20,7 +21,8 @@ namespace Ryujinx.Common } } - public unsafe static void WriteStruct(this BinaryWriter writer, T value) where T : struct + public unsafe static void WriteStruct(this BinaryWriter writer, T value) + where T : struct { long size = Marshal.SizeOf(); diff --git a/Ryujinx.Common/Extensions/EnumExtensions.cs b/Ryujinx.Common/Extensions/EnumExtensions.cs new file mode 100644 index 0000000000..4884e935ed --- /dev/null +++ b/Ryujinx.Common/Extensions/EnumExtensions.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ryujinx.Common +{ + public static class EnumExtensions + { + public static T[] GetValues() + { + return (T[])Enum.GetValues(typeof(T)); + } + } +} diff --git a/Ryujinx.Common/Logging/LogClass.cs b/Ryujinx.Common/Logging/LogClass.cs index f20347b6b5..66a83b376b 100644 --- a/Ryujinx.Common/Logging/LogClass.cs +++ b/Ryujinx.Common/Logging/LogClass.cs @@ -2,6 +2,7 @@ namespace Ryujinx.Common.Logging { public enum LogClass { + Application, Audio, Cpu, Font, diff --git a/Ryujinx.Common/Logging/Logger.cs b/Ryujinx.Common/Logging/Logger.cs index 35ca416bc9..031d48a0da 100644 --- a/Ryujinx.Common/Logging/Logger.cs +++ b/Ryujinx.Common/Logging/Logger.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; @@ -14,9 +15,9 @@ namespace Ryujinx.Common.Logging private static readonly bool[] m_EnabledLevels; private static readonly bool[] m_EnabledClasses; - public static event EventHandler Updated; + private static readonly List m_LogTargets; - public static bool EnableFileLog { get; set; } + public static event EventHandler Updated; static Logger() { @@ -33,9 +34,30 @@ namespace Ryujinx.Common.Logging m_EnabledClasses[index] = true; } + m_LogTargets = new List(); + m_Time = Stopwatch.StartNew(); } + public static void AddTarget(ILogTarget target) + { + m_LogTargets.Add(target); + + Updated += target.Log; + } + + public static void Shutdown() + { + Updated = null; + + foreach(var target in m_LogTargets) + { + target.Dispose(); + } + + m_LogTargets.Clear(); + } + public static void SetEnable(LogLevel logLevel, bool enabled) { m_EnabledLevels[(int)logLevel] = enabled; diff --git a/Ryujinx.Common/BitUtils.cs b/Ryujinx.Common/Utilities/BitUtils.cs similarity index 100% rename from Ryujinx.Common/BitUtils.cs rename to Ryujinx.Common/Utilities/BitUtils.cs diff --git a/Ryujinx.Common/HexUtils.cs b/Ryujinx.Common/Utilities/HexUtils.cs similarity index 100% rename from Ryujinx.Common/HexUtils.cs rename to Ryujinx.Common/Utilities/HexUtils.cs diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs index 5172c6a986..4a15f616e7 100644 --- a/Ryujinx.HLE/Switch.cs +++ b/Ryujinx.HLE/Switch.cs @@ -111,9 +111,8 @@ namespace Ryujinx.HLE { if (disposing) { - //System.Dispose(); - - //VsyncEvent.Dispose(); + System.Dispose(); + VsyncEvent.Dispose(); } } } diff --git a/Ryujinx.sln b/Ryujinx.sln index 148224faa4..990a89a2ed 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Luea", "Ryujinx.LLE\Luea.cs EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Common", "Ryujinx.Common\Ryujinx.Common.csproj", "{5FD4E4F6-8928-4B3C-BE07-28A675C17226}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{464D8AB7-B056-4A99-B207-B8DCFB47AAA9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,6 +75,10 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {EBB55AEA-C7D7-4DEB-BF96-FA1789E225E9} = {464D8AB7-B056-4A99-B207-B8DCFB47AAA9} + {D8F72938-78EF-4E8C-BAFE-531C9C3C8F15} = {464D8AB7-B056-4A99-B207-B8DCFB47AAA9} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {110169B3-3328-4730-8AB0-BA05BEF75C1A} EndGlobalSection diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs deleted file mode 100644 index a1d8cddf4d..0000000000 --- a/Ryujinx/Config.cs +++ /dev/null @@ -1,203 +0,0 @@ -using LibHac.IO; -using Ryujinx.Common.Logging; -using Ryujinx.HLE; -using Ryujinx.HLE.HOS.SystemState; -using Ryujinx.HLE.Input; -using Ryujinx.UI.Input; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; - -namespace Ryujinx -{ - public static class Config - { - public static NpadKeyboard NpadKeyboard { get; private set; } - public static NpadController NpadController { get; private set; } - - public static void Read(Switch device) - { - string iniFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); - - string iniPath = Path.Combine(iniFolder, "Ryujinx.conf"); - - IniParser parser = new IniParser(iniPath); - - GraphicsConfig.ShadersDumpPath = parser.Value("Graphics_Shaders_Dump_Path"); - - Logger.SetEnable(LogLevel.Debug, Convert.ToBoolean(parser.Value("Logging_Enable_Debug"))); - Logger.SetEnable(LogLevel.Stub, Convert.ToBoolean(parser.Value("Logging_Enable_Stub"))); - Logger.SetEnable(LogLevel.Info, Convert.ToBoolean(parser.Value("Logging_Enable_Info"))); - Logger.SetEnable(LogLevel.Warning, Convert.ToBoolean(parser.Value("Logging_Enable_Warn"))); - Logger.SetEnable(LogLevel.Error, Convert.ToBoolean(parser.Value("Logging_Enable_Error"))); - - string[] filteredLogClasses = parser.Value("Logging_Filtered_Classes").Split(',', StringSplitOptions.RemoveEmptyEntries); - - //When the classes are specified on the list, we only - //enable the classes that are on the list. - //So, first disable everything, then enable - //the classes that the user added to the list. - if (filteredLogClasses.Length > 0) - { - foreach (LogClass Class in Enum.GetValues(typeof(LogClass))) - { - Logger.SetEnable(Class, false); - } - } - - foreach (string logClass in filteredLogClasses) - { - if (!string.IsNullOrEmpty(logClass.Trim())) - { - foreach (LogClass Class in Enum.GetValues(typeof(LogClass))) - { - if (Class.ToString().ToLower().Contains(logClass.Trim().ToLower())) - { - Logger.SetEnable(Class, true); - } - } - } - } - - Logger.EnableFileLog = Convert.ToBoolean(parser.Value("Enable_File_Log")); - - SystemLanguage SetLanguage = Enum.Parse(parser.Value("System_Language")); - - device.System.State.SetLanguage(SetLanguage); - - device.System.State.DockedMode = Convert.ToBoolean(parser.Value("Docked_Mode")); - - device.EnableDeviceVsync = Convert.ToBoolean(parser.Value("Enable_Vsync")); - - if (Convert.ToBoolean(parser.Value("Enable_MultiCore_Scheduling"))) - { - device.System.EnableMultiCoreScheduling(); - } - - device.System.FsIntegrityCheckLevel = Convert.ToBoolean(parser.Value("Enable_FS_Integrity_Checks")) - ? IntegrityCheckLevel.ErrorOnInvalid - : IntegrityCheckLevel.None; - - HidControllerType ControllerType = Enum.Parse(parser.Value("Controller_Type")); - - device.Hid.InitilizePrimaryController(ControllerType); - - NpadKeyboard = new NpadKeyboard( - - new NpadKeyboardLeft - { - StickUp = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Stick_Up")), - StickDown = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Stick_Down")), - StickLeft = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Stick_Left")), - StickRight = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Stick_Right")), - StickButton = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Stick_Button")), - DPadUp = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_DPad_Up")), - DPadDown = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_DPad_Down")), - DPadLeft = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_DPad_Left")), - DPadRight = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_DPad_Right")), - ButtonMinus = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Button_Minus")), - ButtonL = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Button_L")), - ButtonZl = Convert.ToInt16(parser.Value("Controls_Left_JoyConKeyboard_Button_ZL")) - }, - - new NpadKeyboardRight - { - StickUp = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Stick_Up")), - StickDown = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Stick_Down")), - StickLeft = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Stick_Left")), - StickRight = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Stick_Right")), - StickButton = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Stick_Button")), - ButtonA = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Button_A")), - ButtonB = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Button_B")), - ButtonX = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Button_X")), - ButtonY = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Button_Y")), - ButtonPlus = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Button_Plus")), - ButtonR = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Button_R")), - ButtonZr = Convert.ToInt16(parser.Value("Controls_Right_JoyConKeyboard_Button_ZR")) - }); - - NpadController = new NpadController( - Convert.ToBoolean(parser.Value("GamePad_Enable")), - Convert.ToInt32 (parser.Value("GamePad_Index")), - (float)Convert.ToDouble (parser.Value("GamePad_Deadzone"), CultureInfo.InvariantCulture), - (float)Convert.ToDouble (parser.Value("GamePad_Trigger_Threshold"), CultureInfo.InvariantCulture), - - new NpadControllerLeft - { - Stick = ToId(parser.Value("Controls_Left_JoyConController_Stick")), - StickButton = ToId(parser.Value("Controls_Left_JoyConController_Stick_Button")), - DPadUp = ToId(parser.Value("Controls_Left_JoyConController_DPad_Up")), - DPadDown = ToId(parser.Value("Controls_Left_JoyConController_DPad_Down")), - DPadLeft = ToId(parser.Value("Controls_Left_JoyConController_DPad_Left")), - DPadRight = ToId(parser.Value("Controls_Left_JoyConController_DPad_Right")), - ButtonMinus = ToId(parser.Value("Controls_Left_JoyConController_Button_Minus")), - ButtonL = ToId(parser.Value("Controls_Left_JoyConController_Button_L")), - ButtonZl = ToId(parser.Value("Controls_Left_JoyConController_Button_ZL")) - }, - - new NpadControllerRight - { - Stick = ToId(parser.Value("Controls_Right_JoyConController_Stick")), - StickButton = ToId(parser.Value("Controls_Right_JoyConController_Stick_Button")), - ButtonA = ToId(parser.Value("Controls_Right_JoyConController_Button_A")), - ButtonB = ToId(parser.Value("Controls_Right_JoyConController_Button_B")), - ButtonX = ToId(parser.Value("Controls_Right_JoyConController_Button_X")), - ButtonY = ToId(parser.Value("Controls_Right_JoyConController_Button_Y")), - ButtonPlus = ToId(parser.Value("Controls_Right_JoyConController_Button_Plus")), - ButtonR = ToId(parser.Value("Controls_Right_JoyConController_Button_R")), - ButtonZr = ToId(parser.Value("Controls_Right_JoyConController_Button_ZR")) - }); - } - - private static ControllerInputId ToId(string key) - { - switch (key.ToUpper()) - { - case "LSTICK": return ControllerInputId.LStick; - case "DPADUP": return ControllerInputId.DPadUp; - case "DPADDOWN": return ControllerInputId.DPadDown; - case "DPADLEFT": return ControllerInputId.DPadLeft; - case "DPADRIGHT": return ControllerInputId.DPadRight; - case "BACK": return ControllerInputId.Back; - case "LSHOULDER": return ControllerInputId.LShoulder; - case "LTRIGGER": return ControllerInputId.LTrigger; - - case "RSTICK": return ControllerInputId.RStick; - case "A": return ControllerInputId.A; - case "B": return ControllerInputId.B; - case "X": return ControllerInputId.X; - case "Y": return ControllerInputId.Y; - case "START": return ControllerInputId.Start; - case "RSHOULDER": return ControllerInputId.RShoulder; - case "RTRIGGER": return ControllerInputId.RTrigger; - - case "LJOYSTICK": return ControllerInputId.LJoystick; - case "RJOYSTICK": return ControllerInputId.RJoystick; - - default: return ControllerInputId.Invalid; - } - } - } - - //https://stackoverflow.com/a/37772571 - public class IniParser - { - private readonly Dictionary _values; - - public IniParser(string path) - { - _values = File.ReadLines(path) - .Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith('#')) - .Select(line => line.Split('=', 2)) - .ToDictionary(parts => parts[0].Trim(), parts => parts.Length > 1 ? parts[1].Trim() : null); - } - - public string Value(string name) - { - return _values.TryGetValue(name, out string value) ? value : null; - } - } -} \ No newline at end of file diff --git a/Ryujinx/Config.json b/Ryujinx/Config.json new file mode 100644 index 0000000000..47839ff44c --- /dev/null +++ b/Ryujinx/Config.json @@ -0,0 +1,124 @@ +{ + "$schema": "./_schema.json", + + // Dump shaders in local directory (e.g. `C:\ShaderDumps`) + "graphics_shaders_dump_path": "WowHello", + + // Enable print debug logs + "logging_enable_debug": false, + + // Enable print stubbed calls logs + "logging_enable_stub": true, + + // Enable print informations logs + "logging_enable_info": true, + + // Enable print warning logs + "logging_enable_warn": true, + + // Enable print error logs + "logging_enable_error": true, + + // Filtered log classes, in a JSON array, eg. `[ "Loader", "ServiceFS" ]` + "logging_filtered_classes": [ ], + + // Enable file logging + "enable_file_log": true, + + // Change System Language + // System Language list: https://gist.github.com/HorrorTroll/b6e4a88d774c3c9b3bdf54d79a7ca43b + "system_language": "AmericanEnglish", + + // Enable or Disable Docked Mode + "docked_mode": false, + + // Enable Game Vsync + "enable_vsync": true, + + // Enable or Disable Multi-core scheduling of threads + "enable_multicore_scheduling": false, + + // Enable integrity checks on Switch content files + "enable_fs_integrity_checks": true, + + // The primary controller's type. + // Supported Values: Handheld, ProController, NpadPair, NpadLeft, NpadRight + "controller_type": "Handheld", + + // Keyboard Controls + // https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs + "keyboard_controls": { + // Left JoyCon Keyboard Bindings + "left_joycon": { + "stick_up": "W", + "stick_down": "S", + "stick_left": "A", + "stick_right": "D", + "stick_button": "F", + "dpad_up": "Up", + "dpad_down": "Down", + "dpad_left": "Left", + "dpad_right": "Right", + "button_minus": "Minus", + "button_l": "E", + "button_zl": "Q" + }, + + // Right JoyCon Keyboard Bindings + "right_joycon": { + "stick_up": "I", + "stick_down": "K", + "stick_left": "J", + "stick_right": "L", + "stick_button": "H", + "button_a": "A", + "button_b": "X", + "button_x": "C", + "button_y": "V", + "button_plus": "Plus", + "button_r": "U", + "button_zr": "O" + } + }, + + // Controller Controls + "gamepad_controls": { + // Whether or not to enable Controller support + "enabled": true, + + // Controller Device Index + "index": 0, + + // Controller Analog Stick Deadzone + "deadzone": 0.05, + + // The value of how pressed down each trigger has to be in order to register a button press + "trigger_threshold": 0.5, + + // Left JoyCon Controller Bindings + "left_joycon": { + "stick": "LJoystick", + "stick_button": "LStick", + "dpad_up": "DPadUp", + "dpad_down": "DPadDown", + "dpad_left": "DPadLeft", + "dpad_right": "DPadRight", + "button_minus": "Back", + "button_l": "LShoulder", + "button_zl": "LTrigger" + }, + + // Right JoyCon Controller Bindings + "right_joycon": { + "stick": "RJoystick", + "stick_button": "RStick", + "button_a": "B", + "button_b": "A", + "button_x": "Y", + "button_y": "X", + "button_plus": "Start", + "button_r": "RShoulder", + "button_zr": "RTrigger" + } + } +} \ No newline at end of file diff --git a/Ryujinx/Configuration.cs b/Ryujinx/Configuration.cs new file mode 100644 index 0000000000..22a4dfb99e --- /dev/null +++ b/Ryujinx/Configuration.cs @@ -0,0 +1,243 @@ +using LibHac.IO; +using OpenTK.Input; +using Ryujinx.Common; +using Ryujinx.Common.Logging; +using Ryujinx.HLE; +using Ryujinx.HLE.HOS.SystemState; +using Ryujinx.HLE.Input; +using Ryujinx.UI.Input; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using Utf8Json; +using Utf8Json.Formatters; +using Utf8Json.Internal; +using Utf8Json.Resolvers; + +namespace Ryujinx +{ + public class Configuration + { + /// + /// The default configuration instance + /// + public static Configuration Default { get; private set; } + + /// + /// Dumps shaders in this local directory + /// + public string GraphicsShadersDumpPath { get; private set; } + + /// + /// Enables printing debug log messages + /// + public bool LoggingEnableDebug { get; private set; } + + /// + /// Enables printing stub log messages + /// + public bool LoggingEnableStub { get; private set; } + + /// + /// Enables printing info log messages + /// + public bool LoggingEnableInfo { get; private set; } + + /// + /// Enables printing warning log messages + /// + public bool LoggingEnableWarn { get; private set; } + + /// + /// Enables printing error log messages + /// + public bool LoggingEnableError { get; private set; } + + /// + /// Controls which log messages are written to the log targets + /// + public LogClass[] LoggingFilteredClasses { get; private set; } + + /// + /// Enables or disables logging to a file on disk + /// + public bool EnableFileLog { get; private set; } + + /// + /// Change System Language + /// + public SystemLanguage SystemLanguage { get; private set; } + + /// + /// Enables or disables Docked Mode + /// + public bool DockedMode { get; private set; } + + /// + /// Enables or disables Vertical Sync + /// + public bool EnableVsync { get; private set; } + + /// + /// Enables or disables multi-core scheduling of threads + /// + public bool EnableMultiCoreScheduling { get; private set; } + + /// + /// Enables integrity checks on Game content files + /// + public bool EnableFsIntegrityChecks { get; private set; } + + /// + /// + /// + public HidControllerType ControllerType { get; private set; } + + /// + /// + /// + public NpadKeyboard KeyboardControls { get; private set; } + + /// + /// + /// + public NpadController GamepadControls { get; private set; } + + /// + /// Loads a configuration file from disk + /// + /// The path to the JSON configuration file + public static void Load(string path) + { + var resolver = CompositeResolver.Create( + new[] { new ConfigurationEnumFormatter() }, + new[] { StandardResolver.AllowPrivateSnakeCase } + ); + + using (Stream stream = File.OpenRead(path)) + { + Default = JsonSerializer.Deserialize(stream, resolver); + } + } + + /// + /// Loads a configuration file asynchronously from disk + /// + /// The path to the JSON configuration file + public static async Task LoadAsync(string path) + { + var resolver = CompositeResolver.Create(StandardResolver.AllowPrivateSnakeCase); + + using (Stream stream = File.OpenRead(path)) + { + Default = await JsonSerializer.DeserializeAsync(stream, resolver); + } + } + + /// + /// Configures a instance + /// + /// The instance to configure + public static void Configure(Switch device) + { + if (Default == null) + { + throw new InvalidOperationException("Configuration has not been loaded yet."); + } + + GraphicsConfig.ShadersDumpPath = Default.GraphicsShadersDumpPath; + + Logger.AddTarget(new AsyncLogTargetWrapper( + new ConsoleLogTarget(), + 1000, + AsyncLogTargetOverflowAction.Block + )); + + if (Default.EnableFileLog) + { + Logger.AddTarget(new AsyncLogTargetWrapper( + new FileLogTarget("Ryujinx.log"), + 1000, + AsyncLogTargetOverflowAction.Block + )); + } + + Logger.SetEnable(LogLevel.Debug, Default.LoggingEnableDebug); + Logger.SetEnable(LogLevel.Stub, Default.LoggingEnableStub); + Logger.SetEnable(LogLevel.Info, Default.LoggingEnableInfo); + Logger.SetEnable(LogLevel.Warning, Default.LoggingEnableWarn); + Logger.SetEnable(LogLevel.Error, Default.LoggingEnableError); + + if (Default.LoggingFilteredClasses.Length > 0) + { + foreach (var logClass in EnumExtensions.GetValues()) + { + Logger.SetEnable(logClass, false); + } + + foreach (var logClass in Default.LoggingFilteredClasses) + { + Logger.SetEnable(logClass, true); + } + } + + device.EnableDeviceVsync = Default.EnableVsync; + + device.System.State.DockedMode = Default.DockedMode; + + device.System.State.SetLanguage(Default.SystemLanguage); + + if (Default.EnableMultiCoreScheduling) + { + device.System.EnableMultiCoreScheduling(); + } + + device.System.FsIntegrityCheckLevel = Default.EnableFsIntegrityChecks + ? IntegrityCheckLevel.ErrorOnInvalid + : IntegrityCheckLevel.None; + + if(Default.GamepadControls.Enabled) + { + if (GamePad.GetName(Default.GamepadControls.Index) == "Unmapped Controller") + { + Default.GamepadControls.SetEnabled(false); + } + } + + device.Hid.InitilizePrimaryController(Default.ControllerType); + } + + private class ConfigurationEnumFormatter : IJsonFormatter + where T : struct + { + public void Serialize(ref JsonWriter writer, T value, IJsonFormatterResolver formatterResolver) + { + formatterResolver.GetFormatterWithVerify() + .Serialize(ref writer, value.ToString(), formatterResolver); + } + + public T Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) + { + if (reader.ReadIsNull()) + { + return default(T); + } + + var enumName = formatterResolver.GetFormatterWithVerify() + .Deserialize(ref reader, formatterResolver); + + if(Enum.TryParse(enumName, out T result)) + { + return result; + } + + return default(T); + } + } + } +} \ No newline at end of file diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs index 8492e58a30..81b0472a0f 100644 --- a/Ryujinx/Program.cs +++ b/Ryujinx/Program.cs @@ -10,9 +10,6 @@ namespace Ryujinx { class Program { - static ILogTarget _fileTarget; - static ILogTarget _consoleTarget; - static void Main(string[] args) { Console.Title = "Ryujinx Console"; @@ -23,13 +20,8 @@ namespace Ryujinx Switch device = new Switch(renderer, audioOut); - Config.Read(device); - - _fileTarget = new AsyncLogTargetWrapper(new FileLogTarget("Ryujinx.log"), 1000, AsyncLogTargetOverflowAction.Block); - _consoleTarget = new AsyncLogTargetWrapper(new ConsoleLogTarget(), 1000, AsyncLogTargetOverflowAction.Block); - - Logger.Updated += _fileTarget.Log; - Logger.Updated += _consoleTarget.Log; + Configuration.Load("Config.json"); + Configuration.Configure(device); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; @@ -47,13 +39,13 @@ namespace Ryujinx if (romFsFiles.Length > 0) { - Console.WriteLine("Loading as cart with RomFS."); + Logger.PrintInfo(LogClass.Application, "Loading as cart with RomFS."); device.LoadCart(args[0], romFsFiles[0]); } else { - Console.WriteLine("Loading as cart WITHOUT RomFS."); + Logger.PrintInfo(LogClass.Application, "Loading as cart WITHOUT RomFS."); device.LoadCart(args[0]); } @@ -63,20 +55,20 @@ namespace Ryujinx switch (Path.GetExtension(args[0]).ToLowerInvariant()) { case ".xci": - Console.WriteLine("Loading as XCI."); + Logger.PrintInfo(LogClass.Application, "Loading as XCI."); device.LoadXci(args[0]); break; case ".nca": - Console.WriteLine("Loading as NCA."); + Logger.PrintInfo(LogClass.Application, "Loading as NCA."); device.LoadNca(args[0]); break; case ".nsp": case ".pfs0": - Console.WriteLine("Loading as NSP."); + Logger.PrintInfo(LogClass.Application, "Loading as NSP."); device.LoadNsp(args[0]); break; default: - Console.WriteLine("Loading as homebrew."); + Logger.PrintInfo(LogClass.Application, "Loading as homebrew."); device.LoadProgram(args[0]); break; } @@ -84,7 +76,7 @@ namespace Ryujinx } else { - Console.WriteLine("Please specify the folder with the NSOs/IStorage or a NSO/NRO."); + Logger.PrintInfo(LogClass.Application, "Please specify the folder with the NSOs/IStorage or a NSO/NRO."); } using (GlScreen screen = new GlScreen(device, renderer)) @@ -95,12 +87,13 @@ namespace Ryujinx } audioOut.Dispose(); + + Logger.Shutdown(); } private static void CurrentDomain_ProcessExit(object sender, EventArgs e) { - _fileTarget.Dispose(); - _consoleTarget.Dispose(); + Logger.Shutdown(); } private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) @@ -111,8 +104,7 @@ namespace Ryujinx if (e.IsTerminating) { - _fileTarget.Dispose(); - _consoleTarget.Dispose(); + Logger.Shutdown(); } } diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf deleted file mode 100644 index 604b14ed6f..0000000000 --- a/Ryujinx/Ryujinx.conf +++ /dev/null @@ -1,107 +0,0 @@ -#Enable cpu memory checks (slow) -Enable_Memory_Checks = false - -#Dump shaders in local directory (e.g. `C:\ShaderDumps`) -Graphics_Shaders_Dump_Path = - -#Enable print debug logs -Logging_Enable_Debug = false - -#Enable print stubbed calls logs -Logging_Enable_Stub = true - -#Enable print informations logs -Logging_Enable_Info = true - -#Enable print warning logs -Logging_Enable_Warn = true - -#Enable print error logs -Logging_Enable_Error = true - -#Filtered log classes, seperated by ", ", eg. `Logging_Filtered_Classes = Loader, ServiceFS` -Logging_Filtered_Classes = - -#Enable file logging -Enable_File_Log = false - -#System Language list: https://gist.github.com/HorrorTroll/b6e4a88d774c3c9b3bdf54d79a7ca43b -#Change System Language -System_Language = AmericanEnglish - -#Enable or Disable Docked Mode -Docked_Mode = false - -#Enable Game Vsync -Enable_Vsync = true - -#Enable or Disable Multi-core scheduling of threads -Enable_MultiCore_Scheduling = false - -#Enable integrity checks on Switch content files -Enable_FS_Integrity_Checks = true - -#Controller Device Index -GamePad_Index = 0 - -#Controller Analog Stick Deadzone -GamePad_Deadzone = 0.05 - -#The value of how pressed down each trigger has to be in order to register a button press -GamePad_Trigger_Threshold = 0.5 - -#Whether or not to enable Controller support -GamePad_Enable = true - -#The primary controller's type. Supported Values: ProController, Handheld, NpadPair, NpadLeft, NpadRight -Controller_Type = Handheld - -#https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs -Controls_Left_JoyConKeyboard_Stick_Up = 105 -Controls_Left_JoyConKeyboard_Stick_Down = 101 -Controls_Left_JoyConKeyboard_Stick_Left = 83 -Controls_Left_JoyConKeyboard_Stick_Right = 86 -Controls_Left_JoyConKeyboard_Stick_Button = 88 -Controls_Left_JoyConKeyboard_DPad_Up = 45 -Controls_Left_JoyConKeyboard_DPad_Down = 46 -Controls_Left_JoyConKeyboard_DPad_Left = 47 -Controls_Left_JoyConKeyboard_DPad_Right = 48 -Controls_Left_JoyConKeyboard_Button_Minus = 120 -Controls_Left_JoyConKeyboard_Button_L = 87 -Controls_Left_JoyConKeyboard_Button_ZL = 99 - -Controls_Right_JoyConKeyboard_Stick_Up = 91 -Controls_Right_JoyConKeyboard_Stick_Down = 93 -Controls_Right_JoyConKeyboard_Stick_Left = 92 -Controls_Right_JoyConKeyboard_Stick_Right = 94 -Controls_Right_JoyConKeyboard_Stick_Button = 90 -Controls_Right_JoyConKeyboard_Button_A = 108 -Controls_Right_JoyConKeyboard_Button_B = 106 -Controls_Right_JoyConKeyboard_Button_X = 85 -Controls_Right_JoyConKeyboard_Button_Y = 104 -Controls_Right_JoyConKeyboard_Button_Plus = 121 -Controls_Right_JoyConKeyboard_Button_R = 103 -Controls_Right_JoyConKeyboard_Button_ZR = 97 - -#Controller Controls - -Controls_Left_JoyConController_Stick_Button = LStick -Controls_Left_JoyConController_DPad_Up = DPadUp -Controls_Left_JoyConController_DPad_Down = DPadDown -Controls_Left_JoyConController_DPad_Left = DPadLeft -Controls_Left_JoyConController_DPad_Right = DPadRight -Controls_Left_JoyConController_Button_Minus = Back -Controls_Left_JoyConController_Button_L = LShoulder -Controls_Left_JoyConController_Button_ZL = LTrigger - -Controls_Right_JoyConController_Stick_Button = RStick -Controls_Right_JoyConController_Button_A = B -Controls_Right_JoyConController_Button_B = A -Controls_Right_JoyConController_Button_X = Y -Controls_Right_JoyConController_Button_Y = X -Controls_Right_JoyConController_Button_Plus = Start -Controls_Right_JoyConController_Button_R = RShoulder -Controls_Right_JoyConController_Button_ZR = RTrigger - -Controls_Left_JoyConController_Stick = LJoystick -Controls_Right_JoyConController_Stick = RJoystick diff --git a/Ryujinx/Ryujinx.csproj b/Ryujinx/Ryujinx.csproj index 1789ef2e9f..3686782e13 100644 --- a/Ryujinx/Ryujinx.csproj +++ b/Ryujinx/Ryujinx.csproj @@ -20,7 +20,7 @@ - + PreserveNewest diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs index e3a6d299bc..f453f7cee6 100644 --- a/Ryujinx/Ui/GLScreen.cs +++ b/Ryujinx/Ui/GLScreen.cs @@ -142,24 +142,24 @@ namespace Ryujinx { KeyboardState keyboard = _keyboard.Value; - currentButton = Config.NpadKeyboard.GetButtons(keyboard); + currentButton = Configuration.Default.KeyboardControls.GetButtons(keyboard); - (leftJoystickDx, leftJoystickDy) = Config.NpadKeyboard.GetLeftStick(keyboard); + (leftJoystickDx, leftJoystickDy) = Configuration.Default.KeyboardControls.GetLeftStick(keyboard); - (rightJoystickDx, rightJoystickDy) = Config.NpadKeyboard.GetRightStick(keyboard); + (rightJoystickDx, rightJoystickDy) = Configuration.Default.KeyboardControls.GetRightStick(keyboard); } - currentButton |= Config.NpadController.GetButtons(); + currentButton |= Configuration.Default.GamepadControls.GetButtons(); //Keyboard has priority stick-wise if (leftJoystickDx == 0 && leftJoystickDy == 0) { - (leftJoystickDx, leftJoystickDy) = Config.NpadController.GetLeftStick(); + (leftJoystickDx, leftJoystickDy) = Configuration.Default.GamepadControls.GetLeftStick(); } if (rightJoystickDx == 0 && rightJoystickDy == 0) { - (rightJoystickDx, rightJoystickDy) = Config.NpadController.GetRightStick(); + (rightJoystickDx, rightJoystickDy) = Configuration.Default.GamepadControls.GetRightStick(); } leftJoystick = new HidJoystickPosition diff --git a/Ryujinx/Ui/NpadController.cs b/Ryujinx/Ui/NpadController.cs index 58d2d46a2f..b55c4a669f 100644 --- a/Ryujinx/Ui/NpadController.cs +++ b/Ryujinx/Ui/NpadController.cs @@ -2,13 +2,13 @@ using OpenTK.Input; using Ryujinx.HLE.Input; using System; +using System.Runtime.Serialization; namespace Ryujinx.UI.Input { public enum ControllerInputId { Invalid, - LStick, DPadUp, DPadDown, @@ -16,7 +16,6 @@ namespace Ryujinx.UI.Input DPadRight, Back, LShoulder, - RStick, A, B, @@ -24,10 +23,8 @@ namespace Ryujinx.UI.Input Y, Start, RShoulder, - LTrigger, RTrigger, - LJoystick, RJoystick } @@ -60,34 +57,55 @@ namespace Ryujinx.UI.Input public class NpadController { - public bool Enabled { private set; get; } - public int Index { private set; get; } - public float Deadzone { private set; get; } - public float TriggerThreshold { private set; get; } + /// + /// Enables or disables controller support + /// + public bool Enabled { get; private set; } - public NpadControllerLeft Left { private set; get; } - public NpadControllerRight Right { private set; get; } + /// + /// Controller Device Index + /// + public int Index { get; private set; } + + /// + /// Controller Analog Stick Deadzone + /// + public float Deadzone { get; private set; } + + /// + /// Controller Trigger Threshold + /// + public float TriggerThreshold { get; private set; } + + /// + /// Left JoyCon Controller Bindings + /// + public NpadControllerLeft LeftJoycon { get; private set; } + + /// + /// Right JoyCon Controller Bindings + /// + public NpadControllerRight RightJoycon { get; private set; } public NpadController( - bool enabled, - int index, - float deadzone, - float triggerThreshold, - NpadControllerLeft left, - NpadControllerRight right) + bool enabled, + int index, + float deadzone, + float triggerThreshold, + NpadControllerLeft leftJoycon, + NpadControllerRight rightJoycon) { Enabled = enabled; Index = index; Deadzone = deadzone; TriggerThreshold = triggerThreshold; - Left = left; - Right = right; + LeftJoycon = leftJoycon; + RightJoycon = rightJoycon; + } - //Unmapped controllers are problematic, skip them - if (GamePad.GetName(index) == "Unmapped Controller") - { - Enabled = false; - } + public void SetEnabled(bool enabled) + { + Enabled = enabled; } public HidControllerButtons GetButtons() @@ -101,23 +119,23 @@ namespace Ryujinx.UI.Input HidControllerButtons buttons = 0; - if (IsPressed(gpState, Left.DPadUp)) buttons |= HidControllerButtons.DpadUp; - if (IsPressed(gpState, Left.DPadDown)) buttons |= HidControllerButtons.DpadDown; - if (IsPressed(gpState, Left.DPadLeft)) buttons |= HidControllerButtons.DpadLeft; - if (IsPressed(gpState, Left.DPadRight)) buttons |= HidControllerButtons.DPadRight; - if (IsPressed(gpState, Left.StickButton)) buttons |= HidControllerButtons.StickLeft; - if (IsPressed(gpState, Left.ButtonMinus)) buttons |= HidControllerButtons.Minus; - if (IsPressed(gpState, Left.ButtonL)) buttons |= HidControllerButtons.L; - if (IsPressed(gpState, Left.ButtonZl)) buttons |= HidControllerButtons.Zl; + if (IsPressed(gpState, LeftJoycon.DPadUp)) buttons |= HidControllerButtons.DpadUp; + if (IsPressed(gpState, LeftJoycon.DPadDown)) buttons |= HidControllerButtons.DpadDown; + if (IsPressed(gpState, LeftJoycon.DPadLeft)) buttons |= HidControllerButtons.DpadLeft; + if (IsPressed(gpState, LeftJoycon.DPadRight)) buttons |= HidControllerButtons.DPadRight; + if (IsPressed(gpState, LeftJoycon.StickButton)) buttons |= HidControllerButtons.StickLeft; + if (IsPressed(gpState, LeftJoycon.ButtonMinus)) buttons |= HidControllerButtons.Minus; + if (IsPressed(gpState, LeftJoycon.ButtonL)) buttons |= HidControllerButtons.L; + if (IsPressed(gpState, LeftJoycon.ButtonZl)) buttons |= HidControllerButtons.Zl; - if (IsPressed(gpState, Right.ButtonA)) buttons |= HidControllerButtons.A; - if (IsPressed(gpState, Right.ButtonB)) buttons |= HidControllerButtons.B; - if (IsPressed(gpState, Right.ButtonX)) buttons |= HidControllerButtons.X; - if (IsPressed(gpState, Right.ButtonY)) buttons |= HidControllerButtons.Y; - if (IsPressed(gpState, Right.StickButton)) buttons |= HidControllerButtons.StickRight; - if (IsPressed(gpState, Right.ButtonPlus)) buttons |= HidControllerButtons.Plus; - if (IsPressed(gpState, Right.ButtonR)) buttons |= HidControllerButtons.R; - if (IsPressed(gpState, Right.ButtonZr)) buttons |= HidControllerButtons.Zr; + if (IsPressed(gpState, RightJoycon.ButtonA)) buttons |= HidControllerButtons.A; + if (IsPressed(gpState, RightJoycon.ButtonB)) buttons |= HidControllerButtons.B; + if (IsPressed(gpState, RightJoycon.ButtonX)) buttons |= HidControllerButtons.X; + if (IsPressed(gpState, RightJoycon.ButtonY)) buttons |= HidControllerButtons.Y; + if (IsPressed(gpState, RightJoycon.StickButton)) buttons |= HidControllerButtons.StickRight; + if (IsPressed(gpState, RightJoycon.ButtonPlus)) buttons |= HidControllerButtons.Plus; + if (IsPressed(gpState, RightJoycon.ButtonR)) buttons |= HidControllerButtons.R; + if (IsPressed(gpState, RightJoycon.ButtonZr)) buttons |= HidControllerButtons.Zr; return buttons; } @@ -129,7 +147,7 @@ namespace Ryujinx.UI.Input return (0, 0); } - return GetStick(Left.Stick); + return GetStick(LeftJoycon.Stick); } public (short, short) GetRightStick() @@ -139,7 +157,7 @@ namespace Ryujinx.UI.Input return (0, 0); } - return GetStick(Right.Stick); + return GetStick(RightJoycon.Stick); } private (short, short) GetStick(ControllerInputId joystick) diff --git a/Ryujinx/Ui/NpadKeyboard.cs b/Ryujinx/Ui/NpadKeyboard.cs index 704c61abc2..d61855cdb6 100644 --- a/Ryujinx/Ui/NpadKeyboard.cs +++ b/Ryujinx/Ui/NpadKeyboard.cs @@ -1,74 +1,74 @@ using OpenTK.Input; using Ryujinx.HLE.Input; +using Utf8Json; namespace Ryujinx.UI.Input { public struct NpadKeyboardLeft { - public int StickUp; - public int StickDown; - public int StickLeft; - public int StickRight; - public int StickButton; - public int DPadUp; - public int DPadDown; - public int DPadLeft; - public int DPadRight; - public int ButtonMinus; - public int ButtonL; - public int ButtonZl; + public Key StickUp; + public Key StickDown; + public Key StickLeft; + public Key StickRight; + public Key StickButton; + public Key DPadUp; + public Key DPadDown; + public Key DPadLeft; + public Key DPadRight; + public Key ButtonMinus; + public Key ButtonL; + public Key ButtonZl; } public struct NpadKeyboardRight { - public int StickUp; - public int StickDown; - public int StickLeft; - public int StickRight; - public int StickButton; - public int ButtonA; - public int ButtonB; - public int ButtonX; - public int ButtonY; - public int ButtonPlus; - public int ButtonR; - public int ButtonZr; + public Key StickUp; + public Key StickDown; + public Key StickLeft; + public Key StickRight; + public Key StickButton; + public Key ButtonA; + public Key ButtonB; + public Key ButtonX; + public Key ButtonY; + public Key ButtonPlus; + public Key ButtonR; + public Key ButtonZr; } public class NpadKeyboard { - public NpadKeyboardLeft Left; - public NpadKeyboardRight Right; + /// + /// Left JoyCon Keyboard Bindings + /// + public NpadKeyboardLeft LeftJoycon { get; private set; } - public NpadKeyboard( - NpadKeyboardLeft left, - NpadKeyboardRight right) - { - Left = left; - Right = right; - } + /// + /// Right JoyCon Keyboard Bindings + /// + public NpadKeyboardRight RightJoycon { get; private set; } public HidControllerButtons GetButtons(KeyboardState keyboard) { HidControllerButtons buttons = 0; - if (keyboard[(Key)Left.StickButton]) buttons |= HidControllerButtons.StickLeft; - if (keyboard[(Key)Left.DPadUp]) buttons |= HidControllerButtons.DpadUp; - if (keyboard[(Key)Left.DPadDown]) buttons |= HidControllerButtons.DpadDown; - if (keyboard[(Key)Left.DPadLeft]) buttons |= HidControllerButtons.DpadLeft; - if (keyboard[(Key)Left.DPadRight]) buttons |= HidControllerButtons.DPadRight; - if (keyboard[(Key)Left.ButtonMinus]) buttons |= HidControllerButtons.Minus; - if (keyboard[(Key)Left.ButtonL]) buttons |= HidControllerButtons.L; - if (keyboard[(Key)Left.ButtonZl]) buttons |= HidControllerButtons.Zl; + if (keyboard[(Key)LeftJoycon.StickButton]) buttons |= HidControllerButtons.StickLeft; + if (keyboard[(Key)LeftJoycon.DPadUp]) buttons |= HidControllerButtons.DpadUp; + if (keyboard[(Key)LeftJoycon.DPadDown]) buttons |= HidControllerButtons.DpadDown; + if (keyboard[(Key)LeftJoycon.DPadLeft]) buttons |= HidControllerButtons.DpadLeft; + if (keyboard[(Key)LeftJoycon.DPadRight]) buttons |= HidControllerButtons.DPadRight; + if (keyboard[(Key)LeftJoycon.ButtonMinus]) buttons |= HidControllerButtons.Minus; + if (keyboard[(Key)LeftJoycon.ButtonL]) buttons |= HidControllerButtons.L; + if (keyboard[(Key)LeftJoycon.ButtonZl]) buttons |= HidControllerButtons.Zl; - if (keyboard[(Key)Right.StickButton]) buttons |= HidControllerButtons.StickRight; - if (keyboard[(Key)Right.ButtonA]) buttons |= HidControllerButtons.A; - if (keyboard[(Key)Right.ButtonB]) buttons |= HidControllerButtons.B; - if (keyboard[(Key)Right.ButtonX]) buttons |= HidControllerButtons.X; - if (keyboard[(Key)Right.ButtonY]) buttons |= HidControllerButtons.Y; - if (keyboard[(Key)Right.ButtonPlus]) buttons |= HidControllerButtons.Plus; - if (keyboard[(Key)Right.ButtonR]) buttons |= HidControllerButtons.R; - if (keyboard[(Key)Right.ButtonZr]) buttons |= HidControllerButtons.Zr; + if (keyboard[(Key)RightJoycon.StickButton]) buttons |= HidControllerButtons.StickRight; + if (keyboard[(Key)RightJoycon.ButtonA]) buttons |= HidControllerButtons.A; + if (keyboard[(Key)RightJoycon.ButtonB]) buttons |= HidControllerButtons.B; + if (keyboard[(Key)RightJoycon.ButtonX]) buttons |= HidControllerButtons.X; + if (keyboard[(Key)RightJoycon.ButtonY]) buttons |= HidControllerButtons.Y; + if (keyboard[(Key)RightJoycon.ButtonPlus]) buttons |= HidControllerButtons.Plus; + if (keyboard[(Key)RightJoycon.ButtonR]) buttons |= HidControllerButtons.R; + if (keyboard[(Key)RightJoycon.ButtonZr]) buttons |= HidControllerButtons.Zr; return buttons; } @@ -78,10 +78,10 @@ namespace Ryujinx.UI.Input short dx = 0; short dy = 0; - if (keyboard[(Key)Left.StickUp]) dy = short.MaxValue; - if (keyboard[(Key)Left.StickDown]) dy = -short.MaxValue; - if (keyboard[(Key)Left.StickLeft]) dx = -short.MaxValue; - if (keyboard[(Key)Left.StickRight]) dx = short.MaxValue; + if (keyboard[(Key)LeftJoycon.StickUp]) dy = short.MaxValue; + if (keyboard[(Key)LeftJoycon.StickDown]) dy = -short.MaxValue; + if (keyboard[(Key)LeftJoycon.StickLeft]) dx = -short.MaxValue; + if (keyboard[(Key)LeftJoycon.StickRight]) dx = short.MaxValue; return (dx, dy); } @@ -91,10 +91,10 @@ namespace Ryujinx.UI.Input short dx = 0; short dy = 0; - if (keyboard[(Key)Right.StickUp]) dy = short.MaxValue; - if (keyboard[(Key)Right.StickDown]) dy = -short.MaxValue; - if (keyboard[(Key)Right.StickLeft]) dx = -short.MaxValue; - if (keyboard[(Key)Right.StickRight]) dx = short.MaxValue; + if (keyboard[(Key)RightJoycon.StickUp]) dy = short.MaxValue; + if (keyboard[(Key)RightJoycon.StickDown]) dy = -short.MaxValue; + if (keyboard[(Key)RightJoycon.StickLeft]) dx = -short.MaxValue; + if (keyboard[(Key)RightJoycon.StickRight]) dx = short.MaxValue; return (dx, dy); } diff --git a/Ryujinx/_schema.json b/Ryujinx/_schema.json new file mode 100644 index 0000000000..013a883452 --- /dev/null +++ b/Ryujinx/_schema.json @@ -0,0 +1,823 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://ryujinx.org/_schema/config.json", + "type": "object", + "title": "Ryujinx Configuration Schema", + "required": [ + "graphics_shaders_dump_path", + "logging_enable_debug", + "logging_enable_stub", + "logging_enable_info", + "logging_enable_warn", + "logging_enable_error", + "logging_filtered_classes", + "enable_file_log", + "system_language", + "docked_mode", + "enable_vsync", + "enable_multicore_scheduling", + "enable_fs_integrity_checks", + "controller_type", + "keyboard_controls", + "gamepad_controls" + ], + "definitions": { + "key": { + "type": "string", + "enum": [ + "ShiftLeft", + "LShift", + "ShiftRight", + "RShift", + "ControlLeft", + "LControl", + "ControlRight", + "RControl", + "AltLeft", + "LAlt", + "AltRight", + "RAlt", + "WinLeft", + "LWin", + "WinRight", + "RWin", + "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", + "Back", + "Insert", + "Delete", + "PageUp", + "PageDown", + "Home", + "End", + "CapsLock", + "ScrollLock", + "PrintScreen", + "Pause", + "NumLock", + "Clear", + "Sleep", + "Keypad0", + "Keypad1", + "Keypad2", + "Keypad3", + "Keypad4", + "Keypad5", + "Keypad6", + "Keypad7", + "Keypad8", + "Keypad9", + "KeypadDivide", + "KeypadMultiply", + "KeypadSubtract", + "KeypadMinus", + "KeypadAdd", + "KeypadPlus", + "KeypadDecimal", + "KeypadPeriod", + "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", + "LBracket", + "BracketRight", + "RBracket", + "Semicolon", + "Quote", + "Comma", + "Period", + "Slash", + "BackSlash", + "NonUSBackSlash", + "LastKey" + ] + }, + "input": { + "type": "string", + "enum": [ + "DPadUp", + "DPadDown", + "DPadLeft", + "DPadRight", + "LStick", + "RStick", + "LShoulder", + "RShoulder", + "LTrigger", + "RTrigger", + "LJoystick", + "RJoystick", + "A", + "B", + "X", + "Y", + "Start", + "Back" + ] + } + }, + "properties": { + "graphics_shaders_dump_path": { + "$id": "#/properties/graphics_shaders_dump_path", + "type": "string", + "title": "Graphics Shaders Dump Path", + "description": "Dumps shaders in this local directory", + "default": "", + "examples": [ + "C:\\ShaderDumps" + ] + }, + "logging_enable_debug": { + "$id": "#/properties/logging_enable_debug", + "type": "boolean", + "title": "Logging Enable Debug", + "description": "Enables printing debug log messages", + "default": false, + "examples": [ + true, + false + ] + }, + "logging_enable_stub": { + "$id": "#/properties/logging_enable_stub", + "type": "boolean", + "title": "Logging Enable Stub", + "description": "Enables printing stub log messages", + "default": true, + "examples": [ + true, + false + ] + }, + "logging_enable_info": { + "$id": "#/properties/logging_enable_info", + "type": "boolean", + "title": "Logging Enable Info", + "description": "Enables printing info log messages", + "default": true, + "examples": [ + true, + false + ] + }, + "logging_enable_warn": { + "$id": "#/properties/logging_enable_warn", + "type": "boolean", + "title": "Logging Enable Warn", + "description": "Enables printing warning log messages", + "default": true, + "examples": [ + true, + false + ] + }, + "logging_enable_error": { + "$id": "#/properties/logging_enable_error", + "type": "boolean", + "title": "Logging Enable Error", + "description": "Enables printing error log messages", + "default": true, + "examples": [ + true, + false + ] + }, + "logging_filtered_classes": { + "$id": "#/properties/logging_filtered_classes", + "type": "array", + "title": "Logging Filtered Classes", + "description": "Controls which log messages are written to the log targets", + "items": { + "type": "string", + "enum": [ + "Application", + "Audio", + "Cpu", + "Font", + "Emulation", + "Gpu", + "Hid", + "Kernel", + "KernelIpc", + "KernelScheduler", + "KernelSvc", + "Loader", + "Service", + "ServiceAcc", + "ServiceAm", + "ServiceApm", + "ServiceAudio", + "ServiceBsd", + "ServiceCaps", + "ServiceFriend", + "ServiceFs", + "ServiceHid", + "ServiceIrs", + "ServiceLdr", + "ServiceLm", + "ServiceMm", + "ServiceNfp", + "ServiceNifm", + "ServiceNs", + "ServiceNv", + "ServicePctl", + "ServicePl", + "ServicePrepo", + "ServicePsm", + "ServiceSet", + "ServiceSfdnsres", + "ServiceSm", + "ServiceSsl", + "ServiceSss", + "ServiceTime", + "ServiceVi" + ] + } + }, + "enable_file_log": { + "$id": "#/properties/enable_file_log", + "type": "boolean", + "title": "Enable File Log", + "description": "Enables logging to a file on disk", + "default": true, + "examples": [ + true, + false + ] + }, + "system_language": { + "$id": "#/properties/system_language", + "type": "string", + "title": "System Language", + "description": "Change System Language", + "default": "AmericanEnglish", + "enum": [ + "Japanese", + "AmericanEnglish", + "French", + "German", + "Italian", + "Spanish", + "Chinese", + "Korean", + "Dutch", + "Portuguese", + "Russian", + "Taiwanese", + "BritishEnglish", + "CanadianFrench", + "LatinAmericanSpanish", + "SimplifiedChinese", + "TraditionalChinese" + ], + "examples": [ + "AmericanEnglish" + ] + }, + "docked_mode": { + "$id": "#/properties/docked_mode", + "type": "boolean", + "title": "Enable Docked Mode", + "description": "Enables or disables Docked Mode", + "default": false, + "examples": [ + true, + false + ] + }, + "enable_vsync": { + "$id": "#/properties/enable_vsync", + "type": "boolean", + "title": "Enable Vertical Sync", + "description": "Enables or disables Vertical Sync", + "default": true, + "examples": [ + true, + false + ] + }, + "enable_multicore_scheduling": { + "$id": "#/properties/enable_multicore_scheduling", + "type": "boolean", + "title": "Enable Multicore Scheduling", + "description": "Enables or disables multi-core scheduling of threads", + "default": false, + "examples": [ + true, + false + ] + }, + "enable_fs_integrity_checks": { + "$id": "#/properties/enable_fs_integrity_checks", + "type": "boolean", + "title": "Enable Filesystem Integrity Checks", + "description": "Enables integrity checks on Game content files. Only applies to ROMs loaded as XCI files", + "default": true, + "examples": [ + true, + false + ] + }, + "controller_type": { + "$id": "#/properties/controller_type", + "type": "string", + "title": "Controller Type", + "default": "Handheld", + "enum": [ + "Handheld", + "ProController", + "NpadPair", + "NpadLeft", + "NpadRight" + ], + "examples": [ + "Handheld", + "ProController", + "NpadPair", + "NpadLeft", + "NpadRight" + ] + }, + "keyboard_controls": { + "$id": "#/properties/keyboard_controls", + "type": "object", + "title": "Keyboard Controls", + "required": [ + "left_joycon", + "right_joycon" + ], + "properties": { + "left_joycon": { + "$id": "#/properties/keyboard_controls/properties/left_joycon", + "type": "object", + "title": "Left JoyCon Controls", + "required": [ + "stick_up", + "stick_down", + "stick_left", + "stick_right", + "stick_button", + "dpad_up", + "dpad_down", + "dpad_left", + "dpad_right", + "button_minus", + "button_l", + "button_zl" + ], + "properties": { + "stick_up": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/stick_up", + "$ref": "#/definitions/key", + "title": "Stick Up", + "default": "w" + }, + "stick_down": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/stick_down", + "$ref": "#/definitions/key", + "title": "Stick Down", + "default": "S" + }, + "stick_left": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/stick_left", + "$ref": "#/definitions/key", + "title": "Stick Left", + "default": "A" + }, + "stick_right": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/stick_right", + "$ref": "#/definitions/key", + "title": "Stick Right", + "default": "D" + }, + "stick_button": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/stick_button", + "$ref": "#/definitions/key", + "title": "Stick Button", + "default": "F" + }, + "dpad_up": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/dpad_up", + "$ref": "#/definitions/key", + "title": "Dpad Up", + "default": "Up" + }, + "dpad_down": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/dpad_down", + "$ref": "#/definitions/key", + "title": "Dpad Down", + "default": "Down" + }, + "dpad_left": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/dpad_left", + "$ref": "#/definitions/key", + "title": "Dpad Left", + "default": "Left" + }, + "dpad_right": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/dpad_right", + "$ref": "#/definitions/key", + "title": "Dpad Right", + "default": "Right" + }, + "button_minus": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/button_minus", + "$ref": "#/definitions/key", + "title": "Button Minus", + "default": "Minus" + }, + "button_l": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/button_l", + "$ref": "#/definitions/key", + "title": "Button L", + "default": "E" + }, + "button_zl": { + "$id": "#/properties/keyboard_controls/properties/left_joycon/properties/button_zl", + "$ref": "#/definitions/key", + "title": "Button ZL", + "default": "Q" + } + } + }, + "right_joycon": { + "$id": "#/properties/keyboard_controls/properties/right_joycon", + "type": "object", + "title": "Right JoyCon Controls", + "required": [ + "stick_up", + "stick_down", + "stick_left", + "stick_right", + "stick_button", + "button_a", + "button_b", + "button_x", + "button_y", + "button_plus", + "button_r", + "button_zr" + ], + "properties": { + "stick_up": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/stick_up", + "$ref": "#/definitions/key", + "title": "Stick Up", + "default": "I" + }, + "stick_down": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/stick_down", + "$ref": "#/definitions/key", + "title": "Stick Down", + "default": "K" + }, + "stick_left": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/stick_left", + "$ref": "#/definitions/key", + "title": "Stick Left", + "default": "J" + }, + "stick_right": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/stick_right", + "$ref": "#/definitions/key", + "title": "Stick Right", + "default": "L" + }, + "stick_button": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/stick_button", + "$ref": "#/definitions/key", + "title": "Stick Button", + "default": "H" + }, + "button_a": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/button_a", + "$ref": "#/definitions/key", + "title": "Button A", + "default": "A" + }, + "button_b": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/button_b", + "$ref": "#/definitions/key", + "title": "Button B", + "default": "X" + }, + "button_x": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/button_x", + "$ref": "#/definitions/key", + "title": "Button X", + "default": "C" + }, + "button_y": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/button_y", + "$ref": "#/definitions/key", + "title": "Button Y", + "default": "V" + }, + "button_plus": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/button_plus", + "$ref": "#/definitions/key", + "title": "Button Plus", + "default": "Plus" + }, + "button_r": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/button_r", + "$ref": "#/definitions/key", + "title": "Button R", + "default": "U" + }, + "button_zr": { + "$id": "#/properties/keyboard_controls/properties/right_joycon/properties/button_zr", + "$ref": "#/definitions/key", + "title": "Button Zr", + "default": "O" + } + } + } + } + }, + "gamepad_controls": { + "$id": "#/properties/gamepad_controls", + "type": "object", + "title": "GamePad Controls", + "required": [ + "left_joycon", + "right_joycon" + ], + "properties": { + "enable": { + "$id": "#/properties/gamepad_controls/properties/enable", + "type": "boolean", + "title": "Gamepad Enable", + "description": "Enables or disables controller support", + "default": true, + "examples": [ + true, + false + ] + }, + "index": { + "$id": "#/properties/gamepad_controls/properties/index", + "type": "integer", + "title": "Gamepad Index", + "description": "Controller Device Index", + "default": 0, + "minimum": 0, + "examples": [ + 0, + 1, + 2 + ] + }, + "deadzone": { + "$id": "#/properties/gamepad_controls/properties/deadzone", + "type": "number", + "title": "Gamepad Deadzone", + "description": "Controller Analog Stick Deadzone", + "default": 0.05, + "minimum": -32768.0, + "maximum": 32767.0, + "examples": [ + 0.05 + ] + }, + "trigger_threshold": { + "$id": "#/properties/gamepad_controls/properties/trigger_threshold", + "type": "number", + "title": "Controller Trigger Threshold", + "description": "The value of how pressed down each trigger has to be in order to register a button press", + "default": 0.5, + "minimum": 0.0, + "maximum": 1.0, + "examples": [ + 0.5 + ] + }, + "left_joycon": { + "$id": "#/properties/gamepad_controls/properties/left_joycon", + "type": "object", + "title": "Left JoyCon Controls", + "required": [ + "stick", + "stick_button", + "dpad_up", + "dpad_down", + "dpad_left", + "dpad_right", + "button_minus", + "button_l", + "button_zl" + ], + "properties": { + "stick": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/stick", + "$ref": "#/definitions/input", + "title": "Stick", + "default": "LJoystick" + }, + "stick_button": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/stick_button", + "$ref": "#/definitions/input", + "title": "Stick Button", + "default": "LStick" + }, + "dpad_up": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/dpad_up", + "$ref": "#/definitions/input", + "title": "Dpad Up", + "default": "DPadUp" + }, + "dpad_down": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/dpad_down", + "$ref": "#/definitions/input", + "title": "Dpad Down", + "default": "DPadDown" + }, + "dpad_left": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/dpad_left", + "$ref": "#/definitions/input", + "title": "Dpad Left", + "default": "DPadLeft" + }, + "dpad_right": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/dpad_right", + "$ref": "#/definitions/input", + "title": "Dpad Right", + "default": "DPadRight" + }, + "button_minus": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/button_minus", + "$ref": "#/definitions/input", + "title": "Button Minus", + "default": "Back" + }, + "button_l": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/button_l", + "$ref": "#/definitions/input", + "title": "Button L", + "default": "LShoulder" + }, + "button_zl": { + "$id": "#/properties/gamepad_controls/properties/left_joycon/properties/button_zl", + "$ref": "#/definitions/input", + "title": "Button ZL", + "default": "LTrigger" + } + } + }, + "right_joycon": { + "$id": "#/properties/gamepad_controls/properties/right_joycon", + "type": "object", + "title": "Right JoyCon Controls", + "required": [ + "stick", + "stick_button", + "button_a", + "button_b", + "button_x", + "button_y", + "button_plus", + "button_r", + "button_zr" + ], + "properties": { + "stick": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/stick", + "$ref": "#/definitions/input", + "title": "Stick", + "default": "RJoystick" + }, + "stick_button": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/stick_button", + "$ref": "#/definitions/input", + "title": "Stick Button", + "default": "RStick" + }, + "button_a": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/button_a", + "$ref": "#/definitions/input", + "title": "Button A", + "default": "B" + }, + "button_b": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/button_b", + "$ref": "#/definitions/input", + "title": "Button B", + "default": "A" + }, + "button_x": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/button_x", + "$ref": "#/definitions/input", + "title": "Button X", + "default": "Y" + }, + "button_y": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/button_y", + "$ref": "#/definitions/input", + "title": "Button Y", + "default": "X" + }, + "button_plus": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/button_plus", + "$ref": "#/definitions/input", + "title": "Button Plus", + "default": "Start" + }, + "button_r": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/button_r", + "$ref": "#/definitions/input", + "title": "Button R", + "default": "RShoulder" + }, + "button_zr": { + "$id": "#/properties/gamepad_controls/properties/right_joycon/properties/button_zr", + "$ref": "#/definitions/input", + "title": "Button ZR", + "default": "RTrigger" + } + } + } + } + } + } +} \ No newline at end of file