Subversion Repositories public

Rev

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