💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
5.4 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_INPUT_GAME_CONTROLLER_HPP
  20. #define ANTKEEPER_INPUT_GAME_CONTROLLER_HPP
  21. #include "device.hpp"
  22. namespace input {
  23. /// Game controller buttons.
  24. enum class game_controller_button
  25. {
  26. a,
  27. b,
  28. x,
  29. y,
  30. back,
  31. guide,
  32. start,
  33. left_stick,
  34. right_stick,
  35. left_shoulder,
  36. right_shoulder,
  37. dpad_up,
  38. dpad_down,
  39. dpad_left,
  40. dpad_right
  41. };
  42. /// Game controller axes.
  43. enum class game_controller_axis
  44. {
  45. /// Left stick x-axis.
  46. left_x,
  47. /// Left stick y-axis.
  48. left_y,
  49. /// Right stick x-axis.
  50. right_x,
  51. /// Right stick y-axis.
  52. right_y,
  53. /// Left trigger.
  54. left_trigger,
  55. /// Right trigger.
  56. right_trigger,
  57. };
  58. /// Game controller axis activation response curves.
  59. enum class game_controller_response_curve
  60. {
  61. /// Linear response curve.
  62. linear,
  63. /// Squared response curve.
  64. square,
  65. /// Cubed response curve.
  66. cube
  67. };
  68. /**
  69. * A virtual game controller which can generate game controller-related input events and pass them to an event dispatcher.
  70. *
  71. * @ingroup input
  72. */
  73. class game_controller: public device
  74. {
  75. public:
  76. /**
  77. * Creates a game controller input device.
  78. */
  79. game_controller();
  80. /// Destroys a game controller input device.
  81. virtual ~game_controller() = default;
  82. /**
  83. * Sets the activation threshold for a game controller axis.
  84. *
  85. * @param axis Game controller axis.
  86. * @param min Axis minimum activation threshold.
  87. * @param max Axis maximum activation threshold.
  88. */
  89. void set_activation_threshold(game_controller_axis axis, float min, float max);
  90. /**
  91. * Sets the activation response curve of an axis.
  92. *
  93. * @param axis Game controller axis.
  94. * @param curve Activation response curve.
  95. */
  96. void set_response_curve(game_controller_axis axis, game_controller_response_curve curve);
  97. /**
  98. * Sets the type of deadzone shape for the axes on the left stick.
  99. *
  100. * @param cross If `true`, the x and y axes are independently activated, if `false`, activation of the x and y axes are dependent on their combined magnitude.
  101. */
  102. void set_left_deadzone_cross(bool cross);
  103. /**
  104. * Sets the type of deadzone shape for the axes on the right stick.
  105. *
  106. * @param cross If `true`, the x and y axes are independently activated, if `false`, activation of the x and y axes are dependent on their combined magnitude.
  107. */
  108. void set_right_deadzone_cross(bool cross);
  109. /**
  110. * Sets the roundness of the deadzone for the axes on the left stick.
  111. *
  112. * @param roundness Roundness of the deadzone shape for non-cross deadzones. A value of `0.0` results in a square deadzone, while a value of `1.0` results in a circular deadzone. Values between `0.0` and `1.0` result in a rounded rectangle deadzone.
  113. */
  114. void set_left_deadzone_roundness(float roundness);
  115. /**
  116. * Sets the roundness of the deadzone for the axes on the right stick.
  117. *
  118. * @param roundness Roundness of the deadzone shape for non-cross deadzones. A value of `0.0` results in a square deadzone, while a value of `1.0` results in a circular deadzone. Values between `0.0` and `1.0` result in a rounded rectangle deadzone.
  119. */
  120. void set_right_deadzone_roundness(float roundness);
  121. /**
  122. * Simulates a game controller button press.
  123. *
  124. * @param button Index of the pressed button.
  125. */
  126. void press(game_controller_button button);
  127. /**
  128. * Simulates a game controller button release.
  129. *
  130. * @param button Index of the released button.
  131. */
  132. void release(game_controller_button button);
  133. /**
  134. * Simulates a game controller axis movement.
  135. *
  136. * @param axis Index of the moved axis.
  137. * @param negative Whether the movement was negative or positive.
  138. * @param value Normalized degree of movement.
  139. */
  140. void move(game_controller_axis axis, float value);
  141. /**
  142. * Simulates a game controller being connected.
  143. *
  144. * @param reconnected `true` if the controller is being reconnected, or `false` if the controller is being connected for the first time.
  145. */
  146. void connect(bool reconnnected);
  147. /// Simulates a game controller being disconnected.
  148. void disconnect();
  149. /// Returns `true` if the controller is currently connected.
  150. bool is_connected() const;
  151. private:
  152. void handle_axial_motion(game_controller_axis axis);
  153. void handle_biaxial_motion(game_controller_axis axis_x, game_controller_axis axis_y);
  154. float curve_response(game_controller_axis axis, float response) const;
  155. bool connected;
  156. float axis_values[6];
  157. float axis_activation_min[6];
  158. float axis_activation_max[6];
  159. game_controller_response_curve axis_response_curves[6];
  160. bool left_deadzone_cross;
  161. bool right_deadzone_cross;
  162. float left_deadzone_roundness;
  163. float right_deadzone_roundness;
  164. };
  165. inline bool game_controller::is_connected() const
  166. {
  167. return connected;
  168. }
  169. } // namespace input
  170. #endif // ANTKEEPER_INPUT_GAME_CONTROLLER_HPP