2

Mac に接続されているゲームパッドをゲームで検出して使用しようとしています。これにはIOKitを使用していますが、成功していません。接続されているすべてのゲームパッドを表示する Mac アプリをダウンロードすると、ゲームパッドが認識されます。これは Logitech F310 で、DirectInput に設定しました。awakeFromNib 内で setupInput を呼び出していますが、コールバックは呼び出されません。エラーや例外はスローされません。コールバックが呼び出されない理由がわかりません。私は何を間違っていますか?おそらく実行ループの問題だと思います。CFRunLoopGetMain と CFRunLoopGetCurrent の両方を試しました。

他に何をすべきかわからない。

編集: 誰かが示唆したように、同じ GamePad コードを新しいプロジェクトに入れようとしたところ、うまくいきました。クラスの構造に多少の違いがありますが、クラスを複製しようとしても、アプリで動作させることができませんでした。私のアプリは AppDelegate と NSOpenGLView を使用しています。奇妙なことに、NSViewController がありません。最小限のアプリは NSOpenGLView だけでなく NSResponder も使用し、(カスタム) NSResponder クラス内にゲームパッド コードを配置すると、「動作」します (ゲームパッドを検出し、入力に応答します)。そのカスタム クラスをアプリに追加しようとしましたが、「機能しませんでした」。私は何が欠けていますか?

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) setupInput {
    //get a HID manager reference
    hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
                                                    kIOHIDOptionsTypeNone);

    //define the device to search for, via usage page and usage key
    NSMutableDictionary* criterion = [[NSMutableDictionary alloc] init];
    [criterion setObject: [NSNumber numberWithInt: kHIDPage_GenericDesktop]
                  forKey: (NSString*)CFSTR(kIOHIDDeviceUsagePageKey)];
    [criterion setObject: [NSNumber numberWithInt: kHIDUsage_GD_Joystick]
                  forKey: (NSString*)CFSTR(kIOHIDDeviceUsageKey)];

    //search for the device
    IOHIDManagerSetDeviceMatching(hidManager,
                                  (__bridge CFDictionaryRef)criterion);

    //register our callback functions
    IOHIDManagerRegisterDeviceMatchingCallback(hidManager, gamepadWasAdded,
                                               (__bridge void*)self);
    IOHIDManagerRegisterDeviceRemovalCallback(hidManager, gamepadWasRemoved,
                                              (__bridge void*)self);
    IOHIDManagerRegisterInputValueCallback(hidManager, gamepadAction,
                                           (__bridge void*)self);

    //scedule our HIDManager with the current run loop, so that we
    //are able to recieve events from the hardware.
    IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetMain(),
                                    kCFRunLoopDefaultMode);

    //open the HID manager, so that it can start routing events
    //to our callbacks.
    IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);

}

// Put our timer in -awakeFromNib, so it can start up right from the beginning
-(void)awakeFromNib
{
    renderTimer = [NSTimer timerWithTimeInterval:0.001   //a 1ms time interval
                                          target:self
                                        selector:@selector(timerFired:)
                                        userInfo:nil
                                         repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:renderTimer
                                 forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] addTimer:renderTimer
                                 forMode:NSEventTrackingRunLoopMode]; //Ensure timer fires during resize
    [self setupInput];
}
4

1 に答える 1

4

わかりました、私は問題を見つけました。問題は、私の Mac アプリがサンドボックスにあり、ハードウェア/USB チェック ボックスをチェックしなかったことです。このオプションをオンにすると、元のコードで動作します。

于 2014-08-13T16:33:59.330 に答える