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