diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/clock.c | 748 |
1 files changed, 748 insertions, 0 deletions
diff --git a/apps/plugins/clock.c b/apps/plugins/clock.c new file mode 100644 index 0000000000..64cf8a56f1 --- /dev/null +++ b/apps/plugins/clock.c | |||
@@ -0,0 +1,748 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: clock.c,v 1.0 2003/12/8 | ||
9 | * | ||
10 | * Copyright (C) 2003 Zakk Roberts | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "plugin.h" | ||
20 | #include "time.h" | ||
21 | |||
22 | #ifdef HAVE_LCD_BITMAP | ||
23 | |||
24 | void draw_7seg_time(int hour, int minute, int x, int y, int width, int height, | ||
25 | bool colon); | ||
26 | void loadSettings(void); | ||
27 | |||
28 | static struct plugin_api* rb; | ||
29 | |||
30 | /* Used for hands to define lengths at a given time */ | ||
31 | static unsigned char yhour[] = { | ||
32 | 47,47,46,46,46,45,44,43,42,41,39,38,36,35,33,32,31,29,28,26,25,23,22,21,20,19,18,18,18,17,17,17,18,18,18,19,20,21,22,23,25,26,28,29,31,32,33,35,36,38,39,41,42,43,44,45,46,46,46,47, | ||
33 | }; | ||
34 | static unsigned char yminute[] = { | ||
35 | 55,54,54,53,53,51,50,49,47,45,43,41,39,36,34,32,30,28,25,23,21,19,17,15,14,13,11,11,10,10,9,10,10,11,11,13,14,15,17,19,21,23,25,28,30,32,34,36,39,41,43,45,47,49,50,51,53,53,54,54, | ||
36 | }; | ||
37 | static unsigned char xhour[] = { | ||
38 | 56,58,59,61,63,65,67,68,70,71,72,73,74,74,75,75,75,74,74,73,72,71,70,68,67,65,63,61,59,58,56,54,53,51,49,47,45,44,42,41,40,39,38,38,37,37,37,38,38,39,40,41,42,44,45,47,49,51,53,54, | ||
39 | }; | ||
40 | static unsigned char xminute[] = { | ||
41 | 56,59,61,64,67,70,72,75,77,79,80,82,83,84,84,84,84,84,83,82,80,79,77,75,72,70,67,64,61,59,56,53,51,48,45,42,40,37,35,33,32,30,29,28,28,28,28,28,29,30,32,33,35,37,40,42,45,48,51,53, | ||
42 | }; | ||
43 | |||
44 | static char default_filename[] = "/.rockbox/rocks/.clock_settings"; | ||
45 | |||
46 | struct saved_settings | ||
47 | { | ||
48 | bool is_date_displayed; | ||
49 | bool are_digits_displayed; | ||
50 | bool is_time_displayed; | ||
51 | bool is_rect_displayed; | ||
52 | bool analog_clock; | ||
53 | } settings; | ||
54 | |||
55 | |||
56 | void save_settings(void) | ||
57 | { | ||
58 | int fd; | ||
59 | |||
60 | fd = rb->creat(default_filename, O_WRONLY); | ||
61 | if(fd >= 0) | ||
62 | { | ||
63 | rb->write (fd, &settings, sizeof(struct saved_settings)); | ||
64 | rb->close(fd); | ||
65 | } | ||
66 | else | ||
67 | { | ||
68 | rb->splash(HZ, 0, true, "Setting save failed"); | ||
69 | } | ||
70 | } | ||
71 | |||
72 | void load_settings(void) | ||
73 | { | ||
74 | int fd; | ||
75 | fd = rb->open(default_filename, O_RDONLY); | ||
76 | |||
77 | /* if file exists, then load. */ | ||
78 | if(fd >= 0) | ||
79 | { | ||
80 | rb->read (fd, &settings, sizeof(struct saved_settings)); | ||
81 | rb->close(fd); | ||
82 | } | ||
83 | /* Else, loading failed */ | ||
84 | else | ||
85 | { | ||
86 | rb->splash(HZ, 0, true, "Setting load failed, using default settings."); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
91 | { | ||
92 | /* time ints */ | ||
93 | int i; | ||
94 | int hour; | ||
95 | int minute; | ||
96 | int second; | ||
97 | int last_second = -1; | ||
98 | int pos = 0; | ||
99 | |||
100 | /* date ints */ | ||
101 | int year; | ||
102 | int day; | ||
103 | int month; | ||
104 | |||
105 | char moday[6]; | ||
106 | char dateyr[5]; | ||
107 | char tmhrmin[5]; | ||
108 | char tmsec[2]; | ||
109 | char current_date[12]; | ||
110 | |||
111 | struct tm* current_time; | ||
112 | |||
113 | TEST_PLUGIN_API(api); | ||
114 | (void)parameter; | ||
115 | rb = api; | ||
116 | |||
117 | /* load settings from disk */ | ||
118 | load_settings(); | ||
119 | |||
120 | rb->lcd_clear_display(); | ||
121 | rb->splash(HZ, 0, true, "F1 for INFO"); | ||
122 | |||
123 | while (!PLUGIN_OK) | ||
124 | { | ||
125 | /* universal font for better display */ | ||
126 | rb->lcd_setfont(FONT_SYSFIXED); | ||
127 | |||
128 | /* start all the clock stuff */ | ||
129 | |||
130 | bool exit = false; | ||
131 | bool used = false; | ||
132 | |||
133 | /* Time info */ | ||
134 | current_time = rb->get_time(); | ||
135 | hour = current_time->tm_hour; | ||
136 | minute = current_time->tm_min; | ||
137 | second = current_time->tm_sec; | ||
138 | |||
139 | /* Date info */ | ||
140 | year = current_time->tm_year+1900; | ||
141 | day = current_time->tm_mday; | ||
142 | month = current_time->tm_mon+1; | ||
143 | |||
144 | if(second != last_second) | ||
145 | { | ||
146 | rb->lcd_clear_display(); | ||
147 | |||
148 | rb->snprintf( moday, 5, "%d/%d", month, day ); | ||
149 | rb->snprintf( dateyr, 4, "%d", year ); | ||
150 | rb->snprintf( tmhrmin, 5, "%02d:%02d", hour, minute ); | ||
151 | rb->snprintf( tmsec, 2, "%02d", second ); | ||
152 | rb->snprintf( current_date, 12, "%d/%d/%d", month, day, year ); | ||
153 | |||
154 | if(settings.analog_clock) | ||
155 | { | ||
156 | /* Now draw the analog clock */ | ||
157 | pos = 90-second; | ||
158 | if(pos >= 60) | ||
159 | pos -= 60; | ||
160 | |||
161 | /* Second hand */ | ||
162 | rb->lcd_drawline((LCD_WIDTH/2), (LCD_HEIGHT/2), | ||
163 | xminute[pos], yminute[pos]); | ||
164 | |||
165 | pos = 90-minute; | ||
166 | if(pos >= 60) | ||
167 | pos -= 60; | ||
168 | |||
169 | /* Minute hand, thicker than the second hand */ | ||
170 | rb->lcd_drawline(LCD_WIDTH/2, LCD_HEIGHT/2, | ||
171 | xminute[pos], yminute[pos]); | ||
172 | rb->lcd_drawline(LCD_WIDTH/2-1, LCD_HEIGHT/2-1, | ||
173 | xminute[pos], yminute[pos]); | ||
174 | rb->lcd_drawline(LCD_WIDTH/2+1, LCD_HEIGHT/2+1, | ||
175 | xminute[pos], yminute[pos]); | ||
176 | rb->lcd_drawline(LCD_WIDTH/2-1, LCD_HEIGHT/2+1, | ||
177 | xminute[pos], yminute[pos]); | ||
178 | rb->lcd_drawline(LCD_WIDTH/2+1, LCD_HEIGHT/2-1, | ||
179 | xminute[pos], yminute[pos]); | ||
180 | |||
181 | if(hour > 12) | ||
182 | hour -= 12; | ||
183 | |||
184 | hour = hour*5 + minute/12;; | ||
185 | pos = 90-hour; | ||
186 | if(pos >= 60) | ||
187 | pos -= 60; | ||
188 | |||
189 | /* Hour hand, thick as the minute hand but shorter */ | ||
190 | rb->lcd_drawline(LCD_WIDTH/2, LCD_HEIGHT/2, xhour[pos], yhour[pos]); | ||
191 | rb->lcd_drawline(LCD_WIDTH/2-1, LCD_HEIGHT/2-1, | ||
192 | xhour[pos], yhour[pos]); | ||
193 | rb->lcd_drawline(LCD_WIDTH/2+1, LCD_HEIGHT/2+1, | ||
194 | xhour[pos], yhour[pos]); | ||
195 | rb->lcd_drawline(LCD_WIDTH/2-1, LCD_HEIGHT/2+1, | ||
196 | xhour[pos], yhour[pos]); | ||
197 | rb->lcd_drawline(LCD_WIDTH/2+1, LCD_HEIGHT/2-1, | ||
198 | xhour[pos], yhour[pos]); | ||
199 | |||
200 | /* Draw the circle */ | ||
201 | for(i=0; i < 60; i+=5) | ||
202 | { | ||
203 | rb->lcd_drawpixel(xminute[i], | ||
204 | yminute[i]); | ||
205 | rb->lcd_drawrect(xminute[i]-1, | ||
206 | yminute[i]-1, | ||
207 | 3, 3); | ||
208 | } | ||
209 | |||
210 | /* Draw the cover over the center */ | ||
211 | rb->lcd_drawline((LCD_WIDTH/2)-1, (LCD_HEIGHT/2)+3, | ||
212 | (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)+3); | ||
213 | rb->lcd_drawline((LCD_WIDTH/2)-3, (LCD_HEIGHT/2)+2, | ||
214 | (LCD_WIDTH/2)+3, (LCD_HEIGHT/2)+2); | ||
215 | rb->lcd_drawline((LCD_WIDTH/2)-4, (LCD_HEIGHT/2)+1, | ||
216 | (LCD_WIDTH/2)+4, (LCD_HEIGHT/2)+1); | ||
217 | rb->lcd_drawline((LCD_WIDTH/2)-4, LCD_HEIGHT/2, | ||
218 | (LCD_WIDTH/2)+4, LCD_HEIGHT/2); | ||
219 | rb->lcd_drawline((LCD_WIDTH/2)-4, (LCD_HEIGHT/2)-1, | ||
220 | (LCD_WIDTH/2)+4, (LCD_HEIGHT/2)-1); | ||
221 | rb->lcd_drawline((LCD_WIDTH/2)-3, (LCD_HEIGHT/2)-2, | ||
222 | (LCD_WIDTH/2)+3, (LCD_HEIGHT/2)-2); | ||
223 | rb->lcd_drawline((LCD_WIDTH/2)-1, (LCD_HEIGHT/2)-3, | ||
224 | (LCD_WIDTH/2)+1, (LCD_HEIGHT/2)-3); | ||
225 | rb->lcd_drawpixel(LCD_WIDTH/2, LCD_HEIGHT/2); | ||
226 | |||
227 | /* Draw the digits around the clock */ | ||
228 | if (settings.are_digits_displayed) | ||
229 | { | ||
230 | rb->lcd_putsxy((LCD_WIDTH/2)-6, 1, "12"); | ||
231 | rb->lcd_putsxy(20, (LCD_HEIGHT/2)-4, "9"); | ||
232 | rb->lcd_putsxy((LCD_WIDTH/2)-4, 56, "6"); | ||
233 | rb->lcd_putsxy(86, (LCD_HEIGHT/2)-4, "3"); | ||
234 | } | ||
235 | |||
236 | /* Draw digital readout */ | ||
237 | if (settings.is_time_displayed) | ||
238 | { | ||
239 | /* HH:MM */ | ||
240 | rb->lcd_putsxy(1, 4, tmhrmin); | ||
241 | /* SS */ | ||
242 | rb->lcd_putsxy(10, 12, tmsec); | ||
243 | } | ||
244 | } | ||
245 | else | ||
246 | { | ||
247 | draw_7seg_time(hour, minute, 8, 16, 16, 32, second & 1); | ||
248 | } | ||
249 | |||
250 | /* Draw the border */ | ||
251 | if (settings.is_rect_displayed) | ||
252 | { | ||
253 | rb->lcd_drawrect(0, 0, 112, 64); | ||
254 | |||
255 | /* top left corner */ | ||
256 | rb->lcd_drawpixel(1, 1); | ||
257 | rb->lcd_drawpixel(2, 2); | ||
258 | rb->lcd_drawpixel(1, 2); | ||
259 | rb->lcd_drawpixel(1, 3); | ||
260 | rb->lcd_drawpixel(2, 1); | ||
261 | rb->lcd_drawpixel(3, 1); | ||
262 | |||
263 | /* bottom left corner */ | ||
264 | rb->lcd_drawpixel(1, 62); | ||
265 | rb->lcd_drawpixel(2, 61); | ||
266 | rb->lcd_drawpixel(1, 61); | ||
267 | rb->lcd_drawpixel(1, 60); | ||
268 | rb->lcd_drawpixel(2, 62); | ||
269 | rb->lcd_drawpixel(3, 62); | ||
270 | |||
271 | /* top right corner */ | ||
272 | rb->lcd_drawpixel(110, 1); | ||
273 | rb->lcd_drawpixel(109, 2); | ||
274 | rb->lcd_drawpixel(110, 2); | ||
275 | rb->lcd_drawpixel(110, 3); | ||
276 | rb->lcd_drawpixel(109, 1); | ||
277 | rb->lcd_drawpixel(108, 1); | ||
278 | |||
279 | /* bottom right corner */ | ||
280 | rb->lcd_drawpixel(110, 62); | ||
281 | rb->lcd_drawpixel(109, 61); | ||
282 | rb->lcd_drawpixel(110, 61); | ||
283 | rb->lcd_drawpixel(110, 60); | ||
284 | rb->lcd_drawpixel(109, 62); | ||
285 | rb->lcd_drawpixel(108, 62); | ||
286 | } | ||
287 | |||
288 | /* Draw the date */ | ||
289 | if (settings.is_date_displayed) | ||
290 | { | ||
291 | if(settings.analog_clock) | ||
292 | { | ||
293 | rb->lcd_putsxy(3, 53, moday); | ||
294 | rb->lcd_putsxy(80, 53, dateyr); | ||
295 | } | ||
296 | else | ||
297 | rb->lcd_putsxy(25, 3, current_date); | ||
298 | } | ||
299 | |||
300 | if (settings.is_time_displayed) | ||
301 | { | ||
302 | if(settings.analog_clock) | ||
303 | { | ||
304 | /* HH:MM */ | ||
305 | rb->lcd_putsxy(1, 4, tmhrmin); | ||
306 | /* SS */ | ||
307 | rb->lcd_putsxy(10, 12, tmsec); | ||
308 | } | ||
309 | else | ||
310 | { | ||
311 | /* Just seconds */ | ||
312 | rb->lcd_putsxy(50, 55, tmsec); | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* Draw all to LCD */ | ||
317 | rb->lcd_update(); | ||
318 | } | ||
319 | |||
320 | switch (rb->button_get_w_tmo(HZ/6)) | ||
321 | { | ||
322 | /* OFF exits */ | ||
323 | case BUTTON_OFF: | ||
324 | |||
325 | /* Tell the user what's going on */ | ||
326 | rb->lcd_clear_display(); | ||
327 | rb->splash(HZ/2, 0, true, "Saving settings..."); | ||
328 | /* Save to disk */ | ||
329 | save_settings(); | ||
330 | rb->lcd_clear_display(); | ||
331 | rb->splash(HZ, 0, true, "Saved!"); | ||
332 | /* ...and exit. */ | ||
333 | return PLUGIN_OK; | ||
334 | break; | ||
335 | |||
336 | /* F1 & OFF exits without saving */ | ||
337 | case BUTTON_F1 | BUTTON_OFF: | ||
338 | return PLUGIN_OK; | ||
339 | break; | ||
340 | |||
341 | /* F1 screen - plugin info */ | ||
342 | case BUTTON_F1: | ||
343 | while (!exit) | ||
344 | { | ||
345 | if(settings.analog_clock) | ||
346 | { | ||
347 | rb->lcd_clear_display(); | ||
348 | rb->lcd_puts(0, 0, "F1 > Help"); | ||
349 | rb->lcd_puts(0, 1, "PLAY > Digital"); | ||
350 | rb->lcd_puts(0, 2, "FF > Show Time"); | ||
351 | rb->lcd_puts(0, 3, "DOWN > Border"); | ||
352 | rb->lcd_puts(0, 4, "REW > Digits"); | ||
353 | rb->lcd_puts(0, 5, "UP > Date"); | ||
354 | rb->lcd_puts(0, 6, "OFF > Save & Exit"); | ||
355 | rb->lcd_update(); | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | rb->lcd_clear_display(); | ||
360 | rb->lcd_puts(0, 0, "F1 > Help"); | ||
361 | rb->lcd_puts(0, 1, "PLAY > Analog"); | ||
362 | rb->lcd_puts(0, 3, "DOWN > Border"); | ||
363 | rb->lcd_puts(0, 4, "UP > Date"); | ||
364 | rb->lcd_puts(0, 5, "FF > Show Seconds"); | ||
365 | rb->lcd_puts(0, 7, "OFF > Save & Exit"); | ||
366 | rb->lcd_update(); | ||
367 | } | ||
368 | |||
369 | switch (rb->button_get(true)) | ||
370 | { | ||
371 | case BUTTON_F1 | BUTTON_REL: | ||
372 | if (used) | ||
373 | exit = true; | ||
374 | used = true; | ||
375 | break; | ||
376 | |||
377 | case BUTTON_OFF: | ||
378 | used = true; | ||
379 | break; | ||
380 | |||
381 | case SYS_USB_CONNECTED: | ||
382 | return PLUGIN_USB_CONNECTED; | ||
383 | rb->usb_screen(); | ||
384 | break; | ||
385 | } | ||
386 | } | ||
387 | break; | ||
388 | |||
389 | /* options screen */ | ||
390 | case BUTTON_F3: | ||
391 | while (!exit) | ||
392 | { | ||
393 | if(settings.analog_clock) | ||
394 | { | ||
395 | rb->lcd_clear_display(); | ||
396 | rb->lcd_putsxy(7, 0, "FF > Show Time"); | ||
397 | rb->lcd_putsxy(7, 10, "DOWN> Show Frame"); | ||
398 | rb->lcd_putsxy(7, 20, "UP > Show Date"); | ||
399 | rb->lcd_putsxy(7, 30, "REW > Show Digits"); | ||
400 | |||
401 | rb->lcd_putsxy(15, 46, "OFF > All OFF"); | ||
402 | rb->lcd_putsxy(17, 56, "ON > All ON"); | ||
403 | |||
404 | rb->lcd_drawline(0, 41, 112, 41); | ||
405 | |||
406 | /* draw checkmarks */ | ||
407 | if(settings.is_time_displayed) | ||
408 | { | ||
409 | rb->lcd_drawline(0, 4, 3, 7); | ||
410 | rb->lcd_drawline(3, 7, 5, 0); | ||
411 | } | ||
412 | if(settings.is_rect_displayed) | ||
413 | { | ||
414 | rb->lcd_drawline(0, 14, 3, 17); | ||
415 | rb->lcd_drawline(3, 17, 5, 10); | ||
416 | } | ||
417 | if(settings.is_date_displayed) | ||
418 | { | ||
419 | rb->lcd_drawline(0, 24, 3, 27); | ||
420 | rb->lcd_drawline(3, 27, 5, 20); | ||
421 | } | ||
422 | if(settings.are_digits_displayed) | ||
423 | { | ||
424 | rb->lcd_drawline(0, 34, 3, 37); | ||
425 | rb->lcd_drawline(3, 37, 5, 30); | ||
426 | } | ||
427 | |||
428 | /* update the LCD after all this madness */ | ||
429 | rb->lcd_update(); | ||
430 | |||
431 | /* ... and finally, setting options from screen: */ | ||
432 | switch (rb->button_get(true)) | ||
433 | { | ||
434 | case BUTTON_F3 | BUTTON_REL: | ||
435 | if (used) | ||
436 | exit = true; | ||
437 | used = true; | ||
438 | break; | ||
439 | |||
440 | case BUTTON_RIGHT: | ||
441 | settings.is_time_displayed = | ||
442 | !settings.is_time_displayed; | ||
443 | break; | ||
444 | |||
445 | case BUTTON_DOWN: | ||
446 | settings.is_rect_displayed = | ||
447 | !settings.is_rect_displayed; | ||
448 | break; | ||
449 | |||
450 | case BUTTON_UP: | ||
451 | settings.is_date_displayed = | ||
452 | !settings.is_date_displayed; | ||
453 | break; | ||
454 | |||
455 | case BUTTON_LEFT: | ||
456 | settings.are_digits_displayed = | ||
457 | !settings.are_digits_displayed; | ||
458 | break; | ||
459 | |||
460 | case BUTTON_ON: | ||
461 | settings.is_time_displayed = true; | ||
462 | settings.is_rect_displayed = true; | ||
463 | settings.is_date_displayed = true; | ||
464 | settings.are_digits_displayed = true; | ||
465 | break; | ||
466 | |||
467 | case BUTTON_OFF: | ||
468 | settings.is_time_displayed = false; | ||
469 | settings.is_rect_displayed = false; | ||
470 | settings.is_date_displayed = false; | ||
471 | settings.are_digits_displayed = false; | ||
472 | break; | ||
473 | |||
474 | case SYS_USB_CONNECTED: | ||
475 | return PLUGIN_USB_CONNECTED; | ||
476 | rb->usb_screen(); | ||
477 | break; | ||
478 | } | ||
479 | } | ||
480 | else /* 7-Segment clock shown, less options */ | ||
481 | { | ||
482 | rb->lcd_clear_display(); | ||
483 | rb->lcd_putsxy(7, 0, "DOWN> Show Frame"); | ||
484 | rb->lcd_putsxy(7, 10, "UP > Show Date"); | ||
485 | rb->lcd_putsxy(7, 20, "FF > Seconds"); | ||
486 | rb->lcd_putsxy(15, 46, "OFF > All OFF"); | ||
487 | rb->lcd_putsxy(17, 56, "ON > All ON"); | ||
488 | rb->lcd_drawline(0, 41, 112, 41); | ||
489 | |||
490 | /* draw checkmarks */ | ||
491 | if(settings.is_rect_displayed) | ||
492 | { | ||
493 | rb->lcd_drawline(0, 4, 3, 7); | ||
494 | rb->lcd_drawline(3, 7, 5, 0); | ||
495 | } | ||
496 | if(settings.is_date_displayed) | ||
497 | { | ||
498 | rb->lcd_drawline(0, 14, 3, 17); | ||
499 | rb->lcd_drawline(3, 17, 5, 10); | ||
500 | } | ||
501 | if(settings.is_time_displayed) | ||
502 | { | ||
503 | rb->lcd_drawline(0, 24, 3, 27); | ||
504 | rb->lcd_drawline(3, 27, 5, 20); | ||
505 | } | ||
506 | |||
507 | /* And finally, update the LCD */ | ||
508 | rb->lcd_update(); | ||
509 | |||
510 | switch (rb->button_get(true)) | ||
511 | { | ||
512 | case BUTTON_F3 | BUTTON_REL: | ||
513 | if (used) | ||
514 | exit = true; | ||
515 | used = true; | ||
516 | break; | ||
517 | |||
518 | case BUTTON_DOWN: | ||
519 | settings.is_rect_displayed = | ||
520 | !settings.is_rect_displayed; | ||
521 | break; | ||
522 | |||
523 | case BUTTON_UP: | ||
524 | settings.is_date_displayed = | ||
525 | !settings.is_date_displayed; | ||
526 | break; | ||
527 | |||
528 | case BUTTON_RIGHT: | ||
529 | settings.is_time_displayed = | ||
530 | !settings.is_time_displayed; | ||
531 | break; | ||
532 | |||
533 | case BUTTON_ON: | ||
534 | settings.is_time_displayed = true; | ||
535 | settings.is_rect_displayed = true; | ||
536 | settings.is_date_displayed = true; | ||
537 | break; | ||
538 | |||
539 | case BUTTON_OFF: | ||
540 | settings.is_time_displayed = false; | ||
541 | settings.is_rect_displayed = false; | ||
542 | settings.is_date_displayed = false; | ||
543 | break; | ||
544 | |||
545 | case SYS_USB_CONNECTED: | ||
546 | return PLUGIN_USB_CONNECTED; | ||
547 | rb->usb_screen(); | ||
548 | break; | ||
549 | } | ||
550 | } | ||
551 | } | ||
552 | break; | ||
553 | |||
554 | /* Toggle analog/digital */ | ||
555 | case BUTTON_PLAY: | ||
556 | settings.analog_clock = !settings.analog_clock; | ||
557 | break; | ||
558 | |||
559 | /* Show time */ | ||
560 | case BUTTON_RIGHT: | ||
561 | settings.is_time_displayed = !settings.is_time_displayed; | ||
562 | break; | ||
563 | |||
564 | /* Show border */ | ||
565 | case BUTTON_DOWN: | ||
566 | settings.is_rect_displayed = !settings.is_rect_displayed ; | ||
567 | break; | ||
568 | |||
569 | /* Show date */ | ||
570 | case BUTTON_UP: | ||
571 | settings.is_date_displayed = !settings.is_date_displayed; | ||
572 | break; | ||
573 | |||
574 | /* Show digits */ | ||
575 | case BUTTON_LEFT: | ||
576 | settings.are_digits_displayed = !settings.are_digits_displayed; | ||
577 | break; | ||
578 | |||
579 | /* USB plugged? */ | ||
580 | case SYS_USB_CONNECTED: | ||
581 | rb->usb_screen(); | ||
582 | return PLUGIN_USB_CONNECTED; | ||
583 | break; | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | |||
588 | /* 7 Segment LED imitation code by Linus Nielsen Feltzing */ | ||
589 | |||
590 | /* | ||
591 | a 0 b | ||
592 | ######### | ||
593 | # # | ||
594 | # # | ||
595 | 1# #2 | ||
596 | # # | ||
597 | # 3 # | ||
598 | c ######### d | ||
599 | # # | ||
600 | # # | ||
601 | 4# #5 | ||
602 | # # | ||
603 | # 6 # | ||
604 | e ######### f | ||
605 | */ | ||
606 | |||
607 | /* The coordinates of each end point (a-f) of the segment lines (0-6) */ | ||
608 | static unsigned int point_coords[6][2] = | ||
609 | { | ||
610 | {0, 0}, /* a */ | ||
611 | {1, 0}, /* b */ | ||
612 | {0, 1}, /* c */ | ||
613 | {1, 1}, /* d */ | ||
614 | {0, 2}, /* e */ | ||
615 | {1, 2} /* f */ | ||
616 | }; | ||
617 | |||
618 | /* The end points (a-f) for each segment line */ | ||
619 | static unsigned int seg_points[7][2] = | ||
620 | { | ||
621 | {0,1}, /* a to b */ | ||
622 | {0,2}, /* a to c */ | ||
623 | {1,3}, /* b to d */ | ||
624 | {2,3}, /* c to d */ | ||
625 | {2,4}, /* c to e */ | ||
626 | {3,5}, /* d to f */ | ||
627 | {4,5} /* e to f */ | ||
628 | }; | ||
629 | |||
630 | /* Lists that tell which segments (0-6) to enable for each digit (0-9), | ||
631 | the list is terminated with -1 */ | ||
632 | static int digit_segs[10][8] = | ||
633 | { | ||
634 | {0,1,2,4,5,6, -1}, /* 0 */ | ||
635 | {2,5, -1}, /* 1 */ | ||
636 | {0,2,3,4,6, -1}, /* 2 */ | ||
637 | {0,2,3,5,6, -1}, /* 3 */ | ||
638 | {1,2,3,5, -1}, /* 4 */ | ||
639 | {0,1,3,5,6, -1}, /* 5 */ | ||
640 | {0,1,3,4,5,6, -1}, /* 6 */ | ||
641 | {0,2,5, -1}, /* 7 */ | ||
642 | {0,1,2,3,4,5,6, -1}, /* 8 */ | ||
643 | {0,1,2,3,5,6, -1} /* 9 */ | ||
644 | }; | ||
645 | |||
646 | /* Draws one segment */ | ||
647 | void draw_seg(int seg, int x, int y, int width, int height) | ||
648 | { | ||
649 | int p1 = seg_points[seg][0]; | ||
650 | int p2 = seg_points[seg][1]; | ||
651 | int x1 = point_coords[p1][0]; | ||
652 | int y1 = point_coords[p1][1]; | ||
653 | int x2 = point_coords[p2][0]; | ||
654 | int y2 = point_coords[p2][1]; | ||
655 | |||
656 | /* It draws parallel lines of different lengths for thicker segments */ | ||
657 | if(seg == 0 || seg == 3 || seg == 6) | ||
658 | { | ||
659 | rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2, | ||
660 | x + x2 * width - 1 , y + y2 * height / 2); | ||
661 | |||
662 | rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 - 1, | ||
663 | x + x2 * width - 2, y + y2 * height / 2 - 1); | ||
664 | rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 1, | ||
665 | x + x2 * width - 2, y + y2 * height / 2 + 1); | ||
666 | |||
667 | rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 - 2, | ||
668 | x + x2 * width - 3, y + y2 * height / 2 - 2); | ||
669 | rb->lcd_drawline(x + x1 * width + 3, y + y1 * height / 2 + 2, | ||
670 | x + x2 * width - 3, y + y2 * height / 2 + 2); | ||
671 | } | ||
672 | else | ||
673 | { | ||
674 | rb->lcd_drawline(x + x1 * width, y + y1 * height / 2 + 1, | ||
675 | x + x2 * width , y + y2 * height / 2 - 1); | ||
676 | |||
677 | rb->lcd_drawline(x + x1 * width - 1, y + y1 * height / 2 + 2, | ||
678 | x + x2 * width - 1, y + y2 * height / 2 - 2); | ||
679 | rb->lcd_drawline(x + x1 * width + 1, y + y1 * height / 2 + 2, | ||
680 | x + x2 * width + 1, y + y2 * height / 2 - 2); | ||
681 | |||
682 | rb->lcd_drawline(x + x1 * width - 2, y + y1 * height / 2 + 3, | ||
683 | x + x2 * width - 2, y + y2 * height / 2 - 3); | ||
684 | |||
685 | rb->lcd_drawline(x + x1 * width + 2, y + y1 * height / 2 + 3, | ||
686 | x + x2 * width + 2, y + y2 * height / 2 - 3); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | /* Draws one digit */ | ||
691 | void draw_7seg_digit(int digit, int x, int y, int width, int height) | ||
692 | { | ||
693 | int i; | ||
694 | int c; | ||
695 | |||
696 | for(i = 0;digit_segs[digit][i] >= 0;i++) | ||
697 | { | ||
698 | c = digit_segs[digit][i]; | ||
699 | |||
700 | draw_seg(c, x, y, width, height); | ||
701 | } | ||
702 | } | ||
703 | |||
704 | /* Draws the entire 7-segment hour-minute time display */ | ||
705 | void draw_7seg_time(int hour, int minute, int x, int y, int width, int height, | ||
706 | bool colon) | ||
707 | { | ||
708 | int xpos = x; | ||
709 | |||
710 | draw_7seg_digit(hour / 10, xpos, y, width, height); | ||
711 | xpos += width + 6; | ||
712 | draw_7seg_digit(hour % 10, xpos, y, width, height); | ||
713 | xpos += width + 6; | ||
714 | |||
715 | if(colon) | ||
716 | { | ||
717 | rb->lcd_drawline(xpos, y + height/3 + 2, | ||
718 | xpos, y + height/3 + 2); | ||
719 | rb->lcd_drawline(xpos+1, y + height/3 + 1, | ||
720 | xpos+1, y + height/3 + 3); | ||
721 | rb->lcd_drawline(xpos+2, y + height/3, | ||
722 | xpos+2, y + height/3 + 4); | ||
723 | rb->lcd_drawline(xpos+3, y + height/3 + 1, | ||
724 | xpos+3, y + height/3 + 3); | ||
725 | rb->lcd_drawline(xpos+4, y + height/3 + 2, | ||
726 | xpos+4, y + height/3 + 2); | ||
727 | |||
728 | rb->lcd_drawline(xpos, y + height-height/3 + 2, | ||
729 | xpos, y + height-height/3 + 2); | ||
730 | rb->lcd_drawline(xpos+1, y + height-height/3 + 1, | ||
731 | xpos+1, y + height-height/3 + 3); | ||
732 | rb->lcd_drawline(xpos+2, y + height-height/3, | ||
733 | xpos+2, y + height-height/3 + 4); | ||
734 | rb->lcd_drawline(xpos+3, y + height-height/3 + 1, | ||
735 | xpos+3, y + height-height/3 + 3); | ||
736 | rb->lcd_drawline(xpos+4, y + height-height/3 + 2, | ||
737 | xpos+4, y + height-height/3 + 2); | ||
738 | } | ||
739 | |||
740 | xpos += 12; | ||
741 | |||
742 | draw_7seg_digit(minute / 10, xpos, y, width, height); | ||
743 | xpos += width + 6; | ||
744 | draw_7seg_digit(minute % 10, xpos, y, width, height); | ||
745 | xpos += width + 6; | ||
746 | } | ||
747 | |||
748 | #endif | ||