AvaloniaKeyboard.cs 8.2 KB

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