Oolite 1.91.0.7646-241128-10e222e
Loading...
Searching...
No Matches
OOMacJoystickManager Class Reference

#include <OOMacJoystickManager.h>

+ Inheritance diagram for OOMacJoystickManager:
+ Collaboration diagram for OOMacJoystickManager:

Instance Methods

(id) - init [implementation]
 
(void) - dealloc [implementation]
 
(NSUInteger) - joystickCount [implementation]
 
(void) - handleDeviceAttach: [implementation]
 
(void) - handleJoystickAttach: [implementation]
 
(void) - handleDeviceRemoval: [implementation]
 
(void) - handleInputEvent: [implementation]
 
(NSString *) - nameOfJoystick: [implementation]
 
(int16_t) - getAxisWithStick:axis: [implementation]
 
- Instance Methods inherited from OOJoystickManager
(NSPoint) - rollPitchAxis
 
(NSPoint) - viewAxis
 
(void) - setFunction:withDict:
 
(void) - unsetAxisFunction:
 
(void) - unsetButtonFunction:
 
(BOOL) - isButtonDown:stick:
 
(BOOL) - getButtonState:
 
(double) - getAxisState:
 
(double) - getSensitivity
 
(void) - setProfile:forAxis:
 
(OOJoystickAxisProfile *) - getProfileForAxis:
 
(void) - saveProfileForAxis:
 
(void) - loadProfileForAxis:
 
(const BOOL *) - getAllButtonStates
 
(NSArray *) - listSticks
 
(NSDictionary *) - axisFunctions
 
(NSDictionary *) - buttonFunctions
 
(void) - setCallback:object:hardware:
 
(void) - clearCallback
 
(void) - setDefaultMapping
 
(void) - clearMappings
 
(void) - clearStickStates
 
(void) - clearStickButtonState:
 
(void) - decodeAxisEvent:
 
(void) - decodeButtonEvent:
 
(void) - decodeHatEvent:
 
(void) - saveStickSettings
 
(void) - loadStickSettings
 
(void) - setFunctionForAxis:function:stick: [implementation]
 
(void) - setFunctionForButton:function:stick: [implementation]
 

Class Methods

(static int+ AxisIndex [implementation]
 
(static uint8_t) + MapHatValue [implementation]
 
- Class Methods inherited from OOJoystickManager
(id) + sharedStickHandler
 
(BOOL) + setStickHandlerClass:
 

Private Attributes

IOHIDManagerRef hidManager
 
CFMutableArrayRef devices
 
int gammaTable [kJoystickGammaTableSize]
 

Detailed Description

Definition at line 40 of file OOMacJoystickManager.h.

Method Documentation

◆ AxisIndex

+ (static int) AxisIndex (uint32_t) page
(uint32_t) usage 
implementation

Definition at line 181 of file OOMacJoystickManager.m.

182{
183 /*
184 Map axis-like HID usages to SDL-like axis indices. These are all the
185 commonly used joystick axes according to Microsoft's DirectInput
186 documentation (hey, you've got to get your info somewhere).
187
188 GD_Slider, GD_Dial, DG_Wheel and Sim_Throttle are actually distinct;
189 unlike the others, they're uncentered. (By implication,
190 IOHIDElementHasPreferredState() should be false.) This should, in
191 particular, be considered when mapping to the throttle: centered axes
192 should provide relative input (for gamepads), while uncentered ones
193 should provide absolute input. Since that festering pool of pus, SDL,
194 can't make this distinction, OOJoystickManager can't either (yet).
195 -- Ahruman 2011-01-04
196 */
197
198 switch (page)
199 {
200 case kHIDPage_GenericDesktop:
201 switch (usage)
202 {
203 case kHIDUsage_GD_X: return 0;
204 case kHIDUsage_GD_Y: return 1;
205 case kHIDUsage_GD_Z: return 2;
206 case kHIDUsage_GD_Rx: return 3;
207 case kHIDUsage_GD_Ry: return 4;
208 case kHIDUsage_GD_Rz: return 5;
209 case kHIDUsage_GD_Slider: return 6;
210 case kHIDUsage_GD_Dial: return 7;
211 case kHIDUsage_GD_Wheel: return 8;
212 }
213 break;
214
215 case kHIDPage_Simulation:
216 switch (usage)
217 {
218 case kHIDUsage_Sim_Throttle:
219 return 9;
220 }
221 }
222
223 // Negative numbers indicate non-axis.
224 return -1;
225}

◆ dealloc

- (void) dealloc
implementation

Definition at line 365 of file OOMacJoystickManager.m.

90{
91 if (hidManager != NULL) CFRelease(hidManager);
92 if (devices != NULL) CFRelease(devices);
93
94 [super dealloc];
95}
CFMutableArrayRef devices

◆ getAxisWithStick:axis:

- (int16_t) getAxisWithStick: (NSUInteger) stickNum
axis: (NSUInteger) axisNum 
implementation

Reimplemented from OOJoystickManager.

Definition at line 228 of file OOMacJoystickManager.m.

340 :(NSUInteger) stickNum axis:(NSUInteger) axisNum
341{
342 return 0;
343}

References JOYHAT_CENTERED, JOYHAT_DOWN, JOYHAT_LEFT, JOYHAT_LEFTDOWN, JOYHAT_LEFTUP, JOYHAT_RIGHT, JOYHAT_RIGHTDOWN, JOYHAT_RIGHTUP, and JOYHAT_UP.

◆ handleDeviceAttach:

- (void) handleDeviceAttach: (IOHIDDeviceRef) device
implementation

Definition at line 365 of file OOMacJoystickManager.m.

104 :(IOHIDDeviceRef)device
105{
106 NSArray *usagePairs = (NSArray *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDDeviceUsagePairsKey));
107
108 for (NSDictionary *pair in usagePairs)
109 {
110 if ([pair oo_unsignedIntForKey:@kIOHIDDeviceUsagePageKey] == kHIDPage_GenericDesktop)
111 {
112 unsigned usage = [pair oo_unsignedIntForKey:@kIOHIDDeviceUsageKey];
113 if (usage == kHIDUsage_GD_Joystick || usage == kHIDUsage_GD_GamePad)
114 {
115 [self handleJoystickAttach:device];
116 return;
117 }
118 }
119 }
120
121 if (OOLogWillDisplayMessagesInClass(@"joystick.reject"))
122 {
123 NSString *product = (NSString *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
124 unsigned usagePage = [(NSNumber *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDPrimaryUsagePageKey)) unsignedIntValue];
125 unsigned usage = [(NSNumber *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDPrimaryUsageKey)) unsignedIntValue];
126 OOLog(@"joystick.reject", @"Ignoring HID device: %@ (primary usage %u:%u)", product, usagePage, usage);
127 }
128}
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
Definition OOLogging.m:144
#define OOLog(class, format,...)
Definition OOLogging.h:88

◆ handleDeviceRemoval:

- (void) handleDeviceRemoval: (IOHIDDeviceRef) device
implementation

Definition at line 365 of file OOMacJoystickManager.m.

172 :(IOHIDDeviceRef)device
173{
174 OOLog(@"joystick.remove", @"Joystick removed: %@", IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)));
175
176 CFIndex index = CFArrayGetFirstIndexOfValue(devices, CFRangeMake(0, CFArrayGetCount(devices)), device);
177 if (index != kCFNotFound) CFArrayRemoveValueAtIndex(devices, index);
178}

◆ handleInputEvent:

- (void) handleInputEvent: (IOHIDValueRef) value
implementation

Definition at line 228 of file OOMacJoystickManager.m.

253 :(IOHIDValueRef)value
254{
255 IOHIDElementRef element = IOHIDValueGetElement(value);
256 uint32_t usagePage = IOHIDElementGetUsagePage(element);
257 uint32_t usage = IOHIDElementGetUsage(element);
258 int buttonNum = 0;
259 int axisNum = 0;
260
261 axisNum = AxisIndex(usagePage, usage);
262 if (axisNum >= 0)
263 {
264 JoyAxisEvent evt;
265 evt.type = JOYAXISMOTION;
266 evt.which = 0;
267 evt.axis = axisNum;
268
269 CFIndex intValue = IOHIDValueGetIntegerValue(value);
270 CFIndex min = IOHIDElementGetLogicalMin(element);
271 CFIndex max = IOHIDElementGetLogicalMax(element);
272 float axisValue = (float)(intValue - min) / (float)(max + 1 - min);
273
274 // Note: this is designed so gammaIndex == intValue if min == 0 and max == kJoystickGammaTableSize - 1 (the common case).
275 unsigned gammaIndex = floor(axisValue * kJoystickGammaTableSize);
276
277 /*
278 CRASH: r4435, Mac OS X 10.6.6, x86_64 -[OOMacJoystickManager handleInputEvent:] + 260
279 http://aegidian.org/bb/viewtopic.php?f=3&t=9382
280 The instruction is:
281 movl (%r15,%rbx,4), %r12d
282 which corresponds to the load gammaTable[gammaIndex].
283 Check added to find out-of-range values.
284 -- Ahruman 2011-03-07
285 */
286 if (EXPECT_NOT(gammaIndex > kJoystickGammaTableSize))
287 {
288 OOLogERR(@"joystick.gamma.overflow", @"Joystick gamma table overflow - gammaIndex is %u of %u. Raw value: %i in [%i..%i]; axisValue: %g; unrounded gammaIndex: %g. Ignoring event. This is an internal error, please report it.",
289 gammaIndex, kJoystickGammaTableSize,
290 (int)intValue, (int)min, (int)max,
291 axisValue,
292 axisValue * kJoystickGammaTableSize
293 );
294
295 return;
296 }
297 // End bug check
298
299 evt.value = gammaTable[gammaIndex];
300 [self decodeAxisEvent:&evt];
301 }
302 else if (usagePage == kHIDPage_GenericDesktop && usage == kHIDUsage_GD_Hatswitch)
303 {
304 CFIndex max = IOHIDElementGetLogicalMax(element);
305 CFIndex min = IOHIDElementGetLogicalMin(element);
306
307 JoyHatEvent evt =
308 {
309 .type = JOYHAT_MOTION,
310 .which = 0,
311 .hat = 0, // The abuse of usage values for identifying elements means we can't distinguish between hats.
312 .value = MapHatValue(IOHIDValueGetIntegerValue(value) - min, max - min)
313 };
314
315 [self decodeHatEvent:&evt];
316 }
317 else if (usagePage == kHIDPage_Button)
318 {
319 // Button Event
320 buttonNum = usage;
321 JoyButtonEvent evt;
322 BOOL buttonState = (IOHIDValueGetIntegerValue(value) != 0);
323 evt.type = buttonState ? JOYBUTTONDOWN : JOYBUTTONUP;
324 evt.which = 0;
325 evt.button = buttonNum;
326 evt.state = buttonState ? 1 : 0;
327 [self decodeButtonEvent:&evt];
328 }
329}
#define EXPECT_NOT(x)
@ JOYHAT_MOTION
@ JOYBUTTONUP
@ JOYAXISMOTION
@ JOYBUTTONDOWN
#define OOLogERR(class, format,...)
Definition OOLogging.h:112
@ kJoystickGammaTableSize
static int AxisIndex(uint32_t page, uint32_t usage)
static uint8_t MapHatValue(CFIndex value, CFIndex max)
int gammaTable[kJoystickGammaTableSize]

◆ handleJoystickAttach:

- (void) handleJoystickAttach: (IOHIDDeviceRef) device
implementation

Definition at line 365 of file OOMacJoystickManager.m.

131 :(IOHIDDeviceRef)device
132{
133 OOLog(@"joystick.connect", @"Joystick connected: %@", IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)));
134
135 CFArrayAppendValue(devices, device);
136 IOHIDDeviceRegisterInputValueCallback(device, HandleInputValueCallback, self);
137
138 if (OOLogWillDisplayMessagesInClass(@"joystick.connect.element"))
139 {
140 // Print out elements of new device
141 CFArrayRef elementList = IOHIDDeviceCopyMatchingElements(device, NULL, 0L);
142 if (elementList != NULL)
143 {
144 OOLogIndent();
145
146 CFIndex idx, count = CFArrayGetCount(elementList);
147
148 for (idx = 0; idx < count; idx++)
149 {
150 IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elementList, idx);
151 IOHIDElementType elementType = IOHIDElementGetType(element);
152 if (elementType > kIOHIDElementTypeInput_ScanCodes)
153 {
154 continue;
155 }
156 IOHIDElementCookie elementCookie = IOHIDElementGetCookie(element);
157 uint32_t usagePage = IOHIDElementGetUsagePage(element);
158 uint32_t usage = IOHIDElementGetUsage(element);
159 uint32_t min = (uint32_t)IOHIDElementGetPhysicalMin(element);
160 uint32_t max = (uint32_t)IOHIDElementGetPhysicalMax(element);
161 NSString *name = (NSString *)IOHIDElementGetProperty(element, CFSTR(kIOHIDElementNameKey)) ?: @"unnamed";
162 OOLog(@"joystick.connect.element", @"%@ - usage %d:%d, cookie %d, range %d-%d", name, usagePage, usage, (int) elementCookie, min, max);
163 }
164
165 OOLogOutdent();
166 CFRelease(elementList);
167 }
168 }
169}
void OOLogOutdent(void)
Definition OOLogging.m:376
void OOLogIndent(void)
Definition OOLogging.m:366
static void HandleInputValueCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDValueRef inIOHIDValueRef)
unsigned count

◆ init

- (id) init
implementation

Reimplemented from OOJoystickManager.

Definition at line 365 of file OOMacJoystickManager.m.

48{
49 if ((self = [super init]))
50 {
51 // Initialise gamma table
52 int i;
53 for (i = 0; i< kJoystickGammaTableSize; i++)
54 {
55 double x = ((double) i - 128.0) / 128.0;
56 double sign = x>=0 ? 1.0 : -1.0;
57 double y = sign * floor(32767.0 * pow (fabs(x), STICK_GAMMA));
58 gammaTable[i] = (int) y;
59 }
60
61 /*
62 SLOW_CODE
63 The call to IOHIDManagerSetDeviceMatching() has a significiant
64 presence in warm startup profiles; sometimes it's even makes
65 -[OOMacJoystickManager init] the single heaviest Oolite symbol
66 within -[GameController applicationDidFinishLaunching]. Setup
67 should be made asynchronous.
68 -- Ahruman 2012-09-14
69 */
70 hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
71 IOHIDManagerSetDeviceMatching(hidManager, NULL);
72
73 IOHIDManagerRegisterDeviceMatchingCallback(hidManager, HandleDeviceMatchingCallback, self);
74 IOHIDManagerRegisterDeviceRemovalCallback(hidManager, HandleDeviceRemovalCallback, self);
75
76 IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
77 IOReturn iores = IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
78 if (iores != kIOReturnSuccess)
79 {
80 OOLog(@"joystick.error.init", @"Cannot open HID manager; joystick support will not function.");
81 }
82
83 devices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
84 }
85 return self;
86}
#define STICK_GAMMA
static void HandleDeviceRemovalCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDDeviceRef inIOHIDDeviceRef)
static void HandleDeviceMatchingCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDDeviceRef inIOHIDDeviceRef)
float y
float x
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque

◆ joystickCount

- (NSUInteger) joystickCount
implementation

Reimplemented from OOJoystickManager.

Definition at line 365 of file OOMacJoystickManager.m.

99{
100 return CFArrayGetCount(devices);
101}

◆ MapHatValue

+ (static uint8_t) MapHatValue (CFIndex) value
(CFIndex) max 
implementation

Definition at line 228 of file OOMacJoystickManager.m.

229{
230 /*
231 A hat switch has four or eight values, indicating directions. 0
232 is straight up/forwards, and subsequent values increase clockwise.
233 Out-of-range values are nulls, indicating no direction is pressed.
234 */
235
236 if (0 <= value && value <= max)
237 {
238 if (max == 3)
239 {
240 const uint8_t valueMap4[4] = { JOYHAT_UP, JOYHAT_RIGHT, JOYHAT_DOWN, JOYHAT_LEFT };
241 return valueMap4[value];
242 }
243 else if (max == 7)
244 {
246 return valueMap8[value];
247 }
248 }
249 return JOYHAT_CENTERED;
250}
@ JOYHAT_DOWN
@ JOYHAT_LEFTDOWN
@ JOYHAT_RIGHTUP
@ JOYHAT_RIGHT
@ JOYHAT_LEFT
@ JOYHAT_LEFTUP
@ JOYHAT_RIGHTDOWN
@ JOYHAT_CENTERED
@ JOYHAT_UP

◆ nameOfJoystick:

- (NSString *) nameOfJoystick: (NSUInteger) stickNumber
implementation

Reimplemented from OOJoystickManager.

Definition at line 228 of file OOMacJoystickManager.m.

332 :(NSUInteger)stickNumber
333{
334 IOHIDDeviceRef device = (IOHIDDeviceRef)CFArrayGetValueAtIndex(devices, stickNumber);
335 return (NSString *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
336}

Member Data Documentation

◆ devices

- (CFMutableArrayRef) devices
private

Definition at line 44 of file OOMacJoystickManager.h.

◆ gammaTable

- (int gammaTable[kJoystickGammaTableSize])
private

Definition at line 45 of file OOMacJoystickManager.h.

◆ hidManager

- (IOHIDManagerRef) hidManager
private

Definition at line 43 of file OOMacJoystickManager.h.


The documentation for this class was generated from the following files: