Comment: | Add OHGamepad |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
c45b04b1f8f1033d61ecd69bc28fee03 |
User & Date: | js on 2024-06-04 23:51:18 |
Other Links: | manifest | tags |
2024-06-08
| ||
19:18 | ObjFWHID: Restore XInput support check-in: 5f0cc05894 user: js tags: trunk | |
2024-06-04
| ||
23:51 | Add OHGamepad check-in: c45b04b1f8 user: js tags: trunk | |
2024-06-03
| ||
19:53 | Compile OHEvdevGameController separately check-in: 82da883fa6 user: js tags: trunk | |
Modified src/OFHostAddressResolver.m from [3978a3f46f] to [1f05972ec7].
︙ | ︙ | |||
111 112 113 114 115 116 117 | object: exception repeats: false]; [[OFRunLoop currentRunLoop] addTimer: timer forMode: runLoopMode]; } } | | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | object: exception repeats: false]; [[OFRunLoop currentRunLoop] addTimer: timer forMode: runLoopMode]; } } @implementation OFHostAddressResolver - (instancetype)initWithHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily resolver: (OFDNSResolver *)resolver settings: (OFDNSResolverSettings *)settings runLoopMode: (OFRunLoopMode)runLoopMode delegate: (id <OFDNSResolverHostDelegate>)delegate { |
︙ | ︙ |
Modified src/OFTarArchive.m from [300800373d] to [0a16baeb97].
︙ | ︙ | |||
73 74 75 76 77 78 79 | } - (instancetype)of_initWithArchive: (OFTarArchive *)archive stream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; @end | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | } - (instancetype)of_initWithArchive: (OFTarArchive *)archive stream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; @end @implementation OFTarArchive @synthesize encoding = _encoding; + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } |
︙ | ︙ |
Modified src/hid/Makefile from [c92a9269e5] to [f964e9ff82].
︙ | ︙ | |||
11 12 13 14 15 16 17 18 | SRCS = OHGameController.m \ OHGameControllerAxis.m \ OHGameControllerButton.m \ OHGameControllerDirectionalPad.m \ OHGameControllerElement.m \ OHGameControllerProfile.m \ ${USE_SRCS_EVDEV} | > | > | > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | SRCS = OHGameController.m \ OHGameControllerAxis.m \ OHGameControllerButton.m \ OHGameControllerDirectionalPad.m \ OHGameControllerElement.m \ OHGameControllerProfile.m \ OHGamepad.m \ ${USE_SRCS_EVDEV} SRCS_EVDEV = OHEvdevGameController.m \ OHEvdevGamepad.m INCLUDES := ${SRCS:.m=.h} \ ObjFWHID.h SRCS += OHGameControllerEmulatedAxis.m \ OHGameControllerEmulatedButton.m \ OHGameControllerEmulatedTriggerButton.m includesubdir = ObjFWHID include ../../buildsys.mk install-extra: i=ObjFWHID.oc; \ |
︙ | ︙ |
Modified src/hid/OHEvdevGameController.h from [95f3f59293] to [10dbd16290].
︙ | ︙ | |||
30 31 32 33 34 35 36 | bool _discardUntilReport; unsigned long *_evBits, *_keyBits, *_absBits; uint16_t _vendorID, _productID; OFString *_name; OHGameControllerProfile *_rawProfile; } | | | | 30 31 32 33 34 35 36 37 38 39 40 41 | bool _discardUntilReport; unsigned long *_evBits, *_keyBits, *_absBits; uint16_t _vendorID, _productID; OFString *_name; OHGameControllerProfile *_rawProfile; } - (instancetype)oh_initWithPath: (OFString *)path OF_METHOD_FAMILY(init); - (void)oh_pollState; @end OF_ASSUME_NONNULL_END |
Modified src/hid/OHEvdevGameController.m from [4aad12f123] to [f6abf87a47].
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #import "OFArray.h" #import "OFDictionary.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerProfile.h" #include <sys/ioctl.h> #include <linux/input.h> | > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #import "OFArray.h" #import "OFDictionary.h" #import "OFFileManager.h" #import "OFLocale.h" #import "OFNumber.h" #import "OHEvdevGamepad.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerProfile.h" #include <sys/ioctl.h> #include <linux/input.h> |
︙ | ︙ | |||
48 49 50 51 52 53 54 | { @public int32_t _minValue, _maxValue; } @end @interface OHEvdevGameControllerProfile: OHGameControllerProfile | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | { @public int32_t _minValue, _maxValue; } @end @interface OHEvdevGameControllerProfile: OHGameControllerProfile - (instancetype)oh_initWithButtons: (OFDictionary *)buttons axes: (OFDictionary *)axes OF_METHOD_FAMILY(init); @end static const uint16_t buttonIDs[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_TL2, BTN_TR2, BTN_SELECT, BTN_START, BTN_MODE, BTN_THUMBL, BTN_THUMBR, BTN_DPAD_UP, BTN_DPAD_DOWN, BTN_DPAD_LEFT, BTN_DPAD_RIGHT, |
︙ | ︙ | |||
112 113 114 115 116 117 118 | case BTN_MODE: return @"Mode"; case BTN_THUMBL: return @"Thumb L"; case BTN_THUMBR: return @"Thumb R"; case BTN_DPAD_UP: | | | | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | case BTN_MODE: return @"Mode"; case BTN_THUMBL: return @"Thumb L"; case BTN_THUMBR: return @"Thumb R"; case BTN_DPAD_UP: return @"D-Pad Up"; case BTN_DPAD_DOWN: return @"D-Pad Down"; case BTN_DPAD_LEFT: return @"D-Pad Left"; case BTN_DPAD_RIGHT: return @"D-Pad Right"; case BTN_TRIGGER_HAPPY1: return @"Trigger Happy 1"; case BTN_TRIGGER_HAPPY2: return @"Trigger Happy 2"; case BTN_TRIGGER_HAPPY3: return @"Trigger Happy 3"; case BTN_TRIGGER_HAPPY4: |
︙ | ︙ | |||
282 283 284 285 286 287 288 | if (![device hasPrefix: @"event"]) continue; path = [@"/dev/input" stringByAppendingPathComponent: device]; @try { controller = [[[OHEvdevGameController alloc] | | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | if (![device hasPrefix: @"event"]) continue; path = [@"/dev/input" stringByAppendingPathComponent: device]; @try { controller = [[[OHEvdevGameController alloc] oh_initWithPath: path] autorelease]; } @catch (OFOpenItemFailedException *e) { if (e.errNo == EACCES) continue; @throw e; } @catch (OFInvalidArgumentException *e) { /* Not a game controller. */ |
︙ | ︙ | |||
304 305 306 307 308 309 310 | [controllers makeImmutable]; objc_autoreleasePoolPop(pool); return controllers; } | | | 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | [controllers makeImmutable]; objc_autoreleasePoolPop(pool); return controllers; } - (instancetype)oh_initWithPath: (OFString *)path { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFStringEncoding encoding = [OFLocale encoding]; struct input_id inputID; |
︙ | ︙ | |||
411 412 413 414 415 416 417 | [axes setObject: axis forKey: axisName]; } } } [axes makeImmutable]; _rawProfile = [[OHEvdevGameControllerProfile alloc] | | | | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | [axes setObject: axis forKey: axisName]; } } } [axes makeImmutable]; _rawProfile = [[OHEvdevGameControllerProfile alloc] oh_initWithButtons: buttons axes: axes]; [self oh_pollState]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
452 453 454 455 456 457 458 | } - (OFNumber *)productID { return [OFNumber numberWithUnsignedShort: _productID]; } | | | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | } - (OFNumber *)productID { return [OFNumber numberWithUnsignedShort: _productID]; } - (void)oh_pollState { unsigned long keyState[OFRoundUpToPowerOf2(OF_ULONG_BIT, KEY_MAX) / OF_ULONG_BIT] = { 0 }; if (ioctl(_fd, EVIOCGKEY(sizeof(keyState)), &keyState) == -1) @throw [OFReadFailedException exceptionWithObject: self |
︙ | ︙ | |||
545 546 547 548 549 550 551 | requestedLength: sizeof(event) errNo: errno]; } if (_discardUntilReport) { if (event.type == EV_SYN && event.value == SYN_REPORT) { _discardUntilReport = false; | | | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | requestedLength: sizeof(event) errNo: errno]; } if (_discardUntilReport) { if (event.type == EV_SYN && event.value == SYN_REPORT) { _discardUntilReport = false; [self oh_pollState]; } continue; } switch (event.type) { case EV_SYN: |
︙ | ︙ | |||
590 591 592 593 594 595 596 597 598 599 600 601 602 603 | axis.value = scale(event.value, axis->_minValue, axis->_maxValue); break; } } } - (OFComparisonResult)compare: (OHEvdevGameController *)otherController { unsigned long long selfIndex, otherIndex; if (![otherController isKindOfClass: [OHEvdevGameController class]]) @throw [OFInvalidArgumentException exception]; | > > > > > > > > > > | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | axis.value = scale(event.value, axis->_minValue, axis->_maxValue); break; } } } - (OHGamepad *)gamepad { @try { return [[[OHEvdevGamepad alloc] initWithController: self] autorelease]; } @catch (OFInvalidArgumentException *e) { return nil; } } - (OFComparisonResult)compare: (OHEvdevGameController *)otherController { unsigned long long selfIndex, otherIndex; if (![otherController isKindOfClass: [OHEvdevGameController class]]) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
615 616 617 618 619 620 621 | } @end @implementation OHEvdevGameControllerAxis @end @implementation OHEvdevGameControllerProfile | | | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 | } @end @implementation OHEvdevGameControllerAxis @end @implementation OHEvdevGameControllerProfile - (instancetype)oh_initWithButtons: (OFDictionary *)buttons axes: (OFDictionary *)axes { self = [super init]; @try { _buttons = [buttons retain]; _axes = [axes retain]; |
︙ | ︙ |
Added src/hid/OHEvdevGamepad.h version [f433593f5a].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im> * * 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 * <https://www.gnu.org/licenses/>. */ #import "OHGamepad.h" OF_ASSUME_NONNULL_BEGIN @class OHEvdevGameController; @class OHGameControllerProfile; @interface OHEvdevGamepad: OHGamepad { OHGameControllerProfile *_rawProfile; } - (instancetype)initWithController: (OHEvdevGameController *)controller; @end OF_ASSUME_NONNULL_END |
Added src/hid/OHEvdevGamepad.m version [a03c43c125].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | /* * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im> * * 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 * <https://www.gnu.org/licenses/>. */ #include "config.h" #import "OHEvdevGamepad.h" #import "OFDictionary.h" #import "OHEvdevGameController.h" #import "OHGameControllerDirectionalPad.h" #import "OHGameControllerEmulatedTriggerButton.h" #import "OFInvalidArgumentException.h" @implementation OHEvdevGamepad - (instancetype)initWithController: (OHEvdevGameController *)controller { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); _rawProfile = [controller.rawProfile retain]; if (self.northButton == nil || self.southButton == nil || self.westButton == nil || self.eastButton == nil || self.leftShoulderButton == nil || self.rightShoulderButton == nil || self.leftTriggerButton == nil || self.rightTriggerButton == nil || self.leftThumbstickButton == nil || self.rightThumbstickButton == nil || self.menuButton == nil || self.optionsButton == nil || self.homeButton == nil || self.leftThumbstick == nil || self.rightThumbstick == nil || self.directionalPad == nil) @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_rawProfile release]; [super dealloc]; } - (OFDictionary OF_GENERIC(OFString *, OHGameControllerButton *) *)buttons { return [OFDictionary dictionaryWithKeysAndObjects: @"North", self.northButton, @"South", self.southButton, @"West", self.westButton, @"East", self.eastButton, @"Left Shoulder", self.leftShoulderButton, @"Right Shoulder", self.rightShoulderButton, @"Left Trigger", self.leftTriggerButton, @"Right Trigger", self.rightTriggerButton, @"Left Thumbstick", self.leftThumbstickButton, @"Right Thumbstick", self.rightThumbstickButton, @"Menu", self.menuButton, @"Options", self.optionsButton, @"Home", self.homeButton, nil]; } - (OFDictionary OF_GENERIC(OFString *, OHGameControllerAxis *) *)axes { return [OFDictionary dictionary]; } - (OFDictionary OF_GENERIC(OFString *, OHGameControllerDirectionalPad *) *) directionalPads { return [OFDictionary dictionaryWithKeysAndObjects: @"Left Thumbstick", self.leftThumbstick, @"Right Thumbstick", self.rightThumbstick, @"D-Pad", self.directionalPad, nil]; } - (OHGameControllerButton *)northButton { return [_rawProfile.buttons objectForKey: @"Y"]; } - (OHGameControllerButton *)southButton { return [_rawProfile.buttons objectForKey: @"A"]; } - (OHGameControllerButton *)westButton { return [_rawProfile.buttons objectForKey: @"X"]; } - (OHGameControllerButton *)eastButton { return [_rawProfile.buttons objectForKey: @"B"]; } - (OHGameControllerButton *)leftShoulderButton { return [_rawProfile.buttons objectForKey: @"TL"]; } - (OHGameControllerButton *)rightShoulderButton { return [_rawProfile.buttons objectForKey: @"TR"]; } - (OHGameControllerButton *)leftTriggerButton { OHGameControllerAxis *axis = [_rawProfile.axes objectForKey: @"Z"]; if (axis != nil) return [[[OHGameControllerEmulatedTriggerButton alloc] initWithAxis: axis] autorelease]; return [_rawProfile.buttons objectForKey: @"TL2"]; } - (OHGameControllerButton *)rightTriggerButton { OHGameControllerAxis *axis = [_rawProfile.axes objectForKey: @"RZ"]; if (axis != nil) return [[[OHGameControllerEmulatedTriggerButton alloc] initWithAxis: axis] autorelease]; return [_rawProfile.buttons objectForKey: @"TR2"]; } - (OHGameControllerButton *)leftThumbstickButton { return [_rawProfile.buttons objectForKey: @"Thumb L"]; } - (OHGameControllerButton *)rightThumbstickButton { return [_rawProfile.buttons objectForKey: @"Thumb R"]; } - (OHGameControllerButton *)menuButton { return [_rawProfile.buttons objectForKey: @"Start"]; } - (OHGameControllerButton *)optionsButton { return [_rawProfile.buttons objectForKey: @"Select"]; } - (OHGameControllerButton *)homeButton { return [_rawProfile.buttons objectForKey: @"Mode"]; } - (OHGameControllerDirectionalPad *)leftThumbstick { OHGameControllerAxis *xAxis = [_rawProfile.axes objectForKey: @"X"]; OHGameControllerAxis *yAxis = [_rawProfile.axes objectForKey: @"Y"]; if (xAxis == nil || yAxis == nil) return nil; return [[[OHGameControllerDirectionalPad alloc] initWithName: @"Left Thumbstick" xAxis: xAxis yAxis: yAxis] autorelease]; } - (OHGameControllerDirectionalPad *)rightThumbstick { OHGameControllerAxis *xAxis = [_rawProfile.axes objectForKey: @"RX"]; OHGameControllerAxis *yAxis = [_rawProfile.axes objectForKey: @"RY"]; if (xAxis == nil || yAxis == nil) return nil; return [[[OHGameControllerDirectionalPad alloc] initWithName: @"Right Thumbstick" xAxis: xAxis yAxis: yAxis] autorelease]; } - (OHGameControllerDirectionalPad *)directionalPad { OHGameControllerAxis *xAxis = [_rawProfile.axes objectForKey: @"HAT0X"]; OHGameControllerAxis *yAxis = [_rawProfile.axes objectForKey: @"HAT0Y"]; OHGameControllerButton *upButton, *downButton; OHGameControllerButton *leftButton, *rightButton; if (xAxis != nil && yAxis != nil) return [[[OHGameControllerDirectionalPad alloc] initWithName: @"D-Pad" xAxis: xAxis yAxis: yAxis] autorelease]; upButton = [_rawProfile.buttons objectForKey: @"D-Pad Up"]; downButton = [_rawProfile.buttons objectForKey: @"D-Pad Down"]; leftButton = [_rawProfile.buttons objectForKey: @"D-Pad Left"]; rightButton = [_rawProfile.buttons objectForKey: @"D-Pad Right"]; if (upButton != nil && downButton != nil && leftButton != nil && rightButton != nil) return [[[OHGameControllerDirectionalPad alloc] initWithName: @"D-Pad" upButton: upButton downButton: downButton leftButton: leftButton rightButton: rightButton] autorelease]; return nil; } @end |
Modified src/hid/OHGameController.h from [f4bfdcdd03] to [5443a68735].
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #endif OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFNumber; @class OHGameControllerProfile; /** * @class OHGameController OHGameController.h ObjFWHID/OHGameController.h * * @brief A class for reading state from a game controller. */ @interface OHGameController: OFObject | > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #endif OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFNumber; @class OHGameControllerProfile; @class OHGamepad; /** * @class OHGameController OHGameController.h ObjFWHID/OHGameController.h * * @brief A class for reading state from a game controller. */ @interface OHGameController: OFObject |
︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 80 | /** * @brief The raw profile for the game controller, meaning no remapping is * being performed. */ @property (readonly, nonatomic) OHGameControllerProfile *rawProfile; /** * @brief Returns the available controllers. * * @return The available controllers */ + (OFArray OF_GENERIC(OHGameController *) *)controllers; | > > > > > > | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | /** * @brief The raw profile for the game controller, meaning no remapping is * being performed. */ @property (readonly, nonatomic) OHGameControllerProfile *rawProfile; /** * @brief The gamepad profile for the game controller, or `nil` if not * supported. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OHGamepad *gamepad; /** * @brief Returns the available controllers. * * @return The available controllers */ + (OFArray OF_GENERIC(OHGameController *) *)controllers; |
︙ | ︙ |
Modified src/hid/OHGameController.m from [350c5f09f7] to [48b11dd8fc].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include "config.h" #import "OHGameController.h" #import "OFArray.h" #import "OFNumber.h" #import "OFSet.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include "OHEvdevGameController.h" #endif @implementation OHGameController @dynamic name, rawProfile; | > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include "config.h" #import "OHGameController.h" #import "OFArray.h" #import "OFNumber.h" #import "OFSet.h" #import "OHGamepad.h" #if defined(OF_LINUX) && defined(OF_HAVE_FILES) # include "OHEvdevGameController.h" #endif @implementation OHGameController @dynamic name, rawProfile; |
︙ | ︙ | |||
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | return nil; } - (void)retrieveState { OF_UNRECOGNIZED_SELECTOR } - (OFString *)description { if (self.vendorID != nil && self.productID != nil) return [OFString stringWithFormat: @"<%@: %@ [%04X:%04X]>", self.class, self.name, self.vendorID.unsignedShortValue, self.productID.unsignedShortValue]; else return [OFString stringWithFormat: @"<%@: %@>", self.class, self.name]; } @end | > > > > > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | return nil; } - (void)retrieveState { OF_UNRECOGNIZED_SELECTOR } - (OHGamepad *)gamepad { return nil; } - (OFString *)description { if (self.vendorID != nil && self.productID != nil) return [OFString stringWithFormat: @"<%@: %@ [%04X:%04X]>", self.class, self.name, self.vendorID.unsignedShortValue, self.productID.unsignedShortValue]; else return [OFString stringWithFormat: @"<%@: %@>", self.class, self.name]; } @end |
Modified src/hid/OHGameControllerEmulatedButton.m from [1d9492427b] to [eefaf93827].
︙ | ︙ | |||
18 19 20 21 22 23 24 | */ #include "config.h" #import "OHGameControllerEmulatedButton.h" #import "OHGameControllerAxis.h" | | < | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | */ #include "config.h" #import "OHGameControllerEmulatedButton.h" #import "OHGameControllerAxis.h" @implementation OHGameControllerEmulatedButton - (instancetype)initWithName: (OFString *)name { OF_INVALID_INIT_METHOD } - (instancetype)initWithAxis: (OHGameControllerAxis *)axis positive: (bool)positive { void *pool = objc_autoreleasePoolPush(); OFString *name; @try { name = [OFString stringWithFormat: @"%@%c", axis.name, (positive ? '+' : '-')]; } @catch (id e) { [self release]; @throw e; } self = [super initWithName: name]; |
︙ | ︙ | |||
63 64 65 66 67 68 69 70 | - (bool)isPressed { if (_positive) return (_axis.value > 0); else return (_axis.value < 0); } @end | > > > > > | 62 63 64 65 66 67 68 69 70 71 72 73 74 | - (bool)isPressed { if (_positive) return (_axis.value > 0); else return (_axis.value < 0); } - (float)value { return (self.isPressed ? 1 : 0); } @end |
Added src/hid/OHGameControllerEmulatedTriggerButton.h version [15a75f9011].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im> * * 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 * <https://www.gnu.org/licenses/>. */ #import "OHGameControllerButton.h" OF_ASSUME_NONNULL_BEGIN @class OHGameControllerAxis; OF_SUBCLASSING_RESTRICTED @interface OHGameControllerEmulatedTriggerButton: OHGameControllerButton { OHGameControllerAxis *_axis; } - (instancetype)initWithName: (OFString *)name OF_UNAVAILABLE; - (instancetype)initWithAxis: (OHGameControllerAxis *)axis; @end OF_ASSUME_NONNULL_END |
Added src/hid/OHGameControllerEmulatedTriggerButton.m version [249698b888].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /* * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im> * * 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 * <https://www.gnu.org/licenses/>. */ #include "config.h" #import "OHGameControllerEmulatedTriggerButton.h" #import "OHGameControllerAxis.h" @implementation OHGameControllerEmulatedTriggerButton - (instancetype)initWithName: (OFString *)name { OF_INVALID_INIT_METHOD } - (instancetype)initWithAxis: (OHGameControllerAxis *)axis { void *pool = objc_autoreleasePoolPush(); OFString *name; @try { name = axis.name; } @catch (id e) { [self release]; @throw e; } self = [super initWithName: name]; objc_autoreleasePoolPop(pool); _axis = [axis retain]; return self; } - (void)dealloc { [_axis release]; [super dealloc]; } - (bool)isPressed { return (_axis.value > -1); } - (float)value { return (_axis.value + 1) / 2; } @end |
Modified src/hid/OHGameControllerProfile.m from [e824f05e06] to [c4be5284ad].
︙ | ︙ | |||
18 19 20 21 22 23 24 | */ #include "config.h" #import "OHGameControllerProfile.h" #import "OFDictionary.h" | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | */ #include "config.h" #import "OHGameControllerProfile.h" #import "OFDictionary.h" @implementation OHGameControllerProfile @synthesize buttons = _buttons, axes = _axes; @synthesize directionalPads = _directionalPads; - (void)dealloc { [_buttons release]; [_axes release]; |
︙ | ︙ |
Added src/hid/OHGamepad.h version [823c3e7afc].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | /* * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im> * * 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 * <https://www.gnu.org/licenses/>. */ #import "OHGameControllerProfile.h" OF_ASSUME_NONNULL_BEGIN /** * @class OHGamepad OHGamepad.h ObjFWHID/OHGamepad.h * * @brief A game controller profile representing a gamepad. */ @interface OHGamepad: OHGameControllerProfile { OF_RESERVE_IVARS(OHGamepad, 4) } @property (readonly, nonatomic) OHGameControllerButton *northButton; @property (readonly, nonatomic) OHGameControllerButton *southButton; @property (readonly, nonatomic) OHGameControllerButton *westButton; @property (readonly, nonatomic) OHGameControllerButton *eastButton; @property (readonly, nonatomic) OHGameControllerButton *leftShoulderButton; @property (readonly, nonatomic) OHGameControllerButton *rightShoulderButton; @property (readonly, nonatomic) OHGameControllerButton *leftTriggerButton; @property (readonly, nonatomic) OHGameControllerButton *rightTriggerButton; @property (readonly, nonatomic) OHGameControllerButton *leftThumbstickButton; @property (readonly, nonatomic) OHGameControllerButton *rightThumbstickButton; @property (readonly, nonatomic) OHGameControllerButton *menuButton; @property (readonly, nonatomic) OHGameControllerButton *optionsButton; @property (readonly, nonatomic) OHGameControllerButton *homeButton; @property (readonly, nonatomic) OHGameControllerDirectionalPad *leftThumbstick; @property (readonly, nonatomic) OHGameControllerDirectionalPad *rightThumbstick; @property (readonly, nonatomic) OHGameControllerDirectionalPad *directionalPad; @end OF_ASSUME_NONNULL_END |
Added src/hid/OHGamepad.m version [422aa06dbe].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im> * * 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 * <https://www.gnu.org/licenses/>. */ #include "config.h" #import "OHGamepad.h" @implementation OHGamepad @dynamic northButton, southButton, westButton, eastButton, leftShoulderButton; @dynamic rightShoulderButton, leftTriggerButton, rightTriggerButton; @dynamic leftThumbstickButton, rightThumbstickButton, menuButton, optionsButton; @dynamic homeButton, leftThumbstick, rightThumbstick, directionalPad; @end |
Modified src/test/OTTestCase.m from [b5276549e5] to [8b6fdc9a7d].
︙ | ︙ | |||
17 18 19 20 21 22 23 | * <https://www.gnu.org/licenses/>. */ #include "config.h" #import "OTTestCase.h" | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | * <https://www.gnu.org/licenses/>. */ #include "config.h" #import "OTTestCase.h" @implementation OTTestCase + (OFArray OF_GENERIC(OFPair OF_GENERIC(OFString *, id) *) *)summary { return nil; } - (void)setUp { |
︙ | ︙ |
Modified tests/gamecontroller/GameControllerTests.m from [049667648c] to [d73797114c].
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #import "OFNumber.h" #import "OFStdIOStream.h" #import "OFThread.h" #import "OHGameController.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerProfile.h" #import "OFReadFailedException.h" #if defined(OF_NINTENDO_DS) static size_t buttonsPerLine = 2; #elif defined(OF_NINTENDO_3DS) static size_t buttonsPerLine = 3; | > > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #import "OFNumber.h" #import "OFStdIOStream.h" #import "OFThread.h" #import "OHGameController.h" #import "OHGameControllerAxis.h" #import "OHGameControllerButton.h" #import "OHGameControllerDirectionalPad.h" #import "OHGameControllerProfile.h" #import "OHGamepad.h" #import "OFReadFailedException.h" #if defined(OF_NINTENDO_DS) static size_t buttonsPerLine = 2; #elif defined(OF_NINTENDO_3DS) static size_t buttonsPerLine = 3; |
︙ | ︙ | |||
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | @end OF_APPLICATION_DELEGATE(GameControllerTests) @implementation GameControllerTests - (void)applicationDidFinishLaunching: (OFNotification *)notification { #if defined(OF_WII) || defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) [OFStdIOStream setUpConsole]; #endif for (;;) { void *pool = objc_autoreleasePoolPush(); if (_lastControllersUpdate == nil || -[_lastControllersUpdate timeIntervalSinceNow] > 1) { [_controllers release]; [_lastControllersUpdate release]; _controllers = [[OHGameController controllers] mutableCopy]; _lastControllersUpdate = [[OFDate alloc] init]; [OFStdOut clear]; } [OFStdOut setCursorPosition: OFMakePoint(0, 0)]; for (OHGameController *controller in _controllers) { | > > > > > | | > > | | | > > | < < < < < | > | > | | > > | | > > > > | > | > | > > > > > > | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | @end OF_APPLICATION_DELEGATE(GameControllerTests) @implementation GameControllerTests - (void)applicationDidFinishLaunching: (OFNotification *)notification { bool gamepad = false; #if defined(OF_WII) || defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) [OFStdIOStream setUpConsole]; #endif if ([[OFApplication arguments].firstObject isEqual: @"gamepad"]) gamepad = true; for (;;) { void *pool = objc_autoreleasePoolPush(); if (_lastControllersUpdate == nil || -[_lastControllersUpdate timeIntervalSinceNow] > 1) { [_controllers release]; [_lastControllersUpdate release]; _controllers = [[OHGameController controllers] mutableCopy]; _lastControllersUpdate = [[OFDate alloc] init]; [OFStdOut clear]; } [OFStdOut setCursorPosition: OFMakePoint(0, 0)]; for (OHGameController *controller in _controllers) { OHGameControllerProfile *profile = (gamepad ? controller.gamepad : controller.rawProfile); OFArray OF_GENERIC(OFString *) *buttons = profile.buttons.allKeys.sortedArray; OFArray OF_GENERIC(OFString *) *axes = profile.axes.allKeys.sortedArray; OFArray OF_GENERIC(OFString *) *directionalPads = profile.directionalPads.allKeys.sortedArray; size_t i; [OFStdOut setForegroundColor: [OFColor green]]; [OFStdOut writeLine: controller.description]; @try { [controller retrieveState]; } @catch (OFReadFailedException *e) { [OFStdOut setForegroundColor: [OFColor red]]; [OFStdOut writeString: e.description]; continue; } i = 0; for (OFString *name in buttons) { OHGameControllerButton *button = [profile.buttons objectForKey: name]; if (i++ == buttonsPerLine) { [OFStdOut writeString: @"\n"]; i = 0; } if (button.value == 1) [OFStdOut setForegroundColor: [OFColor red]]; else if (button.value > 0.5) [OFStdOut setForegroundColor: [OFColor yellow]]; else if (button.value > 0) [OFStdOut setForegroundColor: [OFColor green]]; else [OFStdOut setForegroundColor: [OFColor gray]]; [OFStdOut writeFormat: @"[%@] ", name]; } [OFStdOut setForegroundColor: [OFColor gray]]; [OFStdOut writeString: @"\n"]; i = 0; for (OFString *name in axes) { OHGameControllerAxis *axis = [profile.axes objectForKey: name]; if (i++ == buttonsPerLine) { [OFStdOut writeString: @"\n"]; i = 0; } [OFStdOut writeFormat: @"%@: %5.2f ", name, axis.value]; } if (axes.count > 0) [OFStdOut writeString: @"\n"]; i = 0; for (OFString *name in directionalPads) { OHGameControllerDirectionalPad *directionalPad = [profile.directionalPads objectForKey: name]; if (i++ == 2) { [OFStdOut writeString: @"\n"]; i = 0; } [OFStdOut writeFormat: @"%@: (%5.2f, %5.2f) ", name, directionalPad.xAxis.value, directionalPad.yAxis.value]; } if (directionalPads.count > 0) [OFStdOut writeString: @"\n"]; } #if defined(OF_WII) || defined(OF_NINTENDO_DS) || defined(OF_NINTENDO_3DS) [OFThread waitForVerticalBlank]; #else [OFThread sleepForTimeInterval: 1.f / 60.f]; #endif objc_autoreleasePoolPop(pool); } } @end |