joystick.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*************************************************************************/
  2. /* joystick.h */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. //author: Andreas Haas <hondres, [email protected]>
  31. #ifndef JOYSTICK_H
  32. #define JOYSTICK_H
  33. #include "os_windows.h"
  34. #define DIRECTINPUT_VERSION 0x0800
  35. #include <dinput.h>
  36. #include <xinput.h> // on unix the file is called "xinput.h", on windows I'm sure it won't mind
  37. #ifndef SAFE_RELEASE // when Windows Media Device M? is not present
  38. #define SAFE_RELEASE(x) \
  39. if (x != NULL) { \
  40. x->Release(); \
  41. x = NULL; \
  42. }
  43. #endif
  44. #ifndef XUSER_MAX_COUNT
  45. #define XUSER_MAX_COUNT 4
  46. #endif
  47. class joystick_windows {
  48. public:
  49. joystick_windows();
  50. joystick_windows(InputDefault *_input, HWND *hwnd);
  51. ~joystick_windows();
  52. void probe_joysticks();
  53. unsigned int process_joysticks(unsigned int p_last_id);
  54. private:
  55. enum {
  56. JOYSTICKS_MAX = 16,
  57. JOY_AXIS_COUNT = 6,
  58. MIN_JOY_AXIS = 10,
  59. MAX_JOY_AXIS = 32768,
  60. MAX_JOY_BUTTONS = 128,
  61. KEY_EVENT_BUFFER_SIZE = 512,
  62. MAX_TRIGGER = 255
  63. };
  64. struct dinput_gamepad {
  65. int id;
  66. bool attached;
  67. bool confirmed;
  68. bool last_buttons[MAX_JOY_BUTTONS];
  69. DWORD last_pad;
  70. LPDIRECTINPUTDEVICE8 di_joy;
  71. List<DWORD> joy_axis;
  72. GUID guid;
  73. dinput_gamepad() {
  74. id = -1;
  75. last_pad = -1;
  76. attached = false;
  77. confirmed = false;
  78. for (int i = 0; i < MAX_JOY_BUTTONS; i++)
  79. last_buttons[i] = false;
  80. }
  81. };
  82. struct xinput_gamepad {
  83. int id;
  84. bool attached;
  85. bool vibrating;
  86. DWORD last_packet;
  87. XINPUT_STATE state;
  88. uint64_t ff_timestamp;
  89. uint64_t ff_end_timestamp;
  90. xinput_gamepad() {
  91. attached = false;
  92. vibrating = false;
  93. ff_timestamp = 0;
  94. ff_end_timestamp = 0;
  95. last_packet = 0;
  96. }
  97. };
  98. typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex, XINPUT_STATE *pState);
  99. typedef DWORD(WINAPI *XInputSetState_t)(DWORD dwUserIndex, XINPUT_VIBRATION *pVibration);
  100. HWND *hWnd;
  101. HANDLE xinput_dll;
  102. LPDIRECTINPUT8 dinput;
  103. InputDefault *input;
  104. int id_to_change;
  105. int joystick_count;
  106. bool attached_joysticks[JOYSTICKS_MAX];
  107. dinput_gamepad d_joysticks[JOYSTICKS_MAX];
  108. xinput_gamepad x_joysticks[XUSER_MAX_COUNT];
  109. static BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE *p_instance, void *p_context);
  110. static BOOL CALLBACK objectsCallback(const DIDEVICEOBJECTINSTANCE *instance, void *context);
  111. void setup_joystick_object(const DIDEVICEOBJECTINSTANCE *ob, int p_joy_id);
  112. void close_joystick(int id = -1);
  113. void load_xinput();
  114. void unload_xinput();
  115. unsigned int post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad);
  116. bool have_device(const GUID &p_guid);
  117. bool is_xinput_device(const GUID *p_guid);
  118. bool setup_dinput_joystick(const DIDEVICEINSTANCE *instance);
  119. void joystick_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
  120. void joystick_vibration_stop_xinput(int p_device, uint64_t p_timestamp);
  121. InputDefault::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const;
  122. XInputGetState_t xinput_get_state;
  123. XInputSetState_t xinput_set_state;
  124. };
  125. #endif