windows.cpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include <xinput.h>
  2. #define DIRECTINPUT_VERSION 0x0800
  3. #include <dinput.h>
  4. #include "shared/rawinput.cpp"
  5. #include "keyboard/rawinput.cpp"
  6. #include "mouse/rawinput.cpp"
  7. #include "joypad/xinput.cpp"
  8. #include "joypad/directinput.cpp"
  9. struct InputWindows : InputDriver {
  10. InputWindows& self = *this;
  11. InputWindows(Input& super) : InputDriver(super), keyboard(super), mouse(super), joypadXInput(super), joypadDirectInput(super) {}
  12. ~InputWindows() { terminate(); }
  13. auto create() -> bool override {
  14. return initialize();
  15. }
  16. auto driver() -> string override { return "Windows"; }
  17. auto ready() -> bool override { return isReady; }
  18. auto hasContext() -> bool override { return true; }
  19. auto setContext(uintptr context) -> bool override { return initialize(); }
  20. auto acquired() -> bool override { return mouse.acquired(); }
  21. auto acquire() -> bool override { return mouse.acquire(); }
  22. auto release() -> bool override { return mouse.release(); }
  23. auto poll() -> vector<shared_pointer<HID::Device>> override {
  24. vector<shared_pointer<HID::Device>> devices;
  25. keyboard.poll(devices);
  26. mouse.poll(devices);
  27. joypadXInput.poll(devices);
  28. joypadDirectInput.poll(devices);
  29. return devices;
  30. }
  31. auto rumble(uint64_t id, bool enable) -> bool override {
  32. if(joypadXInput.rumble(id, enable)) return true;
  33. if(joypadDirectInput.rumble(id, enable)) return true;
  34. return false;
  35. }
  36. private:
  37. auto initialize() -> bool {
  38. terminate();
  39. if(!self.context) return false;
  40. //TODO: this won't work if Input is recreated post-initialization; nor will it work with multiple Input instances
  41. if(!rawinput.initialized) {
  42. rawinput.initialized = true;
  43. rawinput.mutex = CreateMutex(nullptr, false, nullptr);
  44. CreateThread(nullptr, 0, RawInputThreadProc, 0, 0, nullptr);
  45. do {
  46. Sleep(1);
  47. WaitForSingleObject(rawinput.mutex, INFINITE);
  48. ReleaseMutex(rawinput.mutex);
  49. } while(!rawinput.ready);
  50. }
  51. DirectInput8Create(GetModuleHandle(0), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&directInputContext, 0);
  52. if(!directInputContext) return false;
  53. if(!keyboard.initialize()) return false;
  54. if(!mouse.initialize(self.context)) return false;
  55. bool xinputAvailable = joypadXInput.initialize();
  56. if(!joypadDirectInput.initialize(self.context, directInputContext, xinputAvailable)) return false;
  57. return isReady = true;
  58. }
  59. auto terminate() -> void {
  60. isReady = false;
  61. keyboard.terminate();
  62. mouse.terminate();
  63. joypadXInput.terminate();
  64. joypadDirectInput.terminate();
  65. if(directInputContext) {
  66. directInputContext->Release();
  67. directInputContext = nullptr;
  68. }
  69. }
  70. bool isReady = false;
  71. InputKeyboardRawInput keyboard;
  72. InputMouseRawInput mouse;
  73. InputJoypadXInput joypadXInput;
  74. InputJoypadDirectInput joypadDirectInput;
  75. LPDIRECTINPUT8 directInputContext = nullptr;
  76. };