]> git.mxchange.org Git - flightgear.git/blob - src/Input/input.hxx
ca15e458d873a1eb33f0ea7e0e8b1c7f469894ea
[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/SGBinding.hxx>
39 #include <simgear/props/condition.hxx>
40 #include <simgear/props/props.hxx>
41 #include <simgear/scene/util/SGSceneUserData.hxx>
42
43 #include <Main/fg_os.hxx>
44 #include <Main/fg_props.hxx>
45 #include <Main/globals.hxx>
46
47 #include <map>
48 #include <list>
49 #include <vector>
50
51 SG_USING_STD(map);
52 SG_USING_STD(vector);
53
54
55 \f
56
57 #if defined( UL_WIN32 )
58 #define TGT_PLATFORM    "windows"
59 #elif defined ( UL_MAC_OSX )
60 #define TGT_PLATFORM    "mac"
61 #else
62 #define TGT_PLATFORM    "unix"
63 #endif
64
65
66 \f
67 ////////////////////////////////////////////////////////////////////////
68 // General input mapping support.
69 ////////////////////////////////////////////////////////////////////////
70
71
72 /**
73  * Generic input module.
74  *
75  * <p>This module is designed to handle input from multiple sources --
76  * keyboard, joystick, mouse, or even panel switches -- in a consistent
77  * way, and to allow users to rebind any of the actions at runtime.</p>
78  */
79 class FGInput : public SGSubsystem
80 {
81 public:
82   /**
83    * Default constructor.
84    */
85   FGInput ();
86
87   /**
88    * Destructor.
89    */
90   virtual ~FGInput();
91
92   //
93   // Implementation of SGSubsystem.
94   //
95   virtual void init ();
96   virtual void reinit ();
97   virtual void postinit ();
98   virtual void bind ();
99   virtual void unbind ();
100   virtual void update (double dt);
101   virtual void suspend ();
102   virtual void resume ();
103   virtual bool is_suspended () const;
104
105
106   /**
107    * Control whether this is the default module to receive events.
108    *
109    * The first input module created will set itself as the default
110    * automatically.
111    *
112    * @param status true if this should be the default module for
113    * events, false otherwise.
114    */
115   virtual void makeDefault (bool status = true);
116
117
118   /**
119    * Handle a single keystroke.
120    *
121    * @param k The integer key code, see Main/fg_os.hxx
122    * @param modifiers Modifier keys pressed (bitfield).
123    * @param x The mouse x position at the time of keypress.
124    * @param y The mouse y position at the time of keypress.
125    */
126   virtual void doKey (int k, int modifiers, int x, int y);
127
128
129   /**
130    * Handle a mouse click event.
131    *
132    * @param button The mouse button selected.
133    * @param updown Button status.
134    * @param x The X position of the mouse event, in screen coordinates.
135    * @param y The Y position of the mouse event, in screen coordinates.
136    */
137   virtual void doMouseClick (int button, int updown, int x, int y);
138
139
140   /**
141    * Handle mouse motion.
142    *
143    * @param x The new mouse x position, in screen coordinates.
144    * @param y The new mouse y position, in screen coordinates.
145    */
146   virtual void doMouseMotion (int x, int y);
147
148
149 private:
150                                 // Constants
151   enum 
152   {
153     MAX_KEYS = 1024,
154
155   #ifdef WIN32
156     MAX_JOYSTICKS = 2,
157   #else
158     MAX_JOYSTICKS = 10,
159   #endif
160     MAX_JOYSTICK_AXES = _JS_MAX_AXES,
161     MAX_JOYSTICK_BUTTONS = 32,
162
163     MAX_MICE = 1,
164     MAX_MOUSE_BUTTONS = 8
165   };
166   struct mouse;
167   friend struct mouse;
168
169   typedef vector<SGSharedPtr<SGBinding> > binding_list_t;
170
171   /**
172    * Settings for a key or button.
173    */
174   struct button {
175     button ();
176     virtual ~button ();
177     bool is_repeatable;
178     float interval_sec;
179     float last_dt;
180     int last_state;
181     binding_list_t bindings[KEYMOD_MAX];
182   };
183
184
185   /**
186    * Settings for a single joystick axis.
187    */
188   struct axis {
189     axis ();
190     virtual ~axis ();
191     float last_value;
192     float tolerance;
193     binding_list_t bindings[KEYMOD_MAX];
194     float low_threshold;
195     float high_threshold;
196     struct button low;
197     struct button high;
198     float interval_sec;
199     double last_dt;
200   };
201
202
203   /**
204    * Settings for a joystick.
205    */
206   struct joystick {
207     joystick ();
208     virtual ~joystick ();
209     int jsnum;
210     jsJoystick * js;
211     int naxes;
212     int nbuttons;
213     axis * axes;
214     button * buttons;
215   };
216
217
218   /**
219    * Settings for a mouse mode.
220    */
221   struct mouse_mode {
222     mouse_mode ();
223     virtual ~mouse_mode ();
224     int cursor;
225     bool constrained;
226     bool pass_through;
227     button * buttons;
228     binding_list_t x_bindings[KEYMOD_MAX];
229     binding_list_t y_bindings[KEYMOD_MAX];
230   };
231
232
233   /**
234    * Settings for a mouse.
235    */
236   struct mouse {
237     mouse ();
238     virtual ~mouse ();
239     int x;
240     int y;
241     SGPropertyNode_ptr mode_node;
242     SGPropertyNode_ptr mouse_button_nodes[MAX_MOUSE_BUTTONS];
243     int nModes;
244     int current_mode;
245     double timeout;
246     int save_x;
247     int save_y;
248     mouse_mode * modes;
249   };
250
251
252   /**
253    * Initialize key bindings.
254    */
255   void _init_keyboard ();
256
257
258   /**
259    * Initialize joystick bindings.
260    */
261   void _init_joystick ();
262
263
264   /**
265    * Scan directory recursively for "named joystick" configuration files,
266    * and read them into /input/joysticks/js-named[index]++.
267    */
268   void _scan_joystick_dir (SGPath *path, SGPropertyNode* node, int *index);
269
270
271   /**
272    * Initialize mouse bindings.
273    */
274   void _init_mouse ();
275
276
277   /**
278    * Initialize a single button.
279    */
280   inline void _init_button (const SGPropertyNode * node,
281                             button &b,
282                             const string name);
283
284   /**
285    * Initialize nasal parts that had to wait for the nasal to get
286    * functional.
287    */
288   void _postinit_joystick ();
289
290   /**
291    * Update the keyboard.
292    */
293   void _update_keyboard ();
294
295
296   /**
297    * Update the joystick.
298    */
299   void _update_joystick (double dt);
300
301
302   /**
303    * Update the mouse.
304    */
305   void _update_mouse (double dt);
306
307
308   /**
309    * Update a single button.
310    */
311   inline void _update_button (button &b, int modifiers, bool pressed,
312                               int x, int y);
313
314
315   /**
316    * Read bindings and modifiers.
317    */
318   void _read_bindings (const SGPropertyNode * node,
319                        binding_list_t * binding_list,
320                        int modifiers);
321
322   /**
323    * Look up the bindings for a key code.
324    */
325   const binding_list_t& _find_key_bindings (unsigned int k,
326                                             int modifiers);
327
328   button _key_bindings[MAX_KEYS];
329   joystick _joystick_bindings[MAX_JOYSTICKS];
330   mouse _mouse_bindings[MAX_MICE];
331
332   /**
333    * Nasal module name/namespace.
334    */
335   char _module[32];
336
337   /**
338    * List of currently pressed mouse button events
339    */
340   std::map<int, std::list<SGSharedPtr<SGPickCallback> > > _activePickCallbacks;
341 };
342
343 #endif // _INPUT_HXX