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,39 +18,68 @@ static IOHIDManagerRef HIDManager = NULL;
|
||||||
static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput");
|
static CFStringRef OurRunLoop = CFSTR("DolphinOSXInput");
|
||||||
|
|
||||||
|
|
||||||
static void DeviceMatching_callback(void* inContext,
|
void DeviceElementDebugPrint(const void *value, void *context)
|
||||||
IOReturn inResult,
|
|
||||||
void* inSender,
|
|
||||||
IOHIDDeviceRef inIOHIDDeviceRef)
|
|
||||||
{
|
{
|
||||||
//NSLog(@"-------------------------");
|
IOHIDElementRef e = (IOHIDElementRef)value;
|
||||||
//NSLog(@"Got Device: %@", IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDProductKey)));
|
bool recurse = false;
|
||||||
|
if (context)
|
||||||
|
recurse = *(bool*)context;
|
||||||
|
|
||||||
// Add to the devices vector if it's of a type we want
|
std::string type = "";
|
||||||
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) ||
|
switch (IOHIDElementGetType(e))
|
||||||
IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad))
|
|
||||||
{
|
{
|
||||||
std::vector<ControllerInterface::Device*> *devices = (std::vector<ControllerInterface::Device*> *)inContext;
|
case kIOHIDElementTypeInput_Axis: type = "axis"; break;
|
||||||
devices->push_back(new Keyboard(inIOHIDDeviceRef));
|
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;
|
||||||
}
|
}
|
||||||
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse))
|
|
||||||
|
std::string c_type = "";
|
||||||
|
if (type == "collection")
|
||||||
{
|
{
|
||||||
std::vector<ControllerInterface::Device*> *devices = (std::vector<ControllerInterface::Device*> *)inContext;
|
switch (IOHIDElementGetCollectionType(e))
|
||||||
devices->push_back(new Mouse(inIOHIDDeviceRef));
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// 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
|
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)
|
||||||
{
|
{
|
||||||
// Actually, we don't want it
|
CFArrayRef elements = IOHIDElementGetChildren(e);
|
||||||
#define shortlog(x)
|
CFRange range = {0, CFArrayGetCount(elements)};
|
||||||
//#define shortlog(x) NSLog(@"%s: %@", x, IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(x)));
|
// 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(kIOHIDTransportKey)
|
||||||
shortlog(kIOHIDVendorIDKey)
|
shortlog(kIOHIDVendorIDKey)
|
||||||
shortlog(kIOHIDVendorIDSourceKey)
|
shortlog(kIOHIDVendorIDSourceKey)
|
||||||
|
@ -71,8 +100,32 @@ static void DeviceMatching_callback(void* inContext,
|
||||||
shortlog(kIOHIDMaxFeatureReportSizeKey)
|
shortlog(kIOHIDMaxFeatureReportSizeKey)
|
||||||
shortlog(kIOHIDReportIntervalKey)
|
shortlog(kIOHIDReportIntervalKey)
|
||||||
shortlog(kIOHIDReportDescriptorKey)
|
shortlog(kIOHIDReportDescriptorKey)
|
||||||
|
#endif
|
||||||
#undef shortlog
|
#undef shortlog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void DeviceMatching_callback(void* inContext,
|
||||||
|
IOReturn inResult,
|
||||||
|
void* inSender,
|
||||||
|
IOHIDDeviceRef inIOHIDDeviceRef)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
devices->push_back(new Keyboard(inIOHIDDeviceRef));
|
||||||
|
}
|
||||||
|
// 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)*/)
|
||||||
|
{
|
||||||
|
devices->push_back(new Mouse(inIOHIDDeviceRef));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init( std::vector<ControllerInterface::Device*>& devices )
|
void Init( std::vector<ControllerInterface::Device*>& devices )
|
||||||
|
@ -129,60 +182,6 @@ void DeInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
friend class Keyboard;
|
||||||
protected:
|
protected:
|
||||||
virtual ControlState GetState() = 0;
|
virtual ControlState GetState(IOHIDDeviceRef device) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Key : public Input
|
class Key : public Input
|
||||||
|
@ -29,9 +29,8 @@ protected:
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
protected:
|
protected:
|
||||||
Key( IOHIDElementRef element );
|
Key( IOHIDElementRef element );
|
||||||
ControlState GetState();
|
ControlState GetState(IOHIDDeviceRef device);
|
||||||
private:
|
private:
|
||||||
IOHIDDeviceRef m_device;
|
|
||||||
IOHIDElementRef m_element;
|
IOHIDElementRef m_element;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,6 +53,13 @@ Keyboard::Keyboard(IOHIDDeviceRef device)
|
||||||
try { inputs.push_back(new Key(e)); }
|
try { inputs.push_back(new Key(e)); }
|
||||||
catch (std::bad_alloc&) { /*Thrown if the key is reserved*/ }
|
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);
|
CFRelease(elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +68,7 @@ Keyboard::Keyboard(IOHIDDeviceRef device)
|
||||||
|
|
||||||
ControlState Keyboard::GetInputState( const ControllerInterface::Device::Input* const input )
|
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 )
|
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_element(element)
|
||||||
, m_name("RESERVED") // for some reason HID Manager gives these to us. bad_alloc!
|
, 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);
|
uint32_t keycode = IOHIDElementGetUsage(m_element);
|
||||||
for (uint32_t i = 0; i < sizeof(named_keys)/sizeof(*named_keys); i++)
|
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();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlState Keyboard::Key::GetState()
|
ControlState Keyboard::Key::GetState(IOHIDDeviceRef device)
|
||||||
{
|
{
|
||||||
IOHIDValueRef value;
|
IOHIDValueRef value;
|
||||||
if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess)
|
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
|
||||||
return IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical) > 0;
|
return IOHIDValueGetIntegerValue(value) > 0;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ protected:
|
||||||
{
|
{
|
||||||
friend class Mouse;
|
friend class Mouse;
|
||||||
protected:
|
protected:
|
||||||
virtual ControlState GetState() = 0;
|
virtual ControlState GetState(IOHIDDeviceRef device) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Button : public Input
|
class Button : public Input
|
||||||
|
@ -29,9 +29,8 @@ protected:
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
protected:
|
protected:
|
||||||
Button( IOHIDElementRef element );
|
Button( IOHIDElementRef element );
|
||||||
ControlState GetState();
|
ControlState GetState(IOHIDDeviceRef device);
|
||||||
private:
|
private:
|
||||||
IOHIDDeviceRef m_device;
|
|
||||||
IOHIDElementRef m_element;
|
IOHIDElementRef m_element;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
};
|
};
|
||||||
|
@ -47,12 +46,12 @@ protected:
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
protected:
|
protected:
|
||||||
Axis( IOHIDElementRef element, direction dir );
|
Axis( IOHIDElementRef element, direction dir );
|
||||||
ControlState GetState();
|
ControlState GetState(IOHIDDeviceRef device);
|
||||||
private:
|
private:
|
||||||
IOHIDDeviceRef m_device;
|
|
||||||
IOHIDElementRef m_element;
|
IOHIDElementRef m_element;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
direction m_direction;
|
direction m_direction;
|
||||||
|
float m_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool UpdateInput();
|
bool UpdateInput();
|
||||||
|
|
|
@ -70,7 +70,7 @@ Mouse::Mouse(IOHIDDeviceRef device)
|
||||||
|
|
||||||
ControlState Mouse::GetInputState( const ControllerInterface::Device::Input* const input )
|
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 )
|
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)
|
Mouse::Button::Button(IOHIDElementRef element)
|
||||||
: m_element(element)
|
: m_element(element)
|
||||||
{
|
{
|
||||||
m_device = IOHIDElementGetDevice(m_element);
|
|
||||||
|
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << IOHIDElementGetUsage(m_element);
|
s << IOHIDElementGetUsage(m_element);
|
||||||
m_name = std::string("Button ") + s.str();
|
m_name = std::string("Button ") + s.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlState Mouse::Button::GetState()
|
ControlState Mouse::Button::GetState(IOHIDDeviceRef device)
|
||||||
{
|
{
|
||||||
IOHIDValueRef value;
|
IOHIDValueRef value;
|
||||||
if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess)
|
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
|
||||||
return IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical) > 0;
|
return IOHIDValueGetIntegerValue(value) > 0;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -132,8 +130,6 @@ Mouse::Axis::Axis(IOHIDElementRef element, direction dir)
|
||||||
: m_element(element)
|
: m_element(element)
|
||||||
, m_direction(dir)
|
, m_direction(dir)
|
||||||
{
|
{
|
||||||
m_device = IOHIDElementGetDevice(m_element);
|
|
||||||
|
|
||||||
// Need to parse the element a bit first
|
// Need to parse the element a bit first
|
||||||
std::string description("unk");
|
std::string description("unk");
|
||||||
|
|
||||||
|
@ -149,23 +145,33 @@ Mouse::Axis::Axis(IOHIDElementRef element, direction dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_name = std::string("Axis ") + description;
|
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;
|
IOHIDValueRef value;
|
||||||
if (IOHIDDeviceGetValue(m_device, m_element, &value) == kIOReturnSuccess)
|
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
|
||||||
{
|
{
|
||||||
double scaled_value = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
|
int int_value = IOHIDValueGetIntegerValue(value);
|
||||||
double actual_value = 0;
|
|
||||||
|
|
||||||
if ((scaled_value < 0) && (m_direction == negative))
|
if (((int_value < 0) && (m_direction == positive)) ||
|
||||||
actual_value = fabs(scaled_value);
|
((int_value > 0) && (m_direction == negative)) ||
|
||||||
else if ((scaled_value > 0) && (m_direction == positive))
|
!int_value)
|
||||||
actual_value = scaled_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;
|
return actual_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue