| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193 |
- using Gtk;
- using Ryujinx.Common.Configuration;
- using Ryujinx.Common.Configuration.Hid;
- using Ryujinx.Common.Configuration.Hid.Controller;
- using Ryujinx.Common.Configuration.Hid.Keyboard;
- using Ryujinx.Common.Utilities;
- using Ryujinx.Configuration;
- using Ryujinx.Input;
- using Ryujinx.Input.GTK3;
- using Ryujinx.Ui.Widgets;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Reflection;
- using System.Text.Json;
- using System.Threading;
- using GUI = Gtk.Builder.ObjectAttribute;
- using Key = Ryujinx.Common.Configuration.Hid.Key;
- using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
- using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
- using Ryujinx.Common.Configuration.Hid.Controller.Motion;
- using Ryujinx.Common.Logging;
- using Ryujinx.Input.Assigner;
- namespace Ryujinx.Ui.Windows
- {
- public class ControllerWindow : Window
- {
- private readonly PlayerIndex _playerIndex;
- private readonly InputConfig _inputConfig;
- private bool _isWaitingForInput;
- #pragma warning disable CS0649, IDE0044
- [GUI] Adjustment _controllerStrongRumble;
- [GUI] Adjustment _controllerWeakRumble;
- [GUI] Adjustment _controllerDeadzoneLeft;
- [GUI] Adjustment _controllerDeadzoneRight;
- [GUI] Adjustment _controllerTriggerThreshold;
- [GUI] Adjustment _slotNumber;
- [GUI] Adjustment _altSlotNumber;
- [GUI] Adjustment _sensitivity;
- [GUI] Adjustment _gyroDeadzone;
- [GUI] CheckButton _enableMotion;
- [GUI] CheckButton _enableCemuHook;
- [GUI] CheckButton _mirrorInput;
- [GUI] Entry _dsuServerHost;
- [GUI] Entry _dsuServerPort;
- [GUI] ComboBoxText _inputDevice;
- [GUI] ComboBoxText _profile;
- [GUI] Box _settingsBox;
- [GUI] Box _motionAltBox;
- [GUI] Box _motionBox;
- [GUI] Box _dsuServerHostBox;
- [GUI] Box _dsuServerPortBox;
- [GUI] Box _motionControllerSlot;
- [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 _lStick;
- [GUI] CheckButton _invertLStickX;
- [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 _rStick;
- [GUI] CheckButton _invertRStickX;
- [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;
- [GUI] CheckButton _enableRumble;
- [GUI] Box _rumbleBox;
- #pragma warning restore CS0649, IDE0044
- private MainWindow _mainWindow;
- private IGamepadDriver _gtk3KeyboardDriver;
- private IGamepad _selectedGamepad;
- private bool _mousePressed;
- private bool _middleMousePressed;
- public ControllerWindow(MainWindow mainWindow, PlayerIndex controllerId) : this(mainWindow, new Builder("Ryujinx.Ui.Windows.ControllerWindow.glade"), controllerId) { }
- private ControllerWindow(MainWindow mainWindow, Builder builder, PlayerIndex controllerId) : base(builder.GetObject("_controllerWin").Handle)
- {
- _mainWindow = mainWindow;
- _selectedGamepad = null;
- // NOTE: To get input in this window, we need to bind a custom keyboard driver instead of using the InputManager one as the main window isn't focused...
- _gtk3KeyboardDriver = new GTK3KeyboardDriver(this);
- Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Logo_Ryujinx.png");
- builder.Autoconnect(this);
- _playerIndex = controllerId;
- _inputConfig = ConfigurationState.Instance.Hid.InputConfig.Value.Find(inputConfig => inputConfig.PlayerIndex == _playerIndex);
- Title = $"Ryujinx - Controller Settings - {_playerIndex}";
- if (_playerIndex == PlayerIndex.Handheld)
- {
- _controllerType.Append(ControllerType.Handheld.ToString(), "Handheld");
- _controllerType.Sensitive = false;
- }
- else
- {
- _controllerType.Append(ControllerType.ProController.ToString(), "Pro Controller");
- _controllerType.Append(ControllerType.JoyconPair.ToString(), "Joycon Pair");
- _controllerType.Append(ControllerType.JoyconLeft.ToString(), "Joycon Left");
- _controllerType.Append(ControllerType.JoyconRight.ToString(), "Joycon Right");
- }
- _controllerType.Active = 0; // Set initial value to first in list.
- // Bind Events.
- _lStick.Clicked += ButtonForStick_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;
- _rStick.Clicked += ButtonForStick_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;
- _enableCemuHook.Clicked += CemuHookCheckButtonPressed;
- // Setup current values.
- UpdateInputDeviceList();
- SetAvailableOptions();
- ClearValues();
- if (_inputDevice.ActiveId != null)
- {
- SetCurrentValues();
- }
- mainWindow.InputManager.GamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
- mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected;
- if (_mainWindow.RendererWidget != null)
- {
- _mainWindow.RendererWidget.NpadManager.BlockInputUpdates();
- }
- }
- private void CemuHookCheckButtonPressed(object sender, EventArgs e)
- {
- UpdateCemuHookSpecificFieldsVisibility();
- }
- private void HandleOnGamepadDisconnected(string id)
- {
- Application.Invoke(delegate
- {
- UpdateInputDeviceList();
- });
- }
- private void HandleOnGamepadConnected(string id)
- {
- Application.Invoke(delegate
- {
- UpdateInputDeviceList();
- });
- }
- protected override void OnDestroyed()
- {
- _mainWindow.InputManager.GamepadDriver.OnGamepadConnected -= HandleOnGamepadConnected;
- _mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected -= HandleOnGamepadDisconnected;
- if (_mainWindow.RendererWidget != null)
- {
- _mainWindow.RendererWidget.NpadManager.UnblockInputUpdates();
- }
- _selectedGamepad?.Dispose();
- _gtk3KeyboardDriver.Dispose();
- }
- private static string GetShrinkedGamepadName(string str)
- {
- const string ShrinkChars = "...";
- const int MaxSize = 50;
- if (str.Length > MaxSize)
- {
- return str.Substring(0, MaxSize - ShrinkChars.Length) + ShrinkChars;
- }
- return str;
- }
- private void UpdateInputDeviceList()
- {
- _inputDevice.RemoveAll();
- _inputDevice.Append("disabled", "Disabled");
- _inputDevice.SetActiveId("disabled");
- foreach (string id in _mainWindow.InputManager.KeyboardDriver.GamepadsIds)
- {
- IGamepad gamepad = _mainWindow.InputManager.KeyboardDriver.GetGamepad(id);
- if (gamepad != null)
- {
- _inputDevice.Append($"keyboard/{id}", GetShrinkedGamepadName($"{gamepad.Name} ({id})"));
- gamepad.Dispose();
- }
- }
- foreach (string id in _mainWindow.InputManager.GamepadDriver.GamepadsIds)
- {
- IGamepad gamepad = _mainWindow.InputManager.GamepadDriver.GetGamepad(id);
- if (gamepad != null)
- {
- _inputDevice.Append($"controller/{id}", GetShrinkedGamepadName($"{gamepad.Name} ({id})"));
- gamepad.Dispose();
- }
- }
- switch (_inputConfig)
- {
- case StandardKeyboardInputConfig keyboard:
- _inputDevice.SetActiveId($"keyboard/{keyboard.Id}");
- break;
- case StandardControllerInputConfig controller:
- _inputDevice.SetActiveId($"controller/{controller.Id}");
- break;
- }
- }
- private void UpdateCemuHookSpecificFieldsVisibility()
- {
- if (_enableCemuHook.Active)
- {
- _dsuServerHostBox.Show();
- _dsuServerPortBox.Show();
- _motionControllerSlot.Show();
- _motionAltBox.Show();
- _mirrorInput.Show();
- }
- else
- {
- _dsuServerHostBox.Hide();
- _dsuServerPortBox.Hide();
- _motionControllerSlot.Hide();
- _motionAltBox.Hide();
- _mirrorInput.Hide();
- }
- }
- private void SetAvailableOptions()
- {
- if (_inputDevice.ActiveId != null && _inputDevice.ActiveId.StartsWith("keyboard"))
- {
- ShowAll();
- _leftStickController.Hide();
- _rightStickController.Hide();
- _deadZoneLeftBox.Hide();
- _deadZoneRightBox.Hide();
- _triggerThresholdBox.Hide();
- _motionBox.Hide();
- _rumbleBox.Hide();
- }
- else if (_inputDevice.ActiveId != null && _inputDevice.ActiveId.StartsWith("controller"))
- {
- ShowAll();
- _leftStickKeyboard.Hide();
- _rightStickKeyboard.Hide();
- UpdateCemuHookSpecificFieldsVisibility();
- }
- else
- {
- _settingsBox.Hide();
- }
- ClearValues();
- }
- private void SetCurrentValues()
- {
- SetControllerSpecificFields();
- SetProfiles();
- if (_inputDevice.ActiveId.StartsWith("keyboard") && _inputConfig is StandardKeyboardInputConfig)
- {
- SetValues(_inputConfig);
- }
- else if (_inputDevice.ActiveId.StartsWith("controller") && _inputConfig is StandardControllerInputConfig)
- {
- SetValues(_inputConfig);
- }
- }
- private void SetControllerSpecificFields()
- {
- _leftSideTriggerBox.Hide();
- _rightSideTriggerBox.Hide();
- _motionAltBox.Hide();
- switch (_controllerType.ActiveId)
- {
- case "JoyconLeft":
- _leftSideTriggerBox.Show();
- break;
- case "JoyconRight":
- _rightSideTriggerBox.Show();
- break;
- case "JoyconPair":
- _motionAltBox.Show();
- break;
- }
- _controllerImage.Pixbuf = _controllerType.ActiveId switch
- {
- "ProController" => new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Controller_ProCon.svg", 400, 400),
- "JoyconLeft" => new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Controller_JoyConLeft.svg", 400, 500),
- "JoyconRight" => new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Controller_JoyConRight.svg", 400, 500),
- _ => new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.Resources.Controller_JoyConPair.svg", 400, 500),
- };
- }
- private void ClearValues()
- {
- _lStick.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";
- _rStick.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";
- _controllerStrongRumble.Value = 1;
- _controllerWeakRumble.Value = 1;
- _controllerDeadzoneLeft.Value = 0;
- _controllerDeadzoneRight.Value = 0;
- _controllerTriggerThreshold.Value = 0;
- _mirrorInput.Active = false;
- _enableMotion.Active = false;
- _enableCemuHook.Active = false;
- _slotNumber.Value = 0;
- _altSlotNumber.Value = 0;
- _sensitivity.Value = 100;
- _gyroDeadzone.Value = 1;
- _dsuServerHost.Buffer.Text = "";
- _dsuServerPort.Buffer.Text = "";
- _enableRumble.Active = false;
- }
- private void SetValues(InputConfig config)
- {
- switch (config)
- {
- case StandardKeyboardInputConfig keyboardConfig:
- if (!_controllerType.SetActiveId(keyboardConfig.ControllerType.ToString()))
- {
- _controllerType.SetActiveId(_playerIndex == PlayerIndex.Handheld
- ? ControllerType.Handheld.ToString()
- : ControllerType.ProController.ToString());
- }
- _lStickUp.Label = keyboardConfig.LeftJoyconStick.StickUp.ToString();
- _lStickDown.Label = keyboardConfig.LeftJoyconStick.StickDown.ToString();
- _lStickLeft.Label = keyboardConfig.LeftJoyconStick.StickLeft.ToString();
- _lStickRight.Label = keyboardConfig.LeftJoyconStick.StickRight.ToString();
- _lStickButton.Label = keyboardConfig.LeftJoyconStick.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.RightJoyconStick.StickUp.ToString();
- _rStickDown.Label = keyboardConfig.RightJoyconStick.StickDown.ToString();
- _rStickLeft.Label = keyboardConfig.RightJoyconStick.StickLeft.ToString();
- _rStickRight.Label = keyboardConfig.RightJoyconStick.StickRight.ToString();
- _rStickButton.Label = keyboardConfig.RightJoyconStick.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 StandardControllerInputConfig controllerConfig:
- if (!_controllerType.SetActiveId(controllerConfig.ControllerType.ToString()))
- {
- _controllerType.SetActiveId(_playerIndex == PlayerIndex.Handheld
- ? ControllerType.Handheld.ToString()
- : ControllerType.ProController.ToString());
- }
- _lStick.Label = controllerConfig.LeftJoyconStick.Joystick.ToString();
- _invertLStickX.Active = controllerConfig.LeftJoyconStick.InvertStickX;
- _invertLStickY.Active = controllerConfig.LeftJoyconStick.InvertStickY;
- _lStickButton.Label = controllerConfig.LeftJoyconStick.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();
- _rStick.Label = controllerConfig.RightJoyconStick.Joystick.ToString();
- _invertRStickX.Active = controllerConfig.RightJoyconStick.InvertStickX;
- _invertRStickY.Active = controllerConfig.RightJoyconStick.InvertStickY;
- _rStickButton.Label = controllerConfig.RightJoyconStick.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();
- _controllerStrongRumble.Value = controllerConfig.Rumble.StrongRumble;
- _controllerWeakRumble.Value = controllerConfig.Rumble.WeakRumble;
- _enableRumble.Active = controllerConfig.Rumble.EnableRumble;
- _controllerDeadzoneLeft.Value = controllerConfig.DeadzoneLeft;
- _controllerDeadzoneRight.Value = controllerConfig.DeadzoneRight;
- _controllerTriggerThreshold.Value = controllerConfig.TriggerThreshold;
- _sensitivity.Value = controllerConfig.Motion.Sensitivity;
- _gyroDeadzone.Value = controllerConfig.Motion.GyroDeadzone;
- _enableMotion.Active = controllerConfig.Motion.EnableMotion;
- _enableCemuHook.Active = controllerConfig.Motion.MotionBackend == MotionInputBackendType.CemuHook;
- if (controllerConfig.Motion is CemuHookMotionConfigController cemuHookMotionConfig)
- {
- _slotNumber.Value = cemuHookMotionConfig.Slot;
- _altSlotNumber.Value = cemuHookMotionConfig.AltSlot;
- _mirrorInput.Active = cemuHookMotionConfig.MirrorInput;
- _dsuServerHost.Buffer.Text = cemuHookMotionConfig.DsuServerHost;
- _dsuServerPort.Buffer.Text = cemuHookMotionConfig.DsuServerPort.ToString();
- }
- 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 StandardKeyboardInputConfig
- {
- Backend = InputBackendType.WindowKeyboard,
- Version = InputConfig.CurrentVersion,
- Id = _inputDevice.ActiveId.Split("/")[1],
- ControllerType = Enum.Parse<ControllerType>(_controllerType.ActiveId),
- PlayerIndex = _playerIndex,
- LeftJoycon = new LeftJoyconCommonConfig<Key>
- {
- ButtonMinus = lButtonMinus,
- ButtonL = lButtonL,
- ButtonZl = lButtonZl,
- ButtonSl = lButtonSl,
- ButtonSr = lButtonSr,
- DpadUp = lDPadUp,
- DpadDown = lDPadDown,
- DpadLeft = lDPadLeft,
- DpadRight = lDPadRight
- },
- LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
- {
- StickUp = lStickUp,
- StickDown = lStickDown,
- StickLeft = lStickLeft,
- StickRight = lStickRight,
- StickButton = lStickButton,
- },
- RightJoycon = new RightJoyconCommonConfig<Key>
- {
- ButtonA = rButtonA,
- ButtonB = rButtonB,
- ButtonX = rButtonX,
- ButtonY = rButtonY,
- ButtonPlus = rButtonPlus,
- ButtonR = rButtonR,
- ButtonZr = rButtonZr,
- ButtonSl = rButtonSl,
- ButtonSr = rButtonSr
- },
- RightJoyconStick = new JoyconConfigKeyboardStick<Key>
- {
- StickUp = rStickUp,
- StickDown = rStickDown,
- StickLeft = rStickLeft,
- StickRight = rStickRight,
- StickButton = rStickButton,
- },
- };
- }
-
- if (_inputDevice.ActiveId.StartsWith("controller"))
- {
- Enum.TryParse(_lStick.Label, out ConfigStickInputId lStick);
- Enum.TryParse(_lStickButton.Label, out ConfigGamepadInputId lStickButton);
- Enum.TryParse(_minus.Label, out ConfigGamepadInputId lButtonMinus);
- Enum.TryParse(_l.Label, out ConfigGamepadInputId lButtonL);
- Enum.TryParse(_zL.Label, out ConfigGamepadInputId lButtonZl);
- Enum.TryParse(_lSl.Label, out ConfigGamepadInputId lButtonSl);
- Enum.TryParse(_lSr.Label, out ConfigGamepadInputId lButtonSr);
- Enum.TryParse(_dpadUp.Label, out ConfigGamepadInputId lDPadUp);
- Enum.TryParse(_dpadDown.Label, out ConfigGamepadInputId lDPadDown);
- Enum.TryParse(_dpadLeft.Label, out ConfigGamepadInputId lDPadLeft);
- Enum.TryParse(_dpadRight.Label, out ConfigGamepadInputId lDPadRight);
- Enum.TryParse(_rStick.Label, out ConfigStickInputId rStick);
- Enum.TryParse(_rStickButton.Label, out ConfigGamepadInputId rStickButton);
- Enum.TryParse(_a.Label, out ConfigGamepadInputId rButtonA);
- Enum.TryParse(_b.Label, out ConfigGamepadInputId rButtonB);
- Enum.TryParse(_x.Label, out ConfigGamepadInputId rButtonX);
- Enum.TryParse(_y.Label, out ConfigGamepadInputId rButtonY);
- Enum.TryParse(_plus.Label, out ConfigGamepadInputId rButtonPlus);
- Enum.TryParse(_r.Label, out ConfigGamepadInputId rButtonR);
- Enum.TryParse(_zR.Label, out ConfigGamepadInputId rButtonZr);
- Enum.TryParse(_rSl.Label, out ConfigGamepadInputId rButtonSl);
- Enum.TryParse(_rSr.Label, out ConfigGamepadInputId rButtonSr);
- int.TryParse(_dsuServerPort.Buffer.Text, out int port);
- MotionConfigController motionConfig;
- if (_enableCemuHook.Active)
- {
- motionConfig = new CemuHookMotionConfigController
- {
- MotionBackend = MotionInputBackendType.CemuHook,
- EnableMotion = _enableMotion.Active,
- Sensitivity = (int)_sensitivity.Value,
- GyroDeadzone = _gyroDeadzone.Value,
- MirrorInput = _mirrorInput.Active,
- Slot = (int)_slotNumber.Value,
- AltSlot = (int)_altSlotNumber.Value,
- DsuServerHost = _dsuServerHost.Buffer.Text,
- DsuServerPort = port
- };
- }
- else
- {
- motionConfig = new StandardMotionConfigController
- {
- MotionBackend = MotionInputBackendType.GamepadDriver,
- EnableMotion = _enableMotion.Active,
- Sensitivity = (int)_sensitivity.Value,
- GyroDeadzone = _gyroDeadzone.Value,
- };
- }
- return new StandardControllerInputConfig
- {
- Backend = InputBackendType.GamepadSDL2,
- Version = InputConfig.CurrentVersion,
- Id = _inputDevice.ActiveId.Split("/")[1].Split(" ")[0],
- ControllerType = Enum.Parse<ControllerType>(_controllerType.ActiveId),
- PlayerIndex = _playerIndex,
- DeadzoneLeft = (float)_controllerDeadzoneLeft.Value,
- DeadzoneRight = (float)_controllerDeadzoneRight.Value,
- TriggerThreshold = (float)_controllerTriggerThreshold.Value,
- LeftJoycon = new LeftJoyconCommonConfig<ConfigGamepadInputId>
- {
- ButtonMinus = lButtonMinus,
- ButtonL = lButtonL,
- ButtonZl = lButtonZl,
- ButtonSl = lButtonSl,
- ButtonSr = lButtonSr,
- DpadUp = lDPadUp,
- DpadDown = lDPadDown,
- DpadLeft = lDPadLeft,
- DpadRight = lDPadRight
- },
- LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
- {
- InvertStickX = _invertLStickX.Active,
- Joystick = lStick,
- InvertStickY = _invertLStickY.Active,
- StickButton = lStickButton,
- },
- RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
- {
- ButtonA = rButtonA,
- ButtonB = rButtonB,
- ButtonX = rButtonX,
- ButtonY = rButtonY,
- ButtonPlus = rButtonPlus,
- ButtonR = rButtonR,
- ButtonZr = rButtonZr,
- ButtonSl = rButtonSl,
- ButtonSr = rButtonSr
- },
- RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
- {
- InvertStickX = _invertRStickX.Active,
- Joystick = rStick,
- InvertStickY = _invertRStickY.Active,
- StickButton = rStickButton,
- },
- Motion = motionConfig,
- Rumble = new RumbleConfigController
- {
- StrongRumble = (float)_controllerStrongRumble.Value,
- WeakRumble = (float)_controllerWeakRumble.Value,
- EnableRumble = _enableRumble.Active
- }
- };
- }
- if (!_inputDevice.ActiveId.StartsWith("disabled"))
- {
- GtkDialog.CreateErrorDialog("Invalid data detected in one or more fields; the configuration was not saved.");
- }
- return null;
- }
- private string GetProfileBasePath()
- {
- if (_inputDevice.ActiveId.StartsWith("keyboard"))
- {
- return System.IO.Path.Combine(AppDataManager.ProfilesDirPath, "keyboard");
- }
- else if (_inputDevice.ActiveId.StartsWith("controller"))
- {
- return System.IO.Path.Combine(AppDataManager.ProfilesDirPath, "controller");
- }
- return AppDataManager.ProfilesDirPath;
- }
- //
- // Events
- //
- private void InputDevice_Changed(object sender, EventArgs args)
- {
- SetAvailableOptions();
- SetControllerSpecificFields();
- _selectedGamepad?.Dispose();
- _selectedGamepad = null;
- if (_inputDevice.ActiveId != null)
- {
- SetProfiles();
- string id = GetCurrentGamepadId();
- if (_inputDevice.ActiveId.StartsWith("keyboard"))
- {
- if (_inputConfig is StandardKeyboardInputConfig)
- {
- SetValues(_inputConfig);
- }
- if (_mainWindow.InputManager.KeyboardDriver is GTK3KeyboardDriver)
- {
- // NOTE: To get input in this window, we need to bind a custom keyboard driver instead of using the InputManager one as the main window isn't focused...
- _selectedGamepad = _gtk3KeyboardDriver.GetGamepad(id);
- }
- else
- {
- _selectedGamepad = _mainWindow.InputManager.KeyboardDriver.GetGamepad(id);
- }
- }
- else if (_inputDevice.ActiveId.StartsWith("controller"))
- {
- if (_inputConfig is StandardControllerInputConfig)
- {
- SetValues(_inputConfig);
- }
- _selectedGamepad = _mainWindow.InputManager.GamepadDriver.GetGamepad(id);
- }
- }
- }
- private string GetCurrentGamepadId()
- {
- if (_inputDevice.ActiveId == null || _inputDevice.ActiveId == "disabled")
- {
- return null;
- }
- return _inputDevice.ActiveId.Split("/")[1].Split(" ")[0];
- }
- private void Controller_Changed(object sender, EventArgs args)
- {
- SetControllerSpecificFields();
- }
- private IButtonAssigner CreateButtonAssigner(bool forStick)
- {
- IButtonAssigner assigner;
- if (_inputDevice.ActiveId.StartsWith("keyboard"))
- {
- assigner = new KeyboardKeyAssigner((IKeyboard)_selectedGamepad);
- }
- else if (_inputDevice.ActiveId.StartsWith("controller"))
- {
- assigner = new GamepadButtonAssigner(_selectedGamepad, (float)_controllerTriggerThreshold.Value, forStick);
- }
- else
- {
- throw new Exception("Controller not supported");
- }
-
- return assigner;
- }
- private void HandleButtonPressed(ToggleButton button, bool forStick)
- {
- if (_isWaitingForInput)
- {
- button.Active = false;
- return;
- }
- _mousePressed = false;
- ButtonPressEvent += MouseClick;
- IButtonAssigner assigner = CreateButtonAssigner(forStick);
- _isWaitingForInput = true;
- // Open GTK3 keyboard for cancel operations
- IKeyboard keyboard = (IKeyboard)_gtk3KeyboardDriver.GetGamepad("0");
- Thread inputThread = new Thread(() =>
- {
- assigner.Initialize();
- while (true)
- {
- Thread.Sleep(10);
- assigner.ReadInput();
- if (_mousePressed || keyboard.IsPressed(Ryujinx.Input.Key.Escape) || assigner.HasAnyButtonPressed() || assigner.ShouldCancel())
- {
- break;
- }
- }
- string pressedButton = assigner.GetPressedButton();
- Application.Invoke(delegate
- {
- if (_middleMousePressed)
- {
- button.Label = "Unbound";
- }
- else if (pressedButton != "")
- {
- button.Label = pressedButton;
- }
- _middleMousePressed = false;
- ButtonPressEvent -= MouseClick;
- keyboard.Dispose();
- button.Active = false;
- _isWaitingForInput = false;
- });
- });
- inputThread.Name = "GUI.InputThread";
- inputThread.IsBackground = true;
- inputThread.Start();
- }
- private void Button_Pressed(object sender, EventArgs args)
- {
- HandleButtonPressed((ToggleButton)sender, false);
- }
- private void ButtonForStick_Pressed(object sender, EventArgs args)
- {
- HandleButtonPressed((ToggleButton)sender, true);
- }
- private void MouseClick(object sender, ButtonPressEventArgs args)
- {
- _mousePressed = true;
- _middleMousePressed = args.Event.Button == 2;
- }
- private void SetProfiles()
- {
- _profile.RemoveAll();
- string basePath = GetProfileBasePath();
- if (!Directory.Exists(basePath))
- {
- Directory.CreateDirectory(basePath);
- }
- if (_inputDevice.ActiveId == null|| _inputDevice.ActiveId.Equals("disabled"))
- {
- _profile.Append("default", "None");
- }
- else
- {
- _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));
- }
- }
- _profile.SetActiveId("default");
- }
- private void ProfileLoad_Activated(object sender, EventArgs args)
- {
- ((ToggleButton)sender).SetStateFlags(StateFlags.Normal, 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 StandardKeyboardInputConfig
- {
- Version = InputConfig.CurrentVersion,
- Backend = InputBackendType.WindowKeyboard,
- Id = null,
- ControllerType = ControllerType.ProController,
- LeftJoycon = new LeftJoyconCommonConfig<Key>
- {
- 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
- },
- LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
- {
- StickUp = Key.W,
- StickDown = Key.S,
- StickLeft = Key.A,
- StickRight = Key.D,
- StickButton = Key.F,
- },
- RightJoycon = new RightJoyconCommonConfig<Key>
- {
- 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
- },
- RightJoyconStick = new JoyconConfigKeyboardStick<Key>
- {
- StickUp = Key.I,
- StickDown = Key.K,
- StickLeft = Key.J,
- StickRight = Key.L,
- StickButton = Key.H,
- }
- };
- }
- else if (_inputDevice.ActiveId.StartsWith("controller"))
- {
- bool isNintendoStyle = _inputDevice.ActiveText.Contains("Nintendo");
- config = new StandardControllerInputConfig
- {
- Version = InputConfig.CurrentVersion,
- Backend = InputBackendType.GamepadSDL2,
- Id = null,
- ControllerType = ControllerType.JoyconPair,
- DeadzoneLeft = 0.1f,
- DeadzoneRight = 0.1f,
- TriggerThreshold = 0.5f,
- LeftJoycon = new LeftJoyconCommonConfig<ConfigGamepadInputId>
- {
- DpadUp = ConfigGamepadInputId.DpadUp,
- DpadDown = ConfigGamepadInputId.DpadDown,
- DpadLeft = ConfigGamepadInputId.DpadLeft,
- DpadRight = ConfigGamepadInputId.DpadRight,
- ButtonMinus = ConfigGamepadInputId.Minus,
- ButtonL = ConfigGamepadInputId.LeftShoulder,
- ButtonZl = ConfigGamepadInputId.LeftTrigger,
- ButtonSl = ConfigGamepadInputId.Unbound,
- ButtonSr = ConfigGamepadInputId.Unbound,
- },
- LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
- {
- Joystick = ConfigStickInputId.Left,
- StickButton = ConfigGamepadInputId.LeftStick,
- InvertStickX = false,
- InvertStickY = false,
- },
- RightJoycon = new RightJoyconCommonConfig<ConfigGamepadInputId>
- {
- ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B,
- ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A,
- ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y,
- ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X,
- ButtonPlus = ConfigGamepadInputId.Plus,
- ButtonR = ConfigGamepadInputId.RightShoulder,
- ButtonZr = ConfigGamepadInputId.RightTrigger,
- ButtonSl = ConfigGamepadInputId.Unbound,
- ButtonSr = ConfigGamepadInputId.Unbound,
- },
- RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
- {
- Joystick = ConfigStickInputId.Right,
- StickButton = ConfigGamepadInputId.RightStick,
- InvertStickX = false,
- InvertStickY = false,
- },
- Motion = new StandardMotionConfigController
- {
- MotionBackend = MotionInputBackendType.GamepadDriver,
- EnableMotion = true,
- Sensitivity = 100,
- GyroDeadzone = 1,
- },
- Rumble = new RumbleConfigController
- {
- StrongRumble = 1f,
- WeakRumble = 1f,
- EnableRumble = false
- }
- };
- }
- }
- else
- {
- string path = System.IO.Path.Combine(GetProfileBasePath(), _profile.ActiveId);
- if (!File.Exists(path))
- {
- if (pos >= 0)
- {
- _profile.Remove(pos);
- }
- return;
- }
- try
- {
- using (Stream stream = File.OpenRead(path))
- {
- config = JsonHelper.Deserialize<InputConfig>(stream);
- }
- }
- catch (JsonException) { }
- }
- SetValues(config);
- }
- private void ProfileAdd_Activated(object sender, EventArgs args)
- {
- ((ToggleButton)sender).SetStateFlags(StateFlags.Normal, 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;
- jsonString = JsonHelper.Serialize(inputConfig, true);
- File.WriteAllText(path, jsonString);
- }
- profileDialog.Dispose();
- SetProfiles();
- }
- private void ProfileRemove_Activated(object sender, EventArgs args)
- {
- ((ToggleButton) sender).SetStateFlags(StateFlags.Normal, true);
- if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == "default" || _profile.ActiveId == null) return;
- MessageDialog confirmDialog = GtkDialog.CreateConfirmationDialog("Deleting Profile", "This action is irreversible, are you 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();
- var newConfig = new List<InputConfig>();
- newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
- if (_inputConfig == null && inputConfig != null)
- {
- newConfig.Add(inputConfig);
- }
- else
- {
- if (_inputDevice.ActiveId == "disabled")
- {
- newConfig.Remove(_inputConfig);
- }
- else if (inputConfig != null)
- {
- int index = newConfig.IndexOf(_inputConfig);
- newConfig[index] = inputConfig;
- }
- }
- if (_mainWindow.RendererWidget != null)
- {
- _mainWindow.RendererWidget.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
- }
- // Atomically replace and signal input change.
- // NOTE: Do not modify InputConfig.Value directly as other code depends on the on-change event.
- ConfigurationState.Instance.Hid.InputConfig.Value = newConfig;
- ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
- Dispose();
- }
- private void CloseToggle_Activated(object sender, EventArgs args)
- {
- Dispose();
- }
- }
- }
|