mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 01:02:03 +00:00
Added polling of analog axes to IOKit gaming controllers handling
This feature helps a lot with buggy gamepads that constantly generate events from "sticky" hats/sticks Polling is enabled by default, use joy_axespolling CVAR to turn it on/off
This commit is contained in:
parent
2b12db153b
commit
31d232e886
1 changed files with 81 additions and 4 deletions
|
@ -45,6 +45,9 @@
|
|||
#include "v_text.h"
|
||||
|
||||
|
||||
EXTERN_CVAR(Bool, joy_axespolling)
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
@ -105,6 +108,8 @@ public:
|
|||
|
||||
void Update();
|
||||
|
||||
void UseAxesPolling(bool axesPolling);
|
||||
|
||||
private:
|
||||
IOHIDDeviceInterface** m_interface;
|
||||
IOHIDQueueInterface** m_queue;
|
||||
|
@ -154,6 +159,8 @@ private:
|
|||
TArray<DigitalButton> m_buttons;
|
||||
TArray<DigitalButton> m_POVs;
|
||||
|
||||
bool m_useAxesPolling;
|
||||
|
||||
|
||||
static const float DEFAULT_DEADZONE;
|
||||
static const float DEFAULT_SENSITIVITY;
|
||||
|
@ -171,7 +178,9 @@ private:
|
|||
void AddAxis(CFDictionaryRef element);
|
||||
void AddButton(CFDictionaryRef element);
|
||||
void AddPOV(CFDictionaryRef element);
|
||||
|
||||
void AddToQueue(IOHIDElementCookie cookie);
|
||||
void RemoveFromQueue(IOHIDElementCookie cookie);
|
||||
};
|
||||
|
||||
|
||||
|
@ -261,6 +270,7 @@ IOKitJoystick::IOKitJoystick(const io_object_t device)
|
|||
: m_interface(CreateDeviceInterface(device))
|
||||
, m_queue(CreateDeviceQueue(m_interface))
|
||||
, m_sensitivity(DEFAULT_SENSITIVITY)
|
||||
, m_useAxesPolling(true)
|
||||
{
|
||||
if (NULL == m_interface || NULL == m_queue)
|
||||
{
|
||||
|
@ -282,6 +292,8 @@ IOKitJoystick::IOKitJoystick(const io_object_t device)
|
|||
|
||||
CFRelease(properties);
|
||||
|
||||
UseAxesPolling(joy_axespolling);
|
||||
|
||||
(*m_queue)->start(m_queue);
|
||||
|
||||
SetDefaultConfig();
|
||||
|
@ -486,6 +498,26 @@ void IOKitJoystick::AddAxes(float axes[NUM_JOYAXIS]) const
|
|||
}
|
||||
|
||||
|
||||
void IOKitJoystick::UseAxesPolling(const bool axesPolling)
|
||||
{
|
||||
m_useAxesPolling = axesPolling;
|
||||
|
||||
for (size_t i = 0, count = m_axes.Size(); i < count; ++i)
|
||||
{
|
||||
AnalogAxis& axis = m_axes[i];
|
||||
|
||||
if (m_useAxesPolling)
|
||||
{
|
||||
RemoveFromQueue(axis.cookie);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddToQueue(axis.cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystick::Update()
|
||||
{
|
||||
if (NULL == m_queue)
|
||||
|
@ -509,12 +541,14 @@ void IOKitJoystick::Update()
|
|||
{
|
||||
Printf(TEXTCOLOR_RED "IOHIDQueueInterface::getNextEvent() failed with code 0x%08X\n", eventResult);
|
||||
}
|
||||
|
||||
ProcessAxes();
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystick::ProcessAxes()
|
||||
{
|
||||
if (NULL == m_interface)
|
||||
if (NULL == m_interface || !m_useAxesPolling)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -546,6 +580,11 @@ void IOKitJoystick::ProcessAxes()
|
|||
|
||||
bool IOKitJoystick::ProcessAxis(const IOHIDEventStruct& event)
|
||||
{
|
||||
if (m_useAxesPolling)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0, count = m_axes.Size(); i < count; ++i)
|
||||
{
|
||||
if (event.elementCookie != m_axes[i].cookie)
|
||||
|
@ -827,8 +866,6 @@ void IOKitJoystick::AddAxis(const CFDictionaryRef element)
|
|||
}
|
||||
|
||||
m_axes.Push(axis);
|
||||
|
||||
AddToQueue(axis.cookie);
|
||||
}
|
||||
|
||||
void IOKitJoystick::AddButton(CFDictionaryRef element)
|
||||
|
@ -849,9 +886,13 @@ void IOKitJoystick::AddPOV(CFDictionaryRef element)
|
|||
AddToQueue(pov.cookie);
|
||||
}
|
||||
|
||||
|
||||
void IOKitJoystick::AddToQueue(const IOHIDElementCookie cookie)
|
||||
{
|
||||
assert(NULL != m_queue);
|
||||
if (NULL == m_queue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(*m_queue)->hasElement(m_queue, cookie))
|
||||
{
|
||||
|
@ -859,6 +900,19 @@ void IOKitJoystick::AddToQueue(const IOHIDElementCookie cookie)
|
|||
}
|
||||
}
|
||||
|
||||
void IOKitJoystick::RemoveFromQueue(const IOHIDElementCookie cookie)
|
||||
{
|
||||
if (NULL == m_queue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*m_queue)->hasElement(m_queue, cookie))
|
||||
{
|
||||
(*m_queue)->removeElement(m_queue, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -879,6 +933,8 @@ public:
|
|||
// Rebuilds device list
|
||||
void Rescan();
|
||||
|
||||
void UseAxesPolling(bool axesPolling);
|
||||
|
||||
private:
|
||||
TArray<IOKitJoystick*> m_joysticks;
|
||||
|
||||
|
@ -993,6 +1049,15 @@ void IOKitJoystickManager::ReleaseJoysticks()
|
|||
}
|
||||
|
||||
|
||||
void IOKitJoystickManager::UseAxesPolling(const bool axesPolling)
|
||||
{
|
||||
for (size_t i = 0, count = m_joysticks.Size(); i <count; ++i)
|
||||
{
|
||||
m_joysticks[i]->UseAxesPolling(axesPolling);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IOKitJoystickManager* s_joystickManager;
|
||||
|
||||
|
||||
|
@ -1068,3 +1133,15 @@ void I_ProcessJoysticks()
|
|||
s_joystickManager->Update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
CUSTOM_CVAR(Bool, joy_axespolling, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
if (NULL != s_joystickManager)
|
||||
{
|
||||
s_joystickManager->UseAxesPolling(self);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue