void WhereAmI(void) { TCHAR toracle[400]; TCHAR ttmp[100]; double dist,brg; wcscpy(toracle,_T("")); int j=FindNearestFarVisibleWayPoint(GPS_INFO.Longitude,GPS_INFO.Latitude,50000); if (!ValidNotResWayPoint(j)) goto _after_nearestwp; DistanceBearing( WayPointList[j].Latitude,WayPointList[j].Longitude, GPS_INFO.Latitude,GPS_INFO.Longitude,&dist,&brg); _tcscat(toracle,_T("The Oracle answered:\n\n")); _tcscat(toracle,_T("You are ")); // nn km south if (dist>2000) { if (ISPARAGLIDER) _stprintf(ttmp,_T("%.1f %s %s "), dist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); else _stprintf(ttmp,_T("%.0f %s %s "), dist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); _tcscat(toracle,ttmp); } // over/below _stprintf(ttmp,_T("%s "),AltDiffToText(GPS_INFO.Altitude, WayPointList[j].Altitude)); _tcscat(toracle,ttmp); // waypoint name _stprintf(ttmp,_T("<%s>"), WayPointList[j].Name); _tcscat(toracle,ttmp); _stprintf(toracle,_T("%s\n%s"),toracle,_T(".... and much more!")); goto _end; _after_nearestwp: wsprintf(toracle,_T("%s"), _T("NO WAYPOINT NEAR YOU")); _end: MessageBoxX(hWndMainWindow, toracle, _T("WHERE AM I ?"), MB_OK|MB_ICONQUESTION, true); }
void WhereAmI::run(void) { #ifdef TESTBENCH StartupStore(_T("Oracle : start to find position") NEWLINE); #endif PeriodClock _time; _time.Update(); ResetNearestTopology(); LockTerrainDataGraphics(); const vectorObj center = { MapWindow::GetPanLongitude(), MapWindow::GetPanLatitude() }; rectObj bounds = { center.x, center.y, center.x, center.y }; for(int i = 0; i < 10; ++i) { double X, Y; FindLatitudeLongitude(center.y, center.x, i*360/10, 30*1000, &Y, &X ); bounds.minx = std::min(bounds.minx, X); bounds.maxx = std::max(bounds.maxx, X); bounds.miny = std::min(bounds.miny, Y); bounds.maxy = std::max(bounds.maxy, Y); } for (int z=0; z<MAXTOPOLOGY; z++) { if (TopoStore[z]) { // See also CheckScale for category checks! We should use a function in fact. if ( TopoStore[z]->scaleCategory == 10 || (TopoStore[z]->scaleCategory >= 70 && TopoStore[z]->scaleCategory <=100)) { TopoStore[z]->SearchNearest(bounds); } } } TCHAR ttmp[100]; double dist,wpdist,brg; NearestTopoItem *item=NULL; bool found=false, over=false, saynear=false, needmorewp=false, secondwpdone=false; #if TESTBENCH if (NearestBigCity.Valid) StartupStore(_T("... NEAREST BIG CITY <%s> at %.0f km brg=%.0f\n"), NearestBigCity.Name,NearestBigCity.Distance/1000,NearestBigCity.Bearing); if (NearestCity.Valid) StartupStore(_T("... NEAREST CITY <%s> at %.0f km brg=%.0f\n"), NearestCity.Name,NearestCity.Distance/1000,NearestCity.Bearing); if (NearestSmallCity.Valid) StartupStore(_T("... NEAREST TOWN <%s> at %.0f km brg=%.0f\n"), NearestSmallCity.Name,NearestSmallCity.Distance/1000,NearestSmallCity.Bearing); if (NearestWaterArea.Valid) StartupStore(_T("... NEAREST WATER AREA <%s> at %.0f km brg=%.0f\n"), NearestWaterArea.Name,NearestWaterArea.Distance/1000,NearestWaterArea.Bearing); #endif _stprintf(toracle,_T("%s\n\n"), MsgToken(1724)); // YOUR POSITION: if (NearestBigCity.Valid) { _tcscat(toracle, OracleFormatDistance(NearestBigCity.Name,MsgToken(1714), NearestBigCity.Distance, NearestBigCity.Bearing,0)); // the city _tcscat(toracle, _T("\n")); } if (NearestCity.Valid && NearestSmallCity.Valid) { if ( (NearestCity.Distance - NearestSmallCity.Distance) <=3000) item=&NearestCity; else item=&NearestSmallCity; } else { if (NearestCity.Valid) item=&NearestCity; else if (NearestSmallCity.Valid) item=&NearestSmallCity; } if (item) { dist=item->Distance; brg=item->Bearing; if (dist>1500) { // // 2km South of city // _stprintf(ttmp,_T("%.0f %s %s %s "), dist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg), MsgToken(1715)); // of the city _tcscat(toracle,ttmp); } else { // // Over city // _stprintf(ttmp,_T("%s "),MsgToken(1716)); // Over the city _tcscat(toracle,ttmp); over=true; } _stprintf(ttmp,_T("<%s>"), item->Name); _tcscat(toracle,ttmp); found=true; } // Careful, some wide water areas have the center far away from us even if we are over them. // We can only check for 2-5km distances max. if (NearestWaterArea.Valid) { if (found) { if (NearestWaterArea.Distance<2000) { if (over) { // // Over city and lake // _stprintf(ttmp,_T(" %s %s"), MsgToken(1717),NearestWaterArea.Name); // and _tcscat(toracle,ttmp); saynear=true; } else { // // 2km South of city // over lake // _stprintf(ttmp,_T("\n%s %s"), MsgToken(1718),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); saynear=true; } } else { if (NearestWaterArea.Distance<6000) { if (over) { // // Over city // near lake // _stprintf(ttmp,_T("\n%s %s"), MsgToken(1719),NearestWaterArea.Name); // near to _tcscat(toracle,ttmp); } else { // // 2km South of city // near lake // _stprintf(ttmp,_T("\n%s %s"), MsgToken(1718),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); } } // else no mention to water area, even if it is the only item. Not accurate! } } else { if (NearestWaterArea.Distance>2000) { brg=NearestWaterArea.Bearing; // // 2km North of lake // _stprintf(ttmp,_T("%.0f %s %s "), NearestWaterArea.Distance*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); _tcscat(toracle,ttmp); _stprintf(ttmp,_T("%s <%s>"), MsgToken(1711),NearestWaterArea.Name); // of _tcscat(toracle,ttmp); } else { // // Over lake // _stprintf(ttmp,_T("%s <%s>"), MsgToken(1718),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); over=true; } found=true; } } _tcscat(toracle,_T("\n")); // find nearest turnpoint & nearest Landable unsigned idx_nearest_airport = 0; unsigned idx_nearest_unknown = 0; { double dist_airport = std::numeric_limits<double>::max(); double dist_unknown = std::numeric_limits<double>::max(); for(unsigned i=NUMRESWP; i<WayPointList.size(); ++i) { if(WayPointList[i].Style == STYLE_THERMAL) continue; DistanceBearing(GPS_INFO.Latitude, GPS_INFO.Longitude, WayPointList[i].Latitude, WayPointList[i].Longitude, &(WayPointCalc[i].Distance), &(WayPointCalc[i].Bearing)); if(WayPointCalc[i].Distance > 70000) continue; // To Far if(WayPointCalc[i].WpType == WPT_AIRPORT) { if(WayPointCalc[i].Distance < dist_airport) { dist_airport = WayPointCalc[i].Distance; idx_nearest_airport = i; } } if(WayPointCalc[i].Distance < dist_unknown) { dist_unknown = WayPointCalc[i].Distance; idx_nearest_unknown = i; } } } int j = idx_nearest_unknown; if (!ValidNotResWayPoint(j)) goto _end; found=true; _dowp: DistanceBearing( WayPointList[j].Latitude,WayPointList[j].Longitude, GPS_INFO.Latitude, GPS_INFO.Longitude, &wpdist,&brg); TCHAR wptype[100]; switch(WayPointList[j].Style) { case STYLE_AIRFIELDGRASS: case STYLE_GLIDERSITE: _stprintf(wptype,_T("%s "), MsgToken(1720)); // the airfield of break; case STYLE_OUTLANDING: _stprintf(wptype,_T("%s "), MsgToken(1721)); // the field of needmorewp=true; break; case STYLE_AIRFIELDSOLID: _stprintf(wptype,_T("%s "), MsgToken(1722)); // the airport of break; default: _tcscpy(wptype,_T("")); needmorewp=true; break; } if ( (_tcslen(wptype)==0) && WayPointCalc[j].IsLandable) { if (WayPointCalc[j].IsAirport) { _stprintf(wptype,_T("%s "), MsgToken(1720)); // the airfield of needmorewp=false; } else { _stprintf(wptype,_T("%s "), MsgToken(1721)); // the field of needmorewp=true; } } else { if (_tcslen(wptype)==0 ) { _tcscpy(wptype,_T("")); needmorewp=true; } } // nn km south if (wpdist>2000) { // // 2km South of city // and/over lake // 4 km SW of waypoint _stprintf(ttmp,_T("\n%.0f %s %s "), wpdist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); _tcscat(toracle,ttmp); _stprintf(ttmp,_T("%s %s<%s>"), MsgToken(1711),wptype,WayPointList[j].Name); // of _tcscat(toracle,ttmp); } else { if (found) { if (over) { if (saynear) { // // 2km South of city // over lake // near waypoint // ---- // Over city and lake // near waypoint _stprintf(ttmp,_T("\n%s %s<%s>"), MsgToken(1719),wptype,WayPointList[j].Name); // near to _tcscat(toracle,ttmp); } else { // Over city // near lake and waypoint _stprintf(ttmp,_T(" %s %s<%s>"), MsgToken(1717),wptype,WayPointList[j].Name); // and _tcscat(toracle,ttmp); } } else { _stprintf(ttmp,_T("\n%s %s<%s>"), MsgToken(1719),wptype,WayPointList[j].Name); // near to _tcscat(toracle,ttmp); } } else { // // Near waypoint (because "over" could be wrong, we have altitudes in wp!) // _stprintf(ttmp,_T("%s %s<%s>"), MsgToken(1723),wptype,WayPointList[j].Name); // Near to _tcscat(toracle,ttmp); } } if (!needmorewp) goto _end; if (secondwpdone) goto _end; j=idx_nearest_airport; if (!ValidNotResWayPoint(j)) goto _end; secondwpdone=true; goto _dowp; _end: UnlockTerrainDataGraphics(); #ifdef ULLIS_PRIVATE_FEATURES _stprintf(ttmp,_T("\n\nin %i ft (MSL)"), (int)( GPS_INFO.Altitude*TOFEET)); // in height _tcscat(toracle,ttmp); #endif // VERY SORRY - YOUR POSITION IS UNKNOWN! if (!found) _stprintf(toracle,_T("\n\n%s\n\n%s"), MsgToken(1725),MsgToken(1726)); CharUpper(toracle); #ifdef TESTBENCH StartupStore(_T("Oracle : Result found in %d ms") NEWLINE, _time.Elapsed()); #endif }
// 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)) { ActiveWayPoint = 0; } UnlockTaskData(); if (TaskInvalid && TaskLoaded) { if (oldversion) { // LKTOKEN _@M360_ = "Invalid old task format!" MessageBoxX(gettext(TEXT("_@M360_")), // LKTOKEN _@M396_ = "Load task" gettext(TEXT("_@M396_")), mbOk); } else { // LKTOKEN _@M264_ = "Error in task file!" MessageBoxX(gettext(TEXT("_@M264_")), // LKTOKEN _@M396_ = "Load task" gettext(TEXT("_@M396_")), mbOk); } } else { #if TESTBENCH StartupStore(_T("------ Task is Loaded%s"),NEWLINE); #endif TaskModified = false; TargetModified = false; _tcscpy(LastTaskFileName, taskFileName); } }
// This is called by the Draw thread // This is still a draft, to find out what's best to tell and how. // It should be recoded once the rules are clear. void WhereAmI(void) { TCHAR toracle[500]; TCHAR ttmp[100]; double dist,wpdist,brg; NearestTopoItem *item=NULL; bool found=false, over=false, saynear=false, needmorewp=false, secondwpdone=false; #if TESTBENCH if (NearestBigCity.Valid) StartupStore(_T("... NEAREST BIG CITY <%s> at %.0f km brg=%.0f\n"), NearestBigCity.Name,NearestBigCity.Distance/1000,NearestBigCity.Bearing); if (NearestCity.Valid) StartupStore(_T("... NEAREST CITY <%s> at %.0f km brg=%.0f\n"), NearestCity.Name,NearestCity.Distance/1000,NearestCity.Bearing); if (NearestSmallCity.Valid) StartupStore(_T("... NEAREST TOWN <%s> at %.0f km brg=%.0f\n"), NearestSmallCity.Name,NearestSmallCity.Distance/1000,NearestSmallCity.Bearing); if (NearestWaterArea.Valid) StartupStore(_T("... NEAREST WATER AREA <%s> at %.0f km brg=%.0f\n"), NearestWaterArea.Name,NearestWaterArea.Distance/1000,NearestWaterArea.Bearing); #endif _stprintf(toracle,_T("%s\n\n"), gettext(_T("_@M1724_"))); // YOUR POSITION: if (NearestBigCity.Valid) { _tcscat(toracle, OracleFormatDistance(NearestBigCity.Name,gettext(_T("_@M1714_")), NearestBigCity.Distance, NearestBigCity.Bearing,0)); // the city _tcscat(toracle, _T("\n")); } if (NearestCity.Valid && NearestSmallCity.Valid) { if ( (NearestCity.Distance - NearestSmallCity.Distance) <=3000) item=&NearestCity; else item=&NearestSmallCity; } else { if (NearestCity.Valid) item=&NearestCity; else if (NearestSmallCity.Valid) item=&NearestSmallCity; } if (item) { dist=item->Distance; brg=item->Bearing; if (dist>1500) { // // 2km South of city // _stprintf(ttmp,_T("%.0f %s %s %s "), dist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg), gettext(_T("_@M1715_"))); // of the city _tcscat(toracle,ttmp); } else { // // Over city // _stprintf(ttmp,_T("%s "),gettext(_T("_@M1716_"))); // Over the city _tcscat(toracle,ttmp); over=true; } _stprintf(ttmp,_T("<%s>"), item->Name); _tcscat(toracle,ttmp); found=true; } // Careful, some wide water areas have the center far away from us even if we are over them. // We can only check for 2-5km distances max. if (NearestWaterArea.Valid) { if (found) { if (NearestWaterArea.Distance<2000) { if (over) { // // Over city and lake // _stprintf(ttmp,_T(" %s %s"), gettext(_T("_@M1717_")),NearestWaterArea.Name); // and _tcscat(toracle,ttmp); saynear=true; } else { // // 2km South of city // over lake // _stprintf(ttmp,_T("\n%s %s"), gettext(_T("_@M1718_")),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); saynear=true; } } else { if (NearestWaterArea.Distance<6000) { if (over) { // // Over city // near lake // _stprintf(ttmp,_T("\n%s %s"), gettext(_T("_@M1719_")),NearestWaterArea.Name); // near to _tcscat(toracle,ttmp); } else { // // 2km South of city // near lake // _stprintf(ttmp,_T("\n%s %s"), gettext(_T("_@M1718_")),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); } } // else no mention to water area, even if it is the only item. Not accurate! } } else { if (NearestWaterArea.Distance>2000) { brg=NearestWaterArea.Bearing; // // 2km North of lake // _stprintf(ttmp,_T("%.0f %s %s "), NearestWaterArea.Distance*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); _tcscat(toracle,ttmp); _stprintf(ttmp,_T("%s <%s>"), gettext(_T("_@M1711_")),NearestWaterArea.Name); // of _tcscat(toracle,ttmp); } else { // // Over lake // _stprintf(ttmp,_T("%s <%s>"), gettext(_T("_@M1718_")),NearestWaterArea.Name); // over _tcscat(toracle,ttmp); over=true; } found=true; } } _tcscat(toracle,_T("\n")); int j=FindNearestFarVisibleWayPoint(GPS_INFO.Longitude,GPS_INFO.Latitude,70000,WPT_UNKNOWN); if (!ValidNotResWayPoint(j)) goto _end; found=true; _dowp: DistanceBearing( WayPointList[j].Latitude,WayPointList[j].Longitude, GPS_INFO.Latitude, GPS_INFO.Longitude, &wpdist,&brg); TCHAR wptype[100]; switch(WayPointList[j].Style) { case 2: case 4: _stprintf(wptype,_T("%s "), gettext(_T("_@M1720_"))); // the airfield of break; case 3: _stprintf(wptype,_T("%s "), gettext(_T("_@M1721_"))); // the field of needmorewp=true; break; case 5: _stprintf(wptype,_T("%s "), gettext(_T("_@M1722_"))); // the airport of break; default: _tcscpy(wptype,_T("")); needmorewp=true; break; } if ( (_tcslen(wptype)==0) && WayPointCalc[j].IsLandable) { if (WayPointCalc[j].IsAirport) { _stprintf(wptype,_T("%s "), gettext(_T("_@M1720_"))); // the airfield of needmorewp=false; } else { _stprintf(wptype,_T("%s "), gettext(_T("_@M1721_"))); // the field of needmorewp=true; } } else { if (_tcslen(wptype)==0 ) { _tcscpy(wptype,_T("")); needmorewp=true; } } // nn km south if (wpdist>2000) { // // 2km South of city // and/over lake // 4 km SW of waypoint _stprintf(ttmp,_T("\n%.0f %s %s "), wpdist*DISTANCEMODIFY, Units::GetDistanceName(), DegreesToText(brg)); _tcscat(toracle,ttmp); _stprintf(ttmp,_T("%s %s<%s>"), gettext(_T("_@M1711_")),wptype,WayPointList[j].Name); // of _tcscat(toracle,ttmp); } else { if (found) { if (over) { if (saynear) { // // 2km South of city // over lake // near waypoint // ---- // Over city and lake // near waypoint _stprintf(ttmp,_T("\n%s %s<%s>"), gettext(_T("_@M1719_")),wptype,WayPointList[j].Name); // near to _tcscat(toracle,ttmp); } else { // Over city // near lake and waypoint _stprintf(ttmp,_T(" %s %s<%s>"), gettext(_T("_@M1717_")),wptype,WayPointList[j].Name); // and _tcscat(toracle,ttmp); } } else { _stprintf(ttmp,_T("\n%s %s<%s>"), gettext(_T("_@M1719_")),wptype,WayPointList[j].Name); // near to _tcscat(toracle,ttmp); } } else { // // Near waypoint (because "over" could be wrong, we have altitudes in wp!) // _stprintf(ttmp,_T("%s %s<%s>"), gettext(_T("_@M1723_")),wptype,WayPointList[j].Name); // Near to _tcscat(toracle,ttmp); } } if (!needmorewp) goto _end; if (secondwpdone) goto _end; j=FindNearestFarVisibleWayPoint(GPS_INFO.Longitude,GPS_INFO.Latitude,70000,WPT_AIRPORT); if (!ValidNotResWayPoint(j)) goto _end; secondwpdone=true; goto _dowp; _end: // VERY SORRY - YOUR POSITION IS UNKNOWN! if (!found) wsprintf(toracle,_T("\n\n%s\n\n%s"), gettext(_T("_@M1725_")),gettext(_T("_@M1726_"))); ConvToUpper(toracle); MessageBoxX(hWndMainWindow, toracle, gettext(_T("_@M1690_")), MB_OK|MB_ICONQUESTION, true); }
// 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<MAXTASKPOINTS;i++) { if(!ReadFile(hFile,&Temp,sizeof(TASK_POINT),&dwBytesRead, (OVERLAPPED *)NULL)) { TaskInvalid = true; break; } memcpy(&Task[i],&Temp, sizeof(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) { PGOpenTime=((PGOpenTimeH*60)+PGOpenTimeM)*60; // 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); } }