Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -176,10 +176,11 @@ enable_shared="no" enable_threads="no" # TODO with_tls="no" AC_DEFINE(OF_WII, 1, [Whether we are compiling for Wii]) + AC_SUBST(USE_SRCS_WII, '${SRCS_WII}') AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map']) ]) AC_ARG_WITH(wii-u, AS_HELP_STRING([--with-wii-u], [build for Wii U])) Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -107,9 +107,10 @@ USE_SRCS_SOCKETS = @USE_SRCS_SOCKETS@ USE_SRCS_SUBPROCESSES = @USE_SRCS_SUBPROCESSES@ USE_SRCS_TAGGED_POINTERS = @USE_SRCS_TAGGED_POINTERS@ USE_SRCS_THREADS = @USE_SRCS_THREADS@ USE_SRCS_UNIX_SOCKETS = @USE_SRCS_UNIX_SOCKETS@ +USE_SRCS_WII = @USE_SRCS_WII@ USE_SRCS_WINDOWS = @USE_SRCS_WINDOWS@ USE_SRCS_XINPUT = @USE_SRCS_XINPUT@ WII_U_TESTS_LIBS = @WII_U_TESTS_LIBS@ WRAPPER = @WRAPPER@ Index: src/hid/Makefile ================================================================== --- src/hid/Makefile +++ src/hid/Makefile @@ -16,10 +16,11 @@ OHGameControllerDirectionalPad.m \ OHGameControllerElement.m \ ${USE_SRCS_EVDEV} \ ${USE_SRCS_NINTENDO_3DS} \ ${USE_SRCS_NINTENDO_DS} \ + ${USE_SRCS_WII} \ ${USE_SRCS_XINPUT} SRCS_EVDEV = OHEvdevDualSense.m \ OHEvdevDualShock4.m \ OHEvdevExtendedGamepad.m \ OHEvdevGameController.m \ @@ -27,10 +28,12 @@ OHEvdevStadiaExtendedGamepad.m SRCS_NINTENDO_3DS = OHNintendo3DSExtendedGamepad.m \ OHNintendo3DSGameController.m SRCS_NINTENDO_DS = OHNintendoDSGamepad.m \ OHNintendoDSGameController.m +SRCS_WII = OHWiiClassicController.m \ + OHWiiGameController.m SRCS_XINPUT = OHXInputExtendedGamepad.m \ OHXInputGameController.m INCLUDES := ${SRCS:.m=.h} \ OHExtendedGamepad.h \ Index: src/hid/OHEvdevGameController.h ================================================================== --- src/hid/OHEvdevGameController.h +++ src/hid/OHEvdevGameController.h @@ -20,12 +20,10 @@ #import "OHGameController.h" #import "OHGameControllerProfile.h" OF_ASSUME_NONNULL_BEGIN -@class OHGameControllerProfile; - @interface OHEvdevGameController: OHGameController { OFString *_path; int _fd; bool _discardUntilReport; Index: src/hid/OHGameController.m ================================================================== --- src/hid/OHGameController.m +++ src/hid/OHGameController.m @@ -34,10 +34,13 @@ # import "OHNintendoDSGameController.h" #endif #ifdef OF_NINTENDO_3DS # import "OHNintendo3DSGameController.h" #endif +#ifdef OF_WII +# import "OHWiiGameController.h" +#endif const uint16_t OHVendorIDSony = 0x054C; const uint16_t OHVendorIDNintendo = 0x057E; const uint16_t OHVendorIDGoogle = 0x18D1; const uint16_t OHProductIDDualShock4 = 0x09CC; @@ -58,10 +61,12 @@ return [OHXInputGameController controllers]; #elif defined(OF_NINTENDO_DS) return [OHNintendoDSGameController controllers]; #elif defined(OF_NINTENDO_3DS) return [OHNintendo3DSGameController controllers]; +#elif defined(OF_WII) + return [OHWiiGameController controllers]; #else return [OFArray array]; #endif } Index: src/hid/OHNintendo3DSGameController.m ================================================================== --- src/hid/OHNintendo3DSGameController.m +++ src/hid/OHNintendo3DSGameController.m @@ -20,11 +20,10 @@ #include "config.h" #import "OHNintendo3DSGameController.h" #import "OFArray.h" #import "OFDictionary.h" -#import "OFNumber.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHNintendo3DSExtendedGamepad.h" Index: src/hid/OHNintendoDSGameController.m ================================================================== --- src/hid/OHNintendoDSGameController.m +++ src/hid/OHNintendoDSGameController.m @@ -20,11 +20,10 @@ #include "config.h" #import "OHNintendoDSGameController.h" #import "OFArray.h" #import "OFDictionary.h" -#import "OFNumber.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHNintendoDSGamepad.h" #import "OFInitializationFailedException.h" ADDED src/hid/OHWiiClassicController.h Index: src/hid/OHWiiClassicController.h ================================================================== --- /dev/null +++ src/hid/OHWiiClassicController.h @@ -0,0 +1,32 @@ +/* + * 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 + +@interface OHWiiClassicController: OFObject +{ + OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) + *_directionalPads; +} +@end + +OF_ASSUME_NONNULL_END ADDED src/hid/OHWiiClassicController.m Index: src/hid/OHWiiClassicController.m ================================================================== --- /dev/null +++ src/hid/OHWiiClassicController.m @@ -0,0 +1,203 @@ +/* + * 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 "OHWiiClassicController.h" +#import "OFDictionary.h" +#import "OHGameControllerAxis.h" +#import "OHGameControllerButton.h" +#import "OHGameControllerDirectionalPad.h" + +static OFString *const buttonNames[] = { + @"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"+", @"-", @"Home" +}; +static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); + +@implementation OHWiiClassicController +@synthesize buttons = _buttons, directionalPads = _directionalPads; + +- (instancetype)init +{ + self = [super init]; + + @try { + void *pool = objc_autoreleasePoolPush(); + OFMutableDictionary *buttons = + [OFMutableDictionary dictionaryWithCapacity: numButtons]; + OFMutableDictionary *directionalPads; + OHGameControllerAxis *xAxis, *yAxis; + OHGameControllerDirectionalPad *directionalPad; + OHGameControllerButton *up, *down, *left, *right; + + for (size_t i = 0; i < numButtons; i++) { + OHGameControllerButton *button = + [[OHGameControllerButton alloc] + initWithName: buttonNames[i]]; + [buttons setObject: button forKey: buttonNames[i]]; + } + [buttons makeImmutable]; + _buttons = [buttons retain]; + + directionalPads = + [OFMutableDictionary dictionaryWithCapacity: 3]; + + xAxis = [[[OHGameControllerAxis alloc] + initWithName: @"X"] autorelease]; + yAxis = [[[OHGameControllerAxis alloc] + initWithName: @"Y"] autorelease]; + directionalPad = [[[OHGameControllerDirectionalPad alloc] + initWithName: @"Left Thumbstick" + xAxis: xAxis + yAxis: yAxis] autorelease]; + [directionalPads setObject: directionalPad + forKey: @"Left Thumbstick"]; + + xAxis = [[[OHGameControllerAxis alloc] + initWithName: @"RX"] autorelease]; + yAxis = [[[OHGameControllerAxis alloc] + initWithName: @"RY"] autorelease]; + directionalPad = [[[OHGameControllerDirectionalPad alloc] + initWithName: @"Right Thumbstick" + xAxis: xAxis + yAxis: yAxis] autorelease]; + [directionalPads setObject: directionalPad + forKey: @"Right Thumbstick"]; + + up = [[[OHGameControllerButton alloc] + initWithName: @"D-Pad Up"] autorelease]; + down = [[[OHGameControllerButton alloc] + initWithName: @"D-Pad Down"] autorelease]; + left = [[[OHGameControllerButton alloc] + initWithName: @"D-Pad Left"] autorelease]; + right = [[[OHGameControllerButton alloc] + initWithName: @"D-Pad Right"] autorelease]; + directionalPad = [[[OHGameControllerDirectionalPad alloc] + initWithName: @"D-Pad" + up: up + down: down + left: left + right: right] autorelease]; + [directionalPads setObject: directionalPad forKey: @"D-Pad"]; + + [directionalPads makeImmutable]; + _directionalPads = [directionalPads retain]; + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @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"]; +} + +- (OHGameControllerButton *)southButton +{ + return [_buttons objectForKey: @"B"]; +} + +- (OHGameControllerButton *)westButton +{ + return [_buttons objectForKey: @"Y"]; +} + +- (OHGameControllerButton *)eastButton +{ + return [_buttons objectForKey: @"A"]; +} + +- (OHGameControllerButton *)leftShoulderButton +{ + return [_buttons objectForKey: @"ZL"]; +} + +- (OHGameControllerButton *)rightShoulderButton +{ + return [_buttons objectForKey: @"ZR"]; +} + +- (OHGameControllerButton *)leftTriggerButton +{ + return [_buttons objectForKey: @"L"]; +} + +- (OHGameControllerButton *)rightTriggerButton +{ + return [_buttons objectForKey: @"R"]; +} + +- (OHGameControllerButton *)leftThumbstickButton +{ + return nil; +} + +- (OHGameControllerButton *)rightThumbstickButton +{ + return nil; +} + +- (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/OHWiiGameController.h Index: src/hid/OHWiiGameController.h ================================================================== --- /dev/null +++ src/hid/OHWiiGameController.h @@ -0,0 +1,34 @@ +/* + * 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 "OHGameController.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHWiiGameController: OHGameController +{ + int32_t _index; + uint32_t _type; + id _rawProfile; +} + +- (instancetype)initWithIndex: (int32_t)index type: (uint32_t)type; +@end + +OF_ASSUME_NONNULL_END ADDED src/hid/OHWiiGameController.m Index: src/hid/OHWiiGameController.m ================================================================== --- /dev/null +++ src/hid/OHWiiGameController.m @@ -0,0 +1,370 @@ +/* + * 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 "OHWiiGameController.h" +#import "OFArray.h" +#import "OFDictionary.h" +#import "OHGameControllerButton.h" +#import "OHGameControllerDirectionalPad.h" +#import "OHWiiClassicController.h" + +#import "OFInitializationFailedException.h" +#import "OFInvalidArgumentException.h" +#import "OFReadFailedException.h" + +#define asm __asm__ +#include +#undef asm + +@interface OHWiiGameControllerProfile: OFObject +{ + OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) + *_directionalPads; +} + +- (instancetype)initWithType: (uint32_t)type; +@end + +static OFString *const buttonNames[] = { + @"A", @"B", @"1", @"2", @"+", @"-", @"Home" +}; +static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); +static OFString *const nunchukButtonNames[] = { + @"C", @"Z" +}; +static const size_t numNunchukButtons = + sizeof(nunchukButtonNames) / sizeof(*nunchukButtonNames); + +static float +scale(float value, float min, float max, float center) +{ + if (value < min) + value = min; + if (value > max) + value = max; + + if (value >= center) + return (value - center) / (max - center); + else + return (value - center) / (center - min); +} + +@implementation OHWiiGameController +@synthesize rawProfile = _rawProfile; + ++ (void)initialize +{ + if (self != [OHWiiGameController class]) + return; + + if (WPAD_Init() != WPAD_ERR_NONE) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +} + ++ (OFArray OF_GENERIC(OHGameController *) *)controllers +{ + OFMutableArray *controllers = [OFMutableArray array]; + void *pool = objc_autoreleasePoolPush(); + + for (int32_t i = 0; i < WPAD_MAX_WIIMOTES; i++) { + uint32_t type; + + if (WPAD_Probe(i, &type) == WPAD_ERR_NONE && + (type == WPAD_EXP_NONE || type == WPAD_EXP_NUNCHUK || + type == WPAD_EXP_CLASSIC)) + [controllers addObject: [[[OHWiiGameController alloc] + initWithIndex: i + type: type] autorelease]]; + } + + [controllers makeImmutable]; + + objc_autoreleasePoolPop(pool); + + return controllers; +} + +- (instancetype)initWithIndex: (int32_t)index type: (uint32_t)type +{ + self = [super init]; + + @try { + _index = index; + _type = type; + + if (type == WPAD_EXP_CLASSIC) + _rawProfile = [[OHWiiClassicController alloc] init]; + else + _rawProfile = [[OHWiiGameControllerProfile alloc] + initWithType: type]; + + [self retrieveState]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_rawProfile release]; + + [super dealloc]; +} + +- (void)retrieveState +{ + OFDictionary *buttons = _rawProfile.buttons; + OFDictionary *directionalPads = _rawProfile.directionalPads; + WPADData *data; + + if (WPAD_ReadPending(_index, NULL) < WPAD_ERR_NONE) + @throw [OFReadFailedException + exceptionWithObject: self + requestedLength: sizeof(WPADData) + errNo: 0]; + + data = WPAD_Data(_index); + + if (_type == WPAD_EXP_NONE || _type == WPAD_EXP_NUNCHUK) { + OHGameControllerDirectionalPad *dPad = + [directionalPads objectForKey: @"D-Pad"]; + + [[buttons objectForKey: @"A"] + setValue: !!(data->btns_h & WPAD_BUTTON_A)]; + [[buttons objectForKey: @"B"] + setValue: !!(data->btns_h & WPAD_BUTTON_B)]; + [[buttons objectForKey: @"1"] + setValue: !!(data->btns_h & WPAD_BUTTON_1)]; + [[buttons objectForKey: @"2"] + setValue: !!(data->btns_h & WPAD_BUTTON_2)]; + [[buttons objectForKey: @"+"] + setValue: !!(data->btns_h & WPAD_BUTTON_PLUS)]; + [[buttons objectForKey: @"-"] + setValue: !!(data->btns_h & WPAD_BUTTON_MINUS)]; + [[buttons objectForKey: @"Home"] + setValue: !!(data->btns_h & WPAD_BUTTON_HOME)]; + + [dPad.up setValue: !!(data->btns_h & WPAD_BUTTON_UP)]; + [dPad.down setValue: !!(data->btns_h & WPAD_BUTTON_DOWN)]; + [dPad.left setValue: !!(data->btns_h & WPAD_BUTTON_LEFT)]; + [dPad.right setValue: !!(data->btns_h & WPAD_BUTTON_RIGHT)]; + } + + if (_type == WPAD_EXP_NUNCHUK) { + joystick_t *js = &data->exp.nunchuk.js; + OHGameControllerDirectionalPad *directionalPad; + + [[buttons objectForKey: @"C"] + setValue: !!(data->btns_h & WPAD_NUNCHUK_BUTTON_C)]; + [[buttons objectForKey: @"Z"] + setValue: !!(data->btns_h & WPAD_NUNCHUK_BUTTON_Z)]; + + directionalPad = + [directionalPads objectForKey: @"Analog Stick"]; + directionalPad.xAxis.value = + scale(js->pos.x, js->min.x, js->max.x, js->center.x); + directionalPad.yAxis.value = + -scale(js->pos.y, js->min.y, js->max.y, js->center.y); + } + + if (_type == WPAD_EXP_CLASSIC) { + joystick_t *ljs = &data->exp.classic.ljs; + joystick_t *rjs = &data->exp.classic.rjs; + OHGameControllerDirectionalPad *directionalPad; + + [[buttons objectForKey: @"X"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_X)]; + [[buttons objectForKey: @"B"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_B)]; + [[buttons objectForKey: @"Y"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_Y)]; + [[buttons objectForKey: @"A"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_A)]; + [[buttons objectForKey: @"ZL"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_ZL)]; + [[buttons objectForKey: @"ZR"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_ZR)]; + [[buttons objectForKey: @"+"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_PLUS)]; + [[buttons objectForKey: @"-"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_MINUS)]; + [[buttons objectForKey: @"Home"] + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_HOME)]; + + directionalPad = + [directionalPads objectForKey: @"Left Thumbstick"]; + directionalPad.xAxis.value = + scale(ljs->pos.x, ljs->min.x, ljs->max.x, ljs->center.x); + directionalPad.yAxis.value = + -scale(ljs->pos.y, ljs->min.y, ljs->max.y, ljs->center.y); + + directionalPad = + [directionalPads objectForKey: @"Right Thumbstick"]; + directionalPad.xAxis.value = + scale(rjs->pos.x, rjs->min.x, rjs->max.x, rjs->center.x); + directionalPad.yAxis.value = + -scale(rjs->pos.y, rjs->min.y, rjs->max.y, rjs->center.y); + + [[buttons objectForKey: @"L"] + setValue: data->exp.classic.l_shoulder]; + [[buttons objectForKey: @"R"] + setValue: data->exp.classic.r_shoulder]; + + directionalPad = [directionalPads objectForKey: @"D-Pad"]; + [directionalPad.up + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_UP)]; + [directionalPad.down + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_DOWN)]; + [directionalPad.left + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_LEFT)]; + [directionalPad.right + setValue: !!(data->btns_h & WPAD_CLASSIC_BUTTON_RIGHT)]; + } +} + +- (OFString *)name +{ + if (_type == WPAD_EXP_NUNCHUK) + return @"Wiimote with Nunchuk"; + else if (_type == WPAD_EXP_CLASSIC) + return @"Wiimote with Classic Controller"; + else + return @"Wiimote"; +} + +- (id )gamepad +{ + if (_type == WPAD_EXP_CLASSIC) + return (id )_rawProfile; + + return nil; +} + +- (id )extendedGamepad +{ + if (_type == WPAD_EXP_CLASSIC) + return (id )_rawProfile; + + return nil; +} +@end + +@implementation OHWiiGameControllerProfile +@synthesize buttons = _buttons, directionalPads = _directionalPads; + +- (instancetype)initWithType: (uint32_t)type +{ + self = [super init]; + + @try { + void *pool = objc_autoreleasePoolPush(); + OFMutableDictionary *buttons; + OFMutableDictionary *directionalPads; + OHGameControllerDirectionalPad *directionalPad; + OHGameControllerButton *up, *down, *left, *right; + OHGameControllerAxis *xAxis, *yAxis; + + if (type != WPAD_EXP_NONE && type != WPAD_EXP_NUNCHUK) + @throw [OFInvalidArgumentException exception]; + + buttons = [OFMutableDictionary + dictionaryWithCapacity: numButtons + numNunchukButtons]; + + for (size_t i = 0; i < numButtons; i++) { + OHGameControllerButton *button = + [[[OHGameControllerButton alloc] + initWithName: buttonNames[i]] autorelease]; + [buttons setObject: button forKey: buttonNames[i]]; + } + + directionalPads = [OFMutableDictionary dictionary]; + + up = [[[OHGameControllerButton alloc] + initWithName: @"D-Pad Up"] autorelease]; + down = [[[OHGameControllerButton alloc] + initWithName: @"D-Pad Down"] autorelease]; + left = [[[OHGameControllerButton alloc] + initWithName: @"D-Pad Left"] autorelease]; + right = [[[OHGameControllerButton alloc] + initWithName: @"D-Pad Right"] autorelease]; + directionalPad = [[[OHGameControllerDirectionalPad alloc] + initWithName: @"D-Pad" + up: up + down: down + left: left + right: right] autorelease]; + [directionalPads setObject: directionalPad forKey: @"D-Pad"]; + + if (type == WPAD_EXP_NUNCHUK) { + for (size_t i = 0; i < numNunchukButtons; i++) { + OHGameControllerButton *button = + [[[OHGameControllerButton alloc] + initWithName: nunchukButtonNames[i]] + autorelease]; + + [buttons setObject: button + forKey: nunchukButtonNames[i]]; + } + + xAxis = [[[OHGameControllerAxis alloc] + initWithName: @"X"] autorelease]; + yAxis = [[[OHGameControllerAxis alloc] + initWithName: @"Y"] autorelease]; + directionalPad = [[[OHGameControllerDirectionalPad alloc] + initWithName: @"Analog Stick" + xAxis: xAxis + yAxis: yAxis] autorelease]; + [directionalPads setObject: directionalPad + forKey: @"Analog Stick"]; + } + + [buttons makeImmutable]; + [directionalPads makeImmutable]; + _buttons = [buttons retain]; + _directionalPads = [directionalPads retain]; + + objc_autoreleasePoolPop(pool); + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_buttons release]; + [_directionalPads release]; + + [super dealloc]; +} + +- (OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *)axes +{ + return [OFDictionary dictionary]; +} +@end Index: src/hid/OHXInputExtendedGamepad.m ================================================================== --- src/hid/OHXInputExtendedGamepad.m +++ src/hid/OHXInputExtendedGamepad.m @@ -22,11 +22,10 @@ #import "OHXInputExtendedGamepad.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" -#import "OHXInputGameController.h" static OFString *const buttonNames[] = { @"A", @"B", @"X", @"Y", @"LB", @"RB", @"LT", @"RT", @"LSB", @"RSB", @"Start", @"Back", @"Guide" };