Line data Source code
1 0 : /*
2 :
3 : OOJoystickManager.h
4 : By Dylan Smith
5 : modified by Alex Smith and Jens Ayton
6 :
7 : JoystickHandler handles joystick events from SDL, and translates them
8 : into the appropriate action via a lookup table. The lookup table is
9 : stored as a simple array rather than an ObjC dictionary since this
10 : will be examined fairly often (once per frame during gameplay).
11 :
12 : Conversion methods are provided to convert between the internal
13 : representation and an NSDictionary (for loading/saving user defaults
14 : and for use in areas where portability/ease of coding are more important
15 : than performance such as the GUI)
16 :
17 :
18 : Oolite
19 : Copyright (C) 2004-2013 Giles C Williams and contributors
20 :
21 : This program is free software; you can redistribute it and/or
22 : modify it under the terms of the GNU General Public License
23 : as published by the Free Software Foundation; either version 2
24 : of the License, or (at your option) any later version.
25 :
26 : This program is distributed in the hope that it will be useful,
27 : but WITHOUT ANY WARRANTY; without even the implied warranty of
28 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 : GNU General Public License for more details.
30 :
31 : You should have received a copy of the GNU General Public License
32 : along with this program; if not, write to the Free Software
33 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
34 : MA 02110-1301, USA.
35 :
36 : */
37 :
38 : #import "OOCocoa.h"
39 :
40 :
41 : // Enums are used here rather than a more complex ObjC object because
42 : // these are required very frequently (once per frame) so must be light
43 : // on CPU cycles (try and avoid too many objc sendmsgs).
44 : // Controls that can be an axis
45 0 : enum {
46 : AXIS_ROLL,
47 : AXIS_PITCH,
48 : AXIS_YAW,
49 : AXIS_PRECISION,
50 : AXIS_THRUST,
51 : AXIS_VIEWX,
52 : AXIS_VIEWY,
53 : #if OO_FOV_INFLIGHT_CONTROL_ENABLED
54 : AXIS_FIELD_OF_VIEW,
55 : #endif
56 : AXIS_end
57 : };
58 :
59 : // Controls that can be a button
60 0 : enum {
61 : BUTTON_INCTHRUST,
62 : BUTTON_DECTHRUST,
63 : BUTTON_SCANNERZOOM,
64 : BUTTON_SCANNERUNZOOM,
65 : BUTTON_JETTISON,
66 : BUTTON_COMPASSMODE,
67 : BUTTON_COMMSLOG,
68 : BUTTON_DOCKCPU,
69 : BUTTON_DOCKCPUFAST,
70 : BUTTON_FUELINJECT,
71 : BUTTON_HYPERSPEED,
72 : BUTTON_HYPERDRIVE,
73 : BUTTON_GALACTICDRIVE,
74 : BUTTON_FIRE,
75 : BUTTON_ARMMISSILE,
76 : BUTTON_LAUNCHMISSILE,
77 : BUTTON_PRIMEEQUIPMENT,
78 : BUTTON_ACTIVATEEQUIPMENT,
79 : BUTTON_UNARM,
80 : BUTTON_TARGETINCOMINGMISSILE,
81 : BUTTON_CYCLEMISSILE,
82 : BUTTON_ENERGYBOMB, // now fast activate B
83 : BUTTON_WEAPONSONLINETOGGLE,
84 : BUTTON_ID,
85 : BUTTON_ECM,
86 : BUTTON_ESCAPE,
87 : BUTTON_CLOAK, // now fast activate A
88 : BUTTON_PRECISION,
89 : BUTTON_VIEWFORWARD,
90 : BUTTON_VIEWAFT,
91 : BUTTON_VIEWPORT,
92 : BUTTON_VIEWSTARBOARD,
93 : BUTTON_SNAPSHOT,
94 : BUTTON_PREVTARGET,
95 : BUTTON_NEXTTARGET,
96 : BUTTON_MODEEQUIPMENT,
97 : #if OO_FOV_INFLIGHT_CONTROL_ENABLED
98 : BUTTON_INC_FIELD_OF_VIEW,
99 : BUTTON_DEC_FIELD_OF_VIEW,
100 : #endif
101 : BUTTON_DOCKINGCLEARANCE,
102 : BUTTON_COMPASSMODE_PREV,
103 : BUTTON_PRIMEEQUIPMENT_PREV,
104 : BUTTON_ROTATECARGO,
105 : BUTTON_MFDSELECTNEXT,
106 : BUTTON_MFDSELECTPREV,
107 : BUTTON_MFDCYCLENEXT,
108 : BUTTON_MFDCYCLEPREV,
109 : BUTTON_EXTVIEWCYCLE,
110 : BUTTON_DOCKINGMUSIC,
111 : BUTTON_PAUSE,
112 : BUTTON_TOGGLEHUD,
113 : BUTTON_end
114 : };
115 :
116 : // Stick constants
117 0 : #define MAX_STICKS 4
118 0 : #define MAX_AXES 16
119 0 : #define MAX_REAL_BUTTONS 64
120 0 : #define MAX_HATS 4
121 0 : #define MAX_BUTTONS (MAX_REAL_BUTTONS + 4 * MAX_HATS)
122 0 : #define STICK_NOFUNCTION -1
123 0 : #define STICK_AXISUNASSIGNED -10.0
124 :
125 0 : #define STICK_PRECISIONFAC 3
126 0 : #define STICK_NORMALDIV 32768
127 0 : #define STICK_PRECISIONDIV (STICK_PRECISIONFAC*STICK_NORMALDIV)
128 :
129 : #if OOLITE_MAC_OS_X
130 0 : #define STICK_DEADZONE 0.0025
131 : #else
132 : #define STICK_DEADZONE 0.05
133 : #endif
134 :
135 0 : #define STICK_MAX_DEADZONE (STICK_DEADZONE * 2)
136 :
137 :
138 : // Kind of stick device (these are bits - if any more are added,
139 : // the next one is 4 and so on).
140 0 : #define HW_AXIS 1
141 0 : #define HW_BUTTON 2
142 :
143 : // The threshold at which an axis can trigger a call back.
144 : // The max of abs(axis) is 32767.
145 0 : #define AXCBTHRESH 20000
146 :
147 : // Dictionary keys - used in the defaults file
148 0 : #define AXIS_SETTINGS @"JoystickAxes" // NSUserDefaults
149 0 : #define BUTTON_SETTINGS @"JoystickButs" // NSUserDefaults
150 0 : #define STICK_ISAXIS @"isAxis" // YES=axis NO=button
151 0 : #define STICK_NUMBER @"stickNum" // Stick number 0 to 4
152 0 : #define STICK_AXBUT @"stickAxBt" // Axis or button number
153 0 : #define STICK_FUNCTION @"stickFunc" // Function of axis/button
154 0 : #define STICK_ROLL_AXIS_PROFILE_SETTING @"RollAxisProfile" // Joystick Profiles
155 0 : #define STICK_PITCH_AXIS_PROFILE_SETTING @"PitchAxisProfile" // Joystick Profiles
156 0 : #define STICK_YAW_AXIS_PROFILE_SETTING @"YawAxisProfile" // Joystick Profiles
157 : // shortcut to make code more readable when using enum as key for
158 : // an NSDictionary
159 0 : #define ENUMKEY(x) [NSString stringWithFormat: @"%d", x]
160 :
161 :
162 :
163 : //SDL Abstracted constants
164 :
165 : #if OOLITE_SDL
166 :
167 : #import <SDL.h>
168 :
169 : enum
170 : {
171 : JOYAXISMOTION = SDL_JOYAXISMOTION,
172 : JOYBUTTONDOWN = SDL_JOYBUTTONDOWN,
173 : JOYBUTTONUP = SDL_JOYBUTTONUP,
174 : JOYBUTTON_PRESSED = SDL_PRESSED,
175 : JOYBUTTON_RELEASED = SDL_RELEASED,
176 : JOYHAT_MOTION = SDL_JOYHATMOTION,
177 :
178 : JOYHAT_CENTERED = SDL_HAT_CENTERED,
179 : JOYHAT_UP = SDL_HAT_UP,
180 : JOYHAT_RIGHT = SDL_HAT_RIGHT,
181 : JOYHAT_DOWN = SDL_HAT_DOWN,
182 : JOYHAT_LEFT = SDL_HAT_LEFT,
183 : JOYHAT_RIGHTUP = SDL_HAT_RIGHTUP,
184 : JOYHAT_RIGHTDOWN = SDL_HAT_RIGHTDOWN,
185 : JOYHAT_LEFTUP = SDL_HAT_LEFTUP,
186 : JOYHAT_LEFTDOWN = SDL_HAT_LEFTDOWN,
187 : };
188 :
189 : typedef SDL_JoyButtonEvent JoyButtonEvent;
190 : typedef SDL_JoyAxisEvent JoyAxisEvent;
191 : typedef SDL_JoyHatEvent JoyHatEvent;
192 :
193 : #else
194 :
195 0 : enum
196 : {
197 : JOYAXISMOTION,
198 : JOYBUTTONDOWN,
199 : JOYBUTTONUP,
200 : JOYBUTTON_PRESSED,
201 : JOYBUTTON_RELEASED,
202 : JOYHAT_MOTION,
203 :
204 : JOYHAT_CENTERED = 0x00,
205 : JOYHAT_UP = 0x01,
206 : JOYHAT_RIGHT = 0x02,
207 : JOYHAT_DOWN = 0x04,
208 : JOYHAT_LEFT = 0x08,
209 : JOYHAT_RIGHTUP = (JOYHAT_RIGHT|JOYHAT_UP),
210 : JOYHAT_RIGHTDOWN = (JOYHAT_RIGHT|JOYHAT_DOWN),
211 : JOYHAT_LEFTUP = (JOYHAT_LEFT|JOYHAT_UP),
212 : JOYHAT_LEFTDOWN = (JOYHAT_LEFT|JOYHAT_DOWN),
213 : };
214 :
215 : // Abstracted SDL event types
216 0 : typedef struct
217 : {
218 0 : uint32_t type;
219 0 : uint8_t which;
220 0 : uint8_t axis;
221 0 : int value;
222 : } JoyAxisEvent;
223 :
224 0 : typedef struct
225 : {
226 0 : uint32_t type;
227 0 : uint8_t which;
228 0 : uint8_t button;
229 0 : int state;
230 :
231 : } JoyButtonEvent;
232 :
233 0 : typedef struct
234 : {
235 0 : uint32_t type;
236 0 : uint8_t which;
237 0 : uint8_t hat;
238 0 : uint8_t value;
239 0 : uint8_t padding;
240 : } JoyHatEvent;
241 :
242 : #endif //OOLITE_SDL
243 :
244 :
245 : #import "OOJoystickProfile.h"
246 :
247 0 : @interface OOJoystickManager: NSObject
248 : {
249 : @private
250 : // Axis/button mapping arrays
251 0 : int8_t axismap[MAX_STICKS][MAX_AXES];
252 0 : int8_t buttonmap[MAX_STICKS][MAX_BUTTONS];
253 0 : BOOL true_butstate[MAX_STICKS][MAX_BUTTONS];
254 0 : double axstate[AXIS_end];
255 0 : BOOL butstate[BUTTON_end];
256 0 : uint8_t hatstate[MAX_STICKS][MAX_HATS];
257 0 : BOOL precisionMode;
258 0 : OOJoystickAxisProfile *roll_profile;
259 0 : OOJoystickAxisProfile *pitch_profile;
260 0 : OOJoystickAxisProfile *yaw_profile;
261 :
262 : // Handle callbacks - the object, selector to call
263 : // the desired function, and the hardware (axis or button etc.)
264 0 : id cbObject;
265 0 : SEL cbSelector;
266 0 : char cbHardware;
267 0 : BOOL invertPitch;
268 :
269 : }
270 :
271 0 : + (id) sharedStickHandler;
272 0 : + (BOOL) setStickHandlerClass:(Class)aClass;
273 :
274 : // General.
275 : // Note: handleSDLEvent returns a BOOL (YES we handled it or NO we
276 : // didn't) so in the future when more handler classes are written,
277 : // the GameView event loop can just go through an NSArray of handlers
278 : // until it finds a handler that handles the event.
279 0 : - (id) init;
280 :
281 : // Roll/pitch axis
282 0 : - (NSPoint) rollPitchAxis;
283 :
284 : // View axis
285 0 : - (NSPoint) viewAxis;
286 :
287 : // convert a dictionary into the internal function map
288 0 : - (void) setFunction:(int)function withDict: (NSDictionary *)stickFn;
289 0 : - (void) unsetAxisFunction:(int)function;
290 0 : - (void) unsetButtonFunction:(int)function;
291 :
292 : // Accessors and discovery about the hardware.
293 : // These work directly on the internal lookup table so to be fast
294 : // since they are likely to be called by the game loop.
295 0 : - (NSUInteger) joystickCount;
296 0 : - (BOOL) isButtonDown:(int)button stick:(int)stickNum;
297 0 : - (BOOL) getButtonState:(int)function;
298 0 : - (double) getAxisState:(int)function;
299 0 : - (double) getSensitivity;
300 :
301 : // Axis profile handling
302 0 : - (void) setProfile: (OOJoystickAxisProfile *) profile forAxis:(int) axis;
303 0 : - (OOJoystickAxisProfile *) getProfileForAxis: (int) axis;
304 0 : - (void) saveProfileForAxis: (int) axis;
305 0 : - (void) loadProfileForAxis: (int) axis;
306 :
307 : // This one just returns a pointer to the entire state array to
308 : // allow for multiple lookups with only one objc_sendMsg
309 0 : - (const BOOL *) getAllButtonStates;
310 :
311 : // Hardware introspection.
312 0 : - (NSArray *) listSticks;
313 :
314 : // These use NSDictionary/NSArray since they are used outside the game
315 : // loop and are needed for loading/saving defaults.
316 0 : - (NSDictionary *) axisFunctions;
317 0 : - (NSDictionary *) buttonFunctions;
318 :
319 : // Set a callback for the next moved axis/pressed button. hwflags
320 : // is in the form HW_AXIS | HW_BUTTON (or just one of).
321 0 : - (void)setCallback:(SEL)selector
322 : object:(id)obj
323 : hardware:(char)hwflags;
324 0 : - (void)clearCallback;
325 :
326 : // Methods generally only used by this class.
327 0 : - (void) setDefaultMapping;
328 0 : - (void) clearMappings;
329 0 : - (void) clearStickStates;
330 0 : - (void) clearStickButtonState: (int)stickButton;
331 0 : - (void) decodeAxisEvent: (JoyAxisEvent *)evt;
332 0 : - (void) decodeButtonEvent: (JoyButtonEvent *)evt;
333 0 : - (void) decodeHatEvent: (JoyHatEvent *)evt;
334 0 : - (void) saveStickSettings;
335 0 : - (void) loadStickSettings;
336 :
337 :
338 : //Methods that should be overridden by all subclasses
339 0 : - (NSString *) nameOfJoystick:(NSUInteger)stickNumber;
340 0 : - (int16_t) getAxisWithStick:(NSUInteger) stickNum axis:(NSUInteger)axisNum;
341 :
342 : @end
|