1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217<
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
* See http://libmpeg2.sourceforge.net/ for updates.
*
* mpeg2dec is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* mpeg2dec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MPEG2_H
#define MPEG2_H
#include "mpeg2dec_config.h"
#define MPEG2_VERSION(a,b,c) (((a)<<16)|((b)<<8)|(c))
#define MPEG2_RELEASE MPEG2_VERSION (0, 4, 0) /* 0.4.0 */
#define SEQ_FLAG_MPEG2 1
#define SEQ_FLAG_CONSTRAINED_PARAMETERS 2
#define SEQ_FLAG_PROGRESSIVE_SEQUENCE 4
#define SEQ_FLAG_LOW_DELAY 8
#define SEQ_FLAG_COLOUR_DESCRIPTION 16
#define SEQ_MASK_VIDEO_FORMAT 0xe0
#define SEQ_VIDEO_FORMAT_COMPONENT 0x00
#define SEQ_VIDEO_FORMAT_PAL 0x20
#define SEQ_VIDEO_FORMAT_NTSC 0x40
#define SEQ_VIDEO_FORMAT_SECAM 0x60
#define SEQ_VIDEO_FORMAT_MAC 0x80
#define SEQ_VIDEO_FORMAT_UNSPECIFIED 0xa0
typedef struct mpeg2_sequence_s
{
unsigned int width, height;
unsigned int chroma_width, chroma_height;
unsigned int byte_rate;
unsigned int vbv_buffer_size;
uint32_t flags;
unsigned int picture_width, picture_height;
unsigned int display_width, display_height;
unsigned int pixel_width, pixel_height;
unsigned int frame_period;
uint8_t profile_level_id;
uint8_t colour_primaries;
uint8_t transfer_characteristics;
uint8_t matrix_coefficients;
} mpeg2_sequence_t;
#define GOP_FLAG_DROP_FRAME 1
#define GOP_FLAG_BROKEN_LINK 2
#define GOP_FLAG_CLOSED_GOP 4
typedef struct mpeg2_gop_s
{
uint8_t hours;
uint8_t minutes;
uint8_t seconds;
uint8_t pictures;
uint32_t flags;
} mpeg2_gop_t;
#define PIC_MASK_CODING_TYPE 7
#define PIC_FLAG_CODING_TYPE_I 1
#define PIC_FLAG_CODING_TYPE_P 2
#define PIC_FLAG_CODING_TYPE_B 3
#define PIC_FLAG_CODING_TYPE_D 4
#define PIC_FLAG_TOP_FIELD_FIRST 8
#define PIC_FLAG_PROGRESSIVE_FRAME 16
#define PIC_FLAG_COMPOSITE_DISPLAY 32
#define PIC_FLAG_SKIP 64
#define PIC_FLAG_TAGS 128
#define PIC_MASK_COMPOSITE_DISPLAY 0xfffff000
typedef struct mpeg2_picture_s
{
unsigned int temporal_reference;
unsigned int nb_fields;
uint32_t tag, tag2;
uint32_t flags;
struct
{
int x, y;
} display_offset[3];
} mpeg2_picture_t;
typedef struct mpeg2_fbuf_s
{
uint8_t * buf[MPEG2_COMPONENTS];
void * id;
} mpeg2_fbuf_t;
typedef struct mpeg2_info_s
{
const mpeg2_sequence_t * sequence;
const mpeg2_gop_t * gop;
const mpeg2_picture_t * current_picture;
const mpeg2_picture_t * current_picture_2nd;
const mpeg2_fbuf_t * current_fbuf;
const mpeg2_picture_t * display_picture;
const mpeg2_picture_t * display_picture_2nd;
const mpeg2_fbuf_t * display_fbuf;
const mpeg2_fbuf_t * discard_fbuf;
const uint8_t * user_data;
unsigned int user_data_len;
} mpeg2_info_t;
typedef struct mpeg2dec_s mpeg2dec_t;
typedef struct mpeg2_decoder_s mpeg2_decoder_t;
typedef enum
{
STATE_BUFFER = 0,
STATE_SEQUENCE = 1,
STATE_SEQUENCE_REPEATED = 2,
STATE_GOP = 3,
STATE_PICTURE = 4,
STATE_SLICE_1ST = 5,
STATE_PICTURE_2ND = 6,
STATE_SLICE = 7,
STATE_END = 8,
STATE_INVALID = 9,
STATE_INVALID_END = 10
} mpeg2_state_t;
typedef struct mpeg2_convert_init_s
{
unsigned int id_size;
unsigned int buf_size[MPEG2_COMPONENTS];
void (* start)(void * id, const mpeg2_fbuf_t * fbuf,
const mpeg2_picture_t * picture, const mpeg2_gop_t * gop);
void (* copy)(void * id, uint8_t * const * src, unsigned int v_offset);
} mpeg2_convert_init_t;
typedef enum
{
MPEG2_CONVERT_SET = 0,
MPEG2_CONVERT_STRIDE = 1,
MPEG2_CONVERT_START = 2
} mpeg2_convert_stage_t;
typedef int mpeg2_convert_t (int stage, void * id,
const mpeg2_sequence_t * sequence, int stride,
void * arg, mpeg2_convert_init_t * result);
int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg);
int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride);
void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[MPEG2_COMPONENTS],
void * id);
void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf);
mpeg2dec_t * mpeg2_init (void);
const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec);
void mpeg2_close (mpeg2dec_t * mpeg2dec);
void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end);
int mpeg2_getpos (mpeg2dec_t * mpeg2dec);
mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec);
void mpe/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002 Kjell Ericson
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "plugin.h"
PLUGIN_HEADER
/* variable button definitions */
#if CONFIG_KEYPAD == RECORDER_PAD
#define CHC_QUIT BUTTON_OFF
#define CHC_STARTSTOP BUTTON_PLAY
#define CHC_RESET BUTTON_LEFT
#define CHC_MENU BUTTON_F1
#define CHC_SETTINGS_INC BUTTON_UP
#define CHC_SETTINGS_DEC BUTTON_DOWN
#define CHC_SETTINGS_OK BUTTON_PLAY
#define CHC_SETTINGS_OK2 BUTTON_LEFT
#define CHC_SETTINGS_CANCEL BUTTON_OFF
#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
#define CHC_QUIT BUTTON_OFF
#define CHC_STARTSTOP BUTTON_SELECT
#define CHC_RESET BUTTON_LEFT
#define CHC_MENU BUTTON_F1
#define CHC_SETTINGS_INC BUTTON_UP
#define CHC_SETTINGS_DEC BUTTON_DOWN
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_OK2 BUTTON_LEFT
#define CHC_SETTINGS_CANCEL BUTTON_OFF
#elif CONFIG_KEYPAD == ONDIO_PAD
#define CHC_QUIT BUTTON_OFF
#define CHC_STARTSTOP BUTTON_RIGHT
#define CHC_RESET BUTTON_LEFT
#define CHC_MENU BUTTON_MENU
#define CHC_SETTINGS_INC BUTTON_UP
#define CHC_SETTINGS_DEC BUTTON_DOWN
#define CHC_SETTINGS_OK BUTTON_RIGHT
#define CHC_SETTINGS_OK2 BUTTON_LEFT
#define CHC_SETTINGS_CANCEL BUTTON_MENU
#elif CONFIG_KEYPAD == PLAYER_PAD
#define CHC_QUIT BUTTON_ON
#define CHC_STARTSTOP BUTTON_PLAY
#define CHC_RESET BUTTON_STOP
#define CHC_MENU BUTTON_MENU
#define CHC_SETTINGS_INC BUTTON_RIGHT
#define CHC_SETTINGS_DEC BUTTON_LEFT
#define CHC_SETTINGS_OK BUTTON_PLAY
#define CHC_SETTINGS_CANCEL BUTTON_STOP
#define CHC_SETTINGS_CANCEL2 BUTTON_MENU
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
(CONFIG_KEYPAD == IRIVER_H300_PAD)
#define CHC_QUIT BUTTON_SELECT
#define CHC_STARTSTOP BUTTON_ON
#define CHC_RESET BUTTON_OFF
#define CHC_MENU BUTTON_REC
#define CHC_SETTINGS_INC BUTTON_RIGHT
#define CHC_SETTINGS_DEC BUTTON_LEFT
#define CHC_SETTINGS_OK BUTTON_ON
#define CHC_SETTINGS_CANCEL BUTTON_OFF
#define CHC_SETTINGS_CANCEL2 BUTTON_REC
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
(CONFIG_KEYPAD == IPOD_3G_PAD) || \
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
#define CHC_QUIT BUTTON_PLAY
#define CHC_STARTSTOP BUTTON_SELECT
#define CHC_RESET BUTTON_LEFT
#define CHC_MENU BUTTON_MENU
#define CHC_SETTINGS_INC BUTTON_SCROLL_FWD
#define CHC_SETTINGS_DEC BUTTON_SCROLL_BACK
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_MENU
#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
#define CHC_QUIT BUTTON_PLAY
#define CHC_STARTSTOP BUTTON_MODE
#define CHC_RESET BUTTON_EQ
#define CHC_MENU BUTTON_SELECT
#define CHC_SETTINGS_INC BUTTON_RIGHT
#define CHC_SETTINGS_DEC BUTTON_LEFT
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_PLAY
#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
#define CHC_QUIT BUTTON_REC
#define CHC_STARTSTOP BUTTON_PLAY
#define CHC_RESET BUTTON_POWER
#define CHC_MENU BUTTON_SELECT
#define CHC_SETTINGS_INC BUTTON_RIGHT
#define CHC_SETTINGS_DEC BUTTON_LEFT
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_REC
#elif CONFIG_KEYPAD == GIGABEAT_PAD
#define CHC_QUIT BUTTON_POWER
#define CHC_STARTSTOP BUTTON_SELECT
#define CHC_RESET BUTTON_A
#define CHC_MENU BUTTON_MENU
#define CHC_SETTINGS_INC BUTTON_UP
#define CHC_SETTINGS_DEC BUTTON_DOWN
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_POWER
#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
(CONFIG_KEYPAD == SANSA_C200_PAD)
#define CHC_QUIT BUTTON_POWER
#define CHC_STARTSTOP BUTTON_SELECT
#define CHC_RESET BUTTON_DOWN
#define CHC_MENU BUTTON_UP
#define CHC_SETTINGS_INC BUTTON_RIGHT
#define CHC_SETTINGS_DEC BUTTON_LEFT
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_POWER
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
#define CHC_QUIT BUTTON_POWER
#define CHC_STARTSTOP BUTTON_PLAY
#define CHC_RESET BUTTON_FF
#define CHC_MENU BUTTON_REW
#define CHC_SETTINGS_INC BUTTON_RIGHT
#define CHC_SETTINGS_DEC BUTTON_LEFT
#define CHC_SETTINGS_OK BUTTON_PLAY
#define CHC_SETTINGS_CANCEL BUTTON_POWER
#elif CONFIG_KEYPAD == MROBE500_PAD
#define CHC_QUIT BUTTON_POWER
#define CHC_STARTSTOP BUTTON_RC_PLAY
#define CHC_RESET BUTTON_RC_HEART
#define CHC_MENU BUTTON_RC_MODE
#define CHC_SETTINGS_INC BUTTON_RC_VOL_UP
#define CHC_SETTINGS_DEC BUTTON_RC_VOL_DOWN
#define CHC_SETTINGS_OK BUTTON_RC_PLAY
#define CHC_SETTINGS_CANCEL BUTTON_POWER
#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
#define CHC_QUIT BUTTON_BACK
#define CHC_STARTSTOP BUTTON_PLAY
#define CHC_RESET BUTTON_PREV
#define CHC_MENU BUTTON_MENU
#define CHC_SETTINGS_INC BUTTON_UP
#define CHC_SETTINGS_DEC BUTTON_DOWN
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_BACK
#elif CONFIG_KEYPAD == MROBE100_PAD
#define CHC_QUIT BUTTON_POWER
#define CHC_STARTSTOP BUTTON_SELECT
#define CHC_RESET BUTTON_DISPLAY
#define CHC_MENU BUTTON_MENU
#define CHC_SETTINGS_INC BUTTON_UP
#define CHC_SETTINGS_DEC BUTTON_DOWN
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_POWER
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
#define CHC_QUIT BUTTON_RC_REC
#define CHC_STARTSTOP BUTTON_RC_PLAY
#define CHC_RESET BUTTON_RC_REW
#define CHC_MENU BUTTON_RC_MENU
#define CHC_SETTINGS_INC BUTTON_RC_VOL_UP
#define CHC_SETTINGS_DEC BUTTON_RC_VOL_DOWN
#define CHC_SETTINGS_OK BUTTON_RC_PLAY
#define CHC_SETTINGS_CANCEL BUTTON_RC_REC
#elif CONFIG_KEYPAD == COWOND2_PAD
#define CHC_QUIT BUTTON_POWER
#define CHC_RESET (BUTTON_CENTER|BUTTON_MENU)
#define CHC_MENU BUTTON_MENU
#define CHC_SETTINGS_INC BUTTON_PLUS
#define CHC_SETTINGS_DEC BUTTON_MINUS
#define CHC_SETTINGS_CANCEL BUTTON_POWER
#else
#error No keymap defined!
#endif
#ifdef HAVE_TOUCHPAD
#ifndef CHC_SETTINGS_OK
#define CHC_SETTINGS_OK BUTTON_CENTER
#endif
#ifndef CHC_STARTSTOP
#define CHC_STARTSTOP BUTTON_CENTER
#endif
#ifndef CHC_SETTINGS_INC
#define CHC_SETTINGS_INC BUTTON_TOPMIDDLE
#endif
#ifndef CHC_SETTINGS_DEC
#define CHC_SETTINGS_DEC BUTTON_BOTTOMMIDDLE
#endif
#ifndef CHC_RESET
#define CHC_RESET BUTTON_TOPLEFT
#endif
#ifndef CHC_MENU
#define CHC_MENU BUTTON_TOPRIGHT
#endif
#endif
/* leave first line blank on bitmap display, for pause icon */
#ifdef HAVE_LCD_BITMAP
#define FIRST_LINE 1
#else
#define FIRST_LINE 0
#endif
/* here is a global api struct pointer. while not strictly necessary,
it's nice not to have to pass the api pointer in all function calls
in the plugin */
static const struct plugin_api* rb;
MEM_FUNCTION_WRAPPERS(rb);
#define MAX_PLAYERS 10
static struct {
int nr_timers;
int total_time;
int round_time;
} settings;
static struct {
int total_time;
int used_time;
bool hidden;
} timer_holder[MAX_PLAYERS];
static int run_timer(int nr);
static int chessclock_set_int(char* string,
int* variable,
int step,
int min,
int max,
int flags);
#define FLAGS_SET_INT_SECONDS 1
static char * show_time(int secs);
static int simple_menu(int nr, unsigned char **strarr);
static bool pause;
#define MAX_TIME 7200
/* this is the plugin entry point */
enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
{
int i;
bool done;
int nr;
(void)parameter;
rb=api;
rb->memset(&settings, 0, sizeof(settings));
/* now go ahead and have fun! */
rb->splash(HZ, "Chess Clock");
rb->lcd_clear_display();
i=0;
while (i>=0) {
int res;
switch (i) {
case 0:
res=chessclock_set_int("Number of players",
&settings.nr_timers, 1, 1,
MAX_PLAYERS, 0);
break;
case 1:
res=chessclock_set_int("Total time",
&settings.total_time, 10, 0, MAX_TIME,
FLAGS_SET_INT_SECONDS);
settings.round_time=settings.total_time;
break;
case 2:
res=chessclock_set_int("Max round time", &settings.round_time,
10, 0, settings.round_time,
FLAGS_SET_INT_SECONDS);
break;
default:
i=-1; /* done */
res=-2;
break;
}
if (res==-1) {
return PLUGIN_USB_CONNECTED;
}
if (res==0) {
i--;
if (i<0) {
return PLUGIN_OK;
}
}
if (res>0) {
i++;
}
}
for (i=0; i<settings.nr_timers; i++) {
timer_holder[i].total_time=settings.total_time;
timer_holder[i].used_time=0;
timer_holder[i].hidden=false;
}
pause=true; /* We start paused */
nr=0;
do {
int ret=0;
done=true;
for (i=0; done && i<settings.nr_timers; i++) {
if (!timer_holder[i].hidden)
done=false;
}
if (done) {
return PLUGIN_OK;
}
if (!timer_holder[nr].hidden) {
done=false;
ret=run_timer(nr);
}
switch (ret) {
case -1: /* exit */
done=true;
break;
case 3:
return PLUGIN_USB_CONNECTED;
case 1:
nr++;
if (nr>=settings.nr_timers)
nr=0;
break;
case 2:
nr--;
if (nr<0)
nr=settings.nr_timers-1;
break;
}
} while (!done);
return PLUGIN_OK;
}
#ifdef HAVE_LCD_BITMAP
static void show_pause_mode(bool enabled)
{
static const char pause_icon[] = {0x00,0x7f,0x7f,0x00,0x7f,0x7f,0x00};
if (enabled)
rb->lcd_mono_bitmap((unsigned char *)pause_icon, 52, 0, 7, 8);
else
{
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
rb->lcd_fillrect(52, 0, 7, 8);
rb->lcd_set_drawmode(DRMODE_SOLID);
}
}
#endif
/*
-1= exit
1 = next player
2 = prev player
3 = usb connected
*/
static int run_timer(int nr)
{
char buf[40];
char player_info[13];
long last_tick;
bool done=false;
int retval=0;
long max_ticks=timer_holder[nr].total_time*HZ-timer_holder[nr].used_time;
long ticks=0;
bool round_time=false;
#ifdef HAVE_LCD_CHARCELLS
rb->lcd_icon(ICON_PAUSE, pause);
#else
show_pause_mode(pause);
#endif
if (settings.round_time*HZ<max_ticks) {
max_ticks=settings.round_time*HZ;
round_time=true;
}
rb->snprintf(player_info, sizeof(player_info), "Player %d", nr+1);
rb->lcd_puts(0, FIRST_LINE, (unsigned char *)player_info);
last_tick=*rb->current_tick;
while (!done) {
int button;
long now;
if (ticks>max_ticks) {
if (round_time)
rb->lcd_puts(0, FIRST_LINE+1, (unsigned char *)"ROUND UP!");
else
rb->lcd_puts(0, FIRST_LINE+1, (unsigned char *)"TIME OUT!");
rb->backlight_on();
} else {
/*
if (((int)(rb->current_tick - start_ticks)/HZ)&1) {
rb->lcd_puts(0, FIRST_LINE, player_info);
} else {
rb->lcd_puts(0, FIRST_LINE, player_info);
}
*/
rb->lcd_puts(0, FIRST_LINE, (unsigned char *)player_info);
now=*rb->current_tick;
if (!pause) {
ticks+=now-last_tick;
if ((max_ticks-ticks)/HZ == 10) {
/* Backlight on if 10 seconds remain */
rb->backlight_on();
}
}
last_tick=now;
if (round_time) {
rb->snprintf(buf, sizeof(buf), "%s/",
show_time((max_ticks-ticks+HZ-1)/HZ));
/* Append total time */
rb->strcpy(&buf[rb->strlen(buf)],
show_time((timer_holder[nr].total_time*HZ-
timer_holder[nr].used_time-
ticks+HZ-1)/HZ));
rb->lcd_puts(0, FIRST_LINE+1, (unsigned char *)buf);
} else {
rb->lcd_puts(0, FIRST_LINE+1,
(unsigned char *)show_time((max_ticks-ticks+HZ-1)/HZ));
}
}
rb->lcd_update();
button = rb->button_get(false);
switch (button) {
/* OFF/ON key to exit */
case CHC_QUIT:
return -1; /* Indicate exit */
/* PLAY = Stop/Start toggle */
case CHC_STARTSTOP:
pause=!pause;
#ifdef HAVE_LCD_CHARCELLS
rb->lcd_icon(ICON_PAUSE, pause);
#else
show_pause_mode(pause);
#endif
break;
/* LEFT = Reset timer */
case CHC_RESET:
ticks=0;
break;
/* MENU */
case CHC_MENU:
{
int ret;
char *menu[]={"Delete player", "Restart round",
"Set round time", "Set total time"};
ret=simple_menu(4, (unsigned char **)menu);
if (ret==-1) {
retval = 3;
done=true;
} else if (ret==-2) {
} else if (ret==0) {
/* delete timer */
timer_holder[nr].hidden=true;
retval=1;
done=true;
break;
} else if (ret==1) {
/* restart */
ticks=0;
break;
} else if (ret==2) {
/* set round time */
int res;
int val=(max_ticks-ticks)/HZ;
res=chessclock_set_int("Round time",
&val,
10, 0, MAX_TIME,
FLAGS_SET_INT_SECONDS);
if (res==-1) { /*usb*/
retval = 3;
done=true;
} else if (res==1) {
ticks=max_ticks-val*HZ;
}
} else if (ret==3) {
/* set total time */
int res;
int val=timer_holder[nr].total_time;
res=chessclock_set_int("Total time",
&val,
10, 0, MAX_TIME,
FLAGS_SET_INT_SECONDS);
if (res==-1) { /*usb*/
retval = 3;
done=true;
} else if (res==1) {
timer_holder[nr].total_time=val;
}
}
}
break;
/* UP (RIGHT/+) = Scroll Lap timer up */
case CHC_SETTINGS_INC:
retval = 1;
done = true;
break;
/* DOWN (LEFT/-) = Scroll Lap timer down */
case CHC_SETTINGS_DEC:
retval = 2;
done = true;
break;
default:
if (rb->default_event_handler(button) == SYS_USB_CONNECTED) {
retval = 3; /* been in usb mode */
done = true;
}
break;
}
rb->sleep(HZ/4); /* Sleep 1/4 of a second */
}
timer_holder[nr].used_time+=ticks;
return retval;
}
static int chessclock_set_int(char* string,
int* variable,
int step,
int min,
int max,
int flags)
{
bool done = false;
int button;
rb->lcd_clear_display();
rb->lcd_puts_scroll(0, FIRST_LINE, (unsigned char *)string);
while (!done) {
char str[32];
if (flags & FLAGS_SET_INT_SECONDS)
rb->snprintf(str, sizeof str,"%s (m:s)", show_time(*variable));
else
rb->snprintf(str, sizeof str,"%d", *variable);
rb->lcd_puts(0, FIRST_LINE+1, (unsigned char *)str);
rb->lcd_update();
button = rb->button_get(true);
switch(button) {
case CHC_SETTINGS_INC:
case CHC_SETTINGS_INC | BUTTON_REPEAT:
*variable += step;
break;
case CHC_SETTINGS_DEC:
case CHC_SETTINGS_DEC | BUTTON_REPEAT:
*variable -= step;
break;
case CHC_SETTINGS_OK:
#ifdef CHC_SETTINGS_OK2
case CHC_SETTINGS_OK2:
#endif
done = true;
break;
case CHC_SETTINGS_CANCEL:
#ifdef CHC_SETTINGS_CANCEL2
case CHC_SETTINGS_CANCEL2:
#endif
return 0; /* cancel */
break;
default:
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
return -1; /* been in usb mode */
break;
}
if(*variable > max )
*variable = max;
if(*variable < min )
*variable = min;
}
rb->lcd_stop_scroll();
return 1;
}
static char * show_time(int seconds)
{
static char buf[]="00:00";
rb->snprintf(buf, sizeof(buf), "%02d:%02d", seconds/60, seconds%60);
return buf;
}
/* -1 = USB
-2 = cancel
*/
static int simple_menu(int nr, unsigned char **strarr)
{
int show=0;
int button;
rb->lcd_clear_display();
while (1) {
if (show>=nr)
show=0;
if (show<0)
show=nr-1;
rb->lcd_puts_scroll(0, FIRST_LINE, strarr[show]);
rb->lcd_update();
button = rb->button_get(true);
switch(button) {
case CHC_SETTINGS_INC:
case CHC_SETTINGS_INC | BUTTON_REPEAT:
show++;
break;
case CHC_SETTINGS_DEC:
case CHC_SETTINGS_DEC | BUTTON_REPEAT:
show--;
break;
case CHC_SETTINGS_OK:
#ifdef CHC_SETTINGS_OK2
case CHC_SETTINGS_OK2:
#endif
return show;
break;
case CHC_SETTINGS_CANCEL:
#ifdef CHC_SETTINGS_CANCEL2
case CHC_SETTINGS_CANCEL2:
#endif
return -2; /* cancel */
break;
default:
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
return -1; /* been in usb mode */
break;
}
}
}
|