GTK3Keyboard.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. using Ryujinx.Common.Configuration.Hid;
  2. using Ryujinx.Common.Configuration.Hid.Keyboard;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Numerics;
  6. using ConfigKey = Ryujinx.Common.Configuration.Hid.Key;
  7. namespace Ryujinx.Input.GTK3
  8. {
  9. public class GTK3Keyboard : IKeyboard
  10. {
  11. private class ButtonMappingEntry
  12. {
  13. public readonly GamepadButtonInputId To;
  14. public readonly Key From;
  15. public ButtonMappingEntry(GamepadButtonInputId to, Key from)
  16. {
  17. To = to;
  18. From = from;
  19. }
  20. }
  21. private object _userMappingLock = new object();
  22. private readonly GTK3KeyboardDriver _driver;
  23. private StandardKeyboardInputConfig _configuration;
  24. private List<ButtonMappingEntry> _buttonsUserMapping;
  25. public GTK3Keyboard(GTK3KeyboardDriver driver, string id, string name)
  26. {
  27. _driver = driver;
  28. Id = id;
  29. Name = name;
  30. _buttonsUserMapping = new List<ButtonMappingEntry>();
  31. }
  32. private bool HasConfiguration => _configuration != null;
  33. public string Id { get; }
  34. public string Name { get; }
  35. public bool IsConnected => true;
  36. public GamepadFeaturesFlag Features => GamepadFeaturesFlag.None;
  37. public void Dispose()
  38. {
  39. // No operations
  40. }
  41. public KeyboardStateSnapshot GetKeyboardStateSnapshot()
  42. {
  43. return IKeyboard.GetStateSnapshot(this);
  44. }
  45. private static float ConvertRawStickValue(short value)
  46. {
  47. const float ConvertRate = 1.0f / (short.MaxValue + 0.5f);
  48. return value * ConvertRate;
  49. }
  50. private static (short, short) GetStickValues(ref KeyboardStateSnapshot snapshot, JoyconConfigKeyboardStick<ConfigKey> stickConfig)
  51. {
  52. short stickX = 0;
  53. short stickY = 0;
  54. if (snapshot.IsPressed((Key)stickConfig.StickUp))
  55. {
  56. stickY += 1;
  57. }
  58. if (snapshot.IsPressed((Key)stickConfig.StickDown))
  59. {
  60. stickY -= 1;
  61. }
  62. if (snapshot.IsPressed((Key)stickConfig.StickRight))
  63. {
  64. stickX += 1;
  65. }
  66. if (snapshot.IsPressed((Key)stickConfig.StickLeft))
  67. {
  68. stickX -= 1;
  69. }
  70. OpenTK.Mathematics.Vector2 stick = new OpenTK.Mathematics.Vector2(stickX, stickY);
  71. stick.NormalizeFast();
  72. return ((short)(stick.X * short.MaxValue), (short)(stick.Y * short.MaxValue));
  73. }
  74. public GamepadStateSnapshot GetMappedStateSnapshot()
  75. {
  76. KeyboardStateSnapshot rawState = GetKeyboardStateSnapshot();
  77. GamepadStateSnapshot result = default;
  78. lock (_userMappingLock)
  79. {
  80. if (!HasConfiguration)
  81. {
  82. return result;
  83. }
  84. foreach (ButtonMappingEntry entry in _buttonsUserMapping)
  85. {
  86. if (entry.From == Key.Unknown || entry.From == Key.Unbound || entry.To == GamepadButtonInputId.Unbound)
  87. {
  88. continue;
  89. }
  90. // Do not touch state of button already pressed
  91. if (!result.IsPressed(entry.To))
  92. {
  93. result.SetPressed(entry.To, rawState.IsPressed(entry.From));
  94. }
  95. }
  96. (short leftStickX, short leftStickY) = GetStickValues(ref rawState, _configuration.LeftJoyconStick);
  97. (short rightStickX, short rightStickY) = GetStickValues(ref rawState, _configuration.RightJoyconStick);
  98. result.SetStick(StickInputId.Left, ConvertRawStickValue(leftStickX), ConvertRawStickValue(leftStickY));
  99. result.SetStick(StickInputId.Right, ConvertRawStickValue(rightStickX), ConvertRawStickValue(rightStickY));
  100. }
  101. return result;
  102. }
  103. public GamepadStateSnapshot GetStateSnapshot()
  104. {
  105. throw new NotSupportedException();
  106. }
  107. public (float, float) GetStick(StickInputId inputId)
  108. {
  109. throw new NotSupportedException();
  110. }
  111. public bool IsPressed(GamepadButtonInputId inputId)
  112. {
  113. throw new NotSupportedException();
  114. }
  115. public bool IsPressed(Key key)
  116. {
  117. return _driver.IsPressed(key);
  118. }
  119. public void SetConfiguration(InputConfig configuration)
  120. {
  121. lock (_userMappingLock)
  122. {
  123. _configuration = (StandardKeyboardInputConfig)configuration;
  124. _buttonsUserMapping.Clear();
  125. // Then left joycon
  126. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftStick, (Key)_configuration.LeftJoyconStick.StickButton));
  127. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadUp, (Key)_configuration.LeftJoycon.DpadUp));
  128. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadDown, (Key)_configuration.LeftJoycon.DpadDown));
  129. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadLeft, (Key)_configuration.LeftJoycon.DpadLeft));
  130. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.DpadRight, (Key)_configuration.LeftJoycon.DpadRight));
  131. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Minus, (Key)_configuration.LeftJoycon.ButtonMinus));
  132. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftShoulder, (Key)_configuration.LeftJoycon.ButtonL));
  133. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.LeftTrigger, (Key)_configuration.LeftJoycon.ButtonZl));
  134. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleRightTrigger0, (Key)_configuration.LeftJoycon.ButtonSr));
  135. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger0, (Key)_configuration.LeftJoycon.ButtonSl));
  136. // Finally right joycon
  137. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightStick, (Key)_configuration.RightJoyconStick.StickButton));
  138. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.A, (Key)_configuration.RightJoycon.ButtonA));
  139. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.B, (Key)_configuration.RightJoycon.ButtonB));
  140. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.X, (Key)_configuration.RightJoycon.ButtonX));
  141. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Y, (Key)_configuration.RightJoycon.ButtonY));
  142. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.Plus, (Key)_configuration.RightJoycon.ButtonPlus));
  143. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightShoulder, (Key)_configuration.RightJoycon.ButtonR));
  144. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.RightTrigger, (Key)_configuration.RightJoycon.ButtonZr));
  145. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleRightTrigger1, (Key)_configuration.RightJoycon.ButtonSr));
  146. _buttonsUserMapping.Add(new ButtonMappingEntry(GamepadButtonInputId.SingleLeftTrigger1, (Key)_configuration.RightJoycon.ButtonSl));
  147. }
  148. }
  149. public void SetTriggerThreshold(float triggerThreshold)
  150. {
  151. // No operations
  152. }
  153. public void Rumble(float lowFrequency, float highFrequency, uint durationMs)
  154. {
  155. // No operations
  156. }
  157. public Vector3 GetMotionData(MotionInputId inputId)
  158. {
  159. // No operations
  160. return Vector3.Zero;
  161. }
  162. }
  163. }