summaryrefslogtreecommitdiffhomepage
path: root/dinput/dinput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dinput/dinput.cpp')
-rw-r--r--dinput/dinput.cpp124
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;
}