Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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();
}
Пример #5
0
// 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]);
}
Пример #6
0
//
// 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;
}
Пример #7
0
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));
        }
    }
}
Пример #8
0
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;
}
Пример #9
0
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);
      }

    }

  }
}
Пример #10
0
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);

}
Пример #11
0
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);
  }

}
Пример #12
0
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);
  }

}
Пример #13
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// 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()
Пример #14
0
//
// 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;
	}
  }
 
} 
Пример #15
0
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);

}
Пример #16
0
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);
        }
    }
}
Пример #17
0
// 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);
  }
}
Пример #18
0
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();
}
Пример #19
0
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);
  }

}
Пример #20
0
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);
		}
	}	
}
Пример #21
0
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_")));
  }
}
Пример #22
0
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
Пример #23
0
//
// 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;

}
Пример #24
0
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;
}
Пример #25
0
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);
      }

    }

  }
}
Пример #26
0
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;
}
Пример #27
0
// 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;
}
Пример #28
0
//
// 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;
  }

}
Пример #29
0
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;

 }
Пример #30
0
//
// 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;
}