Improvements to input and input configuration in the GUI. (#849)
* Improvements to input and input configuration in the GUI * Requested changes * nits * more nits
|
@ -4,9 +4,7 @@ using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
using Ryujinx.Common.Utilities;
|
||||||
using Ryujinx.Configuration.System;
|
using Ryujinx.Configuration.System;
|
||||||
using Ryujinx.Configuration.Hid;
|
|
||||||
using Ryujinx.Configuration.Ui;
|
using Ryujinx.Configuration.Ui;
|
||||||
using Ryujinx.UI.Input;
|
|
||||||
|
|
||||||
namespace Ryujinx.Configuration
|
namespace Ryujinx.Configuration
|
||||||
{
|
{
|
||||||
|
@ -15,7 +13,7 @@ namespace Ryujinx.Configuration
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 5;
|
public const int CurrentVersion = 6;
|
||||||
|
|
||||||
public int Version { get; set; }
|
public int Version { get; set; }
|
||||||
|
|
||||||
|
@ -129,11 +127,6 @@ namespace Ryujinx.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IgnoreMissingServices { get; set; }
|
public bool IgnoreMissingServices { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The primary controller's type
|
|
||||||
/// </summary>
|
|
||||||
public ControllerType ControllerType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to toggle columns in the GUI
|
/// Used to toggle columns in the GUI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -162,12 +155,12 @@ namespace Ryujinx.Configuration
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Keyboard control bindings
|
/// Keyboard control bindings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NpadKeyboard KeyboardControls { get; set; }
|
public List<KeyboardConfig> KeyboardConfig { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controller control bindings
|
/// Controller control bindings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NpadController JoystickControls { get; set; }
|
public List<ControllerConfig> ControllerConfig { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads a configuration file from disk
|
/// Loads a configuration file from disk
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Configuration.Hid;
|
using Ryujinx.Configuration.Hid;
|
||||||
using Ryujinx.Configuration.System;
|
using Ryujinx.Configuration.System;
|
||||||
using Ryujinx.Configuration.Ui;
|
using Ryujinx.Configuration.Ui;
|
||||||
using Ryujinx.UI.Input;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
@ -159,7 +158,7 @@ namespace Ryujinx.Configuration
|
||||||
public ReactiveObject<string> TimeZone { get; private set; }
|
public ReactiveObject<string> TimeZone { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// System Time Offset in seconds
|
/// System Time Offset in Seconds
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<long> SystemTimeOffset { get; private set; }
|
public ReactiveObject<long> SystemTimeOffset { get; private set; }
|
||||||
|
|
||||||
|
@ -207,32 +206,22 @@ namespace Ryujinx.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class HidSection
|
public class HidSection
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The primary controller's type
|
|
||||||
/// </summary>
|
|
||||||
public ReactiveObject<ControllerType> ControllerType { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enable or disable keyboard support (Independent from controllers binding)
|
/// Enable or disable keyboard support (Independent from controllers binding)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> EnableKeyboard { get; private set; }
|
public ReactiveObject<bool> EnableKeyboard { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Keyboard control bindings
|
/// Input device configuration.
|
||||||
|
/// NOTE: This ReactiveObject won't issue an event when the List has elements added or removed.
|
||||||
|
/// TODO: Implement a ReactiveList class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<NpadKeyboard> KeyboardControls { get; private set; }
|
public ReactiveObject<List<InputConfig>> InputConfig { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Controller control bindings
|
|
||||||
/// </summary>
|
|
||||||
public ReactiveObject<NpadController> JoystickControls { get; private set; }
|
|
||||||
|
|
||||||
public HidSection()
|
public HidSection()
|
||||||
{
|
{
|
||||||
ControllerType = new ReactiveObject<ControllerType>();
|
|
||||||
EnableKeyboard = new ReactiveObject<bool>();
|
EnableKeyboard = new ReactiveObject<bool>();
|
||||||
KeyboardControls = new ReactiveObject<NpadKeyboard>();
|
InputConfig = new ReactiveObject<List<InputConfig>>();
|
||||||
JoystickControls = new ReactiveObject<NpadController>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,6 +300,21 @@ namespace Ryujinx.Configuration
|
||||||
|
|
||||||
public ConfigurationFileFormat ToFileFormat()
|
public ConfigurationFileFormat ToFileFormat()
|
||||||
{
|
{
|
||||||
|
List<ControllerConfig> controllerConfigList = new List<ControllerConfig>();
|
||||||
|
List<KeyboardConfig> keyboardConfigList = new List<KeyboardConfig>();
|
||||||
|
|
||||||
|
foreach (InputConfig inputConfig in Hid.InputConfig.Value)
|
||||||
|
{
|
||||||
|
if (inputConfig is ControllerConfig controllerConfig)
|
||||||
|
{
|
||||||
|
controllerConfigList.Add(controllerConfig);
|
||||||
|
}
|
||||||
|
else if (inputConfig is KeyboardConfig keyboardConfig)
|
||||||
|
{
|
||||||
|
keyboardConfigList.Add(keyboardConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConfigurationFileFormat configurationFile = new ConfigurationFileFormat
|
ConfigurationFileFormat configurationFile = new ConfigurationFileFormat
|
||||||
{
|
{
|
||||||
Version = ConfigurationFileFormat.CurrentVersion,
|
Version = ConfigurationFileFormat.CurrentVersion,
|
||||||
|
@ -336,7 +340,6 @@ namespace Ryujinx.Configuration
|
||||||
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
|
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
|
||||||
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
|
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
|
||||||
IgnoreMissingServices = System.IgnoreMissingServices,
|
IgnoreMissingServices = System.IgnoreMissingServices,
|
||||||
ControllerType = Hid.ControllerType,
|
|
||||||
GuiColumns = new GuiColumns()
|
GuiColumns = new GuiColumns()
|
||||||
{
|
{
|
||||||
FavColumn = Ui.GuiColumns.FavColumn,
|
FavColumn = Ui.GuiColumns.FavColumn,
|
||||||
|
@ -354,8 +357,8 @@ namespace Ryujinx.Configuration
|
||||||
EnableCustomTheme = Ui.EnableCustomTheme,
|
EnableCustomTheme = Ui.EnableCustomTheme,
|
||||||
CustomThemePath = Ui.CustomThemePath,
|
CustomThemePath = Ui.CustomThemePath,
|
||||||
EnableKeyboard = Hid.EnableKeyboard,
|
EnableKeyboard = Hid.EnableKeyboard,
|
||||||
KeyboardControls = Hid.KeyboardControls,
|
KeyboardConfig = keyboardConfigList,
|
||||||
JoystickControls = Hid.JoystickControls
|
ControllerConfig = controllerConfigList
|
||||||
};
|
};
|
||||||
|
|
||||||
return configurationFile;
|
return configurationFile;
|
||||||
|
@ -385,7 +388,6 @@ namespace Ryujinx.Configuration
|
||||||
System.EnableFsIntegrityChecks.Value = true;
|
System.EnableFsIntegrityChecks.Value = true;
|
||||||
System.FsGlobalAccessLogMode.Value = 0;
|
System.FsGlobalAccessLogMode.Value = 0;
|
||||||
System.IgnoreMissingServices.Value = false;
|
System.IgnoreMissingServices.Value = false;
|
||||||
Hid.ControllerType.Value = ControllerType.Handheld;
|
|
||||||
Ui.GuiColumns.FavColumn.Value = true;
|
Ui.GuiColumns.FavColumn.Value = true;
|
||||||
Ui.GuiColumns.IconColumn.Value = true;
|
Ui.GuiColumns.IconColumn.Value = true;
|
||||||
Ui.GuiColumns.AppColumn.Value = true;
|
Ui.GuiColumns.AppColumn.Value = true;
|
||||||
|
@ -401,8 +403,13 @@ namespace Ryujinx.Configuration
|
||||||
Ui.CustomThemePath.Value = "";
|
Ui.CustomThemePath.Value = "";
|
||||||
Hid.EnableKeyboard.Value = false;
|
Hid.EnableKeyboard.Value = false;
|
||||||
|
|
||||||
Hid.KeyboardControls.Value = new NpadKeyboard
|
Hid.InputConfig.Value = new List<InputConfig>
|
||||||
{
|
{
|
||||||
|
new KeyboardConfig
|
||||||
|
{
|
||||||
|
Index = 0,
|
||||||
|
ControllerType = ControllerType.JoyconPair,
|
||||||
|
PlayerIndex = PlayerIndex.Player1,
|
||||||
LeftJoycon = new NpadKeyboardLeft
|
LeftJoycon = new NpadKeyboardLeft
|
||||||
{
|
{
|
||||||
StickUp = Key.W,
|
StickUp = Key.W,
|
||||||
|
@ -417,6 +424,8 @@ namespace Ryujinx.Configuration
|
||||||
ButtonMinus = Key.Minus,
|
ButtonMinus = Key.Minus,
|
||||||
ButtonL = Key.E,
|
ButtonL = Key.E,
|
||||||
ButtonZl = Key.Q,
|
ButtonZl = Key.Q,
|
||||||
|
ButtonSl = Key.Home,
|
||||||
|
ButtonSr = Key.End
|
||||||
},
|
},
|
||||||
RightJoycon = new NpadKeyboardRight
|
RightJoycon = new NpadKeyboardRight
|
||||||
{
|
{
|
||||||
|
@ -432,42 +441,13 @@ namespace Ryujinx.Configuration
|
||||||
ButtonPlus = Key.Plus,
|
ButtonPlus = Key.Plus,
|
||||||
ButtonR = Key.U,
|
ButtonR = Key.U,
|
||||||
ButtonZr = Key.O,
|
ButtonZr = Key.O,
|
||||||
|
ButtonSl = Key.PageUp,
|
||||||
|
ButtonSr = Key.PageDown
|
||||||
},
|
},
|
||||||
Hotkeys = new KeyboardHotkeys
|
Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = Key.Tab
|
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,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -521,6 +501,71 @@ namespace Ryujinx.Configuration
|
||||||
configurationFileUpdated = true;
|
configurationFileUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 6)
|
||||||
|
{
|
||||||
|
Common.Logging.Logger.PrintWarning(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 6.");
|
||||||
|
|
||||||
|
configurationFileFormat.ControllerConfig = new List<ControllerConfig>();
|
||||||
|
configurationFileFormat.KeyboardConfig = new List<KeyboardConfig>{
|
||||||
|
new KeyboardConfig
|
||||||
|
{
|
||||||
|
Index = 0,
|
||||||
|
ControllerType = ControllerType.JoyconPair,
|
||||||
|
PlayerIndex = PlayerIndex.Player1,
|
||||||
|
LeftJoycon = new NpadKeyboardLeft
|
||||||
|
{
|
||||||
|
StickUp = Key.W,
|
||||||
|
StickDown = Key.S,
|
||||||
|
StickLeft = Key.A,
|
||||||
|
StickRight = Key.D,
|
||||||
|
StickButton = Key.F,
|
||||||
|
DPadUp = Key.Up,
|
||||||
|
DPadDown = Key.Down,
|
||||||
|
DPadLeft = Key.Left,
|
||||||
|
DPadRight = Key.Right,
|
||||||
|
ButtonMinus = Key.Minus,
|
||||||
|
ButtonL = Key.E,
|
||||||
|
ButtonZl = Key.Q,
|
||||||
|
ButtonSl = Key.Unbound,
|
||||||
|
ButtonSr = Key.Unbound
|
||||||
|
},
|
||||||
|
RightJoycon = new NpadKeyboardRight
|
||||||
|
{
|
||||||
|
StickUp = Key.I,
|
||||||
|
StickDown = Key.K,
|
||||||
|
StickLeft = Key.J,
|
||||||
|
StickRight = Key.L,
|
||||||
|
StickButton = Key.H,
|
||||||
|
ButtonA = Key.Z,
|
||||||
|
ButtonB = Key.X,
|
||||||
|
ButtonX = Key.C,
|
||||||
|
ButtonY = Key.V,
|
||||||
|
ButtonPlus = Key.Plus,
|
||||||
|
ButtonR = Key.U,
|
||||||
|
ButtonZr = Key.O,
|
||||||
|
ButtonSl = Key.Unbound,
|
||||||
|
ButtonSr = Key.Unbound
|
||||||
|
},
|
||||||
|
Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVsync = Key.Tab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<InputConfig> inputConfig = new List<InputConfig>();
|
||||||
|
foreach (ControllerConfig controllerConfig in configurationFileFormat.ControllerConfig)
|
||||||
|
{
|
||||||
|
inputConfig.Add(controllerConfig);
|
||||||
|
}
|
||||||
|
foreach (KeyboardConfig keyboardConfig in configurationFileFormat.KeyboardConfig)
|
||||||
|
{
|
||||||
|
inputConfig.Add(keyboardConfig);
|
||||||
|
}
|
||||||
|
|
||||||
Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
|
Graphics.MaxAnisotropy.Value = configurationFileFormat.MaxAnisotropy;
|
||||||
Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
|
Graphics.ShadersDumpPath.Value = configurationFileFormat.GraphicsShadersDumpPath;
|
||||||
Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
|
Logger.EnableDebug.Value = configurationFileFormat.LoggingEnableDebug;
|
||||||
|
@ -544,7 +589,6 @@ namespace Ryujinx.Configuration
|
||||||
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
|
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
|
||||||
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
|
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
|
||||||
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
|
System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices;
|
||||||
Hid.ControllerType.Value = configurationFileFormat.ControllerType;
|
|
||||||
Ui.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
|
Ui.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn;
|
||||||
Ui.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
|
Ui.GuiColumns.IconColumn.Value = configurationFileFormat.GuiColumns.IconColumn;
|
||||||
Ui.GuiColumns.AppColumn.Value = configurationFileFormat.GuiColumns.AppColumn;
|
Ui.GuiColumns.AppColumn.Value = configurationFileFormat.GuiColumns.AppColumn;
|
||||||
|
@ -559,14 +603,13 @@ namespace Ryujinx.Configuration
|
||||||
Ui.EnableCustomTheme.Value = configurationFileFormat.EnableCustomTheme;
|
Ui.EnableCustomTheme.Value = configurationFileFormat.EnableCustomTheme;
|
||||||
Ui.CustomThemePath.Value = configurationFileFormat.CustomThemePath;
|
Ui.CustomThemePath.Value = configurationFileFormat.CustomThemePath;
|
||||||
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
|
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
|
||||||
Hid.KeyboardControls.Value = configurationFileFormat.KeyboardControls;
|
Hid.InputConfig.Value = inputConfig;
|
||||||
Hid.JoystickControls.Value = configurationFileFormat.JoystickControls;
|
|
||||||
|
|
||||||
if (configurationFileUpdated)
|
if (configurationFileUpdated)
|
||||||
{
|
{
|
||||||
ToFileFormat().SaveConfig(configurationFilePath);
|
ToFileFormat().SaveConfig(configurationFilePath);
|
||||||
|
|
||||||
Common.Logging.Logger.PrintWarning(LogClass.Application, "Configuration file is updated!");
|
Common.Logging.Logger.PrintWarning(LogClass.Application, "Configuration file has been updated!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
namespace Ryujinx.Common.Configuration.Hid
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
{
|
{
|
||||||
public class NpadController
|
public class ControllerConfig : InputConfig
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables controller support
|
/// Controller Left Analog Stick Deadzone
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enabled { get; set; }
|
public float DeadzoneLeft { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controller Device Index
|
/// Controller Right Analog Stick Deadzone
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Index { get; set; }
|
public float DeadzoneRight { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Controller Analog Stick Deadzone
|
|
||||||
/// </summary>
|
|
||||||
public float Deadzone { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controller Trigger Threshold
|
/// Controller Trigger Threshold
|
|
@ -40,6 +40,7 @@
|
||||||
Hat2Up,
|
Hat2Up,
|
||||||
Hat2Down,
|
Hat2Down,
|
||||||
Hat2Left,
|
Hat2Left,
|
||||||
Hat2Right
|
Hat2Right,
|
||||||
|
Unbound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
namespace Ryujinx.Configuration.Hid
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
{
|
{
|
||||||
public enum ControllerType
|
[Flags]
|
||||||
|
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||||
|
public enum ControllerType : int
|
||||||
{
|
{
|
||||||
ProController,
|
None,
|
||||||
Handheld,
|
ProController = 1 << 0,
|
||||||
NpadPair,
|
Handheld = 1 << 1,
|
||||||
NpadLeft,
|
JoyconPair = 1 << 2,
|
||||||
NpadRight
|
JoyconLeft = 1 << 3,
|
||||||
|
JoyconRight = 1 << 4,
|
||||||
|
Invalid = 1 << 5,
|
||||||
|
Pokeball = 1 << 6,
|
||||||
|
SystemExternal = 1 << 29,
|
||||||
|
System = 1 << 30
|
||||||
}
|
}
|
||||||
}
|
}
|
20
Ryujinx.Common/Configuration/Hid/InputConfig.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
|
{
|
||||||
|
public class InputConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Controller Device Index
|
||||||
|
/// </summary>
|
||||||
|
public int Index { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller's Type
|
||||||
|
/// </summary>
|
||||||
|
public ControllerType ControllerType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Player's Index for the controller
|
||||||
|
/// </summary>
|
||||||
|
public PlayerIndex PlayerIndex { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -148,6 +148,7 @@
|
||||||
Slash = 128,
|
Slash = 128,
|
||||||
BackSlash = 129,
|
BackSlash = 129,
|
||||||
NonUSBackSlash = 130,
|
NonUSBackSlash = 130,
|
||||||
LastKey = 131
|
LastKey = 131,
|
||||||
|
Unbound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
Ryujinx.Common/Configuration/Hid/KeyboardConfig.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
|
{
|
||||||
|
public class KeyboardConfig : InputConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Left JoyCon Keyboard Bindings
|
||||||
|
/// </summary>
|
||||||
|
public NpadKeyboardLeft LeftJoycon { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Right JoyCon Keyboard Bindings
|
||||||
|
/// </summary>
|
||||||
|
public NpadKeyboardRight RightJoycon { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Hotkey Keyboard Bindings
|
||||||
|
/// </summary>
|
||||||
|
public KeyboardHotkeys Hotkeys { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
namespace Ryujinx.Configuration.Hid
|
using Ryujinx.Configuration.Hid;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
{
|
{
|
||||||
public struct KeyboardHotkeys
|
public struct KeyboardHotkeys
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,11 +2,16 @@
|
||||||
{
|
{
|
||||||
public struct NpadControllerLeft
|
public struct NpadControllerLeft
|
||||||
{
|
{
|
||||||
public ControllerInputId Stick { get; set; }
|
public ControllerInputId StickX { get; set; }
|
||||||
|
public bool InvertStickX { get; set; }
|
||||||
|
public ControllerInputId StickY { get; set; }
|
||||||
|
public bool InvertStickY { get; set; }
|
||||||
public ControllerInputId StickButton { get; set; }
|
public ControllerInputId StickButton { get; set; }
|
||||||
public ControllerInputId ButtonMinus { get; set; }
|
public ControllerInputId ButtonMinus { get; set; }
|
||||||
public ControllerInputId ButtonL { get; set; }
|
public ControllerInputId ButtonL { get; set; }
|
||||||
public ControllerInputId ButtonZl { get; set; }
|
public ControllerInputId ButtonZl { get; set; }
|
||||||
|
public ControllerInputId ButtonSl { get; set; }
|
||||||
|
public ControllerInputId ButtonSr { get; set; }
|
||||||
public ControllerInputId DPadUp { get; set; }
|
public ControllerInputId DPadUp { get; set; }
|
||||||
public ControllerInputId DPadDown { get; set; }
|
public ControllerInputId DPadDown { get; set; }
|
||||||
public ControllerInputId DPadLeft { get; set; }
|
public ControllerInputId DPadLeft { get; set; }
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
{
|
{
|
||||||
public struct NpadControllerRight
|
public struct NpadControllerRight
|
||||||
{
|
{
|
||||||
public ControllerInputId Stick { get; set; }
|
public ControllerInputId StickX { get; set; }
|
||||||
|
public bool InvertStickX { get; set; }
|
||||||
|
public ControllerInputId StickY { get; set; }
|
||||||
|
public bool InvertStickY { get; set; }
|
||||||
public ControllerInputId StickButton { get; set; }
|
public ControllerInputId StickButton { get; set; }
|
||||||
public ControllerInputId ButtonA { get; set; }
|
public ControllerInputId ButtonA { get; set; }
|
||||||
public ControllerInputId ButtonB { get; set; }
|
public ControllerInputId ButtonB { get; set; }
|
||||||
|
@ -11,5 +14,7 @@
|
||||||
public ControllerInputId ButtonPlus { get; set; }
|
public ControllerInputId ButtonPlus { get; set; }
|
||||||
public ControllerInputId ButtonR { get; set; }
|
public ControllerInputId ButtonR { get; set; }
|
||||||
public ControllerInputId ButtonZr { get; set; }
|
public ControllerInputId ButtonZr { get; set; }
|
||||||
|
public ControllerInputId ButtonSl { get; set; }
|
||||||
|
public ControllerInputId ButtonSr { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
namespace Ryujinx.UI.Input
|
|
||||||
{
|
|
||||||
public class NpadKeyboard
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Left JoyCon Keyboard Bindings
|
|
||||||
/// </summary>
|
|
||||||
public Configuration.Hid.NpadKeyboardLeft LeftJoycon { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Right JoyCon Keyboard Bindings
|
|
||||||
/// </summary>
|
|
||||||
public Configuration.Hid.NpadKeyboardRight RightJoycon { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hotkey Keyboard Bindings
|
|
||||||
/// </summary>
|
|
||||||
public Configuration.Hid.KeyboardHotkeys Hotkeys { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,6 @@
|
||||||
namespace Ryujinx.Configuration.Hid
|
using Ryujinx.Configuration.Hid;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
{
|
{
|
||||||
public struct NpadKeyboardLeft
|
public struct NpadKeyboardLeft
|
||||||
{
|
{
|
||||||
|
@ -14,5 +16,7 @@
|
||||||
public Key ButtonMinus { get; set; }
|
public Key ButtonMinus { get; set; }
|
||||||
public Key ButtonL { get; set; }
|
public Key ButtonL { get; set; }
|
||||||
public Key ButtonZl { get; set; }
|
public Key ButtonZl { get; set; }
|
||||||
|
public Key ButtonSl { get; set; }
|
||||||
|
public Key ButtonSr { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
namespace Ryujinx.Configuration.Hid
|
using Ryujinx.Configuration.Hid;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
{
|
{
|
||||||
public struct NpadKeyboardRight
|
public struct NpadKeyboardRight
|
||||||
{
|
{
|
||||||
|
@ -14,5 +16,7 @@
|
||||||
public Key ButtonPlus { get; set; }
|
public Key ButtonPlus { get; set; }
|
||||||
public Key ButtonR { get; set; }
|
public Key ButtonR { get; set; }
|
||||||
public Key ButtonZr { get; set; }
|
public Key ButtonZr { get; set; }
|
||||||
|
public Key ButtonSl { get; set; }
|
||||||
|
public Key ButtonSr { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
18
Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
|
{
|
||||||
|
// This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
|
||||||
|
public enum PlayerIndex : int
|
||||||
|
{
|
||||||
|
Player1 = 0,
|
||||||
|
Player2 = 1,
|
||||||
|
Player3 = 2,
|
||||||
|
Player4 = 3,
|
||||||
|
Player5 = 4,
|
||||||
|
Player6 = 5,
|
||||||
|
Player7 = 6,
|
||||||
|
Player8 = 7,
|
||||||
|
Handheld = 8,
|
||||||
|
Unknown = 9,
|
||||||
|
Auto = 10 // Shouldn't be used directly
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
public class Hid
|
public class Hid
|
||||||
{
|
{
|
||||||
private readonly Switch _device;
|
private readonly Switch _device;
|
||||||
private long _hidMemoryAddress;
|
private readonly long _hidMemoryAddress;
|
||||||
|
|
||||||
internal ref HidSharedMemory SharedMemory => ref _device.Memory.GetStructRef<HidSharedMemory>(_hidMemoryAddress);
|
internal ref HidSharedMemory SharedMemory => ref _device.Memory.GetStructRef<HidSharedMemory>(_hidMemoryAddress);
|
||||||
internal const int SharedMemEntryCount = 17;
|
internal const int SharedMemEntryCount = 17;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.Hid
|
namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
{
|
{
|
||||||
|
@ -9,14 +9,14 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
internal NpadJoyHoldType JoyHold = NpadJoyHoldType.Vertical;
|
internal NpadJoyHoldType JoyHold = NpadJoyHoldType.Vertical;
|
||||||
internal bool SixAxisActive = false; // TODO: link to hidserver when implemented
|
internal bool SixAxisActive = false; // TODO: link to hidserver when implemented
|
||||||
|
|
||||||
enum FilterState
|
private enum FilterState
|
||||||
{
|
{
|
||||||
Unconfigured = 0,
|
Unconfigured = 0,
|
||||||
Configured = 1,
|
Configured = 1,
|
||||||
Accepted = 2
|
Accepted = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NpadConfig
|
private struct NpadConfig
|
||||||
{
|
{
|
||||||
public ControllerType ConfiguredType;
|
public ControllerType ConfiguredType;
|
||||||
public FilterState State;
|
public FilterState State;
|
||||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
|
|
||||||
public ControllerType SupportedStyleSets
|
public ControllerType SupportedStyleSets
|
||||||
{
|
{
|
||||||
get { return _supportedStyleSets; }
|
get => _supportedStyleSets;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (_supportedStyleSets != value) // Deal with spamming
|
if (_supportedStyleSets != value) // Deal with spamming
|
||||||
|
@ -46,9 +46,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
|
|
||||||
public PlayerIndex PrimaryController { get; set; } = PlayerIndex.Unknown;
|
public PlayerIndex PrimaryController { get; set; } = PlayerIndex.Unknown;
|
||||||
|
|
||||||
KEvent[] _styleSetUpdateEvents;
|
private KEvent[] _styleSetUpdateEvents;
|
||||||
|
|
||||||
static readonly Array3<BatteryCharge> _fullBattery;
|
private static readonly Array3<BatteryCharge> _fullBattery;
|
||||||
|
|
||||||
public NpadDevices(Switch device, bool active = true) : base(device, active)
|
public NpadDevices(Switch device, bool active = true) : base(device, active)
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
MatchControllers();
|
MatchControllers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchControllers()
|
private void MatchControllers()
|
||||||
{
|
{
|
||||||
PrimaryController = PlayerIndex.Unknown;
|
PrimaryController = PlayerIndex.Unknown;
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
return ref _styleSetUpdateEvents[(int)player];
|
return ref _styleSetUpdateEvents[(int)player];
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitController(PlayerIndex player, ControllerType type)
|
private void InitController(PlayerIndex player, ControllerType type)
|
||||||
{
|
{
|
||||||
if (type == ControllerType.Handheld)
|
if (type == ControllerType.Handheld)
|
||||||
{
|
{
|
||||||
|
@ -229,7 +229,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
Logger.PrintInfo(LogClass.Hid, $"Connected ControllerType {type} to PlayerIndex {player}");
|
Logger.PrintInfo(LogClass.Hid, $"Connected ControllerType {type} to PlayerIndex {player}");
|
||||||
}
|
}
|
||||||
|
|
||||||
static NpadLayoutsIndex ControllerTypeToLayout(ControllerType controllerType)
|
private static NpadLayoutsIndex ControllerTypeToLayout(ControllerType controllerType)
|
||||||
=> controllerType switch
|
=> controllerType switch
|
||||||
{
|
{
|
||||||
ControllerType.ProController => NpadLayoutsIndex.ProController,
|
ControllerType.ProController => NpadLayoutsIndex.ProController,
|
||||||
|
@ -251,7 +251,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetGamepadState(PlayerIndex player, ControllerKeys buttons,
|
private void SetGamepadState(PlayerIndex player, ControllerKeys buttons,
|
||||||
JoystickPosition leftJoystick, JoystickPosition rightJoystick)
|
JoystickPosition leftJoystick, JoystickPosition rightJoystick)
|
||||||
{
|
{
|
||||||
if (player == PlayerIndex.Auto)
|
if (player == PlayerIndex.Auto)
|
||||||
|
@ -284,7 +284,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
|
||||||
mainLayout.Entries[(int)mainLayout.Header.LatestEntry] = currentEntry;
|
mainLayout.Entries[(int)mainLayout.Header.LatestEntry] = currentEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAllEntries()
|
private void UpdateAllEntries()
|
||||||
{
|
{
|
||||||
ref Array10<ShMemNpad> controllers = ref _device.Hid.SharedMemory.Npads;
|
ref Array10<ShMemNpad> controllers = ref _device.Hid.SharedMemory.Npads;
|
||||||
for (int i = 0; i < controllers.Length; ++i)
|
for (int i = 0; i < controllers.Length; ++i)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": 5,
|
"version": 6,
|
||||||
"max_anisotropy": -1,
|
"max_anisotropy": -1,
|
||||||
"graphics_shaders_dump_path": "",
|
"graphics_shaders_dump_path": "",
|
||||||
"logging_enable_debug": false,
|
"logging_enable_debug": false,
|
||||||
|
@ -22,7 +22,6 @@
|
||||||
"enable_fs_integrity_checks": true,
|
"enable_fs_integrity_checks": true,
|
||||||
"fs_global_access_log_mode": 0,
|
"fs_global_access_log_mode": 0,
|
||||||
"ignore_missing_services": false,
|
"ignore_missing_services": false,
|
||||||
"controller_type": "Handheld",
|
|
||||||
"gui_columns": {
|
"gui_columns": {
|
||||||
"fav_column": true,
|
"fav_column": true,
|
||||||
"icon_column": true,
|
"icon_column": true,
|
||||||
|
@ -39,7 +38,11 @@
|
||||||
"enable_custom_theme": false,
|
"enable_custom_theme": false,
|
||||||
"custom_theme_path": "",
|
"custom_theme_path": "",
|
||||||
"enable_keyboard": false,
|
"enable_keyboard": false,
|
||||||
"keyboard_controls": {
|
"keyboard_config": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"controller_type": "JoyconPair",
|
||||||
|
"player_index": "Player1",
|
||||||
"left_joycon": {
|
"left_joycon": {
|
||||||
"stick_up": "W",
|
"stick_up": "W",
|
||||||
"stick_down": "S",
|
"stick_down": "S",
|
||||||
|
@ -52,7 +55,9 @@
|
||||||
"dpad_right": "Right",
|
"dpad_right": "Right",
|
||||||
"button_minus": "Minus",
|
"button_minus": "Minus",
|
||||||
"button_l": "E",
|
"button_l": "E",
|
||||||
"button_zl": "Q"
|
"button_zl": "Q",
|
||||||
|
"button_sl": "Unbound",
|
||||||
|
"button_sr": "Unbound"
|
||||||
},
|
},
|
||||||
"right_joycon": {
|
"right_joycon": {
|
||||||
"stick_up": "I",
|
"stick_up": "I",
|
||||||
|
@ -66,38 +71,14 @@
|
||||||
"button_y": "V",
|
"button_y": "V",
|
||||||
"button_plus": "Plus",
|
"button_plus": "Plus",
|
||||||
"button_r": "U",
|
"button_r": "U",
|
||||||
"button_zr": "O"
|
"button_zr": "O",
|
||||||
|
"button_sl": "Unbound",
|
||||||
|
"button_sr": "Unbound"
|
||||||
},
|
},
|
||||||
"hotkeys": {
|
"hotkeys": {
|
||||||
"toggle_vsync": "Tab"
|
"toggle_vsync": "Tab"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"joystick_controls": {
|
|
||||||
"enabled": true,
|
|
||||||
"index": 0,
|
|
||||||
"deadzone": 0.05,
|
|
||||||
"trigger_threshold": 0.5,
|
|
||||||
"left_joycon": {
|
|
||||||
"stick": "Axis0",
|
|
||||||
"stick_button": "Button8",
|
|
||||||
"button_minus": "Button6",
|
|
||||||
"button_l": "Button4",
|
|
||||||
"button_zl": "Axis2",
|
|
||||||
"dpad_up": "Hat0Up",
|
|
||||||
"dpad_down": "Hat0Down",
|
|
||||||
"dpad_left": "Hat0Left",
|
|
||||||
"dpad_right": "Hat0Right"
|
|
||||||
},
|
|
||||||
"right_joycon": {
|
|
||||||
"stick": "Axis3",
|
|
||||||
"stick_button": "Button9",
|
|
||||||
"button_a": "Button1",
|
|
||||||
"button_b": "Button0",
|
|
||||||
"button_x": "Button3",
|
|
||||||
"button_y": "Button2",
|
|
||||||
"button_plus": "Button7",
|
|
||||||
"button_r": "Button5",
|
|
||||||
"button_zr": "Axis5"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"controller_config": []
|
||||||
}
|
}
|
|
@ -31,9 +31,10 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Ui\AboutWindow.glade" />
|
<None Remove="Ui\AboutWindow.glade" />
|
||||||
<None Remove="Ui\assets\BlueCon.png" />
|
<None Remove="Ui\assets\JoyConLeft.svg" />
|
||||||
<None Remove="Ui\assets\ProCon.png" />
|
<None Remove="Ui\assets\JoyConPair.svg" />
|
||||||
<None Remove="Ui\assets\RedCon.png" />
|
<None Remove="Ui\assets\JoyConRight.svg" />
|
||||||
|
<None Remove="Ui\assets\ProCon.svg" />
|
||||||
<None Remove="Ui\assets\NCAIcon.png" />
|
<None Remove="Ui\assets\NCAIcon.png" />
|
||||||
<None Remove="Ui\assets\NROIcon.png" />
|
<None Remove="Ui\assets\NROIcon.png" />
|
||||||
<None Remove="Ui\assets\NSOIcon.png" />
|
<None Remove="Ui\assets\NSOIcon.png" />
|
||||||
|
@ -41,21 +42,23 @@
|
||||||
<None Remove="Ui\assets\XCIIcon.png" />
|
<None Remove="Ui\assets\XCIIcon.png" />
|
||||||
<None Remove="Ui\assets\DiscordLogo.png" />
|
<None Remove="Ui\assets\DiscordLogo.png" />
|
||||||
<None Remove="Ui\assets\GitHubLogo.png" />
|
<None Remove="Ui\assets\GitHubLogo.png" />
|
||||||
<None Remove="Ui\assets\JoyCon.png" />
|
|
||||||
<None Remove="Ui\assets\PatreonLogo.png" />
|
<None Remove="Ui\assets\PatreonLogo.png" />
|
||||||
<None Remove="Ui\assets\Icon.png" />
|
<None Remove="Ui\assets\Icon.png" />
|
||||||
<None Remove="Ui\assets\TwitterLogo.png" />
|
<None Remove="Ui\assets\TwitterLogo.png" />
|
||||||
|
<None Remove="Ui\ControllerWindow.glade" />
|
||||||
<None Remove="Ui\GameTableContextMenu.glade" />
|
<None Remove="Ui\GameTableContextMenu.glade" />
|
||||||
<None Remove="Ui\MainWindow.glade" />
|
<None Remove="Ui\MainWindow.glade" />
|
||||||
<None Remove="Ui\SwitchSettings.glade" />
|
<None Remove="Ui\ProfileDialog.glade" />
|
||||||
|
<None Remove="Ui\SettingsWindow.glade" />
|
||||||
<None Remove="Ui\TitleUpdateWindow.glade" />
|
<None Remove="Ui\TitleUpdateWindow.glade" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Ui\AboutWindow.glade" />
|
<EmbeddedResource Include="Ui\AboutWindow.glade" />
|
||||||
<EmbeddedResource Include="Ui\assets\BlueCon.png" />
|
<EmbeddedResource Include="Ui\assets\JoyConLeft.svg" />
|
||||||
<EmbeddedResource Include="Ui\assets\ProCon.png" />
|
<EmbeddedResource Include="Ui\assets\JoyConPair.svg" />
|
||||||
<EmbeddedResource Include="Ui\assets\RedCon.png" />
|
<EmbeddedResource Include="Ui\assets\JoyConRight.svg" />
|
||||||
|
<EmbeddedResource Include="Ui\assets\ProCon.svg" />
|
||||||
<EmbeddedResource Include="Ui\assets\NCAIcon.png" />
|
<EmbeddedResource Include="Ui\assets\NCAIcon.png" />
|
||||||
<EmbeddedResource Include="Ui\assets\NROIcon.png" />
|
<EmbeddedResource Include="Ui\assets\NROIcon.png" />
|
||||||
<EmbeddedResource Include="Ui\assets\NSOIcon.png" />
|
<EmbeddedResource Include="Ui\assets\NSOIcon.png" />
|
||||||
|
@ -63,13 +66,14 @@
|
||||||
<EmbeddedResource Include="Ui\assets\XCIIcon.png" />
|
<EmbeddedResource Include="Ui\assets\XCIIcon.png" />
|
||||||
<EmbeddedResource Include="Ui\assets\DiscordLogo.png" />
|
<EmbeddedResource Include="Ui\assets\DiscordLogo.png" />
|
||||||
<EmbeddedResource Include="Ui\assets\GitHubLogo.png" />
|
<EmbeddedResource Include="Ui\assets\GitHubLogo.png" />
|
||||||
<EmbeddedResource Include="Ui\assets\JoyCon.png" />
|
|
||||||
<EmbeddedResource Include="Ui\assets\PatreonLogo.png" />
|
<EmbeddedResource Include="Ui\assets\PatreonLogo.png" />
|
||||||
<EmbeddedResource Include="Ui\assets\Icon.png" />
|
<EmbeddedResource Include="Ui\assets\Icon.png" />
|
||||||
<EmbeddedResource Include="Ui\assets\TwitterLogo.png" />
|
<EmbeddedResource Include="Ui\assets\TwitterLogo.png" />
|
||||||
|
<EmbeddedResource Include="Ui\ControllerWindow.glade" />
|
||||||
<EmbeddedResource Include="Ui\GameTableContextMenu.glade" />
|
<EmbeddedResource Include="Ui\GameTableContextMenu.glade" />
|
||||||
<EmbeddedResource Include="Ui\MainWindow.glade" />
|
<EmbeddedResource Include="Ui\MainWindow.glade" />
|
||||||
<EmbeddedResource Include="Ui\SwitchSettings.glade" />
|
<EmbeddedResource Include="Ui\ProfileDialog.glade" />
|
||||||
|
<EmbeddedResource Include="Ui\SettingsWindow.glade" />
|
||||||
<EmbeddedResource Include="Ui\TitleUpdateWindow.glade" />
|
<EmbeddedResource Include="Ui\TitleUpdateWindow.glade" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
#pragma warning disable IDE0044
|
#pragma warning disable IDE0044
|
||||||
[GUI] Window _aboutWin;
|
|
||||||
[GUI] Label _versionText;
|
[GUI] Label _versionText;
|
||||||
[GUI] Image _ryujinxLogo;
|
[GUI] Image _ryujinxLogo;
|
||||||
[GUI] Image _patreonLogo;
|
[GUI] Image _patreonLogo;
|
||||||
|
@ -28,7 +27,7 @@ namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
builder.Autoconnect(this);
|
builder.Autoconnect(this);
|
||||||
|
|
||||||
_aboutWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
this.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
||||||
_ryujinxLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png" , 100, 100);
|
_ryujinxLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png" , 100, 100);
|
||||||
_patreonLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.PatreonLogo.png", 30 , 30 );
|
_patreonLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.PatreonLogo.png", 30 , 30 );
|
||||||
_gitHubLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.GitHubLogo.png" , 30 , 30 );
|
_gitHubLogo.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.GitHubLogo.png" , 30 , 30 );
|
||||||
|
|
|
@ -413,7 +413,7 @@ namespace Ryujinx.Ui
|
||||||
Version = version,
|
Version = version,
|
||||||
TimePlayed = ConvertSecondsToReadableString(appMetadata.TimePlayed),
|
TimePlayed = ConvertSecondsToReadableString(appMetadata.TimePlayed),
|
||||||
LastPlayed = appMetadata.LastPlayed,
|
LastPlayed = appMetadata.LastPlayed,
|
||||||
FileExtension = Path.GetExtension(applicationPath).ToUpper().Remove(0 ,1),
|
FileExtension = Path.GetExtension(applicationPath).ToUpper().Remove(0, 1),
|
||||||
FileSize = (fileSize < 1) ? (fileSize * 1024).ToString("0.##") + "MB" : fileSize.ToString("0.##") + "GB",
|
FileSize = (fileSize < 1) ? (fileSize * 1024).ToString("0.##") + "MB" : fileSize.ToString("0.##") + "GB",
|
||||||
Path = applicationPath,
|
Path = applicationPath,
|
||||||
SaveDataPath = saveDataPath,
|
SaveDataPath = saveDataPath,
|
||||||
|
|
925
Ryujinx/Ui/ControllerWindow.cs
Normal file
|
@ -0,0 +1,925 @@
|
||||||
|
using Gtk;
|
||||||
|
using OpenTK.Input;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
using Ryujinx.Configuration;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
using Ryujinx.Common.Utilities;
|
||||||
|
using Ryujinx.HLE.FileSystem;
|
||||||
|
|
||||||
|
using GUI = Gtk.Builder.ObjectAttribute;
|
||||||
|
using Key = Ryujinx.Configuration.Hid.Key;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ui
|
||||||
|
{
|
||||||
|
public class ControllerWindow : Window
|
||||||
|
{
|
||||||
|
private PlayerIndex _playerIndex;
|
||||||
|
private InputConfig _inputConfig;
|
||||||
|
private bool _isWaitingForInput;
|
||||||
|
private VirtualFileSystem _virtualFileSystem;
|
||||||
|
|
||||||
|
#pragma warning disable CS0649, IDE0044
|
||||||
|
[GUI] Adjustment _controllerDeadzoneLeft;
|
||||||
|
[GUI] Adjustment _controllerDeadzoneRight;
|
||||||
|
[GUI] Adjustment _controllerTriggerThreshold;
|
||||||
|
[GUI] ComboBoxText _inputDevice;
|
||||||
|
[GUI] ComboBoxText _profile;
|
||||||
|
[GUI] ToggleButton _refreshInputDevicesButton;
|
||||||
|
[GUI] Box _settingsBox;
|
||||||
|
[GUI] Grid _leftStickKeyboard;
|
||||||
|
[GUI] Grid _leftStickController;
|
||||||
|
[GUI] Box _deadZoneLeftBox;
|
||||||
|
[GUI] Grid _rightStickKeyboard;
|
||||||
|
[GUI] Grid _rightStickController;
|
||||||
|
[GUI] Box _deadZoneRightBox;
|
||||||
|
[GUI] Grid _leftSideTriggerBox;
|
||||||
|
[GUI] Grid _rightSideTriggerBox;
|
||||||
|
[GUI] Box _triggerThresholdBox;
|
||||||
|
[GUI] ComboBoxText _controllerType;
|
||||||
|
[GUI] ToggleButton _lStickX;
|
||||||
|
[GUI] CheckButton _invertLStickX;
|
||||||
|
[GUI] ToggleButton _lStickY;
|
||||||
|
[GUI] CheckButton _invertLStickY;
|
||||||
|
[GUI] ToggleButton _lStickUp;
|
||||||
|
[GUI] ToggleButton _lStickDown;
|
||||||
|
[GUI] ToggleButton _lStickLeft;
|
||||||
|
[GUI] ToggleButton _lStickRight;
|
||||||
|
[GUI] ToggleButton _lStickButton;
|
||||||
|
[GUI] ToggleButton _dpadUp;
|
||||||
|
[GUI] ToggleButton _dpadDown;
|
||||||
|
[GUI] ToggleButton _dpadLeft;
|
||||||
|
[GUI] ToggleButton _dpadRight;
|
||||||
|
[GUI] ToggleButton _minus;
|
||||||
|
[GUI] ToggleButton _l;
|
||||||
|
[GUI] ToggleButton _zL;
|
||||||
|
[GUI] ToggleButton _rStickX;
|
||||||
|
[GUI] CheckButton _invertRStickX;
|
||||||
|
[GUI] ToggleButton _rStickY;
|
||||||
|
[GUI] CheckButton _invertRStickY;
|
||||||
|
[GUI] ToggleButton _rStickUp;
|
||||||
|
[GUI] ToggleButton _rStickDown;
|
||||||
|
[GUI] ToggleButton _rStickLeft;
|
||||||
|
[GUI] ToggleButton _rStickRight;
|
||||||
|
[GUI] ToggleButton _rStickButton;
|
||||||
|
[GUI] ToggleButton _a;
|
||||||
|
[GUI] ToggleButton _b;
|
||||||
|
[GUI] ToggleButton _x;
|
||||||
|
[GUI] ToggleButton _y;
|
||||||
|
[GUI] ToggleButton _plus;
|
||||||
|
[GUI] ToggleButton _r;
|
||||||
|
[GUI] ToggleButton _zR;
|
||||||
|
[GUI] ToggleButton _lSl;
|
||||||
|
[GUI] ToggleButton _lSr;
|
||||||
|
[GUI] ToggleButton _rSl;
|
||||||
|
[GUI] ToggleButton _rSr;
|
||||||
|
[GUI] Image _controllerImage;
|
||||||
|
#pragma warning restore CS0649, IDE0044
|
||||||
|
|
||||||
|
public ControllerWindow(PlayerIndex controllerId, VirtualFileSystem virtualFileSystem) : this(new Builder("Ryujinx.Ui.ControllerWindow.glade"), controllerId, virtualFileSystem) { }
|
||||||
|
|
||||||
|
private ControllerWindow(Builder builder, PlayerIndex controllerId, VirtualFileSystem virtualFileSystem) : base(builder.GetObject("_controllerWin").Handle)
|
||||||
|
{
|
||||||
|
builder.Autoconnect(this);
|
||||||
|
|
||||||
|
this.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
||||||
|
|
||||||
|
_playerIndex = controllerId;
|
||||||
|
_virtualFileSystem = virtualFileSystem;
|
||||||
|
_inputConfig = ConfigurationState.Instance.Hid.InputConfig.Value.Find(inputConfig => inputConfig.PlayerIndex == _playerIndex);
|
||||||
|
|
||||||
|
//Bind Events
|
||||||
|
_lStickX.Clicked += Button_Pressed;
|
||||||
|
_lStickY.Clicked += Button_Pressed;
|
||||||
|
_lStickUp.Clicked += Button_Pressed;
|
||||||
|
_lStickDown.Clicked += Button_Pressed;
|
||||||
|
_lStickLeft.Clicked += Button_Pressed;
|
||||||
|
_lStickRight.Clicked += Button_Pressed;
|
||||||
|
_lStickButton.Clicked += Button_Pressed;
|
||||||
|
_dpadUp.Clicked += Button_Pressed;
|
||||||
|
_dpadDown.Clicked += Button_Pressed;
|
||||||
|
_dpadLeft.Clicked += Button_Pressed;
|
||||||
|
_dpadRight.Clicked += Button_Pressed;
|
||||||
|
_minus.Clicked += Button_Pressed;
|
||||||
|
_l.Clicked += Button_Pressed;
|
||||||
|
_zL.Clicked += Button_Pressed;
|
||||||
|
_lSl.Clicked += Button_Pressed;
|
||||||
|
_lSr.Clicked += Button_Pressed;
|
||||||
|
_rStickX.Clicked += Button_Pressed;
|
||||||
|
_rStickY.Clicked += Button_Pressed;
|
||||||
|
_rStickUp.Clicked += Button_Pressed;
|
||||||
|
_rStickDown.Clicked += Button_Pressed;
|
||||||
|
_rStickLeft.Clicked += Button_Pressed;
|
||||||
|
_rStickRight.Clicked += Button_Pressed;
|
||||||
|
_rStickButton.Clicked += Button_Pressed;
|
||||||
|
_a.Clicked += Button_Pressed;
|
||||||
|
_b.Clicked += Button_Pressed;
|
||||||
|
_x.Clicked += Button_Pressed;
|
||||||
|
_y.Clicked += Button_Pressed;
|
||||||
|
_plus.Clicked += Button_Pressed;
|
||||||
|
_r.Clicked += Button_Pressed;
|
||||||
|
_zR.Clicked += Button_Pressed;
|
||||||
|
_rSl.Clicked += Button_Pressed;
|
||||||
|
_rSr.Clicked += Button_Pressed;
|
||||||
|
|
||||||
|
// Setup current values
|
||||||
|
UpdateInputDeviceList();
|
||||||
|
SetAvailableOptions();
|
||||||
|
|
||||||
|
ClearValues();
|
||||||
|
if (_inputDevice.ActiveId != null) SetCurrentValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateInputDeviceList()
|
||||||
|
{
|
||||||
|
_inputDevice.RemoveAll();
|
||||||
|
_inputDevice.Append("disabled", "Disabled");
|
||||||
|
_inputDevice.SetActiveId("disabled");
|
||||||
|
|
||||||
|
for (int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
if (Keyboard.GetState(i).IsConnected)
|
||||||
|
_inputDevice.Append($"keyboard/{i}", $"Keyboard/{i}");
|
||||||
|
|
||||||
|
if (GamePad.GetState(i).IsConnected)
|
||||||
|
_inputDevice.Append($"controller/{i}", $"Controller/{i} ({GamePad.GetName(i)})");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_inputConfig)
|
||||||
|
{
|
||||||
|
case KeyboardConfig keyboard:
|
||||||
|
_inputDevice.SetActiveId($"keyboard/{keyboard.Index}");
|
||||||
|
break;
|
||||||
|
case ControllerConfig controller:
|
||||||
|
_inputDevice.SetActiveId($"controller/{controller.Index}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetAvailableOptions()
|
||||||
|
{
|
||||||
|
if (_inputDevice.ActiveId != null && _inputDevice.ActiveId.StartsWith("keyboard"))
|
||||||
|
{
|
||||||
|
this.ShowAll();
|
||||||
|
_leftStickController.Hide();
|
||||||
|
_rightStickController.Hide();
|
||||||
|
_deadZoneLeftBox.Hide();
|
||||||
|
_deadZoneRightBox.Hide();
|
||||||
|
_triggerThresholdBox.Hide();
|
||||||
|
}
|
||||||
|
else if (_inputDevice.ActiveId != null && _inputDevice.ActiveId.StartsWith("controller"))
|
||||||
|
{
|
||||||
|
this.ShowAll();
|
||||||
|
_leftStickKeyboard.Hide();
|
||||||
|
_rightStickKeyboard.Hide();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_settingsBox.Hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCurrentValues()
|
||||||
|
{
|
||||||
|
SetControllerSpecificFields();
|
||||||
|
|
||||||
|
SetProfiles();
|
||||||
|
|
||||||
|
if (_inputDevice.ActiveId.StartsWith("keyboard") && _inputConfig is KeyboardConfig)
|
||||||
|
{
|
||||||
|
SetValues(_inputConfig);
|
||||||
|
}
|
||||||
|
else if (_inputDevice.ActiveId.StartsWith("controller") && _inputConfig is ControllerConfig)
|
||||||
|
{
|
||||||
|
SetValues(_inputConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetControllerSpecificFields()
|
||||||
|
{
|
||||||
|
_leftSideTriggerBox.Hide();
|
||||||
|
_rightSideTriggerBox.Hide();
|
||||||
|
|
||||||
|
switch (_controllerType.ActiveId)
|
||||||
|
{
|
||||||
|
case "JoyconLeft":
|
||||||
|
_leftSideTriggerBox.Show();
|
||||||
|
break;
|
||||||
|
case "JoyconRight":
|
||||||
|
_rightSideTriggerBox.Show();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_controllerType.ActiveId)
|
||||||
|
{
|
||||||
|
case "ProController":
|
||||||
|
_controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.ProCon.svg", 400, 400);
|
||||||
|
break;
|
||||||
|
case "JoyconLeft":
|
||||||
|
_controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyConLeft.svg", 400, 400);
|
||||||
|
break;
|
||||||
|
case "JoyconRight":
|
||||||
|
_controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyConRight.svg", 400, 400);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyConPair.svg", 400, 400);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearValues()
|
||||||
|
{
|
||||||
|
_lStickX.Label = "Unbound";
|
||||||
|
_lStickY.Label = "Unbound";
|
||||||
|
_lStickUp.Label = "Unbound";
|
||||||
|
_lStickDown.Label = "Unbound";
|
||||||
|
_lStickLeft.Label = "Unbound";
|
||||||
|
_lStickRight.Label = "Unbound";
|
||||||
|
_lStickButton.Label = "Unbound";
|
||||||
|
_dpadUp.Label = "Unbound";
|
||||||
|
_dpadDown.Label = "Unbound";
|
||||||
|
_dpadLeft.Label = "Unbound";
|
||||||
|
_dpadRight.Label = "Unbound";
|
||||||
|
_minus.Label = "Unbound";
|
||||||
|
_l.Label = "Unbound";
|
||||||
|
_zL.Label = "Unbound";
|
||||||
|
_lSl.Label = "Unbound";
|
||||||
|
_lSr.Label = "Unbound";
|
||||||
|
_rStickX.Label = "Unbound";
|
||||||
|
_rStickY.Label = "Unbound";
|
||||||
|
_rStickUp.Label = "Unbound";
|
||||||
|
_rStickDown.Label = "Unbound";
|
||||||
|
_rStickLeft.Label = "Unbound";
|
||||||
|
_rStickRight.Label = "Unbound";
|
||||||
|
_rStickButton.Label = "Unbound";
|
||||||
|
_a.Label = "Unbound";
|
||||||
|
_b.Label = "Unbound";
|
||||||
|
_x.Label = "Unbound";
|
||||||
|
_y.Label = "Unbound";
|
||||||
|
_plus.Label = "Unbound";
|
||||||
|
_r.Label = "Unbound";
|
||||||
|
_zR.Label = "Unbound";
|
||||||
|
_rSl.Label = "Unbound";
|
||||||
|
_rSr.Label = "Unbound";
|
||||||
|
_controllerDeadzoneLeft.Value = 0;
|
||||||
|
_controllerDeadzoneRight.Value = 0;
|
||||||
|
_controllerTriggerThreshold.Value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetValues(InputConfig config)
|
||||||
|
{
|
||||||
|
switch (config)
|
||||||
|
{
|
||||||
|
case KeyboardConfig keyboardConfig:
|
||||||
|
_controllerType.SetActiveId(keyboardConfig.ControllerType.ToString());
|
||||||
|
|
||||||
|
_lStickUp.Label = keyboardConfig.LeftJoycon.StickUp.ToString();
|
||||||
|
_lStickDown.Label = keyboardConfig.LeftJoycon.StickDown.ToString();
|
||||||
|
_lStickLeft.Label = keyboardConfig.LeftJoycon.StickLeft.ToString();
|
||||||
|
_lStickRight.Label = keyboardConfig.LeftJoycon.StickRight.ToString();
|
||||||
|
_lStickButton.Label = keyboardConfig.LeftJoycon.StickButton.ToString();
|
||||||
|
_dpadUp.Label = keyboardConfig.LeftJoycon.DPadUp.ToString();
|
||||||
|
_dpadDown.Label = keyboardConfig.LeftJoycon.DPadDown.ToString();
|
||||||
|
_dpadLeft.Label = keyboardConfig.LeftJoycon.DPadLeft.ToString();
|
||||||
|
_dpadRight.Label = keyboardConfig.LeftJoycon.DPadRight.ToString();
|
||||||
|
_minus.Label = keyboardConfig.LeftJoycon.ButtonMinus.ToString();
|
||||||
|
_l.Label = keyboardConfig.LeftJoycon.ButtonL.ToString();
|
||||||
|
_zL.Label = keyboardConfig.LeftJoycon.ButtonZl.ToString();
|
||||||
|
_lSl.Label = keyboardConfig.LeftJoycon.ButtonSl.ToString();
|
||||||
|
_lSr.Label = keyboardConfig.LeftJoycon.ButtonSr.ToString();
|
||||||
|
_rStickUp.Label = keyboardConfig.RightJoycon.StickUp.ToString();
|
||||||
|
_rStickDown.Label = keyboardConfig.RightJoycon.StickDown.ToString();
|
||||||
|
_rStickLeft.Label = keyboardConfig.RightJoycon.StickLeft.ToString();
|
||||||
|
_rStickRight.Label = keyboardConfig.RightJoycon.StickRight.ToString();
|
||||||
|
_rStickButton.Label = keyboardConfig.RightJoycon.StickButton.ToString();
|
||||||
|
_a.Label = keyboardConfig.RightJoycon.ButtonA.ToString();
|
||||||
|
_b.Label = keyboardConfig.RightJoycon.ButtonB.ToString();
|
||||||
|
_x.Label = keyboardConfig.RightJoycon.ButtonX.ToString();
|
||||||
|
_y.Label = keyboardConfig.RightJoycon.ButtonY.ToString();
|
||||||
|
_plus.Label = keyboardConfig.RightJoycon.ButtonPlus.ToString();
|
||||||
|
_r.Label = keyboardConfig.RightJoycon.ButtonR.ToString();
|
||||||
|
_zR.Label = keyboardConfig.RightJoycon.ButtonZr.ToString();
|
||||||
|
_rSl.Label = keyboardConfig.RightJoycon.ButtonSl.ToString();
|
||||||
|
_rSr.Label = keyboardConfig.RightJoycon.ButtonSr.ToString();
|
||||||
|
break;
|
||||||
|
case ControllerConfig controllerConfig:
|
||||||
|
_controllerType.SetActiveId(controllerConfig.ControllerType.ToString());
|
||||||
|
|
||||||
|
_lStickX.Label = controllerConfig.LeftJoycon.StickX.ToString();
|
||||||
|
_invertLStickX.Active = controllerConfig.LeftJoycon.InvertStickX;
|
||||||
|
_lStickY.Label = controllerConfig.LeftJoycon.StickY.ToString();
|
||||||
|
_invertLStickY.Active = controllerConfig.LeftJoycon.InvertStickY;
|
||||||
|
_lStickButton.Label = controllerConfig.LeftJoycon.StickButton.ToString();
|
||||||
|
_dpadUp.Label = controllerConfig.LeftJoycon.DPadUp.ToString();
|
||||||
|
_dpadDown.Label = controllerConfig.LeftJoycon.DPadDown.ToString();
|
||||||
|
_dpadLeft.Label = controllerConfig.LeftJoycon.DPadLeft.ToString();
|
||||||
|
_dpadRight.Label = controllerConfig.LeftJoycon.DPadRight.ToString();
|
||||||
|
_minus.Label = controllerConfig.LeftJoycon.ButtonMinus.ToString();
|
||||||
|
_l.Label = controllerConfig.LeftJoycon.ButtonL.ToString();
|
||||||
|
_zL.Label = controllerConfig.LeftJoycon.ButtonZl.ToString();
|
||||||
|
_lSl.Label = controllerConfig.LeftJoycon.ButtonSl.ToString();
|
||||||
|
_lSr.Label = controllerConfig.LeftJoycon.ButtonSr.ToString();
|
||||||
|
_rStickX.Label = controllerConfig.RightJoycon.StickX.ToString();
|
||||||
|
_invertRStickX.Active = controllerConfig.RightJoycon.InvertStickX;
|
||||||
|
_rStickY.Label = controllerConfig.RightJoycon.StickY.ToString();
|
||||||
|
_invertRStickY.Active = controllerConfig.RightJoycon.InvertStickY;
|
||||||
|
_rStickButton.Label = controllerConfig.RightJoycon.StickButton.ToString();
|
||||||
|
_a.Label = controllerConfig.RightJoycon.ButtonA.ToString();
|
||||||
|
_b.Label = controllerConfig.RightJoycon.ButtonB.ToString();
|
||||||
|
_x.Label = controllerConfig.RightJoycon.ButtonX.ToString();
|
||||||
|
_y.Label = controllerConfig.RightJoycon.ButtonY.ToString();
|
||||||
|
_plus.Label = controllerConfig.RightJoycon.ButtonPlus.ToString();
|
||||||
|
_r.Label = controllerConfig.RightJoycon.ButtonR.ToString();
|
||||||
|
_zR.Label = controllerConfig.RightJoycon.ButtonZr.ToString();
|
||||||
|
_rSl.Label = controllerConfig.RightJoycon.ButtonSl.ToString();
|
||||||
|
_rSr.Label = controllerConfig.RightJoycon.ButtonSr.ToString();
|
||||||
|
_controllerDeadzoneLeft.Value = controllerConfig.DeadzoneLeft;
|
||||||
|
_controllerDeadzoneRight.Value = controllerConfig.DeadzoneRight;
|
||||||
|
_controllerTriggerThreshold.Value = controllerConfig.TriggerThreshold;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputConfig GetValues()
|
||||||
|
{
|
||||||
|
if (_inputDevice.ActiveId.StartsWith("keyboard"))
|
||||||
|
{
|
||||||
|
Enum.TryParse(_lStickUp.Label, out Key lStickUp);
|
||||||
|
Enum.TryParse(_lStickDown.Label, out Key lStickDown);
|
||||||
|
Enum.TryParse(_lStickLeft.Label, out Key lStickLeft);
|
||||||
|
Enum.TryParse(_lStickRight.Label, out Key lStickRight);
|
||||||
|
Enum.TryParse(_lStickButton.Label, out Key lStickButton);
|
||||||
|
Enum.TryParse(_dpadUp.Label, out Key lDPadUp);
|
||||||
|
Enum.TryParse(_dpadDown.Label, out Key lDPadDown);
|
||||||
|
Enum.TryParse(_dpadLeft.Label, out Key lDPadLeft);
|
||||||
|
Enum.TryParse(_dpadRight.Label, out Key lDPadRight);
|
||||||
|
Enum.TryParse(_minus.Label, out Key lButtonMinus);
|
||||||
|
Enum.TryParse(_l.Label, out Key lButtonL);
|
||||||
|
Enum.TryParse(_zL.Label, out Key lButtonZl);
|
||||||
|
Enum.TryParse(_lSl.Label, out Key lButtonSl);
|
||||||
|
Enum.TryParse(_lSr.Label, out Key lButtonSr);
|
||||||
|
|
||||||
|
Enum.TryParse(_rStickUp.Label, out Key rStickUp);
|
||||||
|
Enum.TryParse(_rStickDown.Label, out Key rStickDown);
|
||||||
|
Enum.TryParse(_rStickLeft.Label, out Key rStickLeft);
|
||||||
|
Enum.TryParse(_rStickRight.Label, out Key rStickRight);
|
||||||
|
Enum.TryParse(_rStickButton.Label, out Key rStickButton);
|
||||||
|
Enum.TryParse(_a.Label, out Key rButtonA);
|
||||||
|
Enum.TryParse(_b.Label, out Key rButtonB);
|
||||||
|
Enum.TryParse(_x.Label, out Key rButtonX);
|
||||||
|
Enum.TryParse(_y.Label, out Key rButtonY);
|
||||||
|
Enum.TryParse(_plus.Label, out Key rButtonPlus);
|
||||||
|
Enum.TryParse(_r.Label, out Key rButtonR);
|
||||||
|
Enum.TryParse(_zR.Label, out Key rButtonZr);
|
||||||
|
Enum.TryParse(_rSl.Label, out Key rButtonSl);
|
||||||
|
Enum.TryParse(_rSr.Label, out Key rButtonSr);
|
||||||
|
|
||||||
|
return new KeyboardConfig
|
||||||
|
{
|
||||||
|
Index = int.Parse(_inputDevice.ActiveId.Split("/")[1]),
|
||||||
|
ControllerType = Enum.Parse<ControllerType>(_controllerType.ActiveId),
|
||||||
|
PlayerIndex = _playerIndex,
|
||||||
|
LeftJoycon = new NpadKeyboardLeft
|
||||||
|
{
|
||||||
|
StickUp = lStickUp,
|
||||||
|
StickDown = lStickDown,
|
||||||
|
StickLeft = lStickLeft,
|
||||||
|
StickRight = lStickRight,
|
||||||
|
StickButton = lStickButton,
|
||||||
|
DPadUp = lDPadUp,
|
||||||
|
DPadDown = lDPadDown,
|
||||||
|
DPadLeft = lDPadLeft,
|
||||||
|
DPadRight = lDPadRight,
|
||||||
|
ButtonMinus = lButtonMinus,
|
||||||
|
ButtonL = lButtonL,
|
||||||
|
ButtonZl = lButtonZl,
|
||||||
|
ButtonSl = lButtonSl,
|
||||||
|
ButtonSr = lButtonSr
|
||||||
|
},
|
||||||
|
RightJoycon = new NpadKeyboardRight
|
||||||
|
{
|
||||||
|
StickUp = rStickUp,
|
||||||
|
StickDown = rStickDown,
|
||||||
|
StickLeft = rStickLeft,
|
||||||
|
StickRight = rStickRight,
|
||||||
|
StickButton = rStickButton,
|
||||||
|
ButtonA = rButtonA,
|
||||||
|
ButtonB = rButtonB,
|
||||||
|
ButtonX = rButtonX,
|
||||||
|
ButtonY = rButtonY,
|
||||||
|
ButtonPlus = rButtonPlus,
|
||||||
|
ButtonR = rButtonR,
|
||||||
|
ButtonZr = rButtonZr,
|
||||||
|
ButtonSl = rButtonSl,
|
||||||
|
ButtonSr = rButtonSr
|
||||||
|
},
|
||||||
|
Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVsync = Key.Tab //TODO: Make this an option in the GUI
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_inputDevice.ActiveId.StartsWith("controller"))
|
||||||
|
{
|
||||||
|
Enum.TryParse(_lStickX.Label, out ControllerInputId lStickX);
|
||||||
|
Enum.TryParse(_lStickY.Label, out ControllerInputId lStickY);
|
||||||
|
Enum.TryParse(_lStickButton.Label, out ControllerInputId lStickButton);
|
||||||
|
Enum.TryParse(_minus.Label, out ControllerInputId lButtonMinus);
|
||||||
|
Enum.TryParse(_l.Label, out ControllerInputId lButtonL);
|
||||||
|
Enum.TryParse(_zL.Label, out ControllerInputId lButtonZl);
|
||||||
|
Enum.TryParse(_lSl.Label, out ControllerInputId lButtonSl);
|
||||||
|
Enum.TryParse(_lSr.Label, out ControllerInputId lButtonSr);
|
||||||
|
Enum.TryParse(_dpadUp.Label, out ControllerInputId lDPadUp);
|
||||||
|
Enum.TryParse(_dpadDown.Label, out ControllerInputId lDPadDown);
|
||||||
|
Enum.TryParse(_dpadLeft.Label, out ControllerInputId lDPadLeft);
|
||||||
|
Enum.TryParse(_dpadRight.Label, out ControllerInputId lDPadRight);
|
||||||
|
|
||||||
|
Enum.TryParse(_rStickX.Label, out ControllerInputId rStickX);
|
||||||
|
Enum.TryParse(_rStickY.Label, out ControllerInputId rStickY);
|
||||||
|
Enum.TryParse(_rStickButton.Label, out ControllerInputId rStickButton);
|
||||||
|
Enum.TryParse(_a.Label, out ControllerInputId rButtonA);
|
||||||
|
Enum.TryParse(_b.Label, out ControllerInputId rButtonB);
|
||||||
|
Enum.TryParse(_x.Label, out ControllerInputId rButtonX);
|
||||||
|
Enum.TryParse(_y.Label, out ControllerInputId rButtonY);
|
||||||
|
Enum.TryParse(_plus.Label, out ControllerInputId rButtonPlus);
|
||||||
|
Enum.TryParse(_r.Label, out ControllerInputId rButtonR);
|
||||||
|
Enum.TryParse(_zR.Label, out ControllerInputId rButtonZr);
|
||||||
|
Enum.TryParse(_rSl.Label, out ControllerInputId rButtonSl);
|
||||||
|
Enum.TryParse(_rSr.Label, out ControllerInputId rButtonSr);
|
||||||
|
|
||||||
|
return new ControllerConfig
|
||||||
|
{
|
||||||
|
Index = int.Parse(_inputDevice.ActiveId.Split("/")[1]),
|
||||||
|
ControllerType = Enum.Parse<ControllerType>(_controllerType.ActiveId),
|
||||||
|
PlayerIndex = _playerIndex,
|
||||||
|
DeadzoneLeft = (float)_controllerDeadzoneLeft.Value,
|
||||||
|
DeadzoneRight = (float)_controllerDeadzoneRight.Value,
|
||||||
|
TriggerThreshold = (float)_controllerTriggerThreshold.Value,
|
||||||
|
LeftJoycon = new NpadControllerLeft
|
||||||
|
{
|
||||||
|
InvertStickX = _invertLStickX.Active,
|
||||||
|
StickX = lStickX,
|
||||||
|
InvertStickY = _invertLStickY.Active,
|
||||||
|
StickY = lStickY,
|
||||||
|
StickButton = lStickButton,
|
||||||
|
ButtonMinus = lButtonMinus,
|
||||||
|
ButtonL = lButtonL,
|
||||||
|
ButtonZl = lButtonZl,
|
||||||
|
ButtonSl = lButtonSl,
|
||||||
|
ButtonSr = lButtonSr,
|
||||||
|
DPadUp = lDPadUp,
|
||||||
|
DPadDown = lDPadDown,
|
||||||
|
DPadLeft = lDPadLeft,
|
||||||
|
DPadRight = lDPadRight
|
||||||
|
},
|
||||||
|
RightJoycon = new NpadControllerRight
|
||||||
|
{
|
||||||
|
InvertStickX = _invertRStickX.Active,
|
||||||
|
StickX = rStickX,
|
||||||
|
InvertStickY = _invertRStickY.Active,
|
||||||
|
StickY = rStickY,
|
||||||
|
StickButton = rStickButton,
|
||||||
|
ButtonA = rButtonA,
|
||||||
|
ButtonB = rButtonB,
|
||||||
|
ButtonX = rButtonX,
|
||||||
|
ButtonY = rButtonY,
|
||||||
|
ButtonPlus = rButtonPlus,
|
||||||
|
ButtonR = rButtonR,
|
||||||
|
ButtonZr = rButtonZr,
|
||||||
|
ButtonSl = rButtonSl,
|
||||||
|
ButtonSr = rButtonSr
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_inputDevice.ActiveId.StartsWith("disabled"))
|
||||||
|
{
|
||||||
|
GtkDialog.CreateErrorDialog("Some fields entered where invalid and therefore your config was not saved.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsAnyKeyPressed(out Key pressedKey, int index = 0)
|
||||||
|
{
|
||||||
|
KeyboardState keyboardState = Keyboard.GetState(index);
|
||||||
|
|
||||||
|
foreach (Key key in Enum.GetValues(typeof(Key)))
|
||||||
|
{
|
||||||
|
if (keyboardState.IsKeyDown((OpenTK.Input.Key)key))
|
||||||
|
{
|
||||||
|
pressedKey = key;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pressedKey = Key.Unbound;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsAnyButtonPressed(out ControllerInputId pressedButton, int index, double triggerThreshold)
|
||||||
|
{
|
||||||
|
JoystickState joystickState = Joystick.GetState(index);
|
||||||
|
JoystickCapabilities joystickCapabilities = Joystick.GetCapabilities(index);
|
||||||
|
|
||||||
|
//Buttons
|
||||||
|
for (int i = 0; i != joystickCapabilities.ButtonCount; i++)
|
||||||
|
{
|
||||||
|
if (joystickState.IsButtonDown(i))
|
||||||
|
{
|
||||||
|
Enum.TryParse($"Button{i}", out pressedButton);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Axis
|
||||||
|
for (int i = 0; i != joystickCapabilities.AxisCount; i++)
|
||||||
|
{
|
||||||
|
if (joystickState.GetAxis(i) > 0.5f && joystickState.GetAxis(i) > triggerThreshold)
|
||||||
|
{
|
||||||
|
Enum.TryParse($"Axis{i}", out pressedButton);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hats
|
||||||
|
for (int i = 0; i != joystickCapabilities.HatCount; i++)
|
||||||
|
{
|
||||||
|
JoystickHatState hatState = joystickState.GetHat((JoystickHat)i);
|
||||||
|
string pos = null;
|
||||||
|
|
||||||
|
if (hatState.IsUp) pos = "Up";
|
||||||
|
if (hatState.IsDown) pos = "Down";
|
||||||
|
if (hatState.IsLeft) pos = "Left";
|
||||||
|
if (hatState.IsRight) pos = "Right";
|
||||||
|
if (pos == null) continue;
|
||||||
|
|
||||||
|
Enum.TryParse($"Hat{i}{pos}", out pressedButton);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pressedButton = ControllerInputId.Unbound;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetProfileBasePath()
|
||||||
|
{
|
||||||
|
string path = System.IO.Path.Combine(_virtualFileSystem.GetBasePath(), "profiles");
|
||||||
|
|
||||||
|
if (_inputDevice.ActiveId.StartsWith("keyboard"))
|
||||||
|
{
|
||||||
|
path = System.IO.Path.Combine(path, "keyboard");
|
||||||
|
}
|
||||||
|
else if (_inputDevice.ActiveId.StartsWith("controller"))
|
||||||
|
{
|
||||||
|
path = System.IO.Path.Combine(path, "controller");
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Events
|
||||||
|
private void InputDevice_Changed(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
SetAvailableOptions();
|
||||||
|
SetControllerSpecificFields();
|
||||||
|
|
||||||
|
if (_inputDevice.ActiveId != null) SetProfiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Controller_Changed(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
SetControllerSpecificFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshInputDevicesButton_Pressed(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
UpdateInputDeviceList();
|
||||||
|
|
||||||
|
_refreshInputDevicesButton.SetStateFlags(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Button_Pressed(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
if (_isWaitingForInput)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isWaitingForInput = true;
|
||||||
|
|
||||||
|
Thread inputThread = new Thread(() =>
|
||||||
|
{
|
||||||
|
Button button = (ToggleButton)sender;
|
||||||
|
|
||||||
|
if (_inputDevice.ActiveId.StartsWith("keyboard"))
|
||||||
|
{
|
||||||
|
Key pressedKey;
|
||||||
|
|
||||||
|
int index = int.Parse(_inputDevice.ActiveId.Split("/")[1]);
|
||||||
|
while (!IsAnyKeyPressed(out pressedKey, index))
|
||||||
|
{
|
||||||
|
if (Mouse.GetState().IsAnyButtonDown || Keyboard.GetState().IsKeyDown(OpenTK.Input.Key.Escape))
|
||||||
|
{
|
||||||
|
Application.Invoke(delegate
|
||||||
|
{
|
||||||
|
button.SetStateFlags(0, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
_isWaitingForInput = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Application.Invoke(delegate
|
||||||
|
{
|
||||||
|
button.Label = pressedKey.ToString();
|
||||||
|
button.SetStateFlags(0, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (_inputDevice.ActiveId.StartsWith("controller"))
|
||||||
|
{
|
||||||
|
ControllerInputId pressedButton;
|
||||||
|
|
||||||
|
int index = int.Parse(_inputDevice.ActiveId.Split("/")[1]);
|
||||||
|
while (!IsAnyButtonPressed(out pressedButton, index, _controllerTriggerThreshold.Value))
|
||||||
|
{
|
||||||
|
if (Mouse.GetState().IsAnyButtonDown || Keyboard.GetState().IsAnyKeyDown)
|
||||||
|
{
|
||||||
|
Application.Invoke(delegate
|
||||||
|
{
|
||||||
|
button.SetStateFlags(0, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
_isWaitingForInput = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Application.Invoke(delegate
|
||||||
|
{
|
||||||
|
button.Label = pressedButton.ToString();
|
||||||
|
button.SetStateFlags(0, true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_isWaitingForInput = false;
|
||||||
|
});
|
||||||
|
inputThread.Name = "GUI.InputThread";
|
||||||
|
inputThread.IsBackground = true;
|
||||||
|
inputThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetProfiles()
|
||||||
|
{
|
||||||
|
string basePath = GetProfileBasePath();
|
||||||
|
|
||||||
|
if (!Directory.Exists(basePath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
_profile.RemoveAll();
|
||||||
|
_profile.Append("default", "Default");
|
||||||
|
|
||||||
|
foreach (string profile in Directory.GetFiles(basePath, "*.*", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
_profile.Append(System.IO.Path.GetFileName(profile), System.IO.Path.GetFileNameWithoutExtension(profile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProfileLoad_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
((ToggleButton)sender).SetStateFlags(0, true);
|
||||||
|
|
||||||
|
if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == null) return;
|
||||||
|
|
||||||
|
InputConfig config = null;
|
||||||
|
int pos = _profile.Active;
|
||||||
|
|
||||||
|
if (_profile.ActiveId == "default")
|
||||||
|
{
|
||||||
|
if (_inputDevice.ActiveId.StartsWith("keyboard"))
|
||||||
|
{
|
||||||
|
config = new KeyboardConfig
|
||||||
|
{
|
||||||
|
Index = 0,
|
||||||
|
ControllerType = ControllerType.JoyconPair,
|
||||||
|
LeftJoycon = new NpadKeyboardLeft
|
||||||
|
{
|
||||||
|
StickUp = Key.W,
|
||||||
|
StickDown = Key.S,
|
||||||
|
StickLeft = Key.A,
|
||||||
|
StickRight = Key.D,
|
||||||
|
StickButton = Key.F,
|
||||||
|
DPadUp = Key.Up,
|
||||||
|
DPadDown = Key.Down,
|
||||||
|
DPadLeft = Key.Left,
|
||||||
|
DPadRight = Key.Right,
|
||||||
|
ButtonMinus = Key.Minus,
|
||||||
|
ButtonL = Key.E,
|
||||||
|
ButtonZl = Key.Q,
|
||||||
|
ButtonSl = Key.Unbound,
|
||||||
|
ButtonSr = Key.Unbound
|
||||||
|
},
|
||||||
|
RightJoycon = new NpadKeyboardRight
|
||||||
|
{
|
||||||
|
StickUp = Key.I,
|
||||||
|
StickDown = Key.K,
|
||||||
|
StickLeft = Key.J,
|
||||||
|
StickRight = Key.L,
|
||||||
|
StickButton = Key.H,
|
||||||
|
ButtonA = Key.Z,
|
||||||
|
ButtonB = Key.X,
|
||||||
|
ButtonX = Key.C,
|
||||||
|
ButtonY = Key.V,
|
||||||
|
ButtonPlus = Key.Plus,
|
||||||
|
ButtonR = Key.U,
|
||||||
|
ButtonZr = Key.O,
|
||||||
|
ButtonSl = Key.Unbound,
|
||||||
|
ButtonSr = Key.Unbound
|
||||||
|
},
|
||||||
|
Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVsync = Key.Tab
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (_inputDevice.ActiveId.StartsWith("controller"))
|
||||||
|
{
|
||||||
|
config = new ControllerConfig
|
||||||
|
{
|
||||||
|
Index = 0,
|
||||||
|
ControllerType = ControllerType.ProController,
|
||||||
|
DeadzoneLeft = 0.1f,
|
||||||
|
DeadzoneRight = 0.1f,
|
||||||
|
TriggerThreshold = 0.5f,
|
||||||
|
LeftJoycon = new NpadControllerLeft
|
||||||
|
{
|
||||||
|
StickX = ControllerInputId.Axis0,
|
||||||
|
StickY = ControllerInputId.Axis1,
|
||||||
|
StickButton = ControllerInputId.Button8,
|
||||||
|
DPadUp = ControllerInputId.Hat0Up,
|
||||||
|
DPadDown = ControllerInputId.Hat0Down,
|
||||||
|
DPadLeft = ControllerInputId.Hat0Left,
|
||||||
|
DPadRight = ControllerInputId.Hat0Right,
|
||||||
|
ButtonMinus = ControllerInputId.Button6,
|
||||||
|
ButtonL = ControllerInputId.Button4,
|
||||||
|
ButtonZl = ControllerInputId.Axis2,
|
||||||
|
ButtonSl = ControllerInputId.Unbound,
|
||||||
|
ButtonSr = ControllerInputId.Unbound,
|
||||||
|
InvertStickX = false,
|
||||||
|
InvertStickY = false
|
||||||
|
},
|
||||||
|
RightJoycon = new NpadControllerRight
|
||||||
|
{
|
||||||
|
StickX = ControllerInputId.Axis3,
|
||||||
|
StickY = ControllerInputId.Axis4,
|
||||||
|
StickButton = ControllerInputId.Button9,
|
||||||
|
ButtonA = ControllerInputId.Button1,
|
||||||
|
ButtonB = ControllerInputId.Button0,
|
||||||
|
ButtonX = ControllerInputId.Button3,
|
||||||
|
ButtonY = ControllerInputId.Button2,
|
||||||
|
ButtonPlus = ControllerInputId.Button7,
|
||||||
|
ButtonR = ControllerInputId.Button5,
|
||||||
|
ButtonZr = ControllerInputId.Axis5,
|
||||||
|
ButtonSl = ControllerInputId.Unbound,
|
||||||
|
ButtonSr = ControllerInputId.Unbound,
|
||||||
|
InvertStickX = false,
|
||||||
|
InvertStickY = false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string path = System.IO.Path.Combine(GetProfileBasePath(), _profile.ActiveId);
|
||||||
|
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
if (pos >= 0)
|
||||||
|
{
|
||||||
|
_profile.Remove(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (Stream stream = File.OpenRead(path))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
config = JsonHelper.Deserialize<ControllerConfig>(stream);
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
config = JsonHelper.Deserialize<KeyboardConfig>(stream);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetValues(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProfileAdd_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
((ToggleButton)sender).SetStateFlags(0, true);
|
||||||
|
|
||||||
|
if (_inputDevice.ActiveId == "disabled") return;
|
||||||
|
|
||||||
|
InputConfig inputConfig = GetValues();
|
||||||
|
ProfileDialog profileDialog = new ProfileDialog();
|
||||||
|
|
||||||
|
if (inputConfig == null) return;
|
||||||
|
|
||||||
|
if (profileDialog.Run() == (int)ResponseType.Ok)
|
||||||
|
{
|
||||||
|
string path = System.IO.Path.Combine(GetProfileBasePath(), profileDialog.FileName);
|
||||||
|
string jsonString;
|
||||||
|
|
||||||
|
if (inputConfig is KeyboardConfig keyboardConfig)
|
||||||
|
{
|
||||||
|
jsonString = JsonHelper.Serialize(keyboardConfig, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jsonString = JsonHelper.Serialize(inputConfig as ControllerConfig, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(path, jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
profileDialog.Dispose();
|
||||||
|
|
||||||
|
SetProfiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProfileRemove_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
((ToggleButton) sender).SetStateFlags(0, true);
|
||||||
|
|
||||||
|
if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == "default" || _profile.ActiveId == null) return;
|
||||||
|
|
||||||
|
MessageDialog confirmDialog = GtkDialog.CreateConfirmationDialog("Deleting Profile", "This action is irreversible, are your sure you want to continue?");
|
||||||
|
|
||||||
|
if (confirmDialog.Run() == (int)ResponseType.Yes)
|
||||||
|
{
|
||||||
|
string path = System.IO.Path.Combine(GetProfileBasePath(), _profile.ActiveId);
|
||||||
|
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
File.Delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetProfiles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveToggle_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
InputConfig inputConfig = GetValues();
|
||||||
|
|
||||||
|
if (_inputConfig == null && inputConfig != null)
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.Hid.InputConfig.Value.Add(inputConfig);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_inputDevice.ActiveId == "disabled")
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.Hid.InputConfig.Value.Remove(_inputConfig);
|
||||||
|
}
|
||||||
|
else if (inputConfig != null)
|
||||||
|
{
|
||||||
|
int index = ConfigurationState.Instance.Hid.InputConfig.Value.IndexOf(_inputConfig);
|
||||||
|
|
||||||
|
ConfigurationState.Instance.Hid.InputConfig.Value[index] = inputConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseToggle_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1732
Ryujinx/Ui/ControllerWindow.glade
Normal file
|
@ -1,22 +1,20 @@
|
||||||
using Gdk;
|
using Gdk;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
using OpenTK.Platform;
|
|
||||||
using Ryujinx.Configuration;
|
using Ryujinx.Configuration;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Graphics.OpenGL;
|
using Ryujinx.Graphics.OpenGL;
|
||||||
using Ryujinx.HLE;
|
using Ryujinx.HLE;
|
||||||
using Ryujinx.HLE.HOS.Services.Hid;
|
using Ryujinx.HLE.HOS.Services.Hid;
|
||||||
using Ryujinx.Ui;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Ui
|
namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
public class GLRenderer : GLWidget
|
public class GlRenderer : GLWidget
|
||||||
{
|
{
|
||||||
private const int SwitchPanelWidth = 1280;
|
private const int SwitchPanelWidth = 1280;
|
||||||
private const int SwitchPanelHeight = 720;
|
private const int SwitchPanelHeight = 720;
|
||||||
|
@ -46,11 +44,9 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
private Renderer _renderer;
|
private Renderer _renderer;
|
||||||
|
|
||||||
private HotkeyButtons _prevHotkeyButtons = 0;
|
private HotkeyButtons _prevHotkeyButtons;
|
||||||
|
|
||||||
private Input.NpadController _primaryController;
|
public GlRenderer(Switch device)
|
||||||
|
|
||||||
public GLRenderer(Switch device)
|
|
||||||
: base (GetGraphicsMode(),
|
: base (GetGraphicsMode(),
|
||||||
3, 3,
|
3, 3,
|
||||||
GraphicsContextFlags.ForwardCompatible)
|
GraphicsContextFlags.ForwardCompatible)
|
||||||
|
@ -69,25 +65,18 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
_ticksPerFrame = System.Diagnostics.Stopwatch.Frequency / TargetFps;
|
_ticksPerFrame = System.Diagnostics.Stopwatch.Frequency / TargetFps;
|
||||||
|
|
||||||
_primaryController = new Input.NpadController(ConfigurationState.Instance.Hid.JoystickControls);
|
AddEvents((int)(EventMask.ButtonPressMask
|
||||||
|
| EventMask.ButtonReleaseMask
|
||||||
AddEvents((int)(Gdk.EventMask.ButtonPressMask
|
| EventMask.PointerMotionMask
|
||||||
| Gdk.EventMask.ButtonReleaseMask
|
| EventMask.KeyPressMask
|
||||||
| Gdk.EventMask.PointerMotionMask
|
| EventMask.KeyReleaseMask));
|
||||||
| Gdk.EventMask.KeyPressMask
|
|
||||||
| Gdk.EventMask.KeyReleaseMask));
|
|
||||||
|
|
||||||
this.Shown += Renderer_Shown;
|
this.Shown += Renderer_Shown;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GraphicsMode GetGraphicsMode()
|
private static GraphicsMode GetGraphicsMode()
|
||||||
{
|
{
|
||||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
return Environment.OSVersion.Platform == PlatformID.Unix ? new GraphicsMode(new ColorFormat(24)) : new GraphicsMode(new ColorFormat());
|
||||||
{
|
|
||||||
return new GraphicsMode(new ColorFormat(24));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new GraphicsMode(new ColorFormat());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GLRenderer_ShuttingDown(object sender, EventArgs args)
|
private void GLRenderer_ShuttingDown(object sender, EventArgs args)
|
||||||
|
@ -165,7 +154,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
protected override bool OnConfigureEvent(EventConfigure evnt)
|
protected override bool OnConfigureEvent(EventConfigure evnt)
|
||||||
{
|
{
|
||||||
var result = base.OnConfigureEvent(evnt);
|
bool result = base.OnConfigureEvent(evnt);
|
||||||
|
|
||||||
Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window);
|
Gdk.Monitor monitor = Display.GetMonitorAtWindow(Window);
|
||||||
|
|
||||||
|
@ -382,10 +371,21 @@ namespace Ryujinx.Ui
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HotkeyButtons currentHotkeyButtons = 0;
|
if (IsFocused)
|
||||||
|
{
|
||||||
|
Gtk.Application.Invoke(delegate
|
||||||
|
{
|
||||||
|
HandleScreenState(OpenTK.Input.Keyboard.GetState());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GamepadInput> gamepadInputs = new List<GamepadInput>();
|
||||||
|
|
||||||
|
foreach (InputConfig inputConfig in ConfigurationState.Instance.Hid.InputConfig.Value)
|
||||||
|
{
|
||||||
ControllerKeys currentButton = 0;
|
ControllerKeys currentButton = 0;
|
||||||
JoystickPosition leftJoystick;
|
JoystickPosition leftJoystick = new JoystickPosition();
|
||||||
JoystickPosition rightJoystick;
|
JoystickPosition rightJoystick = new JoystickPosition();
|
||||||
KeyboardInput? hidKeyboard = null;
|
KeyboardInput? hidKeyboard = null;
|
||||||
|
|
||||||
int leftJoystickDx = 0;
|
int leftJoystickDx = 0;
|
||||||
|
@ -393,50 +393,17 @@ namespace Ryujinx.Ui
|
||||||
int rightJoystickDx = 0;
|
int rightJoystickDx = 0;
|
||||||
int rightJoystickDy = 0;
|
int rightJoystickDy = 0;
|
||||||
|
|
||||||
// OpenTK always captures keyboard events, even if out of focus, so check if window is focused.
|
if (inputConfig is KeyboardConfig keyboardConfig)
|
||||||
|
{
|
||||||
if (IsFocused)
|
if (IsFocused)
|
||||||
{
|
{
|
||||||
KeyboardState keyboard = OpenTK.Input.Keyboard.GetState();
|
// Keyboard Input
|
||||||
|
KeyboardController keyboardController = new KeyboardController(keyboardConfig);
|
||||||
|
|
||||||
Gtk.Application.Invoke(delegate
|
currentButton = keyboardController.GetButtons();
|
||||||
{
|
|
||||||
HandleScreenState(keyboard);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Normal Input
|
(leftJoystickDx, leftJoystickDy) = keyboardController.GetLeftStick();
|
||||||
currentHotkeyButtons = KeyboardControls.GetHotkeyButtons(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
|
(rightJoystickDx, rightJoystickDy) = keyboardController.GetRightStick();
|
||||||
currentButton = KeyboardControls.GetButtons(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Hid.EnableKeyboard)
|
|
||||||
{
|
|
||||||
hidKeyboard = KeyboardControls.GetKeysDown(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
(leftJoystickDx, leftJoystickDy) = KeyboardControls.GetLeftStick(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
|
|
||||||
(rightJoystickDx, rightJoystickDy) = KeyboardControls.GetRightStick(ConfigurationState.Instance.Hid.KeyboardControls, keyboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hidKeyboard.HasValue)
|
|
||||||
{
|
|
||||||
hidKeyboard = new KeyboardInput
|
|
||||||
{
|
|
||||||
Modifier = 0,
|
|
||||||
Keys = new int[0x8]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
currentButton |= _primaryController.GetButtons();
|
|
||||||
|
|
||||||
// Keyboard has priority stick-wise
|
|
||||||
if (leftJoystickDx == 0 && leftJoystickDy == 0)
|
|
||||||
{
|
|
||||||
(leftJoystickDx, leftJoystickDy) = _primaryController.GetLeftStick();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rightJoystickDx == 0 && rightJoystickDy == 0)
|
|
||||||
{
|
|
||||||
(rightJoystickDx, rightJoystickDy) = _primaryController.GetRightStick();
|
|
||||||
}
|
|
||||||
|
|
||||||
leftJoystick = new JoystickPosition
|
leftJoystick = new JoystickPosition
|
||||||
{
|
{
|
||||||
|
@ -450,8 +417,74 @@ namespace Ryujinx.Ui
|
||||||
Dy = rightJoystickDy
|
Dy = rightJoystickDy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Hid.EnableKeyboard)
|
||||||
|
{
|
||||||
|
hidKeyboard = keyboardController.GetKeysDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hidKeyboard.HasValue)
|
||||||
|
{
|
||||||
|
hidKeyboard = new KeyboardInput
|
||||||
|
{
|
||||||
|
Modifier = 0,
|
||||||
|
Keys = new int[0x8]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Hid.EnableKeyboard)
|
||||||
|
{
|
||||||
|
_device.Hid.Keyboard.Update(hidKeyboard.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle vsync
|
||||||
|
HotkeyButtons currentHotkeyButtons = keyboardController.GetHotkeyButtons();
|
||||||
|
|
||||||
|
if (currentHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync) &&
|
||||||
|
!_prevHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync))
|
||||||
|
{
|
||||||
|
_device.EnableDeviceVsync = !_device.EnableDeviceVsync;
|
||||||
|
}
|
||||||
|
|
||||||
|
_prevHotkeyButtons = currentHotkeyButtons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (inputConfig is Common.Configuration.Hid.ControllerConfig controllerConfig)
|
||||||
|
{
|
||||||
|
// Controller Input
|
||||||
|
JoystickController joystickController = new JoystickController(controllerConfig);
|
||||||
|
|
||||||
|
currentButton |= joystickController.GetButtons();
|
||||||
|
|
||||||
|
(leftJoystickDx, leftJoystickDy) = joystickController.GetLeftStick();
|
||||||
|
(rightJoystickDx, rightJoystickDy) = joystickController.GetRightStick();
|
||||||
|
|
||||||
|
leftJoystick = new JoystickPosition
|
||||||
|
{
|
||||||
|
Dx = controllerConfig.LeftJoycon.InvertStickX ? -leftJoystickDx : leftJoystickDx,
|
||||||
|
Dy = controllerConfig.LeftJoycon.InvertStickY ? -leftJoystickDy : leftJoystickDy
|
||||||
|
};
|
||||||
|
|
||||||
|
rightJoystick = new JoystickPosition
|
||||||
|
{
|
||||||
|
Dx = controllerConfig.RightJoycon.InvertStickX ? -rightJoystickDx : rightJoystickDx,
|
||||||
|
Dy = controllerConfig.RightJoycon.InvertStickY ? -rightJoystickDy : rightJoystickDy
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
currentButton |= _device.Hid.UpdateStickButtons(leftJoystick, rightJoystick);
|
currentButton |= _device.Hid.UpdateStickButtons(leftJoystick, rightJoystick);
|
||||||
|
|
||||||
|
gamepadInputs.Add(new GamepadInput
|
||||||
|
{
|
||||||
|
PlayerId = (HLE.HOS.Services.Hid.PlayerIndex)inputConfig.PlayerIndex,
|
||||||
|
Buttons = currentButton,
|
||||||
|
LStick = leftJoystick,
|
||||||
|
RStick = rightJoystick
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_device.Hid.Npads.SetGamepadsInput(gamepadInputs.ToArray());
|
||||||
|
|
||||||
|
//Touchscreen
|
||||||
bool hasTouch = false;
|
bool hasTouch = false;
|
||||||
|
|
||||||
// Get screen touch position from left mouse click
|
// Get screen touch position from left mouse click
|
||||||
|
@ -510,30 +543,8 @@ namespace Ryujinx.Ui
|
||||||
_device.Hid.Touchscreen.Update();
|
_device.Hid.Touchscreen.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Hid.EnableKeyboard && hidKeyboard.HasValue)
|
|
||||||
{
|
|
||||||
_device.Hid.Keyboard.Update(hidKeyboard.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
_device.Hid.DebugPad.Update();
|
_device.Hid.DebugPad.Update();
|
||||||
|
|
||||||
_device.Hid.Npads.SetGamepadsInput(new GamepadInput
|
|
||||||
{
|
|
||||||
PlayerId = PlayerIndex.Auto,
|
|
||||||
Buttons = currentButton,
|
|
||||||
LStick = leftJoystick,
|
|
||||||
RStick = rightJoystick
|
|
||||||
});
|
|
||||||
|
|
||||||
// Toggle vsync
|
|
||||||
if (currentHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync) &&
|
|
||||||
!_prevHotkeyButtons.HasFlag(HotkeyButtons.ToggleVSync))
|
|
||||||
{
|
|
||||||
_device.EnableDeviceVsync = !_device.EnableDeviceVsync;
|
|
||||||
}
|
|
||||||
|
|
||||||
_prevHotkeyButtons = currentHotkeyButtons;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,33 +3,46 @@ using System.Reflection;
|
||||||
|
|
||||||
namespace Ryujinx.Ui
|
namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
internal class GtkDialog
|
internal class GtkDialog : MessageDialog
|
||||||
{
|
{
|
||||||
internal static bool _isExitDialogOpen = false;
|
internal static bool _isExitDialogOpen = false;
|
||||||
|
|
||||||
internal static void CreateDialog(string title, string text, string secondaryText)
|
private GtkDialog(string title, string mainText, string secondaryText,
|
||||||
|
MessageType messageType = MessageType.Other, ButtonsType buttonsType = ButtonsType.Ok) : base(null, DialogFlags.Modal, messageType, buttonsType, null)
|
||||||
{
|
{
|
||||||
MessageDialog errorDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, null)
|
Title = title;
|
||||||
{
|
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
||||||
Title = title,
|
Text = mainText;
|
||||||
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
|
SecondaryText = secondaryText;
|
||||||
Text = text,
|
WindowPosition = WindowPosition.Center;
|
||||||
SecondaryText = secondaryText,
|
Response += GtkDialog_Response;
|
||||||
WindowPosition = WindowPosition.Center
|
|
||||||
};
|
SetSizeRequest(100, 20);
|
||||||
errorDialog.SetSizeRequest(100, 20);
|
|
||||||
errorDialog.Run();
|
|
||||||
errorDialog.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void CreateWarningDialog(string text, string secondaryText)
|
private void GtkDialog_Response(object sender, ResponseArgs args)
|
||||||
{
|
{
|
||||||
CreateDialog("Ryujinx - Warning", text, secondaryText);
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void CreateInfoDialog(string title, string mainText, string secondaryText)
|
||||||
|
{
|
||||||
|
new GtkDialog(title, mainText, secondaryText, MessageType.Info).Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void CreateWarningDialog(string mainText, string secondaryText)
|
||||||
|
{
|
||||||
|
new GtkDialog("Ryujinx - Warning", mainText, secondaryText, MessageType.Warning).Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void CreateErrorDialog(string errorMessage)
|
internal static void CreateErrorDialog(string errorMessage)
|
||||||
{
|
{
|
||||||
CreateDialog("Ryujinx - Error", "Ryujinx has encountered an error", errorMessage);
|
new GtkDialog("Ryujinx - Error", "Ryujinx has encountered an error", errorMessage, MessageType.Error).Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static MessageDialog CreateConfirmationDialog(string mainText, string secondaryText = "")
|
||||||
|
{
|
||||||
|
return new GtkDialog("Ryujinx - Confirmation", mainText, secondaryText, MessageType.Question, ButtonsType.YesNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool CreateExitDialog()
|
internal static bool CreateExitDialog()
|
||||||
|
@ -40,27 +53,11 @@ namespace Ryujinx.Ui
|
||||||
}
|
}
|
||||||
|
|
||||||
_isExitDialogOpen = true;
|
_isExitDialogOpen = true;
|
||||||
|
ResponseType res = (ResponseType)new GtkDialog("Ryujinx - Exit", "Are you sure you want to stop emulation?",
|
||||||
MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.OkCancel, null)
|
"All unsaved data will be lost", MessageType.Question, ButtonsType.YesNo).Run();
|
||||||
{
|
|
||||||
Title = "Ryujinx - Exit",
|
|
||||||
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
|
|
||||||
Text = "Are you sure you want to stop emulation?",
|
|
||||||
SecondaryText = "All unsaved data will be lost",
|
|
||||||
WindowPosition = WindowPosition.Center
|
|
||||||
};
|
|
||||||
|
|
||||||
messageDialog.SetSizeRequest(100, 20);
|
|
||||||
ResponseType res = (ResponseType)messageDialog.Run();
|
|
||||||
messageDialog.Dispose();
|
|
||||||
_isExitDialogOpen = false;
|
_isExitDialogOpen = false;
|
||||||
|
|
||||||
if (res == ResponseType.Ok)
|
return res == ResponseType.Yes;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
149
Ryujinx/Ui/JoystickController.cs
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
using OpenTK;
|
||||||
|
using OpenTK.Input;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
using Ryujinx.HLE.HOS.Services.Hid;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using ControllerConfig = Ryujinx.Common.Configuration.Hid.ControllerConfig;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ui
|
||||||
|
{
|
||||||
|
public class JoystickController
|
||||||
|
{
|
||||||
|
private readonly ControllerConfig _config;
|
||||||
|
|
||||||
|
// NOTE: This should be initialized AFTER GTK for compat reasons with OpenTK SDL2 backend and GTK on Linux.
|
||||||
|
// BODY: Usage of Joystick.GetState must be defer to after GTK full initialization. Otherwise, GTK will segfault because SDL2 was already init *sighs*
|
||||||
|
public JoystickController(ControllerConfig config)
|
||||||
|
{
|
||||||
|
_config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsEnabled()
|
||||||
|
{
|
||||||
|
return Joystick.GetState(_config.Index).IsConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControllerKeys GetButtons()
|
||||||
|
{
|
||||||
|
if (!IsEnabled())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JoystickState joystickState = Joystick.GetState(_config.Index);
|
||||||
|
|
||||||
|
ControllerKeys buttons = 0;
|
||||||
|
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.DPadUp)) buttons |= ControllerKeys.DpadUp;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.DPadDown)) buttons |= ControllerKeys.DpadDown;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.DPadLeft)) buttons |= ControllerKeys.DpadLeft;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.DPadRight)) buttons |= ControllerKeys.DpadRight;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.StickButton)) buttons |= ControllerKeys.LStick;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.ButtonMinus)) buttons |= ControllerKeys.Minus;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.ButtonL)) buttons |= ControllerKeys.L;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.ButtonZl)) buttons |= ControllerKeys.Zl;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.ButtonSl)) buttons |= ControllerKeys.SlLeft;
|
||||||
|
if (IsActivated(joystickState, _config.LeftJoycon.ButtonSr)) buttons |= ControllerKeys.SrLeft;
|
||||||
|
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonA)) buttons |= ControllerKeys.A;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonB)) buttons |= ControllerKeys.B;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonX)) buttons |= ControllerKeys.X;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonY)) buttons |= ControllerKeys.Y;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.StickButton)) buttons |= ControllerKeys.RStick;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonPlus)) buttons |= ControllerKeys.Plus;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonR)) buttons |= ControllerKeys.R;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonZr)) buttons |= ControllerKeys.Zr;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonSl)) buttons |= ControllerKeys.SlRight;
|
||||||
|
if (IsActivated(joystickState, _config.RightJoycon.ButtonSr)) buttons |= ControllerKeys.SrRight;
|
||||||
|
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsActivated(JoystickState joystickState, ControllerInputId controllerInputId)
|
||||||
|
{
|
||||||
|
if (controllerInputId <= ControllerInputId.Button20)
|
||||||
|
{
|
||||||
|
return joystickState.IsButtonDown((int)controllerInputId);
|
||||||
|
}
|
||||||
|
else if (controllerInputId <= ControllerInputId.Axis5)
|
||||||
|
{
|
||||||
|
int axis = controllerInputId - ControllerInputId.Axis0;
|
||||||
|
|
||||||
|
return joystickState.GetAxis(axis) > _config.TriggerThreshold;
|
||||||
|
}
|
||||||
|
else if (controllerInputId <= ControllerInputId.Hat2Right)
|
||||||
|
{
|
||||||
|
int hat = (controllerInputId - ControllerInputId.Hat0Up) / 4;
|
||||||
|
|
||||||
|
int baseHatId = (int)ControllerInputId.Hat0Up + (hat * 4);
|
||||||
|
|
||||||
|
JoystickHatState hatState = joystickState.GetHat((JoystickHat)hat);
|
||||||
|
|
||||||
|
if (hatState.IsUp && ((int)controllerInputId % baseHatId == 0)) return true;
|
||||||
|
if (hatState.IsDown && ((int)controllerInputId % baseHatId == 1)) return true;
|
||||||
|
if (hatState.IsLeft && ((int)controllerInputId % baseHatId == 2)) return true;
|
||||||
|
if (hatState.IsRight && ((int)controllerInputId % baseHatId == 3)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public (short, short) GetLeftStick()
|
||||||
|
{
|
||||||
|
if (!IsEnabled())
|
||||||
|
{
|
||||||
|
return (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetStick(_config.LeftJoycon.StickX, _config.LeftJoycon.StickY, _config.DeadzoneLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
public (short, short) GetRightStick()
|
||||||
|
{
|
||||||
|
if (!IsEnabled())
|
||||||
|
{
|
||||||
|
return (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetStick(_config.RightJoycon.StickX, _config.RightJoycon.StickY, _config.DeadzoneRight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private (short, short) GetStick(ControllerInputId stickXInputId, ControllerInputId stickYInputId, float deadzone)
|
||||||
|
{
|
||||||
|
if (stickXInputId < ControllerInputId.Axis0 || stickXInputId > ControllerInputId.Axis5 ||
|
||||||
|
stickYInputId < ControllerInputId.Axis0 || stickYInputId > ControllerInputId.Axis5)
|
||||||
|
{
|
||||||
|
return (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
JoystickState jsState = Joystick.GetState(_config.Index);
|
||||||
|
|
||||||
|
int xAxis = stickXInputId - ControllerInputId.Axis0;
|
||||||
|
int yAxis = stickYInputId - ControllerInputId.Axis0;
|
||||||
|
|
||||||
|
float xValue = jsState.GetAxis(xAxis);
|
||||||
|
float yValue = -jsState.GetAxis(yAxis); // Invert Y-axis
|
||||||
|
|
||||||
|
return ApplyDeadzone(new Vector2(xValue, yValue), deadzone);
|
||||||
|
}
|
||||||
|
|
||||||
|
private (short, short) ApplyDeadzone(Vector2 axis, float deadzone)
|
||||||
|
{
|
||||||
|
return (ClampAxis(MathF.Abs(axis.X) > deadzone ? axis.X : 0f),
|
||||||
|
ClampAxis(MathF.Abs(axis.Y) > deadzone ? axis.Y : 0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static short ClampAxis(float value)
|
||||||
|
{
|
||||||
|
if (value <= -short.MaxValue)
|
||||||
|
{
|
||||||
|
return -short.MaxValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (short)(value * short.MaxValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.HLE.HOS.Services.Hid;
|
using Ryujinx.HLE.HOS.Services.Hid;
|
||||||
using Ryujinx.UI.Input;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ui
|
namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
|
@ -11,64 +11,85 @@ namespace Ryujinx.Ui
|
||||||
ToggleVSync = 1 << 0,
|
ToggleVSync = 1 << 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class KeyboardControls
|
public class KeyboardController
|
||||||
{
|
{
|
||||||
public static ControllerKeys GetButtons(NpadKeyboard npad, KeyboardState keyboard)
|
private readonly KeyboardConfig _config;
|
||||||
|
|
||||||
|
// NOTE: This should be initialized AFTER GTK for compat reasons with OpenTK SDL2 backend and GTK on Linux.
|
||||||
|
// BODY: Usage of Joystick.GetState must be defer to after GTK full initialization. Otherwise, GTK will segfault because SDL2 was already init *sighs*
|
||||||
|
public KeyboardController(KeyboardConfig config)
|
||||||
{
|
{
|
||||||
|
_config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControllerKeys GetButtons()
|
||||||
|
{
|
||||||
|
KeyboardState keyboard = Keyboard.GetState(_config.Index);
|
||||||
|
|
||||||
ControllerKeys buttons = 0;
|
ControllerKeys buttons = 0;
|
||||||
|
|
||||||
if (keyboard[(Key)npad.LeftJoycon.StickButton]) buttons |= ControllerKeys.LStick;
|
if (keyboard[(Key)_config.LeftJoycon.StickButton]) buttons |= ControllerKeys.LStick;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.DPadUp]) buttons |= ControllerKeys.DpadUp;
|
if (keyboard[(Key)_config.LeftJoycon.DPadUp]) buttons |= ControllerKeys.DpadUp;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.DPadDown]) buttons |= ControllerKeys.DpadDown;
|
if (keyboard[(Key)_config.LeftJoycon.DPadDown]) buttons |= ControllerKeys.DpadDown;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.DPadLeft]) buttons |= ControllerKeys.DpadLeft;
|
if (keyboard[(Key)_config.LeftJoycon.DPadLeft]) buttons |= ControllerKeys.DpadLeft;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.DPadRight]) buttons |= ControllerKeys.DpadRight;
|
if (keyboard[(Key)_config.LeftJoycon.DPadRight]) buttons |= ControllerKeys.DpadRight;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.ButtonMinus]) buttons |= ControllerKeys.Minus;
|
if (keyboard[(Key)_config.LeftJoycon.ButtonMinus]) buttons |= ControllerKeys.Minus;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.ButtonL]) buttons |= ControllerKeys.L | ControllerKeys.Sl;
|
if (keyboard[(Key)_config.LeftJoycon.ButtonL]) buttons |= ControllerKeys.L;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.ButtonZl]) buttons |= ControllerKeys.Zl;
|
if (keyboard[(Key)_config.LeftJoycon.ButtonZl]) buttons |= ControllerKeys.Zl;
|
||||||
|
if (keyboard[(Key)_config.LeftJoycon.ButtonSl]) buttons |= ControllerKeys.SlLeft;
|
||||||
|
if (keyboard[(Key)_config.LeftJoycon.ButtonSr]) buttons |= ControllerKeys.SlRight;
|
||||||
|
|
||||||
if (keyboard[(Key)npad.RightJoycon.StickButton]) buttons |= ControllerKeys.RStick;
|
if (keyboard[(Key)_config.RightJoycon.StickButton]) buttons |= ControllerKeys.RStick;
|
||||||
if (keyboard[(Key)npad.RightJoycon.ButtonA]) buttons |= ControllerKeys.A;
|
if (keyboard[(Key)_config.RightJoycon.ButtonA]) buttons |= ControllerKeys.A;
|
||||||
if (keyboard[(Key)npad.RightJoycon.ButtonB]) buttons |= ControllerKeys.B;
|
if (keyboard[(Key)_config.RightJoycon.ButtonB]) buttons |= ControllerKeys.B;
|
||||||
if (keyboard[(Key)npad.RightJoycon.ButtonX]) buttons |= ControllerKeys.X;
|
if (keyboard[(Key)_config.RightJoycon.ButtonX]) buttons |= ControllerKeys.X;
|
||||||
if (keyboard[(Key)npad.RightJoycon.ButtonY]) buttons |= ControllerKeys.Y;
|
if (keyboard[(Key)_config.RightJoycon.ButtonY]) buttons |= ControllerKeys.Y;
|
||||||
if (keyboard[(Key)npad.RightJoycon.ButtonPlus]) buttons |= ControllerKeys.Plus;
|
if (keyboard[(Key)_config.RightJoycon.ButtonPlus]) buttons |= ControllerKeys.Plus;
|
||||||
if (keyboard[(Key)npad.RightJoycon.ButtonR]) buttons |= ControllerKeys.R | ControllerKeys.Sr;
|
if (keyboard[(Key)_config.RightJoycon.ButtonR]) buttons |= ControllerKeys.R;
|
||||||
if (keyboard[(Key)npad.RightJoycon.ButtonZr]) buttons |= ControllerKeys.Zr;
|
if (keyboard[(Key)_config.RightJoycon.ButtonZr]) buttons |= ControllerKeys.Zr;
|
||||||
|
if (keyboard[(Key)_config.RightJoycon.ButtonSl]) buttons |= ControllerKeys.SrLeft;
|
||||||
|
if (keyboard[(Key)_config.RightJoycon.ButtonSr]) buttons |= ControllerKeys.SrRight;
|
||||||
|
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (short, short) GetLeftStick(NpadKeyboard npad, KeyboardState keyboard)
|
public (short, short) GetLeftStick()
|
||||||
{
|
{
|
||||||
|
KeyboardState keyboard = Keyboard.GetState(_config.Index);
|
||||||
|
|
||||||
short dx = 0;
|
short dx = 0;
|
||||||
short dy = 0;
|
short dy = 0;
|
||||||
|
|
||||||
if (keyboard[(Key)npad.LeftJoycon.StickUp]) dy = short.MaxValue;
|
if (keyboard[(Key)_config.LeftJoycon.StickUp]) dy = short.MaxValue;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.StickDown]) dy = -short.MaxValue;
|
if (keyboard[(Key)_config.LeftJoycon.StickDown]) dy = -short.MaxValue;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.StickLeft]) dx = -short.MaxValue;
|
if (keyboard[(Key)_config.LeftJoycon.StickLeft]) dx = -short.MaxValue;
|
||||||
if (keyboard[(Key)npad.LeftJoycon.StickRight]) dx = short.MaxValue;
|
if (keyboard[(Key)_config.LeftJoycon.StickRight]) dx = short.MaxValue;
|
||||||
|
|
||||||
return (dx, dy);
|
return (dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (short, short) GetRightStick(NpadKeyboard npad, KeyboardState keyboard)
|
public (short, short) GetRightStick()
|
||||||
{
|
{
|
||||||
|
KeyboardState keyboard = Keyboard.GetState(_config.Index);
|
||||||
|
|
||||||
short dx = 0;
|
short dx = 0;
|
||||||
short dy = 0;
|
short dy = 0;
|
||||||
|
|
||||||
if (keyboard[(Key)npad.RightJoycon.StickUp]) dy = short.MaxValue;
|
if (keyboard[(Key)_config.RightJoycon.StickUp]) dy = short.MaxValue;
|
||||||
if (keyboard[(Key)npad.RightJoycon.StickDown]) dy = -short.MaxValue;
|
if (keyboard[(Key)_config.RightJoycon.StickDown]) dy = -short.MaxValue;
|
||||||
if (keyboard[(Key)npad.RightJoycon.StickLeft]) dx = -short.MaxValue;
|
if (keyboard[(Key)_config.RightJoycon.StickLeft]) dx = -short.MaxValue;
|
||||||
if (keyboard[(Key)npad.RightJoycon.StickRight]) dx = short.MaxValue;
|
if (keyboard[(Key)_config.RightJoycon.StickRight]) dx = short.MaxValue;
|
||||||
|
|
||||||
return (dx, dy);
|
return (dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HotkeyButtons GetHotkeyButtons(NpadKeyboard npad, KeyboardState keyboard)
|
public HotkeyButtons GetHotkeyButtons()
|
||||||
{
|
{
|
||||||
|
KeyboardState keyboard = Keyboard.GetState(_config.Index);
|
||||||
|
|
||||||
HotkeyButtons buttons = 0;
|
HotkeyButtons buttons = 0;
|
||||||
|
|
||||||
if (keyboard[(Key)npad.Hotkeys.ToggleVsync]) buttons |= HotkeyButtons.ToggleVSync;
|
if (keyboard[(Key)_config.Hotkeys.ToggleVsync]) buttons |= HotkeyButtons.ToggleVSync;
|
||||||
|
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
@ -223,8 +244,10 @@ namespace Ryujinx.Ui
|
||||||
new KeyMappingEntry { TargetKey = Key.NumLock, Target = 10 },
|
new KeyMappingEntry { TargetKey = Key.NumLock, Target = 10 },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static KeyboardInput GetKeysDown(NpadKeyboard npad, KeyboardState keyboard)
|
public KeyboardInput GetKeysDown()
|
||||||
{
|
{
|
||||||
|
KeyboardState keyboard = Keyboard.GetState(_config.Index);
|
||||||
|
|
||||||
KeyboardInput hidKeyboard = new KeyboardInput
|
KeyboardInput hidKeyboard = new KeyboardInput
|
||||||
{
|
{
|
||||||
Modifier = 0,
|
Modifier = 0,
|
|
@ -13,6 +13,7 @@ using Ryujinx.HLE.HOS.Services.Hid;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -28,7 +29,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
private static HLE.Switch _emulationContext;
|
private static HLE.Switch _emulationContext;
|
||||||
|
|
||||||
private static GLRenderer _gLWidget;
|
private static GlRenderer _glWidget;
|
||||||
|
|
||||||
private static AutoResetEvent _deviceExitStatus = new AutoResetEvent(false);
|
private static AutoResetEvent _deviceExitStatus = new AutoResetEvent(false);
|
||||||
|
|
||||||
|
@ -37,40 +38,38 @@ namespace Ryujinx.Ui
|
||||||
private static bool _updatingGameTable;
|
private static bool _updatingGameTable;
|
||||||
private static bool _gameLoaded;
|
private static bool _gameLoaded;
|
||||||
private static bool _ending;
|
private static bool _ending;
|
||||||
#pragma warning disable CS0169
|
|
||||||
private static bool _debuggerOpened;
|
|
||||||
#pragma warning restore CS0169
|
|
||||||
|
|
||||||
#pragma warning disable CS0169
|
#pragma warning disable CS0169
|
||||||
private static Ryujinx.Debugger.Debugger _debugger;
|
private static bool _debuggerOpened;
|
||||||
|
|
||||||
|
private static Debugger.Debugger _debugger;
|
||||||
#pragma warning restore CS0169
|
#pragma warning restore CS0169
|
||||||
|
|
||||||
#pragma warning disable CS0169, CS0649, IDE0044
|
#pragma warning disable CS0169, CS0649, IDE0044
|
||||||
|
|
||||||
[GUI] Window _mainWin;
|
|
||||||
[GUI] MenuBar _menuBar;
|
[GUI] MenuBar _menuBar;
|
||||||
[GUI] Box _footerBox;
|
[GUI] Box _footerBox;
|
||||||
[GUI] MenuItem _fullScreen;
|
|
||||||
[GUI] Box _statusBar;
|
[GUI] Box _statusBar;
|
||||||
[GUI] MenuItem _stopEmulation;
|
[GUI] MenuItem _stopEmulation;
|
||||||
|
[GUI] MenuItem _fullScreen;
|
||||||
[GUI] CheckMenuItem _favToggle;
|
[GUI] CheckMenuItem _favToggle;
|
||||||
[GUI] MenuItem _firmwareInstallFile;
|
|
||||||
[GUI] MenuItem _firmwareInstallDirectory;
|
[GUI] MenuItem _firmwareInstallDirectory;
|
||||||
|
[GUI] MenuItem _firmwareInstallFile;
|
||||||
[GUI] Label _hostStatus;
|
[GUI] Label _hostStatus;
|
||||||
[GUI] MenuItem _openDebugger;
|
[GUI] MenuItem _openDebugger;
|
||||||
[GUI] CheckMenuItem _iconToggle;
|
[GUI] CheckMenuItem _iconToggle;
|
||||||
[GUI] CheckMenuItem _appToggle;
|
|
||||||
[GUI] CheckMenuItem _developerToggle;
|
[GUI] CheckMenuItem _developerToggle;
|
||||||
[GUI] CheckMenuItem _versionToggle;
|
[GUI] CheckMenuItem _appToggle;
|
||||||
[GUI] CheckMenuItem _timePlayedToggle;
|
[GUI] CheckMenuItem _timePlayedToggle;
|
||||||
|
[GUI] CheckMenuItem _versionToggle;
|
||||||
[GUI] CheckMenuItem _lastPlayedToggle;
|
[GUI] CheckMenuItem _lastPlayedToggle;
|
||||||
[GUI] CheckMenuItem _fileExtToggle;
|
[GUI] CheckMenuItem _fileExtToggle;
|
||||||
[GUI] CheckMenuItem _fileSizeToggle;
|
|
||||||
[GUI] CheckMenuItem _pathToggle;
|
[GUI] CheckMenuItem _pathToggle;
|
||||||
|
[GUI] CheckMenuItem _fileSizeToggle;
|
||||||
[GUI] Label _gameStatus;
|
[GUI] Label _gameStatus;
|
||||||
[GUI] TreeView _gameTable;
|
[GUI] TreeView _gameTable;
|
||||||
[GUI] ScrolledWindow _gameTableWindow;
|
|
||||||
[GUI] TreeSelection _gameTableSelection;
|
[GUI] TreeSelection _gameTableSelection;
|
||||||
|
[GUI] ScrolledWindow _gameTableWindow;
|
||||||
[GUI] Label _gpuName;
|
[GUI] Label _gpuName;
|
||||||
[GUI] Label _progressLabel;
|
[GUI] Label _progressLabel;
|
||||||
[GUI] Label _firmwareVersionLabel;
|
[GUI] Label _firmwareVersionLabel;
|
||||||
|
@ -96,9 +95,12 @@ namespace Ryujinx.Ui
|
||||||
this.DeleteEvent += Window_Close;
|
this.DeleteEvent += Window_Close;
|
||||||
_fullScreen.Activated += FullScreen_Toggled;
|
_fullScreen.Activated += FullScreen_Toggled;
|
||||||
|
|
||||||
|
this.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
||||||
|
this.Title = $"Ryujinx {Program.Version}";
|
||||||
|
|
||||||
ApplicationLibrary.ApplicationAdded += Application_Added;
|
ApplicationLibrary.ApplicationAdded += Application_Added;
|
||||||
ApplicationLibrary.ApplicationCountUpdated += ApplicationCount_Updated;
|
ApplicationLibrary.ApplicationCountUpdated += ApplicationCount_Updated;
|
||||||
GLRenderer.StatusUpdatedEvent += Update_StatusBar;
|
GlRenderer.StatusUpdatedEvent += Update_StatusBar;
|
||||||
|
|
||||||
_gameTable.ButtonReleaseEvent += Row_Clicked;
|
_gameTable.ButtonReleaseEvent += Row_Clicked;
|
||||||
|
|
||||||
|
@ -127,8 +129,6 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
ApplyTheme();
|
ApplyTheme();
|
||||||
|
|
||||||
_mainWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
|
||||||
_mainWin.Title = $"Ryujinx {Program.Version}";
|
|
||||||
_stopEmulation.Sensitive = false;
|
_stopEmulation.Sensitive = false;
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true;
|
if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true;
|
||||||
|
@ -302,7 +302,7 @@ namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
if (_gameLoaded)
|
if (_gameLoaded)
|
||||||
{
|
{
|
||||||
GtkDialog.CreateDialog("Ryujinx", "A game has already been loaded", "Please close it first and try again.");
|
GtkDialog.CreateInfoDialog("Ryujinx", "A game has already been loaded", "Please close it first and try again.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -415,7 +415,7 @@ namespace Ryujinx.Ui
|
||||||
#if MACOS_BUILD
|
#if MACOS_BUILD
|
||||||
CreateGameWindow(device);
|
CreateGameWindow(device);
|
||||||
#else
|
#else
|
||||||
var windowThread = new Thread(() =>
|
Thread windowThread = new Thread(() =>
|
||||||
{
|
{
|
||||||
CreateGameWindow(device);
|
CreateGameWindow(device);
|
||||||
})
|
})
|
||||||
|
@ -443,35 +443,29 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
private void CreateGameWindow(HLE.Switch device)
|
private void CreateGameWindow(HLE.Switch device)
|
||||||
{
|
{
|
||||||
ControllerType type = (Ryujinx.Configuration.Hid.ControllerType)ConfigurationState.Instance.Hid.ControllerType switch {
|
device.Hid.Npads.AddControllers(ConfigurationState.Instance.Hid.InputConfig.Value.Select(inputConfig =>
|
||||||
Ryujinx.Configuration.Hid.ControllerType.ProController => ControllerType.ProController,
|
new HLE.HOS.Services.Hid.ControllerConfig
|
||||||
Ryujinx.Configuration.Hid.ControllerType.Handheld => ControllerType.Handheld,
|
{
|
||||||
Ryujinx.Configuration.Hid.ControllerType.NpadPair => ControllerType.JoyconPair,
|
Player = (PlayerIndex)inputConfig.PlayerIndex,
|
||||||
Ryujinx.Configuration.Hid.ControllerType.NpadLeft => ControllerType.JoyconLeft,
|
Type = (ControllerType)inputConfig.ControllerType
|
||||||
Ryujinx.Configuration.Hid.ControllerType.NpadRight => ControllerType.JoyconRight,
|
}
|
||||||
_ => ControllerType.Handheld
|
).ToArray());
|
||||||
};
|
|
||||||
|
|
||||||
device.Hid.Npads.AddControllers(new ControllerConfig {
|
_glWidget = new GlRenderer(_emulationContext);
|
||||||
Player = PlayerIndex.Player1,
|
|
||||||
Type = type
|
|
||||||
});
|
|
||||||
|
|
||||||
_gLWidget = new GLRenderer(_emulationContext);
|
|
||||||
|
|
||||||
Application.Invoke(delegate
|
Application.Invoke(delegate
|
||||||
{
|
{
|
||||||
_viewBox.Remove(_gameTableWindow);
|
_viewBox.Remove(_gameTableWindow);
|
||||||
_gLWidget.Expand = true;
|
_glWidget.Expand = true;
|
||||||
_viewBox.Child = _gLWidget;
|
_viewBox.Child = _glWidget;
|
||||||
|
|
||||||
_gLWidget.ShowAll();
|
_glWidget.ShowAll();
|
||||||
EditFooterForGameRender();
|
EditFooterForGameRender();
|
||||||
});
|
});
|
||||||
|
|
||||||
_gLWidget.WaitEvent.WaitOne();
|
_glWidget.WaitEvent.WaitOne();
|
||||||
|
|
||||||
_gLWidget.Start();
|
_glWidget.Start();
|
||||||
|
|
||||||
device.Dispose();
|
device.Dispose();
|
||||||
_deviceExitStatus.Set();
|
_deviceExitStatus.Set();
|
||||||
|
@ -479,15 +473,15 @@ namespace Ryujinx.Ui
|
||||||
// NOTE: Everything that is here will not be executed when you close the UI.
|
// NOTE: Everything that is here will not be executed when you close the UI.
|
||||||
Application.Invoke(delegate
|
Application.Invoke(delegate
|
||||||
{
|
{
|
||||||
_viewBox.Remove(_gLWidget);
|
_viewBox.Remove(_glWidget);
|
||||||
_gLWidget.Exit();
|
_glWidget.Exit();
|
||||||
|
|
||||||
if(_gLWidget.Window != this.Window && _gLWidget.Window != null)
|
if(_glWidget.Window != this.Window && _glWidget.Window != null)
|
||||||
{
|
{
|
||||||
_gLWidget.Window.Dispose();
|
_glWidget.Window.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
_gLWidget.Dispose();
|
_glWidget.Dispose();
|
||||||
|
|
||||||
_viewBox.Add(_gameTableWindow);
|
_viewBox.Add(_gameTableWindow);
|
||||||
|
|
||||||
|
@ -497,7 +491,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
_emulationContext = null;
|
_emulationContext = null;
|
||||||
_gameLoaded = false;
|
_gameLoaded = false;
|
||||||
_gLWidget = null;
|
_glWidget = null;
|
||||||
|
|
||||||
DiscordIntegrationModule.SwitchToMainMenu();
|
DiscordIntegrationModule.SwitchToMainMenu();
|
||||||
|
|
||||||
|
@ -528,7 +522,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
public void ToggleExtraWidgets(bool show)
|
public void ToggleExtraWidgets(bool show)
|
||||||
{
|
{
|
||||||
if (_gLWidget != null)
|
if (_glWidget != null)
|
||||||
{
|
{
|
||||||
if (show)
|
if (show)
|
||||||
{
|
{
|
||||||
|
@ -562,6 +556,11 @@ namespace Ryujinx.Ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SaveConfig()
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.ToFileFormat().SaveConfig(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
|
||||||
|
}
|
||||||
|
|
||||||
private void End(HLE.Switch device)
|
private void End(HLE.Switch device)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -580,10 +579,10 @@ namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
UpdateGameMetadata(device.System.TitleIdText);
|
UpdateGameMetadata(device.System.TitleIdText);
|
||||||
|
|
||||||
if (_gLWidget != null)
|
if (_glWidget != null)
|
||||||
{
|
{
|
||||||
// We tell the widget that we are exiting
|
// We tell the widget that we are exiting
|
||||||
_gLWidget.Exit();
|
_glWidget.Exit();
|
||||||
|
|
||||||
// Wait for the other thread to dispose the HLE context before exiting.
|
// Wait for the other thread to dispose the HLE context before exiting.
|
||||||
_deviceExitStatus.WaitOne();
|
_deviceExitStatus.WaitOne();
|
||||||
|
@ -773,7 +772,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
private void StopEmulation_Pressed(object sender, EventArgs args)
|
private void StopEmulation_Pressed(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
_gLWidget?.Exit();
|
_glWidget?.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Installer_File_Pressed(object o, EventArgs args)
|
private void Installer_File_Pressed(object o, EventArgs args)
|
||||||
|
@ -808,7 +807,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
private void RefreshFirmwareLabel()
|
private void RefreshFirmwareLabel()
|
||||||
{
|
{
|
||||||
var currentFirmware = _contentManager.GetCurrentFirmwareVersion();
|
SystemVersion currentFirmware = _contentManager.GetCurrentFirmwareVersion();
|
||||||
|
|
||||||
GLib.Idle.Add(new GLib.IdleHandler(() =>
|
GLib.Idle.Add(new GLib.IdleHandler(() =>
|
||||||
{
|
{
|
||||||
|
@ -830,7 +829,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
fileChooser.Dispose();
|
fileChooser.Dispose();
|
||||||
|
|
||||||
var firmwareVersion = _contentManager.VerifyFirmwarePackage(filename);
|
SystemVersion firmwareVersion = _contentManager.VerifyFirmwarePackage(filename);
|
||||||
|
|
||||||
if (firmwareVersion == null)
|
if (firmwareVersion == null)
|
||||||
{
|
{
|
||||||
|
@ -849,7 +848,7 @@ namespace Ryujinx.Ui
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentVersion = _contentManager.GetCurrentFirmwareVersion();
|
SystemVersion currentVersion = _contentManager.GetCurrentFirmwareVersion();
|
||||||
|
|
||||||
string dialogMessage = $"System version {firmwareVersion.VersionString} will be installed.";
|
string dialogMessage = $"System version {firmwareVersion.VersionString} will be installed.";
|
||||||
|
|
||||||
|
@ -989,7 +988,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
private void Settings_Pressed(object sender, EventArgs args)
|
private void Settings_Pressed(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
SwitchSettings settingsWin = new SwitchSettings(_virtualFileSystem, _contentManager);
|
SettingsWindow settingsWin = new SettingsWindow(_virtualFileSystem, _contentManager);
|
||||||
settingsWin.Show();
|
settingsWin.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,10 +1204,5 @@ namespace Ryujinx.Ui
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveConfig()
|
|
||||||
{
|
|
||||||
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
using OpenTK;
|
|
||||||
using OpenTK.Input;
|
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
|
||||||
using Ryujinx.HLE.HOS.Services.Hid;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
using InnerNpadController = Ryujinx.Common.Configuration.Hid.NpadController;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ui.Input
|
|
||||||
{
|
|
||||||
public class NpadController
|
|
||||||
{
|
|
||||||
private InnerNpadController _inner;
|
|
||||||
|
|
||||||
// NOTE: This should be initialized AFTER GTK for compat reasons with OpenTK SDL2 backend and GTK on Linux.
|
|
||||||
// BODY: Usage of Joystick.GetState must be defer to after GTK full initialization. Otherwise, GTK will segfault because SDL2 was already init *sighs*
|
|
||||||
public NpadController(InnerNpadController inner)
|
|
||||||
{
|
|
||||||
_inner = inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsEnabled()
|
|
||||||
{
|
|
||||||
return _inner.Enabled && Joystick.GetState(_inner.Index).IsConnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ControllerKeys GetButtons()
|
|
||||||
{
|
|
||||||
if (!IsEnabled())
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
JoystickState joystickState = Joystick.GetState(_inner.Index);
|
|
||||||
|
|
||||||
ControllerKeys buttons = 0;
|
|
||||||
|
|
||||||
if (IsActivated(joystickState, _inner.LeftJoycon.DPadUp)) buttons |= ControllerKeys.DpadUp;
|
|
||||||
if (IsActivated(joystickState, _inner.LeftJoycon.DPadDown)) buttons |= ControllerKeys.DpadDown;
|
|
||||||
if (IsActivated(joystickState, _inner.LeftJoycon.DPadLeft)) buttons |= ControllerKeys.DpadLeft;
|
|
||||||
if (IsActivated(joystickState, _inner.LeftJoycon.DPadRight)) buttons |= ControllerKeys.DpadRight;
|
|
||||||
if (IsActivated(joystickState, _inner.LeftJoycon.StickButton)) buttons |= ControllerKeys.LStick;
|
|
||||||
if (IsActivated(joystickState, _inner.LeftJoycon.ButtonMinus)) buttons |= ControllerKeys.Minus;
|
|
||||||
if (IsActivated(joystickState, _inner.LeftJoycon.ButtonL)) buttons |= ControllerKeys.L | ControllerKeys.Sl;
|
|
||||||
if (IsActivated(joystickState, _inner.LeftJoycon.ButtonZl)) buttons |= ControllerKeys.Zl;
|
|
||||||
|
|
||||||
if (IsActivated(joystickState, _inner.RightJoycon.ButtonA)) buttons |= ControllerKeys.A;
|
|
||||||
if (IsActivated(joystickState, _inner.RightJoycon.ButtonB)) buttons |= ControllerKeys.B;
|
|
||||||
if (IsActivated(joystickState, _inner.RightJoycon.ButtonX)) buttons |= ControllerKeys.X;
|
|
||||||
if (IsActivated(joystickState, _inner.RightJoycon.ButtonY)) buttons |= ControllerKeys.Y;
|
|
||||||
if (IsActivated(joystickState, _inner.RightJoycon.StickButton)) buttons |= ControllerKeys.RStick;
|
|
||||||
if (IsActivated(joystickState, _inner.RightJoycon.ButtonPlus)) buttons |= ControllerKeys.Plus;
|
|
||||||
if (IsActivated(joystickState, _inner.RightJoycon.ButtonR)) buttons |= ControllerKeys.R | ControllerKeys.Sr;
|
|
||||||
if (IsActivated(joystickState, _inner.RightJoycon.ButtonZr)) buttons |= ControllerKeys.Zr;
|
|
||||||
|
|
||||||
return buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsActivated(JoystickState joystickState, ControllerInputId controllerInputId)
|
|
||||||
{
|
|
||||||
if (controllerInputId <= ControllerInputId.Button20)
|
|
||||||
{
|
|
||||||
return joystickState.IsButtonDown((int)controllerInputId);
|
|
||||||
}
|
|
||||||
else if (controllerInputId <= ControllerInputId.Axis5)
|
|
||||||
{
|
|
||||||
int axis = controllerInputId - ControllerInputId.Axis0;
|
|
||||||
|
|
||||||
return joystickState.GetAxis(axis) > _inner.TriggerThreshold;
|
|
||||||
}
|
|
||||||
else if (controllerInputId <= ControllerInputId.Hat2Right)
|
|
||||||
{
|
|
||||||
int hat = (controllerInputId - ControllerInputId.Hat0Up) / 4;
|
|
||||||
|
|
||||||
int baseHatId = (int)ControllerInputId.Hat0Up + (hat * 4);
|
|
||||||
|
|
||||||
JoystickHatState hatState = joystickState.GetHat((JoystickHat)hat);
|
|
||||||
|
|
||||||
if (hatState.IsUp && ((int)controllerInputId % baseHatId == 0)) return true;
|
|
||||||
if (hatState.IsDown && ((int)controllerInputId % baseHatId == 1)) return true;
|
|
||||||
if (hatState.IsLeft && ((int)controllerInputId % baseHatId == 2)) return true;
|
|
||||||
if (hatState.IsRight && ((int)controllerInputId % baseHatId == 3)) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public (short, short) GetLeftStick()
|
|
||||||
{
|
|
||||||
if (!IsEnabled())
|
|
||||||
{
|
|
||||||
return (0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetStick(_inner.LeftJoycon.Stick);
|
|
||||||
}
|
|
||||||
|
|
||||||
public (short, short) GetRightStick()
|
|
||||||
{
|
|
||||||
if (!IsEnabled())
|
|
||||||
{
|
|
||||||
return (0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetStick(_inner.RightJoycon.Stick);
|
|
||||||
}
|
|
||||||
|
|
||||||
private (short, short) GetStick(ControllerInputId stickInputId)
|
|
||||||
{
|
|
||||||
if (stickInputId < ControllerInputId.Axis0 || stickInputId > ControllerInputId.Axis5)
|
|
||||||
{
|
|
||||||
return (0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
JoystickState jsState = Joystick.GetState(_inner.Index);
|
|
||||||
|
|
||||||
int xAxis = stickInputId - ControllerInputId.Axis0;
|
|
||||||
|
|
||||||
float xValue = jsState.GetAxis(xAxis);
|
|
||||||
float yValue = 0 - jsState.GetAxis(xAxis + 1); // Invert Y-axis
|
|
||||||
|
|
||||||
return ApplyDeadzone(new Vector2(xValue, yValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
private (short, short) ApplyDeadzone(Vector2 axis)
|
|
||||||
{
|
|
||||||
return (ClampAxis(MathF.Abs(axis.X) > _inner.Deadzone ? axis.X : 0f),
|
|
||||||
ClampAxis(MathF.Abs(axis.Y) > _inner.Deadzone ? axis.Y : 0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static short ClampAxis(float value)
|
|
||||||
{
|
|
||||||
if (value <= -short.MaxValue)
|
|
||||||
{
|
|
||||||
return -short.MaxValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (short)(value * short.MaxValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
58
Ryujinx/Ui/ProfileDialog.cs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
using Gtk;
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using GUI = Gtk.Builder.ObjectAttribute;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ui
|
||||||
|
{
|
||||||
|
public class ProfileDialog : Dialog
|
||||||
|
{
|
||||||
|
public string FileName { get; private set; }
|
||||||
|
|
||||||
|
#pragma warning disable CS0649, IDE0044
|
||||||
|
[GUI] Entry _profileEntry;
|
||||||
|
[GUI] Label _errorMessage;
|
||||||
|
#pragma warning restore CS0649, IDE0044
|
||||||
|
|
||||||
|
public ProfileDialog() : this(new Builder("Ryujinx.Ui.ProfileDialog.glade")) { }
|
||||||
|
|
||||||
|
private ProfileDialog(Builder builder) : base(builder.GetObject("_profileDialog").Handle)
|
||||||
|
{
|
||||||
|
builder.Autoconnect(this);
|
||||||
|
|
||||||
|
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OkToggle_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
((ToggleButton)sender).SetStateFlags(0, true);
|
||||||
|
|
||||||
|
bool validFileName = true;
|
||||||
|
|
||||||
|
foreach (char invalidChar in System.IO.Path.GetInvalidFileNameChars())
|
||||||
|
{
|
||||||
|
if (_profileEntry.Text.Contains(invalidChar))
|
||||||
|
{
|
||||||
|
validFileName = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validFileName && !string.IsNullOrEmpty(_profileEntry.Text))
|
||||||
|
{
|
||||||
|
FileName = $"{_profileEntry.Text}.json";
|
||||||
|
|
||||||
|
Respond(ResponseType.Ok);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_errorMessage.Text = "The file name contains invalid characters. Please try again.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelToggle_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
Respond(ResponseType.Cancel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
124
Ryujinx/Ui/ProfileDialog.glade
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generated with glade 3.22.1 -->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.20"/>
|
||||||
|
<object class="GtkDialog" id="_profileDialog">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="title" translatable="yes">Ryujinx - Profile Dialog</property>
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<property name="window_position">center</property>
|
||||||
|
<property name="default_width">400</property>
|
||||||
|
<property name="type_hint">dialog</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">2</property>
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<object class="GtkButtonBox">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToggleButton" id="OkToggle">
|
||||||
|
<property name="label" translatable="yes">OK</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<signal name="toggled" handler="OkToggle_Activated" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToggleButton" id="CancelToggle">
|
||||||
|
<property name="label" translatable="yes">Cancel</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<signal name="toggled" handler="CancelToggle_Activated" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="padding">5</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_left">10</property>
|
||||||
|
<property name="margin_right">10</property>
|
||||||
|
<property name="margin_top">20</property>
|
||||||
|
<property name="margin_bottom">10</property>
|
||||||
|
<property name="label" translatable="yes">Enter a name for the new profile:</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="_profileEntry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="margin_left">20</property>
|
||||||
|
<property name="margin_right">20</property>
|
||||||
|
<property name="margin_top">20</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="_errorMessage">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="margin_left">20</property>
|
||||||
|
<property name="margin_right">10</property>
|
||||||
|
<property name="margin_top">10</property>
|
||||||
|
<property name="margin_bottom">10</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="foreground" value="#ffff00000000"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
409
Ryujinx/Ui/SettingsWindow.cs
Normal file
|
@ -0,0 +1,409 @@
|
||||||
|
using Gtk;
|
||||||
|
using Ryujinx.Configuration;
|
||||||
|
using Ryujinx.Configuration.System;
|
||||||
|
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
||||||
|
using Ryujinx.HLE.FileSystem;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
using GUI = Gtk.Builder.ObjectAttribute;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ui
|
||||||
|
{
|
||||||
|
public class SettingsWindow : Window
|
||||||
|
{
|
||||||
|
private static ListStore _gameDirsBoxStore;
|
||||||
|
private static VirtualFileSystem _virtualFileSystem;
|
||||||
|
|
||||||
|
private long _systemTimeOffset;
|
||||||
|
|
||||||
|
#pragma warning disable CS0649, IDE0044
|
||||||
|
[GUI] CheckButton _errorLogToggle;
|
||||||
|
[GUI] CheckButton _warningLogToggle;
|
||||||
|
[GUI] CheckButton _infoLogToggle;
|
||||||
|
[GUI] CheckButton _stubLogToggle;
|
||||||
|
[GUI] CheckButton _debugLogToggle;
|
||||||
|
[GUI] CheckButton _fileLogToggle;
|
||||||
|
[GUI] CheckButton _guestLogToggle;
|
||||||
|
[GUI] CheckButton _fsAccessLogToggle;
|
||||||
|
[GUI] Adjustment _fsLogSpinAdjustment;
|
||||||
|
[GUI] CheckButton _dockedModeToggle;
|
||||||
|
[GUI] CheckButton _discordToggle;
|
||||||
|
[GUI] CheckButton _vSyncToggle;
|
||||||
|
[GUI] CheckButton _multiSchedToggle;
|
||||||
|
[GUI] CheckButton _fsicToggle;
|
||||||
|
[GUI] CheckButton _ignoreToggle;
|
||||||
|
[GUI] CheckButton _directKeyboardAccess;
|
||||||
|
[GUI] ComboBoxText _systemLanguageSelect;
|
||||||
|
[GUI] ComboBoxText _systemRegionSelect;
|
||||||
|
[GUI] ComboBoxText _systemTimeZoneSelect;
|
||||||
|
[GUI] SpinButton _systemTimeYearSpin;
|
||||||
|
[GUI] SpinButton _systemTimeMonthSpin;
|
||||||
|
[GUI] SpinButton _systemTimeDaySpin;
|
||||||
|
[GUI] SpinButton _systemTimeHourSpin;
|
||||||
|
[GUI] SpinButton _systemTimeMinuteSpin;
|
||||||
|
[GUI] Adjustment _systemTimeYearSpinAdjustment;
|
||||||
|
[GUI] Adjustment _systemTimeMonthSpinAdjustment;
|
||||||
|
[GUI] Adjustment _systemTimeDaySpinAdjustment;
|
||||||
|
[GUI] Adjustment _systemTimeHourSpinAdjustment;
|
||||||
|
[GUI] Adjustment _systemTimeMinuteSpinAdjustment;
|
||||||
|
[GUI] CheckButton _custThemeToggle;
|
||||||
|
[GUI] Entry _custThemePath;
|
||||||
|
[GUI] ToggleButton _browseThemePath;
|
||||||
|
[GUI] Label _custThemePathLabel;
|
||||||
|
[GUI] TreeView _gameDirsBox;
|
||||||
|
[GUI] Entry _addGameDirBox;
|
||||||
|
[GUI] Entry _graphicsShadersDumpPath;
|
||||||
|
[GUI] ComboBoxText _anisotropy;
|
||||||
|
[GUI] ToggleButton _configureController1;
|
||||||
|
[GUI] ToggleButton _configureController2;
|
||||||
|
[GUI] ToggleButton _configureController3;
|
||||||
|
[GUI] ToggleButton _configureController4;
|
||||||
|
[GUI] ToggleButton _configureController5;
|
||||||
|
[GUI] ToggleButton _configureController6;
|
||||||
|
[GUI] ToggleButton _configureController7;
|
||||||
|
[GUI] ToggleButton _configureController8;
|
||||||
|
[GUI] ToggleButton _configureControllerH;
|
||||||
|
#pragma warning restore CS0649, IDE0044
|
||||||
|
|
||||||
|
public SettingsWindow(VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : this(new Builder("Ryujinx.Ui.SettingsWindow.glade"), virtualFileSystem, contentManager) { }
|
||||||
|
|
||||||
|
private SettingsWindow(Builder builder, VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
|
||||||
|
{
|
||||||
|
builder.Autoconnect(this);
|
||||||
|
|
||||||
|
this.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
||||||
|
|
||||||
|
_virtualFileSystem = virtualFileSystem;
|
||||||
|
|
||||||
|
//Bind Events
|
||||||
|
_configureController1.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player1);
|
||||||
|
_configureController2.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player2);
|
||||||
|
_configureController3.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player3);
|
||||||
|
_configureController4.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player4);
|
||||||
|
_configureController5.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player5);
|
||||||
|
_configureController6.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player6);
|
||||||
|
_configureController7.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player7);
|
||||||
|
_configureController8.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Player8);
|
||||||
|
_configureControllerH.Pressed += (sender, args) => ConfigureController_Pressed(sender, args, PlayerIndex.Handheld);
|
||||||
|
|
||||||
|
//Setup Currents
|
||||||
|
if (ConfigurationState.Instance.Logger.EnableFileLog)
|
||||||
|
{
|
||||||
|
_fileLogToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Logger.EnableError)
|
||||||
|
{
|
||||||
|
_errorLogToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Logger.EnableWarn)
|
||||||
|
{
|
||||||
|
_warningLogToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Logger.EnableInfo)
|
||||||
|
{
|
||||||
|
_infoLogToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Logger.EnableStub)
|
||||||
|
{
|
||||||
|
_stubLogToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Logger.EnableDebug)
|
||||||
|
{
|
||||||
|
_debugLogToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Logger.EnableGuest)
|
||||||
|
{
|
||||||
|
_guestLogToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Logger.EnableFsAccessLog)
|
||||||
|
{
|
||||||
|
_fsAccessLogToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.System.EnableDockedMode)
|
||||||
|
{
|
||||||
|
_dockedModeToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.EnableDiscordIntegration)
|
||||||
|
{
|
||||||
|
_discordToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Graphics.EnableVsync)
|
||||||
|
{
|
||||||
|
_vSyncToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.System.EnableMulticoreScheduling)
|
||||||
|
{
|
||||||
|
_multiSchedToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.System.EnableFsIntegrityChecks)
|
||||||
|
{
|
||||||
|
_fsicToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.System.IgnoreMissingServices)
|
||||||
|
{
|
||||||
|
_ignoreToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Hid.EnableKeyboard)
|
||||||
|
{
|
||||||
|
_directKeyboardAccess.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ConfigurationState.Instance.Ui.EnableCustomTheme)
|
||||||
|
{
|
||||||
|
_custThemeToggle.Click();
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeZoneContentManager timeZoneContentManager = new TimeZoneContentManager();
|
||||||
|
|
||||||
|
timeZoneContentManager.InitializeInstance(virtualFileSystem, contentManager, LibHac.FsSystem.IntegrityCheckLevel.None);
|
||||||
|
|
||||||
|
List<string> locationNames = timeZoneContentManager.LocationNameCache.ToList();
|
||||||
|
|
||||||
|
locationNames.Sort();
|
||||||
|
|
||||||
|
foreach (string locationName in locationNames)
|
||||||
|
{
|
||||||
|
_systemTimeZoneSelect.Append(locationName, locationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
_systemLanguageSelect.SetActiveId(ConfigurationState.Instance.System.Language.Value.ToString());
|
||||||
|
_systemRegionSelect.SetActiveId(ConfigurationState.Instance.System.Region.Value.ToString());
|
||||||
|
_systemTimeZoneSelect.SetActiveId(timeZoneContentManager.SanityCheckDeviceLocationName());
|
||||||
|
_anisotropy.SetActiveId(ConfigurationState.Instance.Graphics.MaxAnisotropy.Value.ToString());
|
||||||
|
|
||||||
|
_custThemePath.Buffer.Text = ConfigurationState.Instance.Ui.CustomThemePath;
|
||||||
|
_graphicsShadersDumpPath.Buffer.Text = ConfigurationState.Instance.Graphics.ShadersDumpPath;
|
||||||
|
_fsLogSpinAdjustment.Value = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
|
||||||
|
_systemTimeOffset = ConfigurationState.Instance.System.SystemTimeOffset;
|
||||||
|
|
||||||
|
_gameDirsBox.AppendColumn("", new CellRendererText(), "text", 0);
|
||||||
|
_gameDirsBoxStore = new ListStore(typeof(string));
|
||||||
|
_gameDirsBox.Model = _gameDirsBoxStore;
|
||||||
|
|
||||||
|
foreach (string gameDir in ConfigurationState.Instance.Ui.GameDirs.Value)
|
||||||
|
{
|
||||||
|
_gameDirsBoxStore.AppendValues(gameDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_custThemeToggle.Active == false)
|
||||||
|
{
|
||||||
|
_custThemePath.Sensitive = false;
|
||||||
|
_custThemePathLabel.Sensitive = false;
|
||||||
|
_browseThemePath.Sensitive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup system time spinners
|
||||||
|
UpdateSystemTimeSpinners();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSystemTimeSpinners()
|
||||||
|
{
|
||||||
|
//Bind system time events
|
||||||
|
_systemTimeYearSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
||||||
|
_systemTimeMonthSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
||||||
|
_systemTimeDaySpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
||||||
|
_systemTimeHourSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
||||||
|
_systemTimeMinuteSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
||||||
|
|
||||||
|
//Apply actual system time + SystemTimeOffset to system time spin buttons
|
||||||
|
DateTime systemTime = DateTime.Now.AddSeconds(_systemTimeOffset);
|
||||||
|
|
||||||
|
_systemTimeYearSpinAdjustment.Value = systemTime.Year;
|
||||||
|
_systemTimeMonthSpinAdjustment.Value = systemTime.Month;
|
||||||
|
_systemTimeDaySpinAdjustment.Value = systemTime.Day;
|
||||||
|
_systemTimeHourSpinAdjustment.Value = systemTime.Hour;
|
||||||
|
_systemTimeMinuteSpinAdjustment.Value = systemTime.Minute;
|
||||||
|
|
||||||
|
//Format spin buttons text to include leading zeros
|
||||||
|
_systemTimeYearSpin.Text = systemTime.Year.ToString("0000");
|
||||||
|
_systemTimeMonthSpin.Text = systemTime.Month.ToString("00");
|
||||||
|
_systemTimeDaySpin.Text = systemTime.Day.ToString("00");
|
||||||
|
_systemTimeHourSpin.Text = systemTime.Hour.ToString("00");
|
||||||
|
_systemTimeMinuteSpin.Text = systemTime.Minute.ToString("00");
|
||||||
|
|
||||||
|
//Bind system time events
|
||||||
|
_systemTimeYearSpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
||||||
|
_systemTimeMonthSpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
||||||
|
_systemTimeDaySpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
||||||
|
_systemTimeHourSpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
||||||
|
_systemTimeMinuteSpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Events
|
||||||
|
private void SystemTimeSpin_ValueChanged(Object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
int year = _systemTimeYearSpin.ValueAsInt;
|
||||||
|
int month = _systemTimeMonthSpin.ValueAsInt;
|
||||||
|
int day = _systemTimeDaySpin.ValueAsInt;
|
||||||
|
int hour = _systemTimeHourSpin.ValueAsInt;
|
||||||
|
int minute = _systemTimeMinuteSpin.ValueAsInt;
|
||||||
|
|
||||||
|
if (!DateTime.TryParse(year + "-" + month + "-" + day + " " + hour + ":" + minute, out DateTime newTime))
|
||||||
|
{
|
||||||
|
UpdateSystemTimeSpinners();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
newTime = newTime.AddSeconds(DateTime.Now.Second).AddMilliseconds(DateTime.Now.Millisecond);
|
||||||
|
|
||||||
|
long systemTimeOffset = (long)Math.Ceiling((newTime - DateTime.Now).TotalMinutes) * 60L;
|
||||||
|
|
||||||
|
if (_systemTimeOffset != systemTimeOffset)
|
||||||
|
{
|
||||||
|
_systemTimeOffset = systemTimeOffset;
|
||||||
|
UpdateSystemTimeSpinners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddDir_Pressed(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
if (Directory.Exists(_addGameDirBox.Buffer.Text))
|
||||||
|
{
|
||||||
|
_gameDirsBoxStore.AppendValues(_addGameDirBox.Buffer.Text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FileChooserDialog fileChooser = new FileChooserDialog("Choose the game directory to add to the list", this, FileChooserAction.SelectFolder, "Cancel", ResponseType.Cancel, "Add", ResponseType.Accept);
|
||||||
|
|
||||||
|
if (fileChooser.Run() == (int)ResponseType.Accept)
|
||||||
|
{
|
||||||
|
_gameDirsBoxStore.AppendValues(fileChooser.Filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileChooser.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
_addGameDirBox.Buffer.Text = "";
|
||||||
|
|
||||||
|
((ToggleButton)sender).SetStateFlags(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveDir_Pressed(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
TreeSelection selection = _gameDirsBox.Selection;
|
||||||
|
|
||||||
|
if (selection.GetSelected(out TreeIter treeIter))
|
||||||
|
{
|
||||||
|
_gameDirsBoxStore.Remove(ref treeIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
((ToggleButton)sender).SetStateFlags(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CustThemeToggle_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
_custThemePath.Sensitive = _custThemeToggle.Active;
|
||||||
|
_custThemePathLabel.Sensitive = _custThemeToggle.Active;
|
||||||
|
_browseThemePath.Sensitive = _custThemeToggle.Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BrowseThemeDir_Pressed(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
FileChooserDialog fileChooser = new FileChooserDialog("Choose the theme to load", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Select", ResponseType.Accept);
|
||||||
|
|
||||||
|
fileChooser.Filter = new FileFilter();
|
||||||
|
fileChooser.Filter.AddPattern("*.css");
|
||||||
|
|
||||||
|
if (fileChooser.Run() == (int)ResponseType.Accept)
|
||||||
|
{
|
||||||
|
_custThemePath.Buffer.Text = fileChooser.Filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileChooser.Dispose();
|
||||||
|
|
||||||
|
_browseThemePath.SetStateFlags(0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenLogsFolder_Pressed(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
string logPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
|
||||||
|
|
||||||
|
DirectoryInfo directory = new DirectoryInfo(logPath);
|
||||||
|
directory.Create();
|
||||||
|
|
||||||
|
Process.Start(new ProcessStartInfo()
|
||||||
|
{
|
||||||
|
FileName = logPath,
|
||||||
|
UseShellExecute = true,
|
||||||
|
Verb = "open"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfigureController_Pressed(object sender, EventArgs args, PlayerIndex playerIndex)
|
||||||
|
{
|
||||||
|
((ToggleButton)sender).SetStateFlags(0, true);
|
||||||
|
|
||||||
|
ControllerWindow controllerWin = new ControllerWindow(playerIndex, _virtualFileSystem);
|
||||||
|
controllerWin.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveToggle_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
List<string> gameDirs = new List<string>();
|
||||||
|
|
||||||
|
_gameDirsBoxStore.GetIterFirst(out TreeIter treeIter);
|
||||||
|
for (int i = 0; i < _gameDirsBoxStore.IterNChildren(); i++)
|
||||||
|
{
|
||||||
|
gameDirs.Add((string)_gameDirsBoxStore.GetValue(treeIter, 0));
|
||||||
|
|
||||||
|
_gameDirsBoxStore.IterNext(ref treeIter);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationState.Instance.Logger.EnableError.Value = _errorLogToggle.Active;
|
||||||
|
ConfigurationState.Instance.Logger.EnableWarn.Value = _warningLogToggle.Active;
|
||||||
|
ConfigurationState.Instance.Logger.EnableInfo.Value = _infoLogToggle.Active;
|
||||||
|
ConfigurationState.Instance.Logger.EnableStub.Value = _stubLogToggle.Active;
|
||||||
|
ConfigurationState.Instance.Logger.EnableDebug.Value = _debugLogToggle.Active;
|
||||||
|
ConfigurationState.Instance.Logger.EnableGuest.Value = _guestLogToggle.Active;
|
||||||
|
ConfigurationState.Instance.Logger.EnableFsAccessLog.Value = _fsAccessLogToggle.Active;
|
||||||
|
ConfigurationState.Instance.Logger.EnableFileLog.Value = _fileLogToggle.Active;
|
||||||
|
ConfigurationState.Instance.System.EnableDockedMode.Value = _dockedModeToggle.Active;
|
||||||
|
ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
|
||||||
|
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
|
||||||
|
ConfigurationState.Instance.System.EnableMulticoreScheduling.Value = _multiSchedToggle.Active;
|
||||||
|
ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
|
||||||
|
ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active;
|
||||||
|
ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active;
|
||||||
|
ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
|
||||||
|
ConfigurationState.Instance.System.Language.Value = Enum.Parse<Language>(_systemLanguageSelect.ActiveId);
|
||||||
|
ConfigurationState.Instance.System.Region.Value = Enum.Parse<Configuration.System.Region>(_systemRegionSelect.ActiveId);
|
||||||
|
ConfigurationState.Instance.System.TimeZone.Value = _systemTimeZoneSelect.ActiveId;
|
||||||
|
ConfigurationState.Instance.System.SystemTimeOffset.Value = _systemTimeOffset;
|
||||||
|
ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
|
||||||
|
ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;
|
||||||
|
ConfigurationState.Instance.Ui.GameDirs.Value = gameDirs;
|
||||||
|
ConfigurationState.Instance.System.FsGlobalAccessLogMode.Value = (int)_fsLogSpinAdjustment.Value;
|
||||||
|
ConfigurationState.Instance.Graphics.MaxAnisotropy.Value = float.Parse(_anisotropy.ActiveId);
|
||||||
|
|
||||||
|
MainWindow.SaveConfig();
|
||||||
|
MainWindow.ApplyTheme();
|
||||||
|
MainWindow.UpdateGameTable();
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CloseToggle_Activated(object sender, EventArgs args)
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,611 +0,0 @@
|
||||||
using Gtk;
|
|
||||||
using Ryujinx.Configuration;
|
|
||||||
using Ryujinx.Configuration.Hid;
|
|
||||||
using Ryujinx.Configuration.System;
|
|
||||||
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
using GUI = Gtk.Builder.ObjectAttribute;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ui
|
|
||||||
{
|
|
||||||
public class SwitchSettings : Window
|
|
||||||
{
|
|
||||||
private static ListStore _gameDirsBoxStore;
|
|
||||||
|
|
||||||
private static bool _listeningForKeypress;
|
|
||||||
|
|
||||||
private long _systemTimeOffset;
|
|
||||||
|
|
||||||
#pragma warning disable CS0649
|
|
||||||
#pragma warning disable IDE0044
|
|
||||||
[GUI] Window _settingsWin;
|
|
||||||
[GUI] CheckButton _errorLogToggle;
|
|
||||||
[GUI] CheckButton _warningLogToggle;
|
|
||||||
[GUI] CheckButton _infoLogToggle;
|
|
||||||
[GUI] CheckButton _stubLogToggle;
|
|
||||||
[GUI] CheckButton _debugLogToggle;
|
|
||||||
[GUI] CheckButton _fileLogToggle;
|
|
||||||
[GUI] CheckButton _guestLogToggle;
|
|
||||||
[GUI] CheckButton _fsAccessLogToggle;
|
|
||||||
[GUI] Adjustment _fsLogSpinAdjustment;
|
|
||||||
[GUI] CheckButton _dockedModeToggle;
|
|
||||||
[GUI] CheckButton _discordToggle;
|
|
||||||
[GUI] CheckButton _vSyncToggle;
|
|
||||||
[GUI] CheckButton _multiSchedToggle;
|
|
||||||
[GUI] CheckButton _fsicToggle;
|
|
||||||
[GUI] CheckButton _ignoreToggle;
|
|
||||||
[GUI] CheckButton _directKeyboardAccess;
|
|
||||||
[GUI] ComboBoxText _systemLanguageSelect;
|
|
||||||
[GUI] ComboBoxText _systemRegionSelect;
|
|
||||||
[GUI] ComboBoxText _systemTimeZoneSelect;
|
|
||||||
[GUI] SpinButton _systemTimeYearSpin;
|
|
||||||
[GUI] SpinButton _systemTimeMonthSpin;
|
|
||||||
[GUI] SpinButton _systemTimeDaySpin;
|
|
||||||
[GUI] SpinButton _systemTimeHourSpin;
|
|
||||||
[GUI] SpinButton _systemTimeMinuteSpin;
|
|
||||||
[GUI] Adjustment _systemTimeYearSpinAdjustment;
|
|
||||||
[GUI] Adjustment _systemTimeMonthSpinAdjustment;
|
|
||||||
[GUI] Adjustment _systemTimeDaySpinAdjustment;
|
|
||||||
[GUI] Adjustment _systemTimeHourSpinAdjustment;
|
|
||||||
[GUI] Adjustment _systemTimeMinuteSpinAdjustment;
|
|
||||||
[GUI] CheckButton _custThemeToggle;
|
|
||||||
[GUI] Entry _custThemePath;
|
|
||||||
[GUI] ToggleButton _browseThemePath;
|
|
||||||
[GUI] Label _custThemePathLabel;
|
|
||||||
[GUI] TreeView _gameDirsBox;
|
|
||||||
[GUI] Entry _addGameDirBox;
|
|
||||||
[GUI] ToggleButton _addDir;
|
|
||||||
[GUI] ToggleButton _browseDir;
|
|
||||||
[GUI] ToggleButton _removeDir;
|
|
||||||
[GUI] Entry _graphicsShadersDumpPath;
|
|
||||||
[GUI] ComboBoxText _anisotropy;
|
|
||||||
[GUI] Image _controller1Image;
|
|
||||||
|
|
||||||
[GUI] ComboBoxText _controller1Type;
|
|
||||||
[GUI] ToggleButton _lStickUp1;
|
|
||||||
[GUI] ToggleButton _lStickDown1;
|
|
||||||
[GUI] ToggleButton _lStickLeft1;
|
|
||||||
[GUI] ToggleButton _lStickRight1;
|
|
||||||
[GUI] ToggleButton _lStickButton1;
|
|
||||||
[GUI] ToggleButton _dpadUp1;
|
|
||||||
[GUI] ToggleButton _dpadDown1;
|
|
||||||
[GUI] ToggleButton _dpadLeft1;
|
|
||||||
[GUI] ToggleButton _dpadRight1;
|
|
||||||
[GUI] ToggleButton _minus1;
|
|
||||||
[GUI] ToggleButton _l1;
|
|
||||||
[GUI] ToggleButton _zL1;
|
|
||||||
[GUI] ToggleButton _rStickUp1;
|
|
||||||
[GUI] ToggleButton _rStickDown1;
|
|
||||||
[GUI] ToggleButton _rStickLeft1;
|
|
||||||
[GUI] ToggleButton _rStickRight1;
|
|
||||||
[GUI] ToggleButton _rStickButton1;
|
|
||||||
[GUI] ToggleButton _a1;
|
|
||||||
[GUI] ToggleButton _b1;
|
|
||||||
[GUI] ToggleButton _x1;
|
|
||||||
[GUI] ToggleButton _y1;
|
|
||||||
[GUI] ToggleButton _plus1;
|
|
||||||
[GUI] ToggleButton _r1;
|
|
||||||
[GUI] ToggleButton _zR1;
|
|
||||||
#pragma warning restore CS0649
|
|
||||||
#pragma warning restore IDE0044
|
|
||||||
|
|
||||||
public SwitchSettings(HLE.FileSystem.VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : this(new Builder("Ryujinx.Ui.SwitchSettings.glade"), virtualFileSystem, contentManager) { }
|
|
||||||
|
|
||||||
private SwitchSettings(Builder builder, HLE.FileSystem.VirtualFileSystem virtualFileSystem, HLE.FileSystem.Content.ContentManager contentManager) : base(builder.GetObject("_settingsWin").Handle)
|
|
||||||
{
|
|
||||||
builder.Autoconnect(this);
|
|
||||||
|
|
||||||
_settingsWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
|
||||||
_controller1Image.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyCon.png", 500, 500);
|
|
||||||
|
|
||||||
//Bind Events
|
|
||||||
_lStickUp1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickUp1);
|
|
||||||
_lStickDown1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickDown1);
|
|
||||||
_lStickLeft1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickLeft1);
|
|
||||||
_lStickRight1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickRight1);
|
|
||||||
_lStickButton1.Clicked += (sender, args) => Button_Pressed(sender, args, _lStickButton1);
|
|
||||||
_dpadUp1.Clicked += (sender, args) => Button_Pressed(sender, args, _dpadUp1);
|
|
||||||
_dpadDown1.Clicked += (sender, args) => Button_Pressed(sender, args, _dpadDown1);
|
|
||||||
_dpadLeft1.Clicked += (sender, args) => Button_Pressed(sender, args, _dpadLeft1);
|
|
||||||
_dpadRight1.Clicked += (sender, args) => Button_Pressed(sender, args, _dpadRight1);
|
|
||||||
_minus1.Clicked += (sender, args) => Button_Pressed(sender, args, _minus1);
|
|
||||||
_l1.Clicked += (sender, args) => Button_Pressed(sender, args, _l1);
|
|
||||||
_zL1.Clicked += (sender, args) => Button_Pressed(sender, args, _zL1);
|
|
||||||
_rStickUp1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickUp1);
|
|
||||||
_rStickDown1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickDown1);
|
|
||||||
_rStickLeft1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickLeft1);
|
|
||||||
_rStickRight1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickRight1);
|
|
||||||
_rStickButton1.Clicked += (sender, args) => Button_Pressed(sender, args, _rStickButton1);
|
|
||||||
_a1.Clicked += (sender, args) => Button_Pressed(sender, args, _a1);
|
|
||||||
_b1.Clicked += (sender, args) => Button_Pressed(sender, args, _b1);
|
|
||||||
_x1.Clicked += (sender, args) => Button_Pressed(sender, args, _x1);
|
|
||||||
_y1.Clicked += (sender, args) => Button_Pressed(sender, args, _y1);
|
|
||||||
_plus1.Clicked += (sender, args) => Button_Pressed(sender, args, _plus1);
|
|
||||||
_r1.Clicked += (sender, args) => Button_Pressed(sender, args, _r1);
|
|
||||||
_zR1.Clicked += (sender, args) => Button_Pressed(sender, args, _zR1);
|
|
||||||
_controller1Type.Changed += (sender, args) => Controller_Changed(sender, args, _controller1Type.ActiveId, _controller1Image);
|
|
||||||
|
|
||||||
//Setup Currents
|
|
||||||
if (ConfigurationState.Instance.Logger.EnableFileLog)
|
|
||||||
{
|
|
||||||
_fileLogToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Logger.EnableError)
|
|
||||||
{
|
|
||||||
_errorLogToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Logger.EnableWarn)
|
|
||||||
{
|
|
||||||
_warningLogToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Logger.EnableInfo)
|
|
||||||
{
|
|
||||||
_infoLogToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Logger.EnableStub)
|
|
||||||
{
|
|
||||||
_stubLogToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Logger.EnableDebug)
|
|
||||||
{
|
|
||||||
_debugLogToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Logger.EnableGuest)
|
|
||||||
{
|
|
||||||
_guestLogToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Logger.EnableFsAccessLog)
|
|
||||||
{
|
|
||||||
_fsAccessLogToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.System.EnableDockedMode)
|
|
||||||
{
|
|
||||||
_dockedModeToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.EnableDiscordIntegration)
|
|
||||||
{
|
|
||||||
_discordToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Graphics.EnableVsync)
|
|
||||||
{
|
|
||||||
_vSyncToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.System.EnableMulticoreScheduling)
|
|
||||||
{
|
|
||||||
_multiSchedToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.System.EnableFsIntegrityChecks)
|
|
||||||
{
|
|
||||||
_fsicToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.System.IgnoreMissingServices)
|
|
||||||
{
|
|
||||||
_ignoreToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Hid.EnableKeyboard)
|
|
||||||
{
|
|
||||||
_directKeyboardAccess.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigurationState.Instance.Ui.EnableCustomTheme)
|
|
||||||
{
|
|
||||||
_custThemeToggle.Click();
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeZoneContentManager timeZoneContentManager = new TimeZoneContentManager();
|
|
||||||
|
|
||||||
timeZoneContentManager.InitializeInstance(virtualFileSystem, contentManager, LibHac.FsSystem.IntegrityCheckLevel.None);
|
|
||||||
|
|
||||||
List<string> locationNames = timeZoneContentManager.LocationNameCache.ToList();
|
|
||||||
|
|
||||||
locationNames.Sort();
|
|
||||||
|
|
||||||
foreach (string locationName in locationNames)
|
|
||||||
{
|
|
||||||
_systemTimeZoneSelect.Append(locationName, locationName);
|
|
||||||
}
|
|
||||||
|
|
||||||
_systemLanguageSelect.SetActiveId(ConfigurationState.Instance.System.Language.Value.ToString());
|
|
||||||
_systemRegionSelect .SetActiveId(ConfigurationState.Instance.System.Region.Value.ToString());
|
|
||||||
_systemTimeZoneSelect.SetActiveId(timeZoneContentManager.SanityCheckDeviceLocationName());
|
|
||||||
_anisotropy .SetActiveId(ConfigurationState.Instance.Graphics.MaxAnisotropy.Value.ToString());
|
|
||||||
_controller1Type .SetActiveId(ConfigurationState.Instance.Hid.ControllerType.Value.ToString());
|
|
||||||
Controller_Changed(null, null, _controller1Type.ActiveId, _controller1Image);
|
|
||||||
|
|
||||||
_lStickUp1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickUp.ToString();
|
|
||||||
_lStickDown1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickDown.ToString();
|
|
||||||
_lStickLeft1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickLeft.ToString();
|
|
||||||
_lStickRight1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickRight.ToString();
|
|
||||||
_lStickButton1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.StickButton.ToString();
|
|
||||||
_dpadUp1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.DPadUp.ToString();
|
|
||||||
_dpadDown1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.DPadDown.ToString();
|
|
||||||
_dpadLeft1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.DPadLeft.ToString();
|
|
||||||
_dpadRight1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.DPadRight.ToString();
|
|
||||||
_minus1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.ButtonMinus.ToString();
|
|
||||||
_l1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.ButtonL.ToString();
|
|
||||||
_zL1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon.ButtonZl.ToString();
|
|
||||||
_rStickUp1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickUp.ToString();
|
|
||||||
_rStickDown1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickDown.ToString();
|
|
||||||
_rStickLeft1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickLeft.ToString();
|
|
||||||
_rStickRight1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickRight.ToString();
|
|
||||||
_rStickButton1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.StickButton.ToString();
|
|
||||||
_a1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonA.ToString();
|
|
||||||
_b1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonB.ToString();
|
|
||||||
_x1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonX.ToString();
|
|
||||||
_y1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonY.ToString();
|
|
||||||
_plus1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonPlus.ToString();
|
|
||||||
_r1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonR.ToString();
|
|
||||||
_zR1.Label = ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon.ButtonZr.ToString();
|
|
||||||
|
|
||||||
_custThemePath.Buffer.Text = ConfigurationState.Instance.Ui.CustomThemePath;
|
|
||||||
_graphicsShadersDumpPath.Buffer.Text = ConfigurationState.Instance.Graphics.ShadersDumpPath;
|
|
||||||
_fsLogSpinAdjustment.Value = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
|
|
||||||
_systemTimeOffset = ConfigurationState.Instance.System.SystemTimeOffset;
|
|
||||||
|
|
||||||
_gameDirsBox.AppendColumn("", new CellRendererText(), "text", 0);
|
|
||||||
_gameDirsBoxStore = new ListStore(typeof(string));
|
|
||||||
_gameDirsBox.Model = _gameDirsBoxStore;
|
|
||||||
|
|
||||||
foreach (string gameDir in ConfigurationState.Instance.Ui.GameDirs.Value)
|
|
||||||
{
|
|
||||||
_gameDirsBoxStore.AppendValues(gameDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_custThemeToggle.Active == false)
|
|
||||||
{
|
|
||||||
_custThemePath.Sensitive = false;
|
|
||||||
_custThemePathLabel.Sensitive = false;
|
|
||||||
_browseThemePath.Sensitive = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_listeningForKeypress = false;
|
|
||||||
|
|
||||||
//Setup system time spinners
|
|
||||||
UpdateSystemTimeSpinners();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateSystemTimeSpinners()
|
|
||||||
{
|
|
||||||
//Unbind system time spin events
|
|
||||||
_systemTimeYearSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
|
||||||
_systemTimeMonthSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
|
||||||
_systemTimeDaySpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
|
||||||
_systemTimeHourSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
|
||||||
_systemTimeMinuteSpin.ValueChanged -= SystemTimeSpin_ValueChanged;
|
|
||||||
|
|
||||||
//Apply actual system time + SystemTimeOffset to system time spin buttons
|
|
||||||
DateTime systemTime = DateTime.Now.AddSeconds(_systemTimeOffset);
|
|
||||||
|
|
||||||
_systemTimeYearSpinAdjustment.Value = systemTime.Year;
|
|
||||||
_systemTimeMonthSpinAdjustment.Value = systemTime.Month;
|
|
||||||
_systemTimeDaySpinAdjustment.Value = systemTime.Day;
|
|
||||||
_systemTimeHourSpinAdjustment.Value = systemTime.Hour;
|
|
||||||
_systemTimeMinuteSpinAdjustment.Value = systemTime.Minute;
|
|
||||||
|
|
||||||
//Format spin buttons text to include leading zeros
|
|
||||||
_systemTimeYearSpin.Text = systemTime.Year.ToString("0000");
|
|
||||||
_systemTimeMonthSpin.Text = systemTime.Month.ToString("00");
|
|
||||||
_systemTimeDaySpin.Text = systemTime.Day.ToString("00");
|
|
||||||
_systemTimeHourSpin.Text = systemTime.Hour.ToString("00");
|
|
||||||
_systemTimeMinuteSpin.Text = systemTime.Minute.ToString("00");
|
|
||||||
|
|
||||||
//Bind system time spin button events
|
|
||||||
_systemTimeYearSpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
|
||||||
_systemTimeMonthSpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
|
||||||
_systemTimeDaySpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
|
||||||
_systemTimeHourSpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
|
||||||
_systemTimeMinuteSpin.ValueChanged += SystemTimeSpin_ValueChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Events
|
|
||||||
private void SystemTimeSpin_ValueChanged(Object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
int year = _systemTimeYearSpin.ValueAsInt;
|
|
||||||
int month = _systemTimeMonthSpin.ValueAsInt;
|
|
||||||
int day = _systemTimeDaySpin.ValueAsInt;
|
|
||||||
int hour = _systemTimeHourSpin.ValueAsInt;
|
|
||||||
int minute = _systemTimeMinuteSpin.ValueAsInt;
|
|
||||||
|
|
||||||
if (!DateTime.TryParse(year + "-" + month + "-" + day + " " + hour + ":" + minute, out DateTime newTime))
|
|
||||||
{
|
|
||||||
UpdateSystemTimeSpinners();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newTime = newTime.AddSeconds(DateTime.Now.Second).AddMilliseconds(DateTime.Now.Millisecond);
|
|
||||||
|
|
||||||
long systemTimeOffset = (long)Math.Ceiling((newTime - DateTime.Now).TotalMinutes) * 60L;
|
|
||||||
|
|
||||||
if (_systemTimeOffset != systemTimeOffset)
|
|
||||||
{
|
|
||||||
_systemTimeOffset = systemTimeOffset;
|
|
||||||
UpdateSystemTimeSpinners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Button_Pressed(object sender, EventArgs args, ToggleButton button)
|
|
||||||
{
|
|
||||||
if (_listeningForKeypress == false)
|
|
||||||
{
|
|
||||||
KeyPressEvent += On_KeyPress;
|
|
||||||
|
|
||||||
_listeningForKeypress = true;
|
|
||||||
|
|
||||||
void On_KeyPress(object o, KeyPressEventArgs keyPressed)
|
|
||||||
{
|
|
||||||
string key = keyPressed.Event.Key.ToString();
|
|
||||||
string capKey = key.First().ToString().ToUpper() + key.Substring(1);
|
|
||||||
|
|
||||||
if (Enum.IsDefined(typeof(Configuration.Hid.Key), capKey))
|
|
||||||
{
|
|
||||||
button.Label = capKey;
|
|
||||||
}
|
|
||||||
else if (GdkToOpenTkInput.ContainsKey(key))
|
|
||||||
{
|
|
||||||
button.Label = GdkToOpenTkInput[key];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
button.Label = "Space";
|
|
||||||
}
|
|
||||||
|
|
||||||
button.SetStateFlags(0, true);
|
|
||||||
|
|
||||||
KeyPressEvent -= On_KeyPress;
|
|
||||||
|
|
||||||
_listeningForKeypress = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
button.SetStateFlags(0, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Controller_Changed(object sender, EventArgs args, string controllerType, Image controllerImage)
|
|
||||||
{
|
|
||||||
switch (controllerType)
|
|
||||||
{
|
|
||||||
case "ProController":
|
|
||||||
controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.ProCon.png", 500, 500);
|
|
||||||
break;
|
|
||||||
case "NpadLeft":
|
|
||||||
controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.BlueCon.png", 500, 500);
|
|
||||||
break;
|
|
||||||
case "NpadRight":
|
|
||||||
controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.RedCon.png", 500, 500);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
controllerImage.Pixbuf = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.JoyCon.png", 500, 500);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddDir_Pressed(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
if (Directory.Exists(_addGameDirBox.Buffer.Text))
|
|
||||||
{
|
|
||||||
_gameDirsBoxStore.AppendValues(_addGameDirBox.Buffer.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
_addDir.SetStateFlags(0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BrowseDir_Pressed(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
FileChooserDialog fileChooser = new FileChooserDialog("Choose the game directory to add to the list", this, FileChooserAction.SelectFolder, "Cancel", ResponseType.Cancel, "Add", ResponseType.Accept);
|
|
||||||
|
|
||||||
if (fileChooser.Run() == (int)ResponseType.Accept)
|
|
||||||
{
|
|
||||||
_gameDirsBoxStore.AppendValues(fileChooser.Filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
fileChooser.Dispose();
|
|
||||||
|
|
||||||
_browseDir.SetStateFlags(0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveDir_Pressed(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
TreeSelection selection = _gameDirsBox.Selection;
|
|
||||||
|
|
||||||
selection.GetSelected(out TreeIter treeIter);
|
|
||||||
_gameDirsBoxStore.Remove(ref treeIter);
|
|
||||||
|
|
||||||
_removeDir.SetStateFlags(0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CustThemeToggle_Activated(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
_custThemePath.Sensitive = _custThemeToggle.Active;
|
|
||||||
_custThemePathLabel.Sensitive = _custThemeToggle.Active;
|
|
||||||
_browseThemePath.Sensitive = _custThemeToggle.Active;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BrowseThemeDir_Pressed(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
FileChooserDialog fileChooser = new FileChooserDialog("Choose the theme to load", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Select", ResponseType.Accept);
|
|
||||||
|
|
||||||
fileChooser.Filter = new FileFilter();
|
|
||||||
fileChooser.Filter.AddPattern("*.css");
|
|
||||||
|
|
||||||
if (fileChooser.Run() == (int)ResponseType.Accept)
|
|
||||||
{
|
|
||||||
_custThemePath.Buffer.Text = fileChooser.Filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileChooser.Dispose();
|
|
||||||
|
|
||||||
_browseThemePath.SetStateFlags(0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OpenLogsFolder_Pressed(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
string logPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
|
|
||||||
|
|
||||||
DirectoryInfo directory = new DirectoryInfo(logPath);
|
|
||||||
directory.Create();
|
|
||||||
|
|
||||||
Process.Start(new ProcessStartInfo()
|
|
||||||
{
|
|
||||||
FileName = logPath,
|
|
||||||
UseShellExecute = true,
|
|
||||||
Verb = "open"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SaveToggle_Activated(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
List<string> gameDirs = new List<string>();
|
|
||||||
|
|
||||||
_gameDirsBoxStore.GetIterFirst(out TreeIter treeIter);
|
|
||||||
for (int i = 0; i < _gameDirsBoxStore.IterNChildren(); i++)
|
|
||||||
{
|
|
||||||
_gameDirsBoxStore.GetValue(treeIter, i);
|
|
||||||
|
|
||||||
gameDirs.Add((string)_gameDirsBoxStore.GetValue(treeIter, 0));
|
|
||||||
|
|
||||||
_gameDirsBoxStore.IterNext(ref treeIter);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationState.Instance.Logger.EnableError.Value = _errorLogToggle.Active;
|
|
||||||
ConfigurationState.Instance.Logger.EnableWarn.Value = _warningLogToggle.Active;
|
|
||||||
ConfigurationState.Instance.Logger.EnableInfo.Value = _infoLogToggle.Active;
|
|
||||||
ConfigurationState.Instance.Logger.EnableStub.Value = _stubLogToggle.Active;
|
|
||||||
ConfigurationState.Instance.Logger.EnableDebug.Value = _debugLogToggle.Active;
|
|
||||||
ConfigurationState.Instance.Logger.EnableGuest.Value = _guestLogToggle.Active;
|
|
||||||
ConfigurationState.Instance.Logger.EnableFsAccessLog.Value = _fsAccessLogToggle.Active;
|
|
||||||
ConfigurationState.Instance.Logger.EnableFileLog.Value = _fileLogToggle.Active;
|
|
||||||
ConfigurationState.Instance.System.EnableDockedMode.Value = _dockedModeToggle.Active;
|
|
||||||
ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
|
|
||||||
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
|
|
||||||
ConfigurationState.Instance.System.EnableMulticoreScheduling.Value = _multiSchedToggle.Active;
|
|
||||||
ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
|
|
||||||
ConfigurationState.Instance.System.IgnoreMissingServices.Value = _ignoreToggle.Active;
|
|
||||||
ConfigurationState.Instance.Hid.EnableKeyboard.Value = _directKeyboardAccess.Active;
|
|
||||||
ConfigurationState.Instance.Ui.EnableCustomTheme.Value = _custThemeToggle.Active;
|
|
||||||
|
|
||||||
ConfigurationState.Instance.Hid.KeyboardControls.Value.LeftJoycon = new NpadKeyboardLeft()
|
|
||||||
{
|
|
||||||
StickUp = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickUp1.Label),
|
|
||||||
StickDown = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickDown1.Label),
|
|
||||||
StickLeft = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickLeft1.Label),
|
|
||||||
StickRight = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickRight1.Label),
|
|
||||||
StickButton = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _lStickButton1.Label),
|
|
||||||
DPadUp = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _dpadUp1.Label),
|
|
||||||
DPadDown = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _dpadDown1.Label),
|
|
||||||
DPadLeft = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _dpadLeft1.Label),
|
|
||||||
DPadRight = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _dpadRight1.Label),
|
|
||||||
ButtonMinus = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _minus1.Label),
|
|
||||||
ButtonL = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _l1.Label),
|
|
||||||
ButtonZl = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _zL1.Label),
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigurationState.Instance.Hid.KeyboardControls.Value.RightJoycon = new NpadKeyboardRight()
|
|
||||||
{
|
|
||||||
StickUp = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickUp1.Label),
|
|
||||||
StickDown = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickDown1.Label),
|
|
||||||
StickLeft = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickLeft1.Label),
|
|
||||||
StickRight = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickRight1.Label),
|
|
||||||
StickButton = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _rStickButton1.Label),
|
|
||||||
ButtonA = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _a1.Label),
|
|
||||||
ButtonB = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _b1.Label),
|
|
||||||
ButtonX = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _x1.Label),
|
|
||||||
ButtonY = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _y1.Label),
|
|
||||||
ButtonPlus = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _plus1.Label),
|
|
||||||
ButtonR = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _r1.Label),
|
|
||||||
ButtonZr = (Configuration.Hid.Key)Enum.Parse(typeof(Configuration.Hid.Key), _zR1.Label),
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigurationState.Instance.System.Language.Value = (Language)Enum.Parse(typeof(Language), _systemLanguageSelect.ActiveId);
|
|
||||||
ConfigurationState.Instance.System.Region.Value = (Configuration.System.Region)Enum.Parse(typeof(Configuration.System.Region), _systemRegionSelect.ActiveId);
|
|
||||||
ConfigurationState.Instance.Graphics.MaxAnisotropy.Value = float.Parse(_anisotropy.ActiveId);
|
|
||||||
ConfigurationState.Instance.Hid.ControllerType.Value = (ControllerType)Enum.Parse(typeof(ControllerType), _controller1Type.ActiveId);
|
|
||||||
ConfigurationState.Instance.Ui.CustomThemePath.Value = _custThemePath.Buffer.Text;
|
|
||||||
ConfigurationState.Instance.Graphics.ShadersDumpPath.Value = _graphicsShadersDumpPath.Buffer.Text;
|
|
||||||
ConfigurationState.Instance.Ui.GameDirs.Value = gameDirs;
|
|
||||||
ConfigurationState.Instance.System.FsGlobalAccessLogMode.Value = (int)_fsLogSpinAdjustment.Value;
|
|
||||||
|
|
||||||
ConfigurationState.Instance.System.TimeZone.Value = _systemTimeZoneSelect.ActiveId;
|
|
||||||
ConfigurationState.Instance.System.SystemTimeOffset.Value = _systemTimeOffset;
|
|
||||||
|
|
||||||
MainWindow.SaveConfig();
|
|
||||||
MainWindow.ApplyTheme();
|
|
||||||
MainWindow.UpdateGameTable();
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CloseToggle_Activated(object sender, EventArgs args)
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly Dictionary<string, string> GdkToOpenTkInput = new Dictionary<string, string>()
|
|
||||||
{
|
|
||||||
{ "Key_0", "Number0" },
|
|
||||||
{ "Key_1", "Number1" },
|
|
||||||
{ "Key_2", "Number2" },
|
|
||||||
{ "Key_3", "Number3" },
|
|
||||||
{ "Key_4", "Number4" },
|
|
||||||
{ "Key_5", "Number5" },
|
|
||||||
{ "Key_6", "Number6" },
|
|
||||||
{ "Key_7", "Number7" },
|
|
||||||
{ "Key_8", "Number8" },
|
|
||||||
{ "Key_9", "Number9" },
|
|
||||||
{ "equal", "Plus" },
|
|
||||||
{ "uparrow", "Up" },
|
|
||||||
{ "downarrow", "Down" },
|
|
||||||
{ "leftarrow", "Left" },
|
|
||||||
{ "rightarrow", "Right" },
|
|
||||||
{ "Control_L", "ControlLeft" },
|
|
||||||
{ "Control_R", "ControlRight" },
|
|
||||||
{ "Shift_L", "ShiftLeft" },
|
|
||||||
{ "Shift_R", "ShiftRight" },
|
|
||||||
{ "Alt_L", "AltLeft" },
|
|
||||||
{ "Alt_R", "AltRight" },
|
|
||||||
{ "Page_Up", "PageUp" },
|
|
||||||
{ "Page_Down", "PageDown" },
|
|
||||||
{ "KP_Enter", "KeypadEnter" },
|
|
||||||
{ "KP_Up", "Up" },
|
|
||||||
{ "KP_Down", "Down" },
|
|
||||||
{ "KP_Left", "Left" },
|
|
||||||
{ "KP_Right", "Right" },
|
|
||||||
{ "KP_Divide", "KeypadDivide" },
|
|
||||||
{ "KP_Multiply", "KeypadMultiply" },
|
|
||||||
{ "KP_Subtract", "KeypadSubtract" },
|
|
||||||
{ "KP_Add", "KeypadAdd" },
|
|
||||||
{ "KP_Decimal", "KeypadDecimal" },
|
|
||||||
{ "KP_0", "Keypad0" },
|
|
||||||
{ "KP_1", "Keypad1" },
|
|
||||||
{ "KP_2", "Keypad2" },
|
|
||||||
{ "KP_3", "Keypad3" },
|
|
||||||
{ "KP_4", "Keypad4" },
|
|
||||||
{ "KP_5", "Keypad5" },
|
|
||||||
{ "KP_6", "Keypad6" },
|
|
||||||
{ "KP_7", "Keypad7" },
|
|
||||||
{ "KP_8", "Keypad8" },
|
|
||||||
{ "KP_9", "Keypad9" },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -133,7 +133,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
if (showErrorDialog)
|
if (showErrorDialog)
|
||||||
{
|
{
|
||||||
GtkDialog.CreateDialog("Ryujinx - Error", "Add Update Failed!", "The NCA header content type check has failed. This is usually because the header key is incorrect or missing.");
|
GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add Update Failed!", "The NCA header content type check has failed. This is usually because the header key is incorrect or missing.");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -144,7 +144,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
if (showErrorDialog)
|
if (showErrorDialog)
|
||||||
{
|
{
|
||||||
GtkDialog.CreateDialog("Ryujinx - Error", "Add Update Failed!", $"Your key set is missing a key with the name: {exception.Name}");
|
GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add Update Failed!", $"Your key set is missing a key with the name: {exception.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 324 KiB |
105
Ryujinx/Ui/assets/JoyConLeft.svg
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 1000.8 1000" style="enable-background:new 0 0 1000.8 1000;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{opacity:0.1;}
|
||||||
|
.st1{fill:#02C5E5;}
|
||||||
|
.st2{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g class="st0">
|
||||||
|
<path class="st1" d="M419.1,642.6v67.6c0,3.3-2.7,6-6,6h-4.2v-79.5h4.2C416.4,636.6,419.1,639.3,419.1,642.6z"/>
|
||||||
|
<path class="st1" d="M419.1,239.8v67.6c0,3.3-2.7,6-6,6h-4.2v-79.5h4.2C416.4,233.9,419.1,236.5,419.1,239.8z"/>
|
||||||
|
<path class="st1" d="M330.1,7v2.6h-54.2c-84.8,0-161.4,50.7-194.6,128.7l-3.4-3.4c-1.8-1.7-2.3-4.4-1.3-6.6
|
||||||
|
C111.2,50.8,188.1,1,272.9,1h51.2C327.4,1,330.1,3.7,330.1,7z"/>
|
||||||
|
<path class="st1" d="M359.6,115.1h-46.9c-1.6,0-3-1.3-3-3v-11.7c0-1.6,1.3-3,3-3h46.9c1.6,0,3,1.3,3,3v11.7
|
||||||
|
C362.6,113.8,361.3,115.1,359.6,115.1z"/>
|
||||||
|
<circle class="st1" cx="237.9" cy="464.4" r="37.5"/>
|
||||||
|
<circle class="st1" cx="237.9" cy="611.3" r="37.5"/>
|
||||||
|
<circle class="st1" cx="311.4" cy="537.9" r="37.5"/>
|
||||||
|
<ellipse class="st1" cx="164.5" cy="537.9" rx="37.5" ry="37.5"/>
|
||||||
|
<path class="st1" d="M269.1,689.9h45c4.9,0,8.9,4,8.9,8.9v45c0,4.9-4,8.9-8.9,8.9h-45c-4.9,0-8.9-4-8.9-8.9v-45
|
||||||
|
C260.2,693.9,264.2,689.9,269.1,689.9z"/>
|
||||||
|
<circle class="st1" cx="291.6" cy="721.3" r="19.4"/>
|
||||||
|
<path class="st1" d="M234.6,187.1v12.3c0,3-2.2,5.5-5.2,5.9c-25.2,3.7-45,23.5-48.7,48.7c-0.4,2.9-2.9,5.1-5.9,5.2h-12.3
|
||||||
|
C164.3,220.1,195.5,188.9,234.6,187.1z"/>
|
||||||
|
<path class="st1" d="M234.6,325.6v12.3c-39.1-1.7-70.3-33-72.1-72h12.3c3,0,5.5,2.2,5.9,5.2c3.7,25.2,23.5,45,48.7,48.7
|
||||||
|
C232.4,320.1,234.6,322.6,234.6,325.6z"/>
|
||||||
|
<path class="st1" d="M313.3,265.9c-1.7,39.1-33,70.3-72.1,72v-12.3c0-3,2.2-5.5,5.2-5.9c25.2-3.7,45-23.5,48.7-48.7
|
||||||
|
c0.4-2.9,2.9-5.1,5.9-5.2L313.3,265.9z"/>
|
||||||
|
<path class="st1" d="M313.3,259.2H301c-3,0-5.5-2.2-5.9-5.2c-3.7-25.2-23.5-45-48.7-48.7c-2.9-0.4-5.1-2.9-5.2-5.9v-12.3
|
||||||
|
C280.3,188.9,311.6,220.1,313.3,259.2z"/>
|
||||||
|
<path class="st1" d="M313.4,262.5c0,1.1,0,2.2-0.1,3.3H301c-3,0-5.5,2.2-5.9,5.2c-3.7,25.2-23.5,45-48.7,48.7
|
||||||
|
c-2.9,0.4-5.1,2.9-5.2,5.9v12.3c-1.1,0.1-2.2,0.1-3.3,0.1s-2.2,0-3.3-0.1v-12.3c0-3-2.2-5.5-5.2-5.9c-25.2-3.7-45-23.5-48.7-48.7
|
||||||
|
c-0.4-2.9-2.9-5.1-5.9-5.2h-12.3c-0.1-1.1-0.1-2.2-0.1-3.3s0-2.2,0.1-3.3h12.3c3,0,5.5-2.2,5.9-5.2c3.7-25.2,23.5-45,48.7-48.7
|
||||||
|
c2.9-0.4,5.1-2.9,5.2-5.9v-12.3c1.1-0.1,2.2-0.1,3.3-0.1s2.2,0,3.3,0.1v12.3c0,3,2.2,5.5,5.2,5.9c25.2,3.7,45,23.5,48.7,48.7
|
||||||
|
c0.4,2.9,2.9,5.1,5.9,5.2h12.3C313.4,260.3,313.4,261.4,313.4,262.5z"/>
|
||||||
|
</g>
|
||||||
|
<path class="st2" d="M413.1,906.6h-7.9c-3.6,0-6.4-2.9-6.5-6.5V71.2c0-3.6,2.9-6.4,6.5-6.5h7.9c3.6,0,6.4,2.9,6.5,6.5V207
|
||||||
|
c0,4.9-1.2,9.6-3.4,14l-6.7,13v79.2l6.7,13c2.2,4.3,3.4,9.1,3.4,13.9v269.7c0,4.9-1.2,9.6-3.4,14l-6.7,13V716l6.7,13
|
||||||
|
c2.2,4.3,3.4,9.1,3.4,13.9v157.2C419.6,903.7,416.7,906.6,413.1,906.6z M405.2,65.7c-3,0-5.5,2.4-5.5,5.5v828.9c0,3,2.4,5.5,5.5,5.5
|
||||||
|
h7.9c3,0,5.5-2.4,5.5-5.5V742.9c0-4.7-1.1-9.3-3.3-13.5l-6.8-13.1c0-0.1-0.1-0.2-0.1-0.2v-79.5c0-0.1,0-0.2,0.1-0.2l6.8-13.1
|
||||||
|
c2.2-4.2,3.3-8.8,3.3-13.5V340.1c0-4.7-1.1-9.3-3.3-13.5l-6.8-13.1c0-0.1-0.1-0.2-0.1-0.2v-79.5c0-0.1,0-0.2,0.1-0.2l6.8-13.1
|
||||||
|
c2.2-4.2,3.3-8.8,3.3-13.5V71.2c0-3-2.4-5.5-5.5-5.5H405.2z"/>
|
||||||
|
<path class="st2" d="M399.3,858.9h-11.2c-0.3,0-0.5-0.2-0.5-0.5V72c0-0.3,0.2-0.5,0.5-0.5h11.2c0.3,0,0.5,0.2,0.5,0.5v786.4
|
||||||
|
C399.8,858.7,399.6,858.9,399.3,858.9z M388.6,857.9h10.2V72.5h-10.2V857.9z"/>
|
||||||
|
<path class="st2" d="M382.1,1000H275.9C158.9,1000,64,905.2,64,788.1l0,0V220.9C64,104.1,159.1,9.1,275.9,9.1h106.2
|
||||||
|
c3.6,0,6.5,2.9,6.5,6.5v978C388.6,997.1,385.7,1000,382.1,1000z M275.9,10.1C159.6,10.1,65,104.7,65,220.9v567.2
|
||||||
|
C65,904.4,159.6,999,275.9,999h106.2c3,0,5.5-2.4,5.5-5.5v-978c0-3-2.4-5.5-5.5-5.5H275.9V10.1z"/>
|
||||||
|
<polygon class="st1" points="237.9,448.9 225.8,469.9 250,469.9 "/>
|
||||||
|
<polygon class="st1" points="237.9,626.9 225.8,605.9 250,605.9 "/>
|
||||||
|
<polygon class="st1" points="148.9,537.9 169.9,550 169.9,525.8 "/>
|
||||||
|
<polygon class="st1" points="326.9,537.9 305.9,550 305.9,525.8 "/>
|
||||||
|
<path class="st1" d="M413.1,717.1h-4.2c-0.6,0-1-0.4-1-1l0,0v-79.5c0-0.6,0.4-1,1-1l0,0h4.2c3.8,0,6.9,3.1,7,7v67.6
|
||||||
|
C420.1,714,417,717.1,413.1,717.1z M409.9,715.1h3.2c2.7,0,5-2.2,5-5v-67.6c0-2.7-2.2-5-5-5h-3.2V715.1z"/>
|
||||||
|
<path class="st1" d="M413.1,314.3h-4.2c-0.6,0-1-0.4-1-1v-79.5c0-0.6,0.4-1,1-1h4.2c3.8,0,6.9,3.1,7,7v67.6
|
||||||
|
C420.1,311.2,417,314.3,413.1,314.3z M409.9,312.3h3.2c2.7,0,5-2.2,5-5v-67.6c0-2.7-2.2-5-5-5h-3.2V312.3z"/>
|
||||||
|
<path class="st1" d="M81.3,139.3c-0.3,0-0.5-0.1-0.7-0.3l-3.4-3.4c-2-2-2.6-5.1-1.5-7.8C110.5,50.1,187.7,0.1,272.9,0h51.2
|
||||||
|
c3.8,0,6.9,3.1,7,7v2.6c0,0.6-0.4,1-1,1h-54.2C191.4,10.5,115.1,61,82.2,138.7c-0.1,0.3-0.4,0.5-0.7,0.6
|
||||||
|
C81.4,139.3,81.3,139.3,81.3,139.3z M272.9,2C188.5,2.1,112,51.7,77.5,128.7c-0.8,1.9-0.4,4.1,1.1,5.5l2.4,2.4
|
||||||
|
C114.6,58.8,191.3,8.5,276,8.6h53.2V7c0-2.7-2.2-5-5-5H272.9z"/>
|
||||||
|
<path class="st1" d="M359.6,116.1h-46.9c-2.2,0-4-1.8-4-4v-11.7c0-2.2,1.8-4,4-4h46.9c2.2,0,4,1.8,4,4v11.7
|
||||||
|
C363.6,114.3,361.8,116.1,359.6,116.1z M312.7,98.5c-1.1,0-2,0.9-2,2v11.7c0,1.1,0.9,2,2,2h46.9c1.1,0,2-0.9,2-2v-11.7
|
||||||
|
c0-1.1-0.9-2-2-2H312.7z"/>
|
||||||
|
<path class="st1" d="M237.9,502.9c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C276.4,485.7,259.2,502.9,237.9,502.9z M237.9,428c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5S258.1,428,237.9,428z"/>
|
||||||
|
<path class="st1" d="M237.9,649.8c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
S259.2,649.8,237.9,649.8z M237.9,574.9c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5l0,0
|
||||||
|
C274.4,591.2,258.1,574.9,237.9,574.9z"/>
|
||||||
|
<path class="st1" d="M311.4,576.3c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5l0,0
|
||||||
|
C349.8,559.1,332.6,576.3,311.4,576.3z M311.4,501.4c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5c20.1,0,36.5-16.3,36.5-36.5
|
||||||
|
l0,0C347.8,517.7,331.5,501.4,311.4,501.4L311.4,501.4z"/>
|
||||||
|
<path class="st1" d="M164.5,576.3c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5l0,0
|
||||||
|
C202.9,559.1,185.7,576.3,164.5,576.3z M164.5,501.4c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5l0,0C200.9,517.7,184.6,501.4,164.5,501.4L164.5,501.4z"/>
|
||||||
|
<path class="st1" d="M314.1,753.7h-45c-5.5,0-9.9-4.4-9.9-9.9v-45c0-5.5,4.4-9.9,9.9-9.9h45c5.5,0,9.9,4.4,9.9,9.9v45
|
||||||
|
C324,749.3,319.5,753.7,314.1,753.7z M269.1,690.9c-4.4,0-7.9,3.6-7.9,7.9v45c0,4.4,3.6,7.9,7.9,7.9h45c4.4,0,7.9-3.6,7.9-7.9v-45
|
||||||
|
c0-4.4-3.6-7.9-7.9-7.9H269.1z"/>
|
||||||
|
<path class="st1" d="M291.6,741.7c-11.3,0-20.4-9.2-20.4-20.4c0-11.3,9.2-20.4,20.4-20.4c11.3,0,20.4,9.2,20.4,20.4l0,0
|
||||||
|
C312,732.6,302.9,741.7,291.6,741.7z M291.6,702.8c-10.2,0-18.4,8.3-18.4,18.4s8.3,18.4,18.4,18.4c10.2,0,18.4-8.3,18.4-18.4
|
||||||
|
S301.8,702.9,291.6,702.8z"/>
|
||||||
|
<path class="st1" d="M174.8,260.2h-12.3c-0.6,0-1-0.4-1-1l0,0c1.7-39.6,33.4-71.3,73-73c0.3,0,0.5,0.1,0.7,0.3s0.3,0.4,0.3,0.7v12.3
|
||||||
|
c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9C181.2,257.6,178.3,260.2,174.8,260.2z M163.6,258.2h11.2c2.5,0,4.6-1.8,4.9-4.3
|
||||||
|
c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-11.2C196.2,190.3,165.7,220.8,163.6,258.2L163.6,258.2z"/>
|
||||||
|
<path class="st1" d="M234.6,338.9L234.6,338.9c-39.6-1.7-71.3-33.4-73-73c0-0.6,0.4-1,1-1l0,0h12.3c3.5,0,6.4,2.6,6.9,6
|
||||||
|
c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9V338C235.6,338.5,235.1,338.9,234.6,338.9L234.6,338.9z M163.6,266.9
|
||||||
|
c2.2,37.4,32.6,67.8,70,70v-11.2c0-2.5-1.8-4.6-4.3-4.9c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3H163.6z"/>
|
||||||
|
<path class="st1" d="M241.3,338.9c-0.6,0-1-0.4-1-1v-12.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6
|
||||||
|
h12.3c0.6,0,1,0.4,1,1l0,0C312.6,305.5,280.9,337.2,241.3,338.9L241.3,338.9z M301,266.9c-2.5,0-4.6,1.8-4.9,4.3
|
||||||
|
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v11.2c37.4-2.2,67.8-32.6,70-70H301z"/>
|
||||||
|
<path class="st1" d="M313.3,260.2H301c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-12.3
|
||||||
|
c0-0.3,0.1-0.5,0.3-0.7s0.5-0.3,0.7-0.3c39.6,1.7,71.3,33.4,73,73C314.3,259.7,313.9,260.2,313.3,260.2L313.3,260.2L313.3,260.2z
|
||||||
|
M242.3,188.2v11.2c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h11.2
|
||||||
|
C310.1,220.8,279.6,190.3,242.3,188.2L242.3,188.2z"/>
|
||||||
|
<path class="st1" d="M237.9,339c-1.2,0-2.3,0-3.4-0.1c-0.5,0-0.9-0.5-0.9-1v-12.3c0-2.5-1.8-4.6-4.3-4.9
|
||||||
|
c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-12.3c-0.5,0-1-0.4-1-0.9c-0.1-1.1-0.1-2.2-0.1-3.4s0-2.3,0.1-3.4
|
||||||
|
c0-0.5,0.5-0.9,1-0.9h12.3c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-12.3c0-0.5,0.4-1,0.9-1
|
||||||
|
c2.3-0.1,4.5-0.1,6.8,0c0.5,0,0.9,0.5,0.9,1v12.3c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h12.3
|
||||||
|
c0.5,0,1,0.4,1,0.9c0.1,1.1,0.1,2.2,0.1,3.4s0,2.3-0.1,3.4c0,0.5-0.5,0.9-1,0.9H301c-2.5,0-4.6,1.8-4.9,4.3
|
||||||
|
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v12.3c0,0.5-0.4,1-0.9,1C240.2,339,239.1,339,237.9,339z M235.6,337
|
||||||
|
c1.5,0.1,3.1,0.1,4.7,0v-11.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6h11.3c0-0.8,0-1.5,0-2.3
|
||||||
|
s0-1.6,0-2.3H301c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-11.3c-1.5-0.1-3.1-0.1-4.7,0v11.3
|
||||||
|
c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-11.3c0,0.8,0,1.5,0,2.3s0,1.6,0,2.3h11.3
|
||||||
|
c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9L235.6,337z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 9.2 KiB |
218
Ryujinx/Ui/assets/JoyConPair.svg
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 1000.8 1000" style="enable-background:new 0 0 1000.8 1000;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{opacity:0.1;}
|
||||||
|
.st1{fill:#02C5E5;}
|
||||||
|
.st2{fill:#FF5F55;}
|
||||||
|
.st3{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g class="st0">
|
||||||
|
<path class="st1" d="M419.1,642.6v67.6c0,3.3-2.7,6-6,6h-4.2v-79.5h4.2C416.4,636.6,419.1,639.3,419.1,642.6z"/>
|
||||||
|
<path class="st1" d="M419.1,239.8v67.6c0,3.3-2.7,6-6,6h-4.2v-79.5h4.2C416.4,233.9,419.1,236.5,419.1,239.8z"/>
|
||||||
|
<path class="st1" d="M330.1,7v2.6h-54.2c-84.8,0-161.4,50.7-194.6,128.7l-3.4-3.4c-1.8-1.7-2.3-4.4-1.3-6.6
|
||||||
|
C111.2,50.8,188.1,1,272.9,1h51.2C327.4,1,330.1,3.7,330.1,7z"/>
|
||||||
|
<path class="st1" d="M359.6,115.1h-46.9c-1.6,0-3-1.3-3-3v-11.7c0-1.6,1.3-3,3-3h46.9c1.6,0,3,1.3,3,3v11.7
|
||||||
|
C362.6,113.8,361.3,115.1,359.6,115.1z"/>
|
||||||
|
<circle class="st1" cx="237.9" cy="464.4" r="37.5"/>
|
||||||
|
<circle class="st1" cx="237.9" cy="611.3" r="37.5"/>
|
||||||
|
<circle class="st1" cx="311.4" cy="537.9" r="37.5"/>
|
||||||
|
|
||||||
|
<ellipse transform="matrix(0.9951 -9.853756e-02 9.853756e-02 0.9951 -52.201 18.8252)" class="st1" cx="164.5" cy="537.9" rx="37.5" ry="37.5"/>
|
||||||
|
<path class="st1" d="M269.1,689.9h45c4.9,0,8.9,4,8.9,8.9v45c0,4.9-4,8.9-8.9,8.9h-45c-4.9,0-8.9-4-8.9-8.9v-45
|
||||||
|
C260.2,693.9,264.2,689.9,269.1,689.9z"/>
|
||||||
|
<circle class="st1" cx="291.6" cy="721.3" r="19.4"/>
|
||||||
|
<path class="st1" d="M234.6,187.1v12.3c0,3-2.2,5.5-5.2,5.9c-25.2,3.7-45,23.5-48.7,48.7c-0.4,2.9-2.9,5.1-5.9,5.2h-12.3
|
||||||
|
C164.3,220.1,195.5,188.9,234.6,187.1z"/>
|
||||||
|
<path class="st1" d="M234.6,325.6v12.3c-39.1-1.7-70.3-33-72.1-72h12.3c3,0,5.5,2.2,5.9,5.2c3.7,25.2,23.5,45,48.7,48.7
|
||||||
|
C232.4,320.1,234.6,322.6,234.6,325.6z"/>
|
||||||
|
<path class="st1" d="M313.3,265.9c-1.7,39.1-33,70.3-72.1,72v-12.3c0-3,2.2-5.5,5.2-5.9c25.2-3.7,45-23.5,48.7-48.7
|
||||||
|
c0.4-2.9,2.9-5.1,5.9-5.2L313.3,265.9z"/>
|
||||||
|
<path class="st1" d="M313.3,259.2H301c-3,0-5.5-2.2-5.9-5.2c-3.7-25.2-23.5-45-48.7-48.7c-2.9-0.4-5.1-2.9-5.2-5.9v-12.3
|
||||||
|
C280.3,188.9,311.6,220.1,313.3,259.2z"/>
|
||||||
|
<path class="st1" d="M313.4,262.5c0,1.1,0,2.2-0.1,3.3H301c-3,0-5.5,2.2-5.9,5.2c-3.7,25.2-23.5,45-48.7,48.7
|
||||||
|
c-2.9,0.4-5.1,2.9-5.2,5.9v12.3c-1.1,0.1-2.2,0.1-3.3,0.1s-2.2,0-3.3-0.1v-12.3c0-3-2.2-5.5-5.2-5.9c-25.2-3.7-45-23.5-48.7-48.7
|
||||||
|
c-0.4-2.9-2.9-5.1-5.9-5.2h-12.3c-0.1-1.1-0.1-2.2-0.1-3.3s0-2.2,0.1-3.3h12.3c3,0,5.5-2.2,5.9-5.2c3.7-25.2,23.5-45,48.7-48.7
|
||||||
|
c2.9-0.4,5.1-2.9,5.2-5.9v-12.3c1.1-0.1,2.2-0.1,3.3-0.1s2.2,0,3.3,0.1v12.3c0,3,2.2,5.5,5.2,5.9c25.2,3.7,45,23.5,48.7,48.7
|
||||||
|
c0.4,2.9,2.9,5.1,5.9,5.2h12.3C313.4,260.3,313.4,261.4,313.4,262.5z"/>
|
||||||
|
</g>
|
||||||
|
<g class="st0">
|
||||||
|
<path class="st2" d="M597.9,233.9v79.5h-4.2c-3.3,0-6-2.7-6-6v-67.6c0-3.3,2.7-6,6-6H597.9z"/>
|
||||||
|
<path class="st2" d="M597.9,636.6v79.5h-4.2c-3.3,0-6-2.7-6-6v-67.6c0-3.3,2.7-6,6-6H597.9z"/>
|
||||||
|
<path class="st2" d="M929,134.9l-3.4,3.4C892.4,60.3,815.8,9.6,730.9,9.6h-54.2V7c0-3.3,2.7-6,6-6c0,0,0,0,0,0h51.2
|
||||||
|
c84.8,0,161.7,49.8,196.4,127.2C931.3,130.5,930.8,133.1,929,134.9z"/>
|
||||||
|
<path class="st2" d="M679.5,94.5V82.8c0-1.6-1.3-3-3-3l0,0h-11.7c-1.6,0-3,1.3-3,3c0,0,0,0,0,0v11.7c0,1.6-1.3,3-3,3l0,0h-11.7
|
||||||
|
c-1.6,0-3,1.3-3,3c0,0,0,0,0,0v11.7c0,1.6,1.3,3,3,3l0,0h11.7c1.6,0,3,1.3,3,3c0,0,0,0,0,0v11.7c0,1.6,1.3,3,3,3l0,0h11.7
|
||||||
|
c1.6,0,3-1.3,3-3v0v-11.7c0-1.6,1.3-3,3-3l0,0h11.7c1.6,0,3-1.3,3-3c0,0,0,0,0,0v-11.7c0-1.6-1.3-3-3-3l0,0h-11.7
|
||||||
|
C680.8,97.5,679.5,96.1,679.5,94.5C679.5,94.5,679.5,94.5,679.5,94.5z"/>
|
||||||
|
<circle class="st2" cx="768.9" cy="333.9" r="37.5"/>
|
||||||
|
<circle class="st2" cx="768.9" cy="187.1" r="37.5"/>
|
||||||
|
<circle class="st2" cx="842.3" cy="260.5" r="37.5"/>
|
||||||
|
<circle class="st2" cx="695.5" cy="260.5" r="37.5"/>
|
||||||
|
<circle class="st2" cx="715" cy="721.3" r="27.9"/>
|
||||||
|
<path class="st2" d="M765.6,460.3v12.3c0,3-2.2,5.5-5.2,5.9c-25.2,3.7-45,23.5-48.7,48.7c-0.4,2.9-2.9,5.1-5.9,5.2h-12.3
|
||||||
|
C695.2,493.3,726.5,462,765.6,460.3z"/>
|
||||||
|
<path class="st2" d="M765.6,598.8v12.3c-39.1-1.7-70.3-33-72.1-72h12.3c3,0,5.5,2.2,5.9,5.2c3.7,25.2,23.5,45,48.7,48.7
|
||||||
|
C763.4,593.3,765.6,595.8,765.6,598.8z"/>
|
||||||
|
<path class="st2" d="M844.3,539c-1.7,39.1-33,70.3-72.1,72v-12.3c0-3,2.2-5.5,5.2-5.9c25.2-3.7,45-23.5,48.7-48.7
|
||||||
|
c0.4-2.9,2.9-5.1,5.9-5.2L844.3,539z"/>
|
||||||
|
<path class="st2" d="M844.3,532.4H832c-3,0-5.5-2.2-5.9-5.2c-3.7-25.2-23.5-45-48.7-48.7c-2.9-0.4-5.1-2.9-5.2-5.9v-12.3
|
||||||
|
C811.3,462,842.6,493.3,844.3,532.4z"/>
|
||||||
|
<path class="st2" d="M844.4,535.7c0,1.1,0,2.2-0.1,3.3H832c-3,0-5.5,2.2-5.9,5.2c-3.7,25.2-23.5,45-48.7,48.7
|
||||||
|
c-2.9,0.4-5.1,2.9-5.2,5.9v12.3c-1.1,0.1-2.2,0.1-3.3,0.1s-2.2,0-3.3-0.1v-12.3c0-3-2.2-5.5-5.2-5.9c-25.2-3.7-45-23.5-48.7-48.7
|
||||||
|
c-0.4-2.9-2.9-5.1-5.9-5.2h-12.3c-0.1-1.1-0.1-2.2-0.1-3.3s0-2.2,0.1-3.3h12.3c3,0,5.5-2.2,5.9-5.2c3.7-25.2,23.5-45,48.7-48.7
|
||||||
|
c2.9-0.4,5.1-2.9,5.2-5.9v-12.3c1.1-0.1,2.2-0.1,3.3-0.1s2.2,0,3.3,0.1v12.3c0,3,2.2,5.5,5.2,5.9c25.2,3.7,45,23.5,48.7,48.7
|
||||||
|
c0.4,2.9,2.9,5.1,5.9,5.2h12.3C844.3,533.5,844.4,534.6,844.4,535.7z"/>
|
||||||
|
</g>
|
||||||
|
<path class="st3" d="M413.1,906.6h-7.9c-3.6,0-6.4-2.9-6.5-6.5V71.2c0-3.6,2.9-6.4,6.5-6.5h7.9c3.6,0,6.4,2.9,6.5,6.5V207
|
||||||
|
c0,4.9-1.2,9.6-3.4,14l-6.7,13v79.2l6.7,13c2.2,4.3,3.4,9.1,3.4,13.9v269.7c0,4.9-1.2,9.6-3.4,14l-6.7,13V716l6.7,13
|
||||||
|
c2.2,4.3,3.4,9.1,3.4,13.9v157.2C419.6,903.7,416.7,906.6,413.1,906.6z M405.2,65.7c-3,0-5.5,2.4-5.5,5.5v828.9c0,3,2.4,5.5,5.5,5.5
|
||||||
|
h7.9c3,0,5.5-2.4,5.5-5.5V742.9c0-4.7-1.1-9.3-3.3-13.5l-6.8-13.1c0-0.1-0.1-0.2-0.1-0.2v-79.5c0-0.1,0-0.2,0.1-0.2l6.8-13.1
|
||||||
|
c2.2-4.2,3.3-8.8,3.3-13.5V340.1c0-4.7-1.1-9.3-3.3-13.5l-6.8-13.1c0-0.1-0.1-0.2-0.1-0.2v-79.5c0-0.1,0-0.2,0.1-0.2l6.8-13.1
|
||||||
|
c2.2-4.2,3.3-8.8,3.3-13.5V71.2c0-3-2.4-5.5-5.5-5.5L405.2,65.7z"/>
|
||||||
|
<path class="st3" d="M399.3,858.9h-11.2c-0.3,0-0.5-0.2-0.5-0.5V72c0-0.3,0.2-0.5,0.5-0.5h11.2c0.3,0,0.5,0.2,0.5,0.5v786.4
|
||||||
|
C399.8,858.7,399.6,858.9,399.3,858.9z M388.6,857.9h10.2V72.5h-10.2V857.9z"/>
|
||||||
|
<path class="st3" d="M382.1,1000H275.9C158.9,1000,64,905.2,64,788.1c0,0,0,0,0,0V220.9C64,104.1,159.1,9.1,275.9,9.1h106.2
|
||||||
|
c3.6,0,6.5,2.9,6.5,6.5v978C388.6,997.1,385.7,1000,382.1,1000z M275.9,10.1C159.6,10.1,65,104.7,65,220.9v567.2
|
||||||
|
C65,904.4,159.6,999,275.9,999h106.2c3,0,5.5-2.4,5.5-5.5v-978c0-3-2.4-5.5-5.5-5.5H275.9z"/>
|
||||||
|
<path class="st3" d="M601.6,906.6h-7.9c-3.6,0-6.4-2.9-6.5-6.5V742.9c0-4.9,1.2-9.6,3.4-13.9l6.7-13v-79.2l-6.7-13
|
||||||
|
c-2.2-4.3-3.4-9.1-3.4-14V340.1c0-4.9,1.2-9.6,3.4-13.9l6.7-13V234l-6.7-13c-2.2-4.3-3.4-9.1-3.4-14V71.2c0-3.6,2.9-6.4,6.5-6.5h7.9
|
||||||
|
c3.6,0,6.4,2.9,6.5,6.5v828.9C608,903.7,605.1,906.6,601.6,906.6z M593.7,65.7c-3,0-5.5,2.4-5.5,5.5V207c0,4.7,1.1,9.3,3.3,13.5
|
||||||
|
l6.8,13.1c0,0.1,0.1,0.1,0.1,0.2v79.5c0,0.1,0,0.2-0.1,0.2l-6.8,13.1c-2.2,4.2-3.3,8.8-3.3,13.5v269.7c0,4.7,1.1,9.3,3.3,13.5
|
||||||
|
l6.8,13.1c0,0.1,0.1,0.1,0.1,0.2v79.5c0,0.1,0,0.2-0.1,0.2l-6.8,13.1c-2.2,4.2-3.3,8.8-3.3,13.5v157.2c0,3,2.4,5.5,5.5,5.5h7.9
|
||||||
|
c3,0,5.5-2.4,5.5-5.5V71.2c0-3-2.4-5.5-5.5-5.5L593.7,65.7z"/>
|
||||||
|
<path class="st3" d="M618.8,858.9h-11.3c-0.3,0-0.5-0.2-0.5-0.5c0,0,0,0,0,0V72c0-0.3,0.2-0.5,0.5-0.5h11.3c0.3,0,0.5,0.2,0.5,0.5
|
||||||
|
v786.4C619.3,858.7,619.1,858.9,618.8,858.9C618.8,858.9,618.8,858.9,618.8,858.9z M608,857.9h10.3V72.5H608V857.9z"/>
|
||||||
|
<path class="st3" d="M730.9,1000H624.7c-3.6,0-6.5-2.9-6.5-6.5v-978c0-3.6,2.9-6.5,6.5-6.5h106.2c116.8,0,211.9,95.1,211.9,211.9
|
||||||
|
v567.2C942.8,905.1,848,1000,730.9,1000C730.9,1000,730.9,1000,730.9,1000z M624.7,10.1c-3,0-5.5,2.4-5.5,5.5v978
|
||||||
|
c0,3,2.4,5.5,5.5,5.5h106.2c116.3,0,210.9-94.6,210.9-210.9V220.9c0-116.3-94.6-210.9-210.9-210.9L624.7,10.1z"/>
|
||||||
|
<path class="st3" d="M715,763.2c-23.1,0-41.9-18.7-41.9-41.9s18.7-41.9,41.9-41.9s41.9,18.7,41.9,41.9l0,0
|
||||||
|
C756.8,744.4,738.1,763.1,715,763.2z M715,680.4c-22.6,0-40.9,18.3-40.9,40.9c0,22.6,18.3,40.9,40.9,40.9
|
||||||
|
c22.6,0,40.9-18.3,40.9-40.9v0C755.8,698.7,737.6,680.4,715,680.4z"/>
|
||||||
|
<polygon class="st1" points="237.9,448.9 225.8,469.9 250,469.9 "/>
|
||||||
|
<polygon class="st1" points="237.9,626.9 225.8,605.9 250,605.9 "/>
|
||||||
|
<polygon class="st1" points="148.9,537.9 169.9,550 169.9,525.8 "/>
|
||||||
|
<polygon class="st1" points="326.9,537.9 305.9,550 305.9,525.8 "/>
|
||||||
|
<path class="st2" d="M782.2,203.2h-5.5l-7.8-12.9l-7.8,12.9h-5.4l10.6-16.3l-9.8-15.6h5.2l7.3,12l7.4-12h5l-9.8,15.4L782.2,203.2z"
|
||||||
|
/>
|
||||||
|
<path class="st2" d="M709.2,244.5l-11.6,20.6v11.4h-4.4V265l-11.6-20.5h5.3l6.4,11.7l2.3,4.7l2.2-4.3l6.4-12.1L709.2,244.5z"/>
|
||||||
|
<path class="st2" d="M855.9,276.5h-4.7l-2.2-7h-13.3l-2.3,7h-4.5l10.6-32h6L855.9,276.5z M847.7,265.6l-5.4-17.1l-5.4,17.1
|
||||||
|
L847.7,265.6z"/>
|
||||||
|
<path class="st2" d="M779.4,340.4c0,1.4-0.3,2.8-0.9,4.1c-0.6,1.2-1.5,2.2-2.5,3c-1.2,0.9-2.6,1.5-4,1.9c-1.7,0.4-3.4,0.7-5.2,0.6
|
||||||
|
h-8.4v-32h9.2c7.1,0,10.7,2.6,10.7,7.8c0,1.6-0.4,3.1-1.2,4.5c-1,1.4-2.4,2.3-4,2.8c0.9,0.2,1.7,0.4,2.5,0.8c0.8,0.4,1.5,0.9,2,1.5
|
||||||
|
c0.6,0.6,1.1,1.4,1.4,2.2C779.2,338.4,779.4,339.4,779.4,340.4z M773.7,326.3c0-0.6-0.1-1.3-0.3-1.8c-0.2-0.6-0.6-1.1-1-1.5
|
||||||
|
c-0.6-0.5-1.3-0.8-2-1c-1-0.3-2.1-0.4-3.2-0.4h-4.5v10h4.4c0.9,0,1.8-0.1,2.7-0.3c0.8-0.2,1.5-0.5,2.1-1c0.6-0.4,1-1,1.3-1.7
|
||||||
|
C773.6,327.9,773.7,327.1,773.7,326.3L773.7,326.3z M774.8,340.5c0-0.8-0.2-1.5-0.5-2.2c-0.4-0.7-0.9-1.2-1.5-1.7
|
||||||
|
c-0.7-0.5-1.5-0.8-2.4-1c-1-0.3-2.1-0.4-3.2-0.4h-4.5v11h4.6c2.5,0,4.4-0.5,5.6-1.4C774.2,343.8,774.9,342.2,774.8,340.5
|
||||||
|
L774.8,340.5z"/>
|
||||||
|
<path class="st2" d="M715,701.3L695.4,721h5.6v16.8h28.2V721h5.3L715,701.3z M720.7,731.8h-11.1V721h11.1V731.8z"/>
|
||||||
|
<path class="st1" d="M413.1,717.1h-4.2c-0.6,0-1-0.4-1-1c0,0,0,0,0,0v-79.5c0-0.6,0.4-1,1-1c0,0,0,0,0,0h4.2c3.8,0,6.9,3.1,7,7v67.6
|
||||||
|
C420.1,714,417,717.1,413.1,717.1z M409.9,715.1h3.2c2.7,0,5-2.2,5-5v-67.6c0-2.7-2.2-5-5-5h-3.2V715.1z"/>
|
||||||
|
<path class="st1" d="M413.1,314.3h-4.2c-0.6,0-1-0.4-1-1v-79.5c0-0.6,0.4-1,1-1h4.2c3.8,0,6.9,3.1,7,7v67.6
|
||||||
|
C420.1,311.2,417,314.3,413.1,314.3z M409.9,312.3h3.2c2.7,0,5-2.2,5-5v-67.6c0-2.7-2.2-5-5-5h-3.2V312.3z"/>
|
||||||
|
<path class="st1" d="M81.3,139.3c-0.3,0-0.5-0.1-0.7-0.3l-3.4-3.4c-2-2-2.6-5.1-1.5-7.8C110.5,50.1,187.7,0.1,272.9,0h51.2
|
||||||
|
c3.8,0,6.9,3.1,7,7v2.6c0,0.6-0.4,1-1,1h-54.2C191.4,10.5,115.1,61,82.2,138.7c-0.1,0.3-0.4,0.5-0.7,0.6
|
||||||
|
C81.4,139.3,81.3,139.3,81.3,139.3z M272.9,2C188.5,2.1,112,51.7,77.5,128.7c-0.8,1.9-0.4,4.1,1.1,5.5l2.4,2.4
|
||||||
|
c33.6-77.8,110.3-128.1,195-128h53.2V7c0-2.7-2.2-5-5-5L272.9,2z"/>
|
||||||
|
<path class="st1" d="M359.6,116.1h-46.9c-2.2,0-4-1.8-4-4v-11.7c0-2.2,1.8-4,4-4h46.9c2.2,0,4,1.8,4,4v11.7
|
||||||
|
C363.6,114.3,361.8,116.1,359.6,116.1z M312.7,98.5c-1.1,0-2,0.9-2,2v11.7c0,1.1,0.9,2,2,2h46.9c1.1,0,2-0.9,2-2v-11.7
|
||||||
|
c0-1.1-0.9-2-2-2H312.7z"/>
|
||||||
|
<path class="st1" d="M237.9,502.9c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C276.4,485.7,259.2,502.9,237.9,502.9z M237.9,428c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C274.4,444.3,258.1,428,237.9,428z"/>
|
||||||
|
<path class="st1" d="M237.9,649.8c-21.2,0-38.5-17.2-38.5-38.5s17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C276.4,632.6,259.2,649.8,237.9,649.8z M237.9,574.9c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5s36.5-16.3,36.5-36.5
|
||||||
|
c0,0,0,0,0,0C274.4,591.2,258.1,574.9,237.9,574.9z"/>
|
||||||
|
<path class="st1" d="M311.4,576.3c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5l0,0
|
||||||
|
C349.8,559.1,332.6,576.3,311.4,576.3z M311.4,501.4c-20.1,0-36.5,16.3-36.5,36.5s16.3,36.5,36.5,36.5c20.1,0,36.5-16.3,36.5-36.5
|
||||||
|
c0,0,0,0,0,0C347.8,517.7,331.5,501.4,311.4,501.4L311.4,501.4z"/>
|
||||||
|
<path class="st1" d="M164.5,576.3c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5s38.5,17.2,38.5,38.5l0,0
|
||||||
|
C202.9,559.1,185.7,576.3,164.5,576.3z M164.5,501.4c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5c0,0,0,0,0,0C200.9,517.7,184.6,501.4,164.5,501.4L164.5,501.4z"/>
|
||||||
|
<path class="st1" d="M314.1,753.7h-45c-5.5,0-9.9-4.4-9.9-9.9v-45c0-5.5,4.4-9.9,9.9-9.9h45c5.5,0,9.9,4.4,9.9,9.9v45
|
||||||
|
C324,749.3,319.5,753.7,314.1,753.7z M269.1,690.9c-4.4,0-7.9,3.6-7.9,7.9v45c0,4.4,3.6,7.9,7.9,7.9h45c4.4,0,7.9-3.6,7.9-7.9v-45
|
||||||
|
c0-4.4-3.6-7.9-7.9-7.9H269.1z"/>
|
||||||
|
<path class="st1" d="M291.6,741.7c-11.3,0-20.4-9.2-20.4-20.4c0-11.3,9.2-20.4,20.4-20.4c11.3,0,20.4,9.2,20.4,20.4c0,0,0,0,0,0
|
||||||
|
C312,732.6,302.9,741.7,291.6,741.7z M291.6,702.8c-10.2,0-18.4,8.3-18.4,18.4s8.3,18.4,18.4,18.4c10.2,0,18.4-8.3,18.4-18.4
|
||||||
|
C310,711.1,301.8,702.9,291.6,702.8z"/>
|
||||||
|
<path class="st1" d="M174.8,260.2h-12.3c-0.6,0-1-0.4-1-1c0,0,0,0,0,0c1.7-39.6,33.4-71.3,73-73c0.3,0,0.5,0.1,0.7,0.3
|
||||||
|
c0.2,0.2,0.3,0.4,0.3,0.7v12.3c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9C181.2,257.6,178.3,260.2,174.8,260.2z
|
||||||
|
M163.6,258.2h11.2c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-11.2
|
||||||
|
C196.2,190.3,165.7,220.8,163.6,258.2L163.6,258.2z"/>
|
||||||
|
<path class="st1" d="M234.6,338.9L234.6,338.9c-39.6-1.7-71.3-33.4-73-73c0-0.6,0.4-1,1-1c0,0,0,0,0,0h12.3c3.5,0,6.4,2.6,6.9,6
|
||||||
|
c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9v12.3C235.6,338.5,235.1,338.9,234.6,338.9L234.6,338.9z M163.6,266.9
|
||||||
|
c2.2,37.4,32.6,67.8,70,70v-11.2c0-2.5-1.8-4.6-4.3-4.9c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3L163.6,266.9z"/>
|
||||||
|
<path class="st1" d="M241.3,338.9c-0.6,0-1-0.4-1-1v-12.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6
|
||||||
|
h12.3c0.6,0,1,0.4,1,1c0,0,0,0,0,0C312.6,305.5,280.9,337.2,241.3,338.9L241.3,338.9z M301,266.9c-2.5,0-4.6,1.8-4.9,4.3
|
||||||
|
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v11.2c37.4-2.2,67.8-32.6,70-70L301,266.9z"/>
|
||||||
|
<path class="st1" d="M313.3,260.2H301c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-12.3
|
||||||
|
c0-0.3,0.1-0.5,0.3-0.7c0.2-0.2,0.5-0.3,0.7-0.3c39.6,1.7,71.3,33.4,73,73C314.3,259.7,313.9,260.2,313.3,260.2
|
||||||
|
C313.3,260.2,313.3,260.2,313.3,260.2L313.3,260.2z M242.3,188.2v11.2c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6
|
||||||
|
c0.3,2.5,2.4,4.3,4.9,4.3h11.2C310.1,220.8,279.6,190.3,242.3,188.2L242.3,188.2z"/>
|
||||||
|
<path class="st1" d="M237.9,339c-1.2,0-2.3,0-3.4-0.1c-0.5,0-0.9-0.5-0.9-1v-12.3c0-2.5-1.8-4.6-4.3-4.9
|
||||||
|
c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-12.3c-0.5,0-1-0.4-1-0.9c-0.1-1.1-0.1-2.2-0.1-3.4s0-2.3,0.1-3.4
|
||||||
|
c0-0.5,0.5-0.9,1-0.9h12.3c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-12.3c0-0.5,0.4-1,0.9-1
|
||||||
|
c2.3-0.1,4.5-0.1,6.8,0c0.5,0,0.9,0.5,0.9,1v12.3c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h12.3
|
||||||
|
c0.5,0,1,0.4,1,0.9c0.1,1.1,0.1,2.2,0.1,3.4s0,2.3-0.1,3.4c0,0.5-0.5,0.9-1,0.9H301c-2.5,0-4.6,1.8-4.9,4.3
|
||||||
|
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v12.3c0,0.5-0.4,1-0.9,1C240.2,339,239.1,339,237.9,339z M235.6,337
|
||||||
|
c1.5,0.1,3.1,0.1,4.7,0v-11.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6h11.3c0-0.8,0-1.5,0-2.3
|
||||||
|
s0-1.6,0-2.3H301c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-11.3c-1.5-0.1-3.1-0.1-4.7,0v11.3
|
||||||
|
c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-11.3c0,0.8,0,1.5,0,2.3s0,1.6,0,2.3h11.3
|
||||||
|
c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9L235.6,337z"/>
|
||||||
|
<path class="st2" d="M597.9,314.3h-4.2c-3.8,0-6.9-3.1-7-7v-67.6c0-3.8,3.1-6.9,7-7h4.2c0.6,0,1,0.4,1,1c0,0,0,0,0,0v79.5
|
||||||
|
C598.9,313.9,598.4,314.3,597.9,314.3C597.9,314.3,597.9,314.3,597.9,314.3z M593.7,234.8c-2.7,0-5,2.2-5,5v67.6c0,2.7,2.2,5,5,5
|
||||||
|
h3.2v-77.5H593.7z"/>
|
||||||
|
<path class="st2" d="M597.9,717.1h-4.2c-3.8,0-6.9-3.1-7-7v-67.6c0-3.8,3.1-6.9,7-7h4.2c0.6,0,1,0.4,1,1c0,0,0,0,0,0v79.5
|
||||||
|
C598.9,716.6,598.4,717.1,597.9,717.1C597.9,717.1,597.9,717.1,597.9,717.1z M593.7,637.6c-2.7,0-5,2.2-5,5v67.6c0,2.7,2.2,5,5,5
|
||||||
|
h3.2v-77.5H593.7z"/>
|
||||||
|
<path class="st2" d="M925.6,139.3c-0.1,0-0.1,0-0.2,0c-0.3-0.1-0.6-0.3-0.7-0.6C891.7,61,815.4,10.5,730.9,10.6h-54.2
|
||||||
|
c-0.6,0-1-0.4-1-1c0,0,0,0,0,0V7c0-3.8,3.1-6.9,7-7h51.2c85.2,0.1,162.4,50.1,197.3,127.8c1.2,2.6,0.6,5.7-1.5,7.8l-3.4,3.4
|
||||||
|
C926.1,139.2,925.8,139.3,925.6,139.3z M677.7,8.6h53.2c84.7-0.1,161.3,50.2,195,128l2.4-2.4l0,0c1.5-1.4,1.9-3.6,1.1-5.5
|
||||||
|
C894.8,51.7,818.3,2.1,733.9,2h-51.2c-2.7,0-5,2.2-5,5V8.6z"/>
|
||||||
|
<path class="st2" d="M676.5,133.7h-11.7c-2.2,0-4-1.8-4-4v-11.7c0-1.1-0.9-2-2-2h-11.7c-2.2,0-4-1.8-4-4v-11.7c0-2.2,1.8-4,4-4h11.7
|
||||||
|
c1.1,0,2-0.9,2-2V82.8c0-2.2,1.8-4,4-4h11.7c2.2,0,4,1.8,4,4v11.7c0,1.1,0.9,2,2,2h11.7c2.2,0,4,1.8,4,4v11.7c0,2.2-1.8,4-4,4h-11.7
|
||||||
|
c-1.1,0-2,0.9-2,2v11.7C680.5,131.9,678.7,133.7,676.5,133.7z M647.2,98.5c-1.1,0-2,0.9-2,2v11.7c0,1.1,0.9,2,2,2h11.7
|
||||||
|
c2.2,0,4,1.8,4,4v11.7c0,1.1,0.9,2,2,2h11.7c1.1,0,2-0.9,2-2v-11.7c0-2.2,1.8-4,4-4h11.7c1.1,0,2-0.9,2-2v-11.7c0-1.1-0.9-2-2-2
|
||||||
|
h-11.7c-2.2,0-4-1.8-4-4V82.8c0-1.1-0.9-2-2-2h-11.7c-1.1,0-2,0.9-2,2v11.7c0,2.2-1.8,4-4,4L647.2,98.5z"/>
|
||||||
|
<path class="st2" d="M768.9,372.4c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C807.3,355.2,790.1,372.4,768.9,372.4z M768.9,297.5c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C805.3,313.8,789,297.5,768.9,297.5L768.9,297.5z"/>
|
||||||
|
<path class="st2" d="M768.9,225.5c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C807.3,208.3,790.1,225.5,768.9,225.5z M768.9,150.6c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C805.3,166.9,789,150.6,768.9,150.6L768.9,150.6z"/>
|
||||||
|
<path class="st2" d="M842.3,299c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C880.8,281.7,863.6,298.9,842.3,299z M842.3,224c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C878.8,240.4,862.5,224,842.3,224L842.3,224z"/>
|
||||||
|
<path class="st2" d="M695.5,299c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C733.9,281.7,716.7,298.9,695.5,299z M695.5,224c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C731.9,240.4,715.6,224,695.5,224L695.5,224z"/>
|
||||||
|
<path class="st2" d="M715,750.2c-16,0-28.9-13-28.9-28.9s13-28.9,28.9-28.9c16,0,28.9,13,28.9,28.9c0,0,0,0,0,0
|
||||||
|
C743.9,737.3,731,750.2,715,750.2z M715,694.3c-14.9,0-26.9,12.1-26.9,26.9s12.1,26.9,26.9,26.9c14.9,0,26.9-12.1,26.9-26.9
|
||||||
|
C741.9,706.4,729.9,694.4,715,694.3z"/>
|
||||||
|
<path class="st2" d="M705.8,533.4h-12.3c-0.6,0-1-0.4-1-1c0,0,0,0,0,0c1.7-39.6,33.4-71.3,73-73c0.3,0,0.5,0.1,0.7,0.3
|
||||||
|
c0.2,0.2,0.3,0.4,0.3,0.7v12.3c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9C712.2,530.8,709.3,533.4,705.8,533.4z
|
||||||
|
M694.6,531.4h11.2c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-11.2
|
||||||
|
C727.2,463.5,696.7,494,694.6,531.4z"/>
|
||||||
|
<path class="st2" d="M765.6,612.1C765.6,612.1,765.5,612.1,765.6,612.1c-39.6-1.7-71.3-33.4-73-73c0-0.6,0.4-1,1-1c0,0,0,0,0,0h12.3
|
||||||
|
c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9v12.3C766.6,611.6,766.1,612.1,765.6,612.1
|
||||||
|
C765.6,612.1,765.6,612.1,765.6,612.1L765.6,612.1z M694.6,540c2.2,37.4,32.6,67.8,70,70v-11.2c0-2.5-1.8-4.6-4.3-4.9
|
||||||
|
c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3H694.6z"/>
|
||||||
|
<path class="st2" d="M772.2,612.1c-0.6,0-1-0.4-1-1c0,0,0,0,0,0v-12.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9
|
||||||
|
c0.5-3.4,3.4-6,6.9-6h12.3c0.6,0,1,0.4,1,1c0,0,0,0,0,0C843.5,578.7,811.9,610.3,772.2,612.1C772.3,612.1,772.3,612.1,772.2,612.1z
|
||||||
|
M832,540c-2.5,0-4.6,1.8-4.9,4.3c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9V610c37.4-2.2,67.8-32.6,70-70H832z"/>
|
||||||
|
<path class="st2" d="M844.3,533.4H832c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-12.3
|
||||||
|
c0-0.3,0.1-0.5,0.3-0.7c0.2-0.2,0.5-0.3,0.7-0.3c39.6,1.7,71.3,33.4,73,73C845.3,532.9,844.9,533.3,844.3,533.4
|
||||||
|
C844.3,533.4,844.3,533.4,844.3,533.4L844.3,533.4z M773.2,461.4v11.2c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6
|
||||||
|
c0.3,2.5,2.4,4.3,4.9,4.3h11.2C841.1,494,810.6,463.5,773.2,461.4z"/>
|
||||||
|
<path class="st2" d="M768.9,612.2c-1.2,0-2.3,0-3.4-0.1c-0.5,0-0.9-0.5-0.9-1v-12.3c0-2.5-1.8-4.6-4.3-4.9
|
||||||
|
c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-12.3c-0.5,0-1-0.4-1-0.9c-0.1-1.1-0.1-2.2-0.1-3.4s0-2.3,0.1-3.4
|
||||||
|
c0-0.5,0.5-0.9,1-0.9h12.3c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-12.3c0-0.5,0.4-1,0.9-1
|
||||||
|
c2.3-0.1,4.5-0.1,6.8,0c0.5,0,0.9,0.5,0.9,1v12.3c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h12.3
|
||||||
|
c0.5,0,1,0.4,1,0.9c0.1,1.1,0.1,2.2,0.1,3.4s0,2.3-0.1,3.4c0,0.5-0.5,0.9-1,0.9H832c-2.5,0-4.6,1.8-4.9,4.3
|
||||||
|
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v12.3c0,0.5-0.4,1-0.9,1C771.2,612.1,770.1,612.2,768.9,612.2z M766.6,610.1
|
||||||
|
c1.5,0.1,3.1,0.1,4.7,0v-11.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6h11.3c0-0.8,0-1.5,0-2.3
|
||||||
|
s0-1.6,0-2.3H832c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-11.3c-1.5-0.1-3.1-0.1-4.7,0v11.3
|
||||||
|
c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-11.3c0,0.8,0,1.5,0,2.3s0,1.6,0,2.3h11.3
|
||||||
|
c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9V610.1z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 20 KiB |
120
Ryujinx/Ui/assets/JoyConRight.svg
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 1000.8 1000" style="enable-background:new 0 0 1000.8 1000;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{opacity:0.1;}
|
||||||
|
.st1{fill:#FF5F55;}
|
||||||
|
.st2{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g class="st0">
|
||||||
|
<path class="st1" d="M597.9,233.9v79.5h-4.2c-3.3,0-6-2.7-6-6v-67.6c0-3.3,2.7-6,6-6h4.2V233.9z"/>
|
||||||
|
<path class="st1" d="M597.9,636.6v79.5h-4.2c-3.3,0-6-2.7-6-6v-67.6c0-3.3,2.7-6,6-6L597.9,636.6L597.9,636.6z"/>
|
||||||
|
<path class="st1" d="M929,134.9l-3.4,3.4C892.4,60.3,815.8,9.6,730.9,9.6h-54.2V7c0-3.3,2.7-6,6-6l0,0h51.2
|
||||||
|
c84.8,0,161.7,49.8,196.4,127.2C931.3,130.5,930.8,133.1,929,134.9z"/>
|
||||||
|
<path class="st1" d="M679.5,94.5V82.8c0-1.6-1.3-3-3-3l0,0h-11.7c-1.6,0-3,1.3-3,3l0,0v11.7c0,1.6-1.3,3-3,3l0,0h-11.7
|
||||||
|
c-1.6,0-3,1.3-3,3l0,0v11.7c0,1.6,1.3,3,3,3l0,0h11.7c1.6,0,3,1.3,3,3l0,0v11.7c0,1.6,1.3,3,3,3l0,0h11.7c1.6,0,3-1.3,3-3l0,0
|
||||||
|
v-11.7c0-1.6,1.3-3,3-3l0,0h11.7c1.6,0,3-1.3,3-3l0,0v-11.7c0-1.6-1.3-3-3-3l0,0h-11.7C680.8,97.5,679.5,96.1,679.5,94.5
|
||||||
|
L679.5,94.5z"/>
|
||||||
|
<circle class="st1" cx="768.9" cy="333.9" r="37.5"/>
|
||||||
|
<circle class="st1" cx="768.9" cy="187.1" r="37.5"/>
|
||||||
|
<circle class="st1" cx="842.3" cy="260.5" r="37.5"/>
|
||||||
|
<circle class="st1" cx="695.5" cy="260.5" r="37.5"/>
|
||||||
|
<circle class="st1" cx="715" cy="721.3" r="27.9"/>
|
||||||
|
<path class="st1" d="M765.6,460.3v12.3c0,3-2.2,5.5-5.2,5.9c-25.2,3.7-45,23.5-48.7,48.7c-0.4,2.9-2.9,5.1-5.9,5.2h-12.3
|
||||||
|
C695.2,493.3,726.5,462,765.6,460.3z"/>
|
||||||
|
<path class="st1" d="M765.6,598.8v12.3c-39.1-1.7-70.3-33-72.1-72h12.3c3,0,5.5,2.2,5.9,5.2c3.7,25.2,23.5,45,48.7,48.7
|
||||||
|
C763.4,593.3,765.6,595.8,765.6,598.8z"/>
|
||||||
|
<path class="st1" d="M844.3,539c-1.7,39.1-33,70.3-72.1,72v-12.3c0-3,2.2-5.5,5.2-5.9c25.2-3.7,45-23.5,48.7-48.7
|
||||||
|
c0.4-2.9,2.9-5.1,5.9-5.2L844.3,539z"/>
|
||||||
|
<path class="st1" d="M844.3,532.4H832c-3,0-5.5-2.2-5.9-5.2c-3.7-25.2-23.5-45-48.7-48.7c-2.9-0.4-5.1-2.9-5.2-5.9v-12.3
|
||||||
|
C811.3,462,842.6,493.3,844.3,532.4z"/>
|
||||||
|
<path class="st1" d="M844.4,535.7c0,1.1,0,2.2-0.1,3.3H832c-3,0-5.5,2.2-5.9,5.2c-3.7,25.2-23.5,45-48.7,48.7
|
||||||
|
c-2.9,0.4-5.1,2.9-5.2,5.9v12.3c-1.1,0.1-2.2,0.1-3.3,0.1s-2.2,0-3.3-0.1v-12.3c0-3-2.2-5.5-5.2-5.9c-25.2-3.7-45-23.5-48.7-48.7
|
||||||
|
c-0.4-2.9-2.9-5.1-5.9-5.2h-12.3c-0.1-1.1-0.1-2.2-0.1-3.3s0-2.2,0.1-3.3h12.3c3,0,5.5-2.2,5.9-5.2c3.7-25.2,23.5-45,48.7-48.7
|
||||||
|
c2.9-0.4,5.1-2.9,5.2-5.9v-12.3c1.1-0.1,2.2-0.1,3.3-0.1s2.2,0,3.3,0.1v12.3c0,3,2.2,5.5,5.2,5.9c25.2,3.7,45,23.5,48.7,48.7
|
||||||
|
c0.4,2.9,2.9,5.1,5.9,5.2h12.3C844.3,533.5,844.4,534.6,844.4,535.7z"/>
|
||||||
|
</g>
|
||||||
|
<path class="st2" d="M601.6,906.6h-7.9c-3.6,0-6.4-2.9-6.5-6.5V742.9c0-4.9,1.2-9.6,3.4-13.9l6.7-13v-79.2l-6.7-13
|
||||||
|
c-2.2-4.3-3.4-9.1-3.4-14V340.1c0-4.9,1.2-9.6,3.4-13.9l6.7-13V234l-6.7-13c-2.2-4.3-3.4-9.1-3.4-14V71.2c0-3.6,2.9-6.4,6.5-6.5h7.9
|
||||||
|
c3.6,0,6.4,2.9,6.5,6.5v828.9C608,903.7,605.1,906.6,601.6,906.6z M593.7,65.7c-3,0-5.5,2.4-5.5,5.5V207c0,4.7,1.1,9.3,3.3,13.5
|
||||||
|
l6.8,13.1c0,0.1,0.1,0.1,0.1,0.2v79.5c0,0.1,0,0.2-0.1,0.2l-6.8,13.1c-2.2,4.2-3.3,8.8-3.3,13.5v269.7c0,4.7,1.1,9.3,3.3,13.5
|
||||||
|
l6.8,13.1c0,0.1,0.1,0.1,0.1,0.2v79.5c0,0.1,0,0.2-0.1,0.2l-6.8,13.1c-2.2,4.2-3.3,8.8-3.3,13.5v157.2c0,3,2.4,5.5,5.5,5.5h7.9
|
||||||
|
c3,0,5.5-2.4,5.5-5.5V71.2c0-3-2.4-5.5-5.5-5.5H593.7z"/>
|
||||||
|
<path class="st2" d="M618.8,858.9h-11.3c-0.3,0-0.5-0.2-0.5-0.5l0,0V72c0-0.3,0.2-0.5,0.5-0.5h11.3c0.3,0,0.5,0.2,0.5,0.5v786.4
|
||||||
|
C619.3,858.7,619.1,858.9,618.8,858.9L618.8,858.9z M608,857.9h10.3V72.5H608V857.9z"/>
|
||||||
|
<path class="st2" d="M730.9,1000H624.7c-3.6,0-6.5-2.9-6.5-6.5v-978c0-3.6,2.9-6.5,6.5-6.5h106.2c116.8,0,211.9,95.1,211.9,211.9
|
||||||
|
v567.2C942.8,905.1,848,1000,730.9,1000L730.9,1000z M624.7,10.1c-3,0-5.5,2.4-5.5,5.5v978c0,3,2.4,5.5,5.5,5.5h106.2
|
||||||
|
c116.3,0,210.9-94.6,210.9-210.9V220.9C941.8,104.6,847.2,10,730.9,10L624.7,10.1z"/>
|
||||||
|
<path class="st2" d="M715,763.2c-23.1,0-41.9-18.7-41.9-41.9s18.7-41.9,41.9-41.9s41.9,18.7,41.9,41.9l0,0
|
||||||
|
C756.8,744.4,738.1,763.1,715,763.2z M715,680.4c-22.6,0-40.9,18.3-40.9,40.9c0,22.6,18.3,40.9,40.9,40.9
|
||||||
|
c22.6,0,40.9-18.3,40.9-40.9l0,0C755.8,698.7,737.6,680.4,715,680.4z"/>
|
||||||
|
<path class="st1" d="M782.2,203.2h-5.5l-7.8-12.9l-7.8,12.9h-5.4l10.6-16.3l-9.8-15.6h5.2l7.3,12l7.4-12h5l-9.8,15.4L782.2,203.2z"
|
||||||
|
/>
|
||||||
|
<path class="st1" d="M709.2,244.5l-11.6,20.6v11.4h-4.4V265l-11.6-20.5h5.3l6.4,11.7l2.3,4.7l2.2-4.3l6.4-12.1L709.2,244.5z"/>
|
||||||
|
<path class="st1" d="M855.9,276.5h-4.7l-2.2-7h-13.3l-2.3,7h-4.5l10.6-32h6L855.9,276.5z M847.7,265.6l-5.4-17.1l-5.4,17.1H847.7z"
|
||||||
|
/>
|
||||||
|
<path class="st1" d="M779.4,340.4c0,1.4-0.3,2.8-0.9,4.1c-0.6,1.2-1.5,2.2-2.5,3c-1.2,0.9-2.6,1.5-4,1.9c-1.7,0.4-3.4,0.7-5.2,0.6
|
||||||
|
h-8.4v-32h9.2c7.1,0,10.7,2.6,10.7,7.8c0,1.6-0.4,3.1-1.2,4.5c-1,1.4-2.4,2.3-4,2.8c0.9,0.2,1.7,0.4,2.5,0.8s1.5,0.9,2,1.5
|
||||||
|
c0.6,0.6,1.1,1.4,1.4,2.2C779.2,338.4,779.4,339.4,779.4,340.4z M773.7,326.3c0-0.6-0.1-1.3-0.3-1.8c-0.2-0.6-0.6-1.1-1-1.5
|
||||||
|
c-0.6-0.5-1.3-0.8-2-1c-1-0.3-2.1-0.4-3.2-0.4h-4.5v10h4.4c0.9,0,1.8-0.1,2.7-0.3c0.8-0.2,1.5-0.5,2.1-1c0.6-0.4,1-1,1.3-1.7
|
||||||
|
C773.6,327.9,773.7,327.1,773.7,326.3L773.7,326.3z M774.8,340.5c0-0.8-0.2-1.5-0.5-2.2c-0.4-0.7-0.9-1.2-1.5-1.7
|
||||||
|
c-0.7-0.5-1.5-0.8-2.4-1c-1-0.3-2.1-0.4-3.2-0.4h-4.5v11h4.6c2.5,0,4.4-0.5,5.6-1.4C774.2,343.8,774.9,342.2,774.8,340.5
|
||||||
|
L774.8,340.5z"/>
|
||||||
|
<path class="st1" d="M715,701.3L695.4,721h5.6v16.8h28.2V721h5.3L715,701.3z M720.7,731.8h-11.1V721h11.1V731.8z"/>
|
||||||
|
<path class="st1" d="M597.9,314.3h-4.2c-3.8,0-6.9-3.1-7-7v-67.6c0-3.8,3.1-6.9,7-7h4.2c0.6,0,1,0.4,1,1l0,0v79.5
|
||||||
|
C598.9,313.9,598.4,314.3,597.9,314.3L597.9,314.3z M593.7,234.8c-2.7,0-5,2.2-5,5v67.6c0,2.7,2.2,5,5,5h3.2v-77.5L593.7,234.8
|
||||||
|
L593.7,234.8z"/>
|
||||||
|
<path class="st1" d="M597.9,717.1h-4.2c-3.8,0-6.9-3.1-7-7v-67.6c0-3.8,3.1-6.9,7-7h4.2c0.6,0,1,0.4,1,1l0,0V716
|
||||||
|
C598.9,716.6,598.4,717.1,597.9,717.1L597.9,717.1z M593.7,637.6c-2.7,0-5,2.2-5,5v67.6c0,2.7,2.2,5,5,5h3.2v-77.5L593.7,637.6
|
||||||
|
L593.7,637.6z"/>
|
||||||
|
<path class="st1" d="M925.6,139.3c-0.1,0-0.1,0-0.2,0c-0.3-0.1-0.6-0.3-0.7-0.6C891.7,61,815.4,10.5,730.9,10.6h-54.2
|
||||||
|
c-0.6,0-1-0.4-1-1l0,0V7c0-3.8,3.1-6.9,7-7h51.2c85.2,0.1,162.4,50.1,197.3,127.8c1.2,2.6,0.6,5.7-1.5,7.8l-3.4,3.4
|
||||||
|
C926.1,139.2,925.8,139.3,925.6,139.3z M677.7,8.6h53.2c84.7-0.1,161.3,50.2,195,128l2.4-2.4l0,0c1.5-1.4,1.9-3.6,1.1-5.5
|
||||||
|
C894.8,51.7,818.3,2.1,733.9,2h-51.2c-2.7,0-5,2.2-5,5V8.6z"/>
|
||||||
|
<path class="st1" d="M676.5,133.7h-11.7c-2.2,0-4-1.8-4-4V118c0-1.1-0.9-2-2-2h-11.7c-2.2,0-4-1.8-4-4v-11.7c0-2.2,1.8-4,4-4h11.7
|
||||||
|
c1.1,0,2-0.9,2-2V82.8c0-2.2,1.8-4,4-4h11.7c2.2,0,4,1.8,4,4v11.7c0,1.1,0.9,2,2,2h11.7c2.2,0,4,1.8,4,4v11.7c0,2.2-1.8,4-4,4h-11.7
|
||||||
|
c-1.1,0-2,0.9-2,2v11.7C680.5,131.9,678.7,133.7,676.5,133.7z M647.2,98.5c-1.1,0-2,0.9-2,2v11.7c0,1.1,0.9,2,2,2h11.7
|
||||||
|
c2.2,0,4,1.8,4,4v11.7c0,1.1,0.9,2,2,2h11.7c1.1,0,2-0.9,2-2v-11.7c0-2.2,1.8-4,4-4h11.7c1.1,0,2-0.9,2-2v-11.7c0-1.1-0.9-2-2-2
|
||||||
|
h-11.7c-2.2,0-4-1.8-4-4V82.8c0-1.1-0.9-2-2-2h-11.7c-1.1,0-2,0.9-2,2v11.7c0,2.2-1.8,4-4,4H647.2z"/>
|
||||||
|
<path class="st1" d="M768.9,372.4c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C807.3,355.2,790.1,372.4,768.9,372.4z M768.9,297.5c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C805.3,313.8,789,297.5,768.9,297.5L768.9,297.5z"/>
|
||||||
|
<path class="st1" d="M768.9,225.5c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C807.3,208.3,790.1,225.5,768.9,225.5z M768.9,150.6c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C805.3,166.9,789,150.6,768.9,150.6L768.9,150.6z"/>
|
||||||
|
<path class="st1" d="M842.3,299c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C880.8,281.7,863.6,298.9,842.3,299z M842.3,224c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C878.8,240.4,862.5,224,842.3,224L842.3,224z"/>
|
||||||
|
<path class="st1" d="M695.5,299c-21.2,0-38.5-17.2-38.5-38.5c0-21.2,17.2-38.5,38.5-38.5c21.2,0,38.5,17.2,38.5,38.5
|
||||||
|
C733.9,281.7,716.7,298.9,695.5,299z M695.5,224c-20.1,0-36.5,16.3-36.5,36.5c0,20.1,16.3,36.5,36.5,36.5
|
||||||
|
c20.1,0,36.5-16.3,36.5-36.5C731.9,240.4,715.6,224,695.5,224L695.5,224z"/>
|
||||||
|
<path class="st1" d="M715,750.2c-16,0-28.9-13-28.9-28.9s13-28.9,28.9-28.9c16,0,28.9,13,28.9,28.9l0,0
|
||||||
|
C743.9,737.3,731,750.2,715,750.2z M715,694.3c-14.9,0-26.9,12.1-26.9,26.9s12.1,26.9,26.9,26.9c14.9,0,26.9-12.1,26.9-26.9
|
||||||
|
C741.9,706.4,729.9,694.4,715,694.3z"/>
|
||||||
|
<path class="st1" d="M705.8,533.4h-12.3c-0.6,0-1-0.4-1-1l0,0c1.7-39.6,33.4-71.3,73-73c0.3,0,0.5,0.1,0.7,0.3
|
||||||
|
c0.2,0.2,0.3,0.4,0.3,0.7v12.3c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9C712.2,530.8,709.3,533.4,705.8,533.4z
|
||||||
|
M694.6,531.4h11.2c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-11.2
|
||||||
|
C727.2,463.5,696.7,494,694.6,531.4z"/>
|
||||||
|
<path class="st1" d="M765.6,612.1C765.6,612.1,765.5,612.1,765.6,612.1c-39.6-1.7-71.3-33.4-73-73c0-0.6,0.4-1,1-1l0,0h12.3
|
||||||
|
c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9v12.3C766.6,611.6,766.1,612.1,765.6,612.1L765.6,612.1
|
||||||
|
L765.6,612.1z M694.6,540c2.2,37.4,32.6,67.8,70,70v-11.2c0-2.5-1.8-4.6-4.3-4.9c-25.6-3.9-45.7-24-49.6-49.6
|
||||||
|
c-0.3-2.5-2.4-4.3-4.9-4.3H694.6z"/>
|
||||||
|
<path class="st1" d="M772.2,612.1c-0.6,0-1-0.4-1-1l0,0v-12.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9
|
||||||
|
c0.5-3.4,3.4-6,6.9-6h12.3c0.6,0,1,0.4,1,1l0,0C843.5,578.7,811.9,610.3,772.2,612.1C772.3,612.1,772.3,612.1,772.2,612.1z M832,540
|
||||||
|
c-2.5,0-4.6,1.8-4.9,4.3c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9V610c37.4-2.2,67.8-32.6,70-70H832z"/>
|
||||||
|
<path class="st1" d="M844.3,533.4H832c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-12.3
|
||||||
|
c0-0.3,0.1-0.5,0.3-0.7s0.5-0.3,0.7-0.3c39.6,1.7,71.3,33.4,73,73C845.3,532.9,844.9,533.3,844.3,533.4L844.3,533.4L844.3,533.4z
|
||||||
|
M773.2,461.4v11.2c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h11.2
|
||||||
|
C841.1,494,810.6,463.5,773.2,461.4z"/>
|
||||||
|
<path class="st1" d="M768.9,612.2c-1.2,0-2.3,0-3.4-0.1c-0.5,0-0.9-0.5-0.9-1v-12.3c0-2.5-1.8-4.6-4.3-4.9
|
||||||
|
c-25.6-3.9-45.7-24-49.6-49.6c-0.3-2.5-2.4-4.3-4.9-4.3h-12.3c-0.5,0-1-0.4-1-0.9c-0.1-1.1-0.1-2.2-0.1-3.4s0-2.3,0.1-3.4
|
||||||
|
c0-0.5,0.5-0.9,1-0.9h12.3c2.5,0,4.6-1.8,4.9-4.3c3.9-25.6,24-45.7,49.6-49.6c2.5-0.3,4.3-2.4,4.3-4.9v-12.3c0-0.5,0.4-1,0.9-1
|
||||||
|
c2.3-0.1,4.5-0.1,6.8,0c0.5,0,0.9,0.5,0.9,1v12.3c0,2.5,1.8,4.6,4.3,4.9c25.6,3.9,45.7,24,49.6,49.6c0.3,2.5,2.4,4.3,4.9,4.3h12.3
|
||||||
|
c0.5,0,1,0.4,1,0.9c0.1,1.1,0.1,2.2,0.1,3.4s0,2.3-0.1,3.4c0,0.5-0.5,0.9-1,0.9H832c-2.5,0-4.6,1.8-4.9,4.3
|
||||||
|
c-3.9,25.6-24,45.7-49.6,49.6c-2.5,0.3-4.3,2.4-4.3,4.9v12.3c0,0.5-0.4,1-0.9,1C771.2,612.1,770.1,612.2,768.9,612.2z M766.6,610.1
|
||||||
|
c1.5,0.1,3.1,0.1,4.7,0v-11.3c0-3.5,2.6-6.4,6-6.9c24.7-3.7,44.2-23.1,47.9-47.9c0.5-3.4,3.4-6,6.9-6h11.3c0-0.8,0-1.5,0-2.3
|
||||||
|
s0-1.6,0-2.3H832c-3.5,0-6.4-2.6-6.9-6c-3.7-24.7-23.1-44.2-47.9-47.9c-3.4-0.5-6-3.4-6-6.9v-11.3c-1.5-0.1-3.1-0.1-4.7,0v11.3
|
||||||
|
c0,3.5-2.6,6.4-6,6.9c-24.7,3.7-44.2,23.1-47.9,47.9c-0.5,3.4-3.4,6-6.9,6h-11.3c0,0.8,0,1.5,0,2.3s0,1.6,0,2.3h11.3
|
||||||
|
c3.5,0,6.4,2.6,6.9,6c3.7,24.7,23.1,44.2,47.9,47.9c3.4,0.5,6,3.4,6,6.9v11.3H766.6z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 317 KiB |
149
Ryujinx/Ui/assets/ProCon.svg
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 1000 1000.5" style="enable-background:new 0 0 1000 1000.5;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{opacity:0.1;}
|
||||||
|
.st1{fill:#1ABC9C;}
|
||||||
|
.st2{fill:#CCCCCC;}
|
||||||
|
.st3{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<g class="st0">
|
||||||
|
<path class="st1" d="M259.4,630.9c-22.4,12.5-32.3,39.7-49,69.8c-35.7,64.1-50.5,128.9-116.6,128.9C40.8,829.5,1,776.1,1,705.8
|
||||||
|
c0-48.3,29.9-226.9,55.6-347.6C113.4,453.9,219.5,604.4,259.4,630.9z"/>
|
||||||
|
<path class="st1" d="M999,705.8c0,70.4-39.9,123.8-92.7,123.8c-66.1,0-80.9-64.8-116.6-128.9c-16.7-30-26.7-57.3-49-69.8
|
||||||
|
c39.8-26.5,146-177,202.7-272.7C969.1,478.9,999,657.5,999,705.8z"/>
|
||||||
|
<circle class="st1" cx="630.3" cy="482.7" r="56.2"/>
|
||||||
|
<circle class="st1" cx="630.3" cy="482.7" r="40.5"/>
|
||||||
|
<circle class="st1" cx="764.9" cy="276.6" r="36.6"/>
|
||||||
|
<circle class="st1" cx="764.9" cy="412.6" r="36.6"/>
|
||||||
|
<circle class="st1" cx="223.9" cy="344.8" r="56.2"/>
|
||||||
|
<circle class="st1" cx="223.9" cy="344.8" r="40.5"/>
|
||||||
|
<circle class="st1" cx="843.1" cy="344.6" r="36.6"/>
|
||||||
|
<circle class="st1" cx="686.7" cy="344.6" r="36.6"/>
|
||||||
|
<circle class="st1" cx="624.1" cy="269.3" r="22.1"/>
|
||||||
|
<circle class="st1" cx="571.3" cy="344.6" r="22.1"/>
|
||||||
|
<circle class="st1" cx="375.9" cy="269.3" r="22.1"/>
|
||||||
|
<circle class="st1" cx="428.7" cy="344.6" r="14"/>
|
||||||
|
<path class="st1" d="M414.6,326.5h28.2c2.2,0,4.1,1.8,4.1,4.1v28.2c0,2.2-1.8,4.1-4.1,4.1h-28.2c-2.2,0-4.1-1.8-4.1-4.1v-28.2
|
||||||
|
C410.6,328.3,412.4,326.5,414.6,326.5z"/>
|
||||||
|
<path class="st1" d="M351.6,158.8c-88.4,3.8-169.6,13.7-207,39.4c-14.9,10.2-26.4,16.9-32.9,20.5C142.6,135.9,282,138,299,138
|
||||||
|
c6.5,0,26.6,8.7,39.9,14.8h0C346.3,156.2,351.6,158.8,351.6,158.8z"/>
|
||||||
|
<path class="st1" d="M888.3,218.7c-6.5-3.6-18-10.3-32.9-20.6c-37.4-25.7-118.7-35.6-207-39.4c0,0,5.3-2.6,12.6-6
|
||||||
|
c13.4-6.1,33.4-14.8,40-14.8C717.9,138,857.4,135.9,888.3,218.7z"/>
|
||||||
|
<path class="st1" d="M414.6,461.1H373c-2.2,0-4.1-1.8-4.1-4.1v-41.6c0-2.2-1.8-4.1-4.1-4.1c0,0,0,0,0,0h-36.4
|
||||||
|
c-2.2,0-4.1,1.8-4.1,4.1c0,0,0,0,0,0v41.6c0,2.2-1.8,4.1-4.1,4.1h-41.6c-2.2,0-4.1,1.8-4.1,4.1v36.4c0,2.2,1.8,4.1,4.1,4.1h41.6
|
||||||
|
c2.2,0,4.1,1.8,4.1,4.1l0,0v41.6c0,2.2,1.8,4.1,4.1,4.1c0,0,0,0,0,0h36.4c2.2,0,4.1-1.8,4.1-4.1l0,0v-41.6c0-2.2,1.8-4.1,4.1-4.1
|
||||||
|
l0,0h41.6c2.2,0,4.1-1.8,4.1-4.1v-36.4C418.6,462.9,416.8,461.1,414.6,461.1z"/>
|
||||||
|
</g>
|
||||||
|
<path class="st2" d="M661,153.1L661,153.1c-0.2,0-0.3-0.1-0.3-0.3c0-0.1,0.1-0.2,0.2-0.2c0.1,0,0.3,0.1,0.3,0.2
|
||||||
|
C661.3,153,661.2,153.1,661,153.1C661,153.1,661,153.1,661,153.1z"/>
|
||||||
|
<path class="st3" d="M630.3,560.6c-43,0-77.9-34.9-77.9-77.9s34.9-77.9,77.9-77.9c43,0,77.9,34.9,77.9,77.9
|
||||||
|
C708.2,525.7,673.3,560.6,630.3,560.6z M630.3,405.8c-42.5,0-76.9,34.4-76.9,76.9s34.4,76.9,76.9,76.9c42.5,0,76.9-34.4,76.9-76.9
|
||||||
|
C707.2,440.3,672.8,405.9,630.3,405.8L630.3,405.8z"/>
|
||||||
|
<path class="st3" d="M223.9,422.7c-43,0-77.9-34.9-77.9-77.9c0-43,34.9-77.9,77.9-77.9s77.9,34.9,77.9,77.9l0,0
|
||||||
|
C301.7,387.8,266.9,422.7,223.9,422.7z M223.9,267.9c-42.5,0-76.9,34.4-76.9,76.9c0,42.5,34.4,76.9,76.9,76.9s76.9-34.4,76.9-76.9
|
||||||
|
l0,0C300.7,302.4,266.3,268,223.9,267.9z"/>
|
||||||
|
<path class="st3" d="M648.4,159.3L648.4,159.3c-49.9-2.1-102.8-2.3-148.4-2.3c-45.6,0-98.4,0.2-148.4,2.3c-0.1,0-0.2,0-0.2-0.1
|
||||||
|
c-0.1,0-5.4-2.6-12.6-6c-0.3-0.1-0.4-0.4-0.2-0.7c0.1-0.2,0.2-0.3,0.4-0.3c2-0.2,50-4.9,161.1-4.9c111.7,0,159.1,4.7,161,4.9
|
||||||
|
c0.3,0,0.5,0.3,0.4,0.5c0,0.2-0.1,0.3-0.3,0.4c-7.2,3.3-12.6,5.9-12.6,6C648.5,159.3,648.4,159.3,648.4,159.3z M340.9,153.2
|
||||||
|
c5.8,2.7,10.1,4.8,10.8,5.1c49.9-2.1,102.7-2.3,148.3-2.3c45.6,0,98.4,0.2,148.3,2.3c0.7-0.4,5-2.4,10.8-5.1
|
||||||
|
c-9.8-0.9-58.2-4.7-159.1-4.7C399.6,148.5,350.7,152.3,340.9,153.2L340.9,153.2z"/>
|
||||||
|
<path class="st3" d="M740.6,631.4c-0.1,0-0.2,0-0.2-0.1c-8.6-4.8-18.6-7.2-30.7-7.2H290.3c-12,0-22.1,2.4-30.7,7.2
|
||||||
|
c-0.2,0.1-0.4,0.1-0.5,0C218.3,604.2,110,449.1,56.2,358.4c-0.1-0.1-0.1-0.2-0.1-0.4c11.3-53.3,20.7-90,27.1-106.1
|
||||||
|
c1.2-3.1,2.9-5.9,4.9-8.5l12.7-16.2c2.9-3.7,6.5-6.8,10.6-9c0,0,0,0,0,0l0,0c7.1-3.9,18.5-10.6,32.8-20.5
|
||||||
|
c32-22,99.8-34.9,207.3-39.4c49.5-2.1,100.5-2.3,148.4-2.3c47.9,0,98.8,0.2,148.4,2.3c107.5,4.6,175.3,17.5,207.3,39.4
|
||||||
|
c14.4,9.9,25.8,16.6,32.9,20.5c4.1,2.2,7.7,5.3,10.6,9l12.7,16.2c2.1,2.6,3.7,5.5,4.9,8.6c6.4,16.1,15.7,52.8,27.1,106.1
|
||||||
|
c0,0.1,0,0.3-0.1,0.4C890,449.1,781.7,604.2,740.9,631.3C740.8,631.4,740.7,631.4,740.6,631.4z M57.2,358.1
|
||||||
|
c53.6,90.4,161.4,244.7,202.2,272.2c8.7-4.8,18.8-7.2,30.9-7.2h419.4c12.1,0,22.2,2.3,30.9,7.2c40.8-27.5,148.6-181.8,202.2-272.2
|
||||||
|
c-11.3-53.1-20.6-89.7-27-105.7c-1.2-3-2.8-5.8-4.8-8.3l-12.7-16.2c-2.8-3.6-6.3-6.5-10.3-8.7c-7.1-3.9-18.5-10.7-33-20.6
|
||||||
|
c-31.8-21.9-99.4-34.7-206.8-39.3c-49.5-2.1-100.4-2.3-148.3-2.3c-47.9,0-98.8,0.2-148.4,2.3c-107.3,4.6-174.9,17.4-206.7,39.3
|
||||||
|
c-14.4,9.9-25.8,16.6-32.9,20.5c0,0-0.1,0-0.1,0.1c-4,2.2-7.5,5.2-10.3,8.7l-12.7,16.2c-2,2.5-3.6,5.3-4.8,8.3
|
||||||
|
C77.8,268.4,68.5,305,57.2,358.1z"/>
|
||||||
|
<path class="st1" d="M93.7,830.5C40.3,830.5,0,776.9,0,705.8C0,657.1,29.9,478.8,55.6,358c0.1-0.5,0.6-0.9,1.2-0.8
|
||||||
|
c0.3,0.1,0.5,0.2,0.7,0.5c53.7,90.5,161.9,245.4,202.4,272.4c0.5,0.3,0.6,0.9,0.3,1.4c-0.1,0.1-0.2,0.2-0.3,0.3
|
||||||
|
c-17.4,9.7-27.3,28.8-38.8,50.9c-3.1,6-6.3,12.1-9.8,18.4c-7.3,13.1-13.7,26.1-19.8,38.7C167.5,788.5,146.9,830.5,93.7,830.5z
|
||||||
|
M57.1,360.9C31.5,481.6,2,657.5,2,705.8c0,70,39.4,122.8,91.7,122.8c52,0,72.3-41.5,95.9-89.6c6.2-12.6,12.6-25.7,19.9-38.8
|
||||||
|
c3.5-6.3,6.7-12.4,9.8-18.4c11.3-21.8,21.2-40.7,38.2-51C216.1,601.5,110.7,450.9,57.1,360.9z"/>
|
||||||
|
<path class="st1" d="M906.3,830.5c-53.3,0-73.9-42-97.7-90.7c-6.2-12.6-12.5-25.6-19.8-38.7c-3.5-6.3-6.7-12.5-9.8-18.4
|
||||||
|
c-11.5-22.1-21.4-41.2-38.8-50.9c-0.5-0.3-0.7-0.9-0.4-1.4c0.1-0.1,0.2-0.3,0.3-0.3c40.6-27,148.7-181.8,202.4-272.4
|
||||||
|
c0.3-0.5,0.9-0.6,1.4-0.3c0.2,0.1,0.4,0.4,0.5,0.7c25.7,120.9,55.6,299.1,55.6,347.8C1000,776.9,959.7,830.5,906.3,830.5z
|
||||||
|
M742.5,630.8c17.1,10.2,26.9,29.2,38.2,51c3.1,6,6.3,12.1,9.8,18.4c7.3,13.1,13.7,26.1,19.9,38.7c23.5,48.1,43.9,89.6,95.9,89.6
|
||||||
|
c52.3,0,91.7-52.8,91.7-122.8c0-48.2-29.5-224.2-55.1-344.9C889.3,450.9,783.9,601.5,742.5,630.8z"/>
|
||||||
|
<path class="st1" d="M630.3,539.9c-31.6,0-57.2-25.6-57.2-57.2c0-31.6,25.6-57.2,57.2-57.2c31.6,0,57.2,25.6,57.2,57.2l0,0
|
||||||
|
C687.5,514.3,661.9,539.9,630.3,539.9z M630.3,427.5c-30.5,0-55.2,24.7-55.2,55.2c0,30.5,24.7,55.2,55.2,55.2
|
||||||
|
c30.5,0,55.2-24.7,55.2-55.2C685.5,452.2,660.8,427.5,630.3,427.5L630.3,427.5z"/>
|
||||||
|
<path class="st1" d="M630.3,524.2c-22.9,0-41.5-18.6-41.5-41.5s18.6-41.5,41.5-41.5c22.9,0,41.5,18.6,41.5,41.5
|
||||||
|
C671.8,505.6,653.2,524.2,630.3,524.2z M630.3,443.2c-21.8,0-39.5,17.7-39.5,39.5c0,21.8,17.7,39.5,39.5,39.5
|
||||||
|
c21.8,0,39.5-17.7,39.5-39.5C669.8,460.9,652.1,443.2,630.3,443.2z"/>
|
||||||
|
<path class="st1" d="M764.9,314.2c-20.7,0-37.6-16.8-37.5-37.6c0-20.7,16.8-37.6,37.6-37.5c20.7,0,37.5,16.8,37.5,37.6
|
||||||
|
C802.4,297.4,785.6,314.1,764.9,314.2z M764.9,241.1c-19.6,0-35.6,15.9-35.6,35.6c0,19.6,15.9,35.6,35.6,35.6
|
||||||
|
c19.6,0,35.6-15.9,35.6-35.6C800.4,257,784.5,241.1,764.9,241.1L764.9,241.1z"/>
|
||||||
|
<path class="st1" d="M764.9,450.2c-20.7,0-37.6-16.8-37.5-37.6c0-20.7,16.8-37.6,37.6-37.5c20.7,0,37.5,16.8,37.5,37.6
|
||||||
|
C802.4,433.4,785.6,450.2,764.9,450.2z M764.9,377.1c-19.6,0-35.6,15.9-35.6,35.6c0,19.6,15.9,35.6,35.6,35.6
|
||||||
|
c19.6,0,35.6-15.9,35.6-35.6C800.4,393,784.5,377.1,764.9,377.1z"/>
|
||||||
|
<path class="st1" d="M223.9,402.1c-31.6,0-57.2-25.6-57.2-57.2c0-31.6,25.6-57.2,57.2-57.2s57.2,25.6,57.2,57.2
|
||||||
|
C281.1,376.4,255.5,402,223.9,402.1z M223.9,289.6c-30.5,0-55.2,24.7-55.2,55.2c0,30.5,24.7,55.2,55.2,55.2
|
||||||
|
c30.5,0,55.2-24.7,55.2-55.2c0,0,0,0,0,0C279.1,314.4,254.4,289.7,223.9,289.6L223.9,289.6z"/>
|
||||||
|
<path class="st1" d="M223.9,386.4c-22.9,0-41.5-18.6-41.5-41.5c0-22.9,18.6-41.5,41.5-41.5s41.5,18.6,41.5,41.5
|
||||||
|
C265.4,367.8,246.8,386.3,223.9,386.4z M223.9,305.3c-21.8,0-39.5,17.7-39.5,39.5c0,21.8,17.7,39.5,39.5,39.5s39.5-17.7,39.5-39.5
|
||||||
|
l0,0C263.4,323,245.7,305.3,223.9,305.3L223.9,305.3z"/>
|
||||||
|
<path class="st1" d="M843.1,382.2c-20.7,0-37.6-16.8-37.6-37.5s16.8-37.6,37.5-37.6c20.7,0,37.6,16.8,37.6,37.5c0,0,0,0,0,0
|
||||||
|
C880.6,365.4,863.8,382.2,843.1,382.2z M843.1,309.1c-19.6,0-35.6,15.9-35.6,35.6s15.9,35.6,35.6,35.6c19.6,0,35.6-15.9,35.6-35.6
|
||||||
|
c0,0,0,0,0,0C878.6,325,862.7,309.1,843.1,309.1z"/>
|
||||||
|
<path class="st1" d="M686.7,382.2c-20.7,0-37.6-16.8-37.6-37.6s16.8-37.6,37.6-37.6c20.7,0,37.6,16.8,37.6,37.6
|
||||||
|
C724.2,365.4,707.4,382.2,686.7,382.2z M686.7,309.1c-19.6,0-35.6,15.9-35.6,35.6s15.9,35.6,35.6,35.6c19.6,0,35.6-15.9,35.6-35.6
|
||||||
|
l0,0C722.2,325,706.3,309.1,686.7,309.1z"/>
|
||||||
|
<path class="st1" d="M624.1,292.4c-12.8,0-23.1-10.3-23.1-23.1c0-12.8,10.3-23.1,23.1-23.1c12.8,0,23.1,10.3,23.1,23.1
|
||||||
|
C647.2,282,636.8,292.4,624.1,292.4z M624.1,248.2c-11.7,0-21.1,9.5-21.1,21.1c0,11.7,9.5,21.1,21.1,21.1c11.7,0,21.1-9.5,21.1-21.1
|
||||||
|
C645.2,257.6,635.7,248.2,624.1,248.2z"/>
|
||||||
|
<path class="st1" d="M571.3,367.7c-12.8,0-23.1-10.3-23.1-23.1c0-12.8,10.3-23.1,23.1-23.1c12.8,0,23.1,10.3,23.1,23.1
|
||||||
|
C594.3,357.4,584,367.7,571.3,367.7z M571.3,323.5c-11.7,0-21.1,9.5-21.1,21.1c0,11.7,9.5,21.1,21.1,21.1c11.7,0,21.1-9.5,21.1-21.1
|
||||||
|
C592.3,333,582.9,323.5,571.3,323.5L571.3,323.5z"/>
|
||||||
|
<path class="st1" d="M375.9,292.4c-12.8,0-23.1-10.3-23.1-23.1c0-12.8,10.3-23.1,23.1-23.1c12.8,0,23.1,10.3,23.1,23.1
|
||||||
|
C399,282,388.7,292.4,375.9,292.4z M375.9,248.2c-11.7,0-21.1,9.5-21.1,21.1c0,11.7,9.5,21.1,21.1,21.1c11.7,0,21.1-9.5,21.1-21.1
|
||||||
|
C397,257.6,387.6,248.2,375.9,248.2z"/>
|
||||||
|
<path class="st1" d="M428.7,359.6c-8.3,0-15-6.7-15-15s6.7-15,15-15s15,6.7,15,15l0,0C443.7,352.9,437,359.6,428.7,359.6z
|
||||||
|
M428.7,331.7c-7.2,0-13,5.8-13,13c0,7.2,5.8,13,13,13c7.2,0,13-5.8,13-13c0,0,0,0,0,0C441.7,337.5,435.9,331.7,428.7,331.7
|
||||||
|
L428.7,331.7z"/>
|
||||||
|
<path class="st1" d="M442.8,363.8h-28.2c-2.8,0-5.1-2.3-5.1-5.1v-28.2c0-2.8,2.3-5.1,5.1-5.1h28.2c2.8,0,5.1,2.3,5.1,5.1v28.2
|
||||||
|
C447.9,361.5,445.6,363.8,442.8,363.8z M414.6,327.5c-1.7,0-3.1,1.4-3.1,3.1v28.2c0,1.7,1.4,3.1,3.1,3.1h28.2c1.7,0,3.1-1.4,3.1-3.1
|
||||||
|
v-28.2c0-1.7-1.4-3.1-3.1-3.1H414.6z"/>
|
||||||
|
<path class="st1" d="M111.7,219.7c-0.6,0-1-0.4-1-1c0-0.1,0-0.2,0.1-0.3c27.3-73.2,138.4-81.3,186-81.3c0.3,0,0.6,0,1,0l1.2,0
|
||||||
|
c6.6,0,25.5,8.1,40.3,14.9c0,0,0.1,0,0.1,0c7.2,3.3,12.6,6,12.7,6c0.5,0.2,0.7,0.8,0.5,1.3c-0.2,0.3-0.5,0.5-0.9,0.6
|
||||||
|
c-107.2,4.6-174.8,17.4-206.5,39.2c-14.6,10-26,16.7-33,20.6C112.1,219.6,111.9,219.7,111.7,219.7z M296.8,139
|
||||||
|
c-46.6,0-154.6,7.8-183.1,77.5c7-4,17.5-10.3,30.4-19.1c31.6-21.7,98.2-34.6,203.6-39.4c-2.2-1.1-5.4-2.5-8.9-4.2c0,0-0.1,0-0.1,0
|
||||||
|
c-20.6-9.5-34.7-14.7-39.5-14.7l-1.2,0C297.5,139,297.1,139,296.8,139L296.8,139z"/>
|
||||||
|
<path class="st1" d="M888.3,219.7c-0.2,0-0.3,0-0.5-0.1c-7-3.9-18.5-10.7-33-20.6c-31.7-21.8-99.3-34.6-206.5-39.2c-0.6,0-1-0.5-1-1
|
||||||
|
c0-0.4,0.2-0.7,0.6-0.9c0.1,0,5.4-2.6,12.7-6C682.2,142,695.8,137,701,137l1.2,0c0.3,0,0.6,0,1,0c47.6,0,158.7,8.1,186.1,81.4
|
||||||
|
c0.2,0.5-0.1,1.1-0.6,1.3C888.5,219.7,888.4,219.7,888.3,219.7L888.3,219.7z M652.4,158c105.3,4.7,171.9,17.6,203.6,39.4
|
||||||
|
c12.9,8.8,23.3,15.1,30.4,19.1C857.8,146.8,749.8,139,703.2,139c-0.3,0-0.6,0-1,0l-1.2,0c-4.8,0-18.8,5.2-39.5,14.7
|
||||||
|
C657.8,155.4,654.6,156.9,652.4,158z"/>
|
||||||
|
<path class="st1" d="M364.9,556.4h-36.4c-2.8,0-5.1-2.3-5.1-5.1v-41.6c0-1.7-1.4-3.1-3.1-3.1h-41.6c-2.8,0-5.1-2.3-5.1-5.1v-36.4
|
||||||
|
c0-2.8,2.3-5.1,5.1-5.1h41.6c1.7,0,3.1-1.4,3.1-3.1v-41.6c0-2.8,2.3-5.1,5.1-5.1h36.4c2.8,0,5.1,2.3,5.1,5.1v41.6
|
||||||
|
c0,1.7,1.4,3.1,3.1,3.1h41.6c2.8,0,5.1,2.3,5.1,5.1v36.4c0,2.8-2.3,5.1-5.1,5.1H373c-1.7,0-3.1,1.4-3.1,3.1v41.6
|
||||||
|
C369.9,554.1,367.7,556.4,364.9,556.4z M278.8,462.1c-1.7,0-3.1,1.4-3.1,3.1v36.4c0,1.7,1.4,3.1,3.1,3.1h41.6c2.8,0,5.1,2.3,5.1,5.1
|
||||||
|
v41.6c0,1.7,1.4,3.1,3.1,3.1h36.4c1.7,0,3.1-1.4,3.1-3.1v-41.6c0-2.8,2.3-5.1,5.1-5.1h41.6c1.7,0,3.1-1.4,3.1-3.1v-36.4
|
||||||
|
c0-1.7-1.4-3.1-3.1-3.1H373c-2.8,0-5.1-2.3-5.1-5.1v-41.6c0-1.7-1.4-3.1-3.1-3.1h-36.4c-1.7,0-3.1,1.4-3.1,3.1v41.6
|
||||||
|
c0,2.8-2.3,5.1-5.1,5.1H278.8z"/>
|
||||||
|
<rect x="363.7" y="267.5" class="st1" width="24.4" height="3.5"/>
|
||||||
|
<polygon class="st1" points="636.3,267.5 625.8,267.5 625.8,257.1 622.3,257.1 622.3,267.5 611.9,267.5 611.9,271 622.3,271
|
||||||
|
622.3,281.4 625.8,281.4 625.8,271 636.3,271 "/>
|
||||||
|
<path class="st1" d="M775.5,289.9H771l-6.3-10.4l-6.3,10.4h-4.4l8.6-13.2l-7.9-12.6h4.2l5.9,9.7l5.9-9.7h4l-7.9,12.4L775.5,289.9z"
|
||||||
|
/>
|
||||||
|
<path class="st1" d="M697.8,331.8l-9.3,16.5v9.2h-3.5v-9.3l-9.3-16.5h4.2l5.1,9.4l1.9,3.8l1.7-3.4l5.2-9.8L697.8,331.8z"/>
|
||||||
|
<path class="st1" d="M854,357.5h-3.8l-1.8-5.6h-10.7l-1.8,5.6h-3.6l8.5-25.7h4.8L854,357.5z M847.4,348.8L843,335l-4.4,13.8H847.4z"
|
||||||
|
/>
|
||||||
|
<path class="st1" d="M773.3,417.8c0,1.1-0.2,2.3-0.7,3.3c-0.5,1-1.2,1.8-2,2.4c-1,0.7-2.1,1.2-3.2,1.5c-1.4,0.4-2.8,0.5-4.2,0.5
|
||||||
|
h-6.7v-25.7h7.4c5.7,0,8.6,2.1,8.6,6.3c0,1.3-0.3,2.5-1,3.6c-0.8,1.1-1.9,1.9-3.2,2.2c0.7,0.1,1.4,0.4,2,0.7
|
||||||
|
c0.6,0.3,1.2,0.7,1.6,1.2c0.5,0.5,0.9,1.1,1.1,1.8C773.2,416.2,773.4,417,773.3,417.8z M768.8,406.5c0-0.5-0.1-1-0.2-1.5
|
||||||
|
c-0.2-0.5-0.4-0.9-0.8-1.2c-0.5-0.4-1-0.6-1.6-0.8c-0.8-0.2-1.7-0.3-2.5-0.3H760v8.1h3.5c0.7,0,1.5-0.1,2.2-0.3
|
||||||
|
c0.6-0.1,1.2-0.4,1.7-0.8c0.5-0.3,0.8-0.8,1.1-1.3C768.7,407.8,768.8,407.2,768.8,406.5L768.8,406.5z M769.6,417.9
|
||||||
|
c0-0.6-0.1-1.2-0.4-1.8c-0.3-0.5-0.7-1-1.2-1.3c-0.6-0.4-1.2-0.7-1.9-0.8c-0.8-0.2-1.7-0.3-2.5-0.3H760v8.9h3.7
|
||||||
|
c1.6,0.1,3.2-0.3,4.5-1.1C769.2,420.6,769.7,419.3,769.6,417.9L769.6,417.9z"/>
|
||||||
|
<path class="st1" d="M571.3,329.3L557.7,343h3.9v11.6h19.5V343h3.7L571.3,329.3z M575.2,350.4h-7.7V343h7.7L575.2,350.4z"/>
|
||||||
|
<polygon class="st1" points="346.7,426.4 339.2,439.4 354.2,439.4 "/>
|
||||||
|
<polygon class="st1" points="346.7,540.4 339.2,527.4 354.2,527.4 "/>
|
||||||
|
<polygon class="st1" points="403.7,483.4 390.7,475.9 390.7,490.9 "/>
|
||||||
|
<polygon class="st1" points="289.6,483.4 302.6,475.9 302.6,490.9 "/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 174 KiB |
|
@ -840,8 +840,8 @@
|
||||||
"title": "Joystick Deadzone",
|
"title": "Joystick Deadzone",
|
||||||
"description": "Controller Analog Stick Deadzone",
|
"description": "Controller Analog Stick Deadzone",
|
||||||
"default": 0.05,
|
"default": 0.05,
|
||||||
"minimum": -32768.0,
|
"minimum": 0.00,
|
||||||
"maximum": 32767.0,
|
"maximum": 1.00,
|
||||||
"examples": [
|
"examples": [
|
||||||
0.05
|
0.05
|
||||||
]
|
]
|
||||||
|
|