src/Autopilot/Makefile \
src/Cockpit/Makefile \
src/Cockpit/built_in/Makefile \
- src/Controls/Makefile \
src/Environment/Makefile \
src/FDM/Balloon/Makefile \
src/FDM/ExternalNet/Makefile \
src/MultiPlayer/Makefile \
src/Navaids/Makefile \
src/Network/Makefile \
- src/Objects/Makefile \
- src/Replay/Makefile \
src/Scenery/Makefile \
src/Scripting/Makefile \
src/Sound/Makefile \
noinst_LIBRARIES = libAircraft.a
-libAircraft_a_SOURCES = aircraft.cxx aircraft.hxx
+libAircraft_a_SOURCES = \
+ aircraft.cxx aircraft.hxx \
+ controls.cxx controls.hxx \
+ replay.cxx replay.hxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
#include <FDM/flight.hxx>
-#include <Controls/controls.hxx>
#include <Main/fg_init.hxx>
+#include "controls.hxx"
+
// Define a structure containing all the parameters for an aircraft
typedef struct{
--- /dev/null
+// controls.cxx -- defines a standard interface to all flight sim controls
+//
+// Written by Curtis Olson, started May 1997.
+//
+// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#include <simgear/compiler.h>
+#include <simgear/debug/logstream.hxx>
+#include <Main/fg_props.hxx>
+
+#include "controls.hxx"
+
+
+static const int MAX_NAME_LEN = 128;
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Inline utility methods.
+////////////////////////////////////////////////////////////////////////
+
+static inline void
+CLAMP(double *x, double min, double max )
+{
+ if ( *x < min ) { *x = min; }
+ if ( *x > max ) { *x = max; }
+}
+
+static inline void
+CLAMP(int *i, int min, int max )
+{
+ if ( *i < min ) { *i = min; }
+ if ( *i > max ) { *i = max; }
+}
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGControls.
+////////////////////////////////////////////////////////////////////////
+
+// Constructor
+FGControls::FGControls() :
+ aileron( 0.0 ),
+ aileron_trim( 0.0 ),
+ elevator( 0.0 ),
+ elevator_trim( 0.0 ),
+ rudder( 0.0 ),
+ rudder_trim( 0.0 ),
+ flaps( 0.0 ),
+ slats( 0.0 ),
+ BLC( false ),
+ spoilers( 0.0 ),
+ speedbrake( 0.0 ),
+ wing_sweep( 0.0 ),
+ wing_fold( false ),
+ drag_chute( false ),
+ throttle_idle( true ),
+ dump_valve( false ),
+ brake_left( 0.0 ),
+ brake_right( 0.0 ),
+ copilot_brake_left( 0.0 ),
+ copilot_brake_right( 0.0 ),
+ brake_parking( 0.0 ),
+ steering( 0.0 ),
+ gear_down( true ),
+ antiskid( true ),
+ tailhook( false ),
+ launchbar( false ),
+ catapult_launch_cmd( false ),
+ tailwheel_lock( true ),
+ wing_heat( false ),
+ pitot_heat( true ),
+ wiper( 0 ),
+ window_heat( false ),
+ battery_switch( true ),
+ external_power( false ),
+ APU_generator( false ),
+ APU_bleed( false ),
+ mode( 0 ),
+ dump( false ),
+ outflow_valve( 0.0 ),
+ taxi_light( false ),
+ logo_lights( false ),
+ nav_lights( false ),
+ beacon( false ),
+ strobe( false ),
+ panel_norm( 0.0 ),
+ instruments_norm( 0.0 ),
+ dome_norm( 0.0 ),
+ master_arm( false ),
+ station_select( 1 ),
+ release_ALL( false ),
+ vertical_adjust( 0.0 ),
+ fore_aft_adjust( 0.0 ),
+ off_start_run( 0 ),
+ APU_fire_switch( false ),
+ autothrottle_arm( false ),
+ autothrottle_engage( false ),
+ heading_select( 0.0 ),
+ altitude_select( 50000.0 ),
+ bank_angle_select( 30.0 ),
+ vertical_speed_select( 0.0 ),
+ speed_select( 0.0 ),
+ mach_select( 0.0 ),
+ vertical_mode( 0 ),
+ lateral_mode( 0 )
+{
+}
+
+
+void FGControls::reset_all()
+{
+ set_aileron( 0.0 );
+ set_aileron_trim( 0.0 );
+ set_elevator( 0.0 );
+ set_elevator_trim( 0.0 );
+ set_rudder( 0.0 );
+ set_rudder_trim( 0.0 );
+ BLC = false;
+ set_spoilers( 0.0 );
+ set_speedbrake( 0.0 );
+ set_wing_sweep( 0.0 );
+ wing_fold = false;
+ drag_chute = false;
+ set_throttle( ALL_ENGINES, 0.0 );
+ set_starter( ALL_ENGINES, false );
+ set_magnetos( ALL_ENGINES, 0 );
+ set_fuel_pump( ALL_ENGINES, false );
+ set_fire_switch( ALL_ENGINES, false );
+ set_fire_bottle_discharge( ALL_ENGINES, false );
+ set_cutoff( ALL_ENGINES, true );
+ set_nitrous_injection( ALL_ENGINES, false );
+ set_cowl_flaps_norm( ALL_ENGINES, 1.0 );
+ set_feather( ALL_ENGINES, false );
+ set_ignition( ALL_ENGINES, false );
+ set_augmentation( ALL_ENGINES, false );
+ set_reverser( ALL_ENGINES, false );
+ set_water_injection( ALL_ENGINES, false );
+ set_condition( ALL_ENGINES, 1.0 );
+ throttle_idle = true;
+ set_fuel_selector( ALL_TANKS, true );
+ dump_valve = false;
+ steering = 0.0;
+ gear_down = true;
+ tailhook = false;
+ launchbar = false;
+ catapult_launch_cmd = false;
+ tailwheel_lock = true;
+ set_carb_heat( ALL_ENGINES, false );
+ set_inlet_heat( ALL_ENGINES, false );
+ wing_heat = false;
+ pitot_heat = true;
+ wiper = 0;
+ window_heat = false;
+ set_engine_pump( ALL_HYD_SYSTEMS, true );
+ set_electric_pump( ALL_HYD_SYSTEMS, true );
+ landing_lights = false;
+ turn_off_lights = false;
+ master_arm = false;
+ set_ejection_seat( ALL_EJECTION_SEATS, false );
+ set_eseat_status( ALL_EJECTION_SEATS, SEAT_SAFED );
+ set_cmd_selector_valve( CMD_SEL_NORM );
+ APU_fire_switch = false;
+ autothrottle_arm = false;
+ autothrottle_engage = false;
+ set_autopilot_engage( ALL_AUTOPILOTS, false );
+}
+
+
+// Destructor
+FGControls::~FGControls() {
+}
+
+
+void
+FGControls::init ()
+{
+ throttle_idle = true;
+ for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
+ throttle[engine] = 0.0;
+ mixture[engine] = 1.0;
+ fuel_pump[engine] = false;
+ prop_advance[engine] = 1.0;
+ magnetos[engine] = 0;
+ starter[engine] = false;
+ ignition[engine] = false;
+ fire_switch[engine] = false;
+ cutoff[engine] = true;
+ augmentation[engine] = false;
+ reverser[engine] = false;
+ water_injection[engine] = false;
+ nitrous_injection[engine] = false;
+ cowl_flaps_norm[engine] = 0.0;
+ condition[engine] = 1.0;
+ }
+
+ brake_left = brake_right
+ = copilot_brake_left = copilot_brake_right
+ = brake_parking = 0.0;
+ for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
+ alternate_extension[wheel] = false;
+ }
+
+ auto_coordination = fgGetNode("/sim/auto-coordination", true);
+}
+
+
+void
+FGControls::bind ()
+{
+ int index, i;
+
+ // flight controls
+ fgTie("/controls/flight/aileron", this,
+ &FGControls::get_aileron, &FGControls::set_aileron);
+ fgSetArchivable("/controls/flight/aileron");
+
+ fgTie("/controls/flight/aileron-trim", this,
+ &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
+ fgSetArchivable("/controls/flight/aileron-trim");
+
+ fgTie("/controls/flight/elevator", this,
+ &FGControls::get_elevator, &FGControls::set_elevator);
+ fgSetArchivable("/controls/flight/elevator");
+
+ fgTie("/controls/flight/elevator-trim", this,
+ &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
+ fgSetArchivable("/controls/flight/elevator-trim");
+
+ fgTie("/controls/flight/rudder", this,
+ &FGControls::get_rudder, &FGControls::set_rudder);
+ fgSetArchivable("/controls/flight/rudder");
+
+ fgTie("/controls/flight/rudder-trim", this,
+ &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
+ fgSetArchivable("/controls/flight/rudder-trim");
+
+ fgTie("/controls/flight/flaps", this,
+ &FGControls::get_flaps, &FGControls::set_flaps);
+ fgSetArchivable("/controls/flight/flaps");
+
+ fgTie("/controls/flight/slats", this,
+ &FGControls::get_slats, &FGControls::set_slats);
+ fgSetArchivable("/controls/flight/slats");
+
+ fgTie("/controls/flight/BLC", this,
+ &FGControls::get_BLC, &FGControls::set_BLC);
+ fgSetArchivable("/controls/flight/BLC");
+
+ fgTie("/controls/flight/spoilers", this,
+ &FGControls::get_spoilers, &FGControls::set_spoilers);
+ fgSetArchivable("/controls/flight/spoilers");
+
+ fgTie("/controls/flight/speedbrake", this,
+ &FGControls::get_speedbrake, &FGControls::set_speedbrake);
+ fgSetArchivable("/controls/flight/speedbrake");
+
+ fgTie("/controls/flight/wing-sweep", this,
+ &FGControls::get_wing_sweep, &FGControls::set_wing_sweep);
+ fgSetArchivable("/controls/flight/wing-sweep");
+
+ fgTie("/controls/flight/wing-fold", this,
+ &FGControls::get_wing_fold, &FGControls::set_wing_fold);
+ fgSetArchivable("/controls/flight/wing-fold");
+
+ fgTie("/controls/flight/drag-chute", this,
+ &FGControls::get_drag_chute, &FGControls::set_drag_chute);
+ fgSetArchivable("/controls/flight/drag-chute");
+
+ // engines
+ fgTie("/controls/engines/throttle_idle", this,
+ &FGControls::get_throttle_idle, &FGControls::set_throttle_idle);
+ fgSetArchivable("/controls/engines/throttle_idle");
+
+ for (index = 0; index < MAX_ENGINES; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/throttle", index);
+ fgTie(name, this, index,
+ &FGControls::get_throttle, &FGControls::set_throttle);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/starter", index);
+ fgTie(name, this, index,
+ &FGControls::get_starter, &FGControls::set_starter);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/fuel-pump", index);
+ fgTie(name, this, index,
+ &FGControls::get_fuel_pump, &FGControls::set_fuel_pump);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/fire-switch", index);
+ fgTie(name, this, index,
+ &FGControls::get_fire_switch, &FGControls::set_fire_switch);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/fire-bottle-discharge", index);
+ fgTie(name, this, index,
+ &FGControls::get_fire_bottle_discharge,
+ &FGControls::set_fire_bottle_discharge);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/cutoff", index);
+ fgTie(name, this, index,
+ &FGControls::get_cutoff, &FGControls::set_cutoff);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/mixture", index);
+ fgTie(name, this, index,
+ &FGControls::get_mixture, &FGControls::set_mixture);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/propeller-pitch", index);
+ fgTie(name, this, index,
+ &FGControls::get_prop_advance,
+ &FGControls::set_prop_advance);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/magnetos", index);
+ fgTie(name, this, index,
+ &FGControls::get_magnetos, &FGControls::set_magnetos);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/WEP", index);
+ fgTie(name, this, index,
+ &FGControls::get_nitrous_injection,
+ &FGControls::set_nitrous_injection);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/cowl-flaps-norm", index);
+ fgTie(name, this, index,
+ &FGControls::get_cowl_flaps_norm,
+ &FGControls::set_cowl_flaps_norm);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/propeller-feather", index);
+ fgTie(name, this, index,
+ &FGControls::get_feather, &FGControls::set_feather);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/ignition", index);
+ fgTie(name, this, index,
+ &FGControls::get_ignition, &FGControls::set_ignition);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/augmentation", index);
+ fgTie(name, this, index,
+ &FGControls::get_augmentation,
+ &FGControls::set_augmentation);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/reverser", index);
+ fgTie(name, this, index,
+ &FGControls::get_reverser, &FGControls::set_reverser);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/water-injection", index);
+ fgTie(name, this, index,
+ &FGControls::get_water_injection,
+ &FGControls::set_water_injection);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/condition", index);
+ fgTie(name, this, index,
+ &FGControls::get_condition, &FGControls::set_condition);
+ fgSetArchivable(name);
+ }
+
+ // fuel
+ fgTie("/controls/fuel/dump-valve", this,
+ &FGControls::get_dump_valve, &FGControls::set_dump_valve);
+ fgSetArchivable("/controls/fuel/dump-valve");
+
+ for (index = 0; index < MAX_TANKS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/fuel/tank[%d]/fuel_selector", index);
+ fgTie(name, this, index,
+ &FGControls::get_fuel_selector,
+ &FGControls::set_fuel_selector);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN, "/controls/fuel/tank[%d]/to_engine", index);
+ fgTie(name, this, index,
+ &FGControls::get_to_engine, &FGControls::set_to_engine);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN, "/controls/fuel/tank[%d]/to_tank", index);
+ fgTie(name, this, index,
+ &FGControls::get_to_tank, &FGControls::set_to_tank);
+ fgSetArchivable(name);
+
+ for (i = 0; i < MAX_BOOSTPUMPS; i++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/fuel/tank[%d]/boost-pump[%d]", index, i);
+ fgTie(name, this, index * 2 + i,
+ &FGControls::get_boost_pump,
+ &FGControls::set_boost_pump);
+ fgSetArchivable(name);
+ }
+ }
+
+ // gear
+ fgTie("/controls/gear/brake-left", this,
+ &FGControls::get_brake_left,
+ &FGControls::set_brake_left);
+ fgSetArchivable("/controls/gear/brake-left");
+
+ fgTie("/controls/gear/brake-right", this,
+ &FGControls::get_brake_right,
+ &FGControls::set_brake_right);
+ fgSetArchivable("/controls/gear/brake-right");
+
+ fgTie("/controls/gear/copilot-brake-left", this,
+ &FGControls::get_copilot_brake_left,
+ &FGControls::set_copilot_brake_left);
+ fgSetArchivable("/controls/gear/copilot-brake-left");
+
+ fgTie("/controls/gear/copilot-brake-right", this,
+ &FGControls::get_copilot_brake_right,
+ &FGControls::set_copilot_brake_right);
+ fgSetArchivable("/controls/gear/copilot-brake-right");
+
+ fgTie("/controls/gear/brake-parking", this,
+ &FGControls::get_brake_parking,
+ &FGControls::set_brake_parking);
+ fgSetArchivable("/controls/gear/brake-parking");
+
+ fgTie("/controls/gear/steering", this,
+ &FGControls::get_steering, &FGControls::set_steering);
+ fgSetArchivable("/controls/gear/steering");
+
+ fgTie("/controls/gear/gear-down", this,
+ &FGControls::get_gear_down, &FGControls::set_gear_down);
+ fgSetArchivable("/controls/gear/gear-down");
+
+ fgTie("/controls/gear/antiskid", this,
+ &FGControls::get_antiskid, &FGControls::set_antiskid);
+ fgSetArchivable("/controls/gear/antiskid");
+
+ fgTie("/controls/gear/tailhook", this,
+ &FGControls::get_tailhook, &FGControls::set_tailhook);
+ fgSetArchivable("/controls/gear/tailhook");
+
+ fgTie("/controls/gear/launchbar", this,
+ &FGControls::get_launchbar, &FGControls::set_launchbar);
+ fgSetArchivable("/controls/gear/launchbar");
+
+ fgTie("/controls/gear/catapult-launch-cmd", this,
+ &FGControls::get_catapult_launch_cmd, &FGControls::set_catapult_launch_cmd);
+ fgSetArchivable("/controls/gear/catapult-launch-cmd");
+
+ fgTie("/controls/gear/tailwheel-lock", this,
+ &FGControls::get_tailwheel_lock,
+ &FGControls::set_tailwheel_lock);
+ fgSetArchivable("/controls/gear/tailwheel-lock");
+
+ for (index = 0; index < MAX_WHEELS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/gear/wheel[%d]/alternate-extension", index);
+ fgTie(name, this, index,
+ &FGControls::get_alternate_extension,
+ &FGControls::set_alternate_extension);
+ fgSetArchivable(name);
+ }
+
+ // anti-ice
+ fgTie("/controls/anti-ice/wing-heat", this,
+ &FGControls::get_wing_heat, &FGControls::set_wing_heat);
+ fgSetArchivable("/controls/anti-ice/wing-heat");
+
+ fgTie("/controls/anti-ice/pitot-heat", this,
+ &FGControls::get_pitot_heat, &FGControls::set_pitot_heat);
+ fgSetArchivable("/controls/anti-ice/pitot-heat");
+
+ fgTie("/controls/anti-ice/wiper", this,
+ &FGControls::get_wiper, &FGControls::set_wiper);
+ fgSetArchivable("/controls/anti-ice/wiper");
+
+ fgTie("/controls/anti-ice/window-heat", this,
+ &FGControls::get_window_heat, &FGControls::set_window_heat);
+ fgSetArchivable("/controls/anti-ice/window-heat");
+
+ for (index = 0; index < MAX_ENGINES; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/anti-ice/engine[%d]/carb-heat", index);
+ fgTie(name, this, index,
+ &FGControls::get_carb_heat, &FGControls::set_carb_heat);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/anti-ice/engine[%d]/inlet-heat", index);
+ fgTie(name, this, index,
+ &FGControls::get_inlet_heat, &FGControls::set_inlet_heat);
+ fgSetArchivable(name);
+ }
+
+ // hydraulics
+ for (index = 0; index < MAX_HYD_SYSTEMS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/hydraulic/system[%d]/engine-pump", index);
+ fgTie(name, this, index,
+ &FGControls::get_engine_pump, &FGControls::set_engine_pump);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/hydraulic/system[%d]/electric-pump", index);
+ fgTie(name, this, index,
+ &FGControls::get_electric_pump,
+ &FGControls::set_electric_pump);
+ fgSetArchivable(name);
+ }
+
+ // electric
+ fgTie("/controls/electric/battery-switch", this,
+ &FGControls::get_battery_switch,
+ &FGControls::set_battery_switch);
+ fgSetArchivable("/controls/electric/battery-switch");
+
+ fgTie("/controls/electric/external-power", this,
+ &FGControls::get_external_power,
+ &FGControls::set_external_power);
+ fgSetArchivable("/controls/electric/external-power");
+
+ fgTie("/controls/electric/APU-generator", this,
+ &FGControls::get_APU_generator,
+ &FGControls::set_APU_generator);
+ fgSetArchivable("/controls/electric/APU-generator");
+
+ for (index = 0; index < MAX_ENGINES; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/electric/engine[%d]/generator", index);
+ fgTie(name, this, index,
+ &FGControls::get_generator_breaker,
+ &FGControls::set_generator_breaker);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/electric/engine[%d]/bus-tie", index);
+ fgTie(name, this, index,
+ &FGControls::get_bus_tie,
+ &FGControls::set_bus_tie);
+ fgSetArchivable(name);
+ }
+
+ // pneumatic
+ fgTie("/controls/pneumatic/APU-bleed", this,
+ &FGControls::get_APU_bleed,
+ &FGControls::set_APU_bleed);
+ fgSetArchivable("/controls/pneumatic/APU-bleed");
+
+ for (index = 0; index < MAX_ENGINES; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/pneumatic/engine[%d]/bleed", index);
+ fgTie(name, this, index,
+ &FGControls::get_engine_bleed,
+ &FGControls::set_engine_bleed);
+ fgSetArchivable(name);
+ }
+
+ // pressurization
+ fgTie("/controls/pressurization/mode", this,
+ &FGControls::get_mode, &FGControls::set_mode);
+ fgSetArchivable("/controls/pressurization/mode");
+
+ fgTie("/controls/pressurization/dump", this,
+ &FGControls::get_dump, &FGControls::set_dump);
+ fgSetArchivable("/controls/pressurization/dump");
+
+ fgTie("/controls/pressurization/outflow-valve", this,
+ &FGControls::get_outflow_valve,
+ &FGControls::set_outflow_valve);
+ fgSetArchivable("/controls/pressurization/outflow-valve");
+
+ for (index = 0; index < MAX_PACKS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/pressurization/pack[%d]/pack-on", index);
+ fgTie(name, this, index,
+ &FGControls::get_pack_on, &FGControls::set_pack_on);
+ fgSetArchivable(name);
+ }
+
+ // lights
+ fgTie("/controls/lighting/landing-lights", this,
+ &FGControls::get_landing_lights,
+ &FGControls::set_landing_lights);
+ fgSetArchivable("/controls/lighting/landing-lights");
+
+ fgTie("/controls/lighting/turn-off-lights", this,
+ &FGControls::get_turn_off_lights,
+ &FGControls::set_turn_off_lights);
+ fgSetArchivable("/controls/lighting/turn-off-lights");
+
+ fgTie("/controls/lighting/taxi-light", this,
+ &FGControls::get_taxi_light, &FGControls::set_taxi_light);
+ fgSetArchivable("/controls/lighting/taxi-light");
+
+ fgTie("/controls/lighting/logo-lights", this,
+ &FGControls::get_logo_lights, &FGControls::set_logo_lights);
+ fgSetArchivable("/controls/lighting/logo-lights");
+
+ fgTie("/controls/lighting/nav-lights", this,
+ &FGControls::get_nav_lights, &FGControls::set_nav_lights);
+ fgSetArchivable("/controls/lighting/nav-lights");
+
+ fgTie("/controls/lighting/beacon", this,
+ &FGControls::get_beacon, &FGControls::set_beacon);
+ fgSetArchivable("/controls/lighting/beacon");
+
+ fgTie("/controls/lighting/strobe", this,
+ &FGControls::get_strobe, &FGControls::set_strobe);
+ fgSetArchivable("/controls/lighting/strobe");
+
+ fgTie("/controls/lighting/panel-norm", this,
+ &FGControls::get_panel_norm, &FGControls::set_panel_norm);
+ fgSetArchivable("/controls/lighting/panel-norm");
+
+ fgTie("/controls/lighting/instruments-norm", this,
+ &FGControls::get_instruments_norm,
+ &FGControls::set_instruments_norm);
+ fgSetArchivable("/controls/lighting/instruments-norm");
+
+ fgTie("/controls/lighting/dome-norm", this,
+ &FGControls::get_dome_norm, &FGControls::set_dome_norm);
+ fgSetArchivable("/controls/lighting/dome-norm");
+
+ // armament
+ fgTie("/controls/armament/master-arm", this,
+ &FGControls::get_master_arm, &FGControls::set_master_arm);
+ fgSetArchivable("/controls/armament/master-arm");
+
+ fgTie("/controls/armament/station-select", this,
+ &FGControls::get_station_select,
+ &FGControls::set_station_select);
+ fgSetArchivable("/controls/armament/station-select");
+
+ fgTie("/controls/armament/release-all", this,
+ &FGControls::get_release_ALL,
+ &FGControls::set_release_ALL);
+ fgSetArchivable("/controls/armament/release-all");
+
+ for (index = 0; index < MAX_STATIONS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/armament/station[%d]/stick-size", index);
+ fgTie(name, this, index,
+ &FGControls::get_stick_size, &FGControls::set_stick_size);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/armament/station[%d]/release-stick", index);
+ fgTie(name, this, index,
+ &FGControls::get_release_stick, &FGControls::set_release_stick);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/armament/station[%d]/release-all", index);
+ fgTie(name, this, index,
+ &FGControls::get_release_all, &FGControls::set_release_all);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/armament/station[%d]/jettison-all", index);
+ fgTie(name, this, index,
+ &FGControls::get_jettison_all, &FGControls::set_jettison_all);
+ fgSetArchivable(name);
+ }
+
+ // seat
+ fgTie("/controls/seat/vertical-adjust", this,
+ &FGControls::get_vertical_adjust,
+ &FGControls::set_vertical_adjust);
+ fgSetArchivable("/controls/seat/vertical-adjust");
+
+ fgTie("/controls/seat/fore-aft-adjust", this,
+ &FGControls::get_fore_aft_adjust,
+ &FGControls::set_fore_aft_adjust);
+ fgSetArchivable("/controls/seat/fore-aft-adjust");
+
+ for (index = 0; index < MAX_EJECTION_SEATS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/seat/eject[%d]/initiate", index);
+ fgTie(name, this, index,
+ &FGControls::get_ejection_seat,
+ &FGControls::set_ejection_seat);
+ fgSetArchivable(name);
+
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/seat/eject[%d]/status", index);
+
+ fgTie(name, this, index,
+ &FGControls::get_eseat_status,
+ &FGControls::set_eseat_status);
+
+ fgSetArchivable(name);
+ }
+
+ fgTie("/controls/seat/cmd_selector_valve", this,
+ &FGControls::get_cmd_selector_valve,
+ &FGControls::set_cmd_selector_valve);
+ fgSetArchivable("/controls/seat/eject/cmd_selector_valve");
+
+
+ // APU
+ fgTie("/controls/APU/off-start-run", this,
+ &FGControls::get_off_start_run,
+ &FGControls::set_off_start_run);
+ fgSetArchivable("/controls/APU/off-start-run");
+
+ fgTie("/controls/APU/fire-switch", this,
+ &FGControls::get_APU_fire_switch,
+ &FGControls::set_APU_fire_switch);
+ fgSetArchivable("/controls/APU/fire-switch");
+
+ // autoflight
+ for (index = 0; index < MAX_AUTOPILOTS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/autoflight/autopilot[%d]/engage", index);
+ fgTie(name, this, index,
+ &FGControls::get_autopilot_engage,
+ &FGControls::set_autopilot_engage);
+ fgSetArchivable(name);
+ }
+
+ fgTie("/controls/autoflight/autothrottle-arm", this,
+ &FGControls::get_autothrottle_arm,
+ &FGControls::set_autothrottle_arm);
+ fgSetArchivable("/controls/autoflight/autothrottle-arm");
+
+ fgTie("/controls/autoflight/autothrottle-engage", this,
+ &FGControls::get_autothrottle_engage,
+ &FGControls::set_autothrottle_engage);
+ fgSetArchivable("/controls/autoflight/autothrottle-engage");
+
+ fgTie("/controls/autoflight/heading-select", this,
+ &FGControls::get_heading_select,
+ &FGControls::set_heading_select);
+ fgSetArchivable("/controls/autoflight/heading-select");
+
+ fgTie("/controls/autoflight/altitude-select", this,
+ &FGControls::get_altitude_select,
+ &FGControls::set_altitude_select);
+ fgSetArchivable("/controls/autoflight/altitude-select");
+
+ fgTie("/controls/autoflight/bank-angle-select", this,
+ &FGControls::get_bank_angle_select,
+ &FGControls::set_bank_angle_select);
+ fgSetArchivable("/controls/autoflight/bank-angle-select");
+
+ fgTie("/controls/autoflight/vertical-speed-select", this,
+ &FGControls::get_vertical_speed_select,
+ &FGControls::set_vertical_speed_select);
+ fgSetArchivable("/controls/autoflight/vertical-speed-select");
+
+ fgTie("/controls/autoflight/speed-select", this,
+ &FGControls::get_speed_select,
+ &FGControls::set_speed_select);
+ fgSetArchivable("/controls/autoflight/speed-select");
+
+ fgTie("/controls/autoflight/mach-select", this,
+ &FGControls::get_mach_select,
+ &FGControls::set_mach_select);
+ fgSetArchivable("/controls/autoflight/mach-select");
+
+ fgTie("/controls/autoflight/vertical-mode", this,
+ &FGControls::get_vertical_mode,
+ &FGControls::set_vertical_mode);
+ fgSetArchivable("/controls/autoflight/vertical-mode");
+
+ fgTie("/controls/autoflight/lateral-mode", this,
+ &FGControls::get_lateral_mode,
+ &FGControls::set_lateral_mode);
+ fgSetArchivable("/controls/autoflight/lateral-mode");
+
+}
+
+void FGControls::unbind ()
+{
+ int index, i;
+ //Tie control properties.
+ fgUntie("/controls/flight/aileron");
+ fgUntie("/controls/flight/aileron-trim");
+ fgUntie("/controls/flight/elevator");
+ fgUntie("/controls/flight/elevator-trim");
+ fgUntie("/controls/flight/rudder");
+ fgUntie("/controls/flight/rudder-trim");
+ fgUntie("/controls/flight/flaps");
+ fgUntie("/controls/flight/slats");
+ fgUntie("/controls/flight/BLC");
+ fgUntie("/controls/flight/spoilers");
+ fgUntie("/controls/flight/speedbrake");
+ fgUntie("/controls/flight/wing-sweep");
+ fgUntie("/controls/flight/wing-fold");
+ fgUntie("/controls/flight/drag-chute");
+ for (index = 0; index < MAX_ENGINES; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/throttle", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/starter", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/fuel_pump", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/fire-switch", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/fire-bottle-discharge", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/throttle_idle", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/cutoff", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/mixture", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/propeller-pitch", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/magnetos", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/WEP", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/cowl-flaps-norm", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/propeller-feather", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/ignition", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/augmentation", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/reverser", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/water-injection", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/engines/engine[%d]/condition", index);
+ fgUntie(name);
+ }
+ fgUntie("/controls/fuel/dump-valve");
+ for (index = 0; index < MAX_TANKS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/fuel/tank[%d]/fuel_selector", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN, "/controls/fuel/tank[%d]/to_engine", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN, "/controls/fuel/tank[%d]/to_tank", index);
+ fgUntie(name);
+ for (i = 0; index < MAX_BOOSTPUMPS; i++) {
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/fuel/tank[%d]/boost-pump[%d]", index, i);
+ fgUntie(name);
+ }
+ }
+ fgUntie("/controls/gear/brake-left");
+ fgUntie("/controls/gear/brake-right");
+ fgUntie("/controls/gear/brake-parking");
+ fgUntie("/controls/gear/steering");
+ fgUntie("/controls/gear/gear_down");
+ fgUntie("/controls/gear/antiskid");
+ fgUntie("/controls/gear/tailhook");
+ fgUntie("/controls/gear/launchbar");
+ fgUntie("/controls/gear/catapult-launch-cmd");
+ fgUntie("/controls/gear/tailwheel-lock");
+ for (index = 0; index < MAX_WHEELS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/gear/wheel[%d]/alternate-extension", index);
+ fgUntie(name);
+ }
+ fgUntie("/controls/anti-ice/wing-heat");
+ fgUntie("/controls/anti-ice/pitot-heat");
+ fgUntie("/controls/anti-ice/wiper");
+ fgUntie("/controls/anti-ice/window-heat");
+ for (index = 0; index < MAX_ENGINES; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/anti-ice/engine[%d]/carb-heat", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/anti-ice/engine[%d]/inlet-heat", index);
+ fgUntie(name);
+ }
+ for (index = 0; index < MAX_HYD_SYSTEMS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/hydraulic/system[%d]/engine-pump", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/hydraulic/system[%d]/electric-pump", index);
+ fgUntie(name);
+ }
+ fgUntie("/controls/electric/battery-switch");
+ fgUntie("/controls/electric/external-power");
+ fgUntie("/controls/electric/APU-generator");
+ for (index = 0; index < MAX_ENGINES; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/electric/engine[%d]/generator", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/electric/engine[%d]/bus-tie", index);
+ fgUntie(name);
+ }
+ fgUntie("/controls/pneumatic/APU-bleed");
+ for (index = 0; index < MAX_ENGINES; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/pneumatic/engine[%d]/bleed", index);
+ fgUntie(name);
+ }
+ fgUntie("/controls/pressurization/mode");
+ fgUntie("/controls/pressurization/dump");
+ for (index = 0; index < MAX_PACKS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/pressurization/pack[%d]/pack-on", index);
+ fgUntie(name);
+ }
+ fgUntie("/controls/lighting/landing-lights");
+ fgUntie("/controls/lighting/turn-off-lights");
+ fgUntie("/controls/lighting/taxi-light");
+ fgUntie("/controls/lighting/logo-lights");
+ fgUntie("/controls/lighting/nav-lights");
+ fgUntie("/controls/lighting/beacon");
+ fgUntie("/controls/lighting/strobe");
+ fgUntie("/controls/lighting/panel-norm");
+ fgUntie("/controls/lighting/instruments-norm");
+ fgUntie("/controls/lighting/dome-norm");
+
+ fgUntie("/controls/armament/master-arm");
+ fgUntie("/controls/armament/station-select");
+ fgUntie("/controls/armament/release-all");
+ for (index = 0; index < MAX_STATIONS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/armament/station[%d]/stick-size", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/armament/station[%d]/release-stick", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/armament/station[%d]/release-all", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/armament/station[%d]/jettison-all", index);
+ fgUntie(name);
+ }
+
+ fgUntie("/controls/seat/vertical-adjust");
+ fgUntie("/controls/seat/fore-aft-adjust");
+ for (index = 0; index < MAX_EJECTION_SEATS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/seat/eject[%d]/initiate", index);
+ fgUntie(name);
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/seat/eject[%d]/status", index);
+ fgUntie(name);
+ }
+ fgUntie("/controls/seat/cmd_selector_valve");
+
+ fgUntie("/controls/APU/off-start-run");
+ fgUntie("/controls/APU/fire-switch");
+ for (index = 0; index < MAX_AUTOPILOTS; index++) {
+ char name[MAX_NAME_LEN];
+ snprintf(name, MAX_NAME_LEN,
+ "/controls/autoflight/autopilot[%d]/engage", index);
+ fgUntie(name);
+ }
+ fgUntie("/controls/autoflight/autothrottle-arm");
+ fgUntie("/controls/autoflight/autothrottle-engage");
+ fgUntie("/controls/autoflight/heading-select");
+ fgUntie("/controls/autoflight/altitude-select");
+ fgUntie("/controls/autoflight/bank-angle-select");
+ fgUntie("/controls/autoflight/vertical-speed-select");
+ fgUntie("/controls/autoflight/speed-select");
+ fgUntie("/controls/autoflight/mach-select");
+ fgUntie("/controls/autoflight/vertical-mode");
+ fgUntie("/controls/autoflight/lateral-mode");
+}
+
+
+void
+FGControls::update (double dt)
+{
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Setters and adjusters.
+////////////////////////////////////////////////////////////////////////
+
+void
+FGControls::set_aileron (double pos)
+{
+ aileron = pos;
+ CLAMP( &aileron, -1.0, 1.0 );
+
+ // check for autocoordination
+ if ( auto_coordination->getBoolValue() ) {
+ set_rudder( aileron / 2.0 );
+ }
+}
+
+void
+FGControls::move_aileron (double amt)
+{
+ aileron += amt;
+ CLAMP( &aileron, -1.0, 1.0 );
+
+ // check for autocoordination
+ if ( auto_coordination->getBoolValue() ) {
+ set_rudder( aileron / 2.0 );
+ }
+}
+
+void
+FGControls::set_aileron_trim( double pos )
+{
+ aileron_trim = pos;
+ CLAMP( &aileron_trim, -1.0, 1.0 );
+}
+
+void
+FGControls::move_aileron_trim( double amt )
+{
+ aileron_trim += amt;
+ CLAMP( &aileron_trim, -1.0, 1.0 );
+}
+
+void
+FGControls::set_elevator( double pos )
+{
+ elevator = pos;
+ CLAMP( &elevator, -1.0, 1.0 );
+}
+
+void
+FGControls::move_elevator( double amt )
+{
+ elevator += amt;
+ CLAMP( &elevator, -1.0, 1.0 );
+}
+
+void
+FGControls::set_elevator_trim( double pos )
+{
+ elevator_trim = pos;
+ CLAMP( &elevator_trim, -1.0, 1.0 );
+}
+
+void
+FGControls::move_elevator_trim( double amt )
+{
+ elevator_trim += amt;
+ CLAMP( &elevator_trim, -1.0, 1.0 );
+}
+
+void
+FGControls::set_rudder( double pos )
+{
+ rudder = pos;
+ CLAMP( &rudder, -1.0, 1.0 );
+}
+
+void
+FGControls::move_rudder( double amt )
+{
+ rudder += amt;
+ CLAMP( &rudder, -1.0, 1.0 );
+}
+
+void
+FGControls::set_rudder_trim( double pos )
+{
+ rudder_trim = pos;
+ CLAMP( &rudder_trim, -1.0, 1.0 );
+}
+
+void
+FGControls::move_rudder_trim( double amt )
+{
+ rudder_trim += amt;
+ CLAMP( &rudder_trim, -1.0, 1.0 );
+}
+
+void
+FGControls::set_flaps( double pos )
+{
+ flaps = pos;
+ CLAMP( &flaps, 0.0, 1.0 );
+}
+
+void
+FGControls::move_flaps( double amt )
+{
+ flaps += amt;
+ CLAMP( &flaps, 0.0, 1.0 );
+}
+
+void
+FGControls::set_slats( double pos )
+{
+ slats = pos;
+ CLAMP( &slats, 0.0, 1.0 );
+}
+
+void
+FGControls::move_slats( double amt )
+{
+ slats += amt;
+ CLAMP( &slats, 0.0, 1.0 );
+}
+
+void
+FGControls::set_BLC( bool val )
+{
+ BLC = val;
+}
+
+void
+FGControls::set_spoilers( double pos )
+{
+ spoilers = pos;
+ CLAMP( &spoilers, 0.0, 1.0 );
+}
+
+void
+FGControls::move_spoilers( double amt )
+{
+ spoilers += amt;
+ CLAMP( &spoilers, 0.0, 1.0 );
+}
+
+void
+FGControls::set_speedbrake( double pos )
+{
+ speedbrake = pos;
+ CLAMP( &speedbrake, 0.0, 1.0 );
+}
+
+void
+FGControls::move_speedbrake( double amt )
+{
+ speedbrake += amt;
+ CLAMP( &speedbrake, 0.0, 1.0 );
+}
+
+void
+FGControls::set_wing_sweep( double pos )
+{
+ wing_sweep = pos;
+ CLAMP( &wing_sweep, 0.0, 1.0 );
+}
+
+void
+FGControls::move_wing_sweep( double amt )
+{
+ wing_sweep += amt;
+ CLAMP( &wing_sweep, 0.0, 1.0 );
+}
+
+void
+FGControls::set_wing_fold( bool val )
+{
+ wing_fold = val;
+}
+
+void
+FGControls::set_drag_chute( bool val )
+{
+ drag_chute = val;
+}
+
+void
+FGControls::set_throttle_idle( bool val )
+{
+ throttle_idle = val;
+}
+
+void
+FGControls::set_throttle( int engine, double pos )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ throttle[i] = pos;
+ CLAMP( &throttle[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ throttle[engine] = pos;
+ CLAMP( &throttle[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::move_throttle( int engine, double amt )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ throttle[i] += amt;
+ CLAMP( &throttle[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ throttle[engine] += amt;
+ CLAMP( &throttle[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::set_starter( int engine, bool flag )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ starter[i] = flag;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ starter[engine] = flag;
+ }
+ }
+}
+
+void
+FGControls::set_fuel_pump( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ fuel_pump[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ fuel_pump[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_fire_switch( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ fire_switch[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ fire_switch[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_fire_bottle_discharge( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ fire_bottle_discharge[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ fire_bottle_discharge[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_cutoff( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ cutoff[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ cutoff[engine] = val;
+ }
+ }
+}
+
+
+void
+FGControls::set_mixture( int engine, double pos )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ mixture[i] = pos;
+ CLAMP( &mixture[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ mixture[engine] = pos;
+ CLAMP( &mixture[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::move_mixture( int engine, double amt )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ mixture[i] += amt;
+ CLAMP( &mixture[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ mixture[engine] += amt;
+ CLAMP( &mixture[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::set_prop_advance( int engine, double pos )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ prop_advance[i] = pos;
+ CLAMP( &prop_advance[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ prop_advance[engine] = pos;
+ CLAMP( &prop_advance[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::move_prop_advance( int engine, double amt )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ prop_advance[i] += amt;
+ CLAMP( &prop_advance[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ prop_advance[engine] += amt;
+ CLAMP( &prop_advance[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::set_magnetos( int engine, int pos )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ magnetos[i] = pos;
+ CLAMP( &magnetos[i], 0, 3 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ magnetos[engine] = pos;
+ CLAMP( &magnetos[engine], 0, 3 );
+ }
+ }
+}
+
+void
+FGControls::move_magnetos( int engine, int amt )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ magnetos[i] += amt;
+ CLAMP( &magnetos[i], 0, 3 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ magnetos[engine] += amt;
+ CLAMP( &magnetos[engine], 0, 3 );
+ }
+ }
+}
+
+void
+FGControls::set_nitrous_injection( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ nitrous_injection[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ nitrous_injection[engine] = val;
+ }
+ }
+}
+
+
+void
+FGControls::set_cowl_flaps_norm( int engine, double pos )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ cowl_flaps_norm[i] = pos;
+ CLAMP( &cowl_flaps_norm[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ cowl_flaps_norm[engine] = pos;
+ CLAMP( &cowl_flaps_norm[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::move_cowl_flaps_norm( int engine, double amt )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ cowl_flaps_norm[i] += amt;
+ CLAMP( &cowl_flaps_norm[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ cowl_flaps_norm[engine] += amt;
+ CLAMP( &cowl_flaps_norm[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::set_feather( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ feather[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ feather[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_ignition( int engine, int pos )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ ignition[i] = pos;
+ CLAMP( &ignition[i], 0, 3 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ ignition[engine] = pos;
+ CLAMP( &ignition[engine], 0, 3 );
+ }
+ }
+}
+
+void
+FGControls::set_augmentation( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ augmentation[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ augmentation[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_reverser( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ reverser[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ reverser[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_water_injection( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ water_injection[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ water_injection[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_condition( int engine, double val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ condition[i] = val;
+ CLAMP( &condition[i], 0.0, 1.0 );
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ condition[engine] = val;
+ CLAMP( &condition[engine], 0.0, 1.0 );
+ }
+ }
+}
+
+void
+FGControls::set_dump_valve( bool val )
+{
+ dump_valve = val;
+}
+
+
+void
+FGControls::set_fuel_selector( int tank, bool pos )
+{
+ if ( tank == ALL_TANKS ) {
+ for ( int i = 0; i < MAX_TANKS; i++ ) {
+ fuel_selector[i] = pos;
+ }
+ } else {
+ if ( (tank >= 0) && (tank < MAX_TANKS) ) {
+ fuel_selector[tank] = pos;
+ }
+ }
+}
+
+void
+FGControls::set_to_engine( int tank, int engine )
+{
+ if ( tank == ALL_TANKS ) {
+ for ( int i = 0; i < MAX_TANKS; i++ ) {
+ to_engine[i] = engine;
+ }
+ } else {
+ if ( (tank >= 0) && (tank < MAX_TANKS) ) {
+ to_engine[tank] = engine;
+ }
+ }
+}
+
+void
+FGControls::set_to_tank( int tank, int dest_tank )
+{
+ if ( tank == ALL_TANKS ) {
+ for ( int i = 0; i < MAX_TANKS; i++ ) {
+ to_tank[i] = dest_tank;
+ }
+ } else {
+ if ( (tank >= 0) && (tank < MAX_TANKS) ) {
+ to_tank[tank] = dest_tank;
+ }
+ }
+}
+
+void
+FGControls::set_boost_pump( int index, bool val )
+{
+ if ( index == -1 ) {
+ for ( int i = 0; i < (MAX_TANKS * MAX_BOOSTPUMPS); i++ ) {
+ boost_pump[i] = val;
+ }
+ } else {
+ if ( (index >= 0) && (index < (MAX_TANKS * MAX_BOOSTPUMPS)) ) {
+ boost_pump[index] = val;
+ }
+ }
+}
+
+
+void
+FGControls::set_brake_left( double pos )
+{
+ brake_left = pos;
+ CLAMP(&brake_left, 0.0, 1.0);
+}
+
+void
+FGControls::move_brake_left( double amt )
+{
+ brake_left += amt;
+ CLAMP( &brake_left, 0.0, 1.0 );
+}
+
+void
+FGControls::set_brake_right( double pos )
+{
+ brake_right = pos;
+ CLAMP(&brake_right, 0.0, 1.0);
+}
+
+void
+FGControls::move_brake_right( double amt )
+{
+ brake_right += amt;
+ CLAMP( &brake_right, 0.0, 1.0 );
+}
+
+void
+FGControls::set_copilot_brake_left( double pos )
+{
+ copilot_brake_left = pos;
+ CLAMP(&brake_left, 0.0, 1.0);
+}
+
+void
+FGControls::set_copilot_brake_right( double pos )
+{
+ copilot_brake_right = pos;
+ CLAMP(&brake_right, 0.0, 1.0);
+}
+
+void
+FGControls::set_brake_parking( double pos )
+{
+ brake_parking = pos;
+ CLAMP(&brake_parking, 0.0, 1.0);
+}
+
+void
+FGControls::set_steering( double angle )
+{
+ steering = angle;
+ CLAMP(&steering, -80.0, 80.0);
+}
+
+void
+FGControls::move_steering( double angle )
+{
+ steering += angle;
+ CLAMP(&steering, -80.0, 80.0);
+}
+
+void
+FGControls::set_gear_down( bool gear )
+{
+ gear_down = gear;
+}
+
+void
+FGControls::set_antiskid( bool state )
+{
+ antiskid = state;
+}
+
+void
+FGControls::set_tailhook( bool state )
+{
+ tailhook = state;
+}
+
+void
+FGControls::set_launchbar( bool state )
+{
+ launchbar = state;
+}
+
+void
+FGControls::set_catapult_launch_cmd( bool state )
+{
+ catapult_launch_cmd = state;
+}
+
+void
+FGControls::set_tailwheel_lock( bool state )
+{
+ tailwheel_lock = state;
+}
+
+
+void
+FGControls::set_alternate_extension( int wheel, bool val )
+{
+ if ( wheel == ALL_WHEELS ) {
+ for ( int i = 0; i < MAX_WHEELS; i++ ) {
+ alternate_extension[i] = val;
+ }
+ } else {
+ if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
+ alternate_extension[wheel] = val;
+ }
+ }
+}
+
+void
+FGControls::set_wing_heat( bool state )
+{
+ wing_heat = state;
+}
+
+void
+FGControls::set_pitot_heat( bool state )
+{
+ pitot_heat = state;
+}
+
+void
+FGControls::set_wiper( int state )
+{
+ wiper = state;
+}
+
+void
+FGControls::set_window_heat( bool state )
+{
+ window_heat = state;
+}
+
+void
+FGControls::set_carb_heat( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ carb_heat[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ carb_heat[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_inlet_heat( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ inlet_heat[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ inlet_heat[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_engine_pump( int system, bool val )
+{
+ if ( system == ALL_HYD_SYSTEMS ) {
+ for ( int i = 0; i < MAX_HYD_SYSTEMS; i++ ) {
+ engine_pump[i] = val;
+ }
+ } else {
+ if ( (system >= 0) && (system < MAX_HYD_SYSTEMS) ) {
+ engine_pump[system] = val;
+ }
+ }
+}
+
+void
+FGControls::set_electric_pump( int system, bool val )
+{
+ if ( system == ALL_HYD_SYSTEMS ) {
+ for ( int i = 0; i < MAX_HYD_SYSTEMS; i++ ) {
+ electric_pump[i] = val;
+ }
+ } else {
+ if ( (system >= 0) && (system < MAX_HYD_SYSTEMS) ) {
+ electric_pump[system] = val;
+ }
+ }
+}
+
+void
+FGControls::set_battery_switch( bool state )
+{
+ battery_switch = state;
+}
+
+void
+FGControls::set_external_power( bool state )
+{
+ external_power = state;
+}
+
+void
+FGControls::set_APU_generator( bool state )
+{
+ APU_generator = state;
+}
+
+void
+FGControls::set_generator_breaker( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ generator_breaker[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ generator_breaker[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_bus_tie( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ bus_tie[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ bus_tie[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_APU_bleed( bool state )
+{
+ APU_bleed = state;
+}
+
+void
+FGControls::set_engine_bleed( int engine, bool val )
+{
+ if ( engine == ALL_ENGINES ) {
+ for ( int i = 0; i < MAX_ENGINES; i++ ) {
+ engine_bleed[i] = val;
+ }
+ } else {
+ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
+ engine_bleed[engine] = val;
+ }
+ }
+}
+
+void
+FGControls::set_mode( int new_mode )
+{
+ mode = new_mode;
+}
+
+void
+FGControls::set_outflow_valve( double pos )
+{
+ outflow_valve = pos;
+ CLAMP( &outflow_valve, 0.0, 1.0 );
+}
+
+void
+FGControls::move_outflow_valve( double amt )
+{
+ outflow_valve += amt;
+ CLAMP( &outflow_valve, 0.0, 1.0 );
+}
+
+void
+FGControls::set_dump( bool state )
+{
+ dump = state;
+}
+
+void
+FGControls::set_pack_on( int pack, bool val )
+{
+ if ( pack == ALL_PACKS ) {
+ for ( int i = 0; i < MAX_PACKS; i++ ) {
+ pack_on[i] = val;
+ }
+ } else {
+ if ( (pack >= 0) && (pack < MAX_PACKS) ) {
+ pack_on[pack] = val;
+ }
+ }
+}
+
+void
+FGControls::set_landing_lights( bool state )
+{
+ landing_lights = state;
+}
+
+void
+FGControls::set_turn_off_lights( bool state )
+{
+ turn_off_lights = state;
+}
+
+void
+FGControls::set_taxi_light( bool state )
+{
+ taxi_light = state;
+}
+
+void
+FGControls::set_logo_lights( bool state )
+{
+ logo_lights = state;
+}
+
+void
+FGControls::set_nav_lights( bool state )
+{
+ nav_lights = state;
+}
+
+void
+FGControls::set_beacon( bool state )
+{
+ beacon = state;
+}
+
+void
+FGControls::set_strobe( bool state )
+{
+ strobe = state;
+}
+
+void
+FGControls::set_panel_norm( double intensity )
+{
+ panel_norm = intensity;
+ CLAMP( &panel_norm, 0.0, 1.0 );
+}
+
+void
+FGControls::move_panel_norm( double amt )
+{
+ panel_norm += amt;
+ CLAMP( &panel_norm, 0.0, 1.0 );
+}
+
+void
+FGControls::set_instruments_norm( double intensity )
+{
+ instruments_norm = intensity;
+ CLAMP( &instruments_norm, 0.0, 1.0 );
+}
+
+void
+FGControls::move_instruments_norm( double amt )
+{
+ instruments_norm += amt;
+ CLAMP( &instruments_norm, 0.0, 1.0 );
+}
+
+void
+FGControls::set_dome_norm( double intensity )
+{
+ dome_norm = intensity;
+ CLAMP( &dome_norm, 0.0, 1.0 );
+}
+
+void
+FGControls::move_dome_norm( double amt )
+{
+ dome_norm += amt;
+ CLAMP( &dome_norm, 0.0, 1.0 );
+}
+
+void
+FGControls::set_master_arm( bool val )
+{
+ master_arm = val;
+}
+
+void
+FGControls::set_station_select( int station )
+{
+ station_select = station;
+ CLAMP( &station_select, 0, MAX_STATIONS );
+}
+
+void
+FGControls::set_release_ALL( bool val )
+{
+ release_ALL = val;
+}
+
+void
+FGControls::set_stick_size( int station, int size )
+{
+ if ( station == ALL_STATIONS ) {
+ for ( int i = 0; i < MAX_STATIONS; i++ ) {
+ stick_size[i] = size;
+ CLAMP( &stick_size[i], 1, 20 );
+ }
+ } else {
+ if ( (station >= 0) && (station < MAX_STATIONS) ) {
+ stick_size[station] = size;
+ CLAMP( &stick_size[station], 1, 20 );
+ }
+ }
+}
+
+void
+FGControls::set_release_stick( int station, bool val )
+{
+ if ( station == ALL_STATIONS ) {
+ for ( int i = 0; i < MAX_STATIONS; i++ ) {
+ release_stick[i] = val;
+ }
+ } else {
+ if ( (station >= 0) && (station < MAX_STATIONS) ) {
+ release_stick[station] = val;
+ }
+ }
+}
+
+void
+FGControls::set_release_all( int station, bool val )
+{
+ if ( station == ALL_STATIONS ) {
+ for ( int i = 0; i < MAX_STATIONS; i++ ) {
+ release_all[i] = val;
+ }
+ } else {
+ if ( (station >= 0) && (station < MAX_STATIONS) ) {
+ release_all[station] = val;
+ }
+ }
+}
+
+void
+FGControls::set_jettison_all( int station, bool val )
+{
+ if ( station == ALL_STATIONS ) {
+ for ( int i = 0; i < MAX_STATIONS; i++ ) {
+ jettison_all[i] = val;
+ }
+ } else {
+ if ( (station >= 0) && (station < MAX_STATIONS) ) {
+ jettison_all[station] = val;
+ }
+ }
+}
+
+void
+FGControls::set_vertical_adjust( double pos )
+{
+ vertical_adjust = pos;
+ CLAMP( &vertical_adjust, -1.0, 1.0 );
+}
+
+void
+FGControls::move_vertical_adjust( double amt )
+{
+ vertical_adjust += amt;
+ CLAMP( &vertical_adjust, -1.0, 1.0 );
+}
+
+void
+FGControls::set_fore_aft_adjust( double pos )
+{
+ fore_aft_adjust = pos;
+ CLAMP( &fore_aft_adjust, -1.0, 1.0 );
+}
+
+void
+FGControls::move_fore_aft_adjust( double amt )
+{
+ fore_aft_adjust += amt;
+ CLAMP( &fore_aft_adjust, -1.0, 1.0 );
+}
+
+void
+FGControls::set_ejection_seat( int which_seat, bool val )
+{
+ if ( which_seat == ALL_EJECTION_SEATS ) {
+ for ( int i = 0; i < MAX_EJECTION_SEATS; i++ ) {
+ eject[i] = val;
+ }
+ } else {
+ if ( (which_seat >= 0) && (which_seat <= MAX_EJECTION_SEATS) ) {
+ if ( eseat_status[which_seat] == SEAT_SAFED ||
+ eseat_status[which_seat] == SEAT_FAIL )
+ {
+ // we can never eject if SEAT_SAFED or SEAT_FAIL
+ val = false;
+ }
+
+ eject[which_seat] = val;
+ }
+ }
+}
+
+void
+FGControls::set_eseat_status( int which_seat, int val )
+{
+ if ( which_seat == ALL_EJECTION_SEATS ) {
+ for ( int i = 0; i < MAX_EJECTION_SEATS; i++ ) {
+ eseat_status[i] = val;
+ }
+ } else {
+ if ( (which_seat >=0) && (which_seat <= MAX_EJECTION_SEATS) ) {
+ eseat_status[which_seat] = val;
+ }
+ }
+}
+
+void
+FGControls::set_cmd_selector_valve( int val )
+{
+ cmd_selector_valve = val;
+}
+
+
+void
+FGControls::set_off_start_run( int pos )
+{
+ off_start_run = pos;
+ CLAMP( &off_start_run, 0, 3 );
+}
+
+void
+FGControls::set_APU_fire_switch( bool val )
+{
+ APU_fire_switch = val;
+}
+
+void
+FGControls::set_autothrottle_arm( bool val )
+{
+ autothrottle_arm = val;
+}
+
+void
+FGControls::set_autothrottle_engage( bool val )
+{
+ autothrottle_engage = val;
+}
+
+void
+FGControls::set_heading_select( double heading )
+{
+ heading_select = heading;
+ CLAMP( &heading_select, 0.0, 360.0 );
+}
+
+void
+FGControls::move_heading_select( double amt )
+{
+ heading_select += amt;
+ CLAMP( &heading_select, 0.0, 360.0 );
+}
+
+void
+FGControls::set_altitude_select( double altitude )
+{
+ altitude_select = altitude;
+ CLAMP( &altitude_select, -1000.0, 100000.0 );
+}
+
+void
+FGControls::move_altitude_select( double amt )
+{
+ altitude_select += amt;
+ CLAMP( &altitude_select, -1000.0, 100000.0 );
+}
+
+void
+FGControls::set_bank_angle_select( double angle )
+{
+ bank_angle_select = angle;
+ CLAMP( &bank_angle_select, 10.0, 30.0 );
+}
+
+void
+FGControls::move_bank_angle_select( double amt )
+{
+ bank_angle_select += amt;
+ CLAMP( &bank_angle_select, 10.0, 30.0 );
+}
+
+void
+FGControls::set_vertical_speed_select( double speed )
+{
+ vertical_speed_select = speed;
+ CLAMP( &vertical_speed_select, -3000.0, 4000.0 );
+}
+
+void
+FGControls::move_vertical_speed_select( double amt )
+{
+ vertical_speed_select += amt;
+ CLAMP( &vertical_speed_select, -3000.0, 4000.0 );
+}
+
+void
+FGControls::set_speed_select( double speed )
+{
+ speed_select = speed;
+ CLAMP( &speed_select, 60.0, 400.0 );
+}
+
+void
+FGControls::move_speed_select( double amt )
+{
+ speed_select += amt;
+ CLAMP( &speed_select, 60.0, 400.0 );
+}
+
+void
+FGControls::set_mach_select( double mach )
+{
+ mach_select = mach;
+ CLAMP( &mach_select, 0.4, 4.0 );
+}
+
+void
+FGControls::move_mach_select( double amt )
+{
+ mach_select += amt;
+ CLAMP( &mach_select, 0.4, 4.0 );
+}
+
+void
+FGControls::set_vertical_mode( int mode )
+{
+ vertical_mode = mode;
+ CLAMP( &vertical_mode, 0, 4 );
+}
+
+void
+FGControls::set_lateral_mode( int mode )
+{
+ lateral_mode = mode;
+ CLAMP( &lateral_mode, 0, 4 );
+}
+
+void
+FGControls::set_autopilot_engage( int ap, bool val )
+{
+ if ( ap == ALL_AUTOPILOTS ) {
+ for ( int i = 0; i < MAX_AUTOPILOTS; i++ ) {
+ autopilot_engage[i] = val;
+ }
+ } else {
+ if ( (ap >= 0) && (ap < MAX_AUTOPILOTS) ) {
+ autopilot_engage[ap] = val;
+ }
+ }
+}
--- /dev/null
+// controls.hxx -- defines a standard interface to all flight sim controls
+//
+// Written by Curtis Olson, started May 1997.
+//
+// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifndef _CONTROLS_HXX
+#define _CONTROLS_HXX
+
+#include <simgear/props/props.hxx>
+#include <simgear/structure/subsystem_mgr.hxx>
+
+#include <Main/globals.hxx>
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+
+// Define a structure containing the control parameters
+
+class FGControls : public SGSubsystem
+{
+
+public:
+
+ enum {
+ ALL_ENGINES = -1,
+ MAX_ENGINES = 10
+ };
+
+ enum {
+ ALL_WHEELS = -1,
+ MAX_WHEELS = 3
+ };
+
+ enum {
+ ALL_TANKS = -1,
+ MAX_TANKS = 8
+ };
+
+ enum {
+ ALL_BOOSTPUMPS = -1,
+ MAX_BOOSTPUMPS = 2
+ };
+
+ enum {
+ ALL_HYD_SYSTEMS = -1,
+ MAX_HYD_SYSTEMS = 4
+ };
+
+ enum {
+ ALL_PACKS = -1,
+ MAX_PACKS = 4
+ };
+
+ enum {
+ ALL_LIGHTS = -1,
+ MAX_LIGHTS = 4
+ };
+
+ enum {
+ ALL_STATIONS = -1,
+ MAX_STATIONS = 12
+ };
+
+ enum {
+ ALL_AUTOPILOTS = -1,
+ MAX_AUTOPILOTS = 3
+ };
+
+ enum {
+ ALL_EJECTION_SEATS = -1,
+ MAX_EJECTION_SEATS = 10
+ };
+
+ enum {
+ SEAT_SAFED = -1,
+ SEAT_ARMED = 0,
+ SEAT_FAIL = 1
+ };
+
+ enum {
+ CMD_SEL_NORM = -1,
+ CMD_SEL_AFT = 0,
+ CMD_SEL_SOLO = 1
+ };
+
+private:
+ // controls/flight/
+ double aileron;
+ double aileron_trim;
+ double elevator;
+ double elevator_trim;
+ double rudder;
+ double rudder_trim;
+ double flaps;
+ double slats;
+ bool BLC; // Boundary Layer Control
+ double spoilers;
+ double speedbrake;
+ double wing_sweep;
+ bool wing_fold;
+ bool drag_chute;
+
+ // controls/engines/
+ bool throttle_idle;
+
+ // controls/engines/engine[n]/
+ double throttle[MAX_ENGINES];
+ bool starter[MAX_ENGINES];
+ bool fuel_pump[MAX_ENGINES];
+ bool fire_switch[MAX_ENGINES];
+ bool fire_bottle_discharge[MAX_ENGINES];
+ bool cutoff[MAX_ENGINES];
+ double mixture[MAX_ENGINES];
+ double prop_advance[MAX_ENGINES];
+ int magnetos[MAX_ENGINES];
+ bool nitrous_injection[MAX_ENGINES]; // War Emergency Power
+ double cowl_flaps_norm[MAX_ENGINES];
+ bool feather[MAX_ENGINES];
+ int ignition[MAX_ENGINES];
+ bool augmentation[MAX_ENGINES];
+ bool reverser[MAX_ENGINES];
+ bool water_injection[MAX_ENGINES];
+ double condition[MAX_ENGINES]; // turboprop speed select
+
+ // controls/fuel/
+ bool dump_valve;
+
+ // controls/fuel/tank[n]/
+ bool fuel_selector[MAX_TANKS];
+ int to_engine[MAX_TANKS];
+ int to_tank[MAX_TANKS];
+
+ // controls/fuel/tank[n]/pump[p]/
+ bool boost_pump[MAX_TANKS * MAX_BOOSTPUMPS];
+
+ // controls/gear/
+ double brake_left;
+ double brake_right;
+ double copilot_brake_left;
+ double copilot_brake_right;
+ double brake_parking;
+ double steering;
+ bool gear_down;
+ bool antiskid;
+ bool tailhook;
+ bool launchbar;
+ bool catapult_launch_cmd;
+ bool tailwheel_lock;
+
+ // controls/gear/wheel[n]/
+ bool alternate_extension[MAX_WHEELS];
+
+ // controls/anti-ice/
+ bool wing_heat;
+ bool pitot_heat;
+ int wiper;
+ bool window_heat;
+
+ // controls/anti-ice/engine[n]/
+ bool carb_heat[MAX_ENGINES];
+ bool inlet_heat[MAX_ENGINES];
+
+ // controls/hydraulic/system[n]/
+ bool engine_pump[MAX_HYD_SYSTEMS];
+ bool electric_pump[MAX_HYD_SYSTEMS];
+
+ // controls/electric/
+ bool battery_switch;
+ bool external_power;
+ bool APU_generator;
+
+ // controls/electric/engine[n]/
+ bool generator_breaker[MAX_ENGINES];
+ bool bus_tie[MAX_ENGINES];
+
+ // controls/pneumatic/
+ bool APU_bleed;
+
+ // controls/pneumatic/engine[n]/
+ bool engine_bleed[MAX_ENGINES];
+
+ // controls/pressurization/
+ int mode;
+ bool dump;
+ double outflow_valve;
+
+ // controls/pressurization/pack[n]/
+ bool pack_on[MAX_PACKS];
+
+ // controls/lighting/
+ bool landing_lights;
+ bool turn_off_lights;
+ bool taxi_light;
+ bool logo_lights;
+ bool nav_lights;
+ bool beacon;
+ bool strobe;
+ double panel_norm;
+ double instruments_norm;
+ double dome_norm;
+
+ // controls/armament/
+ bool master_arm;
+ int station_select;
+ bool release_ALL;
+
+ // controls/armament/station[n]/
+ int stick_size[MAX_STATIONS];
+ bool release_stick[MAX_STATIONS];
+ bool release_all[MAX_STATIONS];
+ bool jettison_all[MAX_STATIONS];
+
+ // controls/seat/
+ double vertical_adjust;
+ double fore_aft_adjust;
+ bool eject[MAX_EJECTION_SEATS];
+ int eseat_status[MAX_EJECTION_SEATS];
+ int cmd_selector_valve;
+
+ // controls/APU/
+ int off_start_run;
+ bool APU_fire_switch;
+
+ // controls/autoflight/autopilot[n]/
+ bool autopilot_engage[MAX_AUTOPILOTS];
+
+ // controls/autoflight/
+ bool autothrottle_arm;
+ bool autothrottle_engage;
+ double heading_select;
+ double altitude_select;
+ double bank_angle_select;
+ double vertical_speed_select;
+ double speed_select;
+ double mach_select;
+ int vertical_mode;
+ int lateral_mode;
+
+
+ SGPropertyNode * auto_coordination;
+
+public:
+
+ FGControls();
+ ~FGControls();
+
+ // Implementation of SGSubsystem.
+ void init ();
+ void bind ();
+ void unbind ();
+ void update (double dt);
+
+ // Reset function
+ void reset_all(void);
+
+ // Query functions
+ // controls/flight/
+ inline double get_aileron() const { return aileron; }
+ inline double get_aileron_trim() const { return aileron_trim; }
+ inline double get_elevator() const { return elevator; }
+ inline double get_elevator_trim() const { return elevator_trim; }
+ inline double get_rudder() const { return rudder; }
+ inline double get_rudder_trim() const { return rudder_trim; }
+ inline double get_flaps() const { return flaps; }
+ inline double get_slats() const { return slats; }
+ inline bool get_BLC() const { return BLC; }
+ inline double get_spoilers() const { return spoilers; }
+ inline double get_speedbrake() const { return speedbrake; }
+ inline double get_wing_sweep() const { return wing_sweep; }
+ inline bool get_wing_fold() const { return wing_fold; }
+ inline bool get_drag_chute() const { return drag_chute; }
+
+ // controls/engines/
+ inline bool get_throttle_idle() const { return throttle_idle; }
+
+ // controls/engines/engine[n]/
+ inline double get_throttle(int engine) const { return throttle[engine]; }
+ inline bool get_starter(int engine) const { return starter[engine]; }
+ inline bool get_fuel_pump(int engine) const { return fuel_pump[engine]; }
+ inline bool get_fire_switch(int engine) const { return fire_switch[engine]; }
+ inline bool get_fire_bottle_discharge(int engine) const {
+ return fire_bottle_discharge[engine];
+ }
+ inline bool get_cutoff(int engine) const { return cutoff[engine]; }
+ inline double get_mixture(int engine) const { return mixture[engine]; }
+ inline double get_prop_advance(int engine) const {
+ return prop_advance[engine];
+ }
+ inline int get_magnetos(int engine) const { return magnetos[engine]; }
+ inline bool get_nitrous_injection(int engine) const {
+ return nitrous_injection[engine];
+ }
+ inline double get_cowl_flaps_norm(int engine) const {
+ return cowl_flaps_norm[engine];
+ }
+ inline bool get_feather(int engine) const { return feather[engine]; }
+ inline int get_ignition(int engine) const { return ignition[engine]; }
+ inline bool get_augmentation(int engine) const { return augmentation[engine]; }
+ inline bool get_reverser(int engine) const { return reverser[engine]; }
+ inline bool get_water_injection(int engine) const {
+ return water_injection[engine];
+ }
+ inline double get_condition(int engine) const { return condition[engine]; }
+
+ // controls/fuel/
+ inline bool get_dump_valve() const { return dump_valve; }
+
+ // controls/fuel/tank[n]/
+ inline bool get_fuel_selector(int tank) const {
+ return fuel_selector[tank];
+ }
+ inline int get_to_engine(int tank) const { return to_engine[tank]; }
+ inline int get_to_tank(int tank) const { return to_tank[tank]; }
+
+ // controls/fuel/tank[n]/pump[p]/
+ inline bool get_boost_pump(int index) const {
+ return boost_pump[index];
+ }
+
+ // controls/gear/
+ inline double get_brake_left() const { return brake_left; }
+ inline double get_brake_right() const { return brake_right; }
+ inline double get_copilot_brake_left() const { return copilot_brake_left; }
+ inline double get_copilot_brake_right() const { return copilot_brake_right; }
+ inline double get_brake_parking() const { return brake_parking; }
+ inline double get_steering() const { return steering; }
+ inline bool get_gear_down() const { return gear_down; }
+ inline bool get_antiskid() const { return antiskid; }
+ inline bool get_tailhook() const { return tailhook; }
+ inline bool get_launchbar() const { return launchbar; }
+ inline bool get_catapult_launch_cmd() const { return catapult_launch_cmd; }
+ inline bool get_tailwheel_lock() const { return tailwheel_lock; }
+
+ // controls/gear/wheel[n]/
+ inline bool get_alternate_extension(int wheel) const {
+ return alternate_extension[wheel];
+ }
+
+ // controls/anti-ice/
+ inline bool get_wing_heat() const { return wing_heat; }
+ inline bool get_pitot_heat() const { return pitot_heat; }
+ inline int get_wiper() const { return wiper; }
+ inline bool get_window_heat() const { return window_heat; }
+
+ // controls/anti-ice/engine[n]/
+ inline bool get_carb_heat(int engine) const { return carb_heat[engine]; }
+ inline bool get_inlet_heat(int engine) const { return inlet_heat[engine]; }
+
+ // controls/hydraulic/system[n]/
+ inline bool get_engine_pump(int system) const { return engine_pump[system]; }
+ inline bool get_electric_pump(int system) const { return electric_pump[system]; }
+
+ // controls/electric/
+ inline bool get_battery_switch() const { return battery_switch; }
+ inline bool get_external_power() const { return external_power; }
+ inline bool get_APU_generator() const { return APU_generator; }
+
+ // controls/electric/engine[n]/
+ inline bool get_generator_breaker(int engine) const {
+ return generator_breaker[engine];
+ }
+ inline bool get_bus_tie(int engine) const { return bus_tie[engine]; }
+
+ // controls/pneumatic/
+ inline bool get_APU_bleed() const { return APU_bleed; }
+
+ // controls/pneumatic/engine[n]/
+ inline bool get_engine_bleed(int engine) const { return engine_bleed[engine]; }
+
+ // controls/pressurization/
+ inline int get_mode() const { return mode; }
+ inline double get_outflow_valve() const { return outflow_valve; }
+ inline bool get_dump() const { return dump; }
+
+ // controls/pressurization/pack[n]/
+ inline bool get_pack_on(int pack) const { return pack_on[pack]; }
+
+ // controls/lighting/
+ inline bool get_landing_lights() const { return landing_lights; }
+ inline bool get_turn_off_lights() const { return turn_off_lights; }
+ inline bool get_taxi_light() const { return taxi_light; }
+ inline bool get_logo_lights() const { return logo_lights; }
+ inline bool get_nav_lights() const { return nav_lights; }
+ inline bool get_beacon() const { return beacon; }
+ inline bool get_strobe() const { return strobe; }
+ inline double get_panel_norm() const { return panel_norm; }
+ inline double get_instruments_norm() const { return instruments_norm; }
+ inline double get_dome_norm() const { return dome_norm; }
+
+ // controls/armament/
+ inline bool get_master_arm() const { return master_arm; }
+ inline int get_station_select() const { return station_select; }
+ inline bool get_release_ALL() const { return release_ALL; }
+
+ // controls/armament/station[n]/
+ inline int get_stick_size(int station) const { return stick_size[station]; }
+ inline bool get_release_stick(int station) const { return release_stick[station]; }
+ inline bool get_release_all(int station) const { return release_all[station]; }
+ inline bool get_jettison_all(int station) const { return jettison_all[station]; }
+
+ // controls/seat/
+ inline double get_vertical_adjust() const { return vertical_adjust; }
+ inline double get_fore_aft_adjust() const { return fore_aft_adjust; }
+ inline bool get_ejection_seat( int which_seat ) const {
+ return eject[which_seat];
+ }
+ inline int get_eseat_status( int which_seat ) const {
+ return eseat_status[which_seat];
+ }
+ inline int get_cmd_selector_valve() const { return cmd_selector_valve; }
+
+
+ // controls/APU/
+ inline int get_off_start_run() const { return off_start_run; }
+ inline bool get_APU_fire_switch() const { return APU_fire_switch; }
+
+ // controls/autoflight/
+ inline bool get_autothrottle_arm() const { return autothrottle_arm; }
+ inline bool get_autothrottle_engage() const { return autothrottle_engage; }
+ inline double get_heading_select() const { return heading_select; }
+ inline double get_altitude_select() const { return altitude_select; }
+ inline double get_bank_angle_select() const { return bank_angle_select; }
+ inline double get_vertical_speed_select() const {
+ return vertical_speed_select;
+ }
+ inline double get_speed_select() const { return speed_select; }
+ inline double get_mach_select() const { return mach_select; }
+ inline int get_vertical_mode() const { return vertical_mode; }
+ inline int get_lateral_mode() const { return lateral_mode; }
+
+ // controls/autoflight/autopilot[n]/
+ inline bool get_autopilot_engage(int ap) const {
+ return autopilot_engage[ap];
+ }
+
+
+ // Update functions
+ // controls/flight/
+ void set_aileron( double pos );
+ void move_aileron( double amt );
+ void set_aileron_trim( double pos );
+ void move_aileron_trim( double amt );
+ void set_elevator( double pos );
+ void move_elevator( double amt );
+ void set_elevator_trim( double pos );
+ void move_elevator_trim( double amt );
+ void set_rudder( double pos );
+ void move_rudder( double amt );
+ void set_rudder_trim( double pos );
+ void move_rudder_trim( double amt );
+ void set_flaps( double pos );
+ void move_flaps( double amt );
+ void set_slats( double pos );
+ void move_slats( double amt );
+ void set_BLC( bool val );
+ void set_spoilers( double pos );
+ void move_spoilers( double amt );
+ void set_speedbrake( double pos );
+ void move_speedbrake( double amt );
+ void set_wing_sweep( double pos );
+ void move_wing_sweep( double amt );
+ void set_wing_fold( bool val );
+ void set_drag_chute( bool val );
+
+ // controls/engines/
+ void set_throttle_idle( bool val );
+
+ // controls/engines/engine[n]/
+ void set_throttle( int engine, double pos );
+ void move_throttle( int engine, double amt );
+ void set_starter( int engine, bool flag );
+ void set_fuel_pump( int engine, bool val );
+ void set_fire_switch( int engine, bool val );
+ void set_fire_bottle_discharge( int engine, bool val );
+ void set_cutoff( int engine, bool val );
+ void set_mixture( int engine, double pos );
+ void move_mixture( int engine, double amt );
+ void set_prop_advance( int engine, double pos );
+ void move_prop_advance( int engine, double amt );
+ void set_magnetos( int engine, int pos );
+ void move_magnetos( int engine, int amt );
+ void set_nitrous_injection( int engine, bool val );
+ void set_cowl_flaps_norm( int engine, double pos );
+ void move_cowl_flaps_norm( int engine, double amt );
+ void set_feather( int engine, bool val );
+ void set_ignition( int engine, int val );
+ void set_augmentation( int engine, bool val );
+ void set_reverser( int engine, bool val );
+ void set_water_injection( int engine, bool val );
+ void set_condition( int engine, double val );
+
+ // controls/fuel
+ void set_dump_valve( bool val );
+
+ // controls/fuel/tank[n]/
+ void set_fuel_selector( int tank, bool pos );
+ void set_to_engine( int tank, int engine );
+ void set_to_tank( int tank, int dest_tank );
+
+ // controls/fuel/tank[n]/pump[p]
+ void set_boost_pump( int index, bool val );
+
+ // controls/gear/
+ void set_brake_left( double pos );
+ void move_brake_left( double amt );
+ void set_brake_right( double pos );
+ void move_brake_right( double amt );
+ void set_copilot_brake_left( double pos );
+ void set_copilot_brake_right( double pos );
+ void set_brake_parking( double pos );
+ void set_steering( double pos );
+ void move_steering( double amt );
+ void set_gear_down( bool gear );
+ void set_antiskid( bool val );
+ void set_tailhook( bool val );
+ void set_launchbar( bool val );
+ void set_catapult_launch_cmd( bool val );
+ void set_tailwheel_lock( bool val );
+
+ // controls/gear/wheel[n]/
+ void set_alternate_extension( int wheel, bool val );
+
+ // controls/anti-ice/
+ void set_wing_heat( bool val );
+ void set_pitot_heat( bool val );
+ void set_wiper( int speed );
+ void set_window_heat( bool val );
+
+ // controls/anti-ice/engine[n]/
+ void set_carb_heat( int engine, bool val );
+ void set_inlet_heat( int engine, bool val );
+
+ // controls/hydraulic/system[n]/
+ void set_engine_pump( int system, bool val );
+ void set_electric_pump( int system, bool val );
+
+ // controls/electric/
+ void set_battery_switch( bool val );
+ void set_external_power( bool val );
+ void set_APU_generator( bool val );
+
+ // controls/electric/engine[n]/
+ void set_generator_breaker( int engine, bool val );
+ void set_bus_tie( int engine, bool val );
+
+ // controls/pneumatic/
+ void set_APU_bleed( bool val );
+
+ // controls/pneumatic/engine[n]/
+ void set_engine_bleed( int engine, bool val );
+
+ // controls/pressurization/
+ void set_mode( int mode );
+ void set_outflow_valve( double pos );
+ void move_outflow_valve( double amt );
+ void set_dump( bool val );
+
+ // controls/pressurization/pack[n]/
+ void set_pack_on( int pack, bool val );
+
+ // controls/lighting/
+ void set_landing_lights( bool val );
+ void set_turn_off_lights( bool val );
+ void set_taxi_light( bool val );
+ void set_logo_lights( bool val );
+ void set_nav_lights( bool val );
+ void set_beacon( bool val );
+ void set_strobe( bool val );
+ void set_panel_norm( double intensity );
+ void move_panel_norm( double amt );
+ void set_instruments_norm( double intensity );
+ void move_instruments_norm( double amt );
+ void set_dome_norm( double intensity );
+ void move_dome_norm( double amt );
+
+ // controls/armament/
+ void set_master_arm( bool val );
+ void set_station_select( int station );
+ void set_release_ALL( bool val );
+
+ // controls/armament/station[n]/
+ void set_stick_size( int station, int size );
+ void set_release_stick( int station, bool val );
+ void set_release_all( int station, bool val );
+ void set_jettison_all( int station, bool val );
+
+ // controls/seat/
+ void set_vertical_adjust( double pos );
+ void move_vertical_adjust( double amt );
+ void set_fore_aft_adjust( double pos );
+ void move_fore_aft_adjust( double amt );
+ void set_ejection_seat( int which_seat, bool val );
+ void set_eseat_status( int which_seat, int val );
+ void set_cmd_selector_valve( int val );
+
+ // controls/APU/
+ void set_off_start_run( int pos );
+ void set_APU_fire_switch( bool val );
+
+ // controls/autoflight/
+ void set_autothrottle_arm( bool val );
+ void set_autothrottle_engage( bool val );
+ void set_heading_select( double heading );
+ void move_heading_select( double amt );
+ void set_altitude_select( double altitude );
+ void move_altitude_select( double amt );
+ void set_bank_angle_select( double angle );
+ void move_bank_angle_select( double amt );
+ void set_vertical_speed_select( double vs );
+ void move_vertical_speed_select( double amt );
+ void set_speed_select( double speed );
+ void move_speed_select( double amt );
+ void set_mach_select( double mach );
+ void move_mach_select( double amt );
+ void set_vertical_mode( int mode );
+ void set_lateral_mode( int mode );
+
+ // controls/autoflight/autopilot[n]/
+ void set_autopilot_engage( int ap, bool val );
+
+};
+
+
+#endif // _CONTROLS_HXX
+
+
--- /dev/null
+// replay.cxx - a system to record and replay FlightGear flights
+//
+// Written by Curtis Olson, started Juley 2003.
+//
+// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#include <simgear/constants.h>
+
+#include <FDM/flight.hxx>
+#include <Main/fg_props.hxx>
+#include <Network/native_ctrls.hxx>
+#include <Network/native_fdm.hxx>
+#include <Network/net_ctrls.hxx>
+#include <Network/net_fdm.hxx>
+
+#include "replay.hxx"
+
+const double FGReplay::st_list_time = 60.0; // 60 secs of high res data
+const double FGReplay::mt_list_time = 600.0; // 10 mins of 1 fps data
+const double FGReplay::lt_list_time = 3600.0; // 1 hr of 10 spf data
+
+// short term sample rate is as every frame
+const double FGReplay::mt_dt = 0.5; // medium term sample rate (sec)
+const double FGReplay::lt_dt = 5.0; // long term sample rate (sec)
+
+/**
+ * Constructor
+ */
+
+FGReplay::FGReplay() {
+}
+
+
+/**
+ * Destructor
+ */
+
+FGReplay::~FGReplay() {
+ // no dynamically allocated memory to free
+}
+
+
+/**
+ * Initialize the data structures
+ */
+
+void FGReplay::init() {
+ sim_time = 0.0;
+ last_mt_time = 0.0;
+ last_lt_time = 0.0;
+
+ // Make sure all queues are flushed
+ while ( !short_term.empty() ) {
+ short_term.pop_front();
+ }
+ while ( !medium_term.empty() ) {
+ medium_term.pop_front();
+ }
+ while ( !medium_term.empty() ) {
+ medium_term.pop_front();
+ }
+}
+
+
+/**
+ * Bind to the property tree
+ */
+
+void FGReplay::bind() {
+ disable_replay = fgGetNode( "/sim/replay/disable", true );
+}
+
+
+/**
+ * Unbind from the property tree
+ */
+
+void FGReplay::unbind() {
+ // nothing to unbind
+}
+
+
+/**
+ * Update the saved data
+ */
+
+void FGReplay::update( double dt ) {
+ static SGPropertyNode *replay_master
+ = fgGetNode( "/sim/freeze/replay", true );
+
+ if( disable_replay->getBoolValue() ) {
+ if( sim_time != 0.0 ) {
+ // we were recording data
+ init();
+ }
+ return;
+ }
+
+ if ( replay_master->getBoolValue() ) {
+ // don't record the replay session
+ return;
+ }
+
+ sim_time += dt;
+
+ // build the replay record
+ FGNetFDM f;
+ FGProps2NetFDM( &f, false );
+
+ // sanity check, don't collect data if FDM data isn't good
+ if ( !cur_fdm_state->get_inited() ) {
+ return;
+ }
+
+ FGNetCtrls c;
+ FGProps2NetCtrls( &c, false, false );
+
+ FGReplayData r;
+ r.sim_time = sim_time;
+ r.ctrls = c;
+ r.fdm = f;
+
+ // update the short term list
+ short_term.push_back( r );
+
+ FGReplayData st_front = short_term.front();
+ if ( sim_time - st_front.sim_time > st_list_time ) {
+ while ( sim_time - st_front.sim_time > st_list_time ) {
+ st_front = short_term.front();
+ short_term.pop_front();
+ }
+
+ // update the medium term list
+ if ( sim_time - last_mt_time > mt_dt ) {
+ last_mt_time = sim_time;
+ medium_term.push_back( st_front );
+
+ FGReplayData mt_front = medium_term.front();
+ if ( sim_time - mt_front.sim_time > mt_list_time ) {
+ while ( sim_time - mt_front.sim_time > mt_list_time ) {
+ mt_front = medium_term.front();
+ medium_term.pop_front();
+ }
+
+ // update the long term list
+ if ( sim_time - last_lt_time > lt_dt ) {
+ last_lt_time = sim_time;
+ long_term.push_back( mt_front );
+
+ FGReplayData lt_front = long_term.front();
+ if ( sim_time - lt_front.sim_time > lt_list_time ) {
+ while ( sim_time - lt_front.sim_time > lt_list_time ) {
+ lt_front = long_term.front();
+ long_term.pop_front();
+ }
+ }
+ }
+ }
+ }
+ }
+
+#if 0
+ cout << "short term size = " << short_term.size()
+ << " time = " << sim_time - short_term.front().sim_time
+ << endl;
+ cout << "medium term size = " << medium_term.size()
+ << " time = " << sim_time - medium_term.front().sim_time
+ << endl;
+ cout << "long term size = " << long_term.size()
+ << " time = " << sim_time - long_term.front().sim_time
+ << endl;
+#endif
+}
+
+
+static double weight( double data1, double data2, double ratio,
+ bool rotational = false ) {
+ if ( rotational ) {
+ // special handling of rotational data
+ double tmp = data2 - data1;
+ if ( tmp > SGD_PI ) {
+ tmp -= SGD_2PI;
+ } else if ( tmp < -SGD_PI ) {
+ tmp += SGD_2PI;
+ }
+ return data1 + tmp * ratio;
+ } else {
+ // normal "linear" data
+ return data1 + ( data2 - data1 ) * ratio;
+ }
+}
+
+/**
+ * given two FGReplayData elements and a time, interpolate between them
+ */
+static void update_fdm( FGReplayData frame ) {
+ FGNetFDM2Props( &frame.fdm, false );
+ FGNetCtrls2Props( &frame.ctrls, false, false );
+}
+
+/**
+ * given two FGReplayData elements and a time, interpolate between them
+ */
+static FGReplayData interpolate( double time, FGReplayData f1, FGReplayData f2 )
+{
+ FGReplayData result = f1;
+
+ FGNetFDM fdm1 = f1.fdm;
+ FGNetFDM fdm2 = f2.fdm;
+
+ FGNetCtrls ctrls1 = f1.ctrls;
+ FGNetCtrls ctrls2 = f2.ctrls;
+
+ double ratio = (time - f1.sim_time) / (f2.sim_time - f1.sim_time);
+
+ // Interpolate FDM data
+
+ // Positions
+ result.fdm.longitude = weight( fdm1.longitude, fdm2.longitude, ratio );
+ result.fdm.latitude = weight( fdm1.latitude, fdm2.latitude, ratio );
+ result.fdm.altitude = weight( fdm1.altitude, fdm2.altitude, ratio );
+ result.fdm.agl = weight( fdm1.agl, fdm2.agl, ratio );
+ result.fdm.phi = weight( fdm1.phi, fdm2.phi, ratio, true );
+ result.fdm.theta = weight( fdm1.theta, fdm2.theta, ratio, true );
+ result.fdm.psi = weight( fdm1.psi, fdm2.psi, ratio, true );
+
+ // Velocities
+ result.fdm.phidot = weight( fdm1.phidot, fdm2.phidot, ratio, true );
+ result.fdm.thetadot = weight( fdm1.thetadot, fdm2.thetadot, ratio, true );
+ result.fdm.psidot = weight( fdm1.psidot, fdm2.psidot, ratio, true );
+ result.fdm.vcas = weight( fdm1.vcas, fdm2.vcas, ratio );
+ result.fdm.climb_rate = weight( fdm1.climb_rate, fdm2.climb_rate, ratio );
+ result.fdm.v_north = weight( fdm1.v_north, fdm2.v_north, ratio );
+ result.fdm.v_east = weight( fdm1.v_east, fdm2.v_east, ratio );
+ result.fdm.v_down = weight( fdm1.v_down, fdm2.v_down, ratio );
+
+ result.fdm.v_wind_body_north
+ = weight( fdm1.v_wind_body_north, fdm2.v_wind_body_north, ratio );
+ result.fdm.v_wind_body_east
+ = weight( fdm1.v_wind_body_east, fdm2.v_wind_body_east, ratio );
+ result.fdm.v_wind_body_down
+ = weight( fdm1.v_wind_body_down, fdm2.v_wind_body_down, ratio );
+
+ // Stall
+ result.fdm.stall_warning
+ = weight( fdm1.stall_warning, fdm2.stall_warning, ratio );
+
+ // Accelerations
+ result.fdm.A_X_pilot = weight( fdm1.A_X_pilot, fdm2.A_X_pilot, ratio );
+ result.fdm.A_Y_pilot = weight( fdm1.A_Y_pilot, fdm2.A_Y_pilot, ratio );
+ result.fdm.A_Z_pilot = weight( fdm1.A_Z_pilot, fdm2.A_Z_pilot, ratio );
+
+ unsigned int i;
+
+ // Engine status
+ for ( i = 0; i < fdm1.num_engines; ++i ) {
+ result.fdm.eng_state[i] = fdm1.eng_state[i];
+ result.fdm.rpm[i] = weight( fdm1.rpm[i], fdm2.rpm[i], ratio );
+ result.fdm.fuel_flow[i]
+ = weight( fdm1.fuel_flow[i], fdm2.fuel_flow[i], ratio );
+ result.fdm.egt[i] = weight( fdm1.egt[i], fdm2.egt[i], ratio );
+ result.fdm.cht[i] = weight( fdm1.cht[i], fdm2.cht[i], ratio );
+ result.fdm.mp_osi[i] = weight( fdm1.mp_osi[i], fdm2.mp_osi[i], ratio );
+ result.fdm.tit[i] = weight( fdm1.tit[i], fdm2.tit[i], ratio );
+ result.fdm.oil_temp[i]
+ = weight( fdm1.oil_temp[i], fdm2.oil_temp[i], ratio );
+ result.fdm.oil_px[i] = weight( fdm1.oil_px[i], fdm2.oil_px[i], ratio );
+ }
+
+ // Consumables
+ for ( i = 0; i < fdm1.num_tanks; ++i ) {
+ result.fdm.fuel_quantity[i]
+ = weight( fdm1.fuel_quantity[i], fdm2.fuel_quantity[i], ratio );
+ }
+
+ // Gear status
+ for ( i = 0; i < fdm1.num_wheels; ++i ) {
+ result.fdm.wow[i] = (int)(weight( fdm1.wow[i], fdm2.wow[i], ratio ));
+ result.fdm.gear_pos[i]
+ = weight( fdm1.gear_pos[i], fdm2.gear_pos[i], ratio );
+ result.fdm.gear_steer[i]
+ = weight( fdm1.gear_steer[i], fdm2.gear_steer[i], ratio );
+ result.fdm.gear_compression[i]
+ = weight( fdm1.gear_compression[i], fdm2.gear_compression[i],
+ ratio );
+ }
+
+ // Environment
+ result.fdm.cur_time = fdm1.cur_time;
+ result.fdm.warp = fdm1.warp;
+ result.fdm.visibility = weight( fdm1.visibility, fdm2.visibility, ratio );
+
+ // Control surface positions (normalized values)
+ result.fdm.elevator = weight( fdm1.elevator, fdm2.elevator, ratio );
+ result.fdm.left_flap = weight( fdm1.left_flap, fdm2.left_flap, ratio );
+ result.fdm.right_flap = weight( fdm1.right_flap, fdm2.right_flap, ratio );
+ result.fdm.left_aileron
+ = weight( fdm1.left_aileron, fdm2.left_aileron, ratio );
+ result.fdm.right_aileron
+ = weight( fdm1.right_aileron, fdm2.right_aileron, ratio );
+ result.fdm.rudder = weight( fdm1.rudder, fdm2.rudder, ratio );
+ result.fdm.speedbrake = weight( fdm1.speedbrake, fdm2.speedbrake, ratio );
+ result.fdm.spoilers = weight( fdm1.spoilers, fdm2.spoilers, ratio );
+
+ // Interpolate Control input data
+
+ // Aero controls
+ result.ctrls.aileron = weight( ctrls1.aileron, ctrls2.aileron, ratio );
+ result.ctrls.elevator = weight( ctrls1.elevator, ctrls2.elevator, ratio );
+ result.ctrls.rudder = weight( ctrls1.rudder, ctrls2.rudder, ratio );
+ result.ctrls.aileron_trim
+ = weight( ctrls1.aileron_trim, ctrls2.aileron_trim, ratio );
+ result.ctrls.elevator_trim
+ = weight( ctrls1.elevator_trim, ctrls2.elevator_trim, ratio );
+ result.ctrls.rudder_trim
+ = weight( ctrls1.rudder_trim, ctrls2.rudder_trim, ratio );
+ result.ctrls.flaps = weight( ctrls1.flaps, ctrls2.flaps, ratio );
+ result.ctrls.flaps_power = ctrls1.flaps_power;
+ result.ctrls.flap_motor_ok = ctrls1.flap_motor_ok;
+
+ // Engine controls
+ for ( i = 0; i < ctrls1.num_engines; ++i ) {
+ result.ctrls.master_bat[i] = ctrls1.master_bat[i];
+ result.ctrls.master_alt[i] = ctrls1.master_alt[i];
+ result.ctrls.magnetos[i] = ctrls1.magnetos[i];
+ result.ctrls.starter_power[i] = ctrls1.starter_power[i];
+ result.ctrls.throttle[i]
+ = weight( ctrls1.throttle[i], ctrls2.throttle[i], ratio );
+ result.ctrls.mixture[i]
+ = weight( ctrls1.mixture[i], ctrls2.mixture[i], ratio );
+ result.ctrls.fuel_pump_power[i] = ctrls1.fuel_pump_power[i];
+ result.ctrls.prop_advance[i]
+ = weight( ctrls1.prop_advance[i], ctrls2.prop_advance[i], ratio );
+ result.ctrls.engine_ok[i] = ctrls1.engine_ok[i];
+ result.ctrls.mag_left_ok[i] = ctrls1.mag_left_ok[i];
+ result.ctrls.mag_right_ok[i] = ctrls1.mag_right_ok[i];
+ result.ctrls.spark_plugs_ok[i] = ctrls1.spark_plugs_ok[i];
+ result.ctrls.oil_press_status[i] = ctrls1.oil_press_status[i];
+ result.ctrls.fuel_pump_ok[i] = ctrls1.fuel_pump_ok[i];
+ }
+
+ // Fuel management
+ for ( i = 0; i < ctrls1.num_tanks; ++i ) {
+ result.ctrls.fuel_selector[i] = ctrls1.fuel_selector[i];
+ }
+
+ // Brake controls
+ result.ctrls.brake_left
+ = weight( ctrls1.brake_left, ctrls2.brake_right, ratio );
+ result.ctrls.brake_right
+ = weight( ctrls1.brake_right, ctrls2.brake_right, ratio );
+ result.ctrls.brake_parking
+ = weight( ctrls1.brake_parking, ctrls2.brake_parking, ratio );
+
+ // Landing Gear
+ result.ctrls.gear_handle = ctrls1.gear_handle;
+
+ // Switches
+ result.ctrls.turbulence_norm = ctrls1.turbulence_norm;
+
+ // wind and turbulance
+ result.ctrls.wind_speed_kt
+ = weight( ctrls1.wind_speed_kt, ctrls2.wind_speed_kt, ratio );
+ result.ctrls.wind_dir_deg
+ = weight( ctrls1.wind_dir_deg, ctrls2.wind_dir_deg, ratio );
+ result.ctrls.turbulence_norm
+ = weight( ctrls1.turbulence_norm, ctrls2.turbulence_norm, ratio );
+
+ // other information about environment
+ result.ctrls.hground = weight( ctrls1.hground, ctrls2.hground, ratio );
+ result.ctrls.magvar = weight( ctrls1.magvar, ctrls2.magvar, ratio );
+
+ // simulation control
+ result.ctrls.speedup = ctrls1.speedup;
+ result.ctrls.freeze = ctrls1.freeze;
+
+ return result;
+}
+
+/**
+ * interpolate a specific time from a specific list
+ */
+static void interpolate( double time, const replay_list_type &list ) {
+ // sanity checking
+ if ( list.size() == 0 ) {
+ // handle empty list
+ return;
+ } else if ( list.size() == 1 ) {
+ // handle list size == 1
+ update_fdm( list[0] );
+ return;
+ }
+
+ unsigned int last = list.size() - 1;
+ unsigned int first = 0;
+ unsigned int mid = ( last + first ) / 2;
+
+
+ bool done = false;
+ while ( !done ) {
+ // cout << " " << first << " <=> " << last << endl;
+ if ( last == first ) {
+ done = true;
+ } else if ( list[mid].sim_time < time && list[mid+1].sim_time < time ) {
+ // too low
+ first = mid;
+ mid = ( last + first ) / 2;
+ } else if ( list[mid].sim_time > time && list[mid+1].sim_time > time ) {
+ // too high
+ last = mid;
+ mid = ( last + first ) / 2;
+ } else {
+ done = true;
+ }
+ }
+
+ FGReplayData result = interpolate( time, list[mid], list[mid+1] );
+
+ update_fdm( result );
+}
+
+
+/**
+ * Replay a saved frame based on time, interpolate from the two
+ * nearest saved frames.
+ */
+
+void FGReplay::replay( double time ) {
+ // cout << "replay: " << time << " ";
+ // find the two frames to interpolate between
+ double t1, t2;
+
+ if ( short_term.size() > 0 ) {
+ t1 = short_term.back().sim_time;
+ t2 = short_term.front().sim_time;
+ if ( time > t1 ) {
+ // replay the most recent frame
+ update_fdm( short_term.back() );
+ // cout << "first frame" << endl;
+ } else if ( time <= t1 && time >= t2 ) {
+ interpolate( time, short_term );
+ // cout << "from short term" << endl;
+ } else if ( medium_term.size() > 0 ) {
+ t1 = short_term.front().sim_time;
+ t2 = medium_term.back().sim_time;
+ if ( time <= t1 && time >= t2 ) {
+ FGReplayData result = interpolate( time,
+ medium_term.back(),
+ short_term.front() );
+ update_fdm( result );
+ // cout << "from short/medium term" << endl;
+ } else {
+ t1 = medium_term.back().sim_time;
+ t2 = medium_term.front().sim_time;
+ if ( time <= t1 && time >= t2 ) {
+ interpolate( time, medium_term );
+ // cout << "from medium term" << endl;
+ } else if ( long_term.size() > 0 ) {
+ t1 = medium_term.front().sim_time;
+ t2 = long_term.back().sim_time;
+ if ( time <= t1 && time >= t2 ) {
+ FGReplayData result = interpolate( time,
+ long_term.back(),
+ medium_term.front());
+ update_fdm( result );
+ // cout << "from medium/long term" << endl;
+ } else {
+ t1 = long_term.back().sim_time;
+ t2 = long_term.front().sim_time;
+ if ( time <= t1 && time >= t2 ) {
+ interpolate( time, long_term );
+ // cout << "from long term" << endl;
+ } else {
+ // replay the oldest long term frame
+ update_fdm( long_term.front() );
+ // cout << "oldest long term frame" << endl;
+ }
+ }
+ } else {
+ // replay the oldest medium term frame
+ update_fdm( medium_term.front() );
+ // cout << "oldest medium term frame" << endl;
+ }
+ }
+ } else {
+ // replay the oldest short term frame
+ update_fdm( short_term.front() );
+ // cout << "oldest short term frame" << endl;
+ }
+ } else {
+ // nothing to replay
+ }
+}
+
+
+double FGReplay::get_start_time() {
+ if ( long_term.size() > 0 ) {
+ return long_term.front().sim_time;
+ } else if ( medium_term.size() > 0 ) {
+ return medium_term.front().sim_time;
+ } else if ( short_term.size() ) {
+ return short_term.front().sim_time;
+ } else {
+ return 0.0;
+ }
+}
+
+double FGReplay::get_end_time() {
+ if ( short_term.size() ) {
+ return short_term.back().sim_time;
+ } else {
+ return 0.0;
+ }
+}
--- /dev/null
+// replay.hxx - a system to record and replay FlightGear flights
+//
+// Written by Curtis Olson, started Juley 2003.
+//
+// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifndef _FG_REPLAY_HXX
+#define _FG_REPLAY_HXX 1
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include <deque>
+
+#include <simgear/math/sg_types.hxx>
+#include <simgear/props/props.hxx>
+#include <simgear/structure/subsystem_mgr.hxx>
+
+#include <Network/net_ctrls.hxx>
+#include <Network/net_fdm.hxx>
+
+SG_USING_STD(deque);
+
+
+class FGReplayData {
+
+public:
+
+ double sim_time;
+ FGNetFDM fdm;
+ FGNetCtrls ctrls;
+};
+
+typedef deque < FGReplayData > replay_list_type;
+
+
+
+/**
+ * A recording/replay module for FlightGear flights
+ *
+ */
+
+class FGReplay : public SGSubsystem
+{
+
+public:
+
+ FGReplay ();
+ virtual ~FGReplay();
+
+ virtual void init();
+ virtual void bind();
+ virtual void unbind();
+ virtual void update( double dt );
+
+ void replay( double time );
+ double get_start_time();
+ double get_end_time();
+
+private:
+
+ static const double st_list_time; // 60 secs of high res data
+ static const double mt_list_time; // 10 mins of 1 fps data
+ static const double lt_list_time; // 1 hr of 10 spf data
+
+ // short term sample rate is as every frame
+ static const double mt_dt; // medium term sample rate (sec)
+ static const double lt_dt; // long term sample rate (sec)
+
+ double sim_time;
+ double last_mt_time;
+ double last_lt_time;
+
+ replay_list_type short_term;
+ replay_list_type medium_term;
+ replay_list_type long_term;
+ SGPropertyNode_ptr disable_replay;
+};
+
+
+#endif // _FG_REPLAY_HXX
#include <Aircraft/aircraft.hxx>
#include <FDM/flight.hxx>
-#include <Controls/controls.hxx>
#include <Scenery/scenery.hxx>
#include <simgear/constants.h>
#include <Include/fg_typedefs.h>
#include <Aircraft/aircraft.hxx>
+#include <Aircraft/controls.hxx>
#include <FDM/flight.hxx>
-#include <Controls/controls.hxx>
#include <GUI/gui.h>
#include <Main/globals.hxx>
#include <Main/viewmgr.hxx>
+++ /dev/null
-.deps
-Makefile
-Makefile.in
+++ /dev/null
-noinst_LIBRARIES = libControls.a
-
-libControls_a_SOURCES = controls.cxx controls.hxx
-
-INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
+++ /dev/null
-// controls.cxx -- defines a standard interface to all flight sim controls
-//
-// Written by Curtis Olson, started May 1997.
-//
-// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-
-
-#include <simgear/compiler.h>
-#include <simgear/debug/logstream.hxx>
-#include <Main/fg_props.hxx>
-
-#include "controls.hxx"
-
-
-static const int MAX_NAME_LEN = 128;
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Inline utility methods.
-////////////////////////////////////////////////////////////////////////
-
-static inline void
-CLAMP(double *x, double min, double max )
-{
- if ( *x < min ) { *x = min; }
- if ( *x > max ) { *x = max; }
-}
-
-static inline void
-CLAMP(int *i, int min, int max )
-{
- if ( *i < min ) { *i = min; }
- if ( *i > max ) { *i = max; }
-}
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of FGControls.
-////////////////////////////////////////////////////////////////////////
-
-// Constructor
-FGControls::FGControls() :
- aileron( 0.0 ),
- aileron_trim( 0.0 ),
- elevator( 0.0 ),
- elevator_trim( 0.0 ),
- rudder( 0.0 ),
- rudder_trim( 0.0 ),
- flaps( 0.0 ),
- slats( 0.0 ),
- BLC( false ),
- spoilers( 0.0 ),
- speedbrake( 0.0 ),
- wing_sweep( 0.0 ),
- wing_fold( false ),
- drag_chute( false ),
- throttle_idle( true ),
- dump_valve( false ),
- brake_left( 0.0 ),
- brake_right( 0.0 ),
- copilot_brake_left( 0.0 ),
- copilot_brake_right( 0.0 ),
- brake_parking( 0.0 ),
- steering( 0.0 ),
- gear_down( true ),
- antiskid( true ),
- tailhook( false ),
- launchbar( false ),
- catapult_launch_cmd( false ),
- tailwheel_lock( true ),
- wing_heat( false ),
- pitot_heat( true ),
- wiper( 0 ),
- window_heat( false ),
- battery_switch( true ),
- external_power( false ),
- APU_generator( false ),
- APU_bleed( false ),
- mode( 0 ),
- dump( false ),
- outflow_valve( 0.0 ),
- taxi_light( false ),
- logo_lights( false ),
- nav_lights( false ),
- beacon( false ),
- strobe( false ),
- panel_norm( 0.0 ),
- instruments_norm( 0.0 ),
- dome_norm( 0.0 ),
- master_arm( false ),
- station_select( 1 ),
- release_ALL( false ),
- vertical_adjust( 0.0 ),
- fore_aft_adjust( 0.0 ),
- off_start_run( 0 ),
- APU_fire_switch( false ),
- autothrottle_arm( false ),
- autothrottle_engage( false ),
- heading_select( 0.0 ),
- altitude_select( 50000.0 ),
- bank_angle_select( 30.0 ),
- vertical_speed_select( 0.0 ),
- speed_select( 0.0 ),
- mach_select( 0.0 ),
- vertical_mode( 0 ),
- lateral_mode( 0 )
-{
-}
-
-
-void FGControls::reset_all()
-{
- set_aileron( 0.0 );
- set_aileron_trim( 0.0 );
- set_elevator( 0.0 );
- set_elevator_trim( 0.0 );
- set_rudder( 0.0 );
- set_rudder_trim( 0.0 );
- BLC = false;
- set_spoilers( 0.0 );
- set_speedbrake( 0.0 );
- set_wing_sweep( 0.0 );
- wing_fold = false;
- drag_chute = false;
- set_throttle( ALL_ENGINES, 0.0 );
- set_starter( ALL_ENGINES, false );
- set_magnetos( ALL_ENGINES, 0 );
- set_fuel_pump( ALL_ENGINES, false );
- set_fire_switch( ALL_ENGINES, false );
- set_fire_bottle_discharge( ALL_ENGINES, false );
- set_cutoff( ALL_ENGINES, true );
- set_nitrous_injection( ALL_ENGINES, false );
- set_cowl_flaps_norm( ALL_ENGINES, 1.0 );
- set_feather( ALL_ENGINES, false );
- set_ignition( ALL_ENGINES, false );
- set_augmentation( ALL_ENGINES, false );
- set_reverser( ALL_ENGINES, false );
- set_water_injection( ALL_ENGINES, false );
- set_condition( ALL_ENGINES, 1.0 );
- throttle_idle = true;
- set_fuel_selector( ALL_TANKS, true );
- dump_valve = false;
- steering = 0.0;
- gear_down = true;
- tailhook = false;
- launchbar = false;
- catapult_launch_cmd = false;
- tailwheel_lock = true;
- set_carb_heat( ALL_ENGINES, false );
- set_inlet_heat( ALL_ENGINES, false );
- wing_heat = false;
- pitot_heat = true;
- wiper = 0;
- window_heat = false;
- set_engine_pump( ALL_HYD_SYSTEMS, true );
- set_electric_pump( ALL_HYD_SYSTEMS, true );
- landing_lights = false;
- turn_off_lights = false;
- master_arm = false;
- set_ejection_seat( ALL_EJECTION_SEATS, false );
- set_eseat_status( ALL_EJECTION_SEATS, SEAT_SAFED );
- set_cmd_selector_valve( CMD_SEL_NORM );
- APU_fire_switch = false;
- autothrottle_arm = false;
- autothrottle_engage = false;
- set_autopilot_engage( ALL_AUTOPILOTS, false );
-}
-
-
-// Destructor
-FGControls::~FGControls() {
-}
-
-
-void
-FGControls::init ()
-{
- throttle_idle = true;
- for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
- throttle[engine] = 0.0;
- mixture[engine] = 1.0;
- fuel_pump[engine] = false;
- prop_advance[engine] = 1.0;
- magnetos[engine] = 0;
- starter[engine] = false;
- ignition[engine] = false;
- fire_switch[engine] = false;
- cutoff[engine] = true;
- augmentation[engine] = false;
- reverser[engine] = false;
- water_injection[engine] = false;
- nitrous_injection[engine] = false;
- cowl_flaps_norm[engine] = 0.0;
- condition[engine] = 1.0;
- }
-
- brake_left = brake_right
- = copilot_brake_left = copilot_brake_right
- = brake_parking = 0.0;
- for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
- alternate_extension[wheel] = false;
- }
-
- auto_coordination = fgGetNode("/sim/auto-coordination", true);
-}
-
-
-void
-FGControls::bind ()
-{
- int index, i;
-
- // flight controls
- fgTie("/controls/flight/aileron", this,
- &FGControls::get_aileron, &FGControls::set_aileron);
- fgSetArchivable("/controls/flight/aileron");
-
- fgTie("/controls/flight/aileron-trim", this,
- &FGControls::get_aileron_trim, &FGControls::set_aileron_trim);
- fgSetArchivable("/controls/flight/aileron-trim");
-
- fgTie("/controls/flight/elevator", this,
- &FGControls::get_elevator, &FGControls::set_elevator);
- fgSetArchivable("/controls/flight/elevator");
-
- fgTie("/controls/flight/elevator-trim", this,
- &FGControls::get_elevator_trim, &FGControls::set_elevator_trim);
- fgSetArchivable("/controls/flight/elevator-trim");
-
- fgTie("/controls/flight/rudder", this,
- &FGControls::get_rudder, &FGControls::set_rudder);
- fgSetArchivable("/controls/flight/rudder");
-
- fgTie("/controls/flight/rudder-trim", this,
- &FGControls::get_rudder_trim, &FGControls::set_rudder_trim);
- fgSetArchivable("/controls/flight/rudder-trim");
-
- fgTie("/controls/flight/flaps", this,
- &FGControls::get_flaps, &FGControls::set_flaps);
- fgSetArchivable("/controls/flight/flaps");
-
- fgTie("/controls/flight/slats", this,
- &FGControls::get_slats, &FGControls::set_slats);
- fgSetArchivable("/controls/flight/slats");
-
- fgTie("/controls/flight/BLC", this,
- &FGControls::get_BLC, &FGControls::set_BLC);
- fgSetArchivable("/controls/flight/BLC");
-
- fgTie("/controls/flight/spoilers", this,
- &FGControls::get_spoilers, &FGControls::set_spoilers);
- fgSetArchivable("/controls/flight/spoilers");
-
- fgTie("/controls/flight/speedbrake", this,
- &FGControls::get_speedbrake, &FGControls::set_speedbrake);
- fgSetArchivable("/controls/flight/speedbrake");
-
- fgTie("/controls/flight/wing-sweep", this,
- &FGControls::get_wing_sweep, &FGControls::set_wing_sweep);
- fgSetArchivable("/controls/flight/wing-sweep");
-
- fgTie("/controls/flight/wing-fold", this,
- &FGControls::get_wing_fold, &FGControls::set_wing_fold);
- fgSetArchivable("/controls/flight/wing-fold");
-
- fgTie("/controls/flight/drag-chute", this,
- &FGControls::get_drag_chute, &FGControls::set_drag_chute);
- fgSetArchivable("/controls/flight/drag-chute");
-
- // engines
- fgTie("/controls/engines/throttle_idle", this,
- &FGControls::get_throttle_idle, &FGControls::set_throttle_idle);
- fgSetArchivable("/controls/engines/throttle_idle");
-
- for (index = 0; index < MAX_ENGINES; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/throttle", index);
- fgTie(name, this, index,
- &FGControls::get_throttle, &FGControls::set_throttle);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/starter", index);
- fgTie(name, this, index,
- &FGControls::get_starter, &FGControls::set_starter);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/fuel-pump", index);
- fgTie(name, this, index,
- &FGControls::get_fuel_pump, &FGControls::set_fuel_pump);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/fire-switch", index);
- fgTie(name, this, index,
- &FGControls::get_fire_switch, &FGControls::set_fire_switch);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/fire-bottle-discharge", index);
- fgTie(name, this, index,
- &FGControls::get_fire_bottle_discharge,
- &FGControls::set_fire_bottle_discharge);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/cutoff", index);
- fgTie(name, this, index,
- &FGControls::get_cutoff, &FGControls::set_cutoff);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/mixture", index);
- fgTie(name, this, index,
- &FGControls::get_mixture, &FGControls::set_mixture);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/propeller-pitch", index);
- fgTie(name, this, index,
- &FGControls::get_prop_advance,
- &FGControls::set_prop_advance);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/magnetos", index);
- fgTie(name, this, index,
- &FGControls::get_magnetos, &FGControls::set_magnetos);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/WEP", index);
- fgTie(name, this, index,
- &FGControls::get_nitrous_injection,
- &FGControls::set_nitrous_injection);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/cowl-flaps-norm", index);
- fgTie(name, this, index,
- &FGControls::get_cowl_flaps_norm,
- &FGControls::set_cowl_flaps_norm);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/propeller-feather", index);
- fgTie(name, this, index,
- &FGControls::get_feather, &FGControls::set_feather);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/ignition", index);
- fgTie(name, this, index,
- &FGControls::get_ignition, &FGControls::set_ignition);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/augmentation", index);
- fgTie(name, this, index,
- &FGControls::get_augmentation,
- &FGControls::set_augmentation);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/reverser", index);
- fgTie(name, this, index,
- &FGControls::get_reverser, &FGControls::set_reverser);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/water-injection", index);
- fgTie(name, this, index,
- &FGControls::get_water_injection,
- &FGControls::set_water_injection);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/condition", index);
- fgTie(name, this, index,
- &FGControls::get_condition, &FGControls::set_condition);
- fgSetArchivable(name);
- }
-
- // fuel
- fgTie("/controls/fuel/dump-valve", this,
- &FGControls::get_dump_valve, &FGControls::set_dump_valve);
- fgSetArchivable("/controls/fuel/dump-valve");
-
- for (index = 0; index < MAX_TANKS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/fuel/tank[%d]/fuel_selector", index);
- fgTie(name, this, index,
- &FGControls::get_fuel_selector,
- &FGControls::set_fuel_selector);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN, "/controls/fuel/tank[%d]/to_engine", index);
- fgTie(name, this, index,
- &FGControls::get_to_engine, &FGControls::set_to_engine);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN, "/controls/fuel/tank[%d]/to_tank", index);
- fgTie(name, this, index,
- &FGControls::get_to_tank, &FGControls::set_to_tank);
- fgSetArchivable(name);
-
- for (i = 0; i < MAX_BOOSTPUMPS; i++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/fuel/tank[%d]/boost-pump[%d]", index, i);
- fgTie(name, this, index * 2 + i,
- &FGControls::get_boost_pump,
- &FGControls::set_boost_pump);
- fgSetArchivable(name);
- }
- }
-
- // gear
- fgTie("/controls/gear/brake-left", this,
- &FGControls::get_brake_left,
- &FGControls::set_brake_left);
- fgSetArchivable("/controls/gear/brake-left");
-
- fgTie("/controls/gear/brake-right", this,
- &FGControls::get_brake_right,
- &FGControls::set_brake_right);
- fgSetArchivable("/controls/gear/brake-right");
-
- fgTie("/controls/gear/copilot-brake-left", this,
- &FGControls::get_copilot_brake_left,
- &FGControls::set_copilot_brake_left);
- fgSetArchivable("/controls/gear/copilot-brake-left");
-
- fgTie("/controls/gear/copilot-brake-right", this,
- &FGControls::get_copilot_brake_right,
- &FGControls::set_copilot_brake_right);
- fgSetArchivable("/controls/gear/copilot-brake-right");
-
- fgTie("/controls/gear/brake-parking", this,
- &FGControls::get_brake_parking,
- &FGControls::set_brake_parking);
- fgSetArchivable("/controls/gear/brake-parking");
-
- fgTie("/controls/gear/steering", this,
- &FGControls::get_steering, &FGControls::set_steering);
- fgSetArchivable("/controls/gear/steering");
-
- fgTie("/controls/gear/gear-down", this,
- &FGControls::get_gear_down, &FGControls::set_gear_down);
- fgSetArchivable("/controls/gear/gear-down");
-
- fgTie("/controls/gear/antiskid", this,
- &FGControls::get_antiskid, &FGControls::set_antiskid);
- fgSetArchivable("/controls/gear/antiskid");
-
- fgTie("/controls/gear/tailhook", this,
- &FGControls::get_tailhook, &FGControls::set_tailhook);
- fgSetArchivable("/controls/gear/tailhook");
-
- fgTie("/controls/gear/launchbar", this,
- &FGControls::get_launchbar, &FGControls::set_launchbar);
- fgSetArchivable("/controls/gear/launchbar");
-
- fgTie("/controls/gear/catapult-launch-cmd", this,
- &FGControls::get_catapult_launch_cmd, &FGControls::set_catapult_launch_cmd);
- fgSetArchivable("/controls/gear/catapult-launch-cmd");
-
- fgTie("/controls/gear/tailwheel-lock", this,
- &FGControls::get_tailwheel_lock,
- &FGControls::set_tailwheel_lock);
- fgSetArchivable("/controls/gear/tailwheel-lock");
-
- for (index = 0; index < MAX_WHEELS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/gear/wheel[%d]/alternate-extension", index);
- fgTie(name, this, index,
- &FGControls::get_alternate_extension,
- &FGControls::set_alternate_extension);
- fgSetArchivable(name);
- }
-
- // anti-ice
- fgTie("/controls/anti-ice/wing-heat", this,
- &FGControls::get_wing_heat, &FGControls::set_wing_heat);
- fgSetArchivable("/controls/anti-ice/wing-heat");
-
- fgTie("/controls/anti-ice/pitot-heat", this,
- &FGControls::get_pitot_heat, &FGControls::set_pitot_heat);
- fgSetArchivable("/controls/anti-ice/pitot-heat");
-
- fgTie("/controls/anti-ice/wiper", this,
- &FGControls::get_wiper, &FGControls::set_wiper);
- fgSetArchivable("/controls/anti-ice/wiper");
-
- fgTie("/controls/anti-ice/window-heat", this,
- &FGControls::get_window_heat, &FGControls::set_window_heat);
- fgSetArchivable("/controls/anti-ice/window-heat");
-
- for (index = 0; index < MAX_ENGINES; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/anti-ice/engine[%d]/carb-heat", index);
- fgTie(name, this, index,
- &FGControls::get_carb_heat, &FGControls::set_carb_heat);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/anti-ice/engine[%d]/inlet-heat", index);
- fgTie(name, this, index,
- &FGControls::get_inlet_heat, &FGControls::set_inlet_heat);
- fgSetArchivable(name);
- }
-
- // hydraulics
- for (index = 0; index < MAX_HYD_SYSTEMS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/hydraulic/system[%d]/engine-pump", index);
- fgTie(name, this, index,
- &FGControls::get_engine_pump, &FGControls::set_engine_pump);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/hydraulic/system[%d]/electric-pump", index);
- fgTie(name, this, index,
- &FGControls::get_electric_pump,
- &FGControls::set_electric_pump);
- fgSetArchivable(name);
- }
-
- // electric
- fgTie("/controls/electric/battery-switch", this,
- &FGControls::get_battery_switch,
- &FGControls::set_battery_switch);
- fgSetArchivable("/controls/electric/battery-switch");
-
- fgTie("/controls/electric/external-power", this,
- &FGControls::get_external_power,
- &FGControls::set_external_power);
- fgSetArchivable("/controls/electric/external-power");
-
- fgTie("/controls/electric/APU-generator", this,
- &FGControls::get_APU_generator,
- &FGControls::set_APU_generator);
- fgSetArchivable("/controls/electric/APU-generator");
-
- for (index = 0; index < MAX_ENGINES; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/electric/engine[%d]/generator", index);
- fgTie(name, this, index,
- &FGControls::get_generator_breaker,
- &FGControls::set_generator_breaker);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/electric/engine[%d]/bus-tie", index);
- fgTie(name, this, index,
- &FGControls::get_bus_tie,
- &FGControls::set_bus_tie);
- fgSetArchivable(name);
- }
-
- // pneumatic
- fgTie("/controls/pneumatic/APU-bleed", this,
- &FGControls::get_APU_bleed,
- &FGControls::set_APU_bleed);
- fgSetArchivable("/controls/pneumatic/APU-bleed");
-
- for (index = 0; index < MAX_ENGINES; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/pneumatic/engine[%d]/bleed", index);
- fgTie(name, this, index,
- &FGControls::get_engine_bleed,
- &FGControls::set_engine_bleed);
- fgSetArchivable(name);
- }
-
- // pressurization
- fgTie("/controls/pressurization/mode", this,
- &FGControls::get_mode, &FGControls::set_mode);
- fgSetArchivable("/controls/pressurization/mode");
-
- fgTie("/controls/pressurization/dump", this,
- &FGControls::get_dump, &FGControls::set_dump);
- fgSetArchivable("/controls/pressurization/dump");
-
- fgTie("/controls/pressurization/outflow-valve", this,
- &FGControls::get_outflow_valve,
- &FGControls::set_outflow_valve);
- fgSetArchivable("/controls/pressurization/outflow-valve");
-
- for (index = 0; index < MAX_PACKS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/pressurization/pack[%d]/pack-on", index);
- fgTie(name, this, index,
- &FGControls::get_pack_on, &FGControls::set_pack_on);
- fgSetArchivable(name);
- }
-
- // lights
- fgTie("/controls/lighting/landing-lights", this,
- &FGControls::get_landing_lights,
- &FGControls::set_landing_lights);
- fgSetArchivable("/controls/lighting/landing-lights");
-
- fgTie("/controls/lighting/turn-off-lights", this,
- &FGControls::get_turn_off_lights,
- &FGControls::set_turn_off_lights);
- fgSetArchivable("/controls/lighting/turn-off-lights");
-
- fgTie("/controls/lighting/taxi-light", this,
- &FGControls::get_taxi_light, &FGControls::set_taxi_light);
- fgSetArchivable("/controls/lighting/taxi-light");
-
- fgTie("/controls/lighting/logo-lights", this,
- &FGControls::get_logo_lights, &FGControls::set_logo_lights);
- fgSetArchivable("/controls/lighting/logo-lights");
-
- fgTie("/controls/lighting/nav-lights", this,
- &FGControls::get_nav_lights, &FGControls::set_nav_lights);
- fgSetArchivable("/controls/lighting/nav-lights");
-
- fgTie("/controls/lighting/beacon", this,
- &FGControls::get_beacon, &FGControls::set_beacon);
- fgSetArchivable("/controls/lighting/beacon");
-
- fgTie("/controls/lighting/strobe", this,
- &FGControls::get_strobe, &FGControls::set_strobe);
- fgSetArchivable("/controls/lighting/strobe");
-
- fgTie("/controls/lighting/panel-norm", this,
- &FGControls::get_panel_norm, &FGControls::set_panel_norm);
- fgSetArchivable("/controls/lighting/panel-norm");
-
- fgTie("/controls/lighting/instruments-norm", this,
- &FGControls::get_instruments_norm,
- &FGControls::set_instruments_norm);
- fgSetArchivable("/controls/lighting/instruments-norm");
-
- fgTie("/controls/lighting/dome-norm", this,
- &FGControls::get_dome_norm, &FGControls::set_dome_norm);
- fgSetArchivable("/controls/lighting/dome-norm");
-
-#ifdef FG_HAVE_ARMAMENT
- // armament
- fgTie("/controls/armament/master-arm", this,
- &FGControls::get_master_arm, &FGControls::set_master_arm);
- fgSetArchivable("/controls/armament/master-arm");
-
- fgTie("/controls/armament/station-select", this,
- &FGControls::get_station_select,
- &FGControls::set_station_select);
- fgSetArchivable("/controls/armament/station-select");
-
- fgTie("/controls/armament/release-all", this,
- &FGControls::get_release_ALL,
- &FGControls::set_release_ALL);
- fgSetArchivable("/controls/armament/release-all");
-
- for (index = 0; index < MAX_STATIONS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/armament/station[%d]/stick-size", index);
- fgTie(name, this, index,
- &FGControls::get_stick_size, &FGControls::set_stick_size);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/armament/station[%d]/release-stick", index);
- fgTie(name, this, index,
- &FGControls::get_release_stick, &FGControls::set_release_stick);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/armament/station[%d]/release-all", index);
- fgTie(name, this, index,
- &FGControls::get_release_all, &FGControls::set_release_all);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/armament/station[%d]/jettison-all", index);
- fgTie(name, this, index,
- &FGControls::get_jettison_all, &FGControls::set_jettison_all);
- fgSetArchivable(name);
- }
-
-#endif
-
- // seat
- fgTie("/controls/seat/vertical-adjust", this,
- &FGControls::get_vertical_adjust,
- &FGControls::set_vertical_adjust);
- fgSetArchivable("/controls/seat/vertical-adjust");
-
- fgTie("/controls/seat/fore-aft-adjust", this,
- &FGControls::get_fore_aft_adjust,
- &FGControls::set_fore_aft_adjust);
- fgSetArchivable("/controls/seat/fore-aft-adjust");
-
- for (index = 0; index < MAX_EJECTION_SEATS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/seat/eject[%d]/initiate", index);
- fgTie(name, this, index,
- &FGControls::get_ejection_seat,
- &FGControls::set_ejection_seat);
- fgSetArchivable(name);
-
- snprintf(name, MAX_NAME_LEN,
- "/controls/seat/eject[%d]/status", index);
-
- fgTie(name, this, index,
- &FGControls::get_eseat_status,
- &FGControls::set_eseat_status);
-
- fgSetArchivable(name);
- }
-
- fgTie("/controls/seat/cmd_selector_valve", this,
- &FGControls::get_cmd_selector_valve,
- &FGControls::set_cmd_selector_valve);
- fgSetArchivable("/controls/seat/eject/cmd_selector_valve");
-
-
- // APU
- fgTie("/controls/APU/off-start-run", this,
- &FGControls::get_off_start_run,
- &FGControls::set_off_start_run);
- fgSetArchivable("/controls/APU/off-start-run");
-
- fgTie("/controls/APU/fire-switch", this,
- &FGControls::get_APU_fire_switch,
- &FGControls::set_APU_fire_switch);
- fgSetArchivable("/controls/APU/fire-switch");
-
- // autoflight
- for (index = 0; index < MAX_AUTOPILOTS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/autoflight/autopilot[%d]/engage", index);
- fgTie(name, this, index,
- &FGControls::get_autopilot_engage,
- &FGControls::set_autopilot_engage);
- fgSetArchivable(name);
- }
-
- fgTie("/controls/autoflight/autothrottle-arm", this,
- &FGControls::get_autothrottle_arm,
- &FGControls::set_autothrottle_arm);
- fgSetArchivable("/controls/autoflight/autothrottle-arm");
-
- fgTie("/controls/autoflight/autothrottle-engage", this,
- &FGControls::get_autothrottle_engage,
- &FGControls::set_autothrottle_engage);
- fgSetArchivable("/controls/autoflight/autothrottle-engage");
-
- fgTie("/controls/autoflight/heading-select", this,
- &FGControls::get_heading_select,
- &FGControls::set_heading_select);
- fgSetArchivable("/controls/autoflight/heading-select");
-
- fgTie("/controls/autoflight/altitude-select", this,
- &FGControls::get_altitude_select,
- &FGControls::set_altitude_select);
- fgSetArchivable("/controls/autoflight/altitude-select");
-
- fgTie("/controls/autoflight/bank-angle-select", this,
- &FGControls::get_bank_angle_select,
- &FGControls::set_bank_angle_select);
- fgSetArchivable("/controls/autoflight/bank-angle-select");
-
- fgTie("/controls/autoflight/vertical-speed-select", this,
- &FGControls::get_vertical_speed_select,
- &FGControls::set_vertical_speed_select);
- fgSetArchivable("/controls/autoflight/vertical-speed-select");
-
- fgTie("/controls/autoflight/speed-select", this,
- &FGControls::get_speed_select,
- &FGControls::set_speed_select);
- fgSetArchivable("/controls/autoflight/speed-select");
-
- fgTie("/controls/autoflight/mach-select", this,
- &FGControls::get_mach_select,
- &FGControls::set_mach_select);
- fgSetArchivable("/controls/autoflight/mach-select");
-
- fgTie("/controls/autoflight/vertical-mode", this,
- &FGControls::get_vertical_mode,
- &FGControls::set_vertical_mode);
- fgSetArchivable("/controls/autoflight/vertical-mode");
-
- fgTie("/controls/autoflight/lateral-mode", this,
- &FGControls::get_lateral_mode,
- &FGControls::set_lateral_mode);
- fgSetArchivable("/controls/autoflight/lateral-mode");
-
-}
-
-void FGControls::unbind ()
-{
- int index, i;
- //Tie control properties.
- fgUntie("/controls/flight/aileron");
- fgUntie("/controls/flight/aileron-trim");
- fgUntie("/controls/flight/elevator");
- fgUntie("/controls/flight/elevator-trim");
- fgUntie("/controls/flight/rudder");
- fgUntie("/controls/flight/rudder-trim");
- fgUntie("/controls/flight/flaps");
- fgUntie("/controls/flight/slats");
- fgUntie("/controls/flight/BLC");
- fgUntie("/controls/flight/spoilers");
- fgUntie("/controls/flight/speedbrake");
- fgUntie("/controls/flight/wing-sweep");
- fgUntie("/controls/flight/wing-fold");
- fgUntie("/controls/flight/drag-chute");
- for (index = 0; index < MAX_ENGINES; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/throttle", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/starter", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/fuel_pump", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/fire-switch", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/fire-bottle-discharge", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/throttle_idle", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/cutoff", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/mixture", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/propeller-pitch", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/magnetos", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN, "/controls/engines/engine[%d]/WEP", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/cowl-flaps-norm", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/propeller-feather", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/ignition", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/augmentation", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/reverser", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/water-injection", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/engines/engine[%d]/condition", index);
- fgUntie(name);
- }
- fgUntie("/controls/fuel/dump-valve");
- for (index = 0; index < MAX_TANKS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/fuel/tank[%d]/fuel_selector", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN, "/controls/fuel/tank[%d]/to_engine", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN, "/controls/fuel/tank[%d]/to_tank", index);
- fgUntie(name);
- for (i = 0; index < MAX_BOOSTPUMPS; i++) {
- snprintf(name, MAX_NAME_LEN,
- "/controls/fuel/tank[%d]/boost-pump[%d]", index, i);
- fgUntie(name);
- }
- }
- fgUntie("/controls/gear/brake-left");
- fgUntie("/controls/gear/brake-right");
- fgUntie("/controls/gear/brake-parking");
- fgUntie("/controls/gear/steering");
- fgUntie("/controls/gear/gear_down");
- fgUntie("/controls/gear/antiskid");
- fgUntie("/controls/gear/tailhook");
- fgUntie("/controls/gear/launchbar");
- fgUntie("/controls/gear/catapult-launch-cmd");
- fgUntie("/controls/gear/tailwheel-lock");
- for (index = 0; index < MAX_WHEELS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/gear/wheel[%d]/alternate-extension", index);
- fgUntie(name);
- }
- fgUntie("/controls/anti-ice/wing-heat");
- fgUntie("/controls/anti-ice/pitot-heat");
- fgUntie("/controls/anti-ice/wiper");
- fgUntie("/controls/anti-ice/window-heat");
- for (index = 0; index < MAX_ENGINES; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/anti-ice/engine[%d]/carb-heat", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/anti-ice/engine[%d]/inlet-heat", index);
- fgUntie(name);
- }
- for (index = 0; index < MAX_HYD_SYSTEMS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/hydraulic/system[%d]/engine-pump", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/hydraulic/system[%d]/electric-pump", index);
- fgUntie(name);
- }
- fgUntie("/controls/electric/battery-switch");
- fgUntie("/controls/electric/external-power");
- fgUntie("/controls/electric/APU-generator");
- for (index = 0; index < MAX_ENGINES; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/electric/engine[%d]/generator", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/electric/engine[%d]/bus-tie", index);
- fgUntie(name);
- }
- fgUntie("/controls/pneumatic/APU-bleed");
- for (index = 0; index < MAX_ENGINES; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/pneumatic/engine[%d]/bleed", index);
- fgUntie(name);
- }
- fgUntie("/controls/pressurization/mode");
- fgUntie("/controls/pressurization/dump");
- for (index = 0; index < MAX_PACKS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/pressurization/pack[%d]/pack-on", index);
- fgUntie(name);
- }
- fgUntie("/controls/lighting/landing-lights");
- fgUntie("/controls/lighting/turn-off-lights");
- fgUntie("/controls/lighting/taxi-light");
- fgUntie("/controls/lighting/logo-lights");
- fgUntie("/controls/lighting/nav-lights");
- fgUntie("/controls/lighting/beacon");
- fgUntie("/controls/lighting/strobe");
- fgUntie("/controls/lighting/panel-norm");
- fgUntie("/controls/lighting/instruments-norm");
- fgUntie("/controls/lighting/dome-norm");
-
-#ifdef FG_HAVE_ARMAMENT
- fgUntie("/controls/armament/master-arm");
- fgUntie("/controls/armament/station-select");
- fgUntie("/controls/armament/release-all");
- for (index = 0; index < MAX_STATIONS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/armament/station[%d]/stick-size", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/armament/station[%d]/release-stick", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/armament/station[%d]/release-all", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/armament/station[%d]/jettison-all", index);
- fgUntie(name);
- }
-#endif
- fgUntie("/controls/seat/vertical-adjust");
- fgUntie("/controls/seat/fore-aft-adjust");
- for (index = 0; index < MAX_EJECTION_SEATS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/seat/eject[%d]/initiate", index);
- fgUntie(name);
- snprintf(name, MAX_NAME_LEN,
- "/controls/seat/eject[%d]/status", index);
- fgUntie(name);
- }
- fgUntie("/controls/seat/cmd_selector_valve");
-
- fgUntie("/controls/APU/off-start-run");
- fgUntie("/controls/APU/fire-switch");
- for (index = 0; index < MAX_AUTOPILOTS; index++) {
- char name[MAX_NAME_LEN];
- snprintf(name, MAX_NAME_LEN,
- "/controls/autoflight/autopilot[%d]/engage", index);
- fgUntie(name);
- }
- fgUntie("/controls/autoflight/autothrottle-arm");
- fgUntie("/controls/autoflight/autothrottle-engage");
- fgUntie("/controls/autoflight/heading-select");
- fgUntie("/controls/autoflight/altitude-select");
- fgUntie("/controls/autoflight/bank-angle-select");
- fgUntie("/controls/autoflight/vertical-speed-select");
- fgUntie("/controls/autoflight/speed-select");
- fgUntie("/controls/autoflight/mach-select");
- fgUntie("/controls/autoflight/vertical-mode");
- fgUntie("/controls/autoflight/lateral-mode");
-}
-
-
-void
-FGControls::update (double dt)
-{
-}
-
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Setters and adjusters.
-////////////////////////////////////////////////////////////////////////
-
-void
-FGControls::set_aileron (double pos)
-{
- aileron = pos;
- CLAMP( &aileron, -1.0, 1.0 );
-
- // check for autocoordination
- if ( auto_coordination->getBoolValue() ) {
- set_rudder( aileron / 2.0 );
- }
-}
-
-void
-FGControls::move_aileron (double amt)
-{
- aileron += amt;
- CLAMP( &aileron, -1.0, 1.0 );
-
- // check for autocoordination
- if ( auto_coordination->getBoolValue() ) {
- set_rudder( aileron / 2.0 );
- }
-}
-
-void
-FGControls::set_aileron_trim( double pos )
-{
- aileron_trim = pos;
- CLAMP( &aileron_trim, -1.0, 1.0 );
-}
-
-void
-FGControls::move_aileron_trim( double amt )
-{
- aileron_trim += amt;
- CLAMP( &aileron_trim, -1.0, 1.0 );
-}
-
-void
-FGControls::set_elevator( double pos )
-{
- elevator = pos;
- CLAMP( &elevator, -1.0, 1.0 );
-}
-
-void
-FGControls::move_elevator( double amt )
-{
- elevator += amt;
- CLAMP( &elevator, -1.0, 1.0 );
-}
-
-void
-FGControls::set_elevator_trim( double pos )
-{
- elevator_trim = pos;
- CLAMP( &elevator_trim, -1.0, 1.0 );
-}
-
-void
-FGControls::move_elevator_trim( double amt )
-{
- elevator_trim += amt;
- CLAMP( &elevator_trim, -1.0, 1.0 );
-}
-
-void
-FGControls::set_rudder( double pos )
-{
- rudder = pos;
- CLAMP( &rudder, -1.0, 1.0 );
-}
-
-void
-FGControls::move_rudder( double amt )
-{
- rudder += amt;
- CLAMP( &rudder, -1.0, 1.0 );
-}
-
-void
-FGControls::set_rudder_trim( double pos )
-{
- rudder_trim = pos;
- CLAMP( &rudder_trim, -1.0, 1.0 );
-}
-
-void
-FGControls::move_rudder_trim( double amt )
-{
- rudder_trim += amt;
- CLAMP( &rudder_trim, -1.0, 1.0 );
-}
-
-void
-FGControls::set_flaps( double pos )
-{
- flaps = pos;
- CLAMP( &flaps, 0.0, 1.0 );
-}
-
-void
-FGControls::move_flaps( double amt )
-{
- flaps += amt;
- CLAMP( &flaps, 0.0, 1.0 );
-}
-
-void
-FGControls::set_slats( double pos )
-{
- slats = pos;
- CLAMP( &slats, 0.0, 1.0 );
-}
-
-void
-FGControls::move_slats( double amt )
-{
- slats += amt;
- CLAMP( &slats, 0.0, 1.0 );
-}
-
-void
-FGControls::set_BLC( bool val )
-{
- BLC = val;
-}
-
-void
-FGControls::set_spoilers( double pos )
-{
- spoilers = pos;
- CLAMP( &spoilers, 0.0, 1.0 );
-}
-
-void
-FGControls::move_spoilers( double amt )
-{
- spoilers += amt;
- CLAMP( &spoilers, 0.0, 1.0 );
-}
-
-void
-FGControls::set_speedbrake( double pos )
-{
- speedbrake = pos;
- CLAMP( &speedbrake, 0.0, 1.0 );
-}
-
-void
-FGControls::move_speedbrake( double amt )
-{
- speedbrake += amt;
- CLAMP( &speedbrake, 0.0, 1.0 );
-}
-
-void
-FGControls::set_wing_sweep( double pos )
-{
- wing_sweep = pos;
- CLAMP( &wing_sweep, 0.0, 1.0 );
-}
-
-void
-FGControls::move_wing_sweep( double amt )
-{
- wing_sweep += amt;
- CLAMP( &wing_sweep, 0.0, 1.0 );
-}
-
-void
-FGControls::set_wing_fold( bool val )
-{
- wing_fold = val;
-}
-
-void
-FGControls::set_drag_chute( bool val )
-{
- drag_chute = val;
-}
-
-void
-FGControls::set_throttle_idle( bool val )
-{
- throttle_idle = val;
-}
-
-void
-FGControls::set_throttle( int engine, double pos )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- throttle[i] = pos;
- CLAMP( &throttle[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- throttle[engine] = pos;
- CLAMP( &throttle[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::move_throttle( int engine, double amt )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- throttle[i] += amt;
- CLAMP( &throttle[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- throttle[engine] += amt;
- CLAMP( &throttle[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::set_starter( int engine, bool flag )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- starter[i] = flag;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- starter[engine] = flag;
- }
- }
-}
-
-void
-FGControls::set_fuel_pump( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- fuel_pump[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- fuel_pump[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_fire_switch( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- fire_switch[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- fire_switch[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_fire_bottle_discharge( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- fire_bottle_discharge[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- fire_bottle_discharge[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_cutoff( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- cutoff[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- cutoff[engine] = val;
- }
- }
-}
-
-
-void
-FGControls::set_mixture( int engine, double pos )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- mixture[i] = pos;
- CLAMP( &mixture[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- mixture[engine] = pos;
- CLAMP( &mixture[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::move_mixture( int engine, double amt )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- mixture[i] += amt;
- CLAMP( &mixture[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- mixture[engine] += amt;
- CLAMP( &mixture[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::set_prop_advance( int engine, double pos )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- prop_advance[i] = pos;
- CLAMP( &prop_advance[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- prop_advance[engine] = pos;
- CLAMP( &prop_advance[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::move_prop_advance( int engine, double amt )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- prop_advance[i] += amt;
- CLAMP( &prop_advance[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- prop_advance[engine] += amt;
- CLAMP( &prop_advance[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::set_magnetos( int engine, int pos )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- magnetos[i] = pos;
- CLAMP( &magnetos[i], 0, 3 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- magnetos[engine] = pos;
- CLAMP( &magnetos[engine], 0, 3 );
- }
- }
-}
-
-void
-FGControls::move_magnetos( int engine, int amt )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- magnetos[i] += amt;
- CLAMP( &magnetos[i], 0, 3 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- magnetos[engine] += amt;
- CLAMP( &magnetos[engine], 0, 3 );
- }
- }
-}
-
-void
-FGControls::set_nitrous_injection( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- nitrous_injection[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- nitrous_injection[engine] = val;
- }
- }
-}
-
-
-void
-FGControls::set_cowl_flaps_norm( int engine, double pos )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- cowl_flaps_norm[i] = pos;
- CLAMP( &cowl_flaps_norm[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- cowl_flaps_norm[engine] = pos;
- CLAMP( &cowl_flaps_norm[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::move_cowl_flaps_norm( int engine, double amt )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- cowl_flaps_norm[i] += amt;
- CLAMP( &cowl_flaps_norm[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- cowl_flaps_norm[engine] += amt;
- CLAMP( &cowl_flaps_norm[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::set_feather( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- feather[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- feather[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_ignition( int engine, int pos )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- ignition[i] = pos;
- CLAMP( &ignition[i], 0, 3 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- ignition[engine] = pos;
- CLAMP( &ignition[engine], 0, 3 );
- }
- }
-}
-
-void
-FGControls::set_augmentation( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- augmentation[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- augmentation[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_reverser( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- reverser[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- reverser[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_water_injection( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- water_injection[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- water_injection[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_condition( int engine, double val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- condition[i] = val;
- CLAMP( &condition[i], 0.0, 1.0 );
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- condition[engine] = val;
- CLAMP( &condition[engine], 0.0, 1.0 );
- }
- }
-}
-
-void
-FGControls::set_dump_valve( bool val )
-{
- dump_valve = val;
-}
-
-
-void
-FGControls::set_fuel_selector( int tank, bool pos )
-{
- if ( tank == ALL_TANKS ) {
- for ( int i = 0; i < MAX_TANKS; i++ ) {
- fuel_selector[i] = pos;
- }
- } else {
- if ( (tank >= 0) && (tank < MAX_TANKS) ) {
- fuel_selector[tank] = pos;
- }
- }
-}
-
-void
-FGControls::set_to_engine( int tank, int engine )
-{
- if ( tank == ALL_TANKS ) {
- for ( int i = 0; i < MAX_TANKS; i++ ) {
- to_engine[i] = engine;
- }
- } else {
- if ( (tank >= 0) && (tank < MAX_TANKS) ) {
- to_engine[tank] = engine;
- }
- }
-}
-
-void
-FGControls::set_to_tank( int tank, int dest_tank )
-{
- if ( tank == ALL_TANKS ) {
- for ( int i = 0; i < MAX_TANKS; i++ ) {
- to_tank[i] = dest_tank;
- }
- } else {
- if ( (tank >= 0) && (tank < MAX_TANKS) ) {
- to_tank[tank] = dest_tank;
- }
- }
-}
-
-void
-FGControls::set_boost_pump( int index, bool val )
-{
- if ( index == -1 ) {
- for ( int i = 0; i < (MAX_TANKS * MAX_BOOSTPUMPS); i++ ) {
- boost_pump[i] = val;
- }
- } else {
- if ( (index >= 0) && (index < (MAX_TANKS * MAX_BOOSTPUMPS)) ) {
- boost_pump[index] = val;
- }
- }
-}
-
-
-void
-FGControls::set_brake_left( double pos )
-{
- brake_left = pos;
- CLAMP(&brake_left, 0.0, 1.0);
-}
-
-void
-FGControls::move_brake_left( double amt )
-{
- brake_left += amt;
- CLAMP( &brake_left, 0.0, 1.0 );
-}
-
-void
-FGControls::set_brake_right( double pos )
-{
- brake_right = pos;
- CLAMP(&brake_right, 0.0, 1.0);
-}
-
-void
-FGControls::move_brake_right( double amt )
-{
- brake_right += amt;
- CLAMP( &brake_right, 0.0, 1.0 );
-}
-
-void
-FGControls::set_copilot_brake_left( double pos )
-{
- copilot_brake_left = pos;
- CLAMP(&brake_left, 0.0, 1.0);
-}
-
-void
-FGControls::set_copilot_brake_right( double pos )
-{
- copilot_brake_right = pos;
- CLAMP(&brake_right, 0.0, 1.0);
-}
-
-void
-FGControls::set_brake_parking( double pos )
-{
- brake_parking = pos;
- CLAMP(&brake_parking, 0.0, 1.0);
-}
-
-void
-FGControls::set_steering( double angle )
-{
- steering = angle;
- CLAMP(&steering, -80.0, 80.0);
-}
-
-void
-FGControls::move_steering( double angle )
-{
- steering += angle;
- CLAMP(&steering, -80.0, 80.0);
-}
-
-void
-FGControls::set_gear_down( bool gear )
-{
- gear_down = gear;
-}
-
-void
-FGControls::set_antiskid( bool state )
-{
- antiskid = state;
-}
-
-void
-FGControls::set_tailhook( bool state )
-{
- tailhook = state;
-}
-
-void
-FGControls::set_launchbar( bool state )
-{
- launchbar = state;
-}
-
-void
-FGControls::set_catapult_launch_cmd( bool state )
-{
- catapult_launch_cmd = state;
-}
-
-void
-FGControls::set_tailwheel_lock( bool state )
-{
- tailwheel_lock = state;
-}
-
-
-void
-FGControls::set_alternate_extension( int wheel, bool val )
-{
- if ( wheel == ALL_WHEELS ) {
- for ( int i = 0; i < MAX_WHEELS; i++ ) {
- alternate_extension[i] = val;
- }
- } else {
- if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
- alternate_extension[wheel] = val;
- }
- }
-}
-
-void
-FGControls::set_wing_heat( bool state )
-{
- wing_heat = state;
-}
-
-void
-FGControls::set_pitot_heat( bool state )
-{
- pitot_heat = state;
-}
-
-void
-FGControls::set_wiper( int state )
-{
- wiper = state;
-}
-
-void
-FGControls::set_window_heat( bool state )
-{
- window_heat = state;
-}
-
-void
-FGControls::set_carb_heat( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- carb_heat[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- carb_heat[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_inlet_heat( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- inlet_heat[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- inlet_heat[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_engine_pump( int system, bool val )
-{
- if ( system == ALL_HYD_SYSTEMS ) {
- for ( int i = 0; i < MAX_HYD_SYSTEMS; i++ ) {
- engine_pump[i] = val;
- }
- } else {
- if ( (system >= 0) && (system < MAX_HYD_SYSTEMS) ) {
- engine_pump[system] = val;
- }
- }
-}
-
-void
-FGControls::set_electric_pump( int system, bool val )
-{
- if ( system == ALL_HYD_SYSTEMS ) {
- for ( int i = 0; i < MAX_HYD_SYSTEMS; i++ ) {
- electric_pump[i] = val;
- }
- } else {
- if ( (system >= 0) && (system < MAX_HYD_SYSTEMS) ) {
- electric_pump[system] = val;
- }
- }
-}
-
-void
-FGControls::set_battery_switch( bool state )
-{
- battery_switch = state;
-}
-
-void
-FGControls::set_external_power( bool state )
-{
- external_power = state;
-}
-
-void
-FGControls::set_APU_generator( bool state )
-{
- APU_generator = state;
-}
-
-void
-FGControls::set_generator_breaker( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- generator_breaker[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- generator_breaker[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_bus_tie( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- bus_tie[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- bus_tie[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_APU_bleed( bool state )
-{
- APU_bleed = state;
-}
-
-void
-FGControls::set_engine_bleed( int engine, bool val )
-{
- if ( engine == ALL_ENGINES ) {
- for ( int i = 0; i < MAX_ENGINES; i++ ) {
- engine_bleed[i] = val;
- }
- } else {
- if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
- engine_bleed[engine] = val;
- }
- }
-}
-
-void
-FGControls::set_mode( int new_mode )
-{
- mode = new_mode;
-}
-
-void
-FGControls::set_outflow_valve( double pos )
-{
- outflow_valve = pos;
- CLAMP( &outflow_valve, 0.0, 1.0 );
-}
-
-void
-FGControls::move_outflow_valve( double amt )
-{
- outflow_valve += amt;
- CLAMP( &outflow_valve, 0.0, 1.0 );
-}
-
-void
-FGControls::set_dump( bool state )
-{
- dump = state;
-}
-
-void
-FGControls::set_pack_on( int pack, bool val )
-{
- if ( pack == ALL_PACKS ) {
- for ( int i = 0; i < MAX_PACKS; i++ ) {
- pack_on[i] = val;
- }
- } else {
- if ( (pack >= 0) && (pack < MAX_PACKS) ) {
- pack_on[pack] = val;
- }
- }
-}
-
-void
-FGControls::set_landing_lights( bool state )
-{
- landing_lights = state;
-}
-
-void
-FGControls::set_turn_off_lights( bool state )
-{
- turn_off_lights = state;
-}
-
-void
-FGControls::set_taxi_light( bool state )
-{
- taxi_light = state;
-}
-
-void
-FGControls::set_logo_lights( bool state )
-{
- logo_lights = state;
-}
-
-void
-FGControls::set_nav_lights( bool state )
-{
- nav_lights = state;
-}
-
-void
-FGControls::set_beacon( bool state )
-{
- beacon = state;
-}
-
-void
-FGControls::set_strobe( bool state )
-{
- strobe = state;
-}
-
-void
-FGControls::set_panel_norm( double intensity )
-{
- panel_norm = intensity;
- CLAMP( &panel_norm, 0.0, 1.0 );
-}
-
-void
-FGControls::move_panel_norm( double amt )
-{
- panel_norm += amt;
- CLAMP( &panel_norm, 0.0, 1.0 );
-}
-
-void
-FGControls::set_instruments_norm( double intensity )
-{
- instruments_norm = intensity;
- CLAMP( &instruments_norm, 0.0, 1.0 );
-}
-
-void
-FGControls::move_instruments_norm( double amt )
-{
- instruments_norm += amt;
- CLAMP( &instruments_norm, 0.0, 1.0 );
-}
-
-void
-FGControls::set_dome_norm( double intensity )
-{
- dome_norm = intensity;
- CLAMP( &dome_norm, 0.0, 1.0 );
-}
-
-void
-FGControls::move_dome_norm( double amt )
-{
- dome_norm += amt;
- CLAMP( &dome_norm, 0.0, 1.0 );
-}
-
-#ifdef FG_HAVE_ARMAMENT
-
-void
-FGControls::set_master_arm( bool val )
-{
- master_arm = val;
-}
-
-void
-FGControls::set_station_select( int station )
-{
- station_select = station;
- CLAMP( &station_select, 0, MAX_STATIONS );
-}
-
-void
-FGControls::set_release_ALL( bool val )
-{
- release_ALL = val;
-}
-
-void
-FGControls::set_stick_size( int station, int size )
-{
- if ( station == ALL_STATIONS ) {
- for ( int i = 0; i < MAX_STATIONS; i++ ) {
- stick_size[i] = size;
- CLAMP( &stick_size[i], 1, 20 );
- }
- } else {
- if ( (station >= 0) && (station < MAX_STATIONS) ) {
- stick_size[station] = size;
- CLAMP( &stick_size[station], 1, 20 );
- }
- }
-}
-
-void
-FGControls::set_release_stick( int station, bool val )
-{
- if ( station == ALL_STATIONS ) {
- for ( int i = 0; i < MAX_STATIONS; i++ ) {
- release_stick[i] = val;
- }
- } else {
- if ( (station >= 0) && (station < MAX_STATIONS) ) {
- release_stick[station] = val;
- }
- }
-}
-
-void
-FGControls::set_release_all( int station, bool val )
-{
- if ( station == ALL_STATIONS ) {
- for ( int i = 0; i < MAX_STATIONS; i++ ) {
- release_all[i] = val;
- }
- } else {
- if ( (station >= 0) && (station < MAX_STATIONS) ) {
- release_all[station] = val;
- }
- }
-}
-
-void
-FGControls::set_jettison_all( int station, bool val )
-{
- if ( station == ALL_STATIONS ) {
- for ( int i = 0; i < MAX_STATIONS; i++ ) {
- jettison_all[i] = val;
- }
- } else {
- if ( (station >= 0) && (station < MAX_STATIONS) ) {
- jettison_all[station] = val;
- }
- }
-}
-
-#endif
-
-void
-FGControls::set_vertical_adjust( double pos )
-{
- vertical_adjust = pos;
- CLAMP( &vertical_adjust, -1.0, 1.0 );
-}
-
-void
-FGControls::move_vertical_adjust( double amt )
-{
- vertical_adjust += amt;
- CLAMP( &vertical_adjust, -1.0, 1.0 );
-}
-
-void
-FGControls::set_fore_aft_adjust( double pos )
-{
- fore_aft_adjust = pos;
- CLAMP( &fore_aft_adjust, -1.0, 1.0 );
-}
-
-void
-FGControls::move_fore_aft_adjust( double amt )
-{
- fore_aft_adjust += amt;
- CLAMP( &fore_aft_adjust, -1.0, 1.0 );
-}
-
-void
-FGControls::set_ejection_seat( int which_seat, bool val )
-{
- if ( which_seat == ALL_EJECTION_SEATS ) {
- for ( int i = 0; i < MAX_EJECTION_SEATS; i++ ) {
- eject[i] = val;
- }
- } else {
- if ( (which_seat >= 0) && (which_seat <= MAX_EJECTION_SEATS) ) {
- if ( eseat_status[which_seat] == SEAT_SAFED ||
- eseat_status[which_seat] == SEAT_FAIL )
- {
- // we can never eject if SEAT_SAFED or SEAT_FAIL
- val = false;
- }
-
- eject[which_seat] = val;
- }
- }
-}
-
-void
-FGControls::set_eseat_status( int which_seat, int val )
-{
- if ( which_seat == ALL_EJECTION_SEATS ) {
- for ( int i = 0; i < MAX_EJECTION_SEATS; i++ ) {
- eseat_status[i] = val;
- }
- } else {
- if ( (which_seat >=0) && (which_seat <= MAX_EJECTION_SEATS) ) {
- eseat_status[which_seat] = val;
- }
- }
-}
-
-void
-FGControls::set_cmd_selector_valve( int val )
-{
- cmd_selector_valve = val;
-}
-
-
-void
-FGControls::set_off_start_run( int pos )
-{
- off_start_run = pos;
- CLAMP( &off_start_run, 0, 3 );
-}
-
-void
-FGControls::set_APU_fire_switch( bool val )
-{
- APU_fire_switch = val;
-}
-
-void
-FGControls::set_autothrottle_arm( bool val )
-{
- autothrottle_arm = val;
-}
-
-void
-FGControls::set_autothrottle_engage( bool val )
-{
- autothrottle_engage = val;
-}
-
-void
-FGControls::set_heading_select( double heading )
-{
- heading_select = heading;
- CLAMP( &heading_select, 0.0, 360.0 );
-}
-
-void
-FGControls::move_heading_select( double amt )
-{
- heading_select += amt;
- CLAMP( &heading_select, 0.0, 360.0 );
-}
-
-void
-FGControls::set_altitude_select( double altitude )
-{
- altitude_select = altitude;
- CLAMP( &altitude_select, -1000.0, 100000.0 );
-}
-
-void
-FGControls::move_altitude_select( double amt )
-{
- altitude_select += amt;
- CLAMP( &altitude_select, -1000.0, 100000.0 );
-}
-
-void
-FGControls::set_bank_angle_select( double angle )
-{
- bank_angle_select = angle;
- CLAMP( &bank_angle_select, 10.0, 30.0 );
-}
-
-void
-FGControls::move_bank_angle_select( double amt )
-{
- bank_angle_select += amt;
- CLAMP( &bank_angle_select, 10.0, 30.0 );
-}
-
-void
-FGControls::set_vertical_speed_select( double speed )
-{
- vertical_speed_select = speed;
- CLAMP( &vertical_speed_select, -3000.0, 4000.0 );
-}
-
-void
-FGControls::move_vertical_speed_select( double amt )
-{
- vertical_speed_select += amt;
- CLAMP( &vertical_speed_select, -3000.0, 4000.0 );
-}
-
-void
-FGControls::set_speed_select( double speed )
-{
- speed_select = speed;
- CLAMP( &speed_select, 60.0, 400.0 );
-}
-
-void
-FGControls::move_speed_select( double amt )
-{
- speed_select += amt;
- CLAMP( &speed_select, 60.0, 400.0 );
-}
-
-void
-FGControls::set_mach_select( double mach )
-{
- mach_select = mach;
- CLAMP( &mach_select, 0.4, 4.0 );
-}
-
-void
-FGControls::move_mach_select( double amt )
-{
- mach_select += amt;
- CLAMP( &mach_select, 0.4, 4.0 );
-}
-
-void
-FGControls::set_vertical_mode( int mode )
-{
- vertical_mode = mode;
- CLAMP( &vertical_mode, 0, 4 );
-}
-
-void
-FGControls::set_lateral_mode( int mode )
-{
- lateral_mode = mode;
- CLAMP( &lateral_mode, 0, 4 );
-}
-
-void
-FGControls::set_autopilot_engage( int ap, bool val )
-{
- if ( ap == ALL_AUTOPILOTS ) {
- for ( int i = 0; i < MAX_AUTOPILOTS; i++ ) {
- autopilot_engage[i] = val;
- }
- } else {
- if ( (ap >= 0) && (ap < MAX_AUTOPILOTS) ) {
- autopilot_engage[ap] = val;
- }
- }
-}
+++ /dev/null
-// controls.hxx -- defines a standard interface to all flight sim controls
-//
-// Written by Curtis Olson, started May 1997.
-//
-// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-
-
-#ifndef _CONTROLS_HXX
-#define _CONTROLS_HXX
-
-#include <simgear/props/props.hxx>
-#include <simgear/structure/subsystem_mgr.hxx>
-
-#include <Main/globals.hxx>
-
-#ifndef __cplusplus
-# error This library requires C++
-#endif
-
-
-// Define a structure containing the control parameters
-
-class FGControls : public SGSubsystem
-{
-
-public:
-
- enum {
- ALL_ENGINES = -1,
- MAX_ENGINES = 10
- };
-
- enum {
- ALL_WHEELS = -1,
- MAX_WHEELS = 3
- };
-
- enum {
- ALL_TANKS = -1,
- MAX_TANKS = 8
- };
-
- enum {
- ALL_BOOSTPUMPS = -1,
- MAX_BOOSTPUMPS = 2
- };
-
- enum {
- ALL_HYD_SYSTEMS = -1,
- MAX_HYD_SYSTEMS = 4
- };
-
- enum {
- ALL_PACKS = -1,
- MAX_PACKS = 4
- };
-
- enum {
- ALL_LIGHTS = -1,
- MAX_LIGHTS = 4
- };
-
- enum {
- ALL_STATIONS = -1,
- MAX_STATIONS = 12
- };
-
- enum {
- ALL_AUTOPILOTS = -1,
- MAX_AUTOPILOTS = 3
- };
-
- enum {
- ALL_EJECTION_SEATS = -1,
- MAX_EJECTION_SEATS = 10
- };
-
- enum {
- SEAT_SAFED = -1,
- SEAT_ARMED = 0,
- SEAT_FAIL = 1
- };
-
- enum {
- CMD_SEL_NORM = -1,
- CMD_SEL_AFT = 0,
- CMD_SEL_SOLO = 1
- };
-
-private:
- // controls/flight/
- double aileron;
- double aileron_trim;
- double elevator;
- double elevator_trim;
- double rudder;
- double rudder_trim;
- double flaps;
- double slats;
- bool BLC; // Boundary Layer Control
- double spoilers;
- double speedbrake;
- double wing_sweep;
- bool wing_fold;
- bool drag_chute;
-
- // controls/engines/
- bool throttle_idle;
-
- // controls/engines/engine[n]/
- double throttle[MAX_ENGINES];
- bool starter[MAX_ENGINES];
- bool fuel_pump[MAX_ENGINES];
- bool fire_switch[MAX_ENGINES];
- bool fire_bottle_discharge[MAX_ENGINES];
- bool cutoff[MAX_ENGINES];
- double mixture[MAX_ENGINES];
- double prop_advance[MAX_ENGINES];
- int magnetos[MAX_ENGINES];
- bool nitrous_injection[MAX_ENGINES]; // War Emergency Power
- double cowl_flaps_norm[MAX_ENGINES];
- bool feather[MAX_ENGINES];
- int ignition[MAX_ENGINES];
- bool augmentation[MAX_ENGINES];
- bool reverser[MAX_ENGINES];
- bool water_injection[MAX_ENGINES];
- double condition[MAX_ENGINES]; // turboprop speed select
-
- // controls/fuel/
- bool dump_valve;
-
- // controls/fuel/tank[n]/
- bool fuel_selector[MAX_TANKS];
- int to_engine[MAX_TANKS];
- int to_tank[MAX_TANKS];
-
- // controls/fuel/tank[n]/pump[p]/
- bool boost_pump[MAX_TANKS * MAX_BOOSTPUMPS];
-
- // controls/gear/
- double brake_left;
- double brake_right;
- double copilot_brake_left;
- double copilot_brake_right;
- double brake_parking;
- double steering;
- bool gear_down;
- bool antiskid;
- bool tailhook;
- bool launchbar;
- bool catapult_launch_cmd;
- bool tailwheel_lock;
-
- // controls/gear/wheel[n]/
- bool alternate_extension[MAX_WHEELS];
-
- // controls/anti-ice/
- bool wing_heat;
- bool pitot_heat;
- int wiper;
- bool window_heat;
-
- // controls/anti-ice/engine[n]/
- bool carb_heat[MAX_ENGINES];
- bool inlet_heat[MAX_ENGINES];
-
- // controls/hydraulic/system[n]/
- bool engine_pump[MAX_HYD_SYSTEMS];
- bool electric_pump[MAX_HYD_SYSTEMS];
-
- // controls/electric/
- bool battery_switch;
- bool external_power;
- bool APU_generator;
-
- // controls/electric/engine[n]/
- bool generator_breaker[MAX_ENGINES];
- bool bus_tie[MAX_ENGINES];
-
- // controls/pneumatic/
- bool APU_bleed;
-
- // controls/pneumatic/engine[n]/
- bool engine_bleed[MAX_ENGINES];
-
- // controls/pressurization/
- int mode;
- bool dump;
- double outflow_valve;
-
- // controls/pressurization/pack[n]/
- bool pack_on[MAX_PACKS];
-
- // controls/lighting/
- bool landing_lights;
- bool turn_off_lights;
- bool taxi_light;
- bool logo_lights;
- bool nav_lights;
- bool beacon;
- bool strobe;
- double panel_norm;
- double instruments_norm;
- double dome_norm;
-
- // controls/armament/
- bool master_arm;
- int station_select;
- bool release_ALL;
-
- // controls/armament/station[n]/
- int stick_size[MAX_STATIONS];
- bool release_stick[MAX_STATIONS];
- bool release_all[MAX_STATIONS];
- bool jettison_all[MAX_STATIONS];
-
- // controls/seat/
- double vertical_adjust;
- double fore_aft_adjust;
- bool eject[MAX_EJECTION_SEATS];
- int eseat_status[MAX_EJECTION_SEATS];
- int cmd_selector_valve;
-
- // controls/APU/
- int off_start_run;
- bool APU_fire_switch;
-
- // controls/autoflight/autopilot[n]/
- bool autopilot_engage[MAX_AUTOPILOTS];
-
- // controls/autoflight/
- bool autothrottle_arm;
- bool autothrottle_engage;
- double heading_select;
- double altitude_select;
- double bank_angle_select;
- double vertical_speed_select;
- double speed_select;
- double mach_select;
- int vertical_mode;
- int lateral_mode;
-
-
- SGPropertyNode * auto_coordination;
-
-public:
-
- FGControls();
- ~FGControls();
-
- // Implementation of SGSubsystem.
- void init ();
- void bind ();
- void unbind ();
- void update (double dt);
-
- // Reset function
- void reset_all(void);
-
- // Query functions
- // controls/flight/
- inline double get_aileron() const { return aileron; }
- inline double get_aileron_trim() const { return aileron_trim; }
- inline double get_elevator() const { return elevator; }
- inline double get_elevator_trim() const { return elevator_trim; }
- inline double get_rudder() const { return rudder; }
- inline double get_rudder_trim() const { return rudder_trim; }
- inline double get_flaps() const { return flaps; }
- inline double get_slats() const { return slats; }
- inline bool get_BLC() const { return BLC; }
- inline double get_spoilers() const { return spoilers; }
- inline double get_speedbrake() const { return speedbrake; }
- inline double get_wing_sweep() const { return wing_sweep; }
- inline bool get_wing_fold() const { return wing_fold; }
- inline bool get_drag_chute() const { return drag_chute; }
-
- // controls/engines/
- inline bool get_throttle_idle() const { return throttle_idle; }
-
- // controls/engines/engine[n]/
- inline double get_throttle(int engine) const { return throttle[engine]; }
- inline bool get_starter(int engine) const { return starter[engine]; }
- inline bool get_fuel_pump(int engine) const { return fuel_pump[engine]; }
- inline bool get_fire_switch(int engine) const { return fire_switch[engine]; }
- inline bool get_fire_bottle_discharge(int engine) const {
- return fire_bottle_discharge[engine];
- }
- inline bool get_cutoff(int engine) const { return cutoff[engine]; }
- inline double get_mixture(int engine) const { return mixture[engine]; }
- inline double get_prop_advance(int engine) const {
- return prop_advance[engine];
- }
- inline int get_magnetos(int engine) const { return magnetos[engine]; }
- inline bool get_nitrous_injection(int engine) const {
- return nitrous_injection[engine];
- }
- inline double get_cowl_flaps_norm(int engine) const {
- return cowl_flaps_norm[engine];
- }
- inline bool get_feather(int engine) const { return feather[engine]; }
- inline int get_ignition(int engine) const { return ignition[engine]; }
- inline bool get_augmentation(int engine) const { return augmentation[engine]; }
- inline bool get_reverser(int engine) const { return reverser[engine]; }
- inline bool get_water_injection(int engine) const {
- return water_injection[engine];
- }
- inline double get_condition(int engine) const { return condition[engine]; }
-
- // controls/fuel/
- inline bool get_dump_valve() const { return dump_valve; }
-
- // controls/fuel/tank[n]/
- inline bool get_fuel_selector(int tank) const {
- return fuel_selector[tank];
- }
- inline int get_to_engine(int tank) const { return to_engine[tank]; }
- inline int get_to_tank(int tank) const { return to_tank[tank]; }
-
- // controls/fuel/tank[n]/pump[p]/
- inline bool get_boost_pump(int index) const {
- return boost_pump[index];
- }
-
- // controls/gear/
- inline double get_brake_left() const { return brake_left; }
- inline double get_brake_right() const { return brake_right; }
- inline double get_copilot_brake_left() const { return copilot_brake_left; }
- inline double get_copilot_brake_right() const { return copilot_brake_right; }
- inline double get_brake_parking() const { return brake_parking; }
- inline double get_steering() const { return steering; }
- inline bool get_gear_down() const { return gear_down; }
- inline bool get_antiskid() const { return antiskid; }
- inline bool get_tailhook() const { return tailhook; }
- inline bool get_launchbar() const { return launchbar; }
- inline bool get_catapult_launch_cmd() const { return catapult_launch_cmd; }
- inline bool get_tailwheel_lock() const { return tailwheel_lock; }
-
- // controls/gear/wheel[n]/
- inline bool get_alternate_extension(int wheel) const {
- return alternate_extension[wheel];
- }
-
- // controls/anti-ice/
- inline bool get_wing_heat() const { return wing_heat; }
- inline bool get_pitot_heat() const { return pitot_heat; }
- inline int get_wiper() const { return wiper; }
- inline bool get_window_heat() const { return window_heat; }
-
- // controls/anti-ice/engine[n]/
- inline bool get_carb_heat(int engine) const { return carb_heat[engine]; }
- inline bool get_inlet_heat(int engine) const { return inlet_heat[engine]; }
-
- // controls/hydraulic/system[n]/
- inline bool get_engine_pump(int system) const { return engine_pump[system]; }
- inline bool get_electric_pump(int system) const { return electric_pump[system]; }
-
- // controls/electric/
- inline bool get_battery_switch() const { return battery_switch; }
- inline bool get_external_power() const { return external_power; }
- inline bool get_APU_generator() const { return APU_generator; }
-
- // controls/electric/engine[n]/
- inline bool get_generator_breaker(int engine) const {
- return generator_breaker[engine];
- }
- inline bool get_bus_tie(int engine) const { return bus_tie[engine]; }
-
- // controls/pneumatic/
- inline bool get_APU_bleed() const { return APU_bleed; }
-
- // controls/pneumatic/engine[n]/
- inline bool get_engine_bleed(int engine) const { return engine_bleed[engine]; }
-
- // controls/pressurization/
- inline int get_mode() const { return mode; }
- inline double get_outflow_valve() const { return outflow_valve; }
- inline bool get_dump() const { return dump; }
-
- // controls/pressurization/pack[n]/
- inline bool get_pack_on(int pack) const { return pack_on[pack]; }
-
- // controls/lighting/
- inline bool get_landing_lights() const { return landing_lights; }
- inline bool get_turn_off_lights() const { return turn_off_lights; }
- inline bool get_taxi_light() const { return taxi_light; }
- inline bool get_logo_lights() const { return logo_lights; }
- inline bool get_nav_lights() const { return nav_lights; }
- inline bool get_beacon() const { return beacon; }
- inline bool get_strobe() const { return strobe; }
- inline double get_panel_norm() const { return panel_norm; }
- inline double get_instruments_norm() const { return instruments_norm; }
- inline double get_dome_norm() const { return dome_norm; }
-
-#ifdef FG_HAVE_ARMAMENT
- // controls/armament/
- inline bool get_master_arm() const { return master_arm; }
- inline int get_station_select() const { return station_select; }
- inline bool get_release_ALL() const { return release_ALL; }
-
- // controls/armament/station[n]/
- inline int get_stick_size(int station) const { return stick_size[station]; }
- inline bool get_release_stick(int station) const { return release_stick[station]; }
- inline bool get_release_all(int station) const { return release_all[station]; }
- inline bool get_jettison_all(int station) const { return jettison_all[station]; }
-#endif
-
- // controls/seat/
- inline double get_vertical_adjust() const { return vertical_adjust; }
- inline double get_fore_aft_adjust() const { return fore_aft_adjust; }
- inline bool get_ejection_seat( int which_seat ) const {
- return eject[which_seat];
- }
- inline int get_eseat_status( int which_seat ) const {
- return eseat_status[which_seat];
- }
- inline int get_cmd_selector_valve() const { return cmd_selector_valve; }
-
-
- // controls/APU/
- inline int get_off_start_run() const { return off_start_run; }
- inline bool get_APU_fire_switch() const { return APU_fire_switch; }
-
- // controls/autoflight/
- inline bool get_autothrottle_arm() const { return autothrottle_arm; }
- inline bool get_autothrottle_engage() const { return autothrottle_engage; }
- inline double get_heading_select() const { return heading_select; }
- inline double get_altitude_select() const { return altitude_select; }
- inline double get_bank_angle_select() const { return bank_angle_select; }
- inline double get_vertical_speed_select() const {
- return vertical_speed_select;
- }
- inline double get_speed_select() const { return speed_select; }
- inline double get_mach_select() const { return mach_select; }
- inline int get_vertical_mode() const { return vertical_mode; }
- inline int get_lateral_mode() const { return lateral_mode; }
-
- // controls/autoflight/autopilot[n]/
- inline bool get_autopilot_engage(int ap) const {
- return autopilot_engage[ap];
- }
-
-
- // Update functions
- // controls/flight/
- void set_aileron( double pos );
- void move_aileron( double amt );
- void set_aileron_trim( double pos );
- void move_aileron_trim( double amt );
- void set_elevator( double pos );
- void move_elevator( double amt );
- void set_elevator_trim( double pos );
- void move_elevator_trim( double amt );
- void set_rudder( double pos );
- void move_rudder( double amt );
- void set_rudder_trim( double pos );
- void move_rudder_trim( double amt );
- void set_flaps( double pos );
- void move_flaps( double amt );
- void set_slats( double pos );
- void move_slats( double amt );
- void set_BLC( bool val );
- void set_spoilers( double pos );
- void move_spoilers( double amt );
- void set_speedbrake( double pos );
- void move_speedbrake( double amt );
- void set_wing_sweep( double pos );
- void move_wing_sweep( double amt );
- void set_wing_fold( bool val );
- void set_drag_chute( bool val );
-
- // controls/engines/
- void set_throttle_idle( bool val );
-
- // controls/engines/engine[n]/
- void set_throttle( int engine, double pos );
- void move_throttle( int engine, double amt );
- void set_starter( int engine, bool flag );
- void set_fuel_pump( int engine, bool val );
- void set_fire_switch( int engine, bool val );
- void set_fire_bottle_discharge( int engine, bool val );
- void set_cutoff( int engine, bool val );
- void set_mixture( int engine, double pos );
- void move_mixture( int engine, double amt );
- void set_prop_advance( int engine, double pos );
- void move_prop_advance( int engine, double amt );
- void set_magnetos( int engine, int pos );
- void move_magnetos( int engine, int amt );
- void set_nitrous_injection( int engine, bool val );
- void set_cowl_flaps_norm( int engine, double pos );
- void move_cowl_flaps_norm( int engine, double amt );
- void set_feather( int engine, bool val );
- void set_ignition( int engine, int val );
- void set_augmentation( int engine, bool val );
- void set_reverser( int engine, bool val );
- void set_water_injection( int engine, bool val );
- void set_condition( int engine, double val );
-
- // controls/fuel
- void set_dump_valve( bool val );
-
- // controls/fuel/tank[n]/
- void set_fuel_selector( int tank, bool pos );
- void set_to_engine( int tank, int engine );
- void set_to_tank( int tank, int dest_tank );
-
- // controls/fuel/tank[n]/pump[p]
- void set_boost_pump( int index, bool val );
-
- // controls/gear/
- void set_brake_left( double pos );
- void move_brake_left( double amt );
- void set_brake_right( double pos );
- void move_brake_right( double amt );
- void set_copilot_brake_left( double pos );
- void set_copilot_brake_right( double pos );
- void set_brake_parking( double pos );
- void set_steering( double pos );
- void move_steering( double amt );
- void set_gear_down( bool gear );
- void set_antiskid( bool val );
- void set_tailhook( bool val );
- void set_launchbar( bool val );
- void set_catapult_launch_cmd( bool val );
- void set_tailwheel_lock( bool val );
-
- // controls/gear/wheel[n]/
- void set_alternate_extension( int wheel, bool val );
-
- // controls/anti-ice/
- void set_wing_heat( bool val );
- void set_pitot_heat( bool val );
- void set_wiper( int speed );
- void set_window_heat( bool val );
-
- // controls/anti-ice/engine[n]/
- void set_carb_heat( int engine, bool val );
- void set_inlet_heat( int engine, bool val );
-
- // controls/hydraulic/system[n]/
- void set_engine_pump( int system, bool val );
- void set_electric_pump( int system, bool val );
-
- // controls/electric/
- void set_battery_switch( bool val );
- void set_external_power( bool val );
- void set_APU_generator( bool val );
-
- // controls/electric/engine[n]/
- void set_generator_breaker( int engine, bool val );
- void set_bus_tie( int engine, bool val );
-
- // controls/pneumatic/
- void set_APU_bleed( bool val );
-
- // controls/pneumatic/engine[n]/
- void set_engine_bleed( int engine, bool val );
-
- // controls/pressurization/
- void set_mode( int mode );
- void set_outflow_valve( double pos );
- void move_outflow_valve( double amt );
- void set_dump( bool val );
-
- // controls/pressurization/pack[n]/
- void set_pack_on( int pack, bool val );
-
- // controls/lighting/
- void set_landing_lights( bool val );
- void set_turn_off_lights( bool val );
- void set_taxi_light( bool val );
- void set_logo_lights( bool val );
- void set_nav_lights( bool val );
- void set_beacon( bool val );
- void set_strobe( bool val );
- void set_panel_norm( double intensity );
- void move_panel_norm( double amt );
- void set_instruments_norm( double intensity );
- void move_instruments_norm( double amt );
- void set_dome_norm( double intensity );
- void move_dome_norm( double amt );
-
-#ifdef FG_HAVE_ARMAMENT
- // controls/armament/
- void set_master_arm( bool val );
- void set_station_select( int station );
- void set_release_ALL( bool val );
-
- // controls/armament/station[n]/
- void set_stick_size( int station, int size );
- void set_release_stick( int station, bool val );
- void set_release_all( int station, bool val );
- void set_jettison_all( int station, bool val );
-#endif
-
- // controls/seat/
- void set_vertical_adjust( double pos );
- void move_vertical_adjust( double amt );
- void set_fore_aft_adjust( double pos );
- void move_fore_aft_adjust( double amt );
- void set_ejection_seat( int which_seat, bool val );
- void set_eseat_status( int which_seat, int val );
- void set_cmd_selector_valve( int val );
-
- // controls/APU/
- void set_off_start_run( int pos );
- void set_APU_fire_switch( bool val );
-
- // controls/autoflight/
- void set_autothrottle_arm( bool val );
- void set_autothrottle_engage( bool val );
- void set_heading_select( double heading );
- void move_heading_select( double amt );
- void set_altitude_select( double altitude );
- void move_altitude_select( double amt );
- void set_bank_angle_select( double angle );
- void move_bank_angle_select( double amt );
- void set_vertical_speed_select( double vs );
- void move_vertical_speed_select( double amt );
- void set_speed_select( double speed );
- void move_speed_select( double amt );
- void set_mach_select( double mach );
- void move_mach_select( double amt );
- void set_vertical_mode( int mode );
- void set_lateral_mode( int mode );
-
- // controls/autoflight/autopilot[n]/
- void set_autopilot_engage( int ap, bool val );
-
-};
-
-
-#endif // _CONTROLS_HXX
-
-
#include <simgear/misc/sg_path.hxx>
#include <Aircraft/aircraft.hxx>
-#include <Controls/controls.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <FDM/flight.hxx>
#include <Aircraft/aircraft.hxx>
-#include <Controls/controls.hxx>
+#include <Aircraft/controls.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <simgear/scene/model/placement.hxx>
#include <Aircraft/aircraft.hxx>
-#include <Controls/controls.hxx>
+#include <Aircraft/controls.hxx>
#include <FDM/flight.hxx>
#include <FDM/UIUCModel/uiuc_aircraft.h>
#include <Main/fg_props.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
-#include <Controls/controls.hxx>
+#include <Aircraft/controls.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <simgear/io/sg_socket.hxx>
#include <simgear/constants.h>
-#include <Controls/controls.hxx>
+#include <Aircraft/controls.hxx>
+#include <Scenery/scenery.hxx> //to pass ground elevation to FDM
#include <Main/globals.hxx>
-
#include <Main/fg_props.hxx> //to get ID of window (left/right or center)
-#include <Scenery/scenery.hxx> //to pass ground elevation to FDM
#include "ADA.hxx"
#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
-#include <Controls/controls.hxx>
+#include <Aircraft/controls.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Include/general.hxx>
#include <Aircraft/aircraft.hxx>
+#include <Aircraft/controls.hxx>
#include <Airports/simple.hxx>
#include <Autopilot/auto_gui.hxx>
#include <Cockpit/panel.hxx>
-#include <Controls/controls.hxx>
#include <FDM/flight.hxx>
#include <Main/main.hxx>
#include <Main/fg_init.hxx>
message = "Snapshot saved to \"";
message += filename;
- message += '".';
+ message += "\".";
mkDialog (message.c_str());
free(tile);
#include <Include/general.hxx>
#include <Aircraft/aircraft.hxx>
+#include <Aircraft/controls.hxx>
#include <Airports/simple.hxx>
#include <Autopilot/auto_gui.hxx>
#include <Cockpit/panel.hxx>
-#include <Controls/controls.hxx>
#include <FDM/flight.hxx>
#include <Main/fg_init.hxx>
#include <Main/fg_props.hxx>
$(top_builddir)/src/ATC/libATC.a \
$(top_builddir)/src/Cockpit/libCockpit.a \
$(top_builddir)/src/Cockpit/built_in/libBuilt_in.a \
- $(top_builddir)/src/Controls/libControls.a \
$(top_builddir)/src/FDM/libFlight.a \
$(top_builddir)/src/FDM/Balloon/libBalloon.a \
$(top_builddir)/src/FDM/ExternalNet/libExternalNet.a \
$(top_builddir)/src/Sound/libSound.a \
$(top_builddir)/src/Airports/libAirports.a \
$(MPLAYER_LIBS) \
- $(top_builddir)/src/Replay/libReplay.a \
$(top_builddir)/src/Systems/libSystems.a \
$(top_builddir)/src/Time/libTime.a \
$(top_builddir)/src/Traffic/libTraffic.a \
#include <GUI/gui.h>
#include <GUI/new_gui.hxx>
#include <GUI/dialog.hxx>
-#include <Replay/replay.hxx>
+#include <Aircraft/replay.hxx>
#include <Scenery/tilemgr.hxx>
#if defined(HAVE_PLIB_PSL)
# include <Scripting/scriptmgr.hxx>
#include <simgear/timing/lowleveltime.h>
#include <Aircraft/aircraft.hxx>
+#include <Aircraft/replay.hxx>
#include <Airports/apt_loader.hxx>
#include <Airports/runways.hxx>
#include <Airports/simple.hxx>
#include <AIModel/AIManager.hxx>
#include <Navaids/navdb.hxx>
#include <Navaids/navlist.hxx>
-#include <Replay/replay.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#include <Scripting/NasalSys.hxx>
#include <Traffic/TrafficMgr.hxx>
#ifdef FG_MPLAYER_AS
-#include <MultiPlayer/multiplaymgr.hpp>
+#include <MultiPlayer/multiplaymgr.hxx>
#endif
#include <Environment/environment_mgr.hxx>
#include <simgear/scene/sky/sky.hxx>
#include <Time/light.hxx>
#include <Include/general.hxx>
+#include <Aircraft/replay.hxx>
#include <Cockpit/cockpit.hxx>
#include <Cockpit/hud.hxx>
#include <Model/panelnode.hxx>
#include <ATC/ATCdisplay.hxx>
#include <ATC/ATCmgr.hxx>
#include <ATC/AIMgr.hxx>
-#include <Replay/replay.hxx>
#include <Time/tmp.hxx>
#include <Time/fg_timer.hxx>
#include <Environment/environment_mgr.hxx>
#include <GUI/new_gui.hxx>
#ifdef FG_MPLAYER_AS
-#include <MultiPlayer/multiplaymgr.hpp>
+#include <MultiPlayer/multiplaymgr.hxx>
#endif
#include <Time/light.hxx>
#include <Time/light.hxx>
#include <Aircraft/aircraft.hxx>
+// #include <Aircraft/replay.hxx>
#include <Cockpit/panel.hxx>
#include <Cockpit/cockpit.hxx>
#include <Cockpit/hud.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#include <ATC/ATCdisplay.hxx>
-#include <Replay/replay.hxx>
#include <GUI/new_gui.hxx>
#include "splash.hxx"
-if ENABLE_MPLAYER_AS
-MPLAYER_DIRS = MultiPlayer
-else
-MPLAYER_DIRS =
-endif
-
SUBDIRS = \
Include \
Aircraft \
ATC \
Autopilot \
Cockpit \
- Controls \
Environment \
FDM \
GUI \
AIModel \
Navaids \
Network \
- $(MPLAYER_DIRS) \
- Objects \
- Replay \
+ MultiPlayer \
Scenery \
Scripting \
Sound \
noinst_LIBRARIES = libMultiPlayer.a
-libMultiPlayer_a_SOURCES = multiplaymgr.cpp multiplaymgr.hpp mpplayer.cxx mpplayer.hxx mpmessages.hxx tiny_xdr.cpp tiny_xdr.hpp
+libMultiPlayer_a_SOURCES = multiplaymgr.cxx multiplaymgr.hxx mpplayer.cxx mpplayer.hxx mpmessages.hxx tiny_xdr.cxx tiny_xdr.hxx
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
*
******************************************************************/
-#include <simgear/compiler.h>
-#include "tiny_xdr.hpp"
#include <plib/sg.h>
+#include <simgear/compiler.h>
+#include "tiny_xdr.hxx"
// magic value for messages
const uint32_t MSG_MAGIC = 0x46474653; // "FGFS"
+++ /dev/null
-//////////////////////////////////////////////////////////////////////
-//
-// multiplaymgr.hpp
-//
-// Written by Duncan McCreanor, started February 2003.
-// duncan.mccreanor@airservicesaustralia.com
-//
-// Copyright (C) 2003 Airservices Australia
-// Copyright (C) 2005 Oliver Schroeder
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-//
-//////////////////////////////////////////////////////////////////////
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef FG_MPLAYER_AS
-
-#include <sys/types.h>
-#if !(defined(_MSC_VER) || defined(__MINGW32__))
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-#endif
-#include <plib/netSocket.h>
-#include <stdlib.h>
-#include <simgear/debug/logstream.hxx>
-#include <Main/fg_props.hxx>
-#include "multiplaymgr.hpp"
-#include "mpmessages.hxx"
-#include "mpplayer.hxx"
-#define MAX_PACKET_SIZE 1024
-
-// These constants are provided so that the ident
-// command can list file versions
-const char sMULTIPLAYMGR_BID[] =
- "$Id$";
-const char sMULTIPLAYMGR_HID[] = MULTIPLAYTXMGR_HID;
-
-//////////////////////////////////////////////////////////////////////
-//
-// MultiplayMgr constructor
-//
-//////////////////////////////////////////////////////////////////////
-FGMultiplayMgr::FGMultiplayMgr()
-{
- m_Initialised = false;
- m_LocalPlayer = NULL;
- m_RxAddress = "0";
- m_RxPort = 0;
- m_Initialised = false;
- m_HaveServer = false;
-} // FGMultiplayMgr::FGMultiplayMgr()
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// MultiplayMgr destructor
-//
-//////////////////////////////////////////////////////////////////////
-FGMultiplayMgr::~FGMultiplayMgr()
-{
- Close();
-} // FGMultiplayMgr::~FGMultiplayMgr()
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// Initialise object
-//
-//////////////////////////////////////////////////////////////////////
-bool
-FGMultiplayMgr::init (void)
-{
- string TxAddress; // Destination address
- int TxPort;
-
- //////////////////////////////////////////////////
- // Initialise object if not already done
- //////////////////////////////////////////////////
- if (m_Initialised)
- {
- SG_LOG( SG_NETWORK, SG_WARN,
- "FGMultiplayMgr::init - already initialised" );
- return (false);
- }
- //////////////////////////////////////////////////
- // Set members from property values
- //////////////////////////////////////////////////
- TxAddress = fgGetString ("/sim/multiplay/txhost");
- TxPort = fgGetInt ("/sim/multiplay/txport");
- m_Callsign = fgGetString ("/sim/multiplay/callsign");
- m_RxAddress = fgGetString ("/sim/multiplay/rxhost");
- m_RxPort = fgGetInt ("/sim/multiplay/rxport");
- if (m_RxPort <= 0)
- {
- m_RxPort = 5000;
- }
- if (m_Callsign == "")
- {
- // FIXME: use getpwuid
- m_Callsign = "JohnDoe";
- }
- if (m_RxAddress == "")
- {
- m_RxAddress = "127.0.0.1";
- }
- if ((TxPort > 0) && (TxAddress != ""))
- {
- m_HaveServer = true;
- m_Server.set (TxAddress.c_str(), TxPort);
- }
- SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-txaddress= "<<TxAddress);
- SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-txport= "<<TxPort );
- SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxaddress="<<m_RxAddress );
- SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxport= "<<m_RxPort);
- SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-callsign= "<<m_Callsign);
- m_DataSocket = new netSocket();
- if (!m_DataSocket->open(false))
- {
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::init - Failed to create data socket" );
- return (false);
- }
- m_DataSocket->setBlocking(false);
- m_DataSocket->setBroadcast(true);
- if (m_DataSocket->bind(m_RxAddress.c_str(), m_RxPort) != 0)
- {
- perror("bind");
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::Open - Failed to bind receive socket" );
- return (false);
- }
- m_LocalPlayer = new MPPlayer();
- if (!m_LocalPlayer->Open(m_RxAddress, m_RxPort, m_Callsign,
- fgGetString("/sim/model/path"), true))
- {
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::init - Failed to create local player" );
- return (false);
- }
- m_Initialised = true;
- return (true);
-} // FGMultiplayMgr::init()
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// Closes and deletes the local player object. Closes
-// and deletes the tx socket. Resets the object state to unitialised.
-//
-//////////////////////////////////////////////////////////////////////
-void
-FGMultiplayMgr::Close (void)
-{
- //////////////////////////////////////////////////
- // Delete local player
- //////////////////////////////////////////////////
- if (m_LocalPlayer)
- {
- delete m_LocalPlayer;
- m_LocalPlayer = NULL;
- }
- //////////////////////////////////////////////////
- // Delete any existing players
- //////////////////////////////////////////////////
- t_MPClientListIterator CurrentPlayer;
- t_MPClientListIterator P;
- CurrentPlayer = m_MPClientList.begin ();
- while (CurrentPlayer != m_MPClientList.end ())
- {
- P = CurrentPlayer;
- delete (*P);
- *P = 0;
- CurrentPlayer = m_MPClientList.erase (P);
- }
- //////////////////////////////////////////////////
- // Delete socket
- //////////////////////////////////////////////////
- if (m_DataSocket)
- {
- m_DataSocket->close();
- delete m_DataSocket;
- m_DataSocket = NULL;
- }
- m_Initialised = false;
-} // FGMultiplayMgr::Close(void)
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// Description: Sends the position data for the local position.
-//
-//////////////////////////////////////////////////////////////////////
-void
-FGMultiplayMgr::SendMyPosition
- (
- const sgQuat PlayerOrientation,
- const sgdVec3 PlayerPosition
- )
-{
- T_MsgHdr MsgHdr;
- T_PositionMsg PosMsg;
- char Msg[sizeof(T_MsgHdr) + sizeof(T_PositionMsg)];
-
- if ((! m_Initialised) || (! m_HaveServer))
- {
- if (! m_Initialised)
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::SendMyPosition - not initialised" );
- if (! m_HaveServer)
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::SendMyPosition - no server" );
- return;
- }
- m_LocalPlayer->SetPosition(PlayerOrientation, PlayerPosition);
- m_LocalPlayer->FillPosMsg(&MsgHdr, &PosMsg);
- memcpy(Msg, &MsgHdr, sizeof(T_MsgHdr));
- memcpy(Msg + sizeof(T_MsgHdr), &PosMsg, sizeof(T_PositionMsg));
- m_DataSocket->sendto (Msg,
- sizeof(T_MsgHdr) + sizeof(T_PositionMsg), 0, &m_Server);
-} // FGMultiplayMgr::SendMyPosition()
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// Name: SendTextMessage
-// Description: Sends a message to the player. The message must
-// contain a valid and correctly filled out header and optional
-// message body.
-//
-//////////////////////////////////////////////////////////////////////
-void
-FGMultiplayMgr::SendTextMessage
- (
- const string &MsgText
- ) const
-{
- T_MsgHdr MsgHdr;
- T_ChatMsg ChatMsg;
- unsigned int iNextBlockPosition = 0;
- char Msg[sizeof(T_MsgHdr) + sizeof(T_ChatMsg)];
-
- if ((! m_Initialised) || (! m_HaveServer))
- {
- return;
- }
- m_LocalPlayer->FillMsgHdr(&MsgHdr, CHAT_MSG_ID);
- //////////////////////////////////////////////////
- // Divide the text string into blocks that fit
- // in the message and send the blocks.
- //////////////////////////////////////////////////
- while (iNextBlockPosition < MsgText.length())
- {
- strncpy (ChatMsg.Text,
- MsgText.substr(iNextBlockPosition, MAX_CHAT_MSG_LEN - 1).c_str(),
- MAX_CHAT_MSG_LEN);
- ChatMsg.Text[MAX_CHAT_MSG_LEN - 1] = '\0';
- memcpy (Msg, &MsgHdr, sizeof(T_MsgHdr));
- memcpy (Msg + sizeof(T_MsgHdr), &ChatMsg, sizeof(T_ChatMsg));
- m_DataSocket->sendto (Msg,
- sizeof(T_MsgHdr) + sizeof(T_ChatMsg), 0, &m_Server);
- iNextBlockPosition += MAX_CHAT_MSG_LEN - 1;
- }
-} // FGMultiplayMgr::SendTextMessage ()
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// Name: ProcessData
-// Description: Processes data waiting at the receive socket. The
-// processing ends when there is no more data at the socket.
-//
-//////////////////////////////////////////////////////////////////////
-void
-FGMultiplayMgr::ProcessData (void)
-{
- char Msg[MAX_PACKET_SIZE]; // Buffer for received message
- int Bytes; // Bytes received
- T_MsgHdr* MsgHdr; // Pointer to header in received data
- netAddress SenderAddress;
-
- if (! m_Initialised)
- {
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::ProcessData - not initialised" );
- return;
- }
- //////////////////////////////////////////////////
- // Read the receive socket and process any data
- //////////////////////////////////////////////////
- do {
- //////////////////////////////////////////////////
- // Although the recv call asks for
- // MAX_PACKET_SIZE of data, the number of bytes
- // returned will only be that of the next
- // packet waiting to be processed.
- //////////////////////////////////////////////////
- Bytes = m_DataSocket->recvfrom (Msg, MAX_PACKET_SIZE, 0,
- &SenderAddress);
- //////////////////////////////////////////////////
- // no Data received
- //////////////////////////////////////////////////
- if (Bytes <= 0)
- {
- if (errno != EAGAIN)
- {
- perror("FGMultiplayMgr::MP_ProcessData");
- }
- return;
- }
- if (Bytes <= (int)sizeof(MsgHdr))
- {
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::MP_ProcessData - "
- << "received message with insufficient data" );
- return;
- }
- //////////////////////////////////////////////////
- // Read header
- //////////////////////////////////////////////////
- MsgHdr = (T_MsgHdr *)Msg;
- MsgHdr->Magic = XDR_decode_uint32 (MsgHdr->Magic);
- MsgHdr->Version = XDR_decode_uint32 (MsgHdr->Version);
- MsgHdr->MsgId = XDR_decode_uint32 (MsgHdr->MsgId);
- MsgHdr->MsgLen = XDR_decode_uint32 (MsgHdr->MsgLen);
- MsgHdr->ReplyPort = XDR_decode_uint32 (MsgHdr->ReplyPort);
- if (MsgHdr->Magic != MSG_MAGIC)
- {
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::MP_ProcessData - "
- << "message has invalid magic number!" );
- }
- if (MsgHdr->Version != PROTO_VER)
- {
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::MP_ProcessData - "
- << "message has invalid protocoll number!" );
- }
- //////////////////////////////////////////////////
- // Process the player data unless we generated it
- //////////////////////////////////////////////////
- if (m_Callsign == MsgHdr->Callsign)
- {
- return;
- }
- //////////////////////////////////////////////////
- // Process messages
- //////////////////////////////////////////////////
- switch(MsgHdr->MsgId)
- {
- case CHAT_MSG_ID:
- ProcessChatMsg ((char*) & Msg, SenderAddress);
- break;
- case POS_DATA_ID:
- ProcessPosMsg ((char*) & Msg, SenderAddress);
- break;
- default:
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::MP_ProcessData - "
- << "Unknown message Id received: "
- << MsgHdr->MsgId );
- break;
- } // switch
- } while (Bytes > 0);
-} // FGMultiplayMgr::ProcessData(void)
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// handle a position message
-//
-//////////////////////////////////////////////////////////////////////
-void
-FGMultiplayMgr::ProcessPosMsg
- (
- const char *Msg,
- netAddress & SenderAddress
- )
-{
- T_PositionMsg* PosMsg; // Pointer to position message in received data
- T_MsgHdr* MsgHdr; // Pointer to header in received data
- bool ActivePlayer;
- sgQuat Orientation;
- sgdVec3 Position;
- struct in_addr PlayerAddress;
- t_MPClientListIterator CurrentPlayer;
- int iPlayerCnt;
- char *sIpAddress;
-
- ActivePlayer = false;
- MsgHdr = (T_MsgHdr *)Msg;
- if (MsgHdr->MsgLen != sizeof(T_MsgHdr) + sizeof(T_PositionMsg))
- {
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::MP_ProcessData - "
- << "Position message received with insufficient data" );
- return;
- }
- PosMsg = (T_PositionMsg *)(Msg + sizeof(T_MsgHdr));
- Position[0] = XDR_decode_double (PosMsg->PlayerPosition[0]);
- Position[1] = XDR_decode_double (PosMsg->PlayerPosition[1]);
- Position[2] = XDR_decode_double (PosMsg->PlayerPosition[2]);
- Orientation[0] = XDR_decode_float (PosMsg->PlayerOrientation[0]);
- Orientation[1] = XDR_decode_float (PosMsg->PlayerOrientation[1]);
- Orientation[2] = XDR_decode_float (PosMsg->PlayerOrientation[2]);
- Orientation[3] = XDR_decode_float (PosMsg->PlayerOrientation[3]);
- //////////////////////////////////////////////////
- // Check if the player is already in the game
- // by using the Callsign
- //////////////////////////////////////////////////
- for (CurrentPlayer = m_MPClientList.begin ();
- CurrentPlayer != m_MPClientList.end ();
- CurrentPlayer++)
- {
- if ((*CurrentPlayer)->CompareCallsign(MsgHdr->Callsign))
- {
- // Player found. Update the data for the player.
- (*CurrentPlayer)->SetPosition(Orientation, Position);
- ActivePlayer = true;
- }
- } // for (...)
- if (ActivePlayer)
- { // nothing more to do
- return;
- }
- //////////////////////////////////////////////////
- // Player not active, so add as new player
- //////////////////////////////////////////////////
- MPPlayer* NewPlayer;
- NewPlayer = new MPPlayer;
- NewPlayer->Open(SenderAddress.getHost(), MsgHdr->ReplyPort,
- MsgHdr->Callsign, PosMsg->Model, false);
- NewPlayer->SetPosition(Orientation, Position);
- m_MPClientList.push_back (NewPlayer);
-} // FGMultiplayMgr::ProcessPosMsg()
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// handle a chat message
-// FIXME: display chat message withi flightgear
-//
-//////////////////////////////////////////////////////////////////////
-void
-FGMultiplayMgr::ProcessChatMsg
- (
- const char *Msg,
- netAddress & SenderAddress
- )
-{
- T_ChatMsg* ChatMsg; // Pointer to chat message in received data
- T_MsgHdr* MsgHdr; // Pointer to header in received data
-
- MsgHdr = (T_MsgHdr *)Msg;
- if (MsgHdr->MsgLen != sizeof(T_MsgHdr) + sizeof(T_ChatMsg))
- {
- SG_LOG( SG_NETWORK, SG_ALERT,
- "FGMultiplayMgr::MP_ProcessData - "
- << "Chat message received with insufficient data" );
- return;
- }
- ChatMsg = (T_ChatMsg *)(Msg + sizeof(T_MsgHdr));
- SG_LOG ( SG_NETWORK, SG_ALERT,
- "Chat [" << MsgHdr->Callsign << "]" << " " << ChatMsg->Text << endl);
-} // FGMultiplayMgr::ProcessChatMsg ()
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-//
-// For each active player, tell the player object
-// to update its position on the scene. If a player object
-// returns status information indicating that it has not
-// had an update for some time then the player is deleted.
-//
-//////////////////////////////////////////////////////////////////////
-void
-FGMultiplayMgr::Update (void)
-{
- MPPlayer::TPlayerDataState ePlayerDataState;
- t_MPClientListIterator CurrentPlayer;
-
- CurrentPlayer = m_MPClientList.begin ();
- while (CurrentPlayer != m_MPClientList.end ())
- {
- ePlayerDataState = (*CurrentPlayer)->Draw();
- //////////////////////////////////////////////////
- // If the player has not received an update for
- // some time then assume that the player has quit.
- //////////////////////////////////////////////////
- if (ePlayerDataState == MPPlayer::PLAYER_DATA_EXPIRED)
- {
- SG_LOG( SG_NETWORK, SG_ALERT, "FGMultiplayMgr::Update - "
- << "Deleting player from game. Callsign: "
- << (*CurrentPlayer)->Callsign() );
- t_MPClientListIterator P;
- P = CurrentPlayer;
- delete (*P);
- *P = 0;
- CurrentPlayer = m_MPClientList.erase (P);
- }
- else CurrentPlayer++;
- }
-} // FGMultiplayMgr::Update()
-//////////////////////////////////////////////////////////////////////
-
-#endif // FG_MPLAYER_AS
-
--- /dev/null
+//////////////////////////////////////////////////////////////////////
+//
+// multiplaymgr.hpp
+//
+// Written by Duncan McCreanor, started February 2003.
+// duncan.mccreanor@airservicesaustralia.com
+//
+// Copyright (C) 2003 Airservices Australia
+// Copyright (C) 2005 Oliver Schroeder
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef FG_MPLAYER_AS
+
+#include <sys/types.h>
+#if !(defined(_MSC_VER) || defined(__MINGW32__))
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
+#include <stdlib.h>
+
+#include <plib/netSocket.h>
+
+#include <simgear/debug/logstream.hxx>
+
+#include <Main/fg_props.hxx>
+#include "multiplaymgr.hxx"
+#include "mpmessages.hxx"
+#include "mpplayer.hxx"
+
+#define MAX_PACKET_SIZE 1024
+
+// These constants are provided so that the ident
+// command can list file versions
+const char sMULTIPLAYMGR_BID[] =
+ "$Id$";
+const char sMULTIPLAYMGR_HID[] = MULTIPLAYTXMGR_HID;
+
+//////////////////////////////////////////////////////////////////////
+//
+// MultiplayMgr constructor
+//
+//////////////////////////////////////////////////////////////////////
+FGMultiplayMgr::FGMultiplayMgr()
+{
+ m_Initialised = false;
+ m_LocalPlayer = NULL;
+ m_RxAddress = "0";
+ m_RxPort = 0;
+ m_Initialised = false;
+ m_HaveServer = false;
+} // FGMultiplayMgr::FGMultiplayMgr()
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// MultiplayMgr destructor
+//
+//////////////////////////////////////////////////////////////////////
+FGMultiplayMgr::~FGMultiplayMgr()
+{
+ Close();
+} // FGMultiplayMgr::~FGMultiplayMgr()
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// Initialise object
+//
+//////////////////////////////////////////////////////////////////////
+bool
+FGMultiplayMgr::init (void)
+{
+ string TxAddress; // Destination address
+ int TxPort;
+
+ //////////////////////////////////////////////////
+ // Initialise object if not already done
+ //////////////////////////////////////////////////
+ if (m_Initialised)
+ {
+ SG_LOG( SG_NETWORK, SG_WARN,
+ "FGMultiplayMgr::init - already initialised" );
+ return (false);
+ }
+ //////////////////////////////////////////////////
+ // Set members from property values
+ //////////////////////////////////////////////////
+ TxAddress = fgGetString ("/sim/multiplay/txhost");
+ TxPort = fgGetInt ("/sim/multiplay/txport");
+ m_Callsign = fgGetString ("/sim/multiplay/callsign");
+ m_RxAddress = fgGetString ("/sim/multiplay/rxhost");
+ m_RxPort = fgGetInt ("/sim/multiplay/rxport");
+ if (m_RxPort <= 0)
+ {
+ m_RxPort = 5000;
+ }
+ if (m_Callsign == "")
+ {
+ // FIXME: use getpwuid
+ m_Callsign = "JohnDoe";
+ }
+ if (m_RxAddress == "")
+ {
+ m_RxAddress = "127.0.0.1";
+ }
+ if ((TxPort > 0) && (TxAddress != ""))
+ {
+ m_HaveServer = true;
+ m_Server.set (TxAddress.c_str(), TxPort);
+ }
+ SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-txaddress= "<<TxAddress);
+ SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-txport= "<<TxPort );
+ SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxaddress="<<m_RxAddress );
+ SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-rxport= "<<m_RxPort);
+ SG_LOG(SG_NETWORK,SG_INFO,"FGMultiplayMgr::init-callsign= "<<m_Callsign);
+ m_DataSocket = new netSocket();
+ if (!m_DataSocket->open(false))
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::init - Failed to create data socket" );
+ return (false);
+ }
+ m_DataSocket->setBlocking(false);
+ m_DataSocket->setBroadcast(true);
+ if (m_DataSocket->bind(m_RxAddress.c_str(), m_RxPort) != 0)
+ {
+ perror("bind");
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::Open - Failed to bind receive socket" );
+ return (false);
+ }
+ m_LocalPlayer = new MPPlayer();
+ if (!m_LocalPlayer->Open(m_RxAddress, m_RxPort, m_Callsign,
+ fgGetString("/sim/model/path"), true))
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::init - Failed to create local player" );
+ return (false);
+ }
+ m_Initialised = true;
+ return (true);
+} // FGMultiplayMgr::init()
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// Closes and deletes the local player object. Closes
+// and deletes the tx socket. Resets the object state to unitialised.
+//
+//////////////////////////////////////////////////////////////////////
+void
+FGMultiplayMgr::Close (void)
+{
+ //////////////////////////////////////////////////
+ // Delete local player
+ //////////////////////////////////////////////////
+ if (m_LocalPlayer)
+ {
+ delete m_LocalPlayer;
+ m_LocalPlayer = NULL;
+ }
+ //////////////////////////////////////////////////
+ // Delete any existing players
+ //////////////////////////////////////////////////
+ t_MPClientListIterator CurrentPlayer;
+ t_MPClientListIterator P;
+ CurrentPlayer = m_MPClientList.begin ();
+ while (CurrentPlayer != m_MPClientList.end ())
+ {
+ P = CurrentPlayer;
+ delete (*P);
+ *P = 0;
+ CurrentPlayer = m_MPClientList.erase (P);
+ }
+ //////////////////////////////////////////////////
+ // Delete socket
+ //////////////////////////////////////////////////
+ if (m_DataSocket)
+ {
+ m_DataSocket->close();
+ delete m_DataSocket;
+ m_DataSocket = NULL;
+ }
+ m_Initialised = false;
+} // FGMultiplayMgr::Close(void)
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// Description: Sends the position data for the local position.
+//
+//////////////////////////////////////////////////////////////////////
+void
+FGMultiplayMgr::SendMyPosition
+ (
+ const sgQuat PlayerOrientation,
+ const sgdVec3 PlayerPosition
+ )
+{
+ T_MsgHdr MsgHdr;
+ T_PositionMsg PosMsg;
+ char Msg[sizeof(T_MsgHdr) + sizeof(T_PositionMsg)];
+
+ if ((! m_Initialised) || (! m_HaveServer))
+ {
+ if (! m_Initialised)
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::SendMyPosition - not initialised" );
+ if (! m_HaveServer)
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::SendMyPosition - no server" );
+ return;
+ }
+ m_LocalPlayer->SetPosition(PlayerOrientation, PlayerPosition);
+ m_LocalPlayer->FillPosMsg(&MsgHdr, &PosMsg);
+ memcpy(Msg, &MsgHdr, sizeof(T_MsgHdr));
+ memcpy(Msg + sizeof(T_MsgHdr), &PosMsg, sizeof(T_PositionMsg));
+ m_DataSocket->sendto (Msg,
+ sizeof(T_MsgHdr) + sizeof(T_PositionMsg), 0, &m_Server);
+} // FGMultiplayMgr::SendMyPosition()
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// Name: SendTextMessage
+// Description: Sends a message to the player. The message must
+// contain a valid and correctly filled out header and optional
+// message body.
+//
+//////////////////////////////////////////////////////////////////////
+void
+FGMultiplayMgr::SendTextMessage
+ (
+ const string &MsgText
+ ) const
+{
+ T_MsgHdr MsgHdr;
+ T_ChatMsg ChatMsg;
+ unsigned int iNextBlockPosition = 0;
+ char Msg[sizeof(T_MsgHdr) + sizeof(T_ChatMsg)];
+
+ if ((! m_Initialised) || (! m_HaveServer))
+ {
+ return;
+ }
+ m_LocalPlayer->FillMsgHdr(&MsgHdr, CHAT_MSG_ID);
+ //////////////////////////////////////////////////
+ // Divide the text string into blocks that fit
+ // in the message and send the blocks.
+ //////////////////////////////////////////////////
+ while (iNextBlockPosition < MsgText.length())
+ {
+ strncpy (ChatMsg.Text,
+ MsgText.substr(iNextBlockPosition, MAX_CHAT_MSG_LEN - 1).c_str(),
+ MAX_CHAT_MSG_LEN);
+ ChatMsg.Text[MAX_CHAT_MSG_LEN - 1] = '\0';
+ memcpy (Msg, &MsgHdr, sizeof(T_MsgHdr));
+ memcpy (Msg + sizeof(T_MsgHdr), &ChatMsg, sizeof(T_ChatMsg));
+ m_DataSocket->sendto (Msg,
+ sizeof(T_MsgHdr) + sizeof(T_ChatMsg), 0, &m_Server);
+ iNextBlockPosition += MAX_CHAT_MSG_LEN - 1;
+ }
+} // FGMultiplayMgr::SendTextMessage ()
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// Name: ProcessData
+// Description: Processes data waiting at the receive socket. The
+// processing ends when there is no more data at the socket.
+//
+//////////////////////////////////////////////////////////////////////
+void
+FGMultiplayMgr::ProcessData (void)
+{
+ char Msg[MAX_PACKET_SIZE]; // Buffer for received message
+ int Bytes; // Bytes received
+ T_MsgHdr* MsgHdr; // Pointer to header in received data
+ netAddress SenderAddress;
+
+ if (! m_Initialised)
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::ProcessData - not initialised" );
+ return;
+ }
+ //////////////////////////////////////////////////
+ // Read the receive socket and process any data
+ //////////////////////////////////////////////////
+ do {
+ //////////////////////////////////////////////////
+ // Although the recv call asks for
+ // MAX_PACKET_SIZE of data, the number of bytes
+ // returned will only be that of the next
+ // packet waiting to be processed.
+ //////////////////////////////////////////////////
+ Bytes = m_DataSocket->recvfrom (Msg, MAX_PACKET_SIZE, 0,
+ &SenderAddress);
+ //////////////////////////////////////////////////
+ // no Data received
+ //////////////////////////////////////////////////
+ if (Bytes <= 0)
+ {
+ if (errno != EAGAIN)
+ {
+ perror("FGMultiplayMgr::MP_ProcessData");
+ }
+ return;
+ }
+ if (Bytes <= (int)sizeof(MsgHdr))
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::MP_ProcessData - "
+ << "received message with insufficient data" );
+ return;
+ }
+ //////////////////////////////////////////////////
+ // Read header
+ //////////////////////////////////////////////////
+ MsgHdr = (T_MsgHdr *)Msg;
+ MsgHdr->Magic = XDR_decode_uint32 (MsgHdr->Magic);
+ MsgHdr->Version = XDR_decode_uint32 (MsgHdr->Version);
+ MsgHdr->MsgId = XDR_decode_uint32 (MsgHdr->MsgId);
+ MsgHdr->MsgLen = XDR_decode_uint32 (MsgHdr->MsgLen);
+ MsgHdr->ReplyPort = XDR_decode_uint32 (MsgHdr->ReplyPort);
+ if (MsgHdr->Magic != MSG_MAGIC)
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::MP_ProcessData - "
+ << "message has invalid magic number!" );
+ }
+ if (MsgHdr->Version != PROTO_VER)
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::MP_ProcessData - "
+ << "message has invalid protocoll number!" );
+ }
+ //////////////////////////////////////////////////
+ // Process the player data unless we generated it
+ //////////////////////////////////////////////////
+ if (m_Callsign == MsgHdr->Callsign)
+ {
+ return;
+ }
+ //////////////////////////////////////////////////
+ // Process messages
+ //////////////////////////////////////////////////
+ switch(MsgHdr->MsgId)
+ {
+ case CHAT_MSG_ID:
+ ProcessChatMsg ((char*) & Msg, SenderAddress);
+ break;
+ case POS_DATA_ID:
+ ProcessPosMsg ((char*) & Msg, SenderAddress);
+ break;
+ default:
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::MP_ProcessData - "
+ << "Unknown message Id received: "
+ << MsgHdr->MsgId );
+ break;
+ } // switch
+ } while (Bytes > 0);
+} // FGMultiplayMgr::ProcessData(void)
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// handle a position message
+//
+//////////////////////////////////////////////////////////////////////
+void
+FGMultiplayMgr::ProcessPosMsg
+ (
+ const char *Msg,
+ netAddress & SenderAddress
+ )
+{
+ T_PositionMsg* PosMsg; // Pointer to position message in received data
+ T_MsgHdr* MsgHdr; // Pointer to header in received data
+ bool ActivePlayer;
+ sgQuat Orientation;
+ sgdVec3 Position;
+ struct in_addr PlayerAddress;
+ t_MPClientListIterator CurrentPlayer;
+ int iPlayerCnt;
+ char *sIpAddress;
+
+ ActivePlayer = false;
+ MsgHdr = (T_MsgHdr *)Msg;
+ if (MsgHdr->MsgLen != sizeof(T_MsgHdr) + sizeof(T_PositionMsg))
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::MP_ProcessData - "
+ << "Position message received with insufficient data" );
+ return;
+ }
+ PosMsg = (T_PositionMsg *)(Msg + sizeof(T_MsgHdr));
+ Position[0] = XDR_decode_double (PosMsg->PlayerPosition[0]);
+ Position[1] = XDR_decode_double (PosMsg->PlayerPosition[1]);
+ Position[2] = XDR_decode_double (PosMsg->PlayerPosition[2]);
+ Orientation[0] = XDR_decode_float (PosMsg->PlayerOrientation[0]);
+ Orientation[1] = XDR_decode_float (PosMsg->PlayerOrientation[1]);
+ Orientation[2] = XDR_decode_float (PosMsg->PlayerOrientation[2]);
+ Orientation[3] = XDR_decode_float (PosMsg->PlayerOrientation[3]);
+ //////////////////////////////////////////////////
+ // Check if the player is already in the game
+ // by using the Callsign
+ //////////////////////////////////////////////////
+ for (CurrentPlayer = m_MPClientList.begin ();
+ CurrentPlayer != m_MPClientList.end ();
+ CurrentPlayer++)
+ {
+ if ((*CurrentPlayer)->CompareCallsign(MsgHdr->Callsign))
+ {
+ // Player found. Update the data for the player.
+ (*CurrentPlayer)->SetPosition(Orientation, Position);
+ ActivePlayer = true;
+ }
+ } // for (...)
+ if (ActivePlayer)
+ { // nothing more to do
+ return;
+ }
+ //////////////////////////////////////////////////
+ // Player not active, so add as new player
+ //////////////////////////////////////////////////
+ MPPlayer* NewPlayer;
+ NewPlayer = new MPPlayer;
+ NewPlayer->Open(SenderAddress.getHost(), MsgHdr->ReplyPort,
+ MsgHdr->Callsign, PosMsg->Model, false);
+ NewPlayer->SetPosition(Orientation, Position);
+ m_MPClientList.push_back (NewPlayer);
+} // FGMultiplayMgr::ProcessPosMsg()
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// handle a chat message
+// FIXME: display chat message withi flightgear
+//
+//////////////////////////////////////////////////////////////////////
+void
+FGMultiplayMgr::ProcessChatMsg
+ (
+ const char *Msg,
+ netAddress & SenderAddress
+ )
+{
+ T_ChatMsg* ChatMsg; // Pointer to chat message in received data
+ T_MsgHdr* MsgHdr; // Pointer to header in received data
+
+ MsgHdr = (T_MsgHdr *)Msg;
+ if (MsgHdr->MsgLen != sizeof(T_MsgHdr) + sizeof(T_ChatMsg))
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT,
+ "FGMultiplayMgr::MP_ProcessData - "
+ << "Chat message received with insufficient data" );
+ return;
+ }
+ ChatMsg = (T_ChatMsg *)(Msg + sizeof(T_MsgHdr));
+ SG_LOG ( SG_NETWORK, SG_ALERT,
+ "Chat [" << MsgHdr->Callsign << "]" << " " << ChatMsg->Text << endl);
+} // FGMultiplayMgr::ProcessChatMsg ()
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+//
+// For each active player, tell the player object
+// to update its position on the scene. If a player object
+// returns status information indicating that it has not
+// had an update for some time then the player is deleted.
+//
+//////////////////////////////////////////////////////////////////////
+void
+FGMultiplayMgr::Update (void)
+{
+ MPPlayer::TPlayerDataState ePlayerDataState;
+ t_MPClientListIterator CurrentPlayer;
+
+ CurrentPlayer = m_MPClientList.begin ();
+ while (CurrentPlayer != m_MPClientList.end ())
+ {
+ ePlayerDataState = (*CurrentPlayer)->Draw();
+ //////////////////////////////////////////////////
+ // If the player has not received an update for
+ // some time then assume that the player has quit.
+ //////////////////////////////////////////////////
+ if (ePlayerDataState == MPPlayer::PLAYER_DATA_EXPIRED)
+ {
+ SG_LOG( SG_NETWORK, SG_ALERT, "FGMultiplayMgr::Update - "
+ << "Deleting player from game. Callsign: "
+ << (*CurrentPlayer)->Callsign() );
+ t_MPClientListIterator P;
+ P = CurrentPlayer;
+ delete (*P);
+ *P = 0;
+ CurrentPlayer = m_MPClientList.erase (P);
+ }
+ else CurrentPlayer++;
+ }
+} // FGMultiplayMgr::Update()
+//////////////////////////////////////////////////////////////////////
+
+#endif // FG_MPLAYER_AS
+
+++ /dev/null
-//////////////////////////////////////////////////////////////////////
-//
-// multiplaymgr.hpp
-//
-// Written by Duncan McCreanor, started February 2003.
-// duncan.mccreanor@airservicesaustralia.com
-//
-// Copyright (C) 2003 Airservices Australia
-// Copyright (C) 2005 Oliver Schroeder
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-//
-//////////////////////////////////////////////////////////////////////
-
-#ifndef MULTIPLAYMGR_H
-#define MULTIPLAYMGR_H
-
-#define MULTIPLAYTXMGR_HID "$Id$"
-
-#include "mpplayer.hxx"
-#include "mpmessages.hxx"
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include STL_STRING
-SG_USING_STD(string);
-#include <vector>
-SG_USING_STD(vector);
-
-#include <simgear/compiler.h>
-#include <plib/netSocket.h>
-#include <Main/globals.hxx>
-
-// Maximum number of players that can exist at any time
-// FIXME: use a list<mplayer> instead
-#define MAX_PLAYERS 10
-
-class FGMultiplayMgr
-{
-public:
- FGMultiplayMgr();
- ~FGMultiplayMgr();
- bool init(void);
- void Close(void);
- // transmitter
- void SendMyPosition (const sgQuat PlayerOrientation,
- const sgdVec3 PlayerPosition);
- void SendTextMessage (const string &sMsgText) const;
- // receiver
- void ProcessData(void);
- void ProcessPosMsg ( const char *Msg, netAddress & SenderAddress );
- void ProcessChatMsg ( const char *Msg, netAddress & SenderAddress );
- void Update(void);
-private:
- typedef vector<MPPlayer*> t_MPClientList;
- typedef t_MPClientList::iterator t_MPClientListIterator;
- MPPlayer* m_LocalPlayer;
- netSocket* m_DataSocket;
- netAddress m_Server;
- bool m_HaveServer;
- bool m_Initialised;
- t_MPClientList m_MPClientList;
- string m_RxAddress;
- int m_RxPort;
- string m_Callsign;
-};
-
-#endif
-
--- /dev/null
+//////////////////////////////////////////////////////////////////////
+//
+// multiplaymgr.hpp
+//
+// Written by Duncan McCreanor, started February 2003.
+// duncan.mccreanor@airservicesaustralia.com
+//
+// Copyright (C) 2003 Airservices Australia
+// Copyright (C) 2005 Oliver Schroeder
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef MULTIPLAYMGR_H
+#define MULTIPLAYMGR_H
+
+#define MULTIPLAYTXMGR_HID "$Id$"
+
+#include "mpplayer.hxx"
+#include "mpmessages.hxx"
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include STL_STRING
+SG_USING_STD(string);
+#include <vector>
+SG_USING_STD(vector);
+
+#include <simgear/compiler.h>
+#include <plib/netSocket.h>
+#include <Main/globals.hxx>
+
+// Maximum number of players that can exist at any time
+// FIXME: use a list<mplayer> instead
+#define MAX_PLAYERS 10
+
+class FGMultiplayMgr
+{
+public:
+ FGMultiplayMgr();
+ ~FGMultiplayMgr();
+ bool init(void);
+ void Close(void);
+ // transmitter
+ void SendMyPosition (const sgQuat PlayerOrientation,
+ const sgdVec3 PlayerPosition);
+ void SendTextMessage (const string &sMsgText) const;
+ // receiver
+ void ProcessData(void);
+ void ProcessPosMsg ( const char *Msg, netAddress & SenderAddress );
+ void ProcessChatMsg ( const char *Msg, netAddress & SenderAddress );
+ void Update(void);
+private:
+ typedef vector<MPPlayer*> t_MPClientList;
+ typedef t_MPClientList::iterator t_MPClientListIterator;
+ MPPlayer* m_LocalPlayer;
+ netSocket* m_DataSocket;
+ netAddress m_Server;
+ bool m_HaveServer;
+ bool m_Initialised;
+ t_MPClientList m_MPClientList;
+ string m_RxAddress;
+ int m_RxPort;
+ string m_Callsign;
+};
+
+#endif
+
+++ /dev/null
-//////////////////////////////////////////////////////////////////////
-//
-// Tiny XDR implementation for flightgear
-// written by Oliver Schroeder
-// released to the public domain
-//
-// This implementation is not complete, but implements
-// everything we need.
-//
-// For further reading on XDR read RFC 1832.
-//
-//////////////////////////////////////////////////////////////////////
-
-#include <plib/ul.h>
-
-#include "tiny_xdr.hpp"
-
-/* XDR 8bit integers */
-xdr_data_t
-XDR_encode_int8 ( const int8_t & n_Val )
-{
- return (SWAP32(static_cast<xdr_data_t> (n_Val)));
-}
-
-xdr_data_t
-XDR_encode_uint8 ( const uint8_t & n_Val )
-{
- return (SWAP32(static_cast<xdr_data_t> (n_Val)));
-}
-
-int8_t
-XDR_decode_int8 ( const xdr_data_t & n_Val )
-{
- return (static_cast<int8_t> (SWAP32(n_Val)));
-}
-
-uint8_t
-XDR_decode_uint8 ( const xdr_data_t & n_Val )
-{
- return (static_cast<uint8_t> (SWAP32(n_Val)));
-}
-
-/* XDR 16bit integers */
-xdr_data_t
-XDR_encode_int16 ( const int16_t & n_Val )
-{
- return (SWAP32(static_cast<xdr_data_t> (n_Val)));
-}
-
-xdr_data_t
-XDR_encode_uint16 ( const uint16_t & n_Val )
-{
- return (SWAP32(static_cast<xdr_data_t> (n_Val)));
-}
-
-int16_t
-XDR_decode_int16 ( const xdr_data_t & n_Val )
-{
- return (static_cast<int16_t> (SWAP32(n_Val)));
-}
-
-uint16_t
-XDR_decode_uint16 ( const xdr_data_t & n_Val )
-{
- return (static_cast<uint16_t> (SWAP32(n_Val)));
-}
-
-
-/* XDR 32bit integers */
-xdr_data_t
-XDR_encode_int32 ( const int32_t & n_Val )
-{
- return (SWAP32(static_cast<xdr_data_t> (n_Val)));
-}
-
-xdr_data_t
-XDR_encode_uint32 ( const uint32_t & n_Val )
-{
- return (SWAP32(static_cast<xdr_data_t> (n_Val)));
-}
-
-int32_t
-XDR_decode_int32 ( const xdr_data_t & n_Val )
-{
- return (static_cast<int32_t> (SWAP32(n_Val)));
-}
-
-uint32_t
-XDR_decode_uint32 ( const xdr_data_t & n_Val )
-{
- return (static_cast<uint32_t> (SWAP32(n_Val)));
-}
-
-
-/* XDR 64bit integers */
-xdr_data2_t
-XDR_encode_int64 ( const int64_t & n_Val )
-{
- return (SWAP64(static_cast<xdr_data2_t> (n_Val)));
-}
-
-xdr_data2_t
-XDR_encode_uint64 ( const uint64_t & n_Val )
-{
- return (SWAP64(static_cast<xdr_data2_t> (n_Val)));
-}
-
-int64_t
-XDR_decode_int64 ( const xdr_data2_t & n_Val )
-{
- return (static_cast<int64_t> (SWAP64(n_Val)));
-}
-
-uint64_t
-XDR_decode_uint64 ( const xdr_data2_t & n_Val )
-{
- return (static_cast<uint64_t> (SWAP64(n_Val)));
-}
-
-
-/* float */
-xdr_data_t
-XDR_encode_float ( const float & f_Val )
-{
- xdr_data_t* tmp;
-
- tmp = (xdr_data_t*) &f_Val;
- return (XDR_encode_int32 (*tmp));
-}
-
-float
-XDR_decode_float ( const xdr_data_t & f_Val )
-{
- float* tmp;
- xdr_data_t dummy;
-
- dummy = XDR_decode_int32 (f_Val);
- tmp = (float*) &dummy;
- return (*tmp);
-}
-
-/* double */
-xdr_data2_t
-XDR_encode_double ( const double & d_Val )
-{
- xdr_data2_t* tmp;
-
- tmp = (xdr_data2_t*) &d_Val;
- return (XDR_encode_int64 (*tmp));
-}
-
-double
-XDR_decode_double ( const xdr_data2_t & d_Val )
-{
- double* tmp;
- xdr_data2_t dummy;
-
- dummy = XDR_decode_int64 (d_Val);
- tmp = (double*) &dummy;
- return (*tmp);
-}
-
-
--- /dev/null
+//////////////////////////////////////////////////////////////////////
+//
+// Tiny XDR implementation for flightgear
+// written by Oliver Schroeder
+// released to the public domain
+//
+// This implementation is not complete, but implements
+// everything we need.
+//
+// For further reading on XDR read RFC 1832.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include <plib/ul.h>
+
+#include "tiny_xdr.hxx"
+
+/* XDR 8bit integers */
+xdr_data_t
+XDR_encode_int8 ( const int8_t & n_Val )
+{
+ return (SWAP32(static_cast<xdr_data_t> (n_Val)));
+}
+
+xdr_data_t
+XDR_encode_uint8 ( const uint8_t & n_Val )
+{
+ return (SWAP32(static_cast<xdr_data_t> (n_Val)));
+}
+
+int8_t
+XDR_decode_int8 ( const xdr_data_t & n_Val )
+{
+ return (static_cast<int8_t> (SWAP32(n_Val)));
+}
+
+uint8_t
+XDR_decode_uint8 ( const xdr_data_t & n_Val )
+{
+ return (static_cast<uint8_t> (SWAP32(n_Val)));
+}
+
+/* XDR 16bit integers */
+xdr_data_t
+XDR_encode_int16 ( const int16_t & n_Val )
+{
+ return (SWAP32(static_cast<xdr_data_t> (n_Val)));
+}
+
+xdr_data_t
+XDR_encode_uint16 ( const uint16_t & n_Val )
+{
+ return (SWAP32(static_cast<xdr_data_t> (n_Val)));
+}
+
+int16_t
+XDR_decode_int16 ( const xdr_data_t & n_Val )
+{
+ return (static_cast<int16_t> (SWAP32(n_Val)));
+}
+
+uint16_t
+XDR_decode_uint16 ( const xdr_data_t & n_Val )
+{
+ return (static_cast<uint16_t> (SWAP32(n_Val)));
+}
+
+
+/* XDR 32bit integers */
+xdr_data_t
+XDR_encode_int32 ( const int32_t & n_Val )
+{
+ return (SWAP32(static_cast<xdr_data_t> (n_Val)));
+}
+
+xdr_data_t
+XDR_encode_uint32 ( const uint32_t & n_Val )
+{
+ return (SWAP32(static_cast<xdr_data_t> (n_Val)));
+}
+
+int32_t
+XDR_decode_int32 ( const xdr_data_t & n_Val )
+{
+ return (static_cast<int32_t> (SWAP32(n_Val)));
+}
+
+uint32_t
+XDR_decode_uint32 ( const xdr_data_t & n_Val )
+{
+ return (static_cast<uint32_t> (SWAP32(n_Val)));
+}
+
+
+/* XDR 64bit integers */
+xdr_data2_t
+XDR_encode_int64 ( const int64_t & n_Val )
+{
+ return (SWAP64(static_cast<xdr_data2_t> (n_Val)));
+}
+
+xdr_data2_t
+XDR_encode_uint64 ( const uint64_t & n_Val )
+{
+ return (SWAP64(static_cast<xdr_data2_t> (n_Val)));
+}
+
+int64_t
+XDR_decode_int64 ( const xdr_data2_t & n_Val )
+{
+ return (static_cast<int64_t> (SWAP64(n_Val)));
+}
+
+uint64_t
+XDR_decode_uint64 ( const xdr_data2_t & n_Val )
+{
+ return (static_cast<uint64_t> (SWAP64(n_Val)));
+}
+
+
+/* float */
+xdr_data_t
+XDR_encode_float ( const float & f_Val )
+{
+ xdr_data_t* tmp;
+
+ tmp = (xdr_data_t*) &f_Val;
+ return (XDR_encode_int32 (*tmp));
+}
+
+float
+XDR_decode_float ( const xdr_data_t & f_Val )
+{
+ float* tmp;
+ xdr_data_t dummy;
+
+ dummy = XDR_decode_int32 (f_Val);
+ tmp = (float*) &dummy;
+ return (*tmp);
+}
+
+/* double */
+xdr_data2_t
+XDR_encode_double ( const double & d_Val )
+{
+ xdr_data2_t* tmp;
+
+ tmp = (xdr_data2_t*) &d_Val;
+ return (XDR_encode_int64 (*tmp));
+}
+
+double
+XDR_decode_double ( const xdr_data2_t & d_Val )
+{
+ double* tmp;
+ xdr_data2_t dummy;
+
+ dummy = XDR_decode_int64 (d_Val);
+ tmp = (double*) &dummy;
+ return (*tmp);
+}
+
+
+++ /dev/null
-//////////////////////////////////////////////////////////////////////
-//
-// Tiny XDR implementation for flightgear
-// written by Oliver Schroeder
-// released to the public domain
-//
-// This implementation is not complete, but implements
-// everything we need.
-//
-// For further reading on XDR read RFC 1832.
-//
-// NEW
-//
-//////////////////////////////////////////////////////////////////////
-
-#ifndef TINY_XDR_HEADER
-#define TINY_XDR_HEADER
-
-#if defined HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <simgear/misc/stdint.hxx>
-
-#define SWAP32(arg) sgIsLittleEndian() ? sg_bswap_32(arg) : arg
-#define SWAP64(arg) sgIsLittleEndian() ? sg_bswap_64(arg) : arg
-
-#define XDR_BYTES_PER_UNIT 4
-
-typedef uint32_t xdr_data_t; /* 4 Bytes */
-typedef uint64_t xdr_data2_t; /* 8 Bytes */
-
-/* XDR 8bit integers */
-xdr_data_t XDR_encode_int8 ( const int8_t & n_Val );
-xdr_data_t XDR_encode_uint8 ( const uint8_t & n_Val );
-int8_t XDR_decode_int8 ( const xdr_data_t & n_Val );
-uint8_t XDR_decode_uint8 ( const xdr_data_t & n_Val );
-
-/* XDR 16bit integers */
-xdr_data_t XDR_encode_int16 ( const int16_t & n_Val );
-xdr_data_t XDR_encode_uint16 ( const uint16_t & n_Val );
-int16_t XDR_decode_int16 ( const xdr_data_t & n_Val );
-uint16_t XDR_decode_uint16 ( const xdr_data_t & n_Val );
-
-/* XDR 32bit integers */
-xdr_data_t XDR_encode_int32 ( const int32_t & n_Val );
-xdr_data_t XDR_encode_uint32 ( const uint32_t & n_Val );
-int32_t XDR_decode_int32 ( const xdr_data_t & n_Val );
-uint32_t XDR_decode_uint32 ( const xdr_data_t & n_Val );
-
-/* XDR 64bit integers */
-xdr_data2_t XDR_encode_int64 ( const int64_t & n_Val );
-xdr_data2_t XDR_encode_uint64 ( const uint64_t & n_Val );
-int64_t XDR_decode_int64 ( const xdr_data2_t & n_Val );
-uint64_t XDR_decode_uint64 ( const xdr_data2_t & n_Val );
-
-//////////////////////////////////////////////////
-//
-// FIXME: #1 these funtions must be fixed for
-// none IEEE-encoding architecturs
-// (eg. vax, big suns etc)
-// FIXME: #2 some compilers return 'double'
-// regardless of return-type 'float'
-// this must be fixed, too
-// FIXME: #3 some machines may need to use a
-// different endianess for floats!
-//
-//////////////////////////////////////////////////
-/* float */
-xdr_data_t XDR_encode_float ( const float & f_Val );
-float XDR_decode_float ( const xdr_data_t & f_Val );
-
-/* double */
-xdr_data2_t XDR_encode_double ( const double & d_Val );
-double XDR_decode_double ( const xdr_data2_t & d_Val );
-
-#endif
--- /dev/null
+//////////////////////////////////////////////////////////////////////
+//
+// Tiny XDR implementation for flightgear
+// written by Oliver Schroeder
+// released to the public domain
+//
+// This implementation is not complete, but implements
+// everything we need.
+//
+// For further reading on XDR read RFC 1832.
+//
+// NEW
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef TINY_XDR_HEADER
+#define TINY_XDR_HEADER
+
+#if defined HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <simgear/misc/stdint.hxx>
+
+#define SWAP32(arg) sgIsLittleEndian() ? sg_bswap_32(arg) : arg
+#define SWAP64(arg) sgIsLittleEndian() ? sg_bswap_64(arg) : arg
+
+#define XDR_BYTES_PER_UNIT 4
+
+typedef uint32_t xdr_data_t; /* 4 Bytes */
+typedef uint64_t xdr_data2_t; /* 8 Bytes */
+
+/* XDR 8bit integers */
+xdr_data_t XDR_encode_int8 ( const int8_t & n_Val );
+xdr_data_t XDR_encode_uint8 ( const uint8_t & n_Val );
+int8_t XDR_decode_int8 ( const xdr_data_t & n_Val );
+uint8_t XDR_decode_uint8 ( const xdr_data_t & n_Val );
+
+/* XDR 16bit integers */
+xdr_data_t XDR_encode_int16 ( const int16_t & n_Val );
+xdr_data_t XDR_encode_uint16 ( const uint16_t & n_Val );
+int16_t XDR_decode_int16 ( const xdr_data_t & n_Val );
+uint16_t XDR_decode_uint16 ( const xdr_data_t & n_Val );
+
+/* XDR 32bit integers */
+xdr_data_t XDR_encode_int32 ( const int32_t & n_Val );
+xdr_data_t XDR_encode_uint32 ( const uint32_t & n_Val );
+int32_t XDR_decode_int32 ( const xdr_data_t & n_Val );
+uint32_t XDR_decode_uint32 ( const xdr_data_t & n_Val );
+
+/* XDR 64bit integers */
+xdr_data2_t XDR_encode_int64 ( const int64_t & n_Val );
+xdr_data2_t XDR_encode_uint64 ( const uint64_t & n_Val );
+int64_t XDR_decode_int64 ( const xdr_data2_t & n_Val );
+uint64_t XDR_decode_uint64 ( const xdr_data2_t & n_Val );
+
+//////////////////////////////////////////////////
+//
+// FIXME: #1 these funtions must be fixed for
+// none IEEE-encoding architecturs
+// (eg. vax, big suns etc)
+// FIXME: #2 some compilers return 'double'
+// regardless of return-type 'float'
+// this must be fixed, too
+// FIXME: #3 some machines may need to use a
+// different endianess for floats!
+//
+//////////////////////////////////////////////////
+/* float */
+xdr_data_t XDR_encode_float ( const float & f_Val );
+float XDR_decode_float ( const xdr_data_t & f_Val );
+
+/* double */
+xdr_data2_t XDR_encode_double ( const double & d_Val );
+double XDR_decode_double ( const xdr_data2_t & d_Val );
+
+#endif
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Model/acmodel.hxx>
-#include <MultiPlayer/multiplaymgr.hpp>
+#include <MultiPlayer/multiplaymgr.hxx>
#include "protocol.hxx"
#include STL_STRING
-#include <Controls/controls.hxx>
-
+#include <Aircraft/controls.hxx>
#include "protocol.hxx"
#include "net_ctrls.hxx"
SG_USING_STD(string);
-
class FGNativeCtrls : public FGProtocol {
FGNetCtrls net_ctrls;
#include "opengc.hxx"
#include <FDM/flight.hxx>
#include <Main/globals.hxx>
-#include <Controls/controls.hxx>
#include <Main/fg_props.hxx>
SG_USING_STD(vector);
+++ /dev/null
-.deps
-Makefile
-Makefile.in
+++ /dev/null
-#noinst_LIBRARIES = libObjects.a
-
-#libObjects_a_SOURCES =
-# ssgEntityArray.hxx ssgEntityArray.cxx
-
-INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
+++ /dev/null
-/*
- PLIB - A Suite of Portable Game Libraries
- Copyright (C) 1998,2002 Steve Baker
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For further information visit http://plib.sourceforge.net
-
- $Id$
-*/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "ssgEntityArray.hxx"
-
-
-// Forward declaration of internal ssg stuff (for hot/isec/los/etc.)
-void _ssgPushPath ( ssgEntity *l ) ;
-void _ssgPopPath () ;
-
-
-void ssgEntityArray::copy_from ( ssgEntityArray *src, int clone_flags )
-{
- ssgEntity::copy_from ( src, clone_flags ) ;
-
- ssgEntity *k = src -> getModel ( ) ;
- if ( k != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
- setModel ( (ssgEntity *)( k -> clone ( clone_flags )) ) ;
- else
- setModel ( k ) ;
-
- ssgTransform *t = src -> getPosTransform();
- if ( t != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
- pos = (ssgTransform *)( t -> clone ( clone_flags ) );
- else
- pos = t;
-
- ssgVertexArray *v = src -> getLocations();
- if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
- locations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
- else
- locations = v;
-
- v = src -> getOrientations();
- if ( v != NULL && ( clone_flags & SSG_CLONE_RECURSIVE ) )
- orientations = (ssgVertexArray *)( v -> clone ( clone_flags ) );
- else
- orientations = v;
-}
-
-ssgBase *ssgEntityArray::clone ( int clone_flags )
-{
- ssgEntityArray *b = new ssgEntityArray ;
- b -> copy_from ( this, clone_flags ) ;
- return b ;
-}
-
-
-
-ssgEntityArray::ssgEntityArray (void)
-{
- type = ssgTypeBranch () ;
- pos = new ssgTransform;
- locations = new ssgVertexArray();
- orientations = new ssgVertexArray();
-}
-
-
-ssgEntityArray::~ssgEntityArray (void)
-{
- removeModel() ;
- ssgDeRefDelete( pos );
- locations->removeAll();
- orientations->removeAll();
-
- delete orientations;
- delete locations;
- delete pos;
-}
-
-
-void ssgEntityArray::zeroSpareRecursive ()
-{
- zeroSpare () ;
-
- model -> zeroSpareRecursive () ;
- pos -> zeroSpareRecursive () ;
- locations -> zeroSpareRecursive () ;
- orientations -> zeroSpareRecursive () ;
-}
-
-
-void ssgEntityArray::recalcBSphere (void)
-{
- emptyBSphere () ;
-
- pos->removeAllKids();
- pos->addKid( model );
-
- for ( int i = 0; i < locations->getNum(); ++i ) {
- sgCoord c;
- sgSetCoord( &c, locations->get(i), orientations->get(i) );
- pos->setTransform( &c );
- extendBSphere( pos->getBSphere() );
- }
-
- pos->removeAllKids();
-
- /* FIXME: Traverse placement list
- for ( ssgEntity *k = getKid ( 0 ) ; k != NULL ; k = getNextKid () )
- extendBSphere ( k -> getBSphere () ) ;
- */
-
- bsphere_is_invalid = FALSE ;
-}
-
-
-void ssgEntityArray::removeModel ()
-{
- model->deadBeefCheck () ;
- ssgDeRefDelete ( model ) ;
-}
-
-
-void ssgEntityArray::replaceModel ( ssgEntity *new_entity )
-{
- removeModel();
- setModel( new_entity );
-}
-
-
-void ssgEntityArray::addPlacement ( sgVec3 loc, sgVec3 orient )
-{
- locations->add( loc ) ;
- orientations->add( orient ) ;
- dirtyBSphere () ;
-}
-
-
-void ssgEntityArray::removeAllPlacements()
-{
- locations->removeAll();
- orientations->removeAll();
- dirtyBSphere () ;
-}
-
-
-void ssgEntityArray::print ( FILE *fd, char *indent, int how_much )
-{
- ssgEntity::print ( fd, indent, how_much ) ;
- fprintf ( fd, "%s Num Kids=%d\n", indent, getNumKids() ) ;
-
- if ( getNumParents() != getRef() )
- ulSetError ( UL_WARNING, "Ref count doesn't tally with parent count" ) ;
-
- if ( how_much > 1 )
- { if ( bsphere.isEmpty() )
- fprintf ( fd, "%s BSphere is Empty.\n", indent ) ;
- else
- fprintf ( fd, "%s BSphere R=%g, C=(%g,%g,%g)\n", indent,
- bsphere.getRadius(), bsphere.getCenter()[0], bsphere.getCenter()[1], bsphere.getCenter()[2] ) ;
- }
-
- char in [ 100 ] ;
- sprintf ( in, "%s ", indent ) ;
-
- model -> print ( fd, in, how_much ) ;
-}
-
-
-#ifdef HAVE_PLIB_PSL
-void ssgEntityArray::getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_verts )
-{
- int nb, nl, nt, nv ;
-
- *num_branches = 1 ; /* this! */
- *num_leaves = 0 ;
- *num_tris = 0 ;
- *num_verts = 0 ;
-
- model -> getStats ( & nb, & nl, & nt, & nv ) ;
- *num_branches += nb * locations->getNum() ;
- *num_leaves += nl * locations->getNum() ;
- *num_tris += nt * locations->getNum() ;
- *num_verts += nv * locations->getNum() ;
-}
-#endif
-
-
-void ssgEntityArray::cull ( sgFrustum *f, sgMat4 m, int test_needed )
-{
- if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) )
- return ;
-
- int cull_result = cull_test ( f, m, test_needed ) ;
-
- if ( cull_result == SSG_OUTSIDE )
- return ;
-
- pos->removeAllKids();
- pos->addKid( model );
-
- for ( int i = 0; i < locations->getNum(); ++i ) {
- sgCoord c;
- sgSetCoord( &c, locations->get(i), orientations->get(i) );
- pos->setTransform( &c );
- pos->cull( f, m, cull_result != SSG_INSIDE );
- }
-
- pos->removeAllKids();
-
- postTravTests ( SSGTRAV_CULL ) ;
-}
-
-
-
-void ssgEntityArray::hot ( sgVec3 s, sgMat4 m, int test_needed )
-{
- if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) )
- return ;
-
- int hot_result = hot_test ( s, m, test_needed ) ;
-
- if ( hot_result == SSG_OUTSIDE )
- return ;
-
- _ssgPushPath ( this ) ;
-
- pos->removeAllKids();
- pos->addKid( model );
-
- for ( int i = 0; i < locations->getNum(); ++i ) {
- sgCoord c;
- sgSetCoord( &c, locations->get(i), orientations->get(i) );
- pos->setTransform( &c );
- pos->hot ( s, m, hot_result != SSG_INSIDE );
- }
-
- pos->removeAllKids();
-
- _ssgPopPath () ;
-
- postTravTests ( SSGTRAV_HOT ) ;
-}
-
-
-
-void ssgEntityArray::los ( sgVec3 s, sgMat4 m, int test_needed )
-{
- if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) )
- return ;
-
- int los_result = los_test ( s, m, test_needed ) ;
-
- if ( los_result == SSG_OUTSIDE )
- return ;
-
- _ssgPushPath ( this ) ;
-
- pos->removeAllKids();
- pos->addKid( model );
-
- for ( int i = 0; i < locations->getNum(); ++i ) {
- sgCoord c;
- sgSetCoord( &c, locations->get(i), orientations->get(i) );
- pos->setTransform( &c );
- pos->los ( s, m, los_result != SSG_INSIDE ) ;
- }
-
- pos->removeAllKids();
-
- _ssgPopPath () ;
-
- postTravTests ( SSGTRAV_LOS) ;
-}
-
-
-void ssgEntityArray::isect ( sgSphere *s, sgMat4 m, int test_needed )
-{
- if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) )
- return ;
-
- int isect_result = isect_test ( s, m, test_needed ) ;
-
- if ( isect_result == SSG_OUTSIDE )
- return ;
-
- _ssgPushPath ( this ) ;
-
- pos->removeAllKids();
- pos->addKid( model );
-
- for ( int i = 0; i < locations->getNum(); ++i ) {
- sgCoord c;
- sgSetCoord( &c, locations->get(i), orientations->get(i) );
- pos->setTransform( &c );
- pos->isect ( s, m, isect_result != SSG_INSIDE ) ;
- }
-
- pos->removeAllKids();
-
- _ssgPopPath () ;
-
- postTravTests ( SSGTRAV_ISECT ) ;
-}
-
-
-#if 0
-int ssgEntityArray::load ( FILE *fd )
-{
- int nkids ;
-
- _ssgReadInt ( fd, & nkids ) ;
-
- if ( ! ssgEntity::load ( fd ) )
- return FALSE ;
-
- for ( int i = 0 ; i < nkids ; i++ )
- {
- ssgEntity *kid ;
-
- if ( ! _ssgLoadObject ( fd, (ssgBase **) &kid, ssgTypeEntity () ) )
- return FALSE ;
-
- addKid ( kid ) ;
- }
-
- return TRUE ;
-}
-
-
-int ssgEntityArray::save ( FILE *fd )
-{
- _ssgWriteInt ( fd, getNumKids() ) ;
-
- if ( ! ssgEntity::save ( fd ) )
- return FALSE ;
-
- for ( int i = 0 ; i < getNumKids() ; i++ )
- {
- if ( ! _ssgSaveObject ( fd, getKid ( i ) ) )
- return FALSE ;
- }
-
- return TRUE ;
-}
-#endif
-
+++ /dev/null
-#ifndef _SSG_ENTITY_ARRAY_HXX
-#define _SSG_ENTITY_ARRAY_HXX
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <plib/ssg.h>
-
-
-class ssgEntityArray : public ssgEntity
-{
- // The replicated child
- ssgEntity *model ;
-
- // The one transformation node
- ssgTransform *pos;
-
- // The list of locations and orientations
- ssgVertexArray *locations;
- ssgVertexArray *orientations;
-
-protected:
-
- virtual void copy_from ( ssgEntityArray *src, int clone_flags ) ;
-
-public:
-
- virtual void zeroSpareRecursive ();
-
- virtual ssgBase *clone ( int clone_flags = 0 ) ;
- ssgEntityArray (void) ;
- virtual ~ssgEntityArray (void) ;
-
- ssgEntity *getModel () const { return model ; }
- void setModel ( ssgEntity *entity ) { model = entity; }
- void removeModel () ;
- void replaceModel ( ssgEntity *new_entity ) ;
-
- ssgVertexArray *getLocations () const { return locations; }
- ssgVertexArray *getOrientations () const { return orientations; }
-
- float *getLocation ( int i ) const { return locations->get( i ); }
- float *getOrientation ( int i ) const { return orientations->get( i ); }
- void addPlacement ( sgVec3 loc, sgVec3 orient );
- virtual int getNumPlacements() const { return locations->getNum(); }
- void removeAllPlacements();
-
- ssgTransform *getPosTransform() { return pos; }
-
- virtual const char *getTypeName(void) ;
- virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ;
- virtual void isect ( sgSphere *s, sgMat4 m, int test_needed ) ;
- virtual void hot ( sgVec3 s, sgMat4 m, int test_needed ) ;
- virtual void los ( sgVec3 s, sgMat4 m, int test_needed ) ;
- virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
-#ifdef HAVE_PLIB_PSL
- virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ;
-#endif
- virtual int load ( FILE *fd ) ;
- virtual int save ( FILE *fd ) ;
- virtual void recalcBSphere () ;
-} ;
-
-
-#endif // _SSG_ENTITY_ARRAY_HXX
+++ /dev/null
-.deps
-Makefile
-Makefile.in
+++ /dev/null
-noinst_LIBRARIES = libReplay.a
-
-libReplay_a_SOURCES = replay.hxx replay.cxx
-
-INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
+++ /dev/null
-// replay.cxx - a system to record and replay FlightGear flights
-//
-// Written by Curtis Olson, started Juley 2003.
-//
-// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-
-
-#include <simgear/constants.h>
-
-#include <FDM/flight.hxx>
-#include <Main/fg_props.hxx>
-#include <Network/native_ctrls.hxx>
-#include <Network/native_fdm.hxx>
-#include <Network/net_ctrls.hxx>
-#include <Network/net_fdm.hxx>
-
-#include "replay.hxx"
-
-const double FGReplay::st_list_time = 60.0; // 60 secs of high res data
-const double FGReplay::mt_list_time = 600.0; // 10 mins of 1 fps data
-const double FGReplay::lt_list_time = 3600.0; // 1 hr of 10 spf data
-
-// short term sample rate is as every frame
-const double FGReplay::mt_dt = 0.5; // medium term sample rate (sec)
-const double FGReplay::lt_dt = 5.0; // long term sample rate (sec)
-
-/**
- * Constructor
- */
-
-FGReplay::FGReplay() {
-}
-
-
-/**
- * Destructor
- */
-
-FGReplay::~FGReplay() {
- // no dynamically allocated memory to free
-}
-
-
-/**
- * Initialize the data structures
- */
-
-void FGReplay::init() {
- sim_time = 0.0;
- last_mt_time = 0.0;
- last_lt_time = 0.0;
-
- // Make sure all queues are flushed
- while ( !short_term.empty() ) {
- short_term.pop_front();
- }
- while ( !medium_term.empty() ) {
- medium_term.pop_front();
- }
- while ( !medium_term.empty() ) {
- medium_term.pop_front();
- }
-}
-
-
-/**
- * Bind to the property tree
- */
-
-void FGReplay::bind() {
- disable_replay = fgGetNode( "/sim/replay/disable", true );
-}
-
-
-/**
- * Unbind from the property tree
- */
-
-void FGReplay::unbind() {
- // nothing to unbind
-}
-
-
-/**
- * Update the saved data
- */
-
-void FGReplay::update( double dt ) {
- static SGPropertyNode *replay_master
- = fgGetNode( "/sim/freeze/replay", true );
-
- if( disable_replay->getBoolValue() ) {
- if( sim_time != 0.0 ) {
- // we were recording data
- init();
- }
- return;
- }
-
- if ( replay_master->getBoolValue() ) {
- // don't record the replay session
- return;
- }
-
- sim_time += dt;
-
- // build the replay record
- FGNetFDM f;
- FGProps2NetFDM( &f, false );
-
- // sanity check, don't collect data if FDM data isn't good
- if ( !cur_fdm_state->get_inited() ) {
- return;
- }
-
- FGNetCtrls c;
- FGProps2NetCtrls( &c, false, false );
-
- FGReplayData r;
- r.sim_time = sim_time;
- r.ctrls = c;
- r.fdm = f;
-
- // update the short term list
- short_term.push_back( r );
-
- FGReplayData st_front = short_term.front();
- if ( sim_time - st_front.sim_time > st_list_time ) {
- while ( sim_time - st_front.sim_time > st_list_time ) {
- st_front = short_term.front();
- short_term.pop_front();
- }
-
- // update the medium term list
- if ( sim_time - last_mt_time > mt_dt ) {
- last_mt_time = sim_time;
- medium_term.push_back( st_front );
-
- FGReplayData mt_front = medium_term.front();
- if ( sim_time - mt_front.sim_time > mt_list_time ) {
- while ( sim_time - mt_front.sim_time > mt_list_time ) {
- mt_front = medium_term.front();
- medium_term.pop_front();
- }
-
- // update the long term list
- if ( sim_time - last_lt_time > lt_dt ) {
- last_lt_time = sim_time;
- long_term.push_back( mt_front );
-
- FGReplayData lt_front = long_term.front();
- if ( sim_time - lt_front.sim_time > lt_list_time ) {
- while ( sim_time - lt_front.sim_time > lt_list_time ) {
- lt_front = long_term.front();
- long_term.pop_front();
- }
- }
- }
- }
- }
- }
-
-#if 0
- cout << "short term size = " << short_term.size()
- << " time = " << sim_time - short_term.front().sim_time
- << endl;
- cout << "medium term size = " << medium_term.size()
- << " time = " << sim_time - medium_term.front().sim_time
- << endl;
- cout << "long term size = " << long_term.size()
- << " time = " << sim_time - long_term.front().sim_time
- << endl;
-#endif
-}
-
-
-static double weight( double data1, double data2, double ratio,
- bool rotational = false ) {
- if ( rotational ) {
- // special handling of rotational data
- double tmp = data2 - data1;
- if ( tmp > SGD_PI ) {
- tmp -= SGD_2PI;
- } else if ( tmp < -SGD_PI ) {
- tmp += SGD_2PI;
- }
- return data1 + tmp * ratio;
- } else {
- // normal "linear" data
- return data1 + ( data2 - data1 ) * ratio;
- }
-}
-
-/**
- * given two FGReplayData elements and a time, interpolate between them
- */
-static void update_fdm( FGReplayData frame ) {
- FGNetFDM2Props( &frame.fdm, false );
- FGNetCtrls2Props( &frame.ctrls, false, false );
-}
-
-/**
- * given two FGReplayData elements and a time, interpolate between them
- */
-static FGReplayData interpolate( double time, FGReplayData f1, FGReplayData f2 )
-{
- FGReplayData result = f1;
-
- FGNetFDM fdm1 = f1.fdm;
- FGNetFDM fdm2 = f2.fdm;
-
- FGNetCtrls ctrls1 = f1.ctrls;
- FGNetCtrls ctrls2 = f2.ctrls;
-
- double ratio = (time - f1.sim_time) / (f2.sim_time - f1.sim_time);
-
- // Interpolate FDM data
-
- // Positions
- result.fdm.longitude = weight( fdm1.longitude, fdm2.longitude, ratio );
- result.fdm.latitude = weight( fdm1.latitude, fdm2.latitude, ratio );
- result.fdm.altitude = weight( fdm1.altitude, fdm2.altitude, ratio );
- result.fdm.agl = weight( fdm1.agl, fdm2.agl, ratio );
- result.fdm.phi = weight( fdm1.phi, fdm2.phi, ratio, true );
- result.fdm.theta = weight( fdm1.theta, fdm2.theta, ratio, true );
- result.fdm.psi = weight( fdm1.psi, fdm2.psi, ratio, true );
-
- // Velocities
- result.fdm.phidot = weight( fdm1.phidot, fdm2.phidot, ratio, true );
- result.fdm.thetadot = weight( fdm1.thetadot, fdm2.thetadot, ratio, true );
- result.fdm.psidot = weight( fdm1.psidot, fdm2.psidot, ratio, true );
- result.fdm.vcas = weight( fdm1.vcas, fdm2.vcas, ratio );
- result.fdm.climb_rate = weight( fdm1.climb_rate, fdm2.climb_rate, ratio );
- result.fdm.v_north = weight( fdm1.v_north, fdm2.v_north, ratio );
- result.fdm.v_east = weight( fdm1.v_east, fdm2.v_east, ratio );
- result.fdm.v_down = weight( fdm1.v_down, fdm2.v_down, ratio );
-
- result.fdm.v_wind_body_north
- = weight( fdm1.v_wind_body_north, fdm2.v_wind_body_north, ratio );
- result.fdm.v_wind_body_east
- = weight( fdm1.v_wind_body_east, fdm2.v_wind_body_east, ratio );
- result.fdm.v_wind_body_down
- = weight( fdm1.v_wind_body_down, fdm2.v_wind_body_down, ratio );
-
- // Stall
- result.fdm.stall_warning
- = weight( fdm1.stall_warning, fdm2.stall_warning, ratio );
-
- // Accelerations
- result.fdm.A_X_pilot = weight( fdm1.A_X_pilot, fdm2.A_X_pilot, ratio );
- result.fdm.A_Y_pilot = weight( fdm1.A_Y_pilot, fdm2.A_Y_pilot, ratio );
- result.fdm.A_Z_pilot = weight( fdm1.A_Z_pilot, fdm2.A_Z_pilot, ratio );
-
- unsigned int i;
-
- // Engine status
- for ( i = 0; i < fdm1.num_engines; ++i ) {
- result.fdm.eng_state[i] = fdm1.eng_state[i];
- result.fdm.rpm[i] = weight( fdm1.rpm[i], fdm2.rpm[i], ratio );
- result.fdm.fuel_flow[i]
- = weight( fdm1.fuel_flow[i], fdm2.fuel_flow[i], ratio );
- result.fdm.egt[i] = weight( fdm1.egt[i], fdm2.egt[i], ratio );
- result.fdm.cht[i] = weight( fdm1.cht[i], fdm2.cht[i], ratio );
- result.fdm.mp_osi[i] = weight( fdm1.mp_osi[i], fdm2.mp_osi[i], ratio );
- result.fdm.tit[i] = weight( fdm1.tit[i], fdm2.tit[i], ratio );
- result.fdm.oil_temp[i]
- = weight( fdm1.oil_temp[i], fdm2.oil_temp[i], ratio );
- result.fdm.oil_px[i] = weight( fdm1.oil_px[i], fdm2.oil_px[i], ratio );
- }
-
- // Consumables
- for ( i = 0; i < fdm1.num_tanks; ++i ) {
- result.fdm.fuel_quantity[i]
- = weight( fdm1.fuel_quantity[i], fdm2.fuel_quantity[i], ratio );
- }
-
- // Gear status
- for ( i = 0; i < fdm1.num_wheels; ++i ) {
- result.fdm.wow[i] = (int)(weight( fdm1.wow[i], fdm2.wow[i], ratio ));
- result.fdm.gear_pos[i]
- = weight( fdm1.gear_pos[i], fdm2.gear_pos[i], ratio );
- result.fdm.gear_steer[i]
- = weight( fdm1.gear_steer[i], fdm2.gear_steer[i], ratio );
- result.fdm.gear_compression[i]
- = weight( fdm1.gear_compression[i], fdm2.gear_compression[i],
- ratio );
- }
-
- // Environment
- result.fdm.cur_time = fdm1.cur_time;
- result.fdm.warp = fdm1.warp;
- result.fdm.visibility = weight( fdm1.visibility, fdm2.visibility, ratio );
-
- // Control surface positions (normalized values)
- result.fdm.elevator = weight( fdm1.elevator, fdm2.elevator, ratio );
- result.fdm.left_flap = weight( fdm1.left_flap, fdm2.left_flap, ratio );
- result.fdm.right_flap = weight( fdm1.right_flap, fdm2.right_flap, ratio );
- result.fdm.left_aileron
- = weight( fdm1.left_aileron, fdm2.left_aileron, ratio );
- result.fdm.right_aileron
- = weight( fdm1.right_aileron, fdm2.right_aileron, ratio );
- result.fdm.rudder = weight( fdm1.rudder, fdm2.rudder, ratio );
- result.fdm.speedbrake = weight( fdm1.speedbrake, fdm2.speedbrake, ratio );
- result.fdm.spoilers = weight( fdm1.spoilers, fdm2.spoilers, ratio );
-
- // Interpolate Control input data
-
- // Aero controls
- result.ctrls.aileron = weight( ctrls1.aileron, ctrls2.aileron, ratio );
- result.ctrls.elevator = weight( ctrls1.elevator, ctrls2.elevator, ratio );
- result.ctrls.rudder = weight( ctrls1.rudder, ctrls2.rudder, ratio );
- result.ctrls.aileron_trim
- = weight( ctrls1.aileron_trim, ctrls2.aileron_trim, ratio );
- result.ctrls.elevator_trim
- = weight( ctrls1.elevator_trim, ctrls2.elevator_trim, ratio );
- result.ctrls.rudder_trim
- = weight( ctrls1.rudder_trim, ctrls2.rudder_trim, ratio );
- result.ctrls.flaps = weight( ctrls1.flaps, ctrls2.flaps, ratio );
- result.ctrls.flaps_power = ctrls1.flaps_power;
- result.ctrls.flap_motor_ok = ctrls1.flap_motor_ok;
-
- // Engine controls
- for ( i = 0; i < ctrls1.num_engines; ++i ) {
- result.ctrls.master_bat[i] = ctrls1.master_bat[i];
- result.ctrls.master_alt[i] = ctrls1.master_alt[i];
- result.ctrls.magnetos[i] = ctrls1.magnetos[i];
- result.ctrls.starter_power[i] = ctrls1.starter_power[i];
- result.ctrls.throttle[i]
- = weight( ctrls1.throttle[i], ctrls2.throttle[i], ratio );
- result.ctrls.mixture[i]
- = weight( ctrls1.mixture[i], ctrls2.mixture[i], ratio );
- result.ctrls.fuel_pump_power[i] = ctrls1.fuel_pump_power[i];
- result.ctrls.prop_advance[i]
- = weight( ctrls1.prop_advance[i], ctrls2.prop_advance[i], ratio );
- result.ctrls.engine_ok[i] = ctrls1.engine_ok[i];
- result.ctrls.mag_left_ok[i] = ctrls1.mag_left_ok[i];
- result.ctrls.mag_right_ok[i] = ctrls1.mag_right_ok[i];
- result.ctrls.spark_plugs_ok[i] = ctrls1.spark_plugs_ok[i];
- result.ctrls.oil_press_status[i] = ctrls1.oil_press_status[i];
- result.ctrls.fuel_pump_ok[i] = ctrls1.fuel_pump_ok[i];
- }
-
- // Fuel management
- for ( i = 0; i < ctrls1.num_tanks; ++i ) {
- result.ctrls.fuel_selector[i] = ctrls1.fuel_selector[i];
- }
-
- // Brake controls
- result.ctrls.brake_left
- = weight( ctrls1.brake_left, ctrls2.brake_right, ratio );
- result.ctrls.brake_right
- = weight( ctrls1.brake_right, ctrls2.brake_right, ratio );
- result.ctrls.brake_parking
- = weight( ctrls1.brake_parking, ctrls2.brake_parking, ratio );
-
- // Landing Gear
- result.ctrls.gear_handle = ctrls1.gear_handle;
-
- // Switches
- result.ctrls.turbulence_norm = ctrls1.turbulence_norm;
-
- // wind and turbulance
- result.ctrls.wind_speed_kt
- = weight( ctrls1.wind_speed_kt, ctrls2.wind_speed_kt, ratio );
- result.ctrls.wind_dir_deg
- = weight( ctrls1.wind_dir_deg, ctrls2.wind_dir_deg, ratio );
- result.ctrls.turbulence_norm
- = weight( ctrls1.turbulence_norm, ctrls2.turbulence_norm, ratio );
-
- // other information about environment
- result.ctrls.hground = weight( ctrls1.hground, ctrls2.hground, ratio );
- result.ctrls.magvar = weight( ctrls1.magvar, ctrls2.magvar, ratio );
-
- // simulation control
- result.ctrls.speedup = ctrls1.speedup;
- result.ctrls.freeze = ctrls1.freeze;
-
- return result;
-}
-
-/**
- * interpolate a specific time from a specific list
- */
-static void interpolate( double time, const replay_list_type &list ) {
- // sanity checking
- if ( list.size() == 0 ) {
- // handle empty list
- return;
- } else if ( list.size() == 1 ) {
- // handle list size == 1
- update_fdm( list[0] );
- return;
- }
-
- unsigned int last = list.size() - 1;
- unsigned int first = 0;
- unsigned int mid = ( last + first ) / 2;
-
-
- bool done = false;
- while ( !done ) {
- // cout << " " << first << " <=> " << last << endl;
- if ( last == first ) {
- done = true;
- } else if ( list[mid].sim_time < time && list[mid+1].sim_time < time ) {
- // too low
- first = mid;
- mid = ( last + first ) / 2;
- } else if ( list[mid].sim_time > time && list[mid+1].sim_time > time ) {
- // too high
- last = mid;
- mid = ( last + first ) / 2;
- } else {
- done = true;
- }
- }
-
- FGReplayData result = interpolate( time, list[mid], list[mid+1] );
-
- update_fdm( result );
-}
-
-
-/**
- * Replay a saved frame based on time, interpolate from the two
- * nearest saved frames.
- */
-
-void FGReplay::replay( double time ) {
- // cout << "replay: " << time << " ";
- // find the two frames to interpolate between
- double t1, t2;
-
- if ( short_term.size() > 0 ) {
- t1 = short_term.back().sim_time;
- t2 = short_term.front().sim_time;
- if ( time > t1 ) {
- // replay the most recent frame
- update_fdm( short_term.back() );
- // cout << "first frame" << endl;
- } else if ( time <= t1 && time >= t2 ) {
- interpolate( time, short_term );
- // cout << "from short term" << endl;
- } else if ( medium_term.size() > 0 ) {
- t1 = short_term.front().sim_time;
- t2 = medium_term.back().sim_time;
- if ( time <= t1 && time >= t2 ) {
- FGReplayData result = interpolate( time,
- medium_term.back(),
- short_term.front() );
- update_fdm( result );
- // cout << "from short/medium term" << endl;
- } else {
- t1 = medium_term.back().sim_time;
- t2 = medium_term.front().sim_time;
- if ( time <= t1 && time >= t2 ) {
- interpolate( time, medium_term );
- // cout << "from medium term" << endl;
- } else if ( long_term.size() > 0 ) {
- t1 = medium_term.front().sim_time;
- t2 = long_term.back().sim_time;
- if ( time <= t1 && time >= t2 ) {
- FGReplayData result = interpolate( time,
- long_term.back(),
- medium_term.front());
- update_fdm( result );
- // cout << "from medium/long term" << endl;
- } else {
- t1 = long_term.back().sim_time;
- t2 = long_term.front().sim_time;
- if ( time <= t1 && time >= t2 ) {
- interpolate( time, long_term );
- // cout << "from long term" << endl;
- } else {
- // replay the oldest long term frame
- update_fdm( long_term.front() );
- // cout << "oldest long term frame" << endl;
- }
- }
- } else {
- // replay the oldest medium term frame
- update_fdm( medium_term.front() );
- // cout << "oldest medium term frame" << endl;
- }
- }
- } else {
- // replay the oldest short term frame
- update_fdm( short_term.front() );
- // cout << "oldest short term frame" << endl;
- }
- } else {
- // nothing to replay
- }
-}
-
-
-double FGReplay::get_start_time() {
- if ( long_term.size() > 0 ) {
- return long_term.front().sim_time;
- } else if ( medium_term.size() > 0 ) {
- return medium_term.front().sim_time;
- } else if ( short_term.size() ) {
- return short_term.front().sim_time;
- } else {
- return 0.0;
- }
-}
-
-double FGReplay::get_end_time() {
- if ( short_term.size() ) {
- return short_term.back().sim_time;
- } else {
- return 0.0;
- }
-}
+++ /dev/null
-// replay.hxx - a system to record and replay FlightGear flights
-//
-// Written by Curtis Olson, started Juley 2003.
-//
-// Copyright (C) 2003 Curtis L. Olson - http://www.flightgear.org/~curt
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-
-
-#ifndef _FG_REPLAY_HXX
-#define _FG_REPLAY_HXX 1
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <simgear/compiler.h>
-
-#include <deque>
-
-#include <simgear/math/sg_types.hxx>
-#include <simgear/props/props.hxx>
-#include <simgear/structure/subsystem_mgr.hxx>
-
-#include <Network/net_ctrls.hxx>
-#include <Network/net_fdm.hxx>
-
-SG_USING_STD(deque);
-
-
-class FGReplayData {
-
-public:
-
- double sim_time;
- FGNetFDM fdm;
- FGNetCtrls ctrls;
-};
-
-typedef deque < FGReplayData > replay_list_type;
-
-
-
-/**
- * A recording/replay module for FlightGear flights
- *
- */
-
-class FGReplay : public SGSubsystem
-{
-
-public:
-
- FGReplay ();
- virtual ~FGReplay();
-
- virtual void init();
- virtual void bind();
- virtual void unbind();
- virtual void update( double dt );
-
- void replay( double time );
- double get_start_time();
- double get_end_time();
-
-private:
-
- static const double st_list_time; // 60 secs of high res data
- static const double mt_list_time; // 10 mins of 1 fps data
- static const double lt_list_time; // 1 hr of 10 spf data
-
- // short term sample rate is as every frame
- static const double mt_dt; // medium term sample rate (sec)
- static const double lt_dt; // long term sample rate (sec)
-
- double sim_time;
- double last_mt_time;
- double last_lt_time;
-
- replay_list_type short_term;
- replay_list_type medium_term;
- replay_list_type long_term;
- SGPropertyNode_ptr disable_replay;
-};
-
-
-#endif // _FG_REPLAY_HXX