]> git.mxchange.org Git - flightgear.git/blob - src/Input/input.hxx
Oops. A change to an upstream header seems to have remove glu.h, which
[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., 675 Mass Ave, Cambridge, MA 02139, 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
33 #include <simgear/compiler.h>
34
35 #include <simgear/structure/subsystem_mgr.hxx>
36 #include <simgear/structure/commands.hxx>
37 #include <simgear/props/condition.hxx>
38 #include <simgear/props/props.hxx>
39
40 #include <Main/fg_os.hxx>
41 #include <Main/fg_props.hxx>
42 #include <Main/globals.hxx>
43
44 #include <map>
45 #include <vector>
46
47 SG_USING_STD(map);
48 SG_USING_STD(vector);
49
50
51
52
53 \f
54 ////////////////////////////////////////////////////////////////////////
55 // General binding support.
56 ////////////////////////////////////////////////////////////////////////
57
58
59 /**
60  * An input binding of some sort.
61  *
62  * <p>This class represents a binding that can be assigned to a
63  * keyboard key, a joystick button or axis, or even a panel
64  * instrument.</p>
65  */
66 class FGBinding : public SGConditional
67 {
68 public:
69
70   /**
71    * Default constructor.
72    */
73   FGBinding ();
74
75
76   /**
77    * Convenience constructor.
78    *
79    * @param node The binding will be built from this node.
80    */
81   FGBinding (const SGPropertyNode * node);
82
83
84   /**
85    * Destructor.
86    */
87   virtual ~FGBinding () {}
88
89
90   /**
91    * Get the command name.
92    *
93    * @return The string name of the command for this binding.
94    */
95   virtual const string &getCommandName () const { return _command_name; }
96
97
98   /**
99    * Get the command itself.
100    *
101    * @return The command associated with this binding, or 0 if none
102    * is present.
103    */
104   virtual SGCommandMgr::command_t getCommand () const { return _command; }
105
106
107   /**
108    * Get the argument that will be passed to the command.
109    *
110    * @return A property node that will be passed to the command as its
111    * argument, or 0 if none was supplied.
112    */
113   virtual const SGPropertyNode * getArg () { return _arg; }
114   
115
116   /**
117    * Read a binding from a property node.
118    *
119    * @param node The property node containing the binding.
120    */
121   virtual void read (const SGPropertyNode * node);
122
123
124   /**
125    * Fire a binding.
126    */
127   virtual void fire () const;
128
129
130   /**
131    * Fire a binding with a scaled movement (rather than absolute position).
132    */
133   virtual void fire (double offset, double max) const;
134
135
136   /**
137    * Fire a binding with a setting (i.e. joystick axis).
138    *
139    * A double 'setting' property will be added to the arguments.
140    *
141    * @param setting The input setting, usually between -1.0 and 1.0.
142    */
143   virtual void fire (double setting) const;
144
145
146 private:
147                                 // just to be safe.
148   FGBinding (const FGBinding &binding);
149
150   string _command_name;
151   mutable SGCommandMgr::command_t _command;
152   mutable SGPropertyNode_ptr _arg;
153   mutable SGPropertyNode_ptr _setting;
154 };
155
156
157 \f
158 ////////////////////////////////////////////////////////////////////////
159 // General input mapping support.
160 ////////////////////////////////////////////////////////////////////////
161
162
163 /**
164  * Generic input module.
165  *
166  * <p>This module is designed to handle input from multiple sources --
167  * keyboard, joystick, mouse, or even panel switches -- in a consistent
168  * way, and to allow users to rebind any of the actions at runtime.</p>
169  */
170 class FGInput : public SGSubsystem
171 {
172 public:
173   /**
174    * Default constructor.
175    */
176   FGInput ();
177
178   /**
179    * Destructor.
180    */
181   virtual ~FGInput();
182
183   //
184   // Implementation of SGSubsystem.
185   //
186   virtual void init ();
187   virtual void update (double dt);
188   virtual void suspend ();
189   virtual void resume ();
190   virtual bool is_suspended () const;
191
192
193   /**
194    * Control whether this is the default module to receive events.
195    *
196    * The first input module created will set itself as the default
197    * automatically.
198    *
199    * @param status true if this should be the default module for
200    * events, false otherwise.
201    */
202   virtual void makeDefault (bool status = true);
203
204
205   /**
206    * Handle a single keystroke.
207    *
208    * @param k The integer key code, see Main/fg_os.hxx
209    * @param modifiers Modifier keys pressed (bitfield).
210    * @param x The mouse x position at the time of keypress.
211    * @param y The mouse y position at the time of keypress.
212    */
213   virtual void doKey (int k, int modifiers, int x, int y);
214
215
216   /**
217    * Handle a mouse click event.
218    *
219    * @param button The mouse button selected.
220    * @param updown Button status.
221    * @param x The X position of the mouse event, in screen coordinates.
222    * @param y The Y position of the mouse event, in screen coordinates.
223    */
224   virtual void doMouseClick (int button, int updown, int x, int y);
225
226
227   /**
228    * Handle mouse motion.
229    *
230    * @param x The new mouse x position, in screen coordinates.
231    * @param y The new mouse y position, in screen coordinates.
232    */
233   virtual void doMouseMotion (int x, int y);
234
235
236 private:
237                                 // Constants
238   enum 
239   {
240     MAX_KEYS = 1024,
241
242   #ifdef WIN32
243     MAX_JOYSTICKS = 2,
244   #else
245     MAX_JOYSTICKS = 10,
246   #endif
247     MAX_JOYSTICK_AXES = _JS_MAX_AXES,
248     MAX_JOYSTICK_BUTTONS = 32,
249
250     MAX_MICE = 1,
251     MAX_MOUSE_BUTTONS = 8
252   };
253   struct mouse;
254   friend struct mouse;
255
256   typedef vector<FGBinding *> binding_list_t;
257
258   /**
259    * Settings for a key or button.
260    */
261   struct button {
262     button ();
263     virtual ~button ();
264     bool is_repeatable;
265     float interval_sec;
266     float last_dt;
267     int last_state;
268     binding_list_t bindings[KEYMOD_MAX];
269   };
270
271
272   /**
273    * Settings for a single joystick axis.
274    */
275   struct axis {
276     axis ();
277     virtual ~axis ();
278     float last_value;
279     float tolerance;
280     binding_list_t bindings[KEYMOD_MAX];
281     float low_threshold;
282     float high_threshold;
283     struct button low;
284     struct button high;
285     float interval_sec;
286     double last_dt;
287   };
288
289
290   /**
291    * Settings for a joystick.
292    */
293   struct joystick {
294     joystick ();
295     virtual ~joystick ();
296     int jsnum;
297     jsJoystick * js;
298     int naxes;
299     int nbuttons;
300     axis * axes;
301     button * buttons;
302   };
303
304
305   /**
306    * Settings for a mouse mode.
307    */
308   struct mouse_mode {
309     mouse_mode ();
310     virtual ~mouse_mode ();
311     int cursor;
312     bool constrained;
313     bool pass_through;
314     button * buttons;
315     binding_list_t x_bindings[KEYMOD_MAX];
316     binding_list_t y_bindings[KEYMOD_MAX];
317   };
318
319
320   /**
321    * Settings for a mouse.
322    */
323   struct mouse {
324     mouse ();
325     virtual ~mouse ();
326     int x;
327     int y;
328     SGPropertyNode * mode_node;
329     SGPropertyNode * mouse_button_nodes[MAX_MOUSE_BUTTONS];
330     int nModes;
331     int current_mode;
332     mouse_mode * modes;
333   };
334
335
336   /**
337    * Initialize key bindings.
338    */
339   void _init_keyboard ();
340
341
342   /**
343    * Initialize joystick bindings.
344    */
345   void _init_joystick ();
346
347
348   /**
349    * Initialize mouse bindings.
350    */
351   void _init_mouse ();
352
353
354   /**
355    * Initialize a single button.
356    */
357   inline void _init_button (const SGPropertyNode * node,
358                             button &b,
359                             const string name);
360
361
362   /**
363    * Update the keyboard.
364    */
365   void _update_keyboard ();
366
367
368   /**
369    * Update the joystick.
370    */
371   void _update_joystick (double dt);
372
373
374   /**
375    * Update the mouse.
376    */
377   void _update_mouse ();
378
379
380   /**
381    * Update a single button.
382    */
383   inline void _update_button (button &b, int modifiers, bool pressed,
384                               int x, int y);
385
386
387   /**
388    * Read bindings and modifiers.
389    */
390   void _read_bindings (const SGPropertyNode * node,
391                        binding_list_t * binding_list,
392                        int modifiers);
393
394   /**
395    * Look up the bindings for a key code.
396    */
397   const vector<FGBinding *> &_find_key_bindings (unsigned int k,
398                                                  int modifiers);
399
400   button _key_bindings[MAX_KEYS];
401   joystick _joystick_bindings[MAX_JOYSTICKS];
402   mouse _mouse_bindings[MAX_MICE];
403
404 };
405
406 #endif // _INPUT_HXX