comparison Discovery/Src/t9.c @ 38:5f11787b4f42

include in ostc4 repository
author heinrichsweikamp
date Sat, 28 Apr 2018 11:52:34 +0200
parents
children b364c75005bb
comparison
equal deleted inserted replaced
37:ccc45c0e1ea2 38:5f11787b4f42
1 ///////////////////////////////////////////////////////////////////////////////
2 /// -*- coding: UTF-8 -*-
3 ///
4 /// \file Discovery/Src/t9.c
5 /// \brief Template for screen with 4+1+4 screen layout with plugin
6 /// \author Heinrichs Weikamp gmbh
7 /// \date 23-April-2014
8 ///
9 /// \details
10 /// Bonex t9 -> sp�ter auch andere Pro Anzeigen
11 /// Nur Tauchmodus, sonst Umschaltung t7
12 /// frames used 26 for compass laufband und 23 f�r t9screen
13 ///
14 /// $Id$
15 ///////////////////////////////////////////////////////////////////////////////
16 /// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh
17 ///
18 /// This program is free software: you can redistribute it and/or modify
19 /// it under the terms of the GNU General Public License as published by
20 /// the Free Software Foundation, either version 3 of the License, or
21 /// (at your option) any later version.
22 ///
23 /// This program is distributed in the hope that it will be useful,
24 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
25 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 /// GNU General Public License for more details.
27 ///
28 /// You should have received a copy of the GNU General Public License
29 /// along with this program. If not, see <http://www.gnu.org/licenses/>.
30 //////////////////////////////////////////////////////////////////////////////
31
32 /* Includes ------------------------------------------------------------------*/
33 #include "t9.h"
34
35 #include "data_exchange_main.h"
36 #include "decom.h"
37 #include "gfx_fonts.h"
38 #include "logbook_miniLive.h"
39 #include "math.h"
40 #include "tHome.h"
41 #include "simulation.h"
42 #include "timer.h"
43 #include "unit.h"
44
45 /* Private function prototypes -----------------------------------------------*/
46
47 void t9_refresh_divemode(void);
48 void t9_refresh_divemode_userselected_left_lower_corner(void);
49 void t9_refresh_customview(void);
50
51 void t9_draw_frame(_Bool PluginBoxHeader, _Bool LinesOnTheSides, uint8_t colorBox, uint8_t colorLinesOnTheSide);
52
53 void t9_tissues(const SDiveState * pState);
54 void t9_compass(uint16_t ActualHeading, uint16_t UserSetHeading);
55 void t9_scooter(void);
56 void t9_debug(void);
57 void t9_SummaryOfLeftCorner(void);
58
59 void t9_miniLiveLogProfile(void);
60 void t9_colorscheme_mod(char *text);
61
62 uint8_t t9_test_customview_warnings(void);
63 void t9_show_customview_warnings(void);
64
65 void t9_show_customview_warnings_surface_mode(void);
66
67 uint8_t t9_customtextPrepare(char * text);
68
69 /* Importend function prototypes ---------------------------------------------*/
70 extern uint8_t write_gas(char *text, uint8_t oxygen, uint8_t helium);
71
72 /* Exported variables --------------------------------------------------------*/
73
74 /* Private variables ---------------------------------------------------------*/
75 float t9_depthLastCall[9] = { 0,0,0,0,0,0,0,0,0};
76 uint8_t idt9_depthLastCall = 0;
77 float t9_temperatureLastCall[3] = { 0,0,0};
78 uint8_t idt9_temperatureLastCall = 0;
79
80 GFX_DrawCfgScreen t9screen;
81 GFX_DrawCfgScreen t9screenCompass;
82
83 /* left 3 fields
84 * right 3 fields
85 * centered one field on top of customview, one below
86 * customview header + customview + warning
87 */
88 GFX_DrawCfgWindow t9l1, t9l2, t9l3, t9l4;
89 GFX_DrawCfgWindow t9r1, t9r2, t9r3, t9r4;
90 GFX_DrawCfgWindow t9c1, t9batt, t9c2, t9charge;
91 GFX_DrawCfgWindow t9cH, t9cC, t9cW, t9cY0free;
92 GFX_DrawCfgWindow t9pCompass;
93 GFX_DrawCfgWindow t9surfaceL, t9surfaceR;
94
95 uint8_t t9_selection_custom_field = 0;
96 uint8_t t9_selection_customview = 1;
97
98 typedef struct{
99 uint32_t pointer;
100 uint32_t x0;
101 uint32_t y0;
102 uint32_t width;
103 uint32_t height;
104 } S9Background;
105
106 S9Background t9_background =
107 {
108 .pointer = NULL,
109 };
110
111 /* Private types -------------------------------------------------------------*/
112 const uint8_t t9_customviewsDiveStandard[] =
113 {
114 CVIEW_sensors,
115 CVIEW_Compass,
116 CVIEW_Decolist,
117 CVIEW_Tissues,
118 CVIEW_Profile,
119 CVIEW_Gaslist,
120 CVIEW_sensors_mV,
121 CVIEW_EADTime,
122 // CVIEW_SummaryOfLeftCorner, da hier der scooter drin ist
123 CVIEW_noneOrDebug,
124 CVIEW_END,
125 CVIEW_END
126 };
127
128 const uint8_t t9_customviewsDiveScooter[] =
129 {
130 CVIEW_Scooter,
131 CVIEW_sensors,
132 CVIEW_Compass,
133 CVIEW_Decolist,
134 CVIEW_Tissues,
135 CVIEW_Profile,
136 CVIEW_Gaslist,
137 CVIEW_sensors_mV,
138 CVIEW_EADTime,
139 CVIEW_SummaryOfLeftCorner,
140 CVIEW_noneOrDebug,
141 CVIEW_END,
142 CVIEW_END
143 };
144
145
146 const uint8_t *t9_customviewsDive = t9_customviewsDiveStandard;
147
148 #define TEXTSIZE 16
149 /* offset includes line: 2 = line +1
150 * box (line) is 300 px
151 * inside is 296 px
152 * left of box are 249 px ( 0..248)
153 * right of box are 249 px (551 .. 799)
154 */
155
156 #define CUSTOMBOX_LINE_LEFT (250)
157 #define CUSTOMBOX_LINE_RIGHT (549)
158 #define CUSTOMBOX_INSIDE_OFFSET (2)
159 #define CUSTOMBOX_OUTSIDE_OFFSET (2)
160 #define CUSTOMBOX_SPACE_INSIDE (CUSTOMBOX_LINE_RIGHT + 1 - (CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET + CUSTOMBOX_INSIDE_OFFSET))
161
162
163 /* Exported functions --------------------------------------------------------*/
164
165 void t9_init(void)
166 {
167 if(getLicence() == LICENCEBONEX)
168 {
169 t9_customviewsDive = t9_customviewsDiveScooter;
170 }
171
172 t9_selection_custom_field = 0; // 0 is the new scooter temperature
173 t9_selection_customview = t9_customviewsDive[0];
174
175 t9screen.FBStartAdress = 0;
176 t9screen.ImageHeight = 480;
177 t9screen.ImageWidth = 800;
178 t9screen.LayerIndex = 1;
179
180 t9screenCompass.FBStartAdress = 0;
181 t9screenCompass.ImageHeight = 240;
182 t9screenCompass.ImageWidth = 1600;
183 t9screenCompass.LayerIndex = 0;
184
185 t9l1.Image = &t9screen;
186 t9l1.WindowNumberOfTextLines = 2;
187 t9l1.WindowLineSpacing = 5; // Abstand von Y0
188 t9l1.WindowTab = 100; // vermtl. ohne Verwendung in diesem Fenster
189 t9l1.WindowX0 = 0;
190 t9l1.WindowX1 = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET;
191 t9l1.WindowY1 = 479;
192 t9l1.WindowY0 = t9l1.WindowY1 - 119;
193
194 t9l2.Image = &t9screen;
195 t9l2.WindowNumberOfTextLines = 2;
196 t9l2.WindowLineSpacing = 5; // Abstand von Y0
197 t9l2.WindowTab = 100; // vermtl. ohne Verwendung in diesem Fenster
198 t9l2.WindowX0 = 0;
199 t9l2.WindowX1 = t9l1.WindowX1;
200 t9l2.WindowY1 = t9l1.WindowY0 - 4;
201 t9l2.WindowY0 = t9l2.WindowY1 - 119;
202
203 t9l3.Image = &t9screen;
204 t9l3.WindowNumberOfTextLines = 2;
205 t9l3.WindowLineSpacing = 5; // Abstand von Y0
206 t9l3.WindowTab = 100; // vermtl. ohne Verwendung in diesem Fenster
207 t9l3.WindowX0 = 0;
208 t9l3.WindowX1 = t9l1.WindowX1;
209 t9l3.WindowY1 = t9l2.WindowY0 - 4;
210 t9l3.WindowY0 = t9l3.WindowY1 - 119;
211
212 t9l4.Image = &t9screen;
213 t9l4.WindowNumberOfTextLines = 2;
214 t9l4.WindowLineSpacing = 50; // Abstand von Y0
215 t9l4.WindowTab = 100; // vermtl. ohne Verwendung in diesem Fenster
216 t9l4.WindowX0 = 0;
217 t9l4.WindowX1 = t9l1.WindowX1;
218 t9l4.WindowY1 = t9l3.WindowY0 - 4;
219 t9l4.WindowY0 = 0;
220
221 t9r1.Image = &t9screen;
222 t9r1.WindowNumberOfTextLines = 2;
223 t9r1.WindowLineSpacing = t9l1.WindowLineSpacing;
224 t9r1.WindowTab = 100;
225 t9r1.WindowX0 = 550;
226 t9r1.WindowX1 = 799;
227 t9r1.WindowY0 = t9l1.WindowY0;
228 t9r1.WindowY1 = 479;
229
230 t9r2.Image = &t9screen;
231 t9r2.WindowNumberOfTextLines = 2;
232 t9r2.WindowLineSpacing = t9l2.WindowLineSpacing;
233 t9r2.WindowTab = 100;
234 t9r2.WindowX0 = 550;
235 t9r2.WindowX1 = 799;
236 t9r2.WindowY0 = t9l2.WindowY0;
237 t9r2.WindowY1 = t9l2.WindowY1;
238
239 t9r3.Image = &t9screen;
240 t9r3.WindowNumberOfTextLines = 2;
241 t9r3.WindowLineSpacing = t9l3.WindowLineSpacing;
242 t9r3.WindowTab = 100;
243 t9r3.WindowX0 = 550;
244 t9r3.WindowX1 = 799;
245 t9r3.WindowY0 = t9l3.WindowY0;
246 t9r3.WindowY1 = t9l3.WindowY1;
247
248 t9r4.Image = &t9screen;
249 t9r4.WindowNumberOfTextLines = 2;
250 t9r4.WindowLineSpacing = t9l4.WindowLineSpacing;
251 t9r4.WindowTab = 100;
252 t9r4.WindowX0 = 550;
253 t9r4.WindowX1 = 799;
254 t9r4.WindowY0 = t9l4.WindowY0;
255 t9r4.WindowY1 = t9l4.WindowY1;
256
257
258 /*
259 t9r3.Image = &t9screen;
260 t9r3.WindowNumberOfTextLines = 2;
261 t9r3.WindowLineSpacing = 0;//t9l3.WindowLineSpacing;
262 t9r3.WindowTab = 100;
263 t9r3.WindowX0 = CUSTOMBOX_LINE_RIGHT + CUSTOMBOX_OUTSIDE_OFFSET;
264 t9r3.WindowX1 = 799;
265 t9r3.WindowY0 = t9l3.WindowY0;
266 t9r3.WindowY1 = t9l3.WindowY1;
267 */
268 t9cC.Image = &t9screen;
269 t9cC.WindowNumberOfTextLines = 3;
270 t9cC.WindowLineSpacing = 95; // Abstand von Y0
271 t9cC.WindowTab = 100;
272 t9cC.WindowX0 = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
273 t9cC.WindowX1 = CUSTOMBOX_LINE_RIGHT - CUSTOMBOX_INSIDE_OFFSET;
274 t9cC.WindowY0 = 90;
275 t9cC.WindowY1 = 434 - 95;
276
277 t9cH.Image = &t9screen;
278 t9cH.WindowNumberOfTextLines = 1;
279 t9cH.WindowLineSpacing = 95; // Abstand von Y0
280 t9cH.WindowTab = 100;
281 t9cH.WindowX0 = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
282 t9cH.WindowX1 = CUSTOMBOX_LINE_RIGHT - CUSTOMBOX_INSIDE_OFFSET;
283 t9cH.WindowY0 = 434 - 94;
284 t9cH.WindowY1 = 434;
285
286 t9cW.Image = &t9screen;
287 t9cW.WindowNumberOfTextLines = 3;
288 t9cW.WindowLineSpacing = 95; // Abstand von Y0
289 t9cW.WindowTab = 100;
290 t9cW.WindowX0 = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
291 t9cW.WindowX1 = CUSTOMBOX_LINE_RIGHT - CUSTOMBOX_INSIDE_OFFSET;
292 t9cW.WindowY0 = 90;
293 t9cW.WindowY1 = 434 - 95;
294
295 t9cY0free.Image = &t9screen;
296 t9cY0free.WindowNumberOfTextLines = 1;
297 t9cY0free.WindowLineSpacing = 95;
298 t9cY0free.WindowTab = 100;
299 t9cY0free.WindowX0 = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
300 t9cY0free.WindowX1 = CUSTOMBOX_LINE_RIGHT - CUSTOMBOX_INSIDE_OFFSET;
301 t9cY0free.WindowY0 = 90;
302 t9cY0free.WindowY1 = 434 - 95;
303
304 t9batt.Image = &t9screen;
305 t9batt.WindowNumberOfTextLines = 1;
306 t9batt.WindowLineSpacing = 10;
307 t9batt.WindowTab = 100;
308 t9batt.WindowX1 = CUSTOMBOX_LINE_RIGHT - CUSTOMBOX_INSIDE_OFFSET;
309 t9batt.WindowX0 = t9batt.WindowX1 - (52+52);
310 t9batt.WindowY1 = 479;
311 t9batt.WindowY0 = t9batt.WindowY1 - 25;
312
313 t9charge.Image = &t9screen;
314 t9charge.WindowNumberOfTextLines = 1;
315 t9charge.WindowLineSpacing = 10;
316 t9charge.WindowTab = 100;
317 t9charge.WindowX1 = t9batt.WindowX1 - 18;
318 t9charge.WindowX0 = t9charge.WindowX1 - 14;
319 t9charge.WindowY1 = 479;
320 t9charge.WindowY0 = t9batt.WindowY1 - 25;
321
322 t9c1.Image = &t9screen;
323 t9c1.WindowNumberOfTextLines = 1;
324 t9c1.WindowLineSpacing = 10;
325 t9c1.WindowTab = 100;
326 t9c1.WindowX0 = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
327 t9c1.WindowX1 = t9batt.WindowX0 - 18;
328 t9c1.WindowY0 = 435;
329 t9c1.WindowY1 = 479;
330
331 t9c2.Image = &t9screen;
332 t9c2.WindowNumberOfTextLines = 1;
333 t9c2.WindowLineSpacing = 0; // Abstand von Y0
334 t9c2.WindowTab = 100;
335 t9c2.WindowX0 = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
336 t9c2.WindowX1 = CUSTOMBOX_LINE_RIGHT - CUSTOMBOX_INSIDE_OFFSET;
337 t9c2.WindowY0 = 0;
338 t9c2.WindowY1 = 69;
339
340 t9pCompass.Image = &t9screenCompass;
341 t9pCompass.WindowNumberOfTextLines = 1;
342 t9pCompass.WindowLineSpacing = 100; // Abstand von Y0
343 t9pCompass.WindowTab = 100;
344 t9pCompass.WindowX0 = 0;
345 t9pCompass.WindowX1 = 1600-1;
346 t9pCompass.WindowY0 = 0;
347 t9pCompass.WindowY1 = 100-1;
348
349 init_t9_compass();
350 }
351
352 uint8_t t9_test_customview_warnings(void)
353 {
354 uint8_t count = 0;
355
356 count = 0;
357 count += stateUsed->warnings.decoMissed;
358 count += stateUsed->warnings.ppO2Low;
359 count += stateUsed->warnings.ppO2High;
360 //count += stateUsed->warnings.lowBattery;
361 count += stateUsed->warnings.sensorLinkLost;
362 count += stateUsed->warnings.fallback;
363 return count;
364 }
365
366 void t9_refresh(void)
367 {
368 static uint8_t last_mode = MODE_SURFACE;
369
370 SStateList status;
371 get_globalStateList(&status);
372
373 if(stateUsed->mode != MODE_DIVE)
374 {
375 last_mode = MODE_SURFACE;
376 settingsGetPointer()->design = 7;
377 if(t9screen.FBStartAdress)
378 {
379 releaseFrame(23,t9screen.FBStartAdress);
380 t9screen.FBStartAdress = 0;
381 }
382 return;
383 }
384
385 if(status.base != BaseHome)
386 return;
387
388 t9screen.FBStartAdress = getFrame(23);
389 t9_background.pointer = 0;
390
391 if(stateUsed->mode == MODE_DIVE)
392 {
393 if(last_mode != MODE_DIVE)
394 {
395 last_mode = MODE_DIVE;
396 /* lower left corner primary */
397 // t9_selection_custom_field = settingsGetPointer()->tX_userselectedLeftLowerCornerPrimary;
398 t9_selection_custom_field = 0;
399 /* custom view primary OR debug if automatic return is off */
400 if((settingsGetPointer()->tX_customViewTimeout == 0) && (settingsGetPointer()->showDebugInfo))
401 t9_selection_customview = CVIEW_noneOrDebug;
402 else
403 t9_selection_customview = settingsGetPointer()->tX_customViewPrimary;
404 }
405
406 if(status.page == PageSurface)
407 set_globalState(StD);
408
409 t9_refresh_divemode();
410 }
411
412 if(t9_background.pointer)
413 {
414 GFX_SetFrameTop(t9screen.FBStartAdress);
415 GFX_SetFrameBottom(t9_background.pointer,t9_background.x0 , t9_background.y0, t9_background.width, t9_background.height);
416 }
417 else
418 GFX_SetFramesTopBottom(t9screen.FBStartAdress, NULL,480);
419
420 releaseAllFramesExcept(23,t9screen.FBStartAdress);
421 }
422
423
424 void original_t9_refresh(void)
425 {
426 static uint8_t last_mode = MODE_SURFACE;
427
428 // uint32_t oldScreen;//, oldPlugin;
429 SStateList status;
430 get_globalStateList(&status);
431
432
433 if(stateUsed->mode == MODE_DIVE)
434 {
435 if(last_mode != MODE_DIVE)
436 {
437 last_mode = MODE_DIVE;
438 /* lower left corner primary */
439 t9_selection_custom_field = settingsGetPointer()->tX_userselectedLeftLowerCornerPrimary;
440 /* custom view primary OR debug if automatic return is off */
441 if((settingsGetPointer()->tX_customViewTimeout == 0) && (settingsGetPointer()->showDebugInfo))
442 t9_selection_customview = CVIEW_noneOrDebug;
443 else
444 t9_selection_customview = settingsGetPointer()->tX_customViewPrimary;
445 }
446 if(status.page == PageSurface)
447 set_globalState(StD);
448
449 t9_refresh_divemode();
450 }
451 else
452 {
453 if(last_mode != MODE_SURFACE)
454 {
455 last_mode = MODE_SURFACE;
456 // CHANGE HERE
457 }
458 if(status.page == PageDive)
459 set_globalState(StS);
460 }
461
462 if(status.base == BaseHome)
463 {
464 if(t9_background.pointer)
465 {
466 GFX_SetFrameTop(t9screen.FBStartAdress);
467 GFX_SetFrameBottom(t9_background.pointer,t9_background.x0 , t9_background.y0, t9_background.width, t9_background.height);
468 }
469 else
470 GFX_SetFramesTopBottom(t9screen.FBStartAdress, NULL,480);
471 }
472
473 releaseAllFramesExcept(23,t9screen.FBStartAdress);
474 }
475
476 /* Private functions ---------------------------------------------------------*/
477
478
479 void t9_show_customview_warnings(void)
480 {
481 char text[256];
482 uint8_t textpointer, lineFree;
483
484 text[0] = '\025';
485 text[1] = '\f';
486 text[2] = '\001';
487 text[3] = TXT_Warning;
488 text[4] = 0;
489 GFX_write_string(&FontT42,&t9cH,text,0);
490
491 textpointer = 0;
492 lineFree = 5;
493
494 if(lineFree && stateUsed->warnings.decoMissed)
495 {
496 text[textpointer++] = TXT_2BYTE;
497 text[textpointer++] = TXT2BYTE_WarnDecoMissed;
498 text[textpointer++] = '\n';
499 text[textpointer++] = '\r';
500 text[textpointer] = 0;
501 lineFree--;
502 }
503
504 if(lineFree && stateUsed->warnings.fallback)
505 {
506 text[textpointer++] = TXT_2BYTE;
507 text[textpointer++] = TXT2BYTE_WarnFallback;
508 text[textpointer++] = '\n';
509 text[textpointer++] = '\r';
510 text[textpointer] = 0;
511 lineFree--;
512 }
513
514 if(lineFree && stateUsed->warnings.ppO2Low)
515 {
516 text[textpointer++] = TXT_2BYTE;
517 text[textpointer++] = TXT2BYTE_WarnPPO2Low;
518 text[textpointer++] = '\n';
519 text[textpointer++] = '\r';
520 text[textpointer] = 0;
521 lineFree--;
522 }
523
524 if(lineFree && stateUsed->warnings.ppO2High)
525 {
526 text[textpointer++] = TXT_2BYTE;
527 text[textpointer++] = TXT2BYTE_WarnPPO2High;
528 text[textpointer++] = '\n';
529 text[textpointer++] = '\r';
530 text[textpointer] = 0;
531 lineFree--;
532 }
533
534 if(lineFree && stateUsed->warnings.sensorLinkLost)
535 {
536 text[textpointer++] = TXT_2BYTE;
537 text[textpointer++] = TXT2BYTE_WarnSensorLinkLost;
538 text[textpointer++] = '\n';
539 text[textpointer++] = '\r';
540 text[textpointer] = 0;
541 lineFree--;
542 }
543 /*
544 if(lineFree && stateUsed->warnings.lowBattery)
545 {
546 text[textpointer++] = TXT_2BYTE;
547 text[textpointer++] = TXT2BYTE_WarnBatteryLow;
548 text[textpointer++] = '\n';
549 text[textpointer++] = '\r';
550 text[textpointer] = 0;
551 lineFree--;
552 }
553 */
554 GFX_write_string(&FontT48,&t9cW,text,1);
555 }
556
557
558 void t9_set_customview_to_primary(void)
559 {
560 if(stateUsed->mode == MODE_DIVE)
561 t9_selection_customview = settingsGetPointer()->tX_customViewPrimary;
562 }
563
564
565 void t9_change_customview(void)
566 {
567 const uint8_t *pViews;
568
569 if(stateUsed->mode == MODE_DIVE)
570 pViews = t9_customviewsDive;
571
572 while((*pViews != CVIEW_END) && (*pViews != t9_selection_customview))
573 {pViews++;}
574
575 if(*pViews < CVIEW_END)
576 pViews++;
577 else
578 {
579 if(stateUsed->mode == MODE_DIVE)
580 pViews = t9_customviewsDive;
581 }
582
583 // if((*pViews == CVIEW_Scooter) && (getLicence() != LICENCEBONEX))
584 // pViews++;
585
586 t9_selection_customview = *pViews;
587 }
588
589
590 uint8_t t9_get_length_of_customtext(void)
591 {
592 uint8_t i = 0;
593 settingsGetPointer()->customtext[60-1] = 0;
594 while(settingsGetPointer()->customtext[i] > 0)
595 i++;
596 return i;
597 }
598
599
600 void t9_refresh_customview(void)
601 {
602 if((t9_selection_customview == CVIEW_Scooter) && (getLicence() != LICENCEBONEX))
603 t9_change_customview();
604 if((t9_selection_customview == CVIEW_sensors) &&(stateUsed->diveSettings.ccrOption == 0))
605 t9_change_customview();
606 if((t9_selection_customview == CVIEW_sensors_mV) &&(stateUsed->diveSettings.ccrOption == 0))
607 t9_change_customview();
608 if((t9_selection_customview == CVIEW_sensors) &&(stateUsed->diveSettings.ccrOption == 0))
609 t9_change_customview();
610
611 char text[256];
612 uint16_t textpointer = 0;
613 int16_t start;
614 // int16_t shiftWindowY0;
615 RTC_DateTypeDef Sdate;
616 RTC_TimeTypeDef Stime;
617 float fPpO2limitHigh, fPpO2limitLow, fPpO2ofGasAtThisDepth; // CVIEW_Gaslist
618 const SGasLine * pGasLine; // CVIEW_Gaslist
619 uint8_t oxygen, helium; // CVIEW_Gaslist
620 float depth, surface, fraction_nitrogen, fraction_helium, ead, end; // CVIEW_EADTime
621
622 switch(t9_selection_customview)
623 {
624 case CVIEW_noneOrDebug:
625 if(settingsGetPointer()->showDebugInfo)
626 {
627 // header
628 strcpy(text,"\032\f\001Debug");
629 GFX_write_string(&FontT42,&t9cH,text,0);
630 // content
631 t9_debug();
632 }
633 break;
634 case CVIEW_SummaryOfLeftCorner:
635 snprintf(text,100,"\032\f\001%c%c",TXT_2BYTE,TXT2BYTE_Summary);
636 GFX_write_string(&FontT42,&t9cH,text,0);
637 // content
638 t9_SummaryOfLeftCorner();
639 break;
640 case CVIEW_Scooter:
641 snprintf(text,100,"\032\f\001Scooter");
642 GFX_write_string(&FontT42,&t9cH,text,0);
643 t9_scooter();
644 break;
645 case CVIEW_Gaslist:
646 // a lot of code taken from tMenuGas.c
647 // header
648 snprintf(text,100,"\032\f\001%c%c",TXT_2BYTE,TXT2BYTE_Gaslist);
649 GFX_write_string(&FontT42,&t9cH,text,0);
650 // content
651 textpointer = 0;
652 t9cY0free.WindowY0 = t9cC.WindowY0 - 10;
653 t9cY0free.WindowLineSpacing = 48+9;
654 t9cY0free.WindowNumberOfTextLines = 5; // NUM_GASES == 5
655 t9cY0free.WindowTab = 420;
656
657 pGasLine = settingsGetPointer()->gas;
658 if(actualLeftMaxDepth(stateUsed))
659 fPpO2limitHigh = (float)(settingsGetPointer()->ppO2_max_deco) / 100;
660 else
661 fPpO2limitHigh = (float)(settingsGetPointer()->ppO2_max_std) / 100;
662 fPpO2limitLow = (float)(settingsGetPointer()->ppO2_min) / 100;
663 for(int gasId=1;gasId<=NUM_GASES;gasId++)
664 {
665 textpointer = 0;
666 fPpO2ofGasAtThisDepth = (stateUsed->lifeData.pressure_ambient_bar - WATER_VAPOUR_PRESSURE) * pGasLine[gasId].oxygen_percentage / 100;
667 if(pGasLine[gasId].note.ub.active == 0)
668 strcpy(&text[textpointer++],"\021");
669 else if((fPpO2ofGasAtThisDepth > fPpO2limitHigh) || (fPpO2ofGasAtThisDepth < fPpO2limitLow))
670 strcpy(&text[textpointer++],"\025");
671 else
672 strcpy(&text[textpointer++],"\030");
673
674 text[textpointer++] = ' ';
675 oxygen = pGasLine[gasId].oxygen_percentage;
676 helium = pGasLine[gasId].helium_percentage;
677 textpointer += write_gas(&text[textpointer], oxygen, helium);
678 // Wechseltiefe
679 if(pGasLine[gasId].depth_meter)
680 {
681 textpointer += snprintf(&text[textpointer],6,"\t%u m",pGasLine[gasId].depth_meter);
682 }
683 GFX_write_string(&FontT42, &t9cY0free, text, gasId);
684 }
685 break;
686 case CVIEW_EADTime:
687 snprintf(text,100,"\032\f\001%c%c",TXT_2BYTE,TXT2BYTE_Info );
688 GFX_write_string(&FontT42,&t9cH,text,0);
689 textpointer = 0;
690
691 t9cY0free.WindowY0 = t9cC.WindowY0 - 10;
692 t9cY0free.WindowLineSpacing = 48;
693 t9cY0free.WindowNumberOfTextLines = 6;
694
695 // time
696 snprintf(text,100,"\032\001%c%c",TXT_2BYTE,TXT2BYTE_Clock );
697 GFX_write_string(&FontT42, &t9cY0free, text, 1);
698
699 translateDate(stateRealGetPointer()->lifeData.dateBinaryFormat, &Sdate);
700 translateTime(stateRealGetPointer()->lifeData.timeBinaryFormat, &Stime);
701 if(Stime.Seconds % 2)
702 textpointer += snprintf(&text[textpointer],100,"\030\001%02d:%02d",Stime.Hours,Stime.Minutes);
703 else
704 textpointer += snprintf(&text[textpointer],100,"\030\001%02d\031:\030%02d",Stime.Hours,Stime.Minutes);
705 GFX_write_string(&FontT42, &t9cY0free, text, 2);
706
707 // EAD / END
708 // The equivalent air depth can be calculated for depths in metres as follows:
709 // EAD = (Depth + 10) � Fraction of N2 / 0.79 - 10 (wikipedia)
710 // The equivalent narcotic depth can be calculated for depths in metres as follows:
711 // END = (Depth + 10) � (1 - Fraction of helium) - 10 (wikipedia)
712 decom_get_inert_gases((float)stateUsed->lifeData.pressure_ambient_bar,&(stateUsed->lifeData.actualGas),&fraction_nitrogen,&fraction_helium);
713 depth = stateUsed->lifeData.pressure_ambient_bar;
714 surface = stateUsed->lifeData.pressure_surface_bar;
715 ead = 10.f * ((depth * fraction_nitrogen/0.79f) - surface);
716 end = 10.0f * ((depth * (1.f - fraction_helium)) - surface);
717 if(ead < 0)
718 ead = 0;
719 if(end < 0)
720 end = 0;
721
722 snprintf(text,100,"\032\001EAD");
723 GFX_write_string(&FontT42, &t9cY0free, text, 3);
724 snprintf(text,100,"\030\001%01.1fm", ead);
725 GFX_write_string(&FontT42, &t9cY0free, text, 4);
726
727 snprintf(text,100,"\032\001END");
728 GFX_write_string(&FontT42, &t9cY0free, text, 5);
729 snprintf(text,100,"\030\001%01.1fm", end);
730 GFX_write_string(&FontT42, &t9cY0free, text, 6);
731 break;
732 case CVIEW_Profile:
733 snprintf(text,100,"\032\f\001%c%c",TXT_2BYTE,TXT2BYTE_Profile);
734 GFX_write_string(&FontT42,&t9cH,text,0);
735 textpointer = 0;
736 t9_miniLiveLogProfile();
737 break;
738 case CVIEW_Tissues:
739 snprintf(text,100,"\032\f\001%c%c",TXT_2BYTE,TXT2BYTE_Tissues);
740 GFX_write_string(&FontT42,&t9cH,text,0);
741 textpointer = 0;
742 t9_tissues(stateUsed);
743 break;
744 case CVIEW_sensors:
745 snprintf(text,100,"\032\f\001%c%c",TXT_2BYTE,TXT2BYTE_O2monitor);
746 GFX_write_string(&FontT42,&t9cH,text,0);
747 textpointer = 0;
748 text[textpointer++] = '\030'; // main color
749 for(int i=0;i<3;i++)
750 {
751 if(stateUsed->diveSettings.ppo2sensors_deactivated & (1<<i))
752 {
753 text[textpointer++] = '\031'; // labelcolor
754 text[textpointer++] = '\001';
755 text[textpointer++] = '-';
756 text[textpointer++] = '\n';
757 text[textpointer++] = '\r';
758 text[textpointer++] = '\030'; // main color
759 text[textpointer] = 0;
760 }
761 else
762 {
763 if(stateUsed->warnings.sensorOutOfBounds[i])
764 text[textpointer++] = '\025'; // Warning Red
765 textpointer += snprintf(&text[textpointer],100,"\001%01.2f\n\r\030",stateUsed->lifeData.ppO2Sensor_bar[i]);
766 }
767 }
768 t9cC.WindowLineSpacing = 95;
769 t9cC.WindowNumberOfTextLines = 3;
770 text[textpointer] = 0;
771 GFX_write_string(&FontT105,&t9cC,text,1);
772 break;
773 case CVIEW_sensors_mV:
774 snprintf(text,100,"\032\f\001%c%c",TXT_2BYTE,TXT2BYTE_O2voltage);
775 GFX_write_string(&FontT42,&t9cH,text,0);
776 textpointer = 0;
777 text[textpointer++] = '\030';
778 for(int i=0;i<3;i++)
779 {
780 if(stateUsed->diveSettings.ppo2sensors_deactivated & (1<<i))
781 {
782 text[textpointer++] = '\031';
783 text[textpointer++] = '\001';
784 text[textpointer++] = '-';
785 text[textpointer++] = '\n';
786 text[textpointer++] = '\r';
787 text[textpointer++] = '\030';
788 text[textpointer] = 0;
789 }
790 else
791 {
792 if(stateUsed->warnings.sensorOutOfBounds[i])
793 text[textpointer++] = '\025';
794 textpointer += snprintf(&text[textpointer],100,"\001%01.1f mV\n\r\030",(stateUsed->lifeData.sensorVoltage_mV[i]));
795 }
796 }
797 t9cC.WindowLineSpacing = 95;
798 t9cC.WindowNumberOfTextLines = 3;
799 text[textpointer] = 0;
800 GFX_write_string(&FontT48,&t9cC,text,1);
801 break;
802 case CVIEW_Compass:
803 default:
804 snprintf(text,100,"\032\f\001%c%c",TXT_2BYTE, TXT2BYTE_Compass);
805 GFX_write_string(&FontT42,&t9cH,text,0);
806 t9_compass((uint16_t)stateUsed->lifeData.compass_heading, stateUsed->diveSettings.compassHeading);
807 t9cY0free.WindowY0 = 230;
808 t9cY0free.WindowX0 += 15;
809 snprintf(text,100,"\030\001%03i`",(uint16_t)stateUsed->lifeData.compass_heading);
810 GFX_write_string(&FontT54,&t9cY0free,text,0);
811 t9cY0free.WindowX0 -= 15;
812 break;
813 case CVIEW_Decolist:
814 snprintf(text,100,"\032\f\001%c%c", TXT_2BYTE, TXT2BYTE_Decolist);
815 GFX_write_string(&FontT42,&t9cH,text,0);
816
817 const SDecoinfo * pDecoinfo;
818 uint8_t depthNext, depthLast, depthSecond, depthInc;
819
820 if(stateUsed->diveSettings.deco_type.ub.standard == GF_MODE)
821 pDecoinfo = &stateUsed->decolistBuehlmann;
822 else
823 pDecoinfo = &stateUsed->decolistVPM;
824
825 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10);
826 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10);
827 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10);
828
829 for(start=DECOINFO_STRUCT_MAX_STOPS-1; start>0; start--)
830 if(pDecoinfo->output_stop_length_seconds[start]) break;
831 start -= 6;
832 if(start < 0) start = 0;
833
834 textpointer = 0;
835 for(int i=start;i<6+start;i++)
836 {
837 if(i == 0)
838 depthNext = depthLast;
839 else
840 depthNext = depthSecond + (( i - 1 )* depthInc);
841
842 if(pDecoinfo->output_stop_length_seconds[i])
843 textpointer += snprintf(&text[textpointer],20,"\030\034 %2u\016\016m\017%3i'\n\r",depthNext, (pDecoinfo->output_stop_length_seconds[i]+59)/60);
844 else
845 textpointer += snprintf(&text[textpointer],20,"\031\034 %2u\016\016m\017\n\r",depthNext);
846 if(textpointer > 200) break;
847 }
848 t9cY0free.WindowY0 = t9cC.WindowY0 - 10;
849 t9cY0free.WindowLineSpacing = 48;
850 t9cY0free.WindowNumberOfTextLines = 6;
851 GFX_write_string(&FontT42, &t9cY0free, text, 1);
852 break;
853 }
854 }
855
856 /* DIVE MODE
857 */
858 void t9_refresh_divemode(void)
859 {
860 char TextL1[TEXTSIZE];
861 char TextL2[TEXTSIZE];
862
863 char TextR1[TEXTSIZE];
864 char TextR2[TEXTSIZE];
865 char TextR3[TEXTSIZE];
866
867 char TextC1[2*TEXTSIZE];
868 char TextC2[TEXTSIZE];
869 uint8_t textPointer;
870
871 point_t start, stop;
872 uint8_t color;
873 int textlength;
874
875 uint16_t nextstopLengthSeconds = 0;
876 uint8_t nextstopDepthMeter = 0;
877 uint8_t oxygen_percentage = 0;
878 SDivetime Divetime = {0,0,0, 0};
879 SDivetime SafetyStopTime = {0,0,0,0};
880 SDivetime TimeoutTime = {0,0,0,0};
881 uint8_t customview_warnings = 0;
882 const SDecoinfo * pDecoinfo;
883
884 Divetime.Total = stateUsed->lifeData.dive_time_seconds_without_surface_time;
885 Divetime.Minutes = Divetime.Total / 60;
886 Divetime.Seconds = Divetime.Total - ( Divetime.Minutes * 60 );
887
888 SafetyStopTime.Total = timer_Safetystop_GetCountDown();
889 SafetyStopTime.Minutes = SafetyStopTime.Total / 60;
890 SafetyStopTime.Seconds = SafetyStopTime.Total - (SafetyStopTime.Minutes * 60);
891
892 TimeoutTime.Total = settingsGetPointer()->timeoutDiveReachedZeroDepth - stateUsed->lifeData.counterSecondsShallowDepth;
893 if(TimeoutTime.Total > settingsGetPointer()->timeoutDiveReachedZeroDepth)
894 {
895 TimeoutTime.Total = 0;
896 }
897 TimeoutTime.Minutes = TimeoutTime.Total / 60;
898 TimeoutTime.Seconds = TimeoutTime.Total - (TimeoutTime.Minutes * 60);
899
900 if(stateUsed->diveSettings.deco_type.ub.standard == GF_MODE)
901 pDecoinfo = &stateUsed->decolistBuehlmann;
902 else
903 pDecoinfo = &stateUsed->decolistVPM;
904
905 if(pDecoinfo->output_time_to_surface_seconds)
906 {
907 tHome_findNextStop(pDecoinfo->output_stop_length_seconds, &nextstopDepthMeter, &nextstopLengthSeconds);
908 }
909 else
910 {
911 nextstopDepthMeter = 0;
912 nextstopLengthSeconds = 0;
913 }
914
915 /* depth */
916 float depth = 0;
917 float depthThisCall = unit_depth_float(stateUsed->lifeData.depth_meter);
918 if(is_stateUsedSetToSim())
919 {
920 depth = (depthThisCall + t9_depthLastCall[0] + t9_depthLastCall[1] + t9_depthLastCall[2] + t9_depthLastCall[3] + t9_depthLastCall[4] + t9_depthLastCall[5] + t9_depthLastCall[6] + t9_depthLastCall[7] + t9_depthLastCall[8]) / 10.0f;
921
922 idt9_depthLastCall++;
923 if(idt9_depthLastCall >= 9)
924 idt9_depthLastCall = 0;
925 t9_depthLastCall[idt9_depthLastCall] = depthThisCall;
926 }
927 else
928 {
929 depth = (depthThisCall + t9_depthLastCall[0] + t9_depthLastCall[1] + t9_depthLastCall[2]) / 4.0f;
930
931 idt9_depthLastCall++;
932 if(idt9_depthLastCall >= 3)
933 idt9_depthLastCall = 0;
934 t9_depthLastCall[idt9_depthLastCall] = depthThisCall;
935 }
936
937 if(depth <= 0.3f)
938 depth = 0;
939
940 snprintf(TextL1,TEXTSIZE,"\032\f%c",TXT_Depth);
941 GFX_write_string(&FontT24,&t9l2,TextL1,0);
942
943 if( depth < 100)
944 snprintf(TextL1,TEXTSIZE,"\020%01.1f",depth);
945 else
946 snprintf(TextL1,TEXTSIZE,"\020%01.0f",depth);
947
948 t9_colorscheme_mod(TextL1);
949 GFX_write_string(&FontT105,&t9l2,TextL1,1);
950
951 /* max depth */
952 snprintf(TextL2,TEXTSIZE,"\032\f%c",TXT_MaxDepth);
953 GFX_write_string(&FontT24,&t9l3,TextL2,0);
954
955 if(unit_depth_float(stateUsed->lifeData.max_depth_meter) < 100)
956 snprintf(TextL2,TEXTSIZE,"\020%01.1f",unit_depth_float(stateUsed->lifeData.max_depth_meter));
957 else
958 snprintf(TextL2,TEXTSIZE,"\020%01.0f",unit_depth_float(stateUsed->lifeData.max_depth_meter));
959
960 t9_colorscheme_mod(TextL2);
961 GFX_write_string(&FontT105,&t9l3,TextL2,1);
962
963 /* ascentrate graph */
964 if(stateUsed->lifeData.ascent_rate_meter_per_min > 0)
965 {
966 start.y = t9l1.WindowY0 - 1;
967 for(int i = 0; i<4;i++)
968 {
969 start.y += 5*6;
970 stop.y = start.y;
971 start.x = CUSTOMBOX_LINE_LEFT - 1;
972 stop.x = start.x - 17;
973 GFX_draw_line(&t9screen, start, stop, 0);
974 // start.x = CUSTOMBOX_LINE_RIGHT + 2; old right too
975 // stop.x = start.x + 17;
976 // GFX_draw_line(&t9screen, start, stop, 0);
977 }
978 // new thick bar design Sept. 2015
979 start.x = CUSTOMBOX_LINE_LEFT - CUSTOMBOX_OUTSIDE_OFFSET - 3 - 5;
980 stop.x = start.x;
981 start.y = t9l1.WindowY0 - 1;
982 stop.y = start.y + (uint16_t)(stateUsed->lifeData.ascent_rate_meter_per_min * 6);
983 stop.y -= 3; // wegen der Liniendicke von 12 anstelle von 9
984 if(stop.y >= 470)
985 stop.y = 470;
986 start.y += 7; // starte etwas weiter oben
987 if(stateUsed->lifeData.ascent_rate_meter_per_min <= 10)
988 color = CLUT_EverythingOkayGreen;
989 else
990 if(stateUsed->lifeData.ascent_rate_meter_per_min <= 15)
991 color = CLUT_WarningYellow;
992 else
993 color = CLUT_WarningRed;
994
995 GFX_draw_thick_line(12,&t9screen, start, stop, color);
996 }
997 snprintf(TextL2,TEXTSIZE,"\f%.1f m/min",stateUsed->lifeData.ascent_rate_meter_per_min);
998
999 /* divetime */
1000 if(stateUsed->lifeData.counterSecondsShallowDepth)
1001 {
1002 snprintf(TextR1,TEXTSIZE,"\f\002\136 %u:%02u",TimeoutTime.Minutes, TimeoutTime.Seconds);
1003 GFX_write_string(&FontT24,&t9r2,TextR1,0);
1004 }
1005 else
1006 {
1007 snprintf(TextR1,TEXTSIZE,"\032\f\002%c",TXT_Divetime);
1008 GFX_write_string(&FontT24,&t9r2,TextR1,0);
1009 }
1010
1011 if(Divetime.Minutes < 1000)
1012 snprintf(TextR1,TEXTSIZE,"\020\016\002%u:%02u",Divetime.Minutes, Divetime.Seconds);
1013 else
1014 snprintf(TextR1,TEXTSIZE,"\020\016\002%u'",Divetime.Minutes);
1015 t9_colorscheme_mod(TextR1);
1016 GFX_write_string(&FontT105,&t9r2,TextR1,1);
1017
1018 /* next deco stop */
1019 if(nextstopDepthMeter)
1020 {
1021 snprintf(TextR2,TEXTSIZE,"\032\f\002%c",TXT_Decostop);
1022 GFX_write_string(&FontT24,&t9r3,TextR2,0);
1023 textlength = snprintf(TextR2,TEXTSIZE,"\020\002%um %u'",nextstopDepthMeter,(nextstopLengthSeconds+59)/60);
1024 t9_colorscheme_mod(TextR2);
1025 if(time_elapsed_ms(pDecoinfo->tickstamp, HAL_GetTick()) > MAX_AGE_DECOINFO_MS)
1026 TextR2[0] = '\021';
1027 if(textlength <= 8)
1028 GFX_write_string(&FontT105,&t9r3,TextR2,1);
1029 else
1030 GFX_write_string(&FontT54,&t9r3,TextR2,1);
1031 }
1032 else
1033 if(SafetyStopTime.Total && (depth > timer_Safetystop_GetDepthUpperLimit()))
1034 {
1035 snprintf(TextR2,TEXTSIZE,"\032\f\002%c%c",TXT_2BYTE,TXT2BYTE_SafetyStop2);
1036 GFX_write_string(&FontT24,&t9r3,TextR2,0);
1037 snprintf(TextR2,TEXTSIZE,"\020\016\002%u:%02u",SafetyStopTime.Minutes,SafetyStopTime.Seconds);
1038 t9_colorscheme_mod(TextR2);
1039 GFX_write_string(&FontT105,&t9r3,TextR2,1);
1040 }
1041
1042 /* tts - option 1
1043 * ndl - option 2
1044 * empty - option 3 */
1045 if(pDecoinfo->output_time_to_surface_seconds)
1046 {
1047 snprintf(TextR3,TEXTSIZE,"\032\f\002%c",TXT_TTS);
1048 GFX_write_string(&FontT24,&t9r4,TextR3,0);
1049 if(pDecoinfo->output_time_to_surface_seconds < 1000 * 60)
1050 snprintf(TextR3,TEXTSIZE,"\020\002%i'",(pDecoinfo->output_time_to_surface_seconds + 30)/ 60);
1051 else
1052 snprintf(TextR3,TEXTSIZE,"\020\002%ih",pDecoinfo->output_time_to_surface_seconds / 3600);
1053 t9_colorscheme_mod(TextR3);
1054 if(time_elapsed_ms(pDecoinfo->tickstamp, HAL_GetTick()) > MAX_AGE_DECOINFO_MS)
1055 TextR2[0] = '\021';
1056 GFX_write_string(&FontT105,&t9r4,TextR3,0);
1057 }
1058 else
1059 if(pDecoinfo->output_ndl_seconds)
1060 {
1061 snprintf(TextR3,TEXTSIZE,"\032\f\002%c",TXT_Nullzeit);
1062 GFX_write_string(&FontT24,&t9r4,TextR3,0);
1063 if(pDecoinfo->output_ndl_seconds < 1000 * 60)
1064 snprintf(TextR3,TEXTSIZE,"\020\002%i'",pDecoinfo->output_ndl_seconds/60);
1065 else
1066 snprintf(TextR3,TEXTSIZE,"\020\002%ih",pDecoinfo->output_ndl_seconds/3600);
1067 t9_colorscheme_mod(TextR3);
1068 if(time_elapsed_ms(pDecoinfo->tickstamp, HAL_GetTick()) > MAX_AGE_DECOINFO_MS)
1069 TextR2[0] = '\021';
1070 GFX_write_string(&FontT105,&t9r4,TextR3,0);
1071 }
1072
1073 uint16_t scooterSpeedLocal;
1074 uint8_t scooterResidualCapacity;
1075
1076 scooterSpeedLocal = unit_speed_integer(stateUsed->lifeData.scooterSpeed);
1077 scooterResidualCapacity = stateUsed_scooterRemainingBattCapacity();
1078
1079 /* scooter global for both */
1080 uint16_t ageInMilliSeconds;
1081 ageInMilliSeconds = stateUsed->lifeData.scooterAgeInMilliSeconds;
1082 if(!ageInMilliSeconds)
1083 ageInMilliSeconds = 9999;
1084
1085 /* scooter battery */
1086 snprintf(TextR1,TEXTSIZE,"\032\f\002%c%c",TXT_2BYTE, TXT2BYTE_ScooterRestkapazitaet);
1087 GFX_write_string(&FontT24,&t9r1,TextR1,0);
1088 snprintf(TextR3,TEXTSIZE,"\020\002%u\016\016%%\017",scooterResidualCapacity);
1089 if(ageInMilliSeconds > 1500)
1090 {
1091 for(int i=0; i < TEXTSIZE -2; i++)
1092 {
1093 if(TextR3[i] == '\020')
1094 TextR3[i] = '\031';
1095 }
1096 }
1097 else
1098 t9_colorscheme_mod(TextR3);
1099 GFX_write_string(&FontT105,&t9r1,TextR3,1);
1100
1101 /* scooter speed */
1102 textlength = snprintf(TextR3,TEXTSIZE-7,"\032\f%c%c",TXT_2BYTE, TXT2BYTE_ScooterSpeed);
1103 if(settingsGetPointer()->nonMetricalSystem == 0)
1104 {
1105 snprintf(&TextR3[textlength],8," m/min");
1106 }
1107 else
1108 {
1109 snprintf(&TextR3[textlength],8," ft/min");
1110 }
1111 GFX_write_string(&FontT24,&t9l1,TextR3,0);
1112 snprintf(TextR3,TEXTSIZE,"\020%u",scooterSpeedLocal);
1113 if(ageInMilliSeconds > 1500)
1114 {
1115 for(int i=0; i < TEXTSIZE -2; i++)
1116 {
1117 if(TextR3[i] == '\020')
1118 TextR3[i] = '\031';
1119 }
1120 }
1121 else
1122 t9_colorscheme_mod(TextR3);
1123 GFX_write_string(&FontT105,&t9l1,TextR3,1);
1124
1125
1126
1127 /* Menu Selection (and gas mix) */
1128 if(get_globalState() == StDMGAS)
1129 {
1130 textPointer = 0;
1131 TextR1[textPointer++] = '\a';
1132 // TextR1[textPointer++] = '\f';
1133 TextR1[textPointer++] = '\001';
1134 TextR1[textPointer++] = ' ';
1135 textPointer += tHome_gas_writer(stateUsed->diveSettings.gas[actualBetterGasId()].oxygen_percentage,stateUsed->diveSettings.gas[actualBetterGasId()].helium_percentage,&TextR1[textPointer]);
1136 TextR1[textPointer++] = '?';
1137 TextR1[textPointer++] = ' ';
1138 TextR1[textPointer++] = 0;
1139 GFX_write_string_color(&FontT48,&t9c2,TextR1,0,CLUT_WarningYellow);
1140 }
1141 else
1142 if(get_globalState() == StDMSPT)
1143 {
1144 textPointer = 0;
1145 TextR1[textPointer++] = '\a';
1146 TextR1[textPointer++] = '\001';
1147 TextR1[textPointer++] = ' ';
1148 textPointer += snprintf(&TextR1[textPointer],5,"%f01.2",((float)(stateUsed->diveSettings.setpoint[actualBetterSetpointId()].setpoint_cbar))/100);
1149 TextR1[textPointer++] = '?';
1150 TextR1[textPointer++] = ' ';
1151 TextR1[textPointer++] = 0;
1152 GFX_write_string_color(&FontT48,&t9c2,TextR1,0,CLUT_WarningYellow);
1153 }
1154 else
1155 if(get_globalState() == StDMENU)
1156 {
1157 snprintf(TextR1,TEXTSIZE,"\a\001%c%c", TXT_2BYTE, TXT2BYTE_DiveMenuQ);
1158 GFX_write_string_color(&FontT48,&t9c2,TextR1,0,CLUT_WarningYellow);
1159 }
1160 else
1161 if(get_globalState() == StDSIM1)
1162 {
1163 snprintf(TextR1,TEXTSIZE,"\a\001%c%c", TXT_2BYTE, TXT2BYTE_DiveQuitQ);
1164 GFX_write_string_color(&FontT48,&t9c2,TextR1,0,CLUT_WarningYellow);
1165 }
1166 else
1167 if(get_globalState() == StDSIM2)
1168 {
1169 snprintf(TextR1,TEXTSIZE,"\a\001" " Sim:-1m ");
1170 GFX_write_string_color(&FontT48,&t9c2,TextR1,0,CLUT_WarningYellow);
1171 snprintf(TextR1,TEXTSIZE,"\a\f %u m",simulation_get_aim_depth());
1172 GFX_write_string_color(&FontT42,&t9l1,TextR1,0,CLUT_WarningYellow);
1173
1174 }
1175 else
1176 if(get_globalState() == StDSIM3)
1177 {
1178 snprintf(TextR1,TEXTSIZE,"\a\001" " Sim:+1m ");
1179 GFX_write_string_color(&FontT48,&t9c2,TextR1,0,CLUT_WarningYellow);
1180 snprintf(TextR1,TEXTSIZE,"\a\f %u m",simulation_get_aim_depth());
1181 GFX_write_string_color(&FontT42,&t9l1,TextR1,0,CLUT_WarningYellow);
1182 }
1183 else
1184 if(get_globalState() == StDSIM4)
1185 {
1186 snprintf(TextR1,TEXTSIZE,"\a\001" " Sim:+5' ");
1187 GFX_write_string_color(&FontT48,&t9c2,TextR1,0,CLUT_WarningYellow);
1188 snprintf(TextR1,TEXTSIZE,"\a\f %u m",simulation_get_aim_depth());
1189 GFX_write_string_color(&FontT42,&t9l1,TextR1,0,CLUT_WarningYellow);
1190 }
1191 else
1192 {
1193 /* gas mix */
1194 oxygen_percentage = 100;
1195 oxygen_percentage -= stateUsed->lifeData.actualGas.nitrogen_percentage;
1196 oxygen_percentage -= stateUsed->lifeData.actualGas.helium_percentage;
1197
1198 textPointer = 0;
1199 TextC2[textPointer++] = '\020';
1200 if(stateUsed->warnings.betterGas && warning_count_high_time)
1201 {
1202 TextC2[textPointer++] = '\a';
1203 }
1204 else
1205 {
1206 float fPpO2limitHigh, fPpO2now;
1207
1208 if(actualLeftMaxDepth(stateUsed))
1209 fPpO2limitHigh = settingsGetPointer()->ppO2_max_deco;
1210 else
1211 fPpO2limitHigh = settingsGetPointer()->ppO2_max_std;
1212
1213 fPpO2now = (stateUsed->lifeData.pressure_ambient_bar - WATER_VAPOUR_PRESSURE) * oxygen_percentage;
1214
1215 if((fPpO2now > fPpO2limitHigh) || (fPpO2now < (float)(settingsGetPointer()->ppO2_min)))
1216 TextC2[textPointer++] = '\025';
1217 }
1218 TextC2[textPointer++] = '\002';
1219 textPointer += tHome_gas_writer(oxygen_percentage,stateUsed->lifeData.actualGas.helium_percentage,&TextC2[textPointer]);
1220
1221 if(stateUsed->warnings.betterGas && warning_count_high_time)
1222 {
1223 if(TextC2[0] == '\020')
1224 {
1225 TextC2[0] = '\004'; // NOP
1226 }
1227 GFX_write_string_color(&FontT48,&t9c2,TextC2,0,CLUT_WarningYellow);
1228 }
1229 else
1230 {
1231 t9_colorscheme_mod(TextC2);
1232 GFX_write_string(&FontT48,&t9c2,TextC2,0); // T54 has only numbers
1233 }
1234
1235 if(stateUsed->diveSettings.ccrOption)
1236 {
1237 if(stateUsed->diveSettings.diveMode == DIVEMODE_CCR)
1238 {
1239 snprintf(TextC2,TEXTSIZE,"\020%01.2f",stateUsed->lifeData.ppO2);
1240 if(stateUsed->warnings.betterSetpoint && warning_count_high_time && (stateUsed->diveSettings.diveMode == DIVEMODE_CCR))
1241 {
1242 TextC2[0] = '\a'; // inverse instead of color \020
1243 GFX_write_string_color(&FontT48,&t9c2,TextC2,0,CLUT_WarningYellow);
1244 }
1245 else
1246 {
1247 t9_colorscheme_mod(TextC2);
1248 GFX_write_string(&FontT48,&t9c2,TextC2,0);
1249 }
1250 }
1251 }
1252 else if(settingsGetPointer()->alwaysShowPPO2)
1253 {
1254 snprintf(TextC2,TEXTSIZE,"\020%01.2f",stateUsed->lifeData.ppO2);
1255 t9_colorscheme_mod(TextC2);
1256 GFX_write_string(&FontT48,&t9c2,TextC2,0);
1257 }
1258 }
1259
1260 /* algorithm, ccr, bailout and battery */
1261 /* and permanent warnings (CNS) */
1262
1263 if((stateUsed->warnings.cnsHigh) && display_count_high_time)
1264 {
1265 TextC2[0] = '\f';
1266 TextC2[1] = TXT_2BYTE;
1267 TextC2[2] = TXT2BYTE_WarnCnsHigh;
1268 TextC2[3] = 0;
1269 GFX_write_string_color(&FontT48,&t9c1,TextC2,0,CLUT_WarningRed);
1270 }
1271 else
1272 {
1273 if(stateUsed->warnings.aGf)
1274 {
1275 GFX_write_string_color(&FontT48,&t9c1,"\f" "aGF",0,CLUT_WarningYellow);
1276 }
1277 else if(stateUsed->diveSettings.deco_type.ub.standard == GF_MODE)
1278 {
1279 GFX_write_string(&FontT48,&t9c1,"\027\f" "GF",0);
1280 }
1281 else
1282 {
1283 GFX_write_string(&FontT48,&t9c1,"\027\f" "VPM",0);
1284 }
1285
1286 if(stateUsed->diveSettings.diveMode == DIVEMODE_CCR)
1287 GFX_write_string(&FontT24,&t9c1,"\027\f\002" "CCR",0);
1288 // GFX_write_string(&FontT24,&t9c1,"\f\177\177\x80" "CCR",0);
1289 else
1290 if(stateUsed->diveSettings.ccrOption)
1291 GFX_write_string(&FontT24,&t9c1,"\f\002\024" "Bailout",0);
1292 // GFX_write_string(&FontT24,&t9c1,"\f\177\177\x80\024" "Bailout",0);
1293 }
1294 TextC1[0] = '\020';
1295 TextC1[1] = '3';
1296 TextC1[2] = '1';
1297 TextC1[3] = '1';
1298 TextC1[4] = '1';
1299 TextC1[5] = '1';
1300 TextC1[6] = '1';
1301 TextC1[7] = '1';
1302 TextC1[8] = '1';
1303 TextC1[9] = '1';
1304 TextC1[10] = '1';
1305 TextC1[11] = '1';
1306 TextC1[12] = '0';
1307 TextC1[13] = 0;
1308
1309 for(int i=1;i<=10;i++)
1310 {
1311 if( stateUsed->lifeData.battery_charge > (9 * i))
1312 TextC1[i+1] += 1;
1313 }
1314
1315 if(stateUsed->warnings.lowBattery)
1316 {
1317 TextC1[0] = '\025';
1318 if(warning_count_high_time)
1319 {
1320 for(int i=2;i<=11;i++)
1321 TextC1[i] = '1';
1322 }
1323 else
1324 {
1325 TextC1[2] = '2';
1326 }
1327 GFX_write_string(&Batt24,&t9batt,TextC1,0);
1328
1329 if((stateUsed->lifeData.battery_charge > 0) && (stateUsed->lifeData.battery_charge < 140))
1330 {
1331 snprintf(TextC1,16,"\004\025\f\002%u%%",(uint8_t)stateUsed->lifeData.battery_charge);
1332 if(warning_count_high_time)
1333 TextC1[0] = '\a';
1334 GFX_write_string(&FontT24,&t9batt,TextC1,0);
1335 }
1336 }
1337 else
1338 {
1339 t9_colorscheme_mod(TextC1);
1340 GFX_write_string(&Batt24,&t9batt,TextC1,0);
1341
1342 if((stateUsed->lifeData.battery_charge > 0) && (stateUsed->lifeData.battery_charge < 140))
1343 {
1344 snprintf(TextC1,16,"\020\f\002%u%%",(uint8_t)stateUsed->lifeData.battery_charge);
1345 t9_colorscheme_mod(TextC1);
1346 GFX_write_string(&FontT24,&t9batt,TextC1,0);
1347 }
1348 }
1349
1350 /* customizable left lower corner */
1351 t9_refresh_divemode_userselected_left_lower_corner();
1352
1353
1354 /* customview - option 1
1355 * warning - option 2 */
1356 if(stateUsed->warnings.numWarnings)
1357 customview_warnings = t9_test_customview_warnings();
1358
1359 t9_background.pointer = NULL;
1360 if(customview_warnings && warning_count_high_time)
1361 t9_show_customview_warnings();
1362 else
1363 t9_refresh_customview();
1364
1365
1366 /* the frame */
1367 t9_draw_frame(1,1, CLUT_DIVE_pluginbox, CLUT_DIVE_FieldSeperatorLines);
1368 }
1369
1370
1371 void t9_set_field_to_primary(void)
1372 {
1373 if(stateUsed->mode == MODE_DIVE)
1374 t9_selection_custom_field = settingsGetPointer()->tX_userselectedLeftLowerCornerPrimary;
1375 }
1376
1377
1378 void t9_change_field(void)
1379 {
1380 const uint8_t minVal = 0;
1381 const uint8_t maxVal = 7;
1382
1383 t9_selection_custom_field++;
1384 if(t9_selection_custom_field > maxVal)
1385 t9_selection_custom_field = minVal;
1386 }
1387
1388
1389 void t9_refresh_divemode_userselected_left_lower_corner(void)
1390 {
1391 // zero is scooter temperature :-)
1392
1393 char headerText[10];
1394 char text[TEXTSIZE];
1395 uint8_t textpointer = 0;
1396 _Bool tinyHeaderFont = 0;
1397 uint8_t line = 0;
1398
1399 SDivetime Stopwatch = {0,0,0,0};
1400 float fAverageDepth, fAverageDepthAbsolute;
1401 const SDecoinfo * pDecoinfoStandard;
1402 const SDecoinfo * pDecoinfoFuture;
1403 float fCNS;
1404
1405 float temperatureThisCall;
1406 float temperature;
1407
1408 float scooterTemperatureLocal;
1409 uint16_t ageInMilliSeconds;
1410
1411 if(stateUsed->diveSettings.deco_type.ub.standard == GF_MODE)
1412 {
1413 pDecoinfoStandard = &stateUsed->decolistBuehlmann;
1414 pDecoinfoFuture = &stateUsed->decolistFutureBuehlmann;
1415 }
1416 else
1417 {
1418 pDecoinfoStandard = &stateUsed->decolistVPM;
1419 pDecoinfoFuture = &stateUsed->decolistFutureVPM;
1420 }
1421
1422 Stopwatch.Total = timer_Stopwatch_GetTime();
1423 Stopwatch.Minutes = Stopwatch.Total / 60;
1424 Stopwatch.Seconds = Stopwatch.Total - ( Stopwatch.Minutes * 60 );
1425 fAverageDepth = timer_Stopwatch_GetAvarageDepth_Meter();
1426 fAverageDepthAbsolute = stateUsed->lifeData.average_depth_meter;
1427
1428 headerText[0] = '\032';
1429 headerText[1] = '\f';
1430
1431 switch(t9_selection_custom_field)
1432 {
1433 /* scooter temp. */
1434 case 0:
1435 scooterTemperatureLocal = unit_temperature_float(((float)(stateUsed->lifeData.scooterTemperature)) / 10.0f);
1436 headerText[2] = TXT_2BYTE;
1437 headerText[3] = TXT2BYTE_ScooterTemperature;
1438 textpointer = snprintf(text,TEXTSIZE,"\020\016%01.1f \140",scooterTemperatureLocal); // "\016\016%01.1f `" + C or F
1439 if(settingsGetPointer()->nonMetricalSystem == 0)
1440 text[textpointer++] = 'C';
1441 else
1442 text[textpointer++] = 'F';
1443 text[textpointer++] = 0;
1444 tinyHeaderFont = 0;
1445 // connection active
1446 ageInMilliSeconds = stateUsed->lifeData.scooterAgeInMilliSeconds;
1447 if(!ageInMilliSeconds)
1448 ageInMilliSeconds = 9999;
1449 if(ageInMilliSeconds > 1500)
1450 {
1451 for(int i=0; i < TEXTSIZE -2; i++)
1452 {
1453 if(text[i] == '\020')
1454 text[i] = '\031';
1455 }
1456 }
1457 break;
1458
1459 /* Temperature */
1460 case 1:
1461 default:
1462 // mean value
1463 temperatureThisCall = unit_temperature_float(stateUsed->lifeData.temperature_celsius);
1464 temperature = (temperatureThisCall + t9_temperatureLastCall[0] + t9_temperatureLastCall[1] + t9_temperatureLastCall[2]) / 4.0f;
1465 idt9_temperatureLastCall++;
1466 if(idt9_temperatureLastCall >= 3)
1467 idt9_temperatureLastCall = 0;
1468 t9_temperatureLastCall[idt9_temperatureLastCall] = temperatureThisCall;
1469 // output
1470 headerText[2] = TXT_Temperature;
1471 textpointer = snprintf(text,TEXTSIZE,"\020\016%01.1f \140",temperature); // "\016\016%01.1f `" + C or F
1472 if(settingsGetPointer()->nonMetricalSystem == 0)
1473 text[textpointer++] = 'C';
1474 else
1475 text[textpointer++] = 'F';
1476 text[textpointer++] = 0;
1477 tinyHeaderFont = 0;
1478 break;
1479
1480 /* Average Depth */
1481 case 2:
1482 headerText[2] = TXT_AvgDepth;
1483 snprintf(text,TEXTSIZE,"\020%01.1f",fAverageDepthAbsolute);
1484 break;
1485
1486 /* ppO2 */
1487 case 3:
1488 headerText[2] = TXT_ppO2;
1489 snprintf(text,TEXTSIZE,"\020%01.2f",stateUsed->lifeData.ppO2);
1490 break;
1491
1492 /* Stop Uhr */
1493 case 4:
1494 headerText[2] = TXT_Stopwatch;
1495 snprintf(text,TEXTSIZE,"\020\016\016%u:%02u\n\r%01.1f",Stopwatch.Minutes, Stopwatch.Seconds,fAverageDepth);
1496 tinyHeaderFont = 1;
1497 line = 1;
1498 break;
1499
1500 /* Ceiling */
1501 case 5:
1502 headerText[2] = TXT_Ceiling;
1503 if(pDecoinfoStandard->output_ceiling_meter <= 99.9f)
1504 snprintf(text,TEXTSIZE,"\020%01.1f",pDecoinfoStandard->output_ceiling_meter);
1505 else
1506 snprintf(text,TEXTSIZE,"\020%01.0f",pDecoinfoStandard->output_ceiling_meter);
1507 break;
1508
1509 /* Future TTS */
1510 case 6:
1511 headerText[2] = TXT_FutureTTS;
1512 snprintf(text,TEXTSIZE,"\020\016\016@+%u'\n\r" "%i' TTS",settingsGetPointer()->future_TTS, pDecoinfoFuture->output_time_to_surface_seconds / 60);
1513 tinyHeaderFont = 1;
1514 line = 1;
1515 break;
1516
1517 /* CNS */
1518 case 7:
1519 headerText[2] = TXT_CNS;
1520 fCNS = stateUsed->lifeData .cns;
1521 if(fCNS > 999)
1522 fCNS = 999;
1523 snprintf(text,TEXTSIZE,"\020%.0f\016\016%%\017",fCNS);
1524 break;
1525
1526 /* scooter voltage*/
1527 case 77: // used as 7: alternative for Bonex
1528 headerText[2] = TXT_2BYTE;
1529 headerText[3] = TXT2BYTE_ScooterVolt;
1530 if(stateUsed->lifeData.scooterSpannung < 99)
1531 {
1532 snprintf(text,TEXTSIZE,"\020\016%01.2f",stateUsed->lifeData.scooterSpannung);
1533 ageInMilliSeconds = stateUsed->lifeData.scooterAgeInMilliSeconds;
1534 if(!ageInMilliSeconds)
1535 ageInMilliSeconds = 9999;
1536 if(ageInMilliSeconds > 1500)
1537 {
1538 for(int i=0; i < TEXTSIZE -2; i++)
1539 {
1540 if(text[i] == '\020')
1541 text[i] = '\031';
1542 }
1543 }
1544 }
1545 else
1546 {
1547 text[0] = 0;
1548 }
1549 break;
1550
1551 }
1552 if(headerText[2] == TXT_2BYTE)
1553 headerText[4] = 0;
1554 else
1555 headerText[3] = 0;
1556
1557 if(!tinyHeaderFont)
1558 GFX_write_string(&FontT24,&t9l4,headerText,0);
1559
1560 t9_colorscheme_mod(text);
1561 GFX_write_string(&FontT105,&t9l4,text,line);
1562 }
1563
1564 /* Private functions ---------------------------------------------------------*/
1565
1566 uint8_t t9_customtextPrepare(char * text)
1567 {
1568 uint8_t i, j, textptr, lineCount;
1569 char nextChar;
1570
1571 textptr = 0;
1572 lineCount = 0;
1573
1574 text[textptr++] = TXT_MINIMAL;
1575
1576 j = 0;
1577 i = 0;
1578 do
1579 {
1580 j += i;
1581 i = 0;
1582 do
1583 {
1584 nextChar = settingsGetPointer()->customtext[i+j];
1585 i++;
1586 if((!nextChar) || (nextChar =='\n') || (nextChar =='\r'))
1587 break;
1588 text[textptr++] = nextChar;
1589 } while (i < 12);
1590
1591 if(!nextChar)
1592 break;
1593
1594 if(lineCount < 3)
1595 {
1596 text[textptr++] = '\n';
1597 text[textptr++] = '\r';
1598 }
1599 lineCount++;
1600 for(uint8_t k=0;k<2;k++)
1601 {
1602 nextChar = settingsGetPointer()->customtext[i+j+k];
1603 if((nextChar =='\n') || (nextChar =='\r'))
1604 i++;
1605 else
1606 break;
1607 }
1608
1609 } while (lineCount < 4);
1610
1611 text[textptr] = 0;
1612 return lineCount;
1613 }
1614
1615 /* could be extended to search for \020 inside
1616 */
1617 void t9_colorscheme_mod(char *text)
1618 {
1619 if((text[0] == '\020') && !GFX_is_colorschemeDiveStandard())
1620 {
1621 text[0] = '\027';
1622 }
1623 }
1624
1625 void t9_draw_frame(_Bool PluginBoxHeader, _Bool LinesOnTheSides, uint8_t colorBox, uint8_t colorLinesOnTheSide)
1626 {
1627 point_t LeftLow, WidthHeight;
1628 point_t start, stop;
1629
1630 // plugin box
1631 LeftLow.x = CUSTOMBOX_LINE_LEFT;
1632 WidthHeight.x = CUSTOMBOX_LINE_RIGHT - CUSTOMBOX_LINE_LEFT;
1633 LeftLow.y = 60;
1634 WidthHeight.y = 440 - LeftLow.y;
1635 GFX_draw_box(&t9screen, LeftLow, WidthHeight, 1, colorBox);
1636
1637 if(PluginBoxHeader)
1638 {
1639 // plugin box - header
1640 start.x = CUSTOMBOX_LINE_LEFT;
1641 stop.x = CUSTOMBOX_LINE_RIGHT;
1642 stop.y = start.y = 440 - 60;
1643 GFX_draw_line(&t9screen, start, stop, colorBox);
1644 }
1645
1646 if(LinesOnTheSides)
1647 {
1648 // aufteilung links
1649 start.x = 0;
1650 stop.x = CUSTOMBOX_LINE_LEFT;
1651 stop.y = start.y = t9l1.WindowY0 - 1;
1652 GFX_draw_line(&t9screen, start, stop, colorLinesOnTheSide);
1653 stop.y = start.y = t9l2.WindowY0 -1;
1654 GFX_draw_line(&t9screen, start, stop, colorLinesOnTheSide);
1655 stop.y = start.y = t9l3.WindowY0 -1;
1656 GFX_draw_line(&t9screen, start, stop, colorLinesOnTheSide);
1657
1658 // aufteilung rechts
1659 start.x = CUSTOMBOX_LINE_RIGHT;
1660 stop.x = 799;
1661 stop.y = start.y = t9l1.WindowY0 - 1;
1662 GFX_draw_line(&t9screen, start, stop, colorLinesOnTheSide);
1663 stop.y = start.y = t9l2.WindowY0 - 1;
1664 GFX_draw_line(&t9screen, start, stop, colorLinesOnTheSide);
1665 stop.y = start.y = t9l3.WindowY0 - 1;
1666 GFX_draw_line(&t9screen, start, stop, colorLinesOnTheSide);
1667 }
1668 }
1669
1670
1671 /* Compass like TCOS shellfish
1672 * input is 0 to 359
1673 * 2 px / 1 degree
1674 * Range is 148 degree with CUSTOMBOX_SPACE_INSIDE = 296
1675 * one side is 74 degree (less than 90 degree)
1676 * internal 360 + 180 degree of freedom
1677 * use positive values only, shift by 360 below 90 mid position
1678 */
1679
1680
1681 point_t t9_compass_circle(uint8_t id, uint16_t degree)
1682 {
1683 float fCos, fSin;
1684 const float piMult = ((2 * 3.14159) / 360);
1685 // const int radius[4] = {95,105,115,60};
1686 const int radius[4] = {95,105,115,100};
1687 const point_t offset = {.x = 400, .y = 250};
1688
1689 static point_t r[4][360] = { 0 };
1690
1691 if(r[0][0].y == 0)
1692 {
1693 for(int i=0;i<360;i++)
1694 {
1695 fCos = cos(i * piMult);
1696 fSin = sin(i * piMult);
1697 for(int j=0;j<4;j++)
1698 {
1699 r[j][i].x = offset.x + (int)(fSin * radius[j]);
1700 r[j][i].y = offset.y + (int)(fCos * radius[j]);
1701 }
1702 }
1703 }
1704 if(id > 3) id = 0;
1705 if(degree > 359) degree = 0;
1706 return r[id][degree];
1707 }
1708
1709 /* range should be 0 to 30 bar if 300 meter with 100% of nitrogen or helium
1710 * T24 is 28 high
1711 */
1712 void t9_tissues(const SDiveState * pState)
1713 {
1714 point_t start, change, stop;
1715 float value;
1716 uint16_t front, cns100pixel;
1717 char text[256];
1718 uint8_t textpointer = 0;
1719 uint8_t color;
1720
1721 float percent_N2;
1722 float percent_He;
1723 float partial_pressure_N2;
1724 float partial_pressure_He;
1725
1726
1727 /* N2 */
1728 t9cY0free.WindowLineSpacing = 28 + 48 + 14;
1729 t9cY0free.WindowY0 = t9cH.WindowY0 - 5 - 2 * t9cY0free.WindowLineSpacing;
1730 t9cY0free.WindowNumberOfTextLines = 3;
1731
1732 text[textpointer++] = '\030';
1733 text[textpointer++] = TXT_2BYTE;
1734 text[textpointer++] = TXT2BYTE_Nitrogen;
1735 text[textpointer++] = '\n';
1736 text[textpointer++] = '\r';
1737 text[textpointer++] = TXT_2BYTE;
1738 text[textpointer++] = TXT2BYTE_Helium;
1739 text[textpointer++] = '\n';
1740 text[textpointer++] = '\r';
1741 text[textpointer++] = TXT_2BYTE;
1742 text[textpointer++] = TXT2BYTE_CNS;
1743 text[textpointer++] = 0;
1744
1745 GFX_write_string(&FontT24, &t9cY0free, text, 1);
1746
1747 start.y = t9cH.WindowY0 - 5;
1748 start.x = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
1749 stop.x = start.x + CUSTOMBOX_SPACE_INSIDE;
1750
1751 for(int i=0;i<16;i++)
1752 {
1753 stop.y = start.y;
1754 change.y = start.y;
1755
1756 value = pState->lifeData.tissue_nitrogen_bar[i] - 0.7512f;
1757 value *= 80;//20
1758
1759 if(value < 0)
1760 front = 0;
1761 else if(value > CUSTOMBOX_SPACE_INSIDE)
1762 front = CUSTOMBOX_SPACE_INSIDE;
1763 else
1764 front = (uint16_t)value;
1765
1766 change.x = start.x + front;
1767 if(change.x != start.x)
1768 GFX_draw_thick_line(1,&t9screen, start, change, CLUT_Font030);
1769 if(change.x != stop.x)
1770 GFX_draw_thick_line(1,&t9screen, change, stop, CLUT_Font031);
1771
1772 start.y -= 3;
1773 }
1774
1775 /* He */
1776 start.y -= 28 + 14;
1777 for(int i=0;i<16;i++)
1778 {
1779 stop.y = start.y;
1780 change.y = start.y;
1781
1782 value = pState->lifeData.tissue_helium_bar[i];
1783 value *= 80;//20
1784
1785 if(value < 0)
1786 front = 0;
1787 else if(value > CUSTOMBOX_SPACE_INSIDE)
1788 front = CUSTOMBOX_SPACE_INSIDE;
1789 else
1790 front = (uint16_t)value;
1791
1792 change.x = start.x + front;
1793 if(change.x != start.x)
1794 GFX_draw_thick_line(1,&t9screen, start, change, CLUT_Font030);
1795 if(change.x != stop.x)
1796 GFX_draw_thick_line(1,&t9screen, change, stop, CLUT_Font031);
1797
1798 start.y -= 3;
1799 }
1800
1801 /* CNS == Oxygen */
1802 start.y -= 28 + 14;
1803
1804 cns100pixel = (8 * CUSTOMBOX_SPACE_INSIDE) / 10;
1805 value = pState->lifeData.cns;
1806 value *= cns100pixel;
1807 value /= 100;
1808
1809 if(value < 0)
1810 front = 0;
1811 else if(value > CUSTOMBOX_SPACE_INSIDE)
1812 front = CUSTOMBOX_SPACE_INSIDE;
1813 else
1814 front = (uint16_t)value;
1815
1816 if(pState->lifeData.cns < 95)
1817 color = CLUT_Font030;
1818 else if(pState->lifeData.cns < 100)
1819 color = CLUT_WarningYellow;
1820 else
1821 color = CLUT_WarningRed;
1822
1823 for(int i=0;i<16;i++)
1824 {
1825 stop.y = start.y;
1826 change.y = start.y;
1827
1828 change.x = start.x + front;
1829 if(change.x != start.x)
1830 GFX_draw_thick_line(1,&t9screen, start, change, color);
1831 if(change.x != stop.x)
1832 GFX_draw_thick_line(1,&t9screen, change, stop, CLUT_Font031);
1833
1834 start.y -= 3;
1835 }
1836
1837 /* where is the onload/offload limit for N2 and He */
1838 decom_get_inert_gases(pState->lifeData.pressure_ambient_bar, &pState->lifeData.actualGas, &percent_N2, &percent_He);
1839 partial_pressure_N2 = (pState->lifeData.pressure_ambient_bar - WATER_VAPOUR_PRESSURE) * percent_N2;
1840 partial_pressure_He = (pState->lifeData.pressure_ambient_bar - WATER_VAPOUR_PRESSURE) * percent_He;
1841
1842 // Nitrogen vertical bar
1843 start.y = t9cH.WindowY0 + 1 - 5;
1844 stop.y = start.y - (3 * 15) - 1;
1845 if((percent_N2 > 0) && (partial_pressure_N2 > 0.8f))//(0.8f + 0.5f)))
1846 {
1847 value = partial_pressure_N2;
1848 value *= 80;//20
1849
1850 if(value < 0)
1851 front = 3;
1852 else if(value + 5 > CUSTOMBOX_SPACE_INSIDE)
1853 front = CUSTOMBOX_SPACE_INSIDE - 3;
1854 else
1855 front = (uint16_t)value;
1856 }
1857 else
1858 {
1859 front = 1;
1860 }
1861 start.x = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET + front;
1862 stop.x = start.x;
1863 GFX_draw_thick_line(2,&t9screen, start, stop, CLUT_EverythingOkayGreen);
1864
1865
1866 // Helium vertical bar
1867 start.y = t9cH.WindowY0 + 1 - 5 - 3*16 - 28 - 14;
1868 stop.y = start.y - (3 * 15) - 1;
1869 if((percent_He > 0) && (partial_pressure_He > 0.01f)) // 0.5f
1870 {
1871
1872 value = partial_pressure_He;
1873 value *= 80;//20
1874
1875 if(value < 0)
1876 front = 3;
1877 else if(value + 5 > CUSTOMBOX_SPACE_INSIDE)
1878 front = CUSTOMBOX_SPACE_INSIDE - 3;
1879 else
1880 front = (uint16_t)value;
1881 }
1882 else
1883 {
1884 front = 1;
1885 }
1886
1887 start.x = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET + front;
1888 stop.x = start.x;
1889 GFX_draw_thick_line(2,&t9screen, start, stop, CLUT_EverythingOkayGreen);
1890
1891 // Oxygen vertical bar
1892 start.y = t9cH.WindowY0 + 1 - 5 - 6*16 - 2*28 - 2*14;
1893 stop.y = start.y - (3 * 15) - 1;
1894
1895 start.x = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET + cns100pixel;
1896 stop.x = start.x;
1897 GFX_draw_thick_line(2, &t9screen, start, stop, CLUT_WarningRed);
1898 }
1899
1900
1901 void t9_debug(void)
1902 {
1903 char text[256+50];
1904 uint8_t textpointer = 0;
1905
1906 t9cY0free.WindowLineSpacing = 28 + 48 + 14;
1907 t9cY0free.WindowY0 = t9cH.WindowY0 - 5 - 2 * t9cY0free.WindowLineSpacing;
1908 t9cY0free.WindowNumberOfTextLines = 3;
1909
1910 textpointer += snprintf(&text[textpointer],50,"Ambient [bar]\n\r");
1911 textpointer += snprintf(&text[textpointer],50,"Surface [bar] + salt\n\r");
1912 // textpointer += snprintf(&text[textpointer],50,"Difference [mbar]\n\r");
1913 textpointer += snprintf(&text[textpointer],50,"ShallowCounter [s]\n\r");
1914 GFX_write_string(&FontT24, &t9cY0free, text, 1);
1915
1916 t9cY0free.WindowY0 -= 52;
1917 // snprintf(text,60,"%0.2f\n\r%0.2f %u%%\n\r%0.0f",stateUsed->lifeData.pressure_ambient_bar, stateUsed->lifeData.pressure_surface_bar, settingsGetPointer()->salinity, 1000 * (stateUsed->lifeData.pressure_ambient_bar-stateUsed->lifeData.pressure_surface_bar));
1918 snprintf(text,60,
1919 "%0.2f\n\r"
1920 "%0.2f %u%%\n\r"
1921 "%u"
1922 ,stateUsed->lifeData.pressure_ambient_bar
1923 ,stateUsed->lifeData.pressure_surface_bar
1924 ,settingsGetPointer()->salinity
1925 ,stateUsed->lifeData.counterSecondsShallowDepth);
1926 GFX_write_string(&FontT42, &t9cY0free, text, 1);
1927 }
1928
1929
1930 void t9_SummaryOfLeftCorner(void)
1931 {
1932 char text[256+60];
1933 uint8_t textpointer = 0;
1934
1935 const SDecoinfo * pDecoinfoStandard;
1936 const SDecoinfo * pDecoinfoFuture;
1937 float fCNS;
1938
1939 if(stateUsed->diveSettings.deco_type.ub.standard == GF_MODE)
1940 {
1941 pDecoinfoStandard = &stateUsed->decolistBuehlmann;
1942 pDecoinfoFuture = &stateUsed->decolistFutureBuehlmann;
1943 }
1944 else
1945 {
1946 pDecoinfoStandard = &stateUsed->decolistVPM;
1947 pDecoinfoFuture = &stateUsed->decolistFutureVPM;
1948 }
1949
1950 fCNS = stateUsed->lifeData .cns;
1951 if(fCNS > 999)
1952 fCNS = 999;
1953
1954 t9cY0free.WindowY0 = t9cC.WindowY0 - 10;
1955 t9cY0free.WindowLineSpacing = 48;
1956 t9cY0free.WindowNumberOfTextLines = 6;
1957 t9cY0free.WindowTab = 420;
1958
1959 // header
1960 textpointer = 0;
1961 text[textpointer++] = '\032';
1962 text[textpointer++] = '\016';
1963 text[textpointer++] = '\016';
1964 text[textpointer++] = TXT_ppO2;
1965 text[textpointer++] = '\n';
1966 text[textpointer++] = '\r';
1967 text[textpointer++] = TXT_Ceiling;
1968 text[textpointer++] = '\n';
1969 text[textpointer++] = '\r';
1970 text[textpointer++] = TXT_ActualGradient;
1971 text[textpointer++] = '\n';
1972 text[textpointer++] = '\r';
1973 text[textpointer++] = TXT_CNS;
1974 text[textpointer++] = '\n';
1975 text[textpointer++] = '\r';
1976 text[textpointer++] = TXT_FutureTTS;
1977 text[textpointer++] = '\n';
1978 text[textpointer++] = '\r';
1979 text[textpointer++] = TXT_2BYTE;
1980 text[textpointer++] = TXT2BYTE_ScooterTemperature;
1981 text[textpointer++] = '\017';
1982 text[textpointer++] = 0;
1983 t9cY0free.WindowX0 += 10;
1984 t9cY0free.WindowY0 += 10;
1985 GFX_write_string(&FontT24, &t9cY0free, text, 1);
1986 t9cY0free.WindowX0 -= 10;
1987 t9cY0free.WindowY0 -= 10;
1988
1989 textpointer = 0;
1990 text[textpointer++] = '\t';
1991 textpointer += snprintf(&text[textpointer],10,"\020%01.2f", stateUsed->lifeData.ppO2);
1992 text[textpointer++] = '\n';
1993 text[textpointer++] = '\r';
1994 text[textpointer++] = '\t';
1995 if(pDecoinfoStandard->output_ceiling_meter <= 99.9f)
1996 textpointer += snprintf(&text[textpointer],10,"\020%01.1f",pDecoinfoStandard->output_ceiling_meter);
1997 else
1998 textpointer += snprintf(&text[textpointer],10,"\020%01.0f",pDecoinfoStandard->output_ceiling_meter);
1999 text[textpointer++] = '\n';
2000 text[textpointer++] = '\r';
2001 text[textpointer++] = '\t';
2002 textpointer += snprintf(&text[textpointer],10,"\020%.0f", 100 * pDecoinfoStandard->output_relative_gradient);
2003 text[textpointer++] = '\n';
2004 text[textpointer++] = '\r';
2005 text[textpointer++] = '\t';
2006 textpointer += snprintf(&text[textpointer],10,"\020%.0f\016\016%%\017",fCNS);
2007 text[textpointer++] = '\n';
2008 text[textpointer++] = '\r';
2009 text[textpointer++] = '\t';
2010 textpointer += snprintf(&text[textpointer],10,"\020%i'", pDecoinfoFuture->output_time_to_surface_seconds / 60);
2011 text[textpointer++] = '\n';
2012 text[textpointer++] = '\r';
2013 text[textpointer++] = '\t';
2014 textpointer += snprintf(&text[textpointer],15,"\020\016%01.0f \140",unit_temperature_float(((float)(stateUsed->lifeData.scooterTemperature)) / 10.0f)); // "\016\016%01.1f `" + C or F
2015 if(settingsGetPointer()->nonMetricalSystem == 0)
2016 text[textpointer++] = 'C';
2017 else
2018 text[textpointer++] = 'F';
2019 text[textpointer++] = 0;
2020 text[textpointer++] = 0;
2021 GFX_write_string(&FontT42, &t9cY0free, text, 1);
2022 }
2023
2024
2025 void t9_scooter(void)
2026 {
2027 float scooterTemperatureLocal;
2028 uint16_t scooterSpeedLocal;
2029 // uint16_t scooterDrehzhl;
2030 uint8_t scooterResidualCapacity;
2031 // float scooterVoltage;
2032 // uint8_t scooterCurrent;
2033 //uint16_t scooterWattHours;
2034 // uint16_t bkpX0, bkpX1;
2035
2036 uint16_t ageInMilliSeconds;
2037 uint8_t textSize;
2038
2039 scooterTemperatureLocal = unit_temperature_float(((float)(stateUsed->lifeData.scooterTemperature)) / 10.0f);
2040 scooterSpeedLocal = unit_speed_integer(stateUsed->lifeData.scooterSpeed);
2041 scooterResidualCapacity = stateUsed_scooterRemainingBattCapacity();
2042
2043 // scooterDrehzhl = stateUsed->lifeData.scooterDrehzahl;
2044 // scooterVoltage = stateUsed->lifeData.scooterSpannung;
2045 // scooterCurrent = stateUsed->lifeData.scooterAmpere;
2046 // scooterWattHours = stateUsed->lifeData.scooterWattstunden;
2047
2048 ageInMilliSeconds = stateUsed->lifeData.scooterAgeInMilliSeconds;
2049 if(!ageInMilliSeconds)
2050 ageInMilliSeconds = 9999;
2051
2052 char text[256+60];
2053 uint8_t textpointer = 0;
2054
2055 t9cY0free.WindowLineSpacing = 28 + 48 + 14;
2056 t9cY0free.WindowY0 = t9cH.WindowY0 - 5 - 2 * t9cY0free.WindowLineSpacing;
2057 t9cY0free.WindowNumberOfTextLines = 3;
2058
2059 // header
2060 text[textpointer++] = '\032';
2061 text[textpointer++] = TXT_2BYTE;
2062 text[textpointer++] = TXT2BYTE_ScooterRestkapazitaet;
2063 text[textpointer++] = '\n';
2064 text[textpointer++] = '\r';
2065 text[textpointer++] = TXT_2BYTE;
2066 text[textpointer++] = TXT2BYTE_ScooterTemperature;
2067 text[textpointer++] = '\n';
2068 text[textpointer++] = '\r';
2069 text[textpointer++] = TXT_2BYTE;
2070 text[textpointer++] = TXT2BYTE_ScooterSpeed;
2071 text[textpointer++] = 0;
2072 GFX_write_string(&FontT24, &t9cY0free, text, 1);
2073
2074 /*
2075 snprintf(text,60,
2076 "\032"
2077 "%0u" "\016\016 Wh used\017"
2078 ,stateUsed->lifeData.scooterWattstunden);
2079 */
2080 if(ageInMilliSeconds > 1500)
2081 text[0] = '\031';
2082 GFX_write_string(&FontT24, &t9cY0free, text, 1);
2083
2084 /*
2085 snprintf(text,60,
2086 "\030"
2087 "\n\r"
2088 "\n\r"
2089 "%0u" "\022\016\016 rpm\017\030"
2090 ,stateUsed->lifeData.scooterDrehzahl);
2091 GFX_write_string(&FontT24, &t9cY0free, text, 1);
2092 */
2093 // data
2094 t9cY0free.WindowY0 -= 52;
2095 if(settingsGetPointer()->nonMetricalSystem == 0)
2096 {
2097 textSize = snprintf(text,60,
2098 "\030"
2099 "%0u" "\022\016\016 %%\017\030"
2100 "\n\r"
2101 "%0.0f\140" "\022\016\016 C\017\030"
2102 "\n\r"
2103 "%u" "\022\016\016 m/min\017\030"
2104 ,scooterResidualCapacity,scooterTemperatureLocal,scooterSpeedLocal);
2105 }
2106 else
2107 {
2108 textSize = snprintf(text,60,
2109 "\030"
2110 "%0u" "\022\016\016 %%\017\030"
2111 "\n\r"
2112 "%0.0f\140" "\022\016\016 Fht\017\030"
2113 "\n\r"
2114 "%u" "\022\016\016 ft/min\017\030"
2115 ,scooterResidualCapacity,scooterTemperatureLocal,scooterSpeedLocal);
2116 }
2117 // connection active
2118 if(ageInMilliSeconds > 1500)
2119 {
2120 for(int i=0; i < textSize -2; i++)
2121 {
2122 if(text[i] == '\030')
2123 text[i] = '\031';
2124 }
2125 }
2126 // write data
2127 GFX_write_string(&FontT42, &t9cY0free, text, 1);
2128
2129 // age stamp
2130 if(ageInMilliSeconds < 9999)
2131 {
2132 t9cY0free.WindowY0 -= 30;
2133 snprintf(text,60,
2134 "\021\001%u"
2135 ,ageInMilliSeconds);
2136 GFX_write_string(&FontT24, &t9cY0free, text, 0);
2137 }
2138 }
2139
2140
2141 void t9_scooter_May2016_01(void)
2142 {
2143 float scooterTemperature;
2144 uint16_t scooterDrehzhl;
2145 uint8_t scooterResidualCapacity;
2146 float scooterSpeed;
2147 float scooterVoltage;
2148 uint8_t scooterCurrent;
2149 // uint16_t scooterWattHours;
2150 uint16_t bkpX0, bkpX1;
2151
2152 uint16_t ageInMilliSeconds;
2153 uint8_t textSize;
2154 // old scooterStatus = bC_getData(0,&scooterTemperature,&scooterDrehzhl,&scooterResidualCapacity);
2155
2156 scooterDrehzhl = stateUsed->lifeData.scooterDrehzahl;
2157 scooterTemperature = ((float)(stateUsed->lifeData.scooterTemperature)) / 10.0f;
2158 scooterResidualCapacity = stateUsed_scooterRemainingBattCapacity();
2159
2160 scooterVoltage = stateUsed->lifeData.scooterSpannung;
2161 scooterCurrent = stateUsed->lifeData.scooterAmpere;
2162 // scooterWattHours = stateUsed->lifeData.scooterWattstunden;
2163
2164 ageInMilliSeconds = stateUsed->lifeData.scooterAgeInMilliSeconds;
2165 if(!ageInMilliSeconds)
2166 ageInMilliSeconds = 9999;
2167
2168 scooterSpeed = scooterDrehzhl * 80 / 3300;
2169
2170 char text[256+60];
2171
2172 t9cY0free.WindowLineSpacing = (28 + 48 + 14)/2;
2173 t9cY0free.WindowY0 = t9cH.WindowY0 - 5 - 5 * t9cY0free.WindowLineSpacing;
2174 t9cY0free.WindowNumberOfTextLines = 6;
2175
2176 t9cY0free.WindowY0 -= 7;
2177
2178 bkpX0 = t9cY0free.WindowX0;
2179 bkpX1 = t9cY0free.WindowX1;
2180 t9cY0free.WindowX0 = 430;
2181
2182 textSize = snprintf(text,120,
2183 "\022\016\016"
2184 "%%"
2185 "\n\r"
2186 "celsius"
2187 "\n\r"
2188 "rpm"
2189 "\n\r"
2190 "m/min"
2191 "\n\r"
2192 "Ampere"
2193 "\n\r"
2194 "Volt"
2195 // "\n\r"
2196 // "Wh"
2197 );
2198 GFX_write_string(&FontT42, &t9cY0free, text, 1);
2199
2200 t9cY0free.WindowX0 = bkpX0;
2201 t9cY0free.WindowX1 = 420;
2202
2203 textSize = snprintf(text,120,
2204 "\030"
2205 "\002"
2206 "%0u"
2207 "\n\r"
2208 "\002"
2209 "%0.0f"
2210 "\n\r"
2211 "\002"
2212 "%0u"
2213 "\n\r"
2214 "\002"
2215 "%0.0f"
2216 "\n\r"
2217 "\002"
2218 "%0u"
2219 "\n\r"
2220 "\002"
2221 "%0.1f"
2222 // "\n\r"
2223 // "%0u" "\022\016\016 Wh\017\030"
2224 ,scooterResidualCapacity,scooterTemperature,scooterDrehzhl,scooterSpeed
2225 ,scooterCurrent,scooterVoltage);//,scooterWattHours);
2226
2227 if((ageInMilliSeconds > 1500) || (stateUsed->lifeData.scooterType == 0xFF))
2228 {
2229 for(int i=0; i < textSize -2; i++)
2230 {
2231 if(text[i] == '\030')
2232 text[i] = '\031';
2233 }
2234 }
2235 GFX_write_string(&FontT42, &t9cY0free, text, 1);
2236
2237 t9cY0free.WindowX0 = bkpX0;
2238 t9cY0free.WindowX1 = bkpX1;
2239
2240 t9cY0free.WindowY0 -= 30;
2241 snprintf(text,60,
2242 "\021\001%u"
2243 ,ageInMilliSeconds);
2244 GFX_write_string(&FontT24, &t9cY0free, text, 0);
2245
2246 }
2247
2248
2249 void t9_compass(uint16_t ActualHeading, uint16_t UserSetHeading)
2250 {
2251 uint16_t LeftBorderHeading, LineHeading;
2252 uint32_t offsetPicture;
2253 point_t start, stop, center;
2254 static int32_t LastHeading = 0;
2255 int32_t newHeading = 0;
2256 int32_t diff = 0;
2257 int32_t diff2 = 0;
2258
2259 int32_t diffAbs = 0;
2260 int32_t diffAbs2 = 0;
2261
2262 newHeading = ActualHeading;
2263
2264 diff = newHeading - LastHeading;
2265
2266 if(newHeading < LastHeading)
2267 diff2 = newHeading + 360 - LastHeading;
2268 else
2269 diff2 = newHeading - 360 - LastHeading;
2270
2271 diffAbs = diff;
2272 if(diffAbs < 0)
2273 diffAbs *= -1;
2274
2275 diffAbs2 = diff2;
2276 if(diffAbs2 < 0)
2277 diffAbs2 *= -1;
2278
2279
2280 if(diffAbs <= diffAbs2)
2281 newHeading = LastHeading + (diff / 2);
2282 else
2283 newHeading = LastHeading + (diff2 / 2);
2284
2285 if(newHeading < 0)
2286 newHeading += 360;
2287 else
2288 if(newHeading >= 360)
2289 newHeading -= 360;
2290
2291 LastHeading = newHeading;
2292 ActualHeading = newHeading;
2293
2294 if (ActualHeading < 90)
2295 ActualHeading += 360;
2296
2297 LeftBorderHeading = 2 * (ActualHeading - (CUSTOMBOX_SPACE_INSIDE/4));
2298
2299 offsetPicture = LeftBorderHeading * t9screenCompass.ImageHeight * 2;
2300
2301 t9_background.pointer = t9screenCompass.FBStartAdress+offsetPicture;
2302 t9_background.x0 = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
2303 t9_background.y0 = 65;
2304 t9_background.width = CUSTOMBOX_SPACE_INSIDE;
2305 t9_background.height = t9screenCompass.ImageHeight;
2306
2307 start.x = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET + (CUSTOMBOX_SPACE_INSIDE/2);
2308 stop.x = start.x;
2309 start.y = 65;
2310 stop.y = start.y + 55;
2311 GFX_draw_line(&t9screen, start, stop, CLUT_Font030);
2312
2313
2314 center.x = start.x;
2315 center.y = 300;
2316
2317 stop.x = center.x + 44;
2318 stop.y = center.y + 24;
2319
2320
2321 while(ActualHeading > 359) ActualHeading -= 360;
2322 LineHeading = 360 - ActualHeading;
2323 GFX_draw_thick_line(9,&t9screen, t9_compass_circle(0,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font030); // North
2324 LineHeading += 90;
2325 if(LineHeading > 359) LineHeading -= 360;
2326 GFX_draw_thick_line(9,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031); // Maintick
2327 LineHeading += 90;
2328 if(LineHeading > 359) LineHeading -= 360;
2329 GFX_draw_thick_line(9,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2330 LineHeading += 90;
2331 if(LineHeading > 359) LineHeading -= 360;
2332 GFX_draw_thick_line(9,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2333
2334 LineHeading = 360 - ActualHeading;
2335 LineHeading += 45;
2336 if(LineHeading > 359) LineHeading -= 360;
2337 GFX_draw_thick_line(5,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031); // Subtick
2338 LineHeading += 90;
2339 if(LineHeading > 359) LineHeading -= 360;
2340 GFX_draw_thick_line(5,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2341 LineHeading += 90;
2342 if(LineHeading > 359) LineHeading -= 360;
2343 GFX_draw_thick_line(5,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2344 LineHeading += 90;
2345 if(LineHeading > 359) LineHeading -= 360;
2346 GFX_draw_thick_line(5,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2347
2348 LineHeading = 360 - ActualHeading;
2349 LineHeading += 22;
2350 if(LineHeading > 359) LineHeading -= 360;
2351 GFX_draw_thick_line(3,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031); // Subtick
2352 LineHeading += 45;
2353 if(LineHeading > 359) LineHeading -= 360;
2354 GFX_draw_thick_line(3,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2355 LineHeading += 45;
2356 if(LineHeading > 359) LineHeading -= 360;
2357 GFX_draw_thick_line(3,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2358 LineHeading += 45;
2359 if(LineHeading > 359) LineHeading -= 360;
2360 GFX_draw_thick_line(3,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2361 LineHeading += 45;
2362 if(LineHeading > 359) LineHeading -= 360;
2363 GFX_draw_thick_line(3,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031); // Subtick
2364 LineHeading += 45;
2365 if(LineHeading > 359) LineHeading -= 360;
2366 GFX_draw_thick_line(3,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2367 LineHeading += 45;
2368 if(LineHeading > 359) LineHeading -= 360;
2369 GFX_draw_thick_line(3,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2370 LineHeading += 45;
2371 if(LineHeading > 359) LineHeading -= 360;
2372 GFX_draw_thick_line(3,&t9screen, t9_compass_circle(1,LineHeading), t9_compass_circle(2,LineHeading), CLUT_Font031);
2373
2374 if(UserSetHeading)
2375 {
2376 LineHeading = UserSetHeading + 360 - ActualHeading;
2377 if(LineHeading > 359) LineHeading -= 360;
2378 GFX_draw_thick_line(9,&t9screen, t9_compass_circle(3,LineHeading), t9_compass_circle(2,LineHeading), CLUT_CompassUserHeadingTick);
2379
2380 // R�ckpeilung, User Back Heading
2381 LineHeading = UserSetHeading + 360 + 180 - ActualHeading;
2382 if(LineHeading > 359) LineHeading -= 360;
2383 if(LineHeading > 359) LineHeading -= 360;
2384 GFX_draw_thick_line(9,&t9screen, t9_compass_circle(3,LineHeading), t9_compass_circle(2,LineHeading), CLUT_CompassUserBackHeadingTick);
2385 }
2386
2387 center.x = start.x;
2388 center.y = 250;
2389 GFX_draw_circle(&t9screen, center, 116, CLUT_Font030);
2390 GFX_draw_circle(&t9screen, center, 118, CLUT_Font030);
2391 GFX_draw_circle(&t9screen, center, 117, CLUT_Font030);
2392 }
2393
2394
2395 void init_t9_compass(void)
2396 {
2397 t9screenCompass.FBStartAdress = getFrame(26);
2398
2399 char text[256];
2400 uint8_t textpointer = 0;
2401
2402 text[textpointer++] = '\030';
2403 text[textpointer++] = '\177';
2404 text[textpointer++] = '\177';
2405 text[textpointer++] = 76; // 90 - 14
2406 text[textpointer++] = '\016';
2407 text[textpointer++] = '\016';
2408 text[textpointer++] = 'N';
2409 text[textpointer++] = 'E'; // 96 + 28 = 124 total
2410 text[textpointer++] = '\017';
2411 text[textpointer++] = '\177';
2412 text[textpointer++] = '\177';
2413 text[textpointer++] = 64; // 90 - 14 - 12
2414 text[textpointer++] = 'E'; // 124 + 74 + 23 = 221 total
2415 text[textpointer++] = '\177';
2416 text[textpointer++] = '\177';
2417 text[textpointer++] = 66; // 90 - 11 - 13
2418 text[textpointer++] = '\016';
2419 text[textpointer++] = '\016';
2420 text[textpointer++] = 'S';
2421 text[textpointer++] = 'E';
2422 text[textpointer++] = '\017';
2423 text[textpointer++] = '\177';
2424 text[textpointer++] = '\177';
2425 text[textpointer++] = 68; // 90 - 12 - 10
2426 text[textpointer++] = 'S';
2427 text[textpointer++] = '\177';
2428 text[textpointer++] = '\177';
2429 text[textpointer++] = 64; // 90 - 10 - 16
2430 text[textpointer++] = '\016';
2431 text[textpointer++] = '\016';
2432 text[textpointer++] = 'S';
2433 text[textpointer++] = 'W';
2434 text[textpointer++] = '\017';
2435 text[textpointer++] = '\177';
2436 text[textpointer++] = '\177';
2437 text[textpointer++] = 56; // 90 - 16 - 18
2438 text[textpointer++] = 'W';
2439 text[textpointer++] = '\177';
2440 text[textpointer++] = '\177';
2441 text[textpointer++] = 54; // 90 - 18 - 18
2442 text[textpointer++] = '\016';
2443 text[textpointer++] = '\016';
2444 text[textpointer++] = 'N';
2445 text[textpointer++] = 'W';
2446 text[textpointer++] = '\017';
2447 text[textpointer++] = '\177';
2448 text[textpointer++] = '\177';
2449 text[textpointer++] = 59; // 90 - 17 - 14
2450 text[textpointer++] = 'N';
2451 text[textpointer++] = '\177';
2452 text[textpointer++] = '\177';
2453 text[textpointer++] = 63; // 90 - 13 - 14
2454 text[textpointer++] = '\016';
2455 text[textpointer++] = '\016';
2456 text[textpointer++] = 'N';
2457 text[textpointer++] = 'E';
2458 text[textpointer++] = '\017';
2459 text[textpointer++] = '\177';
2460 text[textpointer++] = '\177';
2461 text[textpointer++] = 64; // 90 - 14 - 12
2462 text[textpointer++] = 'E';
2463 text[textpointer++] = '\177';
2464 text[textpointer++] = '\177';
2465 text[textpointer++] = 66; // 90 - 11 - 13
2466 text[textpointer++] = '\016';
2467 text[textpointer++] = '\016';
2468 text[textpointer++] = 'S';
2469 text[textpointer++] = 'E';
2470 text[textpointer++] = '\017';
2471 text[textpointer++] = '\177';
2472 text[textpointer++] = '\177';
2473 text[textpointer++] = 68; // 90 - 12 - 10
2474 text[textpointer++] = 'S';
2475 text[textpointer++] = '\177';
2476 text[textpointer++] = '\177';
2477 text[textpointer++] = 64; // 90 - 10 - 16
2478 text[textpointer++] = '\016';
2479 text[textpointer++] = '\016';
2480 text[textpointer++] = 'S';
2481 text[textpointer++] = 'W';
2482 text[textpointer++] = '\017';
2483 text[textpointer++] = 0; // end
2484
2485 GFX_write_string(&FontT42,&t9pCompass,text,1);
2486
2487 releaseAllFramesExcept(26,t9screenCompass.FBStartAdress);
2488 }
2489
2490
2491 void t9_miniLiveLogProfile(void)
2492 {
2493 SWindowGimpStyle wintemp;
2494 wintemp.left = CUSTOMBOX_LINE_LEFT + CUSTOMBOX_INSIDE_OFFSET;
2495 wintemp.right = wintemp.left + CUSTOMBOX_SPACE_INSIDE;
2496 wintemp.top = 480 - t9l1.WindowY0;
2497 wintemp.bottom = wintemp. top + 200;
2498
2499 uint16_t max_depth = (uint16_t)(stateUsed->lifeData.max_depth_meter * 10);
2500
2501 GFX_graph_print(&t9screen, &wintemp, 0,1,0, max_depth, getMiniLiveLogbookPointerToData(), getMiniLiveLogbookActualDataLength(), CLUT_Font030, NULL);
2502 }
2503