diff options
Diffstat (limited to 'dinput/dinput.cpp')
-rw-r--r-- | dinput/dinput.cpp | 124 |
1 files changed, 67 insertions, 57 deletions
diff --git a/dinput/dinput.cpp b/dinput/dinput.cpp index 226d3277..b9713b8a 100644 --- a/dinput/dinput.cpp +++ b/dinput/dinput.cpp @@ -1,88 +1,98 @@ +#undef NDEBUG + #include "dinput.hpp" -#include <QDebug> +#include "compat/macros.h" -std::atomic<int> dinput_handle::refcnt; -std::atomic_flag dinput_handle::init_lock = ATOMIC_FLAG_INIT; +#include <cassert> +#include <cstdlib> +#include <dinput.h> -LPDIRECTINPUT8& dinput_handle::init_di() -{ - CoInitialize(nullptr); +#include <QDebug> - static LPDIRECTINPUT8 di_ = nullptr; - if (di_ == nullptr) - { - if (!SUCCEEDED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di_, NULL))) - { - di_ = nullptr; - } - } - return di_; -} +diptr di_t::handle; +QMutex di_t::lock; -dinput_handle::di_t dinput_handle::make_di() +diptr di_t::init_di() { - while (init_lock.test_and_set()) { /* busy loop */ } + QMutexLocker l(&lock); - LPDIRECTINPUT8& ret = init_di(); + CoInitialize(nullptr); - init_lock.clear(); + if (!handle) + handle = init_di_(); - return di_t(ret); + return handle; } -void dinput_handle::di_t::free_di() +diptr di_t::operator->() const { - if (handle && *handle) - { - (*handle)->Release(); - *handle = nullptr; - } - handle = nullptr; + return init_di(); } -void dinput_handle::di_t::ref_di() +di_t::operator bool() const { - //const int refcnt_ = refcnt.fetch_add(1) + 1; - (void) refcnt.fetch_add(1); + return !!init_di(); } -dinput_handle::di_t& dinput_handle::di_t::operator=(const di_t& new_di) +di_t::operator diptr() const { - if (handle) - unref_di(); + return init_di(); +} - handle = new_di.handle; +diptr di_t::init_di_() +{ + diptr di = nullptr; + HRESULT hr = DirectInput8Create(GetModuleHandle(nullptr), + DIRECTINPUT_VERSION, + IID_IDirectInput8, + (void**)&di, + nullptr); + if (!SUCCEEDED(hr)) + { + qDebug() << "can't make dinput:" << (void*)(LONG_PTR)hr; + qDebug() << "crashing!"; + std::abort(); + } - if (handle) - ref_di(); + //qDebug() << "dinput: initialized"; - return *this; + return di; } -void dinput_handle::di_t::unref_di() +di_t::di_t() = default; + +bool di_t::poll_device(IDirectInputDevice8A* dev) { - const int refcnt_ = refcnt.fetch_sub(1) - 1; + HRESULT hr; + assert(handle); - if (refcnt_ == 0) + switch (dev->Poll()) { - while (init_lock.test_and_set()) { /* busy loop */ } - - qDebug() << "exit: di handle"; - free_di(); - - init_lock.clear(); + case DI_OK: + case DI_NOEFFECT: + return true; + default: + break; } -} -dinput_handle::di_t::di_t(LPDIRECTINPUT8& handle) : handle(&handle) -{ - ref_di(); -} + switch (hr = dev->Acquire()) + { + default: + break; + case DI_OK: + case S_FALSE: + switch (hr = dev->Poll()) + { + case DI_OK: + case DI_NOEFFECT: + return true; + default: + break; + } + break; + } -dinput_handle::di_t::di_t() : handle(nullptr) {} + eval_once(qDebug() << "dinput: device poll failed:" << (void*)hr); -dinput_handle::di_t::~di_t() -{ - if (handle) - unref_di(); + return false; } |