diff options
Diffstat (limited to 'dinput/win32-joystick.hpp')
-rw-r--r-- | dinput/win32-joystick.hpp | 74 |
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; |