如何检测OSX 10.5及更高版本上的游戏手柄按键?

时间:2010-02-10 04:12:37

标签: cocoa

如何在OSX 10.5及更高版本的USB游戏手柄上检测到按下按钮?

我无法绕过那个荒谬复杂的HID管理器(虽然显然它已经用10.5进行了简化),而且Apple的代码示例有数千行代码需要花费数天的时间来理解和隔离我需要的东西,如果有人为这个孤立的问题发布一个简单的,完全编码的解决方案,我将不胜感激。


编辑:到目前为止,所有答案都是指向各种HID设备的源代码或半模糊库的链接,这需要比我想投入更多的研究时间。我正在开始获得一个实际的代码片段来解决这个简单问题(使用外部库或不使用外部库)。


编辑POS BOUNTY :感谢所有人的帮助;但不幸的是,系统自动选择的答案对我不起作用,无法弄清楚原因;并且作者尚未回复我的评论。任何见解都会受到赞赏,但是在找到修复之前,任何寻找这个主题资源的人都应该用一点点盐来回答这个问题。

7 个答案:

答案 0 :(得分:11)

首先,导入IOKit Framework并将其包含在头文件和实现文件中:

#import <IOKit/hid/IOHIDLib.h>

在您的头文件中,您可能希望拥有此变量:

IOHIDManagerRef hidManager;

然后将其添加到您的实现中:

void gamepadWasAdded(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device) {
  NSLog(@"Gamepad was plugged in");
}

void gamepadWasRemoved(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device) {
  NSLog(@"Gamepad was unplugged");
}

void gamepadAction(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef value) {
  NSLog(@"Gamepad talked!");
  IOHIDElementRef element = IOHIDValueGetElement(value);
  NSLog(@"Element: %@", element);
  int elementValue = IOHIDValueGetIntegerValue(value);
  NSLog(@"Element value: %i", elementValue);
}

-(void) setupGamepad {
  hidManager = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone);
  NSMutableDictionary* criterion = [[NSMutableDictionary alloc] init];
  [criterion setObject: [NSNumber numberWithInt: kHIDPage_GenericDesktop] forKey: (NSString*)CFSTR(kIOHIDDeviceUsagePageKey)];
  [criterion setObject: [NSNumber numberWithInt: kHIDUsage_GD_GamePad] forKey: (NSString*)CFSTR(kIOHIDDeviceUsageKey)];
  IOHIDManagerSetDeviceMatching(hidManager, criterion);
  IOHIDManagerRegisterDeviceMatchingCallback(hidManager, gamepadWasAdded, (void*)self);
  IOHIDManagerRegisterDeviceRemovalCallback(hidManager, gamepadWasRemoved, (void*)self);
  IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
  IOReturn tIOReturn = IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
  IOHIDManagerRegisterInputValueCallback(hidManager, gamepadAction, (void*)self);
}

从awakeFromNib调用setupGamepad。您可以修改变量“kHIDUsage_GD_GamePad”以注册其他设备。我通过逐步阅读http://developer.apple.com/library/mac/documentation/DeviceDrivers/Conceptual/HID/hid.pdf文档示例并将其与http://abstractable.net/enjoy

上的“真实”源代码进行比较,对上述内容进行了编码 祝你好运。

答案 1 :(得分:8)

Peter对DDHidLib框架的建议正是您所寻找的。该库设计得很好,库附带的示例代码非常清晰。

一个对象的实现,它将所有操纵杆/游戏手柄连接到系统并使用DDHidLib监视按钮按下,如下所示:

#import <Cocoa/Cocoa.h>
#import <DDHidLib/DDHidLib.h>

@interface JoyStickWatcher : NSObject
{
    NSArray* joySticks;
}
- (void)startWatchingJoysticks;
@end


@implementation JoyStickWatcher
- (void)startWatchingJoysticks
{
    //get an array of all joystick objects
    joySticks = [[DDHidJoystick allJoysticks] retain];

    //become the delegate of all available joystick objects
    [joySticks makeObjectsPerformSelector:@selector(setDelegate:) withObject:self];
}

- (void)dealloc
{
    [joySticks release];
    [super dealloc];
}

//these are the DDHidLib joystick delegate methods related to buttons

- (void)ddhidJoystick:(DDHidJoystick *)joystick buttonDown:(unsigned)buttonNumber
{
    NSLog(@"button number %ld of joystick %p went down",joystick,buttonNumber);
}

- (void)ddhidJoystick:(DDHidJoystick *)joystick buttonUp:(unsigned)buttonNumber
{
    NSLog(@"button number %ld of joystick %p went up",joystick,buttonNumber);
}

@end

答案 2 :(得分:4)

您可以尝试Dave DribinDDHidLib

答案 3 :(得分:1)

我使用Procontroll,但那是一个Java库。这很好。

答案 4 :(得分:1)

也许您可以查看MAME OS X的源代码?它具有良好的游戏手柄支持。

答案 5 :(得分:1)

我相信我已经解决了原始海报所述的问题:

DDHidJoystick * currentJoystick = [joySticks objectAtIndex:0]; [currentJoystick startListening];

您必须选择一个操纵杆并开始聆听它。就那么简单!请注意,您可以将任何有效索引的0替换为joySticks数组,以便选择您收听的操纵杆,并且我猜您可以根据需要一次收听多个操纵杆。

另请注意,此(以及上述)初始化必须从具有运行循环的线程完成。如果您正在使用本机mac os x应用程序,这不是问题,但如果您正在编写可移植代码并希望使用POSIX线程,那么您将发现在POSIX中创建时许多cocoa对象不起作用线。我发现你通常可以在创建后从任何线程安全地调用它们,但是创建必须在具有运行循环的线程上进行。几乎所有通过回调样式事件工作的cocoa对象都会从创建它们的线程的运行循环中触发这些事件。

答案 6 :(得分:0)

Rob的示例代码只需要一件事就可以使它工作。

if([joySticks count] > 0)
{
    DDHidJoyStick *myJoyStick = [joySticks objectAtIdex:0];
    [myJoyStick startListening];
}

在调用startWatchingJoySticks之后将它放在awakeFromNib函数中。

BTW,mac没有将所有游戏手柄(至少不是360游戏手柄)注册为HID设备,因此您需要为其下载驱动程序。我测试了这个驱动程序,它的工作原理。 http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/OsxDriver