2020-05-02 22:00:53 -04:00
using Gtk ;
2020-08-30 12:51:53 -04:00
using Ryujinx.Common.Configuration ;
2020-05-03 14:42:17 -04:00
using Ryujinx.Common.Configuration.Hid ;
2021-04-14 06:28:43 -04:00
using Ryujinx.Common.Configuration.Hid.Controller ;
2023-03-04 08:43:08 -05:00
using Ryujinx.Common.Configuration.Hid.Controller.Motion ;
2021-04-14 06:28:43 -04:00
using Ryujinx.Common.Configuration.Hid.Keyboard ;
2023-03-04 08:43:08 -05:00
using Ryujinx.Common.Logging ;
2020-05-03 14:42:17 -04:00
using Ryujinx.Common.Utilities ;
2021-04-14 06:28:43 -04:00
using Ryujinx.Input ;
2023-03-04 08:43:08 -05:00
using Ryujinx.Input.Assigner ;
2021-04-14 06:28:43 -04:00
using Ryujinx.Input.GTK3 ;
2023-03-04 08:43:08 -05:00
using Ryujinx.Ui.Common.Configuration ;
2021-01-08 03:14:13 -05:00
using Ryujinx.Ui.Widgets ;
2020-05-02 22:00:53 -04:00
using System ;
2020-08-23 16:54:11 -04:00
using System.Collections.Generic ;
2020-05-02 22:00:53 -04:00
using System.IO ;
using System.Reflection ;
2020-05-03 14:42:17 -04:00
using System.Text.Json ;
2020-05-02 22:00:53 -04:00
using System.Threading ;
2021-04-14 06:28:43 -04:00
using ConfigGamepadInputId = Ryujinx . Common . Configuration . Hid . Controller . GamepadInputId ;
using ConfigStickInputId = Ryujinx . Common . Configuration . Hid . Controller . StickInputId ;
2023-03-04 08:43:08 -05:00
using GUI = Gtk . Builder . ObjectAttribute ;
using Key = Ryujinx . Common . Configuration . Hid . Key ;
2020-05-02 22:00:53 -04:00
2021-01-08 03:14:13 -05:00
namespace Ryujinx.Ui.Windows
2020-05-02 22:00:53 -04:00
{
public class ControllerWindow : Window
{
2021-01-08 03:14:13 -05:00
private readonly PlayerIndex _playerIndex ;
private readonly InputConfig _inputConfig ;
private bool _isWaitingForInput ;
2020-05-02 22:00:53 -04:00
#pragma warning disable CS0649 , IDE0044
2021-08-04 18:39:40 -04:00
[GUI] Adjustment _controllerStrongRumble ;
[GUI] Adjustment _controllerWeakRumble ;
2020-05-02 22:00:53 -04:00
[GUI] Adjustment _controllerDeadzoneLeft ;
[GUI] Adjustment _controllerDeadzoneRight ;
2022-01-03 06:49:29 -05:00
[GUI] Adjustment _controllerRangeLeft ;
[GUI] Adjustment _controllerRangeRight ;
2020-05-02 22:00:53 -04:00
[GUI] Adjustment _controllerTriggerThreshold ;
2020-09-29 17:32:42 -04:00
[GUI] Adjustment _slotNumber ;
[GUI] Adjustment _altSlotNumber ;
[GUI] Adjustment _sensitivity ;
[GUI] Adjustment _gyroDeadzone ;
[GUI] CheckButton _enableMotion ;
2021-04-14 06:28:43 -04:00
[GUI] CheckButton _enableCemuHook ;
2020-09-29 17:32:42 -04:00
[GUI] CheckButton _mirrorInput ;
[GUI] Entry _dsuServerHost ;
[GUI] Entry _dsuServerPort ;
2020-05-02 22:00:53 -04:00
[GUI] ComboBoxText _inputDevice ;
[GUI] ComboBoxText _profile ;
[GUI] Box _settingsBox ;
2021-04-14 06:28:43 -04:00
[GUI] Box _motionAltBox ;
[GUI] Box _motionBox ;
[GUI] Box _dsuServerHostBox ;
[GUI] Box _dsuServerPortBox ;
[GUI] Box _motionControllerSlot ;
2020-05-02 22:00:53 -04:00
[GUI] Grid _leftStickKeyboard ;
[GUI] Grid _leftStickController ;
[GUI] Box _deadZoneLeftBox ;
2022-01-03 06:49:29 -05:00
[GUI] Box _rangeLeftBox ;
2020-05-02 22:00:53 -04:00
[GUI] Grid _rightStickKeyboard ;
[GUI] Grid _rightStickController ;
[GUI] Box _deadZoneRightBox ;
2022-01-03 06:49:29 -05:00
[GUI] Box _rangeRightBox ;
2020-05-02 22:00:53 -04:00
[GUI] Grid _leftSideTriggerBox ;
[GUI] Grid _rightSideTriggerBox ;
[GUI] Box _triggerThresholdBox ;
[GUI] ComboBoxText _controllerType ;
2021-04-14 06:28:43 -04:00
[GUI] ToggleButton _lStick ;
2020-05-02 22:00:53 -04:00
[GUI] CheckButton _invertLStickX ;
[GUI] CheckButton _invertLStickY ;
2022-03-12 12:23:48 -05:00
[GUI] CheckButton _rotateL90CW ;
2020-05-02 22:00:53 -04:00
[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 ;
2021-04-14 06:28:43 -04:00
[GUI] ToggleButton _rStick ;
2020-05-02 22:00:53 -04:00
[GUI] CheckButton _invertRStickX ;
[GUI] CheckButton _invertRStickY ;
2022-03-12 12:23:48 -05:00
[GUI] CheckButton _rotateR90CW ;
2020-05-02 22:00:53 -04:00
[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 ;
2021-08-04 18:39:40 -04:00
[GUI] CheckButton _enableRumble ;
[GUI] Box _rumbleBox ;
2020-05-02 22:00:53 -04:00
#pragma warning restore CS0649 , IDE0044
2021-04-14 06:28:43 -04:00
private MainWindow _mainWindow ;
private IGamepadDriver _gtk3KeyboardDriver ;
private IGamepad _selectedGamepad ;
private bool _mousePressed ;
2021-06-23 16:51:29 -04:00
private bool _middleMousePressed ;
2021-04-14 06:28:43 -04:00
2023-03-21 18:41:19 -04:00
private static readonly InputConfigJsonSerializerContext SerializerContext = new ( JsonHelper . GetDefaultSerializerOptions ( ) ) ;
2021-04-14 06:28:43 -04:00
public ControllerWindow ( MainWindow mainWindow , PlayerIndex controllerId ) : this ( mainWindow , new Builder ( "Ryujinx.Ui.Windows.ControllerWindow.glade" ) , controllerId ) { }
2020-05-02 22:00:53 -04:00
2022-12-06 17:00:25 -05:00
private ControllerWindow ( MainWindow mainWindow , Builder builder , PlayerIndex controllerId ) : base ( builder . GetRawOwnedObject ( "_controllerWin" ) )
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
_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 ) ;
2022-05-15 07:30:15 -04:00
Icon = new Gdk . Pixbuf ( Assembly . GetAssembly ( typeof ( ConfigurationState ) ) , "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png" ) ;
2021-01-18 15:33:58 -05:00
2020-05-02 22:00:53 -04:00
builder . Autoconnect ( this ) ;
2021-01-08 03:14:13 -05:00
_playerIndex = controllerId ;
_inputConfig = ConfigurationState . Instance . Hid . InputConfig . Value . Find ( inputConfig = > inputConfig . PlayerIndex = = _playerIndex ) ;
2020-05-02 22:00:53 -04:00
2020-08-23 16:54:11 -04:00
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.
2021-01-08 03:14:13 -05:00
// Bind Events.
2021-04-14 06:28:43 -04:00
_lStick . Clicked + = ButtonForStick_Pressed ;
2020-05-02 22:00:53 -04:00
_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 ;
2021-04-14 06:28:43 -04:00
_rStick . Clicked + = ButtonForStick_Pressed ;
2020-05-02 22:00:53 -04:00
_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 ;
2021-04-14 06:28:43 -04:00
_enableCemuHook . Clicked + = CemuHookCheckButtonPressed ;
2020-05-02 22:00:53 -04:00
2021-01-08 03:14:13 -05:00
// Setup current values.
2020-05-02 22:00:53 -04:00
UpdateInputDeviceList ( ) ;
SetAvailableOptions ( ) ;
ClearValues ( ) ;
2021-01-08 03:14:13 -05:00
if ( _inputDevice . ActiveId ! = null )
{
SetCurrentValues ( ) ;
}
2021-04-14 06:28:43 -04:00
mainWindow . InputManager . GamepadDriver . OnGamepadConnected + = HandleOnGamepadConnected ;
mainWindow . InputManager . GamepadDriver . OnGamepadDisconnected + = HandleOnGamepadDisconnected ;
2021-05-04 12:19:04 -04:00
if ( _mainWindow . RendererWidget ! = null )
2021-04-14 06:28:43 -04:00
{
2021-05-04 12:19:04 -04:00
_mainWindow . RendererWidget . NpadManager . BlockInputUpdates ( ) ;
2021-04-14 06:28:43 -04:00
}
}
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 ;
2021-05-04 12:19:04 -04:00
if ( _mainWindow . RendererWidget ! = null )
2021-04-14 06:28:43 -04:00
{
2021-05-04 12:19:04 -04:00
_mainWindow . RendererWidget . NpadManager . UnblockInputUpdates ( ) ;
2021-04-14 06:28:43 -04:00
}
_selectedGamepad ? . Dispose ( ) ;
_gtk3KeyboardDriver . Dispose ( ) ;
}
2022-07-05 14:06:31 -04:00
private static string GetShortGamepadName ( string str )
2021-04-14 06:28:43 -04:00
{
2021-07-06 14:55:03 -04:00
const string ShrinkChars = "..." ;
const int MaxSize = 50 ;
2021-04-14 06:28:43 -04:00
2021-07-06 14:55:03 -04:00
if ( str . Length > MaxSize )
2021-04-14 06:28:43 -04:00
{
2023-01-18 17:25:16 -05:00
return $"{str.AsSpan(0, MaxSize - ShrinkChars.Length)}{ShrinkChars}" ;
2021-04-14 06:28:43 -04:00
}
return str ;
2020-05-02 22:00:53 -04:00
}
private void UpdateInputDeviceList ( )
{
_inputDevice . RemoveAll ( ) ;
_inputDevice . Append ( "disabled" , "Disabled" ) ;
_inputDevice . SetActiveId ( "disabled" ) ;
2021-04-14 06:28:43 -04:00
foreach ( string id in _mainWindow . InputManager . KeyboardDriver . GamepadsIds )
{
IGamepad gamepad = _mainWindow . InputManager . KeyboardDriver . GetGamepad ( id ) ;
if ( gamepad ! = null )
{
2022-07-05 14:06:31 -04:00
_inputDevice . Append ( $"keyboard/{id}" , GetShortGamepadName ( $"{gamepad.Name} ({id})" ) ) ;
2021-04-14 06:28:43 -04:00
gamepad . Dispose ( ) ;
}
}
2020-05-03 09:00:29 -04:00
2021-04-14 06:28:43 -04:00
foreach ( string id in _mainWindow . InputManager . GamepadDriver . GamepadsIds )
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
IGamepad gamepad = _mainWindow . InputManager . GamepadDriver . GetGamepad ( id ) ;
2020-05-02 22:00:53 -04:00
2021-04-14 06:28:43 -04:00
if ( gamepad ! = null )
{
2022-07-05 14:06:31 -04:00
_inputDevice . Append ( $"controller/{id}" , GetShortGamepadName ( $"{gamepad.Name} ({id})" ) ) ;
2021-04-14 06:28:43 -04:00
gamepad . Dispose ( ) ;
}
2020-05-02 22:00:53 -04:00
}
switch ( _inputConfig )
{
2021-04-14 06:28:43 -04:00
case StandardKeyboardInputConfig keyboard :
_inputDevice . SetActiveId ( $"keyboard/{keyboard.Id}" ) ;
2020-05-02 22:00:53 -04:00
break ;
2021-04-14 06:28:43 -04:00
case StandardControllerInputConfig controller :
_inputDevice . SetActiveId ( $"controller/{controller.Id}" ) ;
2020-05-02 22:00:53 -04:00
break ;
}
}
2021-04-14 06:28:43 -04:00
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 ( ) ;
}
}
2020-05-02 22:00:53 -04:00
private void SetAvailableOptions ( )
{
if ( _inputDevice . ActiveId ! = null & & _inputDevice . ActiveId . StartsWith ( "keyboard" ) )
{
2021-01-08 03:14:13 -05:00
ShowAll ( ) ;
2020-05-02 22:00:53 -04:00
_leftStickController . Hide ( ) ;
_rightStickController . Hide ( ) ;
_deadZoneLeftBox . Hide ( ) ;
_deadZoneRightBox . Hide ( ) ;
2022-01-03 06:49:29 -05:00
_rangeLeftBox . Hide ( ) ;
_rangeRightBox . Hide ( ) ;
2020-05-02 22:00:53 -04:00
_triggerThresholdBox . Hide ( ) ;
2021-04-14 06:28:43 -04:00
_motionBox . Hide ( ) ;
2021-08-04 18:39:40 -04:00
_rumbleBox . Hide ( ) ;
2020-05-02 22:00:53 -04:00
}
else if ( _inputDevice . ActiveId ! = null & & _inputDevice . ActiveId . StartsWith ( "controller" ) )
{
2021-01-08 03:14:13 -05:00
ShowAll ( ) ;
2020-05-02 22:00:53 -04:00
_leftStickKeyboard . Hide ( ) ;
_rightStickKeyboard . Hide ( ) ;
2021-04-14 06:28:43 -04:00
UpdateCemuHookSpecificFieldsVisibility ( ) ;
2020-05-02 22:00:53 -04:00
}
else
{
_settingsBox . Hide ( ) ;
}
ClearValues ( ) ;
}
private void SetCurrentValues ( )
{
SetControllerSpecificFields ( ) ;
SetProfiles ( ) ;
2021-04-14 06:28:43 -04:00
if ( _inputDevice . ActiveId . StartsWith ( "keyboard" ) & & _inputConfig is StandardKeyboardInputConfig )
2020-05-02 22:00:53 -04:00
{
SetValues ( _inputConfig ) ;
}
2021-04-14 06:28:43 -04:00
else if ( _inputDevice . ActiveId . StartsWith ( "controller" ) & & _inputConfig is StandardControllerInputConfig )
2020-05-02 22:00:53 -04:00
{
SetValues ( _inputConfig ) ;
}
}
private void SetControllerSpecificFields ( )
{
_leftSideTriggerBox . Hide ( ) ;
_rightSideTriggerBox . Hide ( ) ;
2021-04-14 06:28:43 -04:00
_motionAltBox . Hide ( ) ;
2020-05-02 22:00:53 -04:00
switch ( _controllerType . ActiveId )
{
case "JoyconLeft" :
_leftSideTriggerBox . Show ( ) ;
break ;
case "JoyconRight" :
_rightSideTriggerBox . Show ( ) ;
break ;
2020-09-29 17:32:42 -04:00
case "JoyconPair" :
2021-04-14 06:28:43 -04:00
_motionAltBox . Show ( ) ;
2020-09-29 17:32:42 -04:00
break ;
2020-05-02 22:00:53 -04:00
}
2022-12-06 17:00:25 -05:00
if ( ! OperatingSystem . IsMacOS ( ) )
2020-05-02 22:00:53 -04:00
{
2022-12-06 17:00:25 -05:00
_controllerImage . Pixbuf = _controllerType . ActiveId switch
{
"ProController" = > new Gdk . Pixbuf ( Assembly . GetAssembly ( typeof ( ConfigurationState ) ) , "Ryujinx.Ui.Common.Resources.Controller_ProCon.svg" , 400 , 400 ) ,
"JoyconLeft" = > new Gdk . Pixbuf ( Assembly . GetAssembly ( typeof ( ConfigurationState ) ) , "Ryujinx.Ui.Common.Resources.Controller_JoyConLeft.svg" , 400 , 500 ) ,
"JoyconRight" = > new Gdk . Pixbuf ( Assembly . GetAssembly ( typeof ( ConfigurationState ) ) , "Ryujinx.Ui.Common.Resources.Controller_JoyConRight.svg" , 400 , 500 ) ,
_ = > new Gdk . Pixbuf ( Assembly . GetAssembly ( typeof ( ConfigurationState ) ) , "Ryujinx.Ui.Common.Resources.Controller_JoyConPair.svg" , 400 , 500 ) ,
} ;
}
2020-05-02 22:00:53 -04:00
}
private void ClearValues ( )
{
2021-04-14 06:28:43 -04:00
_lStick . Label = "Unbound" ;
2020-05-02 22:00:53 -04:00
_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" ;
2021-04-14 06:28:43 -04:00
_rStick . Label = "Unbound" ;
2020-05-02 22:00:53 -04:00
_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" ;
2021-08-04 18:39:40 -04:00
_controllerStrongRumble . Value = 1 ;
_controllerWeakRumble . Value = 1 ;
2020-05-02 22:00:53 -04:00
_controllerDeadzoneLeft . Value = 0 ;
_controllerDeadzoneRight . Value = 0 ;
2022-01-03 06:49:29 -05:00
_controllerRangeLeft . Value = 1 ;
_controllerRangeRight . Value = 1 ;
2020-05-02 22:00:53 -04:00
_controllerTriggerThreshold . Value = 0 ;
2020-09-29 17:32:42 -04:00
_mirrorInput . Active = false ;
_enableMotion . Active = false ;
2021-04-14 06:28:43 -04:00
_enableCemuHook . Active = false ;
2020-09-29 17:32:42 -04:00
_slotNumber . Value = 0 ;
_altSlotNumber . Value = 0 ;
_sensitivity . Value = 100 ;
_gyroDeadzone . Value = 1 ;
_dsuServerHost . Buffer . Text = "" ;
_dsuServerPort . Buffer . Text = "" ;
2021-08-04 18:39:40 -04:00
_enableRumble . Active = false ;
2020-05-02 22:00:53 -04:00
}
private void SetValues ( InputConfig config )
{
switch ( config )
{
2021-04-14 06:28:43 -04:00
case StandardKeyboardInputConfig keyboardConfig :
2020-08-23 16:54:11 -04:00
if ( ! _controllerType . SetActiveId ( keyboardConfig . ControllerType . ToString ( ) ) )
{
2021-04-14 06:28:43 -04:00
_controllerType . SetActiveId ( _playerIndex = = PlayerIndex . Handheld
? ControllerType . Handheld . ToString ( )
2020-08-23 16:54:11 -04:00
: ControllerType . ProController . ToString ( ) ) ;
}
2020-05-02 22:00:53 -04:00
2021-04-14 06:28:43 -04:00
_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 ( ) ;
2020-09-29 17:32:42 -04:00
_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 ( ) ;
2021-04-14 06:28:43 -04:00
_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 ( ) ;
2020-09-29 17:32:42 -04:00
_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 ( ) ;
2020-05-02 22:00:53 -04:00
break ;
2021-04-14 06:28:43 -04:00
case StandardControllerInputConfig controllerConfig :
2020-08-23 16:54:11 -04:00
if ( ! _controllerType . SetActiveId ( controllerConfig . ControllerType . ToString ( ) ) )
{
2021-04-14 06:28:43 -04:00
_controllerType . SetActiveId ( _playerIndex = = PlayerIndex . Handheld
? ControllerType . Handheld . ToString ( )
2020-08-23 16:54:11 -04:00
: ControllerType . ProController . ToString ( ) ) ;
}
2020-05-02 22:00:53 -04:00
2021-04-14 06:28:43 -04:00
_lStick . Label = controllerConfig . LeftJoyconStick . Joystick . ToString ( ) ;
_invertLStickX . Active = controllerConfig . LeftJoyconStick . InvertStickX ;
_invertLStickY . Active = controllerConfig . LeftJoyconStick . InvertStickY ;
2022-03-12 12:23:48 -05:00
_rotateL90CW . Active = controllerConfig . LeftJoyconStick . Rotate90CW ;
2021-04-14 06:28:43 -04:00
_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 ( ) ;
2020-05-02 22:00:53 -04:00
_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 ( ) ;
2021-04-14 06:28:43 -04:00
_rStick . Label = controllerConfig . RightJoyconStick . Joystick . ToString ( ) ;
_invertRStickX . Active = controllerConfig . RightJoyconStick . InvertStickX ;
_invertRStickY . Active = controllerConfig . RightJoyconStick . InvertStickY ;
2022-03-12 12:23:48 -05:00
_rotateR90CW . Active = controllerConfig . RightJoyconStick . Rotate90CW ;
2021-04-14 06:28:43 -04:00
_rStickButton . Label = controllerConfig . RightJoyconStick . StickButton . ToString ( ) ;
2020-05-02 22:00:53 -04:00
_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 ( ) ;
2021-08-04 18:39:40 -04:00
_controllerStrongRumble . Value = controllerConfig . Rumble . StrongRumble ;
_controllerWeakRumble . Value = controllerConfig . Rumble . WeakRumble ;
_enableRumble . Active = controllerConfig . Rumble . EnableRumble ;
2020-05-02 22:00:53 -04:00
_controllerDeadzoneLeft . Value = controllerConfig . DeadzoneLeft ;
_controllerDeadzoneRight . Value = controllerConfig . DeadzoneRight ;
2022-01-03 06:49:29 -05:00
_controllerRangeLeft . Value = controllerConfig . RangeLeft ;
_controllerRangeRight . Value = controllerConfig . RangeRight ;
2020-05-02 22:00:53 -04:00
_controllerTriggerThreshold . Value = controllerConfig . TriggerThreshold ;
2021-04-14 06:28:43 -04:00
_sensitivity . Value = controllerConfig . Motion . Sensitivity ;
_gyroDeadzone . Value = controllerConfig . Motion . GyroDeadzone ;
_enableMotion . Active = controllerConfig . Motion . EnableMotion ;
_enableCemuHook . Active = controllerConfig . Motion . MotionBackend = = MotionInputBackendType . CemuHook ;
2022-01-03 06:49:29 -05:00
// If both stick ranges are 0 (usually indicative of an outdated profile load) then both sticks will be set to 1.0.
if ( _controllerRangeLeft . Value < = 0.0 & & _controllerRangeRight . Value < = 0.0 )
{
_controllerRangeLeft . Value = 1.0 ;
_controllerRangeRight . Value = 1.0 ;
Logger . Info ? . Print ( LogClass . Application , $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration" ) ;
}
2021-04-14 06:28:43 -04:00
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 ( ) ;
}
2020-05-02 22:00:53 -04:00
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 ) ;
2021-04-14 06:28:43 -04:00
return new StandardKeyboardInputConfig
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
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 >
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
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
2020-05-02 22:00:53 -04:00
} ,
2021-04-14 06:28:43 -04:00
RightJoyconStick = new JoyconConfigKeyboardStick < Key >
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
StickUp = rStickUp ,
StickDown = rStickDown ,
StickLeft = rStickLeft ,
StickRight = rStickRight ,
StickButton = rStickButton ,
2020-09-29 17:32:42 -04:00
} ,
2020-05-02 22:00:53 -04:00
} ;
}
if ( _inputDevice . ActiveId . StartsWith ( "controller" ) )
{
2021-04-14 06:28:43 -04:00
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 ) ;
2020-05-02 22:00:53 -04:00
2020-10-28 15:52:07 -04:00
int . TryParse ( _dsuServerPort . Buffer . Text , out int port ) ;
2021-04-14 06:28:43 -04:00
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
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
Backend = InputBackendType . GamepadSDL2 ,
Version = InputConfig . CurrentVersion ,
Id = _inputDevice . ActiveId . Split ( "/" ) [ 1 ] . Split ( " " ) [ 0 ] ,
2020-05-02 22:00:53 -04:00
ControllerType = Enum . Parse < ControllerType > ( _controllerType . ActiveId ) ,
PlayerIndex = _playerIndex ,
DeadzoneLeft = ( float ) _controllerDeadzoneLeft . Value ,
DeadzoneRight = ( float ) _controllerDeadzoneRight . Value ,
2022-01-03 06:49:29 -05:00
RangeLeft = ( float ) _controllerRangeLeft . Value ,
RangeRight = ( float ) _controllerRangeRight . Value ,
2020-05-02 22:00:53 -04:00
TriggerThreshold = ( float ) _controllerTriggerThreshold . Value ,
2021-04-14 06:28:43 -04:00
LeftJoycon = new LeftJoyconCommonConfig < ConfigGamepadInputId >
2020-05-02 22:00:53 -04:00
{
ButtonMinus = lButtonMinus ,
ButtonL = lButtonL ,
ButtonZl = lButtonZl ,
ButtonSl = lButtonSl ,
ButtonSr = lButtonSr ,
2021-04-14 06:28:43 -04:00
DpadUp = lDPadUp ,
DpadDown = lDPadDown ,
DpadLeft = lDPadLeft ,
DpadRight = lDPadRight
2020-05-02 22:00:53 -04:00
} ,
2021-04-14 06:28:43 -04:00
LeftJoyconStick = new JoyconConfigControllerStick < ConfigGamepadInputId , ConfigStickInputId >
{
InvertStickX = _invertLStickX . Active ,
Joystick = lStick ,
InvertStickY = _invertLStickY . Active ,
StickButton = lStickButton ,
2022-03-12 12:23:48 -05:00
Rotate90CW = _rotateL90CW . Active ,
2021-04-14 06:28:43 -04:00
} ,
RightJoycon = new RightJoyconCommonConfig < ConfigGamepadInputId >
2020-05-02 22:00:53 -04:00
{
ButtonA = rButtonA ,
ButtonB = rButtonB ,
ButtonX = rButtonX ,
ButtonY = rButtonY ,
ButtonPlus = rButtonPlus ,
ButtonR = rButtonR ,
ButtonZr = rButtonZr ,
ButtonSl = rButtonSl ,
ButtonSr = rButtonSr
2020-09-29 17:32:42 -04:00
} ,
2021-04-14 06:28:43 -04:00
RightJoyconStick = new JoyconConfigControllerStick < ConfigGamepadInputId , ConfigStickInputId >
{
InvertStickX = _invertRStickX . Active ,
Joystick = rStick ,
InvertStickY = _invertRStickY . Active ,
StickButton = rStickButton ,
2022-03-12 12:23:48 -05:00
Rotate90CW = _rotateR90CW . Active ,
2021-04-14 06:28:43 -04:00
} ,
2021-08-04 18:39:40 -04:00
Motion = motionConfig ,
Rumble = new RumbleConfigController
{
StrongRumble = ( float ) _controllerStrongRumble . Value ,
WeakRumble = ( float ) _controllerWeakRumble . Value ,
EnableRumble = _enableRumble . Active
}
2020-05-02 22:00:53 -04:00
} ;
}
if ( ! _inputDevice . ActiveId . StartsWith ( "disabled" ) )
{
2021-03-18 18:44:39 -04:00
GtkDialog . CreateErrorDialog ( "Invalid data detected in one or more fields; the configuration was not saved." ) ;
2020-05-02 22:00:53 -04:00
}
return null ;
}
private string GetProfileBasePath ( )
{
if ( _inputDevice . ActiveId . StartsWith ( "keyboard" ) )
{
2021-04-14 06:28:43 -04:00
return System . IO . Path . Combine ( AppDataManager . ProfilesDirPath , "keyboard" ) ;
2020-05-02 22:00:53 -04:00
}
else if ( _inputDevice . ActiveId . StartsWith ( "controller" ) )
{
2021-04-14 06:28:43 -04:00
return System . IO . Path . Combine ( AppDataManager . ProfilesDirPath , "controller" ) ;
2020-05-02 22:00:53 -04:00
}
2021-04-14 06:28:43 -04:00
return AppDataManager . ProfilesDirPath ;
2020-05-02 22:00:53 -04:00
}
2021-01-08 03:14:13 -05:00
//
// Events
//
2020-05-02 22:00:53 -04:00
private void InputDevice_Changed ( object sender , EventArgs args )
{
SetAvailableOptions ( ) ;
SetControllerSpecificFields ( ) ;
2021-04-14 06:28:43 -04:00
_selectedGamepad ? . Dispose ( ) ;
_selectedGamepad = null ;
2020-05-02 22:00:53 -04:00
2021-04-14 06:28:43 -04:00
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 ) ;
}
}
2020-05-02 22:00:53 -04:00
}
2021-04-14 06:28:43 -04:00
private string GetCurrentGamepadId ( )
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
if ( _inputDevice . ActiveId = = null | | _inputDevice . ActiveId = = "disabled" )
{
return null ;
}
2020-05-02 22:00:53 -04:00
2021-04-14 06:28:43 -04:00
return _inputDevice . ActiveId . Split ( "/" ) [ 1 ] . Split ( " " ) [ 0 ] ;
2020-05-02 22:00:53 -04:00
}
2021-04-14 06:28:43 -04:00
private void Controller_Changed ( object sender , EventArgs args )
2021-02-20 18:22:55 -05:00
{
2021-04-14 06:28:43 -04:00
SetControllerSpecificFields ( ) ;
}
2021-02-20 18:22:55 -05:00
2021-04-14 06:28:43 -04:00
private IButtonAssigner CreateButtonAssigner ( bool forStick )
{
IButtonAssigner assigner ;
2021-02-20 18:22:55 -05:00
if ( _inputDevice . ActiveId . StartsWith ( "keyboard" ) )
{
2021-04-14 06:28:43 -04:00
assigner = new KeyboardKeyAssigner ( ( IKeyboard ) _selectedGamepad ) ;
2021-02-20 18:22:55 -05:00
}
else if ( _inputDevice . ActiveId . StartsWith ( "controller" ) )
{
2021-04-14 06:28:43 -04:00
assigner = new GamepadButtonAssigner ( _selectedGamepad , ( float ) _controllerTriggerThreshold . Value , forStick ) ;
2021-02-20 18:22:55 -05:00
}
else
{
throw new Exception ( "Controller not supported" ) ;
}
return assigner ;
}
2021-04-14 06:28:43 -04:00
private void HandleButtonPressed ( ToggleButton button , bool forStick )
2020-05-02 22:00:53 -04:00
{
if ( _isWaitingForInput )
{
2021-04-14 06:28:43 -04:00
button . Active = false ;
2020-05-02 22:00:53 -04:00
return ;
}
2021-04-14 06:28:43 -04:00
_mousePressed = false ;
ButtonPressEvent + = MouseClick ;
IButtonAssigner assigner = CreateButtonAssigner ( forStick ) ;
2021-02-20 18:22:55 -05:00
2020-05-02 22:00:53 -04:00
_isWaitingForInput = true ;
2021-04-14 06:28:43 -04:00
// Open GTK3 keyboard for cancel operations
IKeyboard keyboard = ( IKeyboard ) _gtk3KeyboardDriver . GetGamepad ( "0" ) ;
2020-05-02 22:00:53 -04:00
Thread inputThread = new Thread ( ( ) = >
{
2021-04-14 06:28:43 -04:00
assigner . Initialize ( ) ;
2020-05-02 22:00:53 -04:00
2021-02-20 18:22:55 -05:00
while ( true )
2020-05-02 22:00:53 -04:00
{
2021-02-20 18:22:55 -05:00
Thread . Sleep ( 10 ) ;
assigner . ReadInput ( ) ;
2020-05-02 22:00:53 -04:00
2021-04-14 06:28:43 -04:00
if ( _mousePressed | | keyboard . IsPressed ( Ryujinx . Input . Key . Escape ) | | assigner . HasAnyButtonPressed ( ) | | assigner . ShouldCancel ( ) )
2020-05-02 22:00:53 -04:00
{
2021-02-20 18:22:55 -05:00
break ;
2020-05-02 22:00:53 -04:00
}
}
2021-02-20 18:22:55 -05:00
string pressedButton = assigner . GetPressedButton ( ) ;
2020-05-02 22:00:53 -04:00
2021-02-20 18:22:55 -05:00
Application . Invoke ( delegate
{
2021-06-23 16:51:29 -04:00
if ( _middleMousePressed )
{
button . Label = "Unbound" ;
}
else if ( pressedButton ! = "" )
2020-05-02 22:00:53 -04:00
{
2021-02-20 18:22:55 -05:00
button . Label = pressedButton ;
}
2021-04-14 06:28:43 -04:00
2021-06-23 16:51:29 -04:00
_middleMousePressed = false ;
2021-04-14 06:28:43 -04:00
ButtonPressEvent - = MouseClick ;
keyboard . Dispose ( ) ;
2021-02-20 18:22:55 -05:00
button . Active = false ;
2021-04-14 06:28:43 -04:00
_isWaitingForInput = false ;
2021-02-20 18:22:55 -05:00
} ) ;
2020-05-02 22:00:53 -04:00
} ) ;
2021-02-20 18:22:55 -05:00
2020-05-02 22:00:53 -04:00
inputThread . Name = "GUI.InputThread" ;
inputThread . IsBackground = true ;
inputThread . Start ( ) ;
}
2021-04-14 06:28:43 -04:00
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 ;
2021-06-23 16:51:29 -04:00
_middleMousePressed = args . Event . Button = = 2 ;
2021-04-14 06:28:43 -04:00
}
2020-05-02 22:00:53 -04:00
private void SetProfiles ( )
{
2021-04-14 06:28:43 -04:00
_profile . RemoveAll ( ) ;
2020-05-02 22:00:53 -04:00
string basePath = GetProfileBasePath ( ) ;
2021-04-14 06:28:43 -04:00
2020-05-02 22:00:53 -04:00
if ( ! Directory . Exists ( basePath ) )
{
Directory . CreateDirectory ( basePath ) ;
}
2021-04-14 06:28:43 -04:00
if ( _inputDevice . ActiveId = = null | | _inputDevice . ActiveId . Equals ( "disabled" ) )
{
_profile . Append ( "default" , "None" ) ;
}
else
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
_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 ) ) ;
}
2020-05-02 22:00:53 -04:00
}
2021-04-14 06:28:43 -04:00
_profile . SetActiveId ( "default" ) ;
2020-05-02 22:00:53 -04:00
}
private void ProfileLoad_Activated ( object sender , EventArgs args )
{
2021-01-08 03:14:13 -05:00
( ( ToggleButton ) sender ) . SetStateFlags ( StateFlags . Normal , true ) ;
2020-05-02 22:00:53 -04:00
if ( _inputDevice . ActiveId = = "disabled" | | _profile . ActiveId = = null ) return ;
InputConfig config = null ;
int pos = _profile . Active ;
if ( _profile . ActiveId = = "default" )
{
if ( _inputDevice . ActiveId . StartsWith ( "keyboard" ) )
{
2021-04-14 06:28:43 -04:00
config = new StandardKeyboardInputConfig
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
Version = InputConfig . CurrentVersion ,
Backend = InputBackendType . WindowKeyboard ,
Id = null ,
2021-06-16 21:48:55 -04:00
ControllerType = ControllerType . ProController ,
2021-04-14 06:28:43 -04:00
LeftJoycon = new LeftJoyconCommonConfig < Key >
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
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
2020-05-02 22:00:53 -04:00
} ,
2021-04-14 06:28:43 -04:00
LeftJoyconStick = new JoyconConfigKeyboardStick < Key >
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
StickUp = Key . W ,
StickDown = Key . S ,
StickLeft = Key . A ,
StickRight = Key . D ,
StickButton = Key . F ,
2020-09-29 17:32:42 -04:00
} ,
2021-04-14 06:28:43 -04:00
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 ,
}
2020-05-02 22:00:53 -04:00
} ;
}
else if ( _inputDevice . ActiveId . StartsWith ( "controller" ) )
{
2021-04-14 06:28:43 -04:00
bool isNintendoStyle = _inputDevice . ActiveText . Contains ( "Nintendo" ) ;
config = new StandardControllerInputConfig
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
Version = InputConfig . CurrentVersion ,
Backend = InputBackendType . GamepadSDL2 ,
Id = null ,
ControllerType = ControllerType . JoyconPair ,
2020-05-02 22:00:53 -04:00
DeadzoneLeft = 0.1f ,
DeadzoneRight = 0.1f ,
2022-01-03 06:49:29 -05:00
RangeLeft = 1.0f ,
RangeRight = 1.0f ,
2020-05-02 22:00:53 -04:00
TriggerThreshold = 0.5f ,
2021-04-14 06:28:43 -04:00
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 >
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
Joystick = ConfigStickInputId . Left ,
StickButton = ConfigGamepadInputId . LeftStick ,
2020-05-02 22:00:53 -04:00
InvertStickX = false ,
2021-04-14 06:28:43 -04:00
InvertStickY = false ,
2022-03-12 12:23:48 -05:00
Rotate90CW = false ,
2020-05-02 22:00:53 -04:00
} ,
2021-04-14 06:28:43 -04:00
RightJoycon = new RightJoyconCommonConfig < ConfigGamepadInputId >
2020-05-02 22:00:53 -04:00
{
2021-04-14 06:28:43 -04:00
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 ,
2020-05-02 22:00:53 -04:00
InvertStickX = false ,
2021-04-14 06:28:43 -04:00
InvertStickY = false ,
2022-03-12 12:23:48 -05:00
Rotate90CW = false ,
2020-09-29 17:32:42 -04:00
} ,
2021-04-14 06:28:43 -04:00
Motion = new StandardMotionConfigController
{
MotionBackend = MotionInputBackendType . GamepadDriver ,
EnableMotion = true ,
Sensitivity = 100 ,
GyroDeadzone = 1 ,
2021-08-04 18:39:40 -04:00
} ,
Rumble = new RumbleConfigController
{
StrongRumble = 1f ,
WeakRumble = 1f ,
EnableRumble = false
2021-04-14 06:28:43 -04:00
}
2020-05-02 22:00:53 -04:00
} ;
}
}
else
{
string path = System . IO . Path . Combine ( GetProfileBasePath ( ) , _profile . ActiveId ) ;
if ( ! File . Exists ( path ) )
{
if ( pos > = 0 )
{
_profile . Remove ( pos ) ;
}
return ;
}
2020-05-03 14:42:17 -04:00
try
2020-05-02 22:00:53 -04:00
{
2023-03-21 18:41:19 -04:00
config = JsonHelper . DeserializeFromFile ( path , SerializerContext . InputConfig ) ;
2020-05-03 14:42:17 -04:00
}
2021-04-14 06:28:43 -04:00
catch ( JsonException ) { }
2020-05-02 22:00:53 -04:00
}
SetValues ( config ) ;
}
private void ProfileAdd_Activated ( object sender , EventArgs args )
{
2021-01-08 03:14:13 -05:00
( ( ToggleButton ) sender ) . SetStateFlags ( StateFlags . Normal , true ) ;
2020-05-02 22:00:53 -04:00
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 ) ;
2023-03-21 18:41:19 -04:00
string jsonString = JsonHelper . Serialize ( inputConfig , SerializerContext . InputConfig ) ;
2020-05-02 22:00:53 -04:00
File . WriteAllText ( path , jsonString ) ;
}
profileDialog . Dispose ( ) ;
SetProfiles ( ) ;
}
private void ProfileRemove_Activated ( object sender , EventArgs args )
{
2021-01-08 03:14:13 -05:00
( ( ToggleButton ) sender ) . SetStateFlags ( StateFlags . Normal , true ) ;
2020-05-02 22:00:53 -04:00
if ( _inputDevice . ActiveId = = "disabled" | | _profile . ActiveId = = "default" | | _profile . ActiveId = = null ) return ;
2021-08-20 17:48:00 -04:00
MessageDialog confirmDialog = GtkDialog . CreateConfirmationDialog ( "Deleting Profile" , "This action is irreversible, are you sure you want to continue?" ) ;
2020-05-02 22:00:53 -04:00
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 ( ) ;
2020-08-23 16:54:11 -04:00
var newConfig = new List < InputConfig > ( ) ;
newConfig . AddRange ( ConfigurationState . Instance . Hid . InputConfig . Value ) ;
2020-05-02 22:00:53 -04:00
if ( _inputConfig = = null & & inputConfig ! = null )
{
2020-08-23 16:54:11 -04:00
newConfig . Add ( inputConfig ) ;
2020-05-02 22:00:53 -04:00
}
else
{
if ( _inputDevice . ActiveId = = "disabled" )
{
2020-08-23 16:54:11 -04:00
newConfig . Remove ( _inputConfig ) ;
2020-05-02 22:00:53 -04:00
}
else if ( inputConfig ! = null )
{
2020-08-23 16:54:11 -04:00
int index = newConfig . IndexOf ( _inputConfig ) ;
2020-05-02 22:00:53 -04:00
2020-08-23 16:54:11 -04:00
newConfig [ index ] = inputConfig ;
2020-05-02 22:00:53 -04:00
}
}
2021-05-04 12:19:04 -04:00
if ( _mainWindow . RendererWidget ! = null )
2021-04-14 06:28:43 -04:00
{
2021-06-23 20:09:08 -04:00
_mainWindow . RendererWidget . NpadManager . ReloadConfiguration ( newConfig , ConfigurationState . Instance . Hid . EnableKeyboard , ConfigurationState . Instance . Hid . EnableMouse ) ;
2021-04-14 06:28:43 -04:00
}
2020-08-23 16:54:11 -04:00
// 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 ;
2021-01-08 03:14:13 -05:00
ConfigurationState . Instance . ToFileFormat ( ) . SaveConfig ( Program . ConfigurationPath ) ;
2020-05-03 06:08:21 -04:00
2020-05-02 22:00:53 -04:00
Dispose ( ) ;
}
private void CloseToggle_Activated ( object sender , EventArgs args )
{
Dispose ( ) ;
}
}
2021-03-18 18:44:39 -04:00
}