Subversion Repositories public

Rev

Rev 249 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
88 andreas 1
/***************************************************************************
119 andreas 2
 *   Copyright (C) 2007, 2008 by Andreas Theofilu                          *
3
 *   andreas@theosys.at                                                    *
88 andreas 4
 *                                                                         *
5
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   it under the terms of the GNU General Public License as published by  *
7
 *   the Free Software Foundation version 3 of the License.                *
8
 *                                                                         *
9
 *   This program is distributed in the hope that it will be useful,       *
10
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12
 *   GNU General Public License for more details.                          *
13
 *                                                                         *
14
 *   You should have received a copy of the GNU General Public License     *
15
 *   along with this program; if not, write to the                         *
16
 *   Free Software Foundation, Inc.,                                       *
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18
 ***************************************************************************/
19
 
20
#include <time.h>
21
#include <string.h>
104 andreas 22
#include <math.h>
314 andreas 23
#include <boost/concept_check.hpp>
88 andreas 24
#include "garmin.h"
25
#include "disassemble.h"
26
 
104 andreas 27
#define Deg2Rad(n)	((n) * DEG_2_RAD)
28
 
88 andreas 29
disassemble::disassemble()
30
{
31
	lap_node = 0;
32
	run_node = 0;
33
	point_node = 0;
248 andreas 34
 
35
	totalDistance = 0.0;
36
	totalTime = 0;
37
	avgHR = 0.0;
38
	avgSpeed = 0.0;
39
	maxSpeed = 0.0;
40
	ascend = 0.0;
41
	descend = 0.0;
88 andreas 42
}
43
 
44
disassemble::~disassemble()
45
{
46
	destroy();
47
}
48
 
49
void disassemble::destroy()
50
{
51
LAP_NODE *lakt, *ln;
52
RUN_NODE *rakt, *rn;
53
POINT_NODE *pakt, *pn;
54
 
55
	if (lap_node != NULL)		// free allocated laps
56
	{
57
	   lakt = lap_node;
58
 
59
	   while (lakt)
60
	   {
61
	      ln = lakt;
62
	      delete ln->lap;
63
	      lakt = lakt->next;
64
	      delete ln;
65
	   }
66
	}
67
 
68
	lap_node = NULL;
69
 
70
	if (lap_node != NULL)		// free allocated runs
71
	{
72
	   rakt = run_node;
73
 
74
	   while (rakt)
75
	   {
76
	      rn = rakt;
77
	      delete rn->run;
78
	      rakt = rakt->next;
79
	      delete rn;
80
	   }
81
	}
82
 
83
	run_node = NULL;
84
 
85
	if (point_node != NULL)		// free allocated points
86
	{
87
	   pakt = point_node;
88
 
89
	   while (pakt)
90
	   {
91
	      pn = pakt;
92
	      delete pn->point;
93
	      pakt = pakt->next;
94
	      delete pn;
95
	   }
96
	}
97
 
98
	point_node = NULL;
248 andreas 99
 
100
	totalDistance = 0.0;
101
	totalTime = 0;
102
	avgHR = 0.0;
103
	avgSpeed = 0.0;
104
	maxSpeed = 0.0;
105
	ascend = 0.0;
106
	descend = 0.0;
107
 
88 andreas 108
}
109
 
110
LAP_NODE *disassemble::addLap ()
111
{
112
LAP_NODE *akt, *n;
113
 
114
	if (lap_node == 0)		// First lap to add
115
	{
116
	   lap_node = new LAP_NODE;
117
	   lap_node->lap = new LAP;
118
 
119
	   memmove (lap_node->lap, &lap, sizeof(LAP));
120
	   lap_node->next = 0;
121
	   akt = lap_node;
122
	}
123
	else				// additional lap to add
124
	{
125
	   n = lap_node;
126
 
127
	   while (n->next)
128
	      n = n->next;
129
 
130
	   akt = new LAP_NODE;
131
	   akt->lap = new LAP;
132
	   memmove (akt->lap, &lap, sizeof(LAP));
133
	   akt->next = 0;
134
	   n->next = akt;
135
	}
136
 
137
	return akt;
138
}
139
 
140
LAP *disassemble::getLap(int index)
141
{
142
LAP_NODE *akt = lap_node;
143
 
144
	while (akt)
145
	{
146
	   if (akt->lap->index == (uint32)index)
147
	      return akt->lap;
148
 
149
	   akt = akt->next;
150
	}
151
 
152
	return NULL;
153
}
154
 
223 andreas 155
LAP *disassemble::getLapT(uint32 time)
156
{
157
LAP_NODE *akt = lap_node;
158
 
159
	while (akt)
160
	{
161
	   if ((akt->lap->start_time + akt->lap->total_time / 100) >= time)
162
	      return akt->lap;
163
 
164
	   akt = akt->next;
165
	}
166
 
167
	return NULL;
168
}
169
 
88 andreas 170
RUN_NODE *disassemble::addRun ()
171
{
172
RUN_NODE *akt, *n;
173
 
174
	if (run_node == 0)		// First run to add
175
	{
176
	   run_node = new RUN_NODE;
177
	   run_node->run = new RUN;
178
 
179
	   memmove (run_node->run, &run, sizeof(RUN));
180
	   run_node->next = 0;
181
	   akt = run_node;
182
	}
183
	else				// additional run to add
184
	{
185
	   n = run_node;
186
 
187
	   while (n != NULL && n->next != NULL)
188
	      n = n->next;
189
 
190
	   akt = new RUN_NODE;
191
	   akt->run = new RUN;
192
	   memmove (akt->run, &run, sizeof(RUN));
193
	   akt->next = 0;
194
	   n->next = akt;
195
	}
196
 
197
	return akt;
198
}
199
 
200
POINT_NODE *disassemble::addPoint ()
201
{
202
POINT_NODE *akt, *n;
203
 
204
	if (point_node == 0)		// First point to add
205
	{
206
	   point_node = new POINT_NODE;
207
	   point_node->point = new POINT;
208
 
209
	   memmove (point_node->point, &point, sizeof(POINT));
210
	   point_node->number = 0;
211
	   point_node->next = 0;
212
	   akt = point_node;
213
	}
214
	else				// additional point to add
215
	{
216
	   n = point_node;
217
 
218
	   while (n != NULL && n->next != NULL)
219
	      n = n->next;
220
 
221
	   akt = new POINT_NODE;
222
	   akt->point = new POINT;
223
	   memmove (akt->point, &point, sizeof(point));
224
	   akt->number = n->number + 1;
225
	   akt->next = 0;
226
	   n->next = akt;
227
	}
228
 
229
	return akt;
230
}
231
 
232
POINT *disassemble::getPoint(int number)
233
{
234
POINT_NODE *akt;
235
 
236
	akt = point_node;
237
 
238
	while (akt)
239
	{
240
	   if (akt->number == number)
241
	      return akt->point;
242
 
243
	   akt = akt->next;
244
	}
245
 
246
	return 0;
247
}
248
 
249
POINT *disassemble::getPoint(uint32 time)
250
{
251
POINT_NODE *akt;
252
 
253
	akt = point_node;
254
 
255
	while (akt)
256
	{
257
	   if (akt->point->time >= time)
258
	      return akt->point;
259
 
260
	   akt = akt->next;
261
	}
262
 
263
	return 0;
264
}
265
 
266
/* 
267
   This file contains functions to get Garmin datatypes.
268
   The functions aim to reproduce the data losslessly, including
269
   floating point data, such that the data can be scanned back from the
270
   output and reconstructed exactly.
271
*/
272
 
273
void disassemble::garmin_print_dlist (garmin_list *l)
274
{
275
garmin_list_node *n;
248 andreas 276
POINT_NODE *akt;
277
uint32 time = 0;
278
int countHR = 0;
279
int countCD = 0;
280
bool pause = false;
281
bool edTime = false;
249 andreas 282
uint32 stTime, pTime;
283
int arrDist[20];
284
uint32 arrTime[20];
285
float32 oldAlt, arrAlt[20];
248 andreas 286
int distPos;
88 andreas 287
 
314 andreas 288
	if (!l || !l->head)
289
		return;
290
 
88 andreas 291
	for (n = l->head; n != NULL; n = n->next)
292
	{
293
	   garmin_print_data(n->data);
294
	}
248 andreas 295
 
296
	// Here all data is into the struct and now we
297
	// figure out some statistics
298
	akt = point_node;
249 andreas 299
	pTime = 0;
314 andreas 300
	stTime = 0;
248 andreas 301
	distPos = 0;
302
	oldAlt = 0;
303
	descend = 99999;
304
 
249 andreas 305
	if (akt && akt->point)
306
	   time = akt->point->time;	// Save the time code of the first point
307
	else
308
	   time = 0;
309
 
248 andreas 310
	while (akt)
311
	{
312
	   // Find out the pause and detect how much seconds it is.
313
	   if (!pause && akt->point->distance >= 0x7fffffff)
314
	   {
315
	      pause = true;
316
	      stTime = akt->point->time;
317
	      akt = akt->next;
318
	      continue;
319
	   }
320
 
321
	   if (pause && akt->point->distance >= 0x7fffffff)
322
	   {
323
	      pause = false;
324
	      edTime = true;
325
	      akt = akt->next;
326
	      continue;
327
	   }
328
 
329
	   if (pause && akt->point->distance < 0x7fffffff)
330
	   {
331
	      pause = false;
332
	      edTime = true;
333
	   }
334
 
335
	   if (edTime)
336
	   {
249 andreas 337
	      pTime += (akt->point->time - stTime);
248 andreas 338
	      edTime = false;
339
	   }
340
 
341
	   // If we have a normal point, use it!
342
	   if (akt->point->distance < 0x7fffffff)
343
	   {
249 andreas 344
	      totalDistance = akt->point->distance;
248 andreas 345
	      arrDist[distPos] = akt->point->distance;
346
	      arrTime[distPos] = akt->point->time;
347
	      arrAlt[distPos] = akt->point->alt;
348
	      distPos++;
349
 
249 andreas 350
	      if (distPos > 19)
248 andreas 351
	      {
352
	      double speed, alt, sumDist = 0.0;
249 andreas 353
	      int secs = arrTime[19] - arrTime[0];
248 andreas 354
 
249 andreas 355
		 for (int i = 0; i < 19; i++)
248 andreas 356
		    sumDist += arrDist[i];
357
 
358
		 speed = sumDist / secs * 3.6;
359
 
360
		 if (speed > maxSpeed)
361
		    maxSpeed = speed;
362
 
363
		 alt = 0.0;
364
 
249 andreas 365
		 for (int i = 0; i < 19; i++)
248 andreas 366
		    alt += arrAlt[i];
367
 
249 andreas 368
		 alt /= 20.0;
248 andreas 369
 
370
		 if (oldAlt < alt)
371
		 {
372
		    ascend += (alt - oldAlt);
373
		    oldAlt = alt;
374
		 }
375
 
376
		 if (descend > alt)
377
		    descend = akt->point->alt;
378
 
379
		 distPos = 0;
380
	      }
381
 
382
	      if (akt->point->heart_rate > 0x00 && akt->point->heart_rate < 0xff)
383
	      {
384
		 avgHR += akt->point->heart_rate;
385
		 countHR++;
386
	      }
387
 
388
	      if (akt->point->cadence > 0 && akt->point->cadence != 0xff)
389
	      {
390
		 avgCadence += akt->point->cadence;
391
		 countCD++;
392
	      }
393
	   }
394
 
249 andreas 395
	   totalTime = akt->point->time;
248 andreas 396
	   akt = akt->next;
397
	}
398
 
399
	if (countHR > 0)
400
	   avgHR /= countHR;
401
 
402
	if (countCD > 0)
403
	   avgCadence /= countCD;
404
 
249 andreas 405
	if (point_node)
406
	{
407
	   totalTime -= time;		// We need the number of seconds
408
	   totalTime -= pTime;		// Subtract the seconds of pause
409
	}
410
	else
411
	   totalTime = 0;
412
 
413
	if (totalTime > 0)
414
	   avgSpeed = (totalDistance / 100.0) / totalTime * 3.6;
415
 
416
	pauseTime = pTime;
88 andreas 417
}
418
 
249 andreas 419
POINT *disassemble::getLastPoint()
420
{
421
POINT_NODE *old, *akt = point_node;
88 andreas 422
 
249 andreas 423
	if (!akt)
424
	   return 0;
425
 
426
	old = 0;
427
 
428
	while (akt)
429
	{
430
	   old = akt;
431
 
432
	   if (!akt->next && akt->point)
433
	   {
434
	      if (akt->point->distance >= 0x7fffffff && old)
435
		 return old->point;
436
 
437
	      return akt->point;
438
	   }
439
 
440
	   akt = akt->next;
441
	}
442
 
443
	return 0;	// This should never happen!
444
}
445
 
88 andreas 446
/* Support function to print a time value in ISO 8601 compliant format */
447
 
448
char *disassemble::garmin_print_dtime (uint32 t)
449
{
450
time_t     tval;
451
struct tm  tmval;
452
char       buf[128], hv0[128];
453
int        len;
454
 
455
	/* 
456
	                                012345678901234567890123
457
	   This will make, for example, 2007-04-20T23:55:01-0700, but that date
458
	   isn't quite ISO 8601 compliant.  We need to stick a ':' in the time
459
	   zone between the hours and the minutes.
460
	*/
461
 
462
	tval = t + TIME_OFFSET;
463
	localtime_r(&tval,&tmval);
464
	strftime(buf,sizeof(buf)-1,"%FT%T%z",&tmval);
465
 
466
	/* 
467
	   If the last character is a 'Z', don't do anything.  Otherwise, we 
468
	   need to move the last two characters out one and stick a colon in 
469
	   the vacated spot.  Let's not forget the trailing '\0' that needs to 
470
	   be moved as well.
471
	*/
472
 
473
	len = strlen(buf);
474
 
475
	if ( len > 0 && buf[len-1] != 'Z' )
476
	{
477
	   memmove(buf+len-1,buf+len-2,3);
478
	   buf[len-2] = ':';
479
	}
480
 
481
	/* OK.  Done. */
482
 
483
	sprintf(hv0,"%s", buf);
137 andreas 484
	return (char *)strdup(hv0);
88 andreas 485
}
486
 
487
 
488
/* Support function to print a position type */
489
 
490
void disassemble::garmin_print_dpos (position_type *pos, double *lat, double *lon)
491
{
314 andreas 492
	if (!pos || !lat || !lon)
493
		return;
494
 
88 andreas 495
	if ( pos->lat != 0x7fffffff )
496
	   *lat = SEMI2DEG(pos->lat);
497
 
498
	if ( pos->lon != 0x7fffffff )
499
	   *lon = SEMI2DEG(pos->lon);
500
}
501
 
502
 
503
/* 
504
   Print a float32 with enough precision such that it can be reconstructed
505
   exactly from its decimal representation.
506
*/
507
 
508
char *disassemble::garmin_print_float32 (float32 f, char *ret)
509
{
510
	if (!ret)
314 andreas 511
	   return 0;
88 andreas 512
 
513
	if ( f > 100000000.0 || f < -100000000.0 )
514
	    sprintf(ret, "%.9e",f);
515
	else if ( f > 10000000.0 || f < -10000000.0 )
516
	   sprintf(ret, "%.1f",f);
517
	else if ( f > 1000000.0 || f < -1000000.0 )
518
	   sprintf(ret, "%.2f",f);
519
	else if ( f > 100000.0 || f < -100000.0 )
520
	   sprintf(ret, "%.3f",f);
521
	else if ( f > 10000.0 || f < -10000.0 )
522
	   sprintf(ret, "%.4f",f);
523
	else if ( f > 1000.0 || f < -1000.0 )
524
	   sprintf(ret, "%.5f",f);
525
	else if ( f > 100.0 || f < -100.0 )
526
	   sprintf(ret, "%.6f",f);
527
	else if ( f > 10.0 || f < -10.0 )
528
	   sprintf(ret, "%.7f",f);
529
	else if ( f > 1.0 || f < -1.0 )
530
	   sprintf(ret, "%.8f",f);
531
	else if ( f > 0.1 || f < -0.1 )
532
	   sprintf(ret, "%.9f",f);
533
	else if ( f != 0 )
534
	   sprintf(ret, "%.9e",f);
535
	else
536
	   sprintf(ret, "%.8f",f);
537
 
538
	return ret;
539
}
540
 
541
 
542
/* 
543
   Print a float64 with enough precision such that it can be reconstructed
544
   exactly from its decimal representation.
545
*/
546
 
547
char *disassemble::garmin_print_float64 (float64 f, char *ret)
548
{
314 andreas 549
	if (!ret)
550
		return 0;
551
 
88 andreas 552
	if ( f > 10000000000000000.0 || f < -10000000000000000.0 )
553
	   sprintf(ret,"%.17e",f);
554
	else if ( f > 1000000000000000.0 || f < -1000000000000000.0 )
555
	   sprintf(ret,"%.1f",f);
556
	else if ( f > 100000000000000.0 || f < -100000000000000.0 )
557
	   sprintf(ret,"%.2f",f);
558
	else if ( f > 10000000000000.0 || f < -10000000000000.0 )
559
	   sprintf(ret,"%.3f",f);
560
	else if ( f > 1000000000000.0 || f < -1000000000000.0 )
561
	   sprintf(ret,"%.4f",f);
562
	else if ( f > 100000000000.0 || f < -100000000000.0 )
563
	   sprintf(ret,"%.5f",f);
564
	else if ( f > 10000000000.0 || f < -10000000000.0 )
565
	   sprintf(ret,"%.6f",f);
566
	else if ( f > 1000000000.0 || f < -1000000000.0 )
567
	   sprintf(ret,"%.7f",f);
568
	else if ( f > 100000000.0 || f < -100000000.0 )
569
	   sprintf(ret,"%.8f",f);
570
	else if ( f > 10000000.0 || f < -10000000.0 )
571
	   sprintf(ret,"%.9f",f);
572
	else if ( f > 1000000.0 || f < -1000000.0 )
573
	   sprintf(ret,"%.10f",f);
574
	else if ( f > 100000.0 || f < -100000.0 )
575
	   sprintf(ret,"%.11f",f);
576
	else if ( f > 10000.0 || f < -10000.0 )
577
	   sprintf(ret,"%.12f",f);
578
	else if ( f > 1000.0 || f < -1000.0 )
579
	   sprintf(ret,"%.13f",f);
580
	else if ( f > 100.0 || f < -100.0 )
581
	   sprintf(ret,"%.14f",f);
582
	else if ( f > 10.0 || f < -10.0 )
583
	   sprintf(ret,"%.15f",f);
584
	else if ( f > 1.0 || f < -1.0 )
585
	   sprintf(ret,"%.16f",f);
586
	else if ( f > 0.1 || f < -0.1 )
587
	   sprintf(ret,"%.17f",f);
588
	else if ( f != 0 )
589
	   sprintf(ret,"%.17e",f);
590
	else
591
	   sprintf(ret,"%.16f",f);
592
 
593
	return ret;
594
}
595
 
596
 
597
/* 
598
   Print a float32 whose value is invalid (and should not be printed) if 
599
   greater than 1.0e24 
600
*/
601
 
602
char *disassemble::garmin_print_dfloat32 (float32 f, char *ret)
603
{
604
	if (!ret)
605
	   return NULL;
606
 
607
	if ( f < 1.0e24 )
608
	   garmin_print_float32(f, ret);
609
 
610
	return ret;
611
}
612
 
613
 
614
/* Print a duration and distance. */
615
 
616
char *disassemble::garmin_print_ddist (uint32 dur, char *ret)
617
{
618
int  hun;
619
int  sec;
620
int  min;
621
int  hrs;
622
 
623
	if (!ret)
624
	   return NULL;
625
 
626
	hun  = dur % 100;
627
	dur -= hun;
628
	dur /= 100;
629
	sec  = dur % 60;
630
	dur -= sec;
631
	dur /= 60;
632
	min  = dur % 60;
633
	dur -= min;
634
	dur /= 60;
635
	hrs  = dur;
636
 
637
	sprintf(ret,"%d:%02d:%02d.%02d", hrs, min, sec, hun);
638
	return ret;
639
}
640
 
641
 
642
/* --------------------------------------------------------------------------*/
643
/* 7.4.1  D100                                                               */
644
/* --------------------------------------------------------------------------*/
645
 
646
void disassemble::garmin_print_d100 (D100 *x)
647
{
648
	memset (&waypoint, 0, sizeof(WAYPOINT));
649
	waypoint.type = 100;
650
	strncpy (waypoint.ident, x->ident, 5);
651
	waypoint.posn = x->posn;
652
	strncpy(waypoint.cmnt, x->cmnt, 40);
653
}
654
 
655
 
656
/* --------------------------------------------------------------------------*/
657
/* 7.4.2  D101                                                               */
658
/* --------------------------------------------------------------------------*/
659
 
660
void disassemble::garmin_print_d101 (D101 *x)
661
{
662
	memset (&waypoint, 0, sizeof(WAYPOINT));
663
	waypoint.type = 101;
664
	strncpy (waypoint.ident, x->ident, sizeof(waypoint.ident)-1);
665
	waypoint.posn = x->posn;
666
	strncpy (waypoint.cmnt, x->cmnt, sizeof(waypoint.cmnt)-1);
667
	waypoint.dst = x->dst;
668
	waypoint.smbl = x->smbl;
669
}
670
 
671
 
672
/* --------------------------------------------------------------------------*/
673
/* 7.4.3  D102                                                               */
674
/* --------------------------------------------------------------------------*/
675
 
676
void disassemble::garmin_print_d102 (D102 *x)
677
{
678
	garmin_print_d101 ((D101 *)x);
679
	waypoint.type = 102;
680
}
681
 
682
 
683
/* --------------------------------------------------------------------------*/
684
/* 7.4.4  D103                                                               */
685
/* --------------------------------------------------------------------------*/
686
 
687
 
688
void disassemble::garmin_print_d103 (D103 *x)
689
{
690
	garmin_print_d101((D101 *)x);
691
	waypoint.type = 103;
692
//	GARMIN_TAGSTR(1,"symbol",garmin_d103_smbl(x->smbl));
693
//	GARMIN_TAGSTR(1,"display",garmin_d103_dspl(x->dspl));
694
}
695
 
696
 
697
/* --------------------------------------------------------------------------*/
698
/* 7.4.5  D104                                                               */
699
/* --------------------------------------------------------------------------*/
700
 
701
void disassemble::garmin_print_d104 (D104 *x)
702
{
703
	garmin_print_d101((D101 *)x);
704
	waypoint.dspl = x->dspl;
705
	waypoint.type = 104;
706
//	GARMIN_TAGF32(1,"proximity_distance",x->dst);
707
//	GARMIN_TAGSTR(1,"display",garmin_d104_dspl(x->dspl));
708
}
709
 
710
 
711
/* --------------------------------------------------------------------------*/
712
/* 7.4.6  D105                                                               */
713
/* --------------------------------------------------------------------------*/
714
 
715
void disassemble::garmin_print_d105 (D105 *x)
716
{
717
	memset (&waypoint, 0, sizeof(WAYPOINT));
718
	waypoint.type = 105;
719
	waypoint.wpt_ident = x->wpt_ident;
720
	waypoint.posn = x->posn;
721
	waypoint.smbl = x->smbl;
722
}
723
 
724
 
725
/* --------------------------------------------------------------------------*/
726
/* 7.4.7  D106                                                               */
727
/* --------------------------------------------------------------------------*/
728
 
729
void disassemble::garmin_print_d106 (D106 *x)
730
{
731
	memset (&waypoint, 0, sizeof(WAYPOINT));
732
	waypoint.type = 106;
733
	waypoint.wpt_class = x->wpt_class;
734
	waypoint.subclass[0] = 0;
735
 
736
	if ( x->wpt_class != 0 )
737
	{
738
	   strncpy ((char *)waypoint.subclass, (char *)x->subclass, 13);
739
	   waypoint.subclass[13] = 0;
740
	}
741
 
742
	waypoint.wpt_ident = x->wpt_ident;
743
	waypoint.posn = x->posn;
744
	waypoint.smbl = x->smbl;
745
	waypoint.lnk_ident = x->lnk_ident;
746
}
747
 
748
 
749
/* --------------------------------------------------------------------------*/
750
/* 7.4.8  D107                                                               */
751
/* --------------------------------------------------------------------------*/
752
 
753
void disassemble::garmin_print_d107 (D107 *x)
754
{
755
	memset (&waypoint, 0, sizeof(WAYPOINT));
756
	waypoint.type = 107;
757
	strncpy(waypoint.ident, x->ident, sizeof(waypoint.ident)-1);
758
	waypoint.posn = x->posn;
759
	strncpy(waypoint.cmnt, x->cmnt, sizeof(waypoint.cmnt)-1);
760
	waypoint.dst = x->dst;
761
	waypoint.smbl = x->smbl;
762
	waypoint.dspl = x->dspl;
763
	waypoint.color = x->color;
764
}
765
 
766
 
767
/* --------------------------------------------------------------------------*/
768
/* 7.4.9  D108                                                               */
769
/* --------------------------------------------------------------------------*/
770
 
771
void disassemble::garmin_print_d108 (D108 *x)
772
{
773
	memset(&waypoint, 0, sizeof(WAYPOINT));
774
	waypoint.type = 108;
775
	waypoint.identity = x->ident;
776
	waypoint.posn = x->posn;
777
	waypoint.comment = x->comment;
778
	waypoint.smbl = x->smbl;
779
	waypoint.dspl = x->dspl;
780
	waypoint.wpt_class = x->wpt_class;
781
	strncpy((char *)waypoint.subclass, (char *)x->subclass, 18);
782
	waypoint.attr = x->attr;
783
	waypoint.color = x->color;
784
	waypoint.alt = x->alt;
785
	waypoint.dpth = x->dpth;
786
	waypoint.dst = x->dist;
787
	waypoint.facility = x->facility;
788
	waypoint.city = x->city;
789
	waypoint.addr = x->addr;
790
	waypoint.cross_road = x->cross_road;
791
}
792
 
793
 
794
/* --------------------------------------------------------------------------*/
795
/* 7.4.10  D109                                                              */
796
/* --------------------------------------------------------------------------*/
797
 
798
void disassemble::garmin_print_d109 (D109 *x)
799
{
800
uint8 color = x->dspl_color & 0x1f;
801
 
802
	if (color == 0x1f)
803
	   color = D108_default_color;
804
 
805
	memset(&waypoint, 0, sizeof(WAYPOINT));
806
	waypoint.type = 109;
807
	waypoint.identity = x->ident;
808
	waypoint.posn = x->posn;
809
	waypoint.comment = x->comment;
810
	waypoint.smbl = x->smbl;
811
	waypoint.wpt_class = x->wpt_class;
812
	strncpy((char *)waypoint.subclass, (char *)x->subclass, 18);
813
	waypoint.attr = x->attr;
814
	waypoint.color = color;
815
	waypoint.alt = x->alt;
816
	waypoint.dtyp = x->dtyp;
817
	waypoint.ete = x->ete;
818
	waypoint.dpth = x->dpth;
819
	waypoint.dst = x->dist;
820
	waypoint.facility = x->facility;
821
	waypoint.city = x->city;
822
	waypoint.addr = x->addr;
823
	waypoint.cross_road = x->cross_road;
824
}
825
 
826
 
827
/* --------------------------------------------------------------------------*/
828
/* 7.4.11  D110                                                              */
829
/* --------------------------------------------------------------------------*/
830
 
831
void disassemble::garmin_print_d110 (D110 *x)
832
{
833
	memset(&waypoint, 0, sizeof(WAYPOINT));
834
	waypoint.type = 110;
835
	waypoint.identity = x->ident;
836
	waypoint.posn = x->posn;
837
	waypoint.comment = x->comment;
838
	waypoint.smbl = x->smbl;
839
	waypoint.wpt_class = x->wpt_class;
840
	strncpy((char *)waypoint.subclass, (char *)x->subclass, 18);
841
	waypoint.attr = x->attr;
842
	waypoint.alt = x->alt;
843
	waypoint.dtyp = x->dtyp;
844
	waypoint.ete = x->ete;
845
	waypoint.dpth = x->dpth;
846
	waypoint.dst = x->dist;
847
	waypoint.facility = x->facility;
848
	waypoint.city = x->city;
849
	waypoint.addr = x->addr;
850
	waypoint.cross_road = x->cross_road;
851
 
852
/*  GARMIN_TAGSTR(1,"wpt_class",garmin_d110_wpt_class(x->wpt_class));
853
  GARMIN_TAGSTR(1,"color",garmin_d110_color((x->dspl_color) & 0x1f));
854
  GARMIN_TAGSTR(1,"display",garmin_d110_dspl((x->dspl_color >> 5) & 0x03));
855
  GARMIN_TAGSYM(1,"symbol",x->smbl);
856
  if ( x->temp < 1.0e24 ) GARMIN_TAGF32(1,"temperature",x->temp);
857
  GARMIN_TAGSTR(1,"state",x->state);
858
  GARMIN_TAGSTR(1,"country_code",x->cc);
859
  if ( x->time != 0xffffffff ) GARMIN_TAGU32(1,"time",x->time);
860
  GARMIN_TAGHEX(1,"category",x->wpt_cat); */
861
}
862
 
863
 
864
/* --------------------------------------------------------------------------*/
865
/* 7.4.12  D120                                                              */
866
/* --------------------------------------------------------------------------*/
867
 
868
void disassemble::garmin_print_d120 (D120 *x)
869
{
870
	memset(&wpcategory, 0, sizeof(WPCATEGORY));
871
	strncpy(wpcategory.name, x->name, 17);
872
}
873
 
874
 
875
/* --------------------------------------------------------------------------*/
876
/* 7.4.13  D150                                                              */
877
/* --------------------------------------------------------------------------*/
878
 
879
void disassemble::garmin_print_d150 (D150 *x)
880
{
881
	memset(&waypoint, 0, sizeof(WAYPOINT));
882
	waypoint.type = 150;
883
	strncpy(waypoint.ident, x->ident, sizeof(waypoint.ident)-1);
884
	waypoint.wpt_class = x->wpt_class;
885
	waypoint.posn = x->posn;
886
	strncpy(waypoint.cmnt, x->cmnt, sizeof(waypoint.cmnt)-1);
887
 
888
	if (x->wpt_class != D150_usr_wpt_class)
889
	{
890
	   waypoint.city = x->city;
891
	   strncpy(waypoint.state, x->state, 2);
892
	   waypoint.facility = x->name;
893
	   strncpy(waypoint.cc, x->cc, 2);
894
	}
895
 
896
	if (x->wpt_class == D150_apt_wpt_class)
897
	   waypoint.alt = x->alt;
898
}
899
 
900
 
901
/* --------------------------------------------------------------------------*/
902
/* 7.4.14  D151                                                              */
903
/* --------------------------------------------------------------------------*/
904
 
905
void disassemble::garmin_print_d151 (D151 *x)
906
{
907
	memset(&waypoint, 0, sizeof(WAYPOINT));
908
	waypoint.type = 151;
909
	strncpy(waypoint.ident, x->ident, sizeof(waypoint.ident)-1);
910
	waypoint.wpt_class = x->wpt_class;
911
	waypoint.posn = x->posn;
912
	strncpy(waypoint.cmnt, x->cmnt, sizeof(waypoint.cmnt)-1);
913
	waypoint.dst = x->dst;
914
 
915
	if (x->wpt_class != D150_usr_wpt_class)
916
	{
917
	   waypoint.city = x->city;
918
	   strncpy(waypoint.state, x->state, 2);
919
	   waypoint.facility = x->name;
920
	   strncpy(waypoint.cc, x->cc, 2);
921
	}
922
 
923
	if (x->wpt_class == D150_apt_wpt_class)
924
	   waypoint.alt = x->alt;
925
}
926
 
927
 
928
/* --------------------------------------------------------------------------*/
929
/* 7.4.15  D152                                                              */
930
/* --------------------------------------------------------------------------*/
931
 
932
void disassemble::garmin_print_d152 (D152 *x)
933
{
934
	memset(&waypoint, 0, sizeof(WAYPOINT));
935
	waypoint.type = 152;
936
	strncpy(waypoint.ident, x->ident, sizeof(waypoint.ident)-1);
937
	waypoint.wpt_class = x->wpt_class;
938
	waypoint.posn = x->posn;
939
	strncpy(waypoint.cmnt, x->cmnt, sizeof(waypoint.cmnt)-1);
940
	waypoint.dst = x->dst;
941
 
942
	if (x->wpt_class != D152_usr_wpt_class)
943
	{
944
	   waypoint.city = x->city;
945
	   strncpy(waypoint.state, x->state, 2);
946
	   waypoint.facility = x->name;
947
	   strncpy(waypoint.cc, x->cc, 2);
948
	}
949
 
950
	if (x->wpt_class == D152_apt_wpt_class)
951
	   waypoint.alt = x->alt;
952
}
953
 
954
 
955
/* --------------------------------------------------------------------------*/
956
/* 7.4.16  D154                                                              */
957
/* --------------------------------------------------------------------------*/
958
 
959
void disassemble::garmin_print_d154 (D154 *x)
960
{
961
	memset(&waypoint, 0, sizeof(WAYPOINT));
962
	waypoint.type = 154;
963
	strncpy(waypoint.ident, x->ident, sizeof(waypoint.ident)-1);
964
	waypoint.wpt_class = x->wpt_class;
965
	waypoint.posn = x->posn;
966
	strncpy(waypoint.cmnt, x->cmnt, sizeof(waypoint.cmnt)-1);
967
	waypoint.dst = x->dst;
968
 
969
	if (x->wpt_class != D154_usr_wpt_class)
970
	{
971
	   waypoint.city = x->city;
972
	   strncpy(waypoint.state, x->state, 2);
973
	   waypoint.facility = x->name;
974
	   strncpy(waypoint.cc, x->cc, 2);
975
	}
976
 
977
	if (x->wpt_class == D154_apt_wpt_class)
978
	   waypoint.alt = x->alt;
979
 
980
	waypoint.smbl = x->smbl;
981
}
982
 
983
 
984
/* --------------------------------------------------------------------------*/
985
/* 7.4.17  D155                                                              */
986
/* --------------------------------------------------------------------------*/
987
 
988
void disassemble::garmin_print_d155 (D155 *x)
989
{
990
	memset(&waypoint, 0, sizeof(WAYPOINT));
991
	waypoint.type = 155;
992
	strncpy(waypoint.ident, x->ident, sizeof(waypoint.ident)-1);
993
	waypoint.wpt_class = x->wpt_class;
994
	waypoint.posn = x->posn;
995
	strncpy(waypoint.cmnt, x->cmnt, sizeof(waypoint.cmnt)-1);
996
	waypoint.dst = x->dst;
997
 
998
	if (x->wpt_class != D155_usr_wpt_class)
999
	{
1000
	   waypoint.city = x->city;
1001
	   strncpy(waypoint.state, x->state, 2);
1002
	   waypoint.facility = x->name;
1003
	   strncpy(waypoint.cc, x->cc, 2);
1004
	}
1005
 
1006
	if (x->wpt_class == D155_apt_wpt_class)
1007
	   waypoint.alt = x->alt;
1008
 
1009
	waypoint.smbl = x->smbl;
1010
	waypoint.dspl = x->dspl;
1011
}
1012
 
1013
 
1014
/* --------------------------------------------------------------------------*/
1015
/* 7.4.18  D200                                                              */
1016
/* --------------------------------------------------------------------------*/
1017
 
1018
void disassemble::garmin_print_d200 (D200 *x)
1019
{
1020
	route_header = *x;
1021
}
1022
 
1023
 
1024
/* --------------------------------------------------------------------------*/
1025
/* 7.4.19  D201                                                              */
1026
/* --------------------------------------------------------------------------*/
1027
 
1028
void disassemble::garmin_print_d201 (D201 *x)
1029
{
1030
	memset(&route, 0, sizeof(ROUTE));
1031
	route.type = 201;
1032
	route.nmbr = x->nmbr;
1033
	strncpy(route.cmnt, x->cmnt, 20);
1034
}
1035
 
1036
 
1037
/* --------------------------------------------------------------------------*/
1038
/* 7.4.20  D202                                                              */
1039
/* --------------------------------------------------------------------------*/
1040
 
1041
void disassemble::garmin_print_d202 (D202 *x)
1042
{
1043
	memset(&route, 0, sizeof(ROUTE));
1044
	route.type = 202;
1045
	route.rte_ident = x->rte_ident;
1046
}
1047
 
1048
 
1049
/* --------------------------------------------------------------------------*/
1050
/* 7.4.21  D210                                                              */
1051
/* --------------------------------------------------------------------------*/
1052
 
1053
void disassemble::garmin_print_d210 (D210 *x)
1054
{
1055
	memset(&route_link, 0, sizeof(ROUTE_LINK));
1056
	route_link.type = 210;
1057
	route_link.klasse = x->klasse;
1058
	route_link.ident = x->ident;
1059
	strncpy((char *)route_link.subclass, (char *)x->subclass, 18);
1060
}
1061
 
1062
 
1063
/* --------------------------------------------------------------------------*/
1064
/* 7.4.22  D300                                                              */
1065
/* --------------------------------------------------------------------------*/
1066
 
1067
void disassemble::garmin_print_d300 (D300 *p)
1068
{
1069
	memset(&point, 0, sizeof(POINT));
1070
	point.type = 300;
1071
	point.time = p->time;
1072
	point.posn = p->posn;
1073
	point.new_trk = p->new_trk;
1074
	addPoint();
1075
}
1076
 
1077
 
1078
/* --------------------------------------------------------------------------*/
1079
/* 7.4.23  D301                                                              */
1080
/* --------------------------------------------------------------------------*/
1081
 
1082
void disassemble::garmin_print_d301 (D301 *p)
1083
{
1084
	memset(&point, 0, sizeof(POINT));
1085
	point.type = 301;
1086
	point.time = p->time;
1087
	point.posn = p->posn;
1088
	point.new_trk = p->new_trk;
1089
	point.alt = p->alt;
1090
	point.dpth = p->dpth;
1091
	addPoint();
1092
}
1093
 
1094
 
1095
/* --------------------------------------------------------------------------*/
1096
/* 7.4.24  D302                                                              */
1097
/* --------------------------------------------------------------------------*/
1098
 
1099
void disassemble::garmin_print_d302 (D302 *p)
1100
{
1101
	memset(&point, 0, sizeof(POINT));
1102
	point.type = 302;
1103
	point.time = p->time;
1104
	point.posn = p->posn;
1105
	point.new_trk = p->new_trk;
1106
	point.alt = p->alt;
1107
	point.dpth = p->dpth;
1108
	point.temp = p->temp;
1109
	addPoint();
1110
}
1111
 
1112
 
1113
/* --------------------------------------------------------------------------*/
1114
/* 7.4.25  D303                                                              */
1115
/* --------------------------------------------------------------------------*/
1116
 
1117
void disassemble::garmin_print_d303 (D303 *p)
1118
{
1119
	memset(&point, 0, sizeof(POINT));
1120
	point.type = 303;
1121
	point.time = p->time;
1122
	point.posn = p->posn;
1123
	point.alt = p->alt;
1124
	point.heart_rate = p->heart_rate;
1125
	addPoint();
1126
}
1127
 
1128
 
1129
/* --------------------------------------------------------------------------*/
1130
/* 7.4.26  D304                                                              */
1131
/* --------------------------------------------------------------------------*/
1132
 
1133
void disassemble::garmin_print_d304 (D304 *p)
1134
{
1135
	memset(&point, 0, sizeof(POINT));
1136
	point.type = 304;
1137
	point.time = p->time;
1138
	point.posn = p->posn;
1139
	point.alt = p->alt;
1140
	point.heart_rate = p->heart_rate;
1141
	point.distance = p->distance;
1142
	point.cadence = p->cadence;
1143
	point.sensor = p->sensor;
1144
	addPoint();
1145
}
1146
 
1147
 
1148
/* --------------------------------------------------------------------------*/
1149
/* 7.4.27  D310                                                              */
1150
/* --------------------------------------------------------------------------*/
1151
 
1152
void disassemble::garmin_print_d310 (D310 *x)
1153
{
1154
	memset(&track, 0, sizeof(TRACK));
1155
	track.type = 310;
1156
	track.trk_ident = x->trk_ident;
1157
	track.color = x->color;
1158
	track.dspl = x->dspl;
1159
}
1160
 
1161
 
1162
/* --------------------------------------------------------------------------*/
1163
/* 7.4.28  D311                                                              */
1164
/* --------------------------------------------------------------------------*/
1165
 
1166
void disassemble::garmin_print_d311 (D311 *h)
1167
{
1168
	memset(&track, 0, sizeof(TRACK));
1169
	track.type = 311;
1170
	track.index = h->index;
1171
}
1172
 
1173
 
1174
/* --------------------------------------------------------------------------*/
1175
/* 7.4.29  D312                                                              */
1176
/* --------------------------------------------------------------------------*/
1177
 
1178
void disassemble::garmin_print_d312 (D312 *h)
1179
{
1180
	memset(&track, 0, sizeof(TRACK));
1181
	track.type = 312;
1182
	track.trk_ident = h->trk_ident;
1183
	track.color = h->color;
1184
	track.dspl = h->dspl;
1185
}
1186
 
1187
 
1188
/* --------------------------------------------------------------------------*/
1189
/* 7.4.30  D400                                                              */
1190
/* --------------------------------------------------------------------------*/
1191
 
1192
void disassemble::garmin_print_d400 (D400 *x)
1193
{
1194
	garmin_print_d400((D400 *)&x->wpt);
1195
	waypoint.type = 400;
1196
	waypoint.dst = x->dst;
1197
}
1198
 
1199
 
1200
/* --------------------------------------------------------------------------*/
1201
/* 7.4.31  D403                                                              */
1202
/* --------------------------------------------------------------------------*/
1203
 
1204
void disassemble::garmin_print_d403 (D403 *x)
1205
{
1206
	garmin_print_d103(&x->wpt);
1207
	waypoint.type = 403;
1208
	waypoint.dst = x->dst;
1209
}
1210
 
1211
 
1212
/* --------------------------------------------------------------------------*/
1213
/* 7.4.32  D450                                                              */
1214
/* --------------------------------------------------------------------------*/
1215
 
1216
void disassemble::garmin_print_d450 (D450 *x)
1217
{
1218
	garmin_print_d150(&x->wpt);
1219
	waypoint.type = 450;
1220
	waypoint.dst = x->dst;
1221
	waypoint.idx = x->idx;
1222
}
1223
 
1224
 
1225
/* --------------------------------------------------------------------------*/
1226
/* 7.4.33  D500                                                              */
1227
/* --------------------------------------------------------------------------*/
1228
 
1229
void disassemble::garmin_print_d500 (D500 *x)
1230
{
1231
	memset(&almanac, 0, sizeof(ALMANAC));
1232
	almanac.type = 500;
1233
	almanac.wn = x->wn;
1234
	almanac.toa = x->toa;
1235
	almanac.af0 = x->af0;
1236
	almanac.af1 = x->af1;
1237
	almanac.e = x->e;
1238
	almanac.sqrta = x->sqrta;
1239
	almanac.m0 = x->m0;
1240
	almanac.w = x->w;
1241
	almanac.omg0 = x->omg0;
1242
	almanac.odot = x->odot;
1243
	almanac.i = x->i;
1244
}
1245
 
1246
 
1247
/* --------------------------------------------------------------------------*/
1248
/* 7.4.34  D501                                                              */
1249
/* --------------------------------------------------------------------------*/
1250
 
1251
void disassemble::garmin_print_d501 (D501 *x)
1252
{
1253
	memset(&almanac, 0, sizeof(ALMANAC));
1254
	almanac.type = 501;
1255
	almanac.wn = x->wn;
1256
	almanac.toa = x->toa;
1257
	almanac.af0 = x->af0;
1258
	almanac.af1 = x->af1;
1259
	almanac.e = x->e;
1260
	almanac.sqrta = x->sqrta;
1261
	almanac.m0 = x->m0;
1262
	almanac.w = x->w;
1263
	almanac.omg0 = x->omg0;
1264
	almanac.odot = x->odot;
1265
	almanac.i = x->i;
1266
	almanac.hlth = x->hlth;
1267
}
1268
 
1269
 
1270
/* --------------------------------------------------------------------------*/
1271
/* 7.4.35  D550                                                              */
1272
/* --------------------------------------------------------------------------*/
1273
 
1274
void disassemble::garmin_print_d550 (D550 *x)
1275
{
1276
	memset(&almanac, 0, sizeof(ALMANAC));
1277
	almanac.type = 550;
1278
	almanac.wn = x->wn;
1279
	almanac.toa = x->toa;
1280
	almanac.af0 = x->af0;
1281
	almanac.af1 = x->af1;
1282
	almanac.e = x->e;
1283
	almanac.sqrta = x->sqrta;
1284
	almanac.m0 = x->m0;
1285
	almanac.w = x->w;
1286
	almanac.omg0 = x->omg0;
1287
	almanac.odot = x->odot;
1288
	almanac.i = x->i;
1289
	almanac.svid = x->svid;
1290
}
1291
 
1292
 
1293
/* --------------------------------------------------------------------------*/
1294
/* 7.4.36  D551                                                              */
1295
/* --------------------------------------------------------------------------*/
1296
 
1297
void disassemble::garmin_print_d551 (D551 *x)
1298
{
1299
	memset(&almanac, 0, sizeof(ALMANAC));
1300
	almanac.type = 551;
1301
	almanac.wn = x->wn;
1302
	almanac.toa = x->toa;
1303
	almanac.af0 = x->af0;
1304
	almanac.af1 = x->af1;
1305
	almanac.e = x->e;
1306
	almanac.sqrta = x->sqrta;
1307
	almanac.m0 = x->m0;
1308
	almanac.w = x->w;
1309
	almanac.omg0 = x->omg0;
1310
	almanac.odot = x->odot;
1311
	almanac.i = x->i;
1312
	almanac.svid = x->svid;
1313
	almanac.hlth = x->hlth;
1314
}
1315
 
1316
 
1317
/* --------------------------------------------------------------------------*/
1318
/* 7.4.37  D600                                                              */
1319
/* --------------------------------------------------------------------------*/
1320
 
1321
void disassemble::garmin_print_d600 (D600 *x)
1322
{
1323
	datetime.year = x->year;
1324
	datetime.month = x->month;
1325
	datetime.day = x->day;
1326
	datetime.hour = x->hour;
1327
	datetime.minute = x->minute;
1328
	datetime.second = x->second;
1329
}
1330
 
1331
 
1332
/* --------------------------------------------------------------------------*/
1333
/* 7.4.38  D650                                                              */
1334
/* --------------------------------------------------------------------------*/
1335
 
1336
void disassemble::garmin_print_d650 (D650 *x)
1337
{
1338
	memset(&flightbook, 0, sizeof(FLIGHTBOOK));
1339
	flightbook.type = 650;
1340
	flightbook.takeoff_time = x->takeoff_time;
1341
	flightbook.landing_time = x->landing_time;
1342
	flightbook.takeoff_posn = x->takeoff_posn;
1343
	flightbook.landing_posn = x->landing_posn;
1344
	flightbook.night_time = x->night_time;
1345
	flightbook.num_landings = x->num_landings;
1346
	flightbook.max_speed = x->max_speed;
1347
	flightbook.max_alt = x->max_alt;
1348
	flightbook.distance = x->distance;
1349
	flightbook.cross_country_flag = x->cross_country_flag;
1350
	flightbook.departure_name = x->departure_name;
1351
	flightbook.departure_ident = x->departure_ident;
1352
	flightbook.arrival_name = x->arrival_name;
1353
	flightbook.arrival_ident = x->arrival_ident;
1354
	flightbook.ac_id = x->ac_id;
1355
}
1356
 
1357
 
1358
/* ------------------------------------------------------------------------- */
1359
/* 7.4.39  D700                                                              */
1360
/* ------------------------------------------------------------------------- */
1361
 
1362
void disassemble::garmin_print_d700 (D700 *x)
1363
{
1364
	rpt.lat = x->lat;
1365
	rpt.lon = x->lon;
1366
}
1367
 
1368
 
1369
/* --------------------------------------------------------------------------*/
1370
/* 7.4.40  D800                                                              */
1371
/* --------------------------------------------------------------------------*/
1372
 
1373
void disassemble::garmin_print_d800 (D800 *x)
1374
{
1375
	memset(&pvt, 0, sizeof(PVT));
1376
	pvt.alt = x->alt;
1377
	pvt.epe = x->epe;
1378
	pvt.eph = x->eph;
1379
	pvt.epv = x->epv;
1380
	pvt.fix = x->fix;
1381
	pvt.posn.lat = x->posn.lat;
1382
	pvt.posn.lon = x->posn.lon;
1383
	pvt.east = x->east;
1384
	pvt.north = x->north;
1385
	pvt.up = x->up;
1386
	pvt.msl_hght = x->msl_hght;
1387
	pvt.leap_scnds = x->leap_scnds;
1388
	pvt.wn_days = x->wn_days;
1389
	pvt.tow = x->tow;
1390
}
1391
 
1392
 
1393
/* --------------------------------------------------------------------------*/
1394
/* 7.4.41  D906                                                              */
1395
/* --------------------------------------------------------------------------*/
1396
 
1397
void disassemble::garmin_print_d906 (D906 *x)
1398
{
1399
	memset (&lap, 0, sizeof(LAP));
1400
	lap.type = 906;
1401
	lap.start_time = x->start_time;
1402
	lap.total_time = x->total_time;
1403
	lap.total_distance = x->total_distance;
1404
	lap.begin.lat = x->begin.lat;
1405
	lap.begin.lon = x->begin.lon;
1406
	lap.end.lat = x->end.lat;
1407
	lap.end.lon = x->end.lon;
1408
	lap.calories = x->calories;
1409
	lap.track_index = x->track_index;
1410
	addLap();
1411
}
1412
 
1413
 
1414
/* --------------------------------------------------------------------------*/
1415
/* 7.4.42  D1000                                                             */
1416
/* --------------------------------------------------------------------------*/
1417
 
1418
 
1419
void disassemble::garmin_print_d1000 (D1000 *x)
1420
{
1421
	memset(&run, 0, sizeof(RUN));
1422
	garmin_print_d1002((D1002 *)&x->workout);
1423
	run.type = 1000;
1424
	run.track_index = x->track_index;
1425
	run.sport_type = x->sport_type;
1426
	run.first_lap_index = x->first_lap_index;
1427
	run.last_lap_index = x->last_lap_index;
1428
	run.program_type = x->program_type;
1429
	run.virtual_partner.time = x->virtual_partner.time;
1430
	run.virtual_partner.distance = x->virtual_partner.distance;
1431
	addRun();
1432
}
1433
 
1434
 
1435
/* --------------------------------------------------------------------------*/
1436
/* 7.4.43  D1001                                                             */
1437
/* --------------------------------------------------------------------------*/
1438
 
1439
 
1440
void disassemble::garmin_print_d1001 (D1001 *x)
1441
{
1442
	memset(&lap, 0, sizeof(LAP));
1443
	lap.type = 1001;
1444
	lap.start_time = x->start_time;
1445
	lap.total_time = x->total_time;
1446
	lap.total_distance = x->total_dist;
1447
	lap.begin.lat = x->begin.lat;
1448
	lap.begin.lon = x->begin.lon;
1449
	lap.end.lat = x->end.lat;
1450
	lap.end.lon = x->end.lon;
1451
	lap.calories = x->calories;
1452
	lap.index = x->index;
1453
	lap.max_speed = x->max_speed;
1454
	lap.avg_heart_rate = x->avg_heart_rate;
1455
	lap.max_heart_rate = x->max_heart_rate;
1456
	lap.intensity = x->intensity;
1457
	addLap();
1458
}
1459
 
1460
 
1461
/* --------------------------------------------------------------------------*/
1462
/* 7.4.44  D1002                                                             */
1463
/* --------------------------------------------------------------------------*/
1464
 
1465
 
1466
void disassemble::garmin_print_d1002 (D1002 *x)
1467
{
213 andreas 1468
unsigned int i;
88 andreas 1469
 
1470
	memset (&workout, 0, sizeof(WORKOUT));
1471
	workout.type = 1002;
1472
	strncpy (workout.name, x->name, 16);
1473
	workout.num_valid_steps = x->num_valid_steps;
1474
 
1475
	if (x->num_valid_steps > 0)
1476
	{
1477
	   for (i = 0; i < x->num_valid_steps; i++)
1478
	   {
1479
	      if (i >= 20)
1480
		 break;
1481
 
1482
	      strncpy (workout.steps[i].custom_name, x->steps[i].custom_name, 16);
1483
	      workout.steps[i].intensity = x->steps[i].intensity;
1484
	      workout.steps[i].duration_type = x->steps[i].duration_type;
1485
	      workout.steps[i].duration_value = x->steps[i].duration_value;
1486
	      workout.steps[i].target_type = x->steps[i].target_type;
1487
	      workout.steps[i].target_value = x->steps[i].target_value;
1488
	      workout.steps[i].target_custom_zone_low = x->steps[i].target_custom_zone_low;
1489
	      workout.steps[i].target_custom_zone_high = x->steps[i].target_custom_zone_high;
1490
	   }
1491
	}
1492
}
1493
 
1494
 
1495
/* --------------------------------------------------------------------------*/
1496
/* 7.4.45  D1003                                                             */
1497
/* --------------------------------------------------------------------------*/
1498
 
1499
void disassemble::garmin_print_d1003 (D1003 *x)
1500
{
1501
	memset (&workout, 0, sizeof(WORKOUT));
1502
	workout.type = 1003;
1503
	strncpy (workout.workout_name, x->workout_name, 16);
1504
	workout.day = x->day;
1505
}
1506
 
1507
 
1508
/* --------------------------------------------------------------------------*/
1509
/* 7.4.46  D1004                                                             */
1510
/* --------------------------------------------------------------------------*/
1511
 
1512
void disassemble::garmin_print_d1004 (D1004 *d)
1513
{
1514
int i;
1515
int j;
1516
 
1517
	memset (&fitness, 0, sizeof(FITNESS));
1518
	fitness.type = 1004;
1519
	fitness.weight = d->weight;
1520
	fitness.birth_year = d->birth_year;
1521
	fitness.birth_month = d->birth_month;
1522
	fitness.birth_day = d->birth_day;
1523
	fitness.gender = d->gender;
1524
 
1525
	for (i = 0; i < 3; i++)
1526
	{
1527
	   fitness.activities[i].gear_weight = d->activities[i].gear_weight;
1528
	   fitness.activities[i].max_heart_rate = d->activities[i].max_heart_rate;
1529
 
1530
	   for (j = 0; j < 5; j++)
1531
	   {
1532
	      fitness.activities[i].heart_rate_zones[j].low_heart_rate = d->activities[i].heart_rate_zones[j].low_heart_rate;
1533
	      fitness.activities[i].heart_rate_zones[j].high_heart_rate = d->activities[i].heart_rate_zones[j].high_heart_rate;
1534
	   }
1535
 
1536
	   for (j = 0; j < 10; j++)
1537
	   {
1538
	      fitness.activities[i].speed_zones[j].low_speed = d->activities[i].speed_zones[j].low_speed;
1539
	      fitness.activities[i].speed_zones[j].high_speed = d->activities[i].speed_zones[j].high_speed;
1540
	      strncpy (fitness.activities[i].speed_zones[j].name, d->activities[i].speed_zones[j].name, 16);
1541
	   }
1542
	}
1543
}
1544
 
1545
 
1546
/* --------------------------------------------------------------------------*/
1547
/* 7.4.47  D1005                                                             */
1548
/* --------------------------------------------------------------------------*/
1549
 
1550
void disassemble::garmin_print_d1005 (D1005 *limits)
1551
{
1552
	memset (&workout, 0, sizeof(WORKOUT));
1553
	workout.type = 1005;
1554
	workout.max_workouts = limits->max_workouts;
1555
	workout.max_unscheduled_workouts = limits->max_unscheduled_workouts;
1556
	workout.max_occurrences = limits->max_occurrences;
1557
}
1558
 
1559
 
1560
/* --------------------------------------------------------------------------*/
1561
/* 7.4.48  D1006                                                             */
1562
/* --------------------------------------------------------------------------*/
1563
 
1564
void disassemble::garmin_print_d1006 (D1006 *x)
1565
{
1566
	memset (&course, 0, sizeof(COURSE));
1567
	course.type = 1006;
1568
	course.index = x->index;
1569
	strncpy(course.course_name, x->course_name, 16);
1570
	course.track_index = x->track_index;
1571
}
1572
 
1573
 
1574
/* --------------------------------------------------------------------------*/
1575
/* 7.4.49  D1007                                                             */
1576
/* --------------------------------------------------------------------------*/
1577
 
1578
void disassemble::garmin_print_d1007 (D1007 *x)
1579
{
1580
	memset (&course, 0, sizeof(COURSE));
1581
	course.type = 1007;
1582
	course.course_index = x->course_index;
1583
	course.lap_index = x->lap_index;
1584
	course.total_time = x->total_time;
1585
	course.total_dist = x->total_dist;
1586
	course.begin.lat = x->begin.lat;
1587
	course.begin.lon = x->begin.lon;
1588
	course.end.lat = x->end.lat;
1589
	course.end.lon = x->end.lon;
1590
	course.avg_heart_rate = x->avg_heart_rate;
1591
	course.max_heart_rate = x->max_heart_rate;
1592
	course.avg_cadence = x->avg_cadence;
1593
	course.intensity = x->intensity;
1594
}
1595
 
1596
 
1597
/* --------------------------------------------------------------------------*/
1598
/* 7.4.50  D1008                                                             */
1599
/* --------------------------------------------------------------------------*/
1600
 
1601
 
1602
void disassemble::garmin_print_d1008 (D1008 *w)
1603
{
1604
	/* For some reason, D1008 is identical to D1002. */
1605
	garmin_print_d1002((D1002 *)w);
1606
	workout.type = 1008;
1607
}
1608
 
1609
 
1610
/* --------------------------------------------------------------------------*/
1611
/* 7.4.51  D1009                                                             */
1612
/* --------------------------------------------------------------------------*/
1613
 
1614
 
1615
void disassemble::garmin_print_d1009 (D1009 *x)
1616
{
1617
	memset(&run, 0, sizeof(RUN));
1618
	garmin_print_d1002((D1002 *)&x->workout);
217 andreas 1619
	memmove (&run.workout, &workout, sizeof (WORKOUT));
88 andreas 1620
	run.type = 1009;
1621
	run.track_index = x->track_index;
1622
	run.sport_type = x->sport_type;
1623
	run.first_lap_index = x->first_lap_index;
1624
	run.last_lap_index = x->last_lap_index;
1625
	run.program_type = x->program_type;
1626
	run.virtual_partner.time = x->quick_workout.time;
1627
	run.virtual_partner.distance = x->quick_workout.distance;
1628
	run.multisport = x->multisport;
1629
	addRun();
1630
}
1631
 
1632
 
1633
/* --------------------------------------------------------------------------*/
1634
/* 7.4.52  D1010                                                             */
1635
/* --------------------------------------------------------------------------*/
1636
 
1637
 
1638
void disassemble::garmin_print_d1010 (D1010 *x)
1639
{
1640
	memset(&run, 0, sizeof(RUN));
1641
	garmin_print_d1002((D1002 *)&x->workout);
1642
	run.type = 1010;
1643
	run.track_index = x->track_index;
1644
	run.sport_type = x->sport_type;
1645
	run.first_lap_index = x->first_lap_index;
1646
	run.last_lap_index = x->last_lap_index;
1647
	run.program_type = x->program_type;
1648
	run.virtual_partner.time = x->virtual_partner.time;
1649
	run.virtual_partner.distance = x->virtual_partner.distance;
1650
	run.multisport = x->multisport;
1651
	addRun();
1652
}
1653
 
1654
 
1655
/* --------------------------------------------------------------------------*/
1656
/* 7.4.53  D1011                                                             */
1657
/* --------------------------------------------------------------------------*/
1658
 
1659
 
1660
void disassemble::garmin_print_d1011 (D1011 *x)
1661
{
1662
	memset(&lap, 0, sizeof(LAP));
1663
	lap.type = 1011;
1664
	lap.start_time = x->start_time;
1665
	lap.total_time = x->total_time;
1666
	lap.total_distance = x->total_dist;
1667
	lap.begin.lat = x->begin.lat;
1668
	lap.begin.lon = x->begin.lon;
1669
	lap.end.lat = x->end.lat;
1670
	lap.end.lon = x->end.lon;
1671
	lap.calories = x->calories;
1672
	lap.index = x->index;
1673
	lap.max_speed = x->max_speed;
1674
	lap.avg_heart_rate = x->avg_heart_rate;
1675
	lap.max_heart_rate = x->max_heart_rate;
1676
	lap.intensity = x->intensity;
1677
	lap.avg_cadence = x->avg_cadence;
1678
	lap.trigger_method = x->trigger_method;
1679
	addLap();
1680
}
1681
 
1682
 
1683
/* --------------------------------------------------------------------------*/
1684
/* 7.4.54  D1012                                                             */
1685
/* --------------------------------------------------------------------------*/
1686
 
1687
void disassemble::garmin_print_d1012 (D1012 *x)
1688
{
1689
	memset (&course, 0, sizeof(COURSE));
1690
	course.type = 1012;
1691
	course.course_index = x->course_index;
1692
	strncpy (course.course_name, x->name, 11);
1693
	course.track_point_time = x->track_point_time;
1694
	course.point_type = x->point_type;
1695
}
1696
 
1697
 
1698
/* --------------------------------------------------------------------------*/
1699
/* 7.4.55  D1013                                                             */
1700
/* --------------------------------------------------------------------------*/
1701
 
1702
void disassemble::garmin_print_d1013 (D1013 *x)
1703
{
1704
	memset (&course, 0, sizeof(COURSE));
1705
	course.type = 1012;
1706
	course.max_courses = x->max_courses;
1707
	course.max_course_laps = x->max_course_laps;
1708
	course.max_course_pnt = x->max_course_pnt;
1709
	course.max_course_trk_pnt = x->max_course_trk_pnt;
1710
}
1711
 
1712
 
1713
/* --------------------------------------------------------------------------*/
1714
/* 7.4.XX  D1015 (Undocumented)                                              */
1715
/* --------------------------------------------------------------------------*/
1716
 
1717
void disassemble::garmin_print_d1015 (D1015 *x)
1718
{
1719
	memset(&lap, 0, sizeof(LAP));
1720
	lap.type = 1011;
1721
	lap.start_time = x->start_time;
1722
	lap.total_time = x->total_time;
1723
	lap.total_distance = x->total_dist;
1724
	lap.begin.lat = x->begin.lat;
1725
	lap.begin.lon = x->begin.lon;
1726
	lap.end.lat = x->end.lat;
1727
	lap.end.lon = x->end.lon;
1728
	lap.calories = x->calories;
1729
	lap.index = x->index;
1730
	lap.max_speed = x->max_speed;
1731
	lap.avg_heart_rate = x->avg_heart_rate;
1732
	lap.max_heart_rate = x->max_heart_rate;
1733
	lap.intensity = x->intensity;
1734
	lap.avg_cadence = x->avg_cadence;
1735
	lap.trigger_method = x->trigger_method;
1736
	addLap();
1737
}
1738
 
1739
 
1740
/* ========================================================================= */
1741
/* garmin_print_data                                                         */
1742
/* ========================================================================= */
1743
 
1744
void disassemble::garmin_print_data (garmin_data *d)
1745
{
314 andreas 1746
	if (!d || !d->data)
245 andreas 1747
	   return;
1748
 
88 andreas 1749
#define CASE_PRINT(x) \
1750
  case data_D##x: garmin_print_d##x((D##x *)d->data); break
1751
 
1752
	switch (d->type)
1753
	{
1754
	   case data_Dlist:
1755
	      garmin_print_dlist ((garmin_list *)d->data);
1756
	   break;
1757
 
1758
	   CASE_PRINT(100);
1759
	   CASE_PRINT(101);
1760
	   CASE_PRINT(102);
1761
	   CASE_PRINT(103);
1762
	   CASE_PRINT(104);
1763
	   CASE_PRINT(105);
1764
	   CASE_PRINT(106);
1765
	   CASE_PRINT(107);
1766
	   CASE_PRINT(108);
1767
	   CASE_PRINT(109);
1768
	   CASE_PRINT(110);
1769
	   CASE_PRINT(120);
1770
	   CASE_PRINT(150);
1771
	   CASE_PRINT(151);
1772
	   CASE_PRINT(152);
1773
	   CASE_PRINT(154);
1774
	   CASE_PRINT(155);
1775
	   CASE_PRINT(200);
1776
	   CASE_PRINT(201);
1777
	   CASE_PRINT(202);
1778
	   CASE_PRINT(210);
1779
	   CASE_PRINT(300);
1780
	   CASE_PRINT(301);
1781
	   CASE_PRINT(302);
1782
	   CASE_PRINT(303);
1783
	   CASE_PRINT(304);
1784
	   CASE_PRINT(310);
1785
	   CASE_PRINT(311);
1786
	   CASE_PRINT(312);
1787
	   CASE_PRINT(400);
1788
	   CASE_PRINT(403);
1789
	   CASE_PRINT(450);
1790
	   CASE_PRINT(500);
1791
	   CASE_PRINT(501);
1792
	   CASE_PRINT(550);
1793
	   CASE_PRINT(551);
1794
	   CASE_PRINT(600);
1795
	   CASE_PRINT(650);
1796
	   CASE_PRINT(700);
1797
	   CASE_PRINT(800);
1798
	   CASE_PRINT(906);
1799
	   CASE_PRINT(1000);
1800
	   CASE_PRINT(1001);
1801
	   CASE_PRINT(1002);
1802
	   CASE_PRINT(1003);
1803
	   CASE_PRINT(1004);
1804
	   CASE_PRINT(1005);
1805
	   CASE_PRINT(1006);
1806
	   CASE_PRINT(1007);
1807
	   CASE_PRINT(1008);
1808
	   CASE_PRINT(1009);
1809
	   CASE_PRINT(1010);
1810
	   CASE_PRINT(1011);
1811
	   CASE_PRINT(1012);
1812
	   CASE_PRINT(1013);
1813
	   CASE_PRINT(1015);
137 andreas 1814
	   default: break;
88 andreas 1815
	}
1816
 
1817
#undef CASE_PRINT
1818
}
1819
 
104 andreas 1820
/*
1821
 * The following functions are to calculate some GPS related parameters.
1822
 * Base is the WGS84 date.
1823
 *
1824
 * This functions are not needed tho handle the files and data out of
1825
 * the GPS-device!
1826
 */
1827
double disassemble::CalcRad(double lat)
1828
/* earth's radius of curvature in meters at specified latitude.*/
1829
{
1830
const double a = 6378.137;
1831
const double e2 = 0.081082 * 0.081082;
1832
 
1833
	/*
1834
	 * the radius of curvature of an ellipsoidal Earth in the plane of a
1835
	 * meridian of latitude is given by
1836
	 *
1837
	 * R' = a * (1 - e^2) / (1 - e^2 * (sin(lat))^2)^(3/2)
1838
	 *
1839
	 * where a is the equatorial radius,
1840
	 * b is the polar radius, and
1841
	 * e is the eccentricity of the ellipsoid = sqrt(1 - b^2/a^2)
1842
	 *
1843
	 * a = 6378 km (3963 mi) Equatorial radius (surface to center distance)
1844
	 * b = 6356.752 km (3950 mi) Polar radius (surface to center distance)
1845
	 * e = 0.081082 Eccentricity
1846
	 */
1847
	double sc = sin(Deg2Rad(lat));
1848
	double x = a * (1.0 - e2);
1849
	double z = 1.0 - e2 * sc * sc;
1850
	double y = pow(z, 1.5);
1851
	double r = x / y;
1852
 
1853
	return r * 1000.0; // Convert to meters
1854
}
1855
 
1856
double disassemble::earth_distance(double lat1, double lon1, double lat2, double lon2)
1857
/* distance in meters between two points specified in degrees. */
1858
{
1859
double x1 = CalcRad(lat1) * cos(Deg2Rad(lon1)) * sin(Deg2Rad(90-lat1));
1860
double x2 = CalcRad(lat2) * cos(Deg2Rad(lon2)) * sin(Deg2Rad(90-lat2));
1861
double y1 = CalcRad(lat1) * sin(Deg2Rad(lon1)) * sin(Deg2Rad(90-lat1));
1862
double y2 = CalcRad(lat2) * sin(Deg2Rad(lon2)) * sin(Deg2Rad(90-lat2));
1863
double z1 = CalcRad(lat1) * cos(Deg2Rad(90-lat1));
1864
double z2 = CalcRad(lat2) * cos(Deg2Rad(90-lat2));
1865
double a = (x1*x2 + y1*y2 + z1*z2)/pow(CalcRad((lat1+lat2)/2),2);
1866
 
1867
	// a should be in [1, -1] but can sometimes fall outside it by
1868
	// a very small amount due to rounding errors in the preceding
1869
	// calculations (this is prone to happen when the argument points
1870
	// are very close together). Thus we constrain it here.
1871
	if (abs(a) > 1)
1872
	   a = 1;
1873
	else if (a < -1)
1874
	   a = -1;
1875
 
1876
	return CalcRad((lat1+lat2) / 2) * acos(a);
1877
}