]> git.mxchange.org Git - flightgear.git/blob - src/Aircraft/controls.cxx
Make FGControls behave like a standard subsystem.
[flightgear.git] / src / Aircraft / controls.cxx
1 // controls.cxx -- defines a standard interface to all flight sim controls
2 //
3 // Written by Curtis Olson, started May 1997.
4 //
5 // Copyright (C) 1997  Curtis L. Olson  - http://www.flightgear.org/~curt
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23 #ifdef HAVE_CONFIG_H
24 #  include "config.h"
25 #endif
26
27 #include <Main/fg_props.hxx>
28 #include <simgear/sg_inlines.h>
29 #include "controls.hxx"
30
31 ////////////////////////////////////////////////////////////////////////
32 // Implementation of FGControls.
33 ////////////////////////////////////////////////////////////////////////
34
35 // Constructor
36 FGControls::FGControls() :
37     aileron( 0.0 ),
38     aileron_trim( 0.0 ),
39     elevator( 0.0 ),
40     elevator_trim( 0.0 ),
41     rudder( 0.0 ),
42     rudder_trim( 0.0 ),
43     flaps( 0.0 ),
44     slats( 0.0 ),
45     BLC( false ),
46     spoilers( 0.0 ),
47     speedbrake( 0.0 ),
48     wing_sweep( 0.0 ),
49     wing_fold( false ),
50     drag_chute( false ),
51     throttle_idle( true ),
52     dump_valve( false ),
53     brake_left( 0.0 ),
54     brake_right( 0.0 ),
55     copilot_brake_left( 0.0 ),
56     copilot_brake_right( 0.0 ),
57     brake_parking( 0.0 ),
58     steering( 0.0 ),
59     nose_wheel_steering( true ),
60     gear_down( true ),
61     antiskid( true ),
62     tailhook( false ),
63     launchbar( false ),
64     catapult_launch_cmd( false ),
65     tailwheel_lock( true ),
66     wing_heat( false ),
67     pitot_heat( true ),
68     wiper( 0 ),
69     window_heat( false ),
70     battery_switch( true ),
71     external_power( false ),
72     APU_generator( false ),
73     APU_bleed( false ),
74     mode( 0 ),
75     dump( false ),
76     outflow_valve( 0.0 ),
77     taxi_light( false ),
78     logo_lights( false ),
79     nav_lights( false ),
80     beacon( false ),
81     strobe( false ),
82     panel_norm( 0.0 ),
83     instruments_norm( 0.0 ),
84     dome_norm( 0.0 ),
85     master_arm( false ),
86     station_select( 1 ),
87     release_ALL( false ),
88     vertical_adjust( 0.0 ),
89     fore_aft_adjust( 0.0 ),
90     off_start_run( 0 ),
91     APU_fire_switch( false ),
92     autothrottle_arm( false ),
93     autothrottle_engage( false ),
94     heading_select( 0.0 ),
95     altitude_select( 50000.0 ),
96     bank_angle_select( 30.0 ),
97     vertical_speed_select( 0.0 ),
98     speed_select( 0.0 ),
99     mach_select( 0.0 ),
100     vertical_mode( 0 ),
101     lateral_mode( 0 )
102 {
103     globals->set_controls( this );
104 }
105
106
107 void FGControls::reset_all()
108 {
109     set_aileron( 0.0 );
110     set_aileron_trim( 0.0 );
111     set_elevator( 0.0 );
112     set_elevator_trim( 0.0 );
113     set_rudder( 0.0 );
114     set_rudder_trim( 0.0 );
115     BLC = false;
116     set_spoilers( 0.0 );
117     set_speedbrake( 0.0 );
118     set_wing_sweep( 0.0 );
119     wing_fold = false;
120     drag_chute = false;
121     set_throttle( ALL_ENGINES, 0.0 );
122     set_starter( ALL_ENGINES, false );
123     set_magnetos( ALL_ENGINES, 0 );
124     set_fuel_pump( ALL_ENGINES, false );
125     set_fire_switch( ALL_ENGINES, false );
126     set_fire_bottle_discharge( ALL_ENGINES, false );
127     set_cutoff( ALL_ENGINES, true );
128     set_nitrous_injection( ALL_ENGINES, false );
129     set_cowl_flaps_norm( ALL_ENGINES, 1.0 );
130     set_feather( ALL_ENGINES, false );
131     set_ignition( ALL_ENGINES, false );
132     set_augmentation( ALL_ENGINES, false );
133     set_reverser( ALL_ENGINES, false );
134     set_water_injection( ALL_ENGINES, false );
135     set_condition( ALL_ENGINES, 1.0 );
136     throttle_idle = true;
137     set_fuel_selector( ALL_TANKS, true );
138     dump_valve = false;
139     steering =  0.0;
140     nose_wheel_steering = true;
141     gear_down = true;
142     tailhook = false;
143     launchbar = false;
144     catapult_launch_cmd = false;
145     tailwheel_lock = true;
146     set_carb_heat( ALL_ENGINES, false );
147     set_inlet_heat( ALL_ENGINES, false );
148     wing_heat = false;
149     pitot_heat = true;
150     wiper = 0;
151     window_heat = false;
152     set_engine_pump( ALL_HYD_SYSTEMS, true );
153     set_electric_pump( ALL_HYD_SYSTEMS, true );
154     landing_lights = false;
155     turn_off_lights = false;
156     master_arm = false;
157     set_ejection_seat( ALL_EJECTION_SEATS, false );
158     set_eseat_status( ALL_EJECTION_SEATS, SEAT_SAFED );
159     set_cmd_selector_valve( CMD_SEL_NORM );
160     APU_fire_switch = false;
161     autothrottle_arm = false;
162     autothrottle_engage = false;
163     set_autopilot_engage( ALL_AUTOPILOTS, false );
164 }
165
166
167 // Destructor
168 FGControls::~FGControls() {
169 }
170
171
172 void
173 FGControls::init ()
174 {
175     throttle_idle = true;
176     for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
177         throttle[engine] = 0.0;
178         mixture[engine] = 1.0;
179         fuel_pump[engine] = false;
180         prop_advance[engine] = 1.0;
181         magnetos[engine] = 0;
182         feed_tank[engine] = -1; // set to -1 to turn off all tanks 0 feeds all engines from center body tank
183         starter[engine] = false;
184         feather[engine] = false;
185         ignition[engine] = false;
186         fire_switch[engine] = false;
187         fire_bottle_discharge[engine] = false;
188         cutoff[engine] = true;
189         augmentation[engine] = false;
190         reverser[engine] = false;
191         water_injection[engine] = false;
192         nitrous_injection[engine] = false;
193         cowl_flaps_norm[engine] = 0.0;
194         condition[engine] = 1.0;
195         carb_heat[engine] = false;
196         inlet_heat[engine] = false;
197         generator_breaker[engine] = false;
198         bus_tie[engine] = false;
199         engine_bleed[engine] = false;
200     }
201
202     for ( int tank = 0; tank < MAX_TANKS; tank++ ) {
203         fuel_selector[tank] = false;
204         to_engine[tank] = 0;
205         to_tank[tank] = 0;
206     }
207
208     for( int pump = 0; pump < MAX_TANKS * MAX_BOOSTPUMPS; pump++ ) {
209         boost_pump[pump] = false;
210     }
211
212     brake_left = brake_right
213         = copilot_brake_left = copilot_brake_right
214         = brake_parking = 0.0;
215     for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
216         alternate_extension[wheel] = false;
217     }
218
219     auto_coordination = fgGetNode("/controls/flight/auto-coordination", true);
220     auto_coordination_factor = fgGetNode("/controls/flight/auto-coordination-factor", false );
221     if( NULL == auto_coordination_factor ) {
222       auto_coordination_factor = fgGetNode("/controls/flight/auto-coordination-factor", true );
223       auto_coordination_factor->setDoubleValue( 0.5 );
224     }
225 }
226
227 static inline void _SetRoot( simgear::TiedPropertyList & tiedProperties, const char * root, int index = 0 )
228 {
229     tiedProperties.setRoot( fgGetNode( root, index, true ) );
230 }
231
232 void
233 FGControls::bind ()
234 {
235     init(); // unfortunately, tie-ing requires init() to have occurred
236     int index, i;
237
238     // flight controls
239     _SetRoot( _tiedProperties, "/controls/flight" );
240
241     _tiedProperties.Tie( "aileron", this, &FGControls::get_aileron, &FGControls::set_aileron )
242         ->setAttribute( SGPropertyNode::ARCHIVE, true );
243
244     _tiedProperties.Tie( "aileron-trim", this, &FGControls::get_aileron_trim, &FGControls::set_aileron_trim )
245         ->setAttribute( SGPropertyNode::ARCHIVE, true );
246
247     _tiedProperties.Tie( "elevator", this, &FGControls::get_elevator, &FGControls::set_elevator )
248         ->setAttribute( SGPropertyNode::ARCHIVE, true );
249
250     _tiedProperties.Tie( "elevator-trim", this, &FGControls::get_elevator_trim, &FGControls::set_elevator_trim )
251         ->setAttribute( SGPropertyNode::ARCHIVE, true );
252
253     _tiedProperties.Tie( "rudder", this, &FGControls::get_rudder, &FGControls::set_rudder )
254         ->setAttribute( SGPropertyNode::ARCHIVE, true );
255
256     _tiedProperties.Tie( "rudder-trim", this, &FGControls::get_rudder_trim, &FGControls::set_rudder_trim )
257         ->setAttribute( SGPropertyNode::ARCHIVE, true );
258
259     _tiedProperties.Tie( "flaps", this, &FGControls::get_flaps, &FGControls::set_flaps )
260         ->setAttribute( SGPropertyNode::ARCHIVE, true );
261
262     _tiedProperties.Tie( "slats", this, &FGControls::get_slats, &FGControls::set_slats )
263         ->setAttribute( SGPropertyNode::ARCHIVE, true );
264
265     _tiedProperties.Tie( "BLC", this, &FGControls::get_BLC, &FGControls::set_BLC )
266         ->setAttribute( SGPropertyNode::ARCHIVE, true );
267
268     _tiedProperties.Tie( "spoilers", this, &FGControls::get_spoilers, &FGControls::set_spoilers )
269         ->setAttribute( SGPropertyNode::ARCHIVE, true );
270
271     _tiedProperties.Tie( "speedbrake", this, &FGControls::get_speedbrake, &FGControls::set_speedbrake )
272         ->setAttribute( SGPropertyNode::ARCHIVE, true );
273
274     _tiedProperties.Tie( "wing-sweep", this, &FGControls::get_wing_sweep, &FGControls::set_wing_sweep )
275         ->setAttribute( SGPropertyNode::ARCHIVE, true );
276
277     _tiedProperties.Tie( "wing-fold", this, &FGControls::get_wing_fold, &FGControls::set_wing_fold )
278         ->setAttribute( SGPropertyNode::ARCHIVE, true );
279
280     _tiedProperties.Tie( "drag-chute", this, &FGControls::get_drag_chute, &FGControls::set_drag_chute )
281         ->setAttribute( SGPropertyNode::ARCHIVE, true );
282
283     // engines
284     _tiedProperties.setRoot( fgGetNode("/controls/engines", true ) );
285
286     _tiedProperties.Tie( "throttle_idle", this, &FGControls::get_throttle_idle, &FGControls::set_throttle_idle )
287         ->setAttribute( SGPropertyNode::ARCHIVE, true );
288
289     for (index = 0; index < MAX_ENGINES; index++) {
290         _SetRoot(_tiedProperties, "/controls/engines/engine", index );
291
292         _tiedProperties.Tie( "throttle", this, index, &FGControls::get_throttle, &FGControls::set_throttle )
293             ->setAttribute( SGPropertyNode::ARCHIVE, true );
294
295         _tiedProperties.Tie( "starter", this, index, &FGControls::get_starter, &FGControls::set_starter )
296             ->setAttribute( SGPropertyNode::ARCHIVE, true );
297
298         _tiedProperties.Tie( "fuel-pump", this, index, &FGControls::get_fuel_pump, &FGControls::set_fuel_pump )
299             ->setAttribute( SGPropertyNode::ARCHIVE, true );
300
301         _tiedProperties.Tie( "fire-switch", this, index, &FGControls::get_fire_switch, &FGControls::set_fire_switch )
302             ->setAttribute( SGPropertyNode::ARCHIVE, true );
303
304         _tiedProperties.Tie( "fire-bottle-discharge", this, index, &FGControls::get_fire_bottle_discharge, &FGControls::set_fire_bottle_discharge )
305             ->setAttribute( SGPropertyNode::ARCHIVE, true );
306
307         _tiedProperties.Tie( "cutoff", this, index, &FGControls::get_cutoff, &FGControls::set_cutoff )
308             ->setAttribute( SGPropertyNode::ARCHIVE, true );
309
310         _tiedProperties.Tie( "mixture", this, index, &FGControls::get_mixture, &FGControls::set_mixture )
311             ->setAttribute( SGPropertyNode::ARCHIVE, true );
312
313         _tiedProperties.Tie( "propeller-pitch", this, index, &FGControls::get_prop_advance, &FGControls::set_prop_advance )
314             ->setAttribute( SGPropertyNode::ARCHIVE, true );
315
316         _tiedProperties.Tie( "magnetos", this, index, &FGControls::get_magnetos, &FGControls::set_magnetos )
317             ->setAttribute( SGPropertyNode::ARCHIVE, true );
318
319         _tiedProperties.Tie( "feed_tank", this, index, &FGControls::get_feed_tank, &FGControls::set_feed_tank )
320             ->setAttribute( SGPropertyNode::ARCHIVE, true );
321
322         _tiedProperties.Tie( "WEP", this, index, &FGControls::get_nitrous_injection, &FGControls::set_nitrous_injection )
323             ->setAttribute( SGPropertyNode::ARCHIVE, true );
324
325         _tiedProperties.Tie( "cowl-flaps-norm", this, index, &FGControls::get_cowl_flaps_norm, &FGControls::set_cowl_flaps_norm )
326             ->setAttribute( SGPropertyNode::ARCHIVE, true );
327
328         _tiedProperties.Tie( "propeller-feather", this, index, &FGControls::get_feather, &FGControls::set_feather )
329             ->setAttribute( SGPropertyNode::ARCHIVE, true );
330
331         _tiedProperties.Tie( "ignition", this, index, &FGControls::get_ignition, &FGControls::set_ignition )
332             ->setAttribute( SGPropertyNode::ARCHIVE, true );
333
334         _tiedProperties.Tie( "augmentation", this, index, &FGControls::get_augmentation, &FGControls::set_augmentation )
335             ->setAttribute( SGPropertyNode::ARCHIVE, true );
336
337         _tiedProperties.Tie( "reverser", this, index, &FGControls::get_reverser, &FGControls::set_reverser )
338             ->setAttribute( SGPropertyNode::ARCHIVE, true );
339
340         _tiedProperties.Tie( "water-injection", this, index, &FGControls::get_water_injection, &FGControls::set_water_injection )
341             ->setAttribute( SGPropertyNode::ARCHIVE, true );
342
343         _tiedProperties.Tie( "condition", this, index, &FGControls::get_condition, &FGControls::set_condition )
344             ->setAttribute( SGPropertyNode::ARCHIVE, true );
345     }
346
347     // fuel
348     _SetRoot( _tiedProperties, "/controls/fuel" );
349
350     _tiedProperties.Tie( "dump-valve", this, &FGControls::get_dump_valve, &FGControls::set_dump_valve)
351         ->setAttribute( SGPropertyNode::ARCHIVE, true );
352
353     for (index = 0; index < MAX_TANKS; index++) {
354         _SetRoot( _tiedProperties, "/controls/fuel/tank", index );
355
356         _tiedProperties.Tie( "fuel_selector", this, index, &FGControls::get_fuel_selector, &FGControls::set_fuel_selector)
357             ->setAttribute( SGPropertyNode::ARCHIVE, true );
358
359         _tiedProperties.Tie( "to_engine", this, index, &FGControls::get_to_engine, &FGControls::set_to_engine)
360             ->setAttribute( SGPropertyNode::ARCHIVE, true );
361
362         _tiedProperties.Tie( "to_tank", this, index, &FGControls::get_to_tank, &FGControls::set_to_tank)
363             ->setAttribute( SGPropertyNode::ARCHIVE, true );
364
365         for (i = 0; i < MAX_BOOSTPUMPS; i++) {
366             _tiedProperties.Tie( "boost-pump", i,
367                 this, index * 2 + i, &FGControls::get_boost_pump, &FGControls::set_boost_pump)
368                 ->setAttribute( SGPropertyNode::ARCHIVE, true );
369         }
370     }
371
372     // gear
373     _SetRoot( _tiedProperties, "/controls/gear" );
374
375     _tiedProperties.Tie( "brake-left", this, &FGControls::get_brake_left, &FGControls::set_brake_left)
376         ->setAttribute( SGPropertyNode::ARCHIVE, true );
377
378     _tiedProperties.Tie( "brake-right", this, &FGControls::get_brake_right, &FGControls::set_brake_right)
379         ->setAttribute( SGPropertyNode::ARCHIVE, true );
380
381     _tiedProperties.Tie( "copilot-brake-left", this, &FGControls::get_copilot_brake_left, &FGControls::set_copilot_brake_left)
382         ->setAttribute( SGPropertyNode::ARCHIVE, true );
383
384     _tiedProperties.Tie( "copilot-brake-right", this, &FGControls::get_copilot_brake_right, &FGControls::set_copilot_brake_right)
385         ->setAttribute( SGPropertyNode::ARCHIVE, true );
386
387     _tiedProperties.Tie( "brake-parking", this, &FGControls::get_brake_parking, &FGControls::set_brake_parking)
388         ->setAttribute( SGPropertyNode::ARCHIVE, true );
389
390     _tiedProperties.Tie( "steering", this, &FGControls::get_steering, &FGControls::set_steering)
391         ->setAttribute( SGPropertyNode::ARCHIVE, true );
392
393     _tiedProperties.Tie( "nose-wheel-steering", this, &FGControls::get_nose_wheel_steering, &FGControls::set_nose_wheel_steering)
394         ->setAttribute( SGPropertyNode::ARCHIVE, true );
395
396     _tiedProperties.Tie( "gear-down", this, &FGControls::get_gear_down, &FGControls::set_gear_down)
397         ->setAttribute( SGPropertyNode::ARCHIVE, true );
398
399     _tiedProperties.Tie( "antiskid", this, &FGControls::get_antiskid, &FGControls::set_antiskid)
400         ->setAttribute( SGPropertyNode::ARCHIVE, true );
401
402     _tiedProperties.Tie( "tailhook", this, &FGControls::get_tailhook, &FGControls::set_tailhook)
403         ->setAttribute( SGPropertyNode::ARCHIVE, true );
404
405     _tiedProperties.Tie( "launchbar", this, &FGControls::get_launchbar, &FGControls::set_launchbar)
406         ->setAttribute( SGPropertyNode::ARCHIVE, true );
407
408     _tiedProperties.Tie( "catapult-launch-cmd", this, &FGControls::get_catapult_launch_cmd, &FGControls::set_catapult_launch_cmd)
409         ->setAttribute( SGPropertyNode::ARCHIVE, true );
410
411     _tiedProperties.Tie( "tailwheel-lock", this, &FGControls::get_tailwheel_lock, &FGControls::set_tailwheel_lock)
412         ->setAttribute( SGPropertyNode::ARCHIVE, true );
413
414     for (index = 0; index < MAX_WHEELS; index++) {
415         _SetRoot( _tiedProperties, "/controls/gear/wheel", index );
416         _tiedProperties.Tie( "alternate-extension", this, index, &FGControls::get_alternate_extension, &FGControls::set_alternate_extension)
417             ->setAttribute( SGPropertyNode::ARCHIVE, true );
418     }
419
420     // anti-ice
421     _SetRoot( _tiedProperties, "/controls/anti-ice" );
422
423     _tiedProperties.Tie( "wing-heat", this, &FGControls::get_wing_heat, &FGControls::set_wing_heat)
424         ->setAttribute( SGPropertyNode::ARCHIVE, true );
425
426     _tiedProperties.Tie( "pitot-heat", this, &FGControls::get_pitot_heat, &FGControls::set_pitot_heat)
427         ->setAttribute( SGPropertyNode::ARCHIVE, true );
428
429     _tiedProperties.Tie( "wiper", this, &FGControls::get_wiper, &FGControls::set_wiper)
430         ->setAttribute( SGPropertyNode::ARCHIVE, true );
431
432     _tiedProperties.Tie( "window-heat", this, &FGControls::get_window_heat, &FGControls::set_window_heat)
433         ->setAttribute( SGPropertyNode::ARCHIVE, true );
434
435     for (index = 0; index < MAX_ENGINES; index++) {
436         _SetRoot( _tiedProperties, "/controls/anti-ice/engine", index );
437
438         _tiedProperties.Tie( "carb-heat", this, index, &FGControls::get_carb_heat, &FGControls::set_carb_heat)
439             ->setAttribute( SGPropertyNode::ARCHIVE, true );
440
441         _tiedProperties.Tie( "inlet-heat", this, index, &FGControls::get_inlet_heat, &FGControls::set_inlet_heat)
442             ->setAttribute( SGPropertyNode::ARCHIVE, true );
443     }
444
445     // hydraulics
446     for (index = 0; index < MAX_HYD_SYSTEMS; index++) {
447         _SetRoot( _tiedProperties, "/controls/hydraulic/system", index );
448
449         _tiedProperties.Tie( "engine-pump", this, index, &FGControls::get_engine_pump, &FGControls::set_engine_pump)
450             ->setAttribute( SGPropertyNode::ARCHIVE, true );
451
452         _tiedProperties.Tie( "electric-pump", this, index, &FGControls::get_electric_pump, &FGControls::set_electric_pump)
453             ->setAttribute( SGPropertyNode::ARCHIVE, true );
454     }  
455
456     // electric
457     _SetRoot( _tiedProperties, "/controls/electric" );
458
459     _tiedProperties.Tie( "battery-switch", this, &FGControls::get_battery_switch, &FGControls::set_battery_switch)
460         ->setAttribute( SGPropertyNode::ARCHIVE, true );
461
462     _tiedProperties.Tie( "external-power", this, &FGControls::get_external_power, &FGControls::set_external_power)
463         ->setAttribute( SGPropertyNode::ARCHIVE, true );
464
465     _tiedProperties.Tie( "APU-generator", this, &FGControls::get_APU_generator, &FGControls::set_APU_generator)
466         ->setAttribute( SGPropertyNode::ARCHIVE, true );
467
468     for (index = 0; index < MAX_ENGINES; index++) {
469         _SetRoot( _tiedProperties, "/controls/electric/engine", index );
470
471         _tiedProperties.Tie( "generator", this, index, &FGControls::get_generator_breaker, &FGControls::set_generator_breaker)
472             ->setAttribute( SGPropertyNode::ARCHIVE, true );
473
474         _tiedProperties.Tie( "bus-tie", this, index, &FGControls::get_bus_tie, &FGControls::set_bus_tie)
475             ->setAttribute( SGPropertyNode::ARCHIVE, true );
476     }  
477
478     // pneumatic
479     _SetRoot( _tiedProperties, "/controls/pneumatic" );
480
481     _tiedProperties.Tie( "APU-bleed", this, &FGControls::get_APU_bleed, &FGControls::set_APU_bleed)
482         ->setAttribute( SGPropertyNode::ARCHIVE, true );
483
484     for (index = 0; index < MAX_ENGINES; index++) {
485         _SetRoot( _tiedProperties, "/controls/pneumatic/engine", index );
486
487         _tiedProperties.Tie( "bleed", this, index, &FGControls::get_engine_bleed, &FGControls::set_engine_bleed)
488             ->setAttribute( SGPropertyNode::ARCHIVE, true );
489     }
490
491     // pressurization
492     _SetRoot( _tiedProperties, "/controls/pressurization" );
493
494     _tiedProperties.Tie( "mode", this, &FGControls::get_mode, &FGControls::set_mode)
495         ->setAttribute( SGPropertyNode::ARCHIVE, true );
496
497     _tiedProperties.Tie( "dump", this, &FGControls::get_dump, &FGControls::set_dump)
498         ->setAttribute( SGPropertyNode::ARCHIVE, true );
499
500     _tiedProperties.Tie( "outflow-valve", this, &FGControls::get_outflow_valve, &FGControls::set_outflow_valve)
501         ->setAttribute( SGPropertyNode::ARCHIVE, true );
502
503     for (index = 0; index < MAX_PACKS; index++) {
504         _SetRoot( _tiedProperties, "/controls/pressurization/pack", index );
505
506         _tiedProperties.Tie( "pack-on", this, index, &FGControls::get_pack_on, &FGControls::set_pack_on)
507             ->setAttribute( SGPropertyNode::ARCHIVE, true );
508     }
509
510     // lights
511     _SetRoot( _tiedProperties, "/controls/lighting" );
512
513     _tiedProperties.Tie( "landing-lights", this, &FGControls::get_landing_lights, &FGControls::set_landing_lights)
514         ->setAttribute( SGPropertyNode::ARCHIVE, true );
515
516     _tiedProperties.Tie( "turn-off-lights", this, &FGControls::get_turn_off_lights, &FGControls::set_turn_off_lights)
517         ->setAttribute( SGPropertyNode::ARCHIVE, true );
518
519     _tiedProperties.Tie( "taxi-light", this, &FGControls::get_taxi_light, &FGControls::set_taxi_light)
520         ->setAttribute( SGPropertyNode::ARCHIVE, true );
521
522     _tiedProperties.Tie( "logo-lights", this, &FGControls::get_logo_lights, &FGControls::set_logo_lights)
523         ->setAttribute( SGPropertyNode::ARCHIVE, true );
524
525     _tiedProperties.Tie( "nav-lights", this, &FGControls::get_nav_lights, &FGControls::set_nav_lights)
526         ->setAttribute( SGPropertyNode::ARCHIVE, true );
527
528     _tiedProperties.Tie( "beacon", this, &FGControls::get_beacon, &FGControls::set_beacon)
529         ->setAttribute( SGPropertyNode::ARCHIVE, true );
530
531     _tiedProperties.Tie( "strobe", this, &FGControls::get_strobe, &FGControls::set_strobe)
532         ->setAttribute( SGPropertyNode::ARCHIVE, true );
533
534     _tiedProperties.Tie( "panel-norm", this, &FGControls::get_panel_norm, &FGControls::set_panel_norm)
535         ->setAttribute( SGPropertyNode::ARCHIVE, true );
536
537     _tiedProperties.Tie( "instruments-norm", this, &FGControls::get_instruments_norm, &FGControls::set_instruments_norm)
538         ->setAttribute( SGPropertyNode::ARCHIVE, true );
539
540     _tiedProperties.Tie( "dome-norm", this, &FGControls::get_dome_norm, &FGControls::set_dome_norm)
541         ->setAttribute( SGPropertyNode::ARCHIVE, true );
542
543     // armament
544     _SetRoot( _tiedProperties, "/controls/armament" );
545
546     _tiedProperties.Tie( "master-arm", this, &FGControls::get_master_arm, &FGControls::set_master_arm)
547         ->setAttribute( SGPropertyNode::ARCHIVE, true );
548
549     _tiedProperties.Tie( "station-select", this, &FGControls::get_station_select, &FGControls::set_station_select)
550         ->setAttribute( SGPropertyNode::ARCHIVE, true );
551
552     _tiedProperties.Tie( "release-all", this, &FGControls::get_release_ALL, &FGControls::set_release_ALL)
553         ->setAttribute( SGPropertyNode::ARCHIVE, true );
554
555     for (index = 0; index < MAX_STATIONS; index++) {
556         _SetRoot( _tiedProperties, "/controls/armament/station", index );
557
558         _tiedProperties.Tie( "stick-size", this, index, &FGControls::get_stick_size, &FGControls::set_stick_size)
559             ->setAttribute( SGPropertyNode::ARCHIVE, true );
560
561         _tiedProperties.Tie( "release-stick", this, index, &FGControls::get_release_stick, &FGControls::set_release_stick)
562             ->setAttribute( SGPropertyNode::ARCHIVE, true );
563
564         _tiedProperties.Tie( "release-all", this, index, &FGControls::get_release_all, &FGControls::set_release_all)
565             ->setAttribute( SGPropertyNode::ARCHIVE, true );
566
567         _tiedProperties.Tie( "jettison-all", this, index, &FGControls::get_jettison_all, &FGControls::set_jettison_all)
568             ->setAttribute( SGPropertyNode::ARCHIVE, true );
569     }
570
571     // seat
572     _SetRoot( _tiedProperties, "/controls/seat" );
573
574     _tiedProperties.Tie( "vertical-adjust", this, &FGControls::get_vertical_adjust, &FGControls::set_vertical_adjust)
575         ->setAttribute( SGPropertyNode::ARCHIVE, true );
576
577     _tiedProperties.Tie( "fore-aft-adjust", this, &FGControls::get_fore_aft_adjust, &FGControls::set_fore_aft_adjust)
578         ->setAttribute( SGPropertyNode::ARCHIVE, true );
579
580     _tiedProperties.Tie( "cmd_selector_valve", this, &FGControls::get_cmd_selector_valve, &FGControls::set_cmd_selector_valve)
581         ->setAttribute( SGPropertyNode::ARCHIVE, true );
582
583     for (index = 0; index < MAX_EJECTION_SEATS; index++) {
584         _SetRoot( _tiedProperties, "/controls/seat/eject", index );
585
586         _tiedProperties.Tie( "initiate", this, index, &FGControls::get_ejection_seat, &FGControls::set_ejection_seat)
587             ->setAttribute( SGPropertyNode::ARCHIVE, true );
588
589         _tiedProperties.Tie( "status", this, index, &FGControls::get_eseat_status, &FGControls::set_eseat_status)
590             ->setAttribute( SGPropertyNode::ARCHIVE, true );
591     }
592
593     // APU
594     _SetRoot( _tiedProperties, "/controls/APU" );
595
596     _tiedProperties.Tie( "off-start-run", this, &FGControls::get_off_start_run, &FGControls::set_off_start_run)
597         ->setAttribute( SGPropertyNode::ARCHIVE, true );
598
599     _tiedProperties.Tie( "fire-switch", this, &FGControls::get_APU_fire_switch, &FGControls::set_APU_fire_switch)
600         ->setAttribute( SGPropertyNode::ARCHIVE, true );
601
602     // autoflight
603     for (index = 0; index < MAX_AUTOPILOTS; index++) {
604
605         _SetRoot( _tiedProperties, "/controls/autoflight/autopilot", index );
606
607         _tiedProperties.Tie( "engage", this, index, &FGControls::get_autopilot_engage, &FGControls::set_autopilot_engage)
608             ->setAttribute( SGPropertyNode::ARCHIVE, true );
609     }
610
611     _SetRoot( _tiedProperties, "/controls/autoflight/" );
612
613     _tiedProperties.Tie( "autothrottle-arm", this, &FGControls::get_autothrottle_arm, &FGControls::set_autothrottle_arm)
614         ->setAttribute( SGPropertyNode::ARCHIVE, true );
615
616     _tiedProperties.Tie( "autothrottle-engage", this, &FGControls::get_autothrottle_engage, &FGControls::set_autothrottle_engage)
617         ->setAttribute( SGPropertyNode::ARCHIVE, true );
618
619     _tiedProperties.Tie( "heading-select", this, &FGControls::get_heading_select, &FGControls::set_heading_select)
620         ->setAttribute( SGPropertyNode::ARCHIVE, true );
621
622     _tiedProperties.Tie( "altitude-select", this, &FGControls::get_altitude_select, &FGControls::set_altitude_select)
623         ->setAttribute( SGPropertyNode::ARCHIVE, true );
624
625     _tiedProperties.Tie( "bank-angle-select", this, &FGControls::get_bank_angle_select, &FGControls::set_bank_angle_select)
626         ->setAttribute( SGPropertyNode::ARCHIVE, true );
627
628     _tiedProperties.Tie( "vertical-speed-select", this, &FGControls::get_vertical_speed_select, &FGControls::set_vertical_speed_select)
629         ->setAttribute( SGPropertyNode::ARCHIVE, true );
630
631     _tiedProperties.Tie( "speed-select", this, &FGControls::get_speed_select, &FGControls::set_speed_select)
632         ->setAttribute( SGPropertyNode::ARCHIVE, true );
633
634     _tiedProperties.Tie( "mach-select", this, &FGControls::get_mach_select, &FGControls::set_mach_select)
635         ->setAttribute( SGPropertyNode::ARCHIVE, true );
636
637     _tiedProperties.Tie( "vertical-mode", this, &FGControls::get_vertical_mode, &FGControls::set_vertical_mode)
638         ->setAttribute( SGPropertyNode::ARCHIVE, true );
639
640     _tiedProperties.Tie( "lateral-mode", this, &FGControls::get_lateral_mode, &FGControls::set_lateral_mode)
641         ->setAttribute( SGPropertyNode::ARCHIVE, true );
642 }
643
644 void FGControls::unbind ()
645 {
646     _tiedProperties.Untie();
647
648
649
650 void
651 FGControls::update (double dt)
652 {
653   SG_UNUSED(dt);
654 }
655 \f
656 ////////////////////////////////////////////////////////////////////////
657 // Setters and adjusters.
658 ////////////////////////////////////////////////////////////////////////
659
660 void
661 FGControls::set_aileron (double pos)
662 {
663     aileron = pos;
664     SG_CLAMP_RANGE<double>( aileron, -1.0, 1.0 );
665     do_autocoordination();
666 }
667
668 void
669 FGControls::move_aileron (double amt)
670 {
671     aileron += amt;
672     SG_CLAMP_RANGE<double>( aileron, -1.0, 1.0 );
673     do_autocoordination();
674 }
675
676 void
677 FGControls::set_aileron_trim( double pos )
678 {
679     aileron_trim = pos;
680     SG_CLAMP_RANGE<double>( aileron_trim, -1.0, 1.0 );
681 }
682
683 void
684 FGControls::move_aileron_trim( double amt )
685 {
686     aileron_trim += amt;
687     SG_CLAMP_RANGE<double>( aileron_trim, -1.0, 1.0 );
688 }
689
690 void
691 FGControls::set_elevator( double pos )
692 {
693     elevator = pos;
694     SG_CLAMP_RANGE<double>( elevator, -1.0, 1.0 );
695 }
696
697 void
698 FGControls::move_elevator( double amt )
699 {
700     elevator += amt;
701     SG_CLAMP_RANGE<double>( elevator, -1.0, 1.0 );
702 }
703
704 void
705 FGControls::set_elevator_trim( double pos )
706 {
707     elevator_trim = pos;
708     SG_CLAMP_RANGE<double>( elevator_trim, -1.0, 1.0 );
709 }
710
711 void
712 FGControls::move_elevator_trim( double amt )
713 {
714     elevator_trim += amt;
715     SG_CLAMP_RANGE<double>( elevator_trim, -1.0, 1.0 );
716 }
717
718 void
719 FGControls::set_rudder( double pos )
720 {
721     rudder = pos;
722     SG_CLAMP_RANGE<double>( rudder, -1.0, 1.0 );
723 }
724
725 void
726 FGControls::move_rudder( double amt )
727 {
728     rudder += amt;
729     SG_CLAMP_RANGE<double>( rudder, -1.0, 1.0 );
730 }
731
732 void
733 FGControls::set_rudder_trim( double pos )
734 {
735     rudder_trim = pos;
736     SG_CLAMP_RANGE<double>( rudder_trim, -1.0, 1.0 );
737 }
738
739 void
740 FGControls::move_rudder_trim( double amt )
741 {
742     rudder_trim += amt;
743     SG_CLAMP_RANGE<double>( rudder_trim, -1.0, 1.0 );
744 }
745
746 void
747 FGControls::set_flaps( double pos )
748 {
749     flaps = pos;
750     SG_CLAMP_RANGE<double>( flaps, 0.0, 1.0 );
751 }
752
753 void
754 FGControls::move_flaps( double amt )
755 {
756     flaps += amt;
757     SG_CLAMP_RANGE<double>( flaps, 0.0, 1.0 );
758 }
759
760 void
761 FGControls::set_slats( double pos )
762 {
763     slats = pos;
764     SG_CLAMP_RANGE<double>( slats, 0.0, 1.0 );
765 }
766
767 void
768 FGControls::move_slats( double amt )
769 {
770     slats += amt;
771     SG_CLAMP_RANGE<double>( slats, 0.0, 1.0 );
772 }
773
774 void
775 FGControls::set_BLC( bool val )
776 {
777     BLC = val;
778 }
779
780 void
781 FGControls::set_spoilers( double pos )
782 {
783     spoilers = pos;
784     SG_CLAMP_RANGE<double>( spoilers, 0.0, 1.0 );
785 }
786
787 void
788 FGControls::move_spoilers( double amt )
789 {
790     spoilers += amt;
791     SG_CLAMP_RANGE<double>( spoilers, 0.0, 1.0 );
792 }
793
794 void
795 FGControls::set_speedbrake( double pos )
796 {
797     speedbrake = pos;
798     SG_CLAMP_RANGE<double>( speedbrake, 0.0, 1.0 );
799 }
800
801 void
802 FGControls::move_speedbrake( double amt )
803 {
804     speedbrake += amt;
805     SG_CLAMP_RANGE<double>( speedbrake, 0.0, 1.0 );
806 }
807
808 void
809 FGControls::set_wing_sweep( double pos )
810 {
811     wing_sweep = pos;
812     SG_CLAMP_RANGE<double>( wing_sweep, 0.0, 1.0 );
813 }
814
815 void
816 FGControls::move_wing_sweep( double amt )
817 {
818     wing_sweep += amt;
819     SG_CLAMP_RANGE<double>( wing_sweep, 0.0, 1.0 );
820 }
821
822 void
823 FGControls::set_wing_fold( bool val )
824 {
825     wing_fold = val;
826 }
827
828 void
829 FGControls::set_drag_chute( bool val )
830 {
831     drag_chute = val;
832 }
833
834 void
835 FGControls::set_throttle_idle( bool val )
836 {
837     throttle_idle = val;
838 }
839
840 void
841 FGControls::set_throttle( int engine, double pos )
842 {
843     if ( engine == ALL_ENGINES ) {
844         for ( int i = 0; i < MAX_ENGINES; i++ ) {
845             throttle[i] = pos;
846             SG_CLAMP_RANGE<double>( throttle[i], 0.0, 1.0 );
847         }
848     } else {
849         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
850             throttle[engine] = pos;
851             SG_CLAMP_RANGE<double>( throttle[engine], 0.0, 1.0 );
852         }
853     }
854 }
855
856 void
857 FGControls::move_throttle( int engine, double amt )
858 {
859     if ( engine == ALL_ENGINES ) {
860         for ( int i = 0; i < MAX_ENGINES; i++ ) {
861             throttle[i] += amt;
862             SG_CLAMP_RANGE<double>( throttle[i], 0.0, 1.0 );
863         }
864     } else {
865         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
866             throttle[engine] += amt;
867             SG_CLAMP_RANGE<double>( throttle[engine], 0.0, 1.0 );
868         }
869     }
870 }
871
872 void
873 FGControls::set_starter( int engine, bool flag )
874 {
875     if ( engine == ALL_ENGINES ) {
876         for ( int i = 0; i < MAX_ENGINES; i++ ) {
877             starter[i] = flag;
878         }
879     } else {
880         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
881             starter[engine] = flag;
882         }
883     }
884 }
885
886 void
887 FGControls::set_fuel_pump( int engine, bool val )
888 {
889     if ( engine == ALL_ENGINES ) {
890         for ( int i = 0; i < MAX_ENGINES; i++ ) {
891             fuel_pump[i] = val;
892         }
893     } else {
894         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
895             fuel_pump[engine] = val;
896         }
897     }
898 }
899
900 void
901 FGControls::set_fire_switch( int engine, bool val )
902 {
903     if ( engine == ALL_ENGINES ) {
904         for ( int i = 0; i < MAX_ENGINES; i++ ) {
905             fire_switch[i] = val;
906         }
907     } else {
908         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
909             fire_switch[engine] = val;
910         }
911     }
912 }
913
914 void
915 FGControls::set_fire_bottle_discharge( int engine, bool val )
916 {
917     if ( engine == ALL_ENGINES ) {
918         for ( int i = 0; i < MAX_ENGINES; i++ ) {
919             fire_bottle_discharge[i] = val;
920         }
921     } else {
922         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
923             fire_bottle_discharge[engine] = val;
924         }
925     }
926 }
927
928 void
929 FGControls::set_cutoff( int engine, bool val )
930 {
931     if ( engine == ALL_ENGINES ) {
932         for ( int i = 0; i < MAX_ENGINES; i++ ) {
933             cutoff[i] = val;
934         }
935     } else {
936         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
937             cutoff[engine] = val;
938         }
939     }
940 }
941
942 void
943 FGControls::set_feed_tank( int engine, int tank )
944
945     if ( engine == ALL_ENGINES ) {
946         for ( int i = 0; i < MAX_ENGINES; i++ ) {
947             feed_tank[i] = tank;
948             SG_CLAMP_RANGE<int>( feed_tank[i], -1, 4 );
949         }
950     } else {
951         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
952             feed_tank[engine] = tank;
953             SG_CLAMP_RANGE<int>( feed_tank[engine], -1, 4 );
954         }
955     } 
956     //   feed_tank[engine] = engine;
957 }
958
959
960 void
961 FGControls::set_mixture( int engine, double pos )
962 {
963     if ( engine == ALL_ENGINES ) {
964         for ( int i = 0; i < MAX_ENGINES; i++ ) {
965             mixture[i] = pos;
966             SG_CLAMP_RANGE<double>( mixture[i], 0.0, 1.0 );
967         }
968     } else {
969         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
970             mixture[engine] = pos;
971             SG_CLAMP_RANGE<double>( mixture[engine], 0.0, 1.0 );
972         }
973     }
974 }
975
976 void
977 FGControls::move_mixture( int engine, double amt )
978 {
979     if ( engine == ALL_ENGINES ) {
980         for ( int i = 0; i < MAX_ENGINES; i++ ) {
981             mixture[i] += amt;
982             SG_CLAMP_RANGE<double>( mixture[i], 0.0, 1.0 );
983         }
984     } else {
985         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
986             mixture[engine] += amt;
987             SG_CLAMP_RANGE<double>( mixture[engine], 0.0, 1.0 );
988         }
989     }
990 }
991
992 void
993 FGControls::set_prop_advance( int engine, double pos )
994 {
995     if ( engine == ALL_ENGINES ) {
996         for ( int i = 0; i < MAX_ENGINES; i++ ) {
997             prop_advance[i] = pos;
998             SG_CLAMP_RANGE<double>( prop_advance[i], 0.0, 1.0 );
999         }
1000     } else {
1001         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1002             prop_advance[engine] = pos;
1003             SG_CLAMP_RANGE<double>( prop_advance[engine], 0.0, 1.0 );
1004         }
1005     }
1006 }
1007
1008 void
1009 FGControls::move_prop_advance( int engine, double amt )
1010 {
1011     if ( engine == ALL_ENGINES ) {
1012         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1013             prop_advance[i] += amt;
1014             SG_CLAMP_RANGE<double>( prop_advance[i], 0.0, 1.0 );
1015         }
1016     } else {
1017         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1018             prop_advance[engine] += amt;
1019             SG_CLAMP_RANGE<double>( prop_advance[engine], 0.0, 1.0 );
1020         }
1021     }
1022 }
1023
1024 void
1025 FGControls::set_magnetos( int engine, int pos )
1026 {
1027     if ( engine == ALL_ENGINES ) {
1028         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1029             magnetos[i] = pos;
1030             SG_CLAMP_RANGE<int>( magnetos[i], 0, 3 );
1031         }
1032     } else {
1033         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1034             magnetos[engine] = pos;
1035             SG_CLAMP_RANGE<int>( magnetos[engine], 0, 3 );
1036         }
1037     }
1038 }
1039
1040 void
1041 FGControls::move_magnetos( int engine, int amt )
1042 {
1043     if ( engine == ALL_ENGINES ) {
1044         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1045             magnetos[i] += amt;
1046             SG_CLAMP_RANGE<int>( magnetos[i], 0, 3 );
1047         }
1048     } else {
1049         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1050             magnetos[engine] += amt;
1051             SG_CLAMP_RANGE<int>( magnetos[engine], 0, 3 );
1052         }
1053     }
1054 }
1055
1056 void
1057 FGControls::set_nitrous_injection( int engine, bool val )
1058 {
1059     if ( engine == ALL_ENGINES ) {
1060         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1061             nitrous_injection[i] = val;
1062         }
1063     } else {
1064         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1065             nitrous_injection[engine] = val;
1066         }
1067     }
1068 }
1069
1070
1071 void
1072 FGControls::set_cowl_flaps_norm( int engine, double pos )
1073 {
1074     if ( engine == ALL_ENGINES ) {
1075         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1076             cowl_flaps_norm[i] = pos;
1077             SG_CLAMP_RANGE<double>( cowl_flaps_norm[i], 0.0, 1.0 );
1078         }
1079     } else {
1080         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1081             cowl_flaps_norm[engine] = pos;
1082             SG_CLAMP_RANGE<double>( cowl_flaps_norm[engine], 0.0, 1.0 );
1083         }
1084     }
1085 }
1086
1087 void
1088 FGControls::move_cowl_flaps_norm( int engine, double amt )
1089 {
1090     if ( engine == ALL_ENGINES ) {
1091         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1092             cowl_flaps_norm[i] += amt;
1093             SG_CLAMP_RANGE<double>( cowl_flaps_norm[i], 0.0, 1.0 );
1094         }
1095     } else {
1096         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1097             cowl_flaps_norm[engine] += amt;
1098             SG_CLAMP_RANGE<double>( cowl_flaps_norm[engine], 0.0, 1.0 );
1099         }
1100     }
1101 }
1102
1103 void
1104 FGControls::set_feather( int engine, bool val )
1105 {
1106     if ( engine == ALL_ENGINES ) {
1107         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1108             feather[i] = val;
1109         }
1110     } else {
1111         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1112             feather[engine] = val;
1113         }
1114     }
1115 }
1116
1117 void
1118 FGControls::set_ignition( int engine, int pos )
1119 {
1120     if ( engine == ALL_ENGINES ) {
1121         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1122             ignition[i] = pos;
1123             SG_CLAMP_RANGE<int>( ignition[i], 0, 3 );
1124         }
1125     } else {
1126         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1127             ignition[engine] = pos;
1128             SG_CLAMP_RANGE<int>( ignition[engine], 0, 3 );
1129         }
1130     }
1131 }
1132
1133 void
1134 FGControls::set_augmentation( int engine, bool val )
1135 {
1136     if ( engine == ALL_ENGINES ) {
1137         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1138             augmentation[i] = val;
1139         }
1140     } else {
1141         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1142             augmentation[engine] = val;
1143         }
1144     }
1145 }
1146
1147 void
1148 FGControls::set_reverser( int engine, bool val )
1149 {
1150     if ( engine == ALL_ENGINES ) {
1151         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1152             reverser[i] = val;
1153         }
1154     } else {
1155         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1156             reverser[engine] = val;
1157         }
1158     }
1159 }
1160
1161 void
1162 FGControls::set_water_injection( int engine, bool val )
1163 {
1164     if ( engine == ALL_ENGINES ) {
1165         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1166             water_injection[i] = val;
1167         }
1168     } else {
1169         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1170             water_injection[engine] = val;
1171         }
1172     }
1173 }
1174
1175 void
1176 FGControls::set_condition( int engine, double val )
1177 {
1178     if ( engine == ALL_ENGINES ) {
1179         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1180             condition[i] = val;
1181             SG_CLAMP_RANGE<double>( condition[i], 0.0, 1.0 );
1182         }
1183     } else {
1184         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1185             condition[engine] = val;
1186             SG_CLAMP_RANGE<double>( condition[engine], 0.0, 1.0 );
1187         }
1188     }
1189 }
1190
1191 void
1192 FGControls::set_dump_valve( bool val )
1193 {
1194     dump_valve = val;
1195 }
1196
1197
1198 void
1199 FGControls::set_fuel_selector( int tank, bool pos )
1200 {
1201     if ( tank == ALL_TANKS ) {
1202         for ( int i = 0; i < MAX_TANKS; i++ ) {
1203             fuel_selector[i] = pos;
1204         }
1205     } else {
1206         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
1207             fuel_selector[tank] = pos;
1208         }
1209     }
1210 }
1211
1212 void
1213 FGControls::set_to_engine( int tank, int engine )
1214 {
1215     if ( tank == ALL_TANKS ) {
1216         for ( int i = 0; i < MAX_TANKS; i++ ) {
1217             to_engine[i] = engine;
1218         }
1219     } else {
1220         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
1221             to_engine[tank] = engine;
1222         }
1223     }
1224 }
1225
1226 void
1227 FGControls::set_to_tank( int tank, int dest_tank )
1228 {
1229     if ( tank == ALL_TANKS ) {
1230         for ( int i = 0; i < MAX_TANKS; i++ ) {
1231             to_tank[i] = dest_tank;
1232         }
1233     } else {
1234         if ( (tank >= 0) && (tank < MAX_TANKS) ) {
1235             to_tank[tank] = dest_tank;
1236         }
1237     }
1238 }
1239
1240 void
1241 FGControls::set_boost_pump( int index, bool val ) 
1242 {
1243     if ( index == -1 ) {
1244         for ( int i = 0; i < (MAX_TANKS * MAX_BOOSTPUMPS); i++ ) {
1245             boost_pump[i] = val;
1246         }
1247     } else {
1248         if ( (index >= 0) && (index < (MAX_TANKS * MAX_BOOSTPUMPS)) ) {
1249             boost_pump[index] = val;
1250         }
1251     }
1252 }
1253
1254
1255 void
1256 FGControls::set_brake_left( double pos )
1257 {
1258     brake_left = pos;
1259     SG_CLAMP_RANGE<double>(brake_left, 0.0, 1.0);
1260 }
1261
1262 void
1263 FGControls::move_brake_left( double amt )
1264 {
1265     brake_left += amt;
1266     SG_CLAMP_RANGE<double>( brake_left, 0.0, 1.0 );
1267 }
1268
1269 void
1270 FGControls::set_brake_right( double pos )
1271 {
1272     brake_right = pos;
1273     SG_CLAMP_RANGE<double>(brake_right, 0.0, 1.0);
1274 }
1275
1276 void
1277 FGControls::move_brake_right( double amt )
1278 {
1279     brake_right += amt;
1280     SG_CLAMP_RANGE<double>( brake_right, 0.0, 1.0 );
1281 }
1282
1283 void
1284 FGControls::set_copilot_brake_left( double pos )
1285 {
1286     copilot_brake_left = pos;
1287     SG_CLAMP_RANGE<double>(brake_left, 0.0, 1.0);
1288 }
1289
1290 void
1291 FGControls::set_copilot_brake_right( double pos )
1292 {
1293     copilot_brake_right = pos;
1294     SG_CLAMP_RANGE<double>(brake_right, 0.0, 1.0);
1295 }
1296
1297 void
1298 FGControls::set_brake_parking( double pos )
1299 {
1300     brake_parking = pos;
1301     SG_CLAMP_RANGE<double>(brake_parking, 0.0, 1.0);
1302 }
1303
1304 void
1305 FGControls::set_steering( double angle )
1306 {
1307     steering = angle;
1308     SG_CLAMP_RANGE<double>(steering, -80.0, 80.0);
1309 }
1310
1311 void
1312 FGControls::set_nose_wheel_steering( bool nws )
1313 {
1314     nose_wheel_steering = nws;
1315 }
1316
1317 void
1318 FGControls::move_steering( double angle )
1319 {
1320     steering += angle;
1321     SG_CLAMP_RANGE<double>(steering, -80.0, 80.0);
1322 }
1323
1324 void
1325 FGControls::set_gear_down( bool gear )
1326 {
1327     gear_down = gear;
1328 }
1329
1330 void
1331 FGControls::set_antiskid( bool state )
1332 {
1333     antiskid = state;
1334 }
1335
1336 void
1337 FGControls::set_tailhook( bool state )
1338 {
1339     tailhook = state;
1340 }
1341
1342 void
1343 FGControls::set_launchbar( bool state )
1344 {
1345     launchbar = state;
1346 }
1347
1348 void
1349 FGControls::set_catapult_launch_cmd( bool state )
1350 {
1351     catapult_launch_cmd = state;
1352 }
1353
1354 void
1355 FGControls::set_tailwheel_lock( bool state )
1356 {
1357     tailwheel_lock = state;
1358 }
1359
1360
1361 void
1362 FGControls::set_alternate_extension( int wheel, bool val )
1363 {
1364     if ( wheel == ALL_WHEELS ) {
1365         for ( int i = 0; i < MAX_WHEELS; i++ ) {
1366             alternate_extension[i] = val;
1367         }
1368     } else {
1369         if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
1370             alternate_extension[wheel] = val;
1371         }
1372     }
1373 }
1374
1375 void
1376 FGControls::set_wing_heat( bool state )
1377 {
1378     wing_heat = state;
1379 }
1380
1381 void
1382 FGControls::set_pitot_heat( bool state )
1383 {
1384     pitot_heat = state;
1385 }
1386
1387 void
1388 FGControls::set_wiper( int state )
1389 {
1390     wiper = state;
1391 }
1392
1393 void
1394 FGControls::set_window_heat( bool state )
1395 {
1396     window_heat = state;
1397 }
1398
1399 void
1400 FGControls::set_carb_heat( int engine, bool val )
1401 {
1402     if ( engine == ALL_ENGINES ) {
1403         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1404             carb_heat[i] = val;
1405         }
1406     } else {
1407         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1408             carb_heat[engine] = val;
1409         }
1410     }
1411 }
1412
1413 void
1414 FGControls::set_inlet_heat( int engine, bool val )
1415 {
1416     if ( engine == ALL_ENGINES ) {
1417         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1418             inlet_heat[i] = val;
1419         }
1420     } else {
1421         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1422             inlet_heat[engine] = val;
1423         }
1424     }
1425 }
1426
1427 void
1428 FGControls::set_engine_pump( int system, bool val )
1429 {
1430     if ( system == ALL_HYD_SYSTEMS ) {
1431         for ( int i = 0; i < MAX_HYD_SYSTEMS; i++ ) {
1432             engine_pump[i] = val;
1433         }
1434     } else {
1435         if ( (system >= 0) && (system < MAX_HYD_SYSTEMS) ) {
1436             engine_pump[system] = val;
1437         }
1438     }
1439 }
1440
1441 void
1442 FGControls::set_electric_pump( int system, bool val )
1443 {
1444     if ( system == ALL_HYD_SYSTEMS ) {
1445         for ( int i = 0; i < MAX_HYD_SYSTEMS; i++ ) {
1446             electric_pump[i] = val;
1447         }
1448     } else {
1449         if ( (system >= 0) && (system < MAX_HYD_SYSTEMS) ) {
1450             electric_pump[system] = val;
1451         }
1452     }
1453 }
1454
1455 void
1456 FGControls::set_battery_switch( bool state )
1457 {
1458     battery_switch = state;
1459 }
1460
1461 void
1462 FGControls::set_external_power( bool state )
1463 {
1464     external_power = state;
1465 }
1466
1467 void
1468 FGControls::set_APU_generator( bool state )
1469 {
1470     APU_generator = state;
1471 }
1472
1473 void
1474 FGControls::set_generator_breaker( int engine, bool val )
1475 {
1476     if ( engine == ALL_ENGINES ) {
1477         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1478             generator_breaker[i] = val;
1479         }
1480     } else {
1481         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1482             generator_breaker[engine] = val;
1483         }
1484     }
1485 }
1486
1487 void
1488 FGControls::set_bus_tie( int engine, bool val )
1489 {
1490     if ( engine == ALL_ENGINES ) {
1491         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1492             bus_tie[i] = val;
1493         }
1494     } else {
1495         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1496             bus_tie[engine] = val;
1497         }
1498     }
1499 }
1500
1501 void
1502 FGControls::set_APU_bleed( bool state )
1503 {
1504     APU_bleed = state;
1505 }
1506
1507 void
1508 FGControls::set_engine_bleed( int engine, bool val )
1509 {
1510     if ( engine == ALL_ENGINES ) {
1511         for ( int i = 0; i < MAX_ENGINES; i++ ) {
1512             engine_bleed[i] = val;
1513         }
1514     } else {
1515         if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
1516             engine_bleed[engine] = val;
1517         }
1518     }
1519 }
1520
1521 void
1522 FGControls::set_mode( int new_mode )
1523 {
1524     mode = new_mode;
1525 }
1526
1527 void
1528 FGControls::set_outflow_valve( double pos )
1529 {
1530     outflow_valve = pos;
1531     SG_CLAMP_RANGE<double>( outflow_valve, 0.0, 1.0 );
1532 }
1533
1534 void
1535 FGControls::move_outflow_valve( double amt )
1536 {
1537     outflow_valve += amt;
1538     SG_CLAMP_RANGE<double>( outflow_valve, 0.0, 1.0 );
1539 }
1540
1541 void
1542 FGControls::set_dump( bool state )
1543 {
1544     dump = state;
1545 }
1546
1547 void
1548 FGControls::set_pack_on( int pack, bool val )
1549 {
1550     if ( pack == ALL_PACKS ) {
1551         for ( int i = 0; i < MAX_PACKS; i++ ) {
1552             pack_on[i] = val;
1553         }
1554     } else {
1555         if ( (pack >= 0) && (pack < MAX_PACKS) ) {
1556             pack_on[pack] = val;
1557         }
1558     }
1559 }
1560
1561 void
1562 FGControls::set_landing_lights( bool state )
1563 {
1564     landing_lights = state;
1565 }
1566
1567 void
1568 FGControls::set_turn_off_lights( bool state )
1569 {
1570     turn_off_lights = state;
1571 }
1572
1573 void
1574 FGControls::set_taxi_light( bool state )
1575 {
1576     taxi_light = state;
1577 }
1578
1579 void
1580 FGControls::set_logo_lights( bool state )
1581 {
1582     logo_lights = state;
1583 }
1584
1585 void
1586 FGControls::set_nav_lights( bool state )
1587 {
1588     nav_lights = state;
1589 }
1590
1591 void
1592 FGControls::set_beacon( bool state )
1593 {
1594     beacon = state;
1595 }
1596
1597 void
1598 FGControls::set_strobe( bool state )
1599 {
1600     strobe = state;
1601 }
1602
1603 void
1604 FGControls::set_panel_norm( double intensity )
1605 {
1606     panel_norm = intensity;
1607     SG_CLAMP_RANGE<double>( panel_norm, 0.0, 1.0 );
1608 }
1609
1610 void
1611 FGControls::move_panel_norm( double amt )
1612 {
1613     panel_norm += amt;
1614     SG_CLAMP_RANGE<double>( panel_norm, 0.0, 1.0 );
1615 }
1616
1617 void
1618 FGControls::set_instruments_norm( double intensity )
1619 {
1620     instruments_norm = intensity;
1621     SG_CLAMP_RANGE<double>( instruments_norm, 0.0, 1.0 );
1622 }
1623
1624 void
1625 FGControls::move_instruments_norm( double amt )
1626 {
1627     instruments_norm += amt;
1628     SG_CLAMP_RANGE<double>( instruments_norm, 0.0, 1.0 );
1629 }
1630
1631 void
1632 FGControls::set_dome_norm( double intensity )
1633 {
1634     dome_norm = intensity;
1635     SG_CLAMP_RANGE<double>( dome_norm, 0.0, 1.0 );
1636 }
1637
1638 void
1639 FGControls::move_dome_norm( double amt )
1640 {
1641     dome_norm += amt;
1642     SG_CLAMP_RANGE<double>( dome_norm, 0.0, 1.0 );
1643 }
1644
1645 void
1646 FGControls::set_master_arm( bool val )
1647 {
1648     master_arm = val;
1649 }
1650
1651 void
1652 FGControls::set_station_select( int station )
1653 {
1654     station_select = station;
1655     SG_CLAMP_RANGE<int>( station_select, 0, MAX_STATIONS );
1656 }
1657
1658 void
1659 FGControls::set_release_ALL( bool val )
1660 {
1661     release_ALL = val;
1662 }
1663
1664 void
1665 FGControls::set_stick_size( int station, int size )
1666 {
1667     if ( station == ALL_STATIONS ) {
1668         for ( int i = 0; i < MAX_STATIONS; i++ ) {
1669             stick_size[i] = size;
1670             SG_CLAMP_RANGE<int>( stick_size[i], 1, 20 );
1671         }
1672     } else {
1673         if ( (station >= 0) && (station < MAX_STATIONS) ) {
1674             stick_size[station] = size;
1675             SG_CLAMP_RANGE<int>( stick_size[station], 1, 20 );
1676         }
1677     }
1678 }
1679
1680 void
1681 FGControls::set_release_stick( int station, bool val )
1682 {
1683     if ( station == ALL_STATIONS ) {
1684         for ( int i = 0; i < MAX_STATIONS; i++ ) {
1685             release_stick[i] = val;
1686         }
1687     } else {
1688         if ( (station >= 0) && (station < MAX_STATIONS) ) {
1689             release_stick[station] = val;
1690         }
1691     }
1692 }
1693
1694 void
1695 FGControls::set_release_all( int station, bool val )
1696 {
1697     if ( station == ALL_STATIONS ) {
1698         for ( int i = 0; i < MAX_STATIONS; i++ ) {
1699             release_all[i] = val;
1700         }
1701     } else {
1702         if ( (station >= 0) && (station < MAX_STATIONS) ) {
1703             release_all[station] = val;
1704         }
1705     }
1706 }
1707
1708 void
1709 FGControls::set_jettison_all( int station, bool val )
1710 {
1711     if ( station == ALL_STATIONS ) {
1712         for ( int i = 0; i < MAX_STATIONS; i++ ) {
1713             jettison_all[i] = val;
1714         }
1715     } else {
1716         if ( (station >= 0) && (station < MAX_STATIONS) ) {
1717             jettison_all[station] = val;
1718         }
1719     }
1720 }
1721
1722 void
1723 FGControls::set_vertical_adjust( double pos )
1724 {
1725     vertical_adjust = pos;
1726     SG_CLAMP_RANGE<double>( vertical_adjust, -1.0, 1.0 );
1727 }
1728
1729 void
1730 FGControls::move_vertical_adjust( double amt )
1731 {
1732     vertical_adjust += amt;
1733     SG_CLAMP_RANGE<double>( vertical_adjust, -1.0, 1.0 );
1734 }
1735
1736 void
1737 FGControls::set_fore_aft_adjust( double pos )
1738 {
1739     fore_aft_adjust = pos;
1740     SG_CLAMP_RANGE<double>( fore_aft_adjust, -1.0, 1.0 );
1741 }
1742
1743 void
1744 FGControls::move_fore_aft_adjust( double amt )
1745 {
1746     fore_aft_adjust += amt;
1747     SG_CLAMP_RANGE<double>( fore_aft_adjust, -1.0, 1.0 );
1748 }
1749
1750 void
1751 FGControls::set_ejection_seat( int which_seat, bool val )
1752 {
1753     if ( which_seat == ALL_EJECTION_SEATS ) {
1754         for ( int i = 0; i < MAX_EJECTION_SEATS; i++ ) {
1755             eject[i] = val;
1756         }
1757     } else {
1758         if ( (which_seat >= 0) && (which_seat <= MAX_EJECTION_SEATS) ) {
1759             if ( eseat_status[which_seat] == SEAT_SAFED ||
1760                 eseat_status[which_seat] == SEAT_FAIL )
1761             {
1762                 // we can never eject if SEAT_SAFED or SEAT_FAIL
1763                 val = false;
1764             }
1765
1766             eject[which_seat] = val;
1767         }
1768     }
1769 }
1770
1771 void
1772 FGControls::set_eseat_status( int which_seat, int val )
1773 {
1774     if ( which_seat == ALL_EJECTION_SEATS ) {
1775         for ( int i = 0; i < MAX_EJECTION_SEATS; i++ ) {
1776             eseat_status[i] = val;
1777         }
1778     } else {
1779         if ( (which_seat >=0) && (which_seat <= MAX_EJECTION_SEATS) ) {
1780             eseat_status[which_seat] = val;
1781         }
1782     }
1783 }
1784
1785 void
1786 FGControls::set_cmd_selector_valve( int val )
1787 {
1788     cmd_selector_valve = val;
1789 }
1790
1791
1792 void
1793 FGControls::set_off_start_run( int pos )
1794 {
1795     off_start_run = pos;
1796     SG_CLAMP_RANGE<int>( off_start_run, 0, 3 );
1797 }
1798
1799 void
1800 FGControls::set_APU_fire_switch( bool val )
1801 {
1802     APU_fire_switch = val;
1803 }
1804
1805 void
1806 FGControls::set_autothrottle_arm( bool val )
1807 {
1808     autothrottle_arm = val;
1809 }
1810
1811 void
1812 FGControls::set_autothrottle_engage( bool val )
1813 {
1814     autothrottle_engage = val;
1815 }
1816
1817 void
1818 FGControls::set_heading_select( double heading )
1819 {
1820     heading_select = heading;
1821     SG_CLAMP_RANGE<double>( heading_select, 0.0, 360.0 );
1822 }
1823
1824 void
1825 FGControls::move_heading_select( double amt )
1826 {
1827     heading_select += amt;
1828     SG_CLAMP_RANGE<double>( heading_select, 0.0, 360.0 );
1829 }
1830
1831 void
1832 FGControls::set_altitude_select( double altitude )
1833 {
1834     altitude_select = altitude;
1835     SG_CLAMP_RANGE<double>( altitude_select, -1000.0, 100000.0 );
1836 }
1837
1838 void
1839 FGControls::move_altitude_select( double amt )
1840 {
1841     altitude_select += amt;
1842     SG_CLAMP_RANGE<double>( altitude_select, -1000.0, 100000.0 );
1843 }
1844
1845 void
1846 FGControls::set_bank_angle_select( double angle )
1847 {
1848     bank_angle_select = angle;
1849     SG_CLAMP_RANGE<double>( bank_angle_select, 10.0, 30.0 );
1850 }
1851
1852 void
1853 FGControls::move_bank_angle_select( double amt )
1854 {
1855     bank_angle_select += amt;
1856     SG_CLAMP_RANGE<double>( bank_angle_select, 10.0, 30.0 );
1857 }
1858
1859 void
1860 FGControls::set_vertical_speed_select( double speed )
1861 {
1862     vertical_speed_select = speed;
1863     SG_CLAMP_RANGE<double>( vertical_speed_select, -3000.0, 4000.0 );
1864 }
1865
1866 void
1867 FGControls::move_vertical_speed_select( double amt )
1868 {
1869     vertical_speed_select += amt;
1870     SG_CLAMP_RANGE<double>( vertical_speed_select, -3000.0, 4000.0 );
1871 }
1872
1873 void
1874 FGControls::set_speed_select( double speed )
1875 {
1876     speed_select = speed;
1877     SG_CLAMP_RANGE<double>( speed_select, 60.0, 400.0 );
1878 }
1879
1880 void
1881 FGControls::move_speed_select( double amt )
1882 {
1883     speed_select += amt;
1884     SG_CLAMP_RANGE<double>( speed_select, 60.0, 400.0 );
1885 }
1886
1887 void
1888 FGControls::set_mach_select( double mach )
1889 {
1890     mach_select = mach;
1891     SG_CLAMP_RANGE<double>( mach_select, 0.4, 4.0 );
1892 }
1893
1894 void
1895 FGControls::move_mach_select( double amt )
1896 {
1897     mach_select += amt;
1898     SG_CLAMP_RANGE<double>( mach_select, 0.4, 4.0 );
1899 }
1900
1901 void
1902 FGControls::set_vertical_mode( int mode )
1903 {
1904     vertical_mode = mode;
1905     SG_CLAMP_RANGE<int>( vertical_mode, 0, 4 );
1906 }
1907
1908 void
1909 FGControls::set_lateral_mode( int mode )
1910 {
1911     lateral_mode = mode;
1912     SG_CLAMP_RANGE<int>( lateral_mode, 0, 4 );
1913 }
1914
1915 void
1916 FGControls::set_autopilot_engage( int ap, bool val )
1917 {
1918     if ( ap == ALL_AUTOPILOTS ) {
1919         for ( int i = 0; i < MAX_AUTOPILOTS; i++ ) {
1920             autopilot_engage[i] = val;
1921         }
1922     } else {
1923         if ( (ap >= 0) && (ap < MAX_AUTOPILOTS) ) {
1924             autopilot_engage[ap] = val;
1925         }
1926     }
1927 }