1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2003 Pierre Delore
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "lib/configfile.h"
24 #ifdef HAVE_LCD_CHARCELLS
26 /* Euro converter for the player */
34 ON+PLAY : Swap Euro<>Home
35 MENU : Display the Menu
36 Currency -> Allows to choose the currency
37 Exit-> Exit the plugin
41 I use signed long long (64 bits).
42 A value have 5 digits after the . (123.45 = 12345000)
45 - The Irish currency needs 6 digits after the . to have sufficient precision on big number
50 /* Name and path of the config file*/
51 static const char cfg_filename
[] = "euroconverter.cfg";
52 #define CFGFILE_VERSION 0 /* Current config file version */
53 #define CFGFILE_MINVERSION 0 /* Minimum config file version to accept */
55 /* typedef for simplifying usage of long long type */
56 typedef long long int longlong_t
;
58 /*Pattern for the converter*/
59 static unsigned char pattern_euro
[]={0x07, 0x08, 0x1E, 0x10, 0x1E, 0x08, 0x07}; /* € */
60 static unsigned char pattern_home
[]={0x04, 0x0A, 0x11, 0x1F, 0x11, 0x11, 0x1F}; /* Home icon*/
62 /* 1 euro = ... (remenber 5 digits after the .)*/
63 static int currency
[12]={
64 655957, /*FRF France*/
65 195583, /*DEM Germany*/
66 1376030, /*ATS Austria*/
67 4033990, /*BEF Belgium*/
68 16638600, /*ESP Spain*/
69 594573, /*FIM Finland*/
70 78756, /*IEP Ireland*/
71 193627000, /*ITL Italy*/
72 4033990, /*LUF Luxemburg*/
73 220371, /*NLG Netherlands*/
74 20048200, /*PTE Portugal*/
75 34075100, /*GRD Greece*/
78 /* Number of digit of the currency (for the display) */
79 static int nb_digit
[12]={
89 2, /*NLG Netherlands*/
94 /* max euro to have home currency */
95 static longlong_t max_euro
[12]={
96 99999999000LL, /*FRF France 999 999.99 */
97 99999999000LL, /*DEM Germany 999 999.99 */
98 99999999000LL, /*ATS Austria 999 999.99 */
99 99999999000LL, /*BEF Belgium 999 999.99 */
100 99999999000LL, /*ESP Spain 99 999 999 */
101 99999999000LL, /*FIM Finland 999 999.99 */
102 99999999000LL, /*IEP Ireland 999 999.99 */
103 51645690000LL, /*ITL Italy 999 999 999 */
104 99999999000LL, /*LUF Luxemburg 999 999.99 */
105 99999999000LL, /*NLG Netherlands 999 999.99 */
106 99999999000LL, /*PTE Portugal 99 999 999 */
107 29347028000LL /*GRD Greece 99 999 999 */
110 /* max home to have euro currency */
111 /* 92233720300000 Limitation due to the max capacity of long long (2^63)*/
112 static longlong_t max_curr
[12]={
113 99999999000LL, /*FRF France 152449.02 */
114 99999999000LL, /*DEM Germany 511291.88 */
115 99999999000LL, /*ATS Austria 72672.83 */
116 99999999000LL, /*BEF Belgium 24789.35 */
117 92233720300000LL,/*ESP Spain 5543358.23 */
118 99999999000LL, /*FIM Finland 168187.92 */
119 9999999900LL, /*IEP Ireland 1269744.51 exact value=1269738.07 */
120 92233720300000LL,/*ITL Italy 476347.41 */
121 99999999000LL, /*LUF Luxemburg 24789.35 */
122 99999999000LL, /*NLG Netherlands 453780.21 */
123 92233720300000LL,/*PTE Portugal 4600598.57 */
124 92233720300000LL /*GRD Greece 2706777.69 */
127 static unsigned char *abbrev_str
[12] = {
128 "...FRF...", /*France*/
129 "...DEM...", /*Germany*/
130 "...ATS...", /*Austria*/
131 "...BEF...", /*Belgium*/
132 "...ESP...", /*Spain*/
133 "...FIM...", /*Finland*/
134 "...IEP...", /*Ireland*/
135 "...ITL...", /*Italy*/
136 "...LUF...", /*Luxemburg*/
137 "...NLG...", /*Netherlands*/
138 "...PTE...", /*Portugal*/
139 "...GRD..." /*Greece*/
143 static unsigned long heuro
,hhome
; /*Handles for the new patterns*/
145 static const struct plugin_api
* rb
;
147 static char *currency_str
[12] = {
163 static int country
; /*Country selected*/
164 static int cur_pos
; /*Cursor position*/
165 static longlong_t inc
;
167 /* Persistent settings */
168 static struct configdata config
[] = {
169 { TYPE_ENUM
, 0, 12, &country
, "country", currency_str
, NULL
}
173 /* 64bits*64 bits with 5 digits after the . */
174 static longlong_t
mymul(longlong_t a
, longlong_t b
)
176 return((a
*b
)/100000LL);
180 /* 64bits/64 bits with 5 digits after the . */
181 static longlong_t
mydiv(longlong_t a
, longlong_t b
)
183 return((a
*100000LL)/b
);
187 /* 123.45=12345000 split => i=123 f=45000*/
188 static void split(longlong_t v
, longlong_t
* i
, longlong_t
* f
)
194 (*f
)=(v
-(t
*100000LL));
199 static longlong_t
pow10(int n
)
211 /* round the i.f at n digit after the . */
212 static void round(longlong_t
* i
, longlong_t
* f
, int n
)
223 (*f
)=((*f
)/(int)pow10(5-n
))+add
;
238 /* Display the imput and the result
239 pos: false : first line
242 static void display(longlong_t euro
, longlong_t home
, bool pos
)
245 unsigned char str
[20];
246 unsigned char s1
[20];
247 unsigned char s2
[20];
250 { /*Edit the second line*/
251 rb
->strcpy(s1
," %6d.%02d");
252 if (nb_digit
[country
]==2)
253 rb
->strcpy(s2
,"\xee\x84\x90%06d.%02d");
255 rb
->strcpy(s2
,"\xee\x84\x90%09d");
259 rb
->strcpy(s1
,"\xee\x84\x90%06d.%02d");
260 if (nb_digit
[country
]==2)
261 rb
->strcpy(s2
," %6d.%02d");
263 rb
->strcpy(s2
," %9d");
266 rb
->lcd_remove_cursor();
268 rb
->lcd_putc(0,0,heuro
);
272 rb
->snprintf(str
,sizeof(str
),s1
,(int)i
,(int)f
);
276 rb
->lcd_puts(1,0,str
);
277 rb
->lcd_put_cursor(10-cur_pos
,0,0x5F);
280 rb
->lcd_puts_scroll(1,0,str
);
283 rb
->lcd_putc(0,1,hhome
);
286 round(&i
,&f
,nb_digit
[country
]);
287 rb
->snprintf(str
,sizeof(str
),s2
,(int)i
,(int)f
);
290 rb
->lcd_puts(1,1,str
);
291 rb
->lcd_put_cursor(10-cur_pos
,1,0x5F);
294 rb
->lcd_puts_scroll(1,1,str
);
300 /* Show country Abbreviation */
301 static void show_abbrev(void)
303 rb
->splash(HZ
*3/4,abbrev_str
[country
]);
307 /* Save the config to disk */
308 static void save_config(void)
310 configfile_save(cfg_filename
, config
, 1, CFGFILE_VERSION
);
314 /* Load the config from disk */
315 static void load_config(void)
317 configfile_load(cfg_filename
, config
, 1, CFGFILE_MINVERSION
);
322 static void currency_menu(void)
326 rb
->lcd_clear_display();
329 rb
->lcd_puts(0,0,"Currency:");
330 rb
->lcd_puts(0,1,currency_str
[c
]);
332 switch (rb
->button_get(true))
334 case BUTTON_RIGHT
|BUTTON_REL
:
339 case BUTTON_LEFT
|BUTTON_REL
:
344 case BUTTON_PLAY
|BUTTON_REL
:
349 case BUTTON_STOP
|BUTTON_REL
:
356 /* Display the choice menu. */
357 static int euro_menu(void)
364 rb
->lcd_clear_display();
365 rb
->lcd_puts(0,0," Currency");
366 rb
->lcd_puts(0,1," Exit");
367 rb
->lcd_putc(0,c
,0xe110);
370 switch (rb
->button_get(true))
372 case BUTTON_RIGHT
|BUTTON_REL
:
375 case BUTTON_LEFT
|BUTTON_REL
:
378 case BUTTON_PLAY
|BUTTON_REL
:
384 case BUTTON_STOP
|BUTTON_REL
:
391 /* Call when the program end */
392 static void euro_exit(void *parameter
)
396 //Restore the old pattern (i don't find another way to do this. An idea?)
397 rb
->lcd_unlock_pattern(heuro
);
398 rb
->lcd_unlock_pattern(hhome
);
401 rb
->lcd_clear_display();
406 /* this is the plugin entry point */
407 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
)
410 longlong_t e
,h
,old_e
,old_h
;
413 /* if you don't use the parameter, you can do like
414 this to avoid the compiler warning about it */
417 /* if you are using a global api pointer, don't forget to copy it!
418 otherwise you will get lovely "I04: IllInstr" errors... :-) */
421 /*Get the pattern handle*/
422 heuro
=rb
->lcd_get_locked_pattern();
423 hhome
=rb
->lcd_get_locked_pattern();
424 rb
->lcd_define_pattern(heuro
, pattern_euro
);
425 rb
->lcd_define_pattern(hhome
, pattern_home
);
439 /*Empty the event queue*/
440 rb
->button_clear_queue();
449 button
= rb
->button_get(true);
452 case BUTTON_MENU
|BUTTON_REL
:
461 if (e
>max_euro
[country
])
467 if (h
>max_curr
[country
])
469 if (nb_digit
[country
]==2)
478 case BUTTON_ON
| BUTTON_PLAY
:
481 case BUTTON_ON
| BUTTON_REL
:
492 if (nb_digit
[country
]==2)
500 case BUTTON_STOP
|BUTTON_REL
:
509 inc
=pow10(3+cur_pos
-1);
511 inc
=pow10(3+cur_pos
);
517 if (nb_digit
[country
]==2)
522 inc
=pow10(3+cur_pos
-1);
524 inc
=pow10(3+cur_pos
);
527 inc
=pow10(5+cur_pos
);
532 case BUTTON_PLAY
|BUTTON_REL
:
541 inc
=pow10(3+cur_pos
-1);
543 inc
=pow10(3+cur_pos
);
549 if (nb_digit
[country
]==2)
554 inc
=pow10(3+cur_pos
-1);
556 inc
=pow10(3+cur_pos
);
559 inc
=pow10(5+cur_pos
);
563 case BUTTON_LEFT
|BUTTON_REL
:
564 case BUTTON_LEFT
|BUTTON_REPEAT
:
579 case BUTTON_RIGHT
|BUTTON_REL
:
580 case BUTTON_RIGHT
|BUTTON_REPEAT
:
586 if (e
>max_euro
[country
])
592 if (h
>max_curr
[country
])
598 if (rb
->default_event_handler_ex(button
, euro_exit
, NULL
)
599 == SYS_USB_CONNECTED
)
600 return PLUGIN_USB_CONNECTED
;
604 if (!pos
) /*Euro>home*/
605 h
=mymul(e
,currency
[country
]);
607 e
=mydiv(h
,currency
[country
]);