Line data Source code
1 0 : /*
2 :
3 : OOJoystickManager.m
4 : By Dylan Smith
5 : modified by Alex Smith
6 :
7 : Oolite
8 : Copyright (C) 2004-2013 Giles C Williams and contributors
9 :
10 : This program is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU General Public License
12 : as published by the Free Software Foundation; either version 2
13 : of the License, or (at your option) any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program; if not, write to the Free Software
22 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 : MA 02110-1301, USA.
24 :
25 : */
26 :
27 : #import "OOJoystickManager.h"
28 : #import "OOLogging.h"
29 : #import "OOCollectionExtractors.h"
30 :
31 :
32 0 : static Class sStickHandlerClass = Nil;
33 0 : static id sSharedStickHandler = nil;
34 :
35 :
36 : @interface OOJoystickManager (Private)
37 :
38 : // Setting button and axis functions
39 0 : - (void) setFunctionForAxis:(int)axis
40 : function:(int)function
41 : stick:(int)stickNum;
42 :
43 0 : - (void) setFunctionForButton:(int)button
44 : function:(int)function
45 : stick:(int)stickNum;
46 :
47 : @end
48 :
49 :
50 :
51 : @implementation OOJoystickManager
52 :
53 : + (id) sharedStickHandler
54 : {
55 : if (sSharedStickHandler == nil)
56 : {
57 : if (sStickHandlerClass == Nil) sStickHandlerClass = [OOJoystickManager class];
58 : sSharedStickHandler = [[sStickHandlerClass alloc] init];
59 : }
60 : return sSharedStickHandler;
61 : }
62 :
63 :
64 : + (BOOL) setStickHandlerClass:(Class)aClass
65 : {
66 : NSAssert(sStickHandlerClass == nil, @"Can't set joystick handler class after joystick handler is initialized.");
67 : NSParameterAssert(aClass == Nil || [aClass isSubclassOfClass:[OOJoystickManager class]]);
68 :
69 : sStickHandlerClass = aClass;
70 : return YES;
71 : }
72 :
73 :
74 : - (id) init
75 : {
76 : if ((self = [super init]))
77 : {
78 : // set initial values for stick buttons/axes (NO for buttons,
79 : // STICK_AXISUNASSIGNED for axes). Caution: calling this again
80 : // after axes have been assigned will set all the axes to
81 : // STICK_AXISUNASSIGNED so if there is a need to do something
82 : // like this, then do it some other way, or change this method
83 : // so it doesn't do that.
84 : [self clearStickStates];
85 :
86 : // Make some sensible mappings. This also ensures unassigned
87 : // axes and buttons are set to unassigned (STICK_NOFUNCTION).
88 : [self loadStickSettings];
89 : invertPitch = NO;
90 : precisionMode = NO;
91 : }
92 : return self;
93 : }
94 :
95 :
96 :
97 : - (NSPoint) rollPitchAxis
98 : {
99 : return NSMakePoint([self getAxisState:AXIS_ROLL], [self getAxisState:AXIS_PITCH]);
100 : }
101 :
102 :
103 : - (NSPoint) viewAxis
104 : {
105 : return NSMakePoint(axstate[AXIS_VIEWX], axstate[AXIS_VIEWY]);
106 : }
107 :
108 :
109 : - (BOOL) getButtonState: (int)function
110 : {
111 : return butstate[function];
112 : }
113 :
114 :
115 : - (const BOOL *)getAllButtonStates
116 : {
117 : return butstate;
118 : }
119 :
120 : - (BOOL) isButtonDown:(int)button stick:(int)stickNum
121 : {
122 : return true_butstate[stickNum][button];
123 : }
124 :
125 : - (double) getAxisState: (int)function
126 : {
127 : if (axstate[function] == STICK_AXISUNASSIGNED)
128 : {
129 : return STICK_AXISUNASSIGNED;
130 : }
131 : switch (function)
132 : {
133 : case AXIS_ROLL:
134 : if (precisionMode)
135 : {
136 : return [roll_profile value:axstate[function]] / STICK_PRECISIONFAC;
137 : }
138 : else
139 : {
140 : return [roll_profile value:axstate[function]];
141 : }
142 : case AXIS_PITCH:
143 : if (precisionMode)
144 : {
145 : return [pitch_profile value:axstate[function]] / STICK_PRECISIONFAC;
146 : }
147 : else
148 : {
149 : return [pitch_profile value:axstate[function]];
150 : }
151 : case AXIS_YAW:
152 : if (precisionMode)
153 : {
154 : return [yaw_profile value:axstate[function]] / STICK_PRECISIONFAC;
155 : }
156 : else
157 : {
158 : return [yaw_profile value:axstate[function]];
159 : }
160 : default:
161 : return axstate[function];
162 : }
163 : }
164 :
165 :
166 : - (double) getSensitivity
167 : {
168 : return precisionMode ? STICK_PRECISIONFAC : 1.0;
169 : }
170 :
171 : - (void) setProfile: (OOJoystickAxisProfile *) profile forAxis: (int) axis
172 : {
173 : switch (axis)
174 : {
175 : case AXIS_ROLL:
176 : [roll_profile release];
177 : roll_profile = [profile retain];
178 : break;
179 :
180 : case AXIS_PITCH:
181 : [pitch_profile release];
182 : pitch_profile = [profile retain];
183 : break;
184 :
185 : case AXIS_YAW:
186 : [yaw_profile release];
187 : yaw_profile = [profile retain];
188 : break;
189 : }
190 : return;
191 : }
192 :
193 : - (OOJoystickAxisProfile *) getProfileForAxis: (int) axis
194 : {
195 : switch (axis)
196 : {
197 : case AXIS_ROLL:
198 : return roll_profile;
199 : case AXIS_PITCH:
200 : return pitch_profile;
201 : case AXIS_YAW:
202 : return yaw_profile;
203 : }
204 : return nil;
205 : }
206 :
207 :
208 : - (void) saveProfileForAxis: (int) axis
209 : {
210 : NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
211 : NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
212 : OOJoystickAxisProfile *profile;
213 : OOJoystickStandardAxisProfile *standard_profile;
214 : OOJoystickSplineAxisProfile *spline_profile;
215 : NSArray *controlPoints;
216 : NSMutableArray *points;
217 : NSPoint point;
218 : NSUInteger i;
219 :
220 : profile = [self getProfileForAxis: axis];
221 : if (!profile) return;
222 : [dict setObject: [NSNumber numberWithDouble: [profile deadzone]] forKey: @"Deadzone"];
223 : if ([profile isKindOfClass: [OOJoystickStandardAxisProfile class]])
224 : {
225 : standard_profile = (OOJoystickStandardAxisProfile *) profile;
226 : [dict setObject: @"Standard" forKey: @"Type"];
227 : [dict setObject: [NSNumber numberWithDouble: [standard_profile power]] forKey: @"Power"];
228 : [dict setObject: [NSNumber numberWithDouble: [standard_profile parameter]] forKey: @"Parameter"];
229 : }
230 : else if ([profile isKindOfClass: [OOJoystickSplineAxisProfile class]])
231 : {
232 : spline_profile = (OOJoystickSplineAxisProfile *) profile;
233 : [dict setObject: @"Spline" forKey: @"Type"];
234 : controlPoints = [NSArray arrayWithArray: [spline_profile controlPoints]];
235 : points = [[NSMutableArray alloc] initWithCapacity: [controlPoints count]];
236 : for (i = 0; i < [controlPoints count]; i++)
237 : {
238 : point = [[controlPoints objectAtIndex: i] pointValue];
239 : [points addObject: [NSArray arrayWithObjects:
240 : [NSNumber numberWithFloat: point.x],
241 : [NSNumber numberWithFloat: point.y],
242 : nil ]];
243 : }
244 : [dict setObject: points forKey: @"ControlPoints"];
245 : }
246 : else
247 : {
248 : [dict setObject: @"Standard" forKey: @"Type"];
249 : }
250 : if (axis == AXIS_ROLL)
251 : {
252 : [defaults setObject: dict forKey: STICK_ROLL_AXIS_PROFILE_SETTING];
253 : }
254 : else if (axis == AXIS_PITCH)
255 : {
256 : [defaults setObject: dict forKey: STICK_PITCH_AXIS_PROFILE_SETTING];
257 : }
258 : else if (axis == AXIS_YAW)
259 : {
260 : [defaults setObject: dict forKey: STICK_YAW_AXIS_PROFILE_SETTING];
261 : }
262 : return;
263 : }
264 :
265 :
266 :
267 : - (void) loadProfileForAxis: (int) axis
268 : {
269 : NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
270 : NSDictionary *dict;
271 : OOJoystickStandardAxisProfile *standard_profile;
272 : OOJoystickSplineAxisProfile *spline_profile;
273 :
274 : if (axis == AXIS_ROLL)
275 : {
276 : dict = [defaults objectForKey: STICK_ROLL_AXIS_PROFILE_SETTING];
277 : }
278 : else if (axis == AXIS_PITCH)
279 : {
280 : dict = [defaults objectForKey: STICK_PITCH_AXIS_PROFILE_SETTING];
281 : }
282 : else if (axis == AXIS_YAW)
283 : {
284 : dict = [defaults objectForKey: STICK_YAW_AXIS_PROFILE_SETTING];
285 : }
286 : else
287 : {
288 : return;
289 : }
290 :
291 : NSString *type = [dict objectForKey: @"Type"];
292 : if ([type isEqualToString: @"Standard"])
293 : {
294 : standard_profile = [[OOJoystickStandardAxisProfile alloc] init];
295 : [standard_profile setDeadzone: [[dict objectForKey: @"Deadzone"] doubleValue]];
296 : [standard_profile setPower: [[dict objectForKey: @"Power"] doubleValue]];
297 : [standard_profile setParameter: [[dict objectForKey: @"Parameter"] doubleValue]];
298 : [self setProfile: [standard_profile autorelease] forAxis: axis];
299 : }
300 : else if([type isEqualToString: @"Spline"])
301 : {
302 : spline_profile = [[OOJoystickSplineAxisProfile alloc] init];
303 : [spline_profile setDeadzone: [[dict objectForKey: @"Deadzone"] doubleValue]];
304 : NSArray *points = [dict objectForKey: @"ControlPoints"], *pointArray;
305 : NSPoint point;
306 : NSUInteger i;
307 :
308 : for (i = 0; i < [points count]; i++)
309 : {
310 : pointArray = [points objectAtIndex: i];
311 : if ([pointArray count] >= 2)
312 : {
313 : point = NSMakePoint([[pointArray objectAtIndex: 0] floatValue], [[pointArray objectAtIndex: 1] floatValue]);
314 : [spline_profile addControl: point];
315 : }
316 : }
317 : [self setProfile: [spline_profile autorelease] forAxis: axis];
318 : }
319 : else
320 : {
321 : [self setProfile: [[[OOJoystickStandardAxisProfile alloc] init] autorelease] forAxis: axis];
322 : }
323 : }
324 :
325 : - (NSArray *)listSticks
326 : {
327 : NSUInteger i, stickCount = [self joystickCount];
328 :
329 : NSMutableArray *stickList = [NSMutableArray array];
330 : for (i = 0; i < stickCount; i++)
331 : {
332 : [stickList addObject:[self nameOfJoystick:i]];
333 : }
334 : return stickList;
335 : }
336 :
337 :
338 : - (NSDictionary *) axisFunctions
339 : {
340 : int i,j;
341 : NSMutableDictionary *fnList = [NSMutableDictionary dictionary];
342 :
343 : // Add axes
344 : for (i = 0; i < MAX_AXES; i++)
345 : {
346 : for (j = 0; j < MAX_STICKS; j++)
347 : {
348 : if(axismap[j][i] >= 0)
349 : {
350 : NSDictionary *fnDict=[NSDictionary dictionaryWithObjectsAndKeys:
351 : [NSNumber numberWithBool:YES], STICK_ISAXIS,
352 : [NSNumber numberWithInt:j], STICK_NUMBER,
353 : [NSNumber numberWithInt:i], STICK_AXBUT,
354 : nil];
355 : [fnList setValue: fnDict
356 : forKey: ENUMKEY(axismap[j][i])];
357 : }
358 : }
359 : }
360 : return fnList;
361 : }
362 :
363 :
364 : - (NSDictionary *)buttonFunctions
365 : {
366 : int i, j;
367 : NSMutableDictionary *fnList = [NSMutableDictionary dictionary];
368 :
369 : // Add buttons
370 : for (i = 0; i < MAX_BUTTONS; i++)
371 : {
372 : for (j = 0; j < MAX_STICKS; j++)
373 : {
374 : if(buttonmap[j][i] >= 0)
375 : {
376 : NSDictionary *fnDict = [NSDictionary dictionaryWithObjectsAndKeys:
377 : [NSNumber numberWithBool:NO], STICK_ISAXIS,
378 : [NSNumber numberWithInt:j], STICK_NUMBER,
379 : [NSNumber numberWithInt:i], STICK_AXBUT,
380 : nil];
381 : [fnList setValue:fnDict
382 : forKey:ENUMKEY(buttonmap[j][i])];
383 : }
384 : }
385 : }
386 : return fnList;
387 : }
388 :
389 :
390 : - (void) setFunction:(int)function withDict:(NSDictionary *)stickFn
391 : {
392 : BOOL isAxis = [stickFn oo_boolForKey:STICK_ISAXIS];
393 : int stickNum = [stickFn oo_intForKey:STICK_NUMBER];
394 : int stickAxBt = [stickFn oo_intForKey:STICK_AXBUT];
395 :
396 : if (isAxis)
397 : {
398 : [self setFunctionForAxis:stickAxBt
399 : function:function
400 : stick:stickNum];
401 : }
402 : else
403 : {
404 : [self setFunctionForButton:stickAxBt
405 : function:function
406 : stick:stickNum];
407 : }
408 : }
409 :
410 :
411 0 : - (void) setFunctionForAxis:(int)axis
412 : function:(int)function
413 : stick:(int)stickNum
414 : {
415 : NSParameterAssert(axis < MAX_AXES && stickNum < MAX_STICKS);
416 :
417 : int16_t axisvalue = [self getAxisWithStick:stickNum axis:axis];
418 : [self unsetAxisFunction:function];
419 : axismap[stickNum][axis] = function;
420 :
421 : // initialize the throttle to what it's set to now (or else the
422 : // commander has to waggle the throttle to wake it up). Other axes
423 : // set as default.
424 : if(function == AXIS_THRUST)
425 : {
426 : axstate[function] = (float)(65536 - (axisvalue + 32768)) / 65536;
427 : }
428 : else
429 : {
430 : axstate[function] = (float)axisvalue / STICK_NORMALDIV;
431 : }
432 : }
433 :
434 :
435 0 : - (void) setFunctionForButton:(int)button
436 : function:(int)function
437 : stick:(int)stickNum
438 : {
439 : NSParameterAssert(button < MAX_BUTTONS && stickNum < MAX_STICKS);
440 :
441 : int i, j;
442 : for (i = 0; i < MAX_BUTTONS; i++)
443 : {
444 : for (j = 0; j < MAX_STICKS; j++)
445 : {
446 : if (buttonmap[j][i] == function)
447 : {
448 : buttonmap[j][i] = STICK_NOFUNCTION;
449 : break;
450 : }
451 : }
452 : }
453 : buttonmap[stickNum][button] = function;
454 : }
455 :
456 :
457 : - (void) unsetAxisFunction:(int)function
458 : {
459 : int i, j;
460 : for (i = 0; i < MAX_AXES; i++)
461 : {
462 : for (j = 0; j < MAX_STICKS; j++)
463 : {
464 : if (axismap[j][i] == function)
465 : {
466 : axismap[j][i] = STICK_NOFUNCTION;
467 : axstate[function] = STICK_AXISUNASSIGNED;
468 : break;
469 : }
470 : }
471 : }
472 : }
473 :
474 :
475 : - (void) unsetButtonFunction:(int)function
476 : {
477 : int i,j;
478 : for (i = 0; i < MAX_BUTTONS; i++)
479 : {
480 : for (j = 0; j < MAX_STICKS; j++)
481 : {
482 : if(buttonmap[j][i] == function)
483 : {
484 : buttonmap[j][i] = STICK_NOFUNCTION;
485 : break;
486 : }
487 : }
488 : }
489 : }
490 :
491 :
492 : - (void) setDefaultMapping
493 : {
494 : // assign the simplest mapping: stick 0 having
495 : // axis 0/1 being roll/pitch and button 0 being fire, 1 being missile
496 : // All joysticks should at least have two axes and two buttons.
497 : axismap[0][0] = AXIS_ROLL;
498 : axismap[0][1] = AXIS_PITCH;
499 : buttonmap[0][0] = BUTTON_FIRE;
500 : buttonmap[0][1] = BUTTON_LAUNCHMISSILE;
501 : }
502 :
503 :
504 : - (void) clearMappings
505 : {
506 : memset(axismap, STICK_NOFUNCTION, sizeof axismap);
507 : memset(buttonmap, STICK_NOFUNCTION, sizeof buttonmap);
508 : }
509 :
510 :
511 : - (void) clearStickStates
512 : {
513 : int i, j;
514 : for (i = 0; i < AXIS_end; i++)
515 : {
516 : axstate[i] = STICK_AXISUNASSIGNED;
517 : }
518 : for (i = 0; i < BUTTON_end; i++)
519 : {
520 : butstate[i] = 0;
521 : }
522 : for (i = 0; i < MAX_BUTTONS; i++)
523 : {
524 : for (j = 0; j < MAX_STICKS; j++)
525 : {
526 : true_butstate[j][i] = NO;
527 : }
528 : }
529 : }
530 :
531 :
532 : - (void) clearStickButtonState:(int)stickButton
533 : {
534 : if (stickButton >= 0 && stickButton < BUTTON_end)
535 : {
536 : butstate[stickButton] = 0;
537 : }
538 : }
539 :
540 :
541 : - (void)setCallback:(SEL) selector
542 : object:(id) obj
543 : hardware:(char)hwflags
544 : {
545 : cbObject = obj;
546 : cbSelector = selector;
547 : cbHardware = hwflags;
548 : }
549 :
550 :
551 : - (void)clearCallback
552 : {
553 : cbObject = nil;
554 : cbHardware = 0;
555 : }
556 :
557 :
558 : - (void)decodeAxisEvent: (JoyAxisEvent *)evt
559 : {
560 : // Which axis moved? Does the value need to be made to fit a
561 : // certain function? Convert axis value to a double.
562 : double axisvalue = (double)evt->value;
563 :
564 : // First check if there is a callback and...
565 : if(cbObject && (cbHardware & HW_AXIS))
566 : {
567 : // ...then check if axis moved more than AXCBTHRESH - (fix for BUG #17482)
568 : if(axisvalue > AXCBTHRESH)
569 : {
570 : NSDictionary *fnDict = [NSDictionary dictionaryWithObjectsAndKeys:
571 : [NSNumber numberWithBool: YES], STICK_ISAXIS,
572 : [NSNumber numberWithInt: evt->which], STICK_NUMBER,
573 : [NSNumber numberWithInt: evt->axis], STICK_AXBUT,
574 : nil];
575 : cbHardware = 0;
576 : [cbObject performSelector:cbSelector withObject:fnDict];
577 : cbObject = nil;
578 : }
579 :
580 : // we are done.
581 : return;
582 : }
583 :
584 : // SDL seems to have some bizarre (perhaps a bug) behaviour when
585 : // events get queued up because the game isn't ready to handle
586 : // them (perhaps it's loading a commander and initializing the
587 : // universe, and the main event loop is blocked).
588 : // What happens is SDL lies about the axis that was triggered. For
589 : // each queued event it adds 1 to the axis number!! This does
590 : // not seem to happen with buttons.
591 : int function;
592 : if (evt->axis < MAX_AXES)
593 : {
594 : function = axismap[evt->which][evt->axis];
595 : }
596 : else
597 : {
598 : OOLog(@"decodeAxisEvent", @"Stick axis out of range - axis was %d", evt->axis);
599 : return;
600 : }
601 : switch (function)
602 : {
603 : case STICK_NOFUNCTION:
604 : // do nothing
605 : break;
606 : case AXIS_THRUST:
607 : // Normalize the thrust setting.
608 : axstate[function] = (float)(65536 - (axisvalue + 32768)) / 65536;
609 : break;
610 : case AXIS_ROLL:
611 : case AXIS_PITCH:
612 : case AXIS_YAW:
613 : case AXIS_VIEWX:
614 : case AXIS_VIEWY:
615 : axstate[function] = axisvalue / STICK_NORMALDIV;
616 : break;
617 : // TODO AXIS_FIELD_OF_VIEW
618 : default:
619 : // set the state with no modification.
620 : axstate[function] = axisvalue / 32768;
621 : }
622 : if ((function == AXIS_PITCH) && invertPitch) axstate[function] = -1.0*axstate[function];
623 : }
624 :
625 :
626 : - (void) decodeButtonEvent:(JoyButtonEvent *)evt
627 : {
628 : BOOL bs = NO;
629 :
630 : // Is there a callback we need to make?
631 : if(cbObject && (cbHardware & HW_BUTTON))
632 : {
633 : NSDictionary *fnDict = [NSDictionary dictionaryWithObjectsAndKeys:
634 : [NSNumber numberWithBool: NO], STICK_ISAXIS,
635 : [NSNumber numberWithInt: evt->which], STICK_NUMBER,
636 : [NSNumber numberWithInt: evt->button], STICK_AXBUT,
637 : nil];
638 : cbHardware = 0;
639 : [cbObject performSelector:cbSelector withObject:fnDict];
640 : cbObject = nil;
641 :
642 : // we are done.
643 : return;
644 : }
645 :
646 : // Defensive measure - see comments in the axis handler for why.
647 : int function;
648 : if (evt->button < MAX_BUTTONS)
649 : {
650 : function = buttonmap[evt->which][evt->button];
651 : }
652 : else
653 : {
654 : OOLog(@"decodeButtonEvent", @"Joystick button out of range: %d", evt->button);
655 : return;
656 : }
657 : if (evt->type == JOYBUTTONDOWN)
658 : {
659 : bs = YES;
660 : if(function == BUTTON_PRECISION)
661 : precisionMode = !precisionMode;
662 : }
663 : true_butstate[evt->which][evt->button] = bs;
664 : if (function >= 0)
665 : {
666 : butstate[function]=bs;
667 : }
668 :
669 : }
670 :
671 :
672 : - (void) decodeHatEvent:(JoyHatEvent *)evt
673 : {
674 : // HACK: handle this as a set of buttons
675 : int i;
676 : JoyButtonEvent btn;
677 :
678 : btn.which = evt->which;
679 :
680 : for (i = 0; i < 4; ++i)
681 : {
682 : if ((evt->value ^ hatstate[evt->which][evt->hat]) & (1 << i))
683 : {
684 : btn.type = (evt->value & (1 << i)) ? JOYBUTTONDOWN : JOYBUTTONUP;
685 : btn.button = MAX_REAL_BUTTONS + i + evt->which * 4;
686 : btn.state = (evt->value & (1 << i)) ? JOYBUTTON_PRESSED : JOYBUTTON_RELEASED;
687 : [self decodeButtonEvent:&btn];
688 : }
689 : }
690 :
691 : hatstate[evt->which][evt->hat] = evt->value;
692 : }
693 :
694 :
695 : - (NSUInteger) joystickCount
696 : {
697 : return 0;
698 : }
699 :
700 :
701 : - (void) saveStickSettings
702 : {
703 : NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
704 :
705 : [defaults setObject:[self axisFunctions]
706 : forKey:AXIS_SETTINGS];
707 : [defaults setObject:[self buttonFunctions]
708 : forKey:BUTTON_SETTINGS];
709 : [self saveProfileForAxis: AXIS_ROLL];
710 : [self saveProfileForAxis: AXIS_PITCH];
711 : [self saveProfileForAxis: AXIS_YAW];
712 : [defaults synchronize];
713 : }
714 :
715 :
716 : - (void) loadStickSettings
717 : {
718 : unsigned i;
719 : [self clearMappings];
720 : NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
721 : NSDictionary *axisSettings = [defaults objectForKey: AXIS_SETTINGS];
722 : NSDictionary *buttonSettings = [defaults objectForKey: BUTTON_SETTINGS];
723 : if(axisSettings)
724 : {
725 : NSArray *keys = [axisSettings allKeys];
726 : for (i = 0; i < [keys count]; i++)
727 : {
728 : NSString *key = [keys objectAtIndex: i];
729 : [self setFunction: [key intValue]
730 : withDict: [axisSettings objectForKey: key]];
731 : }
732 : }
733 : if(buttonSettings)
734 : {
735 : NSArray *keys = [buttonSettings allKeys];
736 : for (i = 0; i < [keys count]; i++)
737 : {
738 : NSString *key = [keys objectAtIndex: i];
739 : [self setFunction:[key intValue]
740 : withDict:[buttonSettings objectForKey: key]];
741 : }
742 : }
743 : else
744 : {
745 : // Nothing to load - set useful defaults
746 : [self setDefaultMapping];
747 : }
748 : [self loadProfileForAxis: AXIS_ROLL];
749 : [self loadProfileForAxis: AXIS_PITCH];
750 : [self loadProfileForAxis: AXIS_YAW];
751 : }
752 :
753 : // These get overidden by subclasses
754 :
755 : - (NSString *) nameOfJoystick:(NSUInteger)stickNumber
756 : {
757 : return @"Dummy joystick";
758 : }
759 :
760 : - (int16_t) getAxisWithStick:(NSUInteger)stickNum axis:(NSUInteger)axisNum
761 : {
762 : return 0;
763 : }
764 :
765 : @end
|