2010-02-10 100 views
10

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

我无法将自己的头围绕在一个非常复杂的HID管理器中(尽管显然它已经被简化为10.5),并且Apple的代码示例中有数千行代码需要数天时间来理解和隔离我需要,所以如果有人发布一个简单的,完全编码的解决方案来解决这个孤立问题,我会很感激。


编辑:到目前为止,所有的答案都指向源代码或半晦涩库各种HID设备,这将需要比想什么,我对这个投入更多的研发时间。我开始获得一个实际的代码段,可以解决这个简单问题(使用外部库或不使用外部库)。


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

+0

这是值得花一点时间调查的选项。我花了五分钟的时间来下载DDHidLib源代码,找到与游戏杆相关的代码并创建一个实现。 – 2010-02-24 06:35:01

+0

彼得发布后,我尽快做了。 30分钟后无法弄清楚。如果我没有从这个答案中得到工作代码片段,我将别无选择,但说实话,我害怕那一刻。这对于这样一个简单的问题来说太复杂了。 – 2010-02-26 03:46:14

回答

7

彼得对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 
+0

您是否在OSX 10.5及更高版本上测试了此代码?这不适合我。 JoySticks数组正确填充,但ddhidJoystick方法不会被调用。我已经将NSLog调用添加到了实际的DDHidJoystick ddhidJoystick方法(以及所有其他输入方法)中,并且尽可能多地按下所有按钮并移动所有的方块,但没有任何方法会被调用。我已经尝试了几个游戏手柄。它们确实在joystick数组中正确显示。 – 2010-02-26 03:44:50

+0

和DDHidJoystick ddhidJoystick方法我的意思是: DDHidJoystick ddhidJoystick:buttonDown:和DDHidJoystick ddhidJoystick:buttonUp: – 2010-02-26 03:52:09

1

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

1

也许你可以看看MAME OS X的源代码?它具有良好的手柄​​支持。

4

你可以试试Dave DribinDDHidLib

+0

戴夫做了Mac MAME端口,所以这可能相当于我的建议。 – Ken 2010-02-12 19:23:50

+0

谢谢彼得。文档很少(如果不是不存在的话)这个库,你知道如何使用它吗? – 2010-02-22 20:30:52

+1

不,我不知道。 (你好,评论长度最低。) – 2010-02-22 21:06:33

1

我相信我已经解决了所陈述的问题关于给出的示例代码的原始海报:

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

您必须选择一个操纵杆并开始聆听它。就那么简单!请注意,您可以用joySticks数组中的任何有效索引替换0,以选择您要听的摇杆,并且我猜测如果您愿意,您可以一次听多个。

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

10

首先,导入由于IOKit框架,包括像这样在你的头和实现文件:

#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); 
} 

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

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

0

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

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

把这个放到你的awakeFromNib函数中,打电话之后startWatchingJoySticks。

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

相关问题