1 // bootstrap.cxx -- bootstrap routines: main()
3 // Written by Curtis Olson, started May 1997.
5 // Copyright (C) 1997 - 2002 Curtis L. Olson - http://www.flightgear.org/~curt
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.
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.
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.
28 #if defined(__linux__) && defined(__i386__)
29 # include <fpu_control.h>
36 #include <simgear/compiler.h>
37 #include <simgear/structure/exception.hxx>
38 #include <simgear/debug/logstream.hxx>
45 #include "globals.hxx"
56 # include <console.h> // -dw- for command line dialog
59 // foreward declaration.
62 #if defined(__linux__) && defined(__i386__)
64 static void handleFPE (int);
69 fpu_control_t fpe_flags = 0;
70 _FPU_GETCW(fpe_flags);
71 // fpe_flags &= ~_FPU_MASK_IM; // invalid operation
72 // fpe_flags &= ~_FPU_MASK_DM; // denormalized operand
73 // fpe_flags &= ~_FPU_MASK_ZM; // zero-divide
74 // fpe_flags &= ~_FPU_MASK_OM; // overflow
75 // fpe_flags &= ~_FPU_MASK_UM; // underflow
76 // fpe_flags &= ~_FPU_MASK_PM; // precision (inexact result)
77 _FPU_SETCW(fpe_flags);
78 signal(SIGFPE, handleFPE);
85 SG_LOG(SG_GENERAL, SG_ALERT, "Floating point interrupt (SIGFPE)");
98 short CPSGetCurrentProcess(PSN *psn);
99 short CPSSetProcessName (PSN *psn, char *processname);
100 short CPSEnableForegroundOperation(PSN *psn, int _arg2, int _arg3, int _arg4, int _arg5);
101 short CPSSetFrontProcess(PSN *psn);
104 #define CPSEnableFG(psn) CPSEnableForegroundOperation(psn,0x03,0x3C,0x2C,0x1103)
109 int main ( int argc, char **argv );
110 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
111 LPSTR lpCmdLine, int nCmdShow) {
113 main( __argc, __argv );
121 set the special "flush zero" bit (FS, bit 24) in the Control Status
122 Register of the FPU of R4k and beyond so that the result of any
123 underflowing operation will be clamped to zero, and no exception of
124 any kind will be generated on the CPU. This has no effect on an
127 the FS bit is inherited by processes fork()ed out of this one,
128 but it is not inherited across an exec(). so anytime you exec()
129 a process, you must re-set the FS bit in that process.
134 f.fc_word = get_fpc_csr();
135 f.fc_struct.flush = 1;
136 set_fpc_csr(f.fc_word);
140 int _bootstrap_OSInit;
142 // Main entry point; catch any exceptions that have made it this far.
143 int main ( int argc, char **argv ) {
145 _bootstrap_OSInit = 0;
147 // Enable floating-point exceptions for Linux/x86
148 #if defined(__linux__) && defined(__i386__)
156 // Enable floating-point exceptions for Windows
157 #if defined( _MSC_VER ) && defined( DEBUG )
158 // Christian, we should document what this does
159 _control87( _EM_INEXACT, _MCW_EM );
162 #if defined( HAVE_BC5PLUS )
163 _control87(MCW_EM, MCW_EM); /* defined in float.h */
166 // Keyboard focus hack
167 #if defined(__APPLE__) && !defined(OSX_BUNDLE)
171 fgOSInit (&argc, argv);
174 CPSGetCurrentProcess(&psn);
175 CPSSetProcessName(&psn, "FlightGear");
177 CPSSetFrontProcess(&psn);
181 // FIXME: add other, more specific
184 atexit(fgExitCleanup);
185 fgMainInit(argc, argv);
186 } catch (sg_throwable &t) {
187 // We must use cerr rather than
188 // logging, since logging may be
190 cerr << "Fatal error: " << t.getFormattedMessage()
191 << "\n (received from " << t.getOrigin() << ')' << endl;
193 cerr << "Unknown exception in the main loop. Aborting..." << endl;
194 perror("Possible cause");
200 // do some clean up on exit. Specifically we want to call alutExit()
201 // which happens in the sound manager destructor.
202 void fgExitCleanup() {
204 if (_bootstrap_OSInit != 0)
205 fgSetMouseCursor(MOUSE_CURSOR_POINTER);