diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSX.mm b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSX.mm index 8696fb407d..1c9e60bb15 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSX.mm +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSX.mm @@ -18,61 +18,114 @@ static IOHIDManagerRef HIDManager = NULL; static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput"); +void DeviceElementDebugPrint(const void *value, void *context) +{ + IOHIDElementRef e = (IOHIDElementRef)value; + bool recurse = false; + if (context) + recurse = *(bool*)context; + + std::string type = ""; + switch (IOHIDElementGetType(e)) + { + case kIOHIDElementTypeInput_Axis: type = "axis"; break; + case kIOHIDElementTypeInput_Button: type = "button"; break; + case kIOHIDElementTypeInput_Misc: type = "misc"; break; + case kIOHIDElementTypeInput_ScanCodes: type = "scancodes"; break; + case kIOHIDElementTypeOutput: type = "output"; break; + case kIOHIDElementTypeFeature: type = "feature"; break; + case kIOHIDElementTypeCollection: type = "collection"; break; + } + + std::string c_type = ""; + if (type == "collection") + { + switch (IOHIDElementGetCollectionType(e)) + { + case kIOHIDElementCollectionTypePhysical: c_type = "physical"; break; + case kIOHIDElementCollectionTypeApplication: c_type = "application"; break; + case kIOHIDElementCollectionTypeLogical: c_type = "logical"; break; + case kIOHIDElementCollectionTypeReport: c_type = "report"; break; + case kIOHIDElementCollectionTypeNamedArray: c_type = "namedArray"; break; + case kIOHIDElementCollectionTypeUsageSwitch: c_type = "usageSwitch"; break; + case kIOHIDElementCollectionTypeUsageModifier: c_type = "usageModifier"; break; + } + } + + c_type.append(" "); + NSLog(@"%s%s%spage: 0x%x usage: 0x%x name: %s lmin: %i lmax: %i pmin: %i pmax: %i", + type.c_str(), + type == "collection" ? ":" : "", + type == "collection" ? c_type.c_str() : " ", + IOHIDElementGetUsagePage(e), + IOHIDElementGetUsage(e), + IOHIDElementGetName(e), // TOO BAD IT"S FUCKING USELESS + IOHIDElementGetLogicalMin(e), + IOHIDElementGetLogicalMax(e), + IOHIDElementGetPhysicalMin(e), + IOHIDElementGetPhysicalMax(e)); + + if ((type == "collection") && recurse) + { + CFArrayRef elements = IOHIDElementGetChildren(e); + CFRange range = {0, CFArrayGetCount(elements)}; + // this leaks...but it's just debug code, right? :D + CFArrayApplyFunction(elements, range, DeviceElementDebugPrint, NULL); + } +} + +void DeviceDebugPrint(IOHIDDeviceRef device) +{ + //#define shortlog(x) NSLog(@"%s: %@", x, IOHIDDeviceGetProperty(device, CFSTR(x))); + #ifdef shortlog + NSLog(@"-------------------------"); + NSLog(@"Got Device: %@", IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey))); + shortlog(kIOHIDTransportKey) + shortlog(kIOHIDVendorIDKey) + shortlog(kIOHIDVendorIDSourceKey) + shortlog(kIOHIDProductIDKey) + shortlog(kIOHIDVersionNumberKey) + shortlog(kIOHIDManufacturerKey) + shortlog(kIOHIDProductKey) + shortlog(kIOHIDSerialNumberKey) + shortlog(kIOHIDCountryCodeKey) + shortlog(kIOHIDLocationIDKey) + shortlog(kIOHIDDeviceUsageKey) + shortlog(kIOHIDDeviceUsagePageKey) + shortlog(kIOHIDDeviceUsagePairsKey) + shortlog(kIOHIDPrimaryUsageKey) + shortlog(kIOHIDPrimaryUsagePageKey) + shortlog(kIOHIDMaxInputReportSizeKey) + shortlog(kIOHIDMaxOutputReportSizeKey) + shortlog(kIOHIDMaxFeatureReportSizeKey) + shortlog(kIOHIDReportIntervalKey) + shortlog(kIOHIDReportDescriptorKey) + #endif + #undef shortlog +} + + static void DeviceMatching_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inIOHIDDeviceRef) { - //NSLog(@"-------------------------"); - //NSLog(@"Got Device: %@", IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductKey))); + DeviceDebugPrint(inIOHIDDeviceRef); + + std::vector *devices = (std::vector *)inContext; // Add to the devices vector if it's of a type we want if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) || IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad)) { - std::vector *devices = (std::vector *)inContext; devices->push_back(new Keyboard(inIOHIDDeviceRef)); } - if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse)) + // We can probably generalize this class for mouse and gamepad inputs + if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse) /*|| + IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)*/) { - std::vector *devices = (std::vector *)inContext; devices->push_back(new Mouse(inIOHIDDeviceRef)); } - /* - // Probably just a lot of fiddling...but then we can kill SDL dependency (?) - else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad)) - { - std::vector *devices = (std::vector *)inContext; - devices->push_back(); - } - */ - else - { - // Actually, we don't want it - #define shortlog(x) - //#define shortlog(x) NSLog(@"%s: %@", x, IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(x))); - shortlog(kIOHIDTransportKey) - shortlog(kIOHIDVendorIDKey) - shortlog(kIOHIDVendorIDSourceKey) - shortlog(kIOHIDProductIDKey) - shortlog(kIOHIDVersionNumberKey) - shortlog(kIOHIDManufacturerKey) - shortlog(kIOHIDProductKey) - shortlog(kIOHIDSerialNumberKey) - shortlog(kIOHIDCountryCodeKey) - shortlog(kIOHIDLocationIDKey) - shortlog(kIOHIDDeviceUsageKey) - shortlog(kIOHIDDeviceUsagePageKey) - shortlog(kIOHIDDeviceUsagePairsKey) - shortlog(kIOHIDPrimaryUsageKey) - shortlog(kIOHIDPrimaryUsagePageKey) - shortlog(kIOHIDMaxInputReportSizeKey) - shortlog(kIOHIDMaxOutputReportSizeKey) - shortlog(kIOHIDMaxFeatureReportSizeKey) - shortlog(kIOHIDReportIntervalKey) - shortlog(kIOHIDReportDescriptorKey) - #undef shortlog - } } void Init( std::vector& devices ) @@ -128,60 +181,6 @@ void DeInit() CFRelease(HIDManager); } - -void DeviceElementDebugPrint(const void *value, void *context) -{ - IOHIDElementRef e = (IOHIDElementRef)value; - - std::string type = ""; - switch (IOHIDElementGetType(e)) - { - case kIOHIDElementTypeInput_Axis: type = "axis"; break; - case kIOHIDElementTypeInput_Button: type = "button"; break; - case kIOHIDElementTypeInput_Misc: type = "misc"; break; - case kIOHIDElementTypeInput_ScanCodes: type = "scancodes"; break; - case kIOHIDElementTypeOutput: type = "output"; break; - case kIOHIDElementTypeFeature: type = "feature"; break; - case kIOHIDElementTypeCollection: type = "collection"; break; - } - - std::string c_type = ""; - if (type == "collection") - { - switch (IOHIDElementGetCollectionType(e)) - { - case kIOHIDElementCollectionTypePhysical: c_type = "physical"; break; - case kIOHIDElementCollectionTypeApplication: c_type = "application"; break; - case kIOHIDElementCollectionTypeLogical: c_type = "logical"; break; - case kIOHIDElementCollectionTypeReport: c_type = "report"; break; - case kIOHIDElementCollectionTypeNamedArray: c_type = "namedArray"; break; - case kIOHIDElementCollectionTypeUsageSwitch: c_type = "usageSwitch"; break; - case kIOHIDElementCollectionTypeUsageModifier: c_type = "usageModifier"; break; - } - } - - c_type.append(" "); - NSLog(@"%s%s%spage: 0x%x usage: 0x%x name: %s lmin: %i lmax: %i pmin: %i pmax: %i", - type.c_str(), - type == "collection" ? ":" : "", - type == "collection" ? c_type.c_str() : " ", - IOHIDElementGetUsagePage(e), - IOHIDElementGetUsage(e), - IOHIDElementGetName(e), // TOO BAD IT"S FUCKING USELESS - IOHIDElementGetLogicalMin(e), - IOHIDElementGetLogicalMax(e), - IOHIDElementGetPhysicalMin(e), - IOHIDElementGetPhysicalMax(e)); - - if (type == "collection") - { - CFArrayRef elements = IOHIDElementGetChildren(e); - CFRange range = {0, CFArrayGetCount(elements)}; - // this leaks...but it's just debug code, right? :D - CFArrayApplyFunction(elements, range, DeviceElementDebugPrint, NULL); - } -} - } } diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.h b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.h index aabbcd14a9..84ab9ae810 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.h @@ -19,7 +19,7 @@ protected: { friend class Keyboard; protected: - virtual ControlState GetState() = 0; + virtual ControlState GetState(IOHIDDeviceRef device) = 0; }; class Key : public Input @@ -29,9 +29,8 @@ protected: std::string GetName() const; protected: Key( IOHIDElementRef element ); - ControlState GetState(); + ControlState GetState(IOHIDDeviceRef device); private: - IOHIDDeviceRef m_device; IOHIDElementRef m_element; std::string m_name; }; diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm index 46b74bf360..0388bbd2d7 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm @@ -53,6 +53,13 @@ Keyboard::Keyboard(IOHIDDeviceRef device) try { inputs.push_back(new Key(e)); } catch (std::bad_alloc&) { /*Thrown if the key is reserved*/ } } + + //// + NSDictionary *melements; + kern_return_t err = kIOReturnSuccess; + if ((err = IOHIDDeviceCopyValueMultiple(m_device, elements, (CFDictionaryRef *)&melements)) != kIOReturnSuccess) + NSLog(@"FAILBOAT %x", err); + //// CFRelease(elements); } @@ -61,7 +68,7 @@ Keyboard::Keyboard(IOHIDDeviceRef device) ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input ) { - return ((Input*)input)->GetState(); + return ((Input*)input)->GetState(m_device); } void Keyboard::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state ) @@ -98,8 +105,6 @@ Keyboard::Key::Key(IOHIDElementRef element) : m_element(element) , m_name("RESERVED") // for some reason HID Manager gives these to us. bad_alloc! { - m_device = IOHIDElementGetDevice(m_element); - uint32_t keycode = IOHIDElementGetUsage(m_element); for (uint32_t i = 0; i < sizeof(named_keys)/sizeof(*named_keys); i++) { @@ -112,11 +117,11 @@ Keyboard::Key::Key(IOHIDElementRef element) throw std::bad_alloc(); } -ControlState Keyboard::Key::GetState() +ControlState Keyboard::Key::GetState(IOHIDDeviceRef device) { IOHIDValueRef value; - if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) - return IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical) > 0; + if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess) + return IOHIDValueGetIntegerValue(value) > 0; return false; } diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.h b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.h index 0049fd311e..97f87942a1 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.h +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.h @@ -19,7 +19,7 @@ protected: { friend class Mouse; protected: - virtual ControlState GetState() = 0; + virtual ControlState GetState(IOHIDDeviceRef device) = 0; }; class Button : public Input @@ -29,9 +29,8 @@ protected: std::string GetName() const; protected: Button( IOHIDElementRef element ); - ControlState GetState(); + ControlState GetState(IOHIDDeviceRef device); private: - IOHIDDeviceRef m_device; IOHIDElementRef m_element; std::string m_name; }; @@ -47,12 +46,12 @@ protected: std::string GetName() const; protected: Axis( IOHIDElementRef element, direction dir ); - ControlState GetState(); + ControlState GetState(IOHIDDeviceRef device); private: - IOHIDDeviceRef m_device; IOHIDElementRef m_element; std::string m_name; direction m_direction; + float m_range; }; bool UpdateInput(); diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.mm b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.mm index a91d91ada1..87810a42e6 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.mm +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXMouse.mm @@ -70,7 +70,7 @@ Mouse::Mouse(IOHIDDeviceRef device) ControlState Mouse::GetInputState( const ControllerInterface::Device::Input* const input ) { - return ((Input*)input)->GetState(); + return ((Input*)input)->GetState(m_device); } void Mouse::SetOutputState( const ControllerInterface::Device::Output* const output, const ControlState state ) @@ -106,18 +106,16 @@ int Mouse::GetId() const Mouse::Button::Button(IOHIDElementRef element) : m_element(element) { - m_device = IOHIDElementGetDevice(m_element); - std::ostringstream s; s << IOHIDElementGetUsage(m_element); m_name = std::string("Button ") + s.str(); } -ControlState Mouse::Button::GetState() +ControlState Mouse::Button::GetState(IOHIDDeviceRef device) { IOHIDValueRef value; - if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) - return IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical) > 0; + if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess) + return IOHIDValueGetIntegerValue(value) > 0; return false; } @@ -132,8 +130,6 @@ Mouse::Axis::Axis(IOHIDElementRef element, direction dir) : m_element(element) , m_direction(dir) { - m_device = IOHIDElementGetDevice(m_element); - // Need to parse the element a bit first std::string description("unk"); @@ -149,23 +145,33 @@ Mouse::Axis::Axis(IOHIDElementRef element, direction dir) } m_name = std::string("Axis ") + description; - m_name.append((m_direction == positive) ? std::string("+") : std::string("-")); + m_name.append((m_direction == positive) ? "+" : "-"); + + // yeah, that factor is completely random :/ + m_range = (float)IOHIDElementGetLogicalMax(m_element) / 1000.; } -ControlState Mouse::Axis::GetState() +ControlState Mouse::Axis::GetState(IOHIDDeviceRef device) { IOHIDValueRef value; - if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess) + if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess) { - double scaled_value = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical); - double actual_value = 0; + int int_value = IOHIDValueGetIntegerValue(value); - if ((scaled_value < 0) && (m_direction == negative)) - actual_value = fabs(scaled_value); - else if ((scaled_value > 0) && (m_direction == positive)) - actual_value = scaled_value; + if (((int_value < 0) && (m_direction == positive)) || + ((int_value > 0) && (m_direction == negative)) || + !int_value) + return false; + + float actual_value = 0; + + if (int_value < 0) + actual_value = abs(int_value) / m_range; + else if (int_value > 0) + actual_value = int_value / m_range; + + //NSLog(@"%s %i %f", m_name.c_str(), int_value, actual_value); - //NSLog(@"%s %f %f", m_name.c_str(), scaled_value, actual_value); return actual_value; }