]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/main.cxx
Merge branch 'torsten/auto'
[flightgear.git] / src / Main / main.cxx
index 8c64afae12ef6a81e6590d292b4f6f2bae48edad..8ac54aa5695984ea8d671a3e80b50954dad03b14 100644 (file)
@@ -47,6 +47,7 @@
 #include <simgear/scene/model/animation.hxx>
 #include <simgear/scene/sky/sky.hxx>
 #include <simgear/structure/event_mgr.hxx>
+#include <simgear/props/AtomicChangeListener.hxx>
 #include <simgear/props/props.hxx>
 #include <simgear/timing/sg_time.hxx>
 #include <simgear/math/sg_random.h>
 #include <Model/acmodel.hxx>
 #include <Scenery/scenery.hxx>
 #include <Scenery/tilemgr.hxx>
+#include <Sound/fg_fx.hxx>
 #include <Sound/beacon.hxx>
 #include <Sound/morse.hxx>
+#include <Sound/fg_fx.hxx>
 #include <FDM/flight.hxx>
 #include <ATCDCL/ATCmgr.hxx>
 #include <ATCDCL/AIMgr.hxx>
 #include "fg_init.hxx"
 #include "fg_os.hxx"
 #include "WindowSystemAdapter.hxx"
-
+#include <Main/viewer.hxx>
 
 static double real_delta_time_sec = 0.0;
 double delta_time_sec = 0.0;
-extern float init_volume;
 
 using namespace flightgear;
 
@@ -103,6 +105,9 @@ long global_multi_loop;
 SGTimeStamp last_time_stamp;
 SGTimeStamp current_time_stamp;
 
+void fgInitSoundManager();
+void fgSetNewSoundDevice(const char *);
+
 // The atexit() function handler should know when the graphical subsystem
 // is initialized.
 extern int _bootstrap_OSInit;
@@ -163,7 +168,7 @@ void fgUpdateTimeDepCalcs() {
                 // normal playback
                 replay_time->setDoubleValue( replay_time->getDoubleValue()
                                              + ( delta_time_sec
-                                               * fgGetInt("/sim/speed-up") ) );
+                                                 * fgGetInt("/sim/speed-up") ) );
             } else if ( replay_state->getIntValue() == 2 ) {
                 // paused playback (don't advance replay time)
             }
@@ -340,14 +345,14 @@ static void fgMainLoop( void ) {
     // probably move eventually
 
     /* printf("Before - ground = %.2f  runway = %.2f  alt = %.2f\n",
-           scenery.get_cur_elev(),
-           cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
-           cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
+       scenery.get_cur_elev(),
+       cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
+       cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
 
     /* printf("Adjustment - ground = %.2f  runway = %.2f  alt = %.2f\n",
-           scenery.get_cur_elev(),
-           cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
-           cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
+       scenery.get_cur_elev(),
+       cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
+       cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
 
     // cout << "Warp = " << globals->get_warp() << endl;
 
@@ -419,7 +424,7 @@ static void fgMainLoop( void ) {
         general.set_frame_rate( frames );
         fgSetInt("/sim/frame-rate", frames);
         SG_LOG( SG_ALL, SG_DEBUG,
-            "--> Frame rate is = " << general.get_frame_rate() );
+                "--> Frame rate is = " << general.get_frame_rate() );
         frames = 0;
     }
     last_time = t->get_cur_time();
@@ -448,15 +453,8 @@ static void fgMainLoop( void ) {
         fgUpdateTimeDepCalcs();
     } else {
         SG_LOG( SG_ALL, SG_DEBUG,
-            "Elapsed time is zero ... we're zinging" );
-    }
-
-    // Run audio scheduler
-#ifdef ENABLE_AUDIO_SUPPORT
-    if ( globals->get_soundmgr()->is_working() ) {
-        globals->get_soundmgr()->update( delta_time_sec );
+                "Elapsed time is zero ... we're zinging" );
     }
-#endif
 
     globals->get_subsystem_mgr()->update(delta_time_sec);
 
@@ -466,9 +464,8 @@ static void fgMainLoop( void ) {
     //   we may want to move this to its own class at some point
     //
     double visibility_meters = fgGetDouble("/environment/visibility-m");
-    FGViewer *current_view = globals->get_current_view();
-
     globals->get_tile_mgr()->prep_ssg_nodes( visibility_meters );
+
     // update tile manager for view...
     SGVec3d viewPos = globals->get_current_view()->get_view_pos();
     SGGeod geodViewPos = SGGeod::fromCart(viewPos);
@@ -484,124 +481,37 @@ static void fgMainLoop( void ) {
     // update the view angle as late as possible, but before sound calculations
     globals->get_viewmgr()->update(real_delta_time_sec);
 
-    // Do any I/O channel work that might need to be done (must come after viewmgr)
-    globals->get_io()->update(real_delta_time_sec);
-
+    // Update the sound manager last so it can use the CPU while the GPU
+    // is processing the scenery (doubled the frame-rate for me) -EMH-
 #ifdef ENABLE_AUDIO_SUPPORT
-    // Right now we make a simplifying assumption that the primary
-    // aircraft is the source of all sounds and that all sounds are
-    // positioned in the aircraft base
-
-    static sgdVec3 last_listener_pos = {0, 0, 0};
-    static sgdVec3 last_model_pos = {0, 0, 0};
-
-    // get the orientation
-    const SGQuatd view_or = current_view->getViewOrientation();
-    SGQuatd surf_or = SGQuatd::fromLonLat(current_view->getPosition());
-    SGQuatd model_or = SGQuatd::fromYawPitchRollDeg(
-        globals->get_aircraft_model()->get3DModel()->getHeadingDeg(),
-        globals->get_aircraft_model()->get3DModel()->getPitchDeg(),
-        globals->get_aircraft_model()->get3DModel()->getRollDeg());
-
-    // get the up and at vector in the aircraft base
-    // (ok, the up vector is a down vector, but the coordinates
-    // are finally calculated in a left hand system and openal
-    // lives in a right hand system. Therefore we need to pass
-    // the down vector to get correct stereo sound.)
-    SGVec3d sgv_up = model_or.rotateBack(
-        surf_or.rotateBack(view_or.rotate(SGVec3d(0, 1, 0))));
-    sgVec3 up;
-    sgSetVec3(up, sgv_up[0], sgv_up[1], sgv_up[2]);
-    SGVec3d sgv_at = model_or.rotateBack(
-        surf_or.rotateBack(view_or.rotate(SGVec3d(0, 0, 1))));
-    sgVec3 at;
-    sgSetVec3(at, sgv_at[0], sgv_at[1], sgv_at[2]);
-
-    // get the location data for the primary FDM (now hardcoded to ac model)...
-    SGGeod geodPos = globals->get_aircraft_model()->get3DModel()->getPosition();
-    SGVec3d model_pos = SGVec3d::fromGeod(geodPos);
-
-    // Calculate speed of listener and model.  This code assumes the
-    // listener is either tracking the model at the same speed or
-    // stationary.
-
-    sgVec3 listener_vel, model_vel;
-    SGVec3d SGV3d_help;
-    sgdVec3 sgdv3_help;
-    sgdVec3 sgdv3_null = {0, 0, 0};
-
-    // the aircraft velocity as reported by the fdm (this will not
-    // vary or be affected by frame rates or timing jitter.)
-    sgVec3 fdm_vel_vec;
-    sgSetVec3( fdm_vel_vec,
-              vn_fps->getDoubleValue() * SG_FEET_TO_METER,
-              ve_fps->getDoubleValue() * SG_FEET_TO_METER,
-              vd_fps->getDoubleValue() * SG_FEET_TO_METER );
-    double fdm_vel = sgLengthVec3(fdm_vel_vec);
-
-    // compute the aircraft velocity vector and scale it to the length
-    // of the fdm velocity vector.  This gives us a vector in the
-    // proper coordinate system, but also with the proper time
-    // invariant magnitude.
-    sgdSubVec3( sgdv3_help,
-                last_model_pos, model_pos.sg());
-    sgdAddVec3( last_model_pos, sgdv3_null, model_pos.sg());
-    SGV3d_help = model_or.rotateBack(
-        surf_or.rotateBack(SGVec3d(sgdv3_help[0],
-        sgdv3_help[1], sgdv3_help[2])));
-    sgSetVec3( model_vel, SGV3d_help[0], SGV3d_help[1], SGV3d_help[2]);
-
-    float vel = sgLengthVec3(model_vel);
-    if ( fabs(vel) > 0.0001 ) {
-       if ( fabs(fdm_vel / vel) > 0.0001 ) {
-           sgScaleVec3( model_vel, fdm_vel / vel );
-       }
-    }
-
-    // check for moving or stationary listener (view position)
-    sgdSubVec3( sgdv3_help,
-                last_listener_pos, current_view->get_view_pos().sg());
-    sgdAddVec3( last_listener_pos,
-               sgdv3_null, current_view->get_view_pos().sg());
-
-    if ( sgdLengthVec3(sgdv3_help) > 0.2 ) {
-       sgCopyVec3( listener_vel, model_vel );
+    static bool smgr_init = true;
+    if (smgr_init == true) {
+        static SGPropertyNode *sound_working = fgGetNode("/sim/sound/working");
+        if (sound_working->getBoolValue() == true) {
+            fgInitSoundManager();
+            smgr_init = false;
+        }
     } else {
-       sgSetVec3( listener_vel, 0.0, 0.0, 0.0 );
-    }
-
-    globals->get_soundmgr()->set_listener_vel( listener_vel );
-
-    // set positional offset for sources
-    sgdVec3 dsource_pos_offset;
-    sgdSubVec3( dsource_pos_offset,
-                current_view->get_view_pos().sg(),
-                model_pos.sg() );
-    SGVec3d sgv_dsource_pos_offset = model_or.rotateBack(
-        surf_or.rotateBack(SGVec3d(dsource_pos_offset[0],
-        dsource_pos_offset[1], dsource_pos_offset[2])));
-
-    sgVec3 source_pos_offset;
-    sgSetVec3(source_pos_offset, sgv_dsource_pos_offset[0],
-        sgv_dsource_pos_offset[1], sgv_dsource_pos_offset[2]);
-
-    globals->get_soundmgr()->set_source_pos_all( source_pos_offset );
+        static SGPropertyNode *sound_enabled = fgGetNode("/sim/sound/enabled");
+        static SGSoundMgr *smgr = globals->get_soundmgr();
+        static bool smgr_enabled = true;
+
+        if (smgr_enabled != sound_enabled->getBoolValue()) {
+            if (smgr_enabled == true) { // request to suspend
+                smgr->suspend();
+                smgr_enabled = false;
+            } else {
+                smgr->resume();
+                smgr_enabled = true;
+            }
+        }
 
-    float orient[6];
-    for (int i = 0; i < 3; i++) {
-        orient[i] = sgv_at[i];
-        orient[i + 3] = sgv_up[i];
+        if (smgr_enabled == true) {
+            static SGPropertyNode *volume = fgGetNode("/sim/sound/volume");
+            smgr->set_volume(volume->getFloatValue());
+            smgr->update(delta_time_sec);
+        }
     }
-    globals->get_soundmgr()->set_listener_orientation( orient );
-
-    // set the velocity
-    // all sources are defined to be in the model
-    globals->get_soundmgr()->set_source_vel_all( model_vel );
-
-    // The listener is always positioned at the origin.
-    sgVec3 listener_pos;
-    sgSetVec3( listener_pos, 0.0, 0.0, 0.0 );
-    globals->get_soundmgr()->set_listener_pos( listener_pos );
 #endif
 
     // END Tile Manager udpates
@@ -609,15 +519,41 @@ static void fgMainLoop( void ) {
     if (!scenery_loaded && globals->get_tile_mgr()->isSceneryLoaded()
         && cur_fdm_state->get_inited()) {
         fgSetBool("sim/sceneryloaded",true);
-        fgSetFloat("/sim/sound/volume", init_volume);
-        globals->get_soundmgr()->set_volume(init_volume);
+        if (fgGetBool("/sim/sound/working")) {
+            globals->get_soundmgr()->activate();
+        }
+        globals->get_props()->tie("/sim/sound/devices/name",
+              SGRawValueFunctions<const char *>(0, fgSetNewSoundDevice), false);
     }
-
+    simgear::AtomicChangeListener::fireChangeListeners();
     fgRequestRedraw();
 
     SG_LOG( SG_ALL, SG_DEBUG, "" );
 }
 
+void fgInitSoundManager()
+{
+    SGSoundMgr *smgr = globals->get_soundmgr();
+
+    smgr->bind();
+    smgr->init(fgGetString("/sim/sound/device-name", NULL));
+
+    vector <const char*>devices = smgr->get_available_devices();
+    for (unsigned int i=0; i<devices.size(); i++) {
+        SGPropertyNode *p = fgGetNode("/sim/sound/devices/device", i, true);
+        p->setStringValue(devices[i]);
+    }
+    devices.clear();
+}
+
+void fgSetNewSoundDevice(const char *device)
+{
+    globals->get_soundmgr()->suspend();
+    globals->get_soundmgr()->stop();
+    globals->get_soundmgr()->init(device);
+    globals->get_soundmgr()->resume();
+}
+
 // Operation for querying OpenGL parameters. This must be done in a
 // valid OpenGL context, potentially in another thread.
 namespace
@@ -748,6 +684,7 @@ static void fgIdleFunction ( void ) {
 
     } else if ( idle_state == 5 ) {
         idle_state++;
+
         ////////////////////////////////////////////////////////////////////
         // Initialize the 3D aircraft model subsystem (has a dependency on
         // the scenery subsystem.)
@@ -844,13 +781,13 @@ static void fgIdleFunction ( void ) {
             SG_LOG( SG_GENERAL, SG_INFO,
                 "Starting intro music: " << mp3file.str() );
 
-#if defined( __CYGWIN__ )
+# if defined( __CYGWIN__ )
             string command = "start /m `cygpath -w " + mp3file.str() + "`";
-#elif defined( WIN32 )
+# elif defined( _WIN32 )
             string command = "start /m " + mp3file.str();
-#else
+# else
             string command = "mpg123 " + mp3file.str() + "> /dev/null 2>&1";
-#endif
+# endif
 
             system ( command.c_str() );
         }
@@ -881,7 +818,9 @@ static void fgIdleFunction ( void ) {
                                          fgGetInt("/sim/startup/ysize") );
 
         fgSplashProgress("loading scenery objects");
-
+        int session = fgGetInt("/sim/session",0);
+        session++;
+        fgSetInt("/sim/session",session);
     }
 
     if ( idle_state == 1000 ) {
@@ -952,7 +891,7 @@ bool fgMainInit( int argc, char **argv ) {
     fgInitFGRoot(argc, argv);
 
     // Check for the correct base package version
-    static char required_version[] = "1.9.0";
+    static char required_version[] = "2.0.0";
     string base_version = fgBasePackageVersion();
     if ( !(base_version == required_version) ) {
         // tell the operator how to use this application