void dlgTextEntryKeyboardShowModal(TCHAR *text, int width, const TCHAR* szFile, const TCHAR* szResource) { first = true; wf = NULL; if (width==0) { width = MAX_TEXTENTRY; } max_width = min(MAX_TEXTENTRY, width); char filename[MAX_PATH]; LocalPathS(filename, szFile); wf = dlgLoadFromXML(CallBackTable, filename, hWndMainWindow, szResource); if (!wf) return; cursor = 0; ClearText(); if (_tcslen(text)>0) { _tcsupr(text); LK_tcsncpy(edittext, text, max_width-1); // show previous test. // this text is replaced by first key down // but used if "OK" is clicked first for don't reset current value. } UpdateTextboxProp(); wf->SetKeyDownNotify(FormKeyDown); wf->ShowModal(); LK_tcsncpy(text, edittext, max_width-1); delete wf; wf=NULL; }
void dlgTextEntryKeyboardShowModal(TCHAR *text, int width, unsigned ResID) { wf = NULL; if (width==0) { width = MAX_TEXTENTRY; } max_width = min(MAX_TEXTENTRY, width); wf = dlgLoadFromXML(CallBackTable, ResID); if (!wf) return; // cursor = _tcslen(text); ClearText(); if (_tcslen(text)>0) { CharUpper(text); LK_tcsncpy(edittext, text, max_width-1); // show previous test. // this text is replaced by first key down // but used if "OK" is clicked first for don't reset current value. } cursor = _tcslen(edittext); UpdateTextboxProp(); WindowControl* pBtHelp = wf->FindByName(TEXT("cmdHelp")); if(pBtHelp) { pBtHelp->SetVisible(wKeyboardPopupWndProperty && wKeyboardPopupWndProperty->HasHelpText()); } wf->SetKeyDownNotify(FormKeyDown); wf->ShowModal(); LK_tcsncpy(text, edittext, max_width-1); // cursor = _tcslen(text); delete wf; wf=NULL; }
void dlgTextEntryKeyboardShowModal(TCHAR *text, int width, const TCHAR* szFile, const TCHAR* szResource) { first = true; wf = NULL; if (width==0) { width = MAX_TEXTENTRY; } max_width = min(MAX_TEXTENTRY, width); char filename[MAX_PATH]; LocalPathS(filename, szFile); wf = dlgLoadFromXML(CallBackTable, filename, hWndMainWindow, szResource); if (!wf) return; cursor = 0; ClearText(); if (_tcslen(text)>0) { _tcsupr(text); LK_tcsncpy(edittext, text, max_width-1); // position cursor at the end of imported text cursor=_tcslen(text); } UpdateTextboxProp(); wf->SetKeyDownNotify(FormKeyDown); wf->ShowModal(); LK_tcsncpy(text, edittext, max_width-1); delete wf; wf=NULL; }
static void OnFilterName(WndButton* pWnd) { int SelectedAsp=-1; int CursorPos=0; TCHAR newNameFilter[NAMEFILTERLEN+1]; LK_tcsncpy(newNameFilter, sNameFilter, NAMEFILTERLEN); SelectedAsp = dlgTextEntryShowModalAirspace(newNameFilter, NAMEFILTERLEN); int i= _tcslen(newNameFilter)-1; while (i>=0) { if (newNameFilter[i]!=_T(' ')) { break; } newNameFilter[i]=0; i--; }; LK_tcsncpy(sNameFilter, newNameFilter, NAMEFILTERLEN); if (wpnewName) { if (sNameFilter[0]=='\0') { SetNameCaption(TEXT("*")); } else { SetNameCaption(sNameFilter); } } FilterMode(true); UpdateList(); if((SelectedAsp>=0) && (SelectedAsp < NumberOfAirspaces)) { CursorPos = SelectedAsp; /* for (i=0; i<UpLimit; i++) { if(AirspaceSelectInfo[i].Index == SelectedAsp) { CursorPos = i; } */ } wAirspaceList->SetFocus(); wAirspaceList->SetItemIndexPos(CursorPos); wAirspaceList->Redraw(); }
// return current overtarget header name TCHAR *GetOvertargetHeader(void) { // Maxmode + 1 because maxmode does not account pos 0 static TCHAR targetheader[OVT_MAXMODE+1][OVERTARGETHEADER_MAX+2]; if (DoInit[MDI_GETOVERTARGETHEADER]) { // LKTOKEN _@M1323_ "T>" LK_tcsncpy(targetheader[OVT_TASK], gettext(TEXT("_@M1323_")), OVERTARGETHEADER_MAX); // LKTOKEN _@M1324_ "B>" LK_tcsncpy(targetheader[OVT_BALT], gettext(TEXT("_@M1324_")), OVERTARGETHEADER_MAX); // LKTOKEN _@M1325_ "1>" LK_tcsncpy(targetheader[OVT_ALT1], gettext(TEXT("_@M1325_")), OVERTARGETHEADER_MAX); // LKTOKEN _@M1326_ "2>" LK_tcsncpy(targetheader[OVT_ALT2], gettext(TEXT("_@M1326_")), OVERTARGETHEADER_MAX); // LKTOKEN _@M1327_ "H>" LK_tcsncpy(targetheader[OVT_HOME], gettext(TEXT("_@M1327_")), OVERTARGETHEADER_MAX); // LKTOKEN _@M1328_ "L>" LK_tcsncpy(targetheader[OVT_THER], gettext(TEXT("_@M1328_")), OVERTARGETHEADER_MAX); // LKTOKEN _@M1329_ "M" LK_tcsncpy(targetheader[OVT_MATE], gettext(TEXT("_@M1329_")), OVERTARGETHEADER_MAX); // LKTOKEN _@M1330_ "F>" LK_tcsncpy(targetheader[OVT_FLARM], gettext(TEXT("_@M1330_")), OVERTARGETHEADER_MAX); for (int i=0; i<OVT_MAXMODE+1; i++) targetheader[i][OVERTARGETHEADER_MAX]='\0'; DoInit[MDI_GETOVERTARGETHEADER]=false; } return(targetheader[OvertargetMode]); }
// // LK Infobox list // Included by lk temporarily, only with CUTIBOX // bool SetDataOption( int index, UnitGroup_t UnitGroup, const TCHAR *Description, const TCHAR *Title) { DATAOPTIONS tag; if (index>=NUMDATAOPTIONS_MAX) return false; tag.UnitGroup = UnitGroup; // if we have Description, we also have Title LK_tcsncpy(tag.Description, gettext(Description), DESCRIPTION_SIZE); LK_tcsncpy(tag.Title, gettext(Title), TITLE_SIZE); memcpy(&Data_Options[index], &tag, sizeof(DATAOPTIONS)); if (NumDataOptions<=index) NumDataOptions=index+1; //No. of items = max index+1 return true; }
static void OnPaintListItem(WindowControl * Sender, LKSurface& Surface) { if (!Sender) { return; } unsigned int n = UpLimit - LowLimit; TCHAR sTmp[50]; Surface.SetTextColor(RGB_BLACK); const int LineHeight = Sender->GetHeight(); const int TextHeight = Surface.GetTextHeight(_T("dp")); const int TextPos = (LineHeight - TextHeight) / 2; // offset for text vertical center if (DrawListIndex < n) { const size_t i = (FullFlag) ? StrIndex[LowLimit + DrawListIndex] : (LowLimit + DrawListIndex); // Poco::Thread::sleep(100); const int width = Sender->GetWidth(); // total width const int w0 = LineHeight; // Picto Width const int w2 = Surface.GetTextWidth(TEXT(" 000km")); // distance Width _stprintf(sTmp, _T(" 000%s "), MsgToken(2179)); const int w3 = Surface.GetTextWidth(sTmp); // bearing width const int w1 = width - w0 - 2*w2 - w3; // Max Name width // Draw Picto const RECT PictoRect = {0, 0, w0, LineHeight}; AirspaceSelectInfo[i].airspace->DrawPicto(Surface, PictoRect); // Draw Name Surface.DrawTextClip(w0, TextPos, AirspaceSelectInfo[i].airspace->Name() , w1); LK_tcsncpy(sTmp, CAirspaceManager::GetAirspaceTypeShortText(AirspaceSelectInfo[i].Type) , 4); const int w4 = Surface.GetTextWidth(sTmp); Surface.DrawTextClip(w1+w2, TextPos, sTmp,w4); // Draw Distance : right justified after waypoint Name _stprintf(sTmp, TEXT("%.0f%s"), AirspaceSelectInfo[i].Distance , Units::GetDistanceName()); const int x2 = width - w3 - Surface.GetTextWidth(sTmp); Surface.DrawText(x2, TextPos, sTmp); // Draw Bearing right justified after distance _stprintf(sTmp, TEXT("%d%s"), iround(AirspaceSelectInfo[i].Direction), MsgToken(2179)); const int x3 = width - Surface.GetTextWidth(sTmp); Surface.DrawText(x3, TextPos, sTmp); } else { if (DrawListIndex == 0) { // LKTOKEN _@M466_ = "No Match!" Surface.DrawText(IBLSCALE(2), TextPos, MsgToken(466)); } } }
bool AddFlarmLookupItem(int id, TCHAR *name, bool saveFile) { bool bRet = false; int index = LookupSecondaryFLARMId(id); #ifdef DEBUG_LKT StartupStore(_T("... LookupSecondary id=%d result index=%d\n"), id, index); #endif if (index == -1) { if (NumberOfFLARMNames < MAXFLARMLOCALS) { // 100322 // create new record index = NumberOfFLARMNames++; } } if(index != -1) { FLARM_Names[index].ID = id; LK_tcsncpy(FLARM_Names[index].Name, name, MAXFLARMNAME); bRet = true; } if (bRet && saveFile) { SaveFLARMDetails(); } return bRet; }
static void OnAirspacePaintListItem(WindowControl * Sender, LKSurface& Surface){ TCHAR label[40]; (void)Sender; if (DrawListIndex < AIRSPACECLASSCOUNT){ int i = DrawListIndex; LK_tcsncpy(label, CAirspaceManager::Instance().GetAirspaceTypeText(i), 39); int w0, w1, w2, x0; if (ScreenLandscape) { w0 = 202*ScreenScale; } else { w0 = 225*ScreenScale; } // LKTOKEN _@M789_ = "Warn" w1 = Surface.GetTextWidth(MsgToken(789))+ScreenScale*10; // LKTOKEN _@M241_ = "Display" w2 = Surface.GetTextWidth(MsgToken(241))+ScreenScale*10; x0 = w0-w1-w2; Surface.SetTextColor(RGB_BLACK); Surface.DrawTextClip(2*ScreenScale, 2*ScreenScale, label, x0-ScreenScale*10); if (colormode) { Surface.SelectObject(LK_WHITE_PEN); Surface.SelectObject(LKBrush_White); Surface.Rectangle(x0, 2*ScreenScale,w0, 22*ScreenScale); Surface.SetTextColor(MapWindow::GetAirspaceColourByClass(i)); Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF)); Surface.SelectObject(MapWindow::GetAirspaceBrushByClass(i)); Surface.Rectangle(x0, 2*ScreenScale,w0, 22*ScreenScale); } else { bool iswarn; bool isdisplay; iswarn = (MapWindow::iAirspaceMode[i]>=2); isdisplay = ((MapWindow::iAirspaceMode[i]%2)>0); if (iswarn) { // LKTOKEN _@M789_ = "Warn" _tcscpy(label, MsgToken(789)); Surface.DrawText(w0-w1-w2, 2*ScreenScale, label); } if (isdisplay) { // LKTOKEN _@M241_ = "Display" _tcscpy(label, MsgToken(241)); Surface.DrawText(w0-w2, 2*ScreenScale, label); } } } }
static void PrepareData(void){ TCHAR sTmp[5]; if (NumberOfAirspaces==0) return; sNameFilter[0] =_T('\0'); AirspaceSelectInfo = (AirspaceSelectInfo_t*) malloc(sizeof(AirspaceSelectInfo_t) * NumberOfAirspaces); if (AirspaceSelectInfo==NULL) { OutOfMemory(_T(__FILE__),__LINE__); return; } StrIndex = (int*)malloc(sizeof(int)*(NumberOfAirspaces+1)); if (StrIndex==NULL) { OutOfMemory(_T(__FILE__),__LINE__); return; } int index=0; double bearing; double distance; CAirspaceList Airspaces = CAirspaceManager::Instance().GetAllAirspaces(); CAirspaceList::const_iterator it; for (it=Airspaces.begin(); it != Airspaces.end(); ++it) { AirspaceSelectInfo[index].airspace = *it; distance = DISTANCEMODIFY * (*it)->Range(Longitude, Latitude, bearing); if (distance<0) distance=0; AirspaceSelectInfo[index].Distance = distance; AirspaceSelectInfo[index].Direction = bearing; LK_tcsncpy(sTmp, (*it)->Name(), 4); CharUpper(sTmp); AirspaceSelectInfo[index].FourChars = (((unsigned)sTmp[0] & 0xff) << 24) + (((unsigned)sTmp[1] & 0xff) << 16) + (((unsigned)sTmp[2] & 0xff) << 8) + (((unsigned)sTmp[3] & 0xff) ); AirspaceSelectInfo[index].Type = (*it)->Type(); index++; } qsort(AirspaceSelectInfo, UpLimit, sizeof(AirspaceSelectInfo_t), AirspaceNameCompare); }
bool Units::FormatUserDistance(double Distance, TCHAR *Buffer, size_t size){ int prec; double value; TCHAR sTmp[32]; UnitDescriptor_t *pU = &UnitDescriptors[UserDistanceUnit]; value = Distance * pU->ToUserFact; // + pU->ToUserOffset; if (value >= 100) prec = 0; else if (value > 10) prec = 1; else if (value > 1) prec = 2; else { prec = 3; if (UserDistanceUnit == unKiloMeter){ prec = 0; pU = &UnitDescriptors[unMeter]; value = Distance * pU->ToUserFact; } if (UserDistanceUnit == unNauticalMiles || UserDistanceUnit == unStatuteMiles) { pU = &UnitDescriptors[unFeet]; value = Distance * pU->ToUserFact; if (value<1000) { prec = 0; } else { prec = 1; pU = &UnitDescriptors[UserDistanceUnit]; value = Distance* pU->ToUserFact; } } } _stprintf(sTmp, TEXT("%.*f%s"), prec, value, GetUnitName(UserDistanceUnit)); if (_tcslen(sTmp) < size-1){ _tcscpy(Buffer, sTmp); return(true); } else { LK_tcsncpy(Buffer, sTmp, size-1); return(false); } }
bool Units::FormatUserMapScale(Units_t *Unit, double Distance, TCHAR *Buffer, size_t size){ int prec; double value; TCHAR sTmp[32]; UnitDescriptor_t *pU = &UnitDescriptors[UserDistanceUnit]; if (Unit != NULL) *Unit = UserDistanceUnit; value = Distance * pU->ToUserFact; // + pU->ToUserOffset; if (value >= 9.999) prec = 0; else if (value >= 0.999) prec = 1; else { prec = 2; if (UserDistanceUnit == unKiloMeter){ prec = 0; if (Unit != NULL) *Unit = unMeter; pU = &UnitDescriptors[unMeter]; value = Distance * pU->ToUserFact; } if ((UserDistanceUnit == unNauticalMiles || UserDistanceUnit == unStatuteMiles) && (value < 0.160)) { prec = 0; if (Unit != NULL) *Unit = unFeet; pU = &UnitDescriptors[unFeet]; value = Distance * pU->ToUserFact; } } _stprintf(sTmp, TEXT("%.*f%s"), prec, value, GetUnitName(unFeet)); if (_tcslen(sTmp) < size-1){ _tcscpy(Buffer, sTmp); return(true); } else { LK_tcsncpy(Buffer, sTmp, size-1); return(false); } }
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /// Opens existing UTF-8 encoded file. /// /// @retval true file open successfully /// @retval false cannot open file /// bool Utf8File::Open(const TCHAR* fileName, Mode ioMode) { TCHAR* fmode; switch (ioMode) { case io_read: fmode = _T("rb"); break; case io_append: fmode = _T("a+t"); break; case io_create: fmode = _T("w+t"); break; default: return(false); } LK_tcsncpy(path, fileName, countof(path)-1); fp = _tfopen(fileName, fmode); return(fp != NULL); } // Open()
// // If it is a virtual waypoint, rename it before saving to task // void RenameIfVirtual(const unsigned int i) { if (i>RESWP_END) return; LKASSERT(i<=NumberOfWayPoints); if ( _tcslen(WayPointList[i].Name)> (NAME_SIZE-5)) return; TCHAR tmp[NAME_SIZE+10]; _stprintf(tmp,_T("TSK_%s"),WayPointList[i].Name); LK_tcsncpy(WayPointList[i].Name,tmp,NAME_SIZE); if (WayPointList[i].Latitude==RESWP_INVALIDNUMBER && WayPointList[i].Longitude==RESWP_INVALIDNUMBER) { if (WayPointList[RESWP_TAKEOFF].Latitude!=RESWP_INVALIDNUMBER) { WayPointList[i].Latitude=WayPointList[RESWP_TAKEOFF].Latitude; WayPointList[i].Longitude=WayPointList[RESWP_TAKEOFF].Longitude; WayPointList[i].Altitude=WayPointList[RESWP_TAKEOFF].Altitude; } } }
static void OnFilterType(DataField *Sender, DataField::DataAccessKind_t Mode) { TCHAR sTmp[20]; switch(Mode){ case DataField::daGet: Sender->Set(TEXT("*")); break; case DataField::daPut: break; case DataField::daChange: break; case DataField::daInc: TypeFilterIdx++; if (TypeFilterIdx > (AIRSPACECLASSCOUNT+1)) TypeFilterIdx = 0; //Need to limit+1 because idx shifted with +1 FilterMode(false); UpdateList(); break; case DataField::daDec: if (TypeFilterIdx == 0) TypeFilterIdx = AIRSPACECLASSCOUNT+1; //Need to limit+1 because idx shifted with +1 else TypeFilterIdx--; FilterMode(false); UpdateList(); break; case DataField::daSpecial: break; } if (TypeFilterIdx>0) { if( TypeFilterIdx == AIRSPACECLASSCOUNT+1) _tcscpy(sTmp, MsgToken(239)); else LK_tcsncpy(sTmp, CAirspaceManager::GetAirspaceTypeText(TypeFilterIdx-1), sizeof(sTmp)/sizeof(sTmp[0])-1); } else { _tcscpy(sTmp, TEXT("*")); } Sender->Set(sTmp); }
void Flaps(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { double speed = 0.0; if (GlidePolar::FlapsMass<=0) return; // avoid division by zero crashes if (Basic->AirspeedAvailable) { speed = (int)(Basic->IndicatedAirspeed); } else { speed = (int)(Calculated->IndicatedAirspeedEstimated); } LKASSERT(GlidePolar::FlapsMass!=0); double massCorrectionFactor = sqrt(GlidePolar::GetAUW()/GlidePolar::FlapsMass); for (int i=0; i<GlidePolar::FlapsPosCount-1; i++) { if (speed >= GlidePolar::FlapsPos[i]*massCorrectionFactor && speed < GlidePolar::FlapsPos[i+1]*massCorrectionFactor) { LK_tcsncpy(Calculated->Flaps,GlidePolar::FlapsName[i],MAXFLAPSNAME); } } }
// I don't think it is a good idea to change, even if for a short time, a global variable at all effect here, // just to be able to call the function above with a parameter missing! bool Units::FormatAlternateUserAltitude(double Altitude, TCHAR *Buffer, size_t size){ Units_t useUnit; TCHAR sTmp[32]; if (UserAltitudeUnit == unMeter) useUnit=unFeet; else useUnit=unMeter; UnitDescriptor_t *pU = &UnitDescriptors[useUnit]; Altitude = Altitude * pU->ToUserFact; _stprintf(sTmp, TEXT("%.*f%s"), 0, Altitude, GetUnitName(useUnit)); if (_tcslen(sTmp) < size-1){ _tcscpy(Buffer, sTmp); return(true); } else { LK_tcsncpy(Buffer, sTmp, size-1); return(false); } }
void DoStatusMessage(const TCHAR* text, const TCHAR *data, const bool playsound) { Message::Lock(); StatusMessageSTRUCT LocalMessage; LocalMessage = StatusMessageData[0]; int i; // Search from end of list (allow overwrites by user) for (i=StatusMessageData_Size - 1; i>0; i--) { #if BUGSTOP LKASSERT(i>=0); #else if (i<0) break; #endif if (_tcscmp(text, StatusMessageData[i].key) == 0) { LocalMessage = StatusMessageData[i]; break; } } // doSound always true, to be removed the StatusFile entirely if (EnableSoundModes && LocalMessage.doSound &&playsound) PlayResource(LocalMessage.sound); // TODO code: consider what is a sensible size? TCHAR msgcache[1024]; if (LocalMessage.doStatus) { LK_tcsncpy(msgcache,gettext(text),800); if (data != NULL) { _tcscat(msgcache, TEXT(" ")); _tcscat(msgcache, data); } Message::AddMessage(LocalMessage.delay_ms, 1, msgcache); } Message::Unlock(); }
bool Units::FormatUserArrival(double Altitude, TCHAR *Buffer, size_t size){ int prec; TCHAR sTmp[32]; UnitDescriptor_t *pU = &UnitDescriptors[UserAltitudeUnit]; Altitude = Altitude * pU->ToUserFact; // + pU->ToUserOffset; // prec = 4-log10(Altitude); // prec = max(prec, 0); prec = 0; _stprintf(sTmp, TEXT("%+.*f%s"), prec, Altitude, GetUnitName(UserAltitudeUnit)); if (_tcslen(sTmp) < size-1){ _tcscpy(Buffer, sTmp); return(true); } else { LK_tcsncpy(Buffer, sTmp, size-1); return(false); } }
void Flaps(NMEA_INFO *Basic, DERIVED_INFO *Calculated) { if (GlidePolar::FlapsMass<=0) return; // avoid division by zero crashes double speed = 0.0; if (Basic->AirspeedAvailable) { speed = (int)(Basic->IndicatedAirspeed); } else { speed = (int)(Calculated->IndicatedAirspeedEstimated); } // correcting speed for calculated bank angle if (cos(Calculated->BankAngle*DEG_TO_RAD)>0) speed = speed/sqrt(1/cos(Calculated->BankAngle*DEG_TO_RAD)); double massCorrectionFactor = sqrt(GlidePolar::GetAUW()/GlidePolar::FlapsMass); for (int i=0;i<GlidePolar::FlapsPosCount-1;i++) { if (speed >= GlidePolar::FlapsPos[i]*massCorrectionFactor && speed < GlidePolar::FlapsPos[i+1]*massCorrectionFactor) { LK_tcsncpy(Calculated->Flaps,GlidePolar::FlapsName[i],MAXFLAPSNAME); } } }
void InitGUI(const TCHAR * FontDescription) { #define FONTEDIT_GUI_MAX_TITLE 128 WndProperty* wp; TCHAR sTitle[FONTEDIT_GUI_MAX_TITLE]; TCHAR sTitlePrefix[]=TEXT("Edit Font: "); _tcscpy(sTitle, sTitlePrefix); LK_tcsncpy(sTitle + _tcslen(sTitlePrefix), FontDescription,FONTEDIT_GUI_MAX_TITLE - _tcslen(sTitlePrefix) -1); wf->SetCaption(sTitle); wp = (WndProperty*)wf->FindByName(TEXT("prpFontName")); if (wp) { DataFieldEnum* dfe; dfe = (DataFieldEnum*)wp->GetDataField(); dfe->addEnumText(TEXT("Tahoma")); dfe->addEnumText(TEXT("TahomaBD")); // dfe->addEnumText(TEXT("DejaVu Sans Condensed")); // RLD ToDo code: add more font faces, and validate their availabiliy } wp = (WndProperty*)wf->FindByName(TEXT("prpFontPitchAndFamily")); if (wp) { DataFieldEnum* dfe; dfe = (DataFieldEnum*)wp->GetDataField(); // LKTOKEN _@M227_ = "Default" dfe->addEnumText(gettext(TEXT("_@M227_"))); // LKTOKEN _@M304_ = "Fixed" dfe->addEnumText(gettext(TEXT("_@M304_"))); // LKTOKEN _@M779_ = "Variable" dfe->addEnumText(gettext(TEXT("_@M779_"))); } }
void MapWindow::DrawWaypointsNew(HDC hdc, const RECT rc) { unsigned int i; int bestwp=-1; TCHAR Buffer[LKSIZEBUFFER]; TCHAR Buffer2[LKSIZEBUFFER]; TCHAR sAltUnit[LKSIZEBUFFERUNIT]; TextInBoxMode_t TextDisplayMode = {0}; static int resizer[10]={ 20,20,20,3,5,8,10,12,0 }; // if pan mode, show full names int pDisplayTextType = DisplayTextType; if (!WayPointList) return; _tcscpy(sAltUnit, Units::GetAltitudeName()); MapWaypointLabelListCount = 0; int arrivalcutoff=0, foundairport=0; bool isairport; bool islandpoint; // setting decluttericons will not paint outlanding, and use minrunway to declutter even more bool decluttericons=false; // inrange : max scale allowed to print non-landable waypoints bool inrange=true; // minimal size of a runway to paint it while decluttering int minrunway=0; // // RealScale // // 2km 1.42 // 3.5km 2.5 // 5km 3.57 // 7.5km 5.35 // 10km 7.14 // 15km 10.71 // 20km 14.28 // 25km 17.85 // 40km 28.57 // 50km 35.71 // 75km 53.57 switch(DeclutterMode) { case dmDisabled: //inrange=(MapWindow::zoom.RealScale() <=18 ? true:false); // 17.85, 25km scale inrange=(MapWindow::zoom.RealScale() <=15 ? true:false); // 14.28, 20km scale decluttericons=false; break; case dmLow: inrange=(MapWindow::zoom.RealScale() <=11 ? true:false); // 10.71, 15km scale decluttericons=(MapWindow::zoom.RealScale() >=14 ? true : false); minrunway=200; break; case dmMedium: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=400; break; case dmHigh: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=800; break; case dmVeryHigh: inrange=(MapWindow::zoom.RealScale() <=10 ? true:false); decluttericons=(MapWindow::zoom.RealScale() >=10 ? true : false); minrunway=1600; break; default: LKASSERT(0); break; } if (MapWindow::zoom.RealScale() <=20) for(i=0;i<NumberOfWayPoints;i++) { if (WayPointList[i].Visible != TRUE ) continue; // false may not be FALSE? if (WayPointCalc[i].IsAirport) { if (WayPointList[i].Reachable == FALSE) { SelectObject(hDCTemp,hBmpAirportUnReachable); } else { SelectObject(hDCTemp,hBmpAirportReachable); if ( arrivalcutoff < (int)(WayPointList[i].AltArivalAGL)) { arrivalcutoff = (int)(WayPointList[i].AltArivalAGL); bestwp=i; foundairport++; } } } else { if ( WayPointCalc[i].IsOutlanding ) { // outlanding if (WayPointList[i].Reachable == FALSE) SelectObject(hDCTemp,hBmpFieldUnReachable); else { SelectObject(hDCTemp,hBmpFieldReachable); // get the outlanding as bestwp only if no other choice if (foundairport == 0) { // do not set arrivalcutoff: any next reachable airport is better than an outlanding if ( arrivalcutoff < (int)(WayPointList[i].AltArivalAGL)) bestwp=i; } } } else continue; // do not draw icons for normal turnpoints here } if(Appearance.IndLandable == wpLandableDefault) { double fScaleFact =MapWindow::zoom.RealScale(); if(fScaleFact < 0.1) fScaleFact = 0.1; // prevent division by zero fScaleFact = zoom.DrawScale(); if(fScaleFact > 20000.0) fScaleFact = 20000.0; // limit to prevent huge airfiel symbols if(fScaleFact < 1600) fScaleFact = 1600; // limit to prevent tiny airfiel symbols if (decluttericons) { if (WayPointCalc[i].IsAirport && (WayPointList[i].RunwayLen>minrunway || WayPointList[i].RunwayLen==0)) { DrawRunway(hdc,&WayPointList[i],rc, fScaleFact); } } else DrawRunway(hdc,&WayPointList[i],rc, fScaleFact); } else { DrawBitmapX(hdc, WayPointList[i].Screen.x-10, WayPointList[i].Screen.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, WayPointList[i].Screen.x-10, WayPointList[i].Screen.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } } // for all waypoints if (foundairport==0 && bestwp>=0) arrivalcutoff = (int)WayPointList[bestwp].AltArivalAGL; for(i=0;i<NumberOfWayPoints;i++) { if(WayPointList[i].Visible ) { bool irange = false; bool intask = false; bool islandable; // isairport+islandpoint bool excluded=false; bool dowrite; intask = WaypointInTask(i); dowrite = intask; // initially set only for intask memset((void*)&TextDisplayMode, 0, sizeof(TextDisplayMode)); // airports are also landpoints. should be better handled isairport=((WayPointList[i].Flags & AIRPORT) == AIRPORT); islandpoint=((WayPointList[i].Flags & LANDPOINT) == LANDPOINT); islandable=WayPointCalc[i].IsLandable; // always in range if MapScale <=10 irange = inrange; if(MapWindow::zoom.RealScale() > 20) { SelectObject(hDCTemp,hInvSmall); irange=false; goto NiklausWirth; // with compliments } if (decluttericons) { if (! (WayPointCalc[i].IsAirport && (WayPointList[i].RunwayLen>minrunway || WayPointList[i].RunwayLen==0))) { SelectObject(hDCTemp,hInvSmall); irange=false; goto NiklausWirth; } } if( islandable ) { if(WayPointList[i].Reachable){ TextDisplayMode.Reachable = 1; if ( isairport ) SelectObject(hDCTemp,hBmpAirportReachable); else SelectObject(hDCTemp,hBmpFieldReachable); if ((GetMultimap_Labels()<MAPLABELS_ALLOFF)||intask) { dowrite = true; // exclude outlandings worst than visible airports, only when there are visible reachable airports! if ( isairport==false && islandpoint==true ) { if ( (int)WayPointList[i].AltArivalAGL >=2000 ) { // more filter excluded=true; } else { if ( (bestwp>=0) && (i==(unsigned)bestwp) && (foundairport==0) ) { // this outlanding is the best option isairport=true; islandpoint=false; // make it an airport TODO paint it as best } else { if ( foundairport >0 ) { if ( (int)WayPointList[i].AltArivalAGL <= arrivalcutoff ) { excluded=true; } } } } } else // do not display airport arrival if close to the best so far. // ex: best arrival is 1200m, include onlye below 1200/4 (prevent division by zero) // This way we only display far points, and skip closer points // WE NEED MORE INFO ABOUT LANDING POINTS: THE .CUP FORMAT WILL LET US KNOW WHAT IS // BEST TO SHOW AND WHAT IS NOT. Winpilot format is useless here. { dowrite=true;// TEST FIX not necessary probably // it's an airport if ( (bestwp>=0) && (i != (unsigned)bestwp) && (arrivalcutoff>600) ) { if ( (arrivalcutoff / ((int)WayPointList[i].AltArivalAGL+1))<4 ) { excluded=true; } } } } } else // landable waypoint is unreachable { dowrite=true; if ( isairport ) { SelectObject(hDCTemp,hBmpAirportUnReachable); } else { SelectObject(hDCTemp,hBmpFieldUnReachable); } } } else { // waypoint is an ordinary turnpoint if(MapWindow::zoom.RealScale() > 4) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); } } // end landable-not landable NiklausWirth: if (intask || (OutlinedTp==(OutlinedTp_t)otAll) ) { TextDisplayMode.WhiteBold = 1; TextDisplayMode.Color=RGB_WHITE; } // No matter of how we thought to draw it, let it up to the user.. switch(NewMapDeclutter) { case 0: excluded=false; // no decluttering: show all airports and outlandings break; case 1: if ( isairport ) excluded=false; // show all airports, declutter outlandings break; default: break; // else work normally } // here come both turnpoints and landables.. if( intask || irange || dowrite) { // irange always set when MapScale <=10 bool draw_alt = TextDisplayMode.Reachable && ((GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask); // 100711 reachable landing point! if (excluded==true) draw_alt=false; // exclude close outlandings switch(pDisplayTextType) { case DISPLAYNAME: case DISPLAYFIRSTTHREE: case DISPLAYFIRSTFIVE: case DISPLAYFIRST8: case DISPLAYFIRST10: case DISPLAYFIRST12: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; // 100711 if ( (islandable && !isairport) && MapWindow::zoom.RealScale() >=10 ) dowrite=0; // FIX then no need to go further // 101215 if (DisplayTextType == DISPLAYNAME) { _tcscpy(Buffer2,WayPointList[i].Name); } else { LK_tcsncpy(Buffer2, WayPointList[i].Name, resizer[DisplayTextType]); } // ConvToUpper(Buffer2); if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%s:%d"), Buffer2, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%s:%d%s"), Buffer2, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%s:%d"), Buffer2, (int)WayPointCalc[i].GR); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { //wsprintf(Buffer, TEXT("%s"),Buffer2); _tcscpy(Buffer,Buffer2); if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } break; case DISPLAYNUMBER: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; if ( (islandable && !isairport) && MapWindow::zoom.RealScale() >=10 ) dowrite=0; // FIX then no need to go further if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%d:%d"), WayPointList[i].Number, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%d:%d%s"), WayPointList[i].Number, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%d:%d"), WayPointList[i].Number, (int)(WayPointCalc[i].GR)); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT("%d"),WayPointList[i].Number); if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } break; case DISPLAYNAMEIFINTASK: dowrite = intask; if (intask) { if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%s:%d"), WayPointList[i].Name, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%s:%d%s"), WayPointList[i].Name, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%s:%d"), WayPointList[i].Name, (int)(WayPointCalc[i].GR)); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT("%s"),WayPointList[i].Name); // TODO CHECK THIS, UNTESTED.. if (islandable && isairport) { TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } } } else { wsprintf(Buffer, TEXT(" ")); dowrite=true; } break; case DISPLAYNONE: dowrite = (GetMultimap_Labels()<MAPLABELS_ONLYTOPO) || intask || islandable; if (draw_alt) { if ( ArrivalValue == (ArrivalValue_t) avAltitude ) { if ( (MapBox == (MapBox_t)mbUnboxedNoUnit) || (MapBox == (MapBox_t)mbBoxedNoUnit) ) wsprintf(Buffer, TEXT("%d"), (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY)); else wsprintf(Buffer, TEXT("%d%s"), (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), sAltUnit); } else wsprintf(Buffer, TEXT("%d"), (int)(WayPointCalc[i].GR) ); if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; TextDisplayMode.WhiteBold = 0; } else TextDisplayMode.WhiteBold = 1; // outlined TextDisplayMode.Color=RGB_WHITE; } else { wsprintf(Buffer, TEXT(" ")); } break; default: #if (WINDOWSPC<1) //ASSERT(0); #endif break; } // end intask/irange/dowrite if (MapWindow::zoom.RealScale()<20 && islandable && dowrite) { TextInBox(hdc, &rc, Buffer, WayPointList[i].Screen.x+5, WayPointList[i].Screen.y, 0, &TextDisplayMode, true); dowrite=false; // do not pass it along } // Do not show takeoff for gliders, check TakeOffWayPoint if (i==RESWP_TAKEOFF) { if (TakeOffWayPoint) { intask=false; // 091031 let TAKEOFF be decluttered WayPointList[i].Visible=TRUE; } else { WayPointList[i].Visible=FALSE; dowrite=false; } } if(i==RESWP_OPTIMIZED) { dowrite = DoOptimizeRoute(); } if (dowrite) { MapWaypointLabelAdd( Buffer, WayPointList[i].Screen.x+5, WayPointList[i].Screen.y, &TextDisplayMode, (int)(WayPointList[i].AltArivalAGL*ALTITUDEMODIFY), intask,islandable,isairport,excluded,i,WayPointList[i].Style); } } // end if intask { ; } } // if visible } // for all waypoints qsort(&MapWaypointLabelList, MapWaypointLabelListCount, sizeof(MapWaypointLabel_t), MapWaypointLabelListCompare); int j; // now draw task/landable waypoints in order of range (closest last) // writing unconditionally for (j=MapWaypointLabelListCount-1; j>=0; j--){ MapWaypointLabel_t *E = &MapWaypointLabelList[j]; // draws if they are in task unconditionally, // otherwise, does comparison if ( E->inTask || (E->isLandable && !E->isExcluded) ) { TextInBox(hdc, &rc, E->Name, E->Pos.x, E->Pos.y, 0, &(E->Mode), false); // At low zoom, dont print the bitmap because drawn task would make it look offsetted if(MapWindow::zoom.RealScale() > 2) continue; // If we are at low zoom, use a dot for icons, so we dont clutter the screen if(MapWindow::zoom.RealScale() > 1) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); } DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } // wp in task } // for all waypoint, searching for those in task // now draw normal waypoints in order of range (furthest away last) // without writing over each other (or the task ones) for (j=0; j<MapWaypointLabelListCount; j++) { MapWaypointLabel_t *E = &MapWaypointLabelList[j]; if (!E->inTask && !E->isLandable ) { if ( TextInBox(hdc, &rc, E->Name, E->Pos.x, E->Pos.y, 0, &(E->Mode), true) == true) { // If we are at low zoom, use a dot for icons, so we dont clutter the screen if(MapWindow::zoom.RealScale() > 4) { if (BlackScreen) SelectObject(hDCTemp,hInvSmall); else SelectObject(hDCTemp,hSmall); } else { // We switch all styles in the correct order, to force a jump table by the compiler // It would be much better to use an array of bitmaps, but no time to do it for 3.0 switch(E->style) { case STYLE_NORMAL: goto turnpoint; break; // These are not used here in fact case STYLE_AIRFIELDGRASS: case STYLE_OUTLANDING: case STYLE_GLIDERSITE: case STYLE_AIRFIELDSOLID: goto turnpoint; break; case STYLE_MTPASS: SelectObject(hDCTemp,hMountpass); break; case STYLE_MTTOP: SelectObject(hDCTemp,hMountop); break; case STYLE_SENDER: SelectObject(hDCTemp,hSender); break; case STYLE_VOR: goto turnpoint; break; case STYLE_NDB: SelectObject(hDCTemp,hNdb); break; case STYLE_COOLTOWER: goto turnpoint; break; case STYLE_DAM: SelectObject(hDCTemp,hDam); break; case STYLE_TUNNEL: goto turnpoint; break; case STYLE_BRIDGE: SelectObject(hDCTemp,hBridge); break; case STYLE_POWERPLANT: case STYLE_CASTLE: goto turnpoint; break; case STYLE_INTERSECTION: SelectObject(hDCTemp,hIntersect); break; case STYLE_TRAFFIC: goto turnpoint; break; case STYLE_THERMAL: SelectObject(hDCTemp,hLKThermal); break; case STYLE_MARKER: SelectObject(hDCTemp,hBmpMarker); break; default: turnpoint: if (BlackScreen) SelectObject(hDCTemp,hInvTurnPoint); else SelectObject(hDCTemp,hTurnPoint); break; } // switch estyle } // below zoom threshold // We dont do stretching here. We are using different bitmaps for hi res. // The 20x20 size is large enough to make much bigger icons than the old ones. DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,0,0,SRCPAINT,false); DrawBitmapX(hdc, E->Pos.x-10, E->Pos.y-10, 20,20, hDCTemp,20,0,SRCAND,false); } } } } // end DrawWaypoint
// // Run every 5 seconds, approx. // This is the hearth of LK. Questions? Ask Paolo.. // THIS IS RUNNING WITH LockComm from ConnectionProcessTimer . // void NMEAParser::UpdateMonitor(void) { short active=0; // active port number for gps static short lastactive=0; static bool lastvalidBaro=false; static bool wasSilent[2]={false,false}; short invalidGps=0; short invalidBaro=0; short validBaro=0; // does anyone have GPS? if (nmeaParser1.gpsValid || nmeaParser2.gpsValid) { if (nmeaParser1.gpsValid && nmeaParser2.gpsValid) { // both valid, just use first nmeaParser2.activeGPS = false; nmeaParser1.activeGPS = true; active=1; } else { // only one valid, pick it up nmeaParser1.activeGPS = nmeaParser1.gpsValid; nmeaParser2.activeGPS = nmeaParser2.gpsValid; active= nmeaParser1.activeGPS ? 1 : 2; } } else { // No valid fix on any port. We use the first port with at least some data going through! // This will keep probably at least the time updated since the gps may still be receiving a // valid time, good for us. if ( (LKHearthBeats-ComPortHB[0])<10 ) { // It is not granted that devA is really a GPS source. // Very unlikely, but possible.. if (devIsGPSSource(devA())) active=1; } else { if ( (LKHearthBeats-ComPortHB[1])<10 ) { // portB is really active, although there is no valid fix on it. // Before electing it to gps, lets be sure it really has one! // LKEXT1 and other instruments do not provide GPS source in fact. if (devIsGPSSource(devB())) active=2; } else { // nothing coming in from any port, recently. if (devIsGPSSource(devA())) active=1; // lets keep waiting for the first port } } switch(active) { case 0: nmeaParser1.activeGPS = false; nmeaParser2.activeGPS = false; break; case 1: nmeaParser1.activeGPS = true; nmeaParser2.activeGPS = false; break; case 2: nmeaParser1.activeGPS = false; nmeaParser2.activeGPS = true; break; default: nmeaParser1.activeGPS = false; nmeaParser2.activeGPS = false; LKASSERT(0); break; } } if (nmeaParser2.activeGPS==true && active==1) { StartupStore(_T(".... GPS Update error: port 1 and 2 are active! %s%s"),WhatTimeIsIt(),NEWLINE); nmeaParser2.activeGPS=false; // force it off active=1; } // wait for some seconds before monitoring, after startup if (LKHearthBeats<20) return; /* check if Flarm disappeared after 30 seconds no activity */ if (GPS_INFO.FLARM_Available && ((GPS_INFO.Time -LastFlarmCommandTime)> 30) ) { static unsigned short MessageCnt =0; if(MessageCnt <10) { MessageCnt++; StartupStore(_T(". FLARM lost! Disable FLARM functions !%s"),NEWLINE); DoStatusMessage(gettext(TEXT("_@M947_"))); // _@M947_ "FLARM SIGNAL LOST" } GPS_INFO.FLARM_Available = false; GPS_INFO.FLARM_HW_Version =0.0; GPS_INFO.FLARM_SW_Version =0.0; } // Check Port 1 with no serial activity in last seconds if ( (LKHearthBeats-ComPortHB[0])>10 ) { #ifdef DEBUGNPM StartupStore(_T("... GPS Port 1 : no activity LKHB=%u CBHB=%u %s"),LKHearthBeats, ComPortHB[0],NEWLINE); #endif // if this is active and supposed to have a valid fix.., but no HB.. if ( (active==1) && (nmeaParser1.gpsValid) ) { StartupStore(_T("... GPS Port 1 no hearthbeats, but still gpsValid: forced invalid %s%s"),WhatTimeIsIt(),NEWLINE); } nmeaParser1.gpsValid=false; invalidGps=1; // We want to be sure that if this device is silent, and it was providing Baro altitude, // now it is set to off. if (GPS_INFO.BaroAltitudeAvailable==TRUE) { if ( devA() == pDevPrimaryBaroSource || nmeaParser1.RMZAvailable || nmeaParser1.TASAvailable ) { invalidBaro=1; } } nmeaParser1._Reset(); nmeaParser1.activeGPS=false; // because Reset is setting it to true // We reset some flags globally only once in case of device gone silent if (!devIsDisabled(0) && !wasSilent[0]) { GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; GPS_INFO.AccelerationAvailable = false; EnableExternalTriggerCruise = false; wasSilent[0]=true; } } else { wasSilent[0]=false; // We have hearth beats, is baro available? if ( devIsBaroSource(devA()) || nmeaParser1.RMZAvailable || nmeaParser1.TASAvailable ) // 100411 validBaro++; } // now check also port 2 if ( (LKHearthBeats-ComPortHB[1])>10 ) { #ifdef DEBUGNPM StartupStore(_T("... GPS Port 2 : no activity LKHB=%u CBHB=%u %s"),LKHearthBeats, ComPortHB[1],NEWLINE); #endif if ( (active==2) && (nmeaParser2.gpsValid) ) { StartupStore(_T("... GPS port 2 no hearthbeats, but still gpsValid: forced invalid %s%s"),WhatTimeIsIt(),NEWLINE); } nmeaParser2.gpsValid=false; invalidGps++; if (GPS_INFO.BaroAltitudeAvailable==TRUE) { if ( devB() == pDevPrimaryBaroSource || nmeaParser2.RMZAvailable || nmeaParser2.TASAvailable ) { invalidBaro++; } } nmeaParser2._Reset(); nmeaParser2.activeGPS=false; // because Reset is setting it to true if (!devIsDisabled(1) && !wasSilent[1]) { GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; GPS_INFO.AccelerationAvailable = false; EnableExternalTriggerCruise = false; wasSilent[1]=true; } } else { wasSilent[1]=false; // We have hearth beats, is baro available? if ( devIsBaroSource(devB()) || nmeaParser2.RMZAvailable || nmeaParser2.TASAvailable ) // 100411 validBaro++; } #ifdef DEBUGNPM if (invalidGps==2) { StartupStore(_T("... GPS no gpsValid available on port 1 and 2, active=%d @%s%s"),active,WhatTimeIsIt(),NEWLINE); } if (invalidBaro>0) { StartupStore(_T("... Baro altitude just lost, current status=%d @%s%s"),GPS_INFO.BaroAltitudeAvailable,WhatTimeIsIt(),NEWLINE); } #endif // do we really still have a baro altitude available? // If some baro source disappeared, let's reset it for safety. Parser will re-enable them immediately if available. // Assuming here that if no Baro is available, no airdata is available also // if (validBaro==0) { if ( GPS_INFO.BaroAltitudeAvailable ) { StartupStore(_T("... GPS no active baro source, and still BaroAltitudeAvailable, forced off %s%s"),WhatTimeIsIt(),NEWLINE); if (EnableNavBaroAltitude && active) { // LKTOKEN _@M122_ = "BARO ALTITUDE NOT AVAILABLE, USING GPS ALTITUDE" DoStatusMessage(MsgToken(122)); PortMonitorMessages++; } else { // LKTOKEN _@M121_ = "BARO ALTITUDE NOT AVAILABLE" DoStatusMessage(MsgToken(121)); } GPS_INFO.BaroAltitudeAvailable=FALSE; // We alse reset these values, just in case we are through a mux GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; GPS_INFO.AccelerationAvailable = false; EnableExternalTriggerCruise = false; nmeaParser1._Reset(); nmeaParser2._Reset(); // 120824 Check this situation better> Reset is setting activeGPS true for both devices! lastvalidBaro=false; } } else { if ( lastvalidBaro==false) { #if DEBUGBARO TCHAR devname[50]; if (pDevPrimaryBaroSource) { LK_tcsncpy(devname,pDevPrimaryBaroSource->Name,49); } else { _tcscpy(devname,_T("unknown")); } StartupStore(_T("... GPS baro source back available from <%s>%s"),devname,NEWLINE); #endif if (GotFirstBaroAltitude) { if (EnableNavBaroAltitude) { DoStatusMessage(MsgToken(1796)); // USING BARO ALTITUDE } else { DoStatusMessage(MsgToken(1795)); // BARO ALTITUDE IS AVAILABLE } StartupStore(_T("... GPS baro source back available %s%s"),WhatTimeIsIt(),NEWLINE); lastvalidBaro=true; } else { static bool said=false; if (!said) { StartupStore(_T("... GPS BARO SOURCE PROBLEM, umnanaged port activity. Wrong device? %s%s"),WhatTimeIsIt(),NEWLINE); said=true; } } } else { // last baro was Ok, currently we still have a validbaro, but no HBs... // Probably it is a special case when no gps fix was found on the secondary baro source. if (invalidBaro||!GotFirstBaroAltitude) { GPS_INFO.BaroAltitudeAvailable=FALSE; #ifdef DEBUGNPM StartupStore(_T(".... We still have valid baro, resetting BaroAltitude OFF %s\n"),WhatTimeIsIt()); #endif } } } // Very important check for multiplexers: if RMZ did not get through in the past seconds, we want to // be very sure that there still is one incoming, otherwise we shall be UpdatingBaroSource using the old one, // never really updated!! This is because GGA and RMC are using RMZAvailable to UpdateBaroSource, no matter if // there was a real RMZ in the NMEA stream lately. // Normally RMZAvailable, RMCAvailable, GGA etc.etc. are reset to false when the com port is silent. // But RMZ is special, because it can be sent through the multiplexer from a flarm box. if ( (nmeaParser1.RMZAvailable || nmeaParser2.RMZAvailable) && (LKHearthBeats > (LastRMZHB+5))) { #if DEBUGBARO StartupStore(_T(".... RMZ not updated recently, resetting HB\n")); #endif nmeaParser1.RMZAvailable = FALSE; nmeaParser2.RMZAvailable = FALSE; } // Check baro altitude problems. This can happen for several reasons: mixed input on baro on same port, // faulty device, etc. The important thing is that we shall not be using baro altitude for navigation in such cases. // So we do this check only for the case we are actually using baro altitude. // A typical case is: mixed devices on same port, baro altitude disappearing because of mechanical switch, // but other traffic still incoming, so hearthbeats are ok. static double lastBaroAltitude=-1, lastGPSAltitude=-1; static unsigned int counterSameBaro=0, counterSameHGPS=0; static unsigned short firstrecovery=0; if (GPS_INFO.BaroAltitudeAvailable && EnableNavBaroAltitude && !GPS_INFO.NAVWarning) { if (GPS_INFO.BaroAltitude==lastBaroAltitude) { counterSameBaro++; } else { lastBaroAltitude=GPS_INFO.BaroAltitude; counterSameBaro=0; } if (GPS_INFO.Altitude==lastGPSAltitude) { counterSameHGPS++; } else { lastGPSAltitude=GPS_INFO.Altitude; counterSameHGPS=0; } // This is suspicious enough, because the baro altitude is a floating value, should not be the same.. // but ok, lets assume it is filtered. // if HBAR is steady for some time ... and HGPS is not steady unsigned short timethreshold=15; // first three times, timeout at about 1 minute if (firstrecovery>=3) timethreshold=40; // then about every 3 minutes if ( ((counterSameBaro > timethreshold) && (counterSameHGPS<2)) && (fabs(GPS_INFO.Altitude-GPS_INFO.BaroAltitude)>100.0) && !CALCULATED_INFO.OnGround ) { DoStatusMessage(MsgToken(122)); // Baro not available, Using GPS ALTITUDE EnableNavBaroAltitude=false; StartupStore(_T("... WARNING, NavBaroAltitude DISABLED due to possible fault: baro steady at %f, HGPS=%f @%s%s"), GPS_INFO.BaroAltitude, GPS_INFO.Altitude,WhatTimeIsIt(),NEWLINE); lastBaroAltitude=-1; lastGPSAltitude=-1; counterSameBaro=0; counterSameHGPS=0; // We do only ONE attempt to recover a faulty device, to avoid flipflopping. // In case of big problems, we shall have disabled the use of the faulty baro altitude, and keep it // incoming sporadically. if (firstrecovery<3) { GPS_INFO.BaroAltitudeAvailable=FALSE; // We alse reset these values, just in case we are through a mux GPS_INFO.AirspeedAvailable=false; GPS_INFO.VarioAvailable=false; GPS_INFO.NettoVarioAvailable=false; GPS_INFO.AccelerationAvailable = false; EnableExternalTriggerCruise = false; nmeaParser1._Reset(); nmeaParser2._Reset(); // 120824 Check this situation better> Reset is setting activeGPS true for both devices! lastvalidBaro=false; GotFirstBaroAltitude=false; firstrecovery++; } } } // Set some fine tuning parameters here, depending on device/situation/mode if (ISCAR) trackbearingminspeed=0; // trekking mode/car mode, min speed >0 else trackbearingminspeed=1; // flymode, min speed >1 knot // // Following is for diagnostics only // // Nothing has changed? No need to give new alerts. We might have no active gps at all, also. // In this case, active and lastactive are 0, nothing we can do about it. if (active == lastactive) return; if (active!=0) StartupStore(_T(". GPS NMEA source changed to port %d %s%s"),active,WhatTimeIsIt(),NEWLINE); else StartupStore(_T("... GPS NMEA source PROBLEM, no active GPS! %s%s"),WhatTimeIsIt(),NEWLINE); if (PortMonitorMessages<15) { // do not overload pilot with messages! // do not say anything if we never got the first port, on startup essentially if ((lastactive!=0) && (nmeaParser1.gpsValid || nmeaParser2.gpsValid)){ TCHAR vbuf[100]; _stprintf(vbuf,_T("%s %d"), MsgToken(277),active); // FALLBACK USING GPS ON PORT .. DoStatusMessage(vbuf); PortMonitorMessages++; } } else { if (PortMonitorMessages==15) { StartupStore(_T("... GOING SILENT on too many Com reportings. %s%s"),WhatTimeIsIt(),NEWLINE); DoStatusMessage(MsgToken(317)); // GOING SILENT ON COM REPORTING PortMonitorMessages++; // we go to 16, and never be back here } } lastactive=active; }
void MapWindow::DrawTraffic(HDC hdc, RECT rc) { SIZE WPTextSize, DSTextSize, BETextSize, RETextSize, AATextSize, HLTextSize, MITextSize; TCHAR Buffer[LKSIZEBUFFERLARGE]; static RECT s_sortBox[6]; static TCHAR Buffer1[MAXTRAFFIC][MAXTRAFFICNUMPAGES][24], Buffer2[MAXTRAFFIC][MAXTRAFFICNUMPAGES][10]; static TCHAR Buffer3[MAXTRAFFIC][MAXTRAFFICNUMPAGES][10]; static TCHAR Buffer4[MAXTRAFFIC][MAXTRAFFICNUMPAGES][12], Buffer5[MAXTRAFFIC][MAXTRAFFICNUMPAGES][12]; static short s_maxnlname; char text[30]; short i, k, iRaw, wlen, rli=0, curpage, drawn_items_onpage; double value; COLORREF rcolor; // column0 starts after writing 1:2 (ModeIndex:CURTYPE+1) with a different font.. static short Column0; static short Column1, Column2, Column3, Column4, Column5; static POINT p1, p2; static short s_rawspace; // Printable area for live nearest values static short left,right,bottom; // one for each mapspace, no matter if 0 and 1 are unused short curmapspace=MapSpaceMode; static int TrafficNumraws=0; //static int TrafficNumpages=0; global.. // Vertical and horizontal spaces #define INTERRAW 1 #define HEADRAW NIBLSCALE(6) HBRUSH sortbrush; RECT invsel; if (INVERTCOLORS) { sortbrush=LKBrush_LightGreen; } else { sortbrush=LKBrush_DarkGreen; } if (DoInit[MDI_DRAWTRAFFIC]) { if ( ScreenSize < (ScreenSize_t)sslandscape ) { left=rc.left+NIBLSCALE(1); right=rc.right-NIBLSCALE(1); bottom=rc.bottom-BottomSize-NIBLSCALE(2); s_maxnlname=MAXNLNAME-5; // 7 chars max, 8 sized _stprintf(Buffer,TEXT("MAKSJSMM")); } else { left=rc.left+NIBLSCALE(5); right=rc.right-NIBLSCALE(5); bottom=rc.bottom-BottomSize; s_maxnlname=MAXNLNAME-3; // 9 chars, sized 10 _stprintf(Buffer,TEXT("ABCDEFGHMx")); } SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest was LK8Title GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &WPTextSize); _stprintf(Buffer,TEXT("000.0")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &DSTextSize); _stprintf(Buffer,TEXT("<<123")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &BETextSize); _stprintf(Buffer,TEXT("5299")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &RETextSize); _stprintf(Buffer,TEXT("+9999")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &AATextSize); SelectObject(hdc, LK8InfoNormalFont); // Heading line was MapWindow QUI _stprintf(Buffer,TEXT("MMMM")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &HLTextSize); SelectObject(hdc, LK8PanelMediumFont); _stprintf(Buffer,TEXT("1.1")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &MITextSize); short afterwpname=left+WPTextSize.cx+NIBLSCALE(5); short intercolumn=(right-afterwpname- DSTextSize.cx-BETextSize.cx-RETextSize.cx-AATextSize.cx)/3; Column0=MITextSize.cx+LEFTLIMITER+NIBLSCALE(5); Column1=left; // WP align left Column2=afterwpname+DSTextSize.cx; // DS align right Column3=Column2+intercolumn+BETextSize.cx; // BE align right Column4=Column3+intercolumn+RETextSize.cx; // RE align right Column5=Column4+intercolumn+AATextSize.cx; // AA align right if ( ScreenSize < (ScreenSize_t)sslandscape ) { TopSize=rc.top+HEADRAW*2+HLTextSize.cy; p1.x=0; p1.y=TopSize; p2.x=rc.right; p2.y=p1.y; TopSize+=HEADRAW; TrafficNumraws=(bottom - TopSize) / (WPTextSize.cy+(INTERRAW*2)); if (TrafficNumraws>MAXTRAFFIC) TrafficNumraws=MAXTRAFFIC; s_rawspace=(WPTextSize.cy+INTERRAW); } else { TopSize=rc.top+HEADRAW*2+HLTextSize.cy; p1.x=0; p1.y=TopSize; p2.x=rc.right; p2.y=p1.y; TopSize+=HEADRAW/2; TrafficNumraws=(bottom - TopSize) / (WPTextSize.cy+INTERRAW); if (TrafficNumraws>MAXTRAFFIC) TrafficNumraws=MAXTRAFFIC; s_rawspace=(WPTextSize.cy+INTERRAW); } #define INTERBOX intercolumn/2 // Traffic name s_sortBox[0].left=Column0; // FIX 090925 era solo 0 if ( ScreenSize < (ScreenSize_t)sslandscape ) s_sortBox[0].right=left+WPTextSize.cx-NIBLSCALE(2); else s_sortBox[0].right=left+WPTextSize.cx-NIBLSCALE(10); s_sortBox[0].top=2; s_sortBox[0].bottom=p1.y; SortBoxX[MSM_TRAFFIC][0]=s_sortBox[0].right; // Distance if ( ScreenSize < (ScreenSize_t)sslandscape ) s_sortBox[1].left=Column1+afterwpname-INTERBOX; else s_sortBox[1].left=Column1+afterwpname-INTERBOX-NIBLSCALE(2); s_sortBox[1].right=Column2+INTERBOX; s_sortBox[1].top=2; s_sortBox[1].bottom=p1.y; SortBoxX[MSM_TRAFFIC][1]=s_sortBox[1].right; // Bearing s_sortBox[2].left=Column2+INTERBOX; s_sortBox[2].right=Column3+INTERBOX; s_sortBox[2].top=2; s_sortBox[2].bottom=p1.y; SortBoxX[MSM_TRAFFIC][2]=s_sortBox[2].right; // Vario s_sortBox[3].left=Column3+INTERBOX; s_sortBox[3].right=Column4+INTERBOX; s_sortBox[3].top=2; s_sortBox[3].bottom=p1.y; SortBoxX[MSM_TRAFFIC][3]=s_sortBox[3].right; // Altitude s_sortBox[4].left=Column4+INTERBOX; //s_sortBox[4].right=Column5+INTERBOX; s_sortBox[4].right=rc.right-1; s_sortBox[4].top=2; s_sortBox[4].bottom=p1.y; SortBoxX[MSM_TRAFFIC][4]=s_sortBox[4].right; SortBoxY[MSM_TRAFFIC]=p1.y; TrafficNumpages=roundupdivision(MAXTRAFFIC, TrafficNumraws); if (TrafficNumpages>MAXTRAFFICNUMPAGES) TrafficNumpages=MAXTRAFFICNUMPAGES; else if (TrafficNumpages<1) TrafficNumpages=1; SelectedRaw[MSM_TRAFFIC]=0; SelectedPage[MSM_TRAFFIC]=0; DoInit[MDI_DRAWTRAFFIC]=false; return; } // doinit DoTraffic(&DrawInfo, &DerivedDrawInfo); TrafficNumpages=roundupdivision(LKNumTraffic, TrafficNumraws); if (TrafficNumpages>MAXTRAFFICNUMPAGES) TrafficNumpages=MAXTRAFFICNUMPAGES; else if (TrafficNumpages<1) TrafficNumpages=1; curpage=SelectedPage[curmapspace]; if (curpage<0||curpage>=MAXTRAFFICNUMPAGES) { // DoStatusMessage(_T("ERR-041 traffic curpage invalid!")); // selection while waiting for data ready SelectedPage[curmapspace]=0; LKevent=LKEVENT_NONE; return; } switch (LKevent) { case LKEVENT_NONE: break; case LKEVENT_ENTER: LKevent=LKEVENT_NONE; i=LKSortedTraffic[SelectedRaw[curmapspace]+(curpage*TrafficNumraws)]; if ( (i<0) || (i>=MAXTRAFFIC) || (LKTraffic[i].ID<=0) ) { #if 0 // selection while waiting for data ready if (LKNumTraffic>0) DoStatusMessage(_T("ERR-045 Invalid selection")); #endif break; } LKevent=LKEVENT_NONE; // Do not update Traffic while in details mode, max 10m LastDoTraffic=DrawInfo.Time+600; dlgLKTrafficDetails(i); LastDoTraffic=0; break; case LKEVENT_DOWN: if (++SelectedRaw[curmapspace] >=TrafficNumraws) SelectedRaw[curmapspace]=0; // Reset LastDoTraffic so that it wont be updated while selecting an item LastDoTraffic=DrawInfo.Time+PAGINGTIMEOUT-1.0; break; case LKEVENT_UP: if (--SelectedRaw[curmapspace] <0) SelectedRaw[curmapspace]=TrafficNumraws-1; LastDoTraffic=DrawInfo.Time+PAGINGTIMEOUT-1.0; break; case LKEVENT_PAGEUP: LKevent=LKEVENT_NONE; break; case LKEVENT_PAGEDOWN: LKevent=LKEVENT_NONE; break; case LKEVENT_NEWRUN: for (i=0; i<MAXTRAFFIC; i++) { for (k=0; k<MAXTRAFFICNUMPAGES; k++) { _stprintf(Buffer1[i][k],_T("------------")); // 12 chars _stprintf(Buffer2[i][k],_T("----")); _stprintf(Buffer3[i][k],_T("----")); _stprintf(Buffer4[i][k],_T("----")); _stprintf(Buffer5[i][k],_T("----")); } } break; case LKEVENT_NEWPAGE: break; default: LKevent=LKEVENT_NONE; break; } if (INVERTCOLORS) _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p1, p2, RGB_GREEN, rc); else _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p1, p2, RGB_DARKGREEN, rc); SelectObject(hdc, LK8InfoNormalFont); // Heading line short cursortbox=SortedMode[curmapspace]; if ( ScreenSize < (ScreenSize_t)sslandscape ) { // portrait mode FillRect(hdc,&s_sortBox[cursortbox], sortbrush); _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); // LKTOKEN _@M1331_ "TRF" _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1331_")), curpage+1,TrafficNumpages); if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1300_ "Dist" _stprintf(Buffer, gettext(TEXT("_@M1300_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0, WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0, WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1301_ "Dir" _stprintf(Buffer, gettext(TEXT("_@M1301_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1332_ "Var" _stprintf(Buffer, gettext(TEXT("_@M1332_"))); if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1334_ "Alt" _stprintf(Buffer, gettext(TEXT("_@M1334_"))); if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } else { FillRect(hdc,&s_sortBox[cursortbox], sortbrush); if ( (ScreenSize == (ScreenSize_t)ss640x480) || (ScreenSize == (ScreenSize_t)ss320x240)|| ScreenSize==ss896x672 ) { _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); // LKTOKEN _@M1331_ "TRF" _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1331_")), curpage+1,TrafficNumpages); if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1300_ "Dist" _stprintf(Buffer, gettext(TEXT("_@M1300_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1301_ "Dir" _stprintf(Buffer, gettext(TEXT("_@M1301_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1332_ "Var" _stprintf(Buffer, gettext(TEXT("_@M1332_"))); if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1334_ "Alt" _stprintf(Buffer, gettext(TEXT("_@M1334_"))); if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } else { _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); // LKTOKEN _@M1331_ "TRF" _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1331_")), curpage+1,TrafficNumpages); if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1304_ "Distance" _stprintf(Buffer, gettext(TEXT("_@M1304_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1305_ "Direction" _stprintf(Buffer, gettext(TEXT("_@M1305_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1333_ "Vario" _stprintf(Buffer, gettext(TEXT("_@M1333_"))); if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1334_ "Alt" _stprintf(Buffer, gettext(TEXT("_@M1334_"))); if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } } // landscape mode SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest #ifdef DEBUG_LKT_DRAWTRAFFIC TCHAR v2buf[100]; wsprintf(v2buf,_T("MAXTRAFFIC=%d LKNumTraff=%d / TrafficNumraws=%d TrafficNumpages=%d calc=%d\n"),MAXTRAFFIC, LKNumTraffic,TrafficNumraws, TrafficNumpages, (short)(ceil(MAXTRAFFIC/TrafficNumraws))); StartupStore(v2buf); #endif for (i=0, drawn_items_onpage=0; i<TrafficNumraws; i++) { iRaw=TopSize+(s_rawspace*i); short curraw=(curpage*TrafficNumraws)+i; if (curraw>=MAXTRAFFIC) break; rli=LKSortedTraffic[curraw]; #ifdef DEBUG_LKT_DRAWTRAFFIC StartupStore(_T("..LKDrawTraff page=%d curraw=%d rli=%d \n"), curpage,curraw,rli); #endif if ( (rli>=0) && (LKTraffic[rli].ID>0) ) { // Traffic name wlen=wcslen(LKTraffic[rli].Name); // if name is unknown then it is a '?' if (wlen==1) { _stprintf(Buffer,_T("%06x"),LKTraffic[rli].ID); Buffer[s_maxnlname]='\0'; } else { // if XY I-ABCD doesnt fit.. if ( (wlen+3)>s_maxnlname) { LK_tcsncpy(Buffer, LKTraffic[rli].Name, s_maxnlname); } else { unsigned short cnlen=_tcslen(LKTraffic[rli].Cn); // if cn is XY create XY I-ABCD if (cnlen==1 || cnlen==2) { _tcscpy(Buffer,LKTraffic[rli].Cn); _tcscat(Buffer,_T(" ")); _tcscat(Buffer,LKTraffic[rli].Name); // for safety Buffer[s_maxnlname]='\0'; } else { // else use only long name LK_tcsncpy(Buffer, LKTraffic[rli].Name, wlen); } } ConvToUpper(Buffer); } if (LKTraffic[rli].Locked) { TCHAR buf2[LKSIZEBUFFERLARGE]; _stprintf(buf2,_T("*%s"),Buffer); buf2[s_maxnlname]='\0'; _tcscpy(Buffer,buf2); } #ifdef DEBUG_LKT_DRAWTRAFFIC StartupStore(_T(".. Traffic[%d] Name=<%s> Id=<%0x> Status=%d Named:<%s>\n"),rli,LKTraffic[rli].Name, LKTraffic[rli].ID, LKTraffic[rli].Status,Buffer); #endif _tcscpy(Buffer1[i][curpage],Buffer); // Distance value=LKTraffic[rli].Distance*DISTANCEMODIFY; _stprintf(Buffer2[i][curpage],TEXT("%0.1lf"),value); // relative bearing if (!MapWindow::mode.Is(MapWindow::Mode::MODE_CIRCLING)) { value = LKTraffic[rli].Bearing - DrawInfo.TrackBearing; if (value < -180.0) value += 360.0; else if (value > 180.0) value -= 360.0; #ifndef __MINGW32__ if (value > 1) _stprintf(Buffer3[i][curpage], TEXT("%2.0f\xB0\xBB"), value); else if (value < -1) _stprintf(Buffer3[i][curpage], TEXT("\xAB%2.0f\xB0"), -value); else _tcscpy(Buffer3[i][curpage], TEXT("\xAB\xBB")); #else if (value > 1) _stprintf(Buffer3[i][curpage], TEXT("%2.0f°»"), value); else if (value < -1) _stprintf(Buffer3[i][curpage], TEXT("«%2.0f°"), -value); else _tcscpy(Buffer3[i][curpage], TEXT("«»")); #endif } else { _stprintf(Buffer3[i][curpage], _T("%2.0f°"), LKTraffic[rli].Bearing); } // Vario value=LIFTMODIFY*LKTraffic[rli].Average30s; if (value<-6 || value>6) _stprintf(Buffer4[i][curpage],_T("---")); else { sprintf(text,"%+.1f",value); _stprintf(Buffer4[i][curpage],_T("%S"),text); } // Altitude value=ALTITUDEMODIFY*LKTraffic[rli].Altitude; if (value<-1000 || value >45000 ) strcpy(text,"---"); else sprintf(text,"%.0f",value); wsprintf(Buffer5[i][curpage], TEXT("%S"),text); } else { // Empty traffic, fill in all empty data and maybe break loop _stprintf(Buffer1[i][curpage],_T("------------")); _stprintf(Buffer2[i][curpage],_T("---")); _stprintf(Buffer3[i][curpage],_T("---")); _stprintf(Buffer4[i][curpage],_T("---")); _stprintf(Buffer5[i][curpage],_T("---")); } if ((rli>=0) && (LKTraffic[rli].ID>0)) { drawn_items_onpage++; if (LKTraffic[rli].Status == LKT_REAL) { rcolor=RGB_WHITE; SelectObject(hdc, LK8InfoBigFont); } else { if (LKTraffic[rli].Status == LKT_GHOST) { rcolor=RGB_LIGHTYELLOW; } else { rcolor=RGB_LIGHTRED; } SelectObject(hdc, LK8InfoBigItalicFont); } } else rcolor=RGB_GREY; LKWriteText(hdc, Buffer1[i][curpage], Column1, iRaw , 0, WTMODE_NORMAL, WTALIGN_LEFT, rcolor, false); SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest LKWriteText(hdc, Buffer2[i][curpage], Column2, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer3[i][curpage], Column3, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer4[i][curpage], Column4, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer5[i][curpage], Column5, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); } // for if (LKevent==LKEVENT_NEWRUN || LKevent==LKEVENT_NEWPAGE ) { LKevent=LKEVENT_NONE; return; } if (drawn_items_onpage>0) { if (SelectedRaw[curmapspace] <0 || SelectedRaw[curmapspace]>(TrafficNumraws-1)) { LKevent=LKEVENT_NONE; // 100328 return; } if (SelectedRaw[curmapspace] >= drawn_items_onpage) { if (LKevent==LKEVENT_DOWN) SelectedRaw[curmapspace]=0; else if (LKevent==LKEVENT_UP) SelectedRaw[curmapspace]=drawn_items_onpage-1; else { SelectedRaw[curmapspace]=0; } } invsel.left=left; invsel.right=right; invsel.top=TopSize+(s_rawspace*SelectedRaw[curmapspace])+NIBLSCALE(2); invsel.bottom=TopSize+(s_rawspace*(SelectedRaw[curmapspace]+1))-NIBLSCALE(1); InvertRect(hdc,&invsel); } LKevent=LKEVENT_NONE; return; }
static void OnAirspacePaintListItem(WindowControl * Sender, HDC hDC){ TCHAR label[40]; (void)Sender; if (DrawListIndex < AIRSPACECLASSCOUNT){ int i = DrawListIndex; LK_tcsncpy(label, CAirspaceManager::Instance().GetAirspaceTypeText(i), 39); int w0, w1, w2, x0; if (ScreenLandscape) { w0 = 202*ScreenScale; } else { w0 = 225*ScreenScale; } // LKTOKEN _@M789_ = "Warn" w1 = GetTextWidth(hDC, gettext(TEXT("_@M789_")))+ScreenScale*10; // LKTOKEN _@M241_ = "Display" w2 = GetTextWidth(hDC, gettext(TEXT("_@M241_")))+ScreenScale*10; x0 = w0-w1-w2; ExtTextOutClip(hDC, 2*ScreenScale, 2*ScreenScale, label, x0-ScreenScale*10); if (colormode) { SelectObject(hDC, GetStockObject(WHITE_PEN)); SelectObject(hDC, GetStockObject(WHITE_BRUSH)); Rectangle(hDC, x0, 2*ScreenScale, w0, 22*ScreenScale); SetTextColor(hDC, MapWindow::GetAirspaceColourByClass(i)); SetBkColor(hDC, RGB(0xFF, 0xFF, 0xFF)); SelectObject(hDC, MapWindow::GetAirspaceBrushByClass(i)); Rectangle(hDC, x0, 2*ScreenScale, w0, 22*ScreenScale); } else { bool iswarn; bool isdisplay; iswarn = (MapWindow::iAirspaceMode[i]>=2); isdisplay = ((MapWindow::iAirspaceMode[i]%2)>0); if (iswarn) { // LKTOKEN _@M789_ = "Warn" _tcscpy(label, gettext(TEXT("_@M789_"))); ExtTextOut(hDC, w0-w1-w2, 2*ScreenScale, ETO_OPAQUE, NULL, label, _tcslen(label), NULL); } if (isdisplay) { // LKTOKEN _@M241_ = "Display" _tcscpy(label, gettext(TEXT("_@M241_"))); ExtTextOut(hDC, w0-w2, 2*ScreenScale, ETO_OPAQUE, NULL, label, _tcslen(label), NULL); } } } }
void propGetFontSettingsFromString(const TCHAR *Buffer1, LOGFONT* lplf) { #define propGetFontSettingsMAX_SIZE 128 TCHAR Buffer[propGetFontSettingsMAX_SIZE+1]; // RLD need a buffer (not sz) for strtok_r w/ gcc optimized ARM920 TCHAR *pWClast, *pToken; LOGFONT lfTmp; LK_tcsncpy(Buffer, Buffer1, propGetFontSettingsMAX_SIZE); // FontDescription of format: // typical font entry // 26,0,0,0,700,1,0,0,0,0,0,4,2,<fontname> //FW_THIN 100 //FW_NORMAL 400 //FW_MEDIUM 500 //FW_BOLD 700 //FW_HEAVY 900 LKASSERT(lplf != NULL); memset ((void *)&lfTmp, 0, sizeof (LOGFONT)); if ((pToken = _tcstok_r(Buffer, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfHeight = _tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfWidth = _tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfEscapement = _tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfOrientation = _tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfWeight = _tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfItalic = (unsigned char)_tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfUnderline = (unsigned char)_tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfStrikeOut = (unsigned char)_tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfCharSet = (unsigned char)_tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfOutPrecision = (unsigned char)_tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfClipPrecision = (unsigned char)_tcstol(pToken, NULL, 10); // FIXFONTS possible multiplier for FT_Set_Pixel in place of Set_Char_Size // double mulp=(8.7 / 10.0)*100; // lfTmp.lfHeight = (int)((lfTmp.lfHeight*mulp)/100.0); // DEFAULT_QUALITY 0 // RASTER_FONTTYPE 0x0001 // DRAFT_QUALITY 1 // NONANTIALIASED_QUALITY 3 // ANTIALIASED_QUALITY 4 // CLEARTYPE_QUALITY 5 // CLEARTYPE_COMPAT_QUALITY 6 if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; ApplyClearType(&lfTmp); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; lfTmp.lfPitchAndFamily = (unsigned char)_tcstol(pToken, NULL, 10); if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return; _tcscpy(lfTmp.lfFaceName, pToken); memcpy((void *)lplf, (void *)&lfTmp, sizeof (LOGFONT)); return; }
// This is converting DAT Winpilot int ParseDAT(TCHAR *String,WAYPOINT *Temp) { TCHAR ctemp[(COMMENT_SIZE*2)+1]; // 101102 BUGFIX, we let +1 for safety TCHAR *Number; TCHAR *pWClast = NULL; TCHAR *pToken; TCHAR TempString[READLINE_LENGTH]; _tcscpy(TempString, String); // 20060513:sgi added wor on a copy of the string, do not modify the // source string, needed on error messages Temp->Visible = true; // default all waypoints visible at start Temp->FarVisible = true; Temp->Format = LKW_DAT; Temp->FileNum = globalFileNum; // ExtractParameter(TempString,ctemp,0); if ((pToken = _tcstok_r(TempString, TEXT(","), &pWClast)) == NULL) return FALSE; Temp->Number = _tcstol(pToken, &Number, 10); //ExtractParameter(TempString,ctemp,1); //Latitude if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return FALSE; Temp->Latitude = CalculateAngle(pToken); if((Temp->Latitude > 90) || (Temp->Latitude < -90)) { return FALSE; } //ExtractParameter(TempString,ctemp,2); //Longitude if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return FALSE; Temp->Longitude = CalculateAngle(pToken); if((Temp->Longitude > 180) || (Temp->Longitude < -180)) { return FALSE; } //ExtractParameter(TempString,ctemp,3); //Altitude if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return FALSE; Temp->Altitude = ReadAltitude(pToken); if (Temp->Altitude == -9999){ return FALSE; } //ExtractParameter(TempString,ctemp,4); //Flags if ((pToken = _tcstok_r(NULL, TEXT(","), &pWClast)) == NULL) return FALSE; Temp->Flags = CheckFlags(pToken); //ExtractParameter(TempString,ctemp,5); // Name if ((pToken = _tcstok_r(NULL, TEXT(",\n\r"), &pWClast)) == NULL) return FALSE; // guard against overrun if (_tcslen(pToken)>NAME_SIZE) { pToken[NAME_SIZE-1]= _T('\0'); } _tcscpy(Temp->Name, pToken); int i; for (i=_tcslen(Temp->Name)-1; i>1; i--) { if (Temp->Name[i]==' ') { Temp->Name[i]=0; } else { break; } } //ExtractParameter(TempString,ctemp,6); // Comment // DAT Comment if ((pToken = _tcstok_r(NULL, TEXT("\n\r"), &pWClast)) != NULL){ LK_tcsncpy(ctemp, pToken, COMMENT_SIZE); //@ 101102 BUGFIX bad. ctemp was not sized correctly! if (_tcslen(ctemp) >0 ) { if (Temp->Comment) { free(Temp->Comment); } Temp->Comment = (TCHAR*)malloc((_tcslen(ctemp)+1)*sizeof(TCHAR)); if (Temp->Comment) _tcscpy(Temp->Comment, ctemp); } } else { Temp->Comment = NULL; // useless } if(Temp->Altitude <= 0) { WaypointAltitudeFromTerrain(Temp); } if (Temp->Details) { free(Temp->Details); } return TRUE; }
// // The purpose of simulating flarm traffic is NOT to play a videogame against flarm objects: // we only need some traffic to display for testing on ground during simulations. // // >>>>> This is accessing directly the GPS_INFO main struct, writing inside it. <<<<< // Called by LKSimulator, already locking FlightData . No worry. // void SimFlarmTraffic(long ID, double offset) { int flarm_slot = 0; bool newtraffic=false; GPS_INFO.FLARM_Available=true; LastFlarmCommandTime=GPS_INFO.Time; // useless really, we dont call UpdateMonitor from SIM flarm_slot = FLARM_FindSlot(&GPS_INFO, ID); if (flarm_slot<0) return; if ( GPS_INFO.FLARM_Traffic[flarm_slot].Status == LKT_EMPTY) { newtraffic=true; } // before changing timefix, see if it was an old target back locked in! CheckBackTarget(&GPS_INFO, flarm_slot); // and then set time of fix to current time GPS_INFO.FLARM_Traffic[flarm_slot].Time_Fix = GPS_INFO.Time; /* TEXT("%hu,%lf,%lf,%lf,%hu,%lx,%lf,%lf,%lf,%lf,%hu"), &GPS_INFO.FLARM_Traffic[flarm_slot].AlarmLevel, // unsigned short 0 &GPS_INFO.FLARM_Traffic[flarm_slot].RelativeNorth, // 1 &GPS_INFO.FLARM_Traffic[flarm_slot].RelativeEast, // 2 &GPS_INFO.FLARM_Traffic[flarm_slot].RelativeAltitude, // 3 &GPS_INFO.FLARM_Traffic[flarm_slot].IDType, // unsigned short 4 &GPS_INFO.FLARM_Traffic[flarm_slot].ID, // 6 char hex &GPS_INFO.FLARM_Traffic[flarm_slot].TrackBearing, // double 6 &GPS_INFO.FLARM_Traffic[flarm_slot].TurnRate, // double 7 &GPS_INFO.FLARM_Traffic[flarm_slot].Speed, // double 8 m/s &GPS_INFO.FLARM_Traffic[flarm_slot].ClimbRate, // double 9 m/s &GPS_INFO.FLARM_Traffic[flarm_slot].Type); // unsigned short 10 */ // If first time seen this traffic, place it nearby if ( newtraffic ) { GPS_INFO.FLARM_Traffic[flarm_slot].RelativeNorth=2; GPS_INFO.FLARM_Traffic[flarm_slot].RelativeEast=2; GPS_INFO.FLARM_Traffic[flarm_slot].Latitude = SimNewCoordinate(GPS_INFO.Latitude, offset); GPS_INFO.FLARM_Traffic[flarm_slot].Longitude = SimNewCoordinate(GPS_INFO.Longitude,offset); GPS_INFO.FLARM_Traffic[flarm_slot].Altitude = SimNewAltitude(GPS_INFO.Altitude); GPS_INFO.FLARM_Traffic[flarm_slot].TrackBearing= (double) rand()/91.276; GPS_INFO.FLARM_Traffic[flarm_slot].AlarmLevel=0; GPS_INFO.FLARM_Traffic[flarm_slot].ID=ID; GPS_INFO.FLARM_Traffic[flarm_slot].TurnRate=0; GPS_INFO.FLARM_Traffic[flarm_slot].Speed= SimNewSpeed(GPS_INFO.Speed); GPS_INFO.FLARM_Traffic[flarm_slot].Status = LKT_REAL; } else { GPS_INFO.FLARM_Traffic[flarm_slot].Latitude += (double)(rand()/20000000.0)*(rand()>15000?1:-1); GPS_INFO.FLARM_Traffic[flarm_slot].Longitude += (double)(rand()/20000000.0)*(rand()>15000?1:-1); GPS_INFO.FLARM_Traffic[flarm_slot].Altitude += (double)(rand()/2200.0)*(rand()>15000?1:-1); } GPS_INFO.FLARM_Traffic[flarm_slot].RelativeAltitude = GPS_INFO.FLARM_Traffic[flarm_slot].Altitude - GPS_INFO.Altitude; // GPS_INFO.FLARM_Traffic[flarm_slot].Average30s = flarmCalculations.Average30s( GPS_INFO.FLARM_Traffic[flarm_slot].ID, GPS_INFO.Time, GPS_INFO.FLARM_Traffic[flarm_slot].Altitude); TCHAR *name = GPS_INFO.FLARM_Traffic[flarm_slot].Name; //TCHAR *cn = GPS_INFO.FLARM_Traffic[flarm_slot].Cn; // If there is no name yet, or if we have a pending update event.. if (!_tcslen(name) || GPS_INFO.FLARM_Traffic[flarm_slot].UpdateNameFlag ) { #ifdef DEBUG_SIMLKT if (GPS_INFO.FLARM_Traffic[flarm_slot].UpdateNameFlag ) { StartupStore(_T("... UpdateNameFlag for slot %d\n"),flarm_slot); } else { StartupStore(_T("... First lookup name for slot %d\n"),flarm_slot); } #endif GPS_INFO.FLARM_Traffic[flarm_slot].UpdateNameFlag=false; // clear flag first TCHAR *fname = LookupFLARMDetails(GPS_INFO.FLARM_Traffic[flarm_slot].ID); if (fname) { LK_tcsncpy(name,fname,MAXFLARMNAME); // Now we have the name, so lookup also for the Cn // This will return either real Cn or Name, again TCHAR *cname = LookupFLARMCn(GPS_INFO.FLARM_Traffic[flarm_slot].ID); if (cname) { int cnamelen=_tcslen(cname); if (cnamelen<=MAXFLARMCN) { _tcscpy( GPS_INFO.FLARM_Traffic[flarm_slot].Cn, cname); } else { // else probably it is the Name again, and we create a fake Cn GPS_INFO.FLARM_Traffic[flarm_slot].Cn[0]=cname[0]; GPS_INFO.FLARM_Traffic[flarm_slot].Cn[1]=cname[cnamelen-2]; GPS_INFO.FLARM_Traffic[flarm_slot].Cn[2]=cname[cnamelen-1]; GPS_INFO.FLARM_Traffic[flarm_slot].Cn[3]=_T('\0'); } } else { _tcscpy( GPS_INFO.FLARM_Traffic[flarm_slot].Cn, _T("Err")); } #ifdef DEBUG_SIMLKT StartupStore(_T("... PFLAA Name to FlarmSlot=%d ID=%lx Name=<%s> Cn=<%s>\n"), flarm_slot, GPS_INFO.FLARM_Traffic[flarm_slot].ID, GPS_INFO.FLARM_Traffic[flarm_slot].Name, GPS_INFO.FLARM_Traffic[flarm_slot].Cn); #endif } else { // Else we NEED to set a name, otherwise it will constantly search for it over and over.. name[0]=_T('?'); name[1]=_T('\0'); GPS_INFO.FLARM_Traffic[flarm_slot].Cn[0]=_T('?'); GPS_INFO.FLARM_Traffic[flarm_slot].Cn[1]=_T('\0'); #ifdef DEBUG_SIMLKT StartupStore(_T("... New FlarmSlot=%d ID=%lx with no name, assigned a \"?\"\n"), flarm_slot, GPS_INFO.FLARM_Traffic[flarm_slot].ID); #endif } } // update Virtual Waypoint for target FLARM if (flarm_slot == LKTargetIndex) { WayPointList[RESWP_FLARMTARGET].Latitude = GPS_INFO.FLARM_Traffic[LKTargetIndex].Latitude; WayPointList[RESWP_FLARMTARGET].Longitude = GPS_INFO.FLARM_Traffic[LKTargetIndex].Longitude; WayPointList[RESWP_FLARMTARGET].Altitude = GPS_INFO.FLARM_Traffic[LKTargetIndex].Altitude; } }
bool ParseCOMPEWayPointString(TCHAR *String,WAYPOINT *Temp) { TCHAR tComment[(COMMENT_SIZE*2)+1]; // must be bigger than COMMENT_SIZE! TCHAR tString[READLINE_LENGTH+1]; TCHAR tName[NAME_SIZE+1]; unsigned int slen; //int flags=0; bool ok; unsigned int startpoint=3; // default unsigned int i, j; #define MAXCOMPENAME 16 slen=_tcslen(String); if (slen<65) { #ifdef COMPEDEBUG if (slen>0) { StartupStore(_T("TOO SHORT LINE:<%s> slen<65%s"),String,NEWLINE); } #endif return false; } LK_tcsncpy(tString, String,READLINE_LENGTH); // only handle W field, format: W__NAME if (tString[0] != 'W') { #ifdef COMPEDEBUG StartupStore(_T("COMPE IN:<%s> missing leading W%s"),tString,NEWLINE); #endif return false; } if (tString[1] != ' ') { #ifdef COMPEDEBUG StartupStore(_T("COMPE IN:<%s> missing space after W%s"),tString,NEWLINE); #endif return false; } // W wptname if (tString[2]!=' ') { startpoint=2; // third char } // W wptname if (tString[2]==' ') { if ( tString[3] == ' ' ) { #ifdef COMPEDEBUG StartupStore(_T("COMPE IN:<%s> missing character after W__%s"),tString,NEWLINE); #endif return false; } startpoint=3; // fourth char } Temp->Visible = true; // default all waypoints visible at start Temp->FarVisible = true; Temp->Format = LKW_COMPE; Temp->Number = NumberOfWayPoints; Temp->FileNum = globalFileNum; #ifdef COMPEDEBUG StartupStore(_T("COMPE IN:<%s>%s"),tString,NEWLINE); #endif // Name starts at position 3 or 4, index 2 or 3 . Search for space at the end of name (<=) for (i=startpoint, j=0, ok=false; i<= startpoint+MAXCOMPENAME; i++) { if (tString[i] != _T(' ')) {; j++; continue; } ok=true; break; } if (j<1) { #ifdef COMPEDEBUG StartupStore(_T("Name is empty ! %s"),NEWLINE); #endif return false; } if (!ok) { #ifdef COMPEDEBUG StartupStore(_T("Name too long! %s"),NEWLINE); #endif return false; } // i now point to first space after name LK_tcsncpy(tName,&tString[startpoint],j); #ifdef COMPEDEBUG StartupStore(_T("WP NAME size=%d: <%s>%s"),j,tName,NEWLINE); #endif if (tString[++i] != _T('A')) { #ifdef COMPEDEBUG StartupStore(_T("Missing A field! %s"),NEWLINE); #endif return false; } if (tString[++i] != _T(' ')) { #ifdef COMPEDEBUG StartupStore(_T("Missing space after A field! %s"),NEWLINE); #endif return false; } i++; // we are now on the first digit of latitude /* // aaaaaaaahhhhh f**k unicode TCHAR tdeg[5]; char sdeg[5]; sprintf(sdeg,"%c",0xBA); _stprintf(tdeg,_T("%s"),sdeg); */ TCHAR cDeg = _T('\xBA'); unsigned int p; // search for cDeg delimiter for (p=i, ok=false; p<(i+20);p++) { if (tString[p] == cDeg) { ok=true; break; } } if (!ok) { #ifdef COMPEDEBUG StartupStore(_T("Missing delimiter in latitude %s"),NEWLINE); #endif return false; } // p points to delimiter // latitude from i to i+12, starting from i counts 13 TCHAR tLatitude[16]; if ( (p-i)>15 ) { #ifdef COMPEDEBUG StartupStore(_T("latitude p-i exceed 15%s"),NEWLINE); #endif return false; } LK_tcsncpy(tLatitude,&tString[i],p-i); i=p+1; // i points to NS bool north=false; TCHAR tNS = tString[i]; TCHAR NS[]=_T("NS"); if ( (tNS != NS[0]) && (tNS != NS[1])) { #ifdef COMPEDEBUG StartupStore(_T("Wrong NS latitude! %s"),NEWLINE); #endif return false; } if ( tNS == NS[0] ) north=true; #ifdef COMPEDEBUG StartupStore(_T("WP LATITUDE : <%s> N1S0=%d%s"),tLatitude,north,NEWLINE); #endif // We are now on the space after latitude if (tString[++i] != _T(' ')) { #ifdef COMPEDEBUG StartupStore(_T("Missing space after latitude %s"),NEWLINE); #endif return false; } i++; // we are now on the first digit of longitude // search for cDeg delimiter for (p=i, ok=false; p<(i+20);p++) { if (tString[p] == cDeg) { ok=true; break; } } if (!ok) { #ifdef COMPEDEBUG StartupStore(_T("Missing delimiter in longitude %s"),NEWLINE); #endif return false; } // p points to delimiter TCHAR tLongitude[16]; if ( (p-i)>15 ) { #ifdef COMPEDEBUG StartupStore(_T("longitude p-i exceed 15%s"),NEWLINE); #endif return false; } LK_tcsncpy(tLongitude,&tString[i],p-i); i=p+1; // i points to EW bool east=false; TCHAR tEW = tString[i]; TCHAR EW[]=_T("EW"); if ( (tEW != EW[0]) && (tEW != EW[1])) { #ifdef COMPEDEBUG StartupStore(_T("Wrong EW longitude! %s"),NEWLINE); #endif return false; } if ( tEW == EW[0] ) east=true; #ifdef COMPEDEBUG StartupStore(_T("WP LONGITUDE : <%s> E1W0=%d%s"),tLongitude,east,NEWLINE); #endif // We are now on the space after longitude if (tString[++i] != _T(' ')) { #ifdef COMPEDEBUG StartupStore(_T("Missing space after longitude %s"),NEWLINE); #endif return false; } i++; // point to beginning of date of recording // we are now on the first digit of DATE // search for space delimiter for (p=i, ok=false; p<slen;p++) { if (tString[p] == _T(' ')) { ok=true; break; } } if (!ok) { #ifdef COMPEDEBUG StartupStore(_T("Missing space after DATE%s"),NEWLINE); #endif return false; } // p points to space after DATE // i points to the presumed first character of TIME i = p+1; if (i>=slen || tString[i] == _T(' ')) { #ifdef COMPEDEBUG StartupStore(_T("No TIME found%s"),NEWLINE); #endif return false; } // we are now on the first digit of DATE // search for space delimiter for (p=i, ok=false; p<slen;p++) { if (tString[p] == _T(' ')) { ok=true; break; } } if (!ok) { #ifdef COMPEDEBUG StartupStore(_T("Missing space after TIME%s"),NEWLINE); #endif return false; } // p points to space after TIME // i points to the presumed first character of ALTITUDE i = p+1; if (i>=slen || tString[i] == _T(' ')) { #ifdef COMPEDEBUG StartupStore(_T("No ALTITUDE found%s"),NEWLINE); #endif return false; } // i now points to first digit of altitude, minim 8 chars // this check can be avoided if ( slen < (i+8) ) { #ifdef COMPEDEBUG StartupStore(_T("Line overflow before altitude%s"),NEWLINE); #endif return false; } // we are now on the first digit of altitude // search for space delimiter for (p=i, ok=false; p<slen;p++) { if (tString[p] == _T(' ')) { ok=true; break; } } if (!ok) { #ifdef COMPEDEBUG StartupStore(_T("Missing space after altitude%s"),NEWLINE); #endif return false; } // p points to space after altitude TCHAR tAltitude[16]; if ( (p-i)>15 ) { #ifdef COMPEDEBUG StartupStore(_T("altitude p-i exceed 15%s"),NEWLINE); #endif return false; } LK_tcsncpy(tAltitude,&tString[i-1],p-i); #ifdef COMPEDEBUG StartupStore(_T("WP ALTITUDE : <%s>%s"),tAltitude,NEWLINE); #endif i=p+1; // we are now on first char of comment // search for line termination for (p=i, ok=false; p<slen;p++) { if ( (tString[p] == _T('\n')) || (tString[p] == _T('\r')) ) { ok=true; break; } } if (!ok) { #ifdef COMPEDEBUG StartupStore(_T("Missing CRLF after comment%s"),NEWLINE); #endif return false; } // p points to CR or LF after comment if ( (p-i)>((COMMENT_SIZE*2)-1) ) { #ifdef COMPEDEBUG StartupStore(_T("Comment too long%s"),NEWLINE); #endif return false; } LK_tcsncpy(tComment,&tString[i],p-i); #ifdef COMPEDEBUG StartupStore(_T("WP COMMENT : <%s>%s"),tComment,NEWLINE); #endif if (_tcslen(tName) > NAME_SIZE ) tName[NAME_SIZE-1]=_T('\0'); _tcscpy(Temp->Name,tName); Temp->Latitude = _tcstod(tLatitude,NULL); if (!north) Temp->Latitude *= -1; // 100218 if((Temp->Latitude > 90) || (Temp->Latitude < -90)) { return false; } Temp->Longitude = _tcstod(tLongitude,NULL); if (!east) Temp->Longitude *= -1; if((Temp->Longitude > 180) || (Temp->Longitude < -180)) { return false; } Temp->Altitude = ReadAltitude(tAltitude); if (Temp->Altitude == -9999) return false; Temp->Flags = TURNPOINT; if (_tcslen(tComment) >COMMENT_SIZE) { tComment[COMMENT_SIZE-1]=_T('\0'); } if (_tcslen(tComment) >0 ) { if (Temp->Comment) { free(Temp->Comment); } Temp->Comment = (TCHAR*)malloc((_tcslen(tComment)+1)*sizeof(TCHAR)); if (Temp->Comment) _tcscpy(Temp->Comment,tComment); } else Temp->Comment=NULL; //@ 101104 return true; }
// // TODO CHECK BUFFER SIZE, which is 100 (set in Buttons). // bool ExpandMacros(const TCHAR *In, TCHAR *OutBuffer, size_t Size){ TCHAR *a; LK_tcsncpy(OutBuffer, In, Size - 1); if (_tcsstr(OutBuffer, TEXT("$(")) == NULL) { return false; } short items=1; bool invalid = false; // Accelerator for entire label replacement- only one macro per label accepted a =_tcsstr(OutBuffer, TEXT("$(AC")); if (a != NULL) { TCHAR tbuf[20]; short i; i= (*(a+4)-'0')*10; i+= *(a+5)-'0'; LKASSERT(i>=0 && i<41); switch(i) { case 0: // LOCKMODE _tcscpy(OutBuffer,_T("")); // default is button invisible if (LockMode(0)) { // query availability if (LockMode(1)) // query status _tcscpy(OutBuffer,MsgToken(965)); // UNLOCK\nSCREEN else _tcscpy(OutBuffer,MsgToken(966)); // LOCK\nSCREEN if (!LockMode(3)) invalid=true; // button not usable } break; case 1: // Pan Supertoggle PanModeStatus mode=pan location=8 if ( MapWindow::mode.AnyPan() ) _stprintf(OutBuffer, _T("%s%s"),MsgToken(2004),MsgToken(491)); // OFF else _stprintf(OutBuffer, _T("%s%s"),MsgToken(2004),MsgToken(894)); // ON break; case 2: // Pan Supertoggle PanModeStatus mode=ScreenMode location=8 if ( MapWindow::mode.AnyPan() ) _stprintf(OutBuffer, _T("%s\n%s"),MsgToken(2082),MsgToken(491)); // OFF else _stprintf(OutBuffer, _T("%s\n%s"),MsgToken(2082),MsgToken(894)); // ON break; case 3: // DISABLED _tcscpy(OutBuffer,MsgToken(2023)); // Reserved invalid=true; break; case 4: // MacCreadyValue + 2078 _stprintf(tbuf,_T("%2.1lf"), iround(LIFTMODIFY*MACCREADY*10)/10.0); _stprintf(OutBuffer, _T("%s\n%s"), MsgToken(2078), tbuf); break; case 5: if (CALCULATED_INFO.AutoMacCready) { switch(AutoMcMode) { case amcFinalGlide: _stprintf(tbuf,_T("%s"), MsgToken(1681)); break; case amcAverageClimb: _stprintf(tbuf,_T("%s"), MsgToken(1682)); break; case amcEquivalent: _stprintf(tbuf,_T("%s"), MsgToken(1683)); break; case amcFinalAndClimb: if (CALCULATED_INFO.FinalGlide) _stprintf(tbuf,_T("%s"), MsgToken(1681)); else _stprintf(tbuf,_T("%s"), MsgToken(1682)); break; default: // LKTOKEN _@M1202_ "Auto" _stprintf(tbuf,_T("%s"), MsgToken(1202)); break; } } else { // LKTOKEN _@M1201_ "Man" _stprintf(tbuf,_T("%s"), MsgToken(1201)); } _stprintf(OutBuffer,_T("Mc %s\n%2.1lf"), tbuf,iround(LIFTMODIFY*MACCREADY*10)/10.0); break; case 6: // WaypointNext invalid = !ValidTaskPoint(ActiveTaskPoint+1); if (!ValidTaskPoint(ActiveTaskPoint+2)) _tcscpy(OutBuffer,MsgToken(801)); // Waypoint Finish else _tcscpy(OutBuffer,MsgToken(802)); // Waypoint Next break; case 7: // WaypointPrevious if (ActiveTaskPoint==1) { invalid = !ValidTaskPoint(ActiveTaskPoint-1); _tcscpy(OutBuffer,MsgToken(804)); // Waypoint Start } else if (EnableMultipleStartPoints) { invalid = !ValidTaskPoint(0); if (ActiveTaskPoint==0) _tcscpy(OutBuffer,_T("StartPnt\nCycle")); else _tcscpy(OutBuffer,MsgToken(803)); // Waypoint Previous } else { invalid = (ActiveTaskPoint<=0); _tcscpy(OutBuffer,MsgToken(803)); // Waypoint Previous } break; case 8: // RealTask check for Task reset if (! (ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1))) { invalid=true; } _tcscpy(OutBuffer,MsgToken(2019)); // Task reset break; case 9: // TerrainVisible for ChangeBack topology color if (CALCULATED_INFO.TerrainValid && IsMultimapTerrain() && !LKVarioBar) { invalid = true; } _tcscpy(OutBuffer,MsgToken(2037)); // Change topo back break; case 10: // TOGGLEHBAR HBARAVAILABLE for Toggle HBAR button if (!GPS_INFO.BaroAltitudeAvailable) { _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2045),MsgToken(1068)); // Nav by HBAR invalid=true; } else { if (EnableNavBaroAltitude) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2045),MsgToken(1174)); // Nav by HGPS else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2045),MsgToken(1068)); // Nav by HBAR } break; case 11: // SIM MENU SIMONLY if (SIMMODE) _tcscpy(OutBuffer,MsgToken(2074)); // SIM MENU else _tcscpy(OutBuffer,_T("")); break; case 12: // THIS MACRO IS AVAILABLE FOR USE break; case 13: if(UseTotalEnergy) { _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2115),MsgToken(894)); // TE ON } else { _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2115),MsgToken(491)); // TE OFF } break; case 14: if ( Shading ) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2080),MsgToken(491)); // OFF else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2080),MsgToken(894)); // ON break; case 15: if (EnableSoundModes) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2055),MsgToken(491)); // OFF else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2055),MsgToken(894)); // ON break; case 16: // ActiveMap no more used now Radio Button #ifdef RADIO_ACTIVE if (RadioPara.Enabled) { _stprintf(OutBuffer,_T("%s\n"),MsgToken(2306)); // TEXT invalid=false; } else { _stprintf(OutBuffer,_T("%s\n"),MsgToken(2306)); // TEXT invalid=true; } #else invalid=true; #endif break; case 17: // Order is: ALL ON, TEXT ONLY, GAUGES ONLY, ALL OFF if (!HaveGauges()) { if (!IsMultimapOverlaysText()) { _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2079),MsgToken(2234)); // TEXT } else { _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2079),MsgToken(491)); // OFF } break; } if (!IsMultimapOverlaysText()&&!IsMultimapOverlaysGauges()) { _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2079),MsgToken(899)); // ALL ON } else { if (IsMultimapOverlaysAll()) { _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2079),MsgToken(2234)); // TEXT } else { if (IsMultimapOverlaysText()) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2079),MsgToken(2235)); // GAUGES else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2079),MsgToken(898)); // ALL OFF } } break; case 18: if (Orbiter) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2065),MsgToken(491)); // OFF else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2065),MsgToken(894)); // ON if (!EnableThermalLocator) invalid = true; break; case 19: if (IsMultimapAirspace()) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2029),MsgToken(491)); // OFF else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2029),MsgToken(894)); // ON break; case 20: if (MapWindow::zoom.AutoZoom() ) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2009),MsgToken(418)); else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2009),MsgToken(897)); break; case 21: if (IsMultimapTopology()) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2027),MsgToken(491)); // OFF else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2027),MsgToken(894)); // ON break; case 22: if (IsMultimapTerrain()) _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2028),MsgToken(491)); // OFF else _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2028),MsgToken(894)); // ON break; case 23: if (MapSpaceMode!=MSM_MAP) invalid=true; if (MapWindow::mode.UserForcedMode() == MapWindow::Mode::MODE_FLY_CIRCLING) _stprintf(OutBuffer,_T("DspMode\n_%s_"),MsgToken(2031)); else _stprintf(OutBuffer,_T("DspMode\n%s"),MsgToken(2031)); break; case 24: if (MapSpaceMode!=MSM_MAP) invalid=true; if (MapWindow::mode.UserForcedMode() == MapWindow::Mode::MODE_FLY_CRUISE) _stprintf(OutBuffer,_T("DspMode\n_%s_"),MsgToken(2032)); else _stprintf(OutBuffer,_T("DspMode\n%s"),MsgToken(2032)); break; case 25: if (MapSpaceMode!=MSM_MAP) invalid=true; if (MapWindow::mode.UserForcedMode() == MapWindow::Mode::MODE_FLY_NONE) _stprintf(OutBuffer,_T("DspMode\n_%s_"),MsgToken(2034)); else _stprintf(OutBuffer,_T("DspMode\n%s"),MsgToken(2034)); break; case 26: if (MapSpaceMode!=MSM_MAP) invalid=true; if (MapWindow::mode.UserForcedMode() == MapWindow::Mode::MODE_FLY_FINAL_GLIDE) _stprintf(OutBuffer,_T("DspMode\n_%s_"),MsgToken(2033)); else _stprintf(OutBuffer,_T("DspMode\n%s"),MsgToken(2033)); break; case 27: // amcIsBoth if (CALCULATED_INFO.AutoMacCready && AutoMcMode==amcFinalAndClimb) _stprintf(OutBuffer,_T("Auto\n_%s_"),MsgToken(2117)); else _stprintf(OutBuffer,_T("Auto\n%s"),MsgToken(2117)); break; case 28: // amcIsFinal if (CALCULATED_INFO.AutoMacCready && AutoMcMode==amcFinalGlide) _stprintf(OutBuffer,_T("Auto\n_%s_"),MsgToken(2033)); else _stprintf(OutBuffer,_T("Auto\n%s"),MsgToken(2033)); break; case 29: // amcIsClimb if (CALCULATED_INFO.AutoMacCready && AutoMcMode==amcAverageClimb) _stprintf(OutBuffer,_T("Auto\n_%s_"),MsgToken(2075)); else _stprintf(OutBuffer,_T("Auto\n%s"),MsgToken(2075)); break; case 30: // amcIsEquiv if (CALCULATED_INFO.AutoMacCready && AutoMcMode==amcEquivalent) _stprintf(OutBuffer,_T("Auto\n_%s_"),MsgToken(2076)); else _stprintf(OutBuffer,_T("Auto\n%s"),MsgToken(2076)); break; case 31: // CheckManMc if (CALCULATED_INFO.AutoMacCready) _stprintf(OutBuffer,_T("Mc\n%s"),MsgToken(2077)); else _stprintf(OutBuffer,_T("Mc\n_%s_"),MsgToken(2077)); break; case 32: // AirspaceMode switch(AltitudeMode) { case 0: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2029),MsgToken(184)); // Clip break; case 1: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2029),MsgToken(897)); // Auto break; case 2: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2029),MsgToken(139)); // Below break; case 3: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2029),MsgToken(359)); // Inside break; case 4: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2029),MsgToken(75)); // All Off break; case 5: default: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2029),MsgToken(76)); // All On break; } break; case 33: // SnailTrailToggleName if (MapSpaceMode!=MSM_MAP) invalid=true; // Since we show the next choice, but the order is not respected in 5.0: // the new order is artificially off-short-long-full, as in the inputevents button management switch(TrailActive) { case 0: // off to short _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2035),MsgToken(612)); // Short break; case 1: // long to full _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2035),MsgToken(312)); // Full break; case 2: // short to long _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2035),MsgToken(410)); // Long break; case 3: // full to off default: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2035),MsgToken(491)); // OFF break; } break; case 34: // MapLabelsToggleActionName switch(GetMultimap_Labels()) { case MAPLABELS_ALLON: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2026),MsgToken(1203)); // WPTS break; case MAPLABELS_ONLYWPS: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2026),MsgToken(1204)); // TOPO break; case MAPLABELS_ONLYTOPO: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2026),MsgToken(898)); break; case MAPLABELS_ALLOFF: default: _stprintf(OutBuffer,_T("%s\n%s"),MsgToken(2026),MsgToken(899)); break; } break; case 35: // SIM PAN MODE REPOSITION, PANREPOS if (SIMMODE) _tcscpy(OutBuffer,MsgToken(2133)); // Position else _tcscpy(OutBuffer,_T("")); break; case 36: // // Order is: ALL ON, TASK ONLY, FAI ONLY, ALL OFF if (Flags_DrawTask&&Flags_DrawFAI) { _tcscpy(OutBuffer,MsgToken(2238)); // Draw Task } else { if (Flags_DrawTask&&!Flags_DrawFAI) { _tcscpy(OutBuffer,MsgToken(2239)); // Draw FAI } else { if (!Flags_DrawTask&&Flags_DrawFAI) { _tcscpy(OutBuffer,MsgToken(2240)); // NoDraw TaskFAI } else { _tcscpy(OutBuffer,MsgToken(2241)); // Draw TaskFAI } } } break; case 37: // if (SonarWarning) _tcscpy(OutBuffer,MsgToken(2243)); // Sonar OFF else _tcscpy(OutBuffer,MsgToken(2242)); // Sonar ON break; case 38: // if (MapSpaceMode!=MSM_MAP) invalid=true; _tcscpy(OutBuffer,MsgToken(2081)); // Set Map break; case 39: if (! (ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1))) { invalid=true; } _tcscpy(OutBuffer,MsgToken(1850)); // Task reverse break; case 40: if(IsKobo()) { #ifdef KOBO if(IsKoboWifiOn()) { _tcscpy(OutBuffer,_T("Wifi\nOff")); } else { _tcscpy(OutBuffer,_T("Wifi\nOn")); } #endif } else { _tcscpy(OutBuffer,_T("")); } break; default: _stprintf(OutBuffer, _T("INVALID\n%d"),i); break; } goto label_ret; } // ACcelerator // No accelerator? First check if we have a second macro embedded in string a =_tcsstr(OutBuffer, TEXT("&(")); if (a != NULL) { *a=_T('$'); items=2; } // Then go for one-by-one match search, slow if (_tcsstr(OutBuffer, TEXT("$(AdvanceArmed)"))) { switch (AutoAdvance) { case 0: ReplaceInString(OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(892), Size); // (manual) invalid = true; break; case 1: ReplaceInString(OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(893), Size); // (auto) invalid = true; break; case 2: if (ActiveTaskPoint>0) { if (ValidTaskPoint(ActiveTaskPoint+1)) { CondReplaceInString(AdvanceArmed, OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(161), // Cancel MsgToken(678), Size); // TURN } else { ReplaceInString(OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(8), Size); // (finish) invalid = true; } } else { CondReplaceInString(AdvanceArmed, OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(161), // Cancel MsgToken(571), Size); // START } break; case 3: if (ActiveTaskPoint==0) { CondReplaceInString(AdvanceArmed, OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(161), // Cancel MsgToken(571), Size); // START } else if (ActiveTaskPoint==1) { CondReplaceInString(AdvanceArmed, OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(161), // Cancel MsgToken(539), Size); // RESTART } else { ReplaceInString(OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(893), Size); // (auto) invalid = true; } break; // TODO bug: no need to arm finish case 4: if (ActiveTaskPoint>0) { if (ValidTaskPoint(ActiveTaskPoint+1)) { CondReplaceInString(AdvanceArmed, OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(161), // Cancel MsgToken(678), Size); // TURN } else { ReplaceInString(OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(8), Size); // (finish) invalid = true; } } else { ReplaceInString(OutBuffer, TEXT("$(AdvanceArmed)"), MsgToken(893), Size); // (auto) invalid = true; } break; default: break; } if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(CheckFlying)"))) { if (!CALCULATED_INFO.Flying) { invalid = true; } ReplaceInString(OutBuffer, TEXT("$(CheckFlying)"), TEXT(""), Size); if (--items<=0) goto label_ret; } if (_tcsstr(OutBuffer, TEXT("$(NotInReplay)"))) { if (ReplayLogger::IsEnabled()) { invalid = true; } ReplaceInString(OutBuffer, TEXT("$(NotInReplay)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(CheckWaypointFile)"))) { if (!ValidWayPoint(NUMRESWP)) { invalid = true; } ReplaceInString(OutBuffer, TEXT("$(CheckWaypointFile)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(CheckSettingsLockout)"))) { if (LockSettingsInFlight && CALCULATED_INFO.Flying) { invalid = true; } ReplaceInString(OutBuffer, TEXT("$(CheckSettingsLockout)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(CheckTask)"))) { if (!ValidTaskPoint(ActiveTaskPoint)) { invalid = true; } ReplaceInString(OutBuffer, TEXT("$(CheckTask)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(CheckAirspace)"))) { if (!CAirspaceManager::Instance().ValidAirspaces()) { invalid = true; } ReplaceInString(OutBuffer, TEXT("$(CheckAirspace)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(CheckFLARM)"))) { if (!GPS_INFO.FLARM_Available) { invalid = true; } ReplaceInString(OutBuffer, TEXT("$(CheckFLARM)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } // If it is not SIM mode, it is invalid if (_tcsstr(OutBuffer, TEXT("$(OnlyInSim)"))) { if (!SIMMODE) invalid = true; ReplaceInString(OutBuffer, TEXT("$(OnlyInSim)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(OnlyInFly)"))) { #if TESTBENCH invalid=false; #else if (SIMMODE) invalid = true; #endif ReplaceInString(OutBuffer, TEXT("$(OnlyInFly)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(WCSpeed)"))) { TCHAR tbuf[10]; _stprintf(tbuf,_T("%.0f%s"),SPEEDMODIFY*WindCalcSpeed,Units::GetUnitName(Units::GetUserHorizontalSpeedUnit()) ); ReplaceInString(OutBuffer, TEXT("$(WCSpeed)"), tbuf, Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(GS"))) { TCHAR tbuf[10]; _stprintf(tbuf,_T("%.0f%s"),SPEEDMODIFY*GPS_INFO.Speed,Units::GetUnitName(Units::GetUserHorizontalSpeedUnit()) ); ReplaceInString(OutBuffer, TEXT("$(GS)"), tbuf, Size); if (--items<=0) goto label_ret; } if (_tcsstr(OutBuffer, TEXT("$(HGPS"))) { TCHAR tbuf[10]; _stprintf(tbuf,_T("%.0f%s"),ALTITUDEMODIFY*GPS_INFO.Altitude,Units::GetUnitName(Units::GetUserAltitudeUnit()) ); ReplaceInString(OutBuffer, TEXT("$(HGPS)"), tbuf, Size); if (--items<=0) goto label_ret; } if (_tcsstr(OutBuffer, TEXT("$(TURN"))) { TCHAR tbuf[10]; _stprintf(tbuf,_T("%.0f"),SimTurn); ReplaceInString(OutBuffer, TEXT("$(TURN)"), tbuf, Size); if (--items<=0) goto label_ret; } if (_tcsstr(OutBuffer, TEXT("$(NETTO"))) { TCHAR tbuf[10]; _stprintf(tbuf,_T("%.1f"),SimNettoVario); ReplaceInString(OutBuffer, TEXT("$(NETTO)"), tbuf, Size); if (--items<=0) goto label_ret; } if (_tcsstr(OutBuffer, TEXT("$(LoggerActive)"))) { CondReplaceInString(LoggerActive, OutBuffer, TEXT("$(LoggerActive)"), MsgToken(670), MsgToken(657), Size); // Stop Start if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(NoSmart)"))) { if (DisplayOrientation == NORTHSMART) invalid = true; ReplaceInString(OutBuffer, TEXT("$(NoSmart)"), TEXT(""), Size); if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(FinalForceToggleActionName)"))) { CondReplaceInString(ForceFinalGlide, OutBuffer, TEXT("$(FinalForceToggleActionName)"), MsgToken(896), // Unforce MsgToken(895), // Force Size); if (AutoForceFinalGlide) { invalid = true; } if (--items<=0) goto label_ret; // 100517 } if (_tcsstr(OutBuffer, TEXT("$(PCONLY)"))) { if(IsEmbedded()) { _tcscpy(OutBuffer,_T("")); invalid = true; } else { ReplaceInString(OutBuffer, TEXT("$(PCONLY)"), TEXT(""), Size); } if (--items<=0) goto label_ret; } if (_tcsstr(OutBuffer, TEXT("$(NOTPC)"))) { if(IsEmbedded()) { ReplaceInString(OutBuffer, TEXT("$(NOTPC)"), TEXT(""), Size); } else { _tcscpy(OutBuffer,_T("")); invalid = true; } if (--items<=0) goto label_ret; } if (_tcsstr(OutBuffer, TEXT("$(ONLYMAP)"))) { if (MapSpaceMode!=MSM_MAP) invalid=true; ReplaceInString(OutBuffer, TEXT("$(ONLYMAP)"), TEXT(""), Size); if (--items<=0) goto label_ret; } if (_tcsstr(OutBuffer, TEXT("$(SCREENROTATE)"))) { if(CanRotateScreen()) { ReplaceInString(OutBuffer, TEXT("$(SCREENROTATE)"), TEXT(""), Size); } else { _tcscpy(OutBuffer,_T("")); invalid = true; } if (--items<=0) goto label_ret; } extern unsigned int CustomKeyLabel[]; // We dont replace macro, we do replace the entire label a =_tcsstr(OutBuffer, TEXT("$(MM")); if (a != NULL) { short i; i= *(a+4)-48; LKASSERT(i>=0 && i<11); // get the label for the custom menu item here // Decide if invalid=true or if no label at all, setting Replace to empty string unsigned int ckeymode; // test mode only switch(i) { case 1: ckeymode=CustomMenu1; break; case 2: ckeymode=CustomMenu2; break; case 3: ckeymode=CustomMenu3; break; case 4: ckeymode=CustomMenu4; break; case 5: ckeymode=CustomMenu5; break; case 6: ckeymode=CustomMenu6; break; case 7: ckeymode=CustomMenu7; break; case 8: ckeymode=CustomMenu8; break; case 9: ckeymode=CustomMenu9; break; case 0: ckeymode=CustomMenu10; break; default: ckeymode=0; break; } if (ckeymode==0 || ckeymode>=ckTOP) { invalid=true; // non selectable // _stprintf(OutBuffer,_T("Key\n%d"),i); _tcscpy(OutBuffer,_T("")); // make it invisible } else { _tcscpy(OutBuffer,MsgToken( CustomKeyLabel[ckeymode] )); } } // MM label_ret: return invalid; }