--- /dev/null
+typedef struct {
+ int type;
+ int time;
+ int a;
+ int b;
+} flight_record;
+
+flight_record
+read_record(file in) {
+ flight_record r;
+ File::fscanf(in, "%c %x %x %x\n",
+ &r.type, &r.time, &r.a, &r.b);
+ return r;
+}
+
+typedef struct {
+ int degrees;
+ int minutes;
+ int minutes_fraction;
+} gps_pos;
+
+typedef struct {
+ int hour;
+ int minute;
+ int second;
+} gps_time;
+
+real combine_gps_pos(gps_pos p, bool flag)
+{
+ real sign = flag ? -1 : 1;
+ return sign * (p.degrees + (p.minutes +
+ p.minutes_fraction / 10000)
+ / 60);
+}
+
+void read_gps(file in)
+{
+ gps_time time;
+ gps_pos lat, lon;
+ int flags;
+ int alt;
+
+ while (!File::end(in)) {
+ flight_record r = read_record(in);
+ switch (r.type) {
+ case 'G':
+ time.hour = r.a & 0xff;
+ time.minute = r.a >> 8;
+ time.second = r.b & 0xff;
+ flags = r.b >> 8;
+ break;
+ case 'N':
+ lat.degrees = r.a & 0xff;
+ lat.minutes = r.a >> 8;
+ lat.minutes_fraction = r.b;
+ break;
+ case 'W':
+ lon.degrees = r.a & 0xff;
+ lon.minutes = r.a >> 8;
+ lon.minutes_fraction = r.b;
+ break;
+ case 'H':
+ alt = r.a;
+ printf ("%5d %d sat ", r.time, flags & 0xf);
+ if ((flags & (1 << 4)) != 0) {
+ printf ("%02d:%02d:%02d ",
+ time.hour, time.minute, time.second);
+ printf ("%4d°%02d.%04d'%c %2d°%02d.%04d'%c %5dm ",
+ lat.degrees, lat.minutes,
+ lat.minutes_fraction,
+ (flags & (1 << 6)) != 0 ? 'S' : 'N',
+ lon.degrees, lon.minutes,
+ lon.minutes_fraction,
+ (flags & (1 << 5)) != 0 ? 'W' : 'E',
+ alt);
+ printf ("%11.6f %11.6f %5d\n",
+ combine_gps_pos(lat,
+ (flags & (1 << 6)) !=
+ 0),
+ combine_gps_pos(lon,
+ (flags & (1 << 5)) !=
+ 0),
+ alt);
+ } else {
+ printf ("unlocked\n");
+ }
+ break;
+ }
+ }
+}
+
+read_gps(stdin);