]> git.mxchange.org Git - flightgear.git/blob - src/Main/fg_props.cxx
000ead9c1cdbdf8b845cbfbef32fec06e0a60ab3
[flightgear.git] / src / Main / fg_props.cxx
1 // fg_props.cxx -- support for FlightGear properties.
2 //
3 // Written by David Megginson, started 2000.
4 //
5 // Copyright (C) 2000, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23 #ifdef HAVE_CONFIG_H
24 #  include <simgear/compiler.h>
25 #endif
26
27 #include STL_IOSTREAM
28
29 #include <Autopilot/newauto.hxx>
30 #include <Aircraft/aircraft.hxx>
31 #include <Time/tmp.hxx>
32 #include <FDM/UIUCModel/uiuc_aircraftdir.h>
33 #ifndef FG_OLD_WEATHER
34 #  include <WeatherCM/FGLocalWeatherDatabase.h>
35 #else
36 #  include <Weather/weather.hxx>
37 #endif
38 #include <Objects/matlib.hxx>
39
40 #include "fgfs.hxx"
41 #include "fg_props.hxx"
42
43 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
44 SG_USING_STD(istream);
45 SG_USING_STD(ostream);
46 #endif
47
48 static double getWindNorth ();
49 static double getWindEast ();
50 static double getWindDown ();
51
52 // Allow the view to be set from two axes (i.e. a joystick hat)
53 // This needs to be in FGViewer itself, somehow.
54 static double axisLong = 0.0;
55 static double axisLat = 0.0;
56
57 /**
58  * Utility function.
59  */
60 static inline void
61 _set_view_from_axes ()
62 {
63                                 // Take no action when hat is centered
64   if ( ( axisLong <  0.01 ) &&
65        ( axisLong > -0.01 ) &&
66        ( axisLat  <  0.01 ) &&
67        ( axisLat  > -0.01 )
68      )
69     return;
70
71   double viewDir = 999;
72
73   /* Do all the quick and easy cases */
74   if (axisLong < 0) {           // Longitudinal axis forward
75     if (axisLat == axisLong)
76       viewDir = 45;
77     else if (axisLat == - axisLong)
78       viewDir = 315;
79     else if (axisLat == 0)
80       viewDir = 0;
81   } else if (axisLong > 0) {    // Longitudinal axis backward
82     if (axisLat == - axisLong)
83       viewDir = 135;
84     else if (axisLat == axisLong)
85       viewDir = 225;
86     else if (axisLat == 0)
87       viewDir = 180;
88   } else if (axisLong == 0) {   // Longitudinal axis neutral
89     if (axisLat < 0)
90       viewDir = 90;
91     else if (axisLat > 0)
92       viewDir = 270;
93     else return; /* And assertion failure maybe? */
94   }
95
96   /* Do all the difficult cases */
97   if ( viewDir > 900 )
98     viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axisLat, -axisLong );
99   if ( viewDir < -1 ) viewDir += 360;
100
101 //  SG_LOG(SG_INPUT, SG_ALERT, "Joystick Lat=" << axisLat << "   and Long="
102 //      << axisLong << "  gave angle=" << viewDir );
103
104   globals->get_current_view()->set_goal_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
105 //   globals->get_current_view()->set_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
106 }
107
108 \f
109 ////////////////////////////////////////////////////////////////////////
110 // Default property bindings (not yet handled by any module).
111 ////////////////////////////////////////////////////////////////////////
112
113
114 /**
115  * Get the pause state of the sim.
116  */
117 static bool
118 getFreeze ()
119 {
120   return globals->get_freeze();
121 }
122
123
124 /**
125  * Set the pause state of the sim.
126  */
127 static void
128 setFreeze (bool freeze)
129 {
130   globals->set_freeze(freeze);
131 }
132
133 /**
134  * Return the current aircraft directory (UIUC) as a string.
135  */
136 static string 
137 getAircraftDir ()
138 {
139   return aircraft_dir;
140 }
141
142
143 /**
144  * Set the current aircraft directory (UIUC).
145  */
146 static void
147 setAircraftDir (string dir)
148 {
149   if (getAircraftDir() != dir) {
150     aircraft_dir = dir;
151 //     needReinit(); FIXME!!
152   }
153 }
154
155
156 /**
157  * Get the current view offset in degrees.
158  */
159 static double
160 getViewOffset ()
161 {
162   return (globals->get_current_view()
163           ->get_view_offset() * SGD_RADIANS_TO_DEGREES);
164 }
165
166
167 static void
168 setViewOffset (double offset)
169 {
170   globals->get_current_view()->set_view_offset(offset * SGD_DEGREES_TO_RADIANS);
171 }
172
173 static double
174 getGoalViewOffset ()
175 {
176   return (globals->get_current_view()
177           ->get_goal_view_offset() * SGD_RADIANS_TO_DEGREES);
178 }
179
180 static void
181 setGoalViewOffset (double offset)
182 {
183   globals->get_current_view()
184     ->set_goal_view_offset(offset * SGD_DEGREES_TO_RADIANS);
185 }
186
187
188 /**
189  * Return the current Zulu time.
190  */
191 static string 
192 getDateString ()
193 {
194   string out;
195   char buf[64];
196   struct tm * t = globals->get_time_params()->getGmt();
197   sprintf(buf, "%.4d-%.2d-%.2dT%.2d:%.2d:%.2d",
198           t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
199           t->tm_hour, t->tm_min, t->tm_sec);
200   out = buf;
201   return out;
202 }
203
204
205 /**
206  * Set the current Zulu time.
207  */
208 static void
209 setDateString (string date_string)
210 {
211   SGTime * st = globals->get_time_params();
212   struct tm * current_time = st->getGmt();
213   struct tm new_time;
214
215                                 // Scan for basic ISO format
216                                 // YYYY-MM-DDTHH:MM:SS
217   int ret = sscanf(date_string.c_str(), "%d-%d-%dT%d:%d:%d",
218                    &(new_time.tm_year), &(new_time.tm_mon),
219                    &(new_time.tm_mday), &(new_time.tm_hour),
220                    &(new_time.tm_min), &(new_time.tm_sec));
221
222                                 // Be pretty picky about this, so
223                                 // that strange things don't happen
224                                 // if the save file has been edited
225                                 // by hand.
226   if (ret != 6) {
227     SG_LOG(SG_INPUT, SG_ALERT, "Date/time string " << date_string
228            << " not in YYYY-MM-DDTHH:MM:SS format; skipped");
229     return;
230   }
231
232                                 // OK, it looks like we got six
233                                 // values, one way or another.
234   new_time.tm_year -= 1900;
235   new_time.tm_mon -= 1;
236
237                                 // Now, tell flight gear to use
238                                 // the new time.  This was far
239                                 // too difficult, by the way.
240   long int warp =
241     mktime(&new_time) - mktime(current_time) + globals->get_warp();
242   double lon = current_aircraft.fdm_state->get_Longitude();
243   double lat = current_aircraft.fdm_state->get_Latitude();
244   globals->set_warp(warp);
245   st->update(lon, lat, warp);
246   fgUpdateSkyAndLightingParams();
247 }
248
249 /**
250  * Return the GMT as a string.
251  */
252 static string 
253 getGMTString ()
254 {
255   string out;
256   char buf[16];
257   struct tm * t = globals->get_time_params()->getGmt();
258   sprintf(buf, " %.2d:%.2d:%.2d",
259           t->tm_hour, t->tm_min, t->tm_sec);
260   out = buf;
261   return out;
262 }
263
264
265 /**
266  * Get the texture rendering state.
267  */
268 static bool
269 getTextures ()
270 {
271   return (material_lib.get_step() == 0);
272 }
273
274
275 /**
276  * Set the texture rendering state.
277  */
278 static void
279 setTextures (bool textures)
280 {
281   if (textures)
282     material_lib.set_step(0);
283   else
284     material_lib.set_step(1);
285 }
286
287
288 /**
289  * Return the magnetic variation
290  */
291 static double
292 getMagVar ()
293 {
294   return globals->get_mag()->get_magvar() * SGD_RADIANS_TO_DEGREES;
295 }
296
297
298 /**
299  * Return the magnetic dip
300  */
301 static double
302 getMagDip ()
303 {
304   return globals->get_mag()->get_magdip() * SGD_RADIANS_TO_DEGREES;
305 }
306
307
308 /**
309  * Return the current heading in degrees.
310  */
311 static double
312 getHeadingMag ()
313 {
314   return current_aircraft.fdm_state->get_Psi() * SGD_RADIANS_TO_DEGREES - getMagVar();
315 }
316
317
318 /**
319  * Return the current engine0 rpm
320  */
321 static double
322 getRPM ()
323 {
324   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
325       return current_aircraft.fdm_state->get_engine(0)->get_RPM();
326   } else {
327       return 0.0;
328   }
329 }
330
331
332 /**
333  * Return the current engine0 EGT.
334  */
335 static double
336 getEGT ()
337 {
338   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
339       return current_aircraft.fdm_state->get_engine(0)->get_EGT();
340   } else {
341       return 0.0;
342   }
343 }
344
345 /**
346  * Return the current engine0 CHT.
347  */
348 static double
349 getCHT ()
350 {
351   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
352       return current_aircraft.fdm_state->get_engine(0)->get_CHT();
353   } else {
354       return 0.0;
355   }
356 }
357
358 /**
359  * Return the current engine0 Manifold Pressure.
360  */
361 static double
362 getMP ()
363 {
364   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
365       return current_aircraft.fdm_state->get_engine(0)->get_Manifold_Pressure();
366   } else {
367       return 0.0;
368   }
369 }
370
371
372 /**
373  * Return the current engine0 fuel flow
374  */
375 static double
376 getFuelFlow ()
377 {
378   if ( current_aircraft.fdm_state->get_engine(0) != NULL ) {
379       return current_aircraft.fdm_state->get_engine(0)->get_Fuel_Flow();
380   } else {
381       return 0.0;
382   }
383 }
384
385 /**
386  * Return the fuel level in tank 1
387  */
388 static double
389 getTank1Fuel ()
390 {
391   return current_aircraft.fdm_state->get_Tank1Fuel();
392 }
393
394 static void
395 setTank1Fuel ( double gals )
396 {
397   current_aircraft.fdm_state->set_Tank1Fuel( gals );
398 }
399
400 /**
401  * Return the fuel level in tank 2
402  */
403 static double
404 getTank2Fuel ()
405 {
406   return current_aircraft.fdm_state->get_Tank2Fuel();
407 }
408
409 static void
410 setTank2Fuel ( double gals )
411 {
412   current_aircraft.fdm_state->set_Tank2Fuel( gals );
413 }
414
415
416 /**
417  * Get the autopilot altitude lock (true=on).
418  */
419 static bool
420 getAPAltitudeLock ()
421 {
422     return (current_autopilot->get_AltitudeEnabled() &&
423             current_autopilot->get_AltitudeMode()
424             == FGAutopilot::FG_ALTITUDE_LOCK);
425 }
426
427
428 /**
429  * Set the autopilot altitude lock (true=on).
430  */
431 static void
432 setAPAltitudeLock (bool lock)
433 {
434   current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_LOCK);
435   current_autopilot->set_AltitudeEnabled(lock);
436 }
437
438
439 /**
440  * Get the autopilot target altitude in feet.
441  */
442 static double
443 getAPAltitude ()
444 {
445   return current_autopilot->get_TargetAltitude() * SG_METER_TO_FEET;
446 }
447
448
449 /**
450  * Set the autopilot target altitude in feet.
451  */
452 static void
453 setAPAltitude (double altitude)
454 {
455     current_autopilot->set_TargetAltitude( altitude * SG_FEET_TO_METER );
456 }
457
458 /**
459  * Get the autopilot altitude lock (true=on).
460  */
461 static bool
462 getAPGSLock ()
463 {
464     return (current_autopilot->get_AltitudeEnabled() &&
465             (current_autopilot->get_AltitudeMode()
466              == FGAutopilot::FG_ALTITUDE_GS1));
467 }
468
469
470 /**
471  * Set the autopilot altitude lock (true=on).
472  */
473 static void
474 setAPGSLock (bool lock)
475 {
476   current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_GS1);
477   current_autopilot->set_AltitudeEnabled(lock);
478 }
479
480
481 /**
482  * Get the autopilot terrain lock (true=on).
483  */
484 static bool
485 getAPTerrainLock ()
486 {
487     return (current_autopilot->get_AltitudeEnabled() &&
488             (current_autopilot->get_AltitudeMode()
489              == FGAutopilot::FG_ALTITUDE_TERRAIN));
490 }
491
492
493 /**
494  * Set the autopilot terrain lock (true=on).
495  */
496 static void
497 setAPTerrainLock (bool lock)
498 {
499   current_autopilot->set_AltitudeMode(FGAutopilot::FG_ALTITUDE_TERRAIN);
500   current_autopilot->set_AltitudeEnabled(lock);
501 }
502
503
504 /**
505  * Get the autopilot target altitude in feet.
506  */
507 static double
508 getAPClimb ()
509 {
510   return current_autopilot->get_TargetClimbRate() * SG_METER_TO_FEET;
511 }
512
513
514 /**
515  * Set the autopilot target altitude in feet.
516  */
517 static void
518 setAPClimb (double rate)
519 {
520     current_autopilot->set_TargetClimbRate( rate * SG_FEET_TO_METER );
521 }
522
523
524 /**
525  * Get the autopilot heading lock (true=on).
526  */
527 static bool
528 getAPHeadingLock ()
529 {
530     return
531       (current_autopilot->get_HeadingEnabled() &&
532        current_autopilot->get_HeadingMode() == DEFAULT_AP_HEADING_LOCK);
533 }
534
535
536 /**
537  * Set the autopilot heading lock (true=on).
538  */
539 static void
540 setAPHeadingLock (bool lock)
541 {
542     if (lock) {
543         current_autopilot->set_HeadingMode(DEFAULT_AP_HEADING_LOCK);
544         current_autopilot->set_HeadingEnabled(true);
545     } else {
546         current_autopilot->set_HeadingEnabled(false);
547     }
548 }
549
550
551 /**
552  * Get the autopilot heading bug in degrees.
553  */
554 static double
555 getAPHeadingBug ()
556 {
557   return current_autopilot->get_DGTargetHeading();
558 }
559
560
561 /**
562  * Set the autopilot heading bug in degrees.
563  */
564 static void
565 setAPHeadingBug (double heading)
566 {
567   current_autopilot->set_DGTargetHeading( heading );
568 }
569
570
571 /**
572  * Get the autopilot wing leveler lock (true=on).
573  */
574 static bool
575 getAPWingLeveler ()
576 {
577     return
578       (current_autopilot->get_HeadingEnabled() &&
579        current_autopilot->get_HeadingMode() == FGAutopilot::FG_TC_HEADING_LOCK);
580 }
581
582
583 /**
584  * Set the autopilot wing leveler lock (true=on).
585  */
586 static void
587 setAPWingLeveler (bool lock)
588 {
589     if (lock) {
590         current_autopilot->set_HeadingMode(FGAutopilot::FG_TC_HEADING_LOCK);
591         current_autopilot->set_HeadingEnabled(true);
592     } else {
593         current_autopilot->set_HeadingEnabled(false);
594     }
595 }
596
597 /**
598  * Return true if the autopilot is locked to NAV1.
599  */
600 static bool
601 getAPNAV1Lock ()
602 {
603   return
604     (current_autopilot->get_HeadingEnabled() &&
605      current_autopilot->get_HeadingMode() == FGAutopilot::FG_HEADING_NAV1);
606 }
607
608
609 /**
610  * Set the autopilot NAV1 lock.
611  */
612 static void
613 setAPNAV1Lock (bool lock)
614 {
615   if (lock) {
616     current_autopilot->set_HeadingMode(FGAutopilot::FG_HEADING_NAV1);
617     current_autopilot->set_HeadingEnabled(true);
618   } else if (current_autopilot->get_HeadingMode() ==
619              FGAutopilot::FG_HEADING_NAV1) {
620     current_autopilot->set_HeadingEnabled(false);
621   }
622 }
623
624 /**
625  * Get the autopilot autothrottle lock.
626  */
627 static bool
628 getAPAutoThrottleLock ()
629 {
630   return current_autopilot->get_AutoThrottleEnabled();
631 }
632
633
634 /**
635  * Set the autothrottle lock.
636  */
637 static void
638 setAPAutoThrottleLock (bool lock)
639 {
640   current_autopilot->set_AutoThrottleEnabled(lock);
641 }
642
643
644 // kludge
645 static double
646 getAPRudderControl ()
647 {
648     if (getAPHeadingLock())
649         return current_autopilot->get_TargetHeading();
650     else
651         return controls.get_rudder();
652 }
653
654 // kludge
655 static void
656 setAPRudderControl (double value)
657 {
658     if (getAPHeadingLock()) {
659         SG_LOG(SG_GENERAL, SG_DEBUG, "setAPRudderControl " << value );
660         value -= current_autopilot->get_TargetHeading();
661         current_autopilot->HeadingAdjust(value < 0.0 ? -1.0 : 1.0);
662     } else {
663         controls.set_rudder(value);
664     }
665 }
666
667 // kludge
668 static double
669 getAPElevatorControl ()
670 {
671   if (getAPAltitudeLock())
672       return current_autopilot->get_TargetAltitude();
673   else
674     return controls.get_elevator();
675 }
676
677 // kludge
678 static void
679 setAPElevatorControl (double value)
680 {
681     if (getAPAltitudeLock()) {
682         SG_LOG(SG_GENERAL, SG_DEBUG, "setAPElevatorControl " << value );
683         value -= current_autopilot->get_TargetAltitude();
684         current_autopilot->AltitudeAdjust(value < 0.0 ? 100.0 : -100.0);
685     } else {
686         controls.set_elevator(value);
687     }
688 }
689
690 // kludge
691 static double
692 getAPThrottleControl ()
693 {
694   if (getAPAutoThrottleLock())
695     return 0.0;                 // always resets
696   else
697     return controls.get_throttle(0);
698 }
699
700 // kludge
701 static void
702 setAPThrottleControl (double value)
703 {
704   if (getAPAutoThrottleLock())
705     current_autopilot->AutoThrottleAdjust(value < 0.0 ? -0.01 : 0.01);
706   else
707     controls.set_throttle(0, value);
708 }
709
710
711 /**
712  * Get the current visibility (meters).
713  */
714 static double
715 getVisibility ()
716 {
717 #ifndef FG_OLD_WEATHER
718   return WeatherDatabase->getWeatherVisibility();
719 #else
720   return current_weather.get_visibility();
721 #endif
722 }
723
724
725 /**
726  * Set the current visibility (meters).
727  */
728 static void
729 setVisibility (double visibility)
730 {
731 #ifndef FG_OLD_WEATHER
732   WeatherDatabase->setWeatherVisibility(visibility);
733 #else
734   current_weather.set_visibility(visibility);
735 #endif
736 }
737
738 /**
739  * Get the current wind north velocity (feet/second).
740  */
741 static double
742 getWindNorth ()
743 {
744   return current_aircraft.fdm_state->get_V_north_airmass();
745 }
746
747
748 /**
749  * Set the current wind north velocity (feet/second).
750  */
751 static void
752 setWindNorth (double speed)
753 {
754   current_aircraft.fdm_state
755     ->set_Velocities_Local_Airmass(speed, getWindEast(), getWindDown());
756 }
757
758
759 /**
760  * Get the current wind east velocity (feet/second).
761  */
762 static double
763 getWindEast ()
764 {
765   return current_aircraft.fdm_state->get_V_east_airmass();
766 }
767
768
769 /**
770  * Set the current wind east velocity (feet/second).
771  */
772 static void
773 setWindEast (double speed)
774 {
775   cout << "Set wind-east to " << speed << endl;
776   current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
777                                                            speed,
778                                                            getWindDown());
779 }
780
781
782 /**
783  * Get the current wind down velocity (feet/second).
784  */
785 static double
786 getWindDown ()
787 {
788   return current_aircraft.fdm_state->get_V_down_airmass();
789 }
790
791
792 /**
793  * Set the current wind down velocity (feet/second).
794  */
795 static void
796 setWindDown (double speed)
797 {
798   current_aircraft.fdm_state->set_Velocities_Local_Airmass(getWindNorth(),
799                                                            getWindEast(),
800                                                            speed);
801 }
802
803 static double
804 getFOV ()
805 {
806   return globals->get_current_view()->get_fov();
807 }
808
809 static void
810 setFOV (double fov)
811 {
812   globals->get_current_view()->set_fov( fov );
813 }
814
815 static long
816 getWarp ()
817 {
818   return globals->get_warp();
819 }
820
821 static void
822 setWarp (long warp)
823 {
824   globals->set_warp(warp);
825 }
826
827 static long
828 getWarpDelta ()
829 {
830   return globals->get_warp_delta();
831 }
832
833 static void
834 setWarpDelta (long delta)
835 {
836   globals->set_warp_delta(delta);
837 }
838
839 static void
840 setViewAxisLong (double axis)
841 {
842   axisLong = axis;
843 }
844
845 static void
846 setViewAxisLat (double axis)
847 {
848   axisLat = axis;
849 }
850
851
852 void
853 fgInitProps ()
854 {
855                                 // Simulation
856   fgTie("/sim/freeze", getFreeze, setFreeze);
857   fgTie("/sim/aircraft-dir", getAircraftDir, setAircraftDir);
858   fgTie("/sim/view/offset", getViewOffset, setViewOffset);
859   fgTie("/sim/view/goal-offset", getGoalViewOffset, setGoalViewOffset);
860   fgTie("/sim/time/gmt", getDateString, setDateString);
861   fgTie("/sim/time/gmt-string", getGMTString);
862   fgTie("/sim/rendering/textures", getTextures, setTextures);
863
864                                 // Orientation
865   fgTie("/orientation/heading-magnetic", getHeadingMag);
866
867                                 // Engine
868   fgTie("/engines/engine0/rpm", getRPM);
869   fgTie("/engines/engine0/egt", getEGT);
870   fgTie("/engines/engine0/cht", getCHT);
871   fgTie("/engines/engine0/mp", getMP);
872   fgTie("/engines/engine0/fuel-flow", getFuelFlow);
873
874   //consumables
875   fgTie("/consumables/fuel/tank1/level", getTank1Fuel, setTank1Fuel, false);
876   fgTie("/consumables/fuel/tank2/level", getTank2Fuel, setTank2Fuel, false);
877
878                                 // Autopilot
879   fgTie("/autopilot/locks/altitude", getAPAltitudeLock, setAPAltitudeLock);
880   fgTie("/autopilot/settings/altitude", getAPAltitude, setAPAltitude);
881   fgTie("/autopilot/locks/glide-slope", getAPGSLock, setAPGSLock);
882   fgTie("/autopilot/locks/terrain", getAPTerrainLock, setAPTerrainLock);
883   fgTie("/autopilot/settings/climb-rate", getAPClimb, setAPClimb, false);
884   fgTie("/autopilot/locks/heading", getAPHeadingLock, setAPHeadingLock);
885   fgTie("/autopilot/settings/heading-bug", getAPHeadingBug, setAPHeadingBug,
886         false);
887   fgTie("/autopilot/locks/wing-leveler", getAPWingLeveler, setAPWingLeveler);
888   fgTie("/autopilot/locks/nav1", getAPNAV1Lock, setAPNAV1Lock);
889   fgTie("/autopilot/locks/auto-throttle",
890         getAPAutoThrottleLock, setAPAutoThrottleLock);
891   fgTie("/autopilot/control-overrides/rudder",
892         getAPRudderControl, setAPRudderControl);
893   fgTie("/autopilot/control-overrides/elevator",
894         getAPElevatorControl, setAPElevatorControl);
895   fgTie("/autopilot/control-overrides/throttle",
896         getAPThrottleControl, setAPThrottleControl);
897
898                                 // Environment
899   fgTie("/environment/visibility", getVisibility, setVisibility);
900   fgTie("/environment/wind-north", getWindNorth, setWindNorth);
901   fgTie("/environment/wind-east", getWindEast, setWindEast);
902   fgTie("/environment/wind-down", getWindDown, setWindDown);
903   fgTie("/environment/magnetic-variation", getMagVar);
904   fgTie("/environment/magnetic-dip", getMagDip);
905
906                                 // View
907   fgTie("/sim/field-of-view", getFOV, setFOV);
908   fgTie("/sim/time/warp", getWarp, setWarp);
909   fgTie("/sim/time/warp-delta", getWarpDelta, setWarpDelta);
910   fgTie("/sim/view/axes/long", (double(*)())0, setViewAxisLong);
911   fgTie("/sim/view/axes/lat", (double(*)())0, setViewAxisLat);
912 }
913
914
915 void
916 fgUpdateProps ()
917 {
918   _set_view_from_axes();
919 }
920
921
922 \f
923 ////////////////////////////////////////////////////////////////////////
924 // Save and restore.
925 ////////////////////////////////////////////////////////////////////////
926
927
928 /**
929  * Save the current state of the simulator to a stream.
930  */
931 bool
932 fgSaveFlight (ostream &output)
933 {
934   return writeProperties(output, globals->get_props());
935 }
936
937
938 /**
939  * Restore the current state of the simulator from a stream.
940  */
941 bool
942 fgLoadFlight (istream &input)
943 {
944   SGPropertyNode props;
945   if (readProperties(input, &props)) {
946     copyProperties(&props, globals->get_props());
947                                 // When loading a flight, make it the
948                                 // new initial state.
949     globals->saveInitialState();
950   } else {
951     SG_LOG(SG_INPUT, SG_ALERT, "Error restoring flight; aborted");
952     return false;
953   }
954
955   return true;
956 }
957
958 // end of fg_props.cxx