1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Kjell Ericson
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 /* variable button definitions */
24 #if CONFIG_KEYPAD == RECORDER_PAD
25 #define CHC_QUIT BUTTON_OFF
26 #define CHC_STARTSTOP BUTTON_PLAY
27 #define CHC_RESET BUTTON_LEFT
28 #define CHC_MENU BUTTON_F1
29 #define CHC_SETTINGS_INC BUTTON_UP
30 #define CHC_SETTINGS_DEC BUTTON_DOWN
31 #define CHC_SETTINGS_OK BUTTON_PLAY
32 #define CHC_SETTINGS_OK2 BUTTON_LEFT
33 #define CHC_SETTINGS_CANCEL BUTTON_OFF
35 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
36 #define CHC_QUIT BUTTON_OFF
37 #define CHC_STARTSTOP BUTTON_SELECT
38 #define CHC_RESET BUTTON_LEFT
39 #define CHC_MENU BUTTON_F1
40 #define CHC_SETTINGS_INC BUTTON_UP
41 #define CHC_SETTINGS_DEC BUTTON_DOWN
42 #define CHC_SETTINGS_OK BUTTON_SELECT
43 #define CHC_SETTINGS_OK2 BUTTON_LEFT
44 #define CHC_SETTINGS_CANCEL BUTTON_OFF
46 #elif CONFIG_KEYPAD == ONDIO_PAD
47 #define CHC_QUIT BUTTON_OFF
48 #define CHC_STARTSTOP BUTTON_RIGHT
49 #define CHC_RESET BUTTON_LEFT
50 #define CHC_MENU BUTTON_MENU
51 #define CHC_SETTINGS_INC BUTTON_UP
52 #define CHC_SETTINGS_DEC BUTTON_DOWN
53 #define CHC_SETTINGS_OK BUTTON_RIGHT
54 #define CHC_SETTINGS_OK2 BUTTON_LEFT
55 #define CHC_SETTINGS_CANCEL BUTTON_MENU
57 #elif CONFIG_KEYPAD == PLAYER_PAD
58 #define CHC_QUIT BUTTON_ON
59 #define CHC_STARTSTOP BUTTON_PLAY
60 #define CHC_RESET BUTTON_STOP
61 #define CHC_MENU BUTTON_MENU
62 #define CHC_SETTINGS_INC BUTTON_RIGHT
63 #define CHC_SETTINGS_DEC BUTTON_LEFT
64 #define CHC_SETTINGS_OK BUTTON_PLAY
65 #define CHC_SETTINGS_CANCEL BUTTON_STOP
66 #define CHC_SETTINGS_CANCEL2 BUTTON_MENU
68 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
69 (CONFIG_KEYPAD == IRIVER_H300_PAD)
70 #define CHC_QUIT BUTTON_SELECT
71 #define CHC_STARTSTOP BUTTON_ON
72 #define CHC_RESET BUTTON_OFF
73 #define CHC_MENU BUTTON_REC
74 #define CHC_SETTINGS_INC BUTTON_RIGHT
75 #define CHC_SETTINGS_DEC BUTTON_LEFT
76 #define CHC_SETTINGS_OK BUTTON_ON
77 #define CHC_SETTINGS_CANCEL BUTTON_OFF
78 #define CHC_SETTINGS_CANCEL2 BUTTON_REC
80 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
81 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
82 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
83 #define CHC_QUIT BUTTON_PLAY
84 #define CHC_STARTSTOP BUTTON_SELECT
85 #define CHC_RESET BUTTON_LEFT
86 #define CHC_MENU BUTTON_MENU
87 #define CHC_SETTINGS_INC BUTTON_SCROLL_FWD
88 #define CHC_SETTINGS_DEC BUTTON_SCROLL_BACK
89 #define CHC_SETTINGS_OK BUTTON_SELECT
90 #define CHC_SETTINGS_CANCEL BUTTON_MENU
92 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
93 #define CHC_QUIT BUTTON_PLAY
94 #define CHC_STARTSTOP BUTTON_MODE
95 #define CHC_RESET BUTTON_EQ
96 #define CHC_MENU BUTTON_SELECT
97 #define CHC_SETTINGS_INC BUTTON_RIGHT
98 #define CHC_SETTINGS_DEC BUTTON_LEFT
99 #define CHC_SETTINGS_OK BUTTON_SELECT
100 #define CHC_SETTINGS_CANCEL BUTTON_PLAY
102 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
103 #define CHC_QUIT BUTTON_REC
104 #define CHC_STARTSTOP BUTTON_PLAY
105 #define CHC_RESET BUTTON_POWER
106 #define CHC_MENU BUTTON_SELECT
107 #define CHC_SETTINGS_INC BUTTON_RIGHT
108 #define CHC_SETTINGS_DEC BUTTON_LEFT
109 #define CHC_SETTINGS_OK BUTTON_SELECT
110 #define CHC_SETTINGS_CANCEL BUTTON_REC
112 #elif CONFIG_KEYPAD == GIGABEAT_PAD
113 #define CHC_QUIT BUTTON_POWER
114 #define CHC_STARTSTOP BUTTON_SELECT
115 #define CHC_RESET BUTTON_A
116 #define CHC_MENU BUTTON_MENU
117 #define CHC_SETTINGS_INC BUTTON_UP
118 #define CHC_SETTINGS_DEC BUTTON_DOWN
119 #define CHC_SETTINGS_OK BUTTON_SELECT
120 #define CHC_SETTINGS_CANCEL BUTTON_POWER
122 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
123 (CONFIG_KEYPAD == SANSA_C200_PAD)
124 #define CHC_QUIT BUTTON_POWER
125 #define CHC_STARTSTOP BUTTON_SELECT
126 #define CHC_RESET BUTTON_DOWN
127 #define CHC_MENU BUTTON_UP
128 #define CHC_SETTINGS_INC BUTTON_RIGHT
129 #define CHC_SETTINGS_DEC BUTTON_LEFT
130 #define CHC_SETTINGS_OK BUTTON_SELECT
131 #define CHC_SETTINGS_CANCEL BUTTON_POWER
133 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
134 #define CHC_QUIT BUTTON_POWER
135 #define CHC_STARTSTOP BUTTON_PLAY
136 #define CHC_RESET BUTTON_FF
137 #define CHC_MENU BUTTON_REW
138 #define CHC_SETTINGS_INC BUTTON_RIGHT
139 #define CHC_SETTINGS_DEC BUTTON_LEFT
140 #define CHC_SETTINGS_OK BUTTON_PLAY
141 #define CHC_SETTINGS_CANCEL BUTTON_POWER
143 #elif CONFIG_KEYPAD == MROBE500_PAD
144 #define CHC_QUIT BUTTON_POWER
145 #define CHC_STARTSTOP BUTTON_RC_PLAY
146 #define CHC_RESET BUTTON_RC_HEART
147 #define CHC_MENU BUTTON_RC_MODE
148 #define CHC_SETTINGS_INC BUTTON_RC_VOL_UP
149 #define CHC_SETTINGS_DEC BUTTON_RC_VOL_DOWN
150 #define CHC_SETTINGS_OK BUTTON_RC_PLAY
151 #define CHC_SETTINGS_CANCEL BUTTON_POWER
153 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
154 #define CHC_QUIT BUTTON_BACK
155 #define CHC_STARTSTOP BUTTON_PLAY
156 #define CHC_RESET BUTTON_PREV
157 #define CHC_MENU BUTTON_MENU
158 #define CHC_SETTINGS_INC BUTTON_UP
159 #define CHC_SETTINGS_DEC BUTTON_DOWN
160 #define CHC_SETTINGS_OK BUTTON_SELECT
161 #define CHC_SETTINGS_CANCEL BUTTON_BACK
163 #elif CONFIG_KEYPAD == MROBE100_PAD
164 #define CHC_QUIT BUTTON_POWER
165 #define CHC_STARTSTOP BUTTON_SELECT
166 #define CHC_RESET BUTTON_DISPLAY
167 #define CHC_MENU BUTTON_MENU
168 #define CHC_SETTINGS_INC BUTTON_UP
169 #define CHC_SETTINGS_DEC BUTTON_DOWN
170 #define CHC_SETTINGS_OK BUTTON_SELECT
171 #define CHC_SETTINGS_CANCEL BUTTON_POWER
174 #error No keymap defined!
179 /* leave first line blank on bitmap display, for pause icon */
180 #ifdef HAVE_LCD_BITMAP
186 /* here is a global api struct pointer. while not strictly necessary,
187 it's nice not to have to pass the api pointer in all function calls
189 static struct plugin_api
* rb
;
190 MEM_FUNCTION_WRAPPERS(rb
);
191 #define MAX_PLAYERS 10
203 } timer_holder
[MAX_PLAYERS
];
205 static int run_timer(int nr
);
206 static int chessclock_set_int(char* string
,
212 #define FLAGS_SET_INT_SECONDS 1
214 static char * show_time(int secs
);
215 static int simple_menu(int nr
, unsigned char **strarr
);
219 #define MAX_TIME 7200
221 /* this is the plugin entry point */
222 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
230 rb
->memset(&settings
, 0, sizeof(settings
));
232 /* now go ahead and have fun! */
233 rb
->splash(HZ
, "Chess Clock");
235 rb
->lcd_clear_display();
241 res
=chessclock_set_int("Number of players",
242 &settings
.nr_timers
, 1, 1,
246 res
=chessclock_set_int("Total time",
247 &settings
.total_time
, 10, 0, MAX_TIME
,
248 FLAGS_SET_INT_SECONDS
);
249 settings
.round_time
=settings
.total_time
;
252 res
=chessclock_set_int("Max round time", &settings
.round_time
,
253 10, 0, settings
.round_time
,
254 FLAGS_SET_INT_SECONDS
);
262 return PLUGIN_USB_CONNECTED
;
274 for (i
=0; i
<settings
.nr_timers
; i
++) {
275 timer_holder
[i
].total_time
=settings
.total_time
;
276 timer_holder
[i
].used_time
=0;
277 timer_holder
[i
].hidden
=false;
280 pause
=true; /* We start paused */
286 for (i
=0; done
&& i
<settings
.nr_timers
; i
++) {
287 if (!timer_holder
[i
].hidden
)
293 if (!timer_holder
[nr
].hidden
) {
302 return PLUGIN_USB_CONNECTED
;
305 if (nr
>=settings
.nr_timers
)
311 nr
=settings
.nr_timers
-1;
318 #ifdef HAVE_LCD_BITMAP
319 static void show_pause_mode(bool enabled
)
321 static const char pause_icon
[] = {0x00,0x7f,0x7f,0x00,0x7f,0x7f,0x00};
324 rb
->lcd_mono_bitmap((unsigned char *)pause_icon
, 52, 0, 7, 8);
327 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
328 rb
->lcd_fillrect(52, 0, 7, 8);
329 rb
->lcd_set_drawmode(DRMODE_SOLID
);
340 static int run_timer(int nr
)
343 char player_info
[13];
347 long max_ticks
=timer_holder
[nr
].total_time
*HZ
-timer_holder
[nr
].used_time
;
349 bool round_time
=false;
351 #ifdef HAVE_LCD_CHARCELLS
352 rb
->lcd_icon(ICON_PAUSE
, pause
);
354 show_pause_mode(pause
);
357 if (settings
.round_time
*HZ
<max_ticks
) {
358 max_ticks
=settings
.round_time
*HZ
;
361 rb
->snprintf(player_info
, sizeof(player_info
), "Player %d", nr
+1);
362 rb
->lcd_puts(0, FIRST_LINE
, (unsigned char *)player_info
);
363 last_tick
=*rb
->current_tick
;
368 if (ticks
>max_ticks
) {
370 rb
->lcd_puts(0, FIRST_LINE
+1, (unsigned char *)"ROUND UP!");
372 rb
->lcd_puts(0, FIRST_LINE
+1, (unsigned char *)"TIME OUT!");
376 if (((int)(rb->current_tick - start_ticks)/HZ)&1) {
377 rb->lcd_puts(0, FIRST_LINE, player_info);
379 rb->lcd_puts(0, FIRST_LINE, player_info);
382 rb
->lcd_puts(0, FIRST_LINE
, (unsigned char *)player_info
);
383 now
=*rb
->current_tick
;
385 ticks
+=now
-last_tick
;
386 if ((max_ticks
-ticks
)/HZ
== 10) {
387 /* Backlight on if 10 seconds remain */
393 rb
->snprintf(buf
, sizeof(buf
), "%s/",
394 show_time((max_ticks
-ticks
+HZ
-1)/HZ
));
395 /* Append total time */
396 rb
->strcpy(&buf
[rb
->strlen(buf
)],
397 show_time((timer_holder
[nr
].total_time
*HZ
-
398 timer_holder
[nr
].used_time
-
400 rb
->lcd_puts(0, FIRST_LINE
+1, (unsigned char *)buf
);
402 rb
->lcd_puts(0, FIRST_LINE
+1,
403 (unsigned char *)show_time((max_ticks
-ticks
+HZ
-1)/HZ
));
408 button
= rb
->button_get(false);
410 /* OFF/ON key to exit */
412 return -1; /* Indicate exit */
414 /* PLAY = Stop/Start toggle */
417 #ifdef HAVE_LCD_CHARCELLS
418 rb
->lcd_icon(ICON_PAUSE
, pause
);
420 show_pause_mode(pause
);
424 /* LEFT = Reset timer */
433 char *menu
[]={"Delete player", "Restart round",
434 "Set round time", "Set total time"};
435 ret
=simple_menu(4, (unsigned char **)menu
);
439 } else if (ret
==-2) {
442 timer_holder
[nr
].hidden
=true;
453 int val
=(max_ticks
-ticks
)/HZ
;
454 res
=chessclock_set_int("Round time",
457 FLAGS_SET_INT_SECONDS
);
458 if (res
==-1) { /*usb*/
462 ticks
=max_ticks
-val
*HZ
;
467 int val
=timer_holder
[nr
].total_time
;
468 res
=chessclock_set_int("Total time",
471 FLAGS_SET_INT_SECONDS
);
472 if (res
==-1) { /*usb*/
476 timer_holder
[nr
].total_time
=val
;
482 /* UP (RIGHT/+) = Scroll Lap timer up */
483 case CHC_SETTINGS_INC
:
488 /* DOWN (LEFT/-) = Scroll Lap timer down */
489 case CHC_SETTINGS_DEC
:
495 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
) {
496 retval
= 3; /* been in usb mode */
501 rb
->sleep(HZ
/4); /* Sleep 1/4 of a second */
504 timer_holder
[nr
].used_time
+=ticks
;
509 static int chessclock_set_int(char* string
,
519 rb
->lcd_clear_display();
520 rb
->lcd_puts_scroll(0, FIRST_LINE
, (unsigned char *)string
);
524 if (flags
& FLAGS_SET_INT_SECONDS
)
525 rb
->snprintf(str
, sizeof str
,"%s (m:s)", show_time(*variable
));
527 rb
->snprintf(str
, sizeof str
,"%d", *variable
);
528 rb
->lcd_puts(0, FIRST_LINE
+1, (unsigned char *)str
);
531 button
= rb
->button_get(true);
533 case CHC_SETTINGS_INC
:
534 case CHC_SETTINGS_INC
| BUTTON_REPEAT
:
538 case CHC_SETTINGS_DEC
:
539 case CHC_SETTINGS_DEC
| BUTTON_REPEAT
:
543 case CHC_SETTINGS_OK
:
544 #ifdef CHC_SETTINGS_OK2
545 case CHC_SETTINGS_OK2
:
550 case CHC_SETTINGS_CANCEL
:
551 #ifdef CHC_SETTINGS_CANCEL2
552 case CHC_SETTINGS_CANCEL2
:
554 return 0; /* cancel */
558 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
559 return -1; /* been in usb mode */
570 rb
->lcd_stop_scroll();
575 static char * show_time(int seconds
)
577 static char buf
[]="00:00";
578 rb
->snprintf(buf
, sizeof(buf
), "%02d:%02d", seconds
/60, seconds
%60);
585 static int simple_menu(int nr
, unsigned char **strarr
)
589 rb
->lcd_clear_display();
596 rb
->lcd_puts_scroll(0, FIRST_LINE
, strarr
[show
]);
599 button
= rb
->button_get(true);
601 case CHC_SETTINGS_INC
:
602 case CHC_SETTINGS_INC
| BUTTON_REPEAT
:
606 case CHC_SETTINGS_DEC
:
607 case CHC_SETTINGS_DEC
| BUTTON_REPEAT
:
611 case CHC_SETTINGS_OK
:
612 #ifdef CHC_SETTINGS_OK2
613 case CHC_SETTINGS_OK2
:
618 case CHC_SETTINGS_CANCEL
:
619 #ifdef CHC_SETTINGS_CANCEL2
620 case CHC_SETTINGS_CANCEL2
:
622 return -2; /* cancel */
626 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
627 return -1; /* been in usb mode */