]> git.mxchange.org Git - flightgear.git/blob - src/GUI/mouse.cxx
Modified Files:
[flightgear.git] / src / GUI / mouse.cxx
1 /**************************************************************************
2  * gui.cxx
3  *
4  * Written 1998 by Durk Talsma, started Juni, 1998.  For the flight gear
5  * project.
6  *
7  * Additional mouse supported added by David Megginson, 1999.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of the
12  * License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22  *
23  * $Id$
24  **************************************************************************/
25
26
27 #ifdef HAVE_CONFIG_H
28 #  include <config.h>
29 #endif
30
31 #include <simgear/compiler.h>
32
33 #ifdef SG_MATH_EXCEPTION_CLASH
34 #  include <math.h>
35 #endif
36
37 #ifdef HAVE_WINDOWS_H
38 #  include <windows.h>
39 #endif
40
41 #include <Main/fg_os.hxx>
42
43 #if defined(FX) && defined(XMESA)
44 #  include <GL/xmesa.h>
45 #endif
46
47 #include STL_STRING
48
49 #include <stdlib.h>
50 #include <string.h>
51
52 #include <simgear/constants.h>
53 #include <simgear/debug/logstream.hxx>
54 #include <simgear/misc/sg_path.hxx>
55
56 #include <Include/general.hxx>
57 #include <Aircraft/aircraft.hxx>
58 #include <Aircraft/controls.hxx>
59 #include <Airports/simple.hxx>
60 #include <Cockpit/panel.hxx>
61 #include <FDM/flight.hxx>
62 #include <Main/fg_init.hxx>
63 #include <Main/fg_props.hxx>
64 #include <Main/viewmgr.hxx>
65
66 #include "gui.h"
67 #include "gui_local.hxx"
68
69 SG_USING_STD(string);
70 SG_USING_STD(cout);
71
72 /* --------------------------------------------------------------------
73 Mouse stuff
74 ---------------------------------------------------------------------*/
75
76 static int _mX = 0;
77 static int _mY = 0;
78 static int _savedX = 0;
79 static int _savedY = 0;
80 static int last_buttons = 0 ;
81 static int mouse_active = 0;
82 static int mouse_joystick_control = 0;
83
84 //static time_t mouse_off_time;
85 //static int mouse_timed_out;
86
87 // to allow returning to previous view
88 // on second left click in MOUSE_VIEW mode
89 // This has file scope so that it can be reset
90 // if the little rodent is moved  NHV
91 static  int _mVtoggle = 0;
92
93 static int MOUSE_XSIZE = 0;
94 static int MOUSE_YSIZE = 0;
95
96 // uncomment this for view to exactly follow mouse in MOUSE_VIEW mode
97 // else smooth out the view panning to .01 radian per frame
98 // see view_offset smoothing mechanism in main.cxx
99 #define NO_SMOOTH_MOUSE_VIEW
100
101 // uncomment following to
102 #define RESET_VIEW_ON_LEAVING_MOUSE_VIEW
103
104 /* --------------------------------------------------------------------
105 Support for mouse as control yoke (david@megginson.com)
106
107 - right button toggles between pointer and yoke
108 - horizontal drag with no buttons moves ailerons
109 - vertical drag with no buttons moves elevators
110 - horizontal drag with left button moves brakes (left=on)
111 - vertical drag with left button moves throttle (up=more)
112 - horizontal drag with middle button moves rudder
113 - vertical drag with middle button moves trim
114
115 For the *_sensitivity variables, a lower number means more sensitive.
116
117 TODO: figure out how to keep pointer from leaving window in yoke mode.
118 TODO: add thresholds and null zones
119 TODO: sensitivity should be configurable at user option.
120 TODO: allow differential braking (this will be useful if FlightGear
121       ever supports tail-draggers like the DC-3)
122 ---------------------------------------------------------------------*/
123
124 MouseMode mouse_mode = MOUSE_POINTER;
125
126 static double aileron_sensitivity = 1.0/500.0;
127 static double elevator_sensitivity = 1.0/500.0;
128 static double brake_sensitivity = 1.0/250.0;
129 static double throttle_sensitivity = 1.0/250.0;
130 static double rudder_sensitivity = 1.0/500.0;
131 static double trim_sensitivity = 1.0/1000.0;
132
133 void guiInitMouse(int width, int height)
134 {
135         MOUSE_XSIZE = width;
136         MOUSE_YSIZE = height;
137 }
138
139 static inline int guiGetMouseButton(void)
140 {
141         return last_buttons;
142 }
143
144 static inline void guiGetMouse(int *x, int *y)
145 {
146         *x = _mX;
147         *y = _mY;
148 };
149
150 static inline int left_button( void ) {
151     return( last_buttons & (1 << MOUSE_BUTTON_LEFT) );
152 }
153
154 static inline int middle_button( void ) {
155     return( last_buttons & (1 << MOUSE_BUTTON_MIDDLE) );
156 }
157
158 static inline int right_button( void ) {
159     return( last_buttons & (1 << MOUSE_BUTTON_RIGHT) );
160 }
161
162 static inline void set_goal_view_offset( float offset )
163 {
164         globals->get_current_view()->setGoalHeadingOffset_deg(offset * SGD_RADIANS_TO_DEGREES);
165 }
166
167 static inline void set_view_offset( float offset )
168 {
169         globals->get_current_view()->setHeadingOffset_deg(offset * SGD_RADIANS_TO_DEGREES);
170 }
171
172 static inline void set_goal_view_tilt( float tilt )
173 {
174         globals->get_current_view()->setGoalPitchOffset_deg(tilt);
175 }
176
177 static inline void set_view_tilt( float tilt )
178 {
179         globals->get_current_view()->setPitchOffset_deg(tilt);
180 }
181
182 static inline float get_view_offset() {
183         return globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
184 }
185
186 static inline float get_goal_view_offset() {
187         return globals->get_current_view()->getGoalHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
188 }
189
190 static inline void move_brake(float offset) {
191         globals->get_controls()->move_brake_left(offset);
192         globals->get_controls()->move_brake_right(offset);
193 }
194
195 static inline void move_throttle(float offset) {
196         globals->get_controls()->move_throttle(FGControls::ALL_ENGINES, offset);
197 }
198
199 static inline void move_rudder(float offset) {
200         globals->get_controls()->move_rudder(offset);
201 }
202
203 static inline void move_elevator_trim(float offset) {
204         globals->get_controls()->move_elevator_trim(offset);
205 }
206
207 static inline void move_aileron(float offset) {
208         globals->get_controls()->move_aileron(offset);
209 }
210
211 static inline void move_elevator(float offset) {
212         globals->get_controls()->move_elevator(offset);
213 }
214
215 static inline float get_aileron() {
216         return globals->get_controls()->get_aileron();
217 }
218
219 static inline float get_elevator() {
220         return globals->get_controls()->get_elevator();
221 }
222
223 static inline bool AP_HeadingEnabled() {
224     static const SGPropertyNode *heading_enabled
225         = fgGetNode("/autopilot/locks/heading");
226     return ( strcmp( heading_enabled->getStringValue(), "" ) != 0 );
227 }
228
229 static inline bool AP_AltitudeEnabled() {
230     static const SGPropertyNode *altitude_enabled
231         = fgGetNode("/autopilot/locks/altitude");
232     return ( strcmp( altitude_enabled->getStringValue(), "" ) != 0 );
233 }
234
235 void TurnCursorOn( void )
236 {
237     mouse_active = ~0;
238 #if defined(WIN32)
239     switch (mouse_mode) {
240         case MOUSE_POINTER:
241             fgSetMouseCursor(MOUSE_CURSOR_POINTER);
242             break;
243         case MOUSE_YOKE:
244             fgSetMouseCursor(MOUSE_CURSOR_CROSSHAIR);
245             break;
246         case MOUSE_VIEW:
247             fgSetMouseCursor(MOUSE_CURSOR_LEFTRIGHT);
248             break;
249     }
250 #endif
251 #if defined(X_CURSOR_TWEAKS)
252     fgWarpMouse( MOUSE_XSIZE/2, MOUSE_YSIZE/2 );
253 #endif
254 }
255
256 void TurnCursorOff( void )
257 {
258     mouse_active = 0;
259 #if defined(WIN32_CURSOR_TWEAKS)
260     fgSetMouseCursor(MOUSE_CURSOR_NONE);
261 #elif defined(X_CURSOR_TWEAKS)
262     fgWarpMouse( MOUSE_XSIZE, MOUSE_YSIZE );
263 #endif
264 }
265
266 void maybeToggleMouse( void )
267 {
268 #if defined(WIN32_CURSOR_TWEAKS_OFF)
269     static int first_time = ~0;
270     static int mouse_changed = 0;
271
272     if ( first_time ) {
273         if(!mouse_active) {
274             mouse_changed = ~mouse_changed;
275             TurnCursorOn();
276         }
277     } else {
278         if( mouse_mode != MOUSE_POINTER )
279             return;
280         if( mouse_changed ) {
281             mouse_changed = ~mouse_changed;
282             if(mouse_active) {
283                 TurnCursorOff();
284             }
285         }
286     }
287     first_time = ~first_time;
288 #endif // #ifdef WIN32
289 }
290
291 //#define TRANSLATE_HUD
292 // temporary hack until pitch_offset is added to view pipeline
293 void fgTranslateHud( void ) {
294 #ifdef TRANSLATE_HUD
295     if(mouse_mode == MOUSE_VIEW) {
296
297         int ww = MOUSE_XSIZE;
298         int wh = MOUSE_YSIZE;
299
300         float y = 4*(_mY-(wh/2));// * ((wh/SGD_PI)*SG_RADIANS_TO_DEGREES);
301         
302         float x =  get_view_offset() * SG_RADIANS_TO_DEGREES;
303
304         if( x < -180 )      x += 360;
305         else if( x > 180 )      x -= 360;
306
307         x *= ww/90.0;
308         //      x *= ww/180.0;
309         //      x *= ww/360.0;
310
311         //      glTranslatef( x*ww/640, y*wh/480, 0 );
312         glTranslatef( x*640/ww, y*480/wh, 0 );
313     }
314 #endif // TRANSLATE_HUD
315 }
316