summaryrefslogtreecommitdiff
path: root/apps/wps-display.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2004-01-14 07:59:06 +0000
committerDaniel Stenberg <daniel@haxx.se>2004-01-14 07:59:06 +0000
commitd2b625f818e8e04ace3c7532fe9c38eb0c0b1662 (patch)
treeb835c1d3a3e03581361528dc818c8e4219c40fb8 /apps/wps-display.c
parente99f3b2b13d63361e348a70ea8b19488f617ca3f (diff)
downloadrockbox-d2b625f818e8e04ace3c7532fe9c38eb0c0b1662.tar.gz
rockbox-d2b625f818e8e04ace3c7532fe9c38eb0c0b1662.zip
Craig Sather's patch #749974:
Adds the ability to define 2 or more alternating lines on each line of the WPS and the ability to control how long each alternating line is displayed before switching to the next one. Backward compatible with the current WPS specification language (existing WPS files will display the same as they do now). His HTML version of the docs is found at: http://home.pacbell.net/csath/rockbox/details.html git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4229 a1c6a512-1295-4272-9138-f99709370657
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