X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FInstrumentation%2FKLN89%2Fkln89_page_apt.cxx;h=67a4c8ddcb03dfbed2ab8e2ca051ed038c3dcc33;hb=2302f040953b030612e1c0cb47fc47414ddbed31;hp=d1272e6cd013afd7d64ac7965540111c81b4915a;hpb=d176715284c9350413777342e24a76aecddd44ad;p=flightgear.git diff --git a/src/Instrumentation/KLN89/kln89_page_apt.cxx b/src/Instrumentation/KLN89/kln89_page_apt.cxx index d1272e6cd..67a4c8ddc 100644 --- a/src/Instrumentation/KLN89/kln89_page_apt.cxx +++ b/src/Instrumentation/KLN89/kln89_page_apt.cxx @@ -3,7 +3,7 @@ // // Written by David Luff, started 2005. // -// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk +// Copyright (C) 2005 - David C Luff - daveluff AT ntlworld.com // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -17,12 +17,26 @@ // // 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. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "kln89_page_apt.hxx" -#include + +#include + +#if ENABLE_ATCDCL +# include +#else + #include +#endif +#include
+#include +#include // This function is copied from Airports/runways.cxx // TODO - Make the original properly available and remove this instance!!!! @@ -175,7 +189,6 @@ void KLN89AptPage::Update(double dt) { 2, 0, 0, _to_flag, (_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 5 ? true : false)); } else if(_subPage == 2) { // Try and calculate a realistic difference from UTC based on longitude - float degLonPerHr = 360.0 / 24.0; // 15 degrees per hour difference. // Since 0 longitude is the middle of UTC, the boundaries will be at 7.5, 22.5, 37.5 etc. int hrDiff = ((int)((fabs(ap->getLongitude())) + 7.5)) / 15; _kln89->DrawText("UTC", 2, 0, 2); @@ -197,8 +210,8 @@ void KLN89AptPage::Update(double dt) { // I guess we can make a heuristic guess as to fuel availability from the runway sizes // For now assume that airports with asphalt or concrete runways will have at least 100L, // and that runways over 4000ft will have JET. - if(_aptRwys[0]._surface_code <= 2) { - if(_aptRwys[0]._length >= 4000) { + if(_aptRwys[0]->surface() <= 2) { + if(_aptRwys[0]->lengthFt() >= 4000) { _kln89->DrawText("JET 100L", 2, 0, 1); } else { _kln89->DrawText("100L", 2, 0, 1); @@ -218,17 +231,17 @@ void KLN89AptPage::Update(double dt) { string s; if(i < _aptRwys.size()) { // Rwy No. - string s = _aptRwys[i]._rwy_no; + string s = _aptRwys[i]->ident(); _kln89->DrawText(s, 2, 9, 3); _kln89->DrawText("/", 2, 12, 3); _kln89->DrawText(GetReverseRunwayNo(s), 2, 13, 3); // Length - s = GPSitoa(int(float(_aptRwys[i]._length) * (_kln89->_altUnits == GPS_ALT_UNITS_FT ? 1.0 : SG_FEET_TO_METER) + 0.5)); + s = GPSitoa(int(float(_aptRwys[i]->lengthFt()) * (_kln89->_altUnits == GPS_ALT_UNITS_FT ? 1.0 : SG_FEET_TO_METER) + 0.5)); _kln89->DrawText(s, 2, 5 - s.size(), 2); _kln89->DrawText((_kln89->_altUnits == GPS_ALT_UNITS_FT ? "ft" : "m"), 2, 5, 2); // Surface // TODO - why not store these strings as an array? - switch(_aptRwys[i]._surface_code) { + switch(_aptRwys[i]->surface()) { case 1: // Asphalt - fall through case 2: @@ -266,17 +279,17 @@ void KLN89AptPage::Update(double dt) { i++; if(i < _aptRwys.size()) { // Rwy No. - string s = _aptRwys[i]._rwy_no; + string s = _aptRwys[i]->ident(); _kln89->DrawText(s, 2, 9, 1); _kln89->DrawText("/", 2, 12, 1); _kln89->DrawText(GetReverseRunwayNo(s), 2, 13, 1); // Length - s = GPSitoa(int(float(_aptRwys[i]._length) * (_kln89->_altUnits == GPS_ALT_UNITS_FT ? 1.0 : SG_FEET_TO_METER) + 0.5)); + s = GPSitoa(int(float(_aptRwys[i]->lengthFt()) * (_kln89->_altUnits == GPS_ALT_UNITS_FT ? 1.0 : SG_FEET_TO_METER) + 0.5)); _kln89->DrawText(s, 2, 5 - s.size(), 0); _kln89->DrawText((_kln89->_altUnits == GPS_ALT_UNITS_FT ? "ft" : "m"), 2, 5, 0); // Surface // TODO - why not store these strings as an array? - switch(_aptRwys[i]._surface_code) { + switch(_aptRwys[i]->surface()) { case 1: // Asphalt - fall through case 2: @@ -347,19 +360,19 @@ void KLN89AptPage::Update(double dt) { _kln89->DrawText("For This Airport", 2, 0, 0); } else { if(_iafDialog) { - _kln89->DrawText(_iaps[_curIap]->_abbrev, 2, 1, 3); + _kln89->DrawText(_iaps[_curIap]->_ident, 2, 1, 3); _kln89->DrawText(_iaps[_curIap]->_rwyStr, 2, 7, 3); - _kln89->DrawText(_iaps[_curIap]->_id, 2, 12, 3); + _kln89->DrawText(_iaps[_curIap]->_aptIdent, 2, 12, 3); _kln89->DrawText("IAF", 2, 2, 2); - int line = 0; - for(unsigned int i=_iafStart; i<_IAF.size(); ++i) { + unsigned int line = 0; + for(unsigned int i=_iafStart; i<_approachRoutes.size(); ++i) { if(line == 2) { - i = _IAF.size() - 1; + i = _approachRoutes.size() - 1; } // Assume that the IAF number is always single digit! _kln89->DrawText(GPSitoa(i+1), 2, 6, 2-line); if(!(_kln89->_mode == KLN89_MODE_CRSR && _kln89->_blink && _uLinePos == (line + 1))) { - _kln89->DrawText(_IAF[i]->id, 2, 8, 2-line); + _kln89->DrawText(_approachRoutes[i]->waypoints[0]->id, 2, 8, 2-line); } if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == (line + 1) && !(_kln89->_blink )) { _kln89->Underline(2, 8, 2-line, 5); @@ -370,9 +383,9 @@ void KLN89AptPage::Update(double dt) { _kln89->DrawEnt(); } } else if(_addDialog) { - _kln89->DrawText(_iaps[_curIap]->_abbrev, 2, 1, 3); + _kln89->DrawText(_iaps[_curIap]->_ident, 2, 1, 3); _kln89->DrawText(_iaps[_curIap]->_rwyStr, 2, 7, 3); - _kln89->DrawText(_iaps[_curIap]->_id, 2, 12, 3); + _kln89->DrawText(_iaps[_curIap]->_aptIdent, 2, 12, 3); string s = GPSitoa(_fStart + 1); _kln89->DrawText(s, 2, 2-s.size(), 2); s = GPSitoa(_kln89->_approachFP->waypoints.size()); @@ -393,9 +406,9 @@ void KLN89AptPage::Update(double dt) { } } } else if(_replaceDialog) { - _kln89->DrawText(_iaps[_curIap]->_abbrev, 2, 1, 3); + _kln89->DrawText(_iaps[_curIap]->_ident, 2, 1, 3); _kln89->DrawText(_iaps[_curIap]->_rwyStr, 2, 7, 3); - _kln89->DrawText(_iaps[_curIap]->_id, 2, 12, 3); + _kln89->DrawText(_iaps[_curIap]->_aptIdent, 2, 12, 3); _kln89->DrawText("Replace Existing", 2, 0, 2); _kln89->DrawText("Approach", 2, 4, 1); if(_uLinePos > 0 && !(_kln89->_blink)) { @@ -405,24 +418,35 @@ void KLN89AptPage::Update(double dt) { } } else { _kln89->DrawText("IAP", 2, 11, 3); - int check = 0; bool selApp = false; if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos > 4) { selApp = true; if(!_kln89->_blink) _kln89->DrawEnt(); } - for(unsigned int i=0; i<_iaps.size(); ++i) { // TODO - do this properly when > 3 IAPs - string s = GPSitoa(i+1); - _kln89->DrawText(s, 2, 2 - s.size(), 2-i); - if(!(selApp && _uLinePos == 5+i && _kln89->_blink)) { - _kln89->DrawText(_iaps[i]->_abbrev, 2, 3, 2-i); - _kln89->DrawText(_iaps[i]->_rwyStr, 2, 9, 2-i); - } - if(selApp && _uLinePos == 5+i && !_kln89->_blink) { - _kln89->Underline(2, 3, 2-i, 9); + // _maxULine pos should be 4 + iaps.size() at this point. + // Draw a maximum of 3 IAPs. + // If there are more than 3 IAPs for this airport, then we need to offset the start + // of the list if _uLinePos is pointing at the 4th or later IAP. + unsigned int offset = 0; + unsigned int index; + if(_uLinePos > 7) { + offset = _uLinePos - 7; + } + for(unsigned int i=0; i<3; ++i) { + index = offset + i; + if(index < _iaps.size()) { + string s = GPSitoa(index+1); + _kln89->DrawText(s, 2, 2 - s.size(), 2-i); + if(!(selApp && _uLinePos == index+5 && _kln89->_blink)) { + _kln89->DrawText(_iaps[index]->_ident, 2, 3, 2-i); + _kln89->DrawText(_iaps[index]->_rwyStr, 2, 9, 2-i); + } + if(selApp && _uLinePos == index+5 && !_kln89->_blink) { + _kln89->Underline(2, 3, 2-i, 9); + } + } else { + break; } - check++; - if(check > 2) break; } } } @@ -462,11 +486,18 @@ void KLN89AptPage::Update(double dt) { KLN89Page::Update(dt); } -void KLN89AptPage::SetId(string s) { +void KLN89AptPage::SetId(const string& s) { + if(s != _apt_id || s != _last_apt_id) { + UpdateAirport(s); // If we don't do this here we break things if s is the same as the current ID since the update wouldn't get called then. + /* + DCL: Hmmm - I wrote the comment above, but I don't quite understand it! + I'm not quite sure why I don't simply set _apt_id here (and NOT _last_apt_id) + and let the logic in Update(...) handle the airport details cache update. + */ + } _last_apt_id = _apt_id; _save_apt_id = _apt_id; _apt_id = s; - UpdateAirport(s); // If we don't do this here we break things if s is the same as the current ID since the update wouldn't get called then. } // Update the cached airport details @@ -502,23 +533,19 @@ void KLN89AptPage::UpdateAirport(const string& id) { // Runways _aptRwys.clear(); - FGRunway r; - bool haveRwy = globals->get_runways()->search(id, &r); - while(haveRwy && r._id == id) { - // Insert the runway with longest at the start of the array - for(unsigned int i = 0; i <= _aptRwys.size(); ++i) { - if(i == _aptRwys.size()) { - _aptRwys.push_back(r); - break; - } else { - if(r._length > _aptRwys[i]._length) { - _aptRwys.insert(_aptRwys.begin() + i, r); - break; - } - } - } - haveRwy = globals->get_runways()->next(&r); - } + const FGAirport* apt = fgFindAirportID(id); + assert(apt); + + // build local array, longest runway first + for (unsigned int r=0; rnumRunways(); ++r) { + FGRunway* rwy(apt->getRunwayByIndex(r)); + if ((r > 0) && (rwy->lengthFt() > _aptRwys.front()->lengthFt())) { + _aptRwys.insert(_aptRwys.begin(), rwy); + } else { + _aptRwys.push_back(rwy); + } + } + _nRwyPages = (_aptRwys.size() + 1) / 2; // 2 runways per page. if(_nFreqPages < 1) _nFreqPages = 1; if(_nRwyPages < 1) _nRwyPages = 1; @@ -530,7 +557,16 @@ void KLN89AptPage::UpdateAirport(const string& id) { if(itr != _kln89->_np_iap.end()) { _iaps = itr->second; } - if(_subPage == 7) _maxULinePos = 4 + _iaps.size(); // We shouldn't need to check the crsr for out-of-bounds here since we only update the airport details when the airport code is changed - ie. _uLinePos <= 4! + if(_subPage == 7) { + if(_iafDialog || _addDialog || _replaceDialog) { + // Eek - major logic error if an airport details cache update occurs + // with one of these dialogs active. + // TODO - output a warning. + //cout << "HELP!!!!!!!!!!\n"; + } else { + _maxULinePos = 4 + _iaps.size(); // We shouldn't need to check the crsr for out-of-bounds here since we only update the airport details when the airport code is changed - ie. _uLinePos <= 4! + } + } } void KLN89AptPage::CrsrPressed() { @@ -553,7 +589,7 @@ void KLN89AptPage::CrsrPressed() { } else if(_subPage == 7) { // Don't *think* we need some of this since some of it we can only get to by pressing ENT, not CRSR. if(_iafDialog) { - _maxULinePos = _IAF.size(); + _maxULinePos = _approachRoutes.size(); _uLinePos = 1; } else if(_addDialog) { _maxULinePos = 1; @@ -589,7 +625,7 @@ void KLN89AptPage::ClrPressed() { } } else if(_addDialog) { _addDialog = false; - if(_IAF.size() > 1) { + if(_approachRoutes.size() > 1) { _iafDialog = true; _maxULinePos = 1; // Don't reset _curIaf since it is remembed. @@ -612,20 +648,21 @@ void KLN89AptPage::ClrPressed() { } void KLN89AptPage::EntPressed() { - //cout << "A\n" if(_entInvert) { _entInvert = false; - _last_apt_id = _apt_id; - _apt_id = _save_apt_id; + if(_kln89->_dtoReview) { + _kln89->DtoInitiate(_apt_id); + } else { + _last_apt_id = _apt_id; + _apt_id = _save_apt_id; + } } else if(_subPage == 7 && _kln89->_mode == KLN89_MODE_CRSR && _uLinePos > 0) { - //cout << "B\n"; // We are selecting an approach if(_iafDialog) { - //cout << "C\n"; if(_uLinePos > 0) { // Record the IAF that was picked if(_uLinePos == 3) { - _curIaf = _IAF.size() - 1; + _curIaf = _approachRoutes.size() - 1; } else { _curIaf = _uLinePos - 1 + _iafStart; } @@ -633,9 +670,8 @@ void KLN89AptPage::EntPressed() { // TODO - delete the waypoints inside _approachFP before clearing them!!!!!!! _kln89->_approachFP->waypoints.clear(); GPSWaypoint* wp = new GPSWaypoint; - *wp = *_IAF[_curIaf]; // Need to make copies here since we're going to alter ID and type sometimes + *wp = *(_approachRoutes[_curIaf]->waypoints[0]); // Need to make copies here since we're going to alter ID and type sometimes string iafid = wp->id; - //wp->id += 'i'; _kln89->_approachFP->waypoints.push_back(wp); for(unsigned int i=0; i<_IAP.size(); ++i) { if(_IAP[i]->id != iafid) { // Don't duplicate waypoints that are part of the initial fix list and the approach procedure list. @@ -651,11 +687,6 @@ void KLN89AptPage::EntPressed() { _kln89->_approachFP->waypoints.push_back(wp); } } - // Only add 1 missed approach procedure waypoint for now. I think this might be standard always anyway. - wp = new GPSWaypoint; - *wp = *_MAP[0]; - //wp->id += 'h'; - _kln89->_approachFP->waypoints.push_back(wp); _iafDialog = false; _addDialog = true; _maxULinePos = _kln89->_approachFP->waypoints.size() + 1; @@ -687,7 +718,7 @@ void KLN89AptPage::EntPressed() { _kln89->_activeFP->waypoints.insert(_kln89->_activeFP->waypoints.end(), _kln89->_approachFP->waypoints.begin(), _kln89->_approachFP->waypoints.end()); } _kln89->_approachID = _apt_id; - _kln89->_approachAbbrev = _iaps[_curIap]->_abbrev; + _kln89->_approachAbbrev = _iaps[_curIap]->_ident; _kln89->_approachRwyStr = _iaps[_curIap]->_rwyStr; _kln89->_approachLoaded = true; //_kln89->_messageStack.push_back("*Press ALT To Set Baro"); @@ -702,20 +733,36 @@ void KLN89AptPage::EntPressed() { } else if(_replaceDialog) { // TODO - load the approach! } else if(_uLinePos > 4) { - _IAF.clear(); + _approachRoutes.clear(); _IAP.clear(); - _MAP.clear(); _curIaf = 0; - _IAF = ((FGNPIAP*)(_iaps[_uLinePos-5]))->_IAF; + _approachRoutes = ((FGNPIAP*)(_iaps[_uLinePos-5]))->_approachRoutes; _IAP = ((FGNPIAP*)(_iaps[_uLinePos-5]))->_IAP; - _MAP = ((FGNPIAP*)(_iaps[_uLinePos-5]))->_MAP; _curIap = _uLinePos - 5; // TODO - handle the start of list ! no. 1, and the end of list not sequential! _uLinePos = 1; - if(_IAF.size() > 1) { + if(_approachRoutes.size() > 1) { // More than 1 IAF - display the selection dialog _iafDialog = true; - _maxULinePos = _IAF.size(); + _maxULinePos = _approachRoutes.size(); } else { + // There is only 1 IAF, so load the waypoints into the approach flightplan here. + // TODO - there is nasty code duplication loading the approach FP between the case here where we have only one + // IAF and the case where we must choose the IAF from a list. Try to tidy this after it is all working properly. + _kln89->_approachFP->waypoints.clear(); + GPSWaypoint* wp = new GPSWaypoint; + *wp = *(_approachRoutes[0]->waypoints[0]); // Need to make copies here since we're going to alter ID and type sometimes + string iafid = wp->id; + _kln89->_approachFP->waypoints.push_back(wp); + for(unsigned int i=0; i<_IAP.size(); ++i) { + if(_IAP[i]->id != iafid) { // Don't duplicate waypoints that are part of the initial fix list and the approach procedure list. + // FIXME - allow the same waypoint to be both the IAF and the FAF in some + // approaches that have a procedure turn eg. KDLL + // Also allow MAF to be the same as IAF! + wp = new GPSWaypoint; + *wp = *_IAP[i]; + _kln89->_approachFP->waypoints.push_back(wp); + } + } _addDialog = true; _maxULinePos = 1; } @@ -787,6 +834,15 @@ void KLN89AptPage::Knob2Left1() { } else { _curRwyPage--; } + } else if(_subPage == 0) { + _subPage = 7; + // We have to set _uLinePos here even though the cursor isn't pressed, to + // ensure that the list displays properly. + if(_iaps.empty()) { + _uLinePos = 1; + } else { + _uLinePos = 5; + } } else { KLN89Page::Knob2Left1(); } @@ -830,6 +886,15 @@ void KLN89AptPage::Knob2Right1() { } else { _curFreqPage++; } + } else if(_subPage == 6) { + _subPage = 7; + // We have to set _uLinePos here even though the cursor isn't pressed, to + // ensure that the list displays properly. + if(_iaps.empty()) { + _uLinePos = 1; + } else { + _uLinePos = 5; + } } else { KLN89Page::Knob2Right1(); }