summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2007-04-04 22:05:04 +0000
committerJens Arnold <amiconn@rockbox.org>2007-04-04 22:05:04 +0000
commitc6fce6cad3e259d4ea4d92ea9022298204125669 (patch)
treef3c52054066ad4aead13a5419860a5ad687ee203
parent830a3a4720331ea3153f01b504222da3dd1f436a (diff)
downloadrockbox-c6fce6cad3e259d4ea4d92ea9022298204125669.tar.gz
rockbox-c6fce6cad3e259d4ea4d92ea9022298204125669.zip
Player progress drawing rewrite (both emptying cup and full-line bar): * Fixes FS #6820, related to the glitch that progress moved in the opposite direction when seeking. * Smaller, more efficient code. * Full-line bar only displays as many software defined characters as needed, freeing the remaining ones for other text. * Don't cut last digit from times >=1 hour (at the cost of inexact last progress bar character).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13021 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/gwps-common.c208
1 files changed, 71 insertions, 137 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index ffb7ed60d5..d9bcfdc99f 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -586,179 +586,113 @@ static void wps_display_images(struct gui_wps *gwps)
586 586
587static bool draw_player_progress(struct gui_wps *gwps) 587static bool draw_player_progress(struct gui_wps *gwps)
588{ 588{
589 char player_progressbar[7];
590 char binline[36];
591 int songpos = 0;
592 int i,j;
593 struct wps_state *state = gwps->state; 589 struct wps_state *state = gwps->state;
594 struct screen *display = gwps->display; 590 struct screen *display = gwps->display;
591 unsigned char progress_pattern[7];
592 int pos = 0;
593 int i;
594
595 if (!state->id3) 595 if (!state->id3)
596 return false; 596 return false;
597 597
598 memset(binline, 1, sizeof binline); 598 if (state->id3->length)
599 memset(player_progressbar, 1, sizeof player_progressbar); 599 pos = 36 * (state->id3->elapsed + state->ff_rewind_count)
600 / state->id3->length;
600 601
601 if(state->id3->elapsed >= state->id3->length) 602 for (i = 0; i < 7; i++, pos -= 5)
602 songpos = 0;
603 else
604 { 603 {
605 if(state->wps_time_countup == false) 604 if (pos <= 0)
606 songpos = ((state->id3->elapsed - state->ff_rewind_count) * 36) / 605 progress_pattern[i] = 0x1f;
607 state->id3->length; 606 else if (pos >= 5)
607 progress_pattern[i] = 0x00;
608 else 608 else
609 songpos = ((state->id3->elapsed + state->ff_rewind_count) * 36) / 609 progress_pattern[i] = 0x1f >> pos;
610 state->id3->length;
611 } 610 }
612 for (i=0; i < songpos; i++)
613 binline[i] = 0;
614 611
615 for (i=0; i<=6; i++) { 612 display->define_pattern(gwps->data->wps_progress_pat[0], progress_pattern);
616 for (j=0;j<5;j++) {
617 player_progressbar[i] <<= 1;
618 player_progressbar[i] += binline[i*5+j];
619 }
620 }
621 display->define_pattern(gwps->data->wps_progress_pat[0], player_progressbar);
622 return true; 613 return true;
623} 614}
624 615
625static char map_fullbar_char(char ascii_val) 616static int map_fullbar_char(int ascii_val)
626{ 617{
627 if (ascii_val >= '0' && ascii_val <= '9') { 618 if (ascii_val >= '0' && ascii_val <= ':') /* 0123456789: */
628 return(ascii_val - '0'); 619 return ascii_val - '0';
629 }
630 else if (ascii_val == ':') {
631 return(10);
632 }
633 else 620 else
634 return(11); /* anything besides a number or ':' is mapped to <blank> */ 621 return -1; /* anything besides a number or ':' is blank */
635} 622}
636 623
637static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) 624static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
638{ 625{
639 int i,j,lcd_char_pos; 626 static const unsigned char numbers[11][4] = {
640 627 {0x1c, 0x14, 0x14, 0x1c}, /* 0 */
641 char player_progressbar[7]; 628 {0x08, 0x18, 0x08, 0x08}, /* 1 */
642 char binline[36]; 629 {0x1c, 0x04, 0x08, 0x1c}, /* 2 */
643 static const char numbers[12][4][3]={ 630 {0x1c, 0x04, 0x0c, 0x1c}, /* 3 */
644 {{1,1,1},{1,0,1},{1,0,1},{1,1,1}},/*0*/ 631 {0x10, 0x18, 0x1c, 0x08}, /* 4 */
645 {{0,1,0},{1,1,0},{0,1,0},{0,1,0}},/*1*/ 632 {0x1c, 0x18, 0x04, 0x18}, /* 5 */
646 {{1,1,1},{0,0,1},{0,1,0},{1,1,1}},/*2*/ 633 {0x1c, 0x10, 0x1c, 0x1c}, /* 6 */
647 {{1,1,1},{0,0,1},{0,1,1},{1,1,1}},/*3*/ 634 {0x1c, 0x04, 0x08, 0x10}, /* 7 */
648 {{1,0,0},{1,1,0},{1,1,1},{0,1,0}},/*4*/ 635 {0x1c, 0x1c, 0x14, 0x1c}, /* 8 */
649 {{1,1,1},{1,1,0},{0,0,1},{1,1,0}},/*5*/ 636 {0x1c, 0x1c, 0x04, 0x1c}, /* 9 */
650 {{1,1,1},{1,0,0},{1,1,1},{1,1,1}},/*6*/ 637 {0x00, 0x08, 0x00, 0x08}, /* : */
651 {{1,1,1},{0,0,1},{0,1,0},{1,0,0}},/*7*/
652 {{1,1,1},{1,1,1},{1,0,1},{1,1,1}},/*8*/
653 {{1,1,1},{1,1,1},{0,0,1},{1,1,1}},/*9*/
654 {{0,0,0},{0,1,0},{0,0,0},{0,1,0}},/*:*/
655 {{0,0,0},{0,0,0},{0,0,0},{0,0,0}} /*<blank>*/
656 }; 638 };
657 639
658 int songpos = 0;
659 int digits[6];
660 int time;
661 char timestr[7];
662
663 struct wps_state *state = gwps->state; 640 struct wps_state *state = gwps->state;
664 struct screen *display = gwps->display; 641 struct screen *display = gwps->display;
665 struct wps_data *data = gwps->data; 642 struct wps_data *data = gwps->data;
643 unsigned char progress_pattern[7];
644 char timestr[12];
645 int time;
646 int pos = 0;
647 int pat_idx = 1;
648 int i, digit;
649 bool softchar;
666 650
667 for (i=0; i < buf_size; i++) 651 if (!state->id3 || buf_size < 34) /* worst case: 11x UTF-8 char + \0 */
668 buf[i] = ' '; 652 return;
669
670 if(state->id3->elapsed >= state->id3->length)
671 songpos = 55;
672 else {
673 if(state->wps_time_countup == false)
674 songpos = ((state->id3->elapsed - state->ff_rewind_count) * 55) /
675 state->id3->length;
676 else
677 songpos = ((state->id3->elapsed + state->ff_rewind_count) * 55) /
678 state->id3->length;
679 }
680 653
681 time=(state->id3->elapsed + state->ff_rewind_count); 654 time = state->id3->elapsed + state->ff_rewind_count;
655 if (state->id3->length)
656 pos = 55 * time / state->id3->length;
682 657
683 memset(timestr, 0, sizeof(timestr)); 658 memset(timestr, 0, sizeof(timestr));
684 format_time(timestr, sizeof(timestr), time); 659 format_time(timestr, sizeof(timestr), time);
685 for(lcd_char_pos=0; lcd_char_pos<6; lcd_char_pos++) {
686 digits[lcd_char_pos] = map_fullbar_char(timestr[lcd_char_pos]);
687 }
688
689 /* build the progressbar-icons */
690 for (lcd_char_pos=0; lcd_char_pos<6; lcd_char_pos++) {
691 memset(binline, 0, sizeof binline);
692 memset(player_progressbar, 0, sizeof player_progressbar);
693
694 /* make the character (progressbar & digit)*/
695 for (i=0; i<7; i++) {
696 for (j=0;j<5;j++) {
697 /* make the progressbar */
698 if (lcd_char_pos==(songpos/5)) {
699 /* partial */
700 if ((j<(songpos%5))&&(i>4))
701 binline[i*5+j] = 1;
702 else
703 binline[i*5+j] = 0;
704 }
705 else {
706 if (lcd_char_pos<(songpos/5)) {
707 /* full character */
708 if (i>4)
709 binline[i*5+j] = 1;
710 }
711 }
712 /* insert the digit */
713 if ((j<3)&&(i<4)) {
714 if (numbers[digits[lcd_char_pos]][i][j]==1)
715 binline[i*5+j] = 1;
716 }
717 }
718 }
719
720 for (i=0; i<=6; i++) {
721 for (j=0;j<5;j++) {
722 player_progressbar[i] <<= 1;
723 player_progressbar[i] += binline[i*5+j];
724 }
725 }
726
727 display->define_pattern(data->wps_progress_pat[lcd_char_pos+1],
728 player_progressbar);
729 buf = utf8encode(data->wps_progress_pat[lcd_char_pos+1], buf);
730 }
731 660
732 /* make rest of the progressbar if necessary */ 661 for (i = 0; i < 11; i++, pos -= 5)
733 if (songpos/5>5) { 662 {
734 663 softchar = false;
735 /* set the characters positions that use the full 5 pixel wide bar */ 664 memset(progress_pattern, 0, sizeof(progress_pattern));
736 for (lcd_char_pos=6; lcd_char_pos < (songpos/5); lcd_char_pos++)
737 buf = utf8encode(0xe115, buf); /* 2/7 '_' */
738 665
739 /* build the partial bar character for the tail character position */ 666 digit = map_fullbar_char(timestr[i]);
740 memset(binline, 0, sizeof binline); 667 if (digit >= 0)
741 memset(player_progressbar, 0, sizeof player_progressbar); 668 {
669 softchar = true;
670 memcpy(progress_pattern, numbers[digit], 4);
742 671
743 for (i=5; i<7; i++) { 672 if (pos >= 5)
744 for (j=0;j<5;j++) { 673 progress_pattern[5] = progress_pattern[6] = 0x1f;
745 if (j<(songpos%5)) {
746 binline[i*5+j] = 1;
747 }
748 }
749 } 674 }
750 675 if (pos > 0 && pos < 5)
751 for (i=0; i<7; i++) { 676 {
752 for (j=0;j<5;j++) { 677 softchar = true;
753 player_progressbar[i] <<= 1; 678 progress_pattern[5] = progress_pattern[6] = (~0x1f >> pos) & 0x1f;
754 player_progressbar[i] += binline[i*5+j];
755 }
756 } 679 }
757 680
758 display->define_pattern(data->wps_progress_pat[7],player_progressbar); 681 if (softchar && pat_idx < 8)
759 buf = utf8encode(data->wps_progress_pat[7], buf); 682 {
760 *buf = '\0'; 683 display->define_pattern(data->wps_progress_pat[pat_idx],
684 progress_pattern);
685 buf = utf8encode(data->wps_progress_pat[pat_idx], buf);
686 pat_idx++;
687 }
688 else if (pos <= 0)
689 buf = utf8encode(' ', buf);
690 else if (pos >= 5)
691 buf = utf8encode(0xe115, buf); /* 2/7 _ */
692 else /* in between, but cannot map */
693 buf = utf8encode('_', buf); /* 1/7 _ */
761 } 694 }
695 *buf = '\0';
762} 696}
763 697
764#endif /* HAVE_LCD_CHARCELL */ 698#endif /* HAVE_LCD_CHARCELL */