summaryrefslogtreecommitdiff
path: root/apps/plugins/bitmaps/native/clock_binary.132x80x16.bmp
blob: e2a177794ccf01a5d5fd41d184db7785ef37700c (plain)
ofshex dumpascii
0000 42 4d 26 0b 00 00 00 00 00 00 36 00 00 00 28 00 00 00 12 00 00 00 32 00 00 00 01 00 18 00 00 00 BM&.......6...(.......2.........
0020 00 00 f0 0a 00 00 13 0b 00 00 13 0b 00 00 00 00 00 00 00 00 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 ................................
0040 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ................................
0060 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ................................
0080 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 ................................
00a0 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e7 c9 b4 ea cb b6 eb cc b7 eb cc ................................
00c0 b7 eb cc b7 eb cc b8 ec cd b8 e9 cb b6 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 ................................
00e0 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ea cb b6 e6 c8 b4 c8 b2 a2 a4 94 8a 8e 82 7b 80 77 70 88 7c 74 a7 ........................{.wp.|t.
0100 95 88 d1 b7 a5 ec cd b8 e9 ca b6 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e7 c8 b4 ea ................................
0120 cc b7 c7 b0 a1 7c 75 70 43 43 43 23 24 25 17 18 19 11 12 13 13 14 15 1d 1e 1f 37 35 34 7c 6f 66 .....|upCCC#$%............754|of
0140 da bd ab ec cd b8 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 ea cb b7 ae 9c 91 4e 4d 4d 17 18 19 ..........................NMM...
0160 01 02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 03 0a 0b 0c 41 3b 38 c8 ae 9d ec cd ........................A;8.....
0180 b9 e6 c8 b4 00 00 e6 c8 b4 ea cc b7 b3 a0 94 43 43 44 0b 0b 0c 00 00 00 00 00 00 00 00 00 00 00 ...............CCD..............
01a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 2f 2a 26 d1 b6 a4 ea cb b7 00 00 ea cb .................../*&..........
01c0 b7 d5 bb aa 54 52 50 0c 0d 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ....TRP.........................
01e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5c 50 48 ec cd b9 00 00 ee ce ba 96 87 7e 1d 1e 1f 00 ..............\PH..........~....
0200 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
0220 00 00 00 00 00 00 09 08 07 bf a6 96 00 00 de c1 af 5a 55 51 07 07 08 00 00 00 00 00 00 00 00 00 .................ZUQ............
0240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
0260 00 7a 6a 5f 00 00 be a7 98 38 35 34 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .zj_.....854....................
0280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4d 43 3c 00 00 a8 95 .........................MC<....
02a0 87 28 26 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .(&&............................
02c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3d 35 30 00 00 aa 95 88 23 21 21 00 00 00 00 .................=50.....#!!....
02e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
0300 00 00 00 00 00 00 00 00 00 42 3a 34 00 00 c7 ad 9c 29 26 24 00 00 00 00 00 00 00 00 00 00 00 00 .........B:4.....)&$............
0320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
0340 00 5e 52 4a 00 00 e8 c9 b5 49 40 3b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .^RJ.....I@;....................
0360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 85 78 00 00 f1 d2 ...........................x....
0380 bd 99 85 78 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...x............................
03a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 1c 19 d9 bd aa 00 00 e8 ca b6 e4 c6 b2 44 3b 35 00 ............................D;5.
03c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................................
03e0 00 00 00 01 01 01 96 82 75 ed ce ba 00 00 e6 c8 b4 ea cc b7 d0 b5 a3 2a 24 21 00 00 00 00 00 00 ........u..............*$!......
0400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 62 58 eb cd ...........................pbX..
0420 b8 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 ec cd b8 cc b1 a0 44 3c 36 00 00 00 00 00 00 00 00 00 00 00 ..................D<6...........
0440 00 00 00 00 00 00 00 00 00 00 00 00 00 0e 0d 0c 82 71 66 e9 cb b6 e7 c9 b5 e6 c8 b4 00 00 e6 c8 .................qf.............
0460 b4 e6 c8 b4 e6 c8 b4 eb cc b8 e5 c8 b4 9b 87 7a 42 39 34 11 0f 0e 03 03 02 00 00 00 06 05 05 22 ...............zB94............"
0480 1d 1b 61 54 4c c1 a8 97 ed ce ba e7 c9 b5 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 ..aTL...........................
04a0 c8 b4 e7 c9 b5 ee cf ba e9 ca b6 ce b3 a1 b3 9c 8d aa 94 85 bd a5 94 da be ab ee cf ba eb cc b8 ................................
04c0 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ................................
04e0 e7 c9 b5 ea cb b7 ec cd b9 ed ce b9 eb cc b8 e8 ca b6 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 ................................
0500 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 ................................
0520 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 ................................
0540 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 ................................
0560 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 ................................
0580 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ................................
05a0 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ................................
05c0 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 ................................
05e0 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 ................................
0600 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 ................................
0620 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e7 c9 b4 e9 cb b6 eb cc b7 eb cc b7 eb cc b7 eb cc b8 ec ................................
0640 cd b8 e9 ca b6 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 ................................
0660 c8 b4 ea cb b6 e6 c8 b5 cc b5 a6 a8 99 8f 90 84 7d 81 78 71 8c 80 78 aa 98 8c d2 b8 a7 ec cd b8 ................}.xq..x.........
0680 e9 ca b6 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 ea cc b7 cb b4 a5 7f 78 73 ..............................xs
06a0 3b 3c 3c 12 15 16 0d 0e 0f 0d 0e 0e 09 0b 0c 12 14 15 36 34 33 7e 71 69 da bd ab ec cd b8 e6 c8 ;<<...............643~qi........
06c0 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e9 cb b6 b2 a1 96 46 46 45 08 09 0b 28 22 1e 75 66 5b a7 90 ..................FFE...(".uf[..
06e0 82 b6 9e 8e 98 84 76 58 4c 44 11 0f 0d 01 03 04 41 3c 37 c8 af 9e ec cd b9 e6 c8 b4 00 00 e6 c8 ......vXLD......A<7.............
0700 b4 ea cb b7 b8 a5 98 36 37 37 0f 0d 0c 87 75 69 e0 c3 af ef d0 bb ed ce ba ec cd b8 ee cf ba ee .......677....ui................
0720 cf ba c8 ae 9d 4e 43 3d 00 00 00 2e 2a 26 d1 b6 a4 ea cb b7 00 00 ea cb b6 d7 bd ab 52 50 4f 06 .....NC=....*&..............RPO.
0740 05 05 a3 8e 7f f2 d2 bd e8 ca b5 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ec cd b9 e8 ca b6 ................................
0760 53 49 41 00 00 00 5c 51 48 ec cd b9 00 00 ee ce b9 99 8c 82 0d 0f 11 5a 4e 46 ee cf bb e6 c8 b4 SIA...\QH..............ZNF......
0780 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ec cd b8 cb b0 9e 14 12 10 08 07 ................................
07a0 07 bf a6 96 00 00 df c3 b0 59 54 50 07 07 07 bc a3 93 ec cd b9 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 .........YTP....................
07c0 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ef d0 bb 6b 5e 55 00 00 00 79 69 5f 00 00 c0 a9 ...................k^U...yi_....
07e0 9a 2f 2e 2c 2c 26 22 e4 c6 b2 e7 c9 b5 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 ./.,,&".........................
0800 c8 b4 e6 c8 b4 e6 c8 b4 ed cd b9 b1 9b 8c 05 05 05 4c 42 3b 00 00 aa 97 89 1c 1c 1c 51 46 3e ec .................LB;........QF>.
0820 cd b8 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ................................
0840 e9 cb b7 ce b5 a3 20 1f 1f 3b 33 2e 00 00 ab 97 89 1c 1c 1b 43 3a 34 ea cc b7 e7 c8 b4 e6 c8 b4 .........;3.........C:4.........
0860 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ea cb b7 cc b3 a3 28 28 ..............................((
0880 28 40 38 32 00 00 c8 ae 9d 27 23 22 18 15 13 d8 bc a9 e9 ca b6 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 (@82.....'#"....................
08a0 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ec cd b8 ae 9b 8f 12 14 16 5b 4f 47 00 00 e8 c9 .........................[OG....
08c0 b5 49 41 3b 00 00 00 98 84 77 ef d0 bb e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 .IA;.....w......................
08e0 c8 b4 e6 c8 b4 e7 c8 b4 e9 cb b6 77 6f 6a 01 03 04 98 84 76 00 00 f1 d2 bd 99 85 78 00 00 00 2b ...........woj.....v.......x...+
0900 26 22 dc c0 ac eb cc b7 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ed cd b8 &"..............................
0920 c0 ab 9d 2e 2e 2f 1e 1a 16 d9 bd aa 00 00 e8 ca b6 e4 c6 b2 43 3a 35 00 00 00 5f 54 4d e1 c4 b1 ...../..............C:5..._TM...
0940 ed ce b9 e8 ca b5 e6 c8 b4 e6 c8 b4 e6 c8 b4 e9 ca b6 ec cc b8 cf b8 a8 5c 59 57 02 03 04 95 81 ........................\YW.....
0960 74 ed ce ba 00 00 e6 c8 b4 ea cc b7 d0 b5 a3 29 23 20 02 04 05 4d 47 44 ad 99 8c dd c1 ae eb cc t..............)#....MGD........
0980 b7 eb cc b8 e8 ca b6 d8 be ad a6 98 8f 4e 4d 4c 06 07 08 6e 60 56 eb cd b8 e6 c8 b4 00 00 e6 c8 .............NML...n`V..........
09a0 b4 e6 c8 b4 ec cd b8 cc b1 a0 43 3a 35 01 02 02 16 18 19 49 46 44 78 6f 69 8f 83 7c 7a 73 6e 4b ..........C:5......IFDxoi..|zsnK
09c0 4b 4a 18 1a 1b 0f 0e 0d 80 70 64 e9 cb b7 e7 c9 b5 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 eb KJ.......pd.....................
09e0 cc b8 e5 c8 b4 9a 86 79 3f 37 31 10 0f 0e 09 09 0a 0d 0e 0f 0c 0c 0c 20 1c 19 5d 51 48 c1 a7 97 .......y?71...............]QH...
0a00 ed ce ba e7 c9 b5 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e7 c9 b5 ee cf ba ................................
0a20 e9 ca b6 cd b3 a1 b2 9b 8b a8 92 83 bc a3 93 da bd ab ee cf ba eb cc b8 e6 c8 b4 e6 c8 b4 e6 c8 ................................
0a40 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e7 c9 b5 ea cb b7 ec cd ................................
0a60 b9 ed ce b9 eb cc b8 e8 ca b6 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 ................................
0a80 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 ................................
0aa0 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 ................................
0ac0 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ................................
0ae0 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 00 00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 ................................
0b00 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 b4 e6 c8 ................................
0b20 b4 e6 c8 b4 00 00 ......
> 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
#include "plugin.h"
#include "lib/helper.h"
#include "lib/configfile.h"

#include "mpegplayer.h"
#include "mpeg_settings.h"

struct mpeg_settings settings;

#define THUMB_DELAY (75*HZ/100)

/* button definitions */
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
    (CONFIG_KEYPAD == IRIVER_H300_PAD)
#define MPEG_START_TIME_SELECT      BUTTON_ON
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_EXIT        BUTTON_OFF

#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
#define MPEG_START_TIME_SELECT      BUTTON_PLAY
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
      (CONFIG_KEYPAD == IPOD_3G_PAD) || \
      (CONFIG_KEYPAD == IPOD_1G2G_PAD)
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_UP          BUTTON_SCROLL_FWD
#define MPEG_START_TIME_DOWN        BUTTON_SCROLL_BACK
#define MPEG_START_TIME_EXIT        BUTTON_MENU

#elif CONFIG_KEYPAD == GIGABEAT_PAD
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_VOL_DOWN
#define MPEG_START_TIME_SCROLL_UP   BUTTON_VOL_UP
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#define MPEG_START_TIME_RC_SELECT      (BUTTON_RC_PLAY | BUTTON_REL)
#define MPEG_START_TIME_RC_LEFT        BUTTON_RC_REW
#define MPEG_START_TIME_RC_RIGHT       BUTTON_RC_FF
#define MPEG_START_TIME_RC_UP          BUTTON_RC_VOL_UP
#define MPEG_START_TIME_RC_DOWN        BUTTON_RC_VOL_DOWN
#define MPEG_START_TIME_RC_EXIT        (BUTTON_RC_PLAY | BUTTON_REPEAT)

#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_VOL_DOWN
#define MPEG_START_TIME_SCROLL_UP   BUTTON_VOL_UP
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#define MPEG_START_TIME_RC_SELECT      (BUTTON_RC_PLAY | BUTTON_REL)
#define MPEG_START_TIME_RC_LEFT        BUTTON_RC_REW
#define MPEG_START_TIME_RC_RIGHT       BUTTON_RC_FF
#define MPEG_START_TIME_RC_UP          BUTTON_RC_VOL_UP
#define MPEG_START_TIME_RC_DOWN        BUTTON_RC_VOL_DOWN
#define MPEG_START_TIME_RC_EXIT        (BUTTON_RC_PLAY | BUTTON_REPEAT)

#elif CONFIG_KEYPAD == IRIVER_H10_PAD
#define MPEG_START_TIME_SELECT      BUTTON_PLAY
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_SCROLL_UP
#define MPEG_START_TIME_DOWN        BUTTON_SCROLL_DOWN
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif (CONFIG_KEYPAD == SANSA_E200_PAD)
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_SCROLL_UP   BUTTON_SCROLL_BACK
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_SCROLL_FWD
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_SCROLL_UP   BUTTON_SCROLL_BACK
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_SCROLL_FWD
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_EXIT        (BUTTON_HOME|BUTTON_REPEAT)

#elif (CONFIG_KEYPAD == SANSA_C200_PAD) || \
(CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
(CONFIG_KEYPAD == SANSA_M200_PAD)
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_SCROLL_UP   BUTTON_VOL_UP
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_VOL_DOWN
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif CONFIG_KEYPAD == MROBE500_PAD
#define MPEG_START_TIME_SELECT      BUTTON_RC_HEART
#define MPEG_START_TIME_SCROLL_UP   BUTTON_RC_VOL_UP
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_RC_VOL_DOWN
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_RC_PLAY
#define MPEG_START_TIME_DOWN        BUTTON_RC_DOWN
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif CONFIG_KEYPAD == MROBE100_PAD
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_MENU
#define MPEG_START_TIME_SCROLL_UP   BUTTON_PLAY
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
#define MPEG_START_TIME_SELECT      BUTTON_RC_PLAY
#define MPEG_START_TIME_LEFT        BUTTON_RC_REW
#define MPEG_START_TIME_RIGHT       BUTTON_RC_FF
#define MPEG_START_TIME_UP          BUTTON_RC_VOL_UP
#define MPEG_START_TIME_DOWN        BUTTON_RC_VOL_DOWN
#define MPEG_START_TIME_EXIT        BUTTON_RC_REC

#elif CONFIG_KEYPAD == COWOND2_PAD
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif CONFIG_KEYPAD == IAUDIO67_PAD
#define MPEG_START_TIME_SELECT      BUTTON_MENU
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_STOP
#define MPEG_START_TIME_DOWN        BUTTON_PLAY
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_SCROLL_UP   BUTTON_PLAY
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_MENU
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_EXIT        BUTTON_BACK

#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
#define MPEG_START_TIME_SELECT      BUTTON_SELECT
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_VOL_DOWN
#define MPEG_START_TIME_SCROLL_UP   BUTTON_VOL_UP
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif CONFIG_KEYPAD == ONDAVX747_PAD
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif CONFIG_KEYPAD == ONDAVX777_PAD
#define MPEG_START_TIME_EXIT        BUTTON_POWER

#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
#define MPEG_START_TIME_SELECT      BUTTON_PLAY
#define MPEG_START_TIME_LEFT        BUTTON_LEFT
#define MPEG_START_TIME_RIGHT       BUTTON_RIGHT
#define MPEG_START_TIME_UP          BUTTON_UP
#define MPEG_START_TIME_DOWN        BUTTON_DOWN
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_FFWD
#define MPEG_START_TIME_SCROLL_UP   BUTTON_REW
#define MPEG_START_TIME_EXIT        BUTTON_REC

#else
#error No keymap defined!
#endif

#ifdef HAVE_TOUCHSCREEN
#ifndef MPEG_START_TIME_SELECT
#define MPEG_START_TIME_SELECT      BUTTON_CENTER
#endif
#ifndef MPEG_START_TIME_SCROLL_UP
#define MPEG_START_TIME_SCROLL_UP   BUTTON_TOPRIGHT
#endif
#ifndef MPEG_START_TIME_SCROLL_DOWN
#define MPEG_START_TIME_SCROLL_DOWN BUTTON_TOPLEFT
#endif
#ifndef MPEG_START_TIME_LEFT
#define MPEG_START_TIME_LEFT        BUTTON_MIDLEFT
#endif
#ifndef MPEG_START_TIME_RIGHT
#define MPEG_START_TIME_RIGHT       BUTTON_MIDRIGHT
#endif
#ifndef MPEG_START_TIME_UP
#define MPEG_START_TIME_UP          BUTTON_TOPMIDDLE
#endif
#ifndef MPEG_START_TIME_DOWN
#define MPEG_START_TIME_DOWN        BUTTON_BOTTOMMIDDLE
#endif
#ifndef MPEG_START_TIME_EXIT
#define MPEG_START_TIME_EXIT        BUTTON_TOPLEFT
#endif
#endif

static struct configdata config[] =
{
    {TYPE_INT, 0, 2, { .int_p = &settings.showfps }, "Show FPS", NULL},
    {TYPE_INT, 0, 2, { .int_p = &settings.limitfps }, "Limit FPS", NULL},
    {TYPE_INT, 0, 2, { .int_p = &settings.skipframes }, "Skip frames", NULL},
    {TYPE_INT, 0, INT_MAX, { .int_p = &settings.resume_count }, "Resume count",
     NULL},
    {TYPE_INT, 0, MPEG_RESUME_NUM_OPTIONS,
     { .int_p = &settings.resume_options }, "Resume options", NULL},
#if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) || defined(SANSA_FUZE) || defined(SANSA_E200V2)
    {TYPE_INT, 0, INT_MAX, { .int_p = &settings.displayoptions },
     "Display options", NULL},
#endif
    {TYPE_INT, 0, 2, { .int_p = &settings.tone_controls }, "Tone controls",
     NULL},
    {TYPE_INT, 0, 2, { .int_p = &settings.channel_modes }, "Channel modes",
     NULL},
    {TYPE_INT, 0, 2, { .int_p = &settings.crossfeed }, "Crossfeed", NULL},
    {TYPE_INT, 0, 2, { .int_p = &settings.equalizer }, "Equalizer", NULL},
    {TYPE_INT, 0, 2, { .int_p = &settings.dithering }, "Dithering", NULL},
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
    {TYPE_INT, -1, INT_MAX, { .int_p = &settings.backlight_brightness },
     "Backlight brightness", NULL},
#endif
};

static const struct opt_items noyes[2] = {
    { "No", -1 },
    { "Yes", -1 },
};

static const struct opt_items enabledisable[2] = {
    { "Disable", -1 },
    { "Enable", -1 },
};

static const struct opt_items globaloff[2] = {
    { "Force off", -1 },
    { "Use sound setting", -1 },
};

#ifdef HAVE_BACKLIGHT_BRIGHTNESS
#define BACKLIGHT_OPTION_DEFAULT "Use setting"
#endif

static void mpeg_settings(void);
static long mpeg_menu_sysevent_id;

void mpeg_menu_sysevent_clear(void)
{
    mpeg_menu_sysevent_id = 0;
}

int mpeg_menu_sysevent_callback(int btn, const struct menu_item_ex *menu)
{
    switch (btn)
    {
    case SYS_USB_CONNECTED:
    case SYS_POWEROFF:
        mpeg_menu_sysevent_id = btn;
        return ACTION_STD_CANCEL;
    }

    return btn;
    (void)menu;
}

long mpeg_menu_sysevent(void)
{
    return mpeg_menu_sysevent_id;
}

void mpeg_menu_sysevent_handle(void)
{
    long id = mpeg_menu_sysevent();
    if (id != 0)
        rb->default_event_handler(id);
}

static bool mpeg_set_option(const char* string,
                            void* variable,
                            enum optiontype type,
                            const struct opt_items* options,
                            int numoptions,
                            void (*function)(int))
{
    mpeg_menu_sysevent_clear();

    /* This eats SYS_POWEROFF - :\ */
    bool usb = rb->set_option(string, variable, type, options, numoptions,
                              function);

    if (usb)
        mpeg_menu_sysevent_id = ACTION_STD_CANCEL;

    return usb;
}

#ifdef HAVE_BACKLIGHT_BRIGHTNESS /* Only used for this atm */
static bool mpeg_set_int(const char *string, const char *unit,
                         int voice_unit, const int *variable,
                         void (*function)(int), int step,
                         int min,
                         int max,
                         const char* (*formatter)(char*, size_t, int, const char*))
{
    mpeg_menu_sysevent_clear();

    bool usb = rb->set_int(string, unit, voice_unit, variable, function,
                           step, min, max, formatter);

    if (usb)
        mpeg_menu_sysevent_id = ACTION_STD_CANCEL;

    return usb;
}
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */

#ifdef HAVE_BACKLIGHT_BRIGHTNESS
void mpeg_backlight_update_brightness(int value)
{
    if (value >= 0)
    {
        value += MIN_BRIGHTNESS_SETTING;
        backlight_brightness_set(value);
    }
    else
    {
        backlight_brightness_use_setting();
    }
}

static void backlight_brightness_function(int value)
{
    mpeg_backlight_update_brightness(value);
}

static const char* backlight_brightness_formatter(char *buf, size_t length,
                                                  int value, const char *input)
{
    (void)input;

    if (value < 0)
        return BACKLIGHT_OPTION_DEFAULT;
    else
        rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING);
    return buf;
}
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */

/* Sync a particular audio setting to global or mpegplayer forced off */
static void sync_audio_setting(int setting, bool global)
{
    int val0, val1;

    switch (setting)
    {
    case MPEG_AUDIO_TONE_CONTROLS:
        if (global || settings.tone_controls)
        {
            val0 = rb->global_settings->bass;
            val1 = rb->global_settings->treble;
        }
        else
        {
            val0 = rb->sound_default(SOUND_BASS);
            val1 = rb->sound_default(SOUND_TREBLE);
        }
        rb->sound_set(SOUND_BASS, val0);
        rb->sound_set(SOUND_TREBLE, val1);
        break;

    case MPEG_AUDIO_CHANNEL_MODES:
        val0 = (global || settings.channel_modes) ?
                rb->global_settings->channel_config :
                SOUND_CHAN_STEREO;
        rb->sound_set(SOUND_CHANNELS, val0);
        break;

    case MPEG_AUDIO_CROSSFEED:
        rb->dsp_set_crossfeed((global || settings.crossfeed) ?
                              rb->global_settings->crossfeed : false);
        break;

    case MPEG_AUDIO_EQUALIZER:
        rb->dsp_set_eq((global || settings.equalizer) ?
                       rb->global_settings->eq_enabled : false);
        break;

    case MPEG_AUDIO_DITHERING:
        rb->dsp_dither_enable((global || settings.dithering) ?
                              rb->global_settings->dithering_enabled : false);
       break;
    }
}

/* Sync all audio settings to global or mpegplayer forced off */
static void sync_audio_settings(bool global)
{
    static const int setting_index[] =
    {
        MPEG_AUDIO_TONE_CONTROLS,
        MPEG_AUDIO_CHANNEL_MODES,
        MPEG_AUDIO_CROSSFEED,
        MPEG_AUDIO_EQUALIZER,
        MPEG_AUDIO_DITHERING,
    };
    unsigned i;

    for (i = 0; i < ARRAYLEN(setting_index); i++)
    {
        sync_audio_setting(setting_index[i], global);
    }
}

#ifndef HAVE_LCD_COLOR
/* Cheapo splash implementation for the grey surface */
static void grey_splash(int ticks, const unsigned char *fmt, ...)
{
    unsigned char buffer[256];
    int x, y, w, h;
    int oldfg, oldmode;

    va_list ap;
    va_start(ap, fmt);

    rb->vsnprintf(buffer, sizeof (buffer), fmt, ap);

    va_end(ap);

    grey_getstringsize(buffer, &w, &h);

    oldfg = grey_get_foreground();
    oldmode = grey_get_drawmode();

    grey_set_drawmode(DRMODE_FG);
    grey_set_foreground(GREY_LIGHTGRAY);

    x = (LCD_WIDTH - w) / 2;
    y = (LCD_HEIGHT - h) / 2;

    grey_fillrect(x - 1, y - 1, w + 2, h + 2);

    grey_set_foreground(GREY_BLACK);

    grey_putsxy(x, y, buffer);
    grey_drawrect(x - 2, y - 2, w + 4, h + 4);

    grey_set_foreground(oldfg);
    grey_set_drawmode(oldmode);

    grey_update();

    if (ticks > 0)
        rb->sleep(ticks);
}
#endif /* !HAVE_LCD_COLOR */

static void show_loading(struct vo_rect *rc)
{
    int oldmode = lcd_(get_drawmode)();
    lcd_(set_drawmode)(DRMODE_SOLID | DRMODE_INVERSEVID);
    lcd_(fillrect)(rc->l-1, rc->t-1, rc->r - rc->l + 2, rc->b - rc->t + 2);
    lcd_(set_drawmode)(oldmode);
    lcd_(splash)(0, "Loading...");
}

static void draw_slider(uint32_t range, uint32_t pos, struct vo_rect *rc)
{
    #define SLIDER_WIDTH   (LCD_WIDTH-SLIDER_LMARGIN-SLIDER_RMARGIN)
    #define SLIDER_X       SLIDER_LMARGIN
    #define SLIDER_Y       (LCD_HEIGHT-SLIDER_HEIGHT-SLIDER_BMARGIN)
    #define SLIDER_HEIGHT  8
    #define SLIDER_TEXTMARGIN 1
    #define SLIDER_LMARGIN 1
    #define SLIDER_RMARGIN 1
    #define SLIDER_TMARGIN 1
    #define SLIDER_BMARGIN 1
    #define SCREEN_MARGIN  1

    struct hms hms;
    char str[32];
    int text_w, text_h, text_y;

    /* Put positition on left */
    ts_to_hms(pos, &hms);
    hms_format(str, sizeof(str), &hms);
    lcd_(getstringsize)(str, NULL, &text_h);
    text_y = SLIDER_Y - SLIDER_TEXTMARGIN - text_h;

    if (rc == NULL)
    {
        int oldmode = lcd_(get_drawmode)();
        lcd_(set_drawmode)(DRMODE_BG | DRMODE_INVERSEVID);
        lcd_(fillrect)(SLIDER_X, text_y, SLIDER_WIDTH,
                       LCD_HEIGHT - SLIDER_BMARGIN - text_y
                       - SLIDER_TMARGIN);
        lcd_(set_drawmode)(oldmode);

        lcd_(putsxy)(SLIDER_X, text_y, str);

        /* Put duration on right */
        ts_to_hms(range, &hms);
        hms_format(str, sizeof(str), &hms);
        lcd_(getstringsize)(str, &text_w, NULL);

        lcd_(putsxy)(SLIDER_X + SLIDER_WIDTH - text_w, text_y, str);

        /* Draw slider */
        lcd_(drawrect)(SLIDER_X, SLIDER_Y, SLIDER_WIDTH, SLIDER_HEIGHT);
        lcd_(fillrect)(SLIDER_X, SLIDER_Y,
                       muldiv_uint32(pos, SLIDER_WIDTH, range),
                       SLIDER_HEIGHT);

        /* Update screen */
        lcd_(update_rect)(SLIDER_X, text_y - SLIDER_TMARGIN, SLIDER_WIDTH,
                          LCD_HEIGHT - SLIDER_BMARGIN - text_y + SLIDER_TEXTMARGIN);
    }
    else
    {
        /* Just return slider rectangle */
        rc->l = SLIDER_X;
        rc->t = text_y - SLIDER_TMARGIN;
        rc->r = rc->l + SLIDER_WIDTH;
        rc->b = rc->t + LCD_HEIGHT - SLIDER_BMARGIN - text_y;
    }
}

static bool display_thumb_image(const struct vo_rect *rc)
{
    if (!stream_display_thumb(rc))
    {
        lcd_(splash)(0, "Frame not available");
        return false;
    }

    /* Draw a raised border around the frame */
    int oldcolor = lcd_(get_foreground)();
    lcd_(set_foreground)(DRAW_LIGHTGRAY);

    lcd_(hline)(rc->l-1, rc->r-1, rc->t-1);
    lcd_(vline)(rc->l-1, rc->t, rc->b-1);

    lcd_(set_foreground)(DRAW_DARKGRAY);

    lcd_(hline)(rc->l-1, rc->r, rc->b);
    lcd_(vline)(rc->r, rc->t-1, rc->b);

    lcd_(set_foreground)(oldcolor);

    lcd_(update_rect)(rc->l-1, rc->t-1, rc->r - rc->l + 2, 1);
    lcd_(update_rect)(rc->l-1, rc->t, 1, rc->b - rc->t);
    lcd_(update_rect)(rc->l-1, rc->b, rc->r - rc->l + 2, 1);
    lcd_(update_rect)(rc->r, rc->t, 1, rc->b - rc->t);

    return true;
}

/* Add an amount to the specified time - with saturation */
static uint32_t increment_time(uint32_t val, int32_t amount, uint32_t range)
{
    if (amount < 0)
    {
        uint32_t off = -amount;
        if (range > off && val >= off)
            val -= off;
        else
            val = 0;
    }
    else if (amount > 0)
    {
        uint32_t off = amount;
        if (range > off && val <= range - off)
            val += off;
        else
            val = range;
    }

    return val;
}

#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
static void get_start_time_lcd_enable_hook(void *param)
{
    (void)param;
    rb->queue_post(rb->button_queue, LCD_ENABLE_EVENT_0, 0);
}
#endif /* HAVE_LCD_ENABLE */

static int get_start_time(uint32_t duration)
{
    int button = 0;
    int tmo = TIMEOUT_NOBLOCK;
    uint32_t resume_time = settings.resume_time;
    struct vo_rect rc_vid, rc_bound;
    uint32_t aspect_vid, aspect_bound;

    enum state_enum slider_state = state0;

    lcd_(clear_display)();
    lcd_(update)();

#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
    rb->add_event(LCD_EVENT_ACTIVATION, false, get_start_time_lcd_enable_hook);
#endif

    draw_slider(0, 100, &rc_bound);
    rc_bound.b = rc_bound.t - SLIDER_TMARGIN;
    rc_bound.t = SCREEN_MARGIN;

    DEBUGF("rc_bound: %d, %d, %d, %d\n", rc_bound.l, rc_bound.t,
           rc_bound.r, rc_bound.b);

    rc_vid.l = rc_vid.t = 0;
    if (!stream_vo_get_size((struct vo_ext *)&rc_vid.r))
    {
        /* Can't get size - fill whole thing */
        rc_vid.r = rc_bound.r - rc_bound.l;
        rc_vid.b = rc_bound.b - rc_bound.t;
    }

    /* Get aspect ratio of bounding rectangle and video in u16.16 */
    aspect_bound = ((rc_bound.r - rc_bound.l) << 16) /
                    (rc_bound.b - rc_bound.t);

    DEBUGF("aspect_bound: %u.%02u\n", (unsigned)(aspect_bound >> 16),
           (unsigned)(100*(aspect_bound & 0xffff) >> 16));

    aspect_vid = (rc_vid.r << 16) / rc_vid.b;

    DEBUGF("aspect_vid: %u.%02u\n", (unsigned)(aspect_vid >> 16),
           (unsigned)(100*(aspect_vid & 0xffff) >> 16));

    if (aspect_vid >= aspect_bound)
    {
        /* Video proportionally wider than or same as bounding rectangle */
        if (rc_vid.r > rc_bound.r - rc_bound.l)
        {
            rc_vid.r = rc_bound.r - rc_bound.l;
            rc_vid.b = (rc_vid.r << 16) / aspect_vid;
        }
        /* else already fits */
    }
    else
    {
        /* Video proportionally narrower than bounding rectangle */
        if (rc_vid.b > rc_bound.b - rc_bound.t)
        {
            rc_vid.b = rc_bound.b - rc_bound.t;
            rc_vid.r = (aspect_vid * rc_vid.b) >> 16;
        }
        /* else already fits */
    }

    /* Even width and height >= 2 */
    rc_vid.r = (rc_vid.r < 2) ? 2 : (rc_vid.r & ~1);
    rc_vid.b = (rc_vid.b < 2) ? 2 : (rc_vid.b & ~1);

    /* Center display in bounding rectangle */
    rc_vid.l = ((rc_bound.l + rc_bound.r) - rc_vid.r) / 2;
    rc_vid.r += rc_vid.l;

    rc_vid.t = ((rc_bound.t + rc_bound.b) - rc_vid.b) / 2;
    rc_vid.b += rc_vid.t;

    DEBUGF("rc_vid: %d, %d, %d, %d\n", rc_vid.l, rc_vid.t,
           rc_vid.r, rc_vid.b);

#ifndef HAVE_LCD_COLOR
    stream_gray_show(true);
#endif

    while (slider_state < state9)
    {
        mpeg_menu_sysevent_clear();
        button = tmo == TIMEOUT_BLOCK ?
            rb->button_get(true) : rb->button_get_w_tmo(tmo);

        button = mpeg_menu_sysevent_callback(button, NULL);

        switch (button)
        {
        case BUTTON_NONE:
            break;

        /* Coarse (1 minute) control */
        case MPEG_START_TIME_DOWN:
        case MPEG_START_TIME_DOWN | BUTTON_REPEAT:
#ifdef MPEG_START_TIME_RC_DOWN
        case MPEG_START_TIME_RC_DOWN:
        case MPEG_START_TIME_RC_DOWN | BUTTON_REPEAT:
#endif
            resume_time = increment_time(resume_time, -60*TS_SECOND, duration);
            slider_state = state0;
            break;

        case MPEG_START_TIME_UP:
        case MPEG_START_TIME_UP | BUTTON_REPEAT:
#ifdef MPEG_START_TIME_RC_UP
        case MPEG_START_TIME_RC_UP:
        case MPEG_START_TIME_RC_UP | BUTTON_REPEAT:
#endif
            resume_time = increment_time(resume_time, 60*TS_SECOND, duration);
            slider_state = state0;
            break;

        /* Fine (1 second) control */
        case MPEG_START_TIME_LEFT:
        case MPEG_START_TIME_LEFT | BUTTON_REPEAT:
#ifdef MPEG_START_TIME_RC_LEFT
        case MPEG_START_TIME_RC_LEFT:
        case MPEG_START_TIME_RC_LEFT | BUTTON_REPEAT:
#endif
#ifdef MPEG_START_TIME_SCROLL_UP
        case MPEG_START_TIME_SCROLL_UP:
        case MPEG_START_TIME_SCROLL_UP | BUTTON_REPEAT:
#endif
            resume_time = increment_time(resume_time, -TS_SECOND, duration);
            slider_state = state0;
            break;

        case MPEG_START_TIME_RIGHT:
        case MPEG_START_TIME_RIGHT | BUTTON_REPEAT:
#ifdef MPEG_START_TIME_RC_RIGHT
        case MPEG_START_TIME_RC_RIGHT:
        case MPEG_START_TIME_RC_RIGHT | BUTTON_REPEAT:
#endif
#ifdef MPEG_START_TIME_SCROLL_DOWN
        case MPEG_START_TIME_SCROLL_DOWN:
        case MPEG_START_TIME_SCROLL_DOWN | BUTTON_REPEAT:
#endif
            resume_time = increment_time(resume_time, TS_SECOND, duration);
            slider_state = state0;
            break;

        case MPEG_START_TIME_SELECT:
#ifdef MPEG_START_TIME_RC_SELECT
        case MPEG_START_TIME_RC_SELECT:
#endif
            settings.resume_time = resume_time;
            button = MPEG_START_SEEK;
            slider_state = state9;
            break;

        case MPEG_START_TIME_EXIT:
#ifdef MPEG_START_TIME_RC_EXIT
        case MPEG_START_TIME_RC_EXIT:
#endif
            button = MPEG_START_EXIT;
            slider_state = state9;
            break;

        case ACTION_STD_CANCEL:
            button = MPEG_START_QUIT;
            slider_state = state9;
            break;

#ifdef HAVE_LCD_ENABLE
        case LCD_ENABLE_EVENT_0:
            if (slider_state == state2)
                display_thumb_image(&rc_vid);
            continue;
#endif

        default:
            rb->default_event_handler(button);
            rb->yield();
            continue;
        }

        switch (slider_state)
        {
        case state0:
            trigger_cpu_boost();
            stream_seek(resume_time, SEEK_SET);
            show_loading(&rc_bound);
            draw_slider(duration, resume_time, NULL);
            slider_state = state1;
            tmo = THUMB_DELAY;
            break;
        case state1:
            display_thumb_image(&rc_vid);
            slider_state = state2;
        case state2:
            cancel_cpu_boost();
            tmo = TIMEOUT_BLOCK;
        default:
            break;
        }

        rb->yield();
    }

#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
    rb->remove_event(LCD_EVENT_ACTIVATION, get_start_time_lcd_enable_hook);
#endif
#ifndef HAVE_LCD_COLOR
    stream_gray_show(false);
    grey_clear_display();
    grey_update();
#endif

    cancel_cpu_boost();

    return button;
}

static int show_start_menu(uint32_t duration)
{
    int selected = 0;
    int result = 0;
    bool menu_quit = false;

    /* add the resume time to the menu display */
    static char resume_str[32];
    char hms_str[32];
    struct hms hms;

    MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_menu_sysevent_callback,
                        "Play from beginning", resume_str, "Set start time",
                        "Settings", "Quit mpegplayer");

    ts_to_hms(settings.resume_time, &hms);
    hms_format(hms_str, sizeof(hms_str), &hms);
    rb->snprintf(resume_str, sizeof (resume_str),
                     "Resume at: %s", hms_str);

    rb->button_clear_queue();

    while (!menu_quit)
    {
        mpeg_menu_sysevent_clear();
        result = rb->do_menu(&menu, &selected, NULL, false);

        switch (result)
        {
        case MPEG_START_RESTART:
            settings.resume_time = 0;
            menu_quit = true;
            break;

        case MPEG_START_RESUME:
            menu_quit = true;
            break;

        case MPEG_START_SEEK:
            if (!stream_can_seek())
            {
                rb->splash(HZ, "Unavailable");
                break;
            }

            result = get_start_time(duration);

            if (result != MPEG_START_EXIT)
                menu_quit = true;
            break;

        case MPEG_START_SETTINGS:
            mpeg_settings();
            break;

        default:
            result = MPEG_START_QUIT;
            menu_quit = true;
            break;
        }

        if (mpeg_menu_sysevent() != 0)
        {
            result = MPEG_START_QUIT;
            menu_quit = true;
        }
    }

    rb->lcd_clear_display();
    rb->lcd_update();

    return result;
}

/* Return the desired resume action */
int mpeg_start_menu(uint32_t duration)
{
    mpeg_menu_sysevent_clear();

    switch (settings.resume_options)
    {
    case MPEG_RESUME_MENU_IF_INCOMPLETE:
        if (!stream_can_seek() || settings.resume_time == 0)
        {
    case MPEG_RESUME_RESTART:
            settings.resume_time = 0;
            return MPEG_START_RESTART;
        }
    default:
    case MPEG_RESUME_MENU_ALWAYS:
        return show_start_menu(duration);
    case MPEG_RESUME_ALWAYS:
        return MPEG_START_SEEK;
    }
}

int mpeg_menu(void)
{
    int result;

    MENUITEM_STRINGLIST(menu, "Mpegplayer Menu", mpeg_menu_sysevent_callback,
                        "Settings", "Resume playback", "Quit mpegplayer");

    rb->button_clear_queue();

    mpeg_menu_sysevent_clear();

    result = rb->do_menu(&menu, NULL, NULL, false);

    switch (result)
    {
    case MPEG_MENU_SETTINGS:
        mpeg_settings();
        break;

    case MPEG_MENU_RESUME:
        break;

    case MPEG_MENU_QUIT:
        break;

    default:
        break;
    }

    if (mpeg_menu_sysevent() != 0)
        result = MPEG_MENU_QUIT;

    rb->lcd_clear_display();
    rb->lcd_update();

    return result;
}

/** MPEG Menu **/
static void display_options(void)
{
    int selected = 0;
    int result;
    bool menu_quit = false;

    MENUITEM_STRINGLIST(menu, "Display Options", mpeg_menu_sysevent_callback,
#if MPEG_OPTION_DITHERING_ENABLED
                        "Dithering",
#endif
                        "Display FPS", "Limit FPS", "Skip frames",
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
                        "Backlight brightness",
#endif
                        );

    rb->button_clear_queue();

    while (!menu_quit)
    {
        mpeg_menu_sysevent_clear();
        result = rb->do_menu(&menu, &selected, NULL, false);

        switch (result)
        {
#if MPEG_OPTION_DITHERING_ENABLED
        case MPEG_OPTION_DITHERING:
            result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0;
            mpeg_set_option("Dithering", &result, INT, noyes, 2, NULL);
            settings.displayoptions =
                (settings.displayoptions & ~LCD_YUV_DITHER)
                      | ((result != 0) ? LCD_YUV_DITHER : 0);
            rb->lcd_yuv_set_options(settings.displayoptions);
            break;
#endif /* MPEG_OPTION_DITHERING_ENABLED */

        case MPEG_OPTION_DISPLAY_FPS:
            mpeg_set_option("Display FPS", &settings.showfps, INT,
                            noyes, 2, NULL);
            break;

        case MPEG_OPTION_LIMIT_FPS:
            mpeg_set_option("Limit FPS", &settings.limitfps, INT,
                            noyes, 2, NULL);
            break;

        case MPEG_OPTION_SKIP_FRAMES:
            mpeg_set_option("Skip frames", &settings.skipframes, INT,
                            noyes, 2, NULL);
            break;

#ifdef HAVE_BACKLIGHT_BRIGHTNESS
        case MPEG_OPTION_BACKLIGHT_BRIGHTNESS:
            result = settings.backlight_brightness;
            mpeg_backlight_update_brightness(result);
            mpeg_set_int("Backlight brightness", NULL, -1, &result,
                         backlight_brightness_function, 1, -1,
                         MAX_BRIGHTNESS_SETTING - MIN_BRIGHTNESS_SETTING,
                         backlight_brightness_formatter);
            settings.backlight_brightness = result;
            mpeg_backlight_update_brightness(-1);
            break;
#endif /* HAVE_BACKLIGHT_BRIGHTNESS */

        default:
            menu_quit = true;
            break;
        }

        if (mpeg_menu_sysevent() != 0)
            menu_quit = true;
    }
}

static void audio_options(void)
{
    int selected = 0;
    int result;
    bool menu_quit = false;

    MENUITEM_STRINGLIST(menu, "Audio Options", mpeg_menu_sysevent_callback,
                        "Tone Controls", "Channel Modes", "Crossfeed",
                        "Equalizer", "Dithering");

    rb->button_clear_queue();

    while (!menu_quit)
    {
        mpeg_menu_sysevent_clear();
        result = rb->do_menu(&menu, &selected, NULL, false);

        switch (result)
        {
        case MPEG_AUDIO_TONE_CONTROLS:
            mpeg_set_option("Tone Controls", &settings.tone_controls, INT,
                            globaloff, 2, NULL);
            sync_audio_setting(result, false);
            break;

        case MPEG_AUDIO_CHANNEL_MODES:
            mpeg_set_option("Channel Modes", &settings.channel_modes,
                            INT, globaloff, 2, NULL);
            sync_audio_setting(result, false);
            break;

        case MPEG_AUDIO_CROSSFEED:
            mpeg_set_option("Crossfeed", &settings.crossfeed, INT,
                            globaloff, 2, NULL);
            sync_audio_setting(result, false);
            break;

        case MPEG_AUDIO_EQUALIZER:
            mpeg_set_option("Equalizer", &settings.equalizer, INT,
                            globaloff, 2, NULL);
            sync_audio_setting(result, false);
            break;

        case MPEG_AUDIO_DITHERING:
            mpeg_set_option("Dithering", &settings.dithering, INT,
                            globaloff, 2, NULL);
            sync_audio_setting(result, false);
            break;

        default:
            menu_quit = true;
            break;
        }

        if (mpeg_menu_sysevent() != 0)
            menu_quit = true;
    }
}

static void resume_options(void)
{
    static const struct opt_items items[MPEG_RESUME_NUM_OPTIONS] = {
        [MPEG_RESUME_MENU_ALWAYS] =
            { "Start menu", -1 },
        [MPEG_RESUME_MENU_IF_INCOMPLETE] =
            { "Start menu if not completed", -1 },
        [MPEG_RESUME_ALWAYS] =
            { "Resume automatically", -1 },
        [MPEG_RESUME_RESTART] =
            { "Play from beginning", -1 },
    };

    mpeg_set_option("Resume Options", &settings.resume_options,
                    INT, items, MPEG_RESUME_NUM_OPTIONS, NULL);
}

static void clear_resume_count(void)
{
    configfile_save(SETTINGS_FILENAME, config, ARRAYLEN(config),
                    SETTINGS_VERSION);

    settings.resume_count = 0;

    /* add this place holder so the count is above resume entries */
    configfile_update_entry(SETTINGS_FILENAME, "Resume count", 0);
}

static void mpeg_settings(void)
{
    int selected = 0;
    int result;
    bool menu_quit = false;
    static char clear_str[32];

    MENUITEM_STRINGLIST(menu, "Settings", mpeg_menu_sysevent_callback,
                        "Display Options", "Audio Options",
                        "Resume Options", clear_str);

    rb->button_clear_queue();

    while (!menu_quit)
    {
        mpeg_menu_sysevent_clear();

        /* Format and add resume option to the menu display */
        rb->snprintf(clear_str, sizeof(clear_str),
                     "Clear all resumes: %u", settings.resume_count);

        result = rb->do_menu(&menu, &selected, NULL, false);

        switch (result)
        {
        case MPEG_SETTING_DISPLAY_SETTINGS:
            display_options();
            break;

        case MPEG_SETTING_AUDIO_SETTINGS:
            audio_options();
            break;

        case MPEG_SETTING_ENABLE_START_MENU:
            resume_options();
            break;

        case MPEG_SETTING_CLEAR_RESUMES:
            clear_resume_count();
            break;

        default:
            menu_quit = true;
            break;
        }

        if (mpeg_menu_sysevent() != 0)
            menu_quit = true;
    }
}

void init_settings(const char* filename)
{
    /* Set the default settings */
    settings.showfps = 0;     /* Do not show FPS */
    settings.limitfps = 1;    /* Limit FPS */
    settings.skipframes = 1;  /* Skip frames */
    settings.resume_options = MPEG_RESUME_MENU_ALWAYS; /* Enable start menu */
    settings.resume_count = -1;
#ifdef HAVE_BACKLIGHT_BRIGHTNESS
    settings.backlight_brightness = -1; /* Use default setting */
#endif
#if MPEG_OPTION_DITHERING_ENABLED
    settings.displayoptions = 0; /* No visual effects */
#endif
    settings.tone_controls = false;
    settings.channel_modes = false;
    settings.crossfeed = false;
    settings.equalizer = false;
    settings.dithering = false;

    if (configfile_load(SETTINGS_FILENAME, config,