Line data Source code
1 0 : /*
2 :
3 : PlayerEntityStickMapper.m
4 :
5 : Oolite
6 : Copyright (C) 2004-2019 Giles C Williams and contributors
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License
10 : as published by the Free Software Foundation; either version 2
11 : of the License, or (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 : MA 02110-1301, USA.
22 :
23 : */
24 :
25 : #import "PlayerEntityStickMapper.h"
26 : #import "PlayerEntityControls.h"
27 : #import "PlayerEntityStickProfile.h"
28 : #import "OOJoystickManager.h"
29 : #import "OOTexture.h"
30 : #import "OOCollectionExtractors.h"
31 : #import "HeadUpDisplay.h"
32 :
33 : @interface PlayerEntity (StickMapperInternal)
34 :
35 0 : - (void) resetStickFunctions;
36 0 : - (void) checkCustomEquipButtons:(NSDictionary *)stickFn ignore:(int)idx;
37 0 : - (void) removeFunction:(int)selFunctionIdx;
38 0 : - (NSArray *)stickFunctionList;
39 0 : - (void)displayFunctionList:(GuiDisplayGen *)gui
40 : skip:(NSUInteger) skip;
41 0 : - (NSString *)describeStickDict:(NSDictionary *)stickDict;
42 0 : - (NSString *)hwToString:(int)hwFlags;
43 :
44 : @end
45 :
46 :
47 : @implementation PlayerEntity (StickMapper)
48 :
49 : - (void) resetStickFunctions
50 : {
51 : [stickFunctions release];
52 : stickFunctions = nil;
53 : }
54 :
55 :
56 : - (void) setGuiToStickMapperScreen:(unsigned)skip
57 : {
58 : [self setGuiToStickMapperScreen: skip resetCurrentRow: NO];
59 : }
60 :
61 : - (void) setGuiToStickMapperScreen:(unsigned)skip resetCurrentRow: (BOOL) resetCurrentRow
62 : {
63 : GuiDisplayGen *gui = [UNIVERSE gui];
64 : OOJoystickManager *stickHandler = [OOJoystickManager sharedStickHandler];
65 : NSArray *stickList = [stickHandler listSticks];
66 : unsigned stickCount = [stickList count];
67 : unsigned i;
68 :
69 : OOGUITabStop tabStop[GUI_MAX_COLUMNS];
70 : tabStop[0] = 10;
71 : tabStop[1] = 290;
72 : tabStop[2] = 400;
73 : [gui setTabStops:tabStop];
74 :
75 : gui_screen = GUI_SCREEN_STICKMAPPER;
76 : [gui clear];
77 : [gui setTitle:[NSString stringWithFormat:@"Configure Joysticks"]];
78 :
79 : for(i=0; i < stickCount; i++)
80 : {
81 : NSString *stickNameForThisRow = [NSString stringWithFormat: @"Stick %d %@", i+1, [stickList objectAtIndex: i]];
82 : // for more than 2 sticks, the stick name rows are populated by more than one name if needed
83 : NSString *stickNameAdditional = nil;
84 : if (stickCount > 2 && OOStringWidthInEm(stickNameForThisRow) > 18.0)
85 : {
86 : // string is too long, truncate it until its length gets below threshold
87 : do {
88 : stickNameForThisRow = [[stickNameForThisRow substringToIndex:[stickNameForThisRow length] - 5]
89 : stringByAppendingString:@"..."];
90 : } while (OOStringWidthInEm(stickNameForThisRow) > 18.0);
91 : }
92 : unsigned j = i + 2;
93 : if (j < stickCount)
94 : {
95 : stickNameAdditional = [NSString stringWithFormat: @"Stick %d %@", j+1, [stickList objectAtIndex: j]];
96 : if (OOStringWidthInEm(stickNameAdditional) > 11.0)
97 : {
98 : // string is too long, truncate it until its length gets below threshold
99 : do {
100 : stickNameAdditional = [[stickNameAdditional substringToIndex:[stickNameAdditional length] - 5]
101 : stringByAppendingString:@"..."];
102 : } while (OOStringWidthInEm(stickNameAdditional) > 11.0);
103 : }
104 : }
105 : [gui setArray:[NSArray arrayWithObjects:
106 : stickNameForThisRow,
107 : @"", // skip one column
108 : stickNameAdditional,
109 : nil]
110 : forRow:i + GUI_ROW_STICKNAME];
111 : }
112 :
113 : [gui setArray: [NSArray arrayWithObjects: DESC(@"stickmapper-profile"), nil] forRow: GUI_ROW_STICKPROFILE];
114 : [gui setKey: GUI_KEY_OK forRow: GUI_ROW_STICKPROFILE];
115 : [self displayFunctionList:gui skip:skip];
116 :
117 : [gui setArray:[NSArray arrayWithObject:@"Select a function and press Enter to modify or 'u' to unset."]
118 : forRow:GUI_ROW_INSTRUCT];
119 :
120 : [gui setText:@"Space to return to previous screen." forRow:GUI_ROW_INSTRUCT+1 align:GUI_ALIGN_CENTER];
121 :
122 : if (resetCurrentRow)
123 : {
124 : [gui setSelectedRow: GUI_ROW_STICKPROFILE];
125 : }
126 : [[UNIVERSE gameView] suppressKeysUntilKeyUp];
127 : [gui setForegroundTextureKey:[self status] == STATUS_DOCKED ? @"docked_overlay" : @"paused_overlay"];
128 : [gui setBackgroundTextureKey:@"settings"];
129 : }
130 :
131 :
132 : - (void) stickMapperInputHandler:(GuiDisplayGen *)gui
133 : view:(MyOpenGLView *)gameView
134 : {
135 : OOJoystickManager *stickHandler = [OOJoystickManager sharedStickHandler];
136 :
137 : // Don't do anything if the user is supposed to be selecting
138 : // a function - other than look for Escape.
139 : if(waitingForStickCallback)
140 : {
141 : if([gameView isDown: 27])
142 : {
143 : [stickHandler clearCallback];
144 : [gui setArray: [NSArray arrayWithObjects:
145 : @"Function setting aborted.", nil]
146 : forRow: GUI_ROW_INSTRUCT];
147 : waitingForStickCallback=NO;
148 : }
149 :
150 : // Break out now.
151 : return;
152 : }
153 :
154 : [self handleGUIUpDownArrowKeys];
155 :
156 : if ([gui selectedRow] == GUI_ROW_STICKPROFILE && [gameView isDown: 13])
157 : {
158 : [self setGuiToStickProfileScreen: gui];
159 : return;
160 : }
161 :
162 : NSString* key = [gui keyForRow: [gui selectedRow]];
163 : if ([key hasPrefix:@"Index:"])
164 : selFunctionIdx=[[[key componentsSeparatedByString:@":"] objectAtIndex: 1] intValue];
165 : else
166 : selFunctionIdx=-1;
167 :
168 : if([gameView isDown: 13])
169 : {
170 : if ([key hasPrefix:@"More:"])
171 : {
172 : int from_function = [[[key componentsSeparatedByString:@":"] objectAtIndex: 1] intValue];
173 : if (from_function < 0) from_function = 0;
174 :
175 : [self setGuiToStickMapperScreen:from_function];
176 : if ([[UNIVERSE gui] selectedRow] < 0)
177 : [[UNIVERSE gui] setSelectedRow: GUI_ROW_FUNCSTART];
178 : if (from_function == 0)
179 : [[UNIVERSE gui] setSelectedRow: GUI_ROW_FUNCSTART + MAX_ROWS_FUNCTIONS - 1];
180 : return;
181 : }
182 :
183 : NSDictionary *entry=[stickFunctions objectAtIndex: selFunctionIdx];
184 : int hw=[(NSNumber *)[entry objectForKey: KEY_ALLOWABLE] intValue];
185 : [stickHandler setCallback: @selector(updateFunction:)
186 : object: self
187 : hardware: hw];
188 :
189 : // Print instructions
190 : NSString *instructions;
191 : switch(hw)
192 : {
193 : case HW_AXIS:
194 : instructions = @"Fully deflect the axis you want to use for this function. Esc aborts.";
195 : break;
196 : case HW_BUTTON:
197 : instructions = @"Press the button you want to use for this function. Esc aborts.";
198 : break;
199 : default:
200 : instructions = @"Press the button or deflect the axis you want to use for this function.";
201 : }
202 : [gui setArray: [NSArray arrayWithObjects: instructions, nil] forRow: GUI_ROW_INSTRUCT];
203 : waitingForStickCallback=YES;
204 : }
205 :
206 : if([gameView isDown: 'u'])
207 : {
208 : if (selFunctionIdx >= 0) [self removeFunction: selFunctionIdx];
209 : }
210 : }
211 :
212 :
213 : // Callback function, called by JoystickHandler when the callback
214 : // is set. The dictionary contains the thing that was pressed/moved.
215 : - (void) updateFunction: (NSDictionary *)hwDict
216 : {
217 : OOJoystickManager *stickHandler = [OOJoystickManager sharedStickHandler];
218 : waitingForStickCallback = NO;
219 :
220 : // Right time and the right place?
221 : if(gui_screen != GUI_SCREEN_STICKMAPPER)
222 : {
223 : OOLog(@"joystick.configure.error", @"%s called when not on stick mapper screen.", __PRETTY_FUNCTION__);
224 : return;
225 : }
226 :
227 : // What moved?
228 : int function;
229 : NSDictionary *entry = [stickFunctions objectAtIndex:selFunctionIdx];
230 : if([hwDict oo_boolForKey:STICK_ISAXIS])
231 : {
232 : function=[entry oo_intForKey: KEY_AXISFN];
233 : if (function == AXIS_THRUST)
234 : {
235 : [stickHandler unsetButtonFunction:BUTTON_INCTHRUST];
236 : [stickHandler unsetButtonFunction:BUTTON_DECTHRUST];
237 : }
238 : #if OO_FOV_INFLIGHT_CONTROL_ENABLED
239 : if (function == AXIS_FIELD_OF_VIEW)
240 : {
241 : [stickHandler unsetButtonFunction:BUTTON_INC_FIELD_OF_VIEW];
242 : [stickHandler unsetButtonFunction:BUTTON_DEC_FIELD_OF_VIEW];
243 : }
244 : #endif
245 : if (function == AXIS_VIEWX)
246 : {
247 : [stickHandler unsetButtonFunction:BUTTON_VIEWPORT];
248 : [stickHandler unsetButtonFunction:BUTTON_VIEWSTARBOARD];
249 : }
250 : if (function == AXIS_VIEWY)
251 : {
252 : [stickHandler unsetButtonFunction:BUTTON_VIEWFORWARD];
253 : [stickHandler unsetButtonFunction:BUTTON_VIEWAFT];
254 : }
255 : }
256 : else
257 : {
258 : function = [entry oo_intForKey:KEY_BUTTONFN];
259 : if (function == BUTTON_INCTHRUST || function == BUTTON_DECTHRUST)
260 : {
261 : [stickHandler unsetAxisFunction:AXIS_THRUST];
262 : }
263 : #if OO_FOV_INFLIGHT_CONTROL_ENABLED
264 : if (function == BUTTON_INC_FIELD_OF_VIEW || function == BUTTON_DEC_FIELD_OF_VIEW)
265 : {
266 : [stickHandler unsetAxisFunction:AXIS_FIELD_OF_VIEW];
267 : }
268 : #endif
269 : if (function == BUTTON_VIEWPORT || function == BUTTON_VIEWSTARBOARD)
270 : {
271 : [stickHandler unsetAxisFunction:AXIS_VIEWX];
272 : }
273 : if (function == BUTTON_VIEWFORWARD || function == BUTTON_VIEWAFT)
274 : {
275 : [stickHandler unsetAxisFunction:AXIS_VIEWY];
276 : }
277 : }
278 : // special case for OXP equipment buttons
279 : if (function >= 10000)
280 : {
281 : NSString *key = CUSTOMEQUIP_BUTTONACTIVATE;
282 : function -= 10000;
283 : if (function >= 10000)
284 : {
285 : function -= 10000;
286 : key = CUSTOMEQUIP_BUTTONMODE;
287 : }
288 : [[customEquipActivation objectAtIndex:function] setObject:hwDict forKey:key];
289 : [self checkCustomEquipButtons:hwDict ignore:function];
290 :
291 : NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
292 : [defaults setObject:customEquipActivation forKey:KEYCONFIG_CUSTOMEQUIP];
293 : }
294 : else
295 : {
296 : [stickHandler setFunction:function withDict:hwDict];
297 : [self checkCustomEquipButtons:hwDict ignore:-1];
298 : [stickHandler saveStickSettings];
299 : }
300 :
301 : // Update the GUI (this will refresh the function list).
302 : unsigned skip;
303 : if (selFunctionIdx < MAX_ROWS_FUNCTIONS - 1)
304 : {
305 : skip = 0;
306 : }
307 : else
308 : {
309 : skip = ((selFunctionIdx - 1) / (MAX_ROWS_FUNCTIONS - 2)) * (MAX_ROWS_FUNCTIONS - 2) + 1;
310 : }
311 :
312 : [self setGuiToStickMapperScreen:skip];
313 : }
314 :
315 :
316 0 : - (void) checkCustomEquipButtons:(NSDictionary *)stickFn ignore:(int)idx
317 : {
318 : int i;
319 : for (i = 0; i < [customEquipActivation count]; i++)
320 : {
321 : if (i != idx) {
322 : NSDictionary *bf = [[customEquipActivation objectAtIndex:i] objectForKey:CUSTOMEQUIP_BUTTONACTIVATE];
323 : if ([bf oo_integerForKey:STICK_NUMBER] == [stickFn oo_integerForKey:STICK_NUMBER] &&
324 : [bf oo_integerForKey:STICK_AXBUT] == [stickFn oo_integerForKey:STICK_AXBUT])
325 : {
326 : [[customEquipActivation objectAtIndex:i] removeObjectForKey:CUSTOMEQUIP_BUTTONACTIVATE];
327 : }
328 : bf = [[customEquipActivation objectAtIndex:i] objectForKey:CUSTOMEQUIP_BUTTONMODE];
329 : if ([bf oo_integerForKey:STICK_NUMBER] == [stickFn oo_integerForKey:STICK_NUMBER] &&
330 : [bf oo_integerForKey:STICK_AXBUT] == [stickFn oo_integerForKey:STICK_AXBUT])
331 : {
332 : [[customEquipActivation objectAtIndex:i] removeObjectForKey:CUSTOMEQUIP_BUTTONMODE];
333 : }
334 : }
335 : }
336 : }
337 :
338 :
339 0 : - (void) removeFunction:(int)idx
340 : {
341 : OOJoystickManager *stickHandler = [OOJoystickManager sharedStickHandler];
342 : NSDictionary *entry = [stickFunctions objectAtIndex:idx];
343 : NSNumber *butfunc = [entry objectForKey:KEY_BUTTONFN];
344 : NSNumber *axfunc = [entry objectForKey:KEY_AXISFN];
345 : BOOL custom = NO;
346 : selFunctionIdx = idx;
347 :
348 : // Some things can have either axis or buttons - make sure we clear
349 : // both!
350 : if(butfunc)
351 : {
352 : // special case for OXP equipment buttons
353 : if ([butfunc intValue] >= 10000)
354 : {
355 : int bf = [butfunc intValue];
356 : custom = YES;
357 : NSString *key = CUSTOMEQUIP_BUTTONACTIVATE;
358 : bf -= 10000;
359 : if (bf >= 10000)
360 : {
361 : bf -= 10000;
362 : key = CUSTOMEQUIP_BUTTONMODE;
363 : }
364 : [[customEquipActivation objectAtIndex:bf] removeObjectForKey:key];
365 : }
366 : else
367 : {
368 : [stickHandler unsetButtonFunction:[butfunc intValue]];
369 : }
370 : }
371 : if(axfunc)
372 : {
373 : [stickHandler unsetAxisFunction:[axfunc intValue]];
374 : }
375 : if (!custom)
376 : {
377 : [stickHandler saveStickSettings];
378 : }
379 : else
380 : {
381 : NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
382 : [defaults setObject:customEquipActivation forKey:KEYCONFIG_CUSTOMEQUIP];
383 : }
384 :
385 : unsigned skip;
386 : if (selFunctionIdx < MAX_ROWS_FUNCTIONS - 1)
387 : skip = 0;
388 : else
389 : skip = ((selFunctionIdx - 1) / (MAX_ROWS_FUNCTIONS - 2)) * (MAX_ROWS_FUNCTIONS - 2) + 1;
390 : [self setGuiToStickMapperScreen: skip];
391 : }
392 :
393 :
394 0 : - (void) displayFunctionList:(GuiDisplayGen *)gui
395 : skip:(NSUInteger)skip
396 : {
397 : OOJoystickManager *stickHandler = [OOJoystickManager sharedStickHandler];
398 :
399 : [gui setColor:[OOColor greenColor] forRow: GUI_ROW_HEADING];
400 : [gui setArray:[NSArray arrayWithObjects:
401 : @"Function", @"Assigned to", @"Type", nil]
402 : forRow:GUI_ROW_HEADING];
403 :
404 : if(!stickFunctions)
405 : {
406 : stickFunctions = [[self stickFunctionList] retain];
407 : }
408 : NSDictionary *assignedAxes = [stickHandler axisFunctions];
409 : NSDictionary *assignedButs = [stickHandler buttonFunctions];
410 :
411 : NSUInteger i, n_functions = [stickFunctions count];
412 : NSInteger n_rows, start_row, previous = 0;
413 :
414 : if (skip >= n_functions)
415 : skip = n_functions - 1;
416 :
417 : if (n_functions < MAX_ROWS_FUNCTIONS)
418 : {
419 : skip = 0;
420 : previous = 0;
421 : n_rows = MAX_ROWS_FUNCTIONS;
422 : start_row = GUI_ROW_FUNCSTART;
423 : }
424 : else
425 : {
426 : n_rows = MAX_ROWS_FUNCTIONS - 1;
427 : start_row = GUI_ROW_FUNCSTART;
428 : if (skip > 0)
429 : {
430 : n_rows -= 1;
431 : start_row += 1;
432 : if (skip > MAX_ROWS_FUNCTIONS)
433 : previous = skip - (MAX_ROWS_FUNCTIONS - 2);
434 : else
435 : previous = 0;
436 : }
437 : }
438 :
439 : if (n_functions > 0)
440 : {
441 : if (skip > 0)
442 : {
443 : [gui setColor:[OOColor greenColor] forRow:GUI_ROW_FUNCSTART];
444 : [gui setArray:[NSArray arrayWithObjects:DESC(@"gui-back"), @" <-- ", nil] forRow:GUI_ROW_FUNCSTART];
445 : [gui setKey:[NSString stringWithFormat:@"More:%ld", previous] forRow:GUI_ROW_FUNCSTART];
446 : }
447 :
448 : for(i=0; i < (n_functions - skip) && (int)i < n_rows; i++)
449 : {
450 : NSDictionary *entry = [stickFunctions objectAtIndex: i + skip];
451 : if ([entry objectForKey:KEY_HEADER]) {
452 : NSString *header = [entry objectForKey:KEY_HEADER];
453 : [gui setArray:[NSArray arrayWithObjects:header, @"", @"", nil] forRow:i + start_row];
454 : [gui setColor:[OOColor cyanColor] forRow:i + start_row];
455 : }
456 : else
457 : {
458 : NSString *allowedThings;
459 : NSString *assignment;
460 : NSString *axFuncKey = [entry oo_stringForKey:KEY_AXISFN];
461 : NSString *butFuncKey = [entry oo_stringForKey:KEY_BUTTONFN];
462 : int allowable = [entry oo_intForKey:KEY_ALLOWABLE];
463 : switch(allowable)
464 : {
465 : case HW_AXIS:
466 : allowedThings=@"Axis";
467 : assignment=[self describeStickDict:
468 : [assignedAxes objectForKey: axFuncKey]];
469 : break;
470 : case HW_BUTTON:
471 : allowedThings=@"Button";
472 : int bf = [butFuncKey integerValue];
473 : if (bf < 10000)
474 : {
475 : assignment=[self describeStickDict:
476 : [assignedButs objectForKey: butFuncKey]];
477 : }
478 : else
479 : {
480 : NSString *key = CUSTOMEQUIP_BUTTONACTIVATE;
481 : bf -= 10000;
482 : if (bf >= 10000)
483 : {
484 : bf -= 10000;
485 : key = CUSTOMEQUIP_BUTTONMODE;
486 : }
487 : assignment=[self describeStickDict:
488 : [[customEquipActivation objectAtIndex:bf] objectForKey:key]];
489 : }
490 : break;
491 : default:
492 : allowedThings=@"Axis/Button";
493 :
494 : // axis has priority
495 : assignment=[self describeStickDict:
496 : [assignedAxes objectForKey: axFuncKey]];
497 : if(!assignment)
498 : assignment=[self describeStickDict:
499 : [assignedButs objectForKey: butFuncKey]];
500 : }
501 :
502 : // Find out what's assigned for this function currently.
503 : if (assignment == nil)
504 : {
505 : assignment = @" - ";
506 : }
507 :
508 : [gui setArray: [NSArray arrayWithObjects:
509 : [entry objectForKey: KEY_GUIDESC], assignment, allowedThings, nil]
510 : forRow: i + start_row];
511 : //[gui setKey: GUI_KEY_OK forRow: i + start_row];
512 : [gui setKey: [NSString stringWithFormat: @"Index:%ld", i + skip] forRow: i + start_row];
513 : }
514 : }
515 : if (i < n_functions - skip)
516 : {
517 : [gui setColor: [OOColor greenColor] forRow: start_row + i];
518 : [gui setArray: [NSArray arrayWithObjects: DESC(@"gui-more"), @" --> ", nil] forRow: start_row + i];
519 : [gui setKey: [NSString stringWithFormat: @"More:%ld", n_rows + skip] forRow: start_row + i];
520 : i++;
521 : }
522 :
523 : [gui setSelectableRange: NSMakeRange(GUI_ROW_STICKPROFILE, i + start_row - GUI_ROW_STICKPROFILE)];
524 : }
525 :
526 : }
527 :
528 :
529 0 : - (NSString *) describeStickDict: (NSDictionary *)stickDict
530 : {
531 : NSString *desc=nil;
532 : if(stickDict)
533 : {
534 : int thingNumber=[(NSNumber *)[stickDict objectForKey: STICK_AXBUT]
535 : intValue];
536 : int stickNumber=[(NSNumber *)[stickDict objectForKey: STICK_NUMBER]
537 : intValue];
538 : // Button or axis?
539 : if([(NSNumber *)[stickDict objectForKey: STICK_ISAXIS] boolValue])
540 : {
541 : desc=[NSString stringWithFormat: @"Stick %d axis %d",
542 : stickNumber+1, thingNumber+1];
543 : }
544 : else if(thingNumber >= MAX_REAL_BUTTONS)
545 : {
546 : static const char dir[][6] = { "up", "right", "down", "left" };
547 : desc=[NSString stringWithFormat: @"Stick %d hat %d %s",
548 : stickNumber+1, (thingNumber - MAX_REAL_BUTTONS) / 4 + 1,
549 : dir[thingNumber & 3]];
550 : }
551 : else
552 : {
553 : desc=[NSString stringWithFormat: @"Stick %d button %d",
554 : stickNumber+1, thingNumber+1];
555 : }
556 : }
557 : return desc;
558 : }
559 :
560 :
561 0 : - (NSString *)hwToString: (int)hwFlags
562 : {
563 : NSString *hwString;
564 : switch(hwFlags)
565 : {
566 : case HW_AXIS:
567 : hwString = @"axis";
568 : break;
569 : case HW_BUTTON:
570 : hwString = @"button";
571 : break;
572 : default:
573 : hwString = @"axis/button";
574 : }
575 : return hwString;
576 : }
577 :
578 :
579 : // TODO: This data could be put into a plist (i18n or just modifiable by
580 : // the user). It is otherwise an ugly method, but it'll do for testing.
581 0 : - (NSArray *)stickFunctionList
582 : {
583 : NSMutableArray *funcList = [NSMutableArray array];
584 :
585 : // propulsion
586 : [funcList addObject:[self makeStickGuiDictHeader:DESC(@"stickmapper-header-propulsion")]];
587 : [funcList addObject:
588 : [self makeStickGuiDict:DESC(@"stickmapper-roll")
589 : allowable:HW_AXIS
590 : axisfn:AXIS_ROLL
591 : butfn:STICK_NOFUNCTION]];
592 : [funcList addObject:
593 : [self makeStickGuiDict:DESC(@"stickmapper-pitch")
594 : allowable:HW_AXIS
595 : axisfn:AXIS_PITCH
596 : butfn:STICK_NOFUNCTION]];
597 : [funcList addObject:
598 : [self makeStickGuiDict:DESC(@"stickmapper-yaw")
599 : allowable:HW_AXIS
600 : axisfn:AXIS_YAW
601 : butfn:STICK_NOFUNCTION]];
602 : [funcList addObject:
603 : [self makeStickGuiDict:DESC(@"stickmapper-increase-thrust")
604 : allowable:HW_AXIS|HW_BUTTON
605 : axisfn:AXIS_THRUST
606 : butfn:BUTTON_INCTHRUST]];
607 : [funcList addObject:
608 : [self makeStickGuiDict:DESC(@"stickmapper-decrease-thrust")
609 : allowable:HW_AXIS|HW_BUTTON
610 : axisfn:AXIS_THRUST
611 : butfn:BUTTON_DECTHRUST]];
612 : [funcList addObject:
613 : [self makeStickGuiDict:DESC(@"stickmapper-fuel-injection")
614 : allowable:HW_BUTTON
615 : axisfn:STICK_NOFUNCTION
616 : butfn:BUTTON_FUELINJECT]];
617 : [funcList addObject:
618 : [self makeStickGuiDict:DESC(@"stickmapper-hyperspeed")
619 : allowable:HW_BUTTON
620 : axisfn:STICK_NOFUNCTION
621 : butfn:BUTTON_HYPERSPEED]];
622 : [funcList addObject:
623 : [self makeStickGuiDict:DESC(@"stickmapper-hyperdrive")
624 : allowable:HW_BUTTON
625 : axisfn:STICK_NOFUNCTION
626 : butfn:BUTTON_HYPERDRIVE]];
627 : [funcList addObject:
628 : [self makeStickGuiDict:DESC(@"stickmapper-gal-hyperdrive")
629 : allowable:HW_BUTTON
630 : axisfn:STICK_NOFUNCTION
631 : butfn:BUTTON_GALACTICDRIVE]];
632 :
633 : [funcList addObject:
634 : [self makeStickGuiDict:DESC(@"stickmapper-roll/pitch-precision-toggle")
635 : allowable:HW_BUTTON
636 : axisfn:STICK_NOFUNCTION
637 : butfn:BUTTON_PRECISION]];
638 :
639 : // navigation
640 : [funcList addObject:[self makeStickGuiDictHeader:DESC(@"stickmapper-header-navigation")]];
641 : [funcList addObject:
642 : [self makeStickGuiDict:DESC(@"stickmapper-compass-mode-next")
643 : allowable:HW_BUTTON
644 : axisfn:STICK_NOFUNCTION
645 : butfn:BUTTON_COMPASSMODE]];
646 : [funcList addObject:
647 : [self makeStickGuiDict:DESC(@"stickmapper-compass-mode-prev")
648 : allowable:HW_BUTTON
649 : axisfn:STICK_NOFUNCTION
650 : butfn:BUTTON_COMPASSMODE_PREV]];
651 : [funcList addObject:
652 : [self makeStickGuiDict:DESC(@"stickmapper-scanner-zoom")
653 : allowable:HW_BUTTON
654 : axisfn:STICK_NOFUNCTION
655 : butfn:BUTTON_SCANNERZOOM]];
656 : [funcList addObject:
657 : [self makeStickGuiDict:DESC(@"stickmapper-scanner-unzoom")
658 : allowable:HW_BUTTON
659 : axisfn:STICK_NOFUNCTION
660 : butfn:BUTTON_SCANNERUNZOOM]];
661 : [funcList addObject:
662 : [self makeStickGuiDict:DESC(@"stickmapper-view-forward")
663 : allowable:HW_AXIS|HW_BUTTON
664 : axisfn:AXIS_VIEWY
665 : butfn:BUTTON_VIEWFORWARD]];
666 : [funcList addObject:
667 : [self makeStickGuiDict:DESC(@"stickmapper-view-aft")
668 : allowable:HW_AXIS|HW_BUTTON
669 : axisfn:AXIS_VIEWY
670 : butfn:BUTTON_VIEWAFT]];
671 : [funcList addObject:
672 : [self makeStickGuiDict:DESC(@"stickmapper-view-port")
673 : allowable:HW_AXIS|HW_BUTTON
674 : axisfn:AXIS_VIEWX
675 : butfn:BUTTON_VIEWPORT]];
676 : [funcList addObject:
677 : [self makeStickGuiDict:DESC(@"stickmapper-view-starboard")
678 : allowable:HW_AXIS|HW_BUTTON
679 : axisfn:AXIS_VIEWX
680 : butfn:BUTTON_VIEWSTARBOARD]];
681 : [funcList addObject:
682 : [self makeStickGuiDict:DESC(@"stickmapper-ext-view-cycle")
683 : allowable:HW_BUTTON
684 : axisfn:STICK_NOFUNCTION
685 : butfn:BUTTON_EXTVIEWCYCLE]];
686 : [funcList addObject:
687 : [self makeStickGuiDict:DESC(@"stickmapper-toggle-ID")
688 : allowable:HW_BUTTON
689 : axisfn:STICK_NOFUNCTION
690 : butfn:BUTTON_ID]];
691 : [funcList addObject:
692 : [self makeStickGuiDict:DESC(@"stickmapper-docking-clearance")
693 : allowable:HW_BUTTON
694 : axisfn:STICK_NOFUNCTION
695 : butfn:BUTTON_DOCKINGCLEARANCE]];
696 : [funcList addObject:
697 : [self makeStickGuiDict:DESC(@"stickmapper-dockcpu")
698 : allowable:HW_BUTTON
699 : axisfn:STICK_NOFUNCTION
700 : butfn:BUTTON_DOCKCPU]];
701 : [funcList addObject:
702 : [self makeStickGuiDict:DESC(@"stickmapper-dockcpufast")
703 : allowable:HW_BUTTON
704 : axisfn:STICK_NOFUNCTION
705 : butfn:BUTTON_DOCKCPUFAST]];
706 : [funcList addObject:
707 : [self makeStickGuiDict:DESC(@"stickmapper-docking-music")
708 : allowable:HW_BUTTON
709 : axisfn:STICK_NOFUNCTION
710 : butfn:BUTTON_DOCKINGMUSIC]];
711 :
712 : // offensive
713 : [funcList addObject:[self makeStickGuiDictHeader:DESC(@"stickmapper-header-offensive")]];
714 : [funcList addObject:
715 : [self makeStickGuiDict:DESC(@"stickmapper-weapons-online-toggle")
716 : allowable:HW_BUTTON
717 : axisfn:STICK_NOFUNCTION
718 : butfn:BUTTON_WEAPONSONLINETOGGLE]];
719 : [funcList addObject:
720 : [self makeStickGuiDict:DESC(@"stickmapper-primary-weapon")
721 : allowable:HW_BUTTON
722 : axisfn:STICK_NOFUNCTION
723 : butfn:BUTTON_FIRE]];
724 : [funcList addObject:
725 : [self makeStickGuiDict:DESC(@"stickmapper-secondary-weapon")
726 : allowable:HW_BUTTON
727 : axisfn:STICK_NOFUNCTION
728 : butfn:BUTTON_LAUNCHMISSILE]];
729 : [funcList addObject:
730 : [self makeStickGuiDict:DESC(@"stickmapper-arm-secondary")
731 : allowable:HW_BUTTON
732 : axisfn:STICK_NOFUNCTION
733 : butfn:BUTTON_ARMMISSILE]];
734 : [funcList addObject:
735 : [self makeStickGuiDict:DESC(@"stickmapper-disarm-secondary")
736 : allowable:HW_BUTTON
737 : axisfn:STICK_NOFUNCTION
738 : butfn:BUTTON_UNARM]];
739 : [funcList addObject:
740 : [self makeStickGuiDict:DESC(@"stickmapper-target-nearest-incoming-missile")
741 : allowable:HW_BUTTON
742 : axisfn:STICK_NOFUNCTION
743 : butfn:BUTTON_TARGETINCOMINGMISSILE]];
744 : [funcList addObject:
745 : [self makeStickGuiDict:DESC(@"stickmapper-cycle-secondary")
746 : allowable:HW_BUTTON
747 : axisfn:STICK_NOFUNCTION
748 : butfn:BUTTON_CYCLEMISSILE]];
749 : [funcList addObject:
750 : [self makeStickGuiDict:DESC(@"stickmapper-next-target")
751 : allowable:HW_BUTTON
752 : axisfn:STICK_NOFUNCTION
753 : butfn:BUTTON_NEXTTARGET]];
754 : [funcList addObject:
755 : [self makeStickGuiDict:DESC(@"stickmapper-previous-target")
756 : allowable:HW_BUTTON
757 : axisfn:STICK_NOFUNCTION
758 : butfn:BUTTON_PREVTARGET]];
759 :
760 : // defensive
761 : [funcList addObject:[self makeStickGuiDictHeader:DESC(@"stickmapper-header-defensive")]];
762 : [funcList addObject:
763 : [self makeStickGuiDict:DESC(@"stickmapper-ECM")
764 : allowable:HW_BUTTON
765 : axisfn:STICK_NOFUNCTION
766 : butfn:BUTTON_ECM]];
767 : [funcList addObject:
768 : [self makeStickGuiDict:DESC(@"stickmapper-jettison")
769 : allowable:HW_BUTTON
770 : axisfn:STICK_NOFUNCTION
771 : butfn:BUTTON_JETTISON]];
772 : [funcList addObject:
773 : [self makeStickGuiDict:DESC(@"stickmapper-rotate-cargo")
774 : allowable:HW_BUTTON
775 : axisfn:STICK_NOFUNCTION
776 : butfn:BUTTON_ROTATECARGO]];
777 : [funcList addObject:
778 : [self makeStickGuiDict:DESC(@"stickmapper-escape-pod")
779 : allowable:HW_BUTTON
780 : axisfn:STICK_NOFUNCTION
781 : butfn:BUTTON_ESCAPE]];
782 :
783 : // oxp special equip
784 : [funcList addObject:[self makeStickGuiDictHeader:DESC(@"stickmapper-header-special-equip")]];
785 : [funcList addObject:
786 : [self makeStickGuiDict:DESC(@"stickmapper-mfd-select-next")
787 : allowable:HW_BUTTON
788 : axisfn:STICK_NOFUNCTION
789 : butfn:BUTTON_MFDSELECTNEXT]];
790 : [funcList addObject:
791 : [self makeStickGuiDict:DESC(@"stickmapper-mfd-select-prev")
792 : allowable:HW_BUTTON
793 : axisfn:STICK_NOFUNCTION
794 : butfn:BUTTON_MFDSELECTPREV]];
795 : [funcList addObject:
796 : [self makeStickGuiDict:DESC(@"stickmapper-mfd-cycle-next")
797 : allowable:HW_BUTTON
798 : axisfn:STICK_NOFUNCTION
799 : butfn:BUTTON_MFDCYCLENEXT]];
800 : [funcList addObject:
801 : [self makeStickGuiDict:DESC(@"stickmapper-mfd-cycle-prev")
802 : allowable:HW_BUTTON
803 : axisfn:STICK_NOFUNCTION
804 : butfn:BUTTON_MFDCYCLEPREV]];
805 : [funcList addObject:
806 : [self makeStickGuiDict:DESC(@"stickmapper-prime-equipment")
807 : allowable:HW_BUTTON
808 : axisfn:STICK_NOFUNCTION
809 : butfn:BUTTON_PRIMEEQUIPMENT]];
810 : [funcList addObject:
811 : [self makeStickGuiDict:DESC(@"stickmapper-prime-prev-equipment")
812 : allowable:HW_BUTTON
813 : axisfn:STICK_NOFUNCTION
814 : butfn:BUTTON_PRIMEEQUIPMENT]];
815 : [funcList addObject:
816 : [self makeStickGuiDict:DESC(@"stickmapper-activate-equipment")
817 : allowable:HW_BUTTON
818 : axisfn:STICK_NOFUNCTION
819 : butfn:BUTTON_ACTIVATEEQUIPMENT]];
820 : [funcList addObject:
821 : [self makeStickGuiDict:DESC(@"stickmapper-mode-equipment")
822 : allowable:HW_BUTTON
823 : axisfn:STICK_NOFUNCTION
824 : butfn:BUTTON_MODEEQUIPMENT]];
825 : [funcList addObject:
826 : [self makeStickGuiDict:DESC(@"stickmapper-fastactivate-a")
827 : allowable:HW_BUTTON
828 : axisfn:STICK_NOFUNCTION
829 : butfn:BUTTON_CLOAK]];
830 : [funcList addObject:
831 : [self makeStickGuiDict:DESC(@"stickmapper-fastactivate-b")
832 : allowable:HW_BUTTON
833 : axisfn:STICK_NOFUNCTION
834 : butfn:BUTTON_ENERGYBOMB]];
835 :
836 : // misc
837 : [funcList addObject:[self makeStickGuiDictHeader:DESC(@"stickmapper-header-misc")]];
838 : [funcList addObject:
839 : [self makeStickGuiDict:DESC(@"stickmapper-snapshot")
840 : allowable:HW_BUTTON
841 : axisfn:STICK_NOFUNCTION
842 : butfn:BUTTON_SNAPSHOT]];
843 : [funcList addObject:
844 : [self makeStickGuiDict:DESC(@"stickmapper-pause")
845 : allowable:HW_BUTTON
846 : axisfn:STICK_NOFUNCTION
847 : butfn:BUTTON_PAUSE]];
848 : [funcList addObject:
849 : [self makeStickGuiDict:DESC(@"stickmapper-toggle-hud")
850 : allowable:HW_BUTTON
851 : axisfn:STICK_NOFUNCTION
852 : butfn:BUTTON_TOGGLEHUD]];
853 : [funcList addObject:
854 : [self makeStickGuiDict:DESC(@"stickmapper-comms-log")
855 : allowable:HW_BUTTON
856 : axisfn:STICK_NOFUNCTION
857 : butfn:BUTTON_COMMSLOG]];
858 : #if OO_FOV_INFLIGHT_CONTROL_ENABLED
859 : [funcList addObject:
860 : [self makeStickGuiDict:DESC(@"stickmapper-increase-field-of-view")
861 : allowable:HW_AXIS|HW_BUTTON
862 : axisfn:AXIS_FIELD_OF_VIEW
863 : butfn:BUTTON_INC_FIELD_OF_VIEW]];
864 : [funcList addObject:
865 : [self makeStickGuiDict:DESC(@"stickmapper-decrease-field-of-view")
866 : allowable:HW_AXIS|HW_BUTTON
867 : axisfn:AXIS_FIELD_OF_VIEW
868 : butfn:BUTTON_DEC_FIELD_OF_VIEW]];
869 : #endif
870 : if ([customEquipActivation count] > 0) {
871 : [funcList addObject:[self makeStickGuiDictHeader:DESC(@"stickmapper-header-oxp-equip")]];
872 : int i;
873 : for (i = 0; i < [customEquipActivation count]; i++)
874 : {
875 : [funcList addObject:
876 : [self makeStickGuiDict:[NSString stringWithFormat: @"Activate '%@'", [[customEquipActivation objectAtIndex:i] oo_stringForKey:CUSTOMEQUIP_EQUIPNAME]]
877 : allowable:HW_BUTTON
878 : axisfn:STICK_NOFUNCTION
879 : butfn:(i+10000)]];
880 : [funcList addObject:
881 : [self makeStickGuiDict:[NSString stringWithFormat: @"Mode '%@'", [[customEquipActivation objectAtIndex:i] oo_stringForKey:CUSTOMEQUIP_EQUIPNAME]]
882 : allowable:HW_BUTTON
883 : axisfn:STICK_NOFUNCTION
884 : butfn:(i+20000)]];
885 : }
886 :
887 : }
888 : return funcList;
889 : }
890 :
891 :
892 :
893 : - (NSDictionary *)makeStickGuiDict:(NSString *)what
894 : allowable:(int)allowable
895 : axisfn:(int)axisfn
896 : butfn:(int)butfn
897 : {
898 : NSMutableDictionary *guiDict = [NSMutableDictionary dictionary];
899 :
900 : if ([what length] > 50) what = [[what substringToIndex:28] stringByAppendingString:@"..."];
901 : [guiDict setObject: what forKey: KEY_GUIDESC];
902 : [guiDict setObject: [NSNumber numberWithInt: allowable]
903 : forKey: KEY_ALLOWABLE];
904 : if(axisfn >= 0)
905 : [guiDict setObject: [NSNumber numberWithInt: axisfn]
906 : forKey: KEY_AXISFN];
907 : if(butfn >= 0)
908 : [guiDict setObject: [NSNumber numberWithInt: butfn]
909 : forKey: KEY_BUTTONFN];
910 : return guiDict;
911 : }
912 :
913 : - (NSDictionary *)makeStickGuiDictHeader:(NSString *)header
914 : {
915 : NSMutableDictionary *guiDict = [NSMutableDictionary dictionary];
916 : [guiDict setObject:header forKey:KEY_HEADER];
917 : [guiDict setObject:@"" forKey:KEY_ALLOWABLE];
918 : [guiDict setObject:@"" forKey:KEY_AXISFN];
919 : [guiDict setObject:@"" forKey:KEY_BUTTONFN];
920 : return guiDict;
921 : }
922 :
923 : @end
924 :
|