osx input: scale mouse axes more nicely
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5417 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
ac8bc6b350
commit
ed71457d46
|
@ -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<ControllerInterface::Device*> *devices = (std::vector<ControllerInterface::Device*> *)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<ControllerInterface::Device*> *devices = (std::vector<ControllerInterface::Device*> *)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<ControllerInterface::Device*> *devices = (std::vector<ControllerInterface::Device*> *)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<ControllerInterface::Device*> *devices = (std::vector<ControllerInterface::Device*> *)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<ControllerInterface::Device*>& 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue