summaryrefslogtreecommitdiff
path: root/apps/wps-display.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/wps-display.c')
-rw-r--r--apps/wps-display.c290
1 files changed, 243 insertions, 47 deletions
diff --git a/apps/wps-display.c b/apps/wps-display.c
index 68d3eb531d..6553e9b542 100644
--- a/apps/wps-display.c
+++ b/apps/wps-display.c
@@ -54,11 +54,16 @@
54 54
55#ifdef HAVE_LCD_BITMAP 55#ifdef HAVE_LCD_BITMAP
56#define MAX_LINES 10 56#define MAX_LINES 10
57#define FORMAT_BUFFER_SIZE 800
57#else 58#else
58#define MAX_LINES 2 59#define MAX_LINES 2
60#define FORMAT_BUFFER_SIZE 400
59#endif 61#endif
60 62#define MAX_SUBLINES 12
61#define FORMAT_BUFFER_SIZE 300 63#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* (10ths of sec) */
64#define BASE_SUBLINE_TIME 10 /* base time that multiplier is applied to
65 (1/HZ sec, or 100ths of sec) */
66#define SUBLINE_RESET -1
62 67
63#ifdef HAVE_LCD_CHARCELLS 68#ifdef HAVE_LCD_CHARCELLS
64static unsigned char wps_progress_pat[8]={0,0,0,0,0,0,0,0}; 69static unsigned char wps_progress_pat[8]={0,0,0,0,0,0,0,0};
@@ -70,8 +75,12 @@ static char map_fullbar_char(char ascii_val);
70#endif 75#endif
71 76
72static char format_buffer[FORMAT_BUFFER_SIZE]; 77static char format_buffer[FORMAT_BUFFER_SIZE];
73static char* format_lines[MAX_LINES]; 78static char* format_lines[MAX_LINES][MAX_SUBLINES];
74static unsigned char line_type[MAX_LINES]; 79static unsigned char line_type[MAX_LINES][MAX_SUBLINES];
80static unsigned char time_mult[MAX_LINES][MAX_SUBLINES];
81static long subline_expire_time[MAX_LINES];
82static int curr_subline[MAX_LINES];
83
75static int ff_rewind_count; 84static int ff_rewind_count;
76bool wps_time_countup = true; 85bool wps_time_countup = true;
77static bool wps_loaded = false; 86static bool wps_loaded = false;
@@ -115,49 +124,76 @@ static void wps_format(char* fmt)
115 char* buf = format_buffer; 124 char* buf = format_buffer;
116 char* start_of_line = format_buffer; 125 char* start_of_line = format_buffer;
117 int line = 0; 126 int line = 0;
127 int subline;
118 128
119 strncpy(format_buffer, fmt, sizeof(format_buffer)); 129 strncpy(format_buffer, fmt, sizeof(format_buffer));
120 format_buffer[sizeof(format_buffer) - 1] = 0; 130 format_buffer[sizeof(format_buffer) - 1] = 0;
121 format_lines[line] = buf;
122 131
132 for (line=0; line<MAX_LINES; line++)
133 {
134 for (subline=0; subline<MAX_SUBLINES; subline++)
135 {
136 format_lines[line][subline] = 0;
137 time_mult[line][subline] = 0;
138 }
139 subline_expire_time[line] = 0;
140 curr_subline[line] = SUBLINE_RESET;
141 }
142
143 line = 0;
144 subline = 0;
145 format_lines[line][subline] = buf;
146
123 while ((*buf) && (line < MAX_LINES)) 147 while ((*buf) && (line < MAX_LINES))
124 { 148 {
125 switch (*buf) 149 switch (*buf)
126 { 150 {
127 case '\r': 151 /* skip % sequences so "%;" doesn't start a new subline */
152 case '%':
153 buf++;
154 break;
155
156 case '\r': /* CR */
128 *buf = 0; 157 *buf = 0;
129 break; 158 break;
130 159
131 case '\n': /* LF */ 160 case '\n': /* LF */
132 *buf = 0; 161 *buf = 0;
133 162
134 if(*start_of_line != '#') /* A comment? */ 163 if (*start_of_line != '#') /* A comment? */
135 line++; 164 line++;
136 165
137 if (line < MAX_LINES) 166 if (line < MAX_LINES)
138 { 167 {
139 /* the next line starts on the next byte */ 168 /* the next line starts on the next byte */
140 format_lines[line] = buf+1; 169 subline = 0;
141 start_of_line = format_lines[line]; 170 format_lines[line][subline] = buf+1;
171 start_of_line = format_lines[line][subline];
142 } 172 }
143 break; 173 break;
144 }
145 buf++;
146 }
147
148 /* if supplied input didn't define a format line
149 for each line on the wps, set the rest to null */
150 if (line < MAX_LINES)
151 {
152 /* if the final line didn't terminate with a newline,
153 the line index wasn't incremented */
154 if (buf != format_lines[line])
155 line++;
156 174
157 for (; line < MAX_LINES; line++) 175 case ';': /* start a new subline */
158 { 176 *buf = 0;
159 format_lines[line] = NULL; 177 subline++;
178 if (subline < MAX_SUBLINES)
179 {
180 format_lines[line][subline] = buf+1;
181 }
182 else /* exceeded max sublines, skip rest of line */
183 {
184 while (*(++buf))
185 {
186 if ((*buf == '\r') || (*buf == '\n'))
187 {
188 break;
189 }
190 }
191 buf--;
192 subline = 0;
193 }
194 break;
160 } 195 }
196 buf++;
161 } 197 }
162} 198}
163 199
@@ -169,6 +205,7 @@ void wps_reset(void)
169 205
170bool wps_load(char* file, bool display) 206bool wps_load(char* file, bool display)
171{ 207{
208 int i, s;
172 char buffer[FORMAT_BUFFER_SIZE]; 209 char buffer[FORMAT_BUFFER_SIZE];
173 int fd; 210 int fd;
174 211
@@ -187,17 +224,36 @@ bool wps_load(char* file, bool display)
187 close(fd); 224 close(fd);
188 225
189 if ( display ) { 226 if ( display ) {
190 int i; 227 bool any_defined_line;
191 lcd_clear_display(); 228 lcd_clear_display();
192#ifdef HAVE_LCD_BITMAP 229#ifdef HAVE_LCD_BITMAP
193 lcd_setmargins(0,0); 230 lcd_setmargins(0,0);
194#endif 231#endif
195 for (i=0; i<MAX_LINES && format_lines[i]; i++) 232 for (s=0; s<MAX_SUBLINES; s++)
196 lcd_puts(0,i,format_lines[i]); 233 {
197 lcd_update(); 234 any_defined_line = false;
198 sleep(HZ); 235 for (i=0; i<MAX_LINES; i++)
236 {
237 if (format_lines[i][s])
238 {
239 if (*format_lines[i][s] == 0)
240 lcd_puts(0,i," ");
241 else
242 lcd_puts(0,i,format_lines[i][s]);
243 any_defined_line = true;
244 }
245 else
246 {
247 lcd_puts(0,i," ");
248 }
249 }
250 if (any_defined_line)
251 {
252 lcd_update();
253 sleep(HZ/2);
254 }
255 }
199 } 256 }
200
201 wps_loaded = true; 257 wps_loaded = true;
202 258
203 return numread > 0; 259 return numread > 0;
@@ -276,13 +332,18 @@ static char* get_tag(struct mp3entry* id3,
276 char* tag, 332 char* tag,
277 char* buf, 333 char* buf,
278 int buf_size, 334 int buf_size,
335 unsigned char* tag_len,
336 unsigned char* subline_time_mult,
279 unsigned char* flags) 337 unsigned char* flags)
280{ 338{
281 if ((0 == tag[0]) || (0 == tag[1])) 339 if ((0 == tag[0]) || (0 == tag[1]))
282 { 340 {
341 *tag_len = 0;
283 return NULL; 342 return NULL;
284 } 343 }
285 344
345 *tag_len = 2;
346
286 switch (tag[0]) 347 switch (tag[0])
287 { 348 {
288 case 'i': /* ID3 Information */ 349 case 'i': /* ID3 Information */
@@ -510,6 +571,46 @@ static char* get_tag(struct mp3entry* id3,
510 } 571 }
511 } 572 }
512 break; 573 break;
574
575 case 't': /* set sub line time multiplier */
576 {
577 int d = 1;
578 int time_mult = 0;
579 bool have_point = false;
580 bool have_tenth = false;
581
582 while (((tag[d] >= '0') &&
583 (tag[d] <= '9')) ||
584 (tag[d] == '.'))
585 {
586 if (tag[d] != '.')
587 {
588 time_mult = time_mult * 10;
589 time_mult = time_mult + tag[d] - '0';
590 if (have_point)
591 {
592 have_tenth = true;
593 d++;
594 break;
595 }
596 }
597 else
598 {
599 have_point = true;
600 }
601 d++;
602 }
603
604 if (have_tenth == false)
605 time_mult *= 10;
606
607 *subline_time_mult = time_mult;
608 *tag_len = d;
609
610 buf[0] = 0;
611 return buf;
612 }
613 break;
513 } 614 }
514 615
515 return NULL; 616 return NULL;
@@ -594,13 +695,18 @@ static void format_display(char* buf,
594 int buf_size, 695 int buf_size,
595 struct mp3entry* id3, 696 struct mp3entry* id3,
596 char* fmt, 697 char* fmt,
698 unsigned char* subline_time_mult,
597 unsigned char* flags) 699 unsigned char* flags)
598{ 700{
599 char temp_buf[128]; 701 char temp_buf[128];
702 char* buf_start = buf;
600 char* buf_end = buf + buf_size - 1; /* Leave room for end null */ 703 char* buf_end = buf + buf_size - 1; /* Leave room for end null */
601 char* value = NULL; 704 char* value = NULL;
602 int level = 0; 705 int level = 0;
603 706 unsigned char tag_length;
707
708 *subline_time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER;
709
604 while (fmt && *fmt && buf < buf_end) 710 while (fmt && *fmt && buf < buf_end)
605 { 711 {
606 switch (*fmt) 712 switch (*fmt)
@@ -639,12 +745,14 @@ static void format_display(char* buf,
639 case '|': 745 case '|':
640 case '<': 746 case '<':
641 case '>': 747 case '>':
748 case ';':
642 *buf++ = *fmt++; 749 *buf++ = *fmt++;
643 break; 750 break;
644 751
645 case '?': 752 case '?':
646 fmt++; 753 fmt++;
647 value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf), flags); 754 value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf),
755 &tag_length, subline_time_mult, flags);
648 756
649 while (*fmt && ('<' != *fmt)) 757 while (*fmt && ('<' != *fmt))
650 fmt++; 758 fmt++;
@@ -660,8 +768,9 @@ static void format_display(char* buf,
660 break; 768 break;
661 769
662 default: 770 default:
663 value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf), flags); 771 value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf),
664 fmt += 2; 772 &tag_length, subline_time_mult, flags);
773 fmt += tag_length;
665 774
666 if (value) 775 if (value)
667 { 776 {
@@ -673,18 +782,27 @@ static void format_display(char* buf,
673 782
674 *buf = 0; 783 *buf = 0;
675 784
785 /* if resulting line is an empty line, set the subline time to 0 */
786 if (*buf_start == 0)
787 *subline_time_mult = 0;
788
676 /* If no flags have been set, the line didn't contain any format codes. 789 /* If no flags have been set, the line didn't contain any format codes.
677 We still want to refresh it. */ 790 We still want to refresh it. */
678 if(*flags == 0) 791 if(*flags == 0)
679 *flags = WPS_REFRESH_STATIC; 792 *flags = WPS_REFRESH_STATIC;
680} 793}
681 794
682bool wps_refresh(struct mp3entry* id3, int ffwd_offset, unsigned char refresh_mode) 795bool wps_refresh(struct mp3entry* id3, int ffwd_offset,
796 unsigned char refresh_mode)
683{ 797{
684 char buf[MAX_PATH]; 798 char buf[MAX_PATH];
685 unsigned char flags; 799 unsigned char flags;
686 int i; 800 int i;
687 bool update_line; 801 bool update_line;
802 bool only_one_subline;
803 bool new_subline_refresh;
804 int search;
805 int search_start;
688#ifdef HAVE_LCD_BITMAP 806#ifdef HAVE_LCD_BITMAP
689 int h = font_get(FONT_UI)->height; 807 int h = font_get(FONT_UI)->height;
690 int offset = global_settings.statusbar ? STATUSBAR_HEIGHT : 0; 808 int offset = global_settings.statusbar ? STATUSBAR_HEIGHT : 0;
@@ -697,6 +815,16 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, unsigned char refresh_mo
697 */ 815 */
698 bool enable_pm = false; 816 bool enable_pm = false;
699#endif 817#endif
818
819 /* reset to first subline if refresh all flag is set */
820 if (refresh_mode == WPS_REFRESH_ALL)
821 {
822 for (i=0; i<MAX_LINES; i++)
823 {
824 curr_subline[i] = SUBLINE_RESET;
825 }
826 }
827
700#ifdef HAVE_LCD_CHARCELLS 828#ifdef HAVE_LCD_CHARCELLS
701 for (i=0; i<8; i++) { 829 for (i=0; i<8; i++) {
702 if (wps_progress_pat[i]==0) 830 if (wps_progress_pat[i]==0)
@@ -714,17 +842,79 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, unsigned char refresh_mo
714 842
715 for (i = 0; i < MAX_LINES; i++) 843 for (i = 0; i < MAX_LINES; i++)
716 { 844 {
845 new_subline_refresh = false;
846 only_one_subline = false;
847
848 /* if time to advance to next sub-line */
849 if (TIME_AFTER(current_tick, subline_expire_time[i] - 1) ||
850 (curr_subline[i] == SUBLINE_RESET))
851 {
852 /* search all sublines until the next subline with time > 0
853 is found or we get back to the subline we started with */
854 if (curr_subline[i] == SUBLINE_RESET)
855 search_start = 0;
856 else
857 search_start = curr_subline[i];
858 for (search=0; search<MAX_SUBLINES; search++)
859 {
860 curr_subline[i]++;
861
862 /* wrap around if beyond last defined subline or MAX_SUBLINES */
863 if ((!format_lines[i][curr_subline[i]]) ||
864 (curr_subline[i] == MAX_SUBLINES))
865 {
866 if (curr_subline[i] == 1)
867 only_one_subline = true;
868 curr_subline[i] = 0;
869 }
870
871 /* if back where we started after search or
872 only one subline is defined on the line */
873 if (((search > 0) && (curr_subline[i] == search_start)) ||
874 only_one_subline)
875 {
876 /* no other subline with a time > 0 exists */
877 subline_expire_time[i] = current_tick + 100 * HZ;
878 break;
879 }
880 else
881 {
882 /* get initial time multiplier and
883 line type flags for this subline */
884 format_display(buf, sizeof(buf), id3,
885 format_lines[i][curr_subline[i]],
886 &time_mult[i][curr_subline[i]],
887 &line_type[i][curr_subline[i]]);
888
889 /* only use this subline if subline time > 0 */
890 if (time_mult[i][curr_subline[i]] > 0)
891 {
892 new_subline_refresh = true;
893 subline_expire_time[i] = current_tick +
894 BASE_SUBLINE_TIME * time_mult[i][curr_subline[i]];
895 break;
896 }
897 }
898 }
899
900 }
901
717 update_line = false; 902 update_line = false;
718 if ( !format_lines[i] ) 903
904 if ( !format_lines[i][curr_subline[i]] )
719 break; 905 break;
720 906
721 if ((line_type[i] & refresh_mode) || 907 if ((line_type[i][curr_subline[i]] & refresh_mode) ||
722 (refresh_mode == WPS_REFRESH_ALL)) 908 (refresh_mode == WPS_REFRESH_ALL) ||
909 new_subline_refresh)
723 { 910 {
724 flags = 0; 911 flags = 0;
725 format_display(buf, sizeof(buf), id3, format_lines[i], &flags); 912 format_display(buf, sizeof(buf), id3,
726 line_type[i] = flags; 913 format_lines[i][curr_subline[i]],
727 914 &time_mult[i][curr_subline[i]],
915 &flags);
916 line_type[i][curr_subline[i]] = flags;
917
728#ifdef HAVE_LCD_BITMAP 918#ifdef HAVE_LCD_BITMAP
729 /* progress */ 919 /* progress */
730 if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) { 920 if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) {
@@ -764,19 +954,25 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, unsigned char refresh_mo
764 draw_player_progress(id3, ff_rewind_count); 954 draw_player_progress(id3, ff_rewind_count);
765 } 955 }
766#endif 956#endif
957
767 if (flags & WPS_REFRESH_SCROLL) { 958 if (flags & WPS_REFRESH_SCROLL) {
959
768 /* scroll line */ 960 /* scroll line */
769 if (refresh_mode & WPS_REFRESH_SCROLL) { 961 if ((refresh_mode & WPS_REFRESH_SCROLL) ||
962 new_subline_refresh) {
770 lcd_puts_scroll(0, i, buf); 963 lcd_puts_scroll(0, i, buf);
771 update_line = true; 964 update_line = true;
772 } 965 }
773 } 966 }
774 /* dynamic / static line */ 967 else if (flags & (WPS_REFRESH_DYNAMIC | WPS_REFRESH_STATIC))
775 else if ((flags & refresh_mode & WPS_REFRESH_DYNAMIC) ||
776 (flags & refresh_mode & WPS_REFRESH_STATIC))
777 { 968 {
778 update_line = true; 969 /* dynamic / static line */
779 lcd_puts(0, i, buf); 970 if ((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC)) ||
971 new_subline_refresh)
972 {
973 update_line = true;
974 lcd_puts(0, i, buf);
975 }
780 } 976 }
781 } 977 }
782#ifdef HAVE_LCD_BITMAP 978#ifdef HAVE_LCD_BITMAP