コード例 #1
0
// Loads a new task from scratch.
// This is called on startup by the even manager because in DEFAULT MENU we have a GCE event
// configured to load Default.tsk for STARTUP_SIMULATOR and STARTUP_REAL.
// Until we change this, which would be a good thing because these configuration are unnecessary ,
// we must use the FullResetAsked trick.
void LoadNewTask(LPCTSTR szFileName)
{
  TASK_POINT Temp;
  START_POINT STemp;
  int i;
  bool TaskInvalid = false;
  bool WaypointInvalid = false;
  bool TaskLoaded = false;
  char taskinfo[LKPREAMBOLSIZE+1]; // 100207
  bool oldversion=false; // 100207
  TCHAR taskFileName[MAX_PATH];

  LockTaskData();

  ClearTask();
  if (FullResetAsked) {
	#if TESTBENCH
	StartupStore(_T("... LoadNewTask detected FullResetAsked, attempt to load DEMO.TSK\n"));
	#endif
	// Clear the flag, forever.
	FullResetAsked=false;
	_tcscpy(taskFileName,_T("%LOCAL_PATH%\\\\_Tasks\\DEMO.TSK"));
	ExpandLocalPath(taskFileName);

  } else {
	_tcscpy(taskFileName,szFileName);
  }

  StartupStore(_T(". LoadNewTask <%s>%s"),taskFileName,NEWLINE);

  FILE* stream = _tfopen(taskFileName, _T("rb"));
  if(stream) {
      // Defaults
      int   old_StartLine    = StartLine;
      int   old_SectorType   = SectorType;
      DWORD old_SectorRadius = SectorRadius;
      DWORD old_StartRadius  = StartRadius;
      int   old_AutoAdvance  = AutoAdvance;
      double old_AATTaskLength = AATTaskLength;
      BOOL   old_AATEnabled  = AATEnabled;
      DWORD  old_FinishRadius = FinishRadius;
      int    old_FinishLine = FinishLine;
      bool   old_EnableMultipleStartPoints = EnableMultipleStartPoints;

      TaskLoaded = true;

      if(fread(taskinfo, sizeof(char), LKPREAMBOLSIZE, stream) != LKPREAMBOLSIZE) {
          TaskInvalid = true;
          goto goEnd;
      }

	// task version check
	if ( (taskinfo[0]!= 'L') || (taskinfo[1]!= 'K') || (taskinfo[2]!=LKTASKVERSION) ) {
		TaskInvalid = true;
		oldversion = true;
		goto goEnd;
	}

      for(i=0;i<OLD_MAXTASKPOINTS;i++) {
          if(fread(&Temp, 1, sizeof(OLD_TASK_POINT), stream) != sizeof(OLD_TASK_POINT)) {
              TaskInvalid = true;
              break;
          }
          if(i < MAXTASKPOINTS) {
            memcpy(&Task[i],&Temp, sizeof(OLD_TASK_POINT));

            if( !ValidNotResWayPoint(Temp.Index) && (Temp.Index != -1) ) { // 091213
                // Task is only invalid here if the index is out of range
                // of the waypoints and not equal to -1.
                // (Because -1 indicates a null task item)
                WaypointInvalid = true;
	    }
          }
        }

      if (!TaskInvalid) {
        TaskInvalid = fread(&AATEnabled, 1, sizeof(BOOL), stream) != sizeof(BOOL);
      }
      if (!TaskInvalid) {
        TaskInvalid = fread(&AATTaskLength, 1, sizeof(double), stream) != sizeof(double);
      }
	// ToDo review by JW

	// 20060521:sgi added additional task parameters
      if (!TaskInvalid) {
        TaskInvalid = fread(&FinishRadius, 1, sizeof(FinishRadius), stream) != sizeof(FinishRadius);
      }
      if (!TaskInvalid) {
        TaskInvalid = fread(&FinishLine, 1, sizeof(FinishLine), stream) != sizeof(FinishLine);
      }
      if (!TaskInvalid) {
        TaskInvalid = fread(&StartRadius, 1, sizeof(StartRadius), stream) != sizeof(StartRadius);
      }
      if (!TaskInvalid) {
        TaskInvalid = fread(&StartLine, 1, sizeof(StartLine), stream) != sizeof(StartLine);
      }
      if (!TaskInvalid) {
        TaskInvalid = fread(&SectorType, 1, sizeof(SectorType), stream) != sizeof(SectorType);
      }
      if (!TaskInvalid) {
        TaskInvalid = fread(&SectorRadius, 1, sizeof(SectorRadius), stream) != sizeof(SectorRadius);
      }
      if (!TaskInvalid) {
        TaskInvalid = fread(&AutoAdvance, 1, sizeof(AutoAdvance), stream) != sizeof(AutoAdvance);
      }
      if (!TaskInvalid) {
        TaskInvalid = fread(&EnableMultipleStartPoints, 1, sizeof(EnableMultipleStartPoints), stream) != sizeof(EnableMultipleStartPoints);
      }
      for(i=0;i<MAXSTARTPOINTS;i++) {
        if(fread(&STemp, 1, sizeof(START_POINT), stream) != sizeof(START_POINT)) {
            TaskInvalid = true;
            break;
        }

          if( ValidNotResWayPoint(STemp.Index) || (STemp.Index==-1) ) { // 091213
            memcpy(&StartPoints[i],&STemp, sizeof(START_POINT));
          } else {
	    WaypointInvalid = true;
		StartupStore(_T("--- LoadNewTask: invalid waypoint=%d found%s"),STemp.Index,NEWLINE); // 091213
	  }
        }

        // search for waypoints...
        if (!TaskInvalid) {
          if (!LoadTaskWaypoints(stream) && WaypointInvalid) {
            // couldn't lookup the waypoints in the file and we know there are invalid waypoints
            TaskInvalid = true;
            StartupStore(_T(". LoadTaskNew: cant locate waypoint in file, and invalid wp in task file%s"),NEWLINE);
          }
        }

        // TimeGate config
        if (!TaskInvalid) {
            TaskInvalid = fread(&PGOpenTimeH, 1, sizeof(PGOpenTimeH), stream) != sizeof(PGOpenTimeH);
        }
        if (!TaskInvalid) {
            TaskInvalid = fread(&PGOpenTimeM, 1, sizeof(PGOpenTimeM), stream) != sizeof(PGOpenTimeM);
        }
        if (!TaskInvalid) {
            InitActiveGate();

            // PGOpenTime is Calculated !
            int tmp;
            TaskInvalid = fread(&tmp, 1, sizeof(tmp), stream) != sizeof(tmp);
        }
        if (!TaskInvalid) {
            PGCloseTime=86399;
            // PGCloseTime is Calculated !
            int tmp;
            TaskInvalid = fread(&tmp, 1, sizeof(tmp), stream) != sizeof(tmp);
        }
        if (!TaskInvalid) {
            TaskInvalid = fread(&PGGateIntervalTime, 1, sizeof(PGGateIntervalTime), stream) != sizeof(PGGateIntervalTime);
        }
        if (!TaskInvalid) {
            TaskInvalid = fread(&PGNumberOfGates, 1, sizeof(PGNumberOfGates), stream) != sizeof(PGNumberOfGates);
        }
        if (!TaskInvalid) {
            TaskInvalid = fread(&PGStartOut, 1, sizeof(PGStartOut), stream) != sizeof(PGStartOut);
        }

goEnd:

      fclose(stream);

      if (TaskInvalid) {
	if (oldversion)
		StartupStore(_T("------ Task is invalid: old task format%s"),NEWLINE);
	else
		StartupStore(_T("------ Task is invalid%s"),NEWLINE);

        StartLine = old_StartLine;
        SectorType = old_SectorType;
        SectorRadius = old_SectorRadius;
        StartRadius = old_StartRadius;
        AutoAdvance = old_AutoAdvance;
        AATTaskLength = old_AATTaskLength;
        AATEnabled = old_AATEnabled;
        FinishRadius = old_FinishRadius;
        FinishLine = old_FinishLine;
        EnableMultipleStartPoints = old_EnableMultipleStartPoints;
      }

  } else {
    StartupStore(_T("... LoadNewTask: file <%s> not found%s"),taskFileName,NEWLINE); // 091213
    TaskInvalid = true;
  }

  if (TaskInvalid) {
    ClearTask();
  }

  RefreshTask();

  if (!ValidTaskPoint(0)) {
    ActiveTaskPoint = 0;
  }

  UnlockTaskData();

  if (TaskInvalid && TaskLoaded) {
	if (oldversion) {
	// LKTOKEN  _@M360_ = "Invalid old task format!"
		MessageBoxX(MsgToken(360),
	// LKTOKEN  _@M396_ = "Load task"
			MsgToken(396), mbOk);
	} else {
	// LKTOKEN  _@M264_ = "Error in task file!"
		MessageBoxX(MsgToken(264),
	// LKTOKEN  _@M396_ = "Load task"
			MsgToken(396), mbOk);
	}
  } else {
	#if TESTBENCH
	StartupStore(_T("------ Task is Loaded%s"),NEWLINE);
	#endif
	TaskModified = false;
	TargetModified = false;
	_tcscpy(LastTaskFileName, taskFileName);
  }

}
コード例 #2
0
ファイル: Orbiter.cpp プロジェクト: IvanSantanna/LK8000
// Thermal orbiter by Paolo Ventafridda, November 2010
void CalculateOrbiter(NMEA_INFO *Basic, DERIVED_INFO *Calculated) {

  static unsigned int timepassed=0;
  static bool alreadywarned=false;

  if (!Calculated->Circling || !EnableSoundModes) return;
  timepassed++;
  if (LKTH_R <1) {
	return;  // no thermal center available
  }

  double thtime = Basic->Time - Calculated->ClimbStartTime;
  // we need a valid thermal center to work on. Assuming 2 minutes is enough to sample the air around.
  if (thtime<120) return;
  // after 1500ft thermal gain, autodisable
  if (Calculated->ThermalGain>500) return;
  if (Calculated->ThermalGain<50) return;

  // StartupStore(_T("*** Tlat=%f Tlon=%f R=%f W=%f  TurnRate=%f \n"), LKTH_LAT, LKTH_LON, LKTH_R, LKTH_W, LK_TURNRATE);
  // StartupStore(_T("*** CalcHeading=%f Track=%f TurnRate=%f Bank=%f \n"), LK_CALCHEADING, LK_MYTRACK,  LK_TURNRATE, LK_BANKING);

  double th_center_distance, th_center_bearing;	// thermal center
  double orbital_bearing;                 	// orbital tangent 
  double orbital_brgdiff;			// current difference between track and orbital_bearing
  double orbital_warning_angle;			// warning angle difference

  double alpha;					// alpha angle to the tangent relative to th_center_bearing
  double circlesense=0;				// 1 for CW, -1 for CCW

  // these parameters should be dynamically calculated for each thermal in the future
  // th_angle should be correlated to IAS

  double th_radius;				// thermal radius
  double th_minoverradius, th_maxoverradius;	// radius+overradius is the minimal and max approach distance
  double th_angle;				// deg/s default turning in the thermal. Pilot should turn with this 
						// angolar speed.
  double reactiontime;			// how many seconds pass before the pilot start turning
  double turningcapacitypersecond;	// how many degrees can I change in my turnrate in a second?

  // TODO: TUNE THEM IN REAL TIME!
  if (ISPARAGLIDER) {
	th_radius=50;
	th_minoverradius=1;
	th_maxoverradius=100;
	th_angle=18;
	turningcapacitypersecond=10;
	reactiontime=1.0;
  } else { 
	th_radius=90;
	th_minoverradius=5;
	th_maxoverradius=160;
	th_angle=16.5;
	turningcapacitypersecond=10;
	reactiontime=1.0;
  }

  circlesense=LK_TURNRATE>0 ? 1 : -1;	//@ CCW: -1   CW: 1
  if (circlesense==0 || (fabs(LK_TURNRATE)<8)) { // 8 deg/sec are 45 seconds per turn
	alreadywarned=false;
	return;
  }

  DistanceBearing(LK_MYLAT, LK_MYLON,LKTH_LAT,LKTH_LON,&th_center_distance,&th_center_bearing);

  if (th_center_distance< (th_radius+th_minoverradius)) {
	#if DEBUG_ORBITER
	StartupStore(_T("*** Too near:  dist=%.0f < %.0f\n"), th_center_distance, th_radius+th_minoverradius);
	#endif
	return;
  }
  if (th_center_distance> (th_radius+th_maxoverradius)) {
	#if DEBUG_ORBITER
	StartupStore(_T("*** Too far:  dist=%.0f >  %.0f\n"), th_center_distance, th_radius+th_maxoverradius);
	#endif
	return;
  }
  // StartupStore(_T("*** distance to orbit %.0f (ratio:%0.f)\n"), 
  // th_center_distance- th_radius , (th_center_distance - th_radius)/th_radius);

  alpha= atan2(th_radius, th_center_distance)*RAD_TO_DEG;

  orbital_bearing  = th_center_bearing - (alpha*circlesense); //@ add for CCW
  if (orbital_bearing>359) orbital_bearing-=360;
  //  orbital_distance = th_radius / sin(alpha);

  // StartupStore(_T("*** tc_dist=%f th_center_bearing=%f  orbital_distance=%f orbital_bearing=%f  alpha=%f  mydir=%f\n"),
  // th_center_distance, th_center_bearing, orbital_distance, orbital_bearing, alpha, LK_CALCHEADING );

  if (circlesense==1) 
	orbital_brgdiff = orbital_bearing-LK_CALCHEADING; // CW
  else
	orbital_brgdiff = LK_CALCHEADING - orbital_bearing; // CCW

  if (orbital_brgdiff<0) {
	#if DEBUG_ORBITER
	StartupStore(_T("*** passed target orbit direction\n"));
	#endif
	return;
  }
  if (orbital_brgdiff>90) {
	#if DEBUG_ORBITER
	StartupStore(_T("*** wrong direction\n"));
	#endif
	return;
  }

  static int lasttimewarned=0;
  double actionadvancetime;		// how many seconds are needed in advance, given the current turnrate?

  // assuming circling with the same radius of the perfect thermal: 18deg/s, 20s turn rate approx.
  actionadvancetime=(circlesense*(LK_TURNRATE/turningcapacitypersecond))+reactiontime;

  // When circling with a radius greater than the default, we have a problem.
  // We must correct the predicted angle threshold
  orbital_warning_angle=actionadvancetime*(LK_TURNRATE*LK_TURNRATE)/th_angle;
  #if DEBUG_ORBITER
  StartupStore(_T("... LK_TURNRATE=%.0f  advancetime=%.2f  angle=%.1f \n"), LK_TURNRATE, actionadvancetime,orbital_warning_angle);
  #endif

  if (orbital_brgdiff<orbital_warning_angle) {
	if (!alreadywarned && ((timepassed-lasttimewarned)>12) ) {

		if (th_center_distance<(th_radius+(th_maxoverradius/2))) {
			#if DEBUG_ORBITER
			StartupStore(_T("****** GO STRAIGHT NOW FOR SHORT TIME ******\n"));
			#endif
			LKSound(_T("LK_ORBITER1.WAV"));
		} else {
			#if DEBUG_ORBITER
			StartupStore(_T("****** GO STRAIGHT NOW FOR LONGER TIME ******\n"));
			#endif
			LKSound(_T("LK_ORBITER2.WAV"));
		}
		alreadywarned=true;
		lasttimewarned=timepassed;
	} else {
		#if DEBUG_ORBITER
		StartupStore(_T("****** GO STRAIGHT, already warned\n"));
		#endif
	}
  } else {
	alreadywarned=false;
  }


}
コード例 #3
0
ファイル: LKInit.cpp プロジェクト: Turbo87/LK8000
// Conversion between submenus and global mapspace modes 
// Basic initialization of global variables and parameters.
//
void InitModeTable() {

	short i,j;
	#if TESTBENCH
	StartupStore(_T(". Init ModeTable for LK8000: "));
	#endif

	for (i=0; i<=LKMODE_TOP; i++)
		for (j=0; j<=MSM_TOP; j++)
			ModeTable[i][j]=INVALID_VALUE;


	// this table is for submenus, order is not important
	ModeTable[LKMODE_MAP][MP_WELCOME]	=	MSM_WELCOME;
	ModeTable[LKMODE_MAP][MP_MOVING]	=	MSM_MAP;
	ModeTable[LKMODE_MAP][MP_MAPTRK]	=	MSM_MAPTRK;
	ModeTable[LKMODE_MAP][MP_MAPWPT]	=	MSM_MAPWPT;
	ModeTable[LKMODE_MAP][MP_MAPASP]	=	MSM_MAPASP;
	ModeTable[LKMODE_MAP][MP_RADAR]		=	MSM_MAPRADAR;
	ModeTable[LKMODE_MAP][MP_TEST]		=	MSM_MAPTEST;

	ModeTable[LKMODE_WP][WP_AIRPORTS]	=	MSM_AIRPORTS;
	ModeTable[LKMODE_WP][WP_LANDABLE]	=	MSM_LANDABLE;
	ModeTable[LKMODE_WP][WP_NEARTPS]	=	MSM_NEARTPS;
	ModeTable[LKMODE_WP][WP_AIRSPACES]	=	MSM_AIRSPACES;

	ModeTable[LKMODE_INFOMODE][IM_CRUISE]	=	MSM_INFO_CRUISE;
	ModeTable[LKMODE_INFOMODE][IM_THERMAL]	=	MSM_INFO_THERMAL;
	ModeTable[LKMODE_INFOMODE][IM_TASK]	=	MSM_INFO_TASK;
	ModeTable[LKMODE_INFOMODE][IM_AUX]	=	MSM_INFO_AUX;
	ModeTable[LKMODE_INFOMODE][IM_CONTEST]	=	MSM_INFO_CONTEST;
	ModeTable[LKMODE_INFOMODE][IM_TRI]	=	MSM_INFO_TRI;

	ModeTable[LKMODE_NAV][NV_COMMONS]	=	MSM_COMMON;
	ModeTable[LKMODE_NAV][NV_HISTORY]	=	MSM_RECENT;
	ModeTable[LKMODE_NAV][NV_THERMALS]	=	MSM_THERMALS;

	ModeTable[LKMODE_TRF][TF_LIST]		=	MSM_TRAFFIC;
	ModeTable[LKMODE_TRF][IM_TRF]		=	MSM_INFO_TRF;
	ModeTable[LKMODE_TRF][IM_TARGET]	=	MSM_INFO_TARGET;

	// startup mode
	ModeIndex=LKMODE_MAP;
	// startup values for each mode. we shall update these defaults using current profile settings
	// for ConfIP real values. 
	#if TESTBENCH
	ModeType[LKMODE_MAP]	=	MP_MOVING;
	#else
	ModeType[LKMODE_MAP]	=	MP_WELCOME;
	#endif
	ModeType[LKMODE_INFOMODE]=	IM_CRUISE;
	ModeType[LKMODE_WP]	=	WP_AIRPORTS;
	ModeType[LKMODE_NAV]	=	NV_COMMONS;
	ModeType[LKMODE_TRF]	=	TF_LIST;

	ModeTableTop[LKMODE_MAP]=MP_TOP;
	ModeTableTop[LKMODE_WP]=WP_TOP;
	ModeTableTop[LKMODE_INFOMODE]=IM_TOP;
	ModeTableTop[LKMODE_NAV]=NV_TOP;
	ModeTableTop[LKMODE_TRF]=TF_TOP;

	// set all sorting type to distance (default) even for unconventional modes just to be sure
	for (i=0; i<=MSM_TOP; i++) SortedMode[i]=1;
	SortedMode[MSM_AIRSPACES]=2; // Airspaces have a different layout

	for (i=0; i<MAXNEAREST;i++) {
		SortedTurnpointIndex[i]=-1;
		SortedLandableIndex[i]=-1;
		SortedAirportIndex[i]=-1;
	}

	for (i=0; i<MAXCOMMON; i++) 
		CommonIndex[i]= -1;

	for (i=0; i<=MSM_TOP; i++) {
		SortBoxY[i]=0;
		for (j=0; j<=MAXSORTBOXES; j++) SortBoxX[i][j]=0;
	}

	SetInitialModeTypes();
	#if TESTBENCH
	StartupStore(_T("Ok%s"),NEWLINE);
	#endif
}
コード例 #4
0
ファイル: RenderMapWindowBg.cpp プロジェクト: jaaaaf/LK8000
void MapWindow::RenderMapWindowBg(LKSurface& Surface, const RECT& rc) {

    if ( (LKSurface::AlphaBlendSupported() && BarOpacity < 100) || mode.AnyPan() ) {
        RECT newRect = {0, 0, ScreenSizeX, ScreenSizeY};
        MapWindow::ChangeDrawRect(newRect);
    } else {
        RECT newRect = {0, 0, ScreenSizeX, ScreenSizeY - BottomSize - (ScreenSizeY-MapRect.bottom)};
        MapWindow::ChangeDrawRect(newRect);
    }

    if (QUICKDRAW) {
        goto _skip_calcs;
    }


    // Here we calculate arrival altitude, GD etc for map waypoints. Splitting with multicalc will result in delayed
    // updating of visible landables, for example. The nearest pages do this separately, with their own sorting.
    // Basically we assume -like for nearest- that values will not change that much in the multicalc split time.
    // Target and tasks are recalculated in real time in any case. Nearest too. 
    LKCalculateWaypointReachable(false);

_skip_calcs:

    if (PGZoomTrigger) {
        if (!mode.Is(Mode::MODE_PANORAMA)) {
            mode.Special(Mode::MODE_SPECIAL_PANORAMA, true);
            LastZoomTrigger = DrawInfo.Time;

            Message::AddMessage(1000, 3, gettext(TEXT("_@M872_"))); // LANDSCAPE ZOOM FOR 20s
            LKSound(TEXT("LK_TONEUP.WAV"));
        } else {
            // previously called, see if time has passed
            if (DrawInfo.Time > (LastZoomTrigger + 20.0)) {
                // time has passed, lets go back
                LastZoomTrigger = 0; // just for safety
                mode.Special(Mode::MODE_SPECIAL_PANORAMA, false);
                PGZoomTrigger = false;
                Message::AddMessage(1500, 3, gettext(TEXT("_@M873_"))); // BACK TO NORMAL ZOOM
                LKSound(TEXT("LK_TONEDOWN.WAV"));
            }
        }
    }

    // 
    // "Checkpoint Charlie"
    // This is were we process stuff for anything else but main map.
    // We let the calculations run also for MapSpace modes.
    // But for multimaps, we can also draw some more stuff..
    // We are also sent back here from next code, when we detect that
    // the MapSpace mode has changed from MAP to something else while we
    // were rendering.
    //
QuickRedraw:
    //
    if (DONTDRAWTHEMAP) {
        const bool isMultimap = IsMultiMapShared(); // DrawMapSpace can change "MapSpaceMode", get this before. 
        DrawMapSpace(Surface, rc);
        // Is this a "shared map" environment? 
        if (isMultimap) {
            // Shared map, of course not MSN_MAP, since dontdrawthemap was checked
            //
            if (IsMultimapOverlaysGauges()) {
                RenderOverlayGauges(Surface, rc);
            }
            if (IsMultimapOverlaysText()) {
                DrawLook8000(Surface, rc);
            }

        } else {
            // Not in map painting environment 
            // ex. nearest pages, but also MAPRADAR..
        }

        // 
        DrawBottomBar(Surface, rc);
#ifdef DRAWDEBUG
        DrawDebug(hdc, rc);
#endif
        // no need to do SelectObject as at the bottom of function
        return;
    }

    POINT Orig, Orig_Aircraft;
    CalculateOrigin(rc, &Orig);
    const ScreenProjection _Proj = CalculateScreenPositions(Orig, rc, &Orig_Aircraft);

    // When no terrain is painted, set a background0
    // Remember that in this case we have plenty of cpu time to spend for best result
    if (!IsMultimapTerrain() || !DerivedDrawInfo.TerrainValid || !RasterTerrain::isTerrainLoaded()) {
        // fill background..
        Surface.FillRect(&rc, hInvBackgroundBrush[BgMapColor]);
        // We force LK painting black values on screen depending on the background color in use
        // TODO make it an array once settled
        // blackscreen would force everything to be painted white, instead
        LKTextBlack = BgMapColorTextBlack[BgMapColor];
        if (BgMapColor > 6) BlackScreen = true;
        else BlackScreen = false;
    } else {
        LKTextBlack = false;
        BlackScreen = false;
    }

    // Logic of DONTDRAWTHEMAP is the following:
    // We are rendering the screen page here. If we are here, we passed Checkpoint Charlie.
    // So we were, at charlie, in MSM_MAP: preparing the main map stuff.
    // If we detect that MapSpace has CHANGED while we were doing our job here,
    // it means that the user has clicked meanwhile. He desires another page, so let's
    // reset our intentions and go back to beginning, or nearby..
    // We have a new job to do, for another MapSpace, no more MAP.
    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    bool terrainpainted = false;

    if ((IsMultimapTerrain() && (DerivedDrawInfo.TerrainValid)
            && RasterTerrain::isTerrainLoaded())
            ) {
        // sunelevation is never used, it is still a todo in Terrain
        double sunelevation = 40.0;
        double sunazimuth = GetAzimuth();

        LockTerrainDataGraphics();
        if (DONTDRAWTHEMAP) { // 100318
            UnlockTerrainDataGraphics();
            goto QuickRedraw;
        }
        DrawTerrain(Surface, DrawRect, _Proj, sunazimuth, sunelevation);
        terrainpainted = true;
        if (DONTDRAWTHEMAP) {
            UnlockTerrainDataGraphics();
            goto QuickRedraw;
        }
        if (!QUICKDRAW) {
            // SHADED terrain unreachable, aka glide amoeba. This is not the outlined perimeter!
#ifdef GTL2
            if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) &&
                    DerivedDrawInfo.TerrainValid) {
#else
            if ((FinalGlideTerrain == 2) && DerivedDrawInfo.TerrainValid) {
#endif
                DrawTerrainAbove(Surface, DrawRect);
            }
        }
        UnlockTerrainDataGraphics();
    }

    //
    // REMINDER: WE ARE IN MAIN MAP HERE: MSM_MAP ONLY, OR PANNING MODE!
    // MAPSPACEMODE CAN STILL CHANGE, DUE TO USER INPUT. BUT WE GOT HERE IN
    // EITHER PAN OR MSM_MAP.
    //

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    if (IsMultimapTopology()) {
        DrawTopology(Surface, DrawRect, _Proj);
    } else {
        // If no topology wanted, but terrain painted, we paint only water stuff
        if (terrainpainted) DrawTopology(Surface, DrawRect, _Proj, true);
    }
#if 0
    StartupStore(_T("... Experimental1=%.0f\n"), Experimental1);
    StartupStore(_T("... Experimental2=%.0f\n"), Experimental2);
    Experimental1 = 0.0;
    Experimental2 = 0.0;
#endif

    // Topology labels are printed first, using OLD wps positions from previous run!
    // Reset for topology labels decluttering engine occurs also in another place here!
    ResetLabelDeclutter();

    if ((Flags_DrawTask || TargetDialogOpen) && ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) {
        DrawTaskAAT(Surface, DrawRect);
    }


    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    if (IsMultimapAirspace()) {
        DrawAirSpace(Surface, rc, _Proj);
    }

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    // In QUICKDRAW dont draw trail, thermals, glide terrain
    if (QUICKDRAW) {
        goto _skip_stuff;
    }

    DrawThermalEstimate(Surface, DrawRect, _Proj);
    if (OvertargetMode == OVT_THER) DrawThermalEstimateMultitarget(Surface, DrawRect, _Proj);

    // draw red cross on glide through terrain marker
    if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid) {
        DrawGlideThroughTerrain(Surface, DrawRect, _Proj);
    }

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

_skip_stuff:

    if (IsMultimapAirspace() && AirspaceWarningMapLabels) {
        DrawAirspaceLabels(Surface, DrawRect, _Proj, Orig_Aircraft);
        if (DONTDRAWTHEMAP) { // 100319
            goto QuickRedraw;
        }
    }

    if (IsMultimapWaypoints()) {
        DrawWaypointsNew(Surface, DrawRect);
    }
    if (TrailActive) {
        LKDrawLongTrail(Surface, Orig_Aircraft, DrawRect);
        // NEED REWRITING
        LKDrawTrail(Surface, DrawRect, _Proj);
    }
    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    if ((Flags_DrawTask || TargetDialogOpen) && ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) {
        DrawTask(Surface, DrawRect, _Proj, Orig_Aircraft);

    }
    if (Flags_DrawFAI) {
        if (MapWindow::DerivedDrawInfo.Flying) { // FAI optimizer does not depend on tasks, being based on trace
            DrawFAIOptimizer(Surface, DrawRect, _Proj, Orig_Aircraft);
        } else { // not flying => show FAI sectors for the task
            if (ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) {
                DrawTaskSectors(Surface, DrawRect, _Proj);
            }
        }
    }


    // In QUICKDRAW do not paint other useless stuff
    if (QUICKDRAW) {
        if (extGPSCONNECT) DrawBearing(Surface, DrawRect, _Proj);
        goto _skip_2;
    }

    // ---------------------------------------------------

    DrawTeammate(Surface, rc, _Proj);

    if (extGPSCONNECT) {
        DrawBestCruiseTrack(Surface, Orig_Aircraft);
        DrawBearing(Surface, DrawRect, _Proj);
    }

    // draw wind vector at aircraft
    if (NOTANYPAN) {
        DrawWindAtAircraft2(Surface, Orig_Aircraft, DrawRect);
    } else if (mode.Is(Mode::MODE_TARGET_PAN)) {
        DrawWindAtAircraft2(Surface, Orig, rc);
    }

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    // Draw traffic and other specifix LK gauges
    LKDrawFLARMTraffic(Surface, DrawRect, _Proj, Orig_Aircraft);

    // ---------------------------------------------------
_skip_2:

    if (NOTANYPAN) {

        if (IsMultimapOverlaysGauges()) {
            RenderOverlayGauges(Surface, rc);
        }
        
        if (TrackBar) {
            DrawHeading(Surface, Orig, DrawRect);
            if (ISGAAIRCRAFT) {
                DrawFuturePos(Surface, Orig, DrawRect);
            }
        }
        
        if (ISGAAIRCRAFT) {
            DrawHSIarc(Surface, Orig, DrawRect);
        }        

        if (IsMultimapOverlaysText()) {
            DrawLook8000(Surface, rc);
        }
        DrawBottomBar(Surface, rc);
    }

    if (DONTDRAWTHEMAP) {
        goto QuickRedraw;
    }

    // Draw glider or paraglider
    if (extGPSCONNECT) {
        DrawAircraft(Surface, Orig_Aircraft);
    }



#if USETOPOMARKS
    // marks on top...
    DrawMarks(hdc, rc);
#endif

    if (!INPAN) {
        DrawMapScale(Surface, rc, zoom.BigZoom()); // unused BigZoom
        DrawCompass(Surface, rc, DisplayAngle);
    }

#ifdef DRAWDEBUG
    DrawDebug(hdc, rc);
#endif

}
コード例 #5
0
ファイル: dlgIgcFile.cpp プロジェクト: acasadoalonso/LK8000
    void OnSend(WndButton* pWnd) {
        if(ItemIndex < FileList.size()) {
            StartHourglassCursor();
            
            //Start Bluetooth if needed...
#ifdef UNDER_CE    
            CObexPush Obex;
            if(Obex.Startup()) {
                StartupStore(_T("Startup OK \n"));
                size_t nDevice = Obex.LookupDevice();
                StartupStore(_T("LookupDevice OK \n"));
                if(nDevice == 0) {
                    StopHourglassCursor();
                    MessageBoxX(_T("No Device"), _T("Error"), mbOk);
                    StartHourglassCursor();
                } else {
                    WndProperty* wp = (WndProperty*)wfDlg->FindByName(TEXT("prpDeviceList"));
                    DataFieldEnum* dfe = NULL;
                    if (wp) {
                        dfe = (DataFieldEnum*)wp->GetDataField();
                    }
                    if(dfe) {
                        dfe->Clear();
                        dfe->addEnumText(_T("none"));
                    }
                    for(size_t i = 0; i < nDevice; ++i) {
                        TCHAR szDeviceName[100] = {0};
                        if(!Obex.GetDeviceName(i, szDeviceName, array_size(szDeviceName))) {
                            _stprintf(szDeviceName, _T("Unknown device <%d>"), i);
                        }
                        StartupStore(_T("GetDeviceName <%d><%s> \n"), i, szDeviceName);
                        if(dfe) {
                            dfe->addEnumText(szDeviceName);
                        }
                    }
                    if(wp) {
                        if(dfe) {
                            dfe->SetAsInteger(0);
                        }
                        wp->SetReadOnly(false);
                        wp->RefreshDisplay();
                    }
                    StopHourglassCursor();
                    size_t DeviceIndex = 0;
                    if(dfe && wp) {
                        dlgComboPicker(wp);
                        DeviceIndex = dfe->GetAsInteger();
                    }
                    StartHourglassCursor();
                    if(DeviceIndex != 0) {
                        DeviceIndex--;

                        TCHAR szFileFullPath[MAX_PATH] = _T("\0");
                        LocalPath(szFileFullPath, _T(LKD_LOGS));
                        size_t nLen = _tcslen(szFileFullPath);
                        if (szFileFullPath[nLen - 1] != _T('\\')) {
                            _tcscat(szFileFullPath, _T("\\"));
                        }
                        FileList_t::const_iterator ItFileName = FileList.begin();
                        std::advance(ItFileName, ItemIndex);
                        _tcscat(szFileFullPath, ItFileName->c_str());

                        if(!Obex.SendFile(DeviceIndex, szFileFullPath)) {
                            StopHourglassCursor();
                            MessageBoxX(_T("Send Failed"), _T("Error"), mbOk);
                            StartHourglassCursor();
                        } else {
                            StopHourglassCursor();
                            MessageBoxX(_T("File sent!"), _T("Success"), mbOk);
                            StartHourglassCursor();
                        }
                    }
                }
                Obex.Shutdown();
            } else {
                MessageBoxX(_T("Unsupported on this device"), _T("Error"), mbOk);
            }
#else
            MessageBoxX(_T("Unsupported on this device"), _T("Error"), mbOk);
#endif
            StopHourglassCursor();
        }
    }
コード例 #6
0
ファイル: Globals.cpp プロジェクト: rkalman/LK8000
//
// Default globals are NOT necessarily default settings.
// We had to give them an initialization, but real init
// is done through ResetProfile. These are the values used
// BEFORE a profile is loaded at startup, FYI.
// There are globals that are not configurable of course,
// and thus are not part of a profile.
//
// Please LOAD NEW GLOBALS always at the bottom of the file
// to keep trace of new items.
//
void Globals_Init(void) {

  #if TESTBENCH
  StartupStore(_T(". Globals_Init\n"));
  #endif
  int i;


//  _tcscpy(LK8000_Version,_T("")); // No, this is initialised by lk8000 on startup as the first thing

  _tcscpy(strAssetNumber,_T(LOGGER_ASSET_ID));

  ProgramStarted = psInitInProgress;

  RangeLandableNumber=0;
  RangeAirportNumber=0;
  RangeTurnpointNumber=0;

  SortedNumber=0;
  CommonNumber=0;
  RecentNumber=0;

  BgMapColor=0;
  BgMapColor_Config=0;

  BgMapColorTextBlack[0] = false;
  BgMapColorTextBlack[1] = false;
  BgMapColorTextBlack[2] = false;
  BgMapColorTextBlack[3] = false;
  BgMapColorTextBlack[4] = true;
  BgMapColorTextBlack[5] = true;
  BgMapColorTextBlack[6] = true;
  BgMapColorTextBlack[7] = true;
  BgMapColorTextBlack[8] = true;
  BgMapColorTextBlack[9] = true;

  //
  // Default infobox groups configuration
  // Real defaults set by ResetDefaults
  //
  for (i=0; i<MAXINFOWINDOWS; i++) InfoType[i]=0;
  InfoType[0] = 1008146198;
  InfoType[1] = 1311715074;
  InfoType[2] = 923929365;
  InfoType[3] = 975776319;
  InfoType[4] = 956959267;
  InfoType[5] = 1178420506;
  InfoType[6] = 1410419993;
  InfoType[7] = 1396384771;
  InfoType[8] = 387389207;


  StatusMessageData_Size = 0;

  //
  // Configuration with default values for new profile
  //
  MenuTimeout_Config = MENUTIMEOUTMAX;	// Config
  MenuTimeOut=0;			// Runtime


  // TODO check!!
  DisplayOrientation = TRACKUP;
  DisplayOrientation_Config = TRACKUP;
  AutoOrientScale = 10;
  DisplayTextType = DISPLAYNONE;

  AltitudeMode_Config = ALLON;
  AltitudeMode = AltitudeMode_Config;
  ClipAltitude = 10000; // m * 10
  AltWarningMargin = 1000; // m *10
  AutoAdvance = 1;
  AutoAdvance_Config = 1;
  AdvanceArmed = false;

  SafetyAltitudeMode = 0;

  GlobalRunning = false;


  GlobalModelType=MODELTYPE_PNA_PNA;


  SPEEDMODIFY = TOKNOTS;
  LIFTMODIFY  = TOKNOTS;
  DISTANCEMODIFY = TONAUTICALMILES;
  ALTITUDEMODIFY = TOFEET;
  TASKSPEEDMODIFY = TOKPH;

  MACCREADY = 0; // in m/s
  QNH = (double)1013.25;
  BUGS = 1; // This is the runtime Efficiency that can be changed by basic settings 1=100% 0.5=50%
  BALLAST = 0;

  AutoMacCready_Config = true;

  TerrainRamp_Config = 0;

  NettoSpeed = 1000;
  GPSCONNECT = FALSE;

  time_in_flight=0;
  time_on_ground=0;
  TakeOffSpeedThreshold=0.0;

  RUN_MODE=RUN_WELCOME;

  EnableFLARMMap = 0;

  // Final Glide Data
  SAFETYALTITUDEARRIVAL = 3000;
  SAFETYALTITUDETERRAIN = 500;
  SAFTEYSPEED = 50.0;

  // Total Energy usage, config and runtime separated
  UseTotalEnergy=false;
  UseTotalEnergy_Config=false;

  POLAR[0] = 0;
  POLAR[1] = 0;
  POLAR[2] = 0;

  WEIGHTS[0] = 250;
  WEIGHTS[1] = 70;
  WEIGHTS[2] = 100;

  POLARV[0] = 21;
  POLARV[1] = 27;
  POLARV[2] = 40;

  POLARLD[0] = 33;
  POLARLD[1] = 30;
  POLARLD[2] = 20;


  Handicap = 85; // KA6CR

  // Team code info
  TeamCodeRefWaypoint = -1;
  TeamFlarmTracking = false;
  TeammateCodeValid = false;

  WayPointList = NULL;
  WayPointCalc = NULL;

  NumberOfWayPoints = 0;
  SectorType = 1; // FAI sector
  SectorRadius = 3000;
  StartLine = TRUE;
  StartRadius = 3000;

  HomeWaypoint = -1;
  TakeOffWayPoint=false;
  AirfieldsHomeWaypoint = -1;

  // Alternates
  Alternate1 = -1;
  Alternate2 = -1;
  BestAlternate = -1;
  ActiveAlternate = -1;

  GPSAltitudeOffset = 0;
  UseGeoidSeparation=false;
  PressureHg=false;

  CustomKeyTime=700;
  CustomKeyModeCenter=(CustomKeyMode_t)ckDisabled;
  CustomKeyModeLeft=(CustomKeyMode_t)ckDisabled;
  CustomKeyModeRight=(CustomKeyMode_t)ckDisabled;
  CustomKeyModeAircraftIcon=(CustomKeyMode_t)ckDisabled;
  CustomKeyModeLeftUpCorner=(CustomKeyMode_t)ckDisabled;
  CustomKeyModeRightUpCorner=(CustomKeyMode_t)ckDisabled;
  CustomKeyModeCenterScreen=(CustomKeyMode_t)ckDisabled;

  QFEAltitudeOffset = 0;
  WasFlying = false;

  LastDoRangeWaypointListTime=0;
  DeviceNeedClipping=false; // forcing extensive clipping 
  ForcedClipping=false;	    // force clipping around
  EnableAutoBacklight=true;
  EnableAutoSoundVolume=true;
  AircraftCategory=0;

  ExtendedVisualGlide=false;
  Look8000=lxcAdvanced;
  HideUnits=false;
  CheckSum=true;
  OutlinedTp_Config=0;
  OutlinedTp=OutlinedTp_Config;
  OverColor=0;
  TpFilter=0;
  MapBox=0;

  ActiveMap=false;
  GlideBarMode=0;
  OverlaySize=0;
  BarOpacity=255;
  FontRenderer=0;
  LockModeStatus=false;
  ArrivalValue=0;
  NewMapDeclutter=0;
  Shading=1;
  Shading_Config=1;

  for (i=0; i<10; i++) ConfMP[i]=1;

  ConfBB0=0, ConfBB1=1, ConfBB2=1, ConfBB3=1, ConfBB4=1, ConfBB5=1, ConfBB6=1, ConfBB7=1, ConfBB8=1, ConfBB9=1, ConfBB0Auto=1;
  ConfIP11=1, ConfIP12=1, ConfIP13=1, ConfIP14=1, ConfIP15=1, ConfIP16=1, ConfIP21=1, ConfIP22=1;
  ConfIP23=1, ConfIP24=1, ConfIP31=1, ConfIP32=1, ConfIP33=1;
  AverEffTime=0;
  DrawBottom=false;
  BottomMode=BM_CRU;
  BottomSize=1; // Init by MapWindow3
  TopSize=0;
  BottomGeom=0;

  // default initialization for gestures. InitLK8000 will fine tune it.
  GestureSize=60;
  // xml dlgconfiguration value replacing 246 which became 278
  LKwdlgConfig=0;
  IphoneGestures=false;

  PGClimbZoom=1;
  PGCruiseZoom=1;
  PGAutoZoomThreshold = 5000;
  // This is the gauge bar on the left for variometer
  LKVarioBar=0;
  // This is the value to be used for painting the bar
  LKVarioVal=0;
  // moving map is all black and need white painting - not much used 091109
  BlackScreen=false;
  // if true, LK specific text on map is painted black, otherwise white
  LKTextBlack=false;;

  LKVarioSize=2; // init by InitLK8000
  // activated by Utils2 in virtual keys, used inside RenderMapWindowBg
  PGZoomTrigger=false;
  BestWarning=false;
  ThermalBar=0;
  McOverlay=true;
  TrackBar=false;
  PGOptimizeRoute=true;

  WindCalcSpeed=0;
  WindCalcTime=WCALC_TIMEBACK;
  RepeatWindCalc=false;

  // FLARM Traffic is real if <=1min, Shadow if <= etc. If >Zombie it is removed
  LKTime_Real=15, LKTime_Ghost=60, LKTime_Zombie=180;
  // Number of IDs (items) of existing traffic updated from DoTraffic
  LKNumTraffic=0;

  // 100404 index inside FLARM_Traffic of our target, and its type as defined in Utils2
  LKTargetIndex=-1;
  LKTargetType=LKT_TYPE_NONE;

  // Number of asps (items) of existing airspaces updated from DoAirspaces
  LKNumAirspaces=0;

  WpHome_Lat=0;
  WpHome_Lon=0;

  // Name of nearest wp to takeoff and landings
  _tcscpy(TAKEOFFWP_Name,_T("")); 
  _tcscpy(LANDINGWP_Name,_T("")); 

  // Number of Thermals updated from DoThermalHistory
  LKNumThermals=0;

  // LK8000 Hearth beats at 2Hz
  LKHearthBeats=0;
  // number of reporting messages from Portmonitor.
  PortMonitorMessages=0;

  PollingMode=false;

  GlideBarOffset=0;
  EngineeringMenu=false; // never saved to registry
  splitter=1; 

  NumDataOptions = 0;

  #if (WINDOWSPC>0)
  SCREENWIDTH=800;
  SCREENHEIGHT=400;
  #endif

  debounceTimeout=200;

  WarningHomeDir=false;

  ScreenSize=0;
  ScreenSizeX=0;
  ScreenSizeY=0;
  ScreenLandscape=false;
  ScreenDScale=1;
  ScreenScale=1;
  ScreenIntScale=false;

  // Default arrival mode calculation type
  // 091016 currently not changed anymore
  AltArrivMode=ALTA_MC;

  // zoomout trigger time handled by MapWindow
  LastZoomTrigger=0;


  // traffic DoTraffic interval, also reset during key up and down to prevent wrong selections
  LastDoTraffic=0;
  LastDoNearest=0;
  LastDoAirspaces=0;
  LastDoCommon=0;
  LastDoThermalH=0;


  // Paraglider's time gates
  PGOpenTimeH=0;
  PGOpenTimeM=0;
  PGOpenTime=0;
  PGCloseTime=0;
  // Interval, in minutes
  PGGateIntervalTime=0;
  // How many gates, 1-x
  PGNumberOfGates=0;
  // Start out or start in?
  PGStartOut=false;
  // Current assigned gate
  ActiveGate=-1;

  // LKMAPS flag for topology: >0 means ON, and indicating how many topo files are loaded
  LKTopo=0;
  // This threshold used in Terrain.cpp to distinguish water altitude
  LKWaterThreshold=0;
  LKTopoZoomCat05=0;
  LKTopoZoomCat10=0;
  LKTopoZoomCat20=0;
  LKTopoZoomCat30=0;
  LKTopoZoomCat40=0;
  LKTopoZoomCat50=0;
  LKTopoZoomCat60=0;
  LKTopoZoomCat70=0;
  LKTopoZoomCat80=0;
  LKTopoZoomCat90=0;
  LKTopoZoomCat100=0;
  LKTopoZoomCat110=0;

  // max number of topo and wp labels painted on map, defined by default in Utils
  LKMaxLabels=0;

  // current mode of overtarget 0=task 1=alt1, 2=alt2, 3=best alt
  OvertargetMode=0;
  // Simulator has one thermal at a time with these values
  SimTurn=0;
  ThLatitude=1;
  ThLongitude=1;
  ThermalRadius=0;
  SinkRadius=0;

  // LK8000 sync flags
  NearestDataReady=false;
  CommonDataReady=false;
  RecentDataReady=false;
  LKForceDoNearest=false;
  LKForceDoCommon=false;
  LKForceDoRecent=false;
  LKevent=LKEVENT_NONE;
  LKForceComPortReset=false;
  LKDoNotResetComms=false;

  Cpu_Draw=0;
  Cpu_Calc=0;
  Cpu_Instrument=0;
  Cpu_PortA=0;
  Cpu_PortB=0;
  Cpu_Aver=0;

  Experimental1=0, Experimental2=0;

  NearestAirspaceHDist=-1;
  NearestAirspaceVDist=0;
  _tcscpy(NearestAirspaceName,_T(""));
  _tcscpy(NearestAirspaceVName,_T(""));

  // FlarmNetCount=0; BUG 120606 this cannot be done here, it is already done by class init!

  //Airspace Warnings
  AIRSPACEWARNINGS = TRUE;
  WarningTime = 60;
  AcknowledgementTime = 900;                  // keep ack level for this time, [secs]
  AirspaceWarningRepeatTime = 300;            // warning repeat time if not acknowledged after 5 minutes
  AirspaceWarningVerticalMargin = 1000;       // vertical distance used to calculate too close condition , in m*10
  AirspaceWarningDlgTimeout = 30;             // airspace warning dialog auto closing in x secs
  AirspaceWarningMapLabels = 1;               // airspace warning map labels showed

  SnailNext = 0;

  // OLC COOKED VALUES
  //CContestMgr::CResult OlcResults[CContestMgr::TYPE_NUM];

  // user interface settings
  FinalGlideTerrain = 1;
  EnableSoundModes = true;
  OverlayClock = false;
  LKLanguageReady = false;


  //IGC Logger
  LoggerActive = false;

  // Others

  COMPORTCHANGED = FALSE;
  MAPFILECHANGED = FALSE;
  AIRSPACEFILECHANGED = FALSE;
  AIRFIELDFILECHANGED = FALSE;
  WAYPOINTFILECHANGED = FALSE;
  TERRAINFILECHANGED = FALSE;
  TOPOLOGYFILECHANGED = FALSE;
  POLARFILECHANGED = FALSE;
  LANGUAGEFILECHANGED = FALSE;
  INPUTFILECHANGED = FALSE;

  ActiveWayPoint = -1;

  // Assigned Area Task
  AATTaskLength = 120;
  AATEnabled = FALSE;
  FinishMinHeight = 0;
  StartMaxHeight = 0;
  StartMaxSpeed = 0;
  StartMaxHeightMargin = 0;
  StartMaxSpeedMargin = 0;

  AlarmMaxAltitude1=0;
  AlarmMaxAltitude2=0;
  AlarmMaxAltitude3=0;
  AlarmTakeoffSafety=0;

  WaypointsOutOfRange = 1; // include by default

  UTCOffset = 0;
  EnableThermalLocator = 1;
  EnableMultipleStartPoints = false;
  StartHeightRef = 0; // MSL

  #if (!defined(WINDOWSPC) || (WINDOWSPC==0))
  SetSystemTimeFromGPS = true;
  #else
  SetSystemTimeFromGPS = false;
  #endif

  SelectedWaypoint = -1;
  TrailActive = TRUE;
  TrailActive_Config = TRUE;
  VisualGlide = 0;
  DisableAutoLogger = false;
  LiveTrackerInterval = 0;
  
  IGCWriteLock=false; // workaround, but not a real solution

  LoggerTimeStepCruise=2;     // 111221 using 2 seconds
  LoggerTimeStepCircling=1;

  AutoWindMode_Config= D_AUTOWIND_CIRCLING;
  AutoWindMode= AutoWindMode_Config;
  EnableTrailDrift_Config = false;
  MapWindow::EnableTrailDrift=EnableTrailDrift_Config;
  AutoZoom_Config = false;
  MapWindow::zoom.AutoZoom(AutoZoom_Config);

  EnableNavBaroAltitude=false;
  EnableNavBaroAltitude_Config=false;
  Orbiter=1;
  Orbiter_Config=1;
  // EnableExternalTriggerCruise=false; REMOVE
  ExternalTriggerCruise= false;
  ExternalTriggerCircling= false;
  EnableExternalTriggerCruise = false;
  ForceFinalGlide= false;
  AutoForceFinalGlide= false;

  AutoMcMode_Config = amcEquivalent; // this is the config saved value
  AutoMcMode = amcEquivalent;        // this is temporary runtime

  EnableFAIFinishHeight = false;
  BallastTimerActive = false;

  FinishLine=1;
  FinishRadius=3000;

  BallastSecsToEmpty = 120;

  // TODO: cancel Appearance struct and reorganize
  Appearance.DefaultMapWidth=206;
  // Only used in MapWindow2, can be de-configured
  Appearance.BestCruiseTrack=ctBestCruiseTrackAltA;
  // Landables style
  Appearance.IndLandable=wpLandableDefault;
  // Black/White inversion
  Appearance.InverseInfoBox=false;
  InverseInfoBox_Config=false;
  Appearance.InfoBoxModel=apImPnaGeneric;

  TerrainContrast   = 140;
  TerrainBrightness = 115;
  TerrainRamp = 0;

  extGPSCONNECT = FALSE;
  DialogActive=false;

  PDABatteryPercent = 100;
  PDABatteryTemperature = 0;
  PDABatteryStatus=0;
  PDABatteryFlag=0;

  szPolarFile[0] = TEXT('\0');
  szAirspaceFile[0] = TEXT('\0');
  szAdditionalAirspaceFile[0] = TEXT('\0');
  szWaypointFile[0] = TEXT('\0');
  szAdditionalWaypointFile[0] = TEXT('\0');
  szTerrainFile[0] = TEXT('\0');
  szAirfieldFile[0] = TEXT('\0');
  szLanguageFile[0] = TEXT('\0');
  szInputFile[0] = TEXT('\0');
  szMapFile[0] = TEXT('\0');

  // Ports and device settings
  dwDeviceName1[0]=_T('\0');
  dwPortIndex1 = 0;
  dwSpeedIndex1 = 2;
  dwBit1Index = (BitIndex_t)bit8N1;
  dwDeviceName2[0]=_T('\0');
  dwPortIndex2 = 0;
  dwSpeedIndex2 = 2;
  dwBit2Index = (BitIndex_t)bit8N1;

  // Units
  SpeedUnit_Config = 2;		// default is kmh
  TaskSpeedUnit_Config = 2;	// default is kph
  DistanceUnit_Config = 2;	// default is km
  LiftUnit_Config = 1;		// default m/s
  AltitudeUnit_Config = 1;	// default m

  // Editable fonts
  FontDesc_MapWindow[0]=_T('\0');
  FontDesc_MapLabel [0]=_T('\0');

  // Logger
  PilotName_Config[0]=_T('\0');
  LiveTrackersrv_Config[0]=_T('\0');
  LiveTrackerusr_Config[0]=_T('\0');
  LiveTrackerpwd_Config[0]=_T('\0');
  AircraftType_Config[0]=_T('\0');
  AircraftRego_Config[0]=_T('\0');
  CompetitionClass_Config[0]=_T('\0');
  CompetitionID_Config[0]=_T('\0');

  LockSettingsInFlight = false;
  LoggerShortName = false;

  /* 
   * These tables are initialized by InitSineTable later than Globals here
  COSTABLE[4096];
  SINETABLE[4096];
  INVCOSINETABLE[4096];
  ISINETABLE[4096];
  ICOSTABLE[4096];
   */

  TouchContext=0;
  BUGS_Config = 1; // equivalent saved in system config and set by default on startup

  // Load and use higher resolution bitmaps
  UseHiresBitmap=false;

  // Coordinate Y of bottombar area valid for click
  BottomBarY=0;

  // Set by InitLKScreen, used in Draw parts
  AircraftMenuSize=0;
  CompassMenuSize=0;

  // Configuration variable for Ungestures
  UseUngestures=true;	// on by default

  // This is a runtime only variable, by default disabled. Must be enabled by customkey
  UseWindRose=false;	// use wind rose (ex: NNE) for wind direction, instead of degrees

  extern void Reset_CustomMenu(void);
  Reset_CustomMenu();

  Reset_Multimap_Flags();
  extern void Reset_Multimap_Mode(void);
  Reset_Multimap_Mode();

  Trip_Moving_Time=0;
  Trip_Steady_Time=0;

  Rotary_Speed=0;
  Rotary_Distance=0;

  // These are not saved to profile
  Flags_DrawTask=true;
  Flags_DrawFAI=true;


  // ^ ADD NEW GLOBALS up here ^ 
  // ---------------------------

}
コード例 #7
0
ファイル: LKCustomKeyHandler.cpp プロジェクト: LK8000/LK8000
// handle custom keys. Input: key pressed (center, left etc.)
// Returns true if handled successfully, false if not
//
// Passthrough mode for keys>=1000 (custom menu keys)
//
bool CustomKeyHandler(const int key) {

  int ckeymode;
  static bool doinit=true;
  static int oldModeIndex;

  if (doinit) {
	oldModeIndex=LKMODE_INFOMODE;;
	doinit=false;
  }

  if (key>=1000) {
	ckeymode=key-1000;
	LKASSERT((ckeymode>=0 && ckeymode<ckTOP));
	goto passthrough;
  }

  switch(key) {
	case CKI_BOTTOMCENTER:
		ckeymode=CustomKeyModeCenter;
		break;
	case CKI_BOTTOMLEFT:
		ckeymode=CustomKeyModeLeft;
		break;
	case CKI_BOTTOMRIGHT:
		ckeymode=CustomKeyModeRight;
		break;
	case CKI_BOTTOMICON:
		ckeymode=CustomKeyModeAircraftIcon;
		break;
	case CKI_TOPLEFT:
		ckeymode=CustomKeyModeLeftUpCorner;
		break;
	case CKI_TOPRIGHT:
		ckeymode=CustomKeyModeRightUpCorner;
		break;
	case CKI_CENTERSCREEN:
		ckeymode=CustomKeyModeCenterScreen;
		break;
	default:
		DoStatusMessage(_T("ERR-725 UNKNOWN CUSTOMKEY"));
		return false;
		break;
  }

passthrough:

  switch(ckeymode) {
	case ckDisabled:
		break;
	case ckZoomIn:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		MapWindow::zoom.EventScaleZoom(1);
		return true;
		break;
	case ckZoomInMore:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		MapWindow::zoom.EventScaleZoom(2);
		return true;
		break;
	case ckZoomOut:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		MapWindow::zoom.EventScaleZoom(-1);
		return true;
		break;
	case ckZoomOutMore:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		MapWindow::zoom.EventScaleZoom(-2);
		return true;
		break;
	case ckMenu:
		ShowMenu();
		return true;
	case ckBackMode:
		PreviousModeIndex();
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckToggleMap: //TODO
		if (ModeIndex==LKMODE_MAP)
			SetModeIndex(oldModeIndex);
		else {
			oldModeIndex=ModeIndex;
			SetModeIndex(LKMODE_MAP);
		}
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;

	case ckTrueWind:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::setMode(_T("TrueWind"));
		return true;

	case ckTeamCode:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventSetup(_T("Teamcode"));
		return true;

	case ckToggleOverlays:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		ToggleMultimapOverlays();
		return true;

	case ckToggleMapLandable:
		if (ModeIndex==LKMODE_MAP)
			SetModeIndex(LKMODE_WP);
		else
			SetModeIndex(LKMODE_MAP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckLandables:
		SetModeIndex(LKMODE_WP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckToggleMapCommons:
		if (ModeIndex==LKMODE_MAP)
			SetModeIndex(LKMODE_NAV);
		else
			SetModeIndex(LKMODE_MAP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckCommons:
		SetModeIndex(LKMODE_NAV);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckToggleMapTraffic:
		if (ModeIndex==LKMODE_MAP)
			SetModeIndex(LKMODE_TRF);
		else
			SetModeIndex(LKMODE_MAP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckTraffic:
		SetModeIndex(LKMODE_TRF);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckInvertColors:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventInvertColor(NULL);
		return true;
	case ckTimeGates:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventTimeGates(NULL);
		return true;
	case ckMarkLocation:
		InputEvents::eventMarkLocation(_T(""));
		return true;
	case ckAutoZoom:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventZoom(_T("auto toggle"));
		InputEvents::eventZoom(_T("auto show"));
		return true;
	case ckActiveMap:
                // NO MORE USED (reserved)
		return true;
	case ckBooster:
		DoStatusMessage(_T("FEEL THE THERMAL"));
		LKSound(_T("LK_BOOSTER.WAV"));
		return true;
	case ckGoHome:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		if (ValidWayPoint(HomeWaypoint)) {
			if ( (ValidTaskPoint(ActiveTaskPoint)) && (Task[ActiveTaskPoint].Index == HomeWaypoint )) {
	// LKTOKEN  _@M82_ = "Already going home"
				DoStatusMessage(MsgToken(82));
			} else {
				GotoWaypoint(HomeWaypoint);
			}
		} else
	// LKTOKEN  _@M465_ = "No Home to go!"
			DoStatusMessage(MsgToken(465));
		return true;
	case ckPanorama:
		if (PGZoomTrigger==false)
			PGZoomTrigger=true;
		else
			LastZoomTrigger=0;
		PlayResource(TEXT("IDR_WAV_CLICK"));
		return true;

	case ckMultitargetRotate:
		RotateOvertarget();
		return true;

	case ckMultitargetMenu:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::setMode(_T("MTarget"));
		return true;
	case ckBaroToggle:
		ToggleBaroAltitude();
		return true;
	case ckBasicSetup:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventSetup(_T("Basic"));
		return true;
	case ckSimMenu:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::setMode(_T("SIMMENU"));
		return true;
	case ckToggleMapAirspace:
		if (ModeIndex==LKMODE_MAP)
			SetModeType(LKMODE_WP,WP_AIRSPACES);
		else
			SetModeIndex(LKMODE_MAP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckAirspaceAnalysis:
		SetModeType(LKMODE_MAP,MP_MAPASP);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckOptimizeRoute:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		PGOptimizeRoute=!PGOptimizeRoute;
		if (ISPARAGLIDER && PGOptimizeRoute) {
			AATEnabled = true;
            ClearOptimizedTargetPos();
		}
		return true;
	case ckLockScreen:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventService(_T("LOCKMODE"));
		return true;
	case ckWhereAmI:
		// no sound here, chime is played by service event
		InputEvents::eventService(_T("ORACLE"));
		return true;
	case ckUseTotalEnergy:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventService(_T("TOTALEN"));
		return true;
	case ckNotepad:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventChecklist(_T(""));
		return true;
	case ckTerrainColors:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventService(_T("TERRCOL"));
		return true;
	case ckNearestAirspace:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventNearestAirspaceDetails(NULL);
		return true;
	case ckOlcAnalysis:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventSetup(_T("OlcAnalysis"));
		return true;
	case ckTerrainColorsBack:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventService(_T("TERRCOLBACK"));
		return true;
	case ckForceFreeFlightRestart:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		if (!CALCULATED_INFO.Flying) {
			DoStatusMessage(MsgToken(922)); // NOT FLYING
		} else {
			if (MessageBoxX(MsgToken(1754), _T(""), mbYesNo) == IdYes) {
				LKSW_ForceFreeFlightRestart=true;
			}
		}
		return true;
	case ckCustomMenu1:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		extern void dlgCustomMenuShowModal(void);
		InputEvents::eventMode(_T("MYMODE"));
		return true;
	case ckTaskCalc:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventCalculator(NULL);
		return true;
	case ckTaskTarget:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventSetup(_T("Target"));
		return true;
	case ckArmAdvance:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventArmAdvance(_T("toggle"));
		InputEvents::eventArmAdvance(_T("show"));
		return true;

	case ckMessageRepeat:
		InputEvents::eventRepeatStatusMessage(NULL);
                return true;

	case ckWaypointLookup:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventWaypointDetails(_T("select"));
		return true;

	case ckPan:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::eventPan(_T("toggle"));
		return true;

	case ckWindRose:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		UseWindRose=!UseWindRose;
		return true;

	case ckFlarmRadar:
		SetModeType(LKMODE_MAP,MP_RADAR);
		MapWindow::RefreshMap();
		SoundModeIndex();
		return true;
	case ckDeviceA:
		if(devA() && devA()->Config) {
			devA()->Config(devA());
		}
		return true;
	case ckDeviceB:
		if(devB() && devB()->Config) {
			devB()->Config(devB());
		}
		return true;
        case ckDeviceC:
                if(devC() && devC()->Config) {
                        devC()->Config(devC());
                }
                return true;
        case ckDeviceD:
                if(devD() && devD()->Config) {
                        devD()->Config(devD());
                }
                return true;
        case ckDeviceE:
                if(devE() && devE()->Config) {
                        devE()->Config(devE());
                }
                return true;
        case ckDeviceF:
                if(devF() && devF()->Config) {
                        devF()->Config(devF());
                }
                return true;
	case ckResetOdometer:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		if (MessageBoxX(MsgToken(2229), _T(""), mbYesNo) == IdYes) {
			LKSW_ResetOdometer=true;
		}
		return true;
	case ckForceLanding:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		if ( !CALCULATED_INFO.Flying ) {
			DoStatusMessage(MsgToken(922)); // NOT FLYING
		} else {
			if ( (GPS_INFO.Speed > TakeOffSpeedThreshold) && (!GPS_INFO.NAVWarning) ) {
				DoStatusMessage(MsgToken(1799)); // STOP MOVING!
			} else {
				if (MessageBoxX(MsgToken(2230), _T(""), mbYesNo) == IdYes) {
					LKSW_ForceLanding=true;
				}
			}
		}
		return true;
	case ckResetTripComputer:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		if (MessageBoxX(MsgToken(2236), _T(""), mbYesNo) == IdYes) {
			LKSW_ResetTripComputer=true;
		}
		return true;
	case ckSonarToggle:
		SonarWarning = !SonarWarning;
		TCHAR sonarmsg[60];
		_stprintf(sonarmsg,_T("%s "),MsgToken(1293)); // SONAR
		if (SonarWarning)
			_tcscat(sonarmsg,MsgToken(1643)); // ENABLED
		else
			_tcscat(sonarmsg,MsgToken(1600)); // DISABLED
		DoStatusMessage(sonarmsg,NULL,false);
        if (SonarWarning)
            LKSound(TEXT("LK_TONEUP.WAV"));
        else
            LKSound(TEXT("LK_TONEDOWN.WAV"));
		return true;
    case ckDrawXCToggle:
      Flags_DrawXC = !Flags_DrawXC;
      if (EnableSoundModes) {
        if (!Flags_DrawXC)
          LKSound(TEXT("LK_TONEUP.WAV"));
        else
          LKSound(TEXT("LK_TONEDOWN.WAV"));
      }
      return true;
	case ckResetView:
		ModeType[LKMODE_MAP]    =       MP_MOVING;
		ModeType[LKMODE_INFOMODE]=      IM_CRUISE;
		ModeType[LKMODE_WP]     =       WP_AIRPORTS;
		ModeType[LKMODE_NAV]    =       NV_COMMONS;
		ModeType[LKMODE_TRF]    =       TF_LIST;

		SetModeType(LKMODE_MAP,MP_MOVING);
		MapWindow::RefreshMap();
		SoundModeIndex();

		return true;

	case  ckMapOrient:
		PlayResource(TEXT("IDR_WAV_CLICK"));

		TCHAR MapOrientMsg[60];

	    if  (MapSpaceMode==MSM_MAP)
	    {
	      DisplayOrientation++;
	      if(DisplayOrientation > TARGETUP)
		DisplayOrientation = 0;
	      MapWindow::SetAutoOrientation(); // 101008 reset it
	      switch(DisplayOrientation)
	      {
            case TRACKUP     : _stprintf(MapOrientMsg,_T("%s"),MsgToken(737)) ; break;  // _@M737_ "Track up"
            case NORTHUP     : _stprintf(MapOrientMsg,_T("%s"),MsgToken(483)) ; break;  // _@M483_ "North up"
            case NORTHCIRCLE : _stprintf(MapOrientMsg,_T("%s"),MsgToken(482)) ; break;  // _@M482_ "North circling"
            case TARGETCIRCLE: _stprintf(MapOrientMsg,_T("%s"),MsgToken(682)) ; break;  // _@M682_ "Target circling"  _@M485_ "NorthUp above "
            case NORTHTRACK  : _stprintf(MapOrientMsg,_T("%s"),MsgToken(484)) ; break;  // _@M484_ "North/track"
            case NORTHSMART  : _stprintf(MapOrientMsg,_T("%s"),MsgToken(481)) ; break;  // _@M481_ "North Smart"
            case TARGETUP    : _stprintf(MapOrientMsg,_T("%s"),MsgToken(2349)); break;  // _@M2349_"Target up"

	      }
	      DoStatusMessage(MapOrientMsg,NULL,false);
	    }
	    else
	    {
		  SetMMNorthUp(GetSideviewPage(), (GetMMNorthUp(GetSideviewPage())+1)%2);
	    }

		return true;
    case ckResetComm:
		PlayResource(TEXT("IDR_WAV_CLICK"));
        InputEvents::eventRestartCommPorts(NULL);
        return true;

    case ckDspMode:
		PlayResource(TEXT("IDR_WAV_CLICK"));
		InputEvents::setMode(_T("Display3"));
		return true;

    case ckAirspaceLookup:
        PlayResource(TEXT("IDR_WAV_CLICK"));
        dlgAirspaceSelect();
        return true;
	default:
		DoStatusMessage(_T("ERR-726 INVALID CUSTOMKEY"));
		StartupStore(_T("... ERR-726 INVALID CUSTOMKEY=%d\n"),ckeymode);
		break;
  }

  return false;

}
コード例 #8
0
ファイル: VirtualKeys.cpp プロジェクト: acasadoalonso/LK8000
// vkmode 0=normal 1=gesture up 2=gesture down
// however we consider a down as up, and viceversa
int ProcessVirtualKey(int X, int Y, long keytime, short vkmode) {

#define VKTIMELONG 1500
	short yup, ydown;
	short i, j;
	short numpages=0;

	static short s_xright=0, s_xleft=0;

	short shortpress_yup, shortpress_ydown;
	short longpress_yup, longpress_ydown;

	static short s_bottomY=0;
	#if 0 // 121123 CHECK AND REMOVE
	static short oldMapSpaceMode=0;
	#endif

	bool dontdrawthemap=(DONTDRAWTHEMAP);
	VKtime=keytime;

	#ifdef DEBUG_PROCVK
	TCHAR buf[100];
	_stprintf(buf,_T("R=%d,%d,%d,%d, X=%d Y=%d kt=%ld"),0, 0, 
	ScreenSizeX, ScreenSizeY,X,Y,keytime);
	DoStatusMessage(buf);
	#endif


	if (DoInit[MDI_PROCESSVIRTUALKEY]) {

		// calculate left and right starting from center
		s_xleft=(MapWindow::MapRect.right+MapWindow::MapRect.left)/2 -(MapWindow::MapRect.right-MapWindow::MapRect.left)/6;
		s_xright=(MapWindow::MapRect.right+MapWindow::MapRect.left)/2 + (MapWindow::MapRect.right-MapWindow::MapRect.left)/6;

		// same for bottom navboxes: they do not exist in infobox mode
		s_bottomY=MapWindow::Y_BottomBar-NIBLSCALE(2);

		DoInit[MDI_PROCESSVIRTUALKEY]=false;
	}


        // LK v6: check we are not out of MapRect bounds.
        if (X<MapWindow::MapRect.left||X>MapWindow::MapRect.right||Y<MapWindow::MapRect.top||Y>MapWindow::MapRect.bottom)
            return ProcessSubScreenVirtualKey(X,Y,keytime,vkmode);

        if (MapSpaceMode==MSM_WELCOME) {
            SetModeType(LKMODE_MAP, MP_MOVING);
            LKevent=LKEVENT_NONE;
            NextModeIndex();
            PreviousModeIndex();
            MapWindow::RefreshMap();
            LKSound(_T("LK_BEEP0.WAV"));
            return 0;
        }


	// 120602 fix
	// TopSize is dynamically assigned by DrawNearest,Drawcommon, DrawXX etc. so we cannot make static yups
	//
	longpress_yup=(short)((MapWindow::Y_BottomBar-TopSize)/3.7)+TopSize;
	longpress_ydown=(short)(MapWindow::Y_BottomBar-(MapWindow::Y_BottomBar/3.7));
	shortpress_yup=(short)((MapWindow::Y_BottomBar-TopSize)/2.7)+TopSize;
	shortpress_ydown=(short)(MapWindow::Y_BottomBar-(MapWindow::Y_BottomBar/2.7));
	
	// do not consider navboxes, they are processed separately
	// These are coordinates for up down center VKs
	// yup and ydown are used normally on nearest page item selection, but also for real VK
	// that currently are almost unused. 

	if (DrawBottom) {
		// Native LK mode: always fullscreen mode
		// If long click, we are processing an Enter, and we want a wider valid center area
		if ( keytime>=(VKSHORTCLICK*2)) { 
			yup=longpress_yup;
			ydown=longpress_ydown;
		} else {
			yup=shortpress_yup;
			ydown=shortpress_ydown;
		}
	} else {
		// This could happen only in Ibox mode. We should never fall here.
		yup=(short)(ScreenSizeY/2.7);
		ydown=(short)(ScreenSizeY-(ScreenSizeY/2.7));
		#if TESTBENCH
		StartupStore(_T("...... DrawBottom FALSE in virtual key processing!\n"));
		#endif
	}

	#ifdef DEBUG_PROCVK
	TCHAR buf[100];
	#endif

	// Handle fullscreen 8000 mode 
	// sound clicks require some attention here
	if (DrawBottom && !MapWindow::mode.AnyPan() && vkmode==LKGESTURE_NONE) { 
		//
		// CLICKS on NAVBOXES, any MapSpaceMode ok
		//
		if (Y>= s_bottomY ) { // TESTFIX 090930

			if ( X>s_xright ) {
				// standard configurable mode
				if (keytime >=CustomKeyTime) {
					// 2 is right key
					if (CustomKeyHandler(CKI_BOTTOMRIGHT)) return 0;
				}
				#ifdef DEBUG_PROCVK
				_stprintf(buf,_T("RIGHT in limit=%d"),MapWindow::Y_BottomBar-NIBLSCALE(20));
				DoStatusMessage(buf);
				#endif
				BottomBarChange(true); // advance
				BottomSounds();
				MapWindow::RefreshMap();
				return 0;
			}
			if ( X<s_xleft ) { // following is ugly
				if (keytime >=CustomKeyTime) {
					// 1 is left key
					if (CustomKeyHandler(CKI_BOTTOMLEFT)) return 0;
				}

				#ifdef DEBUG_PROCVK
				_stprintf(buf,_T("LEFT in limit=%d"),MapWindow::Y_BottomBar-NIBLSCALE(20));
				DoStatusMessage(buf);
				#endif
				BottomBarChange(false); // backwards
				BottomSounds();
				MapWindow::RefreshMap();
				return 0;
			}
			#ifdef DEBUG_PROCVK
			_stprintf(buf,_T("CENTER in limit=%d"),MapWindow::Y_BottomBar-NIBLSCALE(20));
			DoStatusMessage(buf);
			#endif

			//
			// VIRTUAL CENTER KEY HANDLING
			//
			// long press on center navbox 
			// Activate following choices for testing and experimenting. Always disable for real usage.
#if (0)
			// Output NMEA to device
			if (keytime>1000) {
				PlayResource(TEXT("IDR_WAV_HIGHCLICK"));

				devWriteNMEAString(devA(),_T("$PGRMCE"));
				Message::AddMessage(1000, 3, _T("NMEA out $PGRMCE"));
				return 0;
			}
#endif
#if (0)
			// Simulate incoming NMEA string
			if (keytime>1000) {
				static TCHAR mbuf[200];
				_stprintf(mbuf,_T("$VARIO,1010.18,0.0,0.00,2.34,2,000.0,000.0*51\n"));
				NMEAParser::ParseNMEAString(0, (TCHAR *) mbuf, &GPS_INFO);
				return 0;
			}
#endif
#if (0)	// TESTKEY
			// Print a message on the screen for debugging purposes
			TCHAR mbuf[100];
			if (keytime>1000) {
				// _stprintf(mbuf,_T("Cache MCA %d/%d F=%d"), Cache_Hits_MCA, Cache_Calls_MCA, Cache_False_MCA );
				char *point;
				point=(char*)&mbuf;
				*point++='A';
				*point++='\0';
				*point++='B';
				*point++='\0';
				*point++=0x06;
				*point++=0x01;
				*point++='C';
				*point++='\0';
				*point++='\0';
				*point++='\0';
				//mbuf[1]=0xc4;
				//mbuf[1]=0x86;
				Message::AddMessage(20000, 3, mbuf);
				return 0;
			}
#endif

#if (0)
			if (keytime>=CustomKeyTime) {
				if (OvertargetMode==OVT_MAXMODE) OvertargetMode=0;
				else OvertargetMode++;
				PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
				return 0;
			}
#endif

#if (0)
			if (keytime>=CustomKeyTime) {
				PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
				extern bool RunSignature(void);
				RunSignature();

				return 0;
			}
#endif

#if (0)
			// Long press in center screen bottom bar
			if (keytime>=CustomKeyTime) {
				PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
				extern void ReinitScreen(void);
				ReinitScreen();
				return 0;
			}
#endif

			// REAL USAGE, ALWAYS ACTIVATE 
			#if (1)
			// standard configurable mode
			if (keytime >=CustomKeyTime) {
				// 0 is center key
				if (CustomKeyHandler(CKI_BOTTOMCENTER)) return 0;
			}
			#endif

			// normally, we fall down here.
			// If CustomKeyHandler returned false, back as well here (nothing configured in custom).
			//
			///// If we are clicking on center bottom bar while still in welcome page, set map before nextmode.
			NextModeIndex();
			MapWindow::RefreshMap();
			SoundModeIndex();

			return 0;
		// End click on navboxes 
		} else 
		// CLICK ON SORTBOX line at the top, only with no map and only for enabled pages
		if ( (Y<=SortBoxY[MapSpaceMode]) &&
			( MapSpaceMode == MSM_LANDABLE || MapSpaceMode==MSM_AIRPORTS || 
			MapSpaceMode==MSM_NEARTPS || MapSpaceMode==MSM_TRAFFIC ||
			MapSpaceMode==MSM_AIRSPACES || MapSpaceMode==MSM_THERMALS ||
			MapSpaceMode==MSM_COMMON || MapSpaceMode==MSM_RECENT) ) {

			// only search for 1-3, otherwise it's the fourth (fifth really)
			// we don't use 0 now
			for (i=0, j=4; i<4; i++) { // i=1 original 090925 FIX
				if (X <SortBoxX[MapSpaceMode][i]) {
					j=i;
					break;
				}
			}

			#if 0 // 121123 CHECK AND REMOVE
			// 120504 if we are clicking on the already selected sort button, within the same mapspacemode,
			// then simulate a gesture down to advance to next page, if available.
			if ( (MapSpaceMode==oldMapSpaceMode && SortedMode[MapSpaceMode]==j)  ||
			     (MapSpaceMode==MSM_COMMON) || (MapSpaceMode==MSM_RECENT) ) {
				vkmode=LKGESTURE_DOWN;
				goto shortcut_gesture;
			} else {
				oldMapSpaceMode=MapSpaceMode; // becomes current
			}
			#else
			if ( (SortedMode[MapSpaceMode]==j)  ||
			     (MapSpaceMode==MSM_COMMON) || (MapSpaceMode==MSM_RECENT) ) {
				vkmode=LKGESTURE_DOWN;
				goto shortcut_gesture;
			}
			#endif

			switch(MapSpaceMode) {
				case MSM_LANDABLE:
				case MSM_AIRPORTS:
				case MSM_NEARTPS:
							SortedMode[MapSpaceMode]=j;
							LKForceDoNearest=true;
							PlayResource(TEXT("IDR_WAV_CLICK"));
							break;
				case MSM_TRAFFIC:
							SortedMode[MapSpaceMode]=j;
							// force immediate resorting
							LastDoTraffic=0;
							PlayResource(TEXT("IDR_WAV_CLICK"));
							break;
				case MSM_AIRSPACES:
							SortedMode[MapSpaceMode]=j;
							PlayResource(TEXT("IDR_WAV_CLICK"));
							break;

				case MSM_THERMALS:
							SortedMode[MapSpaceMode]=j;
							// force immediate resorting
							LastDoThermalH=0;
							PlayResource(TEXT("IDR_WAV_CLICK"));
							break;
				default:
							DoStatusMessage(_T("ERR-022 UNKNOWN MSM in VK"));
							break;
			}
			SelectedPage[MapSpaceMode]=0;
			SelectedRaw[MapSpaceMode]=0;
			MapWindow::RefreshMap();

			return 0;
		// end sortbox
		}  
	// end newmap  with no gestures
	}

	// REAL virtual keys
	// Emulate real keypresses with wParam

shortcut_gesture:
	// UP gesture
	if (vkmode>LKGESTURE_NONE) {
		// WE MANAGE GESTURES IN ALL MAPSPACES
		switch(MapSpaceMode) {
			case MSM_LANDABLE:
			case MSM_AIRPORTS:
			case MSM_NEARTPS:
						LKForceDoNearest=true;
						numpages=Numpages;
						break;
			case MSM_COMMON:
						LKForceDoCommon=true;
						numpages=Numpages;
						break;
			case MSM_RECENT:
						LKForceDoRecent=true;
						numpages=Numpages;
						break;
			case MSM_AIRSPACES:
						numpages=Numpages;
						break;
			case MSM_TRAFFIC:
						numpages=Numpages;
						break;
			case MSM_THERMALS:
						numpages=Numpages;
						break;
			default:
						break;
		}
		SelectedRaw[MapSpaceMode]=0;

		switch(vkmode) {
			// SCROLL DOWN
			case LKGESTURE_DOWN:
				// no pagedown for main map.. where do you want to go??
				if (NOTANYPAN && IsMultiMapNoMain()) {
					LKevent=LKEVENT_PAGEDOWN;
					MapWindow::RefreshMap();
					return 0;
				}
				// careful, selectedpage starts from 0
				if (++SelectedPage[MapSpaceMode] >=numpages) {
					PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
					SelectedPage[MapSpaceMode]=0;
				} else {
					PlayResource(TEXT("IDR_WAV_CLICK"));
				}
				LKevent=LKEVENT_NEWPAGE;
				MapWindow::RefreshMap();
				return 0;
			// SCROLL UP
			case LKGESTURE_UP:
				// no pagedown for main map.. where do you want to go??
				if (NOTANYPAN && IsMultiMapNoMain()) {
					LKevent=LKEVENT_PAGEUP;
					MapWindow::RefreshMap();
					return 0;
				}
				if (--SelectedPage[MapSpaceMode] <0) {
					PlayResource(TEXT("IDR_WAV_CLICK"));
					SelectedPage[MapSpaceMode]=(numpages-1);
				} else {
					if (SelectedPage[MapSpaceMode]==0) {
						PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
					} else {
						PlayResource(TEXT("IDR_WAV_CLICK"));
					}
				}
				LKevent=LKEVENT_NEWPAGE;
				MapWindow::RefreshMap();
				return 0;
			case LKGESTURE_RIGHT:
gesture_right:
				NextModeType();
				MapWindow::RefreshMap();

                    // Notice: MultiMap has its own sounds. We come here when switching pages, but with
					// an exception: from moving map we generate currently a direct NextModeType from
					// MapWndProc, and thus we dont get ProcessVirtualKeys for that single case.	
					// We should not be playing a CLICK sound while we are playing the MM tone, or
					// it wont come up !
					if (ModeIndex!=LKMODE_MAP) {
						if (CURTYPE == 0)
							PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
						else
							PlayResource(TEXT("IDR_WAV_CLICK"));
					}
				return 0;

				break;

			case LKGESTURE_LEFT:
gesture_left:
				PreviousModeType();
				MapWindow::RefreshMap();
                if (ModeIndex!=LKMODE_MAP) {
                    if (CURTYPE == 0)
                        PlayResource(TEXT("IDR_WAV_HIGHCLICK"));
                    else
                        PlayResource(TEXT("IDR_WAV_CLICK"));
                }
				return 0;

				break;
			default:
				return 0;
		}

		return 0;
	}

	if (!MapWindow::mode.AnyPan() && (IsMultiMap()||MapSpaceMode==MSM_MAPTRK)) {
		if (keytime>=(VKSHORTCLICK*4)) {
			LKevent=LKEVENT_LONGCLICK;
			MapWindow::RefreshMap();
			return 0;
		}
	}

	// UNGESTURES: 
	// No need to use gestures if clicking on right or left center border screen
	// This will dramatically speed up the user interface in turbulence
	if (dontdrawthemap) {
		if (Y>longpress_yup && Y<longpress_ydown) {
			if (UseUngestures || !ISPARAGLIDER) {
				if (X<=MapWindow::X_Left)  goto gesture_left;
				if (X>=MapWindow::X_Right) goto gesture_right;
			}
		}
	}

	///
	/// REMOVE. ActiveMap always false
	///
	///if (!MapWindow::mode.AnyPan() && IsMultiMapNoMain() && ActiveMap) {
	///	LKevent=LKEVENT_SHORTCLICK;
	///	MapWindow::RefreshMap();
	///	return 0;
	///}

	if (Y<yup) {
		// we are processing up/down in mapspacemode i.e. browsing waypoints on the page
		if (dontdrawthemap) {
			if (MapSpaceMode<=MSM_MAP) {
				// DoStatusMessage(_T("DBG-032-A event up not used here"));
				return 0;
			}
        	PlayResource(TEXT("IDR_WAV_CLICK"));
			LKevent=LKEVENT_UP;
			MapWindow::RefreshMap();
			// DoStatusMessage(_T("DBG-032-B event up used here"));
			return 0;
		}
        PlayResource(TEXT("IDR_WAV_CLICK"));
		if (keytime>=VKTIMELONG)
			return 0xc1;
		else
			return 38;
	}
	if (Y>ydown) {
		if (dontdrawthemap) {
			if (MapSpaceMode<=MSM_MAP) return 0;
        	PlayResource(TEXT("IDR_WAV_CLICK"));
			LKevent=LKEVENT_DOWN;
			MapWindow::RefreshMap();
			return 0;
		}
        PlayResource(TEXT("IDR_WAV_CLICK"));
		if (keytime>=VKTIMELONG)
			return 0xc2;
		else
			return 40;
	}

	// This will not be detected in case of UP and DOWN was detected, of course.
	// We must handle this separately, before checking for UP DOWN, above.
	if (!MapWindow::mode.AnyPan() && IsMultiMap()) {
		LKevent=LKEVENT_SHORTCLICK;
		MapWindow::RefreshMap();
		return 0;
	}

	// no click for already clicked events


		// If in mapspacemode process ENTER 
		if ( (keytime>=(VKSHORTCLICK*2)) && dontdrawthemap && !IsMultiMap()) {
			LKSound(_T("LK_BEEP1.WAV"));
			LKevent=LKEVENT_ENTER;
			MapWindow::RefreshMap();
			return 0;
		}
/*
		// do not process enter in panmode, unused
		if ( !MapWindow::mode.AnyPan() ) {
	             DoStatusMessage(_T("Virtual ENTER")); 
		     return 13;
		}
*/

		//
		// Here we are when short clicking in the center area, not an up and not a down.. a center.
		// We do nothing.
		//


		if (SIMMODE) {
			if ( MapWindow::mode.AnyPan() && ISPARAGLIDER) return 99; // 091221 return impossible value
			else return 0;
		} else {
			return 0;
		}
	DoStatusMessage(_T("VirtualKey Error")); 
	return 0;
}
コード例 #9
0
void MapWindow::LKDrawVario(LKSurface& Surface, const RECT& rc) {

    static PixelRect vrc, mrc, hrc, htrc, hbrc;

    static BrushReference greenBrush, darkyellowBrush, orangeBrush, redBrush;
    static BrushReference lakeBrush, blueBrush, indigoBrush;

    static PenReference borderPen; // Pen for border of vario bar and vario bricks ( white or black)
    static BrushReference forgroundBrush; // Brush used for draw middle thick or monochrome brick ( same color of borderPen )

    /* 
     * this array define vario Value for each brick, ( positive value )
     *  Number of brick for positive value is defined by this array size.
     */
    static const double positive_vario_step[] = {0.05, 0.25, 0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 2.00, 2.50, 3.00, 3.50, 4.50, 5.00, 6.00, 7.00};
    static const unsigned positive_brick_count = array_size(positive_vario_step);

    static BrushReference positiveBrush[positive_brick_count];
    static PixelRect positiveBricks[positive_brick_count];

    /* 
     * this array define vario Value for each brick, ( negative value )
     *  Number of brick for negative value is defined by this array size.
     */
    static const double negative_vario_step[] = {-0.05, -0.25, -0.50, -0.75, -1.00, -1.25, -1.50, -1.75, -2.00, -2.50, -3.00, -3.50, -4.50, -5.00, -6.00, -7.00};
    static const unsigned negative_brick_count = array_size(negative_vario_step);

    static BrushReference negativeBrush[negative_brick_count];
    static PixelRect negativeBricks[negative_brick_count];

    static short startInitCounter = 0;
    static bool dogaugeinit = true;
    static double max_positiveGload;
    static double max_negativeGload;

    if (DoInit[MDI_DRAWVARIO]) {

        const int boxthick = IBLSCALE(BOXTHICK);
        const int hpixelseparate = (LKVarioBar > vBarVarioGR) ? 0 : IBLSCALE(PIXELSEPARATE);
        const int vpixelseparate = IBLSCALE(PIXELSEPARATE);
        const int variowidth = LKVarioSize;

        startInitCounter = 0;
        dogaugeinit = true;

        // initial fullscale G loads for 2D driving.
        // These values are then rescaled (only increased) automatically.
        max_positiveGload = 0.1;
        max_negativeGload = -0.1;


        borderPen = (BgMapColor > POSCOLOR) ? LKPen_White_N0 : LKPen_Black_N0;
        forgroundBrush = (BgMapColor > POSCOLOR) ? LKBrush_White : LKBrush_Black;
        
        greenBrush = LKBrush_Green;
        darkyellowBrush = LKBrush_DarkYellow2;
        orangeBrush = LKBrush_Orange;
        redBrush = LKBrush_Red;
        lakeBrush = LKBrush_Lake;
        blueBrush = LKBrush_Blue;
        indigoBrush = LKBrush_Indigo;


        const short lkvariobar = (LKVarioBar > vBarVarioGR) ? LKVarioBar - vBarVarioGR : LKVarioBar;
        switch (lkvariobar) {
            default:
                LKASSERT(false); // wrong config value or disabled, in any case, it's BUG
                // no break; for avoid to have unitialized Brush array.
            case vBarVarioColor:
                // set default background in case of missing values
                std::fill(std::begin(positiveBrush), std::end(positiveBrush), forgroundBrush);
                std::fill(std::begin(negativeBrush), std::end(negativeBrush), forgroundBrush);
                
                static_assert(array_size(positiveBrush)> 15, "\"positiveBrush\" size must be greater than 15, check \"positive_vario_step\" size");
                
                positiveBrush[15] = redBrush;
                positiveBrush[14] = redBrush;
                positiveBrush[13] = redBrush;
                positiveBrush[12] = redBrush;
                positiveBrush[11] = orangeBrush;
                positiveBrush[10] = orangeBrush;
                positiveBrush[9] = orangeBrush;
                positiveBrush[8] = orangeBrush;
                positiveBrush[7] = darkyellowBrush;
                positiveBrush[6] = darkyellowBrush;
                positiveBrush[5] = darkyellowBrush;
                positiveBrush[4] = darkyellowBrush;
                positiveBrush[3] = greenBrush;
                positiveBrush[2] = greenBrush;
                positiveBrush[1] = greenBrush;
                positiveBrush[0] = greenBrush;

                negativeBrush[0] = lakeBrush;
                negativeBrush[1] = lakeBrush;
                negativeBrush[2] = lakeBrush;
                negativeBrush[3] = lakeBrush;
                negativeBrush[4] = blueBrush;
                negativeBrush[5] = blueBrush;
                negativeBrush[6] = blueBrush;
                negativeBrush[7] = blueBrush;
                negativeBrush[8] = indigoBrush;
                negativeBrush[9] = indigoBrush;
                negativeBrush[10] = indigoBrush;
                negativeBrush[11] = indigoBrush;
                negativeBrush[12] = forgroundBrush;
                negativeBrush[13] = forgroundBrush;
                negativeBrush[14] = forgroundBrush;
                negativeBrush[15] = forgroundBrush;

                static_assert(array_size(negativeBrush)> 15, "\"negativeBrush\" size must be greater than 15, check \"negative_vario_step\" size");

                break;
            case vBarVarioMono:
                std::fill(std::begin(positiveBrush), std::end(positiveBrush), forgroundBrush);
                std::fill(std::begin(negativeBrush), std::end(negativeBrush), forgroundBrush);
                break;
            case vBarVarioRB:
                std::fill(std::begin(positiveBrush), std::end(positiveBrush), redBrush);
                std::fill(std::begin(negativeBrush), std::end(negativeBrush), blueBrush);
                break;
            case vBarVarioGR:
                std::fill(std::begin(positiveBrush), std::end(positiveBrush), greenBrush);
                std::fill(std::begin(negativeBrush), std::end(negativeBrush), redBrush);
                break;
        }

        // vario paint area
        vrc.left = rc.left;
        vrc.top = rc.top;
        vrc.right = vrc.left + variowidth;
        vrc.bottom = rc.bottom - BottomSize;

        // meter area
        mrc.left = vrc.left + hpixelseparate;
        mrc.top = vrc.top + vpixelseparate;
        mrc.right = vrc.right - hpixelseparate;
        mrc.bottom = vrc.bottom - vpixelseparate;

        // half vario separator for positive and negative values
        const double vmiddle_height = NIBLSCALE(2) - ((mrc.bottom - mrc.top) % 2);
        const double vmiddle = ((mrc.bottom - mrc.top) / 2.0) + mrc.top;

        hrc.top = vrc.top + vmiddle - (vmiddle_height / 2);
        hrc.bottom = vrc.top + vmiddle + (vmiddle_height / 2);
        hrc.left = vrc.left;
        hrc.right = vrc.right;

        // half top meter area
        htrc.left = mrc.left;
        htrc.right = mrc.right;
        htrc.bottom = hrc.top - vpixelseparate;
        htrc.top = mrc.top + vpixelseparate;

        // half bottom meter area
        hbrc.left = mrc.left;
        hbrc.right = mrc.right;
        hbrc.top = hrc.bottom + vpixelseparate;
        hbrc.bottom = mrc.bottom - vpixelseparate;

        // pixel height of each positive brick
        const int positive_brick_size = (htrc.bottom - htrc.top - (boxthick * (positive_brick_count - 1))) / positive_brick_count;
        const int positive_brick_advance = positive_brick_size + boxthick;

        // Pre-calculate brick positions for half top
        for (unsigned i = 0; i < positive_brick_count; ++i) {
            RECT& brc = positiveBricks[i];
            brc.left = htrc.left;
            brc.right = htrc.right - NIBLSCALE(4);
            brc.bottom = htrc.bottom - (i * positive_brick_advance);
            brc.top = brc.bottom - positive_brick_size;
        }
        // update last box for hide rounding artefact 
        positiveBricks[positive_brick_count - 1].top = htrc.top;

        // pixel height of each negative brick
        const int negative_brick_size = (hbrc.bottom - hbrc.top - (boxthick * (negative_brick_count - 1))) / negative_brick_count;
        const int negative_brick_advance = negative_brick_size + boxthick;

        // Pre-calculate brick positions for half bottom
        for (unsigned i = 0; i < negative_brick_count; ++i) {
            RECT& brc = negativeBricks[i];
            brc.left = hbrc.left;
            brc.right = hbrc.right - NIBLSCALE(4);
            brc.top = hbrc.top + (i * negative_brick_advance);
            brc.bottom = brc.top + negative_brick_size;
        }
        // update last box for hide rounding artefact 
        negativeBricks[negative_brick_count - 1].bottom = hbrc.bottom;

        DoInit[MDI_DRAWVARIO] = false;
    } // END of INIT

    double vario_value = 0; // can be vario, vario netto or STF offset, depending of config and map mode
    double mc_value = 0; // current MacCready value, used only for Vario or VarioNetto.

    if (ISCAR && DrawInfo.Speed > 0) {
        // Heading is setting Gload, but Heading is not calculated while steady!
        // For this case, we force vario_value to 0.
        //
        // Since we use currently a scale 0-6 for vario, we can use 0-2 for cars.
        // This accounts for an acceleration topscale of 0-100kmh in 13.9 seconds.
        // Not a big acceleration, but very good for normal car usage.
        // We make this concept dynamical, and different for positive and negative accelerations.
        // Because negative accelerations are much higher, on a car. Of course!
        //
        if (DerivedDrawInfo.Gload > 0) {
            if (DerivedDrawInfo.Gload > max_positiveGload) {
                max_positiveGload = DerivedDrawInfo.Gload;
                StartupStore(_T("..... NEW MAXPOSITIVE G=%f\n"), max_positiveGload);
            }
            LKASSERT(max_positiveGload > 0);
            vario_value = (DerivedDrawInfo.Gload / max_positiveGload)*6;
            //StartupStore(_T("Speed=%f G=%f max=%f val=%f\n"),DrawInfo.Speed, DerivedDrawInfo.Gload, max_positiveGload,vario_value);
        }
        if (DerivedDrawInfo.Gload < 0) {
            if (DerivedDrawInfo.Gload < max_negativeGload) {
                max_negativeGload = DerivedDrawInfo.Gload;
                StartupStore(_T("..... NEW MAXNEGATIVE G=%f\n"), max_negativeGload);
            }
            LKASSERT(max_negativeGload < 0);
            vario_value = (DerivedDrawInfo.Gload / max_negativeGload)*-6;
            //StartupStore(_T("Speed=%f G=%f max=%f val=%f\n"),DrawInfo.Speed, DerivedDrawInfo.Gload, max_negativeGload,vario_value);
        }

    } else if (MapWindow::mode.Is(MapWindow::Mode::MODE_CIRCLING) || LKVarioVal == vValVarioVario) {
        if (DrawInfo.VarioAvailable) {
            // UHM. I think we are not painting values correctly for knots &c.
            //vario_value = LIFTMODIFY*DrawInfo.Vario;
            vario_value = DrawInfo.Vario;
        } else {
            vario_value = DerivedDrawInfo.Vario;
        }
        mc_value = MACCREADY;
    } else {
        switch (LKVarioVal) {
            default:
            case vValVarioNetto:
                vario_value = DerivedDrawInfo.NettoVario;
                // simple hack for avoid to used polar curve : glider_sink_rate = Vario - NettoVario;
                mc_value = MACCREADY + (DerivedDrawInfo.Vario - DerivedDrawInfo.NettoVario);
                break;
            case vValVarioSoll:
                double ias;
                if (DrawInfo.AirspeedAvailable && DrawInfo.VarioAvailable)
                    ias = DrawInfo.IndicatedAirspeed;
                else
                    ias = DerivedDrawInfo.IndicatedAirspeedEstimated;

                // m/s 0-nnn autolimit to 20m/s full scale (72kmh diff)
                vario_value = clamp(DerivedDrawInfo.VOpt - ias, -20., 20.);
                vario_value /= 3.3333; // 0-20  -> 0-6
                vario_value *= -1; // if up, push down
                break;
        }
    }


    // Backup selected Brush & Pen
    LKSurface::OldPen oldPen = Surface.SelectObject(LK_NULL_PEN);
    LKSurface::OldBrush oldBrush = Surface.SelectObject(LKBrush_Hollow);
    
    // draw Vario box ( only if not transparent )
    if (LKVarioBar <= vBarVarioGR) {
        Surface.SelectObject(borderPen);
        Surface.SelectObject(hInvBackgroundBrush[BgMapColor]);
        Surface.Rectangle(vrc.left, vrc.top, vrc.right, vrc.bottom);
    }
    // draw middle separator for 0 scale indicator
    Surface.FillRect(&hrc, forgroundBrush);

    Surface.SelectObject(borderPen);
    if (dogaugeinit) {

        // this is causing problems on emulators and condor and most of the times when the gps has no valid date
        // so we don't use seconds, but loop counter
        if (startInitCounter++ > 2) {
            dogaugeinit = false;
        }

        // Demo show all bricks
        for (unsigned i = 0; i < positive_brick_count; ++i) {
            const RECT& brc = positiveBricks[i];
            Surface.SelectObject(positiveBrush[i]);
            Surface.Rectangle(brc.left, brc.top, brc.right, brc.bottom);
        }

        for (unsigned i = 0; i < negative_brick_count; ++i) {
            const RECT& brc = negativeBricks[i];
            Surface.SelectObject(negativeBrush[i]);
            Surface.Rectangle(brc.left, brc.top, brc.right, brc.bottom);
        }

    } else {
        // Draw Real Vario Data

        // Draw Positive Brick 
        for (unsigned i = 0; i < positive_brick_count && vario_value >= positive_vario_step[i]; ++i) {
            const RECT& brc = positiveBricks[i];
            Surface.SelectObject(positiveBrush[i]);
            Surface.Rectangle(brc.left, brc.top, brc.right, brc.bottom);
        }

        // Draw Negative Brick 
        for (unsigned i = 0; i < negative_brick_count && vario_value <= negative_vario_step[i]; ++i) {
            const RECT& brc = negativeBricks[i];
            Surface.SelectObject(negativeBrush[i]);
            Surface.Rectangle(brc.left, brc.top, brc.right, brc.bottom);
        }

        // Draw MacCready Indicator
        const auto step_iterator = std::upper_bound(std::begin(positive_vario_step), std::end(positive_vario_step), mc_value);
        size_t mc_brick_idx = std::distance(std::begin(positive_vario_step), step_iterator);
        if (mc_brick_idx > 1) {
            const PixelRect& brc_next = positiveBricks[mc_brick_idx];
            const PixelRect& brc_Prev = positiveBricks[mc_brick_idx-1];
            
            const PixelSize IconSize = hMcVario.GetSize();
            const PixelSize DrawSize = {
                vrc.GetSize().cx,
                IconSize.cy * vrc.GetSize().cx / IconSize.cx
            };
            const RasterPoint DrawPos = {
                vrc.left,
                brc_Prev.top + ((brc_next.bottom - brc_Prev.top) / 2) + (IconSize.cy / 2)
            };
            hMcVario.Draw(Surface, DrawPos.x, DrawPos.y, DrawSize.cx, DrawSize.cy);
        }
    }
    // cleanup
    Surface.SelectObject(oldPen);
    Surface.SelectObject(oldBrush);
}
コード例 #10
0
ファイル: LoadCupTask.cpp プロジェクト: PhilColbert/LK8000
    void UpdateTask() {
        if (mA1 == 180.0) {
            if (mIdx == 0) {
                StartLine = 0;
                StartRadius = mR1;
            } else if (mIdx == (size_t) getFinalWaypoint()) {
                FinishLine = 0;
                FinishRadius = mR1;
            } else {
                Task[mIdx].AATType = CIRCLE;
                Task[mIdx].AATCircleRadius = mR1;
            }
        } else {

            switch (mType) {
                case 0: // - Fixed value,
                    if (mLine) {
                        StartupStore(_T("..Cup Task : \"Fixed\" LINE Turnpoint is not supported%s"), NEWLINE);
                        UpdateFixedLine();
                    } else {
                        UpdateFixedSector();
                    }
                    break;
                case 1: // - Symmetrical, 
                    if (mLine) {
                        StartupStore(_T("..Cup Task : \"Symmetrical\" LINE Turnpoint is not supported%s"), NEWLINE);
                        UpdateSymLine();
                    } else {
                        UpdateSymSector();
                    }
                    break;
                case 2: // - To next point, 
                    if (mLine) {
                        if (mIdx > 0) {
                            StartupStore(_T("..Cup Task : \"To next point\" LINE Turnpoint is not supported%s"), NEWLINE);
                        }
                        UpdateToNextLine();
                    } else {
                        UpdateToNextSector();
                    }
                    break;
                case 3: // - To previous point, 
                    if (mLine) {
                        if (mIdx < (size_t) getFinalWaypoint()) {
                            StartupStore(_T("..Cup Task : \"To previous point\" LINE Turnpoint is not supported%s"), NEWLINE);
                        }
                        UpdateToPrevLine();
                    } else {
                        UpdateToPrevSector();
                    }
                    break;
                case 4: // - To start point
                    if (mLine) {
                        StartupStore(_T("..Cup Task : \"To start point\" LINE Turnpoint is not supported%s"), NEWLINE);
                        UpdateToStartLine();
                    } else {
                        UpdateToStartSector();
                    }
                    break;
            }
        }
    }
コード例 #11
0
ファイル: Process.cpp プロジェクト: jarda-manana/LK8000
/*
	1	Next waypoint
	0	Show waypoint details
	-1	Previous waypoint
	2	Next waypoint with wrap around
	-2	Previous waypoint with wrap around
*/
void NextUpDown(int UpDown)
{

  if (!ValidTaskPoint(ActiveWayPoint)) {	// BUGFIX 091116
	StartupStore(_T(". DBG-801 activewaypoint%s"),NEWLINE);
	return;
  }

  LockTaskData();

  if(UpDown>0) {
    // this was a bug. checking if AWP was < 0 assuming AWP if inactive was -1; actually it can also be 0, a bug is around
    if(ActiveWayPoint < MAXTASKPOINTS) {
      // Increment Waypoint
      if(Task[ActiveWayPoint+1].Index >= 0) {
	if(ActiveWayPoint == 0)	{
	  // manual start
	  // TODO bug: allow restart
	  // TODO bug: make this work only for manual
	  if (CALCULATED_INFO.TaskStartTime==0) {
	    CALCULATED_INFO.TaskStartTime = GPS_INFO.Time;
	  }
	}
	ActiveWayPoint ++;
	AdvanceArmed = false;
	CALCULATED_INFO.LegStartTime = GPS_INFO.Time ;
      }
      // No more, try first
      else 
        if((UpDown == 2) && (Task[0].Index >= 0)) {
          /* ****DISABLED****
          if(ActiveWayPoint == 0)	{
            // TODO bug: allow restart
            // TODO bug: make this work only for manual
            
            // TODO bug: This should trigger reset of flight stats, but 
            // should ask first...
            if (CALCULATED_INFO.TaskStartTime==0) {
              CALCULATED_INFO.TaskStartTime = GPS_INFO.Time ;
            }            
          }
          */
          AdvanceArmed = false;
          ActiveWayPoint = 0;
          CALCULATED_INFO.LegStartTime = GPS_INFO.Time ;
        }
    }
  }
  else if (UpDown<0){
    if(ActiveWayPoint >0) {

      ActiveWayPoint --;
      /*
	XXX How do we know what the last one is?
	} else if (UpDown == -2) {
	ActiveWayPoint = MAXTASKPOINTS;
      */
    } else {
      if (ActiveWayPoint==0) {

        RotateStartPoints();

	// restarted task..
	//	TODO bug: not required? CALCULATED_INFO.TaskStartTime = 0;
      }
    }
    aatdistance.ResetEnterTrigger(ActiveWayPoint);    
  } 
  else if (UpDown==0) {
    SelectedWaypoint = Task[ActiveWayPoint].Index;
    PopupWaypointDetails();
  }
  if (ActiveWayPoint>=0) {
    SelectedWaypoint = Task[ActiveWayPoint].Index;
  }
  UnlockTaskData();
}
コード例 #12
0
ファイル: LoadCupTask.cpp プロジェクト: PhilColbert/LK8000
bool LoadCupTask(LPCTSTR szFileName) {
    LockTaskData();

    mapCode2Waypoint_t mapWaypoint;

    ClearTask();
    size_t idxTP = 0;
    bool bTakeOff = true;
    bool bLoadComplet = true;
    bool bLastInvalid=true;

    TCHAR szString[READLINE_LENGTH + 1];
    TCHAR TpCode[NAME_SIZE + 1];

    szString[READLINE_LENGTH] = _T('\0');
    TpCode[NAME_SIZE] = _T('\0');

    memset(szString, 0, sizeof (szString)); // clear Temp Buffer
    WAYPOINT newPoint = {0};
    WAYPOINT* WPtoAdd=NULL;

    enum {
        none, Waypoint, TaskTp, Option
    } FileSection = none;
    FILE * stream = _tfopen(szFileName, _T("rt"));
    if (stream) {
        charset cs = charset::unknown;
        while (ReadStringX(stream, READLINE_LENGTH, szString, cs)) {

            if ((FileSection == none) && ((_tcsncmp(_T("name,code,country"), szString, 17) == 0) ||
                    (_tcsncmp(_T("Title,Code,Country"), szString, 18) == 0))) {
                FileSection = Waypoint;
                continue;
            } else if ((FileSection == Waypoint) && (_tcscmp(szString, _T("-----Related Tasks-----")) == 0)) {
                FileSection = TaskTp;
                continue;
            }

            TCHAR *pToken = NULL;
            TCHAR *pWClast = NULL;

            switch (FileSection) {
                case Waypoint:
                    memset(&newPoint, 0, sizeof(newPoint));
                    if (ParseCUPWayPointString(szString, &newPoint)) {
                        mapWaypoint[newPoint.Name] = newPoint;
                    }
                    break;
                case TaskTp:
                    // 1. Description
                    //       First column is the description of the task. If filled it should be double quoted.
                    //       If left empty, then SeeYou will determine the task type on runtime.
                    if ((pToken = strsep_r(szString, TEXT(","), &pWClast)) == NULL) {
                        UnlockTaskData();
                        return false;
                    }

                    // 2. and all successive columns, separated by commas
                    //       Each column represents one waypoint name double quoted. The waypoint name must be exactly the
                    //       same as the Long name of a waypoint listed above the Related tasks.
                    WPtoAdd=NULL;
                    while (bLoadComplet && (pToken = strsep_r(NULL, TEXT(","), &pWClast)) != NULL) {
                        if (idxTP < MAXTASKPOINTS) {
                            _tcsncpy(TpCode, pToken, NAME_SIZE);
                            CleanCupCode(TpCode);
                            mapCode2Waypoint_t::iterator It = mapWaypoint.find(TpCode);
                            if(!ISGAAIRCRAFT) {
                                if (It != mapWaypoint.end()) {
                                    if (bTakeOff) {
                                        // skip TakeOff Set At Home Waypoint
                                        int ix = FindOrAddWaypoint(&(It->second),false);
                                        if (ix>=0) {
                                            #if 0 // REMOVE
                                            // We must not change HomeWaypoint without user knowing!
                                            // The takeoff and homewaypoint are independent from task.
                                            // In addition, this is a bug because on next run the index is invalid
                                            // and we have no more HowWaypoint!
                                            HomeWaypoint = ix;
                                            #endif
                                            bTakeOff = false;
                                        }
                                        #if BUGSTOP
                                        else LKASSERT(0); // .. else is unmanaged, TODO
                                        #endif
                                    } else {
                                        int ix =  FindOrAddWaypoint(&(It->second),false);
                                        if (ix>=0) Task[idxTP++].Index = ix;
                                        #if BUGSTOP
                                        else LKASSERT(0); // .. else is unmanaged, TODO
                                        #endif
                                    }
                                    bLastInvalid=false;
                                } else {
                                    // An invalid takeoff, probably a "???" , which we ignore
                                    #if TESTBENCH
                                    if (bTakeOff) StartupStore(_T("....... CUP Takeoff not found: <%s>\n"),TpCode);
                                    #endif
                                    // in any case bTakeOff now is false
                                    bTakeOff=false;
                                    bLastInvalid=true;
                                }
                            } else { //ISGAIRRCRAFT
                                if(It != mapWaypoint.end()) {
                                    if(WPtoAdd!=NULL) {
                                        //add what we found in previous cycle: it was not the last one
                                        int ix = FindOrAddWaypoint(WPtoAdd,false); 
                                        if (ix>=0) Task[idxTP++].Index = ix;
                                        #if BUGSTOP
                                        else LKASSERT(0); // .. else is unmanaged, TODO
                                        #endif
                                    }
                                    if (bTakeOff) { //it's the first: may be we have a corresponding airfield
                                        //look for departure airfield and add it
                                        int ix = FindOrAddWaypoint(&(It->second),true); 
                                        if (ix>=0) {
                                            Task[idxTP++].Index = ix;
                                            bTakeOff = false;
                                        } 
                                        #if BUGSTOP
                                        else LKASSERT(0); // .. else is unmanaged, TODO
                                        #endif
                                    } else WPtoAdd=&(It->second); //store it for next cycle (may be it is the last one)
                                }
                            }
                        } else {
                            bLoadComplet = false;
                        }
                    }
                    if(ISGAAIRCRAFT) { //For GA: check if we have an airport corresponding to the last WP
                        if(WPtoAdd!=NULL) { //if we have the last one (probably an airfield) still to add...
                            if(idxTP<MAXTASKPOINTS) {
                                int ix=FindOrAddWaypoint(WPtoAdd,true); //look for arrival airport and add it
                                if (ix>=0) {
                                    Task[idxTP++].Index= ix;
                                }
                                #if BUGSTOP
                                else LKASSERT(0); // .. else is unmanaged, TODO
                                #endif
                            }
                            else bLoadComplet=false;
                        }
                    }
                    FileSection = Option;
                break;
                case Option:
                    if ((pToken = strsep_r(szString, TEXT(","), &pWClast)) != NULL) {
                        if (_tcscmp(pToken, _T("Options")) == 0) {
                            while ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) != NULL) {
                                if (_tcsstr(pToken, _T("NoStart=")) == pToken) {
                                    // Opening of start line
                                    PGNumberOfGates = 1;
                                    StrToTime(pToken + 8, &PGOpenTimeH, &PGOpenTimeM);
                                } else if (_tcsstr(pToken, _T("TaskTime=")) == pToken) {
                                    // Designated Time for the task
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("WpDis=")) == pToken) {
                                    // Task distance calculation. False = use fixes, True = use waypoints
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("NearDis=")) == pToken) {
                                    // Distance tolerance
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("NearAlt=")) == pToken) {
                                    // Altitude tolerance
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("MinDis=")) == pToken) {
                                    // Uncompleted leg. 
                                    // False = calculate maximum distance from last observation zone.
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("RandomOrder=")) == pToken) {
                                    // if true, then Random order of waypoints is checked
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("MaxPts=")) == pToken) {
                                    // Maximum number of points
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("BeforePts=")) == pToken) {
                                    // Number of mandatory waypoints at the beginning. 1 means start line only, two means
                                    //      start line plus first point in task sequence (Task line).
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("AfterPts=")) == pToken) {
                                    // Number of mandatory waypoints at the end. 1 means finish line only, two means finish line
                                    //      and one point before finish in task sequence (Task line).
                                    // TODO :
                                } else if (_tcsstr(pToken, _T("Bonus=")) == pToken) {
                                    // Bonus for crossing the finish line         
                                    // TODO :
                                }
                            }
                        } else if (_tcsstr(pToken, _T("ObsZone=")) == pToken) {
                            TCHAR *sz = NULL;
                            CupObsZoneUpdater TmpZone;
                            TmpZone.mIdx = _tcstol(pToken + 8, &sz, 10);
                            if (TmpZone.mIdx < MAXSTARTPOINTS) {
                                while ((pToken = strsep_r(NULL, TEXT(","), &pWClast)) != NULL) {
                                    if (_tcsstr(pToken, _T("Style=")) == pToken) {
                                        // Direction. 0 - Fixed value, 1 - Symmetrical, 2 - To next point, 3 - To previous point, 4 - To start point
                                        TmpZone.mType = _tcstol(pToken + 6, &sz, 10);
                                    } else if (_tcsstr(pToken, _T("R1=")) == pToken) {
                                        // Radius 1
                                        TmpZone.mR1 = ReadLength(pToken + 3);
                                    } else if (_tcsstr(pToken, _T("A1=")) == pToken) {
                                        // Angle 1 in degrees
                                        TmpZone.mA1 = _tcstod(pToken + 3, &sz);
                                    } else if (_tcsstr(pToken, _T("R2=")) == pToken) {
                                        // Radius 2
                                        TmpZone.mR2 = ReadLength(pToken + 3);
                                    } else if (_tcsstr(pToken, _T("A2=")) == pToken) {
                                        // Angle 2 in degrees
                                        TmpZone.mA2 = _tcstod(pToken + 3, &sz);
                                    } else if (_tcsstr(pToken, _T("A12=")) == pToken) {
                                        // Angle 12
                                        TmpZone.mA12 = _tcstod(pToken + 4, &sz);
                                    } else if (_tcsstr(pToken, _T("Line=")) == pToken) {
                                        // true For Line Turmpoint type 
                                        // Exist only for start an Goalin LK
                                        TmpZone.mLine = (_tcstol(pToken + 5, &sz, 10) == 1);
                                    }
                                }
                                TmpZone.UpdateTask();
                            }
                        }
                    }
                    break;
                case none:
                default:
                    break;
            }
            memset(szString, 0, sizeof (szString)); // clear Temp Buffer
        }
        fclose(stream);
    }
    if(!ISGAAIRCRAFT) {
        // Landing don't exist in LK Task Systems, so Remove It;
        if ( bLoadComplet && !bLastInvalid ) {
            RemoveTaskPoint(getFinalWaypoint());
        }
    }
    UnlockTaskData();
    for (mapCode2Waypoint_t::iterator It = mapWaypoint.begin(); It != mapWaypoint.end(); ++It) {
        if (It->second.Comment) {
            free(It->second.Comment);
        }
        if (It->second.Details) {
            free(It->second.Details);
        }
    }
    mapWaypoint.clear();

    return ValidTaskPoint(0);
}
コード例 #13
0
ファイル: LiveTracker.cpp プロジェクト: Mazuk/LK8000
// Leonardo Live Tracker (www.livetrack24.com) data exchange thread
static DWORD WINAPI LiveTrackerThread (LPVOID lpvoid)
{
    int tracker_fsm = 0;
    livetracker_point_t sendpoint = {0};
    bool sendpoint_valid = false;
    bool sendpoint_processed = false;
    bool sendpoint_processed_old = false;
    // Session variables
    unsigned int packet_id = 0;
    unsigned int session_id = 0;
    int userid = -1;

    _t_end = false;
    _t_run = true;

    srand(GetTickCount());

    do {
        if (WaitForSingleObject(_hNewDataEvent, 5000) == WAIT_OBJECT_0) ResetEvent(_hNewDataEvent);
        if (!_t_run) break;
        do {
            if (1) {
                sendpoint_valid = false;
                CCriticalSection::CGuard guard(_t_mutex);
                if (!_t_points.empty()) {
                    sendpoint = _t_points.front();
                    sendpoint_valid = true;
                }
            } //mutex
            if (sendpoint_valid) {
                sendpoint_processed = false;
                do {
                    switch (tracker_fsm) {
                    default:
                    case 0:   // Wait for flying
                        if (!sendpoint.flying) {
                            sendpoint_processed = true;
                            break;
                        }
                        tracker_fsm++;
                        break;

                    case 1:
                        // Get User ID
                        userid = GetUserIDFromServer();
                        sendpoint_processed = false;
                        if (userid>=0) tracker_fsm++;
                        break;

                    case 2:
                        //Start of track packet
                        sendpoint_processed = SendStartOfTrackPacket(&packet_id, &session_id, userid);
                        if (sendpoint_processed) {
                            StartupStore(TEXT(". Livetracker new track started.%s"),NEWLINE);
                            sendpoint_processed_old = true;
                            tracker_fsm++;
                        }
                        break;

                    case 3:
                        //Gps point packet
                        sendpoint_processed = SendGPSPointPacket(&packet_id, &session_id, &sendpoint);

                        //Connection lost to server
                        if (sendpoint_processed_old && !sendpoint_processed) {
                            StartupStore(TEXT(". Livetracker connection to server lost.%s"), NEWLINE);
                        }
                        //Connection established to server
                        if (!sendpoint_processed_old && sendpoint_processed) {
                            CCriticalSection::CGuard guard(_t_mutex);
                            int queue_size = _t_points.size();
                            StartupStore(TEXT(". Livetracker connection to server established, start sending %d queued packets.%s"), queue_size, NEWLINE);
                        }
                        sendpoint_processed_old = sendpoint_processed;

                        if (!sendpoint.flying) {
                            tracker_fsm++;
                        }
                        break;

                    case 4:
                        //End of track packet
                        sendpoint_processed = SendEndOfTrackPacket(&packet_id, &session_id);
                        if (sendpoint_processed) {
                            StartupStore(TEXT(". Livetracker track finished, sent %d points.%s"), packet_id, NEWLINE);
                            tracker_fsm=0;
                        }
                        break;
                    }// sw

                    if (sendpoint_processed) {
                        CCriticalSection::CGuard guard(_t_mutex);
                        _t_points.pop_front();
                    } else InterruptibleSleep(2500);
                    sendpoint_processed_old = sendpoint_processed;
                } while (!sendpoint_processed && _t_run);
            }
        } while (sendpoint_valid && _t_run);
    } while (_t_run);

    _t_end = true;
    return 0;
}
コード例 #14
0
ファイル: LiveTracker.cpp プロジェクト: Mazuk/LK8000
// Do a transaction with server
// returns received bytes, -1 if transaction failed
static int DoTransactionToServer(char *txbuf, unsigned int txbuflen, char *rxbuf, unsigned int maxrxbuflen)
{
    SOCKET s = INVALID_SOCKET;
    unsigned int sent = 0;
    int tmpres;
    int rxfsm = 0;
    unsigned int rxlen = 0;
    char recvbuf[BUFSIZ];
    unsigned char cdata;

#ifdef LT_DEBUG
    TCHAR utxbuf[500];
    ascii2unicode(txbuf,utxbuf,400);
    StartupStore(TEXT("Livetracker send: %s%s"), utxbuf, NEWLINE);
#endif

    s = EstablishConnection(_server_name);
    if ( s==INVALID_SOCKET ) return -1;

    //Send the query to the server
    while(sent < txbuflen) {
        tmpres = send(s, txbuf+sent, txbuflen-sent, 0);
        if( tmpres == -1 ) return -1;
        sent += tmpres;
    }

    //Receive the page
    while( (tmpres = recv(s, recvbuf, BUFSIZ, 0)) > 0) {
        for (int i=0; i<tmpres; i++) {
            cdata = recvbuf[i];
            switch (rxfsm) {
            default:
            case 0:
                if (cdata=='\r') rxfsm++;
                break;
            case 1:
                if (cdata=='\n') {
                    rxfsm++;
                    break;
                }
                rxfsm=0;
                break;
            case 2:
                if (cdata=='\r') {
                    rxfsm++;
                    break;
                }
                rxfsm=0;
                break;
            case 3:
                if (cdata=='\n') {
                    rxfsm++;
                    rxlen=0;
                    break;
                }
                rxfsm=0;
                break;
            case 4:
                //Content chr
                rxbuf[rxlen] = cdata;
                if (rxlen<maxrxbuflen) rxlen++;
                break;
            }//sw
        } //for
    } //wh
    closesocket(s);
    rxbuf[rxlen]=0;
#ifdef LT_DEBUG
    TCHAR urxbuf[500];
    ascii2unicode(rxbuf,urxbuf,400);
    StartupStore(TEXT("Livetracker recv len=%d: %s%s"), rxlen, urxbuf, NEWLINE);
#endif
    return rxlen;
}
コード例 #15
0
ファイル: WndProc.cpp プロジェクト: rafagdn/LK8000
void Shutdown(void) {
  int i;

  LKSound(_T("LK_DISCONNECT.WAV")); Sleep(500); // real WAV length is 410+ms
  if (!GlobalRunning) { // shutdown on startup (before sim/fly or clicking on the window X)
	StartupStore(_T(". Quick shutdown requested before terminating startup%s"),NEWLINE);
	// force exit mode for the case of being in welcome screen: OnTimerNotify will catch it
	RUN_MODE=RUN_SHUTDOWN;
	CloseCalculations();
	CloseGeoid();
	DeInitCustomHardware();
	LKRunStartEnd(false);
	return;
  }
  // LKTOKEN _@M1219_ "Shutdown, please wait..."
  CreateProgressDialog(gettext(TEXT("_@M1219_")));

  StartupStore(_T(". Entering shutdown %s%s"), WhatTimeIsIt(),NEWLINE);
  MapWindow::Event_Pan(0);  // return from PAN restores the Task in case of Turnpoint moving
  #if TESTBENCH
  StartupLogFreeRamAndStorage();
  #endif

  // turn off all displays
  GlobalRunning = false;

  // LKTOKEN _@M1220_ "Shutdown, saving logs..."
  CreateProgressDialog(gettext(TEXT("_@M1220_")));

  // In case we quit while are still flying
  UpdateLogBook(false); // false=only log if still flying
  // stop logger
  guiStopLogger(true);

  // LKTOKEN _@M1221_ "Shutdown, saving profile..."
  CreateProgressDialog(gettext(TEXT("_@M1221_")));
  extern void LKAircraftSave(const TCHAR *szFile);
  extern void LKPilotSave(const TCHAR *szFile);
  extern void LKDeviceSave(const TCHAR *szFile);
  LKPilotSave(defaultPilotFile);
  LKAircraftSave(defaultAircraftFile);
  LKProfileSave(defaultProfileFile);
  LKDeviceSave(defaultDeviceFile);

  #if TESTBENCH
  StartupStore(TEXT(". Save_Recent_WP_history%s"),NEWLINE);
  #endif
  SaveRecentList();
  // Stop sound

  // Stop drawing
  // LKTOKEN _@M1219_ "Shutdown, please wait..."
  CreateProgressDialog(gettext(TEXT("_@M1219_")));
 
  StartupStore(TEXT(". CloseDrawingThread%s"),NEWLINE);
  // 100526 this is creating problem in SIM mode when quit is called from X button, and we are in waypoint details
  // or probably in other menu related screens. However it cannot happen from real PNA or PDA because we don't have
  // that X button.
  MapWindow::CloseDrawingThread();

  // Stop calculating too (wake up)
  SetEvent(dataTriggerEvent);
  SetEvent(drawTriggerEvent);

  // Clear data
  // LKTOKEN _@M1222_ "Shutdown, saving task..."
  CreateProgressDialog(gettext(TEXT("_@M1222_")));

  #if TESTBENCH
  StartupStore(TEXT(".... Save default task%s"),NEWLINE);
  #endif

  SaveDefaultTask();

  #if TESTBENCH
  StartupStore(TEXT(".... Clear task data%s"),NEWLINE);
  #endif

  LockTaskData();
  Task[0].Index = -1;  ActiveWayPoint = -1; 
  AATEnabled = FALSE;
  CloseWayPoints();
  UnlockTaskData();

  // LKTOKEN _@M1219_ "Shutdown, please wait..."
  CreateProgressDialog(gettext(TEXT("_@M1219_")));
  #if TESTBENCH
  StartupStore(TEXT(".... CloseTerrainTopology%s"),NEWLINE);
  #endif

  RasterTerrain::CloseTerrain();

  CloseTopology();
  #if USETOPOMARKS
  TopologyCloseMarks();
  #endif
  CloseTerrainRenderer();

  LiveTrackerShutdown();

  extern void CloseFlightDataRecorder(void);
  CloseFlightDataRecorder();
  
  // Stop COM devices
  StartupStore(TEXT(". Stop COM devices%s"),NEWLINE);
  devCloseAll();

  CloseFLARMDetails();

  ProgramStarted = psInitInProgress;

  // Kill windows
  #if TESTBENCH
  StartupStore(TEXT(".... Close Messages%s"),NEWLINE);
  #endif
  Message::Destroy();
  #if TESTBENCH 
  StartupStore(TEXT(".... Destroy Button Labels%s"),NEWLINE);
  #endif
  ButtonLabel::Destroy();

  #if TESTBENCH
  StartupStore(TEXT(".... Delete Objects%s"),NEWLINE);
  #endif
  
  // Kill graphics objects

  DeleteObject(hBrushSelected);
  DeleteObject(hBrushUnselected);
  DeleteObject(hBrushButton);
  #ifdef LXMINIMAP
  DeleteObject(hBrushButtonHasFocus);
  #endif

  extern void DeInitialiseFonts(void);
  DeInitialiseFonts();  
  CAirspaceManager::Instance().CloseAirspaces();
  #if TESTBENCH
  StartupStore(TEXT(".... Delete Critical Sections%s"),NEWLINE);
  #endif

  // Wait end of Calculation thread before deinit critical section.
  WaitForSingleObject(hCalculationThread, INFINITE);
  CloseHandle(hCalculationThread);

  #if TESTBENCH
  StartupStore(TEXT(".... Close Progress Dialog%s"),NEWLINE);
  #endif
  CloseProgressDialog();
  #if TESTBENCH
  StartupStore(TEXT(".... Close Calculations%s"),NEWLINE);
  #endif
  CloseCalculations();

  CloseGeoid();
  DeInitCustomHardware();

  #if TESTBENCH
  StartupStore(TEXT(".... Close Windows%s"),NEWLINE);
  #endif
  DestroyWindow(hWndMapWindow);
  DestroyWindow(hWndMainWindow);
  #if TESTBENCH
  StartupStore(TEXT(".... Close Event Handles%s"),NEWLINE);
  #endif
  CloseHandle(drawTriggerEvent);
  CloseHandle(dataTriggerEvent);

  #if TESTBENCH
  StartupLogFreeRamAndStorage();
  #endif
  for (i=0;i<NUMDEV;i++) {
	if (ComPortStatus[i]!=0) {
		StartupStore(_T(". ComPort %d: status=%d Rx=%d Tx=%d ErrRx=%d + ErrTx=%d (==%d)%s"), i,
		ComPortStatus[i], ComPortRx[i],ComPortTx[i], ComPortErrRx[i],ComPortErrTx[i],ComPortErrors[i],NEWLINE);
	}
  }
  StartupStore(_T(". Finished shutdown %s%s"), WhatTimeIsIt(),NEWLINE);
  LKRunStartEnd(false);

#ifdef DEBUG
  TCHAR foop[80];
  TASK_POINT wp;
  TASK_POINT *wpr = &wp;
  _stprintf(foop,TEXT(". Sizes %d %d %d%s"),
	    sizeof(TASK_POINT), 
	    ((long)&wpr->AATTargetLocked)-((long)wpr),
	    ((long)&wpr->Target)-((long)wpr), NEWLINE
	    );
  StartupStore(foop);
#endif
}
コード例 #16
0
// Called periodically to show new airspace warning messages to user
// return 1 only for requesting run analysis
// This is called by WINMAIN thread, every second (1hz)
short ShowAirspaceWarningsToUser()
{

  if (msg.originator != NULL) return 0;        // Dialog already open


  bool there_is_message = CAirspaceManager::Instance().PopWarningMessage(&msg);
  if (!there_is_message) return 0;        // no message to display

  airspace_copy = CAirspaceManager::Instance().GetAirspaceCopy(msg.originator);

  bool ackdialog_required = false;
  TCHAR msgbuf[128];

  // which message we need to show?
  switch (msg.event) {
    default:
      // normally not show
      DoStatusMessage(TEXT("Unknown airspace warning message"));
      break;    //Unknown msg type

    case aweNone:
    case aweMovingInsideFly:            // normal, no msg, normally this msg type shouldn't get here
    case awePredictedEnteringFly:       // normal, no msg, normally this msg type shouldn't get here
    case aweMovingOutsideNonfly:        // normal, no msg, normally this msg type shouldn't get here
      break;
      
    case awePredictedLeavingFly:
    case aweNearOutsideFly:
    case aweLeavingFly:
    case awePredictedEnteringNonfly:
    case aweNearInsideNonfly:
    case aweEnteringNonfly:
    case aweMovingInsideNonfly:             // repeated messages
    case aweMovingOutsideFly:               // repeated messages
      ackdialog_required = true;
      break;
      
    case aweEnteringFly:
      // LKTOKEN _@M1240_ "Entering"
      wsprintf(msgbuf, TEXT("%s %s"), gettext(TEXT("_@M1240_")), airspace_copy.Name());
      DoStatusMessage(msgbuf);
      break;

    case aweLeavingNonFly:
      // LKTOKEN _@M1241_ "Leaving"
      wsprintf(msgbuf, TEXT("%s %s"), gettext(TEXT("_@M1241_")), airspace_copy.Name());
      DoStatusMessage(msgbuf);
      break;
      
  }

  // show dialog to user if needed
  if (ackdialog_required && (airspace_copy.WarningLevel() == msg.warnlevel)) {
    if (!ScreenLandscape)
      dlg = dlgLoadFromXML(CallBackTable, NULL, hWndMainWindow, TEXT("IDR_XML_LKAIRSPACEWARNING_L"));
    else
      dlg = dlgLoadFromXML(CallBackTable, NULL, hWndMainWindow, TEXT("IDR_XML_LKAIRSPACEWARNING"));

    if (dlg==NULL) {
      StartupStore(_T("------ LKAirspaceWarning setup FAILED!%s"),NEWLINE); //@ 101027
      return 0;
    }
    
    dlg->SetKeyDownNotify(OnKeyDown);
    dlg->SetTimerNotify(OnTimer);
    timer_counter = AirspaceWarningDlgTimeout;                    // Auto closing dialog in x secs

    WndButton *wb = (WndButton*)dlg->FindByName(TEXT("cmdAckForTime"));
    if (wb) {
      TCHAR stmp2[40];
      wsprintf(stmp2,TEXT("%s (%dmin)"), gettext(TEXT("_@M46_")), AcknowledgementTime/60);
      wb->SetCaption(stmp2);
    }    

    dlgLKAirspaceFill();

    #ifndef DISABLEAUDIO
    if (EnableSoundModes) LKSound(_T("LK_AIRSPACE.WAV")); // 100819
    #endif

    _stprintf(msgbuf,_T("%s: %s"),gettext(_T("_@M68_")),airspace_copy.Name());
    dlg->SetCaption(msgbuf);

    dlg->ShowModal();

    delete dlg;
    dlg = NULL;
  }
  
  msg.originator = NULL;

  // If we clicked on Analysis button, we shall return 1 and the calling function will
  // detect and take care of it.
  // 120128 unused, we call directly eventSetup 
  return 1;
}
コード例 #17
0
ファイル: WndProc.cpp プロジェクト: rafagdn/LK8000
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  long wdata;

  switch (message)
    {

    case WM_ERASEBKGND:
      return TRUE; // JMW trying to reduce screen flicker
      break;
    case WM_COMMAND:
      return MainMenu(hWnd, message, wParam, lParam);
      break;
    case WM_CTLCOLORSTATIC:
      wdata = GetWindowLong((HWND)lParam, GWL_USERDATA);
      switch(wdata) {
      case 0:
        SetBkColor((HDC)wParam, ColorUnselected);
        SetTextColor((HDC)wParam, RGB(0x00,0x00,0x00));
        return (LRESULT)hBrushUnselected;
      case 1:
        SetBkColor((HDC)wParam, ColorSelected);
        SetTextColor((HDC)wParam, RGB(0x00,0x00,0x00));
        return (LRESULT)hBrushSelected;
      case 2:
	SetBkColor((HDC)wParam, ColorUnselected);
        SetTextColor((HDC)wParam, ColorWarning);
	return (LRESULT)hBrushUnselected;
      case 3:
	SetBkColor((HDC)wParam, ColorUnselected);
        SetTextColor((HDC)wParam, ColorOK);
	return (LRESULT)hBrushUnselected;
      case 4:
	// black on light green
        SetTextColor((HDC)wParam, RGB_BLACK); 
	SetBkColor((HDC)wParam, ColorButton);
	return (LRESULT)hBrushButton;
      case 5:
	// grey on light green
	SetBkColor((HDC)wParam, ColorButton);
        SetTextColor((HDC)wParam, RGB(0x80,0x80,0x80));
	return (LRESULT)hBrushButton;
#ifdef LXMINIMAP
      case 6:
        // black on dark yellow
        SetTextColor((HDC)wParam, RGB_BLACK);
        SetBkColor((HDC)wParam, ColorButtonHasFocus);
        return (LRESULT)hBrushButtonHasFocus;
      case 7:
        // grey on dark yellow
        SetTextColor((HDC)wParam, RGB(0x80,0x80,0x80));
        SetBkColor((HDC)wParam, ColorButtonHasFocus);
        return (LRESULT)hBrushButtonHasFocus;
#endif

      }
      break;
    case WM_CREATE:
#ifdef HAVE_ACTIVATE_INFO
      memset (&s_sai, 0, sizeof (s_sai));
      s_sai.cbSize = sizeof (s_sai);
#endif
      if (iTimerID == 0) {
        iTimerID = SetTimer(hWnd,1000,500,NULL); // 500ms  2 times per second
      }

      break;

    case WM_ACTIVATE:

      if(LOWORD(wParam) != WA_INACTIVE)
        {
          SetWindowPos(hWndMainWindow,HWND_TOP,
                 0, 0, 0, 0,
                 SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE);

#ifdef HAVE_ACTIVATE_INFO
         SHFullScreen(hWndMainWindow,SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON|SHFS_HIDESTARTICON);
#endif

        }
#ifdef HAVE_ACTIVATE_INFO
      if (api_has_SHHandleWMActivate) {
        SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
      } else {
        #ifdef TESTBENCH
        StartupStore(TEXT("... SHHandleWMActivate not available%s"),NEWLINE);
        #endif
        return DefWindowProc(hWnd, message, wParam, lParam);
      }
#endif
      break;

    case WM_SETTINGCHANGE:
#ifdef HAVE_ACTIVATE_INFO
      if (api_has_SHHandleWMSettingChange) {
        SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
      } else {
        #ifdef TESTBENCH
        StartupStore(TEXT("... SHHandleWMSettingChange not available%s"),NEWLINE);
        #endif
        return DefWindowProc(hWnd, message, wParam, lParam);
      }
#endif
      break;

	#if DEBUG_FOCUS
    case WM_KILLFOCUS:
	// This is happening when focus is given to another window, either internally inside LK
	// or externally, for example to explorer..
	// SO: if we select MapWindow, we get here a KILLFOCUS from it.
	// When we select another process/program, or click on the desktop, the old window having focus is
	// receiving KILLFOCUS. So in case MapWindow was working, the signal will be sent over there, not here.
	// 
	StartupStore(_T("............ WNDPROC LOST FOCUS (KILLFOCUS)\n"));
	break;
	#endif

    case WM_SETFOCUS:
	// When explorer/desktop is giving focus to LK, this is where we get the signal.
	// But we must return focus to previous windows otherwise keys will not be working.
	// Mouse is another story, because mouse click is pertinent to a screen area which is mapped.
	// A mouse click will be sent to the window in the background, whose handler will receive the event.
	//
	// Each event handler receiving focus has to save it in hWndWithFocus, in LK.
	// Each event handler must thus handle SETFOCUS!
	//
	#if DEBUG_FOCUS
	StartupStore(_T("............ WNDPROC HAS FOCUS  (SETFOCUS)\n"));
	if (hWndWithFocus==NULL)
		StartupStore(_T(".....(no Wnd to give focus to)\n"));
	else
		StartupStore(_T(".....(passing focus to other window)\n"));
	#endif
	if (hWndWithFocus!=NULL) SetFocus(hWndWithFocus);
      break;

    case WM_KEYUP:
      break;

    case WM_TIMER:
	// WM_TIMER is run at about 2hz.
	LKHearthBeats++; // 100213
      //      ASSERT(hWnd==hWndMainWindow);
      if (ProgramStarted > psInitInProgress) {
	if (SIMMODE)
		SIMProcessTimer();
	else
		ProcessTimer();
	if (ProgramStarted==psFirstDrawDone) {
	  AfterStartup();
	  ProgramStarted = psNormalOp;
          StartupStore(_T(". ProgramStarted=NormalOp %s%s"), WhatTimeIsIt(),NEWLINE);
          StartupLogFreeRamAndStorage();

	}
      }
      break;

    case WM_INITMENUPOPUP:
      if (ProgramStarted > psInitInProgress) {
	  CheckMenuItem((HMENU) wParam,IDM_FILE_LOCK,MF_CHECKED|MF_BYCOMMAND);
	
	if(LoggerActive)
	  CheckMenuItem((HMENU) wParam,IDM_FILE_LOGGER,MF_CHECKED|MF_BYCOMMAND);
	else
	  CheckMenuItem((HMENU) wParam,IDM_FILE_LOGGER,MF_UNCHECKED|MF_BYCOMMAND);
      }
      break;

    case WM_CLOSE:

      LKASSERT(hWnd==hWndMainWindow);
      if((hWnd==hWndMainWindow) && 
         (MessageBoxX(hWndMainWindow,
		// LKTOKEN  _@M198_ = "Confirm Exit?"
               	gettext(TEXT("_@M198_")),
                      TEXT("LK8000"),
                      MB_YESNO|MB_ICONQUESTION) == IDYES)) 
        {
          if(iTimerID) {
            KillTimer(hWnd,iTimerID);
            iTimerID = 0;
          }

          Shutdown();
        }
      break;

    case WM_DESTROY:
      if (hWnd==hWndMainWindow) {
        PostQuitMessage(0);
      }
      break;

#if TESTBENCH
    case WM_DEVICECHANGE:
	 TCHAR serr[50];
	 static WPARAM oldwparam=0;
	 StartupStore(_T("DEVICE CHANGE DETECTED, CODE=0x%x%s"),wParam,NEWLINE);

	 if (wParam!=oldwparam) {
		 oldwparam=wParam;
	 	wsprintf(serr,_T("DEVICE CHANGE DETECTED\nCODE=0x%x"),wParam);
        	 MessageBoxX(hWndMainWindow, serr, TEXT("LK8000"), MB_OK|MB_ICONQUESTION, true);
		 oldwparam=0;
	 }
	 return TRUE; // acknowledge
	 break;
#endif

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
  return 0;
}
コード例 #18
0
static void SetValues(int indexid) {
  WndProperty* wp;
  TCHAR buffer[80];

  if (indexid<0 || indexid>MAXTHISTORY) { // TODO check
	StartupStore(_T("... LK thermal setvalues invalid indexid=%d%s"),indexid,NEWLINE);
	DoStatusMessage(_T("ERR-216 INVALID THERMAL INDEXID"));
	return;
  }
  if ( !ThermalHistory[indexid].Valid ) {
	DoStatusMessage(_T("ERR-217 INVALID THERMAL INDEXID"));
	return;
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpName"));
  if (wp) {
	_tcscpy(buffer,ThermalHistory[indexid].Name);
	ConvToUpper(buffer);
	wp->SetText(buffer);
	wp->RefreshDisplay();
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpHTop"));
  if (wp) {
	_stprintf(buffer,_T("%.0f %s"),ThermalHistory[indexid].HTop*ALTITUDEMODIFY, Units::GetAltitudeName());
	wp->SetText(buffer);
	wp->RefreshDisplay();
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpHBase"));
  if (wp) {
	_stprintf(buffer,_T("%.0f %s"),ThermalHistory[indexid].HBase*ALTITUDEMODIFY, Units::GetAltitudeName());
	wp->SetText(buffer);
	wp->RefreshDisplay();
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpLift"));
  if (wp) {
	_stprintf(buffer,_T("%+.1f %s"),ThermalHistory[indexid].Lift*LIFTMODIFY, Units::GetVerticalSpeedName());
	wp->SetText(buffer);
	wp->RefreshDisplay();
  }

  wp = (WndProperty*)wf->FindByName(TEXT("prpTeamCode"));
  if (wp) {
	// Taken from CalculateTeamBear..
	if (!WayPointList) return;
	if (TeamCodeRefWaypoint < 0) return;

	double distance=0, bearing=0;

	LL_to_BearRange( WayPointList[TeamCodeRefWaypoint].Latitude,
           WayPointList[TeamCodeRefWaypoint].Longitude,
           ThermalHistory[indexid].Latitude,
           ThermalHistory[indexid].Longitude,
           &bearing, &distance);

	GetTeamCode(buffer, bearing, distance);

	buffer[5]='\0';
	wp->SetText(buffer);
	wp->RefreshDisplay();
  }

}
コード例 #19
0
//
// Set all default values for configuration.
// We need to set runtime variables later, that make use of 
// configuration values. One setting for configuration, and the
// runtime equivalent of the same setting, for the case when it
// is possible to change such runtime value with a button.
//
// ALL configurable parameters MUST be listed here. Add new items at the bottom!
//
// Let's keep this list alpha sorted like in LKPROFILES.h and load/save functions
//
// AFTER this function is called:
// * values must be normalized with ProfileAdjustVariables()
// * Runtime values must be initialised with InitRuntime()
//
void LKProfileResetDefault(void) {

  int i;

  #if TESTBENCH
  StartupStore(TEXT("... ProfileResetDefault%s"),NEWLINE);
  #endif

  AcknowledgementTime = 1800;	// keep ack level for this time, [secs]

  Units::CoordinateFormat = (CoordinateFormats_t)cfDDMMSS;

  // Units
  SpeedUnit_Config = 2;         // default is kmh
  TaskSpeedUnit_Config = 2;     // default is kph
  DistanceUnit_Config = 2;      // default is km
  LiftUnit_Config = 1;          // default m/s
  AltitudeUnit_Config = 1;      // default m

  //
  // Default infobox groups configuration
  // Should be different for each aircraft category
  //
  InfoType[0] = 1326913302;
  InfoType[1] = 1915694850;
  InfoType[2] = 403835669;
  InfoType[3] = 740895295;
  InfoType[4] = 1460275747;
  InfoType[5] = 725435674;
  InfoType[6] = 168906009;
  InfoType[7] = 387389207;

  InfoType[8] = 387389207; // totally unused!

  DisplayOrientation_Config=NORTHCIRCLE;

  DisplayTextType=0;

  AltitudeMode_Config = ALLON;
  ClipAltitude = 10000;	 // * 10
  AltWarningMargin = 1000; // * 10
  AIRSPACEWARNINGS = TRUE;
  WarningTime = 60;
  AirspaceWarningRepeatTime = 300;            // warning repeat time if not acknowledged after 5 minutes
  AirspaceWarningVerticalMargin = 1000;        // vertical distance used to calculate too close condition *10
  AirspaceWarningDlgTimeout = 30;             // airspace warning dialog auto closing in x secs
  AirspaceWarningMapLabels = 1;               // airspace warning map labels showed
  AirspaceAckAllSame = 0;

  SafetyAltitudeMode = 0;

  SAFETYALTITUDEARRIVAL = 3000; // * 10 
  SAFETYALTITUDETERRAIN = 500; // *10
  SAFTEYSPEED = 55.556;

  WindCalcTime=WCALC_TIMEBACK;
  WindCalcSpeed=27.778;

  SectorType = 1;
  SectorRadius = 3000;


  for(i=0;i<AIRSPACECLASSCOUNT;i++) {
	MapWindow::iAirspaceMode[i] = 3; // Display + Warning
  } 

  MapWindow::SetAirSpaceFillType(MapWindow::asp_fill_patterns_full);
  MapWindow::SetAirSpaceOpacity(30);

  TrailActive_Config = TRUE;

  EnableTrailDrift_Config = false;

  EnableThermalLocator = 1;

  FinalGlideTerrain = 1;

  AutoWindMode_Config = D_AUTOWIND_CIRCLING;

  MapWindow::zoom.CircleZoom(1);

  HomeWaypoint = -1;

  Alternate1 = -1;

  Alternate2 = -1;

  MapWindow::SnailWidthScale = 16;

  TeamCodeRefWaypoint = -1;

  StartLine = 1;

  StartRadius = 3000;

  FinishLine = 1;

  FinishRadius = 3000;

  EnableAutoBacklight = 1;

  EnableAutoSoundVolume = 0;

  AircraftCategory = 0;

  AATEnabled=FALSE;

  if (ScreenLandscape)
	Look8000 = (Look8000_t)lxcAdvanced;
  else
	Look8000 = (Look8000_t)lxcStandard;  

  CheckSum = 1;

  PGCruiseZoom=4;
  PGAutoZoomThreshold = 5000;
  PGClimbZoom=1;
  AutoOrientScale=100;

  PGOpenTimeH=12;
  PGOpenTimeM=0;
  PGCloseTimeH=23;
  PGCloseTimeM=59;
  
  PGNumberOfGates=0;
  PGGateIntervalTime=30;
  PGStartOut=0;

  // These values are used on startup, but on reset change also OpenCloseTopology
  LKTopoZoomCat05=DEFAULT_WATER_LABELS_THRESHOLD;	// coast area share the same label management of cat10
  LKTopoZoomCat10=DEFAULT_WATER_LABELS_THRESHOLD;	// water labels threshold, over this realscale, no water labels are printed)
  LKTopoZoomCat20=9999;		// water lines
  LKTopoZoomCat30=25;		// Big Roads
  LKTopoZoomCat40=6;		// Medium road
  LKTopoZoomCat50=3;		// Small road
  LKTopoZoomCat60=8;		// Railroad
  LKTopoZoomCat70=15;		// Big cities
  LKTopoZoomCat80=9999;		// Med city
  LKTopoZoomCat90=9999;		// Small city
  LKTopoZoomCat100=3;		// Very small cities
  LKTopoZoomCat110=9999;	// city polyline area

  LKMaxLabels=70;

  IphoneGestures = (IphoneGestures_t)iphDisabled;

  PollingMode = (PollingMode_t)pollmodeDisabled;

  LKVarioBar = (LKVarioBar_t)vBarDisabled;

  LKVarioVal = (LKVarioVal_t)vValVarioVario;

  OutlinedTp_Config = (OutlinedTp_t)otLandable;

  TpFilter = (TpFilter_t)TfNoLandables;

  OverColor = (OverColor_t)OcBlack;

  DeclutterMode = (DeclutterMode_t)dmHigh;

  // full size overlay by default
  OverlaySize = 0;

  BarOpacity = 65;

  #ifdef PPC2002  
  FontRenderer = 1; // AntiAliasing
  #else
  FontRenderer = 0; // ClearType Compatible
  #endif

  GPSAltitudeOffset = 0;

  UseGeoidSeparation = 1;

  PressureHg = 0;

  CustomKeyTime = 700;
  CustomKeyModeCenter = (CustomKeyMode_t)ckToggleMap;

  CustomKeyModeLeft = (CustomKeyMode_t)ckDisabled;
  CustomKeyModeRight = (CustomKeyMode_t)ckDisabled;
  CustomKeyModeAircraftIcon = (CustomKeyMode_t)ckDisabled;
  CustomKeyModeLeftUpCorner = (CustomKeyMode_t)ckMultitargetRotate;
  CustomKeyModeRightUpCorner = (CustomKeyMode_t)ckToggleOverlays;
  CustomKeyModeCenterScreen = (CustomKeyMode_t)ckWhereAmI;

  MapBox = (MapBox_t)mbBoxed; 

  // Units labels printout
  if ((ScreenSize == (ScreenSize_t)ss240x320) ||
      (ScreenSize == (ScreenSize_t)ss272x480) ||
      (ScreenSize == (ScreenSize_t)ss320x240) )
	HideUnits = 1;
  else
	HideUnits = 0;



  BestWarning=1;

  ThermalBar=0;

  McOverlay=1;

  TrackBar=1;

  PGOptimizeRoute=true;
  PGOptimizeRoute_Config = true;

  GlideBarMode = (GlideBarMode_t)gbDisabled;

  ArrivalValue = (ArrivalValue_t)avAltitude;

  // 1 is showing all airports and declutter only unneeded outlandings
  NewMapDeclutter = 1;

  AverEffTime = (AverEffTime_t)ae30seconds; 

  BgMapColor_Config = 2;

  debounceTimeout = 250;

  DeviceNeedClipping=false;

  Appearance.DefaultMapWidth=206;
  // Landables style
  Appearance.IndLandable=wpLandableDefault;
  // White/Black inversion
  InverseInfoBox_Config=true; // black
  Appearance.InfoBoxModel=apImPnaGeneric;


  AutoAdvance_Config = 1;

  AutoMcMode_Config = amcEquivalent;


  AutoMacCready_Config = true;

  UseTotalEnergy_Config= false;

  WaypointsOutOfRange = 1; // include also wps out of terrain

  EnableFAIFinishHeight = false;

  Handicap = 100; // Std Cirrus

  UTCOffset = 0;

  AutoZoom_Config=false;

  MenuTimeout_Config = MENUTIMEOUTMAX;

  LockSettingsInFlight = 0;

  LoggerShortName = 0;

  EnableFLARMMap = 0;

  TerrainContrast = 128;

  TerrainBrightness = 128;

  TerrainRamp_Config = 0;

  MapWindow::GliderScreenPosition = 40;

  BallastSecsToEmpty =  120;

  #if ((WINDOWSPC==0))
  SetSystemTimeFromGPS = true;
  #else
  SetSystemTimeFromGPS = false;
  #endif

  AutoForceFinalGlide = false;

  UseCustomFonts = 0;

  AlarmMaxAltitude1 = 0;

  AlarmMaxAltitude2 = 0;

  AlarmMaxAltitude3 = 0;

  AlarmTakeoffSafety = 0;

  GearWarningMode=0;

  GearWarningAltitude=200;

  FinishMinHeight = 0;

  StartHeightRef = 0;

  StartMaxHeight = 0;
  
  StartMaxHeightMargin = 0;

  StartMaxSpeed = 0;

  StartMaxSpeedMargin = 0;

  EnableNavBaroAltitude_Config = 1;

  Orbiter_Config = 1;
  Shading_Config = 1;
  OverlayClock = 0;
  SonarWarning_Config = 1; // sonar enabled by default on reset

  // default BB and IP is all ON
  ConfBB0 = 0; // TRM is off by default on v4
  ConfBB1 = 1;
  ConfBB2 = 1;
  ConfBB3 = 1;
  ConfBB4 = 1;
  ConfBB5 = 1;
  ConfBB6 = 1;
  ConfBB7 = 1;
  ConfBB8 = 1;
  ConfBB9 = 1;
  ConfBB0Auto = 1;

  ConfIP11 = 1;
  ConfIP12 = 1;
  ConfIP13 = 1;
  ConfIP14 = 1;
  ConfIP15 = 1;
  ConfIP16 = 1;
  ConfIP17 = 1;
  ConfIP21 = 1;
  ConfIP22 = 1;
  ConfIP23 = 1;
  ConfIP24 = 1;
  ConfIP31 = 1;
  ConfIP32 = 1;
  ConfIP33 = 1;

  LoggerTimeStepCruise = 1;

  LoggerTimeStepCircling = 1;

  GlidePolar::SafetyMacCready = 0.5; // This is saved *10 and loaded /10 in Adjust! 

  DisableAutoLogger = false;
  
  LiveTrackerInterval = 0;
  
  // empty or demo versions
  //szAirspaceFile[0] = TEXT('\0');
  //szWaypointFile[0] = TEXT('\0');
  //szTerrainFile[0] = TEXT('\0');
  //szAirfieldFile[0] = TEXT('\0');
  //szMapFile[0] = TEXT('\0');
  //szPolarFile[0] = TEXT('\0');


  _tcscpy(szPolarFile,_T("%LOCAL_PATH%\\\\_Polars\\Std Cirrus.plr"));
  _tcscpy(szAirspaceFile,_T("%LOCAL_PATH%\\\\_Airspaces\\DEMO.txt"));
  szAdditionalAirspaceFile[0] = TEXT('\0');
  _tcscpy(szWaypointFile,_T("%LOCAL_PATH%\\\\_Waypoints\\DEMO.cup"));
  szAdditionalWaypointFile[0] = TEXT('\0');
  _tcscpy(szTerrainFile,_T("%LOCAL_PATH%\\\\_Maps\\DEMO.DEM"));
  _tcscpy(szAirfieldFile,_T("%LOCAL_PATH%\\\\_Waypoints\\WAYNOTES.txt"));
  _tcscpy(szLanguageFile,_T("%LOCAL_PATH%\\\\_Language\\ENGLISH.LNG"));

  szInputFile[0] = TEXT('\0');
  _tcscpy(szMapFile,_T("%LOCAL_PATH%\\\\_Maps\\DEMO.LKM"));

  // Ports and device settings
  dwDeviceName1[0]=_T('\0');
  szPort1[0] = _T('\0');
  dwSpeedIndex1 = 2;
  dwBit1Index = (BitIndex_t)bit8N1;
  dwDeviceName2[0]=_T('\0');
  szPort2[0] = _T('\0');
  dwSpeedIndex2 = 2;
  dwBit2Index = (BitIndex_t)bit8N1;

  FontDesc_MapWindow[0]=_T('\0');
  FontDesc_MapLabel [0]=_T('\0');

  _tcscpy(PilotName_Config,_T("WOLF.HIRTH"));
  _tcscpy(LiveTrackersrv_Config,_T("www.livetrack24.com"));
  LiveTrackerport_Config = 80;
  _tcscpy(LiveTrackerusr_Config,_T("LK8000"));
  _tcscpy(LiveTrackerpwd_Config,_T(""));

  _tcscpy(AircraftType_Config,_T("CIRRUS-STD"));
  _tcscpy(AircraftRego_Config,_T("D-1900"));
  _tcscpy(CompetitionClass_Config,_T("CLUB"));
  _tcscpy(CompetitionID_Config,_T("WH"));

  LockSettingsInFlight = false;
  LoggerShortName = false;

  BUGS_Config=1; // 1=100%, 0.5 = 50% .. FLOATS!

  UseUngestures=true;

  // This is also reset by global init, but never mind. Done twice.
  extern void Reset_CustomMenu(void);
  Reset_CustomMenu();

  extern void Reset_Multimap_Flags(void);
  Reset_Multimap_Flags();

  extern void Reset_Multimap_Mode(void);
  Reset_Multimap_Mode();

   UseWindRose=false;	// use wind rose (ex: NNE) for wind direction, instead of degrees
                        // only Changed by custom Key

  // ######### ADD NEW ITEMS ABOVE THIS LINE  #########

}
コード例 #20
0
ファイル: Battery.cpp プロジェクト: AlphaLima/LK8000
void LKBatteryManager() {

  static bool invalid=false, recharging=false;
  static bool warn33=true, warn50=true, warn100=true;
  static double last_time=0, init_time=0;
  static int last_percent=0, last_status=0;


  if (invalid) return;
  if (DoInit[MDI_BATTERYMANAGER]) {

	invalid=false, recharging=false;
	warn33=true, warn50=true, warn100=true;
	last_time=0, init_time=0;
	last_percent=0, last_status=0;
	numwarn=0;

	if (PDABatteryPercent<1 || PDABatteryPercent>100) {
		StartupStore(_T("... LK BatteryManager V1: internal battery information not available, function disabled%s"), NEWLINE);
		invalid=true;
		DoInit[MDI_BATTERYMANAGER]=false; // just to be sure
		return;
	}

	StartupStore(_T(". LK Battery Manager V1 started, current charge=%d%%%s"),PDABatteryPercent,NEWLINE);
	init_time=GPS_INFO.Time;
	DoInit[MDI_BATTERYMANAGER]=false;
  }


  // if first run,  and not passed 30 seconds, do nothing
  if (last_percent==0 && (GPS_INFO.Time<(init_time+30))) {
	// StartupStore(_T("... first run, waiting for 30s\n"));
	return;
  }

  TCHAR mbuf[100];

  // first run after 30 seconds: give a message
  if (last_percent==0) {
	// StartupStore(_T("... first run, last percent=0\n"));
	if (PDABatteryPercent <=50) {
		last_time=GPS_INFO.Time;
		// LKTOKEN _@M1352_ "BATTERY LEVEL"
		_stprintf(mbuf,_T("%s %d%%"), gettext(TEXT("_@M1352_")), PDABatteryPercent);
		DoStatusMessage(mbuf);
		warn50=false;
	}
	// special case, pdabattery is 0...
	if (PDABatteryPercent <1) {
		StartupStore(_T("... LK Battery Manager disabled, low battery %s"),NEWLINE);
		// LKTOKEN _@M1353_ "BATTERY MANAGER DISABLED"
		DoStatusMessage(gettext(TEXT("_@M1353_")));
		invalid=true;
		return;
	} else
		last_percent=PDABatteryPercent;

	if (PDABatteryStatus!=AC_LINE_UNKNOWN) {
		last_status=PDABatteryStatus;
	}
	// StartupStore(_T("... last_percent first assigned=%d\n"),last_percent);
	return;
  }

  if (PDABatteryStatus!=AC_LINE_UNKNOWN) {
	if (last_status != PDABatteryStatus) {
		if (PDABatteryStatus==AC_LINE_OFFLINE) {
			if (GiveBatteryWarnings())
	// LKTOKEN  _@M514_ = "POWER SUPPLY OFF" 
			DoStatusMessage(gettext(TEXT("_@M514_")));
		} else {
			if (PDABatteryStatus==AC_LINE_ONLINE) {
				if (GiveBatteryWarnings())
	// LKTOKEN  _@M515_ = "POWER SUPPLY ON" 
				DoStatusMessage(gettext(TEXT("_@M515_")));
			} else {
				if (PDABatteryStatus==AC_LINE_BACKUP_POWER) {
					if (GiveBatteryWarnings())
	// LKTOKEN  _@M119_ = "BACKUP POWER SUPPLY ON" 
					DoStatusMessage(gettext(TEXT("_@M119_")));
				}
			}
		}
	}
	last_status=PDABatteryStatus;
  }

  // Only check every 5 minutes normally
  if (GPS_INFO.Time<(last_time+(60*5))) return;

  // if battery is recharging, reset warnings and do nothing
  if (last_percent<PDABatteryPercent) {
	warn33=true;
	warn50=true;
	warn100=true;
	last_percent=PDABatteryPercent;
	if (!recharging) {
		recharging=true;
		if (PDABatteryFlag==BATTERY_FLAG_CHARGING || PDABatteryStatus==AC_LINE_ONLINE) {
			if (GiveBatteryWarnings())
	// LKTOKEN  _@M124_ = "BATTERY IS RECHARGING" 
			DoStatusMessage(gettext(TEXT("_@M124_")));
  			last_time=GPS_INFO.Time;
		}
	}
	return;
  }
	
  // if battery is same level, do nothing except when 100% during recharge
  if (last_percent == PDABatteryPercent) {
	if (recharging && (PDABatteryPercent==100) && warn100) {
		if (GiveBatteryWarnings())
	// LKTOKEN  _@M123_ = "BATTERY 100% CHARGED" 
		DoStatusMessage(gettext(TEXT("_@M123_")));
		warn100=false;
  		last_time=GPS_INFO.Time;
	}
	return;
  }

  // else battery is discharging
  recharging=false;

  // Time to give a message to the user, if necessary
  if (PDABatteryPercent <=5) {
	// LKTOKEN _@M1354_ "BATTERY LEVEL CRITIC!"
	_stprintf(mbuf,_T("%d%% %s"), PDABatteryPercent, gettext(TEXT("_@M1354_")));
	DoStatusMessage(mbuf);
	#ifndef DISABLEAUDIO
        LKSound(TEXT("LK_RED.WAV"));
	#endif

	// repeat after 1 minute, forced
	last_time=GPS_INFO.Time-(60*4);
	last_percent=PDABatteryPercent;
	return;
  }
  if (PDABatteryPercent <=10) {
	// LKTOKEN _@M1355_ "BATTERY LEVEL VERY LOW!"
	_stprintf(mbuf,_T("%d%% %s"), PDABatteryPercent, gettext(TEXT("_@M1355_")));
	DoStatusMessage(mbuf);
	// repeat after 2 minutes, forced
	last_time=GPS_INFO.Time-(60*3);
	last_percent=PDABatteryPercent;
	return;
  }
  if (PDABatteryPercent <=20) {
	// LKTOKEN _@M1356_ "BATTERY LEVEL LOW!"
	_stprintf(mbuf,_T("%d%% %s"), PDABatteryPercent, gettext(TEXT("_@M1356_")));
	DoStatusMessage(mbuf);
	last_time=GPS_INFO.Time;
	last_percent=PDABatteryPercent;
	return;
  }

  if (PDABatteryPercent <=30) {
	if (warn33) {
		// LKTOKEN _@M1352_ "BATTERY LEVEL"
		_stprintf(mbuf, _T("%s %d%%"), gettext(TEXT("_@M1352_")), PDABatteryPercent);
		DoStatusMessage(mbuf);
		warn33=false;
	}
	last_time=GPS_INFO.Time;
	last_percent=PDABatteryPercent;
	return;
  }
  // DISABLED
  if (PDABatteryPercent <=50) {
	if (warn50) {
		// LKTOKEN _@M1352_ "BATTERY LEVEL"
	//	_stprintf(mbuf, _T("%s %d%%"), gettext(TEXT("_@M1352_")), PDABatteryPercent);
	//	DoStatusMessage(mbuf);
		warn50=false;
	}
	last_time=GPS_INFO.Time;
	last_percent=PDABatteryPercent;
	return;
  }

}
コード例 #21
0
ファイル: Thread_Draw.cpp プロジェクト: PhilColbert/LK8000
void MapWindow::DrawThread ()
{
  while ((!ProgramStarted) || (!Initialised)) {
	Poco::Thread::sleep(50);
  }

  #if TRACETHREAD
  StartupStore(_T("##############  DRAW threadid=%d\n"),GetCurrentThreadId());
  #endif

  #if TESTBENCH
  StartupStore(_T("... DrawThread START%s"),NEWLINE);
  #endif

  // THREADRUNNING = FALSE;
  THREADEXIT = FALSE;
  
  bool lastdrawwasbitblitted=false;
  
  // 
  // Big LOOP
  //

  while (!CLOSETHREAD) 
  {
	if(drawTriggerEvent.tryWait(5000))
	if (CLOSETHREAD) break; // drop out without drawing

	if ((!THREADRUNNING) || (!GlobalRunning)) {
        Poco::Thread::sleep(50);
		continue;
	}
    drawTriggerEvent.reset();
    
#ifdef HAVE_CPU_FREQUENCY
    const ScopeLockCPU cpu;
#endif
  
    ScopeLock Lock(Surface_Mutex);

	// Until MapDirty is set true again, we shall only repaint the screen. No Render, no calculations, no updates.
	// This is intended for very fast immediate screen refresh.
	//
	// MapDirty is set true by:
	//   - TriggerRedraws()  in calculations thread
	//   - RefreshMap()      in drawthread generally
	//


	extern POINT startScreen, targetScreen;
	extern bool OnFastPanning;
	// While we are moving in bitblt mode, ignore RefreshMap requests from LK
	// unless a timeout was triggered by MapWndProc itself.
	if (OnFastPanning) {
		MapDirty=false;
	} 

	// We must check if we are on FastPanning, because we may be in pan mode even while
	// the menu buttons are active and we are using them, accessing other functions.
	// In that case, without checking OnFastPanning, we would fall back here and repaint
	// with bitblt everytime, while instead we were asked a simple fastrefresh!
	//
	// Notice: we could be !MapDirty without OnFastPanning, of course!
	//
	if (!MapDirty && !ForceRenderMap && OnFastPanning && !first_run) {
		
		if (!mode.Is(Mode::MODE_TARGET_PAN) && mode.Is(Mode::MODE_PAN)) {

			const int fromX=startScreen.x-targetScreen.x;
			const int fromY=startScreen.y-targetScreen.y;

            PixelRect  clipSourceArea(MapRect); // Source Rectangle 
            RasterPoint clipDestPoint(clipSourceArea.GetOrigin()); // destination origin position
            PixelRect  WhiteRectV(MapRect); // vertical White band (left or right)
            PixelRect  WhiteRectH(MapRect); // horizontal White band (top or bottom)

            if (fromX<0) {
                clipSourceArea.right += fromX; // negative fromX
                clipDestPoint.x -= fromX;
                WhiteRectV.right = WhiteRectV.left - fromX;
                WhiteRectH.left = WhiteRectV.right;
            } else {
                clipSourceArea.left += fromX;
                WhiteRectV.left = WhiteRectV.right - fromX;
                WhiteRectH.right = WhiteRectV.left;
            }

            if (fromY<0) {
                clipSourceArea.bottom += fromY; // negative fromX
                clipDestPoint.y -= fromY;
                WhiteRectH.bottom = WhiteRectH.top - fromY;
            } else {
                clipSourceArea.top += fromY;
                WhiteRectH.top = WhiteRectH.bottom - fromY;
            }

#ifndef USE_GDI
            ScopeLock Lock(BackBuffer_Mutex);
#endif

            BackBufferSurface.Whiteness(WhiteRectV.left, WhiteRectV.top, WhiteRectV.GetSize().cx, WhiteRectV.GetSize().cy);
            BackBufferSurface.Whiteness(WhiteRectH.left, WhiteRectH.top, WhiteRectH.GetSize().cx, WhiteRectH.GetSize().cy);
            BackBufferSurface.Copy(clipDestPoint.x,clipDestPoint.y,
                clipSourceArea.GetSize().cx,
                clipSourceArea.GetSize().cy,
                DrawSurface, 
                clipSourceArea.left,clipSourceArea.top);


			const RasterPoint centerscreen = { ScreenSizeX/2, ScreenSizeY/2 };
			DrawMapScale(BackBufferSurface,MapRect,false);
			DrawCrossHairs(BackBufferSurface, centerscreen, MapRect);
			lastdrawwasbitblitted=true;
		} else {
			// THIS IS NOT GOING TO HAPPEN!
			//
			// The map was not dirty, and we are not in fastpanning mode.
			// FastRefresh!  We simply redraw old bitmap. 
			//
#ifndef USE_GDI
            ScopeLock Lock(BackBuffer_Mutex);
#endif
            DrawSurface.CopyTo(BackBufferSurface);

			lastdrawwasbitblitted=true;
		}

		// Now we can clear the flag. If it was off already, no problems.
//		OnFastPanning=false;
        MainWindow.Redraw(MapRect);
		continue;

	} else {
		//
		// Else the map wasy dirty, and we must render it..
		// Notice: if we were fastpanning, than the map could not be dirty.
		//

		#if 1 // --------------------- EXPERIMENTAL, CHECK ZOOM IS WORKING IN PNA
		static unsigned lasthere=0;
		// Only for special case: PAN mode, map not dirty (including requests for zooms!)
		// not in the ForceRenderMap run and last time was a real rendering. THEN, at these conditions,
		// we simply redraw old bitmap, for the scope of accelerating touch response.
		// In fact, if we are panning the map while rendering, there would be an annoying delay.
		// This is using lastdrawwasbitblitted
		if (INPAN && !MapDirty && !lastdrawwasbitblitted && !ForceRenderMap && !first_run) {
			// In any case, after 5 seconds redraw all
			if ( (LKHearthBeats-8) >lasthere ) {
				lasthere=LKHearthBeats;
				goto _dontbitblt;
			}
#ifndef USE_GDI
            ScopeLock Lock(BackBuffer_Mutex);
#endif
            DrawSurface.CopyTo(BackBufferSurface);

			const RasterPoint centerscreen = { ScreenSizeX/2, ScreenSizeY/2 };
			DrawMapScale(BackBufferSurface,MapRect,false);
			DrawCrossHairs(BackBufferSurface, centerscreen, MapRect);
            MainWindow.Redraw(MapRect);
			continue;
		} 
		#endif // --------------------------
_dontbitblt:
		MapDirty = false;
		PanRefreshed=true;
	} // MapDirty

	lastdrawwasbitblitted=false;
	MapWindow::UpdateInfo(&GPS_INFO, &CALCULATED_INFO);
	RenderMapWindow(DrawSurface, MapRect);

    {
#ifndef USE_GDI
        ScopeLock Lock(BackBuffer_Mutex);
#endif
        if (!ForceRenderMap && !first_run) {
            DrawSurface.CopyTo(BackBufferSurface);
        }

        // Draw cross sight for pan mode, in the screen center, 
        // after a full repaint while not fastpanning
        if (mode.AnyPan() && !mode.Is(Mode::MODE_TARGET_PAN) && !OnFastPanning) {
            POINT centerscreen;
            centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
            DrawMapScale(BackBufferSurface,MapRect,false);
            DrawCompass(BackBufferSurface, MapRect, DisplayAngle);
            DrawCrossHairs(BackBufferSurface, centerscreen, MapRect);
        }
    }

	UpdateTimeStats(false);

	// we do caching after screen update, to minimise perceived delay
	// UpdateCaches is updating topology bounds when either forced (only here)
	// or because MapWindow::ForceVisibilityScan  is set true.
    const ScreenProjection _Proj;
	UpdateCaches(_Proj, first_run);
	first_run=false;

	ForceRenderMap = false;

	if (ProgramStarted==psInitDone) {
		ProgramStarted = psFirstDrawDone;
	}
    MainWindow.Redraw(MapRect);

  } // Big LOOP

  #if TESTBENCH
  StartupStore(_T("... Thread_Draw terminated\n"));
  #endif
  THREADEXIT = TRUE;

}
コード例 #22
0
ファイル: device.cpp プロジェクト: Mazuk/LK8000
BOOL devInit(LPTSTR CommandLine){
  int i;
  TCHAR DeviceName[DEVNAMESIZE+1];
  PDeviceDescriptor_t pDevNmeaOut = NULL;
  static bool doinit=true;

  for (i=0; i<NUMDEV; i++){
    DeviceList[i].Port = -1;
    DeviceList[i].fhLogFile = NULL;
    DeviceList[i].Name[0] = '\0';
    DeviceList[i].ParseNMEA = NULL;
    DeviceList[i].PutMacCready = NULL;
    DeviceList[i].DirectLink = NULL;
    DeviceList[i].PutBugs = NULL;
    DeviceList[i].PutBallast = NULL;
    DeviceList[i].Open = NULL;
    DeviceList[i].Close = NULL;
    DeviceList[i].Init = NULL;
    DeviceList[i].LinkTimeout = NULL;
    DeviceList[i].Declare = NULL;
    DeviceList[i].IsLogger = devIsFalseReturn;
    DeviceList[i].IsGPSSource = devIsFalseReturn;
    DeviceList[i].IsBaroSource = devIsFalseReturn;
    DeviceList[i].IsRadio = devIsFalseReturn;

    DeviceList[i].PutVoice = (int (*)(struct DeviceDescriptor_t *,TCHAR *))devIsFalseReturn;
    DeviceList[i].PortNumber = i;
    DeviceList[i].PutQNH = NULL;
    DeviceList[i].OnSysTicker = NULL;

    DeviceList[i].pDevPipeTo = NULL;
    DeviceList[i].PutVolume = NULL;
    DeviceList[i].PutFreqActive = NULL;
    DeviceList[i].PutFreqStandby = NULL;
    DeviceList[i].IsCondor = devIsFalseReturn;
    DeviceList[i].Disabled = true;

    ComPortStatus[i]=CPS_UNUSED; // 100210
    ComPortHB[i]=0; // counter
    if (doinit) {
	ComPortRx[i]=0;
	ComPortTx[i]=0;
	ComPortErrTx[i]=0;
	ComPortErrRx[i]=0;
	ComPortErrors[i]=0;

	doinit=false;
    }
  }

  pDevPrimaryBaroSource = NULL;
  pDevSecondaryBaroSource=NULL;

  ReadDeviceSettings(0, DeviceName);
  #ifdef DEBUG_DEVSETTING
  StartupStore(_T(".......... ReadDeviceSetting 0, DeviceName=<%s>\n"),DeviceName);
  #endif
	
  PortIndex1 = 0; SpeedIndex1 = 2; Bit1Index=(BitIndex_t)bit8N1;
  ReadPort1Settings(&PortIndex1,&SpeedIndex1,&Bit1Index);

  //if (_tcslen(DeviceName)>0) // removed 110530
  if (wcscmp(DeviceName,_T(DEV_DISABLED_NAME))!=0) {
	DeviceList[0].Disabled=false;
	StartupStore(_T(". Device A is <%s> Port=%s%s"),DeviceName,COMMPort[PortIndex1],NEWLINE);
  } else {
	DeviceList[0].Disabled=true;
	StartupStore(_T(". Device A is DISABLED.%s"),NEWLINE);
  }

  for (i=DeviceRegisterCount-1; i>=0; i--) {
    if (DeviceList[0].Disabled) break;

    if ((_tcscmp(DeviceRegister[i].Name, DeviceName) == 0)) {

      ComPort *Com = new ComPort(0);

      // remember: Port1 is the port used by device A, port1 may be Com3 or Com1 etc
	// this is port 1, so index 0 for us. 
      if (!Com->Initialize(COMMPort[PortIndex1], dwSpeed[SpeedIndex1],Bit1Index,0)) {
	   	delete Com;
		ComPortStatus[0]=CPS_OPENKO;
        break;
      }
      ComPortStatus[0]=CPS_OPENOK;

      DeviceRegister[i].Installer(devA());

      if ((pDevNmeaOut == NULL) && 
	  (DeviceRegister[i].Flags & (1l << dfNmeaOut))){
        pDevNmeaOut = devA();
      }

      devA()->Com = Com;

      devInit(devA());
      devOpen(devA(), 0);

      if (devIsBaroSource(devA())) {
        if (pDevPrimaryBaroSource == NULL){
          pDevPrimaryBaroSource = devA();
        } else 
        if (pDevSecondaryBaroSource == NULL){
          pDevSecondaryBaroSource = devA();
        }
      }
      break;
    }
  }

  ReadDeviceSettings(1, DeviceName);
  #ifdef DEBUG_DEVSETTING
  StartupStore(_T(".......... ReadDeviceSetting 1, DeviceName=<%s>\n"),DeviceName);
  #endif

  PortIndex2 = 0; SpeedIndex2 = 2, Bit2Index=(BitIndex_t)bit8N1;
  ReadPort2Settings(&PortIndex2,&SpeedIndex2, &Bit2Index);

  //if (_tcslen(DeviceName)>0) // removed 110530
  if (wcscmp(DeviceName,_T(DEV_DISABLED_NAME))!=0) {
	DeviceList[1].Disabled=false;
	StartupStore(_T(". Device B is <%s> Port=%s%s"),DeviceName,COMMPort[PortIndex2],NEWLINE);
  } else {
	DeviceList[1].Disabled=true;
	StartupStore(_T(". Device B is DISABLED.%s"),NEWLINE);
  }

  for (i=DeviceRegisterCount-1; i>=0; i--) {
    if (PortIndex1 == PortIndex2) break;
    if (DeviceList[1].Disabled) break;

    if ((_tcscmp(DeviceRegister[i].Name, DeviceName) == 0)) {
      ComPort *Com = new ComPort(1);

	// this is port 2, so index 1 for us
      if (!Com->Initialize(COMMPort[PortIndex2], dwSpeed[SpeedIndex2],Bit2Index,1)) { // 100210
	delete Com;
	ComPortStatus[1]=CPS_OPENKO;
        break;
      }
      ComPortStatus[1]=CPS_OPENOK;

      DeviceRegister[i].Installer(devB());

      if ((pDevNmeaOut == NULL) && 
          (DeviceRegister[i].Flags & (1l << dfNmeaOut))){
        pDevNmeaOut = devB();
      }

      devB()->Com = Com;

      devInit(devB());
      devOpen(devB(), 1);

      if (devIsBaroSource(devB())) {
        if (pDevPrimaryBaroSource == NULL){
          pDevPrimaryBaroSource = devB();
        } else 
        if (pDevSecondaryBaroSource == NULL){
          pDevSecondaryBaroSource = devB();
        }
      }

      break;
    }
  }

  if (pDevNmeaOut != NULL){
    if (pDevNmeaOut == devA()){
      devB()->pDevPipeTo = devA();
    }
    if (pDevNmeaOut == devB()){
      devA()->pDevPipeTo = devB();
    }
  }

  return(TRUE);
}
コード例 #23
0
// This will NOT be called from PC versions
void InstallSystem() {

  TCHAR srcdir[MAX_PATH];
  TCHAR srcfile[MAX_PATH];

#ifdef UNDER_CE
  TCHAR dstdir[MAX_PATH];
  TCHAR maindir[MAX_PATH];
  TCHAR dstfile[MAX_PATH];
  TCHAR tbuf[MAX_PATH*3];

  dstdir[0]='\0';

#endif

  bool failure=false;

  #if TESTBENCH
  StartupStore(_T(". Welcome to InstallSystem v1.2%s"),NEWLINE);
  #endif
  SystemPath(srcdir,TEXT(LKD_SYSTEM));


  // We now test for a single file existing inside the directory, called _DIRECTORYNAME
  // because GetFileAttributes can be very slow or hang if checking a directory. In any case testing a file is
  // much more faster.
  _stprintf(srcfile,TEXT("%s%s_SYSTEM"),srcdir, _T(DIRSEP));
  if ( !lk::filesystem::exist(srcfile) ) {
	StartupStore(_T("------ InstallSystem ERROR could not find valid system directory <%s>%s"),srcdir,NEWLINE); // 091104
	StartupStore(_T("------ Missing checkfile <%s>%s"),srcfile,NEWLINE);
	failure=true;
  } else {
	#if TESTBENCH
	StartupStore(_T(". InstallSystem source directory <%s> is available%s"),srcdir,NEWLINE);
	#endif
  }

  if (  failure ) {
	StartupStore(_T("------ WARNING: NO font will be installed on device (and thus wrong text size displayed)%s"),NEWLINE);
  } else {

#ifdef PNA
	if (GlobalModelType == MODELTYPE_PNA_HP31X) { // 091109

		StartupStore(_T(". InstallSystem checking desktop links for HP31X%s"),NEWLINE);

		_stprintf(dstdir,TEXT("\\Windows\\Desktop"));
		if ( !lk::filesystem::isDirectory(dstdir) ) { // FIX
			StartupStore(_T("------ Desktop directory <%s> NOT found! Is this REALLY an HP31X?%s"),dstdir,NEWLINE);
		} else {
			_stprintf(srcfile,TEXT("%s\\LK8_HP310.lnk"),srcdir);
			_stprintf(dstfile,TEXT("%s\\LK8000.lnk"),dstdir);
			if ( lk::filesystem::exist(dstfile) ) {
				StartupStore(_T(". Link to LK8000 already found on the desktop, ok.%s"),NEWLINE);
			} else {
				StartupStore(_T(". Installing <%s>%s"),srcfile,NEWLINE);
				if (!lk::filesystem::copyFile(srcfile,dstfile,true))  {
					StartupStore(_T("------ Could not install in <%s>. Strange.%s"),dstfile,NEWLINE);
					StartupStore(_T("------ Error code was: %ld%s"),GetLastError(),NEWLINE);
				} else
					StartupStore(_T(". Installed <%s> link.%s"),dstfile,NEWLINE);
			}
			#if 0
			_stprintf(srcfile,TEXT("%s\\LK8SIM_HP310.lnk"),srcdir);
			_stprintf(dstfile,TEXT("%s\\SIM.lnk"),dstdir);
			if ( lk::filesystem::exist(dstfile) ) {
				StartupStore(_T(". Link to SIM LK8000 already found on the desktop, ok.%s"),NEWLINE);
			} else {
				StartupStore(_T(". Installing <%s>%s"),srcfile,NEWLINE);
				if (!lk::filesystem::copyFile(srcfile,dstfile,true))  {
					StartupStore(_T("------ Could not install in <%s>. Strange.%s"),dstfile,NEWLINE);
					StartupStore(_T("------ Error code was: %ld%s"),GetLastError(),NEWLINE);
				} else
					StartupStore(_T(". Installed <%s> link.%s"),dstfile,NEWLINE);
			}
			#endif
			_stprintf(srcfile,TEXT("%s\\BT_HP310.lnk"),srcdir);
			_stprintf(dstfile,TEXT("%s\\BlueTooth.lnk"),dstdir);
			if ( lk::filesystem::exist(dstfile) ) {
				StartupStore(_T(". Link to BlueTooth already found on the desktop, ok.%s"),NEWLINE);
			} else {
				StartupStore(_T(". Installing <%s>%s"),srcfile,NEWLINE);
				if (!lk::filesystem::copyFile(srcfile,dstfile,true))  {
					StartupStore(_T("------ Could not install in <%s>. Strange.%s"),dstfile,NEWLINE);
					StartupStore(_T("------ Error code was: %ld%s"),GetLastError(),NEWLINE);
				} else
					StartupStore(_T(". Installed <%s> link.%s"),dstfile,NEWLINE);
			}
			_stprintf(srcfile,TEXT("%s\\NAV_HP310.lnk"),srcdir);
			_stprintf(dstfile,TEXT("%s\\CarNav.lnk"),dstdir);
			if ( lk::filesystem::exist(dstfile) ) {
				StartupStore(_T(". Link to Car Navigator already found on the desktop, ok.%s"),NEWLINE);
			} else {
				StartupStore(_T(". Installing <%s>%s"),srcfile,NEWLINE);
				if (!lk::filesystem::copyFile(srcfile,dstfile,true))  {
					StartupStore(_T("------ Could not install in <%s>. Strange.%s"),dstfile,NEWLINE);
					StartupStore(_T("------ Error code was: %ld%s"),GetLastError(),NEWLINE);
				} else
					StartupStore(_T(". Installed <%s> link.%s"),dstfile,NEWLINE);
			}
			_stprintf(srcfile,TEXT("%s\\TLOCK_HP310.lnk"),srcdir);
			_stprintf(dstfile,TEXT("%s\\TouchLock.lnk"),dstdir);
			if ( lk::filesystem::exist(dstfile) ) {
				StartupStore(_T(". Link to TouchLock already found on the desktop, ok.%s"),NEWLINE);
			} else {
				StartupStore(_T(". Installing <%s>%s"),srcfile,NEWLINE);
				if (!lk::filesystem::copyFile(srcfile,dstfile,true))  {
					StartupStore(_T("------ Could not install in <%s>. Strange.%s"),dstfile,NEWLINE);
					StartupStore(_T("------ Error code was: %ld%s"),GetLastError(),NEWLINE);
				} else
					StartupStore(_T(". Installed <%s> link.%s"),dstfile,NEWLINE);
			}
		}
	}
#endif

  }

#ifdef UNDER_CE
  // search for the main system directory on the real device
  // Remember that SHGetSpecialFolder works differently on CE platforms, and you cannot check for result.
  // We need to verify if directory does really exist.

//  SHGetSpecialFolderPath(MainWindow, dstdir, CSIDL_WINDOWS, false);
  if ( _tcslen(dstdir) <6) {
	_stprintf(tbuf,_T("------ InstallSystem PROBLEM: cannot locate the Windows folder, got string:<%s>%s"),dstdir,NEWLINE);
	StartupStore(tbuf);
	StartupStore(_T("------ InstallSystem attempting to use default \"\\Windows\" but no warranty!%s"),NEWLINE);
	_stprintf(dstdir,TEXT("\\Windows")); // 091118
  } else {
	StartupStore(_T(". InstallSystem: Windows path reported from device is: <%s>%s"),dstdir,NEWLINE);
  }
  _tcscpy(maindir,dstdir);

  // we are shure that \Windows does exist already.
  TCHAR fontdir[MAX_PATH];
  fontdir[0] = _T('\0');
  dstdir[0] = _T('\0');
  #ifdef PNA
  if ( GetFontPath(fontdir) == FALSE ) {
	StartupStore(_T(". Special RegKey for fonts not found on this PNA, using standard folder.%s"), NEWLINE);
//	SHGetSpecialFolderPath(MainWindow, dstdir, CSIDL_FONTS, false);
	if ( _tcslen(dstdir) <5 ) {
		_stprintf(tbuf,_T("------ PROBLEM: cannot locate the Fonts folder, got string:<%s>%s"),dstdir,NEWLINE);
		StartupStore(tbuf);
		_stprintf(tbuf,_T("------ Attempting to use directory <%s> as a fallback%s"),maindir,NEWLINE);
		StartupStore(tbuf);
		_tcscpy(dstdir,maindir);
	}
  } else {
	StartupStore(_T(". RegKey Font directory is <%s>%s"),fontdir,NEWLINE);
	lk::filesystem::createDirectory(fontdir);
	_tcscpy(dstdir,fontdir);
  }
  #else
  UNUSED(fontdir);
  // this is not working correctly on PNA, it is reporting Windows Fonts even with another value in regkey
  SHGetSpecialFolderPath(MainWindow.Handle(), dstdir, CSIDL_FONTS, false);
  if ( _tcslen(dstdir) <5 ) {
	_stprintf(tbuf,_T("------ PROBLEM: cannot locate the Fonts folder, got string:<%s>%s"),dstdir,NEWLINE);
	StartupStore(tbuf);
	_stprintf(tbuf,_T("------ Attempting to use directory <%s> as a fallback%s"),maindir,NEWLINE);
	StartupStore(tbuf);
	_tcscpy(dstdir,maindir);
  }
  #endif

  _stprintf(tbuf,_T(". InstallSystem: Copy/Check Fonts from <%s> to <%s>%s"), srcdir, dstdir,NEWLINE);
  StartupStore(tbuf);
  // on PNAs sometimes FolderPath is reported correctly, but the directory is not existing!
  // this is not needed really on PNA, but doesnt hurt
  lk::filesystem::createDirectory(dstdir); // 100820


  // we cannot check directory existance without the risk of hanging for many seconds
  // we can only rely on singe real file existance, not on directories

  #if TESTBENCH
  StartupStore(_T(". Checking TAHOMA font%s"),NEWLINE);
  #endif
  _stprintf(srcfile,TEXT("%s\\TAHOMA.TTF"),srcdir);
  _stprintf(dstfile,TEXT("%s\\TAHOMA.TTF"),dstdir);
  if ( lk::filesystem::exist(dstfile) ) {
	#if TESTBENCH
	StartupStore(_T(". Font TAHOMA.TTF is already installed%s"),NEWLINE);
	#endif
  } else {
	if ( !lk::filesystem::copyFile(srcfile,dstfile,false) )  {
		StartupStore(_T("------ Could not copy TAHOMA.TTF on device, not good.%s"),NEWLINE);
		StartupStore(_T("------ Error code was: %ld%s"),GetLastError(),NEWLINE);
	} else
		StartupStore(_T("... Font TAHOMA.TTF installed on device%s"),NEWLINE);
  }

  // not needed, cannot overwrite tahoma while in use! Tahoma bold not used for some reason in this case.
  // Problem solved, look at FontPath !!

  #if TESTBENCH
  StartupStore(_T(". Checking TAHOMABD font%s"),NEWLINE);
  #endif
  _stprintf(srcfile,TEXT("%s\\TAHOMABD.TTF"),srcdir);
  _stprintf(dstfile,TEXT("%s\\TAHOMABD.TTF"),dstdir);
  if ( lk::filesystem::exist(dstfile) ) {
	#if TESTBENCH
	StartupStore(_T(". Font TAHOMABD.TTF is already installed%s"),NEWLINE);
	#endif
  } else {
	if ( !lk::filesystem::copyFile(srcfile,dstfile,false))  {
		StartupStore(_T("------ Could not copy TAHOMABD.TTF on device, not good.%s"),NEWLINE);
		StartupStore(_T("------ Error code was: %ld%s"),GetLastError(),NEWLINE);
	} else
		StartupStore(_T("... Font TAHOMABD.TTF installed on device%s"),NEWLINE);
  }
#endif
  #if TESTBENCH
  StartupStore(_T(". InstallSystem completed OK%s"),NEWLINE);
  #endif
}
コード例 #24
0
ファイル: RenderMapWindowBg.cpp プロジェクト: Turbo87/LK8000
void MapWindow::RenderMapWindowBg(HDC hdc, const RECT rc,
				  const POINT &Orig,
				  const POINT &Orig_Aircraft)
{

  // Calculations are taking time and slow down painting of map, beware
  #define MULTICALC_MINROBIN	5	// minimum split
  #define MULTICALC_MAXROBIN	20	// max split
  static short multicalc_slot=0;// -1 (which becomes immediately 0) will force full loading on startup, but this is not good
				// because currently we are not waiting for ProgramStarted=3
				// and the first scan is made while still initializing other things

  // TODO assign numslots with a function, based also on available CPU time
  short numslots=1;
  #if NEWSMARTZOOM
  static double quickdrawscale=0.0;
  static double delta_drawscale=1.0;
  #endif

  #if 0 
  extern void TestChangeRect();
  TestChangeRect();
  #endif

  if ((MapWindow::AlphaBlendSupported() && BarOpacity<100) || mode.AnyPan()) {
	MapWindow::ChangeDrawRect(MapRect);
  } else {
	RECT newRect={0,0,ScreenSizeX,ScreenSizeY-BottomSize};
	MapWindow::ChangeDrawRect(newRect);
  }

  if (QUICKDRAW) {
	goto _skip_calcs;
  }

  if (NumberOfWayPoints>200) {
	numslots=NumberOfWayPoints/400;
	// keep numslots optimal
	if (numslots<MULTICALC_MINROBIN) numslots=MULTICALC_MINROBIN; // seconds for full scan, as this is executed at 1Hz
	if (numslots>MULTICALC_MAXROBIN) numslots=MULTICALC_MAXROBIN;

	// When waypointnumber has changed, we wont be using an exceeded multicalc_slot, which would crash the sw
	// In this case, we shall probably continue for the first round to calculate without going from the beginning
	// but this is not a problem, we are round-robin all the time here.
	if (++multicalc_slot>numslots) multicalc_slot=1;
  } else {
	multicalc_slot=0; // forcing full scan
  }

  // Here we calculate arrival altitude, GD etc for map waypoints. Splitting with multicalc will result in delayed
  // updating of visible landables, for example. The nearest pages do this separately, with their own sorting.
  // Basically we assume -like for nearest- that values will not change that much in the multicalc split time.
  // Target and tasks are recalculated in real time in any case. Nearest too. 
  LKCalculateWaypointReachable(multicalc_slot, numslots);

_skip_calcs:
  CalculateScreenPositionsAirspace(rc);

  CalculateScreenPositionsThermalSources();

  // Make the glide amoeba out of the latlon points, converting them to screen
  // (This function is updated for supporting multimaps )
  CalculateScreenPositionsGroundline();

  if (PGZoomTrigger) {
    if(!mode.Is(Mode::MODE_PANORAMA)) {
      mode.Special(Mode::MODE_SPECIAL_PANORAMA, true);
		LastZoomTrigger=DrawInfo.Time;
      
		Message::Lock();
	        Message::AddMessage(1000, 3, gettext(TEXT("_@M872_"))); // LANDSCAPE ZOOM FOR 20s
		Message::Unlock();
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) LKSound(TEXT("LK_TONEUP.WAV"));
		#endif
    }
    else {
		// previously called, see if time has passed
		if ( DrawInfo.Time > (LastZoomTrigger + 20.0)) {
			// time has passed, lets go back
			LastZoomTrigger=0; // just for safety
        mode.Special(Mode::MODE_SPECIAL_PANORAMA, false);
			PGZoomTrigger=false;
			Message::Lock(); 
	        	Message::AddMessage(1500, 3, gettext(TEXT("_@M873_"))); // BACK TO NORMAL ZOOM
			Message::Unlock();
			#ifndef DISABLEAUDIO
			if (EnableSoundModes) LKSound(TEXT("LK_TONEDOWN.WAV"));
			#endif
		}
	}
  }

  // 
  // "Checkpoint Charlie"
  // This is were we process stuff for anything else but main map.
  // We let the calculations run also for MapSpace modes.
  // But for multimaps, we can also draw some more stuff..
  // We are also sent back here from next code, when we detect that
  // the MapSpace mode has changed from MAP to something else while we
  // were rendering.
  //
QuickRedraw:
  //
  if (DONTDRAWTHEMAP) 
  {
	DrawMapSpace(hdc, rc);
	// Is this a "shared map" environment? 
	if (IsMultiMapShared()) { 
		// Shared map, of course not MSN_MAP, since dontdrawthemap was checked
		//
		if (IsMultimapOverlaysText()) {
			DrawLook8000(hdc,rc);
		}
		if (IsMultimapOverlaysGauges()) {
			if (LKVarioBar) LKDrawVario(hdc,rc);

			if ((mode.Is(Mode::MODE_CIRCLING)) )
				if (ThermalBar) DrawThermalBand(hdcDrawWindow, rc);

			DrawFinalGlide(hdcDrawWindow,rc);
		}

	} else {
		// Not in map painting environment 
		// ex. nearest pages, but also MAPRADAR..
	}

	// 
	DrawBottomBar(hdc,rc);
#ifdef CPUSTATS
	DrawCpuStats(hdc,rc);
#endif
#ifdef DRAWDEBUG
	DrawDebug(hdc,rc);
#endif
	// no need to do SelectObject as at the bottom of function
	return;
  }

  // When no terrain is painted, set a background0
  // Remember that in this case we have plenty of cpu time to spend for best result
  if (!IsMultimapTerrain() || !DerivedDrawInfo.TerrainValid || !RasterTerrain::isTerrainLoaded() ) {

    // display border and fill background..
	SelectObject(hdc, hInvBackgroundBrush[BgMapColor]);
	SelectObject(hdc, GetStockObject(WHITE_PEN));

	Rectangle(hdc,rc.left,rc.top,rc.right,rc.bottom);
	// We force LK painting black values on screen depending on the background color in use
	// TODO make it an array once settled
	// blackscreen would force everything to be painted white, instead
	LKTextBlack=BgMapColorTextBlack[BgMapColor];
	if (BgMapColor>6 ) BlackScreen=true; else BlackScreen=false; 
  } else {
	LKTextBlack=false;
	BlackScreen=false;
  }

  #if NEWSMARTZOOM
  // Copy the old background map with no overlays
  if (ONSMARTZOOM) {

	if (quickdrawscale>0) {
		delta_drawscale=zoom.DrawScale() / quickdrawscale;
	}

// StartupStore(_T("... QuickDrawScale=%.2f new zoom=%.2f  delta=%.2f\n"),quickdrawscale,zoom.DrawScale(),delta_drawscale);

	int dx=MapRect.right-MapRect.left;
	int dy=MapRect.bottom-MapRect.top;

	// notice: zoom in is always ok.. but zoom out starting from high zoom levels will make the picture
	// very small and unusable. We can consider to zoom out in fast zoom normally, in such cases?
	//
	// Notice 2: the delta is not yet working correctly 
	//
	if (delta_drawscale>1.0) {
		// zoom in
		StretchBlt(hdcDrawWindow, 
			0,0,
			dx,dy, 
			hdcQuickDrawWindow,
			(int)((dx/2) - (dx / delta_drawscale)/2),
			(int)((dy/2) - (dy / delta_drawscale)/2),
			(int)(dx / delta_drawscale),
			(int)(dy / delta_drawscale), 
			SRCCOPY);
	} else {
		// zoom out
		StretchBlt(hdcDrawWindow,
			(int)((dx/2) - (dx * delta_drawscale)/2),
			(int)((dy/2) - (dy * delta_drawscale)/2),
			(int)(dx * delta_drawscale),
			(int)(dy * delta_drawscale), 
			hdcQuickDrawWindow,
			0,0,
			dx,dy,  
			SRCCOPY);
	}
  }
  #endif


  // Logic of DONTDRAWTHEMAP is the following:
  // We are rendering the screen page here. If we are here, we passed Checkpoint Charlie.
  // So we were, at charlie, in MSM_MAP: preparing the main map stuff.
  // If we detect that MapSpace has CHANGED while we were doing our job here,
  // it means that the user has clicked meanwhile. He desires another page, so let's
  // reset our intentions and go back to beginning, or nearby..
  // We have a new job to do, for another MapSpace, no more MAP.
  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  #if NEWSMARTZOOM
  if ( OFFSMARTZOOM ) {
  #endif

  bool terrainpainted=false;

  if ((IsMultimapTerrain() && (DerivedDrawInfo.TerrainValid) 
       && RasterTerrain::isTerrainLoaded())
	) {
	// sunelevation is never used, it is still a todo in Terrain
	double sunelevation = 40.0;
	double sunazimuth=GetAzimuth();

    LockTerrainDataGraphics();
 	if (DONTDRAWTHEMAP) { // 100318
		UnlockTerrainDataGraphics();
		goto QuickRedraw;
	}
    DrawTerrain(hdc, DrawRect, sunazimuth, sunelevation);
    terrainpainted=true;
 	if (DONTDRAWTHEMAP) {
		UnlockTerrainDataGraphics();
		goto QuickRedraw;
	}
    if (!QUICKDRAW) {
    	// SHADED terrain unreachable, aka glide amoeba. This is not the outlined perimeter!
        #ifdef GTL2
    	if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) && 
            DerivedDrawInfo.TerrainValid) {
        #else
    	if ((FinalGlideTerrain==2) && DerivedDrawInfo.TerrainValid) {
        #endif
    	  DrawTerrainAbove(hdc, DrawRect);
    	}
    }
    UnlockTerrainDataGraphics();
  }

  #if NEWSMARTZOOM
  }
  #endif

  //
  // REMINDER: WE ARE IN MAIN MAP HERE: MSM_MAP ONLY, OR PANNING MODE!
  // MAPSPACEMODE CAN STILL CHANGE, DUE TO USER INPUT. BUT WE GOT HERE IN
  // EITHER PAN OR MSM_MAP.
  //

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  if (IsMultimapTopology()) {
    DrawTopology(hdc, DrawRect);
  } else {
	// If no topology wanted, but terrain painted, we paint only water stuff
	if (terrainpainted) DrawTopology(hdc, DrawRect,true);
  }
  #if 0
  StartupStore(_T("... Experimental1=%.0f\n"),Experimental1);
  StartupStore(_T("... Experimental2=%.0f\n"),Experimental2);
  Experimental1=0.0;
  Experimental2=0.0;
  #endif

  // Topology labels are printed first, using OLD wps positions from previous run!
  // Reset for topology labels decluttering engine occurs also in another place here!
  ResetLabelDeclutter();
  
  if (Flags_DrawTask && ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) {
	DrawTaskAAT(hdc, DrawRect);
  }

  
  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  if (IsMultimapAirspace())
  {
    if ( (GetAirSpaceFillType() == asp_fill_ablend_full) || (GetAirSpaceFillType() == asp_fill_ablend_borders) )
      DrawTptAirSpace(hdc, rc);
    else
      DrawAirSpace(hdc, rc);	 // full screen, to hide clipping effect on low border
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  // In QUICKDRAW dont draw trail, thermals, glide terrain
  if (QUICKDRAW) goto _skip_stuff;
 
  if(TrailActive) {
	// NEED REWRITING
	LKDrawTrail(hdc, Orig_Aircraft, DrawRect);
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  DrawThermalEstimate(hdc, DrawRect);
  if (OvertargetMode==OVT_THER) DrawThermalEstimateMultitarget(hdc, DrawRect);
 
  // draw red cross on glide through terrain marker
  if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid) {
    DrawGlideThroughTerrain(hdc, DrawRect);
  }
  
  if (DONTDRAWTHEMAP) { 
	goto QuickRedraw;
  }

_skip_stuff:

  if (IsMultimapAirspace() && AirspaceWarningMapLabels)
  {
	DrawAirspaceLabels(hdc, DrawRect, Orig_Aircraft);
	if (DONTDRAWTHEMAP) { // 100319
		goto QuickRedraw;
	}
  }

  if (IsMultimapWaypoints()) {
	DrawWaypointsNew(hdc,DrawRect);
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  if (Flags_DrawTask && ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) {
	DrawTask(hdc, DrawRect, Orig_Aircraft);
  }

  // FAI optimizer does not depend on tasks, being based on trace
  if (Flags_DrawFAI)  DrawFAIOptimizer(hdc, DrawRect, Orig_Aircraft);

  // In QUICKDRAW do not paint other useless stuff
  if (QUICKDRAW) {
	if (extGPSCONNECT) DrawBearing(hdc, DrawRect);
	goto _skip_2;
  }

  // ---------------------------------------------------

  DrawTeammate(hdc, rc);

  if (extGPSCONNECT) {
    DrawBestCruiseTrack(hdc, Orig_Aircraft);
    DrawBearing(hdc, DrawRect);
  }

  // draw wind vector at aircraft
  if (NOTANYPAN) {
    DrawWindAtAircraft2(hdc, Orig_Aircraft, DrawRect);
  } else if (mode.Is(Mode::MODE_TARGET_PAN)) {
    DrawWindAtAircraft2(hdc, Orig, rc);
  }

  #if NEWSMARTZOOM
  // Save the current rendered map before painting overlays
  if ( OFFSMARTZOOM ) {
	quickdrawscale=zoom.DrawScale();
	BitBlt(hdcQuickDrawWindow, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top,
		hdcDrawWindow, 0, 0, SRCCOPY);
  }
  #endif

  // VisualGlide drawn BEFORE lk8000 overlays
  if (NOTANYPAN && (VisualGlide > 0)) {
    DrawGlideCircle(hdc, Orig, rc); 
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  // Draw traffic and other specifix LK gauges
  LKDrawFLARMTraffic(hdc, DrawRect, Orig_Aircraft);

  // ---------------------------------------------------
_skip_2:

  if (NOTANYPAN) {
    // REMINDER TODO let it be configurable for not circling also, as before
    if ((mode.Is(Mode::MODE_CIRCLING)) )
      if (ThermalBar) DrawThermalBand(hdcDrawWindow, rc); // 091122
  
    if (IsMultimapOverlaysText()) DrawLook8000(hdc,rc); 
    DrawBottomBar(hdc,rc);
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }
    
  if (IsMultimapOverlaysGauges() && (LKVarioBar && NOTANYPAN)) 
	LKDrawVario(hdc,rc);
  
  // Draw glider or paraglider
  if (extGPSCONNECT) {
    DrawAircraft(hdc, Orig_Aircraft);
  }

  if (NOTANYPAN && !QUICKDRAW) {
	if (TrackBar) DrawHeading(hdc, Orig, DrawRect); 
  }

  #if USETOPOMARKS
  // marks on top...
  DrawMarks(hdc, rc);
  #endif

  if (ISGAAIRCRAFT && IsMultimapOverlaysGauges() && NOTANYPAN) DrawHSI(hdc,Orig,DrawRect); 

  if (!INPAN) {
	DrawMapScale(hdcDrawWindow,rc, zoom.BigZoom()); // unused BigZoom
	DrawCompass(hdcDrawWindow, rc, DisplayAngle);
  }

  if (IsMultimapOverlaysGauges() && NOTANYPAN) DrawFinalGlide(hdcDrawWindow,rc);


#ifdef CPUSTATS
  DrawCpuStats(hdc,rc);
#endif
#ifdef DRAWDEBUG
  DrawDebug(hdc,rc);
#endif

}
コード例 #25
0
ファイル: ZoomTopology.cpp プロジェクト: PhilColbert/LK8000
// mode: 0 normal Change the topology scale of Category with newScale.
// mode: 1 zoom more or less for the category with newScale (newScale is the zoom increment).
// mode: 2 zoom more or less for all categories (tCategory is ignored, newScale is the zoom increment for all items)
// mode: 3 reset default zoom for Category (newScale is ignored)
// mode: 4 reset default zoom for all Categories (Category is ignored, newScale is ignored)
void ChangeZoomTopology(int iCategory, double newScale, short cztmode)
{
  if (LKTopo<1) return;

  LockTerrainDataGraphics();

  if (cztmode==0) {
	for (int z=0; z<MAXTOPOLOGY; z++) {
		if (TopoStore[z]) { 
			if ( TopoStore[z]->scaleCategory == iCategory ) {
				#if DEBUG_LKTOPO
				StartupStore(_T("... ChangeZoomTopology zindex=%d, categ=%d oldscale=%f newscale=%f%s"),z,iCategory,
				TopoStore[z]->scaleThreshold, newScale,NEWLINE);
				#endif
				TopoStore[z]->scaleThreshold = newScale;
			}
		}
	}
	UnlockTerrainDataGraphics();
	return;
  }

  if (cztmode==1) {
	for (int z=0; z<MAXTOPOLOGY; z++) {
		if (TopoStore[z]) { 
			if ( TopoStore[z]->scaleCategory == iCategory ) {
				#if DEBUG_LKTOPO
				StartupStore(_T("... ChangeZoomTopology: zindex=%d, categ=%d oldscale=%f increment=%f%s"),z,iCategory,
				TopoStore[z]->scaleThreshold, newScale,NEWLINE);
				#endif
				TopoStore[z]->scaleThreshold += newScale;
			}
		}
	}
	UnlockTerrainDataGraphics();
	return;
  }

  if (cztmode==2) {
	for (int z=0; z<MAXTOPOLOGY; z++) {
		if (TopoStore[z]) { 
			#if DEBUG_LKTOPO
			StartupStore(_T("... ChangeZoomTopology for all: zindex=%d, categ=%d oldscale=%f increment=%f%s"),z,iCategory,
			TopoStore[z]->scaleThreshold, newScale,NEWLINE);
			#endif
			TopoStore[z]->scaleThreshold += newScale;
		}
	}
	UnlockTerrainDataGraphics();
	return;
  }

  if (cztmode==3) {
	for (int z=0; z<MAXTOPOLOGY; z++) {
		if (TopoStore[z]) { 
			if ( TopoStore[z]->scaleCategory == iCategory ) {
				#if DEBUG_LKTOPO
				StartupStore(_T("... ChangeZoomTopology default zindex=%d, categ=%d oldscale=%f default=%f%s"),
				z,iCategory, TopoStore[z]->scaleThreshold, TopoStore[z]->scaleDefaultThreshold,NEWLINE);
				#endif
				TopoStore[z]->scaleThreshold = TopoStore[z]->scaleDefaultThreshold;
			}
		}
	}
	UnlockTerrainDataGraphics();
	return;
  }

  if (cztmode==4) {
	for (int z=0; z<MAXTOPOLOGY; z++) {
		if (TopoStore[z]) { 
			#if DEBUG_LKTOPO
			StartupStore(_T("... ChangeZoomTopology all default zindex=%d, categ=%d oldscale=%f default=%f%s"),
			z,iCategory, TopoStore[z]->scaleThreshold, TopoStore[z]->scaleDefaultThreshold,NEWLINE);
			#endif
			// 130207 categories 5 and 10 are using DefaultThreshold for polygon paint,
			// and scaleThreshold for labels only. Upon reset, we should use the original
			// LKTopoZoom settings, because the Default is always fixed to 100!
			// Otherwise on reset we get 99.. even if we set LKTopoZoom to something else.
			// This is needed if we want to have a startup setting different from default
			// for these 05 and 10 categories only.
			// Sorry but water areas and labels are not easy to manage because we want to paint
			// blue all the way, but not also their labels.
			// Notice that since LKTopoZoom is saved to configuration, we cannot use it for reset!
			// This is why we have a special define DEFAULT_WATER_LABELS_THRESHOLD
			switch(TopoStore[z]->scaleCategory) {
				case 5:
					TopoStore[z]->scaleThreshold = DEFAULT_WATER_LABELS_THRESHOLD;
					break;
				case 10:
					TopoStore[z]->scaleThreshold = DEFAULT_WATER_LABELS_THRESHOLD;
					break;
				default:
					TopoStore[z]->scaleThreshold = TopoStore[z]->scaleDefaultThreshold;
					break;
			}
		}
	}
	UnlockTerrainDataGraphics();
	return;
  }

  UnlockTerrainDataGraphics();
}
コード例 #26
0
ファイル: Thread_Draw.cpp プロジェクト: Turbo87/LK8000
DWORD MapWindow::DrawThread (LPVOID lpvoid)
{

  FILETIME CreationTime, ExitTime, StartKernelTime, EndKernelTime, StartUserTime, EndUserTime ;


  while ((!ProgramStarted) || (!Initialised)) {
	Sleep(100);
  }

  // THREADRUNNING = FALSE;
  THREADEXIT = FALSE;

  // Reset common topology and waypoint label declutter, first init. Done also in other places.
  ResetLabelDeclutter();

  GetClientRect(hWndMapWindow, &MapRect);
  // Default draw area is full screen, no opacity
  DrawRect=MapRect;

  UpdateTimeStats(true);

  
  SetBkMode(hdcDrawWindow,TRANSPARENT);
  SetBkMode(hDCTemp,OPAQUE);
  SetBkMode(hDCMask,OPAQUE);

  // paint draw window black to start
  SelectObject(hdcDrawWindow, GetStockObject(BLACK_PEN));
  Rectangle(hdcDrawWindow,MapRect.left,MapRect.top,
            MapRect.right,MapRect.bottom);

  BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
         MapRect.bottom-MapRect.top, 
         hdcDrawWindow, 0, 0, SRCCOPY);

  // This is just here to give fully rendered start screen
  UpdateInfo(&GPS_INFO, &CALCULATED_INFO);
  MapDirty = true;
  UpdateTimeStats(true);

  zoom.RequestedScale(zoom.Scale());
  zoom.ModifyMapScale();
  FillScaleListForEngineeringUnits();
  
  bool lastdrawwasbitblitted=false;
  bool first_run=true;

  // 
  // Big LOOP
  //

  while (!CLOSETHREAD) 
  {
	WaitForSingleObject(drawTriggerEvent, 5000);
	ResetEvent(drawTriggerEvent);
	if (CLOSETHREAD) break; // drop out without drawing

	if ((!THREADRUNNING) || (!GlobalRunning)) {
		Sleep(100);
		continue;
	}

	// This is also occuring on resolution change
	if (LKSW_ReloadProfileBitmaps) {
		#if TESTBENCH
		StartupStore(_T(".... SWITCH: ReloadProfileBitmaps detected\n"));
		#endif
		// This is needed to update resolution change
		GetClientRect(hWndMapWindow, &MapRect);
		DrawRect=MapRect;
		FillScaleListForEngineeringUnits();
		LKUnloadProfileBitmaps();
		LKLoadProfileBitmaps();
		LKUnloadFixedBitmaps();
		LKLoadFixedBitmaps();
		MapWindow::zoom.Reset();

		// This will reset the function for the new ScreenScale
		PolygonRotateShift((POINT*)NULL,0,0,0,DisplayAngle+1);

		// Restart from moving map
		if (MapSpaceMode!=MSM_WELCOME) SetModeType(LKMODE_MAP, MP_MOVING);

		LKSW_ReloadProfileBitmaps=false;
		// These should be better checked. first_run is forcing also cache update for topo.
		ForceRenderMap=true;
		first_run=true;
	}



	GetThreadTimes( hDrawThread, &CreationTime, &ExitTime,&StartKernelTime,&StartUserTime);

	// Until MapDirty is set true again, we shall only repaint the screen. No Render, no calculations, no updates.
	// This is intended for very fast immediate screen refresh.
	//
	// MapDirty is set true by:
	//   - TriggerRedraws()  in calculations thread
	//   - RefreshMap()      in drawthread generally
	//


	extern int XstartScreen, YstartScreen, XtargetScreen, YtargetScreen;
	extern bool OnFastPanning;
	// While we are moving in bitblt mode, ignore RefreshMap requests from LK
	// unless a timeout was triggered by MapWndProc itself.
	if (OnFastPanning) {
		MapDirty=false;
	} 

	// We must check if we are on FastPanning, because we may be in pan mode even while
	// the menu buttons are active and we are using them, accessing other functions.
	// In that case, without checking OnFastPanning, we would fall back here and repaint
	// with bitblt everytime, while instead we were asked a simple fastrefresh!
	//
	// Notice: we could be !MapDirty without OnFastPanning, of course!
	//
	if (!MapDirty && !ForceRenderMap && OnFastPanning && !first_run) {
		
		if (!mode.Is(Mode::MODE_TARGET_PAN) && mode.Is(Mode::MODE_PAN)) {

			int fromX=0, fromY=0;

			fromX=XstartScreen-XtargetScreen;
			fromY=YstartScreen-YtargetScreen;

			BitBlt(hdcScreen, 0, 0, 
				MapRect.right-MapRect.left, 
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, WHITENESS);


			BitBlt(hdcScreen, 0, 0,
				MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 
				fromX,fromY, 				// source
				SRCCOPY);

			POINT centerscreen;
			centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
			DrawMapScale(hdcScreen,MapRect,false);
			DrawCrossHairs(hdcScreen, centerscreen, MapRect);
			lastdrawwasbitblitted=true;
		} else {
			// THIS IS NOT GOING TO HAPPEN!
			//
			// The map was not dirty, and we are not in fastpanning mode.
			// FastRefresh!  We simply redraw old bitmap. 
			//
			BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, SRCCOPY);

			lastdrawwasbitblitted=true;
		}

		// Now we can clear the flag. If it was off already, no problems.
		OnFastPanning=false;
		continue;

	} else {
		//
		// Else the map wasy dirty, and we must render it..
		// Notice: if we were fastpanning, than the map could not be dirty.
		//

		#if 1 // --------------------- EXPERIMENTAL, CHECK ZOOM IS WORKING IN PNA
		static double lasthere=0;
		// Only for special case: PAN mode, map not dirty (including requests for zooms!)
		// not in the ForceRenderMap run and last time was a real rendering. THEN, at these conditions,
		// we simply redraw old bitmap, for the scope of accelerating touch response.
		// In fact, if we are panning the map while rendering, there would be an annoying delay.
		// This is using lastdrawwasbitblitted
		if (INPAN && !MapDirty && !lastdrawwasbitblitted && !ForceRenderMap && !first_run) {
			// In any case, after 5 seconds redraw all
			if ( (LKHearthBeats-8) >lasthere ) {
				lasthere=LKHearthBeats;
				goto _dontbitblt;
			}
			BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, SRCCOPY);

			POINT centerscreen;
			centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
			DrawMapScale(hdcScreen,MapRect,false);
			DrawCrossHairs(hdcScreen, centerscreen, MapRect);
			continue;
		} 
		#endif // --------------------------
_dontbitblt:
		MapDirty = false;
		PanRefreshed=true;
	} // MapDirty

	lastdrawwasbitblitted=false;
	MapWindow::UpdateInfo(&GPS_INFO, &CALCULATED_INFO);

	RenderMapWindow(MapRect);
    
	if (!ForceRenderMap && !first_run) {
		BitBlt(hdcScreen, 0, 0, 
			MapRect.right-MapRect.left,
			MapRect.bottom-MapRect.top, 
			hdcDrawWindow, 0, 0, SRCCOPY);
		InvalidateRect(hWndMapWindow, &MapRect, false);
	}

	// Draw cross sight for pan mode, in the screen center, 
	// after a full repaint while not fastpanning
	if (mode.AnyPan() && !mode.Is(Mode::MODE_TARGET_PAN) && !OnFastPanning) {
		POINT centerscreen;
		centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
		DrawMapScale(hdcScreen,MapRect,false);
		DrawCompass(hdcScreen, MapRect, DisplayAngle);
		DrawCrossHairs(hdcScreen, centerscreen, MapRect);
	}

	UpdateTimeStats(false);

	// we do caching after screen update, to minimise perceived delay
	// UpdateCaches is updating topology bounds when either forced (only here)
	// or because MapWindow::ForceVisibilityScan  is set true.
	UpdateCaches(first_run);
	first_run=false;

	ForceRenderMap = false;

	if (ProgramStarted==psInitDone) {
		ProgramStarted = psFirstDrawDone;
	}

	if ( (GetThreadTimes( hDrawThread, &CreationTime, &ExitTime,&EndKernelTime,&EndUserTime)) == 0) {
		Cpu_Draw=9999;
	} else {
		Cpustats(&Cpu_Draw,&StartKernelTime, &EndKernelTime, &StartUserTime, &EndUserTime);
	}
    
  } // Big LOOP

  #if TESTBENCH
  StartupStore(_T("... Thread_Draw terminated\n"));
  #endif
  THREADEXIT = TRUE;
  return 0;
}
コード例 #27
0
ファイル: LoadNewTask.cpp プロジェクト: atrebbi/LK8000
// Loads a new task from scratch.
// This is called on startup by the even manager because in DEFAULT MENU we have a GCE event
// configured to load Default.tsk for STARTUP_SIMULATOR and STARTUP_REAL.
// Until we change this, which would be a good thing because these configuration are unnecessary ,
// we must use the FullResetAsked trick.
void LoadNewTask(LPCTSTR szFileName)
{
  HANDLE hFile;
  TASK_POINT Temp;
  START_POINT STemp;
  DWORD dwBytesRead;
  int i;
  bool TaskInvalid = false;
  bool WaypointInvalid = false;
  bool TaskLoaded = false;
  char taskinfo[LKPREAMBOLSIZE+1]; // 100207
  bool oldversion=false; // 100207
  TCHAR taskFileName[MAX_PATH];

  LockTaskData();

  ClearTask();
  if (FullResetAsked) {
	#if TESTBENCH
	StartupStore(_T("... LoadNewTask detected FullResetAsked, attempt to load DEMO.TSK\n"));
	#endif
	// Clear the flag, forever.
  	FullResetAsked=false;
	_tcscpy(taskFileName,_T("%LOCAL_PATH%\\\\_Tasks\\DEMO.TSK"));
	ExpandLocalPath(taskFileName);

  } else {
	_tcscpy(taskFileName,szFileName);
  }
  
  StartupStore(_T(". LoadNewTask <%s>%s"),taskFileName,NEWLINE);

  hFile = CreateFile(taskFileName,GENERIC_READ,0, (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);

  if(hFile!= INVALID_HANDLE_VALUE )
    {

      // Defaults
      int   old_StartLine    = StartLine;
      int   old_SectorType   = SectorType;
      DWORD old_SectorRadius = SectorRadius;
      DWORD old_StartRadius  = StartRadius;
      int   old_AutoAdvance  = AutoAdvance;
      double old_AATTaskLength = AATTaskLength;
      BOOL   old_AATEnabled  = AATEnabled;
      DWORD  old_FinishRadius = FinishRadius;
      int    old_FinishLine = FinishLine;
      bool   old_EnableMultipleStartPoints = EnableMultipleStartPoints;

      TaskLoaded = true;

	if(!ReadFile(hFile,&taskinfo,LKPREAMBOLSIZE,&dwBytesRead, (OVERLAPPED *)NULL)) {
		TaskInvalid = true;
		goto goEnd;
	}

	// task version check
	if ( (taskinfo[0]!= 'L') || (taskinfo[1]!= 'K') || (taskinfo[2]!=LKTASKVERSION) ) { 
		TaskInvalid = true;
		oldversion = true;
		goto goEnd;
	}

      for(i=0;i<OLD_MAXTASKPOINTS;i++)
        {
          if(!ReadFile(hFile,&Temp,sizeof(OLD_TASK_POINT),&dwBytesRead, (OVERLAPPED *)NULL))
            {
              TaskInvalid = true;
              break;
            }
          if(i < MAXTASKPOINTS) {
            memcpy(&Task[i],&Temp, sizeof(OLD_TASK_POINT));

            if( !ValidNotResWayPoint(Temp.Index) && (Temp.Index != -1) ) { // 091213
                // Task is only invalid here if the index is out of range
                // of the waypoints and not equal to -1.
                // (Because -1 indicates a null task item)
                WaypointInvalid = true; 
        	}
          }
        }

      if (!TaskInvalid) {

	if (!ReadFile(hFile,&AATEnabled,sizeof(BOOL),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }
	if (!ReadFile(hFile,&AATTaskLength,sizeof(double),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }
	
	// ToDo review by JW
	
	// 20060521:sgi added additional task parameters
	if (!ReadFile(hFile,&FinishRadius,sizeof(FinishRadius),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }
	if (!ReadFile(hFile,&FinishLine,sizeof(FinishLine),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }
	if (!ReadFile(hFile,&StartRadius,sizeof(StartRadius),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }
	if (!ReadFile(hFile,&StartLine,sizeof(StartLine),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }
	if (!ReadFile(hFile,&SectorType,sizeof(SectorType),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }
	if (!ReadFile(hFile,&SectorRadius,sizeof(SectorRadius),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }
	if (!ReadFile(hFile,&AutoAdvance,sizeof(AutoAdvance),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }

        if (!ReadFile(hFile,&EnableMultipleStartPoints,sizeof(bool),&dwBytesRead,(OVERLAPPED*)NULL)) {
          TaskInvalid = true;
        }

        for(i=0;i<MAXSTARTPOINTS;i++)
        {
          if(!ReadFile(hFile,&STemp,sizeof(START_POINT),&dwBytesRead, (OVERLAPPED *)NULL)) {
            TaskInvalid = true;
            break;
          }
	  
          if( ValidNotResWayPoint(STemp.Index) || (STemp.Index==-1) ) { // 091213
            memcpy(&StartPoints[i],&STemp, sizeof(START_POINT));
          } else {
	    WaypointInvalid = true;
		StartupStore(_T("--- LoadNewTask: invalid waypoint=%d found%s"),STemp.Index,NEWLINE); // 091213
	  }
        }

        // search for waypoints...
        if (!TaskInvalid) {
          if (!LoadTaskWaypoints(hFile) && WaypointInvalid) {
            // couldn't lookup the waypoints in the file and we know there are invalid waypoints
            TaskInvalid = true;
            StartupStore(_T(". LoadTaskNew: cant locate waypoint in file, and invalid wp in task file%s"),NEWLINE);
          }
        }

      }
      
        // TimeGate config
        if (!TaskInvalid) {
            TaskInvalid = !ReadFile(hFile, &PGOpenTimeH, sizeof (PGOpenTimeH), &dwBytesRead, (OVERLAPPED*) NULL);
        }
        if (!TaskInvalid) {
            TaskInvalid = !ReadFile(hFile, &PGOpenTimeM, sizeof (PGOpenTimeM), &dwBytesRead, (OVERLAPPED*) NULL);
        }
        if (!TaskInvalid) {
            InitActiveGate();

			// PGOpenTime is Calculated !
			int tmp;
            TaskInvalid = !ReadFile(hFile, &tmp, sizeof (tmp), &dwBytesRead, (OVERLAPPED*) NULL);
        }
        if (!TaskInvalid) {
			PGCloseTime=86399;
			
			// PGCloseTime is Calculated !
			int tmp;
            TaskInvalid = !ReadFile(hFile, &tmp, sizeof (tmp), &dwBytesRead, (OVERLAPPED*) NULL);
        }
        if (!TaskInvalid) {
            TaskInvalid = !ReadFile(hFile, &PGGateIntervalTime, sizeof (PGGateIntervalTime), &dwBytesRead, (OVERLAPPED*) NULL);
        }
        if (!TaskInvalid) {
            TaskInvalid = !ReadFile(hFile, &PGNumberOfGates, sizeof (PGNumberOfGates), &dwBytesRead, (OVERLAPPED*) NULL);
        }
        if (!TaskInvalid) {
            TaskInvalid = !ReadFile(hFile, &PGStartOut, sizeof (PGStartOut), &dwBytesRead, (OVERLAPPED*) NULL);
        }    

goEnd:

      CloseHandle(hFile);

      if (TaskInvalid) {
	if (oldversion)
		StartupStore(_T("------ Task is invalid: old task format%s"),NEWLINE);
	else
		StartupStore(_T("------ Task is invalid%s"),NEWLINE);

        StartLine = old_StartLine;
        SectorType = old_SectorType;
        SectorRadius = old_SectorRadius;
        StartRadius = old_StartRadius;
        AutoAdvance = old_AutoAdvance;
        AATTaskLength = old_AATTaskLength;
        AATEnabled = old_AATEnabled;
        FinishRadius = old_FinishRadius;
        FinishLine = old_FinishLine;
        EnableMultipleStartPoints = old_EnableMultipleStartPoints;
      }

  } else {
    StartupStore(_T("... LoadNewTask: file <%s> not found%s"),taskFileName,NEWLINE); // 091213
    TaskInvalid = true;
  }
  
  if (TaskInvalid) {
    ClearTask();
  } 

  RefreshTask();
  
  if (!ValidTaskPoint(0)) {
    ActiveWayPoint = 0;
  }

  UnlockTaskData();

  if (TaskInvalid && TaskLoaded) {
	if (oldversion) {
	// LKTOKEN  _@M360_ = "Invalid old task format!" 
		MessageBoxX(hWndMapWindow, gettext(TEXT("_@M360_")), 
	// LKTOKEN  _@M396_ = "Load task" 
			gettext(TEXT("_@M396_")), MB_OK|MB_ICONEXCLAMATION);
	} else {
	// LKTOKEN  _@M264_ = "Error in task file!" 
		MessageBoxX(hWndMapWindow, gettext(TEXT("_@M264_")), 
	// LKTOKEN  _@M396_ = "Load task" 
			gettext(TEXT("_@M396_")), MB_OK|MB_ICONEXCLAMATION);
	}
  } else {
	#if TESTBENCH
	StartupStore(_T("------ Task is Loaded%s"),NEWLINE);
	#endif
	TaskModified = false; 
	TargetModified = false;
	_tcscpy(LastTaskFileName, taskFileName);
  }

}
コード例 #28
0
short MapWindow::GetVisualGlidePoints(unsigned short numslots) {

#if BUGSTOP
    LKASSERT(numslots <= MAXBSLOT);
#else
    if (numslots > MAXBSLOT) numslots = MAXBSLOT;
#endif

    static short currentFilledNumber = -1;
    static double tmpSlotBrgDiff[MAXBSLOT + 1];

    int i;

    // RESET COMMAND by passing 0, normally by EVENT_NEWRUN 
    if (numslots == 0) {
#if DEBUG_GVG
        StartupStore(_T("...... GVGP: RESET\n"));
#endif
        for (i = 0; i < MAXBSLOT; i++) {
            slotWpIndex[i] = INVALID_VALUE;
        }
        currentFilledNumber = INVALID_VALUE;
        ResetVisualGlideGlobals();

        return INVALID_VALUE;
    }

    bool ndr = NearestDataReady;
    NearestDataReady = false;

    // No data ready..
    // if cfn is -1 we did not ever calculate it yet
    // otherwise 0 or >0  means use what we have already in the list
    if (!ndr) {
#if DEBUG_GVG
        StartupStore(_T("...... GVGP: no data ready, currentFN=%d\n"), currentFilledNumber);
#endif
        return currentFilledNumber;
    }

    if (SortedNumber <= 0) {
#if DEBUG_GVG
        StartupStore(_T("...... GVGP: SortedNumber is 0, no available wpts in this range!\n"));
#endif
        return 0;
    }

    int *pindex;
    int wpindex = 0;
    pindex = SortedTurnpointIndex;
    //
    // Reset  content
    //
    currentFilledNumber = 0;
    for (i = 0; i < MAXBSLOT; i++) {
        slotWpIndex[i] = INVALID_VALUE;
        tmpSlotBrgDiff[i] = -999;
    }

    //
    // set up fine tuned parameters for this run
    //

    int maxgratio = 1, mingratio = 1;
    double maxdistance = 300; // in METERS, not in KM!
    if (ISPARAGLIDER) {
        maxgratio = (int) (GlidePolar::bestld / 2);
        mingratio = (int) (GlidePolar::bestld * 1.5);
        maxdistance = 100;
    }
    if (ISGLIDER) {
        maxgratio = (int) (GlidePolar::bestld / 2);
        mingratio = (int) (GlidePolar::bestld * 1.5);
        maxdistance = 300;
    }
    if (ISGAAIRCRAFT) {
        maxgratio = (int) (GlidePolar::bestld / 2);
        mingratio = (int) (GlidePolar::bestld * 2);
        maxdistance = 300;
    }
    if (ISCAR) {
        maxgratio = 1;
        mingratio = 999;
        maxdistance = 100;
    }

    //
    // WE USE THE 2.3 PAGE (Nearest turnpoints) sorted by DIRECTION
    //

    // We do this in several passes. 
#define MAXPHASES	4
    unsigned short phase = 1;

#if DEBUG_GVG
    StartupStore(_T("GVGP: USING  %d Sorted Items available\n"), SortedNumber);
    int count = 0;
#endif
_tryagain:

    for (i = 0; i < numslots; i++) {
        LKASSERT(phase <= MAXPHASES);
#if DEBUG_GVG
        if (i >= SortedNumber) {
            StartupStore(_T("...... GVGP: PHASE %d warning not enough SortedNumber (%d) for i=%d\n"), phase, SortedNumber, i);
        }
#endif

        // Did we found at least one valid in current phase? Otherwise we skip the rest of numslots.
        // And we pass directly to the next phase.
        bool found = false;

        // look up for an empty slot, needed if running after phase 1
        if (slotWpIndex[i] != INVALID_VALUE) continue;

        // browse results for the best usable items
        for (int k = 0; k < SortedNumber; k++) {
            wpindex = *(pindex + k);
            if (!ValidWayPoint(wpindex)) {
                // since we are not synced with DoNearest update cycle, we might fall here while it
                // has reset the sorted list. No worry, in the worst case we miss a waypoint printed
                // for a second, and the list might be inaccurate for the current second.
                // But in the next run it will be ok, because at the end of its run, the DoNearest
                // will be setting DataReady flag on and we shall update correctly.
                continue;
            }

#if DEBUG_GVG
            count++;
#endif

            // did we already use it?
            bool alreadyused = false;
            for (int j = 0; j < numslots; j++) {
                if (slotWpIndex[j] == INVALID_VALUE) break;
                if (slotWpIndex[j] == wpindex) {
                    alreadyused = true;
                    break;
                }
            }
            if (alreadyused) continue;

            // unused one, decide if good or not
            // We do this in 3 phases..
            double distance = WayPointCalc[wpindex].Distance;
            double brgdiff = WayPointCalc[wpindex].Bearing - DrawInfo.TrackBearing;
            if (brgdiff < -180.0) {
                brgdiff += 360.0;
            } else {
                if (brgdiff > 180.0) brgdiff -= 360.0;
            }
            double abrgdiff = brgdiff;
            if (abrgdiff < 0) abrgdiff *= -1;

#if 0
            // do we already have a wp with same bearing? 
            for (int j = 0; j < numslots; j++) {
                if ((int) tmpSlotBrgDiff[j] == (int) brgdiff) {
                    //StartupStore(_T("%s with bdiff=%d already used\n"),WayPointList[wpindex].Name,(int)brgdiff);
                    alreadyused = true;
                    break;
                }
            }
            if (alreadyused) continue;
#endif

            // Careful: we are selecting abrgdiff from a list that is tuned to max 60, so ok.
            // DIRECTIONRANGE definition in DoNearest

            // Then we make a selective insertion, in several steps

            // First, we pick mountain passes and task points, generally priority #1 points
            // accepted from +-45 deg, but only if they are not absolutely unreachable
            if (phase == 1) {
                if (abrgdiff > 45) continue;
                // if we are practically over the waypoint, skip it 
                if (distance < maxdistance) continue;

                // Consider only Mt.Passes and task points not below us...
                if ((WayPointList[wpindex].Style == STYLE_MTPASS) ||
                        ((WayPointList[wpindex].InTask) && (distance > 100))) {

                    // ... that are not within an obvious glide ratio
                    // (considering even strong headwind, we want a very positive arrival)
                    if (WayPointCalc[wpindex].AltArriv[AltArrivMode] > 150) {
                        if (WayPointCalc[wpindex].GR <= (maxgratio / 1.5)) continue;
                    }
                    if (WayPointCalc[wpindex].AltArriv[AltArrivMode]<-100) {
                        if (WayPointCalc[wpindex].GR >= mingratio) continue;
                    }
                    goto _takeit;
                }
                continue;
            }

            // Second we take anything not obviously reachable
            if (phase == 2) {
                if (abrgdiff > 45) continue;
                if (distance < maxdistance) continue;
                if (WayPointCalc[wpindex].AltArriv[AltArrivMode] > 150) {
                    if (WayPointCalc[wpindex].GR <= (maxgratio)) continue;
                }
                goto _takeit;
            }

            if (phase == 3) {
                if (abrgdiff > 45) continue;
                if (distance < maxdistance) continue;
                goto _takeit;
            }

            // else we accept anything, in the original sort order


_takeit:

            // ok good, use it
            slotWpIndex[i] = wpindex;
            tmpSlotBrgDiff[i] = brgdiff;
            found = true;

#if DEBUG_GVG
            StartupStore(_T("PHASE %d  slot [%d] of %d : wp=%d <%s> brg=%f\n"),
                    phase, i, numslots, wpindex, WayPointList[wpindex].Name, brgdiff);
#endif
            currentFilledNumber++;
            break;
        } // for all sorted wps

        if (!found) {
#if DEBUG_GVG
            StartupStore(_T("PHASE %d  nothing found during search (stop at slot %d), advance to next phase\n"), phase, i >= numslots ? numslots - 1 : i);
#endif
            break;
        }
        if (currentFilledNumber >= numslots) {
#if DEBUG_GVG
            StartupStore(_T("PHASE %d  stop search, all slots taken\n"), phase);
#endif
            break;
        }
    } // for all slots to be filled

    if ((currentFilledNumber < numslots) && (phase < MAXPHASES)) {
#if DEBUG_GVG
        StartupStore(_T("PHASE %d  filled %d of %d slots, going phase %d\n"), phase, currentFilledNumber, numslots, phase + 1);
#endif
        phase++;
        goto _tryagain;
    }
#if DEBUG_GVG
    else {
        StartupStore(_T("PHASE %d  filled %d of %d slots\n"), phase, currentFilledNumber, numslots);
    }
    StartupStore(_T("TOTAL COUNTS=%d\n"), count);
#endif


    //
    // All wpts in the array are shuffled, unsorted by direction.
    // We must reposition them horizontally, using their bearing
    //
    int tmpSlotWpIndex[MAXBSLOT + 1];
    for (i = 0; i < MAXBSLOT; i++) tmpSlotWpIndex[i] = INVALID_VALUE;

#if DEBUG_GVG
    for (i = 0; i < numslots; i++) {
        StartupStore(_T(">>> [%d] %f  (wp=%d)\n"), i, tmpSlotBrgDiff[i], slotWpIndex[i]);
    }
#endif

    bool invalid = true, valid = false;
    unsigned short g;

    for (unsigned short nslot = 0; nslot < numslots; nslot++) {
        g = 0;
        double minim = 999;
        valid = false;
#if DEBUGSORT
        StartupStore(_T(".... Slot [%d]:\n"), nslot);
#endif
        for (unsigned short k = 0; k < numslots; k++) {
            if (tmpSlotBrgDiff[k] <= minim) {
                // is this already used?
                invalid = false;
                if (slotWpIndex[k] == -1) {
#if DEBUGSORT
                    StartupStore(_T(".... not using g=%d, it is an invalid waypoint\n"), k);
#endif
                    continue;
                }
                for (unsigned short n = 0; n < nslot; n++) {
                    if (tmpSlotWpIndex[n] == slotWpIndex[k]) {
#if DEBUGSORT
                        StartupStore(_T(".... not using g=%d, it is already used in newslot=%d\n"), k, n);
#endif
                        invalid = true;
                        continue;
                    }
                }

                if (invalid || !ValidWayPoint(slotWpIndex[k])) continue;

                // We do have a valid choice 
                g = k;
                minim = tmpSlotBrgDiff[k];
#if DEBUGSORT
                StartupStore(_T(".... minim=%f g=%d\n"), minim, g);
#endif
                valid = true;
            }
        }

        if (valid) {
            tmpSlotWpIndex[nslot] = slotWpIndex[g];
#if DEBUGSORT
            StartupStore(_T(".... FINAL for SLOT %d:  minim=%f g=%d\n"), nslot, minim, g);
#endif
        }
#if DEBUGSORT
        else {
            StartupStore(_T(".... FINAL for SLOT %d:  no valid point\n"), nslot);
        }
#endif
    }


    for (i = 0; i < numslots; i++) {
        slotWpIndex[i] = tmpSlotWpIndex[i];
    }

    return currentFilledNumber;
}
コード例 #29
0
ファイル: devWesterboer.cpp プロジェクト: AlphaLima/LK8000
static BOOL PWES0(PDeviceDescriptor_t d, TCHAR *String, NMEA_INFO *pGPS)
{
/*
	Sent by Westerboer VW1150  combining data stream from Flarm and VW1020.
	RMZ is being sent too, which is a problem.

	$PWES0,22,10,8,18,17,6,1767,1804,1073,1073,116,106
               A  B  C  D  E F  G    H    I    J   K    L


	A	Device              21 = VW1000, 21 = VW 1010, 22 = VW1020, 23 = VW1030
	B	vario *10			= 2.2 m/s
	C	average vario *10		= 1.0 m/s
	D	netto vario *10			= 1.8 m/s
	E	average netto vario *10		= 1.7 m/s
	F	 stf 		           = -999.. 999 (neg faster.. slower)
	G	baro altitude 			= 1767 m
	H	baro altitude calibrated by user?
	I	IAS kmh *10 			= 107.3 kmh
	J	TAS kmh *10  ?
	K	battery V *10			= 11.6 V
	L	OAT * 10			= 10.6 C

*/

  TCHAR ctemp[180];
  double vtas, vias;
  double altqne, altqnh;
  static bool initqnh=true;
#ifdef DEVICE_SERIAL  
  static int NoMsg =0;
 // static int HardwareId = 0;



if(_tcslen(String) < 180)
  if(((pGPS->SerialNumber == 0) || (oldSerial != SerialNumber)) && (NoMsg < 5))
  {
	NoMsg++ ;
    NMEAParser::ExtractParameter(String,ctemp,0);
    pGPS->HardwareId= (int)StrToDouble(ctemp,NULL);
    switch (pGPS->HardwareId)
    {
      case 21:  _tcscpy(d->Name, TEXT("VW1010")); break;
      case 22:  _tcscpy(d->Name, TEXT("VW1020")); break;
      case 23:  _tcscpy(d->Name, TEXT("VW1030")); break;
      default:  _tcscpy(d->Name, TEXT("Westerboer")); break;
    }
	StartupStore(_T(". %s\n"),ctemp);
	_stprintf(ctemp, _T("%s  DETECTED"), d->Name);
	oldSerial = pGPS->SerialNumber;
	DoStatusMessage(ctemp);
	StartupStore(_T(". %s\n"),ctemp);
  }
#endif
  // instant vario
  NMEAParser::ExtractParameter(String,ctemp,1);
  pGPS->Vario = StrToDouble(ctemp,NULL)/10;
  pGPS->VarioAvailable = TRUE;

  // netto vario
  NMEAParser::ExtractParameter(String,ctemp,3);
  if (ctemp[0] != '\0') {
	pGPS->NettoVario = StrToDouble(ctemp,NULL)/10;
	pGPS->NettoVarioAvailable = TRUE;
  } else
	pGPS->NettoVarioAvailable = FALSE;


  // Baro altitudes. To be verified, because I have no docs from Westerboer of any kind.
  NMEAParser::ExtractParameter(String,ctemp,6);
  altqne = StrToDouble(ctemp,NULL);
  NMEAParser::ExtractParameter(String,ctemp,7);
  altqnh = StrToDouble(ctemp,NULL);

  // AutoQNH will take care of setting an average QNH if nobody does it for a while
  if (initqnh) {
	// if wester has qnh set by user qne and qnh are of course different
	if (altqne != altqnh) {
		QNH=FindQNH(altqne,altqnh);
        CAirspaceManager::Instance().QnhChangeNotify(QNH);
		StartupStore(_T(". Using WESTERBOER QNH %f%s"),QNH,NEWLINE);
		initqnh=false;
	} else {
		// if locally QNH was set, either by user of by AutoQNH, stop processing QNH from Wester
		if ( (QNH <= 1012) || (QNH>=1014)) initqnh=false;
		// else continue entering initqnh until somebody changes qnh in either Wester or lk8000
	}
  }

  UpdateBaroSource( pGPS, 0,d,  AltitudeToQNHAltitude(altqne));


  // IAS and TAS
  NMEAParser::ExtractParameter(String,ctemp,8);
  vias = StrToDouble(ctemp,NULL)/36;
  NMEAParser::ExtractParameter(String,ctemp,9);
  vtas = StrToDouble(ctemp,NULL)/36;

  if (vias >1) {
	pGPS->TrueAirspeed = vtas;
	pGPS->IndicatedAirspeed = vias;
	pGPS->AirspeedAvailable = TRUE;
  } else
	pGPS->AirspeedAvailable = FALSE;

  // external battery voltage
  NMEAParser::ExtractParameter(String,ctemp,10);
  pGPS->ExtBatt1_Voltage = StrToDouble(ctemp,NULL)/10;

  // OAT
  NMEAParser::ExtractParameter(String,ctemp,11);
  pGPS->OutsideAirTemperature = StrToDouble(ctemp,NULL)/10;
  pGPS->TemperatureAvailable=TRUE;


  TriggerVarioUpdate();

  return TRUE;
}
コード例 #30
0
ファイル: ParseCUP.cpp プロジェクト: PhilColbert/LK8000
//#define CUPDEBUG
bool ParseCUPWayPointString(TCHAR *String,WAYPOINT *Temp)
{
  TCHAR ctemp[(COMMENT_SIZE*2)+1]; // must be bigger than COMMENT_SIZE!
  TCHAR *pToken;
  TCHAR TempString[READLINE_LENGTH+1];
  TCHAR OrigString[READLINE_LENGTH+1];
  TCHAR Tname[NAME_SIZE+1];
  int flags=0;

  unsigned int i, j;
  bool ishome=false; // 100310

  // strtok does not return empty fields. we create them here with special char
  #define DUMCHAR	'|'

  Temp->Visible = true; // default all waypoints visible at start
  Temp->FarVisible = true;
  Temp->Format = LKW_CUP;
  Temp->Number = WayPointList.size();

  Temp->FileNum = globalFileNum;

  #if BUGSTOP
  // This should never happen
  LKASSERT(_tcslen(String) < sizeof(OrigString));
  #endif
  LK_tcsncpy(OrigString, String,READLINE_LENGTH);  
  // if string is too short do nothing
  if (_tcslen(OrigString)<11) return false;

  #ifdef CUPDEBUG
  StartupStore(_T("OLD:<%s>%s"),OrigString,NEWLINE);
  #endif

  for (i=0,j=0; i<_tcslen(OrigString); i++) {

	// skip last comma, and avoid overruning the end
	if (  (i+1)>= _tcslen(OrigString)) break;
	if ( (OrigString[i] == _T(',')) && (OrigString[i+1] == _T(',')) ) {
		TempString[j++] = _T(',');
		TempString[j++] = _T(DUMCHAR);
		continue;
	} 
	/* we need terminations for comments
	if ( OrigString[i] == _T('\r') ) continue;
	if ( OrigString[i] == _T('\n') ) continue; 
	*/

	TempString[j++] = OrigString[i];
  }
  TempString[j] = _T('\0');

  #ifdef CUPDEBUG
  StartupStore(_T("NEW:<%s>%s"),TempString,NEWLINE);
  #endif
  // ---------------- NAME ----------------
  pToken = _tcstok(TempString, TEXT(","));
  if (pToken == NULL) return false;

  if (_tcslen(pToken)>NAME_SIZE) {
	pToken[NAME_SIZE-1]= _T('\0');
  }

  _tcscpy(Temp->Name, pToken); 
  CleanCupCode(Temp->Name);

  #ifdef CUPDEBUG
  StartupStore(_T("   CUP NAME=<%s>%s"),Temp->Name,NEWLINE);
  #endif


  // ---------------- CODE ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;

  if (_tcslen(pToken)>CUPSIZE_CODE) pToken[CUPSIZE_CODE-1]= _T('\0');
  _tcscpy(Temp->Code, pToken); 
  for (i=_tcslen(Temp->Code)-1; i>1; i--) if (Temp->Code[i]==' ') Temp->Code[i]=0; else break;
  _tcscpy(Tname,Temp->Code);
  for (j=0, i=0; i<_tcslen(Tname); i++) 
	//if (Tname[i]!='\"') Temp->Code[j++]=Tname[i];
	if ( (Tname[i]!='\"') && (Tname[i]!=DUMCHAR) ) Temp->Code[j++]=Tname[i]; Temp->Code[j]= _T('\0');

  if (_tcslen(Temp->Code)>5) { // 100310
	if (  _tcscmp(Temp->Code,_T("LKHOME")) == 0 ) {
		StartupStore(_T(". Found LKHOME inside CUP waypoint <%s>%s"),Temp->Name,NEWLINE);
		ishome=true;
	}
  }
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP CODE=<%s>%s"),Temp->Code,NEWLINE);
  #endif

        
  // ---------------- COUNTRY ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  LK_tcsncpy(Temp->Country,pToken,CUPSIZE_COUNTRY);
  if (_tcslen(Temp->Country)>3) {
	Temp->Country[3]= _T('\0');
  }
  if ((_tcslen(Temp->Country) == 1) && Temp->Country[0]==DUMCHAR) Temp->Country[0]=_T('\0');

  #ifdef CUPDEBUG
  StartupStore(_T("   CUP COUNTRY=<%s>%s"),Temp->Country,NEWLINE);
  #endif


  // ---------------- LATITUDE  ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;

  Temp->Latitude = CUPToLat(pToken);

  if((Temp->Latitude > 90) || (Temp->Latitude < -90)) {
	return false;
  }
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP LATITUDE=<%f>%s"),Temp->Latitude,NEWLINE);
  #endif


  // ---------------- LONGITUDE  ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  Temp->Longitude  = CUPToLon(pToken);
  if((Temp->Longitude  > 180) || (Temp->Longitude  < -180)) {
	return false;
  }
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP LONGITUDE=<%f>%s"),Temp->Longitude,NEWLINE);
  #endif



  // ---------------- ELEVATION  ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  Temp->Altitude = ReadAltitude(pToken);
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP ELEVATION=<%f>%s"),Temp->Altitude,NEWLINE);
  #endif
  if (Temp->Altitude == -9999){
	  Temp->Altitude=0;
  }


  // ---------------- STYLE  ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  
  Temp->Style = (int)_tcstol(pToken,NULL,10);
  switch(Temp->Style) {
	case 2:				// airfield grass
	case 4:				// glider site
	case 5:				// airfield solid
		flags = AIRPORT;
		flags += LANDPOINT;
		break;
	case 3:				// outlanding
		flags = LANDPOINT;
		break;
	default:
		flags = TURNPOINT;
		break;
  }
  if (ishome) flags += HOME;
  Temp->Flags = flags;

  #ifdef CUPDEBUG
  StartupStore(_T("   CUP STYLE=<%d> flags=%d %s"),Temp->Style,Temp->Flags,NEWLINE);
  #endif

  // ---------------- RWY DIRECTION   ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  if ((_tcslen(pToken) == 1) && (pToken[0]==DUMCHAR))
	Temp->RunwayDir=-1;
  else
	Temp->RunwayDir = (int)AngleLimit360(_tcstol(pToken, NULL, 10));
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP RUNWAY DIRECTION=<%d>%s"),Temp->RunwayDir,NEWLINE);
  #endif


  // ---------------- RWY LENGTH   ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  if ((_tcslen(pToken) == 1) && (pToken[0]==DUMCHAR))
	Temp->RunwayLen = -1;
  else
	Temp->RunwayLen = (int)ReadLength(pToken);
  #ifdef CUPDEBUG
  StartupStore(_T("   CUP RUNWAY LEN=<%d>%s"),Temp->RunwayLen,NEWLINE);
  #endif



  // ---------------- AIRPORT FREQ   ------------------
  pToken = _tcstok(NULL, TEXT(","));
  if (pToken == NULL) return false;
  if (_tcslen(pToken)>CUPSIZE_FREQ) pToken[CUPSIZE_FREQ-1]= _T('\0');
  _tcscpy(Temp->Freq, pToken); 
  TrimRight(Temp->Freq);
  _tcscpy(Tname,Temp->Freq);
  for (j=0, i=0; i<_tcslen(Tname); i++) 
	if ( (Tname[i]!='\"') && (Tname[i]!=DUMCHAR) ) Temp->Freq[j++]=Tname[i];
  Temp->Freq[j]= _T('\0');

  #ifdef CUPDEBUG
  StartupStore(_T("   CUP FREQ=<%s>%s"),Temp->Freq,NEWLINE);
  #endif


  // ---------------- COMMENT   ------------------
  pToken = _tcstok(NULL, TEXT("\n\r"));
  if (pToken != NULL) {

	if (_tcslen(pToken)>=COMMENT_SIZE) pToken[COMMENT_SIZE-1]= _T('\0');

	// remove trailing spaces and CR LF
	_tcscpy(ctemp, pToken); 
	for (i=_tcslen(ctemp)-1; i>1; i--) {
		if ( (ctemp[i]==' ') || (ctemp[i]=='\r') || (ctemp[i]=='\n') ) ctemp[i]=0;
		else
			break;
	}

	// now remove " " (if there)
	for (j=0, i=0; i<_tcslen(ctemp); i++) 
		if (ctemp[i]!='\"') ctemp[j++]=ctemp[i];
	ctemp[j]= _T('\0');
	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);
	}

	#ifdef CUPDEBUG
	StartupStore(_T("   CUP COMMENT=<%s>%s"),Temp->Comment,NEWLINE);
	#endif
  } else {
	Temp->Comment=NULL; // useless
  }

  if(Temp->Altitude <= 0) {
	WaypointAltitudeFromTerrain(Temp);
  } 

  if (Temp->Details) {
	free(Temp->Details);
  }

  return true;
}