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.

220 lines
7.2 KiB

  1. # Joystick :id=joystick
  2. This feature provides game controller input as a joystick device supporting up to 6 axes and 32 buttons. Axes can be read either from an [ADC-capable input pin](adc_driver.md), or can be virtual, so that its value is provided by your code.
  3. An analog device such as a [potentiometer](https://en.wikipedia.org/wiki/Potentiometer) found on an analog joystick's axes is based on a voltage divider, where adjusting the movable wiper controls the output voltage which can then be read by the microcontroller's ADC.
  4. ## Usage :id=usage
  5. Add the following to your `rules.mk`:
  6. ```make
  7. JOYSTICK_ENABLE = yes
  8. ```
  9. By default the joystick driver is `analog`, but you can change this with:
  10. ```make
  11. JOYSTICK_DRIVER = digital
  12. ```
  13. ## Configuration :id=configuration
  14. By default, two axes and eight buttons are defined, with a reported resolution of 8 bits (-127 to +127). This can be changed in your `config.h`:
  15. ```c
  16. // Min 0, max 32
  17. #define JOYSTICK_BUTTON_COUNT 16
  18. // Min 0, max 6: X, Y, Z, Rx, Ry, Rz
  19. #define JOYSTICK_AXIS_COUNT 3
  20. // Min 8, max 16
  21. #define JOYSTICK_AXIS_RESOLUTION 10
  22. ```
  23. ?> You must define at least one button or axis. Also note that the maximum ADC resolution of the supported AVR MCUs is 10-bit, and 12-bit for most STM32 MCUs.
  24. ### Axes :id=axes
  25. When defining axes for your joystick, you must provide a definition array typically in your `keymap.c`.
  26. For instance, the below example configures two axes. The X axis is read from the `A4` pin. With the default axis resolution of 8 bits, the range of values between 900 and 575 are scaled to -127 through 0, and values 575 to 285 are scaled to 0 through 127. The Y axis is configured as a virtual axis, and its value is not read from any pin. Instead, the user must update the axis value programmatically.
  27. ```c
  28. joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT] = {
  29. JOYSTICK_AXIS_IN(A4, 900, 575, 285),
  30. JOYSTICK_AXIS_VIRTUAL
  31. };
  32. ```
  33. Axes can be configured using one of the following macros:
  34. * `JOYSTICK_AXIS_IN(input_pin, low, rest, high)`
  35. The ADC samples the provided pin. `low`, `high` and `rest` correspond to the minimum, maximum, and resting (or centered) analog values of the axis, respectively.
  36. * `JOYSTICK_AXIS_VIRTUAL`
  37. No ADC reading is performed. The value should be provided by user code.
  38. The `low` and `high` values can be swapped to effectively invert the axis.
  39. #### Virtual Axes :id=virtual-axes
  40. The following example adjusts two virtual axes (X and Y) based on keypad presses, with `KC_P0` as a precision modifier:
  41. ```c
  42. joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT] = {
  43. JOYSTICK_AXIS_VIRTUAL, // x
  44. JOYSTICK_AXIS_VIRTUAL // y
  45. };
  46. static bool precision = false;
  47. static uint16_t precision_mod = 64;
  48. static uint16_t axis_val = 127;
  49. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  50. int16_t precision_val = axis_val;
  51. if (precision) {
  52. precision_val -= precision_mod;
  53. }
  54. switch (keycode) {
  55. case KC_P8:
  56. joystick_set_axis(1, record->event.pressed ? -precision_val : 0);
  57. return false;
  58. case KC_P2:
  59. joystick_set_axis(1, record->event.pressed ? precision_val : 0);
  60. return false;
  61. case KC_P4:
  62. joystick_set_axis(0, record->event.pressed ? -precision_val : 0);
  63. return false;
  64. case KC_P6:
  65. joystick_set_axis(0, record->event.pressed ? precision_val : 0);
  66. return false;
  67. case KC_P0:
  68. precision = record->event.pressed;
  69. return false;
  70. }
  71. return true;
  72. }
  73. ```
  74. ## Keycodes :id=keycodes
  75. |Key |Aliases|Description|
  76. |-----------------------|-------|-----------|
  77. |`QK_JOYSTICK_BUTTON_0` |`JS_0` |Button 0 |
  78. |`QK_JOYSTICK_BUTTON_1` |`JS_1` |Button 1 |
  79. |`QK_JOYSTICK_BUTTON_2` |`JS_2` |Button 2 |
  80. |`QK_JOYSTICK_BUTTON_3` |`JS_3` |Button 3 |
  81. |`QK_JOYSTICK_BUTTON_4` |`JS_4` |Button 4 |
  82. |`QK_JOYSTICK_BUTTON_5` |`JS_5` |Button 5 |
  83. |`QK_JOYSTICK_BUTTON_6` |`JS_6` |Button 6 |
  84. |`QK_JOYSTICK_BUTTON_7` |`JS_7` |Button 7 |
  85. |`QK_JOYSTICK_BUTTON_8` |`JS_8` |Button 8 |
  86. |`QK_JOYSTICK_BUTTON_9` |`JS_9` |Button 9 |
  87. |`QK_JOYSTICK_BUTTON_10`|`JS_10`|Button 10 |
  88. |`QK_JOYSTICK_BUTTON_11`|`JS_11`|Button 11 |
  89. |`QK_JOYSTICK_BUTTON_12`|`JS_12`|Button 12 |
  90. |`QK_JOYSTICK_BUTTON_13`|`JS_13`|Button 13 |
  91. |`QK_JOYSTICK_BUTTON_14`|`JS_14`|Button 14 |
  92. |`QK_JOYSTICK_BUTTON_15`|`JS_15`|Button 15 |
  93. |`QK_JOYSTICK_BUTTON_16`|`JS_16`|Button 16 |
  94. |`QK_JOYSTICK_BUTTON_17`|`JS_17`|Button 17 |
  95. |`QK_JOYSTICK_BUTTON_18`|`JS_18`|Button 18 |
  96. |`QK_JOYSTICK_BUTTON_19`|`JS_19`|Button 19 |
  97. |`QK_JOYSTICK_BUTTON_20`|`JS_20`|Button 20 |
  98. |`QK_JOYSTICK_BUTTON_21`|`JS_21`|Button 21 |
  99. |`QK_JOYSTICK_BUTTON_22`|`JS_22`|Button 22 |
  100. |`QK_JOYSTICK_BUTTON_23`|`JS_23`|Button 23 |
  101. |`QK_JOYSTICK_BUTTON_24`|`JS_24`|Button 24 |
  102. |`QK_JOYSTICK_BUTTON_25`|`JS_25`|Button 25 |
  103. |`QK_JOYSTICK_BUTTON_26`|`JS_26`|Button 26 |
  104. |`QK_JOYSTICK_BUTTON_27`|`JS_27`|Button 27 |
  105. |`QK_JOYSTICK_BUTTON_28`|`JS_28`|Button 28 |
  106. |`QK_JOYSTICK_BUTTON_29`|`JS_29`|Button 29 |
  107. |`QK_JOYSTICK_BUTTON_30`|`JS_30`|Button 30 |
  108. |`QK_JOYSTICK_BUTTON_31`|`JS_31`|Button 31 |
  109. ## API :id=api
  110. ### `struct joystick_t` :id=api-joystick-t
  111. Contains the state of the joystick.
  112. #### Members :id=api-joystick-t-members
  113. - `uint8_t buttons[]`
  114. A bit-packed array containing the joystick button states. The size is calculated as `(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1`.
  115. - `int16_t axes[]`
  116. An array of analog values for each defined axis.
  117. - `bool dirty`
  118. Whether the current state needs to be sent to the host.
  119. ---
  120. ### `struct joystick_config_t` :id=api-joystick-config-t
  121. Describes a single axis.
  122. #### Members :id=api-joystick-config-t-members
  123. - `pin_t input_pin`
  124. The pin to read the analog value from, or `JS_VIRTUAL_AXIS`.
  125. - `uint16_t min_digit`
  126. The minimum analog value.
  127. - `uint16_t mid_digit`
  128. The resting or midpoint analog value.
  129. - `uint16_t max_digit`
  130. The maximum analog value.
  131. ---
  132. ### `void joystick_flush(void)` :id=api-joystick-flush
  133. Send the joystick report to the host, if it has been marked as dirty.
  134. ---
  135. ### `void register_joystick_button(uint8_t button)` :id=api-register-joystick-button
  136. Set the state of a button, and flush the report.
  137. #### Arguments :id=api-register-joystick-button-arguments
  138. - `uint8_t button`
  139. The index of the button to press, from 0 to 31.
  140. ---
  141. ### `void unregister_joystick_button(uint8_t button)` :id=api-unregister-joystick-button
  142. Reset the state of a button, and flush the report.
  143. #### Arguments :id=api-unregister-joystick-button-arguments
  144. - `uint8_t button`
  145. The index of the button to release, from 0 to 31.
  146. ---
  147. ### `int16_t joystick_read_axis(uint8_t axis)` :id=api-joystick-read-axis
  148. Sample and process the analog value of the given axis.
  149. #### Arguments :id=api-joystick-read-axis-arguments
  150. - `uint8_t axis`
  151. The axis to read.
  152. #### Return Value :id=api-joystick-read-axis-return
  153. A signed 16-bit integer, where 0 is the resting or mid point.
  154. ### `void joystick_set_axis(uint8_t axis, int16_t value)` :id=api-joystick-set-axis
  155. Set the value of the given axis.
  156. #### Arguments :id=api-joystick-set-axis-arguments
  157. - `uint8_t axis`
  158. The axis to set the value of.
  159. - `int16_t value`
  160. The value to set.