diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2016-06-29 13:09:28 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2016-06-29 13:18:33 +0200 |
commit | 91160a1142e8564f3ba46a71d86dc88dcbd66114 (patch) | |
tree | 2008fd69739875ed017cb95c49b747081dd96c6e | |
parent | 7e5fae3f4b8de73894e811e7a282d9175e3ab970 (diff) |
logic/joystick: treat each POV hat as 4 buttons
dinput8 has separate logic for pov hats. Before pov hat state was
totally ignored.
Don't support 8-way buttons. Only one button gets registered after a
diagonal pov hat press.
-rw-r--r-- | opentrack-logic/win32-joystick.cpp | 53 | ||||
-rw-r--r-- | opentrack-logic/win32-joystick.hpp | 3 |
2 files changed, 45 insertions, 11 deletions
diff --git a/opentrack-logic/win32-joystick.cpp b/opentrack-logic/win32-joystick.cpp index 02b8c6d1..b16a7021 100644 --- a/opentrack-logic/win32-joystick.cpp +++ b/opentrack-logic/win32-joystick.cpp @@ -2,7 +2,9 @@ #undef NDEBUG #include <cassert> +#include <cstring> #include <algorithm> +#include <cmath> #include "win32-joystick.hpp" #include "opentrack-compat/sleep.hpp" @@ -62,7 +64,7 @@ bool win32_joy_ctx::poll_axis(const QString &guid, int* axes) } DIJOYSTATE2 js; - memset(&js, 0, sizeof(js)); + std::memset(&js, 0, sizeof(js)); if (FAILED(hr = joy_handle->GetDeviceState(sizeof(js), &js))) { @@ -175,7 +177,7 @@ bool win32_joy_ctx::joy::poll(fn f) } DIJOYSTATE2 js; - memset(&js, 0, sizeof(js)); + std::memset(&js, 0, sizeof(js)); if (FAILED(hr = joy_handle->GetDeviceState(sizeof(js), &js))) { @@ -183,9 +185,46 @@ bool win32_joy_ctx::joy::poll(fn f) return false; } + for (unsigned i = 0; i < 4; i++) + { + using std::round; + + unsigned char pos; + unsigned pos_ = js.rgdwPOV[i]; + if ((pos_ & 0xffff) == 0xffff) + pos = 0; + else if (pos_ == ~0u) + pos = 0; + else + { + using uc = unsigned char; + pos = uc(((pos_ / 9000u) % 4u) + 1u); + } + + const bool state[] = + { + pos == 1, + pos == 2, + pos == 3, + pos == 4 + }; + + unsigned idx = 128u + i * 4u; + + for (unsigned j = 0; j < 4; j++, idx++) + { + if (state[j] != pressed[idx]) + { + f(guid, int(idx), state[j]); + qDebug() << "hat" << guid << i << "btn" << j << state[j]; + pressed[idx] = state[j]; + } + } + } + for (int i = 0; i < 128; i++) { - const bool state = !!(js.rgbButtons[i] & 0x80) && js.rgbButtons[i] != js_old.rgbButtons[i]; + const bool state = !!(js.rgbButtons[i] & 0x80); if (state != pressed[i]) { f(guid, i, state); @@ -194,8 +233,6 @@ bool win32_joy_ctx::joy::poll(fn f) pressed[i] = state; } - js_old = js; - return true; } @@ -316,7 +353,7 @@ BOOL CALLBACK win32_joy_ctx::enum_state::EnumObjectsCallback(const DIDEVICEOBJEC if (pdidoi->dwType & DIDFT_AXIS) { DIPROPRANGE diprg; - memset(&diprg, 0, sizeof(diprg)); + std::memset(&diprg, 0, sizeof(diprg)); diprg.diph.dwSize = sizeof( DIPROPRANGE ); diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER ); diprg.diph.dwHow = DIPH_BYID; @@ -340,9 +377,7 @@ win32_joy_ctx::joy::joy(LPDIRECTINPUTDEVICE8 handle, const QString &guid, const : joy_handle(handle), guid(guid), name(name) { qDebug() << "make joy" << guid << name << joy_handle; - for (int i = 0; i < 128; i++) - pressed[i] = false; - memset(&js_old, 0, sizeof(js_old)); + std::memset(pressed, 0, sizeof(pressed)); } win32_joy_ctx::joy::~joy() diff --git a/opentrack-logic/win32-joystick.hpp b/opentrack-logic/win32-joystick.hpp index ac592a54..0da5554b 100644 --- a/opentrack-logic/win32-joystick.hpp +++ b/opentrack-logic/win32-joystick.hpp @@ -42,9 +42,8 @@ struct OPENTRACK_LOGIC_EXPORT win32_joy_ctx { LPDIRECTINPUTDEVICE8 joy_handle; QString guid, name; - bool pressed[128]; + bool pressed[128 + 4 * 4]; Timer first_timer; - DIJOYSTATE2 js_old; joy(LPDIRECTINPUTDEVICE8 handle, const QString& guid, const QString& name); ~joy(); |