Fixed unregistering controllers and emulating extra buttons

This commit is contained in:
Diego Waxemberg
2015-02-10 15:48:01 -05:00
parent c7c28a18c5
commit e31df3f44e
3 changed files with 92 additions and 97 deletions
+1
View File
@@ -12,6 +12,7 @@
@property (nonatomic) int playerIndex; @property (nonatomic) int playerIndex;
@property (nonatomic) int lastButtonFlags; @property (nonatomic) int lastButtonFlags;
@property (nonatomic) int emulatingButtonFlags;
@property (nonatomic) char lastLeftTrigger; @property (nonatomic) char lastLeftTrigger;
@property (nonatomic) char lastRightTrigger; @property (nonatomic) char lastRightTrigger;
@property (nonatomic) short lastLeftStickX; @property (nonatomic) short lastLeftStickX;
+1 -1
View File
@@ -10,6 +10,6 @@
@implementation Controller @implementation Controller
@synthesize playerIndex; @synthesize playerIndex;
@synthesize lastButtonFlags, lastLeftTrigger, lastRightTrigger; @synthesize lastButtonFlags, emulatingButtonFlags, lastLeftTrigger, lastRightTrigger;
@synthesize lastLeftStickX, lastLeftStickY, lastRightStickX, lastRightStickY; @synthesize lastLeftStickX, lastLeftStickY, lastRightStickX, lastRightStickY;
@end @end
+22 -28
View File
@@ -23,10 +23,9 @@
#define EMULATING_SELECT 0x1 #define EMULATING_SELECT 0x1
#define EMULATING_SPECIAL 0x2 #define EMULATING_SPECIAL 0x2
int _emulatingButtonFlags;
} }
// UPDATE_BUTTON_FLAG(flag, pressed) // UPDATE_BUTTON_FLAG(controller, flag, pressed)
#define UPDATE_BUTTON_FLAG(controller, x, y) \ #define UPDATE_BUTTON_FLAG(controller, x, y) \
((y) ? [self setButtonFlag:controller flags:x] : [self clearButtonFlag:controller flags:x]) ((y) ? [self setButtonFlag:controller flags:x] : [self clearButtonFlag:controller flags:x])
@@ -70,16 +69,16 @@
-(void) handleSpecialCombosReleased:(Controller*)controller releasedButtons:(int)releasedButtons -(void) handleSpecialCombosReleased:(Controller*)controller releasedButtons:(int)releasedButtons
{ {
if ((_emulatingButtonFlags & EMULATING_SELECT) && if ((controller.emulatingButtonFlags & EMULATING_SELECT) &&
((releasedButtons & LB_FLAG) || (releasedButtons & PLAY_FLAG))) { ((releasedButtons & LB_FLAG) || (releasedButtons & PLAY_FLAG))) {
controller.lastButtonFlags &= ~BACK_FLAG; controller.lastButtonFlags &= ~BACK_FLAG;
_emulatingButtonFlags &= ~EMULATING_SELECT; controller.emulatingButtonFlags &= ~EMULATING_SELECT;
} }
if ((_emulatingButtonFlags & EMULATING_SPECIAL) && if ((controller.emulatingButtonFlags & EMULATING_SPECIAL) &&
((releasedButtons & RB_FLAG) || (releasedButtons & PLAY_FLAG) || ((releasedButtons & RB_FLAG) || (releasedButtons & PLAY_FLAG) ||
(releasedButtons & BACK_FLAG))) { (releasedButtons & BACK_FLAG))) {
controller.lastButtonFlags &= ~SPECIAL_FLAG; controller.lastButtonFlags &= ~SPECIAL_FLAG;
_emulatingButtonFlags &= ~EMULATING_SPECIAL; controller.emulatingButtonFlags &= ~EMULATING_SPECIAL;
} }
} }
@@ -91,13 +90,13 @@
if (controller.lastButtonFlags & LB_FLAG) { if (controller.lastButtonFlags & LB_FLAG) {
controller.lastButtonFlags |= BACK_FLAG; controller.lastButtonFlags |= BACK_FLAG;
controller.lastButtonFlags &= ~(pressedButtons & (PLAY_FLAG | LB_FLAG)); controller.lastButtonFlags &= ~(pressedButtons & (PLAY_FLAG | LB_FLAG));
_emulatingButtonFlags |= EMULATING_SELECT; controller.emulatingButtonFlags |= EMULATING_SELECT;
} }
// If (RB or select) and start are down, trigger special // If (RB or select) and start are down, trigger special
else if ((controller.lastButtonFlags & RB_FLAG) || (controller.lastButtonFlags & BACK_FLAG)) { else if ((controller.lastButtonFlags & RB_FLAG) || (controller.lastButtonFlags & BACK_FLAG)) {
controller.lastButtonFlags |= SPECIAL_FLAG; controller.lastButtonFlags |= SPECIAL_FLAG;
controller.lastButtonFlags &= ~(pressedButtons & (PLAY_FLAG | RB_FLAG | BACK_FLAG)); controller.lastButtonFlags &= ~(pressedButtons & (PLAY_FLAG | RB_FLAG | BACK_FLAG));
_emulatingButtonFlags |= EMULATING_SPECIAL; controller.emulatingButtonFlags |= EMULATING_SPECIAL;
} }
} }
@@ -145,11 +144,8 @@
[_controllerStreamLock unlock]; [_controllerStreamLock unlock];
} }
-(void) unregisterControllerCallbacks -(void) unregisterControllerCallbacks:(GCController*) controller
{ {
for (int i = 0; i < [[GCController controllers] count]; i++) {
GCController *controller = [GCController controllers][i];
if (controller != NULL) { if (controller != NULL) {
controller.controllerPausedHandler = NULL; controller.controllerPausedHandler = NULL;
@@ -160,15 +156,10 @@
controller.gamepad.valueChangedHandler = NULL; controller.gamepad.valueChangedHandler = NULL;
} }
} }
}
[_controllers removeAllObjects];
} }
-(void) registerControllerCallbacks -(void) registerControllerCallbacks:(GCController*) controller
{ {
for (int i = 0; i < [[GCController controllers] count]; i++) {
GCController *controller = [GCController controllers][i];
if (controller != NULL) { if (controller != NULL) {
controller.controllerPausedHandler = ^(GCController *controller) { controller.controllerPausedHandler = ^(GCController *controller) {
Controller* limeController = [_controllers objectForKey:[NSNumber numberWithInteger:controller.playerIndex]]; Controller* limeController = [_controllers objectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
@@ -236,9 +227,9 @@
[self updateFinished:limeController]; [self updateFinished:limeController];
}; };
} }
} else {
NSLog(@"ERROR: Tried to register controller callbacks on NULL controller");
} }
}
} }
-(void) updateAutoOnScreenControlMode -(void) updateAutoOnScreenControlMode
@@ -300,19 +291,21 @@
_controllers = [[NSMutableDictionary alloc] init]; _controllers = [[NSMutableDictionary alloc] init];
_controllerNumbers = 0; _controllerNumbers = 0;
NSLog(@"Number of controllers connected: %ld", [[GCController controllers] count]); NSLog(@"Number of controllers connected: %ld", (long)[[GCController controllers] count]);
for (GCController* controller in [GCController controllers]) { for (GCController* controller in [GCController controllers]) {
[self assignController:controller]; [self assignController:controller];
[self registerControllerCallbacks:controller];
[self updateAutoOnScreenControlMode];
} }
self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
NSLog(@"Controller connected!"); NSLog(@"Controller connected!");
GCController* controller = (GCController*) note.object; GCController* controller = note.object;
[self assignController:controller]; [self assignController:controller];
// Register callbacks on the new controller // Register callbacks on the new controller
[self registerControllerCallbacks]; [self registerControllerCallbacks:controller];
// Re-evaluate the on-screen control mode // Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode]; [self updateAutoOnScreenControlMode];
@@ -321,6 +314,7 @@
NSLog(@"Controller disconnected!"); NSLog(@"Controller disconnected!");
GCController* controller = note.object; GCController* controller = note.object;
[self unregisterControllerCallbacks:controller];
[_controllers removeObjectForKey:[NSNumber numberWithInteger:controller.playerIndex]]; [_controllers removeObjectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
_controllerNumbers &= ~(1 << controller.playerIndex); _controllerNumbers &= ~(1 << controller.playerIndex);
NSLog(@"Unassigning controller index: %ld", (long)controller.playerIndex); NSLog(@"Unassigning controller index: %ld", (long)controller.playerIndex);
@@ -329,9 +323,6 @@
[self updateAutoOnScreenControlMode]; [self updateAutoOnScreenControlMode];
}]; }];
// Register for controller callbacks on any existing controllers
[self registerControllerCallbacks];
return self; return self;
} }
@@ -339,8 +330,11 @@
{ {
[[NSNotificationCenter defaultCenter] removeObserver:self.connectObserver]; [[NSNotificationCenter defaultCenter] removeObserver:self.connectObserver];
[[NSNotificationCenter defaultCenter] removeObserver:self.disconnectObserver]; [[NSNotificationCenter defaultCenter] removeObserver:self.disconnectObserver];
[_controllers removeAllObjects];
[self unregisterControllerCallbacks]; _controllerNumbers = 0;
for (GCController* controller in [GCController controllers]) {
[self unregisterControllerCallbacks:controller];
}
} }
@end @end