summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2016-06-29 13:09:28 +0200
committerStanislaw Halik <sthalik@misaki.pl>2016-06-29 13:18:33 +0200
commit91160a1142e8564f3ba46a71d86dc88dcbd66114 (patch)
tree2008fd69739875ed017cb95c49b747081dd96c6e
parent7e5fae3f4b8de73894e811e7a282d9175e3ab970 (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.cpp53
-rw-r--r--opentrack-logic/win32-joystick.hpp3
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();