1
0
Fork 0

kln89 user interface logical pages

This commit is contained in:
daveluff 2005-11-30 00:18:42 +00:00
parent f44ed9716a
commit d176715284
26 changed files with 4619 additions and 0 deletions

View file

@ -0,0 +1,125 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_act.hxx"
#include "kln89_page_apt.hxx"
#include "kln89_page_vor.hxx"
#include "kln89_page_ndb.hxx"
#include "kln89_page_int.hxx"
#include "kln89_page_usr.hxx"
KLN89ActPage::KLN89ActPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 1;
_subPage = 0;
_name = "ACT";
_actWp = NULL;
_actWpId = -1;
_actPage = NULL;
_aptPage = new KLN89AptPage(parent);
_vorPage = new KLN89VorPage(parent);
_ndbPage = new KLN89NDBPage(parent);
_intPage = new KLN89IntPage(parent);
_usrPage = new KLN89UsrPage(parent);
}
KLN89ActPage::~KLN89ActPage() {
delete _aptPage;
delete _vorPage;
delete _ndbPage;
delete _intPage;
delete _usrPage;
}
void KLN89ActPage::Update(double dt) {
if(!_actWp) {
_actWp = _kln89->GetActiveWaypoint();
_actWpId = _kln89->GetActiveWaypointIndex();
}
if(_actWp) {
switch(_actWp->type) {
case GPS_WP_APT: _actPage = _aptPage; break;
case GPS_WP_VOR: _actPage = _vorPage; break;
case GPS_WP_NDB: _actPage = _ndbPage; break;
case GPS_WP_INT: _actPage = _intPage; break;
case GPS_WP_USR: _actPage = _usrPage; break;
default:
_actPage = NULL;
// ASSERT(0); // ie. we shouldn't ever get here.
}
}
_id = _actWp->id;
if(_actPage) {
_actPage->SetId(_actWp->id);
_actPage->Update(dt);
} else {
KLN89Page::Update(dt);
}
}
void KLN89ActPage::CrsrPressed() {
if(_actPage) {
_actPage->CrsrPressed();
} else {
KLN89Page::CrsrPressed();
}
}
void KLN89ActPage::EntPressed() {
if(_actPage) {
_actPage->EntPressed();
} else {
KLN89Page::EntPressed();
}
}
void KLN89ActPage::ClrPressed() {
if(_actPage) {
_actPage->ClrPressed();
} else {
KLN89Page::ClrPressed();
}
}
void KLN89ActPage::Knob2Left1() {
if((_kln89->_mode != KLN89_MODE_CRSR) && (_actPage)) {
_actPage->Knob2Left1();
}
}
void KLN89ActPage::Knob2Right1() {
if((_kln89->_mode != KLN89_MODE_CRSR) && (_actPage)) {
_actPage->Knob2Right1();
}
}
void KLN89ActPage::LooseFocus() {
// Setting to NULL and -1 is better than resetting to
// active waypoint and index since we can't guarantee that
// the fpl active waypoint won't change behind our backs
// when we don't have focus.
_actWp = NULL;
_actWpId = -1;
}

View file

@ -0,0 +1,62 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_ACT_HXX
#define _KLN89_PAGE_ACT_HXX
#include "kln89.hxx"
class KLN89ActPage : public KLN89Page {
public:
KLN89ActPage(KLN89* parent);
~KLN89ActPage();
void Update(double dt);
void CrsrPressed();
void EntPressed();
void ClrPressed();
void Knob2Left1();
void Knob2Right1();
void LooseFocus();
private:
// Position of the currently displayed waypoint within the active flightplan.
// -1 indicates no active flightplan.
int _actWpId;
GPSWaypoint* _actWp;
// The actual ACT page that gets displayed...
GPSPage* _actPage;
// ...which points to one of the below.
GPSPage* _aptPage;
GPSPage* _vorPage;
GPSPage* _ndbPage;
GPSPage* _intPage;
GPSPage* _usrPage;
};
#endif // _KLN89_PAGE_ACT_HXX

View file

@ -0,0 +1,854 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_apt.hxx"
#include <ATC/commlist.hxx>
// This function is copied from Airports/runways.cxx
// TODO - Make the original properly available and remove this instance!!!!
// Return reverse rwy number
// eg 01 -> 19
// 03L -> 21R
static string GetReverseRunwayNo(string rwyno) {
// cout << "Original rwyno = " << rwyNo << '\n';
// standardize input number
string tmp = rwyno.substr(1, 1);
if (( tmp == "L" || tmp == "R" || tmp == "C" ) || (rwyno.size() == 1)) {
tmp = rwyno;
rwyno = "0" + tmp;
SG_LOG( SG_GENERAL, SG_INFO,
"Standardising rwy number from " << tmp << " to " << rwyno );
}
char buf[4];
int rn = atoi(rwyno.substr(0,2).c_str());
rn += 18;
while(rn > 36) {
rn -= 36;
}
sprintf(buf, "%02i", rn);
if(rwyno.size() == 3) {
if(rwyno.substr(2,1) == "L") {
buf[2] = 'R';
buf[3] = '\0';
} else if (rwyno.substr(2,1) == "R") {
buf[2] = 'L';
buf[3] = '\0';
} else if (rwyno.substr(2,1) == "C") {
buf[2] = 'C';
buf[3] = '\0';
} else if (rwyno.substr(2,1) == "T") {
buf[2] = 'T';
buf[3] = '\0';
} else {
SG_LOG(SG_GENERAL, SG_ALERT, "Unknown runway code "
<< rwyno << " passed to GetReverseRunwayNo(...)");
}
}
return(buf);
}
KLN89AptPage::KLN89AptPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 8;
_subPage = 0;
_name = "APT";
_apt_id = "KHWD";
// Make sure that _last_apt_id doesn't match at startup to force airport data to be fetched on first update.
_last_apt_id = "XXXX";
_nRwyPages = 1;
_curRwyPage = 0;
_nFreqPages = 1;
_curFreqPage = 0;
ap = NULL;
_iapStart = 0;
_iafStart = 0;
_fStart = 0;
_iaps.clear();
_iafDialog = false;
_addDialog = false;
_replaceDialog = false;
_curIap = 0;
_curIaf = 0;
}
KLN89AptPage::~KLN89AptPage() {
}
void KLN89AptPage::Update(double dt) {
bool actPage = (_kln89->_activePage->GetName() == "ACT" ? true : false);
bool multi; // Not set by FindFirst...
bool exact = false;
if(_apt_id.size() == 4) exact = true;
// TODO - move this search out to where the button is pressed, and cache the result!
if(_apt_id != _last_apt_id || ap == NULL) ap = _kln89->FindFirstAptById(_apt_id, multi, exact);
//if(np == NULL) cout << "NULL... ";
//if(b == false) cout << "false...\n";
/*
if(np && b) {
cout << "VOR FOUND!\n";
} else {
cout << ":-(\n";
}
*/
if(ap) {
//cout << "Valid airport found! id = " << ap->getId() << ", elev = " << ap->getElevation() << '\n';
if(_apt_id != _last_apt_id) {
UpdateAirport(ap->getId());
_last_apt_id = _apt_id;
_curFreqPage = 0;
_curRwyPage = 0;
}
_apt_id = ap->getId();
if(_kln89->GetActiveWaypoint()) {
if(_apt_id == _kln89->GetActiveWaypoint()->id) {
if(!(_kln89->_waypointAlert && _kln89->_blink)) {
// Active waypoint arrow
_kln89->DrawSpecialChar(4, 2, 0, 3);
}
}
}
if(_kln89->_mode != KLN89_MODE_CRSR) {
if(!(_subPage == 7 && (_iafDialog || _addDialog || _replaceDialog))) { // Don't draw the airport name when the IAP dialogs are active
if(!_entInvert) {
if(!actPage) {
_kln89->DrawText(ap->getId(), 2, 1, 3);
} else {
// If it's the ACT page, The ID is shifted slightly right to make space for the waypoint index.
_kln89->DrawText(ap->getId(), 2, 4, 3);
char buf[3];
int n = snprintf(buf, 3, "%i", _kln89->GetActiveWaypointIndex() + 1);
_kln89->DrawText((string)buf, 2, 3 - n, 3);
}
} else {
if(!_kln89->_blink) {
_kln89->DrawText(ap->getId(), 2, 1, 3, false, 99);
_kln89->DrawEnt();
}
}
}
}
if(_subPage == 0) {
// Name
_kln89->DrawText(ap->getName(), 2, 0, 2);
// Elevation
_kln89->DrawText(_kln89->_altUnits == GPS_ALT_UNITS_FT ? "ft" : "m", 2, 14, 3);
char buf[6];
int n = snprintf(buf, 5, "%i", (_kln89->_altUnits == GPS_ALT_UNITS_FT ? (int)(ap->getElevation()) : (int)((double)ap->getElevation() * SG_FEET_TO_METER)));
_kln89->DrawText((string)buf, 2, 14 - n, 3);
// Town
airport_id_str_map_iterator itr = _kln89->_airportTowns.find(_apt_id);
if(itr != _kln89->_airportTowns.end()) {
_kln89->DrawText(itr->second, 2, 0, 1);
}
// State / Province / Country
itr = _kln89->_airportStates.find(_apt_id);
if(itr != _kln89->_airportStates.end()) {
_kln89->DrawText(itr->second, 2, 0, 0);
}
} else if(_subPage == 1) {
_kln89->DrawLatitude(ap->getLatitude(), 2, 3, 2);
_kln89->DrawLongitude(ap->getLongitude(), 2, 3, 1);
_kln89->DrawDirDistField(ap->getLatitude() * SG_DEGREES_TO_RADIANS, ap->getLongitude() * SG_DEGREES_TO_RADIANS,
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);
if(hrDiff != 0) {
_kln89->DrawText(ap->getLongitude() >= 0.0 ? "+" : "-", 2, 3, 2);
char buf[3];
snprintf(buf, 3, "%02i", hrDiff);
_kln89->DrawText((string)buf, 2, 4, 2);
_kln89->DrawText("( DT)", 2, 6, 2);
if(ap->getLongitude() >= 0.0) {
hrDiff++;
} else {
hrDiff--;
}
_kln89->DrawText(ap->getLongitude() >= 0.0 ? "+" : "-", 2, 7, 2);
snprintf(buf, 3, "%02i", hrDiff);
_kln89->DrawText((string)buf, 2, 8, 2);
}
// 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) {
_kln89->DrawText("JET 100L", 2, 0, 1);
} else {
_kln89->DrawText("100L", 2, 0, 1);
}
}
if(_iaps.empty()) {
_kln89->DrawText("NO APR", 2, 0, 0);
} else {
// TODO - output proper differentiation of ILS and NP APR and NP APR type eg GPS(R)
_kln89->DrawText("NP APR", 2, 0, 0);
}
} else if(_subPage == 3) {
if(_nRwyPages > 1) {
_kln89->DrawChar('+', 1, 3, 0);
}
unsigned int i = _curRwyPage * 2;
string s;
if(i < _aptRwys.size()) {
// Rwy No.
string s = _aptRwys[i]._rwy_no;
_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));
_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) {
case 1:
// Asphalt - fall through
case 2:
// Concrete
_kln89->DrawText("HRD", 2, 9, 2);
break;
case 3:
case 8:
// Turf / Turf helipad
_kln89->DrawText("TRF", 2, 9, 2);
break;
case 4:
case 9:
// Dirt / Dirt helipad
_kln89->DrawText("DRT", 2, 9, 2);
break;
case 5:
// Gravel
_kln89->DrawText("GRV", 2, 9, 2);
break;
case 6:
// Asphalt helipad - fall through
case 7:
// Concrete helipad
_kln89->DrawText("HRD", 2, 9, 2);
break;
case 12:
// Lakebed
_kln89->DrawText("CLY", 2, 9, 2);
default:
// erm? ...
_kln89->DrawText("MAT", 2, 9, 2);
}
}
i++;
if(i < _aptRwys.size()) {
// Rwy No.
string s = _aptRwys[i]._rwy_no;
_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));
_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) {
case 1:
// Asphalt - fall through
case 2:
// Concrete
_kln89->DrawText("HRD", 2, 9, 0);
break;
case 3:
case 8:
// Turf / Turf helipad
_kln89->DrawText("TRF", 2, 9, 0);
break;
case 4:
case 9:
// Dirt / Dirt helipad
_kln89->DrawText("DRT", 2, 9, 0);
break;
case 5:
// Gravel
_kln89->DrawText("GRV", 2, 9, 0);
break;
case 6:
// Asphalt helipad - fall through
case 7:
// Concrete helipad
_kln89->DrawText("HRD", 2, 9, 0);
break;
case 12:
// Lakebed
_kln89->DrawText("CLY", 2, 9, 0);
default:
// erm? ...
_kln89->DrawText("MAT", 2, 9, 0);
}
}
} else if(_subPage == 4) {
if(_nFreqPages > 1) {
_kln89->DrawChar('+', 1, 3, 0);
}
unsigned int i = _curFreqPage * 3;
if(i < _aptFreqs.size()) {
_kln89->DrawText(_aptFreqs[i].service, 2, 0, 2);
_kln89->DrawFreq(_aptFreqs[i].freq, 2, 7, 2);
}
i++;
if(i < _aptFreqs.size()) {
_kln89->DrawText(_aptFreqs[i].service, 2, 0, 1);
_kln89->DrawFreq(_aptFreqs[i].freq, 2, 7, 1);
}
i++;
if(i < _aptFreqs.size()) {
_kln89->DrawText(_aptFreqs[i].service, 2, 0, 0);
_kln89->DrawFreq(_aptFreqs[i].freq, 2, 7, 0);
}
} else if(_subPage == 5) {
// TODO - user ought to be allowed to leave persistent remarks
_kln89->DrawText("[Remarks]", 2, 2, 2);
} else if(_subPage == 6) {
// We don't have SID/STAR database yet
// TODO
_kln89->DrawText("No SID/STAR", 2, 3, 2);
_kln89->DrawText("In Data Base", 2, 2, 1);
_kln89->DrawText("For This Airport", 2, 0, 0);
} else if(_subPage == 7) {
if(_iaps.empty()) {
_kln89->DrawText("IAP", 2, 11, 3);
_kln89->DrawText("No Approach", 2, 3, 2);
_kln89->DrawText("In Data Base", 2, 2, 1);
_kln89->DrawText("For This Airport", 2, 0, 0);
} else {
if(_iafDialog) {
_kln89->DrawText(_iaps[_curIap]->_abbrev, 2, 1, 3);
_kln89->DrawText(_iaps[_curIap]->_rwyStr, 2, 7, 3);
_kln89->DrawText(_iaps[_curIap]->_id, 2, 12, 3);
_kln89->DrawText("IAF", 2, 2, 2);
int line = 0;
for(unsigned int i=_iafStart; i<_IAF.size(); ++i) {
if(line == 2) {
i = _IAF.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);
}
if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == (line + 1) && !(_kln89->_blink )) {
_kln89->Underline(2, 8, 2-line, 5);
}
++line;
}
if(_uLinePos > 0 && !(_kln89->_blink)) {
_kln89->DrawEnt();
}
} else if(_addDialog) {
_kln89->DrawText(_iaps[_curIap]->_abbrev, 2, 1, 3);
_kln89->DrawText(_iaps[_curIap]->_rwyStr, 2, 7, 3);
_kln89->DrawText(_iaps[_curIap]->_id, 2, 12, 3);
string s = GPSitoa(_fStart + 1);
_kln89->DrawText(s, 2, 2-s.size(), 2);
s = GPSitoa(_kln89->_approachFP->waypoints.size());
_kln89->DrawText(s, 2, 2-s.size(), 1);
if(!(_uLinePos == _fStart+1 && _kln89->_blink)) {
_kln89->DrawText(_kln89->_approachFP->waypoints[_fStart]->id, 2, 4, 2);
if(_uLinePos == _fStart+1) _kln89->Underline(2, 4, 2, 6);
}
if(!(_uLinePos == _maxULinePos-1 && _kln89->_blink)) {
_kln89->DrawText(_kln89->_approachFP->waypoints[_kln89->_approachFP->waypoints.size()-1]->id, 2, 4, 1);
if(_uLinePos == _maxULinePos-1) _kln89->Underline(2, 4, 1, 6);
}
if(!(_uLinePos > _kln89->_approachFP->waypoints.size() && _kln89->_blink)) {
_kln89->DrawText("ADD TO FPL 0?", 2, 2, 0);
if(_uLinePos > _kln89->_approachFP->waypoints.size()) {
_kln89->Underline(2, 2, 0, 13);
_kln89->DrawEnt();
}
}
} else if(_replaceDialog) {
_kln89->DrawText(_iaps[_curIap]->_abbrev, 2, 1, 3);
_kln89->DrawText(_iaps[_curIap]->_rwyStr, 2, 7, 3);
_kln89->DrawText(_iaps[_curIap]->_id, 2, 12, 3);
_kln89->DrawText("Replace Existing", 2, 0, 2);
_kln89->DrawText("Approach", 2, 4, 1);
if(_uLinePos > 0 && !(_kln89->_blink)) {
_kln89->DrawText("APPROVE?", 2, 4, 0);
_kln89->Underline(2, 4, 0, 8);
_kln89->DrawEnt();
}
} 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);
}
check++;
if(check > 2) break;
}
}
}
}
} else {
if(_kln89->_mode != KLN89_MODE_CRSR) _kln89->DrawText(_apt_id, 2, 1, 3);
if(_subPage == 0) {
/*
_kln89->DrawText("----.-", 2, 9, 3);
_kln89->DrawText("--------------", 2, 0, 2);
_kln89->DrawText("- -- --.--'", 2, 3, 1);
_kln89->DrawText("---- --.--'", 2, 3, 0);
_kln89->DrawSpecialChar(0, 2, 7, 1);
_kln89->DrawSpecialChar(0, 2, 7, 0);
*/
}
}
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(!(_subPage == 7 && (_iafDialog || _addDialog || _replaceDialog))) {
if(_uLinePos > 0 && _uLinePos < 5) {
// TODO - blink as well
_kln89->Underline(2, _uLinePos, 3, 1);
}
for(unsigned int i = 0; i < _apt_id.size(); ++i) {
if(_uLinePos != (i + 1)) {
_kln89->DrawChar(_apt_id[i], 2, i + 1, 3);
} else {
if(!_kln89->_blink) _kln89->DrawChar(_apt_id[i], 2, i + 1, 3);
}
}
}
}
_id = _apt_id;
KLN89Page::Update(dt);
}
void KLN89AptPage::SetId(string s) {
_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
void KLN89AptPage::UpdateAirport(const string& id) {
// Frequencies
_aptFreqs.clear();
ATCData ad;
AptFreq aq;
//cout << "UpdateAirport called, id = " << id << '\n';
// TODO - the logic below only returns one service per type per airport - they can be on more than one freq though.
if(current_commlist->FindByCode(id, ad, ATIS)) {
//cout << "Found ATIS\n";
aq.service = "ATIS*";
aq.freq = ad.freq;
_aptFreqs.push_back(aq);
}
if(current_commlist->FindByCode(id, ad, GROUND)) {
aq.service = "GRND*";
aq.freq = ad.freq;
_aptFreqs.push_back(aq);
}
if(current_commlist->FindByCode(id, ad, TOWER)) {
aq.service = "TWR *";
aq.freq = ad.freq;
_aptFreqs.push_back(aq);
}
if(current_commlist->FindByCode(id, ad, APPROACH)) {
aq.service = "APR";
aq.freq = ad.freq;
_aptFreqs.push_back(aq);
}
_nFreqPages = (unsigned int)ceil((float(_aptFreqs.size())) / 3.0f);
// 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);
}
_nRwyPages = (_aptRwys.size() + 1) / 2; // 2 runways per page.
if(_nFreqPages < 1) _nFreqPages = 1;
if(_nRwyPages < 1) _nRwyPages = 1;
// Instrument approaches
// Only non-precision for now - TODO - handle precision approaches if necessary
_iaps.clear();
iap_map_iterator itr = _kln89->_np_iap.find(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!
}
void KLN89AptPage::CrsrPressed() {
if(_kln89->_mode == KLN89_MODE_DISP) {
if(_subPage == 7) {
// Pressing crsr jumps back to vanilla IAP page.
_iafDialog = false;
_addDialog = false;
_replaceDialog = false;
}
return;
}
if(_kln89->_obsMode) {
_uLinePos = 0;
} else {
_uLinePos = 1;
}
if(_subPage == 0) {
_maxULinePos = 32;
} 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();
_uLinePos = 1;
} else if(_addDialog) {
_maxULinePos = 1;
_uLinePos = 1;
} else if(_replaceDialog) {
_maxULinePos = 1;
_uLinePos = 1;
} else {
_maxULinePos = 4 + _iaps.size();
if(_iaps.empty()) {
_uLinePos = 1;
} else {
_uLinePos = 5;
}
}
} else {
_maxULinePos = 5;
}
}
void KLN89AptPage::ClrPressed() {
if(_subPage == 1 && _uLinePos == 5) {
_to_flag = !_to_flag;
} else if(_subPage == 7) {
// Clear backs out IAP selection one step at a time
if(_iafDialog) {
_iafDialog = false;
_maxULinePos = 4 + _iaps.size();
if(_iaps.empty()) {
_uLinePos = 1;
} else {
_uLinePos = 5;
}
} else if(_addDialog) {
_addDialog = false;
if(_IAF.size() > 1) {
_iafDialog = true;
_maxULinePos = 1;
// Don't reset _curIaf since it is remembed.
_uLinePos = 1 + _curIaf; // TODO - make this robust to more than 3 IAF
} else {
_maxULinePos = 4 + _iaps.size();
if(_iaps.empty()) {
_uLinePos = 1;
} else {
_uLinePos = 5;
}
}
} else if(_replaceDialog) {
_replaceDialog = false;
_addDialog = true;
_maxULinePos = 1;
_uLinePos = 1;
}
}
}
void KLN89AptPage::EntPressed() {
//cout << "A\n"
if(_entInvert) {
_entInvert = false;
_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;
} else {
_curIaf = _uLinePos - 1 + _iafStart;
}
//cout << "_curIaf = " << _curIaf << '\n';
// 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
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.
// 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];
//cout << "Adding waypoint " << wp->id << ", type is " << wp->appType << '\n';
//if(wp->appType == GPS_FAF) wp->id += 'f';
//if(wp->appType == GPS_MAP) wp->id += 'm';
//cout << "New id = " << wp->id << '\n';
_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;
_uLinePos = _maxULinePos;
}
} else if(_addDialog) {
if(_uLinePos == _maxULinePos) {
_addDialog = false;
if(_kln89->ApproachLoaded()) {
_replaceDialog = true;
_uLinePos = 1;
_maxULinePos = 1;
} else {
// Now load the approach into the active flightplan.
// As far as I can tell, the rules are this:
// If the airport of the approach is in the flightplan, insert it prior to this. (Not sure what happens if airport has already been passed).
// If the airport is not in the flightplan, append the approach to the flightplan, even if it is closer than the current active leg,
// in which case reorientate to flightplan might put us on the approach, but unable to activate it.
// However, it appears from the sim as if this can indeed happen if the user is not carefull.
bool added = false;
for(unsigned int i=0; i<_kln89->_activeFP->waypoints.size(); ++i) {
if(_kln89->_activeFP->waypoints[i]->id == _apt_id) {
_kln89->_activeFP->waypoints.insert(_kln89->_activeFP->waypoints.begin()+i, _kln89->_approachFP->waypoints.begin(), _kln89->_approachFP->waypoints.end());
added = true;
break;
}
}
if(!added) {
_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->_approachRwyStr = _iaps[_curIap]->_rwyStr;
_kln89->_approachLoaded = true;
//_kln89->_messageStack.push_back("*Press ALT To Set Baro");
// Actually - this message is only sent when we go into appraoch-arm mode.
// TODO - check the flightplan for consistency
_kln89->OrientateToActiveFlightPlan();
_kln89->_mode = KLN89_MODE_DISP;
_kln89->_curPage = 7;
_kln89->_activePage = _kln89->_pages[7]; // Do we need to clean up here at all before jumping?
}
}
} else if(_replaceDialog) {
// TODO - load the approach!
} else if(_uLinePos > 4) {
_IAF.clear();
_IAP.clear();
_MAP.clear();
_curIaf = 0;
_IAF = ((FGNPIAP*)(_iaps[_uLinePos-5]))->_IAF;
_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) {
// More than 1 IAF - display the selection dialog
_iafDialog = true;
_maxULinePos = _IAF.size();
} else {
_addDialog = true;
_maxULinePos = 1;
}
}
}
}
void KLN89AptPage::Knob1Left1() {
if(_kln89->_mode == KLN89_MODE_CRSR && _subPage == 7 && _addDialog) {
if(_uLinePos == _maxULinePos) {
_uLinePos--;
if(_kln89->_approachFP->waypoints.size() > 1) _fStart = _kln89->_approachFP->waypoints.size() - 2;
} else if(_uLinePos == _maxULinePos - 1) {
_uLinePos--;
} else if(_uLinePos > 0) {
if(_fStart == 0) {
_uLinePos--;
} else {
_uLinePos--;
_fStart--;
}
}
} else {
KLN89Page::Knob1Left1();
}
}
void KLN89AptPage::Knob1Right1() {
if(_kln89->_mode == KLN89_MODE_CRSR && _subPage == 7 && _addDialog) {
if(_uLinePos == _maxULinePos) {
// no-op
} else if(_uLinePos == _maxULinePos - 1) {
_uLinePos++;
_fStart = 0;
} else if(_uLinePos > 0) {
if(_fStart >= _kln89->_approachFP->waypoints.size() - 2) {
_uLinePos++;
} else {
_uLinePos++;
_fStart++;
}
} else if(_uLinePos == 0) {
_uLinePos++;
_fStart = 0;
}
} else {
KLN89Page::Knob1Right1();
}
}
void KLN89AptPage::Knob2Left1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
if(_uLinePos == 0 && _kln89->_mode == KLN89_MODE_CRSR && _kln89->_obsMode) {
KLN89Page::Knob2Left1();
} else if(_subPage == 5) {
_subPage = 4;
_curFreqPage = _nFreqPages - 1;
} else if(_subPage == 4) {
// Freqency pages
if(_curFreqPage == 0) {
_subPage = 3;
_curRwyPage = _nRwyPages - 1;
} else {
_curFreqPage--;
}
} else if(_subPage == 3) {
if(_curRwyPage == 0) {
KLN89Page::Knob2Left1();
} else {
_curRwyPage--;
}
} else {
KLN89Page::Knob2Left1();
}
} else {
if(_uLinePos < 5 && !(_subPage == 7 && (_iafDialog || _addDialog || _replaceDialog))) {
// Same logic for all pages - set the ID
_apt_id = _apt_id.substr(0, _uLinePos);
// ASSERT(_uLinePos > 0);
if(_uLinePos == (_apt_id.size() + 1)) {
_apt_id += '9';
} else {
_apt_id[_uLinePos - 1] = _kln89->DecChar(_apt_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
}
} else {
if(_subPage == 0) {
// TODO - set by name
} else {
// NO-OP - to/fr is cycled by clr button
}
}
}
}
void KLN89AptPage::Knob2Right1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
if(_uLinePos == 0 && _kln89->_mode == KLN89_MODE_CRSR && _kln89->_obsMode) {
KLN89Page::Knob2Right1();
} else if(_subPage == 2) {
_subPage = 3;
_curRwyPage = 0;
} else if(_subPage == 3) {
if(_curRwyPage == _nRwyPages - 1) {
_subPage = 4;
_curFreqPage = 0;
} else {
_curRwyPage++;
}
} else if(_subPage == 4) {
if(_curFreqPage == _nFreqPages - 1) {
_subPage = 5;
} else {
_curFreqPage++;
}
} else {
KLN89Page::Knob2Right1();
}
} else {
if(_uLinePos < 5 && !(_subPage == 7 && (_iafDialog || _addDialog || _replaceDialog))) {
// Same logic for all pages - set the ID
_apt_id = _apt_id.substr(0, _uLinePos);
// ASSERT(_uLinePos > 0);
if(_uLinePos == (_apt_id.size() + 1)) {
_apt_id += 'A';
} else {
_apt_id[_uLinePos - 1] = _kln89->IncChar(_apt_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
}
} else {
if(_subPage == 0) {
// TODO - set by name
} else {
// NO-OP - to/fr is cycled by clr button
}
}
}
}

View file

@ -0,0 +1,95 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_APT
#define _KLN89_PAGE_APT
#include "kln89.hxx"
#include <Airports/runways.hxx>
struct AptFreq {
string service;
unsigned short int freq;
};
class KLN89AptPage : public KLN89Page {
public:
KLN89AptPage(KLN89* parent);
~KLN89AptPage();
void Update(double dt);
void CrsrPressed();
void ClrPressed();
void EntPressed();
void Knob1Left1();
void Knob1Right1();
void Knob2Left1();
void Knob2Right1();
void SetId(string s);
private:
// Update the cached airport details
void UpdateAirport(const string& id);
string _apt_id;
string _last_apt_id;
string _save_apt_id;
const FGAirport* ap;
vector<FGRunway> _aptRwys;
vector<AptFreq> _aptFreqs;
iap_list_type _iaps;
unsigned int _curIap; // The index into _iaps of the IAP we are currently selecting
vector<GPSWaypoint*> _IAF; // The initial approach fix(es)
vector<GPSWaypoint*> _IAP; // The compulsory waypoints of the approach procedure (may duplicate one of the above).
// _IAP includes the FAF and MAF.
vector<GPSWaypoint*> _MAP; // The missed approach procedure (doesn't include the MAF).
unsigned int _curIaf; // The index into _IAF of the IAF we are currently selecting, and then remembered as the one we selected
// Position in rwy pages
unsigned int _curRwyPage;
unsigned int _nRwyPages;
// Position in freq pages
unsigned int _curFreqPage;
unsigned int _nFreqPages;
// Position in IAP list (0-based number of first IAP displayed)
unsigned int _iapStart;
// ditto for IAF list (can't test this since can't find an approach with > 3 IAF at the moment!)
unsigned int _iafStart;
// ditto for list of approach fixes when asking load confirmation
unsigned int _fStart;
// Various IAP related dialog states that we might need to remember
bool _iafDialog;
bool _addDialog;
bool _replaceDialog;
};
#endif // _KLN89_PAGE_APT

View file

@ -0,0 +1,110 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_cal.hxx"
KLN89CalPage::KLN89CalPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 8;
_subPage = 0;
_name = "CAL";
_nFp0 = 0;
_ground_speed_ms = 110 * 0.514444444444;
}
KLN89CalPage::~KLN89CalPage() {
}
void KLN89CalPage::Update(double dt) {
if(_subPage == 0) {
if(1) { // TODO - fix this hardwiring!
// Flightplan calc
_kln89->DrawText(">Fpl:", 2, 0, 3);
_kln89->DrawText("0", 2, 6, 3);// TODO - fix this hardwiring!
GPSFlightPlan* fp = _kln89->_flightPlans[_nFp0];
if(fp) {
unsigned int n = fp->waypoints.size();
if(n < 2) {
// TODO - check that this is what really happens
_kln89->DrawText("----", 2, 9, 3);
_kln89->DrawText("----", 2, 9, 2);
} else {
_kln89->DrawText(fp->waypoints[0]->id, 2, 9, 3);
_kln89->DrawText(fp->waypoints[n-1]->id, 2, 9, 2);
double cum_tot_m = 0.0;
for(unsigned int i = 1; i < fp->waypoints.size(); ++i) {
cum_tot_m += _kln89->GetGreatCircleDistance(fp->waypoints[i-1]->lat, fp->waypoints[i-1]->lon,
fp->waypoints[i]->lat, fp->waypoints[i]->lon);
}
double ete = (cum_tot_m * SG_NM_TO_METER) / _ground_speed_ms;
_kln89->DrawDist(cum_tot_m, 2, 5, 1);
_kln89->DrawSpeed(_ground_speed_ms / 0.5144444444, 2, 5, 0);
_kln89->DrawTime(ete, 2, 14, 0);
}
} else {
_kln89->DrawText("----", 2, 9, 3);
_kln89->DrawText("----", 2, 9, 2);
}
} else {
_kln89->DrawText(">Wpt:", 2, 0, 3);
}
_kln89->DrawText("To", 2, 6, 2);
_kln89->DrawText("ESA ----'", 2, 7, 1); // TODO - implement an ESA calc
_kln89->DrawText("ETE", 2, 7, 0);
} else if(_subPage == 1) {
_kln89->DrawText(">Fpl: 0", 2, 0, 3); // TODO - fix this hardwiring!
_kln89->DrawText("FF:", 2, 0, 2);
_kln89->DrawText("Res:", 2, 7, 1);
_kln89->DrawText("Fuel Req", 2, 0, 0);
} else if(_subPage == 2) {
_kln89->DrawText("Time:", 2, 0, 3);
_kln89->DrawText("Alarm at:", 2, 0, 2);
_kln89->DrawText("in:", 2, 6, 1);
_kln89->DrawText("Elapsed", 2, 0, 0);
} else if(_subPage == 3) {
_kln89->DrawText("PRESSURE ALT", 2, 1, 3);
_kln89->DrawText("Ind:", 2, 0, 2);
_kln89->DrawText("Baro:", 2, 0, 1);
_kln89->DrawText("Prs", 2, 0, 0);
} else if(_subPage == 4) {
_kln89->DrawText("DENSITY ALT", 2, 1, 3);
_kln89->DrawText("Prs:", 2, 0, 2);
_kln89->DrawText("Temp:", 2, 0, 1);
_kln89->DrawText("Den", 2, 0, 0);
} else if(_subPage == 5) {
_kln89->DrawText("CAS:", 2, 0, 3);
_kln89->DrawText("Prs:", 2, 0, 2);
_kln89->DrawText("Temp:", 2, 0, 1);
_kln89->DrawText("TAS", 2, 0, 0);
} else if(_subPage == 6) {
_kln89->DrawText("TAS:", 2, 0, 3);
_kln89->DrawText("Hdg:", 2, 0, 2);
_kln89->DrawText("Headwind:", 2, 0, 1);
_kln89->DrawText("True", 2, 4, 0);
} else {
_kln89->DrawText("SUNRISE", 2, 0, 1);
_kln89->DrawText("SUNSET", 2, 0, 0);
}
KLN89Page::Update(dt);
}

View file

@ -0,0 +1,42 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_CAL
#define _KLN89_PAGE_CAL
#include "kln89.hxx"
class KLN89CalPage : public KLN89Page {
public:
KLN89CalPage(KLN89* parent);
~KLN89CalPage();
void Update(double dt);
private:
unsigned int _nFp0; // flightplan no. displayed on page 1 (_subPage == 0).
double _ground_speed_ms; // Assumed ground speed for ete calc on page 1 (user can alter this).
};
#endif // _KLN89_PAGE_CAL

View file

@ -0,0 +1,103 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_dir.hxx"
KLN89DirPage::KLN89DirPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 1;
_subPage = 0;
_name = "DIR";
_DToWpDispMode = 2;
}
KLN89DirPage::~KLN89DirPage() {
}
void KLN89DirPage::Update(double dt) {
// TODO - this can apparently be "ACTIVATE:" under some circumstances
_kln89->DrawText("DIRECT TO:", 2, 2, 3);
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(_DToWpDispMode == 0) {
string s = _id;
while(s.size() < 5) s += ' ';
if(!_kln89->_blink) {
_kln89->DrawText(s, 2, 4, 1, false, 99);
_kln89->DrawEnt(1, 0, 1);
}
} else if(_DToWpDispMode == 1) {
if(!_kln89->_blink) {
// TODO
_kln89->DrawEnt(1, 0, 1);
}
_kln89->Underline(2, 4, 1, 5);
} else {
if(!_kln89->_blink) _kln89->DrawText("_____", 2, 4, 1);
_kln89->Underline(2, 4, 1, 5);
}
} else {
_kln89->DrawText("_____", 2, 4, 1);
}
KLN89Page::Update(dt);
}
void KLN89DirPage::SetId(string s) {
if(s.size()) {
_id = s;
// TODO - fill in lat, lon, type
// or just pass in waypoints (probably better!)
_DToWpDispMode = 0;
// TODO - this (above) should probably be dependent on whether s is a *valid* waypoint!
} else {
_DToWpDispMode = 2;
}
_saveMasterMode = _kln89->_mode;
_uLinePos = 1; // Needed to stop Leg flashing
}
void KLN89DirPage::ClrPressed() {
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(_DToWpDispMode <= 1) {
_DToWpDispMode = 2;
_id.clear();
} else {
// Restore the original master mode
_kln89->_mode = _saveMasterMode;
// Stop displaying dir page
_kln89->_activePage = _kln89->_pages[_kln89->_curPage];
}
} else {
// TODO
}
}
void KLN89DirPage::EntPressed() {
//cout << "DTO ENT Pressed()\n";
if(_id.empty()) {
_kln89->DtoCancel();
} else {
_kln89->DtoInitiate(_id);
}
}

View file

@ -0,0 +1,54 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_DIR
#define _KLN89_PAGE_DIR
#include "kln89.hxx"
class KLN89DirPage : public KLN89Page {
public:
KLN89DirPage(KLN89* parent);
~KLN89DirPage();
void Update(double dt);
void SetId(string s);
void ClrPressed();
void EntPressed();
private:
// Waypoint display mode.
// There are a number of ways that the waypoint can be displayed in the DIR page:
// 0 => Whole candidate waypoint displayed, entirely inverted. This is normally how the page is initially displayed, unless a candidate waypoint cannot be determined.
// 1 => Waypoint being entered, with a corresponding cursor position, and only the cursor position inverted.
// 2 => Blanks. These can be displayed flashing when the cursor is active (eg. when CLR is pressed) and are always displayed if the cursor is turned off.
int _DToWpDispMode;
// We need to save the mode when DTO gets pressed, since potentially this class handles page exit via. the CLR event handler
KLN89Mode _saveMasterMode;
};
#endif // _KLN89_PAGE_DIR

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_FPL_HXX
#define _KLN89_PAGE_FPL_HXX
#include "kln89.hxx"
class KLN89FplPage : public KLN89Page {
public:
KLN89FplPage(KLN89* parent);
~KLN89FplPage();
void Update(double dt);
void CrsrPressed();
void EntPressed();
void ClrPressed();
void Knob1Left1();
void Knob1Right1();
void Knob2Left1();
void Knob2Right1();
void CleanUp();
void LooseFocus();
// Override the base class GetId function to return the waypoint ID under the cursor
// on FPL0 page, if there is one and the cursor is on.
// Otherwise return an empty string.
inline string GetId() { return(_fp0SelWpId); }
private:
int _fpMode; // 0 = Dis, 1 = Dtk
int _actFpMode; // 0 = Dis, 1 = ETE, 2 = ETA, 3 = Dtk/OBS
bool _bEntWp; // set true when a waypoint is being entered
bool _bEntExp; // Set true when ent is expected to set the currently entered waypoint as entered.
string _entWpStr; // The currently entered wp ID (need not be valid)
GPSWaypoint* _entWp; // Waypoint being currently entered
// The position of the cursor in a waypoint being entered
unsigned int _wLinePos;
unsigned int _fplPos; // The position of the start of the FP (NOT the active one) (zero-based).
// since this is reset when subpage changes we only need 1, not an array of 25!
bool _resetFplPos0; // Set true when a recalculation of _fplPos for the active flightplan page is required.
int _hdrPos;
int _fencePos;
// Get the waypoint (returned thru the pointer) at the zero-based position (pos)
// in the waypoint display of the current page.
// Returns 0 if no waypoint, 1 if sucessfull, 2 if appr header, 3 if approach fence.
//int GetFPWaypoint(GPSWaypoint* wp, int pos);
bool _delFP; // Set true when the delete FP? dialogue is being displayed
bool _delWp; // The position of the waypoint to delete is given by _uLinePos
bool _delAppr; // Set true when the delete approach dialogue is being displayed
bool _changeAppr;
void DrawFpMode(int ypos);
void Calc();
// The ID of the waypoint under the cursor in fpl0, if those conditions exist!
string _fp0SelWpId;
vector<string> _params;
};
#endif // _KLN89_PAGE_FPL_HXX

View file

@ -0,0 +1,242 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_int.hxx"
KLN89IntPage::KLN89IntPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 2;
_subPage = 0;
_name = "INT";
_int_id = "PORTE";
_last_int_id = "";
_fp = NULL;
_nearestVor = NULL;
_refNav = NULL;
}
KLN89IntPage::~KLN89IntPage() {
}
void KLN89IntPage::Update(double dt) {
bool actPage = (_kln89->_activePage->GetName() == "ACT" ? true : false);
bool multi; // Not set by FindFirst...
bool exact = false;
if(_int_id.size() == 5) exact = true;
if(_fp == NULL) {
_fp = _kln89->FindFirstIntById(_int_id, multi, exact);
} else if(_fp->get_ident() != _int_id) {
_fp = _kln89->FindFirstIntById(_int_id, multi, exact);
}
if(_fp) {
_int_id = _fp->get_ident();
if(_kln89->GetActiveWaypoint()) {
if(_int_id == _kln89->GetActiveWaypoint()->id) {
if(!(_kln89->_waypointAlert && _kln89->_blink)) {
// Active waypoint arrow
_kln89->DrawSpecialChar(4, 2, 0, 3);
}
}
}
if(_int_id != _last_int_id) {
_nearestVor = _kln89->FindClosestVor(_fp->get_lat() * SG_DEGREES_TO_RADIANS, _fp->get_lon() * SG_DEGREES_TO_RADIANS);
if(_nearestVor) {
_nvRadial = _kln89->GetMagHeadingFromTo(_nearestVor->get_lat() * SG_DEGREES_TO_RADIANS, _nearestVor->get_lon() * SG_DEGREES_TO_RADIANS,
_fp->get_lat() * SG_DEGREES_TO_RADIANS, _fp->get_lon() * SG_DEGREES_TO_RADIANS);
_nvDist = _kln89->GetGreatCircleDistance(_nearestVor->get_lat() * SG_DEGREES_TO_RADIANS, _nearestVor->get_lon() * SG_DEGREES_TO_RADIANS,
_fp->get_lat() * SG_DEGREES_TO_RADIANS, _fp->get_lon() * SG_DEGREES_TO_RADIANS);
_refNav = _nearestVor; // TODO - check that this *always* holds - eg. when changing INT id after explicitly setting ref nav
// but with no loss of focus.
} else {
_refNav = NULL;
}
_last_int_id = _int_id;
}
if(_kln89->_mode != KLN89_MODE_CRSR) {
if(!_entInvert) {
if(!actPage) {
_kln89->DrawText(_fp->get_ident(), 2, 1, 3);
} else {
// If it's the ACT page, The ID is shifted slightly right to make space for the waypoint index.
_kln89->DrawText(_fp->get_ident(), 2, 4, 3);
char buf[3];
int n = snprintf(buf, 3, "%i", _kln89->GetActiveWaypointIndex() + 1);
_kln89->DrawText((string)buf, 2, 3 - n, 3);
// We also draw an I to differentiate INT from USR when it's the ACT page
_kln89->DrawText("I", 2, 11, 3);
}
} else {
if(!_kln89->_blink) {
_kln89->DrawText(_fp->get_ident(), 2, 1, 3, false, 99);
_kln89->DrawEnt();
}
}
}
if(_subPage == 0) {
_kln89->DrawLatitude(_fp->get_lat(), 2, 3, 2);
_kln89->DrawLongitude(_fp->get_lon(), 2, 3, 1);
_kln89->DrawDirDistField(_fp->get_lat() * SG_DEGREES_TO_RADIANS, _fp->get_lon() * SG_DEGREES_TO_RADIANS, 2, 0, 0,
_to_flag, (_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 6 ? true : false));
} else {
_kln89->DrawText("Ref:", 2, 1, 2);
_kln89->DrawText("Rad:", 2, 1, 1);
_kln89->DrawText("Dis:", 2, 1, 0);
if(_refNav) {
_kln89->DrawText(_refNav->get_ident(), 2, 9, 2); // TODO - flash and allow to change if under cursor
//_kln89->DrawHeading(_nvRadial, 2, 11, 1);
//_kln89->DrawDist(_nvDist, 2, 11, 0);
// Currently our draw heading and draw dist functions don't do as many decimal points as we want here,
// so draw it ourselves!
// Heading
char buf[10];
snprintf(buf, 6, "%.1f", _nvRadial);
string s = buf;
_kln89->DrawText(s, 2, 13 - s.size(), 1);
_kln89->DrawSpecialChar(0, 2, 13, 1); // Degrees symbol
// Dist
double d = _nvDist;
d *= (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001);
snprintf(buf, 9, "%.1f", d);
s = buf;
s += (_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "Km");
_kln89->DrawText(s, 2, 14 - s.size(), 0);
}
}
} else {
// TODO - when we leave the page with invalid id and return it should
// revert to showing the last valid id. Same for vor/ndb/probably apt etc.
if(_kln89->_mode != KLN89_MODE_CRSR) _kln89->DrawText(_int_id, 2, 1, 3);
if(_subPage == 0) {
_kln89->DrawText("- -- --.--'", 2, 3, 2);
_kln89->DrawText("---- --.--'", 2, 3, 1);
_kln89->DrawSpecialChar(0, 2, 7, 2);
_kln89->DrawSpecialChar(0, 2, 7, 1);
_kln89->DrawText(">--- ----", 2, 0, 0);
_kln89->DrawSpecialChar(0, 2, 4, 0);
_kln89->DrawText(_to_flag ? "To" : "Fr", 2, 5, 0);
_kln89->DrawText(_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "km", 2, 12, 0);
}
}
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(_uLinePos > 0 && _uLinePos < 6) {
// TODO - blink as well
_kln89->Underline(2, _uLinePos, 3, 1);
}
for(unsigned int i = 0; i < _int_id.size(); ++i) {
if(_uLinePos != (i + 1)) {
_kln89->DrawChar(_int_id[i], 2, i + 1, 3);
} else {
if(!_kln89->_blink) _kln89->DrawChar(_int_id[i], 2, i + 1, 3);
}
}
}
// TODO - fix this duplication - use _id instead of _apt_id, _vor_id, _ndb_id, _int_id etc!
_id = _int_id;
KLN89Page::Update(dt);
}
void KLN89IntPage::SetId(string s) {
_last_int_id = _int_id;
_save_int_id = _int_id;
_int_id = s;
_fp = NULL;
}
void KLN89IntPage::CrsrPressed() {
if(_kln89->_mode == KLN89_MODE_DISP) return;
if(_kln89->_obsMode) {
_uLinePos = 0;
} else {
_uLinePos = 1;
}
if(_subPage == 0) {
_maxULinePos = 6;
} else {
_maxULinePos = 6;
}
}
void KLN89IntPage::ClrPressed() {
if(_subPage == 0 && _uLinePos == 6) {
_to_flag = !_to_flag;
}
}
void KLN89IntPage::EntPressed() {
if(_entInvert) {
_entInvert = false;
_last_int_id = _int_id;
_int_id = _save_int_id;
}
}
void KLN89IntPage::Knob2Left1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Left1();
} else {
if(_uLinePos < 6) {
// Same logic for both pages - set the ID
_int_id = _int_id.substr(0, _uLinePos);
// ASSERT(_uLinePos > 0);
if(_uLinePos == (_int_id.size() + 1)) {
_int_id += '9';
} else {
_int_id[_uLinePos - 1] = _kln89->DecChar(_int_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
}
} else {
if(_subPage == 0) {
// NO-OP - from/to field is switched by clr button, not inner knob.
} else {
// TODO - LNR type field.
}
}
}
}
void KLN89IntPage::Knob2Right1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Right1();
} else {
if(_uLinePos < 6) {
// Same logic for both pages - set the ID
_int_id = _int_id.substr(0, _uLinePos);
// ASSERT(_uLinePos > 0);
if(_uLinePos == (_int_id.size() + 1)) {
_int_id += 'A';
} else {
_int_id[_uLinePos - 1] = _kln89->IncChar(_int_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
}
} else {
if(_subPage == 0) {
// NO-OP - from/to field is switched by clr button, not inner knob.
} else {
// TODO - LNR type field.
}
}
}
}

View file

@ -0,0 +1,56 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_INT_HXX
#define _KLN89_PAGE_INT_HXX
#include "kln89.hxx"
class KLN89IntPage : public KLN89Page {
public:
KLN89IntPage(KLN89* parent);
~KLN89IntPage();
void Update(double dt);
void CrsrPressed();
void ClrPressed();
void EntPressed();
void Knob2Left1();
void Knob2Right1();
void SetId(string s);
private:
string _int_id;
string _last_int_id;
string _save_int_id;
const FGFix* _fp;
FGNavRecord* _nearestVor;
FGNavRecord* _refNav; // Will usually be the same as _nearestVor, and gets reset to _nearestVor when page looses focus.
double _nvRadial; // radial from nearest VOR
double _nvDist; // distance to nearest VOR
};
#endif // _KLN89_PAGE_INT_HXX

View file

@ -0,0 +1,513 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_nav.hxx"
KLN89NavPage::KLN89NavPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 4;
_subPage = 0;
_name = "NAV";
_posFormat = 0; // Check - should this default to ref from waypoint?
_vnv = 0;
_nav4DataSnippet = 0;
_cdiFormat = 0;
_menuActive = false;
_menuPos = 0;
_suspendAVS = false;
}
KLN89NavPage::~KLN89NavPage() {
}
void KLN89NavPage::Update(double dt) {
GPSFlightPlan* fp = ((KLN89*)_parent)->_activeFP;
GPSWaypoint* awp = _parent->GetActiveWaypoint();
bool crsr = (_kln89->_mode == KLN89_MODE_CRSR);
bool blink = _kln89->_blink;
double lat = _kln89->_gpsLat * SG_RADIANS_TO_DEGREES;
double lon = _kln89->_gpsLon * SG_RADIANS_TO_DEGREES;
if(0 == _subPage) {
if(_kln89->_navFlagged) {
_kln89->DrawText("> F L A G", 2, 0, 2);
_kln89->DrawText("DTK --- TK ---", 2, 0, 1);
_kln89->DrawText(">--- To --:--", 2, 0, 0);
_kln89->DrawSpecialChar(0, 2, 7, 1);
_kln89->DrawSpecialChar(0, 2, 15, 1);
_kln89->DrawSpecialChar(0, 2, 4, 0);
_kln89->DrawSpecialChar(1, 2, 3, 2);
_kln89->DrawSpecialChar(1, 2, 4, 2);
_kln89->DrawSpecialChar(1, 2, 6, 2);
_kln89->DrawSpecialChar(1, 2, 10, 2);
_kln89->DrawSpecialChar(1, 2, 12, 2);
_kln89->DrawSpecialChar(1, 2, 13, 2);
} else {
if(_kln89->_dto) {
_kln89->DrawDTO(2, 7, 3);
} else {
if(!(_kln89->_waypointAlert && _kln89->_blink)) {
_kln89->DrawSpecialChar(3, 2, 8, 3);
}
}
_kln89->DrawText(awp->id, 2, 10, 3);
if(!_kln89->_dto && !_kln89->_obsMode && !_kln89->_fromWaypoint.id.empty()) {
_kln89->DrawText(_kln89->_fromWaypoint.id, 2, 1, 3);
}
if(!(crsr && blink && _uLinePos == 1)) {
if(_cdiFormat == 0) {
_kln89->DrawCDI();
} else if(_cdiFormat == 1) {
_kln89->DrawText("Fly", 2, 2, 2);
double x = _kln89->CalcCrossTrackDeviation();
// TODO - check the R/L from sign of x below - I *think* it holds but not sure!
// Note also that we're setting Fly R or L based on the aircraft
// position only, not the heading. Not sure if this is correct or not.
_kln89->DrawText(x < 0.0 ? "R" : "L", 2, 6, 2);
char buf[6];
int n;
x = fabs(x * (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001));
if(x < 1.0) {
n = snprintf(buf, 6, "%0.2f", x);
} else if(x < 100.0) {
n = snprintf(buf, 6, "%0.1f", x);
} else {
n = snprintf(buf, 6, "%i", (int)(x+0.5));
}
_kln89->DrawText((string)buf, 2, 13-n, 2);
_kln89->DrawText(_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "km", 2, 13, 2);
} else {
_kln89->DrawText("CDI Scale:", 2, 1, 2);
double d = _kln89->_cdiScales[_kln89->_currentCdiScaleIndex] * (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001);
char buf[5];
string s;
if(d >= 1.0) {
snprintf(buf, 4, "%2.1f", d);
s = buf;
} else {
snprintf(buf, 5, "%2.2f", d);
// trim the leading zero
s = buf;
s = s.substr(1, s.size() - 1);
}
_kln89->DrawText(s, 2, 11, 2);
_kln89->DrawText(_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "km", 2, 14, 2);
}
}
_kln89->DrawChar('>', 2, 0, 2);
_kln89->DrawChar('>', 2, 0, 0);
if(crsr) {
if(_uLinePos == 1) _kln89->Underline(2, 1, 2, 15);
else if(_uLinePos == 2) _kln89->Underline(2, 1, 0, 9);
}
// Desired and actual magnetic track
if(!_kln89->_obsMode) {
_kln89->DrawText("DTK", 2, 0, 1);
_kln89->DrawHeading(_kln89->_dtkMag, 2, 7, 1);
}
_kln89->DrawText("TK", 2, 9, 1);
if(_kln89->_groundSpeed_ms > 3) { // about 6 knots, don't know exactly what value to disable track
// The trouble with relying on FG gps's track value is we don't know when it's valid.
_kln89->DrawHeading(_kln89->_magTrackDeg, 2, 15, 1);
} else {
_kln89->DrawText("---", 2, 12, 1);
_kln89->DrawSpecialChar(0, 2, 15, 1);
}
// Radial to/from active waypoint.
// TODO - Not sure if this either is or should be true or mag!!!!!!!
if(!(crsr && blink && _uLinePos == 2)) {
if(0 == _vnv) {
_kln89->DrawHeading((int)_kln89->GetHeadingToActiveWaypoint(), 2, 4, 0);
_kln89->DrawText("To", 2, 5, 0);
} else if(1 == _vnv) {
_kln89->DrawHeading((int)_kln89->GetHeadingFromActiveWaypoint(), 2, 4, 0);
_kln89->DrawText("Fr", 2, 5, 0);
} else {
_kln89->DrawText("Vnv Off", 2, 1, 0);
}
}
// It seems that the floating point groundspeed must be at least 30kt
// for an ETA to be calculated. Note that this means that (integer) 30kt
// can appear in the frame 1 display both with and without an ETA displayed.
// TODO - need to switch off track (and heading bug change) based on instantaneous speed as well
// since the long gps lag filter means we can still be displaying when stopped on ground.
if(_kln89->_groundSpeed_kts > 30.0) {
// Assuming eta display is always hh:mm
// Does it ever switch to seconds when close?
if(_kln89->_eta / 3600.0 > 100.0) {
// More that 100 hours ! - Doesn't fit.
_kln89->DrawText("--:--", 2, 11, 0);
} else {
_kln89->DrawTime(_kln89->_eta, 2, 15, 0);
}
} else {
_kln89->DrawText("--:--", 2, 11, 0);
}
}
} else if(1 == _subPage) {
// Present position
_kln89->DrawChar('>', 2, 1, 3);
if(!(crsr && blink && _uLinePos == 1)) _kln89->DrawText("PRESENT POSN", 2, 2, 3);
if(crsr && _uLinePos == 1) _kln89->Underline(2, 2, 3, 12);
if(0 == _posFormat) {
// Lat/lon
_kln89->DrawLatitude(lat, 2, 3, 1);
_kln89->DrawLongitude(lon, 2, 3, 0);
} else {
// Ref from wp - defaults to nearest vor (and resets to default when page left and re-entered).
}
} else if(2 == _subPage) {
_kln89->DrawText("Time", 2, 0, 3);
// TODO - hardwired to UTC at the moment
_kln89->DrawText("UTC", 2, 6, 3);
string th = fgGetString("/instrumentation/clock/indicated-hour");
string tm = fgGetString("/instrumentation/clock/indicated-min");
if(th.size() == 1) th = "0" + th;
if(tm.size() == 1) tm = "0" + tm;
_kln89->DrawText(th + tm, 2, 11, 3);
_kln89->DrawText("Depart", 2, 0, 2);
_kln89->DrawText(_kln89->_departureTimeString, 2, 11, 2);
_kln89->DrawText("ETA", 2, 0, 1);
if(_kln89->_departed) {
/* Rules of ETA waypoint are:
If the active waypoint is part of the active flightplan, then display
the ETA to the final (destination) waypoint of the active flightplan.
If the active waypoint is not part of the active flightplan, then
display the ETA to the active waypoint. */
// TODO - implement the above properly - we haven't below!
string wid = "";
if(fp->waypoints.size()) {
wid = fp->waypoints[fp->waypoints.size() - 1]->id;
} else if(awp) {
wid = awp->id;
}
if(!wid.empty()) {
_kln89->DrawText(wid, 2, 4, 1);
double tsec = _kln89->GetTimeToWaypoint(wid);
if(tsec < 0.0) {
_kln89->DrawText("----", 2, 11, 1);
} else {
int etah = (int)tsec / 3600;
int etam = ((int)tsec - etah * 3600) / 60;
etah += atoi(fgGetString("/instrumentation/clock/indicated-hour"));
etam += atoi(fgGetString("/instrumentation/clock/indicated-min"));
while(etam > 59) {
etam -= 60;
etah += 1;
}
while(etah > 23) {
etah -= 24;
}
char buf[6];
int n = snprintf(buf, 6, "%02i%02i", etah, etam);
_kln89->DrawText((string)buf, 2, 15-n, 1);
}
} else {
_kln89->DrawText("----", 2, 11, 1);
}
} else {
_kln89->DrawText("----", 2, 11, 1);
}
_kln89->DrawText("Flight", 2, 0, 0);
if(_kln89->_departed) {
int eh = (int)_kln89->_elapsedTime / 3600;
int em = ((int)_kln89->_elapsedTime - eh * 3600) / 60;
char buf[6];
int n = snprintf(buf, 6, "%i:%02i", eh, em);
_kln89->DrawText((string)buf, 2, 15-n, 0);
} else {
_kln89->DrawText("-:--", 2, 11, 0);
}
} else {
// The moving map page the core KLN89 class draws this.
if(_kln89->_mapOrientation == 2 && _kln89->_groundSpeed_kts < 2) {
// Don't draw it if in track up mode and groundspeed < 2kts, as per real-life unit.
} else {
_kln89->DrawMap(!_suspendAVS);
}
// Now draw any annotation over it.
int scale = KLN89MapScales[_kln89->_mapScaleUnits][_kln89->_mapScaleIndex];
string scle_str = GPSitoa(scale);
if(crsr) {
if(_menuActive) {
// Draw a background quad to encompass on/off for the first three at 'off' length
_kln89->DrawMapQuad(28, 9, 48, 36, true);
_kln89->DrawMapText("SUA:", 1, 27, true);
if(!(_menuPos == 0 && _kln89->_blink)) _kln89->DrawMapText((_kln89->_drawSUA ? "on" : "off"), 29, 27, true);
if(_menuPos == 0) _kln89->DrawLine(28, 27, 48, 27);
_kln89->DrawMapText("VOR:", 1, 18, true);
if(!(_menuPos == 1 && _kln89->_blink)) _kln89->DrawMapText((_kln89->_drawVOR ? "on" : "off"), 29, 18, true);
if(_menuPos == 1) _kln89->DrawLine(28, 18, 48, 18);
_kln89->DrawMapText("APT:", 1, 9, true);
if(!(_menuPos == 2 && _kln89->_blink)) _kln89->DrawMapText((_kln89->_drawApt ? "on" : "off"), 29, 9, true);
if(_menuPos == 2) _kln89->DrawLine(28, 9, 48, 9);
_kln89->DrawMapQuad(0, 0, 27, 8, true);
if(!(_menuPos == 3 && _kln89->_blink)) {
if(_kln89->_mapOrientation == 0) {
_kln89->DrawMapText("N", 1, 0, true);
_kln89->DrawMapUpArrow(7, 1);
} else if(_kln89->_mapOrientation == 1) {
_kln89->DrawMapText("DTK", 1, 0, true);
_kln89->DrawMapUpArrow(21, 1);
} else {
// Don't bother with heading up for now!
_kln89->DrawMapText("TK", 1, 0, true);
_kln89->DrawMapUpArrow(14, 1);
}
}
if(_menuPos == 3) _kln89->DrawLine(0, 0, 27, 0);
} else {
if(_uLinePos == 2) {
if(!_kln89->_blink) {
_kln89->DrawMapText("Menu?", 1, 9, true);
_kln89->DrawEnt();
_kln89->DrawLine(0, 9, 34, 9);
} else {
_kln89->DrawMapQuad(0, 9, 34, 17, true);
}
} else {
_kln89->DrawMapText("Menu?", 1, 9, true);
}
// right-justify the scale when _uLinePos == 3
if(!(_uLinePos == 3 && _kln89->_blink)) _kln89->DrawMapText(scle_str, (_uLinePos == 3 ? 29 - (scle_str.size() * 7) : 1), 0, true);
if(_uLinePos == 3) _kln89->DrawLine(0, 0, 27, 0);
}
} else {
// Just draw the scale
_kln89->DrawMapText(scle_str, 1, 0, true);
}
// And do part of the field 1 update, since NAV 4 is a special case for the last line.
_kln89->DrawChar('>', 1, 0, 0);
if(crsr && _uLinePos == 1) _kln89->Underline(1, 1, 0, 5);
if(!(crsr && _uLinePos == 1 && _kln89->_blink)) {
if(_kln89->_obsMode && _nav4DataSnippet == 0) _nav4DataSnippet = 1;
double tsec;
switch(_nav4DataSnippet) {
case 0:
// DTK
_kln89->DrawLabel("DTK", -39, 6);
// TODO - check we have an active FP / dtk and draw dashes if not.
char buf0[4];
snprintf(buf0, 4, "%03i", (int)(_kln89->_dtkMag));
_kln89->DrawText((string)buf0, 1, 3, 0);
break;
case 1:
// groundspeed
_kln89->DrawSpeed(_kln89->_groundSpeed_kts, 1, 5, 0);
break;
case 2:
// ETE
tsec = _kln89->GetETE();
if(tsec < 0.0) {
_kln89->DrawText("--:--", 1, 1, 0);
} else {
int eteh = (int)tsec / 3600;
int etem = ((int)tsec - eteh * 3600) / 60;
char buf[6];
int n = snprintf(buf, 6, "%02i:%02i", eteh, etem);
_kln89->DrawText((string)buf, 1, 6-n, 0);
}
break;
case 3:
// Cross-track correction
double x = _kln89->CalcCrossTrackDeviation();
if(x < 0.0) {
_kln89->DrawSpecialChar(3, 1, 5, 0);
} else {
_kln89->DrawSpecialChar(7, 1, 5, 0);
}
char buf3[6];
int n;
x = fabs(x * (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001));
if(x < 1.0) {
n = snprintf(buf3, 6, "%0.2f", x);
} else if(x < 100.0) {
n = snprintf(buf3, 6, "%0.1f", x);
} else {
n = snprintf(buf3, 6, "%i", (int)(x+0.5));
}
_kln89->DrawText((string)buf3, 1, 5-n, 0);
break;
}
}
}
KLN89Page::Update(dt);
}
void KLN89NavPage::LooseFocus() {
_suspendAVS = false;
}
void KLN89NavPage::CrsrPressed() {
if(_kln89->_mode == KLN89_MODE_DISP) {
// Crsr just switched off
_menuActive = false;
} else {
// Crsr just switched on
if(_subPage < 3) {
_uLinePos = 1;
} else {
_uLinePos = 3;
}
}
}
void KLN89NavPage::EntPressed() {
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(_subPage == 3 && _uLinePos == 2 && !_menuActive) {
_menuActive = true;
_menuPos = 0;
_suspendAVS = false;
}
}
}
void KLN89NavPage::ClrPressed() {
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(_subPage == 0) {
if(_uLinePos == 1) {
_cdiFormat++;
if(_cdiFormat > 2) _cdiFormat = 0;
} else if(_uLinePos == 2) {
_vnv++;
if(_vnv > 2) _vnv = 0;
}
}
if(_subPage == 3) {
if(_uLinePos > 1) {
_suspendAVS = !_suspendAVS;
_menuActive = false;
} else if(_uLinePos == 1) {
_nav4DataSnippet++;
if(_nav4DataSnippet > 3) _nav4DataSnippet = 0;
}
}
} else {
if(_subPage == 3) {
_suspendAVS = !_suspendAVS;
}
}
}
void KLN89NavPage::Knob1Left1() {
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(!(_subPage == 3 && _menuActive)) {
if(_uLinePos > 0) _uLinePos--;
} else {
if(_menuPos > 0) _menuPos--;
}
}
}
void KLN89NavPage::Knob1Right1() {
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(_subPage < 2) {
if(_uLinePos < 2) _uLinePos++;
} else if(_subPage == 2) {
_uLinePos = 1;
} else {
// NAV 4 - this is complicated by whether the menu is displayed or not.
if(_menuActive) {
if(_menuPos < 3) _menuPos++;
} else {
if(_uLinePos < 3) _uLinePos++;
}
}
}
}
void KLN89NavPage::Knob2Left1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Left1();
return;
}
if(_subPage == 0) {
if(_uLinePos == 1 && _cdiFormat == 2) {
_kln89->CDIFSDIncrease();
}
} else if(_subPage == 3) {
if(_menuActive) {
if(_menuPos == 0) {
_kln89->_drawSUA = !_kln89->_drawSUA;
} else if(_menuPos == 1) {
_kln89->_drawVOR = !_kln89->_drawVOR;
} else if(_menuPos == 2) {
_kln89->_drawApt = !_kln89->_drawApt;
} else {
if(_kln89->_mapOrientation == 0) {
// Don't allow heading up for now
_kln89->_mapOrientation = 2;
} else {
_kln89->_mapOrientation--;
}
_kln89->UpdateMapHeading();
}
} else if(_uLinePos == 3) {
// TODO - add AUTO
if(_kln89->_mapScaleIndex == 0) {
_kln89->_mapScaleIndex = 20;
} else {
_kln89->_mapScaleIndex--;
}
}
}
}
void KLN89NavPage::Knob2Right1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Right1();
return;
}
if(_subPage == 0) {
if(_uLinePos == 1 && _cdiFormat == 2) {
_kln89->CDIFSDDecrease();
}
} else if(_subPage == 3) {
if(_menuActive) {
if(_menuPos == 0) {
_kln89->_drawSUA = !_kln89->_drawSUA;
} else if(_menuPos == 1) {
_kln89->_drawVOR = !_kln89->_drawVOR;
} else if(_menuPos == 2) {
_kln89->_drawApt = !_kln89->_drawApt;
} else {
if(_kln89->_mapOrientation >= 2) {
// Don't allow heading up for now
_kln89->_mapOrientation = 0;
} else {
_kln89->_mapOrientation++;
}
_kln89->UpdateMapHeading();
}
} else if(_uLinePos == 3) {
// TODO - add AUTO
if(_kln89->_mapScaleIndex == 20) {
_kln89->_mapScaleIndex = 0;
} else {
_kln89->_mapScaleIndex++;
}
}
}
}

View file

@ -0,0 +1,63 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89.hxx"
class KLN89NavPage : public KLN89Page {
public:
KLN89NavPage(KLN89* parent);
~KLN89NavPage();
void Update(double dt);
void CrsrPressed();
void EntPressed();
void ClrPressed();
void Knob1Left1();
void Knob1Right1();
void Knob2Left1();
void Knob2Right1();
void LooseFocus();
private:
int _posFormat; // 0 => lat,lon; 1 => ref to wp.
int _vnv; // 0 => To, 1 => Fr, 2 => off.
// The data snippet to be displayed in field 1 when the moving map is active (NAV 4)
int _nav4DataSnippet; // 0 => DTK, 1 => groundspeed, 2 => ETE, 3 => cross-track correction.
// Format to draw in the CDI field.
// 0 => CDI, 1 => Cross track correction (eg " Fly R 2.15nm"), 2 => cdi scale (eg "CDI Scale:5.0nm")
int _cdiFormat;
// Drawing of apt, vor and sua on the moving map can be temporarily suspended
// Note that this should be cleared when page focus is lost, or when the menu is displayed.
bool _suspendAVS;
// NAV 4 menu stuff
bool _menuActive;
int _menuPos;
};

View file

@ -0,0 +1,205 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_ndb.hxx"
KLN89NDBPage::KLN89NDBPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 2;
_subPage = 0;
_name = "NDB";
_ndb_id = "SF";
np = NULL;
}
KLN89NDBPage::~KLN89NDBPage() {
}
void KLN89NDBPage::Update(double dt) {
bool actPage = (_kln89->_activePage->GetName() == "ACT" ? true : false);
bool multi; // Not set by FindFirst...
bool exact = false;
if(_ndb_id.size() == 3) exact = true;
if(np == NULL) {
np = _kln89->FindFirstNDBById(_ndb_id, multi, exact);
} else if(np->get_ident() != _ndb_id) {
np = _kln89->FindFirstNDBById(_ndb_id, multi, exact);
}
//if(np == NULL) cout << "NULL... ";
//if(b == false) cout << "false...\n";
/*
if(np && b) {
cout << "VOR FOUND!\n";
} else {
cout << ":-(\n";
}
*/
if(np) {
//cout << np->id << '\n';
_ndb_id = np->get_ident();
if(_kln89->GetActiveWaypoint()) {
if(_ndb_id == _kln89->GetActiveWaypoint()->id) {
if(!(_kln89->_waypointAlert && _kln89->_blink)) {
// Active waypoint arrow
_kln89->DrawSpecialChar(4, 2, 0, 3);
}
}
}
if(_kln89->_mode != KLN89_MODE_CRSR) {
if(!_entInvert) {
if(!actPage) {
_kln89->DrawText(np->get_ident(), 2, 1, 3);
} else {
// If it's the ACT page, The ID is shifted slightly right to make space for the waypoint index.
_kln89->DrawText(np->get_ident(), 2, 4, 3);
char buf[3];
int n = snprintf(buf, 3, "%i", _kln89->GetActiveWaypointIndex() + 1);
_kln89->DrawText((string)buf, 2, 3 - n, 3);
}
} else {
if(!_kln89->_blink) {
_kln89->DrawText(np->get_ident(), 2, 1, 3, false, 99);
_kln89->DrawEnt();
}
}
}
if(_subPage == 0) {
// TODO - trim VOR-DME from the name, convert to uppercase, abbreviate, etc
_kln89->DrawText(np->get_name(), 2, 0, 2);
_kln89->DrawLatitude(np->get_lat(), 2, 3, 1);
_kln89->DrawLongitude(np->get_lon(), 2, 3, 0);
} else {
_kln89->DrawDirDistField(np->get_lat() * SG_DEGREES_TO_RADIANS, np->get_lon() * SG_DEGREES_TO_RADIANS,
2, 0, 0, _to_flag, (_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 4 ? true : false));
}
} else {
if(_kln89->_mode != KLN89_MODE_CRSR) _kln89->DrawText(_ndb_id, 2, 1, 3);
if(_subPage == 0) {
_kln89->DrawText("----.-", 2, 9, 3);
_kln89->DrawText("--------------", 2, 0, 2);
_kln89->DrawText("- -- --.--'", 2, 3, 1);
_kln89->DrawText("---- --.--'", 2, 3, 0);
_kln89->DrawSpecialChar(0, 2, 7, 1);
_kln89->DrawSpecialChar(0, 2, 7, 0);
}
}
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(_uLinePos > 0 && _uLinePos < 4) {
// TODO - blink as well
_kln89->Underline(2, _uLinePos, 3, 1);
}
for(unsigned int i = 0; i < _ndb_id.size(); ++i) {
if(_uLinePos != (i + 1)) {
_kln89->DrawChar(_ndb_id[i], 2, i + 1, 3);
} else {
if(!_kln89->_blink) _kln89->DrawChar(_ndb_id[i], 2, i + 1, 3);
}
}
}
_id = _ndb_id;
KLN89Page::Update(dt);
}
void KLN89NDBPage::SetId(string s) {
_last_ndb_id = _ndb_id;
_save_ndb_id = _ndb_id;
_ndb_id = s;
np = NULL;
}
void KLN89NDBPage::CrsrPressed() {
if(_kln89->_mode == KLN89_MODE_DISP) return;
if(_kln89->_obsMode) {
_uLinePos = 0;
} else {
_uLinePos = 1;
}
if(_subPage == 0) {
_maxULinePos = 17;
} else {
_maxULinePos = 4;
}
}
void KLN89NDBPage::ClrPressed() {
if(_subPage == 1 && _uLinePos == 4) {
_to_flag = !_to_flag;
}
}
void KLN89NDBPage::EntPressed() {
if(_entInvert) {
_entInvert = false;
_last_ndb_id = _ndb_id;
_ndb_id = _save_ndb_id;
}
}
void KLN89NDBPage::Knob2Left1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Left1();
} else {
if(_uLinePos < 4) {
// Same logic for both pages - set the ID
_ndb_id = _ndb_id.substr(0, _uLinePos);
// ASSERT(_uLinePos > 0);
if(_uLinePos == (_ndb_id.size() + 1)) {
_ndb_id += '9';
} else {
_ndb_id[_uLinePos - 1] = _kln89->DecChar(_ndb_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
}
} else {
if(_subPage == 0) {
// set by name
} else {
// NO-OP - from/to field is switched by clr button, not inner knob.
}
}
}
}
void KLN89NDBPage::Knob2Right1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Right1();
} else {
if(_uLinePos < 4) {
// Same logic for both pages - set the ID
_ndb_id = _ndb_id.substr(0, _uLinePos);
// ASSERT(_uLinePos > 0);
if(_uLinePos == (_ndb_id.size() + 1)) {
_ndb_id += 'A';
} else {
_ndb_id[_uLinePos - 1] = _kln89->IncChar(_ndb_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
}
} else {
if(_subPage == 0) {
// set by name
} else {
// NO-OP - from/to field is switched by clr button, not inner knob.
}
}
}
}

View file

@ -0,0 +1,52 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_NDB_HXX
#define _KLN89_PAGE_NDB_HXX
#include "kln89.hxx"
class KLN89NDBPage : public KLN89Page {
public:
KLN89NDBPage(KLN89* parent);
~KLN89NDBPage();
void Update(double dt);
void CrsrPressed();
void ClrPressed();
void EntPressed();
void Knob2Left1();
void Knob2Right1();
void SetId(string s);
private:
string _ndb_id;
string _last_ndb_id;
string _save_ndb_id;
FGNavRecord* np;
};
#endif // _KLN89_PAGE_NDB_HXX

View file

@ -0,0 +1,86 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_nrst.hxx"
KLN89NrstPage::KLN89NrstPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 2;
_subPage = 0;
_name = "NRST";
_uLinePos = 1;
_maxULinePos = 8;
}
KLN89NrstPage::~KLN89NrstPage() {
}
void KLN89NrstPage::Update(double dt) {
// crsr is always on on nearest page
bool blink = _kln89->_blink;
_kln89->DrawText("NEAREST", 2, 3, 3);
if(!(_uLinePos == 1 && blink)) _kln89->DrawText("APT?", 2, 0, 2);
if(!(_uLinePos == 2 && blink)) _kln89->DrawText("VOR?", 2, 5, 2);
if(!(_uLinePos == 3 && blink)) _kln89->DrawText("NDB?", 2, 10, 2);
if(!(_uLinePos == 4 && blink)) _kln89->DrawText("INT?", 2, 0, 1);
if(!(_uLinePos == 5 && blink)) _kln89->DrawText("USR?", 2, 5, 1);
if(!(_uLinePos == 6 && blink)) _kln89->DrawText("SUA?", 2, 10, 1);
if(!(_uLinePos == 7 && blink)) _kln89->DrawText("FSS?", 2, 0, 0);
if(!(_uLinePos == 8 && blink)) _kln89->DrawText("CTR?", 2, 5, 0);
switch(_uLinePos) {
case 1: _kln89->Underline(2, 0, 2, 4); break;
case 2: _kln89->Underline(2, 5, 2, 4); break;
case 3: _kln89->Underline(2, 10, 2, 4); break;
case 4: _kln89->Underline(2, 0, 1, 4); break;
case 5: _kln89->Underline(2, 5, 1, 4); break;
case 6: _kln89->Underline(2, 10, 1, 4); break;
case 7: _kln89->Underline(2, 0, 0, 4); break;
case 8: _kln89->Underline(2, 5, 0, 4); break;
}
// Actually, the kln89 sim from Bendix-King dosn't draw the 'ENT'
// for 'APT?' if it was on 'Leg' (pos 0) immediately previously, but does if
// it was not on 'Leg' immediately previously. I think we can desist from
// reproducing this probable bug.
if(_uLinePos > 0) {
if(!blink) _kln89->DrawEnt();
}
KLN89Page::Update(dt);
}
void KLN89NrstPage::CrsrPressed() {
}
void KLN89NrstPage::EntPressed() {
if(_uLinePos > 4) {
ShowScratchpadMessage(" No ", " Nrst ");
}
}
void KLN89NrstPage::LooseFocus() {
_uLinePos = 1;
_scratchpadMsg = false;
}

View file

@ -0,0 +1,48 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_NRST
#define _KLN89_PAGE_NRST
#include "kln89.hxx"
class KLN89NrstPage : public KLN89Page {
public:
KLN89NrstPage(KLN89* parent);
~KLN89NrstPage();
void Update(double dt);
void CrsrPressed();
void EntPressed();
//void ClrPressed();
//void Knob1Left1();
//void Knob1Right1();
//void Knob2Left1();
//void Knob2Right1();
void LooseFocus();
};
#endif // _KLN89_PAGE_NRST

View file

@ -0,0 +1,58 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_oth.hxx"
KLN89OthPage::KLN89OthPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 12;
_subPage = 0;
_name = "OTH";
}
KLN89OthPage::~KLN89OthPage() {
}
void KLN89OthPage::Update(double dt) {
// The OTH pages aren't terribly important at the moment, since we don't simulate
// error and failure, but lets hardwire some representitive output anyway.
if(_subPage == 0) {
_kln89->DrawText("State", 2, 0, 3);
_kln89->DrawText("GPS Alt", 2, 0, 2);
_kln89->DrawText("Estimated Posn", 2, 0, 1);
_kln89->DrawText("Error", 2, 1, 0);
// FIXME - hardwired value.
_kln89->DrawText("NAV D", 2, 9, 3);
// TODO - add error physics to FG GPS where the alt value comes from.
char buf[6];
int n = snprintf(buf, 5, "%i", _kln89->_altUnits == GPS_ALT_UNITS_FT ? (int)_kln89->_alt : (int)(_kln89->_alt * SG_FEET_TO_METER));
_kln89->DrawText((string)buf, 2, 13-n, 2);
_kln89->DrawText(_kln89->_altUnits == GPS_ALT_UNITS_FT ? "ft" : "m", 2, 13, 2);
// FIXME - hardwired values.
// Note that a 5th digit if required is left padded one further at position 7.
_kln89->DrawText(_kln89->_distUnits == GPS_DIST_UNITS_NM ? "0.02nm" : "0.03km", 2, 8, 0);
}
KLN89Page::Update(dt);
}

View file

@ -0,0 +1,39 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_OTH
#define _KLN89_PAGE_OTH
#include "kln89.hxx"
class KLN89OthPage : public KLN89Page {
public:
KLN89OthPage(KLN89* parent);
~KLN89OthPage();
void Update(double dt);
};
#endif // _KLN89_PAGE_OTH

View file

@ -0,0 +1,291 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_set.hxx"
#include <iostream>
using namespace std;
KLN89SetPage::KLN89SetPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 11;
_subPage = 0;
_name = "SET";
}
KLN89SetPage::~KLN89SetPage() {
}
void KLN89SetPage::Update(double dt) {
string sBaro, sAlt, sVel;
switch(_subPage+1) {
case 1:
_kln89->DrawText("INIT POS:", 2, 0, 3);
break;
case 2:
_kln89->DrawText("DATE", 2, 0, 3);
_kln89->DrawText("TIME", 2, 0, 2);
_kln89->DrawText("Cord", 2, 0, 1);
_kln89->DrawText("Mag Var:", 2, 0, 0);
break;
case 3:
_kln89->DrawText("Update DB on", 2, 1, 3);
_kln89->DrawText("ground only", 2, 1, 2);
_kln89->DrawText("Key", 2, 0, 1);
_kln89->DrawText("Update pub DB?", 2, 0, 0);
break;
case 4:
//cout << "_uLinePos = " << _uLinePos << '\n';
_kln89->DrawText("TURN", 2, 5, 3);
_kln89->DrawText("ANTICIPATION", 2, 1, 2);
if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 1) {
if(!_kln89->_blink) {
_kln89->DrawText((_kln89->GetTurnAnticipation() ? "ENABLED" : "DISABLED"), 2, 3, 1);
}
_kln89->Underline(2, 3, 1, 8);
} else {
_kln89->DrawText((_kln89->GetTurnAnticipation() ? "ENABLED" : "DISABLED"), 2, 3, 1);
}
break;
case 5:
_kln89->DrawText("Default First", 2, 0, 3);
_kln89->DrawText("Character of", 2, 1, 2);
_kln89->DrawText("Wpt identifier", 2, 0, 1);
_kln89->DrawText("Entry:", 2, 3, 0);
break;
case 6:
_kln89->DrawText("NEAREST APT", 2, 1, 3);
_kln89->DrawText("CRITERIA", 2, 3, 2);
_kln89->DrawText("Length:", 2, 0, 1);
_kln89->DrawText("Surface:", 2, 0, 0);
break;
case 7:
_kln89->DrawText("SUA ALERT", 2, 3, 3);
if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 1) {
if(!_kln89->_blink) {
_kln89->DrawText((_kln89->GetSuaAlertEnabled() ? "ENABLED" : "DISABLED"), 2, 4, 2);
}
_kln89->Underline(2, 4, 2, 8);
} else {
_kln89->DrawText((_kln89->GetSuaAlertEnabled() ? "ENABLED" : "DISABLED"), 2, 4, 2);
}
if(_kln89->GetSuaAlertEnabled()) {
_kln89->DrawText("Buffer:", 2, 0, 1);
_kln89->DrawSpecialChar(5, 2, 7, 1); // +- sign.
if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 2) {
if(!_kln89->_blink) {
_kln89->DrawText("00300", 2, 8, 1); // TODO - fix this hardwiring!!!!
}
_kln89->Underline(2, 8, 1, 5);
} else {
_kln89->DrawText("00300", 2, 8, 1); // TODO - fix this hardwiring!!!!
}
_kln89->DrawText("ft", 2, 13, 1); // TODO - fix this hardwiring!!!!
}
break;
case 8:
_kln89->DrawText("SET UNITS:", 2, 3, 3);
_kln89->DrawText("Baro :", 2, 0, 2);
_kln89->DrawText("Alt-APT :", 2, 0, 1);
_kln89->DrawText("Dist-Vel:", 2, 0, 0);
switch(_kln89->_baroUnits) {
case GPS_PRES_UNITS_IN:
sBaro = "\"";
break;
case GPS_PRES_UNITS_MB:
sBaro = "mB";
break;
case GPS_PRES_UNITS_HP:
sBaro = "hP";
break;
}
if(_kln89->_altUnits == GPS_ALT_UNITS_FT) sAlt = "ft";
else sAlt = "m";
if(_kln89->_distUnits == GPS_DIST_UNITS_NM) sVel = "nm-kt";
else sVel = "km-";
if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 1) {
if(!_kln89->_blink) {
_kln89->DrawText(sBaro, 2, 10, 2);
}
_kln89->Underline(2, 10, 2, 2);
} else {
_kln89->DrawText(sBaro, 2, 10, 2);
}
if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 2) {
if(!_kln89->_blink) {
_kln89->DrawText(sAlt, 2, 10, 1);
}
_kln89->Underline(2, 10, 1, 2);
} else {
_kln89->DrawText(sAlt, 2, 10, 1);
}
if(_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 3) {
if(!_kln89->_blink) {
_kln89->DrawText(sVel, 2, 10, 0);
if(_kln89->_distUnits != GPS_DIST_UNITS_NM) _kln89->DrawKPH(2, 13, 0);
}
_kln89->Underline(2, 10, 0, 5);
} else {
_kln89->DrawText(sVel, 2, 10, 0);
if(_kln89->_distUnits != GPS_DIST_UNITS_NM) _kln89->DrawKPH(2, 13, 0);
}
break;
case 9:
_kln89->DrawText("Altitude", 2, 3, 3);
_kln89->DrawText("Alert:", 2, 1, 2);
break;
case 10:
_kln89->DrawText("BUS MONITOR", 2, 2, 3);
_kln89->DrawText("Bus Volt", 2, 0, 2);
_kln89->DrawText("Alert Volt", 2, 0, 1);
_kln89->DrawText("Alert Delay", 2, 0, 0);
break;
case 11:
_kln89->DrawText("MIN DISPLAY", 2, 2, 3);
_kln89->DrawText("BRIGHTNESS ADJ", 2, 1, 2);
break;
}
KLN89Page::Update(dt);
}
void KLN89SetPage::CrsrPressed() {
if(_kln89->_mode == KLN89_MODE_DISP) return;
if(_kln89->_obsMode) {
_uLinePos = 0;
} else {
_uLinePos = 1;
}
switch(_subPage+1) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
_maxULinePos = 1;
break;
case 5:
break;
case 6:
_maxULinePos = 2;
break;
case 7:
if(_kln89->GetSuaAlertEnabled()) _maxULinePos = 2;
else _maxULinePos = 1;
break;
case 8:
_maxULinePos = 3;
break;
case 9:
break;
case 10:
break;
case 11:
break;
}
}
void KLN89SetPage::Knob2Left1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Left1();
} else {
switch(_subPage+1) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
if(_uLinePos == 1) {
_kln89->SetTurnAnticipation(!_kln89->GetTurnAnticipation());
}
break;
case 5:
break;
case 6:
break;
case 7:
if(_uLinePos == 1) {
_kln89->SetSuaAlertEnabled(!_kln89->GetSuaAlertEnabled());
_maxULinePos = (_kln89->GetSuaAlertEnabled() ? 2 : 1);
} else if(_uLinePos == 2) {
// TODO - implement variable sua alert buffer
}
break;
case 8:
if(_uLinePos == 1) { // baro units
_kln89->SetBaroUnits(_kln89->GetBaroUnits() - 1, true);
} else if(_uLinePos == 2) {
_kln89->SetAltUnitsSI(!_kln89->GetAltUnitsSI());
} else if(_uLinePos == 3) {
_kln89->SetDistVelUnitsSI(!_kln89->GetDistVelUnitsSI());
}
break;
}
}
}
void KLN89SetPage::Knob2Right1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Right1();
} else {
switch(_subPage+1) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
if(_uLinePos == 1) { // Which it should be!
_kln89->SetTurnAnticipation(!_kln89->GetTurnAnticipation());
}
break;
case 5:
break;
case 6:
break;
case 7:
if(_uLinePos == 1) {
_kln89->SetSuaAlertEnabled(!_kln89->GetSuaAlertEnabled());
_maxULinePos = (_kln89->GetSuaAlertEnabled() ? 2 : 1);
} else if(_uLinePos == 2) {
// TODO - implement variable sua alert buffer
}
break;
case 8:
if(_uLinePos == 1) { // baro units
_kln89->SetBaroUnits(_kln89->GetBaroUnits() + 1, true);
} else if(_uLinePos == 2) {
_kln89->SetAltUnitsSI(!_kln89->GetAltUnitsSI());
} else if(_uLinePos == 3) {
_kln89->SetDistVelUnitsSI(!_kln89->GetDistVelUnitsSI());
}
break;
}
}
}

View file

@ -0,0 +1,42 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_SET_HXX
#define _KLN89_PAGE_SET_HXX
#include "kln89.hxx"
class KLN89SetPage : public KLN89Page {
public:
KLN89SetPage(KLN89* parent);
~KLN89SetPage();
void Update(double dt);
void CrsrPressed();
void Knob2Left1();
void Knob2Right1();
};
#endif // _KLN89_PAGE_SET_HXX

View file

@ -0,0 +1,51 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_usr.hxx"
KLN89UsrPage::KLN89UsrPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 4;
_subPage = 0;
_name = "USR";
}
KLN89UsrPage::~KLN89UsrPage() {
}
void KLN89UsrPage::Update(double dt) {
bool actPage = (_kln89->_activePage->GetName() == "ACT" ? true : false);
bool crsr = (_kln89->_mode == KLN89_MODE_CRSR);
bool blink = _kln89->_blink;
if(_subPage == 0) {
// Hardwire no-waypoint output for now
_kln89->DrawText("0", 2, 1, 3);
_kln89->DrawText("USR at:", 2, 7, 3);
if(!(crsr && _uLinePos == 6 && blink)) _kln89->DrawText("User Pos L/L?", 2, 1, 2);
if(!(crsr && _uLinePos == 7 && blink)) _kln89->DrawText("User Pos R/D?", 2, 1, 1);
if(!(crsr && _uLinePos == 8 && blink)) _kln89->DrawText("Present Pos?", 2, 1, 0);
}
KLN89Page::Update(dt);
}

View file

@ -0,0 +1,39 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_USR_HXX
#define _KLN89_PAGE_USR_HXX
#include "kln89.hxx"
class KLN89UsrPage : public KLN89Page {
public:
KLN89UsrPage(KLN89* parent);
~KLN89UsrPage();
void Update(double dt);
};
#endif // _KLN89_PAGE_USR_HXX

View file

@ -0,0 +1,217 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 "kln89_page_vor.hxx"
KLN89VorPage::KLN89VorPage(KLN89* parent)
: KLN89Page(parent) {
_nSubPages = 2;
_subPage = 0;
_name = "VOR";
_vor_id = "OSI"; // TODO - check a property for an initial value to allow user-override.
np = NULL;
}
KLN89VorPage::~KLN89VorPage() {
}
void KLN89VorPage::Update(double dt) {
bool actPage = (_kln89->_activePage->GetName() == "ACT" ? true : false);
bool multi; // Not set by FindFirst...
bool exact = false;
if(_vor_id.size() == 3) exact = true;
if(np == NULL) {
np = _kln89->FindFirstVorById(_vor_id, multi, exact);
} else if(np->get_ident() != _vor_id) {
np = _kln89->FindFirstVorById(_vor_id, multi, exact);
}
//if(np == NULL) cout << "NULL... ";
//if(b == false) cout << "false...\n";
/*
if(np && b) {
cout << "VOR FOUND!\n";
} else {
cout << ":-(\n";
}
*/
if(np) {
//cout << np->id << '\n';
_vor_id = np->get_ident();
if(_kln89->GetActiveWaypoint()) {
if(_vor_id == _kln89->GetActiveWaypoint()->id) {
if(!(_kln89->_waypointAlert && _kln89->_blink)) {
// Active waypoint arrow
_kln89->DrawSpecialChar(4, 2, 0, 3);
}
}
}
if(_kln89->_mode != KLN89_MODE_CRSR) {
if(!_entInvert) {
if(!actPage) {
_kln89->DrawText(np->get_ident(), 2, 1, 3);
} else {
// If it's the ACT page, The ID is shifted slightly right to make space for the waypoint index.
_kln89->DrawText(np->get_ident(), 2, 4, 3);
char buf[3];
int n = snprintf(buf, 3, "%i", _kln89->GetActiveWaypointIndex() + 1);
_kln89->DrawText((string)buf, 2, 3 - n, 3);
}
} else {
if(!_kln89->_blink) {
_kln89->DrawText(np->get_ident(), 2, 1, 3, false, 99);
_kln89->DrawEnt();
}
}
}
if(_subPage == 0) {
//// TODO - will almost certainly have to process freq below for FG
_kln89->DrawFreq(np->get_freq(), 2, 9, 3);
// TODO - trim VOR-DME from the name, convert to uppercase, abbreviate, etc
_kln89->DrawText(np->get_name(), 2, 0, 2);
//cout << np->lat << "... ";
_kln89->DrawLatitude(np->get_lat(), 2, 3, 1);
_kln89->DrawLongitude(np->get_lon(), 2, 3, 0);
} else {
_kln89->DrawText("Mag Var", 2, 0, 2);
////float mvf = np->magvar * SG_RADIANS_TO_DEGREES;
//// TODO FIXME BELOW
float mvf = 0.0;
_kln89->DrawChar((mvf <= 0 ? 'E' : 'W'), 2, 9, 2);
int mvi = (int)(fabs(mvf) + 0.5);
string mvs = GPSitoa(mvi);
_kln89->DrawText(mvs, 2, 13 - mvs.size(), 2);
_kln89->DrawSpecialChar(0, 2, 13, 2);
_kln89->DrawDirDistField(np->get_lat() * SG_DEGREES_TO_RADIANS, np->get_lon() * SG_DEGREES_TO_RADIANS, 2, 0, 0,
_to_flag, (_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 4 ? true : false));
}
} else {
if(_kln89->_mode != KLN89_MODE_CRSR) _kln89->DrawText(_vor_id, 2, 1, 3);
if(_subPage == 0) {
_kln89->DrawText("---.--", 2, 9, 3);
_kln89->DrawText("--------------", 2, 0, 2);
_kln89->DrawText("- -- --.--'", 2, 3, 1);
_kln89->DrawText("---- --.--'", 2, 3, 0);
_kln89->DrawSpecialChar(0, 2, 7, 1);
_kln89->DrawSpecialChar(0, 2, 7, 0);
}
}
if(_kln89->_mode == KLN89_MODE_CRSR) {
if(_uLinePos > 0 && _uLinePos < 4) {
// TODO - blink as well
_kln89->Underline(2, _uLinePos, 3, 1);
}
for(unsigned int i = 0; i < _vor_id.size(); ++i) {
if(_uLinePos != (i + 1)) {
_kln89->DrawChar(_vor_id[i], 2, i + 1, 3);
} else {
if(!_kln89->_blink) _kln89->DrawChar(_vor_id[i], 2, i + 1, 3);
}
}
}
_id = _vor_id;
KLN89Page::Update(dt);
}
void KLN89VorPage::SetId(string s) {
_last_vor_id = _vor_id;
_save_vor_id = _vor_id;
_vor_id = s;
np = NULL;
}
void KLN89VorPage::CrsrPressed() {
if(_kln89->_mode == KLN89_MODE_DISP) return;
if(_kln89->_obsMode) {
_uLinePos = 0;
} else {
_uLinePos = 1;
}
if(_subPage == 0) {
_maxULinePos = 17;
} else {
_maxULinePos = 4;
}
}
void KLN89VorPage::ClrPressed() {
if(_subPage == 1 && _uLinePos == 4) {
_to_flag = !_to_flag;
}
}
void KLN89VorPage::EntPressed() {
if(_entInvert) {
_entInvert = false;
_last_vor_id = _vor_id;
_vor_id = _save_vor_id;
}
}
void KLN89VorPage::Knob2Left1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Left1();
} else {
if(_uLinePos < 4) {
// Same logic for both pages - set the ID
_vor_id = _vor_id.substr(0, _uLinePos);
// ASSERT(_uLinePos > 0);
if(_uLinePos == (_vor_id.size() + 1)) {
_vor_id += '9';
} else {
_vor_id[_uLinePos - 1] = _kln89->DecChar(_vor_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
}
} else {
if(_subPage == 0) {
// set by name
} else {
// NO-OP - from/to field is switched by clr button, not inner knob.
}
}
}
}
void KLN89VorPage::Knob2Right1() {
if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
KLN89Page::Knob2Right1();
} else {
if(_uLinePos < 4) {
// Same logic for both pages - set the ID
_vor_id = _vor_id.substr(0, _uLinePos);
// ASSERT(_uLinePos > 0);
if(_uLinePos == (_vor_id.size() + 1)) {
_vor_id += 'A';
} else {
_vor_id[_uLinePos - 1] = _kln89->IncChar(_vor_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
}
} else {
if(_subPage == 0) {
// set by name
} else {
// NO-OP - from/to field is switched by clr button, not inner knob.
}
}
}
}

View file

@ -0,0 +1,52 @@
// kln89_page_*.[ch]xx - this file is one of the "pages" that
// are used in the KLN89 GPS unit simulation.
//
// Written by David Luff, started 2005.
//
// Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
//
// 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 _KLN89_PAGE_VOR_HXX
#define _KLN89_PAGE_VOR_HXX
#include "kln89.hxx"
class KLN89VorPage : public KLN89Page {
public:
KLN89VorPage(KLN89* parent);
~KLN89VorPage();
void Update(double dt);
void CrsrPressed();
void ClrPressed();
void EntPressed();
void Knob2Left1();
void Knob2Right1();
void SetId(string s);
private:
string _vor_id;
string _last_vor_id;
string _save_vor_id;
FGNavRecord* np;
};
#endif // _KLN89_PAGE_VOR_HXX