LCOV - code coverage report
Current view: top level - Core/Entities - PlayerEntityStickMapper.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 14 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          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             : 

Generated by: LCOV version 1.14