summaryrefslogtreecommitdiffhomepage
path: root/dinput/win32-joystick.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'dinput/win32-joystick.hpp')
-rw-r--r--dinput/win32-joystick.hpp74
1 files changed, 39 insertions, 35 deletions
diff --git a/dinput/win32-joystick.hpp b/dinput/win32-joystick.hpp
index 42ecf57f..8e5344d6 100644
--- a/dinput/win32-joystick.hpp
+++ b/dinput/win32-joystick.hpp
@@ -7,65 +7,67 @@
*/
#pragma once
-#ifdef _WIN32
-
#include "dinput.hpp"
#include "compat/timer.hpp"
#include "export.hpp"
-#include <cstring>
+#include "compat/qhash.hpp"
+
#include <memory>
#include <vector>
#include <functional>
-#include <algorithm>
#include <unordered_map>
+#include <iterator>
+
#include <QString>
-#include <QDebug>
#include <QMutex>
-#include <QMutexLocker>
-#include <QWidget>
-namespace std {
-template<>
-struct hash<QString>
-{
- inline std::size_t operator()(const QString& value) const
- {
- return qHash(value);
- }
-};
-}
+namespace win32_joy_impl {
+
+static constexpr unsigned max_buttons = 128;
+static constexpr unsigned max_pov_hats = 4;
+static constexpr unsigned pov_hat_directions = 8;
+
+// cf. https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v=vs.85)
+// see also remarks on the page
+// no need to check for pos == unsigned(-1) || pos == 0xffff,
+// this logic doesn't require that
+static constexpr unsigned value_per_pov_hat_direction = 36000 / pov_hat_directions;
+static constexpr unsigned max_buttons_and_pov_hats = max_buttons + max_pov_hats * pov_hat_directions;
-struct OTR_DINPUT_EXPORT win32_joy_ctx
+//static_assert(pov_hat_directions == 4 || pov_hat_directions == 8);
+
+// XXX how many axis update events can we reasonably get in a short time frame?
+static constexpr unsigned num_buffers = 16;
+
+//#define WIN32_JOY_DEBUG
+
+struct OTR_DINPUT_EXPORT win32_joy_ctx final
{
using fn = std::function<void(const QString& guid, int btn, bool held)>;
- struct joy
+ struct joy final
{
- LPDIRECTINPUTDEVICE8 joy_handle;
+ IDirectInputDevice8A* joy_handle;
QString guid, name;
- enum { num_pressed_keys = 128 + 4 * 4 };
- //bool pressed[num_pressed_keys] {};
- Timer first_timer;
-
- static DIDEVICEOBJECTDATA keystate_buffers[256];
+ bool last_state[max_buttons_and_pov_hats] {};
- joy(LPDIRECTINPUTDEVICE8 handle, const QString& guid, const QString& name);
+ joy(IDirectInputDevice8A* handle, const QString& guid, const QString& name);
~joy();
void release();
- bool poll(fn f);
+ bool poll(fn const& f);
};
using joys_t = std::unordered_map<QString, std::shared_ptr<joy>>;
- static constexpr inline int joy_axis_size = 65536;
+ static constexpr int joy_axis_size = 65536;
struct joy_info
{
QString name, guid;
};
- void poll(fn f);
+ void poll(fn const& f);
bool poll_axis(const QString& guid, int* axes);
std::vector<joy_info> get_joy_info();
@@ -75,8 +77,6 @@ struct OTR_DINPUT_EXPORT win32_joy_ctx
win32_joy_ctx();
void refresh();
- using di_t = dinput_handle::di_t;
-
private:
static QString guid_to_string(const GUID& guid);
@@ -84,10 +84,10 @@ private:
{
std::vector<QString> all;
joys_t joys;
- dinput_handle::di_t di;
+ di_t di;
- static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext);
- static BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* ctx);
+ static BOOL __stdcall EnumJoysticksCallback(const DIDEVICEINSTANCEA* pdidInstance, void* pContext);
+ static BOOL __stdcall EnumObjectsCallback(const DIDEVICEOBJECTINSTANCEA* pdidoi, void* ctx);
public:
static QMutex mtx;
@@ -96,9 +96,13 @@ private:
~enum_state();
void refresh();
const joys_t& get_joys() const;
+
+ enum_state(enum_state const&) = delete;
};
static enum_state enumerator;
};
-#endif
+} // ns win32_joy_impl
+
+using win32_joy_ctx = win32_joy_impl::win32_joy_ctx;