diff --git a/Ryujinx/Configuration.cs b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
similarity index 53%
rename from Ryujinx/Configuration.cs
rename to Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
index c259f9e9d..1a9407cb2 100644
--- a/Ryujinx/Configuration.cs
+++ b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
@@ -1,30 +1,22 @@
using JsonPrettyPrinterPlus;
-using LibHac.FsSystem;
-using OpenTK.Input;
-using Ryujinx.Common;
using Ryujinx.Common.Logging;
-using Ryujinx.HLE;
-using Ryujinx.HLE.HOS.SystemState;
-using Ryujinx.HLE.HOS.Services;
-using Ryujinx.HLE.Input;
-using Ryujinx.Ui;
-using Ryujinx.Ui.Input;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
-using System.Threading.Tasks;
using Utf8Json;
using Utf8Json.Resolvers;
+using Ryujinx.Configuration.System;
+using Ryujinx.Configuration.Hid;
+using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.UI.Input;
+using Ryujinx.Configuration.Ui;
-namespace Ryujinx
+namespace Ryujinx.Configuration
{
- public class Configuration
+ public class ConfigurationFileFormat
{
- ///
- /// The default configuration instance
- ///
- public static Configuration Instance { get; private set; }
+ public int Version { get; set; }
///
/// Dumps shaders in this local directory
@@ -79,7 +71,7 @@ namespace Ryujinx
///
/// Change System Language
///
- public SystemLanguage SystemLanguage { get; set; }
+ public Language SystemLanguage { get; set; }
///
/// Enables or disables Docked Mode
@@ -119,7 +111,7 @@ namespace Ryujinx
///
/// The primary controller's type
///
- public ControllerStatus ControllerType { get; set; }
+ public ControllerType ControllerType { get; set; }
///
/// Used to toggle columns in the GUI
@@ -154,13 +146,13 @@ namespace Ryujinx
///
/// Controller control bindings
///
- public Ui.Input.NpadController JoystickControls { get; private set; }
+ public NpadController JoystickControls { get; set; }
///
/// Loads a configuration file from disk
///
/// The path to the JSON configuration file
- public static void Load(string path)
+ public static ConfigurationFileFormat Load(string path)
{
var resolver = CompositeResolver.Create(
new[] { new ConfigurationEnumFormatter() },
@@ -169,24 +161,7 @@ namespace Ryujinx
using (Stream stream = File.OpenRead(path))
{
- Instance = JsonSerializer.Deserialize(stream, resolver);
- }
- }
-
- ///
- /// Loads a configuration file asynchronously from disk
- ///
- /// The path to the JSON configuration file
- public static async Task LoadAsync(string path)
- {
- IJsonFormatterResolver resolver = CompositeResolver.Create(
- new[] { new ConfigurationEnumFormatter() },
- new[] { StandardResolver.AllowPrivateSnakeCase }
- );
-
- using (Stream stream = File.OpenRead(path))
- {
- Instance = await JsonSerializer.DeserializeAsync(stream, resolver);
+ return JsonSerializer.Deserialize(stream, resolver);
}
}
@@ -194,108 +169,17 @@ namespace Ryujinx
/// Save a configuration file to disk
///
/// The path to the JSON configuration file
- public static void SaveConfig(Configuration config, string path)
+ public void SaveConfig(string path)
{
IJsonFormatterResolver resolver = CompositeResolver.Create(
new[] { new ConfigurationEnumFormatter() },
new[] { StandardResolver.AllowPrivateSnakeCase }
);
- byte[] data = JsonSerializer.Serialize(config, resolver);
+ byte[] data = JsonSerializer.Serialize(this, resolver);
File.WriteAllText(path, Encoding.UTF8.GetString(data, 0, data.Length).PrettyPrintJson());
}
- ///
- /// Configures a instance
- ///
- /// The instance to configure
- public static void InitialConfigure(Switch device)
- {
- if (Instance == null)
- {
- throw new InvalidOperationException("Configuration has not been loaded yet.");
- }
-
- SwitchSettings.ConfigureSettings(Instance);
-
- Logger.AddTarget(new AsyncLogTargetWrapper(
- new ConsoleLogTarget(),
- 1000,
- AsyncLogTargetOverflowAction.Block
- ));
-
- if (Instance.EnableFileLog)
- {
- Logger.AddTarget(new AsyncLogTargetWrapper(
- new FileLogTarget(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.log")),
- 1000,
- AsyncLogTargetOverflowAction.Block
- ));
- }
-
- Configure(device, Instance);
- }
-
- public static void Configure(Switch device, Configuration SwitchConfig)
- {
- GraphicsConfig.ShadersDumpPath = SwitchConfig.GraphicsShadersDumpPath;
-
- Logger.SetEnable(LogLevel.Debug, SwitchConfig.LoggingEnableDebug );
- Logger.SetEnable(LogLevel.Stub, SwitchConfig.LoggingEnableStub );
- Logger.SetEnable(LogLevel.Info, SwitchConfig.LoggingEnableInfo );
- Logger.SetEnable(LogLevel.Warning, SwitchConfig.LoggingEnableWarn );
- Logger.SetEnable(LogLevel.Error, SwitchConfig.LoggingEnableError );
- Logger.SetEnable(LogLevel.Guest, SwitchConfig.LoggingEnableGuest );
- Logger.SetEnable(LogLevel.AccessLog, SwitchConfig.LoggingEnableFsAccessLog);
-
- if (SwitchConfig.LoggingFilteredClasses.Length > 0)
- {
- foreach (var logClass in EnumExtensions.GetValues())
- {
- Logger.SetEnable(logClass, false);
- }
-
- foreach (var logClass in SwitchConfig.LoggingFilteredClasses)
- {
- Logger.SetEnable(logClass, true);
- }
- }
-
- MainWindow.DiscordIntegrationEnabled = SwitchConfig.EnableDiscordIntegration;
-
- device.EnableDeviceVsync = SwitchConfig.EnableVsync;
-
- device.System.State.DockedMode = SwitchConfig.DockedMode;
-
- device.System.State.SetLanguage(SwitchConfig.SystemLanguage);
-
- if (SwitchConfig.EnableMulticoreScheduling)
- {
- device.System.EnableMultiCoreScheduling();
- }
-
- device.System.FsIntegrityCheckLevel = SwitchConfig.EnableFsIntegrityChecks
- ? IntegrityCheckLevel.ErrorOnInvalid
- : IntegrityCheckLevel.None;
-
- device.System.GlobalAccessLogMode = SwitchConfig.FsGlobalAccessLogMode;
-
- ServiceConfiguration.IgnoreMissingServices = SwitchConfig.IgnoreMissingServices;
- }
-
- public static void ConfigureHid(Switch device, Configuration SwitchConfig)
- {
- if (SwitchConfig.JoystickControls.Enabled)
- {
- if (!Joystick.GetState(SwitchConfig.JoystickControls.Index).IsConnected)
- {
- SwitchConfig.JoystickControls.SetEnabled(false);
- }
- }
- device.Hid.InitializePrimaryController(SwitchConfig.ControllerType);
- device.Hid.InitializeKeyboard();
- }
-
private class ConfigurationEnumFormatter : IJsonFormatter
where T : struct
{
diff --git a/Ryujinx.Common/Configuration/ConfigurationState.cs b/Ryujinx.Common/Configuration/ConfigurationState.cs
new file mode 100644
index 000000000..050b49738
--- /dev/null
+++ b/Ryujinx.Common/Configuration/ConfigurationState.cs
@@ -0,0 +1,502 @@
+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;
+
+namespace Ryujinx.Configuration
+{
+ public class ConfigurationState
+ {
+ ///
+ /// UI configuration section
+ ///
+ public class UiSection
+ {
+ public class Columns
+ {
+ public ReactiveObject FavColumn { get; private set; }
+ public ReactiveObject IconColumn { get; private set; }
+ public ReactiveObject AppColumn { get; private set; }
+ public ReactiveObject DevColumn { get; private set; }
+ public ReactiveObject VersionColumn { get; private set; }
+ public ReactiveObject TimePlayedColumn { get; private set; }
+ public ReactiveObject LastPlayedColumn { get; private set; }
+ public ReactiveObject FileExtColumn { get; private set; }
+ public ReactiveObject FileSizeColumn { get; private set; }
+ public ReactiveObject PathColumn { get; private set; }
+
+ public Columns()
+ {
+ FavColumn = new ReactiveObject();
+ IconColumn = new ReactiveObject();
+ AppColumn = new ReactiveObject();
+ DevColumn = new ReactiveObject();
+ VersionColumn = new ReactiveObject();
+ TimePlayedColumn = new ReactiveObject();
+ LastPlayedColumn = new ReactiveObject();
+ FileExtColumn = new ReactiveObject();
+ FileSizeColumn = new ReactiveObject();
+ PathColumn = new ReactiveObject();
+ }
+ }
+
+ ///
+ /// Used to toggle columns in the GUI
+ ///
+ public Columns GuiColumns { get; private set; }
+
+ ///
+ /// A list of directories containing games to be used to load games into the games list
+ ///
+ public ReactiveObject> GameDirs { get; private set; }
+
+ ///
+ /// Enable or disable custom themes in the GUI
+ ///
+ public ReactiveObject EnableCustomTheme { get; private set; }
+
+ ///
+ /// Path to custom GUI theme
+ ///
+ public ReactiveObject CustomThemePath { get; private set; }
+
+ public UiSection()
+ {
+ GuiColumns = new Columns();
+ GameDirs = new ReactiveObject>();
+ EnableCustomTheme = new ReactiveObject();
+ CustomThemePath = new ReactiveObject();
+ }
+ }
+
+ ///
+ /// Logger configuration section
+ ///
+ public class LoggerSection
+ {
+ ///
+ /// Enables printing debug log messages
+ ///
+ public ReactiveObject EnableDebug { get; private set; }
+
+ ///
+ /// Enables printing stub log messages
+ ///
+ public ReactiveObject EnableStub { get; private set; }
+
+ ///
+ /// Enables printing info log messages
+ ///
+ public ReactiveObject EnableInfo { get; private set; }
+
+ ///
+ /// Enables printing warning log messages
+ ///
+ public ReactiveObject EnableWarn { get; private set; }
+
+ ///
+ /// Enables printing error log messages
+ ///
+ public ReactiveObject EnableError { get; private set; }
+
+ ///
+ /// Enables printing guest log messages
+ ///
+ public ReactiveObject EnableGuest { get; private set; }
+
+ ///
+ /// Enables printing FS access log messages
+ ///
+ public ReactiveObject EnableFsAccessLog { get; private set; }
+
+ ///
+ /// Controls which log messages are written to the log targets
+ ///
+ public ReactiveObject FilteredClasses { get; private set; }
+
+ ///
+ /// Enables or disables logging to a file on disk
+ ///
+ public ReactiveObject EnableFileLog { get; private set; }
+
+ public LoggerSection()
+ {
+ EnableDebug = new ReactiveObject();
+ EnableStub = new ReactiveObject();
+ EnableInfo = new ReactiveObject();
+ EnableWarn = new ReactiveObject();
+ EnableError = new ReactiveObject();
+ EnableGuest = new ReactiveObject();
+ EnableFsAccessLog = new ReactiveObject();
+ FilteredClasses = new ReactiveObject();
+ EnableFileLog = new ReactiveObject();
+ }
+ }
+
+ ///
+ /// System configuration section
+ ///
+ public class SystemSection
+ {
+ ///
+ /// Change System Language
+ ///
+ public ReactiveObject Language { get; private set; }
+
+ ///
+ /// Enables or disables Docked Mode
+ ///
+ public ReactiveObject EnableDockedMode { get; private set; }
+
+ ///
+ /// Enables or disables multi-core scheduling of threads
+ ///
+ public ReactiveObject EnableMulticoreScheduling { get; private set; }
+
+ ///
+ /// Enables integrity checks on Game content files
+ ///
+ public ReactiveObject EnableFsIntegrityChecks { get; private set; }
+
+ ///
+ /// Enables FS access log output to the console. Possible modes are 0-3
+ ///
+ public ReactiveObject FsGlobalAccessLogMode { get; private set; }
+
+ ///
+ /// Enable or disable ignoring missing services
+ ///
+ public ReactiveObject IgnoreMissingServices { get; private set; }
+
+ public SystemSection()
+ {
+ Language = new ReactiveObject();
+ EnableDockedMode = new ReactiveObject();
+ EnableMulticoreScheduling = new ReactiveObject();
+ EnableFsIntegrityChecks = new ReactiveObject();
+ FsGlobalAccessLogMode = new ReactiveObject();
+ IgnoreMissingServices = new ReactiveObject();
+ }
+ }
+
+ ///
+ /// Hid configuration section
+ ///
+ 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
+ ///
+ public ReactiveObject KeyboardControls { get; private set; }
+
+ ///
+ /// Controller control bindings
+ ///
+ public ReactiveObject JoystickControls { get; private set; }
+
+ public HidSection()
+ {
+ ControllerType = new ReactiveObject();
+ EnableKeyboard = new ReactiveObject();
+ KeyboardControls = new ReactiveObject();
+ JoystickControls = new ReactiveObject();
+ }
+ }
+
+ ///
+ /// Graphics configuration section
+ ///
+ public class GraphicsSection
+ {
+ ///
+ /// Dumps shaders in this local directory
+ ///
+ public ReactiveObject ShadersDumpPath { get; private set; }
+
+ ///
+ /// Enables or disables Vertical Sync
+ ///
+ public ReactiveObject EnableVsync { get; private set; }
+
+ public GraphicsSection()
+ {
+ ShadersDumpPath = new ReactiveObject();
+ EnableVsync = new ReactiveObject();
+ }
+ }
+
+ ///
+ /// The default configuration instance
+ ///
+ public static ConfigurationState Instance { get; private set; }
+
+ ///
+ /// The Ui section
+ ///
+ public UiSection Ui { get; private set; }
+
+ ///
+ /// The Logger section
+ ///
+ public LoggerSection Logger { get; private set; }
+
+ ///
+ /// The System section
+ ///
+ public SystemSection System { get; private set; }
+
+ ///
+ /// The Graphics section
+ ///
+ public GraphicsSection Graphics { get; private set; }
+
+ ///
+ /// The Hid section
+ ///
+ public HidSection Hid { get; private set; }
+
+ ///
+ /// Enables or disables Discord Rich Presence
+ ///
+ public ReactiveObject EnableDiscordIntegration { get; private set; }
+
+ private ConfigurationState()
+ {
+ Ui = new UiSection();
+ Logger = new LoggerSection();
+ System = new SystemSection();
+ Graphics = new GraphicsSection();
+ Hid = new HidSection();
+ EnableDiscordIntegration = new ReactiveObject();
+ }
+
+ public ConfigurationFileFormat ToFileFormat()
+ {
+ ConfigurationFileFormat configurationFile = new ConfigurationFileFormat
+ {
+ Version = 1,
+ GraphicsShadersDumpPath = Graphics.ShadersDumpPath,
+ LoggingEnableDebug = Logger.EnableDebug,
+ LoggingEnableStub = Logger.EnableStub,
+ LoggingEnableInfo = Logger.EnableInfo,
+ LoggingEnableWarn = Logger.EnableWarn,
+ LoggingEnableError = Logger.EnableError,
+ LoggingEnableGuest = Logger.EnableGuest,
+ LoggingEnableFsAccessLog = Logger.EnableFsAccessLog,
+ LoggingFilteredClasses = Logger.FilteredClasses,
+ EnableFileLog = Logger.EnableFileLog,
+ SystemLanguage = System.Language,
+ DockedMode = System.EnableDockedMode,
+ EnableDiscordIntegration = EnableDiscordIntegration,
+ EnableVsync = Graphics.EnableVsync,
+ EnableMulticoreScheduling = System.EnableMulticoreScheduling,
+ EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
+ FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
+ IgnoreMissingServices = System.IgnoreMissingServices,
+ ControllerType = Hid.ControllerType,
+ GuiColumns = new GuiColumns()
+ {
+ FavColumn = Ui.GuiColumns.FavColumn,
+ IconColumn = Ui.GuiColumns.IconColumn,
+ AppColumn = Ui.GuiColumns.AppColumn,
+ DevColumn = Ui.GuiColumns.DevColumn,
+ VersionColumn = Ui.GuiColumns.VersionColumn,
+ TimePlayedColumn = Ui.GuiColumns.TimePlayedColumn,
+ LastPlayedColumn = Ui.GuiColumns.LastPlayedColumn,
+ FileExtColumn = Ui.GuiColumns.FileExtColumn,
+ FileSizeColumn = Ui.GuiColumns.FileSizeColumn,
+ PathColumn = Ui.GuiColumns.PathColumn,
+ },
+ GameDirs = Ui.GameDirs,
+ EnableCustomTheme = Ui.EnableCustomTheme,
+ CustomThemePath = Ui.CustomThemePath,
+ EnableKeyboard = Hid.EnableKeyboard,
+ KeyboardControls = Hid.KeyboardControls,
+ JoystickControls = Hid.JoystickControls
+ };
+
+ return configurationFile;
+ }
+
+ public void LoadDefault()
+ {
+ Graphics.ShadersDumpPath.Value = "";
+ Logger.EnableDebug.Value = false;
+ Logger.EnableStub.Value = true;
+ Logger.EnableInfo.Value = true;
+ Logger.EnableWarn.Value = true;
+ Logger.EnableError.Value = true;
+ Logger.EnableGuest.Value = true;
+ Logger.EnableFsAccessLog.Value = false;
+ Logger.FilteredClasses.Value = new LogClass[] { };
+ Logger.EnableFileLog.Value = true;
+ System.Language.Value = Language.AmericanEnglish;
+ System.EnableDockedMode.Value = false;
+ EnableDiscordIntegration.Value = true;
+ Graphics.EnableVsync.Value = true;
+ System.EnableMulticoreScheduling.Value = true;
+ 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;
+ Ui.GuiColumns.DevColumn.Value = true;
+ Ui.GuiColumns.VersionColumn.Value = true;
+ Ui.GuiColumns.TimePlayedColumn.Value = true;
+ Ui.GuiColumns.LastPlayedColumn.Value = true;
+ Ui.GuiColumns.FileExtColumn.Value = true;
+ Ui.GuiColumns.FileSizeColumn.Value = true;
+ Ui.GuiColumns.PathColumn.Value = true;
+ Ui.GameDirs.Value = new List();
+ Ui.EnableCustomTheme.Value = false;
+ Ui.CustomThemePath.Value = "";
+ Hid.EnableKeyboard.Value = false;
+
+ Hid.KeyboardControls.Value = new NpadKeyboard
+ {
+ 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,
+ },
+ 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,
+ }
+ };
+ }
+
+ public void Load(ConfigurationFileFormat configurationFileFormat)
+ {
+ if (configurationFileFormat.Version != 1 && configurationFileFormat.Version != 0)
+ {
+ Common.Logging.Logger.PrintWarning(LogClass.Application, $"Unsupported configuration version {configurationFileFormat.Version}, loading default.");
+
+ LoadDefault();
+
+ return;
+ }
+
+ Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
+ Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
+ Logger.EnableStub.Value = configurationFileFormat.LoggingEnableStub;
+ Logger.EnableInfo.Value = configurationFileFormat.LoggingEnableInfo;
+ Logger.EnableWarn.Value = configurationFileFormat.LoggingEnableWarn;
+ Logger.EnableError.Value = configurationFileFormat.LoggingEnableError;
+ Logger.EnableGuest.Value = configurationFileFormat.LoggingEnableGuest;
+ Logger.EnableFsAccessLog.Value = configurationFileFormat.LoggingEnableFsAccessLog;
+ Logger.FilteredClasses.Value = configurationFileFormat.LoggingFilteredClasses;
+ Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
+ System.Language.Value = configurationFileFormat.SystemLanguage;
+ System.EnableDockedMode.Value = configurationFileFormat.DockedMode;
+ System.EnableDockedMode.Value = configurationFileFormat.DockedMode;
+ EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
+ Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
+ System.EnableMulticoreScheduling.Value = configurationFileFormat.EnableMulticoreScheduling;
+ 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;
+ Ui.GuiColumns.DevColumn.Value = configurationFileFormat.GuiColumns.DevColumn;
+ Ui.GuiColumns.VersionColumn.Value = configurationFileFormat.GuiColumns.VersionColumn;
+ Ui.GuiColumns.TimePlayedColumn.Value = configurationFileFormat.GuiColumns.TimePlayedColumn;
+ Ui.GuiColumns.LastPlayedColumn.Value = configurationFileFormat.GuiColumns.LastPlayedColumn;
+ Ui.GuiColumns.FileExtColumn.Value = configurationFileFormat.GuiColumns.FileExtColumn;
+ Ui.GuiColumns.FileSizeColumn.Value = configurationFileFormat.GuiColumns.FileSizeColumn;
+ Ui.GuiColumns.PathColumn.Value = configurationFileFormat.GuiColumns.PathColumn;
+ Ui.GameDirs.Value = configurationFileFormat.GameDirs;
+ 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;
+ }
+
+ public static void Initialize()
+ {
+ if (Instance != null)
+ {
+ throw new InvalidOperationException("Configuration is already initialized");
+ }
+
+ Instance = new ConfigurationState();
+ }
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs b/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs
new file mode 100644
index 000000000..8969b6a4b
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/ControllerInputId.cs
@@ -0,0 +1,45 @@
+namespace Ryujinx.Common.Configuration.Hid
+{
+ public enum ControllerInputId
+ {
+ Button0,
+ Button1,
+ Button2,
+ Button3,
+ Button4,
+ Button5,
+ Button6,
+ Button7,
+ Button8,
+ Button9,
+ Button10,
+ Button11,
+ Button12,
+ Button13,
+ Button14,
+ Button15,
+ Button16,
+ Button17,
+ Button18,
+ Button19,
+ Button20,
+ Axis0,
+ Axis1,
+ Axis2,
+ Axis3,
+ Axis4,
+ Axis5,
+ Hat0Up,
+ Hat0Down,
+ Hat0Left,
+ Hat0Right,
+ Hat1Up,
+ Hat1Down,
+ Hat1Left,
+ Hat1Right,
+ Hat2Up,
+ Hat2Down,
+ Hat2Left,
+ Hat2Right
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/ControllerType.cs b/Ryujinx.Common/Configuration/Hid/ControllerType.cs
new file mode 100644
index 000000000..b0613b2d6
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/ControllerType.cs
@@ -0,0 +1,11 @@
+namespace Ryujinx.Configuration.Hid
+{
+ public enum ControllerType
+ {
+ ProController,
+ Handheld,
+ NpadPair,
+ NpadLeft,
+ NpadRight
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/Key.cs b/Ryujinx.Common/Configuration/Hid/Key.cs
new file mode 100644
index 000000000..b658396b9
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/Key.cs
@@ -0,0 +1,153 @@
+namespace Ryujinx.Configuration.Hid
+{
+ public enum Key
+ {
+ Unknown = 0,
+ ShiftLeft = 1,
+ LShift = 1,
+ ShiftRight = 2,
+ RShift = 2,
+ ControlLeft = 3,
+ LControl = 3,
+ ControlRight = 4,
+ RControl = 4,
+ AltLeft = 5,
+ LAlt = 5,
+ AltRight = 6,
+ RAlt = 6,
+ WinLeft = 7,
+ LWin = 7,
+ WinRight = 8,
+ RWin = 8,
+ Menu = 9,
+ F1 = 10,
+ F2 = 11,
+ F3 = 12,
+ F4 = 13,
+ F5 = 14,
+ F6 = 15,
+ F7 = 16,
+ F8 = 17,
+ F9 = 18,
+ F10 = 19,
+ F11 = 20,
+ F12 = 21,
+ F13 = 22,
+ F14 = 23,
+ F15 = 24,
+ F16 = 25,
+ F17 = 26,
+ F18 = 27,
+ F19 = 28,
+ F20 = 29,
+ F21 = 30,
+ F22 = 31,
+ F23 = 32,
+ F24 = 33,
+ F25 = 34,
+ F26 = 35,
+ F27 = 36,
+ F28 = 37,
+ F29 = 38,
+ F30 = 39,
+ F31 = 40,
+ F32 = 41,
+ F33 = 42,
+ F34 = 43,
+ F35 = 44,
+ Up = 45,
+ Down = 46,
+ Left = 47,
+ Right = 48,
+ Enter = 49,
+ Escape = 50,
+ Space = 51,
+ Tab = 52,
+ BackSpace = 53,
+ Back = 53,
+ Insert = 54,
+ Delete = 55,
+ PageUp = 56,
+ PageDown = 57,
+ Home = 58,
+ End = 59,
+ CapsLock = 60,
+ ScrollLock = 61,
+ PrintScreen = 62,
+ Pause = 63,
+ NumLock = 64,
+ Clear = 65,
+ Sleep = 66,
+ Keypad0 = 67,
+ Keypad1 = 68,
+ Keypad2 = 69,
+ Keypad3 = 70,
+ Keypad4 = 71,
+ Keypad5 = 72,
+ Keypad6 = 73,
+ Keypad7 = 74,
+ Keypad8 = 75,
+ Keypad9 = 76,
+ KeypadDivide = 77,
+ KeypadMultiply = 78,
+ KeypadSubtract = 79,
+ KeypadMinus = 79,
+ KeypadAdd = 80,
+ KeypadPlus = 80,
+ KeypadDecimal = 81,
+ KeypadPeriod = 81,
+ KeypadEnter = 82,
+ A = 83,
+ B = 84,
+ C = 85,
+ D = 86,
+ E = 87,
+ F = 88,
+ G = 89,
+ H = 90,
+ I = 91,
+ J = 92,
+ K = 93,
+ L = 94,
+ M = 95,
+ N = 96,
+ O = 97,
+ P = 98,
+ Q = 99,
+ R = 100,
+ S = 101,
+ T = 102,
+ U = 103,
+ V = 104,
+ W = 105,
+ X = 106,
+ Y = 107,
+ Z = 108,
+ Number0 = 109,
+ Number1 = 110,
+ Number2 = 111,
+ Number3 = 112,
+ Number4 = 113,
+ Number5 = 114,
+ Number6 = 115,
+ Number7 = 116,
+ Number8 = 117,
+ Number9 = 118,
+ Tilde = 119,
+ Grave = 119,
+ Minus = 120,
+ Plus = 121,
+ BracketLeft = 122,
+ LBracket = 122,
+ BracketRight = 123,
+ RBracket = 123,
+ Semicolon = 124,
+ Quote = 125,
+ Comma = 126,
+ Period = 127,
+ Slash = 128,
+ BackSlash = 129,
+ NonUSBackSlash = 130,
+ LastKey = 131
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs b/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
new file mode 100644
index 000000000..1d0b05049
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
@@ -0,0 +1,7 @@
+namespace Ryujinx.Configuration.Hid
+{
+ public struct KeyboardHotkeys
+ {
+ public Key ToggleVsync;
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/NpadController.cs b/Ryujinx.Common/Configuration/Hid/NpadController.cs
new file mode 100644
index 000000000..f00865d55
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/NpadController.cs
@@ -0,0 +1,35 @@
+namespace Ryujinx.Common.Configuration.Hid
+{
+ public class NpadController
+ {
+ ///
+ /// Enables or disables controller support
+ ///
+ public bool Enabled;
+
+ ///
+ /// Controller Device Index
+ ///
+ public int Index;
+
+ ///
+ /// Controller Analog Stick Deadzone
+ ///
+ public float Deadzone;
+
+ ///
+ /// Controller Trigger Threshold
+ ///
+ public float TriggerThreshold;
+
+ ///
+ /// Left JoyCon Controller Bindings
+ ///
+ public NpadControllerLeft LeftJoycon;
+
+ ///
+ /// Right JoyCon Controller Bindings
+ ///
+ public NpadControllerRight RightJoycon;
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs b/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs
new file mode 100644
index 000000000..54ac0f03a
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/NpadControllerLeft.cs
@@ -0,0 +1,15 @@
+namespace Ryujinx.Common.Configuration.Hid
+{
+ public struct NpadControllerLeft
+ {
+ public ControllerInputId Stick;
+ public ControllerInputId StickButton;
+ public ControllerInputId ButtonMinus;
+ public ControllerInputId ButtonL;
+ public ControllerInputId ButtonZl;
+ public ControllerInputId DPadUp;
+ public ControllerInputId DPadDown;
+ public ControllerInputId DPadLeft;
+ public ControllerInputId DPadRight;
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs b/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs
new file mode 100644
index 000000000..315136d9f
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/NpadControllerRight.cs
@@ -0,0 +1,15 @@
+namespace Ryujinx.Common.Configuration.Hid
+{
+ public struct NpadControllerRight
+ {
+ public ControllerInputId Stick;
+ public ControllerInputId StickButton;
+ public ControllerInputId ButtonA;
+ public ControllerInputId ButtonB;
+ public ControllerInputId ButtonX;
+ public ControllerInputId ButtonY;
+ public ControllerInputId ButtonPlus;
+ public ControllerInputId ButtonR;
+ public ControllerInputId ButtonZr;
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/NpadKeyboard.cs b/Ryujinx.Common/Configuration/Hid/NpadKeyboard.cs
new file mode 100644
index 000000000..911f5119e
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/NpadKeyboard.cs
@@ -0,0 +1,20 @@
+namespace Ryujinx.UI.Input
+{
+ public class NpadKeyboard
+ {
+ ///
+ /// Left JoyCon Keyboard Bindings
+ ///
+ public Configuration.Hid.NpadKeyboardLeft LeftJoycon;
+
+ ///
+ /// Right JoyCon Keyboard Bindings
+ ///
+ public Configuration.Hid.NpadKeyboardRight RightJoycon;
+
+ ///
+ /// Hotkey Keyboard Bindings
+ ///
+ public Configuration.Hid.KeyboardHotkeys Hotkeys;
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs b/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs
new file mode 100644
index 000000000..799cdfdb8
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/NpadKeyboardLeft.cs
@@ -0,0 +1,18 @@
+namespace Ryujinx.Configuration.Hid
+{
+ public struct NpadKeyboardLeft
+ {
+ public Key StickUp;
+ public Key StickDown;
+ public Key StickLeft;
+ public Key StickRight;
+ public Key StickButton;
+ public Key DPadUp;
+ public Key DPadDown;
+ public Key DPadLeft;
+ public Key DPadRight;
+ public Key ButtonMinus;
+ public Key ButtonL;
+ public Key ButtonZl;
+ }
+}
diff --git a/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs b/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs
new file mode 100644
index 000000000..311504bb7
--- /dev/null
+++ b/Ryujinx.Common/Configuration/Hid/NpadKeyboardRight.cs
@@ -0,0 +1,18 @@
+namespace Ryujinx.Configuration.Hid
+{
+ public struct NpadKeyboardRight
+ {
+ public Key StickUp;
+ public Key StickDown;
+ public Key StickLeft;
+ public Key StickRight;
+ public Key StickButton;
+ public Key ButtonA;
+ public Key ButtonB;
+ public Key ButtonX;
+ public Key ButtonY;
+ public Key ButtonPlus;
+ public Key ButtonR;
+ public Key ButtonZr;
+ }
+}
diff --git a/Ryujinx.Common/Configuration/LoggerModule.cs b/Ryujinx.Common/Configuration/LoggerModule.cs
new file mode 100644
index 000000000..504a81418
--- /dev/null
+++ b/Ryujinx.Common/Configuration/LoggerModule.cs
@@ -0,0 +1,109 @@
+using Ryujinx.Common;
+using Ryujinx.Common.Logging;
+using System;
+using System.IO;
+
+namespace Ryujinx.Configuration
+{
+ public static class LoggerModule
+ {
+ public static void Initialize()
+ {
+ AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
+ AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
+
+ ConfigurationState.Instance.Logger.EnableDebug.Event += ReloadEnableDebug;
+ ConfigurationState.Instance.Logger.EnableStub.Event += ReloadEnableStub;
+ ConfigurationState.Instance.Logger.EnableInfo.Event += ReloadEnableInfo;
+ ConfigurationState.Instance.Logger.EnableWarn.Event += ReloadEnableWarning;
+ ConfigurationState.Instance.Logger.EnableError.Event += ReloadEnableError;
+ ConfigurationState.Instance.Logger.EnableGuest.Event += ReloadEnableGuest;
+ ConfigurationState.Instance.Logger.EnableFsAccessLog.Event += ReloadEnableFsAccessLog;
+ ConfigurationState.Instance.Logger.FilteredClasses.Event += ReloadFilteredClasses;
+ ConfigurationState.Instance.Logger.EnableFileLog.Event += ReloadFileLogger;
+ }
+
+ private static void ReloadEnableDebug(object sender, ReactiveEventArgs e)
+ {
+ Logger.SetEnable(LogLevel.Debug, e.NewValue);
+ }
+
+ private static void ReloadEnableStub(object sender, ReactiveEventArgs e)
+ {
+ Logger.SetEnable(LogLevel.Stub, e.NewValue);
+ }
+
+ private static void ReloadEnableInfo(object sender, ReactiveEventArgs e)
+ {
+ Logger.SetEnable(LogLevel.Info, e.NewValue);
+ }
+
+ private static void ReloadEnableWarning(object sender, ReactiveEventArgs e)
+ {
+ Logger.SetEnable(LogLevel.Warning, e.NewValue);
+ }
+
+ private static void ReloadEnableError(object sender, ReactiveEventArgs e)
+ {
+ Logger.SetEnable(LogLevel.Error, e.NewValue);
+ }
+
+ private static void ReloadEnableGuest(object sender, ReactiveEventArgs e)
+ {
+ Logger.SetEnable(LogLevel.Guest, e.NewValue);
+ }
+
+ private static void ReloadEnableFsAccessLog(object sender, ReactiveEventArgs e)
+ {
+ Logger.SetEnable(LogLevel.AccessLog, e.NewValue);
+ }
+
+ private static void ReloadFilteredClasses(object sender, ReactiveEventArgs e)
+ {
+ bool noFilter = e.NewValue.Length == 0;
+
+ foreach (var logClass in EnumExtensions.GetValues())
+ {
+ Logger.SetEnable(logClass, noFilter);
+ }
+
+ foreach (var logClass in e.NewValue)
+ {
+ Logger.SetEnable(logClass, true);
+ }
+ }
+
+ private static void ReloadFileLogger(object sender, ReactiveEventArgs e)
+ {
+ if (e.NewValue)
+ {
+ Logger.AddTarget(new AsyncLogTargetWrapper(
+ new FileLogTarget(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.log"), "file"),
+ 1000,
+ AsyncLogTargetOverflowAction.Block
+ ));
+ }
+ else
+ {
+ Logger.RemoveTarget("file");
+ }
+ }
+
+ private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
+ {
+ Logger.Shutdown();
+ }
+
+ private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
+ {
+ var exception = e.ExceptionObject as Exception;
+
+ Logger.PrintError(LogClass.Emulation, $"Unhandled exception caught: {exception}");
+
+ if (e.IsTerminating)
+ {
+ Logger.Shutdown();
+ }
+ }
+ }
+}
diff --git a/Ryujinx.Common/Configuration/System/Language.cs b/Ryujinx.Common/Configuration/System/Language.cs
new file mode 100644
index 000000000..d3af296ba
--- /dev/null
+++ b/Ryujinx.Common/Configuration/System/Language.cs
@@ -0,0 +1,23 @@
+namespace Ryujinx.Configuration.System
+{
+ public enum Language
+ {
+ Japanese,
+ AmericanEnglish,
+ French,
+ German,
+ Italian,
+ Spanish,
+ Chinese,
+ Korean,
+ Dutch,
+ Portuguese,
+ Russian,
+ Taiwanese,
+ BritishEnglish,
+ CanadianFrench,
+ LatinAmericanSpanish,
+ SimplifiedChinese,
+ TraditionalChinese
+ }
+}
diff --git a/Ryujinx/Ui/GuiColumns.cs b/Ryujinx.Common/Configuration/Ui/GuiColumns.cs
similarity index 90%
rename from Ryujinx/Ui/GuiColumns.cs
rename to Ryujinx.Common/Configuration/Ui/GuiColumns.cs
index b86a273ea..2b3524aa8 100644
--- a/Ryujinx/Ui/GuiColumns.cs
+++ b/Ryujinx.Common/Configuration/Ui/GuiColumns.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.Ui
+namespace Ryujinx.Configuration.Ui
{
public struct GuiColumns
{
diff --git a/Ryujinx.Common/Logging/Logger.cs b/Ryujinx.Common/Logging/Logger.cs
index 10b1d9703..83af97b12 100644
--- a/Ryujinx.Common/Logging/Logger.cs
+++ b/Ryujinx.Common/Logging/Logger.cs
@@ -37,6 +37,12 @@ namespace Ryujinx.Common.Logging
m_LogTargets = new List();
m_Time = Stopwatch.StartNew();
+
+ // Logger should log to console by default
+ AddTarget(new AsyncLogTargetWrapper(
+ new ConsoleLogTarget("console"),
+ 1000,
+ AsyncLogTargetOverflowAction.Block));
}
public static void RestartTime()
@@ -44,6 +50,19 @@ namespace Ryujinx.Common.Logging
m_Time.Restart();
}
+ private static ILogTarget GetTarget(string targetName)
+ {
+ foreach (var target in m_LogTargets)
+ {
+ if (target.Name.Equals(targetName))
+ {
+ return target;
+ }
+ }
+
+ return null;
+ }
+
public static void AddTarget(ILogTarget target)
{
m_LogTargets.Add(target);
@@ -51,6 +70,20 @@ namespace Ryujinx.Common.Logging
Updated += target.Log;
}
+ public static void RemoveTarget(string target)
+ {
+ ILogTarget logTarget = GetTarget(target);
+
+ if (logTarget != null)
+ {
+ Updated -= logTarget.Log;
+
+ m_LogTargets.Remove(logTarget);
+
+ logTarget.Dispose();
+ }
+ }
+
public static void Shutdown()
{
Updated = null;
diff --git a/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs b/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs
index a805a83b6..c946b6788 100644
--- a/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs
+++ b/Ryujinx.Common/Logging/Targets/AsyncLogTargetWrapper.cs
@@ -27,6 +27,8 @@ namespace Ryujinx.Common.Logging
private readonly int _overflowTimeout;
+ string ILogTarget.Name { get => _target.Name; }
+
public AsyncLogTargetWrapper(ILogTarget target)
: this(target, -1, AsyncLogTargetOverflowAction.Block)
{ }
diff --git a/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs b/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs
index 871076a41..ff5c6f5ac 100644
--- a/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs
+++ b/Ryujinx.Common/Logging/Targets/ConsoleLogTarget.cs
@@ -9,6 +9,10 @@ namespace Ryujinx.Common.Logging
private readonly ILogFormatter _formatter;
+ private readonly string _name;
+
+ string ILogTarget.Name { get => _name; }
+
static ConsoleLogTarget()
{
_logColors = new ConcurrentDictionary {
@@ -19,9 +23,10 @@ namespace Ryujinx.Common.Logging
};
}
- public ConsoleLogTarget()
+ public ConsoleLogTarget(string name)
{
_formatter = new DefaultLogFormatter();
+ _name = name;
}
public void Log(object sender, LogEventArgs args)
diff --git a/Ryujinx.Common/Logging/Targets/FileLogTarget.cs b/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
index 85dc82497..4db5f7bce 100644
--- a/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
+++ b/Ryujinx.Common/Logging/Targets/FileLogTarget.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
using System.Text;
namespace Ryujinx.Common.Logging
@@ -9,13 +10,17 @@ namespace Ryujinx.Common.Logging
private readonly StreamWriter _logWriter;
private readonly ILogFormatter _formatter;
+ private readonly string _name;
- public FileLogTarget(string path)
- : this(path, FileShare.Read, FileMode.Append)
+ string ILogTarget.Name { get => _name; }
+
+ public FileLogTarget(string path, string name)
+ : this(path, name, FileShare.Read, FileMode.Append)
{ }
- public FileLogTarget(string path, FileShare fileShare, FileMode fileMode)
+ public FileLogTarget(string path, string name, FileShare fileShare, FileMode fileMode)
{
+ _name = name;
_logWriter = new StreamWriter(File.Open(path, fileMode, FileAccess.Write, fileShare));
_formatter = new DefaultLogFormatter();
}
diff --git a/Ryujinx.Common/Logging/Targets/ILogTarget.cs b/Ryujinx.Common/Logging/Targets/ILogTarget.cs
index 261c5e64b..d4d26a936 100644
--- a/Ryujinx.Common/Logging/Targets/ILogTarget.cs
+++ b/Ryujinx.Common/Logging/Targets/ILogTarget.cs
@@ -5,5 +5,7 @@ namespace Ryujinx.Common.Logging
public interface ILogTarget : IDisposable
{
void Log(object sender, LogEventArgs args);
+
+ string Name { get; }
}
}
diff --git a/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs b/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs
index 410394aa2..3729b18d1 100644
--- a/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs
+++ b/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
using Utf8Json;
namespace Ryujinx.Common.Logging
@@ -7,10 +8,14 @@ namespace Ryujinx.Common.Logging
{
private Stream _stream;
private bool _leaveOpen;
+ private string _name;
- public JsonLogTarget(Stream stream)
+ string ILogTarget.Name { get => _name; }
+
+ public JsonLogTarget(Stream stream, string name)
{
_stream = stream;
+ _name = name;
}
public JsonLogTarget(Stream stream, bool leaveOpen)
diff --git a/Ryujinx.Common/ReactiveObject.cs b/Ryujinx.Common/ReactiveObject.cs
new file mode 100644
index 000000000..be30e9b2c
--- /dev/null
+++ b/Ryujinx.Common/ReactiveObject.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Threading;
+
+namespace Ryujinx.Common
+{
+ public class ReactiveObject
+ {
+ private ReaderWriterLock _readerWriterLock = new ReaderWriterLock();
+ private T _value;
+
+ public event EventHandler> Event;
+
+ public T Value
+ {
+ get
+ {
+ _readerWriterLock.AcquireReaderLock(Timeout.Infinite);
+ T value = _value;
+ _readerWriterLock.ReleaseReaderLock();
+
+ return value;
+ }
+ set
+ {
+ _readerWriterLock.AcquireWriterLock(Timeout.Infinite);
+
+ T oldValue = _value;
+
+ _value = value;
+
+ _readerWriterLock.ReleaseWriterLock();
+
+ if (oldValue == null || !oldValue.Equals(_value))
+ {
+ Event?.Invoke(this, new ReactiveEventArgs(oldValue, value));
+ }
+ }
+ }
+
+ public static implicit operator T(ReactiveObject obj)
+ {
+ return obj.Value;
+ }
+ }
+
+ public class ReactiveEventArgs
+ {
+ public T OldValue { get; }
+ public T NewValue { get; }
+
+ public ReactiveEventArgs(T oldValue, T newValue)
+ {
+ OldValue = oldValue;
+ NewValue = newValue;
+ }
+ }
+}
diff --git a/Ryujinx.Common/Ryujinx.Common.csproj b/Ryujinx.Common/Ryujinx.Common.csproj
index c777b402c..7f6fa3232 100644
--- a/Ryujinx.Common/Ryujinx.Common.csproj
+++ b/Ryujinx.Common/Ryujinx.Common.csproj
@@ -27,6 +27,7 @@
+
diff --git a/Ryujinx.HLE/Input/Hid.cs b/Ryujinx.HLE/Input/Hid.cs
index 27e6a3087..5cb7f09de 100644
--- a/Ryujinx.HLE/Input/Hid.cs
+++ b/Ryujinx.HLE/Input/Hid.cs
@@ -1,5 +1,7 @@
using Ryujinx.Common;
+using Ryujinx.Configuration.Hid;
using Ryujinx.HLE.HOS;
+using System;
namespace Ryujinx.HLE.Input
{
@@ -47,18 +49,31 @@ namespace Ryujinx.HLE.Input
_keyboardOffset = HidPosition + HidKeyboardOffset;
}
- public void InitializePrimaryController(ControllerStatus controllerType)
+ private static ControllerStatus ConvertControllerTypeToState(ControllerType controllerType)
{
- ControllerId controllerId = controllerType == ControllerStatus.Handheld ?
+ switch (controllerType)
+ {
+ case ControllerType.Handheld: return ControllerStatus.Handheld;
+ case ControllerType.NpadLeft: return ControllerStatus.NpadLeft;
+ case ControllerType.NpadRight: return ControllerStatus.NpadRight;
+ case ControllerType.NpadPair: return ControllerStatus.NpadPair;
+ case ControllerType.ProController: return ControllerStatus.ProController;
+ default: throw new NotImplementedException();
+ }
+ }
+
+ public void InitializePrimaryController(ControllerType controllerType)
+ {
+ ControllerId controllerId = controllerType == ControllerType.Handheld ?
ControllerId.ControllerHandheld : ControllerId.ControllerPlayer1;
- if (controllerType == ControllerStatus.ProController)
+ if (controllerType == ControllerType.ProController)
{
PrimaryController = new ProController(_device, NpadColor.Black, NpadColor.Black);
}
else
{
- PrimaryController = new NpadController(controllerType,
+ PrimaryController = new NpadController(ConvertControllerTypeToState(controllerType),
_device,
(NpadColor.BodyNeonRed, NpadColor.BodyNeonRed),
(NpadColor.ButtonsNeonBlue, NpadColor.ButtonsNeonBlue));
@@ -67,11 +82,6 @@ namespace Ryujinx.HLE.Input
PrimaryController.Connect(controllerId);
}
- public void InitializeKeyboard()
- {
- _device.Memory.FillWithZeros(HidPosition + HidKeyboardOffset, HidKeyboardSize);
- }
-
public ControllerButtons UpdateStickButtons(
JoystickPosition leftStick,
JoystickPosition rightStick)
diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs
index 4a15f616e..a4d07f6ac 100644
--- a/Ryujinx.HLE/Switch.cs
+++ b/Ryujinx.HLE/Switch.cs
@@ -1,8 +1,12 @@
+using LibHac.FsSystem;
using Ryujinx.Audio;
+using Ryujinx.Configuration;
using Ryujinx.Graphics;
using Ryujinx.Graphics.Gal;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
+using Ryujinx.HLE.HOS.Services;
+using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Input;
using System;
using System.Threading;
@@ -60,6 +64,29 @@ namespace Ryujinx.HLE
VsyncEvent = new AutoResetEvent(true);
}
+ public void Initialize()
+ {
+ System.State.SetLanguage((SystemLanguage)ConfigurationState.Instance.System.Language.Value);
+
+ EnableDeviceVsync = ConfigurationState.Instance.Graphics.EnableVsync;
+
+ // TODO: Make this reloadable and implement Docking/Undocking logic.
+ System.State.DockedMode = ConfigurationState.Instance.System.EnableDockedMode;
+
+ if (ConfigurationState.Instance.System.EnableMulticoreScheduling)
+ {
+ System.EnableMultiCoreScheduling();
+ }
+
+ System.FsIntegrityCheckLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
+ ? IntegrityCheckLevel.ErrorOnInvalid
+ : IntegrityCheckLevel.None;
+
+ System.GlobalAccessLogMode = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
+
+ ServiceConfiguration.IgnoreMissingServices = ConfigurationState.Instance.System.IgnoreMissingServices;
+ }
+
public void LoadCart(string exeFsDir, string romFsFile = null)
{
System.LoadCart(exeFsDir, romFsFile);
diff --git a/Ryujinx/Config.json b/Ryujinx/Config.json
index 8463081fa..e35a67acd 100644
--- a/Ryujinx/Config.json
+++ b/Ryujinx/Config.json
@@ -1,4 +1,5 @@
{
+ "version": 1,
"graphics_shaders_dump_path": "",
"logging_enable_debug": false,
"logging_enable_stub": true,
@@ -7,9 +8,7 @@
"logging_enable_error": true,
"logging_enable_guest": true,
"logging_enable_fs_access_log": false,
- "logging_filtered_classes": [
-
- ],
+ "logging_filtered_classes": [],
"enable_file_log": true,
"system_language": "AmericanEnglish",
"docked_mode": false,
@@ -32,9 +31,7 @@
"file_size_column": true,
"path_column": true
},
- "game_dirs": [
-
- ],
+ "game_dirs": [],
"enable_custom_theme": false,
"custom_theme_path": "",
"enable_keyboard": false,
diff --git a/Ryujinx/Configuration/DiscordIntegrationModule.cs b/Ryujinx/Configuration/DiscordIntegrationModule.cs
new file mode 100644
index 000000000..15540a1c8
--- /dev/null
+++ b/Ryujinx/Configuration/DiscordIntegrationModule.cs
@@ -0,0 +1,92 @@
+using DiscordRPC;
+using Ryujinx.Common;
+using System;
+using System.IO;
+using System.Linq;
+
+namespace Ryujinx.Configuration
+{
+ static class DiscordIntegrationModule
+ {
+ private static DiscordRpcClient DiscordClient;
+
+ private static string LargeDescription = "Ryujinx is a Nintendo Switch emulator.";
+
+ public static RichPresence DiscordPresence { get; private set; }
+
+ public static void Initialize()
+ {
+ DiscordPresence = new RichPresence
+ {
+ Assets = new Assets
+ {
+ LargeImageKey = "ryujinx",
+ LargeImageText = LargeDescription
+ },
+ Details = "Main Menu",
+ State = "Idling",
+ Timestamps = new Timestamps(DateTime.UtcNow)
+ };
+
+ ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
+ }
+
+ private static void Update(object sender, ReactiveEventArgs e)
+ {
+ if (e.OldValue != e.NewValue)
+ {
+ // If the integration was active, disable it and unload everything
+ if (e.OldValue)
+ {
+ DiscordClient?.Dispose();
+
+ DiscordClient = null;
+ }
+
+ // If we need to activate it and the client isn't active, initialize it
+ if (e.NewValue && DiscordClient == null)
+ {
+ DiscordClient = new DiscordRpcClient("568815339807309834");
+
+ DiscordClient.Initialize();
+ DiscordClient.SetPresence(DiscordPresence);
+ }
+ }
+ }
+
+ public static void SwitchToPlayingState(string titleId, string titleName)
+ {
+ if (File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RPsupported.dat")).Contains(titleId))
+ {
+ DiscordPresence.Assets.LargeImageKey = titleId;
+ }
+
+ string state = titleId;
+
+ if (state == null)
+ {
+ state = "Ryujinx";
+ }
+ else
+ {
+ state = state.ToUpper();
+ }
+
+ string details = "Idling";
+
+ if (titleName != null)
+ {
+ details = $"Playing {titleName}";
+ }
+
+ DiscordPresence.Details = details;
+ DiscordPresence.State = state;
+ DiscordPresence.Assets.LargeImageText = titleName;
+ DiscordPresence.Assets.SmallImageKey = "ryujinx";
+ DiscordPresence.Assets.SmallImageText = LargeDescription;
+ DiscordPresence.Timestamps = new Timestamps(DateTime.UtcNow);
+
+ DiscordClient?.SetPresence(DiscordPresence);
+ }
+ }
+}
diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs
index 96e9e8dec..98b8d692d 100644
--- a/Ryujinx/Program.cs
+++ b/Ryujinx/Program.cs
@@ -1,5 +1,6 @@
using Gtk;
using Ryujinx.Common.Logging;
+using Ryujinx.Configuration;
using Ryujinx.Profiler;
using Ryujinx.Ui;
using System;
@@ -16,9 +17,32 @@ namespace Ryujinx
string systemPath = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("Path", $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin")};{systemPath}");
- AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
- AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
- GLib.ExceptionManager.UnhandledException += Glib_UnhandledException;
+ GLib.ExceptionManager.UnhandledException += Glib_UnhandledException;
+
+ // Initialize the configuration
+ ConfigurationState.Initialize();
+
+ // Initialize the logger system
+ LoggerModule.Initialize();
+
+ // Initialize Discord integration
+ DiscordIntegrationModule.Initialize();
+
+ string configurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
+
+ // Now load the configuration as the other subsystems are now registered
+ if (File.Exists(configurationPath))
+ {
+ ConfigurationFileFormat configurationFileFormat = ConfigurationFileFormat.Load(configurationPath);
+ ConfigurationState.Instance.Load(configurationFileFormat);
+ }
+ else
+ {
+ // No configuration, we load the default values and save it on disk
+ ConfigurationState.Instance.LoadDefault();
+ ConfigurationState.Instance.ToFileFormat().SaveConfig(configurationPath);
+ }
+
Profile.Initialize();
@@ -42,23 +66,6 @@ namespace Ryujinx
Application.Run();
}
- private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
- {
- Logger.Shutdown();
- }
-
- private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
- {
- Exception exception = e.ExceptionObject as Exception;
-
- Logger.PrintError(LogClass.Emulation, $"Unhandled exception caught: {exception}");
-
- if (e.IsTerminating)
- {
- Logger.Shutdown();
- }
- }
-
private static void Glib_UnhandledException(GLib.UnhandledExceptionArgs e)
{
Exception exception = e.ExceptionObject as Exception;
diff --git a/Ryujinx/Ryujinx.csproj b/Ryujinx/Ryujinx.csproj
index c54beffe4..b231ddb8d 100644
--- a/Ryujinx/Ryujinx.csproj
+++ b/Ryujinx/Ryujinx.csproj
@@ -71,7 +71,6 @@
-
diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs
index c23a36929..e1994803a 100644
--- a/Ryujinx/Ui/GLScreen.cs
+++ b/Ryujinx/Ui/GLScreen.cs
@@ -1,10 +1,12 @@
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
+using Ryujinx.Configuration;
using Ryujinx.Graphics.Gal;
using Ryujinx.HLE;
using Ryujinx.HLE.Input;
using Ryujinx.Profiler.UI;
+using Ryujinx.Ui;
using System;
using System.Threading;
@@ -29,6 +31,8 @@ namespace Ryujinx.Ui
private MouseState? _mouse = null;
+ private Input.NpadController _primaryController;
+
private Thread _renderThread;
private bool _resizeEvent;
@@ -50,6 +54,8 @@ namespace Ryujinx.Ui
_device = device;
_renderer = renderer;
+ _primaryController = new Input.NpadController(ConfigurationState.Instance.Hid.JoystickControls);
+
Location = new Point(
(DisplayDevice.Default.Width / 2) - (Width / 2),
(DisplayDevice.Default.Height / 2) - (Height / 2));
@@ -162,16 +168,16 @@ namespace Ryujinx.Ui
#endif
// Normal Input
- currentHotkeyButtons = Configuration.Instance.KeyboardControls.GetHotkeyButtons(keyboard);
- currentButton = Configuration.Instance.KeyboardControls.GetButtons(keyboard);
+ currentHotkeyButtons = KeyboardControls.GetHotkeyButtons(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
+ currentButton = KeyboardControls.GetButtons(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
- if (Configuration.Instance.EnableKeyboard)
+ if (ConfigurationState.Instance.Hid.EnableKeyboard)
{
- hidKeyboard = Configuration.Instance.KeyboardControls.GetKeysDown(keyboard);
+ hidKeyboard = KeyboardControls.GetKeysDown(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
}
- (leftJoystickDx, leftJoystickDy) = Configuration.Instance.KeyboardControls.GetLeftStick(keyboard);
- (rightJoystickDx, rightJoystickDy) = Configuration.Instance.KeyboardControls.GetRightStick(keyboard);
+ (leftJoystickDx, leftJoystickDy) = KeyboardControls.GetLeftStick(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
+ (rightJoystickDx, rightJoystickDy) = KeyboardControls.GetRightStick(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
}
if (!hidKeyboard.HasValue)
@@ -183,17 +189,17 @@ namespace Ryujinx.Ui
};
}
- currentButton |= Configuration.Instance.JoystickControls.GetButtons();
+ currentButton |= _primaryController.GetButtons();
// Keyboard has priority stick-wise
if (leftJoystickDx == 0 && leftJoystickDy == 0)
{
- (leftJoystickDx, leftJoystickDy) = Configuration.Instance.JoystickControls.GetLeftStick();
+ (leftJoystickDx, leftJoystickDy) = _primaryController.GetLeftStick();
}
if (rightJoystickDx == 0 && rightJoystickDy == 0)
{
- (rightJoystickDx, rightJoystickDy) = Configuration.Instance.JoystickControls.GetRightStick();
+ (rightJoystickDx, rightJoystickDy) = _primaryController.GetRightStick();
}
leftJoystick = new JoystickPosition
@@ -269,7 +275,7 @@ namespace Ryujinx.Ui
_device.Hid.SetTouchPoints();
}
- if (Configuration.Instance.EnableKeyboard && hidKeyboard.HasValue)
+ if (ConfigurationState.Instance.Hid.EnableKeyboard && hidKeyboard.HasValue)
{
_device.Hid.WriteKeyboard(hidKeyboard.Value);
}
diff --git a/Ryujinx/Ui/NpadKeyboard.cs b/Ryujinx/Ui/KeyboardControls.cs
similarity index 74%
rename from Ryujinx/Ui/NpadKeyboard.cs
rename to Ryujinx/Ui/KeyboardControls.cs
index 95fb22218..db9c0cda8 100644
--- a/Ryujinx/Ui/NpadKeyboard.cs
+++ b/Ryujinx/Ui/KeyboardControls.cs
@@ -1,118 +1,67 @@
-using OpenTK.Input;
+using OpenTK.Input;
using Ryujinx.HLE.Input;
+using Ryujinx.UI.Input;
-namespace Ryujinx.Ui.Input
+namespace Ryujinx.Ui
{
- public struct NpadKeyboardLeft
+ public static class KeyboardControls
{
- public Key StickUp;
- public Key StickDown;
- public Key StickLeft;
- public Key StickRight;
- public Key StickButton;
- public Key DPadUp;
- public Key DPadDown;
- public Key DPadLeft;
- public Key DPadRight;
- public Key ButtonMinus;
- public Key ButtonL;
- public Key ButtonZl;
- }
-
- public struct NpadKeyboardRight
- {
- public Key StickUp;
- public Key StickDown;
- public Key StickLeft;
- public Key StickRight;
- public Key StickButton;
- public Key ButtonA;
- public Key ButtonB;
- public Key ButtonX;
- public Key ButtonY;
- public Key ButtonPlus;
- public Key ButtonR;
- public Key ButtonZr;
- }
-
- public struct KeyboardHotkeys
- {
- public Key ToggleVsync;
- }
-
- public class NpadKeyboard
- {
- ///
- /// 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; private set; }
-
- public ControllerButtons GetButtons(KeyboardState keyboard)
+ public static ControllerButtons GetButtons(NpadKeyboard npad, KeyboardState keyboard)
{
ControllerButtons buttons = 0;
- if (keyboard[(Key)LeftJoycon.StickButton]) buttons |= ControllerButtons.StickLeft;
- if (keyboard[(Key)LeftJoycon.DPadUp]) buttons |= ControllerButtons.DpadUp;
- if (keyboard[(Key)LeftJoycon.DPadDown]) buttons |= ControllerButtons.DpadDown;
- if (keyboard[(Key)LeftJoycon.DPadLeft]) buttons |= ControllerButtons.DpadLeft;
- if (keyboard[(Key)LeftJoycon.DPadRight]) buttons |= ControllerButtons.DPadRight;
- if (keyboard[(Key)LeftJoycon.ButtonMinus]) buttons |= ControllerButtons.Minus;
- if (keyboard[(Key)LeftJoycon.ButtonL]) buttons |= ControllerButtons.L;
- if (keyboard[(Key)LeftJoycon.ButtonZl]) buttons |= ControllerButtons.Zl;
+ if (keyboard[(Key)npad.LeftJoycon.StickButton]) buttons |= ControllerButtons.StickLeft;
+ if (keyboard[(Key)npad.LeftJoycon.DPadUp]) buttons |= ControllerButtons.DpadUp;
+ if (keyboard[(Key)npad.LeftJoycon.DPadDown]) buttons |= ControllerButtons.DpadDown;
+ if (keyboard[(Key)npad.LeftJoycon.DPadLeft]) buttons |= ControllerButtons.DpadLeft;
+ if (keyboard[(Key)npad.LeftJoycon.DPadRight]) buttons |= ControllerButtons.DPadRight;
+ if (keyboard[(Key)npad.LeftJoycon.ButtonMinus]) buttons |= ControllerButtons.Minus;
+ if (keyboard[(Key)npad.LeftJoycon.ButtonL]) buttons |= ControllerButtons.L;
+ if (keyboard[(Key)npad.LeftJoycon.ButtonZl]) buttons |= ControllerButtons.Zl;
- if (keyboard[(Key)RightJoycon.StickButton]) buttons |= ControllerButtons.StickRight;
- if (keyboard[(Key)RightJoycon.ButtonA]) buttons |= ControllerButtons.A;
- if (keyboard[(Key)RightJoycon.ButtonB]) buttons |= ControllerButtons.B;
- if (keyboard[(Key)RightJoycon.ButtonX]) buttons |= ControllerButtons.X;
- if (keyboard[(Key)RightJoycon.ButtonY]) buttons |= ControllerButtons.Y;
- if (keyboard[(Key)RightJoycon.ButtonPlus]) buttons |= ControllerButtons.Plus;
- if (keyboard[(Key)RightJoycon.ButtonR]) buttons |= ControllerButtons.R;
- if (keyboard[(Key)RightJoycon.ButtonZr]) buttons |= ControllerButtons.Zr;
+ if (keyboard[(Key)npad.RightJoycon.StickButton]) buttons |= ControllerButtons.StickRight;
+ if (keyboard[(Key)npad.RightJoycon.ButtonA]) buttons |= ControllerButtons.A;
+ if (keyboard[(Key)npad.RightJoycon.ButtonB]) buttons |= ControllerButtons.B;
+ if (keyboard[(Key)npad.RightJoycon.ButtonX]) buttons |= ControllerButtons.X;
+ if (keyboard[(Key)npad.RightJoycon.ButtonY]) buttons |= ControllerButtons.Y;
+ if (keyboard[(Key)npad.RightJoycon.ButtonPlus]) buttons |= ControllerButtons.Plus;
+ if (keyboard[(Key)npad.RightJoycon.ButtonR]) buttons |= ControllerButtons.R;
+ if (keyboard[(Key)npad.RightJoycon.ButtonZr]) buttons |= ControllerButtons.Zr;
return buttons;
}
- public (short, short) GetLeftStick(KeyboardState keyboard)
+ public static (short, short) GetLeftStick(NpadKeyboard npad, KeyboardState keyboard)
{
short dx = 0;
short dy = 0;
- if (keyboard[(Key)LeftJoycon.StickUp]) dy = short.MaxValue;
- if (keyboard[(Key)LeftJoycon.StickDown]) dy = -short.MaxValue;
- if (keyboard[(Key)LeftJoycon.StickLeft]) dx = -short.MaxValue;
- if (keyboard[(Key)LeftJoycon.StickRight]) dx = short.MaxValue;
+ 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;
return (dx, dy);
}
- public (short, short) GetRightStick(KeyboardState keyboard)
+ public static (short, short) GetRightStick(NpadKeyboard npad, KeyboardState keyboard)
{
short dx = 0;
short dy = 0;
- if (keyboard[(Key)RightJoycon.StickUp]) dy = short.MaxValue;
- if (keyboard[(Key)RightJoycon.StickDown]) dy = -short.MaxValue;
- if (keyboard[(Key)RightJoycon.StickLeft]) dx = -short.MaxValue;
- if (keyboard[(Key)RightJoycon.StickRight]) dx = short.MaxValue;
+ 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;
return (dx, dy);
}
- public HotkeyButtons GetHotkeyButtons(KeyboardState keyboard)
+ public static HotkeyButtons GetHotkeyButtons(NpadKeyboard npad, KeyboardState keyboard)
{
HotkeyButtons buttons = 0;
- if (keyboard[(Key)Hotkeys.ToggleVsync]) buttons |= HotkeyButtons.ToggleVSync;
+ if (keyboard[(Key)npad.Hotkeys.ToggleVsync]) buttons |= HotkeyButtons.ToggleVSync;
return buttons;
}
@@ -267,7 +216,7 @@ namespace Ryujinx.Ui.Input
new KeyMappingEntry { TargetKey = Key.NumLock, Target = 10 },
};
- public HLE.Input.Keyboard GetKeysDown(KeyboardState keyboard)
+ public static HLE.Input.Keyboard GetKeysDown(NpadKeyboard npad, KeyboardState keyboard)
{
HLE.Input.Keyboard hidKeyboard = new HLE.Input.Keyboard
{
diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs
index a24f3ed05..e0bd84947 100644
--- a/Ryujinx/Ui/MainWindow.cs
+++ b/Ryujinx/Ui/MainWindow.cs
@@ -1,22 +1,22 @@
-using DiscordRPC;
using Gtk;
-using JsonPrettyPrinterPlus;
using Ryujinx.Audio;
using Ryujinx.Common.Logging;
-using Ryujinx.Graphics.Gal.OpenGL;
using Ryujinx.Graphics.Gal;
-using Ryujinx.HLE.FileSystem;
+using Ryujinx.Graphics.Gal.OpenGL;
using Ryujinx.Profiler;
using System;
-using System.Diagnostics;
using System.IO;
-using System.Linq;
using System.Reflection;
using System.Text;
-using System.Threading.Tasks;
using System.Threading;
+using Ryujinx.Configuration;
+using System.Diagnostics;
+using System.Threading.Tasks;
using Utf8Json;
+using JsonPrettyPrinterPlus;
using Utf8Json.Resolvers;
+using Ryujinx.HLE.FileSystem;
+
using GUI = Gtk.Builder.ObjectAttribute;
@@ -50,12 +50,6 @@ namespace Ryujinx.Ui
private static TreeView _treeView;
- public static bool DiscordIntegrationEnabled { get; set; }
-
- public static DiscordRpcClient DiscordClient;
-
- public static RichPresence DiscordPresence;
-
#pragma warning disable CS0649
#pragma warning disable IDE0044
[GUI] Window _mainWin;
@@ -91,60 +85,39 @@ namespace Ryujinx.Ui
_audioOut = InitializeAudioEngine();
- _device = new HLE.Switch(_renderer, _audioOut);
+ // TODO: Initialization and dispose of HLE.Switch when starting/stoping emulation.
+ _device = InitializeSwitchInstance();
_treeView = _gameTable;
- Configuration.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
- Configuration.InitialConfigure(_device);
-
ApplyTheme();
- if (DiscordIntegrationEnabled)
- {
- DiscordClient = new DiscordRpcClient("568815339807309834");
- DiscordPresence = new RichPresence
- {
- Assets = new Assets
- {
- LargeImageKey = "ryujinx",
- LargeImageText = "Ryujinx is an emulator for the Nintendo Switch"
- },
- Details = "Main Menu",
- State = "Idling",
- Timestamps = new Timestamps(DateTime.UtcNow)
- };
-
- DiscordClient.Initialize();
- DiscordClient.SetPresence(DiscordPresence);
- }
-
_mainWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
_stopEmulation.Sensitive = false;
- if (SwitchSettings.SwitchConfig.GuiColumns.FavColumn) { _favToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.IconColumn) { _iconToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.AppColumn) { _appToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.DevColumn) { _developerToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.VersionColumn) { _versionToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.TimePlayedColumn) { _timePlayedToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.LastPlayedColumn) { _lastPlayedToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.FileExtColumn) { _fileExtToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.FileSizeColumn) { _fileSizeToggle.Active = true; }
- if (SwitchSettings.SwitchConfig.GuiColumns.PathColumn) { _pathToggle.Active = true; }
+ if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) _iconToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _appToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.DevColumn) _developerToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.VersionColumn) _versionToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn) _timePlayedToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn) _lastPlayedToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn) _fileExtToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn) _fileSizeToggle.Active = true;
+ if (ConfigurationState.Instance.Ui.GuiColumns.PathColumn) _pathToggle.Active = true;
_gameTable.Model = _tableStore = new ListStore(
- typeof(bool),
- typeof(Gdk.Pixbuf),
- typeof(string),
- typeof(string),
- typeof(string),
- typeof(string),
- typeof(string),
- typeof(string),
- typeof(string),
+ typeof(bool),
+ typeof(Gdk.Pixbuf),
+ typeof(string),
+ typeof(string),
+ typeof(string),
+ typeof(string),
+ typeof(string),
+ typeof(string),
+ typeof(string),
typeof(string));
-
+
_tableStore.SetSortFunc(5, TimePlayedSort);
_tableStore.SetSortFunc(6, LastPlayedSort);
_tableStore.SetSortFunc(8, FileSizeSort);
@@ -158,22 +131,22 @@ namespace Ryujinx.Ui
internal static void ApplyTheme()
{
- if (!SwitchSettings.SwitchConfig.EnableCustomTheme)
+ if (!ConfigurationState.Instance.Ui.EnableCustomTheme)
{
return;
}
- if (File.Exists(SwitchSettings.SwitchConfig.CustomThemePath) && (System.IO.Path.GetExtension(SwitchSettings.SwitchConfig.CustomThemePath) == ".css"))
+ if (File.Exists(ConfigurationState.Instance.Ui.CustomThemePath) && (System.IO.Path.GetExtension(ConfigurationState.Instance.Ui.CustomThemePath) == ".css"))
{
CssProvider cssProvider = new CssProvider();
- cssProvider.LoadFromPath(SwitchSettings.SwitchConfig.CustomThemePath);
+ cssProvider.LoadFromPath(ConfigurationState.Instance.Ui.CustomThemePath);
StyleContext.AddProviderForScreen(Gdk.Screen.Default, cssProvider, 800);
}
else
{
- Logger.PrintWarning(LogClass.Application, $"The \"custom_theme_path\" section in \"Config.json\" contains an invalid path: \"{SwitchSettings.SwitchConfig.CustomThemePath}\".");
+ Logger.PrintWarning(LogClass.Application, $"The \"custom_theme_path\" section in \"Config.json\" contains an invalid path: \"{ConfigurationState.Instance.Ui.CustomThemePath}\".");
}
}
@@ -187,39 +160,48 @@ namespace Ryujinx.Ui
CellRendererToggle favToggle = new CellRendererToggle();
favToggle.Toggled += FavToggle_Toggled;
- if (SwitchSettings.SwitchConfig.GuiColumns.FavColumn) { _gameTable.AppendColumn("Fav", favToggle, "active", 0); }
- if (SwitchSettings.SwitchConfig.GuiColumns.IconColumn) { _gameTable.AppendColumn("Icon", new CellRendererPixbuf(), "pixbuf", 1); }
- if (SwitchSettings.SwitchConfig.GuiColumns.AppColumn) { _gameTable.AppendColumn("Application", new CellRendererText(), "text", 2); }
- if (SwitchSettings.SwitchConfig.GuiColumns.DevColumn) { _gameTable.AppendColumn("Developer", new CellRendererText(), "text", 3); }
- if (SwitchSettings.SwitchConfig.GuiColumns.VersionColumn) { _gameTable.AppendColumn("Version", new CellRendererText(), "text", 4); }
- if (SwitchSettings.SwitchConfig.GuiColumns.TimePlayedColumn) { _gameTable.AppendColumn("Time Played", new CellRendererText(), "text", 5); }
- if (SwitchSettings.SwitchConfig.GuiColumns.LastPlayedColumn) { _gameTable.AppendColumn("Last Played", new CellRendererText(), "text", 6); }
- if (SwitchSettings.SwitchConfig.GuiColumns.FileExtColumn) { _gameTable.AppendColumn("File Ext", new CellRendererText(), "text", 7); }
- if (SwitchSettings.SwitchConfig.GuiColumns.FileSizeColumn) { _gameTable.AppendColumn("File Size", new CellRendererText(), "text", 8); }
- if (SwitchSettings.SwitchConfig.GuiColumns.PathColumn) { _gameTable.AppendColumn("Path", new CellRendererText(), "text", 9); }
+ if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _gameTable.AppendColumn("Fav", favToggle, "active", 0);
+ if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) _gameTable.AppendColumn("Icon", new CellRendererPixbuf(), "pixbuf", 1);
+ if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _gameTable.AppendColumn("Application", new CellRendererText(), "text", 2);
+ if (ConfigurationState.Instance.Ui.GuiColumns.DevColumn) _gameTable.AppendColumn("Developer", new CellRendererText(), "text", 3);
+ if (ConfigurationState.Instance.Ui.GuiColumns.VersionColumn) _gameTable.AppendColumn("Version", new CellRendererText(), "text", 4);
+ if (ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn) _gameTable.AppendColumn("Time Played", new CellRendererText(), "text", 5);
+ if (ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn) _gameTable.AppendColumn("Last Played", new CellRendererText(), "text", 6);
+ if (ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn) _gameTable.AppendColumn("File Ext", new CellRendererText(), "text", 7);
+ if (ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn) _gameTable.AppendColumn("File Size", new CellRendererText(), "text", 8);
+ if (ConfigurationState.Instance.Ui.GuiColumns.PathColumn) _gameTable.AppendColumn("Path", new CellRendererText(), "text", 9);
foreach (TreeViewColumn column in _gameTable.Columns)
{
- if (column.Title == "Fav") { _favColumn = column; }
- else if (column.Title == "Application") { _appColumn = column; }
- else if (column.Title == "Developer") { _devColumn = column; }
- else if (column.Title == "Version") { _versionColumn = column; }
- else if (column.Title == "Time Played") { _timePlayedColumn = column; }
- else if (column.Title == "Last Played") { _lastPlayedColumn = column; }
- else if (column.Title == "File Ext") { _fileExtColumn = column; }
- else if (column.Title == "File Size") { _fileSizeColumn = column; }
- else if (column.Title == "Path") { _pathColumn = column; }
+ if (column.Title == "Fav") _favColumn = column;
+ else if (column.Title == "Application") _appColumn = column;
+ else if (column.Title == "Developer") _devColumn = column;
+ else if (column.Title == "Version") _versionColumn = column;
+ else if (column.Title == "Time Played") _timePlayedColumn = column;
+ else if (column.Title == "Last Played") _lastPlayedColumn = column;
+ else if (column.Title == "File Ext") _fileExtColumn = column;
+ else if (column.Title == "File Size") _fileSizeColumn = column;
+ else if (column.Title == "Path") _pathColumn = column;
}
- if (SwitchSettings.SwitchConfig.GuiColumns.FavColumn) { _favColumn.SortColumnId = 0; }
- if (SwitchSettings.SwitchConfig.GuiColumns.IconColumn) { _appColumn.SortColumnId = 2; }
- if (SwitchSettings.SwitchConfig.GuiColumns.AppColumn) { _devColumn.SortColumnId = 3; }
- if (SwitchSettings.SwitchConfig.GuiColumns.DevColumn) { _versionColumn.SortColumnId = 4; }
- if (SwitchSettings.SwitchConfig.GuiColumns.TimePlayedColumn) { _timePlayedColumn.SortColumnId = 5; }
- if (SwitchSettings.SwitchConfig.GuiColumns.LastPlayedColumn) { _lastPlayedColumn.SortColumnId = 6; }
- if (SwitchSettings.SwitchConfig.GuiColumns.FileExtColumn) { _fileExtColumn.SortColumnId = 7; }
- if (SwitchSettings.SwitchConfig.GuiColumns.FileSizeColumn) { _fileSizeColumn.SortColumnId = 8; }
- if (SwitchSettings.SwitchConfig.GuiColumns.PathColumn) { _pathColumn.SortColumnId = 9; }
+ if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favColumn.SortColumnId = 0;
+ if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _appColumn.SortColumnId = 2;
+ if (ConfigurationState.Instance.Ui.GuiColumns.DevColumn) _devColumn.SortColumnId = 3;
+ if (ConfigurationState.Instance.Ui.GuiColumns.VersionColumn) _versionColumn.SortColumnId = 4;
+ if (ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn) _timePlayedColumn.SortColumnId = 5;
+ if (ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn) _lastPlayedColumn.SortColumnId = 6;
+ if (ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn) _fileExtColumn.SortColumnId = 7;
+ if (ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn) _fileSizeColumn.SortColumnId = 8;
+ if (ConfigurationState.Instance.Ui.GuiColumns.PathColumn) _pathColumn.SortColumnId = 9;
+ }
+
+ private HLE.Switch InitializeSwitchInstance()
+ {
+ HLE.Switch instance = new HLE.Switch(_renderer, _audioOut);
+
+ instance.Initialize();
+
+ return instance;
}
internal static async Task UpdateGameTable()
@@ -233,7 +215,7 @@ namespace Ryujinx.Ui
_tableStore.Clear();
- await Task.Run(() => ApplicationLibrary.LoadApplications(SwitchSettings.SwitchConfig.GameDirs, _device.System.KeySet, _device.System.State.DesiredTitleLanguage));
+ await Task.Run(() => ApplicationLibrary.LoadApplications(ConfigurationState.Instance.Ui.GameDirs, _device.System.KeySet, _device.System.State.DesiredTitleLanguage));
_updatingGameTable = false;
}
@@ -248,6 +230,9 @@ namespace Ryujinx.Ui
{
Logger.RestartTime();
+ // TODO: Move this somewhere else + reloadable?
+ GraphicsConfig.ShadersDumpPath = ConfigurationState.Instance.Graphics.ShadersDumpPath;
+
if (Directory.Exists(path))
{
string[] romFsFiles = Directory.GetFiles(path, "*.istorage");
@@ -313,40 +298,7 @@ namespace Ryujinx.Ui
_gameLoaded = true;
_stopEmulation.Sensitive = true;
- if (DiscordIntegrationEnabled)
- {
- if (File.ReadAllLines(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RPsupported.dat")).Contains(_device.System.TitleId))
- {
- DiscordPresence.Assets.LargeImageKey = _device.System.TitleId;
- }
-
- string state = _device.System.TitleId;
-
- if (state == null)
- {
- state = "Ryujinx";
- }
- else
- {
- state = state.ToUpper();
- }
-
- string details = "Idling";
-
- if (_device.System.TitleName != null)
- {
- details = $"Playing {_device.System.TitleName}";
- }
-
- DiscordPresence.Details = details;
- DiscordPresence.State = state;
- DiscordPresence.Assets.LargeImageText = _device.System.TitleName;
- DiscordPresence.Assets.SmallImageKey = "ryujinx";
- DiscordPresence.Assets.SmallImageText = "Ryujinx is an emulator for the Nintendo Switch";
- DiscordPresence.Timestamps = new Timestamps(DateTime.UtcNow);
-
- DiscordClient.SetPresence(DiscordPresence);
- }
+ DiscordIntegrationModule.SwitchToPlayingState(_device.System.TitleId, _device.System.TitleName);
string metadataFolder = System.IO.Path.Combine(new VirtualFileSystem().GetBasePath(), "games", _device.System.TitleId, "gui");
string metadataFile = System.IO.Path.Combine(metadataFolder, "metadata.json");
@@ -384,8 +336,8 @@ namespace Ryujinx.Ui
private static void CreateGameWindow()
{
- Configuration.ConfigureHid(_device, SwitchSettings.SwitchConfig);
-
+ _device.Hid.InitializePrimaryController(ConfigurationState.Instance.Hid.ControllerType);
+
using (_screen = new GlScreen(_device, _renderer))
{
_screen.MainLoop();
@@ -444,7 +396,6 @@ namespace Ryujinx.Ui
Profile.FinishProfiling();
_device.Dispose();
_audioOut.Dispose();
- DiscordClient?.Dispose();
Logger.Shutdown();
Environment.Exit(0);
}
@@ -607,7 +558,7 @@ namespace Ryujinx.Ui
private void Settings_Pressed(object sender, EventArgs args)
{
- SwitchSettings settingsWin = new SwitchSettings(_device);
+ SwitchSettings settingsWin = new SwitchSettings();
settingsWin.Show();
}
@@ -633,121 +584,81 @@ namespace Ryujinx.Ui
private void Fav_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.FavColumn = _favToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.FavColumn.Value = _favToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void Icon_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.IconColumn = _iconToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.IconColumn.Value = _iconToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void Title_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.AppColumn = _appToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.AppColumn.Value = _appToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void Developer_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.DevColumn = _developerToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.DevColumn.Value = _developerToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void Version_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.VersionColumn = _versionToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.VersionColumn.Value = _versionToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void TimePlayed_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.TimePlayedColumn = _timePlayedToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn.Value = _timePlayedToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void LastPlayed_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.LastPlayedColumn = _lastPlayedToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn.Value = _lastPlayedToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void FileExt_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.FileExtColumn = _fileExtToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn.Value = _fileExtToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void FileSize_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.FileSizeColumn = _fileSizeToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn.Value = _fileSizeToggle.Active;
+ SaveConfig();
UpdateColumns();
}
private void Path_Toggled(object sender, EventArgs args)
{
- GuiColumns updatedColumns = SwitchSettings.SwitchConfig.GuiColumns;
-
- updatedColumns.PathColumn = _pathToggle.Active;
- SwitchSettings.SwitchConfig.GuiColumns = updatedColumns;
-
- Configuration.SaveConfig(SwitchSettings.SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ ConfigurationState.Instance.Ui.GuiColumns.PathColumn.Value = _pathToggle.Active;
+ SaveConfig();
UpdateColumns();
}
@@ -865,5 +776,10 @@ namespace Ryujinx.Ui
return 0;
}
}
+
+ public static void SaveConfig()
+ {
+ ConfigurationState.Instance.ToFileFormat().SaveConfig(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
+ }
}
}
diff --git a/Ryujinx/Ui/NpadController.cs b/Ryujinx/Ui/NpadController.cs
index f72c40755..67961b491 100644
--- a/Ryujinx/Ui/NpadController.cs
+++ b/Ryujinx/Ui/NpadController.cs
@@ -1,160 +1,57 @@
using OpenTK;
using OpenTK.Input;
+using Ryujinx.Common.Configuration.Hid;
using Ryujinx.HLE.Input;
using System;
+using InnerNpadController = Ryujinx.Common.Configuration.Hid.NpadController;
+
namespace Ryujinx.Ui.Input
{
- public enum ControllerInputId
- {
- Button0,
- Button1,
- Button2,
- Button3,
- Button4,
- Button5,
- Button6,
- Button7,
- Button8,
- Button9,
- Button10,
- Button11,
- Button12,
- Button13,
- Button14,
- Button15,
- Button16,
- Button17,
- Button18,
- Button19,
- Button20,
- Axis0,
- Axis1,
- Axis2,
- Axis3,
- Axis4,
- Axis5,
- Hat0Up,
- Hat0Down,
- Hat0Left,
- Hat0Right,
- Hat1Up,
- Hat1Down,
- Hat1Left,
- Hat1Right,
- Hat2Up,
- Hat2Down,
- Hat2Left,
- Hat2Right,
- }
-
- public struct NpadControllerLeft
- {
- public ControllerInputId Stick;
- public ControllerInputId StickButton;
- public ControllerInputId ButtonMinus;
- public ControllerInputId ButtonL;
- public ControllerInputId ButtonZl;
- public ControllerInputId DPadUp;
- public ControllerInputId DPadDown;
- public ControllerInputId DPadLeft;
- public ControllerInputId DPadRight;
- }
-
- public struct NpadControllerRight
- {
- public ControllerInputId Stick;
- public ControllerInputId StickButton;
- public ControllerInputId ButtonA;
- public ControllerInputId ButtonB;
- public ControllerInputId ButtonX;
- public ControllerInputId ButtonY;
- public ControllerInputId ButtonPlus;
- public ControllerInputId ButtonR;
- public ControllerInputId ButtonZr;
- }
-
public class NpadController
{
- ///
- /// Enables or disables controller support
- ///
- public bool Enabled { get; private set; }
+ private InnerNpadController _inner;
- ///
- /// Controller Device Index
- ///
- public int Index { get; private set; }
-
- ///
- /// Controller Analog Stick Deadzone
- ///
- public float Deadzone { get; private set; }
-
- ///
- /// Controller Trigger Threshold
- ///
- public float TriggerThreshold { get; private set; }
-
- ///
- /// Left JoyCon Controller Bindings
- ///
- public NpadControllerLeft LeftJoycon { get; private set; }
-
- ///
- /// Right JoyCon Controller Bindings
- ///
- public NpadControllerRight RightJoycon { get; private set; }
-
- public NpadController(
- bool enabled,
- int index,
- float deadzone,
- float triggerThreshold,
- NpadControllerLeft leftJoycon,
- NpadControllerRight rightJoycon)
+ // 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)
{
- Enabled = enabled;
- Index = index;
- Deadzone = deadzone;
- TriggerThreshold = triggerThreshold;
- LeftJoycon = leftJoycon;
- RightJoycon = rightJoycon;
+ _inner = inner;
}
- public void SetEnabled(bool enabled)
+ private bool IsEnabled()
{
- Enabled = enabled;
+ return _inner.Enabled && Joystick.GetState(_inner.Index).IsConnected;
}
public ControllerButtons GetButtons()
{
- if (!Enabled)
+ if (!IsEnabled())
{
return 0;
}
- JoystickState joystickState = Joystick.GetState(Index);
+ JoystickState joystickState = Joystick.GetState(_inner.Index);
ControllerButtons buttons = 0;
- if (IsActivated(joystickState, LeftJoycon.DPadUp)) buttons |= ControllerButtons.DpadUp;
- if (IsActivated(joystickState, LeftJoycon.DPadDown)) buttons |= ControllerButtons.DpadDown;
- if (IsActivated(joystickState, LeftJoycon.DPadLeft)) buttons |= ControllerButtons.DpadLeft;
- if (IsActivated(joystickState, LeftJoycon.DPadRight)) buttons |= ControllerButtons.DPadRight;
- if (IsActivated(joystickState, LeftJoycon.StickButton)) buttons |= ControllerButtons.StickLeft;
- if (IsActivated(joystickState, LeftJoycon.ButtonMinus)) buttons |= ControllerButtons.Minus;
- if (IsActivated(joystickState, LeftJoycon.ButtonL)) buttons |= ControllerButtons.L;
- if (IsActivated(joystickState, LeftJoycon.ButtonZl)) buttons |= ControllerButtons.Zl;
+ if (IsActivated(joystickState, _inner.LeftJoycon.DPadUp)) buttons |= ControllerButtons.DpadUp;
+ if (IsActivated(joystickState, _inner.LeftJoycon.DPadDown)) buttons |= ControllerButtons.DpadDown;
+ if (IsActivated(joystickState, _inner.LeftJoycon.DPadLeft)) buttons |= ControllerButtons.DpadLeft;
+ if (IsActivated(joystickState, _inner.LeftJoycon.DPadRight)) buttons |= ControllerButtons.DPadRight;
+ if (IsActivated(joystickState, _inner.LeftJoycon.StickButton)) buttons |= ControllerButtons.StickLeft;
+ if (IsActivated(joystickState, _inner.LeftJoycon.ButtonMinus)) buttons |= ControllerButtons.Minus;
+ if (IsActivated(joystickState, _inner.LeftJoycon.ButtonL)) buttons |= ControllerButtons.L;
+ if (IsActivated(joystickState, _inner.LeftJoycon.ButtonZl)) buttons |= ControllerButtons.Zl;
- if (IsActivated(joystickState, RightJoycon.ButtonA)) buttons |= ControllerButtons.A;
- if (IsActivated(joystickState, RightJoycon.ButtonB)) buttons |= ControllerButtons.B;
- if (IsActivated(joystickState, RightJoycon.ButtonX)) buttons |= ControllerButtons.X;
- if (IsActivated(joystickState, RightJoycon.ButtonY)) buttons |= ControllerButtons.Y;
- if (IsActivated(joystickState, RightJoycon.StickButton)) buttons |= ControllerButtons.StickRight;
- if (IsActivated(joystickState, RightJoycon.ButtonPlus)) buttons |= ControllerButtons.Plus;
- if (IsActivated(joystickState, RightJoycon.ButtonR)) buttons |= ControllerButtons.R;
- if (IsActivated(joystickState, RightJoycon.ButtonZr)) buttons |= ControllerButtons.Zr;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonA)) buttons |= ControllerButtons.A;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonB)) buttons |= ControllerButtons.B;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonX)) buttons |= ControllerButtons.X;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonY)) buttons |= ControllerButtons.Y;
+ if (IsActivated(joystickState, _inner.RightJoycon.StickButton)) buttons |= ControllerButtons.StickRight;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonPlus)) buttons |= ControllerButtons.Plus;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonR)) buttons |= ControllerButtons.R;
+ if (IsActivated(joystickState, _inner.RightJoycon.ButtonZr)) buttons |= ControllerButtons.Zr;
return buttons;
}
@@ -169,7 +66,7 @@ namespace Ryujinx.Ui.Input
{
int axis = controllerInputId - ControllerInputId.Axis0;
- return joystickState.GetAxis(axis) > TriggerThreshold;
+ return joystickState.GetAxis(axis) > _inner.TriggerThreshold;
}
else if (controllerInputId <= ControllerInputId.Hat2Right)
{
@@ -190,22 +87,22 @@ namespace Ryujinx.Ui.Input
public (short, short) GetLeftStick()
{
- if (!Enabled)
+ if (!IsEnabled())
{
return (0, 0);
}
- return GetStick(LeftJoycon.Stick);
+ return GetStick(_inner.LeftJoycon.Stick);
}
public (short, short) GetRightStick()
{
- if (!Enabled)
+ if (!IsEnabled())
{
return (0, 0);
}
- return GetStick(RightJoycon.Stick);
+ return GetStick(_inner.RightJoycon.Stick);
}
private (short, short) GetStick(ControllerInputId stickInputId)
@@ -215,7 +112,7 @@ namespace Ryujinx.Ui.Input
return (0, 0);
}
- JoystickState jsState = Joystick.GetState(Index);
+ JoystickState jsState = Joystick.GetState(_inner.Index);
int xAxis = stickInputId - ControllerInputId.Axis0;
@@ -227,8 +124,8 @@ namespace Ryujinx.Ui.Input
private (short, short) ApplyDeadzone(Vector2 axis)
{
- return (ClampAxis(MathF.Abs(axis.X) > Deadzone ? axis.X : 0f),
- ClampAxis(MathF.Abs(axis.Y) > Deadzone ? axis.Y : 0f));
+ 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)
diff --git a/Ryujinx/Ui/SwitchSettings.cs b/Ryujinx/Ui/SwitchSettings.cs
index 955c6b0b6..5c56cf7ea 100644
--- a/Ryujinx/Ui/SwitchSettings.cs
+++ b/Ryujinx/Ui/SwitchSettings.cs
@@ -1,12 +1,12 @@
using Gtk;
-using Ryujinx.HLE.HOS.SystemState;
-using Ryujinx.HLE.Input;
-using Ryujinx.Ui.Input;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
+using Ryujinx.Configuration;
+using Ryujinx.Configuration.System;
+using Ryujinx.Configuration.Hid;
using GUI = Gtk.Builder.ObjectAttribute;
@@ -14,10 +14,6 @@ namespace Ryujinx.Ui
{
public class SwitchSettings : Window
{
- internal static Configuration SwitchConfig { get; set; }
-
- private readonly HLE.Switch _device;
-
private static ListStore _gameDirsBoxStore;
private static bool _listeningForKeypress;
@@ -83,16 +79,12 @@ namespace Ryujinx.Ui
#pragma warning restore CS0649
#pragma warning restore IDE0044
- public static void ConfigureSettings(Configuration instance) { SwitchConfig = instance; }
+ public SwitchSettings() : this(new Builder("Ryujinx.Ui.SwitchSettings.glade")) { }
- public SwitchSettings(HLE.Switch device) : this(new Builder("Ryujinx.Ui.SwitchSettings.glade"), device) { }
-
- private SwitchSettings(Builder builder, HLE.Switch device) : base(builder.GetObject("_settingsWin").Handle)
+ private SwitchSettings(Builder builder) : base(builder.GetObject("_settingsWin").Handle)
{
builder.Autoconnect(this);
- _device = device;
-
_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);
@@ -124,60 +116,123 @@ namespace Ryujinx.Ui
_controller1Type.Changed += (sender, args) => Controller_Changed(sender, args, _controller1Type.ActiveId, _controller1Image);
//Setup Currents
- if (SwitchConfig.EnableFileLog) _fileLogToggle.Click();
- if (SwitchConfig.LoggingEnableError) _errorLogToggle.Click();
- if (SwitchConfig.LoggingEnableWarn) _warningLogToggle.Click();
- if (SwitchConfig.LoggingEnableInfo) _infoLogToggle.Click();
- if (SwitchConfig.LoggingEnableStub) _stubLogToggle.Click();
- if (SwitchConfig.LoggingEnableDebug) _debugLogToggle.Click();
- if (SwitchConfig.LoggingEnableGuest) _guestLogToggle.Click();
- if (SwitchConfig.LoggingEnableFsAccessLog) _fsAccessLogToggle.Click();
- if (SwitchConfig.DockedMode) _dockedModeToggle.Click();
- if (SwitchConfig.EnableDiscordIntegration) _discordToggle.Click();
- if (SwitchConfig.EnableVsync) _vSyncToggle.Click();
- if (SwitchConfig.EnableMulticoreScheduling) _multiSchedToggle.Click();
- if (SwitchConfig.EnableFsIntegrityChecks) _fsicToggle.Click();
- if (SwitchConfig.IgnoreMissingServices) _ignoreToggle.Click();
- if (SwitchConfig.EnableKeyboard) _directKeyboardAccess.Click();
- if (SwitchConfig.EnableCustomTheme) _custThemeToggle.Click();
+ if (ConfigurationState.Instance.Logger.EnableFileLog)
+ {
+ _fileLogToggle.Click();
+ }
- _systemLanguageSelect.SetActiveId(SwitchConfig.SystemLanguage.ToString());
- _controller1Type .SetActiveId(SwitchConfig.ControllerType.ToString());
+ 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();
+ }
+
+ _systemLanguageSelect.SetActiveId(ConfigurationState.Instance.System.Language.Value.ToString());
+ _controller1Type .SetActiveId(ConfigurationState.Instance.Hid.ControllerType.Value.ToString());
Controller_Changed(null, null, _controller1Type.ActiveId, _controller1Image);
- _lStickUp1.Label = SwitchConfig.KeyboardControls.LeftJoycon.StickUp.ToString();
- _lStickDown1.Label = SwitchConfig.KeyboardControls.LeftJoycon.StickDown.ToString();
- _lStickLeft1.Label = SwitchConfig.KeyboardControls.LeftJoycon.StickLeft.ToString();
- _lStickRight1.Label = SwitchConfig.KeyboardControls.LeftJoycon.StickRight.ToString();
- _lStickButton1.Label = SwitchConfig.KeyboardControls.LeftJoycon.StickButton.ToString();
- _dpadUp1.Label = SwitchConfig.KeyboardControls.LeftJoycon.DPadUp.ToString();
- _dpadDown1.Label = SwitchConfig.KeyboardControls.LeftJoycon.DPadDown.ToString();
- _dpadLeft1.Label = SwitchConfig.KeyboardControls.LeftJoycon.DPadLeft.ToString();
- _dpadRight1.Label = SwitchConfig.KeyboardControls.LeftJoycon.DPadRight.ToString();
- _minus1.Label = SwitchConfig.KeyboardControls.LeftJoycon.ButtonMinus.ToString();
- _l1.Label = SwitchConfig.KeyboardControls.LeftJoycon.ButtonL.ToString();
- _zL1.Label = SwitchConfig.KeyboardControls.LeftJoycon.ButtonZl.ToString();
- _rStickUp1.Label = SwitchConfig.KeyboardControls.RightJoycon.StickUp.ToString();
- _rStickDown1.Label = SwitchConfig.KeyboardControls.RightJoycon.StickDown.ToString();
- _rStickLeft1.Label = SwitchConfig.KeyboardControls.RightJoycon.StickLeft.ToString();
- _rStickRight1.Label = SwitchConfig.KeyboardControls.RightJoycon.StickRight.ToString();
- _rStickButton1.Label = SwitchConfig.KeyboardControls.RightJoycon.StickButton.ToString();
- _a1.Label = SwitchConfig.KeyboardControls.RightJoycon.ButtonA.ToString();
- _b1.Label = SwitchConfig.KeyboardControls.RightJoycon.ButtonB.ToString();
- _x1.Label = SwitchConfig.KeyboardControls.RightJoycon.ButtonX.ToString();
- _y1.Label = SwitchConfig.KeyboardControls.RightJoycon.ButtonY.ToString();
- _plus1.Label = SwitchConfig.KeyboardControls.RightJoycon.ButtonPlus.ToString();
- _r1.Label = SwitchConfig.KeyboardControls.RightJoycon.ButtonR.ToString();
- _zR1.Label = SwitchConfig.KeyboardControls.RightJoycon.ButtonZr.ToString();
+ _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 = SwitchConfig.CustomThemePath;
- _graphicsShadersDumpPath.Buffer.Text = SwitchConfig.GraphicsShadersDumpPath;
- _fsLogSpinAdjustment.Value = SwitchConfig.FsGlobalAccessLogMode;
+ _custThemePath.Buffer.Text = ConfigurationState.Instance.Ui.CustomThemePath;
+ _graphicsShadersDumpPath.Buffer.Text = ConfigurationState.Instance.Graphics.ShadersDumpPath;
+ _fsLogSpinAdjustment.Value = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
_gameDirsBox.AppendColumn("", new CellRendererText(), "text", 0);
_gameDirsBoxStore = new ListStore(typeof(string));
_gameDirsBox.Model = _gameDirsBoxStore;
- foreach (string gameDir in SwitchConfig.GameDirs)
+ foreach (string gameDir in ConfigurationState.Instance.Ui.GameDirs.Value)
{
_gameDirsBoxStore.AppendValues(gameDir);
}
@@ -208,7 +263,7 @@ namespace Ryujinx.Ui
string key = keyPressed.Event.Key.ToString();
string capKey = key.First().ToString().ToUpper() + key.Substring(1);
- if (Enum.IsDefined(typeof(OpenTK.Input.Key), capKey))
+ if (Enum.IsDefined(typeof(Configuration.Hid.Key), capKey))
{
button.Label = capKey;
}
@@ -325,65 +380,63 @@ namespace Ryujinx.Ui
_gameDirsBoxStore.IterNext(ref treeIter);
}
- SwitchConfig.LoggingEnableError = _errorLogToggle.Active;
- SwitchConfig.LoggingEnableWarn = _warningLogToggle.Active;
- SwitchConfig.LoggingEnableInfo = _infoLogToggle.Active;
- SwitchConfig.LoggingEnableStub = _stubLogToggle.Active;
- SwitchConfig.LoggingEnableDebug = _debugLogToggle.Active;
- SwitchConfig.LoggingEnableGuest = _guestLogToggle.Active;
- SwitchConfig.LoggingEnableFsAccessLog = _fsAccessLogToggle.Active;
- SwitchConfig.EnableFileLog = _fileLogToggle.Active;
- SwitchConfig.DockedMode = _dockedModeToggle.Active;
- SwitchConfig.EnableDiscordIntegration = _discordToggle.Active;
- SwitchConfig.EnableVsync = _vSyncToggle.Active;
- SwitchConfig.EnableMulticoreScheduling = _multiSchedToggle.Active;
- SwitchConfig.EnableFsIntegrityChecks = _fsicToggle.Active;
- SwitchConfig.IgnoreMissingServices = _ignoreToggle.Active;
- SwitchConfig.EnableKeyboard = _directKeyboardAccess.Active;
- SwitchConfig.EnableCustomTheme = _custThemeToggle.Active;
+ 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;
- SwitchConfig.KeyboardControls.LeftJoycon = new NpadKeyboardLeft()
+ ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon = new NpadKeyboardLeft()
{
- StickUp = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _lStickUp1.Label),
- StickDown = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _lStickDown1.Label),
- StickLeft = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _lStickLeft1.Label),
- StickRight = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _lStickRight1.Label),
- StickButton = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _lStickButton1.Label),
- DPadUp = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _dpadUp1.Label),
- DPadDown = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _dpadDown1.Label),
- DPadLeft = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _dpadLeft1.Label),
- DPadRight = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _dpadRight1.Label),
- ButtonMinus = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _minus1.Label),
- ButtonL = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _l1.Label),
- ButtonZl = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _zL1.Label),
+ 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),
};
- SwitchConfig.KeyboardControls.RightJoycon = new NpadKeyboardRight()
+ ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon = new NpadKeyboardRight()
{
- StickUp = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _rStickUp1.Label),
- StickDown = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _rStickDown1.Label),
- StickLeft = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _rStickLeft1.Label),
- StickRight = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _rStickRight1.Label),
- StickButton = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _rStickButton1.Label),
- ButtonA = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _a1.Label),
- ButtonB = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _b1.Label),
- ButtonX = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _x1.Label),
- ButtonY = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _y1.Label),
- ButtonPlus = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _plus1.Label),
- ButtonR = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _r1.Label),
- ButtonZr = (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), _zR1.Label),
+ 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),
};
- SwitchConfig.SystemLanguage = (SystemLanguage)Enum.Parse(typeof(SystemLanguage), _systemLanguageSelect.ActiveId);
- SwitchConfig.ControllerType = (ControllerStatus)Enum.Parse(typeof(ControllerStatus), _controller1Type.ActiveId);
- SwitchConfig.CustomThemePath = _custThemePath.Buffer.Text;
- SwitchConfig.GraphicsShadersDumpPath = _graphicsShadersDumpPath.Buffer.Text;
- SwitchConfig.GameDirs = gameDirs;
- SwitchConfig.FsGlobalAccessLogMode = (int)_fsLogSpinAdjustment.Value;
-
- Configuration.SaveConfig(SwitchConfig, System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
- Configuration.Configure(_device, SwitchConfig);
+ ConfigurationState.Instance.System.Language.Value = (Language)Enum.Parse(typeof(Language), _systemLanguageSelect.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;
+ MainWindow.SaveConfig();
MainWindow.ApplyTheme();
#pragma warning disable CS4014
MainWindow.UpdateGameTable();