Accept arbitrary HID devices as gamepads instead of using SDL,

which has too narrow a view of what constitutes a joystick.

Now if only I could find my Apple IR Remote.. :-)


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6844 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Soren Jorvang 2011-01-14 05:06:08 +00:00
parent d0de395a46
commit f292f6d5a7
7 changed files with 79 additions and 123 deletions

View File

@ -132,7 +132,7 @@ if sys.platform == 'darwin':
env['FRAMEWORKS'] += ['IOBluetooth', 'IOKit', 'OpenGL'] env['FRAMEWORKS'] += ['IOBluetooth', 'IOKit', 'OpenGL']
env['FRAMEWORKSFLAGS'] = ['-Xarch_i386', '-Wl,-framework,QuickTime'] env['FRAMEWORKSFLAGS'] = ['-Xarch_i386', '-Wl,-framework,QuickTime']
env['LIBPATH'] += ['/usr/lib'] env['LIBPATH'] += ['/usr/lib']
env['LIBS'] = ['iconv', 'SDL'] env['LIBS'] = ['iconv']
env['LINKFLAGS'] += ccld env['LINKFLAGS'] += ccld
env['LINKFLAGS'] += ['-Wl,-search_paths_first', '-Wl,-Z', '-F' + system] env['LINKFLAGS'] += ['-Wl,-search_paths_first', '-Wl,-Z', '-F' + system]
env['SHLINKFLAGS'] += ['-Wl,-undefined,dynamic_lookup'] env['SHLINKFLAGS'] += ['-Wl,-undefined,dynamic_lookup']

View File

@ -28,7 +28,6 @@
#endif #endif
#if defined(__APPLE__) #if defined(__APPLE__)
#define CIFACE_USE_OSX #define CIFACE_USE_OSX
#define CIFACE_USE_SDL
#endif #endif
// idk in case i wanted to change it to double or somethin, idk what's best // idk in case i wanted to change it to double or somethin, idk what's best

View File

@ -4,7 +4,7 @@
#include "../ControllerInterface.h" #include "../ControllerInterface.h"
#include "OSX.h" #include "OSX.h"
#include "OSXKeyboard.h" #include "OSXKeyboard.h"
#include "OSXMouse.h" #include "OSXJoystick.h"
namespace ciface namespace ciface
{ {
@ -143,60 +143,23 @@ static void DeviceMatching_callback(void* inContext,
// Add to the devices vector if it's of a type we want // Add to the devices vector if it's of a type we want
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) || kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard))
IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad))
{
devices->push_back(new Keyboard(inIOHIDDeviceRef)); devices->push_back(new Keyboard(inIOHIDDeviceRef));
} else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse))
// We can probably generalize this class for mouse and gamepad inputs return; // XXX devices->push_back(new Mouse(inIOHIDDeviceRef));
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef, else
kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse) /*|| devices->push_back(new Joystick(inIOHIDDeviceRef));
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)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, HIDManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone); kIOHIDOptionsTypeNone);
if (!HIDManager) if (!HIDManager)
NSLog(@"Failed to create HID Manager reference"); NSLog(@"Failed to create HID Manager reference");
// HID Manager will give us the following devices: IOHIDManagerSetDeviceMatchingMultiple(HIDManager, NULL);
// Keyboard, Keypad, Mouse, GamePad
NSArray *matchingDevices =
[NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
@kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Keyboard],
@kIOHIDDeviceUsageKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
@kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Keypad],
@kIOHIDDeviceUsageKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
@kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_Mouse],
@kIOHIDDeviceUsageKey, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kHIDPage_GenericDesktop],
@kIOHIDDeviceUsagePageKey,
[NSNumber numberWithInteger:kHIDUsage_GD_GamePad],
@kIOHIDDeviceUsageKey, nil],
nil];
// Pass NULL to get all devices
IOHIDManagerSetDeviceMatchingMultiple(HIDManager,
(CFArrayRef)matchingDevices);
// Callbacks for acquisition or loss of a matching device // Callbacks for acquisition or loss of a matching device
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, IOHIDManagerRegisterDeviceMatchingCallback(HIDManager,
@ -218,8 +181,6 @@ void Init(std::vector<ControllerInterface::Device*>& devices)
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, NULL, NULL); IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, NULL, NULL);
IOHIDManagerUnscheduleFromRunLoop(HIDManager, IOHIDManagerUnscheduleFromRunLoop(HIDManager,
CFRunLoopGetCurrent(), OurRunLoop); CFRunLoopGetCurrent(), OurRunLoop);
[pool release];
} }
void DeInit() void DeInit()

View File

@ -7,7 +7,7 @@ namespace ciface
namespace OSX namespace OSX
{ {
class Mouse : public ControllerInterface::Device class Joystick : public ControllerInterface::Device
{ {
friend class ControllerInterface; friend class ControllerInterface;
friend class ControllerInterface::ControlReference; friend class ControllerInterface::ControlReference;
@ -15,14 +15,14 @@ class Mouse : public ControllerInterface::Device
protected: protected:
class Input : public ControllerInterface::Device::Input class Input : public ControllerInterface::Device::Input
{ {
friend class Mouse; friend class Joystick;
protected: protected:
virtual ControlState GetState(IOHIDDeviceRef device) const = 0; virtual ControlState GetState(IOHIDDeviceRef device) const = 0;
}; };
class Button : public Input class Button : public Input
{ {
friend class Mouse; friend class Joystick;
public: public:
std::string GetName() const; std::string GetName() const;
protected: protected:
@ -35,7 +35,7 @@ protected:
class Axis : public Input class Axis : public Input
{ {
friend class Mouse; friend class Joystick;
public: public:
enum direction { enum direction {
positive = 0, positive = 0,
@ -49,7 +49,7 @@ protected:
IOHIDElementRef m_element; IOHIDElementRef m_element;
std::string m_name; std::string m_name;
direction m_direction; direction m_direction;
float m_range; float m_neutral;
}; };
bool UpdateInput(); bool UpdateInput();
@ -62,7 +62,7 @@ protected:
const ControlState state); const ControlState state);
public: public:
Mouse(IOHIDDeviceRef device); Joystick(IOHIDDeviceRef device);
std::string GetName() const; std::string GetName() const;
std::string GetSource() const; std::string GetSource() const;

View File

@ -2,7 +2,7 @@
#include <IOKit/hid/IOHIDLib.h> #include <IOKit/hid/IOHIDLib.h>
#include "../ControllerInterface.h" #include "../ControllerInterface.h"
#include "OSXMouse.h" #include "OSXJoystick.h"
namespace ciface namespace ciface
{ {
@ -11,20 +11,18 @@ namespace OSX
extern void DeviceElementDebugPrint(const void*, void*); extern void DeviceElementDebugPrint(const void*, void*);
Mouse::Mouse(IOHIDDeviceRef device) Joystick::Joystick(IOHIDDeviceRef device)
: m_device(device) : m_device(device)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device, m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device,
CFSTR(kIOHIDProductKey)) UTF8String]; CFSTR(kIOHIDProductKey)) UTF8String];
// Buttons // Buttons
NSDictionary *buttonDict = NSDictionary *buttonDict =
[NSDictionary dictionaryWithObjectsAndKeys: [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button], [NSNumber numberWithInteger: kIOHIDElementTypeInput_Button],
@kIOHIDElementTypeKey, @kIOHIDElementTypeKey,
[NSNumber numberWithInteger:kHIDPage_Button], [NSNumber numberWithInteger: kHIDPage_Button],
@kIOHIDElementUsagePageKey, @kIOHIDElementUsagePageKey,
nil]; nil];
@ -47,7 +45,7 @@ Mouse::Mouse(IOHIDDeviceRef device)
// Axes // Axes
NSDictionary *axisDict = NSDictionary *axisDict =
[NSDictionary dictionaryWithObjectsAndKeys: [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Misc], [NSNumber numberWithInteger: kIOHIDElementTypeInput_Misc],
@kIOHIDElementTypeKey, @kIOHIDElementTypeKey,
nil]; nil];
@ -67,73 +65,72 @@ Mouse::Mouse(IOHIDDeviceRef device)
} }
CFRelease(axes); CFRelease(axes);
} }
[pool release];
} }
ControlState Mouse::GetInputState( ControlState Joystick::GetInputState(
const ControllerInterface::Device::Input* const input) const const ControllerInterface::Device::Input* const input) const
{ {
return ((Input*)input)->GetState(m_device); return ((Input*)input)->GetState(m_device);
} }
void Mouse::SetOutputState( void Joystick::SetOutputState(
const ControllerInterface::Device::Output* const output, const ControllerInterface::Device::Output* const output,
const ControlState state) const ControlState state)
{ {
} }
bool Mouse::UpdateInput() bool Joystick::UpdateInput()
{ {
return true; return true;
} }
bool Mouse::UpdateOutput() bool Joystick::UpdateOutput()
{ {
return true; return true;
} }
std::string Mouse::GetName() const std::string Joystick::GetName() const
{ {
return m_device_name; return m_device_name;
} }
std::string Mouse::GetSource() const std::string Joystick::GetSource() const
{ {
return "HID"; return "HID";
} }
int Mouse::GetId() const int Joystick::GetId() const
{ {
// Overload the "id" to identify devices by HID type when names collide // Overload the "id" to identify devices by HID type when names collide
return kHIDUsage_GD_Mouse; // XXX This class is now a catch-all, so query the usage page number
return kHIDUsage_GD_GamePad;
} }
Mouse::Button::Button(IOHIDElementRef element) Joystick::Button::Button(IOHIDElementRef element)
: m_element(element) : m_element(element)
{ {
std::ostringstream s; std::ostringstream s;
s << IOHIDElementGetUsage(m_element); s << IOHIDElementGetUsage(m_element);
m_name = std::string("Click ") + s.str(); m_name = std::string("Button ") + s.str();
} }
ControlState Mouse::Button::GetState(IOHIDDeviceRef device) const ControlState Joystick::Button::GetState(IOHIDDeviceRef device) const
{ {
IOHIDValueRef value; IOHIDValueRef value;
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess) if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
return IOHIDValueGetIntegerValue(value) > 0; return IOHIDValueGetIntegerValue(value);
else
return false; return 0;
} }
std::string Mouse::Button::GetName() const std::string Joystick::Button::GetName() const
{ {
return m_name; return m_name;
} }
Mouse::Axis::Axis(IOHIDElementRef element, direction dir) Joystick::Axis::Axis(IOHIDElementRef element, direction dir)
: m_element(element) : m_element(element)
, m_direction(dir) , m_direction(dir)
{ {
@ -141,54 +138,65 @@ Mouse::Axis::Axis(IOHIDElementRef element, direction dir)
std::string description("unk"); std::string description("unk");
switch (IOHIDElementGetUsage(m_element)) { switch (IOHIDElementGetUsage(m_element)) {
default:
NSLog(@"Unknown axis type 0x%x, using it anyway...",
IOHIDElementGetUsage(m_element));
break;
case kHIDUsage_GD_X: case kHIDUsage_GD_X:
description = "X"; description = "X";
break; break;
case kHIDUsage_GD_Y: case kHIDUsage_GD_Y:
description = "Y"; description = "Y";
break; break;
case kHIDUsage_GD_Z:
description = "Z";
break;
case kHIDUsage_GD_Rx:
description = "Rx";
break;
case kHIDUsage_GD_Ry:
description = "Ry";
break;
case kHIDUsage_GD_Rz:
description = "Rz";
break;
case kHIDUsage_GD_Wheel: case kHIDUsage_GD_Wheel:
description = "Wheel"; description = "Wheel";
break; break;
case kHIDUsage_GD_Hatswitch:
description = "Hat";
break;
case kHIDUsage_Csmr_ACPan: case kHIDUsage_Csmr_ACPan:
description = "Pan"; description = "Pan";
break; break;
default:
WARN_LOG(PAD, "Unknown axis type 0x%x, using it anyway...",
IOHIDElementGetUsage(m_element));
} }
m_name = std::string("Axis ") + description; m_name = std::string("Axis ") + description;
m_name.append((m_direction == positive) ? "+" : "-"); m_name.append((m_direction == positive) ? "+" : "-");
// yeah, that factor is completely random :/ m_neutral = (IOHIDElementGetLogicalMax(m_element) -
m_range = (float)IOHIDElementGetLogicalMax(m_element) / 1000.; IOHIDElementGetLogicalMin(m_element)) / 2.;
} }
ControlState Mouse::Axis::GetState(IOHIDDeviceRef device) const ControlState Joystick::Axis::GetState(IOHIDDeviceRef device) const
{ {
IOHIDValueRef value; IOHIDValueRef value;
if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess) if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
{ {
int int_value = IOHIDValueGetIntegerValue(value); float position = IOHIDValueGetIntegerValue(value);
if (((int_value < 0) && (m_direction == positive)) || //NSLog(@"%s %f %f", m_name.c_str(), m_neutral, position);
((int_value > 0) && (m_direction == negative)) ||
!int_value)
return false;
float actual_value = abs(int_value) / m_range; if (m_direction == positive && position > m_neutral)
return (position - m_neutral) / m_neutral;
//NSLog(@"%s %i %f", m_name.c_str(), int_value, actual_value); if (m_direction == negative && position < m_neutral)
return (m_neutral - position) / m_neutral;
return actual_value; }
}
return 0;
return false;
} }
std::string Mouse::Axis::GetName() const std::string Joystick::Axis::GetName() const
{ {
return m_name; return m_name;
} }

View File

@ -24,8 +24,6 @@ extern void DeviceElementDebugPrint(const void *, void *);
Keyboard::Keyboard(IOHIDDeviceRef device) Keyboard::Keyboard(IOHIDDeviceRef device)
: m_device(device) : m_device(device)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device, m_device_name = [(NSString *)IOHIDDeviceGetProperty(m_device,
CFSTR(kIOHIDProductKey)) UTF8String]; CFSTR(kIOHIDProductKey)) UTF8String];
@ -33,7 +31,7 @@ Keyboard::Keyboard(IOHIDDeviceRef device)
// Now, filter on just the buttons we can handle sanely // Now, filter on just the buttons we can handle sanely
NSDictionary *matchingElements = NSDictionary *matchingElements =
[NSDictionary dictionaryWithObjectsAndKeys: [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:kIOHIDElementTypeInput_Button], [NSNumber numberWithInteger: kIOHIDElementTypeInput_Button],
@kIOHIDElementTypeKey, @kIOHIDElementTypeKey,
[NSNumber numberWithInteger: 0], @kIOHIDElementMinKey, [NSNumber numberWithInteger: 0], @kIOHIDElementMinKey,
[NSNumber numberWithInteger: 1], @kIOHIDElementMaxKey, [NSNumber numberWithInteger: 1], @kIOHIDElementMaxKey,
@ -54,8 +52,6 @@ Keyboard::Keyboard(IOHIDDeviceRef device)
} }
CFRelease(elements); CFRelease(elements);
} }
[pool release];
} }
ControlState Keyboard::GetInputState( ControlState Keyboard::GetInputState(
@ -99,30 +95,23 @@ int Keyboard::GetId() const
Keyboard::Key::Key(IOHIDElementRef element) Keyboard::Key::Key(IOHIDElementRef element)
: m_element(element) : m_element(element)
{ {
uint32_t keycode = IOHIDElementGetUsage(m_element); uint32_t i, keycode;
for (uint32_t i = 0; i < sizeof(named_keys)/sizeof(*named_keys); i++) m_name = "RESERVED";
{ keycode = IOHIDElementGetUsage(m_element);
for (i = 0; i < sizeof named_keys / sizeof *named_keys; i++)
if (named_keys[i].code == keycode) if (named_keys[i].code == keycode)
{
m_name = named_keys[i].name; m_name = named_keys[i].name;
return;
}
}
m_name = "RESERVED"; /* XXX */
} }
ControlState Keyboard::Key::GetState(IOHIDDeviceRef device) const ControlState Keyboard::Key::GetState(IOHIDDeviceRef device) const
{ {
IOHIDValueRef value; IOHIDValueRef value;
if (IOHIDDeviceGetValue(device, m_element, &value) == if (IOHIDDeviceGetValue(device, m_element, &value) == kIOReturnSuccess)
kIOReturnSuccess) { return IOHIDValueGetIntegerValue(value);
return IOHIDValueGetIntegerValue(value) > 0; else
} return 0;
return false;
} }
std::string Keyboard::Key::GetName() const std::string Keyboard::Key::GetName() const

View File

@ -22,8 +22,7 @@ elif sys.platform == 'darwin':
files += [ files += [
'ControllerInterface/OSX/OSX.mm', 'ControllerInterface/OSX/OSX.mm',
'ControllerInterface/OSX/OSXKeyboard.mm', 'ControllerInterface/OSX/OSXKeyboard.mm',
'ControllerInterface/OSX/OSXMouse.mm', 'ControllerInterface/OSX/OSXJoystick.mm',
'ControllerInterface/SDL/SDL.cpp',
] ]
elif env['HAVE_X11']: elif env['HAVE_X11']:
files += [ files += [