diff --git a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
index ff5a67c4..09252b77 100644
--- a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
+++ b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
@@ -4,9 +4,7 @@ using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using Ryujinx.Configuration.System;
-using Ryujinx.Configuration.Hid;
using Ryujinx.Configuration.Ui;
-using Ryujinx.UI.Input;
namespace Ryujinx.Configuration
{
@@ -15,7 +13,7 @@ namespace Ryujinx.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 5;
+ public const int CurrentVersion = 6;
public int Version { get; set; }
@@ -129,11 +127,6 @@ namespace Ryujinx.Configuration
///
public bool IgnoreMissingServices { get; set; }
- ///
- /// The primary controller's type
- ///
- public ControllerType ControllerType { get; set; }
-
///
/// Used to toggle columns in the GUI
///
@@ -162,12 +155,12 @@ namespace Ryujinx.Configuration
///
/// Keyboard control bindings
///
- public NpadKeyboard KeyboardControls { get; set; }
+ public List KeyboardConfig { get; set; }
///
/// Controller control bindings
///
- public NpadController JoystickControls { get; set; }
+ public List ControllerConfig { get; set; }
///
/// Loads a configuration file from disk
diff --git a/Ryujinx.Common/Configuration/ConfigurationState.cs b/Ryujinx.Common/Configuration/ConfigurationState.cs
index d2826d36..a994e6d5 100644
--- a/Ryujinx.Common/Configuration/ConfigurationState.cs
+++ b/Ryujinx.Common/Configuration/ConfigurationState.cs
@@ -1,10 +1,9 @@
-using Ryujinx.Common;
+using Ryujinx.Common;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
using Ryujinx.Configuration.Hid;
using Ryujinx.Configuration.System;
using Ryujinx.Configuration.Ui;
-using Ryujinx.UI.Input;
using System;
using System.Collections.Generic;
@@ -159,7 +158,7 @@ namespace Ryujinx.Configuration
public ReactiveObject TimeZone { get; private set; }
///
- /// System Time Offset in seconds
+ /// System Time Offset in Seconds
///
public ReactiveObject SystemTimeOffset { get; private set; }
@@ -207,32 +206,22 @@ namespace Ryujinx.Configuration
///
public class HidSection
{
- ///
- /// The primary controller's type
- ///
- public ReactiveObject ControllerType { get; private set; }
-
///
/// Enable or disable keyboard support (Independent from controllers binding)
///
public ReactiveObject EnableKeyboard { get; private set; }
///
- /// Keyboard control bindings
+ /// Input device configuration.
+ /// NOTE: This ReactiveObject won't issue an event when the List has elements added or removed.
+ /// TODO: Implement a ReactiveList class.
///
- public ReactiveObject KeyboardControls { get; private set; }
-
- ///
- /// Controller control bindings
- ///
- public ReactiveObject JoystickControls { get; private set; }
+ public ReactiveObject> InputConfig { get; private set; }
public HidSection()
{
- ControllerType = new ReactiveObject();
- EnableKeyboard = new ReactiveObject();
- KeyboardControls = new ReactiveObject();
- JoystickControls = new ReactiveObject();
+ EnableKeyboard = new ReactiveObject();
+ InputConfig = new ReactiveObject>();
}
}
@@ -311,6 +300,21 @@ namespace Ryujinx.Configuration
public ConfigurationFileFormat ToFileFormat()
{
+ List controllerConfigList = new List();
+ List keyboardConfigList = new List();
+
+ foreach (InputConfig inputConfig in Hid.InputConfig.Value)
+ {
+ if (inputConfig is ControllerConfig controllerConfig)
+ {
+ controllerConfigList.Add(controllerConfig);
+ }
+ else if (inputConfig is KeyboardConfig keyboardConfig)
+ {
+ keyboardConfigList.Add(keyboardConfig);
+ }
+ }
+
ConfigurationFileFormat configurationFile = new ConfigurationFileFormat
{
Version = ConfigurationFileFormat.CurrentVersion,
@@ -336,7 +340,6 @@ namespace Ryujinx.Configuration
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
IgnoreMissingServices = System.IgnoreMissingServices,
- ControllerType = Hid.ControllerType,
GuiColumns = new GuiColumns()
{
FavColumn = Ui.GuiColumns.FavColumn,
@@ -354,8 +357,8 @@ namespace Ryujinx.Configuration
EnableCustomTheme = Ui.EnableCustomTheme,
CustomThemePath = Ui.CustomThemePath,
EnableKeyboard = Hid.EnableKeyboard,
- KeyboardControls = Hid.KeyboardControls,
- JoystickControls = Hid.JoystickControls
+ KeyboardConfig = keyboardConfigList,
+ ControllerConfig = controllerConfigList
};
return configurationFile;
@@ -385,7 +388,6 @@ namespace Ryujinx.Configuration
System.EnableFsIntegrityChecks.Value = true;
System.FsGlobalAccessLogMode.Value = 0;
System.IgnoreMissingServices.Value = false;
- Hid.ControllerType.Value = ControllerType.Handheld;
Ui.GuiColumns.FavColumn.Value = true;
Ui.GuiColumns.IconColumn.Value = true;
Ui.GuiColumns.AppColumn.Value = true;
@@ -401,73 +403,51 @@ namespace Ryujinx.Configuration
Ui.CustomThemePath.Value = "";
Hid.EnableKeyboard.Value = false;
- Hid.KeyboardControls.Value = new NpadKeyboard
+ Hid.InputConfig.Value = new List
{
- LeftJoycon = new NpadKeyboardLeft
+ new KeyboardConfig
{
- StickUp = Key.W,
- StickDown = Key.S,
- StickLeft = Key.A,
- StickRight = Key.D,
- StickButton = Key.F,
- DPadUp = Key.Up,
- DPadDown = Key.Down,
- DPadLeft = Key.Left,
- DPadRight = Key.Right,
- ButtonMinus = Key.Minus,
- ButtonL = Key.E,
- ButtonZl = Key.Q,
- },
- RightJoycon = new NpadKeyboardRight
- {
- StickUp = Key.I,
- StickDown = Key.K,
- StickLeft = Key.J,
- StickRight = Key.L,
- StickButton = Key.H,
- ButtonA = Key.Z,
- ButtonB = Key.X,
- ButtonX = Key.C,
- ButtonY = Key.V,
- ButtonPlus = Key.Plus,
- ButtonR = Key.U,
- ButtonZr = Key.O,
- },
- Hotkeys = new KeyboardHotkeys
- {
- ToggleVsync = Key.Tab
- }
- };
-
- Hid.JoystickControls.Value = new NpadController
- {
- Enabled = true,
- Index = 0,
- Deadzone = 0.05f,
- TriggerThreshold = 0.5f,
- LeftJoycon = new NpadControllerLeft
- {
- Stick = ControllerInputId.Axis0,
- StickButton = ControllerInputId.Button8,
- DPadUp = ControllerInputId.Hat0Up,
- DPadDown = ControllerInputId.Hat0Down,
- DPadLeft = ControllerInputId.Hat0Left,
- DPadRight = ControllerInputId.Hat0Right,
- ButtonMinus = ControllerInputId.Button6,
- ButtonL = ControllerInputId.Button4,
- ButtonZl = ControllerInputId.Axis2,
- },
- RightJoycon = new NpadControllerRight
- {
- Stick = ControllerInputId.Axis3,
- StickButton = ControllerInputId.Button9,
- ButtonA = ControllerInputId.Button1,
- ButtonB = ControllerInputId.Button0,
- ButtonX = ControllerInputId.Button3,
- ButtonY = ControllerInputId.Button2,
- ButtonPlus = ControllerInputId.Button7,
- ButtonR = ControllerInputId.Button5,
- ButtonZr = ControllerInputId.Axis5,
+ Index = 0,
+ ControllerType = ControllerType.JoyconPair,
+ PlayerIndex = PlayerIndex.Player1,
+ LeftJoycon = new NpadKeyboardLeft
+ {
+ StickUp = Key.W,
+ StickDown = Key.S,
+ StickLeft = Key.A,
+ StickRight = Key.D,
+ StickButton = Key.F,
+ DPadUp = Key.Up,
+ DPadDown = Key.Down,
+ DPadLeft = Key.Left,
+ DPadRight = Key.Right,
+ ButtonMinus = Key.Minus,
+ ButtonL = Key.E,
+ ButtonZl = Key.Q,
+ ButtonSl = Key.Home,
+ ButtonSr = Key.End
+ },
+ RightJoycon = new NpadKeyboardRight
+ {
+ StickUp = Key.I,
+ StickDown = Key.K,
+ StickLeft = Key.J,
+ StickRight = Key.L,
+ StickButton = Key.H,
+ ButtonA = Key.Z,
+ ButtonB = Key.X,
+ ButtonX = Key.C,
+ ButtonY = Key.V,
+ ButtonPlus = Key.Plus,
+ ButtonR = Key.U,
+ ButtonZr = Key.O,
+ ButtonSl = Key.PageUp,
+ ButtonSr = Key.PageDown
+ },
+ Hotkeys = new KeyboardHotkeys
+ {
+ ToggleVsync = Key.Tab
+ }
}
};
}
@@ -521,6 +501,71 @@ namespace Ryujinx.Configuration
configurationFileUpdated = true;
}
+ if (configurationFileFormat.Version < 6)
+ {
+ Common.Logging.Logger.PrintWarning(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 6.");
+
+ configurationFileFormat.ControllerConfig = new List();
+ configurationFileFormat.KeyboardConfig = new List{
+ new KeyboardConfig
+ {
+ Index = 0,
+ ControllerType = ControllerType.JoyconPair,
+ PlayerIndex = PlayerIndex.Player1,
+ LeftJoycon = new NpadKeyboardLeft
+ {
+ StickUp = Key.W,
+ StickDown = Key.S,
+ StickLeft = Key.A,
+ StickRight = Key.D,
+ StickButton = Key.F,
+ DPadUp = Key.Up,
+ DPadDown = Key.Down,
+ DPadLeft = Key.Left,
+ DPadRight = Key.Right,
+ ButtonMinus = Key.Minus,
+ ButtonL = Key.E,
+ ButtonZl = Key.Q,
+ ButtonSl = Key.Unbound,
+ ButtonSr = Key.Unbound
+ },
+ RightJoycon = new NpadKeyboardRight
+ {
+ StickUp = Key.I,
+ StickDown = Key.K,
+ StickLeft = Key.J,
+ StickRight = Key.L,
+ StickButton = Key.H,
+ ButtonA = Key.Z,
+ ButtonB = Key.X,
+ ButtonX = Key.C,
+ ButtonY = Key.V,
+ ButtonPlus = Key.Plus,
+ ButtonR = Key.U,
+ ButtonZr = Key.O,
+ ButtonSl = Key.Unbound,
+ ButtonSr = Key.Unbound
+ },
+ Hotkeys = new KeyboardHotkeys
+ {
+ ToggleVsync = Key.Tab
+ }
+ }
+ };
+
+ configurationFileUpdated = true;
+ }
+
+ List inputConfig = new List();
+ foreach (ControllerConfig controllerConfig in configurationFileFormat.ControllerConfig)
+ {
+ inputConfig.Add(controllerConfig);
+ }
+ foreach (KeyboardConfig keyboardConfig in configurationFileFormat.KeyboardConfig)
+ {
+ inputConfig.Add(keyboardConfig);
+ }
+
Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
@@ -544,7 +589,6 @@ namespace Ryujinx.Configuration
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
- Hid.ControllerType.Value = configurationFileFormat.ControllerType;
Ui.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
Ui.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
Ui.GuiColumns.AppColumn.Value = configurationFileFormat.GuiColumns.AppColumn;
@@ -559,14 +603,13 @@ namespace Ryujinx.Configuration
Ui.EnableCustomTheme.Value = configurationFileFormat.EnableCustomTheme;
Ui.CustomThemePath.Value = configurationFileFormat.CustomThemePath;
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
- Hid.KeyboardControls.Value = configurationFileFormat.KeyboardControls;
- Hid.JoystickControls.Value = configurationFileFormat.JoystickControls;
+ Hid.InputConfig.Value = inputConfig;
if (configurationFileUpdated)
{
ToFileFormat().SaveConfig(configurationFilePath);
- Common.Logging.Logger.PrintWarning(LogClass.Application, "Configuration file is updated!");
+ Common.Logging.Logger.PrintWarning(LogClass.Application, "Configuration file has been updated!");
}
}
diff --git a/Ryujinx.Common/Configuration/Hid/NpadController.cs b/Ryujinx.Common/Configuration/Hid/ControllerConfig.cs
similarity index 63%
rename from Ryujinx.Common/Configuration/Hid/NpadController.cs
rename to Ryujinx.Common/Configuration/Hid/ControllerConfig.cs
index 94b985d5..3e414055 100644
--- a/Ryujinx.Common/Configuration/Hid/NpadController.cs
+++ b/Ryujinx.Common/Configuration/Hid/ControllerConfig.cs
@@ -1,21 +1,16 @@
namespace Ryujinx.Common.Configuration.Hid
{
- public class NpadController
+ public class ControllerConfig : InputConfig
{
///
- /// Enables or disables controller support
+ /// Controller Left Analog Stick Deadzone
///
- public bool Enabled { get; set; }
+ public float DeadzoneLeft { get; set; }
///
- /// Controller Device Index
+ /// Controller Right Analog Stick Deadzone
///
- public int Index { get; set; }
-
- ///
- /// Controller Analog Stick Deadzone
- ///
- public float Deadzone { get; set; }
+ public float DeadzoneRight { get; set; }
///
/// Controller Trigger Threshold
@@ -32,4 +27,4 @@
///
public NpadControllerRight RightJoycon { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs b/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs
index 8969b6a4..606a1b0c 100644
--- a/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs
+++ b/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs
@@ -40,6 +40,7 @@
Hat2Up,
Hat2Down,
Hat2Left,
- Hat2Right
+ Hat2Right,
+ Unbound
}
}
diff --git a/Ryujinx.Common/Configuration/Hid/ControllerType.cs b/Ryujinx.Common/Configuration/Hid/ControllerType.cs
index b0613b2d..0ad01bbb 100644
--- a/Ryujinx.Common/Configuration/Hid/ControllerType.cs
+++ b/Ryujinx.Common/Configuration/Hid/ControllerType.cs
@@ -1,11 +1,20 @@
-namespace Ryujinx.Configuration.Hid
+using System;
+
+namespace Ryujinx.Common.Configuration.Hid
{
- public enum ControllerType
+ [Flags]
+ // This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
+ public enum ControllerType : int
{
- ProController,
- Handheld,
- NpadPair,
- NpadLeft,
- NpadRight
+ 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
}
-}
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/InputConfig.cs b/Ryujinx.Common/Configuration/Hid/InputConfig.cs
new file mode 100644
index 00000000..540506d5
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/InputConfig.cs
@@ -0,0 +1,20 @@
+namespace Ryujinx.Common.Configuration.Hid
+{
+ public class InputConfig
+ {
+ ///
+ /// Controller Device Index
+ ///
+ public int Index { get; set; }
+
+ ///
+ /// Controller's Type
+ ///
+ public ControllerType ControllerType { get; set; }
+
+ ///
+ /// Player's Index for the controller
+ ///
+ public PlayerIndex PlayerIndex { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/Key.cs b/Ryujinx.Common/Configuration/Hid/Key.cs
index b658396b..67177eec 100644
--- a/Ryujinx.Common/Configuration/Hid/Key.cs
+++ b/Ryujinx.Common/Configuration/Hid/Key.cs
@@ -148,6 +148,7 @@
Slash = 128,
BackSlash = 129,
NonUSBackSlash = 130,
- LastKey = 131
+ LastKey = 131,
+ Unbound
}
}
diff --git a/Ryujinx.Common/Configuration/Hid/KeyboardConfig.cs b/Ryujinx.Common/Configuration/Hid/KeyboardConfig.cs
new file mode 100644
index 00000000..664fdff0
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/KeyboardConfig.cs
@@ -0,0 +1,20 @@
+namespace Ryujinx.Common.Configuration.Hid
+{
+ public class KeyboardConfig : InputConfig
+ {
+ ///
+ /// Left JoyCon Keyboard Bindings
+ ///
+ public NpadKeyboardLeft LeftJoycon { get; set; }
+
+ ///
+ /// Right JoyCon Keyboard Bindings
+ ///
+ public NpadKeyboardRight RightJoycon { get; set; }
+
+ ///
+ /// Hotkey Keyboard Bindings
+ ///
+ public KeyboardHotkeys Hotkeys { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs b/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
index 30cc8d84..19cc0487 100644
--- a/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
+++ b/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
@@ -1,7 +1,9 @@
-namespace Ryujinx.Configuration.Hid
+using Ryujinx.Configuration.Hid;
+
+namespace Ryujinx.Common.Configuration.Hid
{
public struct KeyboardHotkeys
{
public Key ToggleVsync { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs b/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs
index c221b5e8..00816e56 100644
--- a/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs
+++ b/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs
@@ -2,14 +2,19 @@
{
public struct NpadControllerLeft
{
- public ControllerInputId Stick { get; set; }
+ public ControllerInputId StickX { get; set; }
+ public bool InvertStickX { get; set; }
+ public ControllerInputId StickY { get; set; }
+ public bool InvertStickY { get; set; }
public ControllerInputId StickButton { get; set; }
public ControllerInputId ButtonMinus { get; set; }
public ControllerInputId ButtonL { get; set; }
public ControllerInputId ButtonZl { get; set; }
+ public ControllerInputId ButtonSl { get; set; }
+ public ControllerInputId ButtonSr { get; set; }
public ControllerInputId DPadUp { get; set; }
public ControllerInputId DPadDown { get; set; }
public ControllerInputId DPadLeft { get; set; }
public ControllerInputId DPadRight { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs b/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs
index f52f6f16..b7b289cc 100644
--- a/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs
+++ b/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs
@@ -2,7 +2,10 @@
{
public struct NpadControllerRight
{
- public ControllerInputId Stick { get; set; }
+ public ControllerInputId StickX { get; set; }
+ public bool InvertStickX { get; set; }
+ public ControllerInputId StickY { get; set; }
+ public bool InvertStickY { get; set; }
public ControllerInputId StickButton { get; set; }
public ControllerInputId ButtonA { get; set; }
public ControllerInputId ButtonB { get; set; }
@@ -11,5 +14,7 @@
public ControllerInputId ButtonPlus { get; set; }
public ControllerInputId ButtonR { get; set; }
public ControllerInputId ButtonZr { get; set; }
+ public ControllerInputId ButtonSl { get; set; }
+ public ControllerInputId ButtonSr { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/NpadKeyboard.cs b/Ryujinx.Common/Configuration/Hid/NpadKeyboard.cs
deleted file mode 100644
index 5ae82756..00000000
--- a/Ryujinx.Common/Configuration/Hid/NpadKeyboard.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace Ryujinx.UI.Input
-{
- public class NpadKeyboard
- {
- ///
- /// Left JoyCon Keyboard Bindings
- ///
- public Configuration.Hid.NpadKeyboardLeft LeftJoycon { get; set; }
-
- ///
- /// Right JoyCon Keyboard Bindings
- ///
- public Configuration.Hid.NpadKeyboardRight RightJoycon { get; set; }
-
- ///
- /// Hotkey Keyboard Bindings
- ///
- public Configuration.Hid.KeyboardHotkeys Hotkeys { get; set; }
- }
-}
diff --git a/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs b/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs
index 4a61d932..6b78f5b6 100644
--- a/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs
+++ b/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.Configuration.Hid
+using Ryujinx.Configuration.Hid;
+
+namespace Ryujinx.Common.Configuration.Hid
{
public struct NpadKeyboardLeft
{
@@ -14,5 +16,7 @@
public Key ButtonMinus { get; set; }
public Key ButtonL { get; set; }
public Key ButtonZl { get; set; }
+ public Key ButtonSl { get; set; }
+ public Key ButtonSr { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs b/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs
index 0677b573..e2109902 100644
--- a/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs
+++ b/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs
@@ -1,4 +1,6 @@
-namespace Ryujinx.Configuration.Hid
+using Ryujinx.Configuration.Hid;
+
+namespace Ryujinx.Common.Configuration.Hid
{
public struct NpadKeyboardRight
{
@@ -14,5 +16,7 @@
public Key ButtonPlus { get; set; }
public Key ButtonR { get; set; }
public Key ButtonZr { get; set; }
+ public Key ButtonSl { get; set; }
+ public Key ButtonSr { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs b/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
new file mode 100644
index 00000000..2e34cb96
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
@@ -0,0 +1,18 @@
+namespace Ryujinx.Common.Configuration.Hid
+{
+ // This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
+ 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
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs
index e07577ed..c4935a64 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs
@@ -7,16 +7,16 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public class Hid
{
private readonly Switch _device;
- private long _hidMemoryAddress;
+ private readonly long _hidMemoryAddress;
internal ref HidSharedMemory SharedMemory => ref _device.Memory.GetStructRef(_hidMemoryAddress);
internal const int SharedMemEntryCount = 17;
public DebugPadDevice DebugPad;
- public TouchDevice Touchscreen;
- public MouseDevice Mouse;
+ public TouchDevice Touchscreen;
+ public MouseDevice Mouse;
public KeyboardDevice Keyboard;
- public NpadDevices Npads;
+ public NpadDevices Npads;
static Hid()
{
@@ -48,7 +48,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public Hid(in Switch device, long sharedHidMemoryAddress)
{
- _device = device;
+ _device = device;
_hidMemoryAddress = sharedHidMemoryAddress;
device.Memory.FillWithZeros(sharedHidMemoryAddress, Horizon.HidSize);
@@ -56,26 +56,26 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public void InitDevices()
{
- DebugPad = new DebugPadDevice(_device, true);
+ DebugPad = new DebugPadDevice(_device, true);
Touchscreen = new TouchDevice(_device, true);
- Mouse = new MouseDevice(_device, false);
- Keyboard = new KeyboardDevice(_device, false);
- Npads = new NpadDevices(_device, true);
+ Mouse = new MouseDevice(_device, false);
+ Keyboard = new KeyboardDevice(_device, false);
+ Npads = new NpadDevices(_device, true);
}
public ControllerKeys UpdateStickButtons(JoystickPosition leftStick, JoystickPosition rightStick)
{
ControllerKeys result = 0;
- result |= (leftStick.Dx < 0) ? ControllerKeys.LStickLeft : result;
+ result |= (leftStick.Dx < 0) ? ControllerKeys.LStickLeft : result;
result |= (leftStick.Dx > 0) ? ControllerKeys.LStickRight : result;
- result |= (leftStick.Dy < 0) ? ControllerKeys.LStickDown : result;
- result |= (leftStick.Dy > 0) ? ControllerKeys.LStickUp : result;
+ result |= (leftStick.Dy < 0) ? ControllerKeys.LStickDown : result;
+ result |= (leftStick.Dy > 0) ? ControllerKeys.LStickUp : result;
- result |= (rightStick.Dx < 0) ? ControllerKeys.RStickLeft : result;
+ result |= (rightStick.Dx < 0) ? ControllerKeys.RStickLeft : result;
result |= (rightStick.Dx > 0) ? ControllerKeys.RStickRight : result;
- result |= (rightStick.Dy < 0) ? ControllerKeys.RStickDown : result;
- result |= (rightStick.Dy > 0) ? ControllerKeys.RStickUp : result;
+ result |= (rightStick.Dy < 0) ? ControllerKeys.RStickDown : result;
+ result |= (rightStick.Dy > 0) ? ControllerKeys.RStickUp : result;
return result;
}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs
index ff330312..c4c9d095 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/NpadDevices.cs
@@ -1,6 +1,6 @@
using System;
-using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Kernel.Threading;
namespace Ryujinx.HLE.HOS.Services.Hid
{
@@ -9,14 +9,14 @@ namespace Ryujinx.HLE.HOS.Services.Hid
internal NpadJoyHoldType JoyHold = NpadJoyHoldType.Vertical;
internal bool SixAxisActive = false; // TODO: link to hidserver when implemented
- enum FilterState
+ private enum FilterState
{
Unconfigured = 0,
- Configured = 1,
- Accepted = 2
+ Configured = 1,
+ Accepted = 2
}
- struct NpadConfig
+ private struct NpadConfig
{
public ControllerType ConfiguredType;
public FilterState State;
@@ -33,7 +33,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public ControllerType SupportedStyleSets
{
- get { return _supportedStyleSets; }
+ get => _supportedStyleSets;
set
{
if (_supportedStyleSets != value) // Deal with spamming
@@ -46,9 +46,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid
public PlayerIndex PrimaryController { get; set; } = PlayerIndex.Unknown;
- KEvent[] _styleSetUpdateEvents;
+ private KEvent[] _styleSetUpdateEvents;
- static readonly Array3 _fullBattery;
+ private static readonly Array3 _fullBattery;
public NpadDevices(Switch device, bool active = true) : base(device, active)
{
@@ -68,7 +68,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
for (int i = 0; i < configs.Length; ++i)
{
- PlayerIndex player = configs[i].Player;
+ PlayerIndex player = configs[i].Player;
ControllerType controllerType = configs[i].Type;
if (player > PlayerIndex.Handheld)
@@ -87,7 +87,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
MatchControllers();
}
- void MatchControllers()
+ private void MatchControllers()
{
PrimaryController = PlayerIndex.Unknown;
@@ -141,7 +141,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return ref _styleSetUpdateEvents[(int)player];
}
- void InitController(PlayerIndex player, ControllerType type)
+ private void InitController(PlayerIndex player, ControllerType type)
{
if (type == ControllerType.Handheld)
{
@@ -155,13 +155,13 @@ namespace Ryujinx.HLE.HOS.Services.Hid
// TODO: Allow customizing colors at config
NpadStateHeader defaultHeader = new NpadStateHeader
{
- IsHalf = false,
- SingleColorBody = NpadColor.BodyGray,
+ IsHalf = false,
+ SingleColorBody = NpadColor.BodyGray,
SingleColorButtons = NpadColor.ButtonGray,
- LeftColorBody = NpadColor.BodyNeonBlue,
- LeftColorButtons = NpadColor.ButtonGray,
- RightColorBody = NpadColor.BodyNeonRed,
- RightColorButtons = NpadColor.ButtonGray
+ LeftColorBody = NpadColor.BodyNeonBlue,
+ LeftColorButtons = NpadColor.ButtonGray,
+ RightColorBody = NpadColor.BodyNeonRed,
+ RightColorButtons = NpadColor.ButtonGray
};
controller.SystemProperties = NpadSystemProperties.PowerInfo0Connected |
@@ -173,44 +173,44 @@ namespace Ryujinx.HLE.HOS.Services.Hid
switch (type)
{
case ControllerType.ProController:
- defaultHeader.Type = ControllerType.ProController;
- controller.DeviceType = DeviceType.FullKey;
+ defaultHeader.Type = ControllerType.ProController;
+ controller.DeviceType = DeviceType.FullKey;
controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented |
NpadSystemProperties.PlusButtonCapability |
NpadSystemProperties.MinusButtonCapability;
break;
case ControllerType.Handheld:
- defaultHeader.Type = ControllerType.Handheld;
- controller.DeviceType = DeviceType.HandheldLeft |
+ defaultHeader.Type = ControllerType.Handheld;
+ controller.DeviceType = DeviceType.HandheldLeft |
DeviceType.HandheldRight;
controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented |
NpadSystemProperties.PlusButtonCapability |
NpadSystemProperties.MinusButtonCapability;
break;
case ControllerType.JoyconPair:
- defaultHeader.Type = ControllerType.JoyconPair;
- controller.DeviceType = DeviceType.JoyLeft |
+ defaultHeader.Type = ControllerType.JoyconPair;
+ controller.DeviceType = DeviceType.JoyLeft |
DeviceType.JoyRight;
controller.SystemProperties |= NpadSystemProperties.AbxyButtonOriented |
NpadSystemProperties.PlusButtonCapability |
NpadSystemProperties.MinusButtonCapability;
break;
case ControllerType.JoyconLeft:
- defaultHeader.Type = ControllerType.JoyconLeft;
- defaultHeader.IsHalf = true;
- controller.DeviceType = DeviceType.JoyLeft;
+ defaultHeader.Type = ControllerType.JoyconLeft;
+ defaultHeader.IsHalf = true;
+ controller.DeviceType = DeviceType.JoyLeft;
controller.SystemProperties |= NpadSystemProperties.SlSrButtonOriented |
NpadSystemProperties.MinusButtonCapability;
break;
case ControllerType.JoyconRight:
- defaultHeader.Type = ControllerType.JoyconRight;
- defaultHeader.IsHalf = true;
- controller.DeviceType = DeviceType.JoyRight;
+ defaultHeader.Type = ControllerType.JoyconRight;
+ defaultHeader.IsHalf = true;
+ controller.DeviceType = DeviceType.JoyRight;
controller.SystemProperties |= NpadSystemProperties.SlSrButtonOriented |
NpadSystemProperties.PlusButtonCapability;
break;
case ControllerType.Pokeball:
- defaultHeader.Type = ControllerType.Pokeball;
+ defaultHeader.Type = ControllerType.Pokeball;
controller.DeviceType = DeviceType.Palma;
break;
}
@@ -229,16 +229,16 @@ namespace Ryujinx.HLE.HOS.Services.Hid
Logger.PrintInfo(LogClass.Hid, $"Connected ControllerType {type} to PlayerIndex {player}");
}
- static NpadLayoutsIndex ControllerTypeToLayout(ControllerType controllerType)
+ private static NpadLayoutsIndex ControllerTypeToLayout(ControllerType controllerType)
=> controllerType switch
{
ControllerType.ProController => NpadLayoutsIndex.ProController,
- ControllerType.Handheld => NpadLayoutsIndex.Handheld,
- ControllerType.JoyconPair => NpadLayoutsIndex.JoyDual,
- ControllerType.JoyconLeft => NpadLayoutsIndex.JoyLeft,
- ControllerType.JoyconRight => NpadLayoutsIndex.JoyRight,
- ControllerType.Pokeball => NpadLayoutsIndex.Pokeball,
- _ => NpadLayoutsIndex.SystemExternal
+ ControllerType.Handheld => NpadLayoutsIndex.Handheld,
+ ControllerType.JoyconPair => NpadLayoutsIndex.JoyDual,
+ ControllerType.JoyconLeft => NpadLayoutsIndex.JoyLeft,
+ ControllerType.JoyconRight => NpadLayoutsIndex.JoyRight,
+ ControllerType.Pokeball => NpadLayoutsIndex.Pokeball,
+ _ => NpadLayoutsIndex.SystemExternal
};
public void SetGamepadsInput(params GamepadInput[] states)
@@ -251,8 +251,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
}
}
- void SetGamepadState(PlayerIndex player, ControllerKeys buttons,
- JoystickPosition leftJoystick, JoystickPosition rightJoystick)
+ private void SetGamepadState(PlayerIndex player, ControllerKeys buttons,
+ JoystickPosition leftJoystick, JoystickPosition rightJoystick)
{
if (player == PlayerIndex.Auto)
{
@@ -269,9 +269,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return;
}
- ref ShMemNpad currentNpad = ref _device.Hid.SharedMemory.Npads[(int)player];
+ ref ShMemNpad currentNpad = ref _device.Hid.SharedMemory.Npads[(int)player];
ref NpadLayout currentLayout = ref currentNpad.Layouts[(int)ControllerTypeToLayout(currentNpad.Header.Type)];
- ref NpadState currentEntry = ref currentLayout.Entries[(int)currentLayout.Header.LatestEntry];
+ ref NpadState currentEntry = ref currentLayout.Entries[(int)currentLayout.Header.LatestEntry];
currentEntry.Buttons = buttons;
currentEntry.LStickX = leftJoystick.Dx;
@@ -284,7 +284,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
mainLayout.Entries[(int)mainLayout.Header.LatestEntry] = currentEntry;
}
- void UpdateAllEntries()
+ private void UpdateAllEntries()
{
ref Array10 controllers = ref _device.Hid.SharedMemory.Npads;
for (int i = 0; i < controllers.Length; ++i)
@@ -296,9 +296,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid
int currentIndex = UpdateEntriesHeader(ref currentLayout.Header, out int previousIndex);
ref NpadState currentEntry = ref currentLayout.Entries[currentIndex];
- NpadState previousEntry = currentLayout.Entries[previousIndex];
+ NpadState previousEntry = currentLayout.Entries[previousIndex];
- currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1;
+ currentEntry.SampleTimestamp = previousEntry.SampleTimestamp + 1;
currentEntry.SampleTimestamp2 = previousEntry.SampleTimestamp2 + 1;
if (controllers[i].Header.Type == ControllerType.None)
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/ControllerConfig.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/ControllerConfig.cs
index e59ba312..477e1a84 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/ControllerConfig.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/ControllerConfig.cs
@@ -2,7 +2,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
public struct ControllerConfig
{
- public PlayerIndex Player;
+ public PlayerIndex Player;
public ControllerType Type;
}
}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/GamepadInput.cs b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/GamepadInput.cs
index 2488057e..633671df 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/GamepadInput.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/HidDevices/Types/GamepadInput.cs
@@ -2,8 +2,8 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
public struct GamepadInput
{
- public PlayerIndex PlayerId;
- public ControllerKeys Buttons;
+ public PlayerIndex PlayerId;
+ public ControllerKeys Buttons;
public JoystickPosition LStick;
public JoystickPosition RStick;
}
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerKeys.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerKeys.cs
index db0319ed..c91636b2 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerKeys.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerKeys.cs
@@ -5,41 +5,41 @@ namespace Ryujinx.HLE.HOS.Services.Hid
[Flags]
public enum ControllerKeys : long
{
- A = 1 << 0,
- B = 1 << 1,
- X = 1 << 2,
- Y = 1 << 3,
- LStick = 1 << 4,
- RStick = 1 << 5,
- L = 1 << 6,
- R = 1 << 7,
- Zl = 1 << 8,
- Zr = 1 << 9,
- Plus = 1 << 10,
- Minus = 1 << 11,
- DpadLeft = 1 << 12,
- DpadUp = 1 << 13,
- DpadRight = 1 << 14,
- DpadDown = 1 << 15,
- LStickLeft = 1 << 16,
- LStickUp = 1 << 17,
+ A = 1 << 0,
+ B = 1 << 1,
+ X = 1 << 2,
+ Y = 1 << 3,
+ LStick = 1 << 4,
+ RStick = 1 << 5,
+ L = 1 << 6,
+ R = 1 << 7,
+ Zl = 1 << 8,
+ Zr = 1 << 9,
+ Plus = 1 << 10,
+ Minus = 1 << 11,
+ DpadLeft = 1 << 12,
+ DpadUp = 1 << 13,
+ DpadRight = 1 << 14,
+ DpadDown = 1 << 15,
+ LStickLeft = 1 << 16,
+ LStickUp = 1 << 17,
LStickRight = 1 << 18,
- LStickDown = 1 << 19,
- RStickLeft = 1 << 20,
- RStickUp = 1 << 21,
+ LStickDown = 1 << 19,
+ RStickLeft = 1 << 20,
+ RStickUp = 1 << 21,
RStickRight = 1 << 22,
- RStickDown = 1 << 23,
- SlLeft = 1 << 24,
- SrLeft = 1 << 25,
- SlRight = 1 << 26,
- SrRight = 1 << 27,
+ RStickDown = 1 << 23,
+ SlLeft = 1 << 24,
+ SrLeft = 1 << 25,
+ SlRight = 1 << 26,
+ SrRight = 1 << 27,
// Generic Catch-all
- Up = DpadUp | LStickUp | RStickUp,
- Down = DpadDown | LStickDown | RStickDown,
- Left = DpadLeft | LStickLeft | RStickLeft,
+ Up = DpadUp | LStickUp | RStickUp,
+ Down = DpadDown | LStickDown | RStickDown,
+ Left = DpadLeft | LStickLeft | RStickLeft,
Right = DpadRight | LStickRight | RStickRight,
- Sl = SlLeft | SlRight,
- Sr = SrLeft | SrRight
+ Sl = SlLeft | SlRight,
+ Sr = SrLeft | SrRight
}
}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs
index f65c3079..b2d34e8e 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/Npad/ControllerType.cs
@@ -6,14 +6,14 @@ namespace Ryujinx.HLE.HOS.Services.Hid
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,
+ 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
+ System = 1 << 30
}
}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs
index 29eb8d3d..c4419336 100644
--- a/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs
+++ b/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMem/Npad/NpadLayoutsIndex.cs
@@ -2,12 +2,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid
{
enum NpadLayoutsIndex : int
{
- ProController = 0,
- Handheld = 1,
- JoyDual = 2,
- JoyLeft = 3,
- JoyRight = 4,
- Pokeball = 5,
+ ProController = 0,
+ Handheld = 1,
+ JoyDual = 2,
+ JoyLeft = 3,
+ JoyRight = 4,
+ Pokeball = 5,
SystemExternal = 6
}
}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs
index 7eaf4ac8..3ff3489b 100644
--- a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs
+++ b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/UserManager/Types/Device.cs
@@ -14,6 +14,6 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp.UserManager
public DeviceState State = DeviceState.Unavailable;
public PlayerIndex Handle;
- public NpadIdType NpadIdType;
+ public NpadIdType NpadIdType;
}
}
\ No newline at end of file
diff --git a/Ryujinx/Config.json b/Ryujinx/Config.json
index 8df901e2..c5d08f9f 100644
--- a/Ryujinx/Config.json
+++ b/Ryujinx/Config.json
@@ -1,5 +1,5 @@
{
- "version": 5,
+ "version": 6,
"max_anisotropy": -1,
"graphics_shaders_dump_path": "",
"logging_enable_debug": false,
@@ -22,7 +22,6 @@
"enable_fs_integrity_checks": true,
"fs_global_access_log_mode": 0,
"ignore_missing_services": false,
- "controller_type": "Handheld",
"gui_columns": {
"fav_column": true,
"icon_column": true,
@@ -39,65 +38,47 @@
"enable_custom_theme": false,
"custom_theme_path": "",
"enable_keyboard": false,
- "keyboard_controls": {
- "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": {
- "stick_up": "I",
- "stick_down": "K",
- "stick_left": "J",
- "stick_right": "L",
- "stick_button": "H",
- "button_a": "Z",
- "button_b": "X",
- "button_x": "C",
- "button_y": "V",
- "button_plus": "Plus",
- "button_r": "U",
- "button_zr": "O"
- },
- "hotkeys": {
- "toggle_vsync": "Tab"
+ "keyboard_config": [
+ {
+ "index": 0,
+ "controller_type": "JoyconPair",
+ "player_index": "Player1",
+ "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",
+ "button_sl": "Unbound",
+ "button_sr": "Unbound"
+ },
+ "right_joycon": {
+ "stick_up": "I",
+ "stick_down": "K",
+ "stick_left": "J",
+ "stick_right": "L",
+ "stick_button": "H",
+ "button_a": "Z",
+ "button_b": "X",
+ "button_x": "C",
+ "button_y": "V",
+ "button_plus": "Plus",
+ "button_r": "U",
+ "button_zr": "O",
+ "button_sl": "Unbound",
+ "button_sr": "Unbound"
+ },
+ "hotkeys": {
+ "toggle_vsync": "Tab"
+ }
}
- },
- "joystick_controls": {
- "enabled": true,
- "index": 0,
- "deadzone": 0.05,
- "trigger_threshold": 0.5,
- "left_joycon": {
- "stick": "Axis0",
- "stick_button": "Button8",
- "button_minus": "Button6",
- "button_l": "Button4",
- "button_zl": "Axis2",
- "dpad_up": "Hat0Up",
- "dpad_down": "Hat0Down",
- "dpad_left": "Hat0Left",
- "dpad_right": "Hat0Right"
- },
- "right_joycon": {
- "stick": "Axis3",
- "stick_button": "Button9",
- "button_a": "Button1",
- "button_b": "Button0",
- "button_x": "Button3",
- "button_y": "Button2",
- "button_plus": "Button7",
- "button_r": "Button5",
- "button_zr": "Axis5"
- }
- }
+ ],
+ "controller_config": []
}
\ No newline at end of file
diff --git a/Ryujinx/Ryujinx.csproj b/Ryujinx/Ryujinx.csproj
index 28a0b601..b8258f58 100644
--- a/Ryujinx/Ryujinx.csproj
+++ b/Ryujinx/Ryujinx.csproj
@@ -31,9 +31,10 @@
-
-
-
+
+
+
+
@@ -41,21 +42,23 @@
-
+
-
+
+
-
-
-
+
+
+
+
@@ -63,13 +66,14 @@
-
+
-
+
+
diff --git a/Ryujinx/Ui/AboutWindow.cs b/Ryujinx/Ui/AboutWindow.cs
index 6a18058a..5f1645da 100644
--- a/Ryujinx/Ui/AboutWindow.cs
+++ b/Ryujinx/Ui/AboutWindow.cs
@@ -12,7 +12,6 @@ namespace Ryujinx.Ui
{
#pragma warning disable CS0649
#pragma warning disable IDE0044
- [GUI] Window _aboutWin;
[GUI] Label _versionText;
[GUI] Image _ryujinxLogo;
[GUI] Image _patreonLogo;
@@ -28,7 +27,7 @@ namespace Ryujinx.Ui
{
builder.Autoconnect(this);
- _aboutWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
+ this.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
_ryujinxLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png" , 100, 100);
_patreonLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.PatreonLogo.png", 30 , 30 );
_gitHubLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.GitHubLogo.png" , 30 , 30 );
diff --git a/Ryujinx/Ui/ApplicationLibrary.cs b/Ryujinx/Ui/ApplicationLibrary.cs
index 02b6541f..2dd88196 100644
--- a/Ryujinx/Ui/ApplicationLibrary.cs
+++ b/Ryujinx/Ui/ApplicationLibrary.cs
@@ -413,7 +413,7 @@ namespace Ryujinx.Ui
Version = version,
TimePlayed = ConvertSecondsToReadableString(appMetadata.TimePlayed),
LastPlayed = appMetadata.LastPlayed,
- FileExtension = Path.GetExtension(applicationPath).ToUpper().Remove(0 ,1),
+ FileExtension = Path.GetExtension(applicationPath).ToUpper().Remove(0, 1),
FileSize = (fileSize < 1) ? (fileSize * 1024).ToString("0.##") + "MB" : fileSize.ToString("0.##") + "GB",
Path = applicationPath,
SaveDataPath = saveDataPath,
diff --git a/Ryujinx/Ui/ControllerWindow.cs b/Ryujinx/Ui/ControllerWindow.cs
new file mode 100644
index 00000000..581c7d56
--- /dev/null
+++ b/Ryujinx/Ui/ControllerWindow.cs
@@ -0,0 +1,925 @@
+using Gtk;
+using OpenTK.Input;
+using System;
+using System.IO;
+using System.Reflection;
+using System.Threading;
+using Ryujinx.Configuration;
+using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.Common.Utilities;
+using Ryujinx.HLE.FileSystem;
+
+using GUI = Gtk.Builder.ObjectAttribute;
+using Key = Ryujinx.Configuration.Hid.Key;
+
+namespace Ryujinx.Ui
+{
+ public class ControllerWindow : Window
+ {
+ private PlayerIndex _playerIndex;
+ private InputConfig _inputConfig;
+ private bool _isWaitingForInput;
+ private VirtualFileSystem _virtualFileSystem;
+
+#pragma warning disable CS0649, IDE0044
+ [GUI] Adjustment _controllerDeadzoneLeft;
+ [GUI] Adjustment _controllerDeadzoneRight;
+ [GUI] Adjustment _controllerTriggerThreshold;
+ [GUI] ComboBoxText _inputDevice;
+ [GUI] ComboBoxText _profile;
+ [GUI] ToggleButton _refreshInputDevicesButton;
+ [GUI] Box _settingsBox;
+ [GUI] Grid _leftStickKeyboard;
+ [GUI] Grid _leftStickController;
+ [GUI] Box _deadZoneLeftBox;
+ [GUI] Grid _rightStickKeyboard;
+ [GUI] Grid _rightStickController;
+ [GUI] Box _deadZoneRightBox;
+ [GUI] Grid _leftSideTriggerBox;
+ [GUI] Grid _rightSideTriggerBox;
+ [GUI] Box _triggerThresholdBox;
+ [GUI] ComboBoxText _controllerType;
+ [GUI] ToggleButton _lStickX;
+ [GUI] CheckButton _invertLStickX;
+ [GUI] ToggleButton _lStickY;
+ [GUI] CheckButton _invertLStickY;
+ [GUI] ToggleButton _lStickUp;
+ [GUI] ToggleButton _lStickDown;
+ [GUI] ToggleButton _lStickLeft;
+ [GUI] ToggleButton _lStickRight;
+ [GUI] ToggleButton _lStickButton;
+ [GUI] ToggleButton _dpadUp;
+ [GUI] ToggleButton _dpadDown;
+ [GUI] ToggleButton _dpadLeft;
+ [GUI] ToggleButton _dpadRight;
+ [GUI] ToggleButton _minus;
+ [GUI] ToggleButton _l;
+ [GUI] ToggleButton _zL;
+ [GUI] ToggleButton _rStickX;
+ [GUI] CheckButton _invertRStickX;
+ [GUI] ToggleButton _rStickY;
+ [GUI] CheckButton _invertRStickY;
+ [GUI] ToggleButton _rStickUp;
+ [GUI] ToggleButton _rStickDown;
+ [GUI] ToggleButton _rStickLeft;
+ [GUI] ToggleButton _rStickRight;
+ [GUI] ToggleButton _rStickButton;
+ [GUI] ToggleButton _a;
+ [GUI] ToggleButton _b;
+ [GUI] ToggleButton _x;
+ [GUI] ToggleButton _y;
+ [GUI] ToggleButton _plus;
+ [GUI] ToggleButton _r;
+ [GUI] ToggleButton _zR;
+ [GUI] ToggleButton _lSl;
+ [GUI] ToggleButton _lSr;
+ [GUI] ToggleButton _rSl;
+ [GUI] ToggleButton _rSr;
+ [GUI] Image _controllerImage;
+#pragma warning restore CS0649, IDE0044
+
+ public ControllerWindow(PlayerIndex controllerId, VirtualFileSystem virtualFileSystem) : this(new Builder("Ryujinx.Ui.ControllerWindow.glade"), controllerId, virtualFileSystem) { }
+
+ private ControllerWindow(Builder builder, PlayerIndex controllerId, VirtualFileSystem virtualFileSystem) : base(builder.GetObject("_controllerWin").Handle)
+ {
+ builder.Autoconnect(this);
+
+ this.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
+
+ _playerIndex = controllerId;
+ _virtualFileSystem = virtualFileSystem;
+ _inputConfig = ConfigurationState.Instance.Hid.InputConfig.Value.Find(inputConfig => inputConfig.PlayerIndex == _playerIndex);
+
+ //Bind Events
+ _lStickX.Clicked += Button_Pressed;
+ _lStickY.Clicked += Button_Pressed;
+ _lStickUp.Clicked += Button_Pressed;
+ _lStickDown.Clicked += Button_Pressed;
+ _lStickLeft.Clicked += Button_Pressed;
+ _lStickRight.Clicked += Button_Pressed;
+ _lStickButton.Clicked += Button_Pressed;
+ _dpadUp.Clicked += Button_Pressed;
+ _dpadDown.Clicked += Button_Pressed;
+ _dpadLeft.Clicked += Button_Pressed;
+ _dpadRight.Clicked += Button_Pressed;
+ _minus.Clicked += Button_Pressed;
+ _l.Clicked += Button_Pressed;
+ _zL.Clicked += Button_Pressed;
+ _lSl.Clicked += Button_Pressed;
+ _lSr.Clicked += Button_Pressed;
+ _rStickX.Clicked += Button_Pressed;
+ _rStickY.Clicked += Button_Pressed;
+ _rStickUp.Clicked += Button_Pressed;
+ _rStickDown.Clicked += Button_Pressed;
+ _rStickLeft.Clicked += Button_Pressed;
+ _rStickRight.Clicked += Button_Pressed;
+ _rStickButton.Clicked += Button_Pressed;
+ _a.Clicked += Button_Pressed;
+ _b.Clicked += Button_Pressed;
+ _x.Clicked += Button_Pressed;
+ _y.Clicked += Button_Pressed;
+ _plus.Clicked += Button_Pressed;
+ _r.Clicked += Button_Pressed;
+ _zR.Clicked += Button_Pressed;
+ _rSl.Clicked += Button_Pressed;
+ _rSr.Clicked += Button_Pressed;
+
+ // Setup current values
+ UpdateInputDeviceList();
+ SetAvailableOptions();
+
+ ClearValues();
+ if (_inputDevice.ActiveId != null) SetCurrentValues();
+ }
+
+ private void UpdateInputDeviceList()
+ {
+ _inputDevice.RemoveAll();
+ _inputDevice.Append("disabled", "Disabled");
+ _inputDevice.SetActiveId("disabled");
+
+ for (int i = 0; i < 20; i++)
+ {
+ if (Keyboard.GetState(i).IsConnected)
+ _inputDevice.Append($"keyboard/{i}", $"Keyboard/{i}");
+
+ if (GamePad.GetState(i).IsConnected)
+ _inputDevice.Append($"controller/{i}", $"Controller/{i} ({GamePad.GetName(i)})");
+ }
+
+ switch (_inputConfig)
+ {
+ case KeyboardConfig keyboard:
+ _inputDevice.SetActiveId($"keyboard/{keyboard.Index}");
+ break;
+ case ControllerConfig controller:
+ _inputDevice.SetActiveId($"controller/{controller.Index}");
+ break;
+ }
+ }
+
+ private void SetAvailableOptions()
+ {
+ if (_inputDevice.ActiveId != null && _inputDevice.ActiveId.StartsWith("keyboard"))
+ {
+ this.ShowAll();
+ _leftStickController.Hide();
+ _rightStickController.Hide();
+ _deadZoneLeftBox.Hide();
+ _deadZoneRightBox.Hide();
+ _triggerThresholdBox.Hide();
+ }
+ else if (_inputDevice.ActiveId != null && _inputDevice.ActiveId.StartsWith("controller"))
+ {
+ this.ShowAll();
+ _leftStickKeyboard.Hide();
+ _rightStickKeyboard.Hide();
+ }
+ else
+ {
+ _settingsBox.Hide();
+ }
+
+ ClearValues();
+ }
+
+ private void SetCurrentValues()
+ {
+ SetControllerSpecificFields();
+
+ SetProfiles();
+
+ if (_inputDevice.ActiveId.StartsWith("keyboard") && _inputConfig is KeyboardConfig)
+ {
+ SetValues(_inputConfig);
+ }
+ else if (_inputDevice.ActiveId.StartsWith("controller") && _inputConfig is ControllerConfig)
+ {
+ SetValues(_inputConfig);
+ }
+ }
+
+ private void SetControllerSpecificFields()
+ {
+ _leftSideTriggerBox.Hide();
+ _rightSideTriggerBox.Hide();
+
+ switch (_controllerType.ActiveId)
+ {
+ case "JoyconLeft":
+ _leftSideTriggerBox.Show();
+ break;
+ case "JoyconRight":
+ _rightSideTriggerBox.Show();
+ break;
+ }
+
+ switch (_controllerType.ActiveId)
+ {
+ case "ProController":
+ _controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.ProCon.svg", 400, 400);
+ break;
+ case "JoyconLeft":
+ _controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyConLeft.svg", 400, 400);
+ break;
+ case "JoyconRight":
+ _controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyConRight.svg", 400, 400);
+ break;
+ default:
+ _controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyConPair.svg", 400, 400);
+ break;
+ }
+ }
+
+ private void ClearValues()
+ {
+ _lStickX.Label = "Unbound";
+ _lStickY.Label = "Unbound";
+ _lStickUp.Label = "Unbound";
+ _lStickDown.Label = "Unbound";
+ _lStickLeft.Label = "Unbound";
+ _lStickRight.Label = "Unbound";
+ _lStickButton.Label = "Unbound";
+ _dpadUp.Label = "Unbound";
+ _dpadDown.Label = "Unbound";
+ _dpadLeft.Label = "Unbound";
+ _dpadRight.Label = "Unbound";
+ _minus.Label = "Unbound";
+ _l.Label = "Unbound";
+ _zL.Label = "Unbound";
+ _lSl.Label = "Unbound";
+ _lSr.Label = "Unbound";
+ _rStickX.Label = "Unbound";
+ _rStickY.Label = "Unbound";
+ _rStickUp.Label = "Unbound";
+ _rStickDown.Label = "Unbound";
+ _rStickLeft.Label = "Unbound";
+ _rStickRight.Label = "Unbound";
+ _rStickButton.Label = "Unbound";
+ _a.Label = "Unbound";
+ _b.Label = "Unbound";
+ _x.Label = "Unbound";
+ _y.Label = "Unbound";
+ _plus.Label = "Unbound";
+ _r.Label = "Unbound";
+ _zR.Label = "Unbound";
+ _rSl.Label = "Unbound";
+ _rSr.Label = "Unbound";
+ _controllerDeadzoneLeft.Value = 0;
+ _controllerDeadzoneRight.Value = 0;
+ _controllerTriggerThreshold.Value = 0;
+ }
+
+ private void SetValues(InputConfig config)
+ {
+ switch (config)
+ {
+ case KeyboardConfig keyboardConfig:
+ _controllerType.SetActiveId(keyboardConfig.ControllerType.ToString());
+
+ _lStickUp.Label = keyboardConfig.LeftJoycon.StickUp.ToString();
+ _lStickDown.Label = keyboardConfig.LeftJoycon.StickDown.ToString();
+ _lStickLeft.Label = keyboardConfig.LeftJoycon.StickLeft.ToString();
+ _lStickRight.Label = keyboardConfig.LeftJoycon.StickRight.ToString();
+ _lStickButton.Label = keyboardConfig.LeftJoycon.StickButton.ToString();
+ _dpadUp.Label = keyboardConfig.LeftJoycon.DPadUp.ToString();
+ _dpadDown.Label = keyboardConfig.LeftJoycon.DPadDown.ToString();
+ _dpadLeft.Label = keyboardConfig.LeftJoycon.DPadLeft.ToString();
+ _dpadRight.Label = keyboardConfig.LeftJoycon.DPadRight.ToString();
+ _minus.Label = keyboardConfig.LeftJoycon.ButtonMinus.ToString();
+ _l.Label = keyboardConfig.LeftJoycon.ButtonL.ToString();
+ _zL.Label = keyboardConfig.LeftJoycon.ButtonZl.ToString();
+ _lSl.Label = keyboardConfig.LeftJoycon.ButtonSl.ToString();
+ _lSr.Label = keyboardConfig.LeftJoycon.ButtonSr.ToString();
+ _rStickUp.Label = keyboardConfig.RightJoycon.StickUp.ToString();
+ _rStickDown.Label = keyboardConfig.RightJoycon.StickDown.ToString();
+ _rStickLeft.Label = keyboardConfig.RightJoycon.StickLeft.ToString();
+ _rStickRight.Label = keyboardConfig.RightJoycon.StickRight.ToString();
+ _rStickButton.Label = keyboardConfig.RightJoycon.StickButton.ToString();
+ _a.Label = keyboardConfig.RightJoycon.ButtonA.ToString();
+ _b.Label = keyboardConfig.RightJoycon.ButtonB.ToString();
+ _x.Label = keyboardConfig.RightJoycon.ButtonX.ToString();
+ _y.Label = keyboardConfig.RightJoycon.ButtonY.ToString();
+ _plus.Label = keyboardConfig.RightJoycon.ButtonPlus.ToString();
+ _r.Label = keyboardConfig.RightJoycon.ButtonR.ToString();
+ _zR.Label = keyboardConfig.RightJoycon.ButtonZr.ToString();
+ _rSl.Label = keyboardConfig.RightJoycon.ButtonSl.ToString();
+ _rSr.Label = keyboardConfig.RightJoycon.ButtonSr.ToString();
+ break;
+ case ControllerConfig controllerConfig:
+ _controllerType.SetActiveId(controllerConfig.ControllerType.ToString());
+
+ _lStickX.Label = controllerConfig.LeftJoycon.StickX.ToString();
+ _invertLStickX.Active = controllerConfig.LeftJoycon.InvertStickX;
+ _lStickY.Label = controllerConfig.LeftJoycon.StickY.ToString();
+ _invertLStickY.Active = controllerConfig.LeftJoycon.InvertStickY;
+ _lStickButton.Label = controllerConfig.LeftJoycon.StickButton.ToString();
+ _dpadUp.Label = controllerConfig.LeftJoycon.DPadUp.ToString();
+ _dpadDown.Label = controllerConfig.LeftJoycon.DPadDown.ToString();
+ _dpadLeft.Label = controllerConfig.LeftJoycon.DPadLeft.ToString();
+ _dpadRight.Label = controllerConfig.LeftJoycon.DPadRight.ToString();
+ _minus.Label = controllerConfig.LeftJoycon.ButtonMinus.ToString();
+ _l.Label = controllerConfig.LeftJoycon.ButtonL.ToString();
+ _zL.Label = controllerConfig.LeftJoycon.ButtonZl.ToString();
+ _lSl.Label = controllerConfig.LeftJoycon.ButtonSl.ToString();
+ _lSr.Label = controllerConfig.LeftJoycon.ButtonSr.ToString();
+ _rStickX.Label = controllerConfig.RightJoycon.StickX.ToString();
+ _invertRStickX.Active = controllerConfig.RightJoycon.InvertStickX;
+ _rStickY.Label = controllerConfig.RightJoycon.StickY.ToString();
+ _invertRStickY.Active = controllerConfig.RightJoycon.InvertStickY;
+ _rStickButton.Label = controllerConfig.RightJoycon.StickButton.ToString();
+ _a.Label = controllerConfig.RightJoycon.ButtonA.ToString();
+ _b.Label = controllerConfig.RightJoycon.ButtonB.ToString();
+ _x.Label = controllerConfig.RightJoycon.ButtonX.ToString();
+ _y.Label = controllerConfig.RightJoycon.ButtonY.ToString();
+ _plus.Label = controllerConfig.RightJoycon.ButtonPlus.ToString();
+ _r.Label = controllerConfig.RightJoycon.ButtonR.ToString();
+ _zR.Label = controllerConfig.RightJoycon.ButtonZr.ToString();
+ _rSl.Label = controllerConfig.RightJoycon.ButtonSl.ToString();
+ _rSr.Label = controllerConfig.RightJoycon.ButtonSr.ToString();
+ _controllerDeadzoneLeft.Value = controllerConfig.DeadzoneLeft;
+ _controllerDeadzoneRight.Value = controllerConfig.DeadzoneRight;
+ _controllerTriggerThreshold.Value = controllerConfig.TriggerThreshold;
+ break;
+ }
+ }
+
+ private InputConfig GetValues()
+ {
+ if (_inputDevice.ActiveId.StartsWith("keyboard"))
+ {
+ Enum.TryParse(_lStickUp.Label, out Key lStickUp);
+ Enum.TryParse(_lStickDown.Label, out Key lStickDown);
+ Enum.TryParse(_lStickLeft.Label, out Key lStickLeft);
+ Enum.TryParse(_lStickRight.Label, out Key lStickRight);
+ Enum.TryParse(_lStickButton.Label, out Key lStickButton);
+ Enum.TryParse(_dpadUp.Label, out Key lDPadUp);
+ Enum.TryParse(_dpadDown.Label, out Key lDPadDown);
+ Enum.TryParse(_dpadLeft.Label, out Key lDPadLeft);
+ Enum.TryParse(_dpadRight.Label, out Key lDPadRight);
+ Enum.TryParse(_minus.Label, out Key lButtonMinus);
+ Enum.TryParse(_l.Label, out Key lButtonL);
+ Enum.TryParse(_zL.Label, out Key lButtonZl);
+ Enum.TryParse(_lSl.Label, out Key lButtonSl);
+ Enum.TryParse(_lSr.Label, out Key lButtonSr);
+
+ Enum.TryParse(_rStickUp.Label, out Key rStickUp);
+ Enum.TryParse(_rStickDown.Label, out Key rStickDown);
+ Enum.TryParse(_rStickLeft.Label, out Key rStickLeft);
+ Enum.TryParse(_rStickRight.Label, out Key rStickRight);
+ Enum.TryParse(_rStickButton.Label, out Key rStickButton);
+ Enum.TryParse(_a.Label, out Key rButtonA);
+ Enum.TryParse(_b.Label, out Key rButtonB);
+ Enum.TryParse(_x.Label, out Key rButtonX);
+ Enum.TryParse(_y.Label, out Key rButtonY);
+ Enum.TryParse(_plus.Label, out Key rButtonPlus);
+ Enum.TryParse(_r.Label, out Key rButtonR);
+ Enum.TryParse(_zR.Label, out Key rButtonZr);
+ Enum.TryParse(_rSl.Label, out Key rButtonSl);
+ Enum.TryParse(_rSr.Label, out Key rButtonSr);
+
+ return new KeyboardConfig
+ {
+ Index = int.Parse(_inputDevice.ActiveId.Split("/")[1]),
+ ControllerType = Enum.Parse(_controllerType.ActiveId),
+ PlayerIndex = _playerIndex,
+ LeftJoycon = new NpadKeyboardLeft
+ {
+ StickUp = lStickUp,
+ StickDown = lStickDown,
+ StickLeft = lStickLeft,
+ StickRight = lStickRight,
+ StickButton = lStickButton,
+ DPadUp = lDPadUp,
+ DPadDown = lDPadDown,
+ DPadLeft = lDPadLeft,
+ DPadRight = lDPadRight,
+ ButtonMinus = lButtonMinus,
+ ButtonL = lButtonL,
+ ButtonZl = lButtonZl,
+ ButtonSl = lButtonSl,
+ ButtonSr = lButtonSr
+ },
+ RightJoycon = new NpadKeyboardRight
+ {
+ StickUp = rStickUp,
+ StickDown = rStickDown,
+ StickLeft = rStickLeft,
+ StickRight = rStickRight,
+ StickButton = rStickButton,
+ ButtonA = rButtonA,
+ ButtonB = rButtonB,
+ ButtonX = rButtonX,
+ ButtonY = rButtonY,
+ ButtonPlus = rButtonPlus,
+ ButtonR = rButtonR,
+ ButtonZr = rButtonZr,
+ ButtonSl = rButtonSl,
+ ButtonSr = rButtonSr
+ },
+ Hotkeys = new KeyboardHotkeys
+ {
+ ToggleVsync = Key.Tab //TODO: Make this an option in the GUI
+ }
+ };
+ }
+
+ if (_inputDevice.ActiveId.StartsWith("controller"))
+ {
+ Enum.TryParse(_lStickX.Label, out ControllerInputId lStickX);
+ Enum.TryParse(_lStickY.Label, out ControllerInputId lStickY);
+ Enum.TryParse(_lStickButton.Label, out ControllerInputId lStickButton);
+ Enum.TryParse(_minus.Label, out ControllerInputId lButtonMinus);
+ Enum.TryParse(_l.Label, out ControllerInputId lButtonL);
+ Enum.TryParse(_zL.Label, out ControllerInputId lButtonZl);
+ Enum.TryParse(_lSl.Label, out ControllerInputId lButtonSl);
+ Enum.TryParse(_lSr.Label, out ControllerInputId lButtonSr);
+ Enum.TryParse(_dpadUp.Label, out ControllerInputId lDPadUp);
+ Enum.TryParse(_dpadDown.Label, out ControllerInputId lDPadDown);
+ Enum.TryParse(_dpadLeft.Label, out ControllerInputId lDPadLeft);
+ Enum.TryParse(_dpadRight.Label, out ControllerInputId lDPadRight);
+
+ Enum.TryParse(_rStickX.Label, out ControllerInputId rStickX);
+ Enum.TryParse(_rStickY.Label, out ControllerInputId rStickY);
+ Enum.TryParse(_rStickButton.Label, out ControllerInputId rStickButton);
+ Enum.TryParse(_a.Label, out ControllerInputId rButtonA);
+ Enum.TryParse(_b.Label, out ControllerInputId rButtonB);
+ Enum.TryParse(_x.Label, out ControllerInputId rButtonX);
+ Enum.TryParse(_y.Label, out ControllerInputId rButtonY);
+ Enum.TryParse(_plus.Label, out ControllerInputId rButtonPlus);
+ Enum.TryParse(_r.Label, out ControllerInputId rButtonR);
+ Enum.TryParse(_zR.Label, out ControllerInputId rButtonZr);
+ Enum.TryParse(_rSl.Label, out ControllerInputId rButtonSl);
+ Enum.TryParse(_rSr.Label, out ControllerInputId rButtonSr);
+
+ return new ControllerConfig
+ {
+ Index = int.Parse(_inputDevice.ActiveId.Split("/")[1]),
+ ControllerType = Enum.Parse(_controllerType.ActiveId),
+ PlayerIndex = _playerIndex,
+ DeadzoneLeft = (float)_controllerDeadzoneLeft.Value,
+ DeadzoneRight = (float)_controllerDeadzoneRight.Value,
+ TriggerThreshold = (float)_controllerTriggerThreshold.Value,
+ LeftJoycon = new NpadControllerLeft
+ {
+ InvertStickX = _invertLStickX.Active,
+ StickX = lStickX,
+ InvertStickY = _invertLStickY.Active,
+ StickY = lStickY,
+ StickButton = lStickButton,
+ ButtonMinus = lButtonMinus,
+ ButtonL = lButtonL,
+ ButtonZl = lButtonZl,
+ ButtonSl = lButtonSl,
+ ButtonSr = lButtonSr,
+ DPadUp = lDPadUp,
+ DPadDown = lDPadDown,
+ DPadLeft = lDPadLeft,
+ DPadRight = lDPadRight
+ },
+ RightJoycon = new NpadControllerRight
+ {
+ InvertStickX = _invertRStickX.Active,
+ StickX = rStickX,
+ InvertStickY = _invertRStickY.Active,
+ StickY = rStickY,
+ StickButton = rStickButton,
+ ButtonA = rButtonA,
+ ButtonB = rButtonB,
+ ButtonX = rButtonX,
+ ButtonY = rButtonY,
+ ButtonPlus = rButtonPlus,
+ ButtonR = rButtonR,
+ ButtonZr = rButtonZr,
+ ButtonSl = rButtonSl,
+ ButtonSr = rButtonSr
+ }
+ };
+ }
+
+ if (!_inputDevice.ActiveId.StartsWith("disabled"))
+ {
+ GtkDialog.CreateErrorDialog("Some fields entered where invalid and therefore your config was not saved.");
+ }
+
+ return null;
+ }
+
+ private static bool IsAnyKeyPressed(out Key pressedKey, int index = 0)
+ {
+ KeyboardState keyboardState = Keyboard.GetState(index);
+
+ foreach (Key key in Enum.GetValues(typeof(Key)))
+ {
+ if (keyboardState.IsKeyDown((OpenTK.Input.Key)key))
+ {
+ pressedKey = key;
+
+ return true;
+ }
+ }
+
+ pressedKey = Key.Unbound;
+
+ return false;
+ }
+
+ private static bool IsAnyButtonPressed(out ControllerInputId pressedButton, int index, double triggerThreshold)
+ {
+ JoystickState joystickState = Joystick.GetState(index);
+ JoystickCapabilities joystickCapabilities = Joystick.GetCapabilities(index);
+
+ //Buttons
+ for (int i = 0; i != joystickCapabilities.ButtonCount; i++)
+ {
+ if (joystickState.IsButtonDown(i))
+ {
+ Enum.TryParse($"Button{i}", out pressedButton);
+
+ return true;
+ }
+ }
+
+ //Axis
+ for (int i = 0; i != joystickCapabilities.AxisCount; i++)
+ {
+ if (joystickState.GetAxis(i) > 0.5f && joystickState.GetAxis(i) > triggerThreshold)
+ {
+ Enum.TryParse($"Axis{i}", out pressedButton);
+
+ return true;
+ }
+ }
+
+ //Hats
+ for (int i = 0; i != joystickCapabilities.HatCount; i++)
+ {
+ JoystickHatState hatState = joystickState.GetHat((JoystickHat)i);
+ string pos = null;
+
+ if (hatState.IsUp) pos = "Up";
+ if (hatState.IsDown) pos = "Down";
+ if (hatState.IsLeft) pos = "Left";
+ if (hatState.IsRight) pos = "Right";
+ if (pos == null) continue;
+
+ Enum.TryParse($"Hat{i}{pos}", out pressedButton);
+
+ return true;
+ }
+
+ pressedButton = ControllerInputId.Unbound;
+
+ return false;
+ }
+
+ private string GetProfileBasePath()
+ {
+ string path = System.IO.Path.Combine(_virtualFileSystem.GetBasePath(), "profiles");
+
+ if (_inputDevice.ActiveId.StartsWith("keyboard"))
+ {
+ path = System.IO.Path.Combine(path, "keyboard");
+ }
+ else if (_inputDevice.ActiveId.StartsWith("controller"))
+ {
+ path = System.IO.Path.Combine(path, "controller");
+ }
+
+ return path;
+ }
+
+ //Events
+ private void InputDevice_Changed(object sender, EventArgs args)
+ {
+ SetAvailableOptions();
+ SetControllerSpecificFields();
+
+ if (_inputDevice.ActiveId != null) SetProfiles();
+ }
+
+ private void Controller_Changed(object sender, EventArgs args)
+ {
+ SetControllerSpecificFields();
+ }
+
+ private void RefreshInputDevicesButton_Pressed(object sender, EventArgs args)
+ {
+ UpdateInputDeviceList();
+
+ _refreshInputDevicesButton.SetStateFlags(0, true);
+ }
+
+ private void Button_Pressed(object sender, EventArgs args)
+ {
+ if (_isWaitingForInput)
+ {
+ return;
+ }
+
+ _isWaitingForInput = true;
+
+ Thread inputThread = new Thread(() =>
+ {
+ Button button = (ToggleButton)sender;
+
+ if (_inputDevice.ActiveId.StartsWith("keyboard"))
+ {
+ Key pressedKey;
+
+ int index = int.Parse(_inputDevice.ActiveId.Split("/")[1]);
+ while (!IsAnyKeyPressed(out pressedKey, index))
+ {
+ if (Mouse.GetState().IsAnyButtonDown || Keyboard.GetState().IsKeyDown(OpenTK.Input.Key.Escape))
+ {
+ Application.Invoke(delegate
+ {
+ button.SetStateFlags(0, true);
+ });
+
+ _isWaitingForInput = false;
+
+ return;
+ }
+ }
+
+ Application.Invoke(delegate
+ {
+ button.Label = pressedKey.ToString();
+ button.SetStateFlags(0, true);
+ });
+ }
+ else if (_inputDevice.ActiveId.StartsWith("controller"))
+ {
+ ControllerInputId pressedButton;
+
+ int index = int.Parse(_inputDevice.ActiveId.Split("/")[1]);
+ while (!IsAnyButtonPressed(out pressedButton, index, _controllerTriggerThreshold.Value))
+ {
+ if (Mouse.GetState().IsAnyButtonDown || Keyboard.GetState().IsAnyKeyDown)
+ {
+ Application.Invoke(delegate
+ {
+ button.SetStateFlags(0, true);
+ });
+
+ _isWaitingForInput = false;
+
+ return;
+ }
+ }
+
+ Application.Invoke(delegate
+ {
+ button.Label = pressedButton.ToString();
+ button.SetStateFlags(0, true);
+ });
+ }
+
+ _isWaitingForInput = false;
+ });
+ inputThread.Name = "GUI.InputThread";
+ inputThread.IsBackground = true;
+ inputThread.Start();
+ }
+
+ private void SetProfiles()
+ {
+ string basePath = GetProfileBasePath();
+
+ if (!Directory.Exists(basePath))
+ {
+ Directory.CreateDirectory(basePath);
+ }
+
+ _profile.RemoveAll();
+ _profile.Append("default", "Default");
+
+ foreach (string profile in Directory.GetFiles(basePath, "*.*", SearchOption.AllDirectories))
+ {
+ _profile.Append(System.IO.Path.GetFileName(profile), System.IO.Path.GetFileNameWithoutExtension(profile));
+ }
+ }
+
+ private void ProfileLoad_Activated(object sender, EventArgs args)
+ {
+ ((ToggleButton)sender).SetStateFlags(0, true);
+
+ if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == null) return;
+
+ InputConfig config = null;
+ int pos = _profile.Active;
+
+ if (_profile.ActiveId == "default")
+ {
+ if (_inputDevice.ActiveId.StartsWith("keyboard"))
+ {
+ config = new KeyboardConfig
+ {
+ Index = 0,
+ ControllerType = ControllerType.JoyconPair,
+ LeftJoycon = new NpadKeyboardLeft
+ {
+ StickUp = Key.W,
+ StickDown = Key.S,
+ StickLeft = Key.A,
+ StickRight = Key.D,
+ StickButton = Key.F,
+ DPadUp = Key.Up,
+ DPadDown = Key.Down,
+ DPadLeft = Key.Left,
+ DPadRight = Key.Right,
+ ButtonMinus = Key.Minus,
+ ButtonL = Key.E,
+ ButtonZl = Key.Q,
+ ButtonSl = Key.Unbound,
+ ButtonSr = Key.Unbound
+ },
+ RightJoycon = new NpadKeyboardRight
+ {
+ StickUp = Key.I,
+ StickDown = Key.K,
+ StickLeft = Key.J,
+ StickRight = Key.L,
+ StickButton = Key.H,
+ ButtonA = Key.Z,
+ ButtonB = Key.X,
+ ButtonX = Key.C,
+ ButtonY = Key.V,
+ ButtonPlus = Key.Plus,
+ ButtonR = Key.U,
+ ButtonZr = Key.O,
+ ButtonSl = Key.Unbound,
+ ButtonSr = Key.Unbound
+ },
+ Hotkeys = new KeyboardHotkeys
+ {
+ ToggleVsync = Key.Tab
+ }
+ };
+ }
+ else if (_inputDevice.ActiveId.StartsWith("controller"))
+ {
+ config = new ControllerConfig
+ {
+ Index = 0,
+ ControllerType = ControllerType.ProController,
+ DeadzoneLeft = 0.1f,
+ DeadzoneRight = 0.1f,
+ TriggerThreshold = 0.5f,
+ LeftJoycon = new NpadControllerLeft
+ {
+ StickX = ControllerInputId.Axis0,
+ StickY = ControllerInputId.Axis1,
+ StickButton = ControllerInputId.Button8,
+ DPadUp = ControllerInputId.Hat0Up,
+ DPadDown = ControllerInputId.Hat0Down,
+ DPadLeft = ControllerInputId.Hat0Left,
+ DPadRight = ControllerInputId.Hat0Right,
+ ButtonMinus = ControllerInputId.Button6,
+ ButtonL = ControllerInputId.Button4,
+ ButtonZl = ControllerInputId.Axis2,
+ ButtonSl = ControllerInputId.Unbound,
+ ButtonSr = ControllerInputId.Unbound,
+ InvertStickX = false,
+ InvertStickY = false
+ },
+ RightJoycon = new NpadControllerRight
+ {
+ StickX = ControllerInputId.Axis3,
+ StickY = ControllerInputId.Axis4,
+ StickButton = ControllerInputId.Button9,
+ ButtonA = ControllerInputId.Button1,
+ ButtonB = ControllerInputId.Button0,
+ ButtonX = ControllerInputId.Button3,
+ ButtonY = ControllerInputId.Button2,
+ ButtonPlus = ControllerInputId.Button7,
+ ButtonR = ControllerInputId.Button5,
+ ButtonZr = ControllerInputId.Axis5,
+ ButtonSl = ControllerInputId.Unbound,
+ ButtonSr = ControllerInputId.Unbound,
+ InvertStickX = false,
+ InvertStickY = false
+ }
+ };
+ }
+ }
+ else
+ {
+ string path = System.IO.Path.Combine(GetProfileBasePath(), _profile.ActiveId);
+
+ if (!File.Exists(path))
+ {
+ if (pos >= 0)
+ {
+ _profile.Remove(pos);
+ }
+
+ return;
+ }
+
+ using (Stream stream = File.OpenRead(path))
+ {
+ try
+ {
+ config = JsonHelper.Deserialize(stream);
+ }
+ catch (ArgumentException)
+ {
+ try
+ {
+ config = JsonHelper.Deserialize(stream);
+ }
+ catch { }
+ }
+ }
+ }
+
+ SetValues(config);
+ }
+
+ private void ProfileAdd_Activated(object sender, EventArgs args)
+ {
+ ((ToggleButton)sender).SetStateFlags(0, true);
+
+ if (_inputDevice.ActiveId == "disabled") return;
+
+ InputConfig inputConfig = GetValues();
+ ProfileDialog profileDialog = new ProfileDialog();
+
+ if (inputConfig == null) return;
+
+ if (profileDialog.Run() == (int)ResponseType.Ok)
+ {
+ string path = System.IO.Path.Combine(GetProfileBasePath(), profileDialog.FileName);
+ string jsonString;
+
+ if (inputConfig is KeyboardConfig keyboardConfig)
+ {
+ jsonString = JsonHelper.Serialize(keyboardConfig, true);
+ }
+ else
+ {
+ jsonString = JsonHelper.Serialize(inputConfig as ControllerConfig, true);
+ }
+
+ File.WriteAllText(path, jsonString);
+ }
+
+ profileDialog.Dispose();
+
+ SetProfiles();
+ }
+
+ private void ProfileRemove_Activated(object sender, EventArgs args)
+ {
+ ((ToggleButton) sender).SetStateFlags(0, true);
+
+ if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == "default" || _profile.ActiveId == null) return;
+
+ MessageDialog confirmDialog = GtkDialog.CreateConfirmationDialog("Deleting Profile", "This action is irreversible, are your sure you want to continue?");
+
+ if (confirmDialog.Run() == (int)ResponseType.Yes)
+ {
+ string path = System.IO.Path.Combine(GetProfileBasePath(), _profile.ActiveId);
+
+ if (File.Exists(path))
+ {
+ File.Delete(path);
+ }
+
+ SetProfiles();
+ }
+ }
+
+ private void SaveToggle_Activated(object sender, EventArgs args)
+ {
+ InputConfig inputConfig = GetValues();
+
+ if (_inputConfig == null && inputConfig != null)
+ {
+ ConfigurationState.Instance.Hid.InputConfig.Value.Add(inputConfig);
+ }
+ else
+ {
+ if (_inputDevice.ActiveId == "disabled")
+ {
+ ConfigurationState.Instance.Hid.InputConfig.Value.Remove(_inputConfig);
+ }
+ else if (inputConfig != null)
+ {
+ int index = ConfigurationState.Instance.Hid.InputConfig.Value.IndexOf(_inputConfig);
+
+ ConfigurationState.Instance.Hid.InputConfig.Value[index] = inputConfig;
+ }
+ }
+
+ Dispose();
+ }
+
+ private void CloseToggle_Activated(object sender, EventArgs args)
+ {
+ Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx/Ui/ControllerWindow.glade b/Ryujinx/Ui/ControllerWindow.glade
new file mode 100644
index 00000000..2b780f13
--- /dev/null
+++ b/Ryujinx/Ui/ControllerWindow.glade
@@ -0,0 +1,1732 @@
+
+
+
+
+
+
+
+
+
diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs
index d266eefc..b37ab448 100644
--- a/Ryujinx/Ui/GLRenderer.cs
+++ b/Ryujinx/Ui/GLRenderer.cs
@@ -1,26 +1,24 @@
-using Gdk;
+using Gdk;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
-using OpenTK.Platform;
using Ryujinx.Configuration;
+using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.HLE;
using Ryujinx.HLE.HOS.Services.Hid;
-using Ryujinx.Ui;
using System;
using System.Collections.Generic;
-using System.Text;
using System.Threading;
namespace Ryujinx.Ui
{
- public class GLRenderer : GLWidget
+ public class GlRenderer : GLWidget
{
- private const int SwitchPanelWidth = 1280;
+ private const int SwitchPanelWidth = 1280;
private const int SwitchPanelHeight = 720;
- private const int TargetFps = 60;
+ private const int TargetFps = 60;
public ManualResetEvent WaitEvent { get; set; }
@@ -32,7 +30,7 @@ namespace Ryujinx.Ui
private double _mouseX;
private double _mouseY;
- private bool _mousePressed;
+ private bool _mousePressed;
private bool _toggleFullscreen;
@@ -46,11 +44,9 @@ namespace Ryujinx.Ui
private Renderer _renderer;
- private HotkeyButtons _prevHotkeyButtons = 0;
+ private HotkeyButtons _prevHotkeyButtons;
- private Input.NpadController _primaryController;
-
- public GLRenderer(Switch device)
+ public GlRenderer(Switch device)
: base (GetGraphicsMode(),
3, 3,
GraphicsContextFlags.ForwardCompatible)
@@ -59,8 +55,8 @@ namespace Ryujinx.Ui
_device = device;
- this.Initialized += GLRenderer_Initialized;
- this.Destroyed += GLRenderer_Destroyed;
+ this.Initialized += GLRenderer_Initialized;
+ this.Destroyed += GLRenderer_Destroyed;
this.ShuttingDown += GLRenderer_ShuttingDown;
Initialize();
@@ -69,25 +65,18 @@ namespace Ryujinx.Ui
_ticksPerFrame = System.Diagnostics.Stopwatch.Frequency / TargetFps;
- _primaryController = new Input.NpadController(ConfigurationState.Instance.Hid.JoystickControls);
-
- AddEvents((int)(Gdk.EventMask.ButtonPressMask
- | Gdk.EventMask.ButtonReleaseMask
- | Gdk.EventMask.PointerMotionMask
- | Gdk.EventMask.KeyPressMask
- | Gdk.EventMask.KeyReleaseMask));
+ AddEvents((int)(EventMask.ButtonPressMask
+ | EventMask.ButtonReleaseMask
+ | EventMask.PointerMotionMask
+ | EventMask.KeyPressMask
+ | EventMask.KeyReleaseMask));
this.Shown += Renderer_Shown;
}
private static GraphicsMode GetGraphicsMode()
{
- if (Environment.OSVersion.Platform == PlatformID.Unix)
- {
- return new GraphicsMode(new ColorFormat(24));
- }
-
- return new GraphicsMode(new ColorFormat());
+ return Environment.OSVersion.Platform == PlatformID.Unix ? new GraphicsMode(new ColorFormat(24)) : new GraphicsMode(new ColorFormat());
}
private void GLRenderer_ShuttingDown(object sender, EventArgs args)
@@ -117,11 +106,11 @@ namespace Ryujinx.Ui
public void HandleScreenState(KeyboardState keyboard)
{
- bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11)
+ bool toggleFullscreen = keyboard.IsKeyDown(OpenTK.Input.Key.F11)
|| ((keyboard.IsKeyDown(OpenTK.Input.Key.AltLeft)
|| keyboard.IsKeyDown(OpenTK.Input.Key.AltRight))
&& keyboard.IsKeyDown(OpenTK.Input.Key.Enter))
- || keyboard.IsKeyDown(OpenTK.Input.Key.Escape);
+ || keyboard.IsKeyDown(OpenTK.Input.Key.Escape);
bool fullScreenToggled = ParentWindow.State.HasFlag(Gdk.WindowState.Fullscreen);
@@ -165,7 +154,7 @@ namespace Ryujinx.Ui
protected override bool OnConfigureEvent(EventConfigure evnt)
{
- var result = base.OnConfigureEvent(evnt);
+ bool result = base.OnConfigureEvent(evnt);
Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window);
@@ -184,7 +173,7 @@ namespace Ryujinx.Ui
Gtk.Window parent = this.Toplevel as Gtk.Window;
- parent.FocusInEvent += Parent_FocusInEvent;
+ parent.FocusInEvent += Parent_FocusInEvent;
parent.FocusOutEvent += Parent_FocusOutEvent;
Gtk.Application.Invoke(delegate
@@ -347,7 +336,7 @@ namespace Ryujinx.Ui
_device.EnableDeviceVsync,
$"Host: {_device.Statistics.GetSystemFrameRate():00.00} FPS",
$"Game: {_device.Statistics.GetGameFrameRate():00.00} FPS",
- $"GPU: {_renderer.GpuVendor}"));
+ $"GPU: {_renderer.GpuVendor}"));
_ticks = Math.Min(_ticks - _ticksPerFrame, _ticksPerFrame);
}
@@ -382,83 +371,127 @@ namespace Ryujinx.Ui
return false;
}
- HotkeyButtons currentHotkeyButtons = 0;
- ControllerKeys currentButton = 0;
- JoystickPosition leftJoystick;
- JoystickPosition rightJoystick;
- KeyboardInput? hidKeyboard = null;
-
- int leftJoystickDx = 0;
- int leftJoystickDy = 0;
- int rightJoystickDx = 0;
- int rightJoystickDy = 0;
-
- // OpenTK always captures keyboard events, even if out of focus, so check if window is focused.
if (IsFocused)
{
- KeyboardState keyboard = OpenTK.Input.Keyboard.GetState();
-
Gtk.Application.Invoke(delegate
{
- HandleScreenState(keyboard);
+ HandleScreenState(OpenTK.Input.Keyboard.GetState());
});
+ }
- // Normal Input
- currentHotkeyButtons = KeyboardControls.GetHotkeyButtons(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
- currentButton = KeyboardControls.GetButtons(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
+ List gamepadInputs = new List();
- if (ConfigurationState.Instance.Hid.EnableKeyboard)
+ foreach (InputConfig inputConfig in ConfigurationState.Instance.Hid.InputConfig.Value)
+ {
+ ControllerKeys currentButton = 0;
+ JoystickPosition leftJoystick = new JoystickPosition();
+ JoystickPosition rightJoystick = new JoystickPosition();
+ KeyboardInput? hidKeyboard = null;
+
+ int leftJoystickDx = 0;
+ int leftJoystickDy = 0;
+ int rightJoystickDx = 0;
+ int rightJoystickDy = 0;
+
+ if (inputConfig is KeyboardConfig keyboardConfig)
{
- hidKeyboard = KeyboardControls.GetKeysDown(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
+ if (IsFocused)
+ {
+ // Keyboard Input
+ KeyboardController keyboardController = new KeyboardController(keyboardConfig);
+
+ currentButton = keyboardController.GetButtons();
+
+ (leftJoystickDx, leftJoystickDy) = keyboardController.GetLeftStick();
+ (rightJoystickDx, rightJoystickDy) = keyboardController.GetRightStick();
+
+ leftJoystick = new JoystickPosition
+ {
+ Dx = leftJoystickDx,
+ Dy = leftJoystickDy
+ };
+
+ rightJoystick = new JoystickPosition
+ {
+ Dx = rightJoystickDx,
+ Dy = rightJoystickDy
+ };
+
+ if (ConfigurationState.Instance.Hid.EnableKeyboard)
+ {
+ hidKeyboard = keyboardController.GetKeysDown();
+ }
+
+ if (!hidKeyboard.HasValue)
+ {
+ hidKeyboard = new KeyboardInput
+ {
+ Modifier = 0,
+ Keys = new int[0x8]
+ };
+ }
+
+ if (ConfigurationState.Instance.Hid.EnableKeyboard)
+ {
+ _device.Hid.Keyboard.Update(hidKeyboard.Value);
+ }
+
+ // Toggle vsync
+ HotkeyButtons currentHotkeyButtons = keyboardController.GetHotkeyButtons();
+
+ if (currentHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync) &&
+ !_prevHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync))
+ {
+ _device.EnableDeviceVsync = !_device.EnableDeviceVsync;
+ }
+
+ _prevHotkeyButtons = currentHotkeyButtons;
+ }
+ }
+ else if (inputConfig is Common.Configuration.Hid.ControllerConfig controllerConfig)
+ {
+ // Controller Input
+ JoystickController joystickController = new JoystickController(controllerConfig);
+
+ currentButton |= joystickController.GetButtons();
+
+ (leftJoystickDx, leftJoystickDy) = joystickController.GetLeftStick();
+ (rightJoystickDx, rightJoystickDy) = joystickController.GetRightStick();
+
+ leftJoystick = new JoystickPosition
+ {
+ Dx = controllerConfig.LeftJoycon.InvertStickX ? -leftJoystickDx : leftJoystickDx,
+ Dy = controllerConfig.LeftJoycon.InvertStickY ? -leftJoystickDy : leftJoystickDy
+ };
+
+ rightJoystick = new JoystickPosition
+ {
+ Dx = controllerConfig.RightJoycon.InvertStickX ? -rightJoystickDx : rightJoystickDx,
+ Dy = controllerConfig.RightJoycon.InvertStickY ? -rightJoystickDy : rightJoystickDy
+ };
}
- (leftJoystickDx, leftJoystickDy) = KeyboardControls.GetLeftStick(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
- (rightJoystickDx, rightJoystickDy) = KeyboardControls.GetRightStick(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
- }
+ currentButton |= _device.Hid.UpdateStickButtons(leftJoystick, rightJoystick);
- if (!hidKeyboard.HasValue)
- {
- hidKeyboard = new KeyboardInput
+ gamepadInputs.Add(new GamepadInput
{
- Modifier = 0,
- Keys = new int[0x8]
- };
+ PlayerId = (HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex,
+ Buttons = currentButton,
+ LStick = leftJoystick,
+ RStick = rightJoystick
+ });
}
- currentButton |= _primaryController.GetButtons();
-
- // Keyboard has priority stick-wise
- if (leftJoystickDx == 0 && leftJoystickDy == 0)
- {
- (leftJoystickDx, leftJoystickDy) = _primaryController.GetLeftStick();
- }
-
- if (rightJoystickDx == 0 && rightJoystickDy == 0)
- {
- (rightJoystickDx, rightJoystickDy) = _primaryController.GetRightStick();
- }
-
- leftJoystick = new JoystickPosition
- {
- Dx = leftJoystickDx,
- Dy = leftJoystickDy
- };
-
- rightJoystick = new JoystickPosition
- {
- Dx = rightJoystickDx,
- Dy = rightJoystickDy
- };
-
- currentButton |= _device.Hid.UpdateStickButtons(leftJoystick, rightJoystick);
+ _device.Hid.Npads.SetGamepadsInput(gamepadInputs.ToArray());
+ //Touchscreen
bool hasTouch = false;
// Get screen touch position from left mouse click
// OpenTK always captures mouse events, even if out of focus, so check if window is focused.
if (IsFocused && _mousePressed)
{
- int screenWidth = AllocatedWidth;
+ int screenWidth = AllocatedWidth;
int screenHeight = AllocatedHeight;
if (AllocatedWidth > (AllocatedHeight * SwitchPanelWidth) / SwitchPanelHeight)
@@ -470,7 +503,7 @@ namespace Ryujinx.Ui
screenHeight = (AllocatedWidth * SwitchPanelHeight) / SwitchPanelWidth;
}
- int startX = (AllocatedWidth - screenWidth) >> 1;
+ int startX = (AllocatedWidth - screenWidth) >> 1;
int startY = (AllocatedHeight - screenHeight) >> 1;
int endX = startX + screenWidth;
@@ -496,7 +529,7 @@ namespace Ryujinx.Ui
// Placeholder values till more data is acquired
DiameterX = 10,
DiameterY = 10,
- Angle = 90
+ Angle = 90
};
hasTouch = true;
@@ -510,30 +543,8 @@ namespace Ryujinx.Ui
_device.Hid.Touchscreen.Update();
}
- if (ConfigurationState.Instance.Hid.EnableKeyboard && hidKeyboard.HasValue)
- {
- _device.Hid.Keyboard.Update(hidKeyboard.Value);
- }
-
_device.Hid.DebugPad.Update();
- _device.Hid.Npads.SetGamepadsInput(new GamepadInput
- {
- PlayerId = PlayerIndex.Auto,
- Buttons = currentButton,
- LStick = leftJoystick,
- RStick = rightJoystick
- });
-
- // Toggle vsync
- if (currentHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync) &&
- !_prevHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync))
- {
- _device.EnableDeviceVsync = !_device.EnableDeviceVsync;
- }
-
- _prevHotkeyButtons = currentHotkeyButtons;
-
return true;
}
}
diff --git a/Ryujinx/Ui/GtkDialog.cs b/Ryujinx/Ui/GtkDialog.cs
index 698b8b7e..9a14f63d 100644
--- a/Ryujinx/Ui/GtkDialog.cs
+++ b/Ryujinx/Ui/GtkDialog.cs
@@ -3,33 +3,46 @@ using System.Reflection;
namespace Ryujinx.Ui
{
- internal class GtkDialog
+ internal class GtkDialog : MessageDialog
{
internal static bool _isExitDialogOpen = false;
- internal static void CreateDialog(string title, string text, string secondaryText)
+ private GtkDialog(string title, string mainText, string secondaryText,
+ MessageType messageType = MessageType.Other, ButtonsType buttonsType = ButtonsType.Ok) : base(null, DialogFlags.Modal, messageType, buttonsType, null)
{
- MessageDialog errorDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, null)
- {
- Title = title,
- Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
- Text = text,
- SecondaryText = secondaryText,
- WindowPosition = WindowPosition.Center
- };
- errorDialog.SetSizeRequest(100, 20);
- errorDialog.Run();
- errorDialog.Dispose();
+ Title = title;
+ Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
+ Text = mainText;
+ SecondaryText = secondaryText;
+ WindowPosition = WindowPosition.Center;
+ Response += GtkDialog_Response;
+
+ SetSizeRequest(100, 20);
}
- internal static void CreateWarningDialog(string text, string secondaryText)
+ private void GtkDialog_Response(object sender, ResponseArgs args)
{
- CreateDialog("Ryujinx - Warning", text, secondaryText);
+ Dispose();
+ }
+
+ internal static void CreateInfoDialog(string title, string mainText, string secondaryText)
+ {
+ new GtkDialog(title, mainText, secondaryText, MessageType.Info).Run();
+ }
+
+ internal static void CreateWarningDialog(string mainText, string secondaryText)
+ {
+ new GtkDialog("Ryujinx - Warning", mainText, secondaryText, MessageType.Warning).Run();
}
internal static void CreateErrorDialog(string errorMessage)
{
- CreateDialog("Ryujinx - Error", "Ryujinx has encountered an error", errorMessage);
+ new GtkDialog("Ryujinx - Error", "Ryujinx has encountered an error", errorMessage, MessageType.Error).Run();
+ }
+
+ internal static MessageDialog CreateConfirmationDialog(string mainText, string secondaryText = "")
+ {
+ return new GtkDialog("Ryujinx - Confirmation", mainText, secondaryText, MessageType.Question, ButtonsType.YesNo);
}
internal static bool CreateExitDialog()
@@ -40,27 +53,11 @@ namespace Ryujinx.Ui
}
_isExitDialogOpen = true;
-
- MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.OkCancel, null)
- {
- Title = "Ryujinx - Exit",
- Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
- Text = "Are you sure you want to stop emulation?",
- SecondaryText = "All unsaved data will be lost",
- WindowPosition = WindowPosition.Center
- };
-
- messageDialog.SetSizeRequest(100, 20);
- ResponseType res = (ResponseType)messageDialog.Run();
- messageDialog.Dispose();
+ ResponseType res = (ResponseType)new GtkDialog("Ryujinx - Exit", "Are you sure you want to stop emulation?",
+ "All unsaved data will be lost", MessageType.Question, ButtonsType.YesNo).Run();
_isExitDialogOpen = false;
- if (res == ResponseType.Ok)
- {
- return true;
- }
-
- return false;
+ return res == ResponseType.Yes;
}
}
-}
+}
\ No newline at end of file
diff --git a/Ryujinx/Ui/JoystickController.cs b/Ryujinx/Ui/JoystickController.cs
new file mode 100644
index 00000000..f5d7450a
--- /dev/null
+++ b/Ryujinx/Ui/JoystickController.cs
@@ -0,0 +1,149 @@
+using OpenTK;
+using OpenTK.Input;
+using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.HLE.HOS.Services.Hid;
+using System;
+
+using ControllerConfig = Ryujinx.Common.Configuration.Hid.ControllerConfig;
+
+namespace Ryujinx.Ui
+{
+ public class JoystickController
+ {
+ private readonly ControllerConfig _config;
+
+ // NOTE: This should be initialized AFTER GTK for compat reasons with OpenTK SDL2 backend and GTK on Linux.
+ // BODY: Usage of Joystick.GetState must be defer to after GTK full initialization. Otherwise, GTK will segfault because SDL2 was already init *sighs*
+ public JoystickController(ControllerConfig config)
+ {
+ _config = config;
+ }
+
+ private bool IsEnabled()
+ {
+ return Joystick.GetState(_config.Index).IsConnected;
+ }
+
+ public ControllerKeys GetButtons()
+ {
+ if (!IsEnabled())
+ {
+ return 0;
+ }
+
+ JoystickState joystickState = Joystick.GetState(_config.Index);
+
+ ControllerKeys buttons = 0;
+
+ if (IsActivated(joystickState, _config.LeftJoycon.DPadUp)) buttons |= ControllerKeys.DpadUp;
+ if (IsActivated(joystickState, _config.LeftJoycon.DPadDown)) buttons |= ControllerKeys.DpadDown;
+ if (IsActivated(joystickState, _config.LeftJoycon.DPadLeft)) buttons |= ControllerKeys.DpadLeft;
+ if (IsActivated(joystickState, _config.LeftJoycon.DPadRight)) buttons |= ControllerKeys.DpadRight;
+ if (IsActivated(joystickState, _config.LeftJoycon.StickButton)) buttons |= ControllerKeys.LStick;
+ if (IsActivated(joystickState, _config.LeftJoycon.ButtonMinus)) buttons |= ControllerKeys.Minus;
+ if (IsActivated(joystickState, _config.LeftJoycon.ButtonL)) buttons |= ControllerKeys.L;
+ if (IsActivated(joystickState, _config.LeftJoycon.ButtonZl)) buttons |= ControllerKeys.Zl;
+ if (IsActivated(joystickState, _config.LeftJoycon.ButtonSl)) buttons |= ControllerKeys.SlLeft;
+ if (IsActivated(joystickState, _config.LeftJoycon.ButtonSr)) buttons |= ControllerKeys.SrLeft;
+
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonA)) buttons |= ControllerKeys.A;
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonB)) buttons |= ControllerKeys.B;
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonX)) buttons |= ControllerKeys.X;
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonY)) buttons |= ControllerKeys.Y;
+ if (IsActivated(joystickState, _config.RightJoycon.StickButton)) buttons |= ControllerKeys.RStick;
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonPlus)) buttons |= ControllerKeys.Plus;
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonR)) buttons |= ControllerKeys.R;
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonZr)) buttons |= ControllerKeys.Zr;
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonSl)) buttons |= ControllerKeys.SlRight;
+ if (IsActivated(joystickState, _config.RightJoycon.ButtonSr)) buttons |= ControllerKeys.SrRight;
+
+ return buttons;
+ }
+
+ private bool IsActivated(JoystickState joystickState, ControllerInputId controllerInputId)
+ {
+ if (controllerInputId <= ControllerInputId.Button20)
+ {
+ return joystickState.IsButtonDown((int)controllerInputId);
+ }
+ else if (controllerInputId <= ControllerInputId.Axis5)
+ {
+ int axis = controllerInputId - ControllerInputId.Axis0;
+
+ return joystickState.GetAxis(axis) > _config.TriggerThreshold;
+ }
+ else if (controllerInputId <= ControllerInputId.Hat2Right)
+ {
+ int hat = (controllerInputId - ControllerInputId.Hat0Up) / 4;
+
+ int baseHatId = (int)ControllerInputId.Hat0Up + (hat * 4);
+
+ JoystickHatState hatState = joystickState.GetHat((JoystickHat)hat);
+
+ if (hatState.IsUp && ((int)controllerInputId % baseHatId == 0)) return true;
+ if (hatState.IsDown && ((int)controllerInputId % baseHatId == 1)) return true;
+ if (hatState.IsLeft && ((int)controllerInputId % baseHatId == 2)) return true;
+ if (hatState.IsRight && ((int)controllerInputId % baseHatId == 3)) return true;
+ }
+
+ return false;
+ }
+
+ public (short, short) GetLeftStick()
+ {
+ if (!IsEnabled())
+ {
+ return (0, 0);
+ }
+
+ return GetStick(_config.LeftJoycon.StickX, _config.LeftJoycon.StickY, _config.DeadzoneLeft);
+ }
+
+ public (short, short) GetRightStick()
+ {
+ if (!IsEnabled())
+ {
+ return (0, 0);
+ }
+
+ return GetStick(_config.RightJoycon.StickX, _config.RightJoycon.StickY, _config.DeadzoneRight);
+ }
+
+ private (short, short) GetStick(ControllerInputId stickXInputId, ControllerInputId stickYInputId, float deadzone)
+ {
+ if (stickXInputId < ControllerInputId.Axis0 || stickXInputId > ControllerInputId.Axis5 ||
+ stickYInputId < ControllerInputId.Axis0 || stickYInputId > ControllerInputId.Axis5)
+ {
+ return (0, 0);
+ }
+
+ JoystickState jsState = Joystick.GetState(_config.Index);
+
+ int xAxis = stickXInputId - ControllerInputId.Axis0;
+ int yAxis = stickYInputId - ControllerInputId.Axis0;
+
+ float xValue = jsState.GetAxis(xAxis);
+ float yValue = -jsState.GetAxis(yAxis); // Invert Y-axis
+
+ return ApplyDeadzone(new Vector2(xValue, yValue), deadzone);
+ }
+
+ private (short, short) ApplyDeadzone(Vector2 axis, float deadzone)
+ {
+ return (ClampAxis(MathF.Abs(axis.X) > deadzone ? axis.X : 0f),
+ ClampAxis(MathF.Abs(axis.Y) > deadzone ? axis.Y : 0f));
+ }
+
+ private static short ClampAxis(float value)
+ {
+ if (value <= -short.MaxValue)
+ {
+ return -short.MaxValue;
+ }
+ else
+ {
+ return (short)(value * short.MaxValue);
+ }
+ }
+ }
+}
diff --git a/Ryujinx/Ui/KeyboardControls.cs b/Ryujinx/Ui/KeyboardController.cs
similarity index 74%
rename from Ryujinx/Ui/KeyboardControls.cs
rename to Ryujinx/Ui/KeyboardController.cs
index 1f19fe32..ed4a4b3f 100644
--- a/Ryujinx/Ui/KeyboardControls.cs
+++ b/Ryujinx/Ui/KeyboardController.cs
@@ -1,7 +1,7 @@
using System;
using OpenTK.Input;
+using Ryujinx.Common.Configuration.Hid;
using Ryujinx.HLE.HOS.Services.Hid;
-using Ryujinx.UI.Input;
namespace Ryujinx.Ui
{
@@ -11,64 +11,85 @@ namespace Ryujinx.Ui
ToggleVSync = 1 << 0,
}
- public static class KeyboardControls
+ public class KeyboardController
{
- public static ControllerKeys GetButtons(NpadKeyboard npad, KeyboardState keyboard)
+ private readonly KeyboardConfig _config;
+
+ // NOTE: This should be initialized AFTER GTK for compat reasons with OpenTK SDL2 backend and GTK on Linux.
+ // BODY: Usage of Joystick.GetState must be defer to after GTK full initialization. Otherwise, GTK will segfault because SDL2 was already init *sighs*
+ public KeyboardController(KeyboardConfig config)
{
+ _config = config;
+ }
+
+ public ControllerKeys GetButtons()
+ {
+ KeyboardState keyboard = Keyboard.GetState(_config.Index);
+
ControllerKeys buttons = 0;
- if (keyboard[(Key)npad.LeftJoycon.StickButton]) buttons |= ControllerKeys.LStick;
- if (keyboard[(Key)npad.LeftJoycon.DPadUp]) buttons |= ControllerKeys.DpadUp;
- if (keyboard[(Key)npad.LeftJoycon.DPadDown]) buttons |= ControllerKeys.DpadDown;
- if (keyboard[(Key)npad.LeftJoycon.DPadLeft]) buttons |= ControllerKeys.DpadLeft;
- if (keyboard[(Key)npad.LeftJoycon.DPadRight]) buttons |= ControllerKeys.DpadRight;
- if (keyboard[(Key)npad.LeftJoycon.ButtonMinus]) buttons |= ControllerKeys.Minus;
- if (keyboard[(Key)npad.LeftJoycon.ButtonL]) buttons |= ControllerKeys.L | ControllerKeys.Sl;
- if (keyboard[(Key)npad.LeftJoycon.ButtonZl]) buttons |= ControllerKeys.Zl;
+ if (keyboard[(Key)_config.LeftJoycon.StickButton]) buttons |= ControllerKeys.LStick;
+ if (keyboard[(Key)_config.LeftJoycon.DPadUp]) buttons |= ControllerKeys.DpadUp;
+ if (keyboard[(Key)_config.LeftJoycon.DPadDown]) buttons |= ControllerKeys.DpadDown;
+ if (keyboard[(Key)_config.LeftJoycon.DPadLeft]) buttons |= ControllerKeys.DpadLeft;
+ if (keyboard[(Key)_config.LeftJoycon.DPadRight]) buttons |= ControllerKeys.DpadRight;
+ if (keyboard[(Key)_config.LeftJoycon.ButtonMinus]) buttons |= ControllerKeys.Minus;
+ if (keyboard[(Key)_config.LeftJoycon.ButtonL]) buttons |= ControllerKeys.L;
+ if (keyboard[(Key)_config.LeftJoycon.ButtonZl]) buttons |= ControllerKeys.Zl;
+ if (keyboard[(Key)_config.LeftJoycon.ButtonSl]) buttons |= ControllerKeys.SlLeft;
+ if (keyboard[(Key)_config.LeftJoycon.ButtonSr]) buttons |= ControllerKeys.SlRight;
- if (keyboard[(Key)npad.RightJoycon.StickButton]) buttons |= ControllerKeys.RStick;
- if (keyboard[(Key)npad.RightJoycon.ButtonA]) buttons |= ControllerKeys.A;
- if (keyboard[(Key)npad.RightJoycon.ButtonB]) buttons |= ControllerKeys.B;
- if (keyboard[(Key)npad.RightJoycon.ButtonX]) buttons |= ControllerKeys.X;
- if (keyboard[(Key)npad.RightJoycon.ButtonY]) buttons |= ControllerKeys.Y;
- if (keyboard[(Key)npad.RightJoycon.ButtonPlus]) buttons |= ControllerKeys.Plus;
- if (keyboard[(Key)npad.RightJoycon.ButtonR]) buttons |= ControllerKeys.R | ControllerKeys.Sr;
- if (keyboard[(Key)npad.RightJoycon.ButtonZr]) buttons |= ControllerKeys.Zr;
+ if (keyboard[(Key)_config.RightJoycon.StickButton]) buttons |= ControllerKeys.RStick;
+ if (keyboard[(Key)_config.RightJoycon.ButtonA]) buttons |= ControllerKeys.A;
+ if (keyboard[(Key)_config.RightJoycon.ButtonB]) buttons |= ControllerKeys.B;
+ if (keyboard[(Key)_config.RightJoycon.ButtonX]) buttons |= ControllerKeys.X;
+ if (keyboard[(Key)_config.RightJoycon.ButtonY]) buttons |= ControllerKeys.Y;
+ if (keyboard[(Key)_config.RightJoycon.ButtonPlus]) buttons |= ControllerKeys.Plus;
+ if (keyboard[(Key)_config.RightJoycon.ButtonR]) buttons |= ControllerKeys.R;
+ if (keyboard[(Key)_config.RightJoycon.ButtonZr]) buttons |= ControllerKeys.Zr;
+ if (keyboard[(Key)_config.RightJoycon.ButtonSl]) buttons |= ControllerKeys.SrLeft;
+ if (keyboard[(Key)_config.RightJoycon.ButtonSr]) buttons |= ControllerKeys.SrRight;
return buttons;
}
- public static (short, short) GetLeftStick(NpadKeyboard npad, KeyboardState keyboard)
+ public (short, short) GetLeftStick()
{
+ KeyboardState keyboard = Keyboard.GetState(_config.Index);
+
short dx = 0;
short dy = 0;
- if (keyboard[(Key)npad.LeftJoycon.StickUp]) dy = short.MaxValue;
- if (keyboard[(Key)npad.LeftJoycon.StickDown]) dy = -short.MaxValue;
- if (keyboard[(Key)npad.LeftJoycon.StickLeft]) dx = -short.MaxValue;
- if (keyboard[(Key)npad.LeftJoycon.StickRight]) dx = short.MaxValue;
+ if (keyboard[(Key)_config.LeftJoycon.StickUp]) dy = short.MaxValue;
+ if (keyboard[(Key)_config.LeftJoycon.StickDown]) dy = -short.MaxValue;
+ if (keyboard[(Key)_config.LeftJoycon.StickLeft]) dx = -short.MaxValue;
+ if (keyboard[(Key)_config.LeftJoycon.StickRight]) dx = short.MaxValue;
return (dx, dy);
}
- public static (short, short) GetRightStick(NpadKeyboard npad, KeyboardState keyboard)
+ public (short, short) GetRightStick()
{
+ KeyboardState keyboard = Keyboard.GetState(_config.Index);
+
short dx = 0;
short dy = 0;
- if (keyboard[(Key)npad.RightJoycon.StickUp]) dy = short.MaxValue;
- if (keyboard[(Key)npad.RightJoycon.StickDown]) dy = -short.MaxValue;
- if (keyboard[(Key)npad.RightJoycon.StickLeft]) dx = -short.MaxValue;
- if (keyboard[(Key)npad.RightJoycon.StickRight]) dx = short.MaxValue;
+ if (keyboard[(Key)_config.RightJoycon.StickUp]) dy = short.MaxValue;
+ if (keyboard[(Key)_config.RightJoycon.StickDown]) dy = -short.MaxValue;
+ if (keyboard[(Key)_config.RightJoycon.StickLeft]) dx = -short.MaxValue;
+ if (keyboard[(Key)_config.RightJoycon.StickRight]) dx = short.MaxValue;
return (dx, dy);
}
- public static HotkeyButtons GetHotkeyButtons(NpadKeyboard npad, KeyboardState keyboard)
+ public HotkeyButtons GetHotkeyButtons()
{
+ KeyboardState keyboard = Keyboard.GetState(_config.Index);
+
HotkeyButtons buttons = 0;
- if (keyboard[(Key)npad.Hotkeys.ToggleVsync]) buttons |= HotkeyButtons.ToggleVSync;
+ if (keyboard[(Key)_config.Hotkeys.ToggleVsync]) buttons |= HotkeyButtons.ToggleVSync;
return buttons;
}
@@ -223,12 +244,14 @@ namespace Ryujinx.Ui
new KeyMappingEntry { TargetKey = Key.NumLock, Target = 10 },
};
- public static KeyboardInput GetKeysDown(NpadKeyboard npad, KeyboardState keyboard)
+ public KeyboardInput GetKeysDown()
{
+ KeyboardState keyboard = Keyboard.GetState(_config.Index);
+
KeyboardInput hidKeyboard = new KeyboardInput
{
- Modifier = 0,
- Keys = new int[0x8]
+ Modifier = 0,
+ Keys = new int[0x8]
};
foreach (KeyMappingEntry entry in KeyMapping)
diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs
index eb8077e5..756ca231 100644
--- a/Ryujinx/Ui/MainWindow.cs
+++ b/Ryujinx/Ui/MainWindow.cs
@@ -13,6 +13,7 @@ using Ryujinx.HLE.HOS.Services.Hid;
using System;
using System.Diagnostics;
using System.IO;
+using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
@@ -28,7 +29,7 @@ namespace Ryujinx.Ui
private static HLE.Switch _emulationContext;
- private static GLRenderer _gLWidget;
+ private static GlRenderer _glWidget;
private static AutoResetEvent _deviceExitStatus = new AutoResetEvent(false);
@@ -37,40 +38,38 @@ namespace Ryujinx.Ui
private static bool _updatingGameTable;
private static bool _gameLoaded;
private static bool _ending;
-#pragma warning disable CS0169
- private static bool _debuggerOpened;
-#pragma warning restore CS0169
#pragma warning disable CS0169
- private static Ryujinx.Debugger.Debugger _debugger;
+ private static bool _debuggerOpened;
+
+ private static Debugger.Debugger _debugger;
#pragma warning restore CS0169
#pragma warning disable CS0169, CS0649, IDE0044
- [GUI] Window _mainWin;
[GUI] MenuBar _menuBar;
[GUI] Box _footerBox;
- [GUI] MenuItem _fullScreen;
[GUI] Box _statusBar;
[GUI] MenuItem _stopEmulation;
+ [GUI] MenuItem _fullScreen;
[GUI] CheckMenuItem _favToggle;
- [GUI] MenuItem _firmwareInstallFile;
[GUI] MenuItem _firmwareInstallDirectory;
+ [GUI] MenuItem _firmwareInstallFile;
[GUI] Label _hostStatus;
[GUI] MenuItem _openDebugger;
[GUI] CheckMenuItem _iconToggle;
- [GUI] CheckMenuItem _appToggle;
[GUI] CheckMenuItem _developerToggle;
- [GUI] CheckMenuItem _versionToggle;
+ [GUI] CheckMenuItem _appToggle;
[GUI] CheckMenuItem _timePlayedToggle;
+ [GUI] CheckMenuItem _versionToggle;
[GUI] CheckMenuItem _lastPlayedToggle;
[GUI] CheckMenuItem _fileExtToggle;
- [GUI] CheckMenuItem _fileSizeToggle;
[GUI] CheckMenuItem _pathToggle;
+ [GUI] CheckMenuItem _fileSizeToggle;
[GUI] Label _gameStatus;
[GUI] TreeView _gameTable;
- [GUI] ScrolledWindow _gameTableWindow;
[GUI] TreeSelection _gameTableSelection;
+ [GUI] ScrolledWindow _gameTableWindow;
[GUI] Label _gpuName;
[GUI] Label _progressLabel;
[GUI] Label _firmwareVersionLabel;
@@ -96,9 +95,12 @@ namespace Ryujinx.Ui
this.DeleteEvent += Window_Close;
_fullScreen.Activated += FullScreen_Toggled;
+ this.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
+ this.Title = $"Ryujinx {Program.Version}";
+
ApplicationLibrary.ApplicationAdded += Application_Added;
ApplicationLibrary.ApplicationCountUpdated += ApplicationCount_Updated;
- GLRenderer.StatusUpdatedEvent += Update_StatusBar;
+ GlRenderer.StatusUpdatedEvent += Update_StatusBar;
_gameTable.ButtonReleaseEvent += Row_Clicked;
@@ -127,8 +129,6 @@ namespace Ryujinx.Ui
ApplyTheme();
- _mainWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
- _mainWin.Title = $"Ryujinx {Program.Version}";
_stopEmulation.Sensitive = false;
if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true;
@@ -302,7 +302,7 @@ namespace Ryujinx.Ui
{
if (_gameLoaded)
{
- GtkDialog.CreateDialog("Ryujinx", "A game has already been loaded", "Please close it first and try again.");
+ GtkDialog.CreateInfoDialog("Ryujinx", "A game has already been loaded", "Please close it first and try again.");
}
else
{
@@ -415,7 +415,7 @@ namespace Ryujinx.Ui
#if MACOS_BUILD
CreateGameWindow(device);
#else
- var windowThread = new Thread(() =>
+ Thread windowThread = new Thread(() =>
{
CreateGameWindow(device);
})
@@ -443,35 +443,29 @@ namespace Ryujinx.Ui
private void CreateGameWindow(HLE.Switch device)
{
- ControllerType type = (Ryujinx.Configuration.Hid.ControllerType)ConfigurationState.Instance.Hid.ControllerType switch {
- Ryujinx.Configuration.Hid.ControllerType.ProController => ControllerType.ProController,
- Ryujinx.Configuration.Hid.ControllerType.Handheld => ControllerType.Handheld,
- Ryujinx.Configuration.Hid.ControllerType.NpadPair => ControllerType.JoyconPair,
- Ryujinx.Configuration.Hid.ControllerType.NpadLeft => ControllerType.JoyconLeft,
- Ryujinx.Configuration.Hid.ControllerType.NpadRight => ControllerType.JoyconRight,
- _ => ControllerType.Handheld
- };
-
- device.Hid.Npads.AddControllers(new ControllerConfig {
- Player = PlayerIndex.Player1,
- Type = type
- });
+ device.Hid.Npads.AddControllers(ConfigurationState.Instance.Hid.InputConfig.Value.Select(inputConfig =>
+ new HLE.HOS.Services.Hid.ControllerConfig
+ {
+ Player = (PlayerIndex)inputConfig.PlayerIndex,
+ Type = (ControllerType)inputConfig.ControllerType
+ }
+ ).ToArray());
- _gLWidget = new GLRenderer(_emulationContext);
+ _glWidget = new GlRenderer(_emulationContext);
Application.Invoke(delegate
{
_viewBox.Remove(_gameTableWindow);
- _gLWidget.Expand = true;
- _viewBox.Child = _gLWidget;
+ _glWidget.Expand = true;
+ _viewBox.Child = _glWidget;
- _gLWidget.ShowAll();
+ _glWidget.ShowAll();
EditFooterForGameRender();
});
- _gLWidget.WaitEvent.WaitOne();
+ _glWidget.WaitEvent.WaitOne();
- _gLWidget.Start();
+ _glWidget.Start();
device.Dispose();
_deviceExitStatus.Set();
@@ -479,15 +473,15 @@ namespace Ryujinx.Ui
// NOTE: Everything that is here will not be executed when you close the UI.
Application.Invoke(delegate
{
- _viewBox.Remove(_gLWidget);
- _gLWidget.Exit();
+ _viewBox.Remove(_glWidget);
+ _glWidget.Exit();
- if(_gLWidget.Window != this.Window && _gLWidget.Window != null)
+ if(_glWidget.Window != this.Window && _glWidget.Window != null)
{
- _gLWidget.Window.Dispose();
+ _glWidget.Window.Dispose();
}
- _gLWidget.Dispose();
+ _glWidget.Dispose();
_viewBox.Add(_gameTableWindow);
@@ -497,7 +491,7 @@ namespace Ryujinx.Ui
_emulationContext = null;
_gameLoaded = false;
- _gLWidget = null;
+ _glWidget = null;
DiscordIntegrationModule.SwitchToMainMenu();
@@ -528,7 +522,7 @@ namespace Ryujinx.Ui
public void ToggleExtraWidgets(bool show)
{
- if (_gLWidget != null)
+ if (_glWidget != null)
{
if (show)
{
@@ -562,6 +556,11 @@ namespace Ryujinx.Ui
}
}
+ public static void SaveConfig()
+ {
+ ConfigurationState.Instance.ToFileFormat().SaveConfig(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ }
+
private void End(HLE.Switch device)
{
@@ -580,10 +579,10 @@ namespace Ryujinx.Ui
{
UpdateGameMetadata(device.System.TitleIdText);
- if (_gLWidget != null)
+ if (_glWidget != null)
{
// We tell the widget that we are exiting
- _gLWidget.Exit();
+ _glWidget.Exit();
// Wait for the other thread to dispose the HLE context before exiting.
_deviceExitStatus.WaitOne();
@@ -773,7 +772,7 @@ namespace Ryujinx.Ui
private void StopEmulation_Pressed(object sender, EventArgs args)
{
- _gLWidget?.Exit();
+ _glWidget?.Exit();
}
private void Installer_File_Pressed(object o, EventArgs args)
@@ -808,7 +807,7 @@ namespace Ryujinx.Ui
private void RefreshFirmwareLabel()
{
- var currentFirmware = _contentManager.GetCurrentFirmwareVersion();
+ SystemVersion currentFirmware = _contentManager.GetCurrentFirmwareVersion();
GLib.Idle.Add(new GLib.IdleHandler(() =>
{
@@ -830,7 +829,7 @@ namespace Ryujinx.Ui
fileChooser.Dispose();
- var firmwareVersion = _contentManager.VerifyFirmwarePackage(filename);
+ SystemVersion firmwareVersion = _contentManager.VerifyFirmwarePackage(filename);
if (firmwareVersion == null)
{
@@ -849,7 +848,7 @@ namespace Ryujinx.Ui
return;
}
- var currentVersion = _contentManager.GetCurrentFirmwareVersion();
+ SystemVersion currentVersion = _contentManager.GetCurrentFirmwareVersion();
string dialogMessage = $"System version {firmwareVersion.VersionString} will be installed.";
@@ -989,7 +988,7 @@ namespace Ryujinx.Ui
private void Settings_Pressed(object sender, EventArgs args)
{
- SwitchSettings settingsWin = new SwitchSettings(_virtualFileSystem, _contentManager);
+ SettingsWindow settingsWin = new SettingsWindow(_virtualFileSystem, _contentManager);
settingsWin.Show();
}
@@ -1205,10 +1204,5 @@ namespace Ryujinx.Ui
return 0;
}
}
-
- public static void SaveConfig()
- {
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- }
}
}
diff --git a/Ryujinx/Ui/NpadController.cs b/Ryujinx/Ui/NpadController.cs
deleted file mode 100644
index b92f687c..00000000
--- a/Ryujinx/Ui/NpadController.cs
+++ /dev/null
@@ -1,143 +0,0 @@
-using OpenTK;
-using OpenTK.Input;
-using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.HLE.HOS.Services.Hid;
-using System;
-
-using InnerNpadController = Ryujinx.Common.Configuration.Hid.NpadController;
-
-namespace Ryujinx.Ui.Input
-{
- public class NpadController
- {
- private InnerNpadController _inner;
-
- // NOTE: This should be initialized AFTER GTK for compat reasons with OpenTK SDL2 backend and GTK on Linux.
- // BODY: Usage of Joystick.GetState must be defer to after GTK full initialization. Otherwise, GTK will segfault because SDL2 was already init *sighs*
- public NpadController(InnerNpadController inner)
- {
- _inner = inner;
- }
-
- private bool IsEnabled()
- {
- return _inner.Enabled && Joystick.GetState(_inner.Index).IsConnected;
- }
-
- public ControllerKeys GetButtons()
- {
- if (!IsEnabled())
- {
- return 0;
- }
-
- JoystickState joystickState = Joystick.GetState(_inner.Index);
-
- ControllerKeys buttons = 0;
-
- if (IsActivated(joystickState, _inner.LeftJoycon.DPadUp)) buttons |= ControllerKeys.DpadUp;
- if (IsActivated(joystickState, _inner.LeftJoycon.DPadDown)) buttons |= ControllerKeys.DpadDown;
- if (IsActivated(joystickState, _inner.LeftJoycon.DPadLeft)) buttons |= ControllerKeys.DpadLeft;
- if (IsActivated(joystickState, _inner.LeftJoycon.DPadRight)) buttons |= ControllerKeys.DpadRight;
- if (IsActivated(joystickState, _inner.LeftJoycon.StickButton)) buttons |= ControllerKeys.LStick;
- if (IsActivated(joystickState, _inner.LeftJoycon.ButtonMinus)) buttons |= ControllerKeys.Minus;
- if (IsActivated(joystickState, _inner.LeftJoycon.ButtonL)) buttons |= ControllerKeys.L | ControllerKeys.Sl;
- if (IsActivated(joystickState, _inner.LeftJoycon.ButtonZl)) buttons |= ControllerKeys.Zl;
-
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonA)) buttons |= ControllerKeys.A;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonB)) buttons |= ControllerKeys.B;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonX)) buttons |= ControllerKeys.X;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonY)) buttons |= ControllerKeys.Y;
- if (IsActivated(joystickState, _inner.RightJoycon.StickButton)) buttons |= ControllerKeys.RStick;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonPlus)) buttons |= ControllerKeys.Plus;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonR)) buttons |= ControllerKeys.R | ControllerKeys.Sr;
- if (IsActivated(joystickState, _inner.RightJoycon.ButtonZr)) buttons |= ControllerKeys.Zr;
-
- return buttons;
- }
-
- private bool IsActivated(JoystickState joystickState, ControllerInputId controllerInputId)
- {
- if (controllerInputId <= ControllerInputId.Button20)
- {
- return joystickState.IsButtonDown((int)controllerInputId);
- }
- else if (controllerInputId <= ControllerInputId.Axis5)
- {
- int axis = controllerInputId - ControllerInputId.Axis0;
-
- return joystickState.GetAxis(axis) > _inner.TriggerThreshold;
- }
- else if (controllerInputId <= ControllerInputId.Hat2Right)
- {
- int hat = (controllerInputId - ControllerInputId.Hat0Up) / 4;
-
- int baseHatId = (int)ControllerInputId.Hat0Up + (hat * 4);
-
- JoystickHatState hatState = joystickState.GetHat((JoystickHat)hat);
-
- if (hatState.IsUp && ((int)controllerInputId % baseHatId == 0)) return true;
- if (hatState.IsDown && ((int)controllerInputId % baseHatId == 1)) return true;
- if (hatState.IsLeft && ((int)controllerInputId % baseHatId == 2)) return true;
- if (hatState.IsRight && ((int)controllerInputId % baseHatId == 3)) return true;
- }
-
- return false;
- }
-
- public (short, short) GetLeftStick()
- {
- if (!IsEnabled())
- {
- return (0, 0);
- }
-
- return GetStick(_inner.LeftJoycon.Stick);
- }
-
- public (short, short) GetRightStick()
- {
- if (!IsEnabled())
- {
- return (0, 0);
- }
-
- return GetStick(_inner.RightJoycon.Stick);
- }
-
- private (short, short) GetStick(ControllerInputId stickInputId)
- {
- if (stickInputId < ControllerInputId.Axis0 || stickInputId > ControllerInputId.Axis5)
- {
- return (0, 0);
- }
-
- JoystickState jsState = Joystick.GetState(_inner.Index);
-
- int xAxis = stickInputId - ControllerInputId.Axis0;
-
- float xValue = jsState.GetAxis(xAxis);
- float yValue = 0 - jsState.GetAxis(xAxis + 1); // Invert Y-axis
-
- return ApplyDeadzone(new Vector2(xValue, yValue));
- }
-
- private (short, short) ApplyDeadzone(Vector2 axis)
- {
- return (ClampAxis(MathF.Abs(axis.X) > _inner.Deadzone ? axis.X : 0f),
- ClampAxis(MathF.Abs(axis.Y) > _inner.Deadzone ? axis.Y : 0f));
- }
-
- private static short ClampAxis(float value)
- {
- if (value <= -short.MaxValue)
- {
- return -short.MaxValue;
- }
- else
- {
- return (short)(value * short.MaxValue);
- }
- }
- }
-}
diff --git a/Ryujinx/Ui/ProfileDialog.cs b/Ryujinx/Ui/ProfileDialog.cs
new file mode 100644
index 00000000..2b26cbef
--- /dev/null
+++ b/Ryujinx/Ui/ProfileDialog.cs
@@ -0,0 +1,58 @@
+using Gtk;
+using System;
+using System.Reflection;
+
+using GUI = Gtk.Builder.ObjectAttribute;
+
+namespace Ryujinx.Ui
+{
+ public class ProfileDialog : Dialog
+ {
+ public string FileName { get; private set; }
+
+#pragma warning disable CS0649, IDE0044
+ [GUI] Entry _profileEntry;
+ [GUI] Label _errorMessage;
+#pragma warning restore CS0649, IDE0044
+
+ public ProfileDialog() : this(new Builder("Ryujinx.Ui.ProfileDialog.glade")) { }
+
+ private ProfileDialog(Builder builder) : base(builder.GetObject("_profileDialog").Handle)
+ {
+ builder.Autoconnect(this);
+
+ Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
+ }
+
+ private void OkToggle_Activated(object sender, EventArgs args)
+ {
+ ((ToggleButton)sender).SetStateFlags(0, true);
+
+ bool validFileName = true;
+
+ foreach (char invalidChar in System.IO.Path.GetInvalidFileNameChars())
+ {
+ if (_profileEntry.Text.Contains(invalidChar))
+ {
+ validFileName = false;
+ }
+ }
+
+ if (validFileName && !string.IsNullOrEmpty(_profileEntry.Text))
+ {
+ FileName = $"{_profileEntry.Text}.json";
+
+ Respond(ResponseType.Ok);
+ }
+ else
+ {
+ _errorMessage.Text = "The file name contains invalid characters. Please try again.";
+ }
+ }
+
+ private void CancelToggle_Activated(object sender, EventArgs args)
+ {
+ Respond(ResponseType.Cancel);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx/Ui/ProfileDialog.glade b/Ryujinx/Ui/ProfileDialog.glade
new file mode 100644
index 00000000..adaf6608
--- /dev/null
+++ b/Ryujinx/Ui/ProfileDialog.glade
@@ -0,0 +1,124 @@
+
+
+
+
+
+ False
+ Ryujinx - Profile Dialog
+ True
+ center
+ 400
+ dialog
+
+
+
+
+
+ False
+ vertical
+ 2
+
+
+ False
+ end
+
+
+ OK
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ Cancel
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 5
+ 1
+
+
+
+
+ False
+ False
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 10
+ 10
+ 20
+ 10
+ Enter a name for the new profile:
+
+
+ True
+ True
+ 0
+
+
+
+
+ True
+ True
+ 20
+ 20
+ 20
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ False
+ start
+ 20
+ 10
+ 10
+ 10
+
+
+
+
+
+ False
+ True
+ 2
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+
+
diff --git a/Ryujinx/Ui/SettingsWindow.cs b/Ryujinx/Ui/SettingsWindow.cs
new file mode 100644
index 00000000..1b24e72b
--- /dev/null
+++ b/Ryujinx/Ui/SettingsWindow.cs
@@ -0,0 +1,409 @@
+using Gtk;
+using Ryujinx.Configuration;
+using Ryujinx.Configuration.System;
+using Ryujinx.HLE.HOS.Services.Time.TimeZone;
+using Ryujinx.HLE.FileSystem;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using Ryujinx.Common.Configuration.Hid;
+using GUI = Gtk.Builder.ObjectAttribute;
+
+namespace Ryujinx.Ui
+{
+ public class SettingsWindow : Window
+ {
+ private static ListStore _gameDirsBoxStore;
+ private static VirtualFileSystem _virtualFileSystem;
+
+ private long _systemTimeOffset;
+
+#pragma warning disable CS0649, IDE0044
+ [GUI] CheckButton _errorLogToggle;
+ [GUI] CheckButton _warningLogToggle;
+ [GUI] CheckButton _infoLogToggle;
+ [GUI] CheckButton _stubLogToggle;
+ [GUI] CheckButton _debugLogToggle;
+ [GUI] CheckButton _fileLogToggle;
+ [GUI] CheckButton _guestLogToggle;
+ [GUI] CheckButton _fsAccessLogToggle;
+ [GUI] Adjustment _fsLogSpinAdjustment;
+ [GUI] CheckButton _dockedModeToggle;
+ [GUI] CheckButton _discordToggle;
+ [GUI] CheckButton _vSyncToggle;
+ [GUI] CheckButton _multiSchedToggle;
+ [GUI] CheckButton _fsicToggle;
+ [GUI] CheckButton _ignoreToggle;
+ [GUI] CheckButton _directKeyboardAccess;
+ [GUI] ComboBoxText _systemLanguageSelect;
+ [GUI] ComboBoxText _systemRegionSelect;
+ [GUI] ComboBoxText _systemTimeZoneSelect;
+ [GUI] SpinButton _systemTimeYearSpin;
+ [GUI] SpinButton _systemTimeMonthSpin;
+ [GUI] SpinButton _systemTimeDaySpin;
+ [GUI] SpinButton _systemTimeHourSpin;
+ [GUI] SpinButton _systemTimeMinuteSpin;
+ [GUI] Adjustment _systemTimeYearSpinAdjustment;
+ [GUI] Adjustment _systemTimeMonthSpinAdjustment;
+ [GUI] Adjustment _systemTimeDaySpinAdjustment;
+ [GUI] Adjustment _systemTimeHourSpinAdjustment;
+ [GUI] Adjustment _systemTimeMinuteSpinAdjustment;
+ [GUI] CheckButton _custThemeToggle;
+ [GUI] Entry _custThemePath;
+ [GUI] ToggleButton _browseThemePath;
+ [GUI] Label _custThemePathLabel;
+ [GUI] TreeView _gameDirsBox;
+ [GUI] Entry _addGameDirBox;
+ [GUI] Entry _graphicsShadersDumpPath;
+ [GUI] ComboBoxText _anisotropy;
+ [GUI] ToggleButton _configureController1;
+ [GUI] ToggleButton _configureController2;
+ [GUI] ToggleButton _configureController3;
+ [GUI] ToggleButton _configureController4;
+ [GUI] ToggleButton _configureController5;
+ [GUI] ToggleButton _configureController6;
+ [GUI] ToggleButton _configureController7;
+ [GUI] ToggleButton _configureController8;
+ [GUI] ToggleButton _configureControllerH;
+#pragma warning restore CS0649, IDE0044
+
+ public SettingsWindow(VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : this(new Builder("Ryujinx.Ui.SettingsWindow.glade"), virtualFileSystem, contentManager) { }
+
+ private SettingsWindow(Builder builder, VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
+ {
+ builder.Autoconnect(this);
+
+ this.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
+
+ _virtualFileSystem = virtualFileSystem;
+
+ //Bind Events
+ _configureController1.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player1);
+ _configureController2.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player2);
+ _configureController3.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player3);
+ _configureController4.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player4);
+ _configureController5.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player5);
+ _configureController6.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player6);
+ _configureController7.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player7);
+ _configureController8.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player8);
+ _configureControllerH.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Handheld);
+
+ //Setup Currents
+ if (ConfigurationState.Instance.Logger.EnableFileLog)
+ {
+ _fileLogToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Logger.EnableError)
+ {
+ _errorLogToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Logger.EnableWarn)
+ {
+ _warningLogToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Logger.EnableInfo)
+ {
+ _infoLogToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Logger.EnableStub)
+ {
+ _stubLogToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Logger.EnableDebug)
+ {
+ _debugLogToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Logger.EnableGuest)
+ {
+ _guestLogToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Logger.EnableFsAccessLog)
+ {
+ _fsAccessLogToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.System.EnableDockedMode)
+ {
+ _dockedModeToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.EnableDiscordIntegration)
+ {
+ _discordToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Graphics.EnableVsync)
+ {
+ _vSyncToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.System.EnableMulticoreScheduling)
+ {
+ _multiSchedToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.System.EnableFsIntegrityChecks)
+ {
+ _fsicToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.System.IgnoreMissingServices)
+ {
+ _ignoreToggle.Click();
+ }
+
+ if (ConfigurationState.Instance.Hid.EnableKeyboard)
+ {
+ _directKeyboardAccess.Click();
+ }
+
+ if (ConfigurationState.Instance.Ui.EnableCustomTheme)
+ {
+ _custThemeToggle.Click();
+ }
+
+ TimeZoneContentManager timeZoneContentManager = new TimeZoneContentManager();
+
+ timeZoneContentManager.InitializeInstance(virtualFileSystem, contentManager, LibHac.FsSystem.IntegrityCheckLevel.None);
+
+ List locationNames = timeZoneContentManager.LocationNameCache.ToList();
+
+ locationNames.Sort();
+
+ foreach (string locationName in locationNames)
+ {
+ _systemTimeZoneSelect.Append(locationName, locationName);
+ }
+
+ _systemLanguageSelect.SetActiveId(ConfigurationState.Instance.System.Language.Value.ToString());
+ _systemRegionSelect.SetActiveId(ConfigurationState.Instance.System.Region.Value.ToString());
+ _systemTimeZoneSelect.SetActiveId(timeZoneContentManager.SanityCheckDeviceLocationName());
+ _anisotropy.SetActiveId(ConfigurationState.Instance.Graphics.MaxAnisotropy.Value.ToString());
+
+ _custThemePath.Buffer.Text = ConfigurationState.Instance.Ui.CustomThemePath;
+ _graphicsShadersDumpPath.Buffer.Text = ConfigurationState.Instance.Graphics.ShadersDumpPath;
+ _fsLogSpinAdjustment.Value = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
+ _systemTimeOffset = ConfigurationState.Instance.System.SystemTimeOffset;
+
+ _gameDirsBox.AppendColumn("", new CellRendererText(), "text", 0);
+ _gameDirsBoxStore = new ListStore(typeof(string));
+ _gameDirsBox.Model = _gameDirsBoxStore;
+
+ foreach (string gameDir in ConfigurationState.Instance.Ui.GameDirs.Value)
+ {
+ _gameDirsBoxStore.AppendValues(gameDir);
+ }
+
+ if (_custThemeToggle.Active == false)
+ {
+ _custThemePath.Sensitive = false;
+ _custThemePathLabel.Sensitive = false;
+ _browseThemePath.Sensitive = false;
+ }
+
+ //Setup system time spinners
+ UpdateSystemTimeSpinners();
+ }
+
+ private void UpdateSystemTimeSpinners()
+ {
+ //Bind system time events
+ _systemTimeYearSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
+ _systemTimeMonthSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
+ _systemTimeDaySpin.ValueChanged -= SystemTimeSpin_ValueChanged;
+ _systemTimeHourSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
+ _systemTimeMinuteSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
+
+ //Apply actual system time + SystemTimeOffset to system time spin buttons
+ DateTime systemTime = DateTime.Now.AddSeconds(_systemTimeOffset);
+
+ _systemTimeYearSpinAdjustment.Value = systemTime.Year;
+ _systemTimeMonthSpinAdjustment.Value = systemTime.Month;
+ _systemTimeDaySpinAdjustment.Value = systemTime.Day;
+ _systemTimeHourSpinAdjustment.Value = systemTime.Hour;
+ _systemTimeMinuteSpinAdjustment.Value = systemTime.Minute;
+
+ //Format spin buttons text to include leading zeros
+ _systemTimeYearSpin.Text = systemTime.Year.ToString("0000");
+ _systemTimeMonthSpin.Text = systemTime.Month.ToString("00");
+ _systemTimeDaySpin.Text = systemTime.Day.ToString("00");
+ _systemTimeHourSpin.Text = systemTime.Hour.ToString("00");
+ _systemTimeMinuteSpin.Text = systemTime.Minute.ToString("00");
+
+ //Bind system time events
+ _systemTimeYearSpin.ValueChanged += SystemTimeSpin_ValueChanged;
+ _systemTimeMonthSpin.ValueChanged += SystemTimeSpin_ValueChanged;
+ _systemTimeDaySpin.ValueChanged += SystemTimeSpin_ValueChanged;
+ _systemTimeHourSpin.ValueChanged += SystemTimeSpin_ValueChanged;
+ _systemTimeMinuteSpin.ValueChanged += SystemTimeSpin_ValueChanged;
+ }
+
+ //Events
+ private void SystemTimeSpin_ValueChanged(Object sender, EventArgs e)
+ {
+ int year = _systemTimeYearSpin.ValueAsInt;
+ int month = _systemTimeMonthSpin.ValueAsInt;
+ int day = _systemTimeDaySpin.ValueAsInt;
+ int hour = _systemTimeHourSpin.ValueAsInt;
+ int minute = _systemTimeMinuteSpin.ValueAsInt;
+
+ if (!DateTime.TryParse(year + "-" + month + "-" + day + " " + hour + ":" + minute, out DateTime newTime))
+ {
+ UpdateSystemTimeSpinners();
+
+ return;
+ }
+
+ newTime = newTime.AddSeconds(DateTime.Now.Second).AddMilliseconds(DateTime.Now.Millisecond);
+
+ long systemTimeOffset = (long)Math.Ceiling((newTime - DateTime.Now).TotalMinutes) * 60L;
+
+ if (_systemTimeOffset != systemTimeOffset)
+ {
+ _systemTimeOffset = systemTimeOffset;
+ UpdateSystemTimeSpinners();
+ }
+ }
+
+ private void AddDir_Pressed(object sender, EventArgs args)
+ {
+ if (Directory.Exists(_addGameDirBox.Buffer.Text))
+ {
+ _gameDirsBoxStore.AppendValues(_addGameDirBox.Buffer.Text);
+ }
+ else
+ {
+ FileChooserDialog fileChooser = new FileChooserDialog("Choose the game directory to add to the list", this, FileChooserAction.SelectFolder, "Cancel", ResponseType.Cancel, "Add", ResponseType.Accept);
+
+ if (fileChooser.Run() == (int)ResponseType.Accept)
+ {
+ _gameDirsBoxStore.AppendValues(fileChooser.Filename);
+ }
+
+ fileChooser.Dispose();
+ }
+
+ _addGameDirBox.Buffer.Text = "";
+
+ ((ToggleButton)sender).SetStateFlags(0, true);
+ }
+
+ private void RemoveDir_Pressed(object sender, EventArgs args)
+ {
+ TreeSelection selection = _gameDirsBox.Selection;
+
+ if (selection.GetSelected(out TreeIter treeIter))
+ {
+ _gameDirsBoxStore.Remove(ref treeIter);
+ }
+
+ ((ToggleButton)sender).SetStateFlags(0, true);
+ }
+
+ private void CustThemeToggle_Activated(object sender, EventArgs args)
+ {
+ _custThemePath.Sensitive = _custThemeToggle.Active;
+ _custThemePathLabel.Sensitive = _custThemeToggle.Active;
+ _browseThemePath.Sensitive = _custThemeToggle.Active;
+ }
+
+ private void BrowseThemeDir_Pressed(object sender, EventArgs args)
+ {
+ FileChooserDialog fileChooser = new FileChooserDialog("Choose the theme to load", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Select", ResponseType.Accept);
+
+ fileChooser.Filter = new FileFilter();
+ fileChooser.Filter.AddPattern("*.css");
+
+ if (fileChooser.Run() == (int)ResponseType.Accept)
+ {
+ _custThemePath.Buffer.Text = fileChooser.Filename;
+ }
+
+ fileChooser.Dispose();
+
+ _browseThemePath.SetStateFlags(0, true);
+ }
+
+ private void OpenLogsFolder_Pressed(object sender, EventArgs args)
+ {
+ string logPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
+
+ DirectoryInfo directory = new DirectoryInfo(logPath);
+ directory.Create();
+
+ Process.Start(new ProcessStartInfo()
+ {
+ FileName = logPath,
+ UseShellExecute = true,
+ Verb = "open"
+ });
+ }
+
+ private void ConfigureController_Pressed(object sender, EventArgs args, PlayerIndex playerIndex)
+ {
+ ((ToggleButton)sender).SetStateFlags(0, true);
+
+ ControllerWindow controllerWin = new ControllerWindow(playerIndex, _virtualFileSystem);
+ controllerWin.Show();
+ }
+
+ private void SaveToggle_Activated(object sender, EventArgs args)
+ {
+ List gameDirs = new List();
+
+ _gameDirsBoxStore.GetIterFirst(out TreeIter treeIter);
+ for (int i = 0; i < _gameDirsBoxStore.IterNChildren(); i++)
+ {
+ gameDirs.Add((string)_gameDirsBoxStore.GetValue(treeIter, 0));
+
+ _gameDirsBoxStore.IterNext(ref treeIter);
+ }
+
+ ConfigurationState.Instance.Logger.EnableError.Value = _errorLogToggle.Active;
+ ConfigurationState.Instance.Logger.EnableWarn.Value = _warningLogToggle.Active;
+ ConfigurationState.Instance.Logger.EnableInfo.Value = _infoLogToggle.Active;
+ ConfigurationState.Instance.Logger.EnableStub.Value = _stubLogToggle.Active;
+ ConfigurationState.Instance.Logger.EnableDebug.Value = _debugLogToggle.Active;
+ ConfigurationState.Instance.Logger.EnableGuest.Value = _guestLogToggle.Active;
+ ConfigurationState.Instance.Logger.EnableFsAccessLog.Value = _fsAccessLogToggle.Active;
+ ConfigurationState.Instance.Logger.EnableFileLog.Value = _fileLogToggle.Active;
+ ConfigurationState.Instance.System.EnableDockedMode.Value = _dockedModeToggle.Active;
+ ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
+ ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
+ ConfigurationState.Instance.System.EnableMulticoreScheduling.Value = _multiSchedToggle.Active;
+ ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
+ ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active;
+ ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active;
+ ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
+ ConfigurationState.Instance.System.Language.Value = Enum.Parse(_systemLanguageSelect.ActiveId);
+ ConfigurationState.Instance.System.Region.Value = Enum.Parse(_systemRegionSelect.ActiveId);
+ ConfigurationState.Instance.System.TimeZone.Value = _systemTimeZoneSelect.ActiveId;
+ ConfigurationState.Instance.System.SystemTimeOffset.Value = _systemTimeOffset;
+ ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
+ ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;
+ ConfigurationState.Instance.Ui.GameDirs.Value = gameDirs;
+ ConfigurationState.Instance.System.FsGlobalAccessLogMode.Value = (int)_fsLogSpinAdjustment.Value;
+ ConfigurationState.Instance.Graphics.MaxAnisotropy.Value = float.Parse(_anisotropy.ActiveId);
+
+ MainWindow.SaveConfig();
+ MainWindow.ApplyTheme();
+ MainWindow.UpdateGameTable();
+ Dispose();
+ }
+
+ private void CloseToggle_Activated(object sender, EventArgs args)
+ {
+ Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx/Ui/SwitchSettings.glade b/Ryujinx/Ui/SettingsWindow.glade
similarity index 65%
rename from Ryujinx/Ui/SwitchSettings.glade
rename to Ryujinx/Ui/SettingsWindow.glade
index 7415e76e..ea662de0 100644
--- a/Ryujinx/Ui/SwitchSettings.glade
+++ b/Ryujinx/Ui/SettingsWindow.glade
@@ -7,95 +7,21 @@
1
10
-
- 2000
- 2060
- 1
- 10
-
-
- 1
- 12
- 1
- 5
-
-
- 1
- 31
- 1
- 5
-
-
- 0
- 23
- 1
- 5
-
-
- 0
- 59
- 1
- 5
-
-
+
False
Ryujinx - Settings
True
center
- 910
- 790
- dialog
+ 650
+ 520
-
+
+ True
False
vertical
- 2
-
-
- False
- 5
- 3
- 3
- end
-
-
- Save
- True
- True
- True
-
-
-
- False
- True
- 0
-
-
-
-
- Close
- True
- True
- True
-
-
-
- False
- True
- 5
- 1
-
-
-
-
- False
- False
- 0
-
-
True
@@ -142,303 +68,19 @@
-
+
True
False
+ 10
+ 10
vertical
-
-
- True
- False
-
-
- True
- False
- Change System Language
- end
- System Language:
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- Change System Language
- 5
-
- - American English
- - British English
- - Canadian French
- - Chinese
- - Dutch
- - French
- - German
- - Italian
- - Japanese
- - Korean
- - Latin American Spanish
- - Portuguese
- - Russian
- - Simplified Chinese
- - Spanish
- - Taiwanese
- - Traditional Chinese
-
-
-
- False
- True
- 1
-
-
-
-
- True
- False
- Change System Region
- end
- System Region:
-
-
- False
- True
- 5
- 2
-
-
-
-
- True
- False
- Change System Region
- 5
-
- - Japan
- - USA
- - Europe
- - Australia
- - China
- - Korea
- - Taiwan
-
-
-
- False
- True
- 3
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- vertical
-
-
- True
- False
-
-
- True
- False
- Change System TimeZone
- end
- System TimeZone:
-
-
- False
- True
- 1
-
-
-
-
- True
- False
- Change System TimeZone
- 5
-
-
- False
- True
- 2
-
-
-
-
- False
- True
- 0
-
-
-
-
- False
- True
- 1
-
-
-
-
- True
- False
-
-
- True
- False
- end
- System Time:
-
-
- False
- True
- 5
- 0
-
-
-
-
- True
- False
- 5
- vertical
- _systemTimeYearSpinAdjustment
- True
-
-
- False
- True
- 1
-
-
-
-
- True
- False
- end
- -
-
-
- False
- True
- 5
- 2
-
-
-
-
- True
- False
- 0
- vertical
- _systemTimeMonthSpinAdjustment
- True
-
-
- False
- True
- 3
-
-
-
-
- True
- False
- end
- -
-
-
- False
- True
- 5
- 4
-
-
-
-
- True
- False
- 0
- vertical
- _systemTimeDaySpinAdjustment
- True
-
-
- False
- True
- 5
-
-
-
-
- True
- False
- 25
- vertical
- _systemTimeHourSpinAdjustment
- True
-
-
- False
- True
- 6
-
-
-
-
- True
- False
- end
- :
-
-
- False
- True
- 5
- 7
-
-
-
-
- True
- False
- 0
- vertical
- _systemTimeMinuteSpinAdjustment
- True
-
-
- False
- True
- 8
-
-
-
-
- False
- True
- 2
-
-
Enable Discord Rich Presence
True
True
False
- Enables or disables Discord Rich Presense
+ Enables or disables Discord Rich Presence
start
True
@@ -446,7 +88,7 @@
False
True
5
- 3
+ 2
@@ -569,23 +211,6 @@
1
-
-
- Browse...
- 80
- True
- True
- True
- Browse for a game directory
- 5
-
-
-
- False
- True
- 2
-
-
Remove
@@ -775,6 +400,9 @@
True
False
+ 5
+ 10
+ 5
vertical
@@ -834,653 +462,553 @@
-
+
True
False
- 10
- 10
- 5
+ center
+ center
+ 20
True
False
vertical
-
+
True
False
-
-
- True
- False
- The primary controller's type
- center
- 5
- 5
- Controller Type:
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- The primary controller's type
- 5
- 0
-
- - Handheld
- - Pro Controller
- - Paired Joycons
- - Left Joycon
- - Right Joycon
-
-
-
- True
- True
- 1
-
-
+ 20
+ 20
+ Player 1
False
True
- 10
0
-
+
+ Configure
True
- False
- 2
- 5
-
-
- True
- False
- LStick Up
-
-
- 0
- 0
-
-
-
-
- True
- False
- LStick Down
-
-
- 0
- 1
-
-
-
-
- True
- False
- LStick Left
-
-
- 0
- 2
-
-
-
-
- True
- False
- LStick Right
-
-
- 0
- 3
-
-
-
-
- True
- False
- LStick Button
-
-
- 0
- 4
-
-
-
-
- True
- False
- Dpad Up
-
-
- 0
- 5
-
-
-
-
- True
- False
- Dpad Down
-
-
- 0
- 6
-
-
-
-
- True
- False
- Dpad Left
-
-
- 0
- 7
-
-
-
-
- True
- False
- Dpad Right
-
-
- 0
- 8
-
-
-
-
- True
- False
- -
-
-
- 0
- 9
-
-
-
-
- True
- False
- L
-
-
- 0
- 10
-
-
-
-
- True
- False
- ZL
-
-
- 0
- 11
-
-
-
-
- True
- False
- ZR
-
-
- 2
- 11
-
-
-
-
- True
- False
- R
-
-
- 2
- 10
-
-
-
-
- True
- False
- +
-
-
- 2
- 9
-
-
-
-
- True
- False
- Y
-
-
- 2
- 8
-
-
-
-
- True
- False
- X
-
-
- 2
- 7
-
-
-
-
- True
- False
- B
-
-
- 2
- 6
-
-
-
-
- True
- False
- A
-
-
- 2
- 5
-
-
-
-
- True
- False
- RStick Button
-
-
- 2
- 4
-
-
-
-
- True
- False
- RStick Right
-
-
- 2
- 3
-
-
-
-
- True
- False
- RStick Left
-
-
- 2
- 2
-
-
-
-
- True
- False
- RStick Down
-
-
- 2
- 1
-
-
-
-
- True
- False
- RStick Up
-
-
- 2
- 0
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 0
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 1
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 2
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 3
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 4
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 5
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 6
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 7
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 8
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 9
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 10
-
-
-
-
-
- True
- True
- True
-
-
- 1
- 11
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 0
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 1
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 2
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 3
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 4
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 5
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 6
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 7
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 8
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 9
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 10
-
-
-
-
-
- True
- True
- True
-
-
- 3
- 11
-
-
+ True
+ True
+ 20
+ 20
+ 20
+ 20
False
True
- 10
1
- False
- True
- 0
+ 0
+ 0
-
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ 20
+ Player 3
+
+
+ False
+ True
+ 0
+
+
+
+
+ Configure
+ True
+ True
+ True
+ 20
+ 20
+ 20
+ 20
+
+
+ False
+ True
+ 1
+
+
+
+
+ 4
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ 20
+ Player 2
+
+
+ False
+ True
+ 0
+
+
+
+
+ Configure
+ True
+ True
+ True
+ 20
+ 20
+ 20
+ 20
+
+
+ False
+ True
+ 1
+
+
+
+
+ 2
+ 0
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ 20
+ Handheld
+
+
+ False
+ True
+ 0
+
+
+
+
+ Configure
+ True
+ True
+ True
+ 20
+ 20
+ 20
+ 20
+
+
+ False
+ True
+ 1
+
+
+
+
+ 4
+ 4
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ 20
+ Player 6
+
+
+ False
+ True
+ 0
+
+
+
+
+ Configure
+ True
+ True
+ True
+ 20
+ 20
+ 20
+ 20
+
+
+ False
+ True
+ 1
+
+
+
+
+ 4
+ 2
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ 20
+ Player 5
+
+
+ False
+ True
+ 0
+
+
+
+
+ Configure
+ True
+ True
+ True
+ 20
+ 20
+ 20
+ 20
+
+
+ False
+ True
+ 1
+
+
+
+
+ 2
+ 2
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ 20
+ Player 7
+
+
+ False
+ True
+ 0
+
+
+
+
+ Configure
+ True
+ True
+ True
+ 20
+ 20
+ 20
+ 20
+
+
+ False
+ True
+ 1
+
+
+
+
+ 0
+ 4
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ 20
+ Player 4
+
+
+ False
+ True
+ 0
+
+
+
+
+ Configure
+ True
+ True
+ True
+ 20
+ 20
+ 20
+ 20
+
+
+ False
+ True
+ 1
+
+
+
+
+ 0
+ 2
+
+
+
+
+ True
+ False
+ vertical
+
+
+ True
+ False
+ 20
+ 20
+ Player 8
+
+
+ False
+ True
+ 0
+
+
+
+
+ Configure
+ True
+ True
+ True
+ 20
+ 20
+ 20
+ 20
+
+
+ False
+ True
+ 1
+
+
+
+
+ 2
+ 4
+
+
+
+
True
False
- True
- True
- 1
+ 1
+ 0
+
+
+
+
+ True
+ False
+
+
+ 3
+ 0
+
+
+
+
+ True
+ False
+
+
+ 3
+ 2
+
+
+
+
+ True
+ False
+
+
+ 3
+ 4
+
+
+
+
+ True
+ False
+
+
+ 1
+ 2
+
+
+
+
+ True
+ False
+
+
+ 1
+ 4
+
+
+
+
+ True
+ False
+
+
+ 1
+ 1
+
+
+
+
+ True
+ False
+
+
+ 1
+ 3
+
+
+
+
+ True
+ False
+
+
+ 3
+ 1
+
+
+
+
+ True
+ False
+
+
+ 3
+ 3
+
+
+
+
+ True
+ False
+
+
+ 0
+ 1
+
+
+
+
+ True
+ False
+
+
+ 2
+ 1
+
+
+
+
+ True
+ False
+
+
+ 4
+ 1
+
+
+
+
+ True
+ False
+
+
+ 0
+ 3
+
+
+
+
+ True
+ False
+
+
+ 2
+ 3
+
+
+
+
+ True
+ False
+
+
+ 4
+ 3
- False
+ True
True
2
@@ -1522,7 +1050,6 @@
True
False
start
- 5
5
Core
@@ -1542,6 +1069,299 @@
10
10
vertical
+
+
+ True
+ False
+
+
+ True
+ False
+ Change System Region
+ end
+ System Region:
+
+
+ False
+ True
+ 5
+ 2
+
+
+
+
+ True
+ False
+ Change System Region
+ 5
+
+ - Japan
+ - USA
+ - Europe
+ - Australia
+ - China
+ - Korea
+ - Taiwan
+
+
+
+ False
+ True
+ 3
+
+
+
+
+ False
+ True
+ 5
+ 0
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ Change System Language
+ end
+ System Language:
+
+
+ False
+ True
+ 5
+ 0
+
+
+
+
+ True
+ False
+ Change System Language
+
+ - American English
+ - British English
+ - Canadian French
+ - Chinese
+ - Dutch
+ - French
+ - German
+ - Italian
+ - Japanese
+ - Korean
+ - Latin American Spanish
+ - Portuguese
+ - Russian
+ - Simplified Chinese
+ - Spanish
+ - Taiwanese
+ - Traditional Chinese
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 5
+ 1
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ Change System TimeZone
+ end
+ System TimeZone:
+
+
+ False
+ True
+ 5
+ 1
+
+
+
+
+ True
+ False
+ Change System TimeZone
+ 5
+
+
+ False
+ True
+ 2
+
+
+
+
+ False
+ True
+ 5
+ 2
+
+
+
+
+ True
+ False
+
+
+ True
+ False
+ end
+ System Time:
+
+
+ False
+ True
+ 5
+ 0
+
+
+
+
+ True
+ True
+ 2000
+ vertical
+ _systemTimeYearSpinAdjustment
+ True
+ 2000
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ end
+ -
+
+
+ False
+ True
+ 5
+ 2
+
+
+
+
+ True
+ True
+ 1
+ vertical
+ _systemTimeMonthSpinAdjustment
+ True
+ 1
+
+
+ False
+ True
+ 3
+
+
+
+
+ True
+ False
+ end
+ -
+
+
+ False
+ True
+ 5
+ 4
+
+
+
+
+ True
+ True
+ 1
+ vertical
+ _systemTimeDaySpinAdjustment
+ True
+ 1
+
+
+ False
+ True
+ 5
+
+
+
+
+ True
+ True
+ 0
+ vertical
+ _systemTimeHourSpinAdjustment
+ True
+
+
+ False
+ True
+ 6
+
+
+
+
+ True
+ False
+ end
+ :
+
+
+ False
+ True
+ 5
+ 7
+
+
+
+
+ True
+ True
+ 0
+ vertical
+ _systemTimeMinuteSpinAdjustment
+ True
+
+
+ False
+ True
+ 8
+
+
+
+
+ False
+ True
+ 5
+ 3
+
+
Enable VSync
@@ -1557,7 +1377,7 @@
False
True
- 0
+ 4
@@ -1575,7 +1395,7 @@
False
True
- 1
+ 5
@@ -1593,53 +1413,190 @@
False
True
- 2
+ 6
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ True
+ 5
+ 0
+
+
+
+
+ True
+ False
+ 5
+ 5
+
+
+ False
+ True
+ 5
+ 1
+
+
+
+
+ True
+ False
+ start
+ 5
+ 5
+ vertical
+
+
+ True
+ False
-
+
True
False
-
-
- True
- False
- Graphics Shaders Dump Path
- Graphics Shaders Dump Path:
-
-
- False
- True
- 5
- 0
-
-
-
-
- True
- True
- Graphics Shaders Dump Path
- center
- False
-
-
- True
- True
- 1
-
-
+ start
+ 5
+ Hacks
+
+
+
False
True
- 5
- 3
+ 0
+
+
+ True
+ False
+ start
+ 5
+ - These may cause instability
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ False
+ 10
+ 10
+ vertical
+
+
+ Ignore Missing Services
+ True
+ True
+ False
+ Enable or disable ignoring missing services
+ start
+ 5
+ 5
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ True
+ 2
+
+
+
+
+ False
+ True
+ 5
+ 4
+
+
+
+
+ 2
+
+
+
+
+ True
+ False
+ end
+ System
+
+
+ 2
+ False
+
+
+
+
+ True
+ False
+ 5
+ vertical
+
+
+ True
+ False
+ 5
+ 5
+ vertical
+
+
+ True
+ False
+ start
+ 5
+ 5
+ 5
+ Enhancements
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 10
+ 10
+ vertical
True
False
+ 5
+ 5
True
@@ -1679,12 +1636,12 @@
False
True
5
- 4
+ 0
- True
+ False
True
1
@@ -1701,8 +1658,6 @@
True
False
- 5
- 5
False
@@ -1712,7 +1667,121 @@
-
+
+ True
+ False
+ 5
+ 5
+ vertical
+
+
+ True
+ False
+ start
+ 5
+ 5
+ 5
+ Developer Options
+
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ True
+ False
+ 10
+ 10
+ vertical
+
+
+ True
+ False
+ 5
+ 5
+
+
+ True
+ False
+ Graphics Shaders Dump Path
+ Graphics Shaders Dump Path:
+
+
+ False
+ True
+ 5
+ 0
+
+
+
+
+ True
+ True
+ Graphics Shaders Dump Path
+ center
+ False
+
+
+ True
+ True
+ 1
+
+
+
+
+ False
+ True
+ 5
+ 0
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 5
+ 4
+
+
+
+
+ 3
+
+
+
+
+ True
+ False
+ Graphics
+
+
+ 3
+ False
+
+
+
+
+ True
+ False
+ 5
+ 10
+ 5
+ vertical
+
+
True
False
5
@@ -1736,52 +1805,24 @@
-
+
True
False
+ start
10
10
vertical
-
+
+ Enable Logging to File
True
- False
-
-
- Enable Logging to File
- True
- True
- False
- Enables or disables logging to a file on disk
- start
- 5
- 5
- True
-
-
- False
- True
- 0
-
-
-
-
- Open Logs Folder
- True
- True
- True
- Opens the folder where logs are written to.
- 5
- 5
- 5
-
-
-
- False
- True
- 1
-
-
+ True
+ False
+ Enables or disables logging to a file on disk
+ start
+ 5
+ 5
+ True
False
@@ -1789,6 +1830,23 @@
0
+
+
+ Open Logs Folder
+ True
+ True
+ True
+ Opens the folder where logs are written to.
+ start
+ 10
+
+
+
+ False
+ True
+ 1
+
+
Enable Debug Logs
@@ -1938,6 +1996,7 @@
True
True
Enables FS access log output to the console. Possible modes are 0-3
+ 0
_fsLogSpinAdjustment
@@ -1966,126 +2025,22 @@
False
True
5
- 2
-
-
-
-
- True
- False
- 5
- 5
-
-
- False
- True
- 5
- 3
-
-
-
-
- True
- False
- 5
- 5
- vertical
-
-
- True
- False
-
-
- True
- False
- start
- 5
- Hacks
-
-
-
-
-
- False
- True
- 0
-
-
-
-
- True
- False
- start
- 5
- - These may cause instability
-
-
- False
- True
- 1
-
-
-
-
- False
- True
- 1
-
-
-
-
- True
- False
- 10
- 10
- vertical
-
-
- Ignore Missing Services
- True
- True
- False
- Enable or disable ignoring missing services
- start
- 5
- 5
- True
-
-
- False
- True
- 0
-
-
-
-
- True
- True
- 2
-
-
-
-
- False
- True
- 5
- 4
+ 0
- 2
+ 4
True
False
- end
- System
+ Logging
- 2
+ 4
False
@@ -2097,10 +2052,83 @@
True
True
+ 0
+
+
+
+
+ True
+ False
+ 5
+ 3
+ 3
+ end
+
+
+ Save
+ True
+ True
+ True
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ Close
+ True
+ True
+ True
+ 4
+
+
+
+ False
+ True
+ 5
+ 1
+
+
+
+
+ False
+ False
1
+
+ 1
+ 31
+ 1
+ 5
+
+
+ 23
+ 1
+ 5
+
+
+ 59
+ 1
+ 5
+
+
+ 1
+ 12
+ 1
+ 5
+
+
+ 2000
+ 2060
+ 1
+ 10
+
diff --git a/Ryujinx/Ui/SwitchSettings.cs b/Ryujinx/Ui/SwitchSettings.cs
deleted file mode 100644
index 28435572..00000000
--- a/Ryujinx/Ui/SwitchSettings.cs
+++ /dev/null
@@ -1,611 +0,0 @@
-using Gtk;
-using Ryujinx.Configuration;
-using Ryujinx.Configuration.Hid;
-using Ryujinx.Configuration.System;
-using Ryujinx.HLE.HOS.Services.Time.TimeZone;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-
-using GUI = Gtk.Builder.ObjectAttribute;
-
-namespace Ryujinx.Ui
-{
- public class SwitchSettings : Window
- {
- private static ListStore _gameDirsBoxStore;
-
- private static bool _listeningForKeypress;
-
- private long _systemTimeOffset;
-
-#pragma warning disable CS0649
-#pragma warning disable IDE0044
- [GUI] Window _settingsWin;
- [GUI] CheckButton _errorLogToggle;
- [GUI] CheckButton _warningLogToggle;
- [GUI] CheckButton _infoLogToggle;
- [GUI] CheckButton _stubLogToggle;
- [GUI] CheckButton _debugLogToggle;
- [GUI] CheckButton _fileLogToggle;
- [GUI] CheckButton _guestLogToggle;
- [GUI] CheckButton _fsAccessLogToggle;
- [GUI] Adjustment _fsLogSpinAdjustment;
- [GUI] CheckButton _dockedModeToggle;
- [GUI] CheckButton _discordToggle;
- [GUI] CheckButton _vSyncToggle;
- [GUI] CheckButton _multiSchedToggle;
- [GUI] CheckButton _fsicToggle;
- [GUI] CheckButton _ignoreToggle;
- [GUI] CheckButton _directKeyboardAccess;
- [GUI] ComboBoxText _systemLanguageSelect;
- [GUI] ComboBoxText _systemRegionSelect;
- [GUI] ComboBoxText _systemTimeZoneSelect;
- [GUI] SpinButton _systemTimeYearSpin;
- [GUI] SpinButton _systemTimeMonthSpin;
- [GUI] SpinButton _systemTimeDaySpin;
- [GUI] SpinButton _systemTimeHourSpin;
- [GUI] SpinButton _systemTimeMinuteSpin;
- [GUI] Adjustment _systemTimeYearSpinAdjustment;
- [GUI] Adjustment _systemTimeMonthSpinAdjustment;
- [GUI] Adjustment _systemTimeDaySpinAdjustment;
- [GUI] Adjustment _systemTimeHourSpinAdjustment;
- [GUI] Adjustment _systemTimeMinuteSpinAdjustment;
- [GUI] CheckButton _custThemeToggle;
- [GUI] Entry _custThemePath;
- [GUI] ToggleButton _browseThemePath;
- [GUI] Label _custThemePathLabel;
- [GUI] TreeView _gameDirsBox;
- [GUI] Entry _addGameDirBox;
- [GUI] ToggleButton _addDir;
- [GUI] ToggleButton _browseDir;
- [GUI] ToggleButton _removeDir;
- [GUI] Entry _graphicsShadersDumpPath;
- [GUI] ComboBoxText _anisotropy;
- [GUI] Image _controller1Image;
-
- [GUI] ComboBoxText _controller1Type;
- [GUI] ToggleButton _lStickUp1;
- [GUI] ToggleButton _lStickDown1;
- [GUI] ToggleButton _lStickLeft1;
- [GUI] ToggleButton _lStickRight1;
- [GUI] ToggleButton _lStickButton1;
- [GUI] ToggleButton _dpadUp1;
- [GUI] ToggleButton _dpadDown1;
- [GUI] ToggleButton _dpadLeft1;
- [GUI] ToggleButton _dpadRight1;
- [GUI] ToggleButton _minus1;
- [GUI] ToggleButton _l1;
- [GUI] ToggleButton _zL1;
- [GUI] ToggleButton _rStickUp1;
- [GUI] ToggleButton _rStickDown1;
- [GUI] ToggleButton _rStickLeft1;
- [GUI] ToggleButton _rStickRight1;
- [GUI] ToggleButton _rStickButton1;
- [GUI] ToggleButton _a1;
- [GUI] ToggleButton _b1;
- [GUI] ToggleButton _x1;
- [GUI] ToggleButton _y1;
- [GUI] ToggleButton _plus1;
- [GUI] ToggleButton _r1;
- [GUI] ToggleButton _zR1;
-#pragma warning restore CS0649
-#pragma warning restore IDE0044
-
- public SwitchSettings(HLE.FileSystem.VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : this(new Builder("Ryujinx.Ui.SwitchSettings.glade"), virtualFileSystem, contentManager) { }
-
- private SwitchSettings(Builder builder, HLE.FileSystem.VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
- {
- builder.Autoconnect(this);
-
- _settingsWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
- _controller1Image.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyCon.png", 500, 500);
-
- //Bind Events
- _lStickUp1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickUp1);
- _lStickDown1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickDown1);
- _lStickLeft1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickLeft1);
- _lStickRight1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickRight1);
- _lStickButton1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickButton1);
- _dpadUp1.Clicked += (sender, args) => Button_Pressed(sender, args, _dpadUp1);
- _dpadDown1.Clicked += (sender, args) => Button_Pressed(sender, args, _dpadDown1);
- _dpadLeft1.Clicked += (sender, args) => Button_Pressed(sender, args, _dpadLeft1);
- _dpadRight1.Clicked += (sender, args) => Button_Pressed(sender, args, _dpadRight1);
- _minus1.Clicked += (sender, args) => Button_Pressed(sender, args, _minus1);
- _l1.Clicked += (sender, args) => Button_Pressed(sender, args, _l1);
- _zL1.Clicked += (sender, args) => Button_Pressed(sender, args, _zL1);
- _rStickUp1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickUp1);
- _rStickDown1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickDown1);
- _rStickLeft1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickLeft1);
- _rStickRight1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickRight1);
- _rStickButton1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickButton1);
- _a1.Clicked += (sender, args) => Button_Pressed(sender, args, _a1);
- _b1.Clicked += (sender, args) => Button_Pressed(sender, args, _b1);
- _x1.Clicked += (sender, args) => Button_Pressed(sender, args, _x1);
- _y1.Clicked += (sender, args) => Button_Pressed(sender, args, _y1);
- _plus1.Clicked += (sender, args) => Button_Pressed(sender, args, _plus1);
- _r1.Clicked += (sender, args) => Button_Pressed(sender, args, _r1);
- _zR1.Clicked += (sender, args) => Button_Pressed(sender, args, _zR1);
- _controller1Type.Changed += (sender, args) => Controller_Changed(sender, args, _controller1Type.ActiveId, _controller1Image);
-
- //Setup Currents
- if (ConfigurationState.Instance.Logger.EnableFileLog)
- {
- _fileLogToggle.Click();
- }
-
- if (ConfigurationState.Instance.Logger.EnableError)
- {
- _errorLogToggle.Click();
- }
-
- if (ConfigurationState.Instance.Logger.EnableWarn)
- {
- _warningLogToggle.Click();
- }
-
- if (ConfigurationState.Instance.Logger.EnableInfo)
- {
- _infoLogToggle.Click();
- }
-
- if (ConfigurationState.Instance.Logger.EnableStub)
- {
- _stubLogToggle.Click();
- }
-
- if (ConfigurationState.Instance.Logger.EnableDebug)
- {
- _debugLogToggle.Click();
- }
-
- if (ConfigurationState.Instance.Logger.EnableGuest)
- {
- _guestLogToggle.Click();
- }
-
- if (ConfigurationState.Instance.Logger.EnableFsAccessLog)
- {
- _fsAccessLogToggle.Click();
- }
-
- if (ConfigurationState.Instance.System.EnableDockedMode)
- {
- _dockedModeToggle.Click();
- }
-
- if (ConfigurationState.Instance.EnableDiscordIntegration)
- {
- _discordToggle.Click();
- }
-
- if (ConfigurationState.Instance.Graphics.EnableVsync)
- {
- _vSyncToggle.Click();
- }
-
- if (ConfigurationState.Instance.System.EnableMulticoreScheduling)
- {
- _multiSchedToggle.Click();
- }
-
- if (ConfigurationState.Instance.System.EnableFsIntegrityChecks)
- {
- _fsicToggle.Click();
- }
-
- if (ConfigurationState.Instance.System.IgnoreMissingServices)
- {
- _ignoreToggle.Click();
- }
-
- if (ConfigurationState.Instance.Hid.EnableKeyboard)
- {
- _directKeyboardAccess.Click();
- }
-
- if (ConfigurationState.Instance.Ui.EnableCustomTheme)
- {
- _custThemeToggle.Click();
- }
-
- TimeZoneContentManager timeZoneContentManager = new TimeZoneContentManager();
-
- timeZoneContentManager.InitializeInstance(virtualFileSystem, contentManager, LibHac.FsSystem.IntegrityCheckLevel.None);
-
- List locationNames = timeZoneContentManager.LocationNameCache.ToList();
-
- locationNames.Sort();
-
- foreach (string locationName in locationNames)
- {
- _systemTimeZoneSelect.Append(locationName, locationName);
- }
-
- _systemLanguageSelect.SetActiveId(ConfigurationState.Instance.System.Language.Value.ToString());
- _systemRegionSelect .SetActiveId(ConfigurationState.Instance.System.Region.Value.ToString());
- _systemTimeZoneSelect.SetActiveId(timeZoneContentManager.SanityCheckDeviceLocationName());
- _anisotropy .SetActiveId(ConfigurationState.Instance.Graphics.MaxAnisotropy.Value.ToString());
- _controller1Type .SetActiveId(ConfigurationState.Instance.Hid.ControllerType.Value.ToString());
- Controller_Changed(null, null, _controller1Type.ActiveId, _controller1Image);
-
- _lStickUp1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickUp.ToString();
- _lStickDown1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickDown.ToString();
- _lStickLeft1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickLeft.ToString();
- _lStickRight1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickRight.ToString();
- _lStickButton1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickButton.ToString();
- _dpadUp1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.DPadUp.ToString();
- _dpadDown1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.DPadDown.ToString();
- _dpadLeft1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.DPadLeft.ToString();
- _dpadRight1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.DPadRight.ToString();
- _minus1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.ButtonMinus.ToString();
- _l1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.ButtonL.ToString();
- _zL1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.ButtonZl.ToString();
- _rStickUp1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickUp.ToString();
- _rStickDown1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickDown.ToString();
- _rStickLeft1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickLeft.ToString();
- _rStickRight1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickRight.ToString();
- _rStickButton1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickButton.ToString();
- _a1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonA.ToString();
- _b1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonB.ToString();
- _x1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonX.ToString();
- _y1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonY.ToString();
- _plus1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonPlus.ToString();
- _r1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonR.ToString();
- _zR1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonZr.ToString();
-
- _custThemePath.Buffer.Text = ConfigurationState.Instance.Ui.CustomThemePath;
- _graphicsShadersDumpPath.Buffer.Text = ConfigurationState.Instance.Graphics.ShadersDumpPath;
- _fsLogSpinAdjustment.Value = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
- _systemTimeOffset = ConfigurationState.Instance.System.SystemTimeOffset;
-
- _gameDirsBox.AppendColumn("", new CellRendererText(), "text", 0);
- _gameDirsBoxStore = new ListStore(typeof(string));
- _gameDirsBox.Model = _gameDirsBoxStore;
-
- foreach (string gameDir in ConfigurationState.Instance.Ui.GameDirs.Value)
- {
- _gameDirsBoxStore.AppendValues(gameDir);
- }
-
- if (_custThemeToggle.Active == false)
- {
- _custThemePath.Sensitive = false;
- _custThemePathLabel.Sensitive = false;
- _browseThemePath.Sensitive = false;
- }
-
- _listeningForKeypress = false;
-
- //Setup system time spinners
- UpdateSystemTimeSpinners();
- }
-
- private void UpdateSystemTimeSpinners()
- {
- //Unbind system time spin events
- _systemTimeYearSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
- _systemTimeMonthSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
- _systemTimeDaySpin.ValueChanged -= SystemTimeSpin_ValueChanged;
- _systemTimeHourSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
- _systemTimeMinuteSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
-
- //Apply actual system time + SystemTimeOffset to system time spin buttons
- DateTime systemTime = DateTime.Now.AddSeconds(_systemTimeOffset);
-
- _systemTimeYearSpinAdjustment.Value = systemTime.Year;
- _systemTimeMonthSpinAdjustment.Value = systemTime.Month;
- _systemTimeDaySpinAdjustment.Value = systemTime.Day;
- _systemTimeHourSpinAdjustment.Value = systemTime.Hour;
- _systemTimeMinuteSpinAdjustment.Value = systemTime.Minute;
-
- //Format spin buttons text to include leading zeros
- _systemTimeYearSpin.Text = systemTime.Year.ToString("0000");
- _systemTimeMonthSpin.Text = systemTime.Month.ToString("00");
- _systemTimeDaySpin.Text = systemTime.Day.ToString("00");
- _systemTimeHourSpin.Text = systemTime.Hour.ToString("00");
- _systemTimeMinuteSpin.Text = systemTime.Minute.ToString("00");
-
- //Bind system time spin button events
- _systemTimeYearSpin.ValueChanged += SystemTimeSpin_ValueChanged;
- _systemTimeMonthSpin.ValueChanged += SystemTimeSpin_ValueChanged;
- _systemTimeDaySpin.ValueChanged += SystemTimeSpin_ValueChanged;
- _systemTimeHourSpin.ValueChanged += SystemTimeSpin_ValueChanged;
- _systemTimeMinuteSpin.ValueChanged += SystemTimeSpin_ValueChanged;
- }
-
- //Events
- private void SystemTimeSpin_ValueChanged(Object sender, EventArgs e)
- {
- int year = _systemTimeYearSpin.ValueAsInt;
- int month = _systemTimeMonthSpin.ValueAsInt;
- int day = _systemTimeDaySpin.ValueAsInt;
- int hour = _systemTimeHourSpin.ValueAsInt;
- int minute = _systemTimeMinuteSpin.ValueAsInt;
-
- if (!DateTime.TryParse(year + "-" + month + "-" + day + " " + hour + ":" + minute, out DateTime newTime))
- {
- UpdateSystemTimeSpinners();
-
- return;
- }
-
- newTime = newTime.AddSeconds(DateTime.Now.Second).AddMilliseconds(DateTime.Now.Millisecond);
-
- long systemTimeOffset = (long)Math.Ceiling((newTime - DateTime.Now).TotalMinutes) * 60L;
-
- if (_systemTimeOffset != systemTimeOffset)
- {
- _systemTimeOffset = systemTimeOffset;
- UpdateSystemTimeSpinners();
- }
- }
-
- private void Button_Pressed(object sender, EventArgs args, ToggleButton button)
- {
- if (_listeningForKeypress == false)
- {
- KeyPressEvent += On_KeyPress;
-
- _listeningForKeypress = true;
-
- void On_KeyPress(object o, KeyPressEventArgs keyPressed)
- {
- string key = keyPressed.Event.Key.ToString();
- string capKey = key.First().ToString().ToUpper() + key.Substring(1);
-
- if (Enum.IsDefined(typeof(Configuration.Hid.Key), capKey))
- {
- button.Label = capKey;
- }
- else if (GdkToOpenTkInput.ContainsKey(key))
- {
- button.Label = GdkToOpenTkInput[key];
- }
- else
- {
- button.Label = "Space";
- }
-
- button.SetStateFlags(0, true);
-
- KeyPressEvent -= On_KeyPress;
-
- _listeningForKeypress = false;
- }
- }
- else
- {
- button.SetStateFlags(0, true);
- }
- }
-
- private void Controller_Changed(object sender, EventArgs args, string controllerType, Image controllerImage)
- {
- switch (controllerType)
- {
- case "ProController":
- controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.ProCon.png", 500, 500);
- break;
- case "NpadLeft":
- controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.BlueCon.png", 500, 500);
- break;
- case "NpadRight":
- controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.RedCon.png", 500, 500);
- break;
- default:
- controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyCon.png", 500, 500);
- break;
- }
- }
-
- private void AddDir_Pressed(object sender, EventArgs args)
- {
- if (Directory.Exists(_addGameDirBox.Buffer.Text))
- {
- _gameDirsBoxStore.AppendValues(_addGameDirBox.Buffer.Text);
- }
-
- _addDir.SetStateFlags(0, true);
- }
-
- private void BrowseDir_Pressed(object sender, EventArgs args)
- {
- FileChooserDialog fileChooser = new FileChooserDialog("Choose the game directory to add to the list", this, FileChooserAction.SelectFolder, "Cancel", ResponseType.Cancel, "Add", ResponseType.Accept);
-
- if (fileChooser.Run() == (int)ResponseType.Accept)
- {
- _gameDirsBoxStore.AppendValues(fileChooser.Filename);
- }
-
- fileChooser.Dispose();
-
- _browseDir.SetStateFlags(0, true);
- }
-
- private void RemoveDir_Pressed(object sender, EventArgs args)
- {
- TreeSelection selection = _gameDirsBox.Selection;
-
- selection.GetSelected(out TreeIter treeIter);
- _gameDirsBoxStore.Remove(ref treeIter);
-
- _removeDir.SetStateFlags(0, true);
- }
-
- private void CustThemeToggle_Activated(object sender, EventArgs args)
- {
- _custThemePath.Sensitive = _custThemeToggle.Active;
- _custThemePathLabel.Sensitive = _custThemeToggle.Active;
- _browseThemePath.Sensitive = _custThemeToggle.Active;
- }
-
- private void BrowseThemeDir_Pressed(object sender, EventArgs args)
- {
- FileChooserDialog fileChooser = new FileChooserDialog("Choose the theme to load", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Select", ResponseType.Accept);
-
- fileChooser.Filter = new FileFilter();
- fileChooser.Filter.AddPattern("*.css");
-
- if (fileChooser.Run() == (int)ResponseType.Accept)
- {
- _custThemePath.Buffer.Text = fileChooser.Filename;
- }
-
- fileChooser.Dispose();
-
- _browseThemePath.SetStateFlags(0, true);
- }
-
- private void OpenLogsFolder_Pressed(object sender, EventArgs args)
- {
- string logPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
-
- DirectoryInfo directory = new DirectoryInfo(logPath);
- directory.Create();
-
- Process.Start(new ProcessStartInfo()
- {
- FileName = logPath,
- UseShellExecute = true,
- Verb = "open"
- });
- }
-
- private void SaveToggle_Activated(object sender, EventArgs args)
- {
- List gameDirs = new List();
-
- _gameDirsBoxStore.GetIterFirst(out TreeIter treeIter);
- for (int i = 0; i < _gameDirsBoxStore.IterNChildren(); i++)
- {
- _gameDirsBoxStore.GetValue(treeIter, i);
-
- gameDirs.Add((string)_gameDirsBoxStore.GetValue(treeIter, 0));
-
- _gameDirsBoxStore.IterNext(ref treeIter);
- }
-
- ConfigurationState.Instance.Logger.EnableError.Value = _errorLogToggle.Active;
- ConfigurationState.Instance.Logger.EnableWarn.Value = _warningLogToggle.Active;
- ConfigurationState.Instance.Logger.EnableInfo.Value = _infoLogToggle.Active;
- ConfigurationState.Instance.Logger.EnableStub.Value = _stubLogToggle.Active;
- ConfigurationState.Instance.Logger.EnableDebug.Value = _debugLogToggle.Active;
- ConfigurationState.Instance.Logger.EnableGuest.Value = _guestLogToggle.Active;
- ConfigurationState.Instance.Logger.EnableFsAccessLog.Value = _fsAccessLogToggle.Active;
- ConfigurationState.Instance.Logger.EnableFileLog.Value = _fileLogToggle.Active;
- ConfigurationState.Instance.System.EnableDockedMode.Value = _dockedModeToggle.Active;
- ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
- ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
- ConfigurationState.Instance.System.EnableMulticoreScheduling.Value = _multiSchedToggle.Active;
- ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
- ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active;
- ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active;
- ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
-
- ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon = new NpadKeyboardLeft()
- {
- StickUp = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickUp1.Label),
- StickDown = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickDown1.Label),
- StickLeft = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickLeft1.Label),
- StickRight = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickRight1.Label),
- StickButton = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickButton1.Label),
- DPadUp = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _dpadUp1.Label),
- DPadDown = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _dpadDown1.Label),
- DPadLeft = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _dpadLeft1.Label),
- DPadRight = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _dpadRight1.Label),
- ButtonMinus = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _minus1.Label),
- ButtonL = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _l1.Label),
- ButtonZl = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _zL1.Label),
- };
-
- ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon = new NpadKeyboardRight()
- {
- StickUp = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickUp1.Label),
- StickDown = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickDown1.Label),
- StickLeft = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickLeft1.Label),
- StickRight = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickRight1.Label),
- StickButton = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickButton1.Label),
- ButtonA = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _a1.Label),
- ButtonB = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _b1.Label),
- ButtonX = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _x1.Label),
- ButtonY = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _y1.Label),
- ButtonPlus = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _plus1.Label),
- ButtonR = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _r1.Label),
- ButtonZr = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _zR1.Label),
- };
-
- ConfigurationState.Instance.System.Language.Value = (Language)Enum.Parse(typeof(Language), _systemLanguageSelect.ActiveId);
- ConfigurationState.Instance.System.Region.Value = (Configuration.System.Region)Enum.Parse(typeof(Configuration.System.Region), _systemRegionSelect.ActiveId);
- ConfigurationState.Instance.Graphics.MaxAnisotropy.Value = float.Parse(_anisotropy.ActiveId);
- ConfigurationState.Instance.Hid.ControllerType.Value = (ControllerType)Enum.Parse(typeof(ControllerType), _controller1Type.ActiveId);
- ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
- ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;
- ConfigurationState.Instance.Ui.GameDirs.Value = gameDirs;
- ConfigurationState.Instance.System.FsGlobalAccessLogMode.Value = (int)_fsLogSpinAdjustment.Value;
-
- ConfigurationState.Instance.System.TimeZone.Value = _systemTimeZoneSelect.ActiveId;
- ConfigurationState.Instance.System.SystemTimeOffset.Value = _systemTimeOffset;
-
- MainWindow.SaveConfig();
- MainWindow.ApplyTheme();
- MainWindow.UpdateGameTable();
- Dispose();
- }
-
- private void CloseToggle_Activated(object sender, EventArgs args)
- {
- Dispose();
- }
-
- public readonly Dictionary GdkToOpenTkInput = new Dictionary()
- {
- { "Key_0", "Number0" },
- { "Key_1", "Number1" },
- { "Key_2", "Number2" },
- { "Key_3", "Number3" },
- { "Key_4", "Number4" },
- { "Key_5", "Number5" },
- { "Key_6", "Number6" },
- { "Key_7", "Number7" },
- { "Key_8", "Number8" },
- { "Key_9", "Number9" },
- { "equal", "Plus" },
- { "uparrow", "Up" },
- { "downarrow", "Down" },
- { "leftarrow", "Left" },
- { "rightarrow", "Right" },
- { "Control_L", "ControlLeft" },
- { "Control_R", "ControlRight" },
- { "Shift_L", "ShiftLeft" },
- { "Shift_R", "ShiftRight" },
- { "Alt_L", "AltLeft" },
- { "Alt_R", "AltRight" },
- { "Page_Up", "PageUp" },
- { "Page_Down", "PageDown" },
- { "KP_Enter", "KeypadEnter" },
- { "KP_Up", "Up" },
- { "KP_Down", "Down" },
- { "KP_Left", "Left" },
- { "KP_Right", "Right" },
- { "KP_Divide", "KeypadDivide" },
- { "KP_Multiply", "KeypadMultiply" },
- { "KP_Subtract", "KeypadSubtract" },
- { "KP_Add", "KeypadAdd" },
- { "KP_Decimal", "KeypadDecimal" },
- { "KP_0", "Keypad0" },
- { "KP_1", "Keypad1" },
- { "KP_2", "Keypad2" },
- { "KP_3", "Keypad3" },
- { "KP_4", "Keypad4" },
- { "KP_5", "Keypad5" },
- { "KP_6", "Keypad6" },
- { "KP_7", "Keypad7" },
- { "KP_8", "Keypad8" },
- { "KP_9", "Keypad9" },
- };
- }
-}
diff --git a/Ryujinx/Ui/TitleUpdateWindow.cs b/Ryujinx/Ui/TitleUpdateWindow.cs
index 6808b4da..06d0dcdb 100644
--- a/Ryujinx/Ui/TitleUpdateWindow.cs
+++ b/Ryujinx/Ui/TitleUpdateWindow.cs
@@ -133,7 +133,7 @@ namespace Ryujinx.Ui
if (showErrorDialog)
{
- GtkDialog.CreateDialog("Ryujinx - Error", "Add Update Failed!", "The NCA header content type check has failed. This is usually because the header key is incorrect or missing.");
+ GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add Update Failed!", "The NCA header content type check has failed. This is usually because the header key is incorrect or missing.");
}
break;
@@ -144,7 +144,7 @@ namespace Ryujinx.Ui
if (showErrorDialog)
{
- GtkDialog.CreateDialog("Ryujinx - Error", "Add Update Failed!", $"Your key set is missing a key with the name: {exception.Name}");
+ GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add Update Failed!", $"Your key set is missing a key with the name: {exception.Name}");
}
break;
diff --git a/Ryujinx/Ui/assets/BlueCon.png b/Ryujinx/Ui/assets/BlueCon.png
deleted file mode 100644
index 25691957..00000000
Binary files a/Ryujinx/Ui/assets/BlueCon.png and /dev/null differ
diff --git a/Ryujinx/Ui/assets/JoyCon.png b/Ryujinx/Ui/assets/JoyCon.png
deleted file mode 100644
index ec745863..00000000
Binary files a/Ryujinx/Ui/assets/JoyCon.png and /dev/null differ
diff --git a/Ryujinx/Ui/assets/JoyConLeft.svg b/Ryujinx/Ui/assets/JoyConLeft.svg
new file mode 100644
index 00000000..40d06136
--- /dev/null
+++ b/Ryujinx/Ui/assets/JoyConLeft.svg
@@ -0,0 +1,105 @@
+
+
+
diff --git a/Ryujinx/Ui/assets/JoyConPair.svg b/Ryujinx/Ui/assets/JoyConPair.svg
new file mode 100644
index 00000000..fca94d18
--- /dev/null
+++ b/Ryujinx/Ui/assets/JoyConPair.svg
@@ -0,0 +1,218 @@
+
+
+
diff --git a/Ryujinx/Ui/assets/JoyConRight.svg b/Ryujinx/Ui/assets/JoyConRight.svg
new file mode 100644
index 00000000..014c0ae3
--- /dev/null
+++ b/Ryujinx/Ui/assets/JoyConRight.svg
@@ -0,0 +1,120 @@
+
+
+
diff --git a/Ryujinx/Ui/assets/ProCon.png b/Ryujinx/Ui/assets/ProCon.png
deleted file mode 100644
index 85636226..00000000
Binary files a/Ryujinx/Ui/assets/ProCon.png and /dev/null differ
diff --git a/Ryujinx/Ui/assets/ProCon.svg b/Ryujinx/Ui/assets/ProCon.svg
new file mode 100644
index 00000000..8c2b879f
--- /dev/null
+++ b/Ryujinx/Ui/assets/ProCon.svg
@@ -0,0 +1,149 @@
+
+
+
diff --git a/Ryujinx/Ui/assets/RedCon.png b/Ryujinx/Ui/assets/RedCon.png
deleted file mode 100644
index 6094b2e8..00000000
Binary files a/Ryujinx/Ui/assets/RedCon.png and /dev/null differ
diff --git a/Ryujinx/_schema.json b/Ryujinx/_schema.json
index f075b608..e89e2bf7 100644
--- a/Ryujinx/_schema.json
+++ b/Ryujinx/_schema.json
@@ -840,8 +840,8 @@
"title": "Joystick Deadzone",
"description": "Controller Analog Stick Deadzone",
"default": 0.05,
- "minimum": -32768.0,
- "maximum": 32767.0,
+ "minimum": 0.00,
+ "maximum": 1.00,
"examples": [
0.05
]