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['FRAMEWORKSFLAGS'] = ['-Xarch_i386', '-Wl,-framework,QuickTime']
env['LIBPATH'] += ['/usr/lib']
env['LIBS'] = ['iconv', 'SDL']
env['LIBS'] = ['iconv']
env['LINKFLAGS'] += ccld
env['LINKFLAGS'] += ['-Wl,-search_paths_first', '-Wl,-Z', '-F' + system]
env['SHLINKFLAGS'] += ['-Wl,-undefined,dynamic_lookup']

View File

@ -28,7 +28,6 @@
#endif
#if defined(__APPLE__)
#define CIFACE_USE_OSX
#define CIFACE_USE_SDL
#endif
// 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 "OSX.h"
#include "OSXKeyboard.h"
#include "OSXMouse.h"
#include "OSXJoystick.h"
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
if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard) ||
IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad))
{
kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard))
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));
}
else if (IOHIDDeviceConformsTo(inIOHIDDeviceRef,
kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse))
return; // XXX devices->push_back(new Mouse(inIOHIDDeviceRef));
else
devices->push_back(new Joystick(inIOHIDDeviceRef));
}
void Init(std::vector<ControllerInterface::Device*>& devices)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
HIDManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);
if (!HIDManager)
NSLog(@"Failed to create HID Manager reference");
// HID Manager will give us the following devices:
// 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);
IOHIDManagerSetDeviceMatchingMultiple(HIDManager, NULL);
// Callbacks for acquisition or loss of a matching device
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager,
@ -218,8 +181,6 @@ void Init(std::vector<ControllerInterface::Device*>& devices)
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, NULL, NULL);
IOHIDManagerUnscheduleFromRunLoop(HIDManager,
CFRunLoopGetCurrent(), OurRunLoop);
[pool release];
}
void DeInit()

View File

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

View File

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

View File

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

View File

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