Index: src/hid/Makefile ================================================================== --- src/hid/Makefile +++ src/hid/Makefile @@ -8,18 +8,15 @@ LIB_MAJOR = ${OBJFWHID_LIB_MAJOR} LIB_MINOR = ${OBJFWHID_LIB_MINOR} LIB_PATCH = ${OBJFWHID_LIB_PATCH} SRCS = OHCombinedJoyCons.m \ - OHExtendedGamepad.m \ OHGameController.m \ OHGameControllerAxis.m \ OHGameControllerButton.m \ OHGameControllerDirectionalPad.m \ OHGameControllerElement.m \ - OHGameControllerProfile.m \ - OHGamepad.m \ ${USE_SRCS_EVDEV} \ ${USE_SRCS_NINTENDO_3DS} \ ${USE_SRCS_NINTENDO_DS} \ ${USE_SRCS_XINPUT} SRCS_EVDEV = OHEvdevDualSense.m \ @@ -33,11 +30,14 @@ SRCS_NINTENDO_DS = OHNintendoDSGamepad.m \ OHNintendoDSGameController.m SRCS_XINPUT = OHXInputExtendedGamepad.m \ OHXInputGameController.m -INCLUDES := ${SRCS:.m=.h} \ +INCLUDES := ${SRCS:.m=.h} \ + OHExtendedGamepad.h \ + OHGameControllerProfile.h \ + OHGamepad.h \ ObjFWHID.h SRCS += OHGameControllerEmulatedAxis.m \ OHGameControllerEmulatedButton.m \ OHGameControllerEmulatedTriggerButton.m Index: src/hid/OHCombinedJoyCons.h ================================================================== --- src/hid/OHCombinedJoyCons.h +++ src/hid/OHCombinedJoyCons.h @@ -20,19 +20,26 @@ #import "OHExtendedGamepad.h" OF_ASSUME_NONNULL_BEGIN @class OHGameController; +@class OHGameControllerButton; +@class OHGameControllerDirectionalPad; /** * @class OHCombinedJoyCons OHCombinedJoyCons.h ObjFWHID/OHCombinedJoyCons.h * * @brief Combines a left and a right Joy-Con into a gamepad. */ -@interface OHCombinedJoyCons: OHExtendedGamepad +OF_SUBCLASSING_RESTRICTED +@interface OHCombinedJoyCons: OFObject { - OHGameControllerProfile *_leftJoyCon, *_rightJoyCon; + id _leftJoyCon; + id _rightJoyCon; + OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) + *_directionalPads; } /** * @brief Creates a new @ref OHCombinedJoyCons with the specified left and * right Joy-Con. Index: src/hid/OHCombinedJoyCons.m ================================================================== --- src/hid/OHCombinedJoyCons.m +++ src/hid/OHCombinedJoyCons.m @@ -26,10 +26,12 @@ #import "OHGameControllerDirectionalPad.h" #import "OFInvalidArgumentException.h" @implementation OHCombinedJoyCons +@synthesize buttons = _buttons, directionalPads = _directionalPads; + + (instancetype)gamepadWithLeftJoyCon: (OHGameController *)leftJoyCon rightJoyCon: (OHGameController *)rightJoyCon { return [[[self alloc] initWithLeftJoyCon: leftJoyCon rightJoyCon: rightJoyCon] autorelease]; @@ -80,12 +82,10 @@ [buttons removeObjectForKey: @"SL"]; [buttons removeObjectForKey: @"SR"]; [buttons makeImmutable]; _buttons = [buttons retain]; - _axes = [[OFDictionary alloc] init]; - directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; directionalPad = [[[OHGameControllerDirectionalPad alloc] initWithName: @"Left Thumbstick" @@ -126,13 +126,20 @@ - (void)dealloc { [_leftJoyCon release]; [_rightJoyCon release]; + [_buttons release]; + [_directionalPads release]; [super dealloc]; } + +- (OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *)axes +{ + return [OFDictionary dictionary]; +} - (OHGameControllerButton *)northButton { return [_buttons objectForKey: @"X"]; } @@ -195,20 +202,20 @@ - (OHGameControllerButton *)homeButton { return [_buttons objectForKey: @"Home"]; } -- (OHGameControllerDirectionalPad *)leftThumbStick +- (OHGameControllerDirectionalPad *)leftThumbstick { return [_directionalPads objectForKey: @"Left Thumbstick"]; } -- (OHGameControllerDirectionalPad *)rightThumbStick +- (OHGameControllerDirectionalPad *)rightThumbstick { return [_directionalPads objectForKey: @"Right Thumbstick"]; } - (OHGameControllerDirectionalPad *)dPad { return [_directionalPads objectForKey: @"D-Pad"]; } @end Index: src/hid/OHEvdevExtendedGamepad.h ================================================================== --- src/hid/OHEvdevExtendedGamepad.h +++ src/hid/OHEvdevExtendedGamepad.h @@ -20,15 +20,14 @@ #import "OHExtendedGamepad.h" OF_ASSUME_NONNULL_BEGIN @class OHEvdevGameController; -@class OHGameControllerProfile; -@interface OHEvdevExtendedGamepad: OHExtendedGamepad +@interface OHEvdevExtendedGamepad: OFObject { - OHGameControllerProfile *_rawProfile; + id _rawProfile; } - (instancetype)initWithController: (OHEvdevGameController *)controller; @end Index: src/hid/OHEvdevGameController.h ================================================================== --- src/hid/OHEvdevGameController.h +++ src/hid/OHEvdevGameController.h @@ -16,10 +16,11 @@ * version 3.0 along with this program. If not, see * . */ #import "OHGameController.h" +#import "OHGameControllerProfile.h" OF_ASSUME_NONNULL_BEGIN @class OHGameControllerProfile; @@ -29,13 +30,13 @@ int _fd; bool _discardUntilReport; unsigned long *_evBits, *_keyBits, *_absBits; uint16_t _vendorID, _productID; OFString *_name; - OHGameControllerProfile *_rawProfile; + id _rawProfile; } - (instancetype)oh_initWithPath: (OFString *)path OF_METHOD_FAMILY(init); - (void)oh_pollState; @end OF_ASSUME_NONNULL_END Index: src/hid/OHEvdevGameController.m ================================================================== --- src/hid/OHEvdevGameController.m +++ src/hid/OHEvdevGameController.m @@ -53,11 +53,16 @@ @public int32_t _minValue, _maxValue; } @end -@interface OHEvdevGameControllerProfile: OHGameControllerProfile +@interface OHEvdevGameControllerProfile: OFObject +{ + OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *_axes; +} + - (instancetype)oh_initWithButtons: (OFDictionary *)buttons axes: (OFDictionary *)axes OF_METHOD_FAMILY(init); @end static const uint16_t buttonIDs[] = { @@ -727,16 +732,16 @@ break; } } } -- (OHGamepad *)gamepad +- (id )gamepad { return self.extendedGamepad; } -- (OHExtendedGamepad *)extendedGamepad +- (id )extendedGamepad { @try { if (_vendorID == OHVendorIDSony && _productID == OHProductIDDualSense) return [[[OHEvdevDualSense alloc] @@ -779,10 +784,12 @@ @implementation OHEvdevGameControllerAxis @end @implementation OHEvdevGameControllerProfile +@synthesize buttons = _buttons, axes = _axes; + - (instancetype)oh_initWithButtons: (OFDictionary *)buttons axes: (OFDictionary *)axes { self = [super init]; @@ -794,6 +801,20 @@ @throw e; } return self; } + +- (void)dealloc +{ + [_buttons release]; + [_axes release]; + + [super dealloc]; +} + +- (OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *) + directionalPads +{ + return [OFDictionary dictionary]; +} @end Index: src/hid/OHExtendedGamepad.h ================================================================== --- src/hid/OHExtendedGamepad.h +++ src/hid/OHExtendedGamepad.h @@ -20,19 +20,15 @@ #import "OHGamepad.h" OF_ASSUME_NONNULL_BEGIN /** - * @class OHExtendedGamepad OHExtendedGamepad.h ObjFWHID/OHExtendedGamepad.h + * @protocol OHExtendedGamepad OHExtendedGamepad.h ObjFWHID/OHExtendedGamepad.h * * @brief A game controller profile representing a gamepad. */ -@interface OHExtendedGamepad: OHGamepad -{ - OF_RESERVE_IVARS(OHExtendedGamepad, 4) -} - +@protocol OHExtendedGamepad /** * @brief The left trigger button. */ @property (readonly, nonatomic) OHGameControllerButton *leftTriggerButton; DELETED src/hid/OHExtendedGamepad.m Index: src/hid/OHExtendedGamepad.m ================================================================== --- src/hid/OHExtendedGamepad.m +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2008-2024 Jonathan Schleifer - * - * All rights reserved. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version 3.0 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * version 3.0 for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * version 3.0 along with this program. If not, see - * . - */ - -#include "config.h" - -#import "OHExtendedGamepad.h" - -@implementation OHExtendedGamepad -@dynamic leftTriggerButton, rightTriggerButton, leftThumbstick, rightThumbstick; -@dynamic dPad; - -- (OHGameControllerButton *)leftThumbstickButton -{ - return nil; -} - -- (OHGameControllerButton *)rightThumbstickButton -{ - return nil; -} - -- (OHGameControllerButton *)homeButton -{ - return nil; -} -@end Index: src/hid/OHGameController.h ================================================================== --- src/hid/OHGameController.h +++ src/hid/OHGameController.h @@ -27,17 +27,18 @@ # import # import # endif #endif +#import "OHGamepad.h" +#import "OHExtendedGamepad.h" + OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFNumber; -@class OHExtendedGamepad; @class OHGameControllerProfile; -@class OHGamepad; /** * @class OHGameController OHGameController.h ObjFWHID/OHGameController.h * * @brief A class for reading state from a game controller. @@ -69,24 +70,24 @@ /** * @brief The raw profile for the game controller, meaning no remapping is * being performed. */ -@property (readonly, nonatomic) OHGameControllerProfile *rawProfile; +@property (readonly, nonatomic) id rawProfile; /** * @brief The gamepad profile for the game controller, or `nil` if not * supported. */ -@property OF_NULLABLE_PROPERTY (readonly, nonatomic) OHGamepad *gamepad; +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) id gamepad; /** * @brief The extended gamepad profile for the game controller, or `nil` if not * supported. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) - OHExtendedGamepad *extendedGamepad; + id extendedGamepad; /** * @brief Returns the available controllers. * * @return The available controllers Index: src/hid/OHGameController.m ================================================================== --- src/hid/OHGameController.m +++ src/hid/OHGameController.m @@ -94,16 +94,16 @@ - (void)retrieveState { OF_UNRECOGNIZED_SELECTOR } -- (OHGamepad *)gamepad +- (id )gamepad { return nil; } -- (OHExtendedGamepad *)extendedGamepad +- (id )extendedGamepad { return nil; } - (OFString *)description Index: src/hid/OHGameControllerProfile.h ================================================================== --- src/hid/OHGameControllerProfile.h +++ src/hid/OHGameControllerProfile.h @@ -35,24 +35,16 @@ @class OHGameControllerAxis; @class OHGameControllerButton; @class OHGameControllerDirectionalPad; /** - * @class OHGameControllerProfile \ - * OHGameControllerProfile.h ObjFWHID/OHGameControllerProfile.h + * @protocol OHGameControllerProfile \ + * OHGameControllerProfile.h ObjFWHID/OHGameControllerProfile.h * * @brief A profile for a @ref OHGameController. */ -@interface OHGameControllerProfile: OFObject -{ - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; - OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *_axes; - OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) - *_directionalPads; - OF_RESERVE_IVARS(OHGameControllerProfile, 4) -} - +@protocol OHGameControllerProfile /** * @brief A map of all button names to their @ref OHGameControllerButton. */ @property (readonly, nonatomic) OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *buttons; DELETED src/hid/OHGameControllerProfile.m Index: src/hid/OHGameControllerProfile.m ================================================================== --- src/hid/OHGameControllerProfile.m +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2008-2024 Jonathan Schleifer - * - * All rights reserved. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version 3.0 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * version 3.0 for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * version 3.0 along with this program. If not, see - * . - */ - -#include "config.h" - -#import "OHGameControllerProfile.h" -#import "OFDictionary.h" - -@implementation OHGameControllerProfile -@synthesize buttons = _buttons, axes = _axes; -@synthesize directionalPads = _directionalPads; - -- (void)dealloc -{ - [_buttons release]; - [_axes release]; - [_directionalPads release]; - - [super dealloc]; -} -@end Index: src/hid/OHGamepad.h ================================================================== --- src/hid/OHGamepad.h +++ src/hid/OHGamepad.h @@ -20,19 +20,15 @@ #import "OHGameControllerProfile.h" OF_ASSUME_NONNULL_BEGIN /** - * @class OHGamepad OHGamepad.h ObjFWHID/OHGamepad.h + * @protocol OHGamepad OHGamepad.h ObjFWHID/OHGamepad.h * * @brief A game controller profile representing a gamepad. */ -@interface OHGamepad: OHGameControllerProfile -{ - OF_RESERVE_IVARS(OHGamepad, 4) -} - +@protocol OHGamepad /** * @brief The north button on the gamepad's diamond pad. */ @property (readonly, nonatomic) OHGameControllerButton *northButton; DELETED src/hid/OHGamepad.m Index: src/hid/OHGamepad.m ================================================================== --- src/hid/OHGamepad.m +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2008-2024 Jonathan Schleifer - * - * All rights reserved. - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License version 3.0 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * version 3.0 for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * version 3.0 along with this program. If not, see - * . - */ - -#include "config.h" - -#import "OHGamepad.h" - -@implementation OHGamepad -@dynamic northButton, southButton, westButton, eastButton, leftShoulderButton; -@dynamic rightShoulderButton, menuButton, optionsButton, dPad; -@end Index: src/hid/OHNintendo3DSExtendedGamepad.h ================================================================== --- src/hid/OHNintendo3DSExtendedGamepad.h +++ src/hid/OHNintendo3DSExtendedGamepad.h @@ -19,9 +19,14 @@ #import "OHExtendedGamepad.h" OF_ASSUME_NONNULL_BEGIN -@interface OHNintendo3DSExtendedGamepad: OHExtendedGamepad +@interface OHNintendo3DSExtendedGamepad: OFObject +{ + OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) + *_directionalPads; +} @end OF_ASSUME_NONNULL_END Index: src/hid/OHNintendo3DSExtendedGamepad.m ================================================================== --- src/hid/OHNintendo3DSExtendedGamepad.m +++ src/hid/OHNintendo3DSExtendedGamepad.m @@ -29,10 +29,12 @@ @"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"Start", @"Select" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @implementation OHNintendo3DSExtendedGamepad +@synthesize buttons = _buttons, directionalPads = _directionalPads; + - (instancetype)init { self = [super init]; @try { @@ -51,12 +53,10 @@ [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; - _axes = [[OFDictionary alloc] init]; - directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; xAxis = [[[OHGameControllerAxis alloc] initWithName: @"X"] autorelease]; @@ -105,10 +105,23 @@ @throw e; } return self; } + +- (void)dealloc +{ + [_buttons release]; + [_directionalPads release]; + + [super dealloc]; +} + +- (OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *)axes +{ + return [OFDictionary dictionary]; +} - (OHGameControllerButton *)northButton { return [_buttons objectForKey: @"X"]; } @@ -145,10 +158,20 @@ - (OHGameControllerButton *)rightTriggerButton { return [_buttons objectForKey: @"ZR"]; } + +- (OHGameControllerButton *)leftThumbstickButton +{ + return nil; +} + +- (OHGameControllerButton *)rightThumbstickButton +{ + return nil; +} - (OHGameControllerButton *)menuButton { return [_buttons objectForKey: @"Start"]; } @@ -155,10 +178,15 @@ - (OHGameControllerButton *)optionsButton { return [_buttons objectForKey: @"Select"]; } + +- (OHGameControllerButton *)homeButton +{ + return nil; +} - (OHGameControllerDirectionalPad *)leftThumbstick { return [_directionalPads objectForKey: @"Circle Pad"]; } Index: src/hid/OHNintendo3DSGameController.m ================================================================== --- src/hid/OHNintendo3DSGameController.m +++ src/hid/OHNintendo3DSGameController.m @@ -136,15 +136,15 @@ - (OFString *)name { return @"Nintendo 3DS"; } -- (OHGameControllerProfile *)rawProfile +- (id )rawProfile { return _extendedGamepad; } -- (OHGamepad *)gamepad +- (id )gamepad { return _extendedGamepad; } @end Index: src/hid/OHNintendoDSGameController.m ================================================================== --- src/hid/OHNintendoDSGameController.m +++ src/hid/OHNintendoDSGameController.m @@ -108,10 +108,10 @@ - (OFString *)name { return @"Nintendo DS"; } -- (OHGameControllerProfile *)rawProfile +- (id )rawProfile { return _gamepad; } @end Index: src/hid/OHNintendoDSGamepad.h ================================================================== --- src/hid/OHNintendoDSGamepad.h +++ src/hid/OHNintendoDSGamepad.h @@ -19,9 +19,14 @@ #import "OHGamepad.h" OF_ASSUME_NONNULL_BEGIN -@interface OHNintendoDSGamepad: OHGamepad +@interface OHNintendoDSGamepad: OFObject +{ + OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) + *_directionalPads; +} @end OF_ASSUME_NONNULL_END Index: src/hid/OHNintendoDSGamepad.m ================================================================== --- src/hid/OHNintendoDSGamepad.m +++ src/hid/OHNintendoDSGamepad.m @@ -28,10 +28,12 @@ @"A", @"B", @"X", @"Y", @"L", @"R", @"Start", @"Select" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @implementation OHNintendoDSGamepad +@synthesize buttons = _buttons, directionalPads = _directionalPads; + - (instancetype)init { self = [super init]; @try { @@ -48,12 +50,10 @@ [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; - _axes = [[OFMutableDictionary alloc] init]; - up = [[[OHGameControllerButton alloc] initWithName: @"D-Pad Up"] autorelease]; down = [[[OHGameControllerButton alloc] initWithName: @"D-Pad Down"] autorelease]; left = [[[OHGameControllerButton alloc] @@ -77,10 +77,23 @@ @throw e; } return self; } + +- (void)dealloc +{ + [_buttons release]; + [_directionalPads release]; + + [super dealloc]; +} + +- (OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *)axes +{ + return [OFDictionary dictionary]; +} - (OHGameControllerButton *)northButton { return [_buttons objectForKey: @"X"]; } Index: src/hid/OHXInputExtendedGamepad.h ================================================================== --- src/hid/OHXInputExtendedGamepad.h +++ src/hid/OHXInputExtendedGamepad.h @@ -19,9 +19,14 @@ #import "OHExtendedGamepad.h" OF_ASSUME_NONNULL_BEGIN -@interface OHXInputExtendedGamepad: OHExtendedGamepad +@interface OHXInputExtendedGamepad: OFObject +{ + OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) + *_directionalPads; +} @end OF_ASSUME_NONNULL_END Index: src/hid/OHXInputExtendedGamepad.m ================================================================== --- src/hid/OHXInputExtendedGamepad.m +++ src/hid/OHXInputExtendedGamepad.m @@ -31,10 +31,12 @@ @"Start", @"Back", @"Guide" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @implementation OHXInputExtendedGamepad +@synthesize buttons = _buttons, directionalPads = _directionalPads; + - (instancetype)init { self = [super init]; @try { @@ -58,12 +60,10 @@ [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; - _axes = [[OFDictionary alloc] init]; - directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; xAxis = [[[OHGameControllerAxis alloc] initWithName: @"X"] autorelease]; @@ -112,10 +112,23 @@ @throw e; } return self; } + +- (void)dealloc +{ + [_buttons release]; + [_directionalPads release]; + + [super dealloc]; +} + +- (OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *)axes +{ + return [OFDictionary dictionary]; +} - (OHGameControllerButton *)northButton { return [_buttons objectForKey: @"Y"]; } Index: src/hid/OHXInputGameController.m ================================================================== --- src/hid/OHXInputGameController.m +++ src/hid/OHXInputGameController.m @@ -234,15 +234,15 @@ } return nil; } -- (OHGameControllerProfile *)rawProfile +- (id )rawProfile { return _extendedGamepad; } -- (OHGamepad *)gamepad +- (id )gamepad { return _extendedGamepad; } @end Index: tests/gamecontroller/GameControllerTests.m ================================================================== --- tests/gamecontroller/GameControllerTests.m +++ tests/gamecontroller/GameControllerTests.m @@ -60,11 +60,11 @@ } @end OF_APPLICATION_DELEGATE(GameControllerTests) -static void printProfile(OHGameControllerProfile *profile) +static void printProfile(id profile) { OFArray OF_GENERIC(OFString *) *buttons = profile.buttons.allKeys.sortedArray; OFArray OF_GENERIC(OFString *) *axes = profile.axes.allKeys.sortedArray; OFArray OF_GENERIC(OFString *) *directionalPads = @@ -125,12 +125,12 @@ directionalPad.xAxis.value, directionalPad.yAxis.value]; } if (directionalPads.count > 0) [OFStdOut writeString: @"\n"]; - if ([profile isKindOfClass: [OHGamepad class]]) { - OHGamepad *gamepad = (OHGamepad *)profile; + if ([profile conformsToProtocol: @protocol(OHGamepad)]) { + id gamepad = (id )profile; [OFStdOut writeFormat: @"[Map] North: %@ South: %@ West: %@ East: %@\n", gamepad.northButton.name, gamepad.southButton.name, gamepad.westButton.name, gamepad.eastButton.name]; @@ -138,13 +138,13 @@ @"[Map] Left Shoulder: %@ Right Shoulder: %@\n", gamepad.leftShoulderButton.name, gamepad.rightShoulderButton.name]; } - if ([profile isKindOfClass: [OHExtendedGamepad class]]) { - OHExtendedGamepad *extendedGamepad = - (OHExtendedGamepad *)profile; + if ([profile conformsToProtocol: @protocol(OHExtendedGamepad)]) { + id extendedGamepad = + (id )profile; [OFStdOut writeFormat: @"[Map] Left Trigger: %@ Right Trigger: %@\n", extendedGamepad.leftTriggerButton.name, extendedGamepad.rightTriggerButton.name]; @@ -152,27 +152,27 @@ @"[Map] Left Thumbstick: %@ Right Thumbstick: %@\n", extendedGamepad.leftThumbstickButton.name, extendedGamepad.rightThumbstickButton.name]; } - if ([profile isKindOfClass: [OHGamepad class]]) { - OHGamepad *gamepad = (OHGamepad *)profile; + if ([profile conformsToProtocol: @protocol(OHGamepad)]) { + id gamepad = (id )profile; [OFStdOut writeFormat: @"[Map] Menu: %@ Options: %@", gamepad.menuButton.name, gamepad.optionsButton.name]; } - if ([profile isKindOfClass: [OHExtendedGamepad class]]) { - OHExtendedGamepad *extendedGamepad = - (OHExtendedGamepad *)profile; + if ([profile conformsToProtocol: @protocol(OHExtendedGamepad)]) { + id extendedGamepad = + (id )profile; [OFStdOut writeFormat: @" Home: %@", extendedGamepad.homeButton.name]; } - if ([profile isKindOfClass: [OHGamepad class]]) + if ([profile conformsToProtocol: @protocol(OHGamepad)]) [OFStdOut writeString: @"\n"]; } @implementation GameControllerTests - (void)applicationDidFinishLaunching: (OFNotification *)notification @@ -197,11 +197,11 @@ } [OFStdOut setCursorPosition: OFMakePoint(0, 0)]; for (OHGameController *controller in _controllers) { - OHGameControllerProfile *profile; + id profile; profile = controller.extendedGamepad; if (profile == nil) profile = controller.gamepad; if (profile == nil)