]> git.mxchange.org Git - flightgear.git/blob - src/Input/input.hxx
Mark's dynamic sun color changes.
[flightgear.git] / src / Input / input.hxx
1 // input.hxx -- handle user input from various sources.
2 //
3 // Written by David Megginson, started May 2001.
4 //
5 // Copyright (C) 2001 David Megginson, david@megginson.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23
24 #ifndef _INPUT_HXX
25 #define _INPUT_HXX
26
27 #ifndef __cplusplus                                                          
28 # error This library requires C++
29 #endif
30
31 #include <plib/js.h>
32 #include <plib/ul.h>
33
34 #include <simgear/compiler.h>
35
36 #include <simgear/misc/sg_path.hxx>
37 #include <simgear/structure/subsystem_mgr.hxx>
38 #include <simgear/structure/commands.hxx>
39 #include <simgear/props/condition.hxx>
40 #include <simgear/props/props.hxx>
41
42 #include <Main/fg_os.hxx>
43 #include <Main/fg_props.hxx>
44 #include <Main/globals.hxx>
45
46 #include <map>
47 #include <vector>
48
49 SG_USING_STD(map);
50 SG_USING_STD(vector);
51
52
53 \f
54
55 #if defined( UL_WIN32 )
56 #define TGT_PLATFORM    "windows"
57 #elif defined ( UL_MAC_OSX )
58 #define TGT_PLATFORM    "mac"
59 #else
60 #define TGT_PLATFORM    "unix"
61 #endif
62
63
64 \f
65 ////////////////////////////////////////////////////////////////////////
66 // General binding support.
67 ////////////////////////////////////////////////////////////////////////
68
69
70 /**
71  * An input binding of some sort.
72  *
73  * <p>This class represents a binding that can be assigned to a
74  * keyboard key, a joystick button or axis, or even a panel
75  * instrument.</p>
76  */
77 class FGBinding : public SGConditional
78 {
79 public:
80
81   /**
82    * Default constructor.
83    */
84   FGBinding ();
85
86
87   /**
88    * Convenience constructor.
89    *
90    * @param node The binding will be built from this node.
91    */
92   FGBinding (const SGPropertyNode * node);
93
94
95   /**
96    * Destructor.
97    */
98   virtual ~FGBinding ();
99
100
101   /**
102    * Get the command name.
103    *
104    * @return The string name of the command for this binding.
105    */
106   virtual const string &getCommandName () const { return _command_name; }
107
108
109   /**
110    * Get the command itself.
111    *
112    * @return The command associated with this binding, or 0 if none
113    * is present.
114    */
115   virtual SGCommandMgr::command_t getCommand () const { return _command; }
116
117
118   /**
119    * Get the argument that will be passed to the command.
120    *
121    * @return A property node that will be passed to the command as its
122    * argument, or 0 if none was supplied.
123    */
124   virtual const SGPropertyNode * getArg () { return _arg; }
125   
126
127   /**
128    * Read a binding from a property node.
129    *
130    * @param node The property node containing the binding.
131    */
132   virtual void read (const SGPropertyNode * node);
133
134
135   /**
136    * Fire a binding.
137    */
138   virtual void fire () const;
139
140
141   /**
142    * Fire a binding with a scaled movement (rather than absolute position).
143    */
144   virtual void fire (double offset, double max) const;
145
146
147   /**
148    * Fire a binding with a setting (i.e. joystick axis).
149    *
150    * A double 'setting' property will be added to the arguments.
151    *
152    * @param setting The input setting, usually between -1.0 and 1.0.
153    */
154   virtual void fire (double setting) const;
155
156
157 private:
158                                 // just to be safe.
159   FGBinding (const FGBinding &binding);
160
161   string _command_name;
162   mutable SGCommandMgr::command_t _command;
163   mutable SGPropertyNode_ptr _arg;
164   mutable SGPropertyNode_ptr _setting;
165 };
166
167
168 \f
169 ////////////////////////////////////////////////////////////////////////
170 // General input mapping support.
171 ////////////////////////////////////////////////////////////////////////
172
173
174 /**
175  * Generic input module.
176  *
177  * <p>This module is designed to handle input from multiple sources --
178  * keyboard, joystick, mouse, or even panel switches -- in a consistent
179  * way, and to allow users to rebind any of the actions at runtime.</p>
180  */
181 class FGInput : public SGSubsystem
182 {
183 public:
184   /**
185    * Default constructor.
186    */
187   FGInput ();
188
189   /**
190    * Destructor.
191    */
192   virtual ~FGInput();
193
194   //
195   // Implementation of SGSubsystem.
196   //
197   virtual void init ();
198   virtual void reinit ();
199   virtual void postinit ();
200   virtual void bind ();
201   virtual void unbind ();
202   virtual void update (double dt);
203   virtual void suspend ();
204   virtual void resume ();
205   virtual bool is_suspended () const;
206
207
208   /**
209    * Control whether this is the default module to receive events.
210    *
211    * The first input module created will set itself as the default
212    * automatically.
213    *
214    * @param status true if this should be the default module for
215    * events, false otherwise.
216    */
217   virtual void makeDefault (bool status = true);
218
219
220   /**
221    * Handle a single keystroke.
222    *
223    * @param k The integer key code, see Main/fg_os.hxx
224    * @param modifiers Modifier keys pressed (bitfield).
225    * @param x The mouse x position at the time of keypress.
226    * @param y The mouse y position at the time of keypress.
227    */
228   virtual void doKey (int k, int modifiers, int x, int y);
229
230
231   /**
232    * Handle a mouse click event.
233    *
234    * @param button The mouse button selected.
235    * @param updown Button status.
236    * @param x The X position of the mouse event, in screen coordinates.
237    * @param y The Y position of the mouse event, in screen coordinates.
238    */
239   virtual void doMouseClick (int button, int updown, int x, int y);
240
241
242   /**
243    * Handle mouse motion.
244    *
245    * @param x The new mouse x position, in screen coordinates.
246    * @param y The new mouse y position, in screen coordinates.
247    */
248   virtual void doMouseMotion (int x, int y);
249
250
251 private:
252                                 // Constants
253   enum 
254   {
255     MAX_KEYS = 1024,
256
257   #ifdef WIN32
258     MAX_JOYSTICKS = 2,
259   #else
260     MAX_JOYSTICKS = 10,
261   #endif
262     MAX_JOYSTICK_AXES = _JS_MAX_AXES,
263     MAX_JOYSTICK_BUTTONS = 32,
264
265     MAX_MICE = 1,
266     MAX_MOUSE_BUTTONS = 8
267   };
268   struct mouse;
269   friend struct mouse;
270
271   typedef vector<FGBinding *> binding_list_t;
272
273   /**
274    * Settings for a key or button.
275    */
276   struct button {
277     button ();
278     virtual ~button ();
279     bool is_repeatable;
280     float interval_sec;
281     float last_dt;
282     int last_state;
283     binding_list_t bindings[KEYMOD_MAX];
284   };
285
286
287   /**
288    * Settings for a single joystick axis.
289    */
290   struct axis {
291     axis ();
292     virtual ~axis ();
293     float last_value;
294     float tolerance;
295     binding_list_t bindings[KEYMOD_MAX];
296     float low_threshold;
297     float high_threshold;
298     struct button low;
299     struct button high;
300     float interval_sec;
301     double last_dt;
302   };
303
304
305   /**
306    * Settings for a joystick.
307    */
308   struct joystick {
309     joystick ();
310     virtual ~joystick ();
311     int jsnum;
312     jsJoystick * js;
313     int naxes;
314     int nbuttons;
315     axis * axes;
316     button * buttons;
317   };
318
319
320   /**
321    * Settings for a mouse mode.
322    */
323   struct mouse_mode {
324     mouse_mode ();
325     virtual ~mouse_mode ();
326     int cursor;
327     bool constrained;
328     bool pass_through;
329     button * buttons;
330     binding_list_t x_bindings[KEYMOD_MAX];
331     binding_list_t y_bindings[KEYMOD_MAX];
332   };
333
334
335   /**
336    * Settings for a mouse.
337    */
338   struct mouse {
339     mouse ();
340     virtual ~mouse ();
341     int x;
342     int y;
343     SGPropertyNode_ptr mode_node;
344     SGPropertyNode_ptr mouse_button_nodes[MAX_MOUSE_BUTTONS];
345     int nModes;
346     int current_mode;
347     double timeout;
348     int save_x;
349     int save_y;
350     mouse_mode * modes;
351   };
352
353
354   /**
355    * Initialize key bindings.
356    */
357   void _init_keyboard ();
358
359
360   /**
361    * Initialize joystick bindings.
362    */
363   void _init_joystick ();
364
365
366   /**
367    * Scan directory recursively for "named joystick" configuration files,
368    * and read them into /input/joysticks/js-named[index]++.
369    */
370   void _scan_joystick_dir (SGPath *path, SGPropertyNode* node, int *index);
371
372
373   /**
374    * Initialize mouse bindings.
375    */
376   void _init_mouse ();
377
378
379   /**
380    * Initialize a single button.
381    */
382   inline void _init_button (const SGPropertyNode * node,
383                             button &b,
384                             const string name);
385
386   /**
387    * Initialize nasal parts that had to wait for the nasal to get
388    * functional.
389    */
390   void _postinit_joystick ();
391
392   /**
393    * Update the keyboard.
394    */
395   void _update_keyboard ();
396
397
398   /**
399    * Update the joystick.
400    */
401   void _update_joystick (double dt);
402
403
404   /**
405    * Update the mouse.
406    */
407   void _update_mouse (double dt);
408
409
410   /**
411    * Update a single button.
412    */
413   inline void _update_button (button &b, int modifiers, bool pressed,
414                               int x, int y);
415
416
417   /**
418    * Read bindings and modifiers.
419    */
420   void _read_bindings (const SGPropertyNode * node,
421                        binding_list_t * binding_list,
422                        int modifiers);
423
424   /**
425    * Look up the bindings for a key code.
426    */
427   const vector<FGBinding *> &_find_key_bindings (unsigned int k,
428                                                  int modifiers);
429
430   button _key_bindings[MAX_KEYS];
431   joystick _joystick_bindings[MAX_JOYSTICKS];
432   mouse _mouse_bindings[MAX_MICE];
433
434   /**
435    * Nasal module name/namespace.
436    */
437   char _module[32];
438 };
439
440 #endif // _INPUT_HXX