summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/mpeg_settings.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mpegplayer/mpeg_settings.c')
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.c529
1 files changed, 349 insertions, 180 deletions
diff --git a/apps/plugins/mpegplayer/mpeg_settings.c b/apps/plugins/mpegplayer/mpeg_settings.c
index 6cd5f7b186..7336507aaa 100644
--- a/apps/plugins/mpegplayer/mpeg_settings.c
+++ b/apps/plugins/mpegplayer/mpeg_settings.c
@@ -2,27 +2,16 @@
2#include "lib/configfile.h" 2#include "lib/configfile.h"
3#include "lib/oldmenuapi.h" 3#include "lib/oldmenuapi.h"
4 4
5#include "mpegplayer.h"
5#include "mpeg_settings.h" 6#include "mpeg_settings.h"
6 7
7extern struct plugin_api* rb;
8
9struct mpeg_settings settings; 8struct mpeg_settings settings;
10 9
11ssize_t seek_PTS(int in_file, int startTime, int accept_button);
12void display_thumb(int in_file);
13
14#ifndef HAVE_LCD_COLOR
15void gray_show(bool enable);
16#endif
17
18#define SETTINGS_VERSION 2 10#define SETTINGS_VERSION 2
19#define SETTINGS_MIN_VERSION 1 11#define SETTINGS_MIN_VERSION 1
20#define SETTINGS_FILENAME "mpegplayer.cfg" 12#define SETTINGS_FILENAME "mpegplayer.cfg"
21 13
22enum slider_state_t {state0, state1, state2, 14#define THUMB_DELAY (75*HZ/100)
23 state3, state4, state5} slider_state;
24
25volatile long thumbDelayTimer;
26 15
27/* button definitions */ 16/* button definitions */
28#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ 17#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
@@ -30,16 +19,16 @@ volatile long thumbDelayTimer;
30#define MPEG_SELECT BUTTON_ON 19#define MPEG_SELECT BUTTON_ON
31#define MPEG_RIGHT BUTTON_RIGHT 20#define MPEG_RIGHT BUTTON_RIGHT
32#define MPEG_LEFT BUTTON_LEFT 21#define MPEG_LEFT BUTTON_LEFT
33#define MPEG_SCROLL_DOWN BUTTON_UP 22#define MPEG_UP BUTTON_UP
34#define MPEG_SCROLL_UP BUTTON_DOWN 23#define MPEG_DOWN BUTTON_DOWN
35#define MPEG_EXIT BUTTON_OFF 24#define MPEG_EXIT BUTTON_OFF
36 25
37#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) 26#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
38#define MPEG_SELECT BUTTON_PLAY 27#define MPEG_SELECT BUTTON_PLAY
39#define MPEG_RIGHT BUTTON_RIGHT 28#define MPEG_RIGHT BUTTON_RIGHT
40#define MPEG_LEFT BUTTON_LEFT 29#define MPEG_LEFT BUTTON_LEFT
41#define MPEG_SCROLL_DOWN BUTTON_UP 30#define MPEG_UP BUTTON_UP
42#define MPEG_SCROLL_UP BUTTON_DOWN 31#define MPEG_DOWN BUTTON_DOWN
43#define MPEG_EXIT BUTTON_POWER 32#define MPEG_EXIT BUTTON_POWER
44 33
45#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ 34#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
@@ -48,8 +37,8 @@ volatile long thumbDelayTimer;
48#define MPEG_SELECT BUTTON_SELECT 37#define MPEG_SELECT BUTTON_SELECT
49#define MPEG_RIGHT BUTTON_RIGHT 38#define MPEG_RIGHT BUTTON_RIGHT
50#define MPEG_LEFT BUTTON_LEFT 39#define MPEG_LEFT BUTTON_LEFT
51#define MPEG_SCROLL_DOWN BUTTON_SCROLL_FWD 40#define MPEG_UP BUTTON_SCROLL_FWD
52#define MPEG_SCROLL_UP BUTTON_SCROLL_BACK 41#define MPEG_DOWN BUTTON_SCROLL_BACK
53#define MPEG_EXIT BUTTON_MENU 42#define MPEG_EXIT BUTTON_MENU
54 43
55#elif CONFIG_KEYPAD == GIGABEAT_PAD 44#elif CONFIG_KEYPAD == GIGABEAT_PAD
@@ -64,10 +53,10 @@ volatile long thumbDelayTimer;
64 53
65#elif CONFIG_KEYPAD == IRIVER_H10_PAD 54#elif CONFIG_KEYPAD == IRIVER_H10_PAD
66#define MPEG_SELECT BUTTON_PLAY 55#define MPEG_SELECT BUTTON_PLAY
67#define MPEG_SCROLL_UP BUTTON_SCROLL_UP
68#define MPEG_SCROLL_DOWN BUTTON_SCROLL_DOWN
69#define MPEG_LEFT BUTTON_LEFT 56#define MPEG_LEFT BUTTON_LEFT
70#define MPEG_RIGHT BUTTON_RIGHT 57#define MPEG_RIGHT BUTTON_RIGHT
58#define MPEG_UP BUTTON_SCROLL_UP
59#define MPEG_DOWN BUTTON_SCROLL_DOWN
71#define MPEG_EXIT BUTTON_POWER 60#define MPEG_EXIT BUTTON_POWER
72 61
73#elif (CONFIG_KEYPAD == SANSA_E200_PAD) 62#elif (CONFIG_KEYPAD == SANSA_E200_PAD)
@@ -136,10 +125,10 @@ static void display_options(void)
136 int options_quit = 0; 125 int options_quit = 0;
137 126
138 static const struct menu_item items[] = { 127 static const struct menu_item items[] = {
139#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) 128#if MPEG_OPTION_DITHERING_ENABLED
140 [MPEG_OPTION_DITHERING] = 129 [MPEG_OPTION_DITHERING] =
141 { "Dithering", NULL }, 130 { "Dithering", NULL },
142#endif /* #ifdef TOSHIBA_GIGABEAT_F */ 131#endif
143 [MPEG_OPTION_DISPLAY_FPS] = 132 [MPEG_OPTION_DISPLAY_FPS] =
144 { "Display FPS", NULL }, 133 { "Display FPS", NULL },
145 [MPEG_OPTION_LIMIT_FPS] = 134 [MPEG_OPTION_LIMIT_FPS] =
@@ -159,7 +148,7 @@ static void display_options(void)
159 148
160 switch (result) 149 switch (result)
161 { 150 {
162#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) 151#if MPEG_OPTION_DITHERING_ENABLED
163 case MPEG_OPTION_DITHERING: 152 case MPEG_OPTION_DITHERING:
164 result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0; 153 result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0;
165 rb->set_option("Dithering", &result, INT, noyes, 2, NULL); 154 rb->set_option("Dithering", &result, INT, noyes, 2, NULL);
@@ -167,7 +156,7 @@ static void display_options(void)
167 | ((result != 0) ? LCD_YUV_DITHER : 0); 156 | ((result != 0) ? LCD_YUV_DITHER : 0);
168 rb->lcd_yuv_set_options(settings.displayoptions); 157 rb->lcd_yuv_set_options(settings.displayoptions);
169 break; 158 break;
170#endif /* #ifdef TOSHIBA_GIGABEAT_F */ 159#endif /* MPEG_OPTION_DITHERING_ENABLED */
171 case MPEG_OPTION_DISPLAY_FPS: 160 case MPEG_OPTION_DISPLAY_FPS:
172 rb->set_option("Display FPS",&settings.showfps,INT, 161 rb->set_option("Display FPS",&settings.showfps,INT,
173 noyes, 2, NULL); 162 noyes, 2, NULL);
@@ -189,168 +178,343 @@ static void display_options(void)
189 menu_exit(menu_id); 178 menu_exit(menu_id);
190} 179}
191 180
192void draw_slider(int slider_ypos, int max_val, int current_val) 181static void show_loading(struct vo_rect *rc)
193{ 182{
194 int slider_margin = LCD_WIDTH*12/100; /* 12% */ 183 int oldmode;
195 int slider_width = LCD_WIDTH-(slider_margin*2); 184#ifndef HAVE_LCD_COLOR
196 char resume_str[32]; 185 stream_gray_show(false);
186#endif
187 oldmode = rb->lcd_get_drawmode();
188 rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
189 rb->lcd_fillrect(rc->l-1, rc->t-1, rc->r - rc->l + 2, rc->b - rc->t + 2);
190 rb->lcd_set_drawmode(oldmode);
191 rb->splash(0, "Loading...");
192}
193
194void draw_slider(uint32_t range, uint32_t pos, struct vo_rect *rc)
195{
196 #define SLIDER_WIDTH (LCD_WIDTH-SLIDER_LMARGIN-SLIDER_RMARGIN)
197 #define SLIDER_X SLIDER_LMARGIN
198 #define SLIDER_Y (LCD_HEIGHT-SLIDER_HEIGHT-SLIDER_BMARGIN)
199 #define SLIDER_HEIGHT 8
200 #define SLIDER_TEXTMARGIN 1
201 #define SLIDER_LMARGIN 1
202 #define SLIDER_RMARGIN 1
203 #define SLIDER_TMARGIN 1
204 #define SLIDER_BMARGIN 1
205 #define SCREEN_MARGIN 1
206
207 struct hms hms;
208 char str[32];
209 int text_w, text_h, text_y;
210
211 /* Put positition on left */
212 ts_to_hms(pos, &hms);
213 hms_format(str, sizeof(str), &hms);
214 rb->lcd_getstringsize(str, NULL, &text_h);
215 text_y = SLIDER_Y - SLIDER_TEXTMARGIN - text_h;
216
217 if (rc == NULL)
218 {
219 int oldmode = rb->lcd_get_drawmode();
220 rb->lcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID);
221 rb->lcd_fillrect(SLIDER_X, text_y, SLIDER_WIDTH,
222 LCD_HEIGHT - SLIDER_BMARGIN - text_y
223 - SLIDER_TMARGIN);
224 rb->lcd_set_drawmode(oldmode);
225
226 rb->lcd_putsxy(SLIDER_X, text_y, str);
227
228 /* Put duration on right */
229 ts_to_hms(range, &hms);
230 hms_format(str, sizeof(str), &hms);
231 rb->lcd_getstringsize(str, &text_w, NULL);
232
233 rb->lcd_putsxy(SLIDER_X + SLIDER_WIDTH - text_w, text_y, str);
234
235 /* Draw slider */
236 rb->lcd_drawrect(SLIDER_X, SLIDER_Y, SLIDER_WIDTH, SLIDER_HEIGHT);
237 rb->lcd_fillrect(SLIDER_X, SLIDER_Y,
238 muldiv_uint32(pos, SLIDER_WIDTH, range),
239 SLIDER_HEIGHT);
240
241 /* Update screen */
242 rb->lcd_update_rect(SLIDER_X, text_y - SLIDER_TMARGIN, SLIDER_WIDTH,
243 LCD_HEIGHT - SLIDER_BMARGIN - text_y + SLIDER_TEXTMARGIN);
244 }
245 else
246 {
247 /* Just return slider rectangle */
248 rc->l = SLIDER_X;
249 rc->t = text_y - SLIDER_TMARGIN;
250 rc->r = rc->l + SLIDER_WIDTH;
251 rc->b = rc->t + LCD_HEIGHT - SLIDER_BMARGIN - text_y;
252 }
253}
254
255bool display_thumb_image(const struct vo_rect *rc)
256{
257 if (!stream_display_thumb(rc))
258 {
259 rb->splash(0, "Frame not available");
260 return false;
261 }
262
263#ifdef HAVE_LCD_COLOR
264 /* Draw a raised border around the frame */
265 int oldcolor = rb->lcd_get_foreground();
266 rb->lcd_set_foreground(LCD_LIGHTGRAY);
267
268 rb->lcd_hline(rc->l-1, rc->r-1, rc->t-1);
269 rb->lcd_vline(rc->l-1, rc->t, rc->b-1);
197 270
198 /* max_val and current_val are in half minutes 271 rb->lcd_set_foreground(LCD_DARKGRAY);
199 determine value .0 or .5 to display */ 272
200 int max_hol = max_val/2; 273 rb->lcd_hline(rc->l-1, rc->r, rc->b);
201 int max_rem = (max_val-(max_hol*2))*5; 274 rb->lcd_vline(rc->r, rc->t-1, rc->b);
202 int current_hol = current_val/2; 275
203 int current_rem = (current_val-(current_hol*2))*5; 276 rb->lcd_set_foreground(oldcolor);
204 277
205 rb->snprintf(resume_str, sizeof(resume_str), "0.0"); 278 rb->lcd_update_rect(rc->l-1, rc->t-1, rc->r - rc->l + 2, 1);
206 rb->lcd_putsxy(slider_margin, slider_ypos, resume_str); 279 rb->lcd_update_rect(rc->l-1, rc->t, 1, rc->b - rc->t);
207 280 rb->lcd_update_rect(rc->l-1, rc->b, rc->r - rc->l + 2, 1);
208 rb->snprintf(resume_str, sizeof(resume_str), "%u.%u", max_hol, max_rem); 281 rb->lcd_update_rect(rc->r, rc->t, 1, rc->b - rc->t);
209 rb->lcd_putsxy(LCD_WIDTH-slider_margin-25, slider_ypos, resume_str); 282#else
210 283 /* Just show the thumbnail */
211 rb->lcd_drawrect(slider_margin, slider_ypos+17, slider_width, 8); 284 stream_gray_show(true);
212 rb->lcd_fillrect(slider_margin, slider_ypos+17, 285#endif
213 current_val*slider_width/max_val, 8); 286
214 287 return true;
215 rb->snprintf(resume_str, sizeof(resume_str), "%u.%u", current_hol, 288}
216 current_rem); 289
217 rb->lcd_putsxy(slider_margin+(current_val*slider_width/max_val)-16, 290/* Add an amount to the specified time - with saturation */
218 slider_ypos+29, resume_str); 291uint32_t increment_time(uint32_t val, int32_t amount, uint32_t range)
219 292{
220 rb->lcd_update_rect(0, slider_ypos, LCD_WIDTH, LCD_HEIGHT-slider_ypos); 293 if (amount < 0)
294 {
295 uint32_t off = -amount;
296 if (range > off && val >= off)
297 val -= off;
298 else
299 val = 0;
300 }
301 else if (amount > 0)
302 {
303 uint32_t off = amount;
304 if (range > off && val <= range - off)
305 val += off;
306 else
307 val = range;
308 }
309
310 return val;
221} 311}
222 312
223int get_start_time(int play_time, int in_file) 313int get_start_time(uint32_t duration)
224{ 314{
225 int seek_quit = 0;
226 int button = 0; 315 int button = 0;
227 int resume_time = settings.resume_time; 316 int tmo = TIMEOUT_NOBLOCK;
228 int slider_ypos = LCD_HEIGHT-45; 317 uint32_t resume_time = settings.resume_time;
229 int seek_return; 318 struct vo_rect rc_vid, rc_bound;
230 319 uint32_t aspect_vid, aspect_bound;
231 slider_state = state0; 320
232 thumbDelayTimer = *(rb->current_tick); 321 enum state_enum slider_state = state0;
322
233 rb->lcd_clear_display(); 323 rb->lcd_clear_display();
234 rb->lcd_update(); 324 rb->lcd_update();
235 325
236 while(seek_quit == 0) 326 draw_slider(0, 100, &rc_bound);
327 rc_bound.b = rc_bound.t - SLIDER_TMARGIN;
328#ifdef HAVE_LCD_COLOR
329 rc_bound.t = SCREEN_MARGIN;
330#else
331 rc_bound.t = 0;
332 rc_bound.l = 0;
333 rc_bound.r = LCD_WIDTH;
334#endif
335
336 DEBUGF("rc_bound: %d, %d, %d, %d\n", rc_bound.l, rc_bound.t,
337 rc_bound.r, rc_bound.b);
338
339 rc_vid.l = rc_vid.t = 0;
340 if (!stream_vo_get_size((struct vo_ext *)&rc_vid.r))
237 { 341 {
238 button = rb->button_get(false); 342 /* Can't get size - fill whole thing */
343 rc_vid.r = rc_bound.r - rc_bound.l;
344 rc_vid.b = rc_bound.b - rc_bound.t;
345 }
346
347#if !defined (HAVE_LCD_COLOR)
348#if LCD_PIXELFORMAT == VERTICAL_PACKING
349 rc_bound.b &= ~7; /* Align bottom edge */
350#endif
351#endif
352
353 /* Get aspect ratio of bounding rectangle and video in u16.16 */
354 aspect_bound = ((rc_bound.r - rc_bound.l) << 16) /
355 (rc_bound.b - rc_bound.t);
356
357 DEBUGF("aspect_bound: %ld.%02ld\n", aspect_bound >> 16,
358 100*(aspect_bound & 0xffff) >> 16);
359
360 aspect_vid = (rc_vid.r << 16) / rc_vid.b;
361
362 DEBUGF("aspect_vid: %ld.%02ld\n", aspect_vid >> 16,
363 100*(aspect_vid & 0xffff) >> 16);
364
365 if (aspect_vid >= aspect_bound)
366 {
367 /* Video proportionally wider than or same as bounding rectangle */
368 if (rc_vid.r > rc_bound.r - rc_bound.l)
369 {
370 rc_vid.r = rc_bound.r - rc_bound.l;
371 rc_vid.b = (rc_vid.r << 16) / aspect_vid;
372 }
373 /* else already fits */
374 }
375 else
376 {
377 /* Video proportionally narrower than bounding rectangle */
378 if (rc_vid.b > rc_bound.b - rc_bound.t)
379 {
380 rc_vid.b = rc_bound.b - rc_bound.t;
381 rc_vid.r = (aspect_vid * rc_vid.b) >> 16;
382 }
383 /* else already fits */
384 }
385
386 /* Even width and height >= 2 */
387 rc_vid.r = (rc_vid.r < 2) ? 2 : (rc_vid.r & ~1);
388 rc_vid.b = (rc_vid.b < 2) ? 2 : (rc_vid.b & ~1);
389
390 /* Center display in bounding rectangle */
391 rc_vid.l = ((rc_bound.l + rc_bound.r) - rc_vid.r) / 2;
392 rc_vid.r += rc_vid.l;
393
394 rc_vid.t = ((rc_bound.t + rc_bound.b) - rc_vid.b) / 2;
395 rc_vid.b += rc_vid.t;
396
397 DEBUGF("rc_vid: %d, %d, %d, %d\n", rc_vid.l, rc_vid.t,
398 rc_vid.r, rc_vid.b);
399
400#ifndef HAVE_LCD_COLOR
401 /* Set gray overlay to the bounding rectangle */
402 stream_set_gray_rect(&rc_bound);
403#endif
404
405 while(slider_state < state9)
406 {
407 button = tmo == TIMEOUT_BLOCK ?
408 rb->button_get(true) : rb->button_get_w_tmo(tmo);
409
239 switch (button) 410 switch (button)
240 { 411 {
241#if (CONFIG_KEYPAD == GIGABEAT_PAD) || \ 412 case BUTTON_NONE:
242 (CONFIG_KEYPAD == SANSA_E200_PAD) || \ 413 break;
243 (CONFIG_KEYPAD == SANSA_C200_PAD) 414
244 case MPEG_DOWN: 415 /* Coarse (1 minute) control */
245 case MPEG_DOWN | BUTTON_REPEAT: 416 case MPEG_DOWN:
246 if ((resume_time -= 20) < 0) 417 case MPEG_DOWN | BUTTON_REPEAT:
247 resume_time = 0; 418 resume_time = increment_time(resume_time, -60*TS_SECOND, duration);
248 slider_state = state0; 419 slider_state = state0;
249 thumbDelayTimer = *(rb->current_tick); 420 break;
250 break; 421
251 case MPEG_UP: 422 case MPEG_UP:
252 case MPEG_UP | BUTTON_REPEAT: 423 case MPEG_UP | BUTTON_REPEAT:
253 if ((resume_time += 20) > play_time) 424 resume_time = increment_time(resume_time, 60*TS_SECOND, duration);
254 resume_time = play_time; 425 slider_state = state0;
255 slider_state = state0; 426 break;
256 thumbDelayTimer = *(rb->current_tick); 427
257 break; 428 /* Fine (1 second) control */
429 case MPEG_LEFT:
430 case MPEG_LEFT | BUTTON_REPEAT:
431#ifdef MPEG_SCROLL_UP
432 case MPEG_SCROLL_UP:
433 case MPEG_SCROLL_UP | BUTTON_REPEAT:
258#endif 434#endif
259 case MPEG_LEFT: 435 resume_time = increment_time(resume_time, -TS_SECOND, duration);
260 case MPEG_LEFT | BUTTON_REPEAT: 436 slider_state = state0;
261 case MPEG_SCROLL_UP: 437 break;
262 case MPEG_SCROLL_UP | BUTTON_REPEAT: 438
263 if (--resume_time < 0) 439 case MPEG_RIGHT:
264 resume_time = 0; 440 case MPEG_RIGHT | BUTTON_REPEAT:
265 slider_state = state0; 441#ifdef MPEG_SCROLL_DOWN
266 thumbDelayTimer = *(rb->current_tick); 442 case MPEG_SCROLL_DOWN:
267 break; 443 case MPEG_SCROLL_DOWN | BUTTON_REPEAT:
268 case MPEG_RIGHT: 444#endif
269 case MPEG_RIGHT | BUTTON_REPEAT: 445 resume_time = increment_time(resume_time, TS_SECOND, duration);
270 case MPEG_SCROLL_DOWN: 446 slider_state = state0;
271 case MPEG_SCROLL_DOWN | BUTTON_REPEAT: 447 break;
272 if (++resume_time > play_time) 448
273 resume_time = play_time; 449 case MPEG_SELECT:
274 slider_state = state0; 450 settings.resume_time = resume_time;
275 thumbDelayTimer = *(rb->current_tick); 451 case MPEG_EXIT:
276 break; 452 slider_state = state9;
277 case MPEG_SELECT: 453 break;
278 settings.resume_time = resume_time; 454
279 case MPEG_EXIT: 455 case SYS_USB_CONNECTED:
280 seek_quit = 1; 456 slider_state = state9;
281 break; 457#ifndef HAVE_LCD_COLOR
282 default: 458 stream_gray_show(false);
283 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) 459#endif
284 seek_quit = 1; 460 cancel_cpu_boost();
285 break; 461 default:
462 rb->default_event_handler(button);
463 rb->yield();
464 continue;
286 } 465 }
287 466
288 rb->yield();
289
290 switch(slider_state) 467 switch(slider_state)
291 { 468 {
292 case state0: 469 case state0:
293 rb->lcd_clear_display(); 470 trigger_cpu_boost();
294 rb->lcd_update(); 471 stream_seek(resume_time, SEEK_SET);
295#ifdef HAVE_LCD_COLOR 472 show_loading(&rc_bound);
296 if (resume_time > 0) 473 draw_slider(duration, resume_time, NULL);
297 rb->splash(0, "Loading..."); 474 slider_state = state1;
298#endif 475 tmo = THUMB_DELAY;
299 slider_state = state1; 476 break;
300 break; 477 case state1:
301 case state1: 478 display_thumb_image(&rc_vid);
302 if (*(rb->current_tick) - thumbDelayTimer > 75) 479 slider_state = state2;
303 slider_state = state2; 480 case state2:
304 if (resume_time == 0) 481 case state9:
305 { 482 cancel_cpu_boost();
306 seek_return = 0; 483 tmo = TIMEOUT_BLOCK;
307 slider_state = state5; 484 default:
308 } 485 break;
309 draw_slider(slider_ypos, play_time, resume_time);
310 break;
311 case state2:
312 if ( (seek_return = seek_PTS(in_file, resume_time, 1)) >= 0)
313 slider_state = state3;
314 else if (seek_return == -101)
315 {
316 slider_state = state0;
317 thumbDelayTimer = *(rb->current_tick);
318 }
319 else
320 slider_state = state4;
321 break;
322 case state3:
323 display_thumb(in_file);
324 draw_slider(slider_ypos, play_time, resume_time);
325 slider_state = state4;
326 break;
327 case state4:
328 draw_slider(slider_ypos, play_time, resume_time);
329 slider_state = state5;
330 break;
331 case state5:
332 break;
333 } 486 }
334 } 487 }
335 488
489#ifndef HAVE_LCD_COLOR
490 /* Restore gray overlay dimensions */
491 stream_gray_show(false);
492 rc_bound.b = LCD_HEIGHT;
493 stream_set_gray_rect(&rc_bound);
494#endif
495
496 cancel_cpu_boost();
497
336 return button; 498 return button;
337} 499}
338 500
339enum mpeg_start_id mpeg_start_menu(int play_time, int in_file) 501enum mpeg_start_id mpeg_start_menu(uint32_t duration)
340{ 502{
341 int menu_id; 503 int menu_id;
342 int result = 0; 504 int result = 0;
343 int menu_quit = 0; 505 int menu_quit = 0;
344 506
345 /* add the resume time to the menu display */ 507 /* add the resume time to the menu display */
346 char resume_str[32]; 508 char resume_str[32];
347 int time_hol = (int)(settings.resume_time/2); 509 char hms_str[32];
348 int time_rem = ((settings.resume_time%2)==0) ? 0 : 5; 510 struct hms hms;
511
512 ts_to_hms(settings.resume_time, &hms);
513 hms_format(hms_str, sizeof(hms_str), &hms);
349 514
350 if (settings.enable_start_menu == 0) 515 if (settings.enable_start_menu == 0)
351 { 516 {
352 rb->snprintf(resume_str, sizeof(resume_str), 517 rb->snprintf(resume_str, sizeof(resume_str), "Yes: %s", hms_str);
353 "Yes (min): %d.%d", time_hol, time_rem);
354 518
355 struct opt_items resume_no_yes[2] = 519 struct opt_items resume_no_yes[2] =
356 { 520 {
@@ -369,11 +533,10 @@ enum mpeg_start_id mpeg_start_menu(int play_time, int in_file)
369 return MPEG_START_RESTART; 533 return MPEG_START_RESTART;
370 } 534 }
371 else 535 else
372 return MPEG_START_RESUME; 536 return MPEG_START_RESUME;
373 } 537 }
374 538
375 rb->snprintf(resume_str, sizeof(resume_str), 539 rb->snprintf(resume_str, sizeof(resume_str), "Resume at: %s", hms_str);
376 "Resume time (min): %d.%d", time_hol, time_rem);
377 540
378 struct menu_item items[] = 541 struct menu_item items[] =
379 { 542 {
@@ -382,7 +545,7 @@ enum mpeg_start_id mpeg_start_menu(int play_time, int in_file)
382 [MPEG_START_RESUME] = 545 [MPEG_START_RESUME] =
383 { resume_str, NULL }, 546 { resume_str, NULL },
384 [MPEG_START_SEEK] = 547 [MPEG_START_SEEK] =
385 { "Set start time (min)", NULL }, 548 { "Set start time", NULL },
386 [MPEG_START_QUIT] = 549 [MPEG_START_QUIT] =
387 { "Quit mpegplayer", NULL }, 550 { "Quit mpegplayer", NULL },
388 }; 551 };
@@ -390,9 +553,9 @@ enum mpeg_start_id mpeg_start_menu(int play_time, int in_file)
390 553
391 menu_id = menu_init(rb, items, sizeof(items) / sizeof(*items), 554 menu_id = menu_init(rb, items, sizeof(items) / sizeof(*items),
392 NULL, NULL, NULL, NULL); 555 NULL, NULL, NULL, NULL);
393 556
394 rb->button_clear_queue(); 557 rb->button_clear_queue();
395 558
396 while(menu_quit == 0) 559 while(menu_quit == 0)
397 { 560 {
398 result = menu_show(menu_id); 561 result = menu_show(menu_id);
@@ -407,15 +570,19 @@ enum mpeg_start_id mpeg_start_menu(int play_time, int in_file)
407 menu_quit = 1; 570 menu_quit = 1;
408 break; 571 break;
409 case MPEG_START_SEEK: 572 case MPEG_START_SEEK:
410#ifndef HAVE_LCD_COLOR 573 {
411 gray_show(true); 574 if (!stream_can_seek())
412#endif 575 {
413 if (get_start_time(play_time, in_file) == MPEG_SELECT) 576 rb->splash(HZ, "Unavailable");
577 break;
578 }
579
580 bool vis = stream_show_vo(false);
581 if (get_start_time(duration) == MPEG_SELECT)
414 menu_quit = 1; 582 menu_quit = 1;
415#ifndef HAVE_LCD_COLOR 583 stream_show_vo(vis);
416 gray_show(false);
417#endif
418 break; 584 break;
585 }
419 case MPEG_START_QUIT: 586 case MPEG_START_QUIT:
420 menu_quit = 1; 587 menu_quit = 1;
421 break; 588 break;
@@ -428,13 +595,15 @@ enum mpeg_start_id mpeg_start_menu(int play_time, int in_file)
428 595
429 menu_exit(menu_id); 596 menu_exit(menu_id);
430 597
598 rb->lcd_clear_display();
599 rb->lcd_update();
600
431 return result; 601 return result;
432} 602}
433 603
434void clear_resume_count(void) 604void clear_resume_count(void)
435{ 605{
436 configfile_save(SETTINGS_FILENAME, config, 606 configfile_save(SETTINGS_FILENAME, config, ARRAYLEN(config),
437 sizeof(config)/sizeof(*config),
438 SETTINGS_VERSION); 607 SETTINGS_VERSION);
439 608
440 settings.resume_count = 0; 609 settings.resume_count = 0;
@@ -514,7 +683,7 @@ void init_settings(const char* filename)
514 settings.skipframes = 1; /* Skip frames */ 683 settings.skipframes = 1; /* Skip frames */
515 settings.enable_start_menu = 1; /* Enable start menu */ 684 settings.enable_start_menu = 1; /* Enable start menu */
516 settings.resume_count = -1; 685 settings.resume_count = -1;
517#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) 686#if MPEG_OPTION_DITHERING_ENABLED
518 settings.displayoptions = 0; /* No visual effects */ 687 settings.displayoptions = 0; /* No visual effects */
519#endif 688#endif
520 689
@@ -530,7 +699,7 @@ void init_settings(const char* filename)
530 SETTINGS_VERSION); 699 SETTINGS_VERSION);
531 } 700 }
532 701
533#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) 702#if MPEG_OPTION_DITHERING_ENABLED
534 if ((settings.displayoptions = 703 if ((settings.displayoptions =
535 configfile_get_value(SETTINGS_FILENAME, "Display options")) < 0) 704 configfile_get_value(SETTINGS_FILENAME, "Display options")) < 0)
536 { 705 {
@@ -546,7 +715,7 @@ void init_settings(const char* filename)
546 configfile_update_entry(SETTINGS_FILENAME, "Resume count", 0); 715 configfile_update_entry(SETTINGS_FILENAME, "Resume count", 0);
547 } 716 }
548 717
549 rb->strcpy(settings.resume_filename, filename); 718 rb->snprintf(settings.resume_filename, MAX_PATH, "%s", filename);
550 719
551 /* get the resume time for the current mpeg if it exist */ 720 /* get the resume time for the current mpeg if it exist */
552 if ((settings.resume_time = configfile_get_value 721 if ((settings.resume_time = configfile_get_value
@@ -558,11 +727,11 @@ void init_settings(const char* filename)
558 727
559void save_settings(void) 728void save_settings(void)
560{ 729{
561 configfile_update_entry(SETTINGS_FILENAME, "Show FPS", 730 configfile_update_entry(SETTINGS_FILENAME, "Show FPS",
562 settings.showfps); 731 settings.showfps);
563 configfile_update_entry(SETTINGS_FILENAME, "Limit FPS", 732 configfile_update_entry(SETTINGS_FILENAME, "Limit FPS",
564 settings.limitfps); 733 settings.limitfps);
565 configfile_update_entry(SETTINGS_FILENAME, "Skip frames", 734 configfile_update_entry(SETTINGS_FILENAME, "Skip frames",
566 settings.skipframes); 735 settings.skipframes);
567 configfile_update_entry(SETTINGS_FILENAME, "Enable start menu", 736 configfile_update_entry(SETTINGS_FILENAME, "Enable start menu",
568 settings.enable_start_menu); 737 settings.enable_start_menu);
@@ -575,8 +744,8 @@ void save_settings(void)
575 ++settings.resume_count); 744 ++settings.resume_count);
576 } 745 }
577 746
578#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) 747#if MPEG_OPTION_DITHERING_ENABLED
579 configfile_update_entry(SETTINGS_FILENAME, "Display options", 748 configfile_update_entry(SETTINGS_FILENAME, "Display options",
580 settings.displayoptions); 749 settings.displayoptions);
581#endif 750#endif
582} 751}