diff --git a/src/Autopilot/newauto.cxx b/src/Autopilot/newauto.cxx index b0a41c728..8c7eb6f86 100644 --- a/src/Autopilot/newauto.cxx +++ b/src/Autopilot/newauto.cxx @@ -219,6 +219,7 @@ void FGAutopilot::init() { heading_hold = false ; // turn the heading hold off altitude_hold = false ; // turn the altitude hold off auto_throttle = false ; // turn the auto throttle off + heading_mode = DEFAULT_AP_HEADING_LOCK; sg_srandom_time(); DGTargetHeading = sg_random() * 360.0; @@ -235,8 +236,8 @@ void FGAutopilot::init() { alt_error_accum = 0.0; climb_error_accum = 0.0; - MakeTargetAltitudeStr( 3000.0); - MakeTargetHeadingStr( 0.0 ); + MakeTargetAltitudeStr( TargetAltitude ); + MakeTargetHeadingStr( TargetHeading ); // These eventually need to be read from current_aircaft somehow. @@ -279,11 +280,12 @@ void FGAutopilot::reset() { heading_hold = false ; // turn the heading hold off altitude_hold = false ; // turn the altitude hold off auto_throttle = false ; // turn the auto throttle off + heading_mode = DEFAULT_AP_HEADING_LOCK; - TargetHeading = 0.0; // default direction, due north + // TargetHeading = 0.0; // default direction, due north MakeTargetHeadingStr( TargetHeading ); - TargetAltitude = 3000; // default altitude in meters + // TargetAltitude = 3000; // default altitude in meters MakeTargetAltitudeStr( TargetAltitude ); alt_error_accum = 0.0; @@ -395,6 +397,9 @@ int FGAutopilot::run() { // coordinator zero'd } else if ( heading_mode == FG_TRUE_HEADING_LOCK ) { // leave "true" target heading as is + while ( TargetHeading < 0.0 ) { TargetHeading += 360.0; } + while ( TargetHeading > 360.0 ) { TargetHeading -= 360.0; } + MakeTargetHeadingStr( TargetHeading ); } else if ( heading_mode == FG_HEADING_NAV1 ) { // track the NAV1 heading needle deflection @@ -1010,13 +1015,19 @@ void FGAutopilot::HeadingAdjust( double inc ) { void FGAutopilot::HeadingSet( double new_heading ) { - heading_mode = FG_DG_HEADING_LOCK; - - new_heading = NormalizeDegrees( new_heading ); - DGTargetHeading = new_heading; - // following cast needed ambiguous plib - // ApHeadingDialogInput -> setValue ((float)APData->TargetHeading ); - MakeTargetHeadingStr( DGTargetHeading ); + if( heading_mode == FG_TRUE_HEADING_LOCK ) { + new_heading = NormalizeDegrees( new_heading ); + TargetHeading = new_heading; + MakeTargetHeadingStr( TargetHeading ); + } else { + heading_mode = FG_DG_HEADING_LOCK; + + new_heading = NormalizeDegrees( new_heading ); + DGTargetHeading = new_heading; + // following cast needed ambiguous plib + // ApHeadingDialogInput -> setValue ((float)APData->TargetHeading ); + MakeTargetHeadingStr( DGTargetHeading ); + } update_old_control_values(); } diff --git a/src/Input/input.cxx b/src/Input/input.cxx index b6e8b6d66..f3dcdb756 100644 --- a/src/Input/input.cxx +++ b/src/Input/input.cxx @@ -26,6 +26,8 @@ #include +#include + #include STL_FSTREAM #include STL_STRING @@ -69,152 +71,152 @@ SG_USING_STD(string); //////////////////////////////////////////////////////////////////////// FGBinding::FGBinding () - : _action(ACTION_NONE), _node(0), _adjust_step(0), _assign_value(0) + : _action(ACTION_NONE), _node(0), _adjust_step(0), _assign_value(0) { } FGBinding::FGBinding (const SGPropertyNode * node) - : _action(ACTION_NONE), _node(0), _adjust_step(0), _assign_value(0) + : _action(ACTION_NONE), _node(0), _adjust_step(0), _assign_value(0) { - read(node); + read(node); } FGBinding::~FGBinding () { - // no op + // no op } void FGBinding::setAction (Action action) { - _action = action; + _action = action; } void FGBinding::setProperty (SGPropertyNode * node) { - _node = node; + _node = node; } void FGBinding::setAdjustStep (const SGValue * step) { - _adjust_step = step; + _adjust_step = step; } void FGBinding::setAssignValue (const SGValue * value) { - _assign_value = value; + _assign_value = value; } void FGBinding::read (const SGPropertyNode * node) { - if (node->hasValue("action")) { - string action = node->getStringValue("action"); - if (action == "none") - _action = ACTION_NONE; - else if (action == "switch") - _action = ACTION_SWITCH; - else if (action == "adjust") - _action = ACTION_ADJUST; - else if (action == "assign") - _action = ACTION_ASSIGN; - else - SG_LOG(SG_INPUT, SG_ALERT, "Ignoring unrecognized action type " - << action); - } + if (node->hasValue("action")) { + string action = node->getStringValue("action"); + if (action == "none") + _action = ACTION_NONE; + else if (action == "switch") + _action = ACTION_SWITCH; + else if (action == "adjust") + _action = ACTION_ADJUST; + else if (action == "assign") + _action = ACTION_ASSIGN; + else + SG_LOG(SG_INPUT, SG_ALERT, "Ignoring unrecognized action type " + << action); + } - if (node->hasValue("control")) - _node = fgGetNode(node->getStringValue("control"), true); + if (node->hasValue("control")) + _node = fgGetNode(node->getStringValue("control"), true); - if (node->hasValue("step")) - _adjust_step = node->getChild("step")->getValue(); + if (node->hasValue("step")) + _adjust_step = node->getChild("step")->getValue(); - if (node->hasValue("value")) - _assign_value = node->getChild("value")->getValue(); + if (node->hasValue("value")) + _assign_value = node->getChild("value")->getValue(); } void FGBinding::fire () const { - if (_node == 0) { - SG_LOG(SG_INPUT, SG_ALERT, "No control property attached to binding"); - return; - } - - switch (_action) { - - case ACTION_NONE: - break; - - case ACTION_SWITCH: - _node->setBoolValue(!_node->getBoolValue()); - break; - - case ACTION_ADJUST: - if (_adjust_step == 0) { - SG_LOG(SG_INPUT, SG_ALERT, "No step provided for adjust binding"); - break; + if (_node == 0) { + SG_LOG(SG_INPUT, SG_ALERT, "No control property attached to binding"); + return; } - switch (_node->getType()) { - case SGValue::BOOL: - if (_adjust_step->getBoolValue()) - _node->setBoolValue(!_node->getBoolValue()); - break; - case SGValue::INT: - _node->setIntValue(_node->getIntValue() + _adjust_step->getIntValue()); - break; - case SGValue::LONG: - _node->setLongValue(_node->getLongValue() + _adjust_step->getLongValue()); - break; - case SGValue::FLOAT: - _node->setFloatValue(_node->getFloatValue() - + _adjust_step->getFloatValue()); - break; - case SGValue::DOUBLE: - case SGValue::UNKNOWN: // force to double - _node->setDoubleValue(_node->getDoubleValue() - + _adjust_step->getDoubleValue()); - break; - case SGValue::STRING: - SG_LOG(SG_INPUT, SG_ALERT, "Cannot increment or decrement string value" - << _node->getStringValue()); - break; - } - break; - case ACTION_ASSIGN: - if (_assign_value == 0) { - SG_LOG(SG_INPUT, SG_ALERT, "No value provided for assign binding"); - break; + switch (_action) { + + case ACTION_NONE: + break; + + case ACTION_SWITCH: + _node->setBoolValue(!_node->getBoolValue()); + break; + + case ACTION_ADJUST: + if (_adjust_step == 0) { + SG_LOG(SG_INPUT, SG_ALERT, "No step provided for adjust binding"); + break; + } + switch (_node->getType()) { + case SGValue::BOOL: + if (_adjust_step->getBoolValue()) + _node->setBoolValue(!_node->getBoolValue()); + break; + case SGValue::INT: + _node->setIntValue(_node->getIntValue() + _adjust_step->getIntValue()); + break; + case SGValue::LONG: + _node->setLongValue(_node->getLongValue() + _adjust_step->getLongValue()); + break; + case SGValue::FLOAT: + _node->setFloatValue(_node->getFloatValue() + + _adjust_step->getFloatValue()); + break; + case SGValue::DOUBLE: + case SGValue::UNKNOWN: // force to double + _node->setDoubleValue(_node->getDoubleValue() + + _adjust_step->getDoubleValue()); + break; + case SGValue::STRING: + SG_LOG(SG_INPUT, SG_ALERT, "Cannot increment or decrement string value" + << _node->getStringValue()); + break; + } + break; + + case ACTION_ASSIGN: + if (_assign_value == 0) { + SG_LOG(SG_INPUT, SG_ALERT, "No value provided for assign binding"); + break; + } + switch (_node->getType()) { + case SGValue::BOOL: + _node->setBoolValue(_assign_value->getBoolValue()); + break; + case SGValue::INT: + _node->setIntValue(_assign_value->getIntValue()); + break; + case SGValue::LONG: + _node->setLongValue(_assign_value->getLongValue()); + break; + case SGValue::FLOAT: + _node->setFloatValue(_assign_value->getFloatValue()); + break; + case SGValue::DOUBLE: + _node->setDoubleValue(_assign_value->getDoubleValue()); + break; + case SGValue::STRING: + _node->setStringValue(_assign_value->getStringValue()); + break; + case SGValue::UNKNOWN: + _node->setUnknownValue(_assign_value->getStringValue()); + break; + } + break; } - switch (_node->getType()) { - case SGValue::BOOL: - _node->setBoolValue(_assign_value->getBoolValue()); - break; - case SGValue::INT: - _node->setIntValue(_assign_value->getIntValue()); - break; - case SGValue::LONG: - _node->setLongValue(_assign_value->getLongValue()); - break; - case SGValue::FLOAT: - _node->setFloatValue(_assign_value->getFloatValue()); - break; - case SGValue::DOUBLE: - _node->setDoubleValue(_assign_value->getDoubleValue()); - break; - case SGValue::STRING: - _node->setStringValue(_assign_value->getStringValue()); - break; - case SGValue::UNKNOWN: - _node->setUnknownValue(_assign_value->getStringValue()); - break; - } - break; - } } @@ -223,7 +225,7 @@ FGBinding::fire () const // Implementation of FGInput. //////////////////////////////////////////////////////////////////////// - // From main.cxx +// From main.cxx extern void fgReshape( int width, int height ); FGInput current_input; @@ -231,96 +233,102 @@ FGInput current_input; FGInput::FGInput () { - // no op + // no op } FGInput::~FGInput () { - // no op + // no op } void FGInput::init () { - // Read the keyboard bindings. - // TODO: zero the old bindings first. - const SGPropertyNode * keyboard = - globals->get_props()->getNode("/input/keyboard", true); - vector keys = keyboard->getChildren("key"); + // Read the keyboard bindings. + // TODO: zero the old bindings first. + const SGPropertyNode * keyboard = + globals->get_props()->getNode("/input/keyboard", true); + vector keys = keyboard->getChildren("key"); - for (unsigned int i = 0; i < keys.size(); i++) { - int index = keys[i]->getIndex(); - int modifiers = FG_MOD_NONE; - if (keys[i]->getBoolValue("mod-shift")) - modifiers |= FG_MOD_SHIFT; - if (keys[i]->getBoolValue("mod-ctrl")) - modifiers |= FG_MOD_CTRL; - if (keys[i]->getBoolValue("mod-alt")) - modifiers |= FG_MOD_ALT; - SG_LOG(SG_INPUT, SG_INFO, "Binding key " << index - << " with modifiers " << modifiers); + for (unsigned int i = 0; i < keys.size(); i++) { + int code = keys[i]->getIndex(); + int modifiers = FG_MOD_NONE; + if (keys[i]->getBoolValue("mod-shift")) + modifiers |= FG_MOD_SHIFT; + if (keys[i]->getBoolValue("mod-ctrl")) + modifiers |= FG_MOD_CTRL; + if (keys[i]->getBoolValue("mod-alt")) + modifiers |= FG_MOD_ALT; - vector bindings = keys[i]->getChildren("binding"); - for (unsigned int j = 0; j < bindings.size(); j++) { - SG_LOG(SG_INPUT, SG_INFO, " Adding binding " << j); - _key_bindings[modifiers][index].push_back(FGBinding(bindings[j])); + if (code < 0) { + SG_LOG(SG_INPUT, SG_ALERT, "Key stroke not bound = " + << keys[i]->getStringValue("name", "[unnamed]")); + } else { + SG_LOG(SG_INPUT, SG_INFO, "Binding key " << code + << " with modifiers " << modifiers); + vector bindings = + keys[i]->getChildren("binding"); + for (unsigned int j = 0; j < bindings.size(); j++) { + SG_LOG(SG_INPUT, SG_INFO, " Adding binding " << j); + _key_bindings[modifiers][code].push_back(FGBinding(bindings[j])); + } + } } - } } void FGInput::bind () { - // no op + // no op } void FGInput::unbind () { - // no op + // no op } void FGInput::update () { - // we'll do something here with the joystick + // we'll do something here with the joystick } void FGInput::doKey (int k, int modifiers, int x, int y) { - float fov, tmp; - static bool winding_ccw = true; - int speed; + float fov, tmp; + static bool winding_ccw = true; + int speed; - SG_LOG(SG_INPUT, SG_INFO, "User pressed key " << k - << " with modifiers " << modifiers); + SG_LOG(SG_INPUT, SG_INFO, "User pressed key " << k + << " with modifiers " << modifiers); - if (_key_bindings[modifiers].find(k) != _key_bindings[modifiers].end()) { - const vector &bindings = _key_bindings[modifiers][k]; - for (unsigned int i = 0; i < bindings.size(); i++) { - bindings[i].fire(); + if (_key_bindings[modifiers].find(k) != _key_bindings[modifiers].end()) { + const vector &bindings = _key_bindings[modifiers][k]; + for (unsigned int i = 0; i < bindings.size(); i++) { + bindings[i].fire(); + } + return; } - return; - } - SG_LOG(SG_INPUT, SG_INFO, "(No user binding.)"); + SG_LOG(SG_INPUT, SG_INFO, "(No user binding.)"); - // Use the old, default actions. - FGInterface *f = current_aircraft.fdm_state; - FGViewer *v = globals->get_current_view(); + // Use the old, default actions. + FGInterface *f = current_aircraft.fdm_state; + FGViewer *v = globals->get_current_view(); - // everything after here will be removed sooner or later... + // everything after here will be removed sooner or later... - if (modifiers & FG_MOD_SHIFT) { + if (modifiers & FG_MOD_SHIFT) { switch (k) { case 7: // Ctrl-G key current_autopilot->set_AltitudeMode( - FGAutopilot::FG_ALTITUDE_GS1 ); + FGAutopilot::FG_ALTITUDE_GS1 ); current_autopilot->set_AltitudeEnabled( - ! current_autopilot->get_AltitudeEnabled() - ); + ! current_autopilot->get_AltitudeEnabled() + ); return; case 18: // Ctrl-R key // temporary @@ -333,15 +341,15 @@ FGInput::doKey (int k, int modifiers, int x, int y) return; case 19: // Ctrl-S key current_autopilot->set_AutoThrottleEnabled( - ! current_autopilot->get_AutoThrottleEnabled() - ); + ! current_autopilot->get_AutoThrottleEnabled() + ); return; case 20: // Ctrl-T key current_autopilot->set_AltitudeMode( - FGAutopilot::FG_ALTITUDE_TERRAIN ); + FGAutopilot::FG_ALTITUDE_TERRAIN ); current_autopilot->set_AltitudeEnabled( - ! current_autopilot->get_AltitudeEnabled() - ); + ! current_autopilot->get_AltitudeEnabled() + ); return; case 49: // numeric keypad 1 v->set_goal_view_offset( SGD_PI * 0.75 ); @@ -412,7 +420,7 @@ FGInput::doKey (int k, int modifiers, int x, int y) #endif return; -// START SPECIALS + // START SPECIALS case 256+GLUT_KEY_F1: { ifstream input("fgfs.sav"); @@ -521,7 +529,7 @@ FGInput::doKey (int k, int modifiers, int x, int y) v->set_goal_view_offset( SGD_PI * 1.75 ); return; -// END SPECIALS + // END SPECIALS } @@ -624,7 +632,7 @@ FGInput::doKey (int k, int modifiers, int x, int y) ConfirmExitDialog(); return; -// START SPECIALS + // START SPECIALS case 256+GLUT_KEY_F2: // F2 Reload Tile Cache... { @@ -636,8 +644,8 @@ FGInput::doKey (int k, int modifiers, int x, int y) if ( global_tile_mgr.init() ) { // Load the local scenery data global_tile_mgr.update( - cur_fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES, - cur_fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES ); + cur_fdm_state->get_Longitude() * SGD_RADIANS_TO_DEGREES, + cur_fdm_state->get_Latitude() * SGD_RADIANS_TO_DEGREES ); } else { SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" ); @@ -645,7 +653,7 @@ FGInput::doKey (int k, int modifiers, int x, int y) } BusyCursor(1); if ( !freeze ) - globals->set_freeze( false ); + globals->set_freeze( false ); return; } case 256+GLUT_KEY_F3: // F3 Take a screen shot @@ -658,28 +666,28 @@ FGInput::doKey (int k, int modifiers, int x, int y) if ( current_autopilot->get_HeadingMode() != FGAutopilot::FG_HEADING_WAYPOINT ) { current_autopilot->set_HeadingMode( - FGAutopilot::FG_HEADING_WAYPOINT ); + FGAutopilot::FG_HEADING_WAYPOINT ); current_autopilot->set_HeadingEnabled( true ); } else { current_autopilot->set_HeadingMode( - FGAutopilot::FG_TC_HEADING_LOCK ); + FGAutopilot::FG_TC_HEADING_LOCK ); } return; case 256+GLUT_KEY_F8: {// F8 toggles fog ... off fastest nicest... const string &fog = fgGetString("/sim/rendering/fog"); if (fog == "disabled") { - fgSetString("/sim/rendering/fog", "fastest"); - SG_LOG(SG_INPUT, SG_INFO, "Fog enabled, hint=fastest"); + fgSetString("/sim/rendering/fog", "fastest"); + SG_LOG(SG_INPUT, SG_INFO, "Fog enabled, hint=fastest"); } else if (fog == "fastest") { - fgSetString("/sim/rendering/fog", "nicest"); - SG_LOG(SG_INPUT, SG_INFO, "Fog enabled, hint=nicest"); + fgSetString("/sim/rendering/fog", "nicest"); + SG_LOG(SG_INPUT, SG_INFO, "Fog enabled, hint=nicest"); } else if (fog == "nicest") { - fgSetString("/sim/rendering/fog", "disabled"); - SG_LOG(SG_INPUT, SG_INFO, "Fog disabled"); + fgSetString("/sim/rendering/fog", "disabled"); + SG_LOG(SG_INPUT, SG_INFO, "Fog disabled"); } else { - fgSetString("/sim/rendering/fog", "disabled"); - SG_LOG(SG_INPUT, SG_ALERT, "Unrecognized fog type " - << fog << ", changed to 'disabled'"); + fgSetString("/sim/rendering/fog", "disabled"); + SG_LOG(SG_INPUT, SG_ALERT, "Unrecognized fog type " + << fog << ", changed to 'disabled'"); } return; } @@ -707,7 +715,7 @@ FGInput::doKey (int k, int modifiers, int x, int y) return; } -// END SPECIALS + // END SPECIALS } } @@ -716,110 +724,110 @@ FGInput::doKey (int k, int modifiers, int x, int y) void FGInput::action (const SGPropertyNode * binding) { - const string &action = binding->getStringValue("action", ""); - const string &control = binding->getStringValue("control", ""); - bool repeatable = binding->getBoolValue("repeatable", false); - int step = binding->getIntValue("step", 0.0); + const string &action = binding->getStringValue("action", ""); + const string &control = binding->getStringValue("control", ""); + bool repeatable = binding->getBoolValue("repeatable", false); + int step = binding->getIntValue("step", 0.0); - if (control == "") { - SG_LOG(SG_INPUT, SG_ALERT, "No control specified for key " - << binding->getIndex()); - return; - } - - else if (action == "") { - SG_LOG(SG_INPUT, SG_ALERT, "No action specified for key " - << binding->getIndex()); - return; - } - - else if (action == "switch") { - fgSetBool(control, !fgGetBool(control)); - } - - else if (action == "adjust") { - const SGValue * step = binding->getValue("step"); - if (step == 0) { - SG_LOG(SG_INPUT, SG_ALERT, "No step supplied for adjust action for key " - << binding->getIndex()); - return; + if (control == "") { + SG_LOG(SG_INPUT, SG_ALERT, "No control specified for key " + << binding->getIndex()); + return; } - SGValue * target = fgGetValue(control, true); - // Use the target's type... - switch (target->getType()) { - case SGValue::BOOL: - case SGValue::INT: - target->setIntValue(target->getIntValue() + step->getIntValue()); - break; - case SGValue::LONG: - target->setLongValue(target->getLongValue() + step->getLongValue()); - break; - case SGValue::FLOAT: - target->setFloatValue(target->getFloatValue() + step->getFloatValue()); - break; - case SGValue::DOUBLE: - case SGValue::UNKNOWN: // treat unknown as a double - target->setDoubleValue(target->getDoubleValue() - + step->getDoubleValue()); - break; - case SGValue::STRING: - SG_LOG(SG_INPUT, SG_ALERT, "Failed attempt to adjust string property " - << control); - break; - } - } - else if (action == "assign") { - const SGValue * value = binding->getValue("value"); - if (value == 0) { - SG_LOG(SG_INPUT, SG_ALERT, "No value supplied for assign action for key " - << binding->getIndex()); - return; + else if (action == "") { + SG_LOG(SG_INPUT, SG_ALERT, "No action specified for key " + << binding->getIndex()); + return; } - SGValue * target = fgGetValue(control, true); - // Use the target's type... - switch (target->getType()) { - case SGValue::BOOL: - target->setBoolValue(value->getBoolValue()); - break; - case SGValue::INT: - target->setIntValue(value->getIntValue()); - break; - case SGValue::LONG: - target->setLongValue(value->getLongValue()); - break; - case SGValue::FLOAT: - target->setFloatValue(value->getFloatValue()); - break; - case SGValue::DOUBLE: - target->setDoubleValue(value->getDoubleValue()); - break; - case SGValue::STRING: - target->setStringValue(value->getStringValue()); - break; - case SGValue::UNKNOWN: - target->setUnknownValue(value->getStringValue()); - break; - } - } - else { - SG_LOG(SG_INPUT, SG_ALERT, "Unknown action " << action - << " for key " << binding->getIndex()); - } + else if (action == "switch") { + fgSetBool(control, !fgGetBool(control)); + } + + else if (action == "adjust") { + const SGValue * step = binding->getValue("step"); + if (step == 0) { + SG_LOG(SG_INPUT, SG_ALERT, "No step supplied for adjust action for key " + << binding->getIndex()); + return; + } + SGValue * target = fgGetValue(control, true); + // Use the target's type... + switch (target->getType()) { + case SGValue::BOOL: + case SGValue::INT: + target->setIntValue(target->getIntValue() + step->getIntValue()); + break; + case SGValue::LONG: + target->setLongValue(target->getLongValue() + step->getLongValue()); + break; + case SGValue::FLOAT: + target->setFloatValue(target->getFloatValue() + step->getFloatValue()); + break; + case SGValue::DOUBLE: + case SGValue::UNKNOWN: // treat unknown as a double + target->setDoubleValue(target->getDoubleValue() + + step->getDoubleValue()); + break; + case SGValue::STRING: + SG_LOG(SG_INPUT, SG_ALERT, "Failed attempt to adjust string property " + << control); + break; + } + } + + else if (action == "assign") { + const SGValue * value = binding->getValue("value"); + if (value == 0) { + SG_LOG(SG_INPUT, SG_ALERT, "No value supplied for assign action for key " + << binding->getIndex()); + return; + } + SGValue * target = fgGetValue(control, true); + // Use the target's type... + switch (target->getType()) { + case SGValue::BOOL: + target->setBoolValue(value->getBoolValue()); + break; + case SGValue::INT: + target->setIntValue(value->getIntValue()); + break; + case SGValue::LONG: + target->setLongValue(value->getLongValue()); + break; + case SGValue::FLOAT: + target->setFloatValue(value->getFloatValue()); + break; + case SGValue::DOUBLE: + target->setDoubleValue(value->getDoubleValue()); + break; + case SGValue::STRING: + target->setStringValue(value->getStringValue()); + break; + case SGValue::UNKNOWN: + target->setUnknownValue(value->getStringValue()); + break; + } + } + + else { + SG_LOG(SG_INPUT, SG_ALERT, "Unknown action " << action + << " for key " << binding->getIndex()); + } } #if 0 - FGViewer *v = globals->get_current_view(); +FGViewer *v = globals->get_current_view(); - SG_LOG( SG_INPUT, SG_DEBUG, "Special key hit = " << k ); +SG_LOG( SG_INPUT, SG_DEBUG, "Special key hit = " << k ); - if ( GLUT_ACTIVE_SHIFT && glutGetModifiers() ) { - SG_LOG( SG_INPUT, SG_DEBUG, " SHIFTED" ); - switch (k) - } else -} +if ( GLUT_ACTIVE_SHIFT && glutGetModifiers() ) { + SG_LOG( SG_INPUT, SG_DEBUG, " SHIFTED" ); + switch (k) + } else + } #endif diff --git a/src/Input/input.hxx b/src/Input/input.hxx index 2e2dc8703..46d8c6c2c 100644 --- a/src/Input/input.hxx +++ b/src/Input/input.hxx @@ -174,6 +174,11 @@ public: private: + /** + * Look up the bindings for a key code. + */ + const vector * _find_bindings (int k, int modifiers); + typedef map > keyboard_map; keyboard_map _key_bindings[FG_MOD_MAX]; diff --git a/src/Main/bfi.cxx b/src/Main/bfi.cxx index 3707f4e8e..c1ab91178 100644 --- a/src/Main/bfi.cxx +++ b/src/Main/bfi.cxx @@ -207,6 +207,14 @@ FGBFI::init () false); fgTie("/autopilot/locks/wing-leveler", getAPWingLeveler, setAPWingLeveler); fgTie("/autopilot/locks/nav1", getAPNAV1Lock, setAPNAV1Lock); + fgTie("/autopilot/locks/auto-throttle", + getAPAutoThrottleLock, setAPAutoThrottleLock); + fgTie("/autopilot/control-overrides/rudder", + getAPRudderControl, setAPRudderControl); + fgTie("/autopilot/control-overrides/elevator", + getAPElevatorControl, setAPElevatorControl); + fgTie("/autopilot/control-overrides/throttle", + getAPThrottleControl, setAPThrottleControl); // Weather fgTie("/environment/visibility", getVisibility, setVisibility); @@ -737,271 +745,6 @@ FGBFI::getSpeedDown () // } - -//////////////////////////////////////////////////////////////////////// -// Controls -//////////////////////////////////////////////////////////////////////// - -#if 0 - -/** - * Get the throttle setting, from 0.0 (none) to 1.0 (full). - */ -double -FGBFI::getThrottle () -{ - // FIXME: add engine selector - return controls.get_throttle(0); -} - - -/** - * Set the throttle, from 0.0 (none) to 1.0 (full). - */ -void -FGBFI::setThrottle (double throttle) -{ - // FIXME: allow engine selection - controls.set_throttle(0, throttle); -} - - -/** - * Get the fuel mixture setting, from 0.0 (none) to 1.0 (full). - */ -double -FGBFI::getMixture () -{ - // FIXME: add engine selector - return controls.get_mixture(0); -} - - -/** - * Set the fuel mixture, from 0.0 (none) to 1.0 (full). - */ -void -FGBFI::setMixture (double mixture) -{ - // FIXME: allow engine selection - controls.set_mixture(0, mixture); -} - - -/** - * Get the propellor pitch setting, from 0.0 (none) to 1.0 (full). - */ -double -FGBFI::getPropAdvance () -{ - // FIXME: add engine selector - return controls.get_prop_advance(0); -} - - -/** - * Set the propellor pitch, from 0.0 (none) to 1.0 (full). - */ -void -FGBFI::setPropAdvance (double pitch) -{ - // FIXME: allow engine selection - controls.set_prop_advance(0, pitch); -} - - -/** - * Get the flaps setting, from 0.0 (none) to 1.0 (full). - */ -double -FGBFI::getFlaps () -{ - return controls.get_flaps(); -} - - -/** - * Set the flaps, from 0.0 (none) to 1.0 (full). - */ -void -FGBFI::setFlaps (double flaps) -{ - // FIXME: clamp? - controls.set_flaps(flaps); -} - - -/** - * Get the aileron, from -1.0 (left) to 1.0 (right). - */ -double -FGBFI::getAileron () -{ - return controls.get_aileron(); -} - - -/** - * Set the aileron, from -1.0 (left) to 1.0 (right). - */ -void -FGBFI::setAileron (double aileron) -{ - // FIXME: clamp? - controls.set_aileron(aileron); -} - - -/** - * Get the rudder setting, from -1.0 (left) to 1.0 (right). - */ -double -FGBFI::getRudder () -{ - return controls.get_rudder(); -} - - -/** - * Set the rudder, from -1.0 (left) to 1.0 (right). - */ -void -FGBFI::setRudder (double rudder) -{ - // FIXME: clamp? - controls.set_rudder(rudder); -} - - -/** - * Get the elevator setting, from -1.0 (down) to 1.0 (up). - */ -double -FGBFI::getElevator () -{ - return controls.get_elevator(); -} - - -/** - * Set the elevator, from -1.0 (down) to 1.0 (up). - */ -void -FGBFI::setElevator (double elevator) -{ - // FIXME: clamp? - controls.set_elevator(elevator); -} - - -/** - * Get the elevator trim, from -1.0 (down) to 1.0 (up). - */ -double -FGBFI::getElevatorTrim () -{ - return controls.get_elevator_trim(); -} - - -/** - * Set the elevator trim, from -1.0 (down) to 1.0 (up). - */ -void -FGBFI::setElevatorTrim (double trim) -{ - // FIXME: clamp? - controls.set_elevator_trim(trim); -} - - -/** - * Get the highest brake setting, from 0.0 (none) to 1.0 (full). - */ -double -FGBFI::getBrakes () -{ - double b1 = getCenterBrake(); - double b2 = getLeftBrake(); - double b3 = getRightBrake(); - return (b1 > b2 ? (b1 > b3 ? b1 : b3) : (b2 > b3 ? b2 : b3)); -} - - -/** - * Set all brakes, from 0.0 (none) to 1.0 (full). - */ -void -FGBFI::setBrakes (double brake) -{ - setCenterBrake(brake); - setLeftBrake(brake); - setRightBrake(brake); -} - - -/** - * Get the center brake, from 0.0 (none) to 1.0 (full). - */ -double -FGBFI::getCenterBrake () -{ - return controls.get_brake(2); -} - - -/** - * Set the center brake, from 0.0 (none) to 1.0 (full). - */ -void -FGBFI::setCenterBrake (double brake) -{ - controls.set_brake(2, brake); -} - - -/** - * Get the left brake, from 0.0 (none) to 1.0 (full). - */ -double -FGBFI::getLeftBrake () -{ - return controls.get_brake(0); -} - - -/** - * Set the left brake, from 0.0 (none) to 1.0 (full). - */ -void -FGBFI::setLeftBrake (double brake) -{ - controls.set_brake(0, brake); -} - - -/** - * Get the right brake, from 0.0 (none) to 1.0 (full). - */ -double -FGBFI::getRightBrake () -{ - return controls.get_brake(1); -} - - -/** - * Set the right brake, from 0.0 (none) to 1.0 (full). - */ -void -FGBFI::setRightBrake (double brake) -{ - controls.set_brake(1, brake); -} - - -#endif - //////////////////////////////////////////////////////////////////////// // Autopilot @@ -1077,7 +820,7 @@ FGBFI::getAPHeadingLock () { return (current_autopilot->get_HeadingEnabled() && - current_autopilot->get_HeadingMode() == FGAutopilot::FG_DG_HEADING_LOCK); + current_autopilot->get_HeadingMode() == DEFAULT_AP_HEADING_LOCK); } @@ -1088,7 +831,7 @@ void FGBFI::setAPHeadingLock (bool lock) { if (lock) { - current_autopilot->set_HeadingMode(FGAutopilot::FG_DG_HEADING_LOCK); + current_autopilot->set_HeadingMode(DEFAULT_AP_HEADING_LOCK); current_autopilot->set_HeadingEnabled(true); } else { current_autopilot->set_HeadingEnabled(false); @@ -1170,6 +913,92 @@ FGBFI::setAPNAV1Lock (bool lock) } } +/** + * Get the autopilot autothrottle lock. + */ +bool +FGBFI::getAPAutoThrottleLock () +{ + return current_autopilot->get_AutoThrottleEnabled(); +} + + +/** + * Set the autothrottle lock. + */ +void +FGBFI::setAPAutoThrottleLock (bool lock) +{ + current_autopilot->set_AutoThrottleEnabled(lock); +} + + +// kludge +double +FGBFI::getAPRudderControl () +{ + if (getAPHeadingLock()) + return current_autopilot->get_TargetHeading(); + else + return controls.get_rudder(); +} + +// kludge +void +FGBFI::setAPRudderControl (double value) +{ + if (getAPHeadingLock()) { + SG_LOG(SG_GENERAL, SG_DEBUG, "setAPRudderControl " << value ); + value -= current_autopilot->get_TargetHeading(); + current_autopilot->HeadingAdjust(value < 0.0 ? -1.0 : 1.0); + } else { + controls.set_rudder(value); + } +} + +// kludge +double +FGBFI::getAPElevatorControl () +{ + if (getAPAltitudeLock()) + return current_autopilot->get_TargetAltitude(); + else + return controls.get_elevator(); +} + +// kludge +void +FGBFI::setAPElevatorControl (double value) +{ + if (getAPAltitudeLock()) { + SG_LOG(SG_GENERAL, SG_DEBUG, "setAPElevatorControl " << value ); + value -= current_autopilot->get_TargetAltitude(); + current_autopilot->AltitudeAdjust(value < 0.0 ? 100.0 : -100.0); + } else { + controls.set_elevator(value); + } +} + +// kludge +double +FGBFI::getAPThrottleControl () +{ + if (getAPAutoThrottleLock()) + return 0.0; // always resets + else + return controls.get_throttle(0); +} + +// kludge +void +FGBFI::setAPThrottleControl (double value) +{ + if (getAPAutoThrottleLock()) + current_autopilot->AutoThrottleAdjust(value < 0.0 ? -0.01 : 0.01); + else + controls.set_throttle(0, value); +} + //////////////////////////////////////////////////////////////////////// @@ -1224,17 +1053,6 @@ FGBFI::getGPSTargetLongitude () return current_autopilot->get_TargetLongitude(); } -#if 0 -/** - * Set the GPS target longitude in degrees (negative for west). - */ -void -FGBFI::setGPSTargetLongitude (double longitude) -{ - current_autopilot->set_TargetLongitude( longitude ); -} -#endif - //////////////////////////////////////////////////////////////////////// diff --git a/src/Main/bfi.hxx b/src/Main/bfi.hxx index ac250b24d..b54be7bb4 100644 --- a/src/Main/bfi.hxx +++ b/src/Main/bfi.hxx @@ -29,6 +29,11 @@ SG_USING_NAMESPACE(std); +// Uncomment the appropriate line to get the desired heading hold +// autopilot behavior + +// #define DEFAULT_AP_HEADING_LOCK FGAutopilot::FG_TRUE_HEADING_LOCK +#define DEFAULT_AP_HEADING_LOCK FGAutopilot::FG_DG_HEADING_LOCK /** * Big Flat Interface @@ -153,6 +158,16 @@ public: static bool getAPNAV1Lock (); static void setAPNAV1Lock (bool lock); + static bool getAPAutoThrottleLock (); + static void setAPAutoThrottleLock (bool lock); + + static double getAPRudderControl (); + static void setAPRudderControl (double value); + static double getAPElevatorControl (); + static void setAPElevatorControl (double value); + static double getAPThrottleControl (); + static void setAPThrottleControl (double value); + // GPS static string getTargetAirport ();