ADDED .github/workflows/CXXTest.mm Index: .github/workflows/CXXTest.mm ================================================================== --- /dev/null +++ .github/workflows/CXXTest.mm @@ -0,0 +1,31 @@ +#import + +#include + +@interface CXXTest: OFObject +@end + +OF_APPLICATION_DELEGATE(CXXTest) + +@implementation CXXTest +- (void)applicationDidFinishLaunching: (OFNotification *)notification +{ + std::string output; + + try { + @try { + throw @"Hello "; + } @catch (OFString *string) { + output += string.UTF8String; + } + + throw std::string("C++"); + } catch (std::string &string) { + output += "C++"; + } + + OFLog(@"%s", output.c_str()); + + [OFApplication terminate]; +} +@end ADDED .github/workflows/fedora-mingw-gcc.yml Index: .github/workflows/fedora-mingw-gcc.yml ================================================================== --- /dev/null +++ .github/workflows/fedora-mingw-gcc.yml @@ -0,0 +1,31 @@ +name: fedora-mingw-gcc +on: [push, pull_request] +jobs: + tests: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - prefix: mingw32 + triple: i686-w64-mingw32 + - prefix: mingw64 + triple: x86_64-w64-mingw32 + - prefix: ucrt64 + triple: x86_64-w64-mingw32ucrt + container: fedora + steps: + - name: Install dependencies + run: | + sudo dnf upgrade --refresh -y + sudo dnf install -y ${{matrix.prefix}}-gcc-objc ${{matrix.prefix}}-openssl autoconf automake make wine + - uses: actions/checkout@v4 + - name: autogen.sh + run: ./autogen.sh + - name: configure + run: ./configure --host=${{matrix.triple}} + - name: make + run: make -j$(nproc) + - name: make check + run: WINEPATH=/usr/${{matrix.triple}}/sys-root/mingw/bin WINEPREFIX=/tmp/wineprefix make check + - name: make install + run: sudo make install Index: .github/workflows/macos-14.yml ================================================================== --- .github/workflows/macos-14.yml +++ .github/workflows/macos-14.yml @@ -27,5 +27,9 @@ run: make -j$(sysctl -n hw.logicalcpu) - name: make check run: make check - name: make install run: sudo make install + - name: C++ test + run: | + objfw-compile -o cxxtest .github/workflows/CXXTest.mm + ./cxxtest Index: .github/workflows/ubuntu-latest-32bit.yml ================================================================== --- .github/workflows/ubuntu-latest-32bit.yml +++ .github/workflows/ubuntu-latest-32bit.yml @@ -21,11 +21,11 @@ - --without-tls --disable-compiler-tls --disable-threads steps: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install gcc-multilib + sudo apt-get install g++-multilib - uses: actions/checkout@v4 - name: autogen.sh run: ./autogen.sh - name: configure run: ./configure OBJC="clang -m32" ${{ matrix.configure_flags }} @@ -33,5 +33,9 @@ run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install + - name: C++ test + run: | + objfw-compile -o cxxtest .github/workflows/CXXTest.mm + ./cxxtest Index: .github/workflows/ubuntu-latest.yml ================================================================== --- .github/workflows/ubuntu-latest.yml +++ .github/workflows/ubuntu-latest.yml @@ -37,5 +37,9 @@ run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install + - name: C++ test + run: | + objfw-compile -o cxxtest .github/workflows/CXXTest.mm + ./cxxtest Index: src/OFApplication.h ================================================================== --- src/OFApplication.h +++ src/OFApplication.h @@ -91,21 +91,27 @@ \ WINAPI int \ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, \ LPSTR lpCmdLine, int nShowCmd) \ { \ - extern void __getmainargs(int *, char ***, char ***, \ - int, int *); \ - extern int _CRT_glob; \ int argc = 0, si = 0; \ char **argv = NULL, **envp = NULL; \ \ __getmainargs(&argc, &argv, &envp, _CRT_glob, &si); \ \ return OFApplicationMain(&argc, &argv, \ (class_ *)[[class_ alloc] init]); \ } +# ifdef __cplusplus +extern "C" { +# endif +extern void __getmainargs(int *_Nonnull, char *_Nonnull *_Nullable *_Nullable, + char *_Nonnull *_Nullable *_Nullable, int, int *_Nonnull); +extern int _CRT_glob; +# ifdef __cplusplus +} +# endif #endif #ifdef OF_HAVE_PLEDGE # define OF_HAVE_SANDBOX #endif Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -156,11 +156,13 @@ #endif #import "OFAllocFailedException.h" #import "OFAlreadyOpenException.h" #import "OFException.h" -#import "OFChangeCurrentDirectoryFailedException.h" +#ifdef OF_HAVE_FILES +# import "OFChangeCurrentDirectoryFailedException.h" +#endif #import "OFChecksumMismatchException.h" #import "OFCopyItemFailedException.h" #import "OFCreateDirectoryFailedException.h" #import "OFCreateSymbolicLinkFailedException.h" #import "OFEnumerationMutationException.h" Index: src/hid/OHDualSenseGamepad+Private.h ================================================================== --- src/hid/OHDualSenseGamepad+Private.h +++ src/hid/OHDualSenseGamepad+Private.h @@ -23,11 +23,13 @@ # import "OHEvdevGameController.h" #endif OF_ASSUME_NONNULL_BEGIN +@interface OHDualSenseGamepad () #if defined(OF_LINUX) && defined(OF_HAVE_FILES) -@interface OHDualSenseGamepad () -@end + #endif +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end OF_ASSUME_NONNULL_END Index: src/hid/OHDualSenseGamepad.h ================================================================== --- src/hid/OHDualSenseGamepad.h +++ src/hid/OHDualSenseGamepad.h @@ -26,12 +26,15 @@ * * @brief A Sony DualSense gamepad. */ @interface OHDualSenseGamepad: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHDualSenseGamepad.m ================================================================== --- src/hid/OHDualSenseGamepad.m +++ src/hid/OHDualSenseGamepad.m @@ -24,10 +24,13 @@ #import "OFDictionary.h" #import "OHEmulatedGameControllerTriggerButton.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include # import "evdev_compat.h" #endif @@ -41,10 +44,15 @@ @implementation OHDualSenseGamepad @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init { + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init +{ self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *buttons = @@ -53,77 +61,69 @@ OFMutableDictionary *directionalPads; OHGameControllerAxis *axis, *xAxis, *yAxis; OHGameControllerDirectionalPad *directionalPad; for (size_t i = 0; i < numButtons; i++) { - button = [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: false] autorelease]; + button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } - axis = [[[OHGameControllerAxis alloc] - initWithName: @"L2" - analog: true] autorelease]; - button = [[[OHEmulatedGameControllerTriggerButton alloc] - initWithName: @"L2" - axis: axis] autorelease]; + axis = [OHGameControllerAxis oh_elementWithName: @"L2" + analog: true]; + button = [OHEmulatedGameControllerTriggerButton + oh_buttonWithName: @"L2" + axis: axis]; [buttons setObject: button forKey: @"L2"]; - axis = [[[OHGameControllerAxis alloc] - initWithName: @"R2" - analog: true] autorelease]; - button = [[[OHEmulatedGameControllerTriggerButton alloc] - initWithName: @"R2" - axis: axis] autorelease]; + axis = [OHGameControllerAxis oh_elementWithName: @"R2" + analog: true]; + button = [OHEmulatedGameControllerTriggerButton + oh_buttonWithName: @"R2" + axis: axis]; [buttons setObject: button forKey: @"R2"]; [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Left Stick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Left Stick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Left Stick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RX" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RY" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Right Stick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"RX" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"RY" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Right Stick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Right Stick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"D-Pad X" - analog: false] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"D-Pad Y" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - xAxis: xAxis - yAxis: yAxis - analog: false] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad X" + analog: false]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad Y" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + xAxis: xAxis + yAxis: yAxis + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; @@ -289,16 +289,14 @@ case ABS_HAT0X: return [[_directionalPads objectForKey: @"D-Pad"] xAxis]; case ABS_HAT0Y: return [[_directionalPads objectForKey: @"D-Pad"] yAxis]; case ABS_Z: - return ((OHEmulatedGameControllerTriggerButton *) - [_buttons objectForKey: @"L2"]).axis; + return [[_buttons objectForKey: @"L2"] oh_axis]; case ABS_RZ: - return ((OHEmulatedGameControllerTriggerButton *) - [_buttons objectForKey: @"R2"]).axis; + return [[_buttons objectForKey: @"R2"] oh_axis]; default: return nil; } } #endif @end Index: src/hid/OHDualShock4Gamepad+Private.h ================================================================== --- src/hid/OHDualShock4Gamepad+Private.h +++ src/hid/OHDualShock4Gamepad+Private.h @@ -23,11 +23,13 @@ # import "OHEvdevGameController.h" #endif OF_ASSUME_NONNULL_BEGIN +@interface OHDualShock4Gamepad () #if defined(OF_LINUX) && defined(OF_HAVE_FILES) -@interface OHDualShock4Gamepad () -@end + #endif +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end OF_ASSUME_NONNULL_END Index: src/hid/OHDualShock4Gamepad.h ================================================================== --- src/hid/OHDualShock4Gamepad.h +++ src/hid/OHDualShock4Gamepad.h @@ -26,12 +26,15 @@ * * @brief A Sony DualShock 4 gamepad. */ @interface OHDualShock4Gamepad: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHDualShock4Gamepad.m ================================================================== --- src/hid/OHDualShock4Gamepad.m +++ src/hid/OHDualShock4Gamepad.m @@ -24,10 +24,13 @@ #import "OFDictionary.h" #import "OHEmulatedGameControllerTriggerButton.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include # import "evdev_compat.h" #endif @@ -41,10 +44,15 @@ @implementation OHDualShock4Gamepad @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init { + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init +{ self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *buttons = @@ -53,77 +61,69 @@ OFMutableDictionary *directionalPads; OHGameControllerAxis *axis, *xAxis, *yAxis; OHGameControllerDirectionalPad *directionalPad; for (size_t i = 0; i < numButtons; i++) { - button = [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: false] autorelease]; + button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } - axis = [[[OHGameControllerAxis alloc] - initWithName: @"L2" - analog: true] autorelease]; - button = [[[OHEmulatedGameControllerTriggerButton alloc] - initWithName: @"L2" - axis: axis] autorelease]; + axis = [OHGameControllerAxis oh_elementWithName: @"L2" + analog: true]; + button = [OHEmulatedGameControllerTriggerButton + oh_buttonWithName: @"L2" + axis: axis]; [buttons setObject: button forKey: @"L2"]; - axis = [[[OHGameControllerAxis alloc] - initWithName: @"R2" - analog: true] autorelease]; - button = [[[OHEmulatedGameControllerTriggerButton alloc] - initWithName: @"R2" - axis: axis] autorelease]; + axis = [OHGameControllerAxis oh_elementWithName: @"R2" + analog: true]; + button = [OHEmulatedGameControllerTriggerButton + oh_buttonWithName: @"R2" + axis: axis]; [buttons setObject: button forKey: @"R2"]; [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Left Stick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Left Stick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Left Stick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RX" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RY" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Right Stick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"RX" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"RY" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Right Stick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Right Stick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"D-Pad X" - analog: false] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"D-Pad Y" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - xAxis: xAxis - yAxis: yAxis - analog: false] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad X" + analog: false]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad Y" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + xAxis: xAxis + yAxis: yAxis + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; @@ -289,16 +289,14 @@ case ABS_HAT0X: return [[_directionalPads objectForKey: @"D-Pad"] xAxis]; case ABS_HAT0Y: return [[_directionalPads objectForKey: @"D-Pad"] yAxis]; case ABS_Z: - return ((OHEmulatedGameControllerTriggerButton *) - [_buttons objectForKey: @"L2"]).axis; + return [[_buttons objectForKey: @"L2"] oh_axis]; case ABS_RZ: - return ((OHEmulatedGameControllerTriggerButton *) - [_buttons objectForKey: @"R2"]).axis; + return [[_buttons objectForKey: @"R2"] oh_axis]; default: return nil; } } #endif @end Index: src/hid/OHEmulatedGameControllerAxis.h ================================================================== --- src/hid/OHEmulatedGameControllerAxis.h +++ src/hid/OHEmulatedGameControllerAxis.h @@ -27,14 +27,14 @@ @interface OHEmulatedGameControllerAxis: OHGameControllerAxis { OHGameControllerButton *_negativeButton, *_positiveButton; } -- (instancetype)initWithName: (OFString *)name - analog: (bool)analog OF_UNAVAILABLE; +- (instancetype)oh_initWithName: (OFString *)name + analog: (bool)analog OF_UNAVAILABLE; - (instancetype) - initWithNegativeButton: (OHGameControllerButton *)negativeButton - positiveButton: (OHGameControllerButton *)positiveButton - OF_DESIGNATED_INITIALIZER; + oh_initWithNegativeButton: (OHGameControllerButton *)negativeButton + positiveButton: (OHGameControllerButton *)positiveButton + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHEmulatedGameControllerAxis.m ================================================================== --- src/hid/OHEmulatedGameControllerAxis.m +++ src/hid/OHEmulatedGameControllerAxis.m @@ -19,19 +19,22 @@ #import "config.h" #import "OHEmulatedGameControllerAxis.h" #import "OHGameControllerButton.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" @implementation OHEmulatedGameControllerAxis -- (instancetype)initWithName: (OFString *)name analog: (bool)analog +- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog { OF_INVALID_INIT_METHOD } -- (instancetype)initWithNegativeButton: (OHGameControllerButton *)negativeButton - positiveButton: (OHGameControllerButton *)positiveButton +- (instancetype) + oh_initWithNegativeButton: (OHGameControllerButton *)negativeButton + positiveButton: (OHGameControllerButton *)positiveButton { void *pool = objc_autoreleasePoolPush(); OFString *name; @try { @@ -41,11 +44,11 @@ } @catch (id e) { [self release]; @throw e; } - self = [super initWithName: name analog: false]; + self = [super oh_initWithName: name analog: false]; objc_autoreleasePoolPop(pool); _negativeButton = [negativeButton retain]; _positiveButton = [positiveButton retain]; Index: src/hid/OHEmulatedGameControllerButton.h ================================================================== --- src/hid/OHEmulatedGameControllerButton.h +++ src/hid/OHEmulatedGameControllerButton.h @@ -28,12 +28,13 @@ { OHGameControllerAxis *_axis; bool _positive; } -- (instancetype)initWithName: (OFString *)name - analog: (bool)analog OF_UNAVAILABLE; -- (instancetype)initWithAxis: (OHGameControllerAxis *)axis - positive: (bool)positive OF_DESIGNATED_INITIALIZER; +- (instancetype)oh_initWithName: (OFString *)name + analog: (bool)analog OF_UNAVAILABLE; +- (instancetype)oh_initWithAxis: (OHGameControllerAxis *)axis + positive: (bool)positive + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHEmulatedGameControllerButton.m ================================================================== --- src/hid/OHEmulatedGameControllerButton.m +++ src/hid/OHEmulatedGameControllerButton.m @@ -19,19 +19,21 @@ #include "config.h" #import "OHEmulatedGameControllerButton.h" #import "OHGameControllerAxis.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" @implementation OHEmulatedGameControllerButton -- (instancetype)initWithName: (OFString *)name analog: (bool)analog +- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog { OF_INVALID_INIT_METHOD } -- (instancetype)initWithAxis: (OHGameControllerAxis *)axis - positive: (bool)positive +- (instancetype)oh_initWithAxis: (OHGameControllerAxis *)axis + positive: (bool)positive { void *pool = objc_autoreleasePoolPush(); OFString *name; @try { @@ -40,11 +42,11 @@ } @catch (id e) { [self release]; @throw e; } - self = [super initWithName: name analog: false]; + self = [super oh_initWithName: name analog: false]; objc_autoreleasePoolPop(pool); _axis = [axis retain]; _positive = positive; Index: src/hid/OHEmulatedGameControllerTriggerButton.h ================================================================== --- src/hid/OHEmulatedGameControllerTriggerButton.h +++ src/hid/OHEmulatedGameControllerTriggerButton.h @@ -27,15 +27,19 @@ @interface OHEmulatedGameControllerTriggerButton: OHGameControllerButton { OHGameControllerAxis *_axis; } -@property (readonly, nonatomic) OHGameControllerAxis *axis; +@property (readonly, nonatomic) OHGameControllerAxis *oh_axis; -- (instancetype)initWithName: (OFString *)name - analog: (bool)analog OF_UNAVAILABLE; -- (instancetype)initWithName: (OFString *)name - axis: (OHGameControllerAxis *)axis - OF_DESIGNATED_INITIALIZER; ++ (instancetype)oh_buttonWithName: (OFString *)name + analog: (bool)analog OF_UNAVAILABLE; ++ (instancetype)oh_buttonWithName: (OFString *)name + axis: (OHGameControllerAxis *)axis; +- (instancetype)oh_initWithName: (OFString *)name + analog: (bool)analog OF_UNAVAILABLE; +- (instancetype)oh_initWithName: (OFString *)name + axis: (OHGameControllerAxis *)axis + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHEmulatedGameControllerTriggerButton.m ================================================================== --- src/hid/OHEmulatedGameControllerTriggerButton.m +++ src/hid/OHEmulatedGameControllerTriggerButton.m @@ -19,23 +19,36 @@ #include "config.h" #import "OHEmulatedGameControllerTriggerButton.h" #import "OHGameControllerAxis.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" @implementation OHEmulatedGameControllerTriggerButton -@synthesize axis = _axis; +@synthesize oh_axis = _axis; + ++ (instancetype)oh_buttonWithName: (OFString *)name analog: (bool)analog +{ + OF_UNRECOGNIZED_SELECTOR +} + ++ (instancetype)oh_buttonWithName: (OFString *)name + axis: (OHGameControllerAxis *)axis +{ + return [[[self alloc] oh_initWithName: name axis: axis] autorelease]; +} -- (instancetype)initWithName: (OFString *)name analog: (bool)analog +- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog { OF_INVALID_INIT_METHOD } -- (instancetype)initWithName: (OFString *)name - axis: (OHGameControllerAxis *)axis +- (instancetype)oh_initWithName: (OFString *)name + axis: (OHGameControllerAxis *)axis { - self = [super initWithName: name analog: true]; + self = [super oh_initWithName: name analog: true]; _axis = [axis retain]; return self; } Index: src/hid/OHEvdevExtendedGamepad.m ================================================================== --- src/hid/OHEvdevExtendedGamepad.m +++ src/hid/OHEvdevExtendedGamepad.m @@ -22,25 +22,26 @@ #import "OHEvdevExtendedGamepad.h" #import "OFDictionary.h" #import "OHEmulatedGameControllerTriggerButton.h" #import "OHEvdevGameController.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" #import "OFInvalidArgumentException.h" @implementation OHEvdevExtendedGamepad -- (instancetype)initWithKeyBits: (unsigned long *)keyBits - evBits: (unsigned long *)evBits - absBits: (unsigned long *)absBits - vendorID: (uint16_t)vendorID - productID: (uint16_t)productID -{ - self = [super initWithKeyBits: keyBits - evBits: evBits - absBits: absBits - vendorID: vendorID - productID: productID]; +- (instancetype)oh_initWithKeyBits: (unsigned long *)keyBits + evBits: (unsigned long *)evBits + absBits: (unsigned long *)absBits + vendorID: (uint16_t)vendorID + productID: (uint16_t)productID +{ + self = [super oh_initWithKeyBits: keyBits + evBits: evBits + absBits: absBits + vendorID: vendorID + productID: productID]; @try { void *pool = objc_autoreleasePoolPush(); if (self.northButton == nil || self.southButton == nil || @@ -143,25 +144,25 @@ - (OHGameControllerButton *)leftTriggerButton { OHGameControllerAxis *axis = [_axes objectForKey: @"Z"]; if (axis != nil) - return [[[OHEmulatedGameControllerTriggerButton alloc] - initWithName: @"LT" - axis: axis] autorelease]; + return [OHEmulatedGameControllerTriggerButton + oh_buttonWithName: @"LT" + axis: axis]; return [_buttons objectForKey: @"LT"]; } - (OHGameControllerButton *)rightTriggerButton { OHGameControllerAxis *axis = [_axes objectForKey: @"RZ"]; if (axis != nil) - return [[[OHEmulatedGameControllerTriggerButton alloc] - initWithName: @"RT" - axis: axis] autorelease]; + return [OHEmulatedGameControllerTriggerButton + oh_buttonWithName: @"RT" + axis: axis]; return [_buttons objectForKey: @"RT"]; } - (OHGameControllerButton *)leftThumbstickButton @@ -195,15 +196,15 @@ OHGameControllerAxis *yAxis = [_axes objectForKey: @"Y"]; if (xAxis == nil || yAxis == nil) return nil; - return [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Left Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + return [OHGameControllerDirectionalPad + oh_padWithName: @"Left Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; } - (OHGameControllerDirectionalPad *)rightThumbstick { OHGameControllerAxis *xAxis = [_axes objectForKey: @"RX"]; @@ -210,42 +211,42 @@ OHGameControllerAxis *yAxis = [_axes objectForKey: @"RY"]; if (xAxis == nil || yAxis == nil) return nil; - return [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Right Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + return [OHGameControllerDirectionalPad + oh_padWithName: @"Right Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; } - (OHGameControllerDirectionalPad *)dPad { OHGameControllerAxis *xAxis = [_axes objectForKey: @"HAT0X"]; OHGameControllerAxis *yAxis = [_axes objectForKey: @"HAT0Y"]; OHGameControllerButton *up, *down, *left, *right; if (xAxis != nil && yAxis != nil) - return [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - xAxis: xAxis - yAxis: yAxis - analog: false] autorelease]; + return [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + xAxis: xAxis + yAxis: yAxis + analog: false]; up = [_buttons objectForKey: @"D-Pad Up"]; down = [_buttons objectForKey: @"D-Pad Down"]; left = [_buttons objectForKey: @"D-Pad Left"]; right = [_buttons objectForKey: @"D-Pad Right"]; if (up != nil && down != nil && left != nil && right != nil) - return [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + return [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + up: up + down: down + left: left + right: right + analog: false]; return nil; } @end Index: src/hid/OHEvdevGameController.h ================================================================== --- src/hid/OHEvdevGameController.h +++ src/hid/OHEvdevGameController.h @@ -36,11 +36,13 @@ uint16_t _vendorID, _productID; OFString *_name; id _profile; } -- (instancetype)initWithPath: (OFString *)path; +- (instancetype)oh_init OF_UNAVAILABLE; +- (instancetype)oh_initWithPath: (OFString *)path + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; - (void)oh_pollState; @end extern const uint16_t OHEvdevButtonIDs[]; extern const size_t OHNumEvdevButtonIDs; Index: src/hid/OHEvdevGameController.m ================================================================== --- src/hid/OHEvdevGameController.m +++ src/hid/OHEvdevGameController.m @@ -36,10 +36,12 @@ #import "OHDualSenseGamepad+Private.h" #import "OHDualShock4Gamepad.h" #import "OHDualShock4Gamepad+Private.h" #import "OHEvdevExtendedGamepad.h" #import "OHExtendedN64Controller.h" +#import "OHGameController.h" +#import "OHGameController+Private.h" #import "OHGameControllerAxis+Private.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerProfile.h" #import "OHLeftJoyCon.h" @@ -120,11 +122,11 @@ path = [@"/dev/input" stringByAppendingPathComponent: device]; @try { controller = [[[OHEvdevGameController alloc] - initWithPath: path] autorelease]; + oh_initWithPath: path] autorelease]; } @catch (OFOpenItemFailedException *e) { if (e.errNo == EACCES) continue; @throw e; @@ -142,13 +144,18 @@ objc_autoreleasePoolPop(pool); return controllers; } -- (instancetype)initWithPath: (OFString *)path +- (instancetype)oh_init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_initWithPath: (OFString *)path { - self = [super init]; + self = [super oh_init]; @try { void *pool = objc_autoreleasePoolPush(); OFStringEncoding encoding = [OFLocale encoding]; struct input_id inputID; @@ -210,33 +217,33 @@ exception]; } if (_vendorID == OHVendorIDSony && _productID == OHProductIDDualSense) - _profile = [[OHDualSenseGamepad alloc] init]; + _profile = [[OHDualSenseGamepad alloc] oh_init]; else if (_vendorID == OHVendorIDSony && _productID == OHProductIDDualShock4) - _profile = [[OHDualShock4Gamepad alloc] init]; + _profile = [[OHDualShock4Gamepad alloc] oh_init]; else if (_vendorID == OHVendorIDNintendo && _productID == OHProductIDN64Controller) - _profile = [[OHExtendedN64Controller alloc] init]; + _profile = [[OHExtendedN64Controller alloc] oh_init]; else if (_vendorID == OHVendorIDNintendo && _productID == OHProductIDLeftJoyCon) - _profile = [[OHLeftJoyCon alloc] init]; + _profile = [[OHLeftJoyCon alloc] oh_init]; else if (_vendorID == OHVendorIDNintendo && _productID == OHProductIDRightJoyCon) - _profile = [[OHRightJoyCon alloc] init]; + _profile = [[OHRightJoyCon alloc] oh_init]; else if (_vendorID == OHVendorIDGoogle && _productID == OHProductIDStadiaController) - _profile = [[OHStadiaGamepad alloc] init]; + _profile = [[OHStadiaGamepad alloc] oh_init]; else _profile = [[OHEvdevExtendedGamepad alloc] - initWithKeyBits: _keyBits - evBits: _evBits - absBits: _absBits - vendorID: _vendorID - productID: _productID]; + oh_initWithKeyBits: _keyBits + evBits: _evBits + absBits: _absBits + vendorID: _vendorID + productID: _productID]; [self oh_pollState]; objc_autoreleasePoolPop(pool); } @catch (id e) { Index: src/hid/OHEvdevGameControllerProfile.h ================================================================== --- src/hid/OHEvdevGameControllerProfile.h +++ src/hid/OHEvdevGameControllerProfile.h @@ -23,18 +23,22 @@ OF_ASSUME_NONNULL_BEGIN @interface OHEvdevGameControllerProfile: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *_axes; uint16_t _vendorID, _productID; } -- (instancetype)initWithKeyBits: (unsigned long *)keyBits - evBits: (unsigned long *)evBits - absBits: (unsigned long *)absBits - vendorID: (uint16_t)vendorID - productID: (uint16_t)productID; +- (instancetype)init OF_UNAVAILABLE; + +- (instancetype)oh_initWithKeyBits: (unsigned long *)keyBits + evBits: (unsigned long *)evBits + absBits: (unsigned long *)absBits + vendorID: (uint16_t)vendorID + productID: (uint16_t)productID + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHEvdevGameControllerProfile.m ================================================================== --- src/hid/OHEvdevGameControllerProfile.m +++ src/hid/OHEvdevGameControllerProfile.m @@ -21,10 +21,12 @@ #import "OHEvdevGameControllerProfile.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" #include #import "evdev_compat.h" @@ -203,15 +205,20 @@ } @implementation OHEvdevGameControllerProfile @synthesize buttons = _buttons, axes = _axes; -- (instancetype)initWithKeyBits: (unsigned long *)keyBits - evBits: (unsigned long *)evBits - absBits: (unsigned long *)absBits - vendorID: (uint16_t)vendorID - productID: (uint16_t)productID +- (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_initWithKeyBits: (unsigned long *)keyBits + evBits: (unsigned long *)evBits + absBits: (unsigned long *)absBits + vendorID: (uint16_t)vendorID + productID: (uint16_t)productID { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); @@ -226,13 +233,13 @@ buttonName = buttonToName(OHEvdevButtonIDs[i], vendorID, productID); if (buttonName == nil) continue; - button = [[[OHGameControllerButton alloc] - initWithName: buttonName - analog: false] autorelease]; + button = [OHGameControllerButton + oh_elementWithName: buttonName + analog: false]; [buttons setObject: button forKey: buttonName]; } } [buttons makeImmutable]; @@ -247,14 +254,13 @@ axisName = axisToName(OHEvdevAxisIDs[i]); if (axisName == nil) continue; - axis = [[[OHGameControllerAxis - alloc] - initWithName: axisName - analog: true] autorelease]; + axis = [OHGameControllerAxis + oh_elementWithName: axisName + analog: true]; [axes setObject: axis forKey: axisName]; } } } Index: src/hid/OHExtendedN64Controller.m ================================================================== --- src/hid/OHExtendedN64Controller.m +++ src/hid/OHExtendedN64Controller.m @@ -18,13 +18,16 @@ */ #include "config.h" #import "OHExtendedN64Controller.h" +#import "OHN64Controller.h" #import "OHN64Controller+Private.h" #import "OFDictionary.h" #import "OHGameControllerButton.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include #endif @@ -32,24 +35,23 @@ @"ZR", @"Home", @"Capture" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @implementation OHExtendedN64Controller -- (instancetype)init +- (instancetype)oh_init { - self = [super init]; + self = [super oh_init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *buttons = [[_buttons mutableCopy] autorelease]; for (size_t i = 0; i < numButtons; i++) { - OHGameControllerButton *button = - [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; [_buttons release]; _buttons = [buttons retain]; ADDED src/hid/OHGameController+Private.h Index: src/hid/OHGameController+Private.h ================================================================== --- /dev/null +++ src/hid/OHGameController+Private.h @@ -0,0 +1,28 @@ +/* + * 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 OHGameController () +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHGameController.h ================================================================== --- src/hid/OHGameController.h +++ src/hid/OHGameController.h @@ -90,10 +90,12 @@ * @brief Returns the available controllers. * * @return The available controllers */ + (OFArray OF_GENERIC(OHGameController *) *)controllers; + +- (instancetype)init OF_UNAVAILABLE; /** * @brief Updates the current state from the game controller. * * The state returned by @ref OHGameController's methods does not change until Index: src/hid/OHGameController.m ================================================================== --- src/hid/OHGameController.m +++ src/hid/OHGameController.m @@ -75,21 +75,15 @@ #endif } - (instancetype)init { - if ([self isMemberOfClass: [OHGameController class]]) { - @try { - [self doesNotRecognizeSelector: _cmd]; - } @catch (id e) { - [self release]; - @throw e; - } - - abort(); - } - + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init +{ return [super init]; } - (OFNumber *)vendorID { ADDED src/hid/OHGameControllerDirectionalPad+Private.h Index: src/hid/OHGameControllerDirectionalPad+Private.h ================================================================== --- /dev/null +++ src/hid/OHGameControllerDirectionalPad+Private.h @@ -0,0 +1,49 @@ +/* + * 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 "OHGameControllerDirectionalPad.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHGameControllerDirectionalPad () ++ (instancetype)oh_padWithName: (OFString *)name + xAxis: (OHGameControllerAxis *)xAxis + yAxis: (OHGameControllerAxis *)yAxis + analog: (bool)analog; ++ (instancetype)oh_padWithName: (OFString *)name + up: (OHGameControllerButton *)up + down: (OHGameControllerButton *)down + left: (OHGameControllerButton *)left + right: (OHGameControllerButton *)right + analog: (bool)analog; +- (instancetype)oh_initWithName: (OFString *)name + analog: (bool)analog OF_UNAVAILABLE; +- (instancetype)oh_initWithName: (OFString *)name + xAxis: (OHGameControllerAxis *)xAxis + yAxis: (OHGameControllerAxis *)yAxis + analog: (bool)analog OF_METHOD_FAMILY(init); +- (instancetype)oh_initWithName: (OFString *)name + up: (OHGameControllerButton *)up + down: (OHGameControllerButton *)down + left: (OHGameControllerButton *)left + right: (OHGameControllerButton *)right + analog: (bool)analog OF_METHOD_FAMILY(init); +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHGameControllerDirectionalPad.h ================================================================== --- src/hid/OHGameControllerDirectionalPad.h +++ src/hid/OHGameControllerDirectionalPad.h @@ -25,11 +25,11 @@ /** * @class OHGameControllerDirectionalPad OHGameControllerDirectionalPad.h * ObjFWHID/ObjFWID.h * - * @brief An directional pad or thumb stick of a game controller. + * @brief A directional pad or thumb stick of a game controller. */ OF_SUBCLASSING_RESTRICTED @interface OHGameControllerDirectionalPad: OHGameControllerElement { OHGameControllerAxis *_xAxis, *_yAxis; @@ -63,23 +63,8 @@ /** * @brief The right button of the directional pad. */ @property (readonly, nonatomic) OHGameControllerButton *right; - -- (instancetype)initWithName: (OFString *)name - analog: (bool)analog OF_UNAVAILABLE; - -- (instancetype)initWithName: (OFString *)name - xAxis: (OHGameControllerAxis *)xAxis - yAxis: (OHGameControllerAxis *)yAxis - analog: (bool)analog; - -- (instancetype)initWithName: (OFString *)name - up: (OHGameControllerButton *)up - down: (OHGameControllerButton *)down - left: (OHGameControllerButton *)left - right: (OHGameControllerButton *)right - analog: (bool)analog; @end OF_ASSUME_NONNULL_END Index: src/hid/OHGameControllerDirectionalPad.m ================================================================== --- src/hid/OHGameControllerDirectionalPad.m +++ src/hid/OHGameControllerDirectionalPad.m @@ -18,74 +18,103 @@ */ #include "config.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" #import "OHEmulatedGameControllerAxis.h" #import "OHEmulatedGameControllerButton.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" @implementation OHGameControllerDirectionalPad @synthesize xAxis = _xAxis, yAxis = _yAxis; @synthesize up = _up, down = _down, left = _left, right = _right; -- (instancetype)initWithName: (OFString *)name analog: (bool)analog ++ (instancetype)oh_padWithName: (OFString *)name + xAxis: (OHGameControllerAxis *)xAxis + yAxis: (OHGameControllerAxis *)yAxis + analog: (bool)analog +{ + return [[[self alloc] oh_initWithName: name + xAxis: xAxis + yAxis: yAxis + analog: analog] autorelease]; +} + ++ (instancetype)oh_padWithName: (OFString *)name + up: (OHGameControllerButton *)up + down: (OHGameControllerButton *)down + left: (OHGameControllerButton *)left + right: (OHGameControllerButton *)right + analog: (bool)analog +{ + return [[[self alloc] oh_initWithName: name + up: up + down: down + left: left + right: right + analog: analog] autorelease]; +} + +- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog { OF_INVALID_INIT_METHOD } -- (instancetype)initWithName: (OFString *)name - xAxis: (OHGameControllerAxis *)xAxis - yAxis: (OHGameControllerAxis *)yAxis - analog: (bool)analog +- (instancetype)oh_initWithName: (OFString *)name + xAxis: (OHGameControllerAxis *)xAxis + yAxis: (OHGameControllerAxis *)yAxis + analog: (bool)analog { - self = [super initWithName: name analog: analog]; + self = [super oh_initWithName: name analog: analog]; @try { _xAxis = [xAxis retain]; _yAxis = [yAxis retain]; _up = [[OHEmulatedGameControllerButton alloc] - initWithAxis: _yAxis - positive: false]; + oh_initWithAxis: _yAxis + positive: false]; _down = [[OHEmulatedGameControllerButton alloc] - initWithAxis: _yAxis - positive: true]; + oh_initWithAxis: _yAxis + positive: true]; _left = [[OHEmulatedGameControllerButton alloc] - initWithAxis: _xAxis - positive: false]; + oh_initWithAxis: _xAxis + positive: false]; _right = [[OHEmulatedGameControllerButton alloc] - initWithAxis: _xAxis - positive: true]; + oh_initWithAxis: _xAxis + positive: true]; } @catch (id e) { [self release]; @throw e; } return self; } -- (instancetype)initWithName: (OFString *)name - up: (OHGameControllerButton *)up - down: (OHGameControllerButton *)down - left: (OHGameControllerButton *)left - right: (OHGameControllerButton *)right - analog: (bool)analog -{ - self = [super initWithName: name analog: analog]; +- (instancetype)oh_initWithName: (OFString *)name + up: (OHGameControllerButton *)up + down: (OHGameControllerButton *)down + left: (OHGameControllerButton *)left + right: (OHGameControllerButton *)right + analog: (bool)analog +{ + self = [super oh_initWithName: name analog: analog]; @try { _up = [up retain]; _down = [down retain]; _left = [left retain]; _right = [right retain]; _xAxis = [[OHEmulatedGameControllerAxis alloc] - initWithNegativeButton: _left - positiveButton: _right]; + oh_initWithNegativeButton: _left + positiveButton: _right]; _yAxis = [[OHEmulatedGameControllerAxis alloc] - initWithNegativeButton: _up - positiveButton: _down]; + oh_initWithNegativeButton: _up + positiveButton: _down]; } @catch (id e) { [self release]; @throw e; } ADDED src/hid/OHGameControllerElement+Private.h Index: src/hid/OHGameControllerElement+Private.h ================================================================== --- /dev/null +++ src/hid/OHGameControllerElement+Private.h @@ -0,0 +1,31 @@ +/* + * 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 "OHGameControllerElement.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHGameControllerElement () ++ (instancetype)oh_elementWithName: (OFString *)name analog: (bool)analog; +- (instancetype)oh_initWithName: (OFString *)name + analog: (bool)analog + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHGameControllerElement.h ================================================================== --- src/hid/OHGameControllerElement.h +++ src/hid/OHGameControllerElement.h @@ -53,11 +53,8 @@ * @brief Whether the game controller element is analog. */ @property (readonly, nonatomic, getter=isAnalog) bool analog; - (instancetype)init OF_UNAVAILABLE; - -- (instancetype)initWithName: (OFString *)name - analog: (bool)analog OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHGameControllerElement.m ================================================================== --- src/hid/OHGameControllerElement.m +++ src/hid/OHGameControllerElement.m @@ -18,21 +18,27 @@ */ #include "config.h" #import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" @implementation OHGameControllerElement @synthesize name = _name, analog = _analog; + ++ (instancetype)oh_elementWithName: (OFString *)name analog: (bool)analog +{ + return [[[self alloc] oh_initWithName: name + analog: analog] autorelease]; +} - (instancetype)init { OF_INVALID_INIT_METHOD } -- (instancetype)initWithName: (OFString *)name - analog: (bool)analog +- (instancetype)oh_initWithName: (OFString *)name analog: (bool)analog { self = [super init]; @try { _name = [name copy]; Index: src/hid/OHJoyConPair.h ================================================================== --- src/hid/OHJoyConPair.h +++ src/hid/OHJoyConPair.h @@ -61,9 +61,10 @@ * @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; + rightJoyCon: (OHRightJoyCon *)rightJoyCon + OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHLeftJoyCon+Private.h ================================================================== --- src/hid/OHLeftJoyCon+Private.h +++ src/hid/OHLeftJoyCon+Private.h @@ -23,11 +23,13 @@ # import "OHEvdevGameController.h" #endif OF_ASSUME_NONNULL_BEGIN +@interface OHLeftJoyCon () #if defined(OF_LINUX) && defined(OF_HAVE_FILES) -@interface OHLeftJoyCon () -@end + #endif +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end OF_ASSUME_NONNULL_END Index: src/hid/OHLeftJoyCon.h ================================================================== --- src/hid/OHLeftJoyCon.h +++ src/hid/OHLeftJoyCon.h @@ -26,12 +26,15 @@ * * @brief A left Nintendo Switch Joy-Con. */ @interface OHLeftJoyCon: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHLeftJoyCon.m ================================================================== --- src/hid/OHLeftJoyCon.m +++ src/hid/OHLeftJoyCon.m @@ -23,10 +23,13 @@ #import "OHLeftJoyCon+Private.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include # import "evdev_compat.h" #endif @@ -39,10 +42,15 @@ @implementation OHLeftJoyCon @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init { + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init +{ self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *buttons = @@ -51,55 +59,49 @@ 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] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 2]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Left Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Left Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Left Thumbstick"]; - up = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Up" - analog: false] autorelease]; - down = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Down" - analog: false] autorelease]; - left = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Left" - analog: false] autorelease]; - right = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Right" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up" + analog: false]; + down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down" + analog: false]; + left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left" + analog: false]; + right = [OHGameControllerButton + oh_elementWithName: @"D-Pad Right" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + up: up + down: down + left: left + right: right + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; Index: src/hid/OHN64Controller+Private.h ================================================================== --- src/hid/OHN64Controller+Private.h +++ src/hid/OHN64Controller+Private.h @@ -23,11 +23,13 @@ # import "OHEvdevGameController.h" #endif OF_ASSUME_NONNULL_BEGIN +@interface OHN64Controller () #if defined(OF_LINUX) && defined(OF_HAVE_FILES) -@interface OHN64Controller () -@end + #endif +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end OF_ASSUME_NONNULL_END Index: src/hid/OHN64Controller.h ================================================================== --- src/hid/OHN64Controller.h +++ src/hid/OHN64Controller.h @@ -26,12 +26,15 @@ * * @brief A Nintendo 64 controller. */ @interface OHN64Controller: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHN64Controller.m ================================================================== --- src/hid/OHN64Controller.m +++ src/hid/OHN64Controller.m @@ -23,10 +23,13 @@ #import "OHN64Controller+Private.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include #endif @@ -38,10 +41,15 @@ @implementation OHN64Controller @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init { + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init +{ self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *buttons = @@ -50,68 +58,59 @@ 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] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Thumbstick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"D-Pad X" - analog: false] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"D-Pad Y" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - xAxis: xAxis - yAxis: yAxis - analog: false] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad X" + analog: false]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad Y" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + xAxis: xAxis + yAxis: yAxis + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; - up = [[[OHGameControllerButton alloc] - initWithName: @"C-Up" - analog: false] autorelease]; - down = [[[OHGameControllerButton alloc] - initWithName: @"C-Down" - analog: false] autorelease]; - left = [[[OHGameControllerButton alloc] - initWithName: @"C-Left" - analog: false] autorelease]; - right = [[[OHGameControllerButton alloc] - initWithName: @"C-Right" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"C-Buttons" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + up = [OHGameControllerButton oh_elementWithName: @"C-Up" + analog: false]; + down = [OHGameControllerButton oh_elementWithName: @"C-Down" + analog: false]; + left = [OHGameControllerButton oh_elementWithName: @"C-Left" + analog: false]; + right = [OHGameControllerButton oh_elementWithName: @"C-Right" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"C-Buttons" + up: up + down: down + left: left + right: right + analog: false]; [directionalPads setObject: directionalPad forKey: @"C-Buttons"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; ADDED src/hid/OHNintendo3DSExtendedGamepad+Private.h Index: src/hid/OHNintendo3DSExtendedGamepad+Private.h ================================================================== --- /dev/null +++ src/hid/OHNintendo3DSExtendedGamepad+Private.h @@ -0,0 +1,28 @@ +/* + * 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 "OHNintendo3DSExtendedGamepad.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHNintendo3DSExtendedGamepad () +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHNintendo3DSExtendedGamepad.h ================================================================== --- src/hid/OHNintendo3DSExtendedGamepad.h +++ src/hid/OHNintendo3DSExtendedGamepad.h @@ -21,12 +21,15 @@ OF_ASSUME_NONNULL_BEGIN @interface OHNintendo3DSExtendedGamepad: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHNintendo3DSExtendedGamepad.m ================================================================== --- src/hid/OHNintendo3DSExtendedGamepad.m +++ src/hid/OHNintendo3DSExtendedGamepad.m @@ -18,14 +18,18 @@ */ #include "config.h" #import "OHNintendo3DSExtendedGamepad.h" +#import "OHNintendo3DSExtendedGamepad+Private.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" static OFString *const buttonNames[] = { @"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"Start", @"Select" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @@ -32,10 +36,15 @@ @implementation OHNintendo3DSExtendedGamepad @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); @@ -45,69 +54,61 @@ 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] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Circle Pad" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Circle Pad" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Circle Pad"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"CX" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"CY" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"C-Stick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"CX" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"CY" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"C-Stick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"C-Stick"]; - up = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Up" - analog: false] autorelease]; - down = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Down" - analog: false] autorelease]; - left = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Left" - analog: false] autorelease]; - right = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Right" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up" + analog: false]; + down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down" + analog: false]; + left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left" + analog: false]; + right = [OHGameControllerButton + oh_elementWithName: @"D-Pad Right" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + up: up + down: down + left: left + right: right + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; Index: src/hid/OHNintendo3DSGameController.m ================================================================== --- src/hid/OHNintendo3DSGameController.m +++ src/hid/OHNintendo3DSGameController.m @@ -20,14 +20,17 @@ #include "config.h" #import "OHNintendo3DSGameController.h" #import "OFArray.h" #import "OFDictionary.h" +#import "OHGameController.h" +#import "OHGameController+Private.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHNintendo3DSExtendedGamepad.h" +#import "OHNintendo3DSExtendedGamepad+Private.h" #import "OFInitializationFailedException.h" #import "OFReadFailedException.h" #define id id_3ds @@ -46,25 +49,26 @@ if (self != [OHNintendo3DSGameController class]) return; pool = objc_autoreleasePoolPush(); controllers = [[OFArray alloc] initWithObject: - [[[OHNintendo3DSGameController alloc] init] autorelease]]; + [[[OHNintendo3DSGameController alloc] oh_init] autorelease]]; objc_autoreleasePoolPop(pool); } + (OFArray OF_GENERIC(OHGameController *) *)controllers { return controllers; } -- (instancetype)init +- (instancetype)oh_init { - self = [super init]; + self = [super oh_init]; @try { - _extendedGamepad = [[OHNintendo3DSExtendedGamepad alloc] init]; + _extendedGamepad = + [[OHNintendo3DSExtendedGamepad alloc] oh_init]; [self updateState]; } @catch (id e) { [self release]; @throw e; Index: src/hid/OHNintendoDSGameController.m ================================================================== --- src/hid/OHNintendoDSGameController.m +++ src/hid/OHNintendoDSGameController.m @@ -20,13 +20,16 @@ #include "config.h" #import "OHNintendoDSGameController.h" #import "OFArray.h" #import "OFDictionary.h" +#import "OHGameController.h" +#import "OHGameController+Private.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHNintendoDSGamepad.h" +#import "OHNintendoDSGamepad+Private.h" #import "OFInitializationFailedException.h" #import "OFReadFailedException.h" #define asm __asm__ @@ -45,25 +48,25 @@ if (self != [OHNintendoDSGameController class]) return; pool = objc_autoreleasePoolPush(); controllers = [[OFArray alloc] initWithObject: - [[[OHNintendoDSGameController alloc] init] autorelease]]; + [[[OHNintendoDSGameController alloc] oh_init] autorelease]]; objc_autoreleasePoolPop(pool); } + (OFArray OF_GENERIC(OHGameController *) *)controllers { return controllers; } -- (instancetype)init +- (instancetype)oh_init { - self = [super init]; + self = [super oh_init]; @try { - _gamepad = [[OHNintendoDSGamepad alloc] init]; + _gamepad = [[OHNintendoDSGamepad alloc] oh_init]; [self updateState]; } @catch (id e) { [self release]; @throw e; ADDED src/hid/OHNintendoDSGamepad+Private.h Index: src/hid/OHNintendoDSGamepad+Private.h ================================================================== --- /dev/null +++ src/hid/OHNintendoDSGamepad+Private.h @@ -0,0 +1,28 @@ +/* + * 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 "OHNintendoDSGamepad.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHNintendoDSGamepad () +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHNintendoDSGamepad.h ================================================================== --- src/hid/OHNintendoDSGamepad.h +++ src/hid/OHNintendoDSGamepad.h @@ -21,12 +21,15 @@ OF_ASSUME_NONNULL_BEGIN @interface OHNintendoDSGamepad: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHNintendoDSGamepad.m ================================================================== --- src/hid/OHNintendoDSGamepad.m +++ src/hid/OHNintendoDSGamepad.m @@ -18,13 +18,19 @@ */ #include "config.h" #import "OHNintendoDSGamepad.h" +#import "OHNintendoDSGamepad+Private.h" #import "OFDictionary.h" +#import "OHGameController.h" +#import "OHGameController+Private.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" static OFString *const buttonNames[] = { @"A", @"B", @"X", @"Y", @"L", @"R", @"Start", @"Select" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @@ -31,10 +37,15 @@ @implementation OHNintendoDSGamepad @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); @@ -42,38 +53,33 @@ [OFMutableDictionary dictionaryWithCapacity: numButtons]; OHGameControllerButton *up, *down, *left, *right; OHGameControllerDirectionalPad *dPad; for (size_t i = 0; i < numButtons; i++) { - OHGameControllerButton *button = - [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; - up = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Up" - analog: false] autorelease]; - down = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Down" - analog: false] autorelease]; - left = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Left" - analog: false] autorelease]; - right = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Right" - analog: false] autorelease]; - dPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up" + analog: false]; + down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down" + analog: false]; + left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left" + analog: false]; + right = [OHGameControllerButton + oh_elementWithName: @"D-Pad Right" + analog: false]; + dPad = [OHGameControllerDirectionalPad oh_padWithName: @"D-Pad" + up: up + down: down + left: left + right: right + analog: false]; _directionalPads = [[OFDictionary alloc] initWithObject: dPad forKey: @"D-Pad"]; ADDED src/hid/OHNintendoSwitchExtendedGamepad+Private.h Index: src/hid/OHNintendoSwitchExtendedGamepad+Private.h ================================================================== --- /dev/null +++ src/hid/OHNintendoSwitchExtendedGamepad+Private.h @@ -0,0 +1,28 @@ +/* + * 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 "OHNintendoSwitchExtendedGamepad.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHNintendoSwitchExtendedGamepad () +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHNintendoSwitchExtendedGamepad.h ================================================================== --- src/hid/OHNintendoSwitchExtendedGamepad.h +++ src/hid/OHNintendoSwitchExtendedGamepad.h @@ -21,12 +21,15 @@ OF_ASSUME_NONNULL_BEGIN @interface OHNintendoSwitchExtendedGamepad: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHNintendoSwitchExtendedGamepad.m ================================================================== --- src/hid/OHNintendoSwitchExtendedGamepad.m +++ src/hid/OHNintendoSwitchExtendedGamepad.m @@ -18,14 +18,18 @@ */ #include "config.h" #import "OHNintendoSwitchExtendedGamepad.h" +#import "OHNintendoSwitchExtendedGamepad+Private.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" static OFString *const buttonNames[] = { @"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"Left Thumbstick", @"Right Thumbstick", @"+", @"-" }; @@ -33,10 +37,15 @@ @implementation OHNintendoSwitchExtendedGamepad @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); @@ -46,69 +55,61 @@ 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] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Left Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Left Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Left Thumbstick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RX" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RY" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Right Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"RX" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"RY" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Right Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Right Thumbstick"]; - up = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Up" - analog: false] autorelease]; - down = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Down" - analog: false] autorelease]; - left = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Left" - analog: false] autorelease]; - right = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Right" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up" + analog: false]; + down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down" + analog: false]; + left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left" + analog: false]; + right = [OHGameControllerButton + oh_elementWithName: @"D-Pad Right" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + up: up + down: down + left: left + right: right + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; Index: src/hid/OHNintendoSwitchGameController.h ================================================================== --- src/hid/OHNintendoSwitchGameController.h +++ src/hid/OHNintendoSwitchGameController.h @@ -31,9 +31,11 @@ { PadState _pad; OHNintendoSwitchExtendedGamepad *_extendedGamepad; } -- (instancetype)initWithIndex: (size_t)index; +- (instancetype)oh_init OF_UNAVAILABLE; +- (instancetype)oh_initWithIndex: (size_t)index + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHNintendoSwitchGameController.m ================================================================== --- src/hid/OHNintendoSwitchGameController.m +++ src/hid/OHNintendoSwitchGameController.m @@ -20,14 +20,17 @@ #include "config.h" #import "OHNintendoSwitchGameController.h" #import "OFArray.h" #import "OFDictionary.h" +#import "OHGameController.h" +#import "OHGameController+Private.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHNintendoSwitchExtendedGamepad.h" +#import "OHNintendoSwitchExtendedGamepad+Private.h" #import "OFInitializationFailedException.h" #import "OFReadFailedException.h" #define id nx_id @@ -53,11 +56,11 @@ for (size_t i = 0; i < maxControllers; i++) { OHGameController *controller; @try { controller = [[[OHNintendoSwitchGameController alloc] - initWithIndex: i] autorelease]; + oh_initWithIndex: i] autorelease]; } @catch (OFInitializationFailedException *e) { /* Controller does not exist. */ continue; } @@ -69,13 +72,18 @@ objc_autoreleasePoolPop(pool); return controllers; } -- (instancetype)initWithIndex: (size_t)index +- (instancetype)oh_init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_initWithIndex: (size_t)index { - self = [super init]; + self = [super oh_init]; @try { padInitialize(&_pad, HidNpadIdType_No1 + index, (index == 0 ? HidNpadIdType_Handheld : 0)); padUpdate(&_pad); @@ -83,11 +91,11 @@ if (!padIsConnected(&_pad)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; _extendedGamepad = - [[OHNintendoSwitchExtendedGamepad alloc] init]; + [[OHNintendoSwitchExtendedGamepad alloc] oh_init]; [self updateState]; } @catch (id e) { [self release]; @throw e; Index: src/hid/OHRightJoyCon+Private.h ================================================================== --- src/hid/OHRightJoyCon+Private.h +++ src/hid/OHRightJoyCon+Private.h @@ -23,11 +23,13 @@ # import "OHEvdevGameController.h" #endif OF_ASSUME_NONNULL_BEGIN +@interface OHRightJoyCon () #if defined(OF_LINUX) && defined(OF_HAVE_FILES) -@interface OHRightJoyCon () -@end + #endif +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end OF_ASSUME_NONNULL_END Index: src/hid/OHRightJoyCon.h ================================================================== --- src/hid/OHRightJoyCon.h +++ src/hid/OHRightJoyCon.h @@ -26,12 +26,15 @@ * * @brief A right Nintendo Switch Joy-Con. */ @interface OHRightJoyCon: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHRightJoyCon.m ================================================================== --- src/hid/OHRightJoyCon.m +++ src/hid/OHRightJoyCon.m @@ -23,10 +23,13 @@ #import "OHRightJoyCon+Private.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include # import "evdev_compat.h" #endif @@ -40,10 +43,15 @@ @implementation OHRightJoyCon @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init { + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init +{ self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *buttons = @@ -50,30 +58,27 @@ [OFMutableDictionary dictionaryWithCapacity: numButtons]; OHGameControllerAxis *xAxis, *yAxis; OHGameControllerDirectionalPad *directionalPad; for (size_t i = 0; i < numButtons; i++) { - OHGameControllerButton *button = - [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Right Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Right Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; _directionalPads = [[OFDictionary alloc] initWithObject: directionalPad forKey: @"Right Thumbstick"]; Index: src/hid/OHStadiaGamepad+Private.h ================================================================== --- src/hid/OHStadiaGamepad+Private.h +++ src/hid/OHStadiaGamepad+Private.h @@ -23,11 +23,13 @@ # import "OHEvdevGameController.h" #endif OF_ASSUME_NONNULL_BEGIN +@interface OHStadiaGamepad () #if defined(OF_LINUX) && defined(OF_HAVE_FILES) -@interface OHStadiaGamepad () -@end + #endif +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end OF_ASSUME_NONNULL_END Index: src/hid/OHStadiaGamepad.h ================================================================== --- src/hid/OHStadiaGamepad.h +++ src/hid/OHStadiaGamepad.h @@ -26,12 +26,15 @@ * * @brief A Stadia gamepad. */ @interface OHStadiaGamepad: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHStadiaGamepad.m ================================================================== --- src/hid/OHStadiaGamepad.m +++ src/hid/OHStadiaGamepad.m @@ -24,10 +24,13 @@ #import "OFDictionary.h" #import "OHEmulatedGameControllerTriggerButton.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include #endif @@ -40,10 +43,15 @@ @implementation OHStadiaGamepad @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init { + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init +{ self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *buttons = @@ -52,77 +60,69 @@ OFMutableDictionary *directionalPads; OHGameControllerAxis *axis, *xAxis, *yAxis; OHGameControllerDirectionalPad *directionalPad; for (size_t i = 0; i < numButtons; i++) { - button = [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: false] autorelease]; + button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } - axis = [[[OHGameControllerAxis alloc] - initWithName: @"L2" - analog: true] autorelease]; - button = [[[OHEmulatedGameControllerTriggerButton alloc] - initWithName: @"L2" - axis: axis] autorelease]; + axis = [OHGameControllerAxis oh_elementWithName: @"L2" + analog: true]; + button = [OHEmulatedGameControllerTriggerButton + oh_buttonWithName: @"L2" + axis: axis]; [buttons setObject: button forKey: @"L2"]; - axis = [[[OHGameControllerAxis alloc] - initWithName: @"R2" - analog: true] autorelease]; - button = [[[OHEmulatedGameControllerTriggerButton alloc] - initWithName: @"R2" - axis: axis] autorelease]; + axis = [OHGameControllerAxis oh_elementWithName: @"R2" + analog: true]; + button = [OHEmulatedGameControllerTriggerButton + oh_buttonWithName: @"R2" + axis: axis]; [buttons setObject: button forKey: @"R2"]; [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Left Stick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Left Stick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Left Stick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RX" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RY" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Right Stick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"RX" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"RY" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Right Stick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Right Stick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"D-Pad X" - analog: false] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"D-Pad Y" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - xAxis: xAxis - yAxis: yAxis - analog: false] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad X" + analog: false]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"D-Pad Y" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + xAxis: xAxis + yAxis: yAxis + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; @@ -294,16 +294,14 @@ case ABS_HAT0X: return [[_directionalPads objectForKey: @"D-Pad"] xAxis]; case ABS_HAT0Y: return [[_directionalPads objectForKey: @"D-Pad"] yAxis]; case ABS_BRAKE: - return ((OHEmulatedGameControllerTriggerButton *) - [_buttons objectForKey: @"L2"]).axis; + return [[_buttons objectForKey: @"L2"] oh_axis]; case ABS_GAS: - return ((OHEmulatedGameControllerTriggerButton *) - [_buttons objectForKey: @"R2"]).axis; + return [[_buttons objectForKey: @"R2"] oh_axis]; default: return nil; } } #endif @end ADDED src/hid/OHWiiClassicController+Private.h Index: src/hid/OHWiiClassicController+Private.h ================================================================== --- /dev/null +++ src/hid/OHWiiClassicController+Private.h @@ -0,0 +1,28 @@ +/* + * 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 "OHWiiClassicController.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHWiiClassicController () +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHWiiClassicController.h ================================================================== --- src/hid/OHWiiClassicController.h +++ src/hid/OHWiiClassicController.h @@ -25,8 +25,10 @@ { OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHWiiClassicController.m ================================================================== --- src/hid/OHWiiClassicController.m +++ src/hid/OHWiiClassicController.m @@ -18,14 +18,18 @@ */ #include "config.h" #import "OHWiiClassicController.h" +#import "OHWiiClassicController+Private.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" static OFString *const buttonNames[] = { @"A", @"B", @"X", @"Y", @"L", @"R", @"ZL", @"ZR", @"+", @"-", @"Home" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @@ -32,10 +36,15 @@ @implementation OHWiiClassicController @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); @@ -45,69 +54,61 @@ 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] - analog: false]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Left Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Left Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Left Thumbstick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RX" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RY" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Right Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"RX" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"RY" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Right Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Right Thumbstick"]; - up = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Up" - analog: false] autorelease]; - down = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Down" - analog: false] autorelease]; - left = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Left" - analog: false] autorelease]; - right = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Right" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up" + analog: false]; + down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down" + analog: false]; + left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left" + analog: false]; + right = [OHGameControllerButton + oh_elementWithName: @"D-Pad Right" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + up: up + down: down + left: left + right: right + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; Index: src/hid/OHWiiGameController.h ================================================================== --- src/hid/OHWiiGameController.h +++ src/hid/OHWiiGameController.h @@ -26,9 +26,12 @@ int32_t _index; uint32_t _type; id _profile; } -- (instancetype)initWithIndex: (int32_t)index type: (uint32_t)type; +- (instancetype)oh_init OF_UNAVAILABLE; +- (instancetype)oh_initWithIndex: (int32_t)index + type: (uint32_t)type + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHWiiGameController.m ================================================================== --- src/hid/OHWiiGameController.m +++ src/hid/OHWiiGameController.m @@ -20,14 +20,18 @@ #include "config.h" #import "OHWiiGameController.h" #import "OFArray.h" #import "OFDictionary.h" +#import "OHGameController.h" +#import "OHGameController+Private.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHWiiClassicController.h" +#import "OHWiiClassicController+Private.h" #import "OHWiimote.h" +#import "OHWiimote+Private.h" #import "OHWiimoteWithNunchuk.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFReadFailedException.h" @@ -73,35 +77,40 @@ 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]]; + oh_initWithIndex: i + type: type] autorelease]]; } [controllers makeImmutable]; objc_autoreleasePoolPop(pool); return controllers; } -- (instancetype)initWithIndex: (int32_t)index type: (uint32_t)type +- (instancetype)oh_init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_initWithIndex: (int32_t)index type: (uint32_t)type { - self = [super init]; + self = [super oh_init]; @try { _index = index; _type = type; if (type == WPAD_EXP_CLASSIC) - _profile = [[OHWiiClassicController alloc] init]; + _profile = [[OHWiiClassicController alloc] oh_init]; else if (type == WPAD_EXP_NUNCHUK) - _profile = [[OHWiimoteWithNunchuk alloc] init]; + _profile = [[OHWiimoteWithNunchuk alloc] oh_init]; else - _profile = [[OHWiimote alloc] init]; + _profile = [[OHWiimote alloc] oh_init]; [self updateState]; } @catch (id e) { [self release]; @throw e; ADDED src/hid/OHWiimote+Private.h Index: src/hid/OHWiimote+Private.h ================================================================== --- /dev/null +++ src/hid/OHWiimote+Private.h @@ -0,0 +1,28 @@ +/* + * 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 "OHWiimote.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHWiimote () +- (instancetype)oh_init OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHWiimote.h ================================================================== --- src/hid/OHWiimote.h +++ src/hid/OHWiimote.h @@ -25,8 +25,10 @@ { OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } + +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHWiimote.m ================================================================== --- src/hid/OHWiimote.m +++ src/hid/OHWiimote.m @@ -18,14 +18,18 @@ */ #include "config.h" #import "OHWiimote.h" +#import "OHWiimote+Private.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" static OFString *const buttonNames[] = { @"A", @"B", @"1", @"2", @"+", @"-", @"Home" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @@ -32,10 +36,15 @@ @implementation OHWiimote @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_init { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); @@ -44,38 +53,33 @@ OHGameControllerButton *up, *down, *left, *right; buttons = [OFMutableDictionary dictionaryWithCapacity: numButtons]; for (size_t i = 0; i < numButtons; i++) { - OHGameControllerButton *button = - [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; - up = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Up" - analog: false] autorelease]; - down = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Down" - analog: false] autorelease]; - left = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Left" - analog: false] autorelease]; - right = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Right" - analog: false] autorelease]; - dPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up" + analog: false]; + down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down" + analog: false]; + left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left" + analog: false]; + right = [OHGameControllerButton + oh_elementWithName: @"D-Pad Right" + analog: false]; + dPad = [OHGameControllerDirectionalPad oh_padWithName: @"D-Pad" + up: up + down: down + left: left + right: right + analog: false]; _directionalPads = [[OFDictionary alloc] initWithObject: dPad forKey: @"D-Pad"]; Index: src/hid/OHWiimoteWithNunchuk.m ================================================================== --- src/hid/OHWiimoteWithNunchuk.m +++ src/hid/OHWiimoteWithNunchuk.m @@ -22,20 +22,24 @@ #import "OHWiimoteWithNunchuk.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" +#import "OHWiimote+Private.h" static OFString *const buttonNames[] = { @"C", @"Z" }; static const size_t numButtons = sizeof(buttonNames) / sizeof(*buttonNames); @implementation OHWiimoteWithNunchuk -- (instancetype)init +- (instancetype)oh_init { - self = [super init]; + self = [super oh_init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *buttons = [[_buttons mutableCopy] autorelease]; @@ -43,29 +47,26 @@ [[_directionalPads mutableCopy] autorelease]; OHGameControllerAxis *xAxis, *yAxis; OHGameControllerDirectionalPad *directionalPad; for (size_t i = 0; i < numButtons; i++) { - OHGameControllerButton *button = - [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: false] autorelease]; + OHGameControllerButton *button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: false]; [buttons setObject: button forKey: buttonNames[i]]; } - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Analog Stick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Analog Stick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Analog Stick"]; [buttons makeImmutable]; [_buttons release]; Index: src/hid/OHXInputGameController.h ================================================================== --- src/hid/OHXInputGameController.h +++ src/hid/OHXInputGameController.h @@ -30,9 +30,11 @@ DWORD _index; OFNumber *_Nullable _vendorID, *_Nullable _productID; OHXboxGamepad *_extendedGamepad; } -- (instancetype)initWithIndex: (DWORD)index; +- (instancetype)oh_init OF_UNAVAILABLE; +- (instancetype)oh_initWithIndex: (DWORD)index + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END Index: src/hid/OHXInputGameController.m ================================================================== --- src/hid/OHXInputGameController.m +++ src/hid/OHXInputGameController.m @@ -21,14 +21,17 @@ #import "OHXInputGameController.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFNumber.h" +#import "OHGameController.h" +#import "OHGameController+Private.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHXboxGamepad.h" +#import "OHXboxGamepad+Private.h" #import "OFInitializationFailedException.h" #import "OFReadFailedException.h" #include @@ -93,11 +96,11 @@ for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) { OHGameController *controller; @try { controller = [[[OHXInputGameController alloc] - initWithIndex: i] autorelease]; + oh_initWithIndex: i] autorelease]; } @catch (OFInitializationFailedException *e) { /* Controller does not exist. */ continue; } @@ -110,13 +113,18 @@ [controllers makeImmutable]; return controllers; } -- (instancetype)initWithIndex: (DWORD)index +- (instancetype)oh_init +{ + OF_INVALID_INIT_METHOD +} + +- (instancetype)oh_initWithIndex: (DWORD)index { - self = [super init]; + self = [super oh_init]; @try { XINPUT_STATE state = { 0 }; if (XInputGetStateFuncPtr(index, &state) == @@ -140,11 +148,11 @@ capabilities.productID]; } } _extendedGamepad = [[OHXboxGamepad alloc] - initWithHasGuideButton: (XInputVersion != 910)]; + oh_initWithHasGuideButton: (XInputVersion != 910)]; [self updateState]; } @catch (id e) { [self release]; @throw e; @@ -169,60 +177,60 @@ if (XInputGetStateFuncPtr(_index, &state) != ERROR_SUCCESS) @throw [OFReadFailedException exceptionWithObject: self requestedLength: sizeof(state) errNo: 0]; - _extendedGamepad.northButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y); - _extendedGamepad.southButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_A); - _extendedGamepad.westButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_X); - _extendedGamepad.eastButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_B); - _extendedGamepad.leftShoulderButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER); - _extendedGamepad.rightShoulderButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER); - _extendedGamepad.leftThumbstickButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB); - _extendedGamepad.rightThumbstickButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB); - _extendedGamepad.menuButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_START); - _extendedGamepad.optionsButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK); + [_extendedGamepad.northButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y)]; + [_extendedGamepad.southButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_A)]; + [_extendedGamepad.westButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_X)]; + [_extendedGamepad.eastButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_B)]; + [_extendedGamepad.leftShoulderButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER)]; + [_extendedGamepad.rightShoulderButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)]; + [_extendedGamepad.leftThumbstickButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)]; + [_extendedGamepad.rightThumbstickButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB)]; + [_extendedGamepad.menuButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_START)]; + [_extendedGamepad.optionsButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK)]; if (XInputVersion != 910) - _extendedGamepad.homeButton.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE); - - _extendedGamepad.leftTriggerButton.value = - (float)state.Gamepad.bLeftTrigger / 255; - _extendedGamepad.rightTriggerButton.value = - (float)state.Gamepad.bRightTrigger / 255; - - _extendedGamepad.leftThumbstick.xAxis.value = - (float)state.Gamepad.sThumbLX / - (state.Gamepad.sThumbLX < 0 ? -INT16_MIN : INT16_MAX); - _extendedGamepad.leftThumbstick.yAxis.value = - -(float)state.Gamepad.sThumbLY / - (state.Gamepad.sThumbLY < 0 ? -INT16_MIN : INT16_MAX); - _extendedGamepad.rightThumbstick.xAxis.value = + [_extendedGamepad.homeButton setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE)]; + + [_extendedGamepad.leftTriggerButton setValue: + (float)state.Gamepad.bLeftTrigger / 255]; + [_extendedGamepad.rightTriggerButton setValue: + (float)state.Gamepad.bRightTrigger / 255]; + + [_extendedGamepad.leftThumbstick.xAxis setValue: + (float)state.Gamepad.sThumbLX / + (state.Gamepad.sThumbLX < 0 ? -INT16_MIN : INT16_MAX)]; + [_extendedGamepad.leftThumbstick.yAxis setValue: + -(float)state.Gamepad.sThumbLY / + (state.Gamepad.sThumbLY < 0 ? -INT16_MIN : INT16_MAX)]; + [_extendedGamepad.rightThumbstick.xAxis setValue: (float)state.Gamepad.sThumbRX / - (state.Gamepad.sThumbRX < 0 ? -INT16_MIN : INT16_MAX); - _extendedGamepad.rightThumbstick.yAxis.value = - -(float)state.Gamepad.sThumbRY / - (state.Gamepad.sThumbRY < 0 ? -INT16_MIN : INT16_MAX); - - _extendedGamepad.dPad.up.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP); - _extendedGamepad.dPad.down.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN); - _extendedGamepad.dPad.left.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT); - _extendedGamepad.dPad.right.value = - !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT); + (state.Gamepad.sThumbRX < 0 ? -INT16_MIN : INT16_MAX)]; + [_extendedGamepad.rightThumbstick.yAxis setValue: + -(float)state.Gamepad.sThumbRY / + (state.Gamepad.sThumbRY < 0 ? -INT16_MIN : INT16_MAX)]; + + [_extendedGamepad.dPad.up setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)]; + [_extendedGamepad.dPad.down setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)]; + [_extendedGamepad.dPad.left setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)]; + [_extendedGamepad.dPad.right setValue: + !!(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)]; } - (OFString *)name { switch (XInputVersion) { ADDED src/hid/OHXboxGamepad+Private.h Index: src/hid/OHXboxGamepad+Private.h ================================================================== --- /dev/null +++ src/hid/OHXboxGamepad+Private.h @@ -0,0 +1,29 @@ +/* + * 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 "OHXboxGamepad.h" + +OF_ASSUME_NONNULL_BEGIN + +@interface OHXboxGamepad () +- (instancetype)oh_initWithHasGuideButton: (bool)hasGuideButton + OF_METHOD_FAMILY(init) OF_DESIGNATED_INITIALIZER; +@end + +OF_ASSUME_NONNULL_END Index: src/hid/OHXboxGamepad.h ================================================================== --- src/hid/OHXboxGamepad.h +++ src/hid/OHXboxGamepad.h @@ -26,14 +26,15 @@ * * @brief A Microsoft Xbox gamepad. */ @interface OHXboxGamepad: OFObject { - OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *_buttons; + OFDictionary OF_GENERIC(OFString *, OF_KINDOF(OHGameControllerButton *)) + *_buttons; OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *_directionalPads; } -- (instancetype)initWithHasGuideButton: (bool)hasGuideButton; +- (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END Index: src/hid/OHXboxGamepad.m ================================================================== --- src/hid/OHXboxGamepad.m +++ src/hid/OHXboxGamepad.m @@ -18,14 +18,18 @@ */ #include "config.h" #import "OHXboxGamepad.h" +#import "OHXboxGamepad+Private.h" #import "OFDictionary.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" +#import "OHGameControllerDirectionalPad+Private.h" +#import "OHGameControllerElement.h" +#import "OHGameControllerElement+Private.h" static OFString *const buttonNames[] = { @"A", @"B", @"X", @"Y", @"LB", @"RB", @"LT", @"RT", @"LSB", @"RSB", @"Start", @"Back", @"Guide" }; @@ -34,14 +38,14 @@ @implementation OHXboxGamepad @synthesize buttons = _buttons, directionalPads = _directionalPads; - (instancetype)init { - return [self initWithHasGuideButton: true]; + OF_INVALID_INIT_METHOD } -- (instancetype)initWithHasGuideButton: (bool)hasGuideButton +- (instancetype)oh_initWithHasGuideButton: (bool)hasGuideButton { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); @@ -59,68 +63,61 @@ if ([buttonNames[i] isEqual: @"Guide"] && !hasGuideButton) continue; - button = [[[OHGameControllerButton alloc] - initWithName: buttonNames[i] - analog: analog] autorelease]; + button = [OHGameControllerButton + oh_elementWithName: buttonNames[i] + analog: analog]; [buttons setObject: button forKey: buttonNames[i]]; } [buttons makeImmutable]; _buttons = [buttons retain]; directionalPads = [OFMutableDictionary dictionaryWithCapacity: 3]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"X" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"Y" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Left Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"X" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"Y" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Left Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Left Thumbstick"]; - xAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RX" - analog: true] autorelease]; - yAxis = [[[OHGameControllerAxis alloc] - initWithName: @"RY" - analog: true] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"Right Thumbstick" - xAxis: xAxis - yAxis: yAxis - analog: true] autorelease]; + xAxis = [OHGameControllerAxis oh_elementWithName: @"RX" + analog: true]; + yAxis = [OHGameControllerAxis oh_elementWithName: @"RY" + analog: true]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"Right Thumbstick" + xAxis: xAxis + yAxis: yAxis + analog: true]; [directionalPads setObject: directionalPad forKey: @"Right Thumbstick"]; - up = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Up" - analog: false] autorelease]; - down = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Down" - analog: false] autorelease]; - left = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Left" - analog: false] autorelease]; - right = [[[OHGameControllerButton alloc] - initWithName: @"D-Pad Right" - analog: false] autorelease]; - directionalPad = [[[OHGameControllerDirectionalPad alloc] - initWithName: @"D-Pad" - up: up - down: down - left: left - right: right - analog: false] autorelease]; + up = [OHGameControllerButton oh_elementWithName: @"D-Pad Up" + analog: false]; + down = [OHGameControllerButton oh_elementWithName: @"D-Pad Down" + analog: false]; + left = [OHGameControllerButton oh_elementWithName: @"D-Pad Left" + analog: false]; + right = [OHGameControllerButton + oh_elementWithName: @"D-Pad Right" + analog: false]; + directionalPad = [OHGameControllerDirectionalPad + oh_padWithName: @"D-Pad" + up: up + down: down + left: left + right: right + analog: false]; [directionalPads setObject: directionalPad forKey: @"D-Pad"]; [directionalPads makeImmutable]; _directionalPads = [directionalPads retain]; Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -97,22 +97,22 @@ # define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1)) # define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0)) # define OF_CONST_FUNC __attribute__((__const__)) # define OF_NO_RETURN_FUNC __attribute__((__noreturn__)) # define OF_WEAK_REF(sym) __attribute__((__weakref__(sym))) +# if defined(OF_ELF) || defined(OF_MACHO) +# define OF_VISIBILITY_HIDDEN __attribute__((__visibility__("hidden"))) +# else +# define OF_VISIBILITY_HIDDEN +# endif #else # define OF_INLINE inline # define OF_LIKELY(cond) (cond) # define OF_UNLIKELY(cond) (cond) # define OF_CONST_FUNC # define OF_NO_RETURN_FUNC # define OF_WEAK_REF(sym) -#endif - -#ifndef OF_DJGPP -# define OF_VISIBILITY_HIDDEN __attribute__((__visibility__("hidden"))) -#else # define OF_VISIBILITY_HIDDEN #endif #if __STDC_VERSION__ >= 201112L # define OF_ALIGN(size) _Alignas(size) Index: src/runtime/exception.m ================================================================== --- src/runtime/exception.m +++ src/runtime/exception.m @@ -36,11 +36,11 @@ #ifdef __SEH__ # include #endif #if defined(__SEH__) -# define PERSONALITY gnu_objc_personality +# define PERSONALITY gnu_objc_personality #elif defined(__USING_SJLJ_EXCEPTIONS__) # define PERSONALITY __gnu_objc_personality_sj0 # define CXX_PERSONALITY_STR "__gxx_personality_sj0" # define _Unwind_RaiseException _Unwind_SjLj_RaiseException # define __builtin_eh_return_data_regno(i) (i) @@ -235,11 +235,11 @@ uintptr_t thumb = _Unwind_GetGR(ctx, 15) & 1; _Unwind_SetGR(ctx, 15, (value | thumb)); } #endif -#ifdef CXX_PERSONALITY +#if defined(CXX_PERSONALITY_STR) && !defined(OF_AMIGAOS_M68K) static PERSONALITY_FUNC(cxx_personality) OF_WEAK_REF(CXX_PERSONALITY_STR); #endif #ifdef __SEH__ extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, @@ -613,11 +613,11 @@ uint8_t found = 0; intptr_t filter = 0; if (foreign) { switch (exClass) { -#ifdef CXX_PERSONALITY +#if defined(CXX_PERSONALITY_STR) && !defined(OF_AMIGAOS_M68K) case GNUCCXX0_EXCEPTION_CLASS: case CLNGCXX0_EXCEPTION_CLASS: if (cxx_personality != NULL) return CALL_PERSONALITY(cxx_personality); break; Index: tests/OFSCTPSocketTests.m ================================================================== --- tests/OFSCTPSocketTests.m +++ tests/OFSCTPSocketTests.m @@ -51,12 +51,25 @@ } } [server listen]; - [client connectToHost: @"127.0.0.1" - port: OFSocketAddressIPPort(&address)]; + @try { + [client connectToHost: @"127.0.0.1" + port: OFSocketAddressIPPort(&address)]; + } @catch (OFConnectSocketFailedException *e) { + switch (e.errNo) { + case ENOPROTOOPT: + /* + * When running in qemu-user, binding works but + * connecting fails?! + */ + OTSkip(@"SCTP unsupported"); + default: + @throw e; + } + } accepted = [server accept]; OTAssertEqualObjects(OFSocketAddressString(accepted.remoteAddress), @"127.0.0.1"); Index: tests/OFUNIXSequencedPacketSocketTests.m ================================================================== --- tests/OFUNIXSequencedPacketSocketTests.m +++ tests/OFUNIXSequencedPacketSocketTests.m @@ -59,11 +59,13 @@ } @catch (OFBindSocketFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: case EPERM: case EPROTONOSUPPORT: +#ifdef ESOCKTNOSUPPORT case ESOCKTNOSUPPORT: +#endif OTSkip(@"UNIX sequenced packet sockets unsupported"); default: @throw e; } } Index: utils/objfw-compile ================================================================== --- utils/objfw-compile +++ utils/objfw-compile @@ -328,20 +328,10 @@ if test x"$lib" = x"yes"; then export SHARED_LIB="$out_prefix$out$out_suffix" LDFLAGS="$LDFLAGS $($OBJFW_CONFIG --lib-ldflags)" fi -if test x"$plugin" = x"yes" -a x"$out_suffix" = x".bundle"; then - # If $out_suffix is .bundle, it means we are creating a macOS bundle. - # These are not just a single file, but have a certain directory - # structure. Therefore we amend the output path to match the expected - # directory structure. - mkdir -p $out$out_suffix/Contents/MacOS - out="$out$out_suffix/Contents/MacOS/$(basename $out)" - out_suffix="" -fi - if test ! -f "$out_prefix$out$out_suffix" -o x"$link" = x"yes"; then status_linking $out_prefix$out$out_suffix $OBJC -o $out_prefix$out$out_suffix $objs $LIBS $LDFLAGS || \ status_link_failed $out $? status_linked $out_prefix$out$out_suffix