Example #1
0
int TimeLocal(int localtime) {
  localtime += GetUTCOffset();
  if (localtime<0) {
    localtime+= 3600*24;
  }
  return localtime;
}
Example #2
0
/**
 * Is called by the CalculationThread and processes the received GPS data in Basic()
 */
bool
GlideComputer::ProcessGPS()
{
  const MoreData &basic = Basic();
  DerivedInfo &calculated = SetCalculated();

  calculated.date_time_local = basic.date_time_utc + GetUTCOffset();

  calculated.Expire(basic.clock);

  // Process basic information
  air_data_computer.ProcessBasic(Basic(), SetCalculated(),
                                 GetComputerSettings());

  // Process basic task information
  task_computer.ProcessBasicTask(basic, LastBasic(),
                                 calculated, LastCalculated(),
                                 GetComputerSettings());
  task_computer.ProcessMoreTask(basic, calculated, LastCalculated(),
                                GetComputerSettings());

  // Check if everything is okay with the gps time and process it
  if (!air_data_computer.FlightTimes(Basic(), LastBasic(), SetCalculated(),
                                     GetComputerSettings()))
    return false;

  TakeoffLanding();

  if (!time_retreated())
    task_computer.ProcessAutoTask(basic, calculated, LastCalculated());

  // Process extended information
  air_data_computer.ProcessVertical(Basic(), LastBasic(),
                                    SetCalculated(), LastCalculated(),
                                    GetComputerSettings());

  if (!time_retreated())
    stats_computer.ProcessClimbEvents(calculated, LastCalculated());

  // Calculate the team code
  CalculateOwnTeamCode();

  // Calculate the bearing and range of the teammate
  CalculateTeammateBearingRange();

  vegavoice.Update(basic, Calculated(), GetComputerSettings().voice);

  // update basic trace history
  if (time_advanced())
    calculated.trace_history.append(basic);

  // Update the ConditionMonitors
  ConditionMonitorsUpdate(*this);

  return idle_clock.CheckUpdate(500);
}
Example #3
0
// simple localtime with no 24h exceeding
int LocalTime() {
  int localtime = (int)GPS_INFO.Time;
  localtime += GetUTCOffset();
  if (localtime<0) {
	localtime+= 86400;
  } else {
	if (localtime>86400) {
		localtime -=86400;
	}
  }
  return localtime;
}
Example #4
0
void
WaypointInfoWidget::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  RowFormWidget::Prepare(parent, rc);

  const MoreData &basic = CommonInterface::Basic();
  const DerivedInfo &calculated = CommonInterface::Calculated();
  const ComputerSettings &settings = CommonInterface::GetComputerSettings();

  StaticString<64> buffer;

  if (!waypoint.comment.empty())
    AddMultiLine(waypoint.comment.c_str());

  if (waypoint.radio_frequency.IsDefined() &&
      waypoint.radio_frequency.Format(buffer.buffer(),
                                      buffer.MAX_SIZE) != NULL) {
    buffer += _T(" MHz");
    AddReadOnly(_("Radio frequency"), NULL, buffer);
  }

  if (waypoint.runway.IsDirectionDefined())
    buffer.UnsafeFormat(_T("%02u"), waypoint.runway.GetDirectionName());
  else
    buffer.clear();

  if (waypoint.runway.IsLengthDefined()) {
    if (!buffer.empty())
      buffer += _T("; ");

    TCHAR length_buffer[16];
    FormatSmallUserDistance(length_buffer,
                                   fixed(waypoint.runway.GetLength()));
    buffer += length_buffer;
  }

  if (!buffer.empty())
    AddReadOnly(_("Runway"), NULL, buffer);

  if (FormatGeoPoint(waypoint.location,
                     buffer.buffer(), buffer.MAX_SIZE) != NULL)
    AddReadOnly(_("Location"), NULL, buffer);

  FormatUserAltitude(waypoint.elevation,
                            buffer.buffer(), buffer.MAX_SIZE);
  AddReadOnly(_("Elevation"), NULL, buffer);

  if (basic.time_available) {
    const SunEphemeris::Result sun =
      SunEphemeris::CalcSunTimes(waypoint.location, basic.date_time_utc,
                                 fixed(GetUTCOffset()) / 3600);

    const unsigned sunrisehours = (int)sun.time_of_sunrise;
    const unsigned sunrisemins = (int)((sun.time_of_sunrise - fixed(sunrisehours)) * 60);
    const unsigned sunset_hour = (int)sun.time_of_sunset;
    const unsigned sunset_minute = (int)((sun.time_of_sunset - fixed(sunset_hour)) * 60);

    buffer.UnsafeFormat(_T("%02u:%02u - %02u:%02u"), sunrisehours, sunrisemins, sunset_hour, sunset_minute);
    AddReadOnly(_("Daylight time"), NULL, buffer);
  }

  if (basic.location_available) {
    const GeoVector vector = basic.location.DistanceBearing(waypoint.location);

    TCHAR distance_buffer[32];
    FormatUserDistanceSmart(vector.distance, distance_buffer,
                                   ARRAY_SIZE(distance_buffer));

    FormatBearing(buffer.buffer(), buffer.MAX_SIZE,
                  vector.bearing, distance_buffer);
    AddReadOnly(_("Bearing and Distance"), NULL, buffer);
  }

  if (basic.location_available && basic.NavAltitudeAvailable() &&
      settings.polar.glide_polar_task.IsValid()) {
    const GlideState glide_state(basic.location.DistanceBearing(waypoint.location),
                                 waypoint.elevation + settings.task.safety_height_arrival,
                                 basic.nav_altitude,
                                 calculated.GetWindOrZero());

    GlidePolar gp0 = settings.polar.glide_polar_task;
    gp0.SetMC(fixed(0));
    AddGlideResult(_("Alt. diff. MC 0"),
                   MacCready::Solve(settings.task.glide,
                                    gp0, glide_state));

    AddGlideResult(_("Alt. diff. MC safety"),
                   MacCready::Solve(settings.task.glide,
                                    calculated.glide_polar_safety,
                                    glide_state));

    AddGlideResult(_("Alt. diff. MC current"),
                   MacCready::Solve(settings.task.glide,
                                    settings.polar.glide_polar_task,
                                    glide_state));
  }
}
Example #5
0
void 
dlgWayPointDetailsShowModal(SingleWindow &parent, const Waypoint& way_point)
{
  selected_waypoint = &way_point;

  TCHAR sTmp[128];
  double sunsettime;
  int sunsethours;
  int sunsetmins;
  WndProperty *wp;

  if (Layout::landscape)
    wf = LoadDialog(CallBackTable,
                        parent, _T("IDR_XML_WAYPOINTDETAILS_L"));
  else
    wf = LoadDialog(CallBackTable,
                        parent, _T("IDR_XML_WAYPOINTDETAILS"));

  nTextLines = 0;

  if (!wf)
    return;

  Profile::GetPath(szProfileWayPointFile, szWaypointFile);
  ExtractDirectory(Directory, szWaypointFile);

  _stprintf(path_modis, _T("%s" DIR_SEPARATOR_S "modis-%03d.jpg"),
           Directory,
           selected_waypoint->id+1);
  _stprintf(path_google,_T("%s" DIR_SEPARATOR_S "google-%03d.jpg"),
           Directory,
           selected_waypoint->id+1);

  _stprintf(sTmp, _T("%s: '%s'"), wf->GetCaption(), selected_waypoint->Name.c_str());
  wf->SetCaption(sTmp);

  wp = ((WndProperty *)wf->FindByName(_T("prpWpComment")));
  wp->SetText(selected_waypoint->Comment.c_str());

  Units::LongitudeToString(selected_waypoint->Location.Longitude, sTmp, sizeof(sTmp)-1);
  ((WndProperty *)wf->FindByName(_T("prpLongitude")))
    ->SetText(sTmp);

  Units::LatitudeToString(selected_waypoint->Location.Latitude, sTmp, sizeof(sTmp)-1);
  ((WndProperty *)wf->FindByName(_T("prpLatitude")))
    ->SetText(sTmp);

  Units::FormatUserAltitude(selected_waypoint->Altitude, sTmp, sizeof(sTmp)-1);
  ((WndProperty *)wf->FindByName(_T("prpAltitude")))
    ->SetText(sTmp);

  SunEphemeris sun;
  sunsettime = sun.CalcSunTimes
    (selected_waypoint->Location,
     XCSoarInterface::Basic().DateTime,
     GetUTCOffset()/3600);

  sunsethours = (int)sunsettime;
  sunsetmins = (int)((sunsettime - sunsethours) * 60);

  _stprintf(sTmp, _T("%02d:%02d"), sunsethours, sunsetmins);
  ((WndProperty *)wf->FindByName(_T("prpSunset")))->SetText(sTmp);

  fixed distance;
  Angle bearing;
  DistanceBearing(XCSoarInterface::Basic().Location,
                  selected_waypoint->Location,
                  &distance,
                  &bearing);

  TCHAR DistanceText[MAX_PATH];
  Units::FormatUserDistance(distance, DistanceText, 10);
  ((WndProperty *)wf->FindByName(_T("prpDistance"))) ->SetText(DistanceText);

  _stprintf(sTmp, _T("%d")_T(DEG), iround(bearing.value_degrees()));
  ((WndProperty *)wf->FindByName(_T("prpBearing"))) ->SetText(sTmp);

  GlidePolar glide_polar = protected_task_manager.get_glide_polar();
  GlidePolar safety_polar = protected_task_manager.get_safety_polar();

  UnorderedTaskPoint t(way_point, XCSoarInterface::SettingsComputer());
  GlideResult r;

  // alt reqd at current mc

  const AIRCRAFT_STATE aircraft_state =
    ToAircraftState(XCSoarInterface::Basic());
  r = TaskSolution::glide_solution_remaining(t, aircraft_state, glide_polar);
  wp = (WndProperty *)wf->FindByName(_T("prpMc2"));
  if (wp) {
    _stprintf(sTmp, _T("%.0f %s"),
              (double)Units::ToUserAltitude(r.AltitudeDifference),
              Units::GetAltitudeName());
    wp->SetText(sTmp);
  }

  // alt reqd at mc 0

  glide_polar.set_mc(fixed_zero);
  r = TaskSolution::glide_solution_remaining(t, aircraft_state, glide_polar);
  wp = (WndProperty *)wf->FindByName(_T("prpMc0"));
  if (wp) {
    _stprintf(sTmp, _T("%.0f %s"),
              (double)Units::ToUserAltitude(r.AltitudeDifference),
              Units::GetAltitudeName());
    wp->SetText(sTmp);
  }

  // alt reqd at safety mc

  r = TaskSolution::glide_solution_remaining(t, aircraft_state, safety_polar);
  wp = (WndProperty *)wf->FindByName(_T("prpMc1"));
  if (wp) {
    _stprintf(sTmp, _T("%.0f %s"),
              (double)Units::ToUserAltitude(r.AltitudeDifference),
              Units::GetAltitudeName());
    wp->SetText(sTmp);
  }

  wf->SetKeyDownNotify(FormKeyDown);

  ((WndButton *)wf->FindByName(_T("cmdClose")))->SetOnClickNotify(OnCloseClicked);

  wInfo = ((WndFrame *)wf->FindByName(_T("frmInfos")));
  wCommand = ((WndFrame *)wf->FindByName(_T("frmCommands")));
  wSpecial = ((WndFrame *)wf->FindByName(_T("frmSpecial")));
  wImage = ((WndOwnerDrawFrame *)wf->FindByName(_T("frmImage")));
  wDetails = (WndListFrame*)wf->FindByName(_T("frmDetails"));
  wDetails->SetPaintItemCallback(OnPaintDetailsListItem);

  assert(wInfo != NULL);
  assert(wCommand != NULL);
  assert(wSpecial != NULL);
  assert(wImage != NULL);
  assert(wDetails != NULL);

  nTextLines = TextToLineOffsets(way_point.Details.c_str(), LineOffsets, MAXLINES);
  wDetails->SetLength(nTextLines);

  /*
  TODO enhancement: wpdetails
  wp = ((WndProperty *)wf->FindByName(_T("prpWpDetails")));
  wp->SetText(way_point.Details);
  */

  wCommand->hide();
  wSpecial->hide();
  wImage->SetCaption(_("Blank!"));
  wImage->SetOnPaintNotify(OnImagePaint);

  WndButton *wb;

  wb = ((WndButton *)wf->FindByName(_T("cmdGoto")));
  if (wb)
    wb->SetOnClickNotify(OnGotoClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdReplace")));
  if (wb)
    wb->SetOnClickNotify(OnReplaceClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdNewHome")));
  if (wb)
    wb->SetOnClickNotify(OnNewHomeClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdSetAlternate1")));
  if (wb)
    wb->SetOnClickNotify(OnSetAlternate1Clicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdSetAlternate2")));
  if (wb)
    wb->SetOnClickNotify(OnSetAlternate2Clicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdClearAlternates")));
  if (wb)
    wb->SetOnClickNotify(OnClearAlternatesClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdTeamCode")));
  if (wb)
    wb->SetOnClickNotify(OnTeamCodeClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdInserInTask")));
  if (wb)
    wb->SetOnClickNotify(OnInsertInTaskClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdAppendInTask")));
  if (wb)
    wb->SetOnClickNotify(OnAppendInTaskClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdRemoveFromTask")));
  if (wb)
    wb->SetOnClickNotify(OnRemoveFromTaskClicked);

  hasimage1 = jpgimage1.load_file(path_modis);
  hasimage2 = jpgimage2.load_file(path_google);

  page = 0;

  NextPage(0); // JMW just to turn proper pages on/off

  wf->ShowModal();

  delete wf;

  wf = NULL;
}
Example #6
0
void
TimesStatusPanel::Refresh()
{
  const NMEAInfo &basic = CommonInterface::Basic();
  const FlyingState &flight = CommonInterface::Calculated().flight;

  StaticString<64> temp;

  if (basic.location_available && basic.date_available) {
    SunEphemeris::Result sun = SunEphemeris::CalcSunTimes(
        basic.location, basic.date_time_utc, fixed(GetUTCOffset()) / 3600);

    const unsigned sunrisehours = (int)sun.time_of_sunrise;
    const unsigned sunrisemins = (int)((sun.time_of_sunrise - fixed(sunrisehours)) * 60);
    const unsigned sunsethours = (int)sun.time_of_sunset;
    const unsigned sunsetmins = (int)((sun.time_of_sunset - fixed(sunsethours)) * 60);

    temp.Format(_T("%02u:%02u - %02u:%02u"), sunrisehours, sunrisemins, sunsethours, sunsetmins);
    SetText(Daylight, temp);
  } else {
    SetText(Daylight, _T(""));
  }

  if (basic.time_available) {
    FormatSignedTimeHHMM(temp.buffer(), DetectCurrentTime(basic));
    SetText(LocalTime, temp);
    FormatSignedTimeHHMM(temp.buffer(), (int) basic.time);
    SetText(UTCTime, temp);
  } else {
    SetText(LocalTime, _T(""));
    SetText(UTCTime, _T(""));
  }

  if (basic.date_available) {
    temp.Format(_T("%04d-%02d-%02d"), basic.date_time_utc.year,
                basic.date_time_utc.month, basic.date_time_utc.day);
    SetText(UTCDate, temp);
  } else {
    SetText(UTCDate, _T(""));
  }

  if (positive(flight.flight_time)) {
    FormatSignedTimeHHMM(temp.buffer(), TimeLocal((int)flight.takeoff_time));
    SetText(TakeoffTime, temp);
  } else {
    SetText(TakeoffTime, _T(""));
  }

  if (!flight.flying && positive(flight.flight_time)) {
    FormatSignedTimeHHMM(temp.buffer(),
                      TimeLocal((long)(flight.takeoff_time
                                       + flight.flight_time)));
    SetText(LandingTime, temp);
  } else {
    SetText(LandingTime, _T(""));
  }

  if (positive(flight.flight_time)) {
    FormatSignedTimeHHMM(temp.buffer(), (int)flight.flight_time);
    SetText(FlightTime, temp);
  } else {
    SetText(FlightTime, _T(""));
  }
}
Example #7
0
void 
dlgWayPointDetailsShowModal(SingleWindow &parent, const Waypoint& way_point,
                            bool allow_navigation)
{
  const NMEA_INFO &basic = CommonInterface::Basic();
  const DERIVED_INFO &calculated = CommonInterface::Calculated();
  const SETTINGS_COMPUTER &settings_computer =
    CommonInterface::SettingsComputer();

  selected_waypoint = &way_point;

  wf = LoadDialog(CallBackTable, parent,
                  Layout::landscape ? _T("IDR_XML_WAYPOINTDETAILS_L") :
                                      _T("IDR_XML_WAYPOINTDETAILS"));
  assert(wf != NULL);

  nTextLines = 0;

  TCHAR buffer[MAX_PATH];
  const TCHAR *Directory = NULL;
  if (Profile::GetPath(szProfileWayPointFile, szWaypointFile))
    Directory = DirName(szWaypointFile, buffer);
  if (Directory == NULL)
    Directory = _T("");

  _stprintf(path_modis, _T("%s" DIR_SEPARATOR_S "modis-%03d.jpg"),
           Directory,
            selected_waypoint->original_id);
  _stprintf(path_google,_T("%s" DIR_SEPARATOR_S "google-%03d.jpg"),
           Directory,
            selected_waypoint->original_id);

  TCHAR sTmp[128];
  _stprintf(sTmp, _T("%s: '%s'"), wf->GetCaption(), selected_waypoint->Name.c_str());
  wf->SetCaption(sTmp);

  WndProperty *wp;
  wp = ((WndProperty *)wf->FindByName(_T("prpWpComment")));
  wp->SetText(selected_waypoint->Comment.c_str());

  Units::LongitudeToString(selected_waypoint->Location.Longitude, sTmp, sizeof(sTmp)-1);
  ((WndProperty *)wf->FindByName(_T("prpLongitude")))
    ->SetText(sTmp);

  Units::LatitudeToString(selected_waypoint->Location.Latitude, sTmp, sizeof(sTmp)-1);
  ((WndProperty *)wf->FindByName(_T("prpLatitude")))
    ->SetText(sTmp);

  Units::FormatUserAltitude(selected_waypoint->Altitude, sTmp, sizeof(sTmp)-1);
  ((WndProperty *)wf->FindByName(_T("prpAltitude")))
    ->SetText(sTmp);

  SunEphemeris sun;
  sun.CalcSunTimes(selected_waypoint->Location,
                   basic.DateTime,
                   fixed(GetUTCOffset()) / 3600);

  int sunsethours = (int)sun.TimeOfSunSet;
  int sunsetmins = (int)((sun.TimeOfSunSet - fixed(sunsethours)) * 60);

  _stprintf(sTmp, _T("%02d:%02d"), sunsethours, sunsetmins);
  ((WndProperty *)wf->FindByName(_T("prpSunset")))->SetText(sTmp);

  GeoVector gv = basic.Location.distance_bearing(selected_waypoint->Location);

  TCHAR DistanceText[MAX_PATH];
  Units::FormatUserDistance(gv.Distance, DistanceText, 10);
  ((WndProperty *)wf->FindByName(_T("prpDistance"))) ->SetText(DistanceText);

  _stprintf(sTmp, _T("%d")_T(DEG), iround(gv.Bearing.value_degrees()));
  ((WndProperty *)wf->FindByName(_T("prpBearing"))) ->SetText(sTmp);

  if (protected_task_manager != NULL) {
    GlidePolar glide_polar = settings_computer.glide_polar_task;
    const GlidePolar &safety_polar = calculated.glide_polar_safety;

    UnorderedTaskPoint t(way_point, settings_computer);
    GlideResult r;

    // alt reqd at current mc

    const AIRCRAFT_STATE aircraft_state = ToAircraftState(basic, calculated);
    r = TaskSolution::glide_solution_remaining(t, aircraft_state, glide_polar);
    wp = (WndProperty *)wf->FindByName(_T("prpMc2"));
    if (wp) {
      _stprintf(sTmp, _T("%.0f %s"),
                (double)Units::ToUserAltitude(r.AltitudeDifference),
                Units::GetAltitudeName());
      wp->SetText(sTmp);
    }

    // alt reqd at mc 0

    glide_polar.set_mc(fixed_zero);
    r = TaskSolution::glide_solution_remaining(t, aircraft_state, glide_polar);
    wp = (WndProperty *)wf->FindByName(_T("prpMc0"));
    if (wp) {
      _stprintf(sTmp, _T("%.0f %s"),
                (double)Units::ToUserAltitude(r.AltitudeDifference),
                Units::GetAltitudeName());
      wp->SetText(sTmp);
    }

    // alt reqd at safety mc

    r = TaskSolution::glide_solution_remaining(t, aircraft_state, safety_polar);
    wp = (WndProperty *)wf->FindByName(_T("prpMc1"));
    if (wp) {
      _stprintf(sTmp, _T("%.0f %s"),
                (double)Units::ToUserAltitude(r.AltitudeDifference),
                Units::GetAltitudeName());
      wp->SetText(sTmp);
    }
  }

  wf->SetKeyDownNotify(FormKeyDown);

  ((WndButton *)wf->FindByName(_T("cmdClose")))->SetOnClickNotify(OnCloseClicked);

  wInfo = ((WndFrame *)wf->FindByName(_T("frmInfos")));
  wCommand = ((WndFrame *)wf->FindByName(_T("frmCommands")));
  wImage = ((WndOwnerDrawFrame *)wf->FindByName(_T("frmImage")));
  wDetails = (WndListFrame*)wf->FindByName(_T("frmDetails"));
  wDetails->SetPaintItemCallback(OnPaintDetailsListItem);

  assert(wInfo != NULL);
  assert(wCommand != NULL);
  assert(wImage != NULL);
  assert(wDetails != NULL);

  nTextLines = TextToLineOffsets(way_point.Details.c_str(), LineOffsets, MAXLINES);
  wDetails->SetLength(nTextLines);

  wCommand->hide();
  wImage->SetOnPaintNotify(OnImagePaint);

  if (!allow_navigation) {
    WndButton* butnav = NULL;
    butnav = (WndButton *)wf->FindByName(_T("cmdPrev"));
    assert(butnav);
    butnav->hide();
    butnav = (WndButton *)wf->FindByName(_T("cmdNext"));
    assert(butnav);
    butnav->hide();
    butnav = (WndButton *)wf->FindByName(_T("cmdGoto"));
    assert(butnav);
    butnav->hide();
  }

  WndButton *wb;

  wb = ((WndButton *)wf->FindByName(_T("cmdGoto")));
  if (wb)
    wb->SetOnClickNotify(OnGotoClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdReplace")));
  if (wb)
    wb->SetOnClickNotify(OnReplaceClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdNewHome")));
  if (wb)
    wb->SetOnClickNotify(OnNewHomeClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdInserInTask")));
  if (wb)
    wb->SetOnClickNotify(OnInsertInTaskClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdAppendInTask")));
  if (wb)
    wb->SetOnClickNotify(OnAppendInTaskClicked);

  wb = ((WndButton *)wf->FindByName(_T("cmdRemoveFromTask")));
  if (wb)
    wb->SetOnClickNotify(OnRemoveFromTaskClicked);

  /* JMW disabled until 6.2 work, see #996
  wb = ((WndButton *)wf->FindByName(_T("cmdGotoAndClearTask")));
  if (wb)
    wb->SetOnClickNotify(OnGotoAndClearTaskClicked);
  */

  wb = ((WndButton *)wf->FindByName(_T("cmdActivatePan")));
  if (wb)
    wb->SetOnClickNotify(OnActivatePanClicked);

  hasimage1 = jpgimage1.load_file(path_modis);
  hasimage2 = jpgimage2.load_file(path_google);

  page = 0;

  NextPage(0); // JMW just to turn proper pages on/off

  wf->ShowModal();

  delete wf;

  jpgimage1.reset();
  jpgimage2.reset();
}
Example #8
0
  int CalcSunTimes(float longit, float latit){

    //    float intz;
    double tzone,d,lambda;
    double obliq,alpha,delta,LL,equation,ha,hb,twx;
    int y, m, day, h;

    // testing

    // JG Removed simulator conditional code, since GPS_INFO now set up
    // from system time.

    m = GPS_INFO.Month;
    y = GPS_INFO.Year;
    day = GPS_INFO.Day;
    h = ((int)GPS_INFO.Time)/3600;
    h = (h % 24);

    // TODO code: use TimeLocal function from Process here?
    tzone = GetUTCOffset()/3600.0;

    d = FNday(y, m, day, (float)h);

    //   Use FNsun to find the ecliptic longitude of the
    //   Sun

    lambda = FNsun(d);

    //   Obliquity of the ecliptic

    obliq = 23.439 * DEG_TO_RAD - .0000004 * DEG_TO_RAD * d;

    //   Find the RA and DEC of the Sun

    alpha = atan2(cos(obliq) * sin(lambda), cos(lambda));
    delta = asin(sin(obliq) * sin(lambda));

    // Find the Equation of Time
    // in minutes
    // Correction suggested by David Smith
    LL = L - alpha;
    if (L < PI) LL += 2.0*PI;
    equation = 1440.0 * (1.0 - LL / PI/2.0);
    ha = f0(latit,delta);
    hb = f1(latit,delta);
    twx = hb - ha;  // length of twilight in radians
    twx = 12.0*twx/PI;              // length of twilight in hours

    //  printf("ha= %.2f   hb= %.2f \n",ha,hb);

    // Conversion of angle to hours and minutes //
    daylen = RAD_TO_DEG*ha/7.5;
    if (daylen<0.0001) {daylen = 0.0;}
    // arctic winter     //

    riset = 12.0 - 12.0 * ha/PI + tzone - longit/15.0 + equation/60.0;
    settm = 12.0 + 12.0 * ha/PI + tzone - longit/15.0 + equation/60.0;
    noont = riset + 12.0 * ha/PI;
    altmax = 90.0 + delta * RAD_TO_DEG - latit; 

    // Correction for S HS suggested by David Smith
    // to express altitude as degrees from the N horizon
    if (latit < delta * RAD_TO_DEG) altmax = 180.0 - altmax;

    twam = riset - twx;     // morning twilight begin
    twpm = settm + twx;     // evening twilight end

    if (riset > 24.0) riset-= 24.0;
    if (settm > 24.0) settm-= 24.0;

    /*
      puts("\n Sunrise and set");
      puts("===============");

      printf("  year  : %d \n",(int)y);
      printf("  month : %d \n",(int)m);
      printf("  day   : %d \n\n",(int)day);
      printf("Days since Y2K :  %d \n",(int)d);

      printf("Latitude :  %3.1f, longitude: %3.1f, timezone: %3.1f \n",(float)latit,(float)longit,(float)tzone);
      printf("Declination   :  %.2f \n",delta * RAD_TO_DEG);
      printf("Daylength     : "); showhrmn(daylen); puts(" hours \n");
      printf("Civil twilight: ");
      showhrmn(twam); puts("");
      printf("Sunrise       : ");
      showhrmn(riset); puts("");

      printf("Sun altitude ");
      // Amendment by D. Smith
      printf(" %.2f degr",altmax);
      printf(latit>=0.0 ? " South" : " North");
      printf(" at noontime "); showhrmn(noont); puts("");
      printf("Sunset        : ");
      showhrmn(settm);  puts("");
      printf("Civil twilight: ");
      showhrmn(twpm);  puts("\n");
    */
    return 0;
  }