You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

enigma.cc 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. Enigma route and waypoint file format.
  3. http://www.mglavionics.co.za/Docs/Enigma%20Waypoint%20format.pdf
  4. Binary data are stored in little endian (Intel)
  5. Copyright (C) 2009 Tobias Kretschmar, tobias.kretschmar@gmx.de
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
  17. */
  18. #include "defs.h"
  19. #include <math.h>
  20. #include <stdlib.h>
  21. #define MYNAME "Enigma binary route and waypoint file format"
  22. #define WTYPE_WAYPOINT 0 // Waypoint of unspecified type
  23. #define WTYPE_AIRPORT 1 // Typical assignment for medium sized airports
  24. #define WTYPE_MAJORAIRPORT 2 // Typical assignment for large and international airports
  25. #define WTYPE_SEAPLANEBASE 3
  26. #define WTYPE_AIRFIELD 4 // Typical assignment for smaller municipal airfields, glider fields etc
  27. #define WTYPE_PRIVATEAIRFIELD 5
  28. #define WTYPE_ULTRALIGHTFIELD 6
  29. #define WTYPE_INTERSECTION 7 // (reporting point, boundary crossing)
  30. #define WTYPE_HELIPORT 8
  31. #define WTYPE_TACAN 9
  32. #define WTYPE_NDBDME 10
  33. #define WTYPE_NDB 11
  34. #define WTYPE_VORDME 12
  35. #define WTYPE_VORTAC 13
  36. #define WTYPE_FANMARKER 14
  37. #define WTYPE_VOR 15
  38. #define WTYPE_REPPT 16
  39. #define WTYPE_LFR 17
  40. #define WTYPE_UHFNDB 18
  41. #define WTYPE_MNDB 19
  42. #define WTYPE_MNDBDME 20
  43. #define WTYPE_LOM 21
  44. #define WTYPE_LMM 22
  45. #define WTYPE_LOCSDF 23
  46. #define WTYPE_MLSISMLS 24
  47. #define WTYPE_OTHERNAV 25 // Navaid not falling into any of the above types
  48. #define WTYPE_ALTITUDECHANGE 26 // Location at which altitude should be changed
  49. union wpt_data {
  50. int32_t wp_altitude; // Waypoint type 0-6,8: waypoint altitude in feet
  51. int32_t tg_altitude; // Waypoint type 26: target altitude in feet
  52. uint32_t frequency; // Waypoint type 9-25: freq in steps of 1000Hz (118Mhz = 180000)
  53. int32_t dummy; // waypoint type 7, unused
  54. };
  55. typedef struct enigma_wpt {
  56. int32_t latitude;
  57. int32_t longitude;
  58. union wpt_data data;
  59. uint8_t waypoint_type;
  60. uint8_t shortname_len;
  61. char shortname[6];
  62. uint8_t longname_len;
  63. char longname[27];
  64. } ENIGMA_WPT;
  65. static gbfile* file_in, *file_out;
  66. static void
  67. rd_init(const QString& fname)
  68. {
  69. file_in = gbfopen_le(fname, "rb", MYNAME);
  70. }
  71. int32_t decToEnigmaPosition(double val)
  72. {
  73. int degrees = fabs(val);
  74. double frac = fabs(val) - degrees;
  75. int enigmadeg = degrees * 180000;
  76. int enigmafrac = 180000 * frac;
  77. int sign = (val < 0) ? -1 : +1;
  78. return sign * (enigmadeg + enigmafrac);
  79. }
  80. float enigmaPositionToDec(int32_t val)
  81. {
  82. int deg = abs(val) / 180000;
  83. int enigmafrac = abs(val) % 180000;
  84. double frac = (double)enigmafrac / 180000;
  85. int sign = (val < 0) ? -1 : +1;
  86. return sign * (deg + frac);
  87. }
  88. static void
  89. data_read(void)
  90. {
  91. struct enigma_wpt ewpt;
  92. route_head* route = route_head_alloc();
  93. route_add_head(route);
  94. while (1 == gbfread(&ewpt, sizeof(ewpt), 1, file_in)) {
  95. Waypoint* wpt = new Waypoint;
  96. wpt->latitude = enigmaPositionToDec(le_read32(&ewpt.latitude));
  97. wpt->longitude = enigmaPositionToDec(le_read32(&ewpt.longitude));
  98. char*sn = xstrndup(ewpt.shortname, ewpt.shortname_len);
  99. wpt->shortname = sn;
  100. xfree(sn);
  101. char* ds = xstrndup(ewpt.longname, ewpt.longname_len);
  102. wpt->description = ds;
  103. xfree(ds);
  104. switch (ewpt.waypoint_type) {
  105. case WTYPE_WAYPOINT: // 0
  106. case WTYPE_AIRPORT: // 1
  107. case WTYPE_MAJORAIRPORT: // 2
  108. case WTYPE_SEAPLANEBASE: // 3
  109. case WTYPE_AIRFIELD: // 4
  110. case WTYPE_PRIVATEAIRFIELD: // 5
  111. case WTYPE_ULTRALIGHTFIELD: // 6
  112. case WTYPE_HELIPORT: // 8
  113. // waypoint altitude
  114. wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.wp_altitude) - 1000);
  115. break;
  116. case WTYPE_ALTITUDECHANGE: // 26
  117. // target altitude
  118. wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.tg_altitude) - 1000);
  119. break;
  120. case WTYPE_INTERSECTION: // 7
  121. // unused
  122. break;
  123. default:
  124. // frequency
  125. // wpt->frequency = wpt.le_readu32(ewpt.data.frequency);
  126. ;
  127. }
  128. route_add_wpt(route, wpt);
  129. }
  130. }
  131. static void
  132. rd_deinit(void)
  133. {
  134. gbfclose(file_in);
  135. }
  136. static void
  137. wr_init(const QString& fname)
  138. {
  139. file_out = gbfopen_le(fname, "wb", MYNAME);
  140. }
  141. #ifndef min
  142. #define min(a,b) ((a) < (b)) ? (a) : (b)
  143. #endif
  144. #ifndef max
  145. #define max(a,b) ((a) > (b)) ? (a) : (b)
  146. #endif
  147. static void
  148. enigma_waypt_disp(const Waypoint* wpt)
  149. {
  150. struct enigma_wpt ewpt;
  151. memset(&ewpt, 0, sizeof(ewpt));
  152. le_write32(&ewpt.latitude, decToEnigmaPosition(wpt->latitude));
  153. le_write32(&ewpt.longitude, decToEnigmaPosition(wpt->longitude));
  154. ewpt.waypoint_type = WTYPE_WAYPOINT;
  155. if (wpt->altitude != unknown_alt) {
  156. le_write32(&ewpt.data.wp_altitude, METERS_TO_FEET(wpt->altitude) + 1000);
  157. }
  158. if (wpt->shortname != NULL) {
  159. ewpt.shortname_len = min(6, strlen(CSTRc(wpt->shortname)));
  160. strncpy(ewpt.shortname, CSTRc(wpt->shortname), 6);
  161. }
  162. if (wpt->description != NULL) {
  163. ewpt.longname_len = min(27, strlen(CSTRc(wpt->description)));
  164. strncpy(ewpt.longname, CSTRc(wpt->description), 27);
  165. }
  166. gbfwrite(&ewpt, sizeof(ewpt), 1, file_out);
  167. }
  168. static void
  169. data_write(void)
  170. {
  171. route_disp_all(NULL, NULL, enigma_waypt_disp);
  172. }
  173. static void
  174. wr_deinit(void)
  175. {
  176. gbfclose(file_out);
  177. }
  178. ff_vecs_t enigma_vecs = {
  179. ff_type_file,
  180. {
  181. ff_cap_none, /* waypoints */
  182. ff_cap_none, /* tracks */
  183. (ff_cap)(ff_cap_read | ff_cap_write) /* routes */
  184. },
  185. rd_init,
  186. wr_init,
  187. rd_deinit,
  188. wr_deinit,
  189. data_read,
  190. data_write,
  191. NULL,
  192. NULL,
  193. CET_CHARSET_ASCII, 0 /* CET-REVIEW */
  194. };