summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dinput/keybinding-worker.cpp166
-rw-r--r--dinput/keybinding-worker.hpp3
2 files changed, 92 insertions, 77 deletions
diff --git a/dinput/keybinding-worker.cpp b/dinput/keybinding-worker.cpp
index 9c2b06d4..8ef99921 100644
--- a/dinput/keybinding-worker.cpp
+++ b/dinput/keybinding-worker.cpp
@@ -114,83 +114,13 @@ void KeybindingWorker::run()
if (!receivers.empty())
{
- /* There are some problems reported on various forums
- * with regard to key-up events. But that's what I dug up:
- *
- * https://www.gamedev.net/forums/topic/633011-keyboard-getdevicedata-buffered-never-releases-keys/
- *
- * "Over in the xna forums (http://xboxforums.create.msdn.com/forums/p/108722/642144.aspx#642144)
- * we discovered this behavior is caused by calling Unacquire in your event processing loop.
- * Funnily enough only the keyboard seems to be affected."
- *
- * Key-up events work on my end.
- */
-
- {
- DWORD sz = num_keyboard_states;
- const HRESULT hr = dinkeyboard->GetDeviceData(sizeof(*keyboard_states), keyboard_states, &sz, 0);
-
- if (hr != DI_OK)
- {
- qDebug() << "Tracker::run GetDeviceData function failed!" << hr;
- Sleep(25);
- continue;
- }
- else
- {
- for (unsigned k = 0; k < sz; k++)
- {
- const unsigned idx = keyboard_states[k].dwOfs & 0xff; // defensive programming
- const bool held = !!(keyboard_states[k].dwData & 0x80);
-
- switch (idx)
- {
- case DIK_LCONTROL:
- case DIK_LSHIFT:
- case DIK_LALT:
- case DIK_RCONTROL:
- case DIK_RSHIFT:
- case DIK_RALT:
- case DIK_LWIN:
- case DIK_RWIN:
- break;
- default:
- {
- Key k;
- k.shift = keystate[DIK_LSHIFT] | keystate[DIK_RSHIFT];
- k.alt = keystate[DIK_LALT] | keystate[DIK_RALT];
- k.ctrl = keystate[DIK_LCONTROL] | keystate[DIK_RCONTROL];
- k.keycode = idx;
- k.held = held;
-
- for (auto& r : receivers)
- (*r)(k);
- break;
- }
- }
- keystate[idx] = held;
- }
- }
- }
-
- {
- using joy_fn = std::function<void(const QString& guid, int idx, bool held)>;
-
- joy_fn f = [&](const QString& guid, int idx, bool held) {
- Key k;
- k.keycode = idx;
- k.shift = keystate[DIK_LSHIFT] | keystate[DIK_RSHIFT];
- k.alt = keystate[DIK_LALT] | keystate[DIK_RALT];
- k.ctrl = keystate[DIK_LCONTROL] | keystate[DIK_RCONTROL];
- k.guid = guid;
- k.held = held;
-
- for (auto& r : receivers)
- (*r)(k);
- };
-
- joy_ctx.poll(f);
- }
+ bool ok = true;
+
+ ok &= run_keyboard_nolock();
+ ok &= run_joystick_nolock();
+
+ if (!ok)
+ Sleep(500);
}
}
@@ -198,6 +128,88 @@ void KeybindingWorker::run()
}
}
+bool KeybindingWorker::run_keyboard_nolock()
+{
+ /* There are some problems reported on various forums
+ * with regard to key-up events. But that's what I dug up:
+ *
+ * https://www.gamedev.net/forums/topic/633011-keyboard-getdevicedata-buffered-never-releases-keys/
+ *
+ * "Over in the xna forums (http://xboxforums.create.msdn.com/forums/p/108722/642144.aspx#642144)
+ * we discovered this behavior is caused by calling Unacquire in your event processing loop.
+ * Funnily enough only the keyboard seems to be affected."
+ *
+ * Key-up events work on my end.
+ */
+
+ DWORD sz = num_keyboard_states;
+ const HRESULT hr = dinkeyboard->GetDeviceData(sizeof(*keyboard_states), keyboard_states, &sz, 0);
+
+ if (hr != DI_OK)
+ {
+ eval_once(qDebug() << "dinput: keyboard GetDeviceData failed" << hr);
+ return false;
+ }
+
+ for (unsigned k = 0; k < sz; k++)
+ {
+ const unsigned idx = keyboard_states[k].dwOfs & 0xff; // defensive programming
+ const bool held = !!(keyboard_states[k].dwData & 0x80);
+
+ switch (idx)
+ {
+ case DIK_LCONTROL:
+ case DIK_LSHIFT:
+ case DIK_LALT:
+ case DIK_RCONTROL:
+ case DIK_RSHIFT:
+ case DIK_RALT:
+ case DIK_LWIN:
+ case DIK_RWIN:
+ break;
+ default:
+ {
+ Key k;
+ k.shift = keystate[DIK_LSHIFT] | keystate[DIK_RSHIFT];
+ k.alt = keystate[DIK_LALT] | keystate[DIK_RALT];
+ k.ctrl = keystate[DIK_LCONTROL] | keystate[DIK_RCONTROL];
+ k.keycode = idx;
+ k.held = held;
+
+ for (auto& r : receivers)
+ (*r)(k);
+ }
+ break;
+ }
+
+ keystate[idx] = held;
+ }
+
+ return true;
+}
+
+bool KeybindingWorker::run_joystick_nolock()
+{
+ using joy_fn = std::function<void(const QString& guid, int idx, bool held)>;
+
+ joy_fn f = [&](const QString& guid, int idx, bool held) {
+ Key k;
+ k.keycode = idx;
+ k.shift = keystate[DIK_LSHIFT] | keystate[DIK_RSHIFT];
+ k.alt = keystate[DIK_LALT] | keystate[DIK_RALT];
+ k.ctrl = keystate[DIK_LCONTROL] | keystate[DIK_RCONTROL];
+ k.guid = guid;
+ k.held = held;
+
+ for (auto& r : receivers)
+ (*r)(k);
+ };
+
+ joy_ctx.poll(f);
+
+ return true;
+}
+
KeybindingWorker::fun* KeybindingWorker::_add_receiver(fun& receiver)
{
QMutexLocker l(&mtx);
diff --git a/dinput/keybinding-worker.hpp b/dinput/keybinding-worker.hpp
index 6b7d6882..9d067c10 100644
--- a/dinput/keybinding-worker.hpp
+++ b/dinput/keybinding-worker.hpp
@@ -53,6 +53,9 @@ private:
bool old_keystate[256] {};
void run() override;
+ bool run_keyboard_nolock();
+ bool run_joystick_nolock();
+
bool init();
KeybindingWorker();