]> git.mxchange.org Git - flightgear.git/blob - src/Main/fg_os.cxx
Add a command to dump just the terrain portion of the scene graph to a .osg
[flightgear.git] / src / Main / fg_os.cxx
1 #ifndef _MSC_VER // MSVC really needs a definition for wchar_t
2 #define _WCHAR_T_DEFINED 1 // Glut needs this, or else it tries to
3                            // redefine it
4 #endif
5
6 #ifdef HAVE_CONFIG_H
7 #  include <config.h>
8 #endif
9
10 #include <simgear/compiler.h>
11
12 #include SG_GLUT_H
13
14 #include <plib/pu.h>
15
16 #include "fg_props.hxx"
17 #include "fg_os.hxx"
18
19 //
20 // fg_os callback registration APIs
21 // (These are not glut-specific)
22 //
23
24 static fgIdleHandler IdleHandler = 0;
25 static fgDrawHandler DrawHandler = 0;
26 static fgWindowResizeHandler WindowResizeHandler = 0;
27 static fgKeyHandler KeyHandler = 0;
28 static fgMouseClickHandler MouseClickHandler = 0;
29 static fgMouseMotionHandler MouseMotionHandler = 0;
30
31 // We need to flush all pending mouse move events past a mouse warp to avoid
32 // a race condition ending in warping twice and having huge increments for the
33 // second warp.
34 // I am not aware of such a flush function in glut. So we emulate that by
35 // ignoring mouse move events between a warp mouse and the next frame.
36 static bool mouseWarped = false;
37
38 void fgRegisterIdleHandler(fgIdleHandler func)
39 {
40     IdleHandler = func;
41 }
42
43 void fgRegisterDrawHandler(fgDrawHandler func)
44 {
45     DrawHandler = func;
46 }
47
48 void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
49 {
50     WindowResizeHandler = func;
51 }
52
53 void fgRegisterKeyHandler(fgKeyHandler func)
54 {
55     KeyHandler = func;
56 }
57
58 void fgRegisterMouseClickHandler(fgMouseClickHandler func)
59 {
60     MouseClickHandler = func;
61 }
62
63 void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
64 {
65     MouseMotionHandler = func;
66 }
67
68 //
69 // Native glut callbacks.
70 // These translate the glut event model into fg*Handler callbacks
71 //
72
73 static int GlutModifiers = 0;
74
75 static void callKeyHandler(int k, int mods, int x, int y)
76 {
77     int puiup = mods & KEYMOD_RELEASED ? PU_UP : PU_DOWN;
78     if(puKeyboard(k, puiup))
79         return;
80     if(KeyHandler) (*KeyHandler)(k, mods, x, y);
81 }
82
83 static void GLUTmotion (int x, int y)
84 {
85     if (mouseWarped)
86         return;
87     if(MouseMotionHandler) (*MouseMotionHandler)(x, y);
88 }
89
90 static void GLUTmouse (int button, int updown, int x, int y)
91 {
92     GlutModifiers = glutGetModifiers();
93     if(MouseClickHandler) (*MouseClickHandler)(button, updown, x, y, true, 0);
94 }
95
96 static void GLUTspecialkeyup(int k, int x, int y)
97 {
98     GlutModifiers = glutGetModifiers();
99     callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
100 }
101
102 static void GLUTspecialkey(int k, int x, int y)
103 {
104     GlutModifiers = glutGetModifiers();
105     callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
106 }
107
108 static unsigned char release_keys[256];
109
110 static void GLUTkeyup(unsigned char k, int x, int y)
111 {
112     GlutModifiers = glutGetModifiers();
113     callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
114 }
115
116 static void GLUTkey(unsigned char k, int x, int y)
117 {
118     GlutModifiers = glutGetModifiers();
119     release_keys[k] = k;
120     if (k >= 1 && k <= 26) {
121         release_keys[k + '@'] = k;
122         release_keys[k + '`'] = k;
123     } else if (k >= 'A' && k <= 'Z') {
124         release_keys[k - '@'] = k;
125         release_keys[tolower(k)] = k;
126     } else if (k >= 'a' && k <= 'z') {
127         release_keys[k - '`'] = k;
128         release_keys[toupper(k)] = k;
129     }
130     callKeyHandler(k, fgGetKeyModifiers(), x, y);
131 }
132
133 static void GLUTidle()
134 {
135     if(IdleHandler) (*IdleHandler)();
136     mouseWarped = false;
137 }
138
139 static void GLUTdraw()
140 {
141     if(DrawHandler) (*DrawHandler)();
142     glutSwapBuffers();
143     mouseWarped = false;
144 }
145
146 static void GLUTreshape(int w, int h)
147 {
148     if(WindowResizeHandler) (*WindowResizeHandler)(w, h);
149 }
150
151 //
152 // fg_os API definition
153 //
154
155 void fgOSInit(int* argc, char** argv)
156 {
157     glutInit(argc, argv);
158 }
159
160 void fgOSFullScreen()
161 {
162     glutFullScreen();
163 }
164
165 void fgOSMainLoop()
166 {
167     glutMainLoop();
168 }
169
170 void fgOSExit(int code)
171 {
172     exit(code);
173 }
174
175 static int CurrentCursor = MOUSE_CURSOR_POINTER;
176
177 int fgGetMouseCursor()
178 {
179     return CurrentCursor;
180 }
181
182 void fgSetMouseCursor(int cursor)
183 {
184     CurrentCursor = cursor;
185     if     (cursor == MOUSE_CURSOR_NONE)      cursor = GLUT_CURSOR_NONE;
186     else if(cursor == MOUSE_CURSOR_POINTER)   cursor = GLUT_CURSOR_INHERIT;
187     else if(cursor == MOUSE_CURSOR_WAIT)      cursor = GLUT_CURSOR_WAIT;
188     else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
189     else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
190     // Otherwise, pass it through unchanged...
191     glutSetCursor(cursor);
192 }
193
194 void fgWarpMouse(int x, int y)
195 {
196     mouseWarped = true;
197     glutWarpPointer(x, y);
198 }
199
200 int fgGetKeyModifiers()
201 {
202     int result = 0;
203     if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
204     if(GlutModifiers & GLUT_ACTIVE_CTRL)  result |= KEYMOD_CTRL;
205     if(GlutModifiers & GLUT_ACTIVE_ALT)   result |= KEYMOD_ALT;
206     return result;
207 }
208
209 void fgRequestRedraw()
210 {
211     glutPostRedisplay();
212 }
213
214 void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
215                     bool stencil, bool fullscreen)
216 {
217     int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
218     if(alpha) mode |= GLUT_ALPHA;
219     if(stencil && bpp > 16) mode |= GLUT_STENCIL;
220
221     glutInitDisplayMode(mode);
222     glutInitWindowSize(w, h);
223     if(!fgGetBool("/sim/startup/game-mode")) {
224         glutCreateWindow("FlightGear");
225     } else {
226         char game_mode_str[20];
227         SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
228         if (p) {
229             int hz = p->getIntValue();
230             snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
231         } else {
232             snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
233         }
234         glutGameModeString( game_mode_str );
235         glutEnterGameMode();
236     }
237
238     // Register these here.  Calling them before the window is open
239     // crashes.
240     glutMotionFunc(GLUTmotion);
241     glutPassiveMotionFunc(GLUTmotion);
242     glutMouseFunc(GLUTmouse);
243     glutSpecialUpFunc(GLUTspecialkeyup);
244     glutSpecialFunc(GLUTspecialkey);
245     glutKeyboardUpFunc(GLUTkeyup);
246     glutKeyboardFunc(GLUTkey);
247     glutIdleFunc(GLUTidle);
248     glutDisplayFunc(GLUTdraw);
249     glutReshapeFunc(GLUTreshape);
250 }
251
252 // Noop; the graphics context is always current
253 void fgMakeCurrent()
254 {
255 }
256
257 bool fgOSIsMainCamera(const osg::Camera*)
258 {
259   return true;
260 }
261
262 bool fgOSIsMainContext(const osg::GraphicsContext*)
263 {
264   return true;
265 }