Merge pull request #31 from lioncash/hid

HIDParser: Use std::array where applicable
This commit is contained in:
Phillip Stephens 2019-08-24 18:06:10 -07:00 committed by GitHub
commit 4d1c7d444d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,8 +1,8 @@
#include "boo/inputdev/HIDParser.hpp" #include "boo/inputdev/HIDParser.hpp"
#include <algorithm> #include <algorithm>
#include <array>
#include <map> #include <map>
#include <type_traits>
#undef min #undef min
#undef max #undef max
@ -13,251 +13,257 @@ namespace boo {
* http://www.usb.org/developers/hidpage/HID1_11.pdf * http://www.usb.org/developers/hidpage/HID1_11.pdf
*/ */
static const char* UsagePageNames[] = {"Undefined", "Generic Desktop", "Simulation", "VR", "Sport", constexpr std::array<const char*, 14> UsagePageNames{
"Game Controls", "Generic Device", "Keyboard", "LEDs", "Button", "Undefined", "Generic Desktop", "Simulation", "VR", "Sport",
"Ordinal", "Telephony", "Consumer", "Digitizer"}; "Game Controls", "Generic Device", "Keyboard", "LEDs", "Button",
"Ordinal", "Telephony", "Consumer", "Digitizer",
};
static const char* GenericDesktopUsages[] = {"Undefined", constexpr std::array<const char*, 182> GenericDesktopUsages{
"Pointer", "Undefined",
"Mouse", "Pointer",
"Reserved", "Mouse",
"Joystick", "Reserved",
"Game Pad", "Joystick",
"Keyboard", "Game Pad",
"Keypad", "Keyboard",
"Multi-axis Controller", "Keypad",
"Tablet PC System Controls", "Multi-axis Controller",
nullptr, "Tablet PC System Controls",
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
"X", nullptr,
"Y", "X",
"Z", "Y",
"Rx", "Z",
"Ry", "Rx",
"Rz", "Ry",
"Slider", "Rz",
"Dial", "Slider",
"Wheel", "Dial",
"Hat Switch", "Wheel",
"Counted Buffer", "Hat Switch",
"Byte Count", "Counted Buffer",
"Motion Wakeup", "Byte Count",
"Start", "Motion Wakeup",
"Select", "Start",
"Reserved", "Select",
"Vx", "Reserved",
"Vy", "Vx",
"Vz", "Vy",
"Vbrx", "Vz",
"Vbry", "Vbrx",
"Vbrz", "Vbry",
"Vno", "Vbrz",
"Feature Notification", "Vno",
"Resolution Multiplier", "Feature Notification",
nullptr, "Resolution Multiplier",
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
"System Control", nullptr,
"System Power Down", "System Control",
"System Sleep", "System Power Down",
"System Wake Up", "System Sleep",
"System Context Menu", "System Wake Up",
"System Main Menu", "System Context Menu",
"System App Menu", "System Main Menu",
"System Menu Help", "System App Menu",
"System Menu Exit", "System Menu Help",
"System Menu Select", "System Menu Exit",
"System Menu Right", "System Menu Select",
"System Menu Left", "System Menu Right",
"System Menu Up", "System Menu Left",
"System Menu Down", "System Menu Up",
"System Cold Restart", "System Menu Down",
"System Warm Restart", "System Cold Restart",
"D-pad Up", "System Warm Restart",
"D-pad Down", "D-pad Up",
"D-pad Right", "D-pad Down",
"D-pad Left", "D-pad Right",
nullptr, "D-pad Left",
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
"System Dock", nullptr,
"System Undock", "System Dock",
"System Setup", "System Undock",
"System Break", "System Setup",
"System Debugger Break", "System Break",
"Application Break", "System Debugger Break",
"Application Debugger Break", "Application Break",
"System Speaker Mute", "Application Debugger Break",
"System Hibernate", "System Speaker Mute",
nullptr, "System Hibernate",
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
"System Display Invert", nullptr,
"System Display Internal", "System Display Invert",
"System Display External", "System Display Internal",
"System Display Both", "System Display External",
"System Display Dual", "System Display Both",
"System Display Toggle Int/Ext"}; "System Display Dual",
"System Display Toggle Int/Ext",
};
static const char* GameUsages[] = {"Undefined", constexpr std::array<const char*, 58> GameUsages{
"3D Game Controller", "Undefined",
"Pinball Device", "3D Game Controller",
"Gun Device", "Pinball Device",
nullptr, "Gun Device",
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr,
"Point of View", nullptr,
"Turn Right/Left", "Point of View",
"Pitch Forward/Backward", "Turn Right/Left",
"Roll Right/Left", "Pitch Forward/Backward",
"Move Right/Left", "Roll Right/Left",
"Move Forward/Backward", "Move Right/Left",
"Move Up/Down", "Move Forward/Backward",
"Lean Right/Left", "Move Up/Down",
"Lean Forward/Backward", "Lean Right/Left",
"Height of POV", "Lean Forward/Backward",
"Flipper", "Height of POV",
"Secondary Flipper", "Flipper",
"Bump", "Secondary Flipper",
"New Game", "Bump",
"Shoot Ball", "New Game",
"Player", "Shoot Ball",
"Gun Bolt", "Player",
"Gun Clip", "Gun Bolt",
"Gun Selector", "Gun Clip",
"Gun Single Shot", "Gun Selector",
"Gun Burst", "Gun Single Shot",
"Gun Automatic", "Gun Burst",
"Gun Safety", "Gun Automatic",
"Gemepad Fire/Jump", "Gun Safety",
nullptr, "Gemepad Fire/Jump",
"Gamepad Trigger"}; nullptr,
"Gamepad Trigger",
};
enum class HIDCollectionType : uint8_t { enum class HIDCollectionType : uint8_t {
Physical, Physical,
@ -382,21 +388,31 @@ HIDMainItem::HIDMainItem(uint32_t flags, HIDUsagePage usagePage, HIDUsage usage,
, m_reportSize(reportSize) {} , m_reportSize(reportSize) {}
const char* HIDMainItem::GetUsagePageName() const { const char* HIDMainItem::GetUsagePageName() const {
if (int(m_usagePage) >= std::extent<decltype(UsagePageNames)>::value) const auto index = size_t(m_usagePage);
if (index >= UsagePageNames.size()) {
return nullptr; return nullptr;
return UsagePageNames[int(m_usagePage)]; }
return UsagePageNames[index];
} }
const char* HIDMainItem::GetUsageName() const { const char* HIDMainItem::GetUsageName() const {
const auto index = size_t(m_usage);
switch (m_usagePage) { switch (m_usagePage) {
case HIDUsagePage::GenericDesktop: case HIDUsagePage::GenericDesktop:
if (int(m_usage) >= std::extent<decltype(GenericDesktopUsages)>::value) if (index >= GenericDesktopUsages.size()) {
return nullptr; return nullptr;
return GenericDesktopUsages[int(m_usage)]; }
return GenericDesktopUsages[index];
case HIDUsagePage::Game: case HIDUsagePage::Game:
if (int(m_usage) >= std::extent<decltype(GameUsages)>::value) if (index >= GameUsages.size()) {
return nullptr; return nullptr;
return GameUsages[int(m_usage)]; }
return GameUsages[index];
default: default:
return nullptr; return nullptr;
} }
@ -445,17 +461,17 @@ HIDParser::ParserStatus HIDParser::Parse(const PHIDP_PREPARSED_DATA descriptorDa
USHORT length = caps.NumberInputButtonCaps; USHORT length = caps.NumberInputButtonCaps;
std::vector<HIDP_BUTTON_CAPS> bCaps(caps.NumberInputButtonCaps, HIDP_BUTTON_CAPS()); std::vector<HIDP_BUTTON_CAPS> bCaps(caps.NumberInputButtonCaps, HIDP_BUTTON_CAPS());
HidP_GetButtonCaps(HidP_Input, bCaps.data(), &length, descriptorData); HidP_GetButtonCaps(HidP_Input, bCaps.data(), &length, descriptorData);
for (const HIDP_BUTTON_CAPS& caps : bCaps) { for (const HIDP_BUTTON_CAPS& buttonCaps : bCaps) {
if (caps.IsRange) { if (buttonCaps.IsRange) {
int usage = caps.Range.UsageMin; int usage = buttonCaps.Range.UsageMin;
for (int i = caps.Range.DataIndexMin; i <= caps.Range.DataIndexMax; ++i, ++usage) { for (int i = buttonCaps.Range.DataIndexMin; i <= buttonCaps.Range.DataIndexMax; ++i, ++usage) {
inputItems.insert(std::make_pair( inputItems.emplace(i, HIDMainItem(buttonCaps.BitField, HIDUsagePage(buttonCaps.UsagePage), HIDUsage(usage),
i, HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(usage), std::make_pair(0, 1), 1))); std::make_pair(0, 1), 1));
} }
} else { } else {
inputItems.insert(std::make_pair(caps.NotRange.DataIndex, inputItems.emplace(buttonCaps.NotRange.DataIndex,
HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDMainItem(buttonCaps.BitField, HIDUsagePage(buttonCaps.UsagePage),
HIDUsage(caps.NotRange.Usage), std::make_pair(0, 1), 1))); HIDUsage(buttonCaps.NotRange.Usage), std::make_pair(0, 1), 1));
} }
} }
} }
@ -465,19 +481,19 @@ HIDParser::ParserStatus HIDParser::Parse(const PHIDP_PREPARSED_DATA descriptorDa
USHORT length = caps.NumberInputValueCaps; USHORT length = caps.NumberInputValueCaps;
std::vector<HIDP_VALUE_CAPS> vCaps(caps.NumberInputValueCaps, HIDP_VALUE_CAPS()); std::vector<HIDP_VALUE_CAPS> vCaps(caps.NumberInputValueCaps, HIDP_VALUE_CAPS());
HidP_GetValueCaps(HidP_Input, vCaps.data(), &length, descriptorData); HidP_GetValueCaps(HidP_Input, vCaps.data(), &length, descriptorData);
for (const HIDP_VALUE_CAPS& caps : vCaps) { for (const HIDP_VALUE_CAPS& valueCaps : vCaps) {
if (caps.IsRange) { if (valueCaps.IsRange) {
int usage = caps.Range.UsageMin; int usage = valueCaps.Range.UsageMin;
for (int i = caps.Range.DataIndexMin; i <= caps.Range.DataIndexMax; ++i, ++usage) { for (int i = valueCaps.Range.DataIndexMin; i <= valueCaps.Range.DataIndexMax; ++i, ++usage) {
inputItems.insert( inputItems.emplace(i, HIDMainItem(valueCaps.BitField, HIDUsagePage(valueCaps.UsagePage), HIDUsage(usage),
std::make_pair(i, HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(usage), std::make_pair(valueCaps.LogicalMin, valueCaps.LogicalMax),
std::make_pair(caps.LogicalMin, caps.LogicalMax), caps.BitSize))); valueCaps.BitSize));
} }
} else { } else {
inputItems.insert( inputItems.emplace(valueCaps.NotRange.DataIndex,
std::make_pair(caps.NotRange.DataIndex, HIDMainItem(valueCaps.BitField, HIDUsagePage(valueCaps.UsagePage),
HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(caps.NotRange.Usage), HIDUsage(valueCaps.NotRange.Usage),
HIDRange(caps.LogicalMin, caps.LogicalMax), caps.BitSize))); HIDRange(valueCaps.LogicalMin, valueCaps.LogicalMax), valueCaps.BitSize));
} }
} }
} }
@ -806,9 +822,9 @@ void HIDParser::ScanValues(const std::function<bool(const HIDMainItem& item, int
continue; continue;
int32_t value = 0; int32_t value = 0;
if (it != end) { if (it != end) {
const HIDP_DATA& data = *it; const HIDP_DATA& hidData = *it;
if (data.DataIndex == idx) { if (hidData.DataIndex == idx) {
value = data.RawValue; value = hidData.RawValue;
++it; ++it;
} }
} }