Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -15,11 +15,10 @@ */.deps .deps .git aclocal.m4 autom4te.cache -boot.dol buildsys.mk config.h config.h.in config.log config.status @@ -29,10 +28,11 @@ generators/library/gen_libraries generators/unicode/gen_tables src/Info.plist src/bridge/Info.plist src/hid/Info.plist +src/hid/ObjFWHID.oc src/libobjfw.* src/objfw-defs.h src/runtime/Info.plist src/runtime/libobjfwrt.* src/test/libobjfwtest.a @@ -41,10 +41,12 @@ tests/DerivedData tests/EBOOT.PBP tests/Info.plist tests/PARAM.SFO tests/big_dictionary_msgpack_gz.m +tests/boot.dol +tests/gamecontroller/boot.dol tests/gamecontroller/gamecontroller_tests tests/gamecontroller/gamecontroller_tests.3dsx tests/gamecontroller/gamecontroller_tests.arm9 tests/gamecontroller/gamecontroller_tests.nds tests/iOS.xcodeproj/*.pbxuser Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -170,11 +170,11 @@ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags" CPPFLAGS="$CPPFLAGS -DGEKKO -I$DEVKITPRO/libogc/include" OBJFW_CPPFLAGS="$OBJFW_CPPFLAGS -DGEKKO -I\$DEVKITPRO/libogc/include" LDFLAGS="$LDFLAGS -mrvl -mcpu=750 -meabi -mhard-float" LIBS="$LIBS -L$DEVKITPRO/libogc/lib/wii -lfat -logc" - TESTS_LIBS="$TESTS_LIBS -lwiiuse -lbte" + HID_LIBS="$HID_LIBS -lwiiuse -lbte" enable_shared="no" enable_threads="no" # TODO with_tls="no" AC_DEFINE(OF_WII, 1, [Whether we are compiling for Wii]) @@ -436,11 +436,12 @@ TESTS_LIBS="-framework ObjFW \${RUNTIME_FRAMEWORK_LIBS} $TESTS_LIBS" TESTS_LIBS="-framework ObjFWHID $TESTS_LIBS" TESTS_LIBS="-F../src -F../src/runtime -F../src/hid $TESTS_LIBS" ], [ TESTS_LIBS="-L../src/runtime \${RUNTIME_LIBS} $TESTS_LIBS" - TESTS_LIBS="-L../src/hid -lobjfwhid -L../src -lobjfw $TESTS_LIBS" + TESTS_LIBS="-L../src -lobjfw $TESTS_LIBS" + TESTS_LIBS="-L../src/hid -lobjfwhid $HID_LIBS $TESTS_LIBS" ]) AC_ARG_ENABLE(static, AS_HELP_STRING([--enable-static], [build static library])) AS_IF([test x"$enable_shared" = x"no"], [ enable_static="yes" @@ -2382,17 +2383,19 @@ AC_SUBST(DEP_ASFLAGS, '${DEP_OBJCFLAGS}') AC_SUBST(OBJFW_CPPFLAGS) AC_SUBST(OBJFW_OBJCFLAGS) +AC_SUBST(HID_LIBS) AC_SUBST(TESTS_LIBS) AC_CONFIG_FILES([ buildsys.mk extra.mk src/Info.plist src/hid/Info.plist + src/hid/ObjFWHID.oc tests/Info.plist utils/objfw-config ]) AC_CONFIG_HEADERS([config.h src/objfw-defs.h]) AC_OUTPUT Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -43,10 +43,11 @@ ENCODINGS_SRCS = @ENCODINGS_SRCS@ EXCEPTIONS_A = @EXCEPTIONS_A@ EXCEPTIONS_LIB_A = @EXCEPTIONS_LIB_A@ FORWARDING_A = @FORWARDING_A@ FORWARDING_LIB_A = @FORWARDING_LIB_A@ +HID_LIBS = @HID_LIBS@ LIBBASES_M = @LIBBASES_M@ LIBOBJFWHID_DEP = @LIBOBJFWHID_DEP@ LIBOBJFWHID_DEP_LVL2 = @LIBOBJFWHID_DEP_LVL2@ LIBOBJFWRT_DEP = @LIBOBJFWRT_DEP@ LIBOBJFWRT_DEP_LVL2 = @LIBOBJFWRT_DEP_LVL2@ Index: src/hid/OFEvdevGameController.h ================================================================== --- src/hid/OFEvdevGameController.h +++ src/hid/OFEvdevGameController.h @@ -25,11 +25,12 @@ { OFString *_path; int _fd; uint16_t _vendorID, _productID; OFString *_name; - OFMutableSet *_buttons, *_pressedButtons; + OFMutableSet OF_GENERIC(OFGameControllerButton) *_buttons; + OFMutableSet OF_GENERIC(OFGameControllerButton) *_pressedButtons; bool _hasLeftAnalogStick, _hasRightAnalogStick; bool _hasLeftTriggerPressure, _hasRightTriggerPressure; unsigned int _leftTriggerPressureBit, _rightTriggerPressureBit; OFPoint _leftAnalogStickPosition, _rightAnalogStickPosition; float _leftTriggerPressure, _rightTriggerPressure; Index: src/hid/OFEvdevGameController.m ================================================================== --- src/hid/OFEvdevGameController.m +++ src/hid/OFEvdevGameController.m @@ -239,15 +239,10 @@ objc_autoreleasePoolPop(pool); return controllers; } -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - - (instancetype)of_initWithPath: (OFString *)path { self = [super init]; @try { Index: src/hid/OFGameController.h ================================================================== --- src/hid/OFGameController.h +++ src/hid/OFGameController.h @@ -71,11 +71,11 @@ * * @ref OFGameControllerCPadDownButton * * @ref OFGameControllerCPadLeftButton * * @ref OFGameControllerCPadRightButton * * @ref OFGameControllerSLButton * * @ref OFGameControllerSRButton - * * @ref OFGameControllerModeButton + * * @ref OFGameControllerAssistantButton */ typedef OFConstantString *OFGameControllerButton; #ifdef __cplusplus extern "C" { @@ -229,15 +229,10 @@ /** * @brief The SR button on a game controller. */ extern const OFGameControllerButton OFGameControllerSRButton; -/** - * @brief The Mode button on a game controller. - */ -extern const OFGameControllerButton OFGameControllerModeButton; - /** * @brief The Assistant button on a game controller. */ extern const OFGameControllerButton OFGameControllerAssistantButton; #ifdef __cplusplus Index: src/hid/OFGameController.m ================================================================== --- src/hid/OFGameController.m +++ src/hid/OFGameController.m @@ -28,10 +28,13 @@ # include "OFEvdevGameController.h" #endif #ifdef OF_WINDOWS # include "OFXInputGameController.h" #endif +#ifdef OF_WII +# include "OFWiiGameController.h" +#endif #ifdef OF_NINTENDO_DS # include "OFNintendoDSGameController.h" #endif #ifdef OF_NINTENDO_3DS # include "OFNintendo3DSGameController.h" @@ -69,11 +72,10 @@ const OFGameControllerButton OFGameControllerCPadDownButton = @"C-Pad Down"; const OFGameControllerButton OFGameControllerCPadLeftButton = @"C-Pad Left"; const OFGameControllerButton OFGameControllerCPadRightButton = @"C-Pad Right"; const OFGameControllerButton OFGameControllerSLButton = @"SL"; const OFGameControllerButton OFGameControllerSRButton = @"SR"; -const OFGameControllerButton OFGameControllerModeButton = @"Mode"; const OFGameControllerButton OFGameControllerAssistantButton = @"Assistant"; @implementation OFGameController @dynamic name, buttons, pressedButtons, hasLeftAnalogStick; @dynamic leftAnalogStickPosition, hasRightAnalogStick, rightAnalogStickPosition; @@ -82,10 +84,12 @@ { #if defined(OF_LINUX) && defined(OF_HAVE_FILES) return [OFEvdevGameController controllers]; #elif defined(OF_WINDOWS) return [OFXInputGameController controllers]; +#elif defined(OF_WII) + return [OFWiiGameController controllers]; #elif defined(OF_NINTENDO_DS) return [OFNintendoDSGameController controllers]; #elif defined(OF_NINTENDO_3DS) return [OFNintendo3DSGameController controllers]; #else @@ -146,11 +150,14 @@ # include "OFEvdevGameController.m" #endif #ifdef OF_WINDOWS # include "OFXInputGameController.m" #endif +#ifdef OF_WII +# include "OFWiiGameController.m" +#endif #ifdef OF_NINTENDO_DS # include "OFNintendoDSGameController.m" #endif #ifdef OF_NINTENDO_3DS # include "OFNintendo3DSGameController.m" #endif Index: src/hid/OFNintendo3DSGameController.h ================================================================== --- src/hid/OFNintendo3DSGameController.h +++ src/hid/OFNintendo3DSGameController.h @@ -21,11 +21,11 @@ OF_ASSUME_NONNULL_BEGIN @interface OFNintendo3DSGameController: OFGameController { - OFMutableSet *_pressedButtons; + OFMutableSet OF_GENERIC(OFGameControllerButton) *_pressedButtons; OFPoint _leftAnalogStickPosition; } @end OF_ASSUME_NONNULL_END Index: src/hid/OFNintendo3DSGameController.m ================================================================== --- src/hid/OFNintendo3DSGameController.m +++ src/hid/OFNintendo3DSGameController.m @@ -29,31 +29,29 @@ #include <3ds.h> #undef id static OFArray OF_GENERIC(OFGameController *) *controllers; -static void -initControllers(void) +@implementation OFNintendo3DSGameController +@synthesize leftAnalogStickPosition = _leftAnalogStickPosition; + ++ (void)initialize { - void *pool = objc_autoreleasePoolPush(); + void *pool; + + if (self != [OFNintendo3DSGameController class]) + return; + pool = objc_autoreleasePoolPush(); controllers = [[OFArray alloc] initWithObject: [[[OFNintendo3DSGameController alloc] init] autorelease]]; - objc_autoreleasePoolPop(pool); } -@implementation OFNintendo3DSGameController -@synthesize leftAnalogStickPosition = _leftAnalogStickPosition; - + (OFArray OF_GENERIC(OFGameController *) *)controllers { - static OFOnceControl onceControl = OFOnceControlInitValue; - - OFOnce(&onceControl, initControllers); - - return [[controllers retain] autorelease]; + return controllers; } - (instancetype)init { self = [super init]; Index: src/hid/OFNintendoDSGameController.h ================================================================== --- src/hid/OFNintendoDSGameController.h +++ src/hid/OFNintendoDSGameController.h @@ -21,10 +21,10 @@ OF_ASSUME_NONNULL_BEGIN @interface OFNintendoDSGameController: OFGameController { - OFMutableSet *_pressedButtons; + OFMutableSet OF_GENERIC(OFGameControllerButton) *_pressedButtons; } @end OF_ASSUME_NONNULL_END Index: src/hid/OFNintendoDSGameController.m ================================================================== --- src/hid/OFNintendoDSGameController.m +++ src/hid/OFNintendoDSGameController.m @@ -29,29 +29,27 @@ #include #undef asm static OFArray OF_GENERIC(OFGameController *) *controllers; -static void -initControllers(void) +@implementation OFNintendoDSGameController ++ (void)initialize { - void *pool = objc_autoreleasePoolPush(); + void *pool; + + if (self != [OFNintendoDSGameController class]) + return; + pool = objc_autoreleasePoolPush(); controllers = [[OFArray alloc] initWithObject: [[[OFNintendoDSGameController alloc] init] autorelease]]; - objc_autoreleasePoolPop(pool); } -@implementation OFNintendoDSGameController + (OFArray OF_GENERIC(OFGameController *) *)controllers { - static OFOnceControl onceControl = OFOnceControlInitValue; - - OFOnce(&onceControl, initControllers); - - return [[controllers retain] autorelease]; + return controllers; } - (instancetype)init { self = [super init]; ADDED src/hid/OFWiiGameController.h Index: src/hid/OFWiiGameController.h ================================================================== --- /dev/null +++ src/hid/OFWiiGameController.h @@ -0,0 +1,36 @@ +/* + * 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 "OFGameController.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OFWiiGameController: OFGameController +{ + int32_t _index; + uint32_t _type; + OFMutableSet OF_GENERIC(OFGameControllerButton) *_pressedButtons; + OFPoint _leftAnalogStickPosition; +} + +- (instancetype)of_initWithIndex: (int32_t)index + type: (uint32_t)type OF_METHOD_FAMILY(init); +@end + +OF_ASSUME_NONNULL_END ADDED src/hid/OFWiiGameController.m Index: src/hid/OFWiiGameController.m ================================================================== --- /dev/null +++ src/hid/OFWiiGameController.m @@ -0,0 +1,217 @@ +/* + * 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 "OFWiiGameController.h" +#import "OFMutableSet.h" + +#import "OFInitializationFailedException.h" +#import "OFNotImplementedException.h" +#import "OFReadFailedException.h" + +#define asm __asm__ +#include +#undef asm + +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 OFWiiGameController ++ (void)initialize +{ + if (self != [OFWiiGameController class]) + return; + + if (WPAD_Init() != WPAD_ERR_NONE) + @throw [OFInitializationFailedException + exceptionWithClass: self]; +} + ++ (OFArray OF_GENERIC(OFGameController *) *)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)) + [controllers addObject: [[[OFWiiGameController alloc] + of_initWithIndex: i + type: type] autorelease]]; + } + + [controllers makeImmutable]; + + objc_autoreleasePoolPop(pool); + + return controllers; +} + +- (instancetype)of_initWithIndex: (int32_t)index type: (uint32_t)type +{ + self = [super init]; + + @try { + _index = index; + _type = type; + + _pressedButtons = [[OFMutableSet alloc] initWithCapacity: 13]; + + [self retrieveState]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_pressedButtons release]; + + [super dealloc]; +} + +- (void)retrieveState +{ + WPADData *data; + + if (WPAD_ReadPending(_index, NULL) < WPAD_ERR_NONE) + @throw [OFReadFailedException + exceptionWithObject: self + requestedLength: sizeof(WPADData) + errNo: 0]; + + data = WPAD_Data(_index); + + [_pressedButtons removeAllObjects]; + + if (data->btns_h & WPAD_BUTTON_A) + [_pressedButtons addObject: OFGameControllerEastButton]; + if (data->btns_h & WPAD_BUTTON_B) + [_pressedButtons addObject: OFGameControllerRightTriggerButton]; + if (data->btns_h & WPAD_BUTTON_1) + [_pressedButtons addObject: OFGameControllerWestButton]; + if (data->btns_h & WPAD_BUTTON_2) + [_pressedButtons addObject: OFGameControllerSouthButton]; + if (data->btns_h & WPAD_BUTTON_UP) + [_pressedButtons addObject: OFGameControllerDPadUpButton]; + if (data->btns_h & WPAD_BUTTON_DOWN) + [_pressedButtons addObject: OFGameControllerDPadDownButton]; + if (data->btns_h & WPAD_BUTTON_LEFT) + [_pressedButtons addObject: OFGameControllerDPadLeftButton]; + if (data->btns_h & WPAD_BUTTON_RIGHT) + [_pressedButtons addObject: OFGameControllerDPadRightButton]; + if (data->btns_h & WPAD_BUTTON_PLUS) + [_pressedButtons addObject: OFGameControllerStartButton]; + if (data->btns_h & WPAD_BUTTON_MINUS) + [_pressedButtons addObject: OFGameControllerSelectButton]; + if (data->btns_h & WPAD_BUTTON_HOME) + [_pressedButtons addObject: OFGameControllerHomeButton]; + + if (_type == WPAD_EXP_NUNCHUK) { + joystick_t *js; + + if (data->btns_h & WPAD_NUNCHUK_BUTTON_C) + [_pressedButtons addObject: + OFGameControllerLeftShoulderButton]; + if (data->btns_h & WPAD_NUNCHUK_BUTTON_Z) + [_pressedButtons addObject: + OFGameControllerLeftTriggerButton]; + + js = &data->exp.nunchuk.js; + _leftAnalogStickPosition = OFMakePoint( + scale(js->pos.x, js->min.x, js->max.x, js->center.x), + -scale(js->pos.y, js->min.y, js->max.y, js->center.y)); + } +} + +- (OFString *)name +{ + if (_type == WPAD_EXP_NUNCHUK) + return @"Wiimote with Nunchuk"; + + return @"Wiimote"; +} + +- (OFSet OF_GENERIC(OFGameControllerButton) *)buttons +{ + OFMutableSet *buttons = [OFMutableSet setWithCapacity: 13]; + + [buttons addObject: OFGameControllerSouthButton]; + [buttons addObject: OFGameControllerRightTriggerButton]; + [buttons addObject: OFGameControllerWestButton]; + [buttons addObject: OFGameControllerEastButton]; + [buttons addObject: OFGameControllerDPadUpButton]; + [buttons addObject: OFGameControllerDPadDownButton]; + [buttons addObject: OFGameControllerDPadLeftButton]; + [buttons addObject: OFGameControllerDPadRightButton]; + [buttons addObject: OFGameControllerStartButton]; + [buttons addObject: OFGameControllerSelectButton]; + [buttons addObject: OFGameControllerHomeButton]; + + if (_type == WPAD_EXP_NUNCHUK) { + [buttons addObject: OFGameControllerLeftShoulderButton]; + [buttons addObject: OFGameControllerLeftTriggerButton]; + } + + [buttons makeImmutable]; + + return buttons; +} + +- (OFSet OF_GENERIC(OFGameControllerButton) *)pressedButtons +{ + return [[_pressedButtons copy] autorelease]; +} + +- (bool)hasLeftAnalogStick +{ + return (_type == WPAD_EXP_NUNCHUK); +} + +- (bool)hasRightAnalogStick +{ + return false; +} + +- (OFPoint)leftAnalogStickPosition +{ + if (_type != WPAD_EXP_NUNCHUK) + @throw [OFNotImplementedException exceptionWithSelector: _cmd + object: self]; + + return _leftAnalogStickPosition; +} +@end Index: src/hid/OFXInputGameController.h ================================================================== --- src/hid/OFXInputGameController.h +++ src/hid/OFXInputGameController.h @@ -23,11 +23,11 @@ @interface OFXInputGameController: OFGameController { DWORD _index; OFNumber *_Nullable _vendorID, *_Nullable productID; - OFMutableSet *_pressedButtons; + OFMutableSet OF_GENERIC(OFGameControllerButton) *_pressedButtons; OFPoint _leftAnalogStickPosition, _rightAnalogStickPosition; float _leftTriggerPressure, _rightTriggerPressure; } - (instancetype)of_initWithIndex: (DWORD)index OF_METHOD_FAMILY(init); Index: src/hid/OFXInputGameController.m ================================================================== --- src/hid/OFXInputGameController.m +++ src/hid/OFXInputGameController.m @@ -103,15 +103,10 @@ [controllers makeImmutable]; return controllers; } -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - - (instancetype)of_initWithIndex: (DWORD)index { self = [super init]; @try { DELETED src/hid/ObjFWHID.oc Index: src/hid/ObjFWHID.oc ================================================================== --- src/hid/ObjFWHID.oc +++ /dev/null @@ -1,4 +0,0 @@ -package_format 1 -LIBS="-lobjfwhid $LIBS" -FRAMEWORK_LIBS="-framework ObjFWHID $FRAMEWORK_LIBS" -STATIC_LIBS="${libdir}/libobjfwhid.a $STATIC_LIBS" ADDED src/hid/ObjFWHID.oc.in Index: src/hid/ObjFWHID.oc.in ================================================================== --- /dev/null +++ src/hid/ObjFWHID.oc.in @@ -0,0 +1,4 @@ +package_format 1 +LIBS="-lobjfwhid @HID_LIBS@ $LIBS" +FRAMEWORK_LIBS="-framework ObjFWHID @HID_LIBS@ $FRAMEWORK_LIBS" +STATIC_LIBS="${libdir}/libobjfwhid.a @HID_LIBS@ $STATIC_LIBS" Index: src/test/OTAppDelegate.m ================================================================== --- src/test/OTAppDelegate.m +++ src/test/OTAppDelegate.m @@ -39,11 +39,10 @@ #endif #ifdef OF_WII # define asm __asm__ # include -# include # undef asm #endif #ifdef OF_NINTENDO_DS # define asm __asm__ @@ -122,11 +121,10 @@ #elif defined(OF_WII) GXRModeObj *mode; void *nextFB; VIDEO_Init(); - WPAD_Init(); mode = VIDEO_GetPreferredMode(NULL); nextFB = MEM_K0_TO_K1(SYS_AllocateFramebuffer(mode)); VIDEO_Configure(mode); VIDEO_SetNextFramebuffer(nextFB); @@ -311,36 +309,28 @@ break; } if (status == StatusFailed) { -#if defined(OF_WII) - [OFStdOut setForegroundColor: [OFColor silver]]; - [OFStdOut writeLine: @"Press A to continue"]; - - for (;;) { - WPAD_ScanPads(); - - if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A) - break; - - VIDEO_WaitVSync(); - } -#elif defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) +#if defined(OF_WII) || defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) [OFStdOut setForegroundColor: [OFColor silver]]; [OFStdOut writeLine: @"Press A to continue"]; for (;;) { void *pool = objc_autoreleasePoolPush(); OFGameController *controller = [[OFGameController controllers] objectAtIndex: 0]; + + [controller retrieveState]; if ([controller.pressedButtons containsObject: OFGameControllerEastButton]) break; -# if defined(OF_NINTENDO_DS) +# if defined(OF_WII) + VIDEO_WaitVSync(); +# elif defined(OF_NINTENDO_DS) swiWaitForVBlank(); # elif defined(OF_NINTENDO_3DS) gspWaitForVBlank(); # endif objc_autoreleasePoolPop(pool); @@ -596,44 +586,42 @@ [OFStdOut setForegroundColor: [OFColor purple]]; [OFStdOut writeFormat: @" test%s skipped\n", (numSkipped != 1 ? "s" : "")]; [OFStdOut reset]; -#if defined(OF_WII) - [OFStdOut setForegroundColor: [OFColor silver]]; - [OFStdOut writeLine: @"Press home button to exit"]; - - for (;;) { - WPAD_ScanPads(); - - if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) - break; - - VIDEO_WaitVSync(); - } -#elif defined(OF_NINTENDO_DS) - [OFStdOut setForegroundColor: [OFColor silver]]; - [OFStdOut writeLine: @"Press start button to exit"]; - - for (;;) { - swiWaitForVBlank(); - scanKeys(); - - if (keysDown() & KEY_START) - break; - } -#elif defined(OF_NINTENDO_3DS) - [OFStdOut setForegroundColor: [OFColor silver]]; - [OFStdOut writeLine: @"Press start button to exit"]; - - for (;;) { - hidScanInput(); - - if (hidKeysDown() & KEY_START) - break; - - gspWaitForVBlank(); +#if defined(OF_WII) || defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) + [OFStdOut setForegroundColor: [OFColor silver]]; +# ifdef OF_WII + [OFStdOut writeLine: @"Press Home button to exit"]; +# else + [OFStdOut writeLine: @"Press Start button to exit"]; +# endif + + for (;;) { + void *pool = objc_autoreleasePoolPush(); + OFGameController *controller = + [[OFGameController controllers] objectAtIndex: 0]; + + [controller retrieveState]; + +# ifdef OF_WII + if ([controller.pressedButtons containsObject: + OFGameControllerHomeButton]) +# else + if ([controller.pressedButtons containsObject: + OFGameControllerStartButton]) +# endif + break; + +# if defined(OF_WII) + VIDEO_WaitVSync(); +# elif defined(OF_NINTENDO_DS) + swiWaitForVBlank(); +# elif defined(OF_NINTENDO_3DS) + gspWaitForVBlank(); +# endif + objc_autoreleasePoolPop(pool); } #elif defined(OF_NINTENDO_SWITCH) while (appletMainLoop()) updateConsole(true); Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -6,10 +6,11 @@ ${OBJC_SYNC} \ terminal CLEAN = EBOOT.PBP \ boot.dol \ + ${PROG_NOINST}.3dsx \ ${PROG_NOINST}.arm9 \ ${PROG_NOINST}.nds \ ${PROG_NOINST}.nro \ ${PROG_NOINST}.rpx \ big_dictionary_msgpack_gz.m \ Index: tests/gamecontroller/GameControllerTests.m ================================================================== --- tests/gamecontroller/GameControllerTests.m +++ tests/gamecontroller/GameControllerTests.m @@ -25,10 +25,16 @@ #import "OFGameController.h" #import "OFNumber.h" #import "OFSet.h" #import "OFStdIOStream.h" #import "OFThread.h" + +#ifdef OF_WII +# define asm __asm__ +# include +# undef asm +#endif #ifdef OF_NINTENDO_DS # define asm __asm__ # include # undef asm @@ -45,11 +51,11 @@ #ifndef BUTTONS_PER_LINE # define BUTTONS_PER_LINE 5 #endif -#if defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) +#if defined(OF_WII) || defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) # define red maroon # define yellow olive # define gray silver #endif @@ -61,11 +67,30 @@ @implementation GameControllerTests - (void)applicationDidFinishLaunching: (OFNotification *)notification { OFArray *controllers; -#if defined(OF_NINTENDO_DS) +#if defined(OF_WII) + GXRModeObj *mode; + void *nextFB; + + VIDEO_Init(); + + mode = VIDEO_GetPreferredMode(NULL); + nextFB = MEM_K0_TO_K1(SYS_AllocateFramebuffer(mode)); + VIDEO_Configure(mode); + VIDEO_SetNextFramebuffer(nextFB); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + + VIDEO_WaitVSync(); + if (mode->viTVMode & VI_NON_INTERLACE) + VIDEO_WaitVSync(); + + CON_InitEx(mode, 2, 2, mode->fbWidth - 4, mode->xfbHeight - 4); + VIDEO_ClearFrameBuffer(mode, nextFB, COLOR_BLACK); +#elif defined(OF_NINTENDO_DS) consoleDemoInit(); #elif defined(OF_NINTENDO_3DS) gfxInitDefault(); atexit(gfxExit); @@ -76,10 +101,15 @@ [OFStdOut clear]; for (;;) { void *pool = objc_autoreleasePoolPush(); + +#ifdef OF_WII + /* Wii needs some time before controllers are found. */ + controllers = [OFGameController controllers]; +#endif [OFStdOut setCursorPosition: OFMakePoint(0, 0)]; for (OFGameController *controller in controllers) { OFArray OF_GENERIC(OFGameControllerButton) *buttons = Index: tests/gamecontroller/Makefile ================================================================== --- tests/gamecontroller/Makefile +++ tests/gamecontroller/Makefile @@ -1,7 +1,12 @@ include ../../extra.mk +CLEAN = boot.dol \ + ${PROG_NOINST}.3dsx \ + ${PROG_NOINST}.arm9 \ + ${PROG_NOINST}.ndsd \ + PROG_NOINST = gamecontroller_tests${PROG_SUFFIX} SRCS = GameControllerTests.m include ../../buildsys.mk @@ -88,10 +93,13 @@ rm -f libobjfwhid.so.${OBJFWHID_LIB_MAJOR_MINOR}; \ rm -f objfwhid${OBJFWHID_LIB_MAJOR}.dll; \ rm -f libobjfwhid.${OBJFWHID_LIB_MAJOR}.dylib; \ exit $$EXIT +boot.dol: ${PROG_NOINST} + elf2dol ${PROG_NOINST} $@ + ${PROG_NOINST}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2} \ ${LIBOBJFWHID_DEP_LVL2} ${PROG_NOINST}.3dsx: ${PROG_NOINST} 3dsxtool $< $@ @@ -106,10 +114,10 @@ -I../../src/exceptions \ -I../../src/hid \ -I../../src/runtime \ -I../.. \ -DOBJFWHID_LOCAL_INCLUDES -LIBS := -L../../src/hid -lobjfwhid \ +LIBS := -L../../src/hid -lobjfwhid ${HID_LIBS} \ -L../../src -lobjfw \ -L../../src/runtime ${RUNTIME_LIBS} \ ${LIBS} LD = ${OBJC}