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

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

Generated by: LCOV version 1.14