Index: src/hid/Makefile ================================================================== --- src/hid/Makefile +++ src/hid/Makefile @@ -7,19 +7,19 @@ FRAMEWORK = ${OBJFWHID_FRAMEWORK} LIB_MAJOR = ${OBJFWHID_LIB_MAJOR} LIB_MINOR = ${OBJFWHID_LIB_MINOR} LIB_PATCH = ${OBJFWHID_LIB_PATCH} -SRCS = OHCombinedJoyCons.m \ - OHDualSenseGamepad.m \ +SRCS = OHDualSenseGamepad.m \ OHDualShock4Gamepad.m \ OHExtendedN64Controller.m \ OHGameController.m \ OHGameControllerAxis.m \ OHGameControllerButton.m \ OHGameControllerDirectionalPad.m \ OHGameControllerElement.m \ + OHJoyConPair.m \ OHLeftJoyCon.m \ OHN64Controller.m \ OHRightJoyCon.m \ OHStadiaGamepad.m \ OHXboxGamepad.m DELETED src/hid/OHCombinedJoyCons.h Index: src/hid/OHCombinedJoyCons.h ================================================================== --- src/hid/OHCombinedJoyCons.h +++ /dev/null @@ -1,68 +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 - * . - */ - -#import "OHExtendedGamepad.h" - -OF_ASSUME_NONNULL_BEGIN - -@class OHGameController; -@class OHGameControllerButton; -@class OHGameControllerDirectionalPad; - -/** - * @class OHCombinedJoyCons OHCombinedJoyCons.h ObjFWHID/ObjFWHID.h - * - * @brief Combines a left and a right Joy-Con into a gamepad. - */ -OF_SUBCLASSING_RESTRICTED -@interface OHCombinedJoyCons: OFObject -{ - 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. - * - * @param leftJoyCon The left Joy-Con - * @param rightJoyCon The right Joy-Con - * @return An new @ref OHCombinedJoyCons - */ -+ (instancetype)gamepadWithLeftJoyCon: (OHGameController *)leftJoyCon - rightJoyCon: (OHGameController *)rightJoyCon; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated @ref OHCombinedJoyCons with the - * specified left and right Joy-Con. - * - * @param leftJoyCon The left Joy-Con - * @param rightJoyCon The right Joy-Con - * @return An initialized @ref OHCombinedJoyCons - */ -- (instancetype)initWithLeftJoyCon: (OHGameController *)leftJoyCon - rightJoyCon: (OHGameController *)rightJoyCon; -@end - -OF_ASSUME_NONNULL_END DELETED src/hid/OHCombinedJoyCons.m Index: src/hid/OHCombinedJoyCons.m ================================================================== --- src/hid/OHCombinedJoyCons.m +++ /dev/null @@ -1,194 +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 "OHCombinedJoyCons.h" -#import "OFDictionary.h" -#import "OFNumber.h" -#import "OHGameController.h" -#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]; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (instancetype)initWithLeftJoyCon: (OHGameController *)leftJoyCon - rightJoyCon: (OHGameController *)rightJoyCon -{ - self = [super init]; - - @try { - void *pool = objc_autoreleasePoolPush(); - OFDictionary *leftButtons, *rightButtons; - OFMutableDictionary *buttons, *directionalPads; - - if (leftJoyCon.vendorID.unsignedShortValue != - OHVendorIDNintendo || - rightJoyCon.vendorID.unsignedShortValue != - OHVendorIDNintendo) - @throw [OFInvalidArgumentException exception]; - - if (leftJoyCon.productID.unsignedShortValue != - OHProductIDLeftJoyCon || - rightJoyCon.productID.unsignedShortValue != - OHProductIDRightJoyCon) - @throw [OFInvalidArgumentException exception]; - - _leftJoyCon = [leftJoyCon.profile retain]; - _rightJoyCon = [rightJoyCon.profile retain]; - - leftButtons = _leftJoyCon.buttons; - rightButtons = _rightJoyCon.buttons; - - buttons = [OFMutableDictionary dictionaryWithCapacity: - leftButtons.count + rightButtons.count]; - [buttons addEntriesFromDictionary: leftButtons]; - [buttons addEntriesFromDictionary: rightButtons]; - [buttons removeObjectForKey: @"SL"]; - [buttons removeObjectForKey: @"SR"]; - [buttons makeImmutable]; - _buttons = [buttons retain]; - - directionalPads = - [OFMutableDictionary dictionaryWithCapacity: 3]; - [directionalPads addEntriesFromDictionary: - _leftJoyCon.directionalPads]; - [directionalPads addEntriesFromDictionary: - _rightJoyCon.directionalPads]; - [directionalPads makeImmutable]; - _directionalPads = [directionalPads retain]; - - objc_autoreleasePoolPop(pool); - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (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"]; -} - -- (OHGameControllerButton *)southButton -{ - return [_buttons objectForKey: @"B"]; -} - -- (OHGameControllerButton *)westButton -{ - return [_buttons objectForKey: @"Y"]; -} - -- (OHGameControllerButton *)eastButton -{ - return [_buttons objectForKey: @"A"]; -} - -- (OHGameControllerButton *)leftShoulderButton -{ - return [_buttons objectForKey: @"L"]; -} - -- (OHGameControllerButton *)rightShoulderButton -{ - return [_buttons objectForKey: @"R"]; -} - -- (OHGameControllerButton *)leftTriggerButton -{ - return [_buttons objectForKey: @"ZL"]; -} - -- (OHGameControllerButton *)rightTriggerButton -{ - return [_buttons objectForKey: @"ZR"]; -} - -- (OHGameControllerButton *)leftThumbstickButton -{ - return [_buttons objectForKey: @"Left Thumbstick"]; -} - -- (OHGameControllerButton *)rightThumbstickButton -{ - return [_buttons objectForKey: @"Right Thumbstick"]; -} - -- (OHGameControllerButton *)menuButton -{ - return [_buttons objectForKey: @"+"]; -} - -- (OHGameControllerButton *)optionsButton -{ - return [_buttons objectForKey: @"-"]; -} - -- (OHGameControllerButton *)homeButton -{ - return [_buttons objectForKey: @"Home"]; -} - -- (OHGameControllerDirectionalPad *)leftThumbstick -{ - return [_directionalPads objectForKey: @"Left Thumbstick"]; -} - -- (OHGameControllerDirectionalPad *)rightThumbstick -{ - return [_directionalPads objectForKey: @"Right Thumbstick"]; -} - -- (OHGameControllerDirectionalPad *)dPad -{ - return [_directionalPads objectForKey: @"D-Pad"]; -} -@end ADDED src/hid/OHJoyConPair.h Index: src/hid/OHJoyConPair.h ================================================================== --- /dev/null +++ src/hid/OHJoyConPair.h @@ -0,0 +1,69 @@ +/* + * 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 + * . + */ + +#import "OHExtendedGamepad.h" + +OF_ASSUME_NONNULL_BEGIN + +@class OHGameController; +@class OHGameControllerButton; +@class OHGameControllerDirectionalPad; +@class OHLeftJoyCon; +@class OHRightJoyCon; + +/** + * @class OHJoyConPair OHJoyConPair.h ObjFWHID/ObjFWHID.h + * + * @brief Combines a left and a right Joy-Con into a gamepad. + */ +OF_SUBCLASSING_RESTRICTED +@interface OHJoyConPair: OFObject +{ + OHLeftJoyCon *_leftJoyCon; + OHRightJoyCon *_rightJoyCon; + OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) + *_directionalPads; +} + +/** + * @brief Creates a new Joy-Con pair with the specified left and right Joy-Con. + * + * @param leftJoyCon The left Joy-Con for the pair + * @param rightJoyCon The right Joy-Con for the pair + * @return An new Joy-Con pair + */ ++ (instancetype)gamepadWithLeftJoyCon: (OHLeftJoyCon *)leftJoyCon + rightJoyCon: (OHRightJoyCon *)rightJoyCon; + +- (instancetype)init OF_UNAVAILABLE; + +/** + * @brief Initializes an already allocated Joy-Con pair with the specified left + * and right Joy-Con. + * + * @param leftJoyCon The left Joy-Con for the pair + * @param rightJoyCon The right Joy-Con for the pair + * @return An initialized Joy-Con pair + */ +- (instancetype)initWithLeftJoyCon: (OHLeftJoyCon *)leftJoyCon + rightJoyCon: (OHRightJoyCon *)rightJoyCon; +@end + +OF_ASSUME_NONNULL_END ADDED src/hid/OHJoyConPair.m Index: src/hid/OHJoyConPair.m ================================================================== --- /dev/null +++ src/hid/OHJoyConPair.m @@ -0,0 +1,180 @@ +/* + * 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 "OHJoyConPair.h" +#import "OFDictionary.h" +#import "OFNumber.h" +#import "OHGameController.h" +#import "OHGameControllerDirectionalPad.h" +#import "OHLeftJoyCon.h" +#import "OHRightJoyCon.h" + +#import "OFInvalidArgumentException.h" + +@implementation OHJoyConPair +@synthesize buttons = _buttons, directionalPads = _directionalPads; + ++ (instancetype)gamepadWithLeftJoyCon: (OHLeftJoyCon *)leftJoyCon + rightJoyCon: (OHRightJoyCon *)rightJoyCon +{ + return [[[self alloc] initWithLeftJoyCon: leftJoyCon + rightJoyCon: rightJoyCon] autorelease]; +} + +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)initWithLeftJoyCon: (OHLeftJoyCon *)leftJoyCon + rightJoyCon: (OHRightJoyCon *)rightJoyCon +{ + self = [super init]; + + @try { + void *pool = objc_autoreleasePoolPush(); + OFMutableDictionary *buttons, *directionalPads; + + _leftJoyCon = [leftJoyCon retain]; + _rightJoyCon = [rightJoyCon retain]; + + buttons = [OFMutableDictionary dictionaryWithCapacity: + _leftJoyCon.buttons.count + _rightJoyCon.buttons.count]; + [buttons addEntriesFromDictionary: _leftJoyCon.buttons]; + [buttons addEntriesFromDictionary: _rightJoyCon.buttons]; + [buttons removeObjectForKey: @"SL"]; + [buttons removeObjectForKey: @"SR"]; + [buttons makeImmutable]; + _buttons = [buttons retain]; + + directionalPads = + [OFMutableDictionary dictionaryWithCapacity: 3]; + [directionalPads addEntriesFromDictionary: + _leftJoyCon.directionalPads]; + [directionalPads addEntriesFromDictionary: + _rightJoyCon.directionalPads]; + [directionalPads makeImmutable]; + _directionalPads = [directionalPads retain]; + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (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"]; +} + +- (OHGameControllerButton *)southButton +{ + return [_buttons objectForKey: @"B"]; +} + +- (OHGameControllerButton *)westButton +{ + return [_buttons objectForKey: @"Y"]; +} + +- (OHGameControllerButton *)eastButton +{ + return [_buttons objectForKey: @"A"]; +} + +- (OHGameControllerButton *)leftShoulderButton +{ + return [_buttons objectForKey: @"L"]; +} + +- (OHGameControllerButton *)rightShoulderButton +{ + return [_buttons objectForKey: @"R"]; +} + +- (OHGameControllerButton *)leftTriggerButton +{ + return [_buttons objectForKey: @"ZL"]; +} + +- (OHGameControllerButton *)rightTriggerButton +{ + return [_buttons objectForKey: @"ZR"]; +} + +- (OHGameControllerButton *)leftThumbstickButton +{ + return [_buttons objectForKey: @"Left Thumbstick"]; +} + +- (OHGameControllerButton *)rightThumbstickButton +{ + return [_buttons objectForKey: @"Right Thumbstick"]; +} + +- (OHGameControllerButton *)menuButton +{ + return [_buttons objectForKey: @"+"]; +} + +- (OHGameControllerButton *)optionsButton +{ + return [_buttons objectForKey: @"-"]; +} + +- (OHGameControllerButton *)homeButton +{ + return [_buttons objectForKey: @"Home"]; +} + +- (OHGameControllerDirectionalPad *)leftThumbstick +{ + return [_directionalPads objectForKey: @"Left Thumbstick"]; +} + +- (OHGameControllerDirectionalPad *)rightThumbstick +{ + return [_directionalPads objectForKey: @"Right Thumbstick"]; +} + +- (OHGameControllerDirectionalPad *)dPad +{ + return [_directionalPads objectForKey: @"D-Pad"]; +} +@end Index: src/hid/ObjFWHID.h ================================================================== --- src/hid/ObjFWHID.h +++ src/hid/ObjFWHID.h @@ -24,14 +24,14 @@ #import "OHGameControllerDirectionalPad.h" #import "OHGameControllerProfile.h" #import "OHGamepad.h" #import "OHExtendedGamepad.h" -#import "OHCombinedJoyCons.h" #import "OHDualSenseGamepad.h" #import "OHDualShock4Gamepad.h" #import "OHExtendedN64Controller.h" #import "OHLeftJoyCon.h" -#import "OHN64Controller.h" #import "OHRightJoyCon.h" +#import "OHJoyConPair.h" +#import "OHN64Controller.h" #import "OHStadiaGamepad.h" #import "OHXboxGamepad.h" Index: tests/gamecontroller/GameControllerTests.m ================================================================== --- tests/gamecontroller/GameControllerTests.m +++ tests/gamecontroller/GameControllerTests.m @@ -26,18 +26,20 @@ #import "OFDictionary.h" #import "OFNumber.h" #import "OFStdIOStream.h" #import "OFThread.h" -#import "OHCombinedJoyCons.h" #import "OHExtendedGamepad.h" #import "OHGameController.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHGameControllerProfile.h" #import "OHGamepad.h" +#import "OHJoyConPair.h" +#import "OHLeftJoyCon.h" +#import "OHRightJoyCon.h" #import "OFReadFailedException.h" #if defined(OF_NINTENDO_DS) static size_t buttonsPerLine = 2; @@ -193,11 +195,12 @@ while (appletMainLoop()) { #else for (;;) { #endif void *pool = objc_autoreleasePoolPush(); - OHGameController *leftJoyCon = nil, *rightJoyCon = nil; + OHLeftJoyCon *leftJoyCon = nil; + OHRightJoyCon *rightJoyCon = nil; if (_lastControllersUpdate == nil || -[_lastControllersUpdate timeIntervalSinceNow] > 1) { [_controllers release]; [_lastControllersUpdate release]; @@ -225,30 +228,25 @@ continue; } printProfile(profile); - if (controller.vendorID.unsignedShortValue == - OHVendorIDNintendo) { - if (controller.productID.unsignedShortValue == - OHProductIDLeftJoyCon) - leftJoyCon = controller; - if (controller.productID.unsignedShortValue == - OHProductIDRightJoyCon) - rightJoyCon = controller; - } + if ([profile isKindOfClass: [OHLeftJoyCon class]]) + leftJoyCon = (OHLeftJoyCon *)profile; + else if ([profile isKindOfClass: [OHRightJoyCon class]]) + rightJoyCon = (OHRightJoyCon *)profile; } if (leftJoyCon != nil && rightJoyCon != nil) { - OHCombinedJoyCons *combinedJoyCons = [OHCombinedJoyCons + OHJoyConPair *joyConPair = [OHJoyConPair gamepadWithLeftJoyCon: leftJoyCon rightJoyCon: rightJoyCon]; [OFStdOut setForegroundColor: [OFColor green]]; - [OFStdOut writeLine: @"Combined Joy-Cons"]; + [OFStdOut writeLine: @"Joy-Con Pair"]; - printProfile(combinedJoyCons); + printProfile(joyConPair); } #if defined(OF_WII) || defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) [OFThread waitForVerticalBlank]; #elif defined(OF_NINTENDO_SWITCH)