diff options
-rw-r--r-- | apps/wps-display.c | 224 | ||||
-rw-r--r-- | apps/wps-display.h | 5 | ||||
-rw-r--r-- | apps/wps.c | 37 | ||||
-rw-r--r-- | docs/CUSTOM_WPS_FORMAT | 13 |
4 files changed, 160 insertions, 119 deletions
diff --git a/apps/wps-display.c b/apps/wps-display.c index c45008ef93..e11ec8a520 100644 --- a/apps/wps-display.c +++ b/apps/wps-display.c | |||
@@ -17,8 +17,8 @@ | |||
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | ||
20 | /* ID3 formatting based on code from the MAD Winamp plugin (in_mad.dll), | 20 | /* ID3 formatting based on code from the MAD Winamp plugin (in_mad.dll), |
21 | * Copyright (C) 2000-2001 Robert Leslie. | 21 | * Copyright (C) 2000-2001 Robert Leslie. |
22 | * See http://www.mars.org/home/rob/proj/mpeg/ for more information. | 22 | * See http://www.mars.org/home/rob/proj/mpeg/ for more information. |
23 | */ | 23 | */ |
24 | 24 | ||
@@ -61,7 +61,7 @@ | |||
61 | #endif | 61 | #endif |
62 | #define MAX_SUBLINES 12 | 62 | #define MAX_SUBLINES 12 |
63 | #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* (10ths of sec) */ | 63 | #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* (10ths of sec) */ |
64 | #define BASE_SUBLINE_TIME 10 /* base time that multiplier is applied to | 64 | #define BASE_SUBLINE_TIME 10 /* base time that multiplier is applied to |
65 | (1/HZ sec, or 100ths of sec) */ | 65 | (1/HZ sec, or 100ths of sec) */ |
66 | #define SUBLINE_RESET -1 | 66 | #define SUBLINE_RESET -1 |
67 | 67 | ||
@@ -78,7 +78,7 @@ static char format_buffer[FORMAT_BUFFER_SIZE]; | |||
78 | static char* format_lines[MAX_LINES][MAX_SUBLINES]; | 78 | static char* format_lines[MAX_LINES][MAX_SUBLINES]; |
79 | static unsigned char line_type[MAX_LINES][MAX_SUBLINES]; | 79 | static unsigned char line_type[MAX_LINES][MAX_SUBLINES]; |
80 | static unsigned char time_mult[MAX_LINES][MAX_SUBLINES]; | 80 | static unsigned char time_mult[MAX_LINES][MAX_SUBLINES]; |
81 | static long subline_expire_time[MAX_LINES]; | 81 | static long subline_expire_time[MAX_LINES]; |
82 | static int curr_subline[MAX_LINES]; | 82 | static int curr_subline[MAX_LINES]; |
83 | 83 | ||
84 | static int ff_rewind_count; | 84 | static int ff_rewind_count; |
@@ -115,7 +115,7 @@ char* wps_get_genre(struct mp3entry* id3) | |||
115 | { | 115 | { |
116 | if( id3->genre_string ) | 116 | if( id3->genre_string ) |
117 | return id3->genre_string ; | 117 | return id3->genre_string ; |
118 | 118 | ||
119 | if (id3->genre < sizeof(genres)/sizeof(char*)) | 119 | if (id3->genre < sizeof(genres)/sizeof(char*)) |
120 | return (char*)genres[id3->genre]; | 120 | return (char*)genres[id3->genre]; |
121 | return NULL; | 121 | return NULL; |
@@ -128,10 +128,10 @@ static void wps_format(char* fmt) | |||
128 | char* start_of_line = format_buffer; | 128 | char* start_of_line = format_buffer; |
129 | int line = 0; | 129 | int line = 0; |
130 | int subline; | 130 | int subline; |
131 | 131 | ||
132 | strncpy(format_buffer, fmt, sizeof(format_buffer)); | 132 | strncpy(format_buffer, fmt, sizeof(format_buffer)); |
133 | format_buffer[sizeof(format_buffer) - 1] = 0; | 133 | format_buffer[sizeof(format_buffer) - 1] = 0; |
134 | 134 | ||
135 | for (line=0; line<MAX_LINES; line++) | 135 | for (line=0; line<MAX_LINES; line++) |
136 | { | 136 | { |
137 | for (subline=0; subline<MAX_SUBLINES; subline++) | 137 | for (subline=0; subline<MAX_SUBLINES; subline++) |
@@ -152,7 +152,7 @@ static void wps_format(char* fmt) | |||
152 | switch (*buf) | 152 | switch (*buf) |
153 | { | 153 | { |
154 | /* skip % sequences so "%;" doesn't start a new subline */ | 154 | /* skip % sequences so "%;" doesn't start a new subline */ |
155 | case '%': | 155 | case '%': |
156 | buf++; | 156 | buf++; |
157 | break; | 157 | break; |
158 | 158 | ||
@@ -165,7 +165,7 @@ static void wps_format(char* fmt) | |||
165 | 165 | ||
166 | if (*start_of_line != '#') /* A comment? */ | 166 | if (*start_of_line != '#') /* A comment? */ |
167 | line++; | 167 | line++; |
168 | 168 | ||
169 | if (line < MAX_LINES) | 169 | if (line < MAX_LINES) |
170 | { | 170 | { |
171 | /* the next line starts on the next byte */ | 171 | /* the next line starts on the next byte */ |
@@ -184,7 +184,7 @@ static void wps_format(char* fmt) | |||
184 | } | 184 | } |
185 | else /* exceeded max sublines, skip rest of line */ | 185 | else /* exceeded max sublines, skip rest of line */ |
186 | { | 186 | { |
187 | while (*(++buf)) | 187 | while (*(++buf)) |
188 | { | 188 | { |
189 | if ((*buf == '\r') || (*buf == '\n')) | 189 | if ((*buf == '\r') || (*buf == '\n')) |
190 | { | 190 | { |
@@ -213,17 +213,17 @@ bool wps_load(char* file, bool display) | |||
213 | int fd; | 213 | int fd; |
214 | 214 | ||
215 | fd = open(file, O_RDONLY); | 215 | fd = open(file, O_RDONLY); |
216 | 216 | ||
217 | if (fd >= 0) | 217 | if (fd >= 0) |
218 | { | 218 | { |
219 | int numread = read(fd, buffer, sizeof(buffer) - 1); | 219 | int numread = read(fd, buffer, sizeof(buffer) - 1); |
220 | 220 | ||
221 | if (numread > 0) | 221 | if (numread > 0) |
222 | { | 222 | { |
223 | buffer[numread] = 0; | 223 | buffer[numread] = 0; |
224 | wps_format(buffer); | 224 | wps_format(buffer); |
225 | } | 225 | } |
226 | 226 | ||
227 | close(fd); | 227 | close(fd); |
228 | 228 | ||
229 | if ( display ) { | 229 | if ( display ) { |
@@ -237,7 +237,7 @@ bool wps_load(char* file, bool display) | |||
237 | any_defined_line = false; | 237 | any_defined_line = false; |
238 | for (i=0; i<MAX_LINES; i++) | 238 | for (i=0; i<MAX_LINES; i++) |
239 | { | 239 | { |
240 | if (format_lines[i][s]) | 240 | if (format_lines[i][s]) |
241 | { | 241 | { |
242 | if (*format_lines[i][s] == 0) | 242 | if (*format_lines[i][s] == 0) |
243 | lcd_puts(0,i," "); | 243 | lcd_puts(0,i," "); |
@@ -261,7 +261,7 @@ bool wps_load(char* file, bool display) | |||
261 | 261 | ||
262 | return numread > 0; | 262 | return numread > 0; |
263 | } | 263 | } |
264 | 264 | ||
265 | return false; | 265 | return false; |
266 | } | 266 | } |
267 | 267 | ||
@@ -281,7 +281,7 @@ static void format_time(char* buf, int buf_size, int time) | |||
281 | * buf - buffer extract part to. | 281 | * buf - buffer extract part to. |
282 | * buf_size - size of buffer. | 282 | * buf_size - size of buffer. |
283 | * path - path to extract from. | 283 | * path - path to extract from. |
284 | * level - what to extract. 0 is file name, 1 is parent of file, 2 is | 284 | * level - what to extract. 0 is file name, 1 is parent of file, 2 is |
285 | * parent of parent, etc. | 285 | * parent of parent, etc. |
286 | * | 286 | * |
287 | * Returns buf if the desired level was found, NULL otherwise. | 287 | * Returns buf if the desired level was found, NULL otherwise. |
@@ -303,7 +303,7 @@ static char* get_dir(char* buf, int buf_size, char* path, int level) | |||
303 | { | 303 | { |
304 | break; | 304 | break; |
305 | } | 305 | } |
306 | 306 | ||
307 | level--; | 307 | level--; |
308 | last_sep = sep - 1; | 308 | last_sep = sep - 1; |
309 | } | 309 | } |
@@ -323,32 +323,41 @@ static char* get_dir(char* buf, int buf_size, char* path, int level) | |||
323 | /* Get the tag specified by the two characters at fmt. | 323 | /* Get the tag specified by the two characters at fmt. |
324 | * | 324 | * |
325 | * id3 - ID3 data to get tag values from. | 325 | * id3 - ID3 data to get tag values from. |
326 | * nid3 - next-song ID3 data to get tag values from. | ||
326 | * tag - string (of two characters) specifying the tag to get. | 327 | * tag - string (of two characters) specifying the tag to get. |
327 | * buf - buffer to certain tags, such as track number, play time or | 328 | * buf - buffer to certain tags, such as track number, play time or |
328 | * directory name. | 329 | * directory name. |
329 | * buf_size - size of buffer. | 330 | * buf_size - size of buffer. |
330 | * flags - returns the type of the line. See constants i wps-display.h | 331 | * flags - returns the type of the line. See constants i wps-display.h |
331 | * | 332 | * |
332 | * Returns the tag. NULL indicates the tag wasn't available. | 333 | * Returns the tag. NULL indicates the tag wasn't available. |
333 | */ | 334 | */ |
334 | static char* get_tag(struct mp3entry* id3, | 335 | static char* get_tag(struct mp3entry* cid3, |
335 | char* tag, | 336 | struct mp3entry* nid3, |
336 | char* buf, | 337 | char* tag, |
338 | char* buf, | ||
337 | int buf_size, | 339 | int buf_size, |
338 | unsigned char* tag_len, | 340 | unsigned char* tag_len, |
339 | unsigned char* subline_time_mult, | 341 | unsigned char* subline_time_mult, |
340 | unsigned char* flags) | 342 | unsigned char* flags) |
341 | { | 343 | { |
344 | struct mp3entry *id3 = cid3; /* default to current song */ | ||
345 | |||
342 | if ((0 == tag[0]) || (0 == tag[1])) | 346 | if ((0 == tag[0]) || (0 == tag[1])) |
343 | { | 347 | { |
344 | *tag_len = 0; | 348 | *tag_len = 0; |
345 | return NULL; | 349 | return NULL; |
346 | } | 350 | } |
347 | 351 | ||
348 | *tag_len = 2; | 352 | *tag_len = 2; |
349 | 353 | ||
350 | switch (tag[0]) | 354 | switch (tag[0]) |
351 | { | 355 | { |
356 | case 'I': /* ID3 Information */ | ||
357 | id3 = nid3; /* display next-song data */ | ||
358 | if(!id3) | ||
359 | return NULL; /* no such info (yet) */ | ||
360 | /* fall-through */ | ||
352 | case 'i': /* ID3 Information */ | 361 | case 'i': /* ID3 Information */ |
353 | *flags |= WPS_REFRESH_STATIC; | 362 | *flags |= WPS_REFRESH_STATIC; |
354 | switch (tag[1]) | 363 | switch (tag[1]) |
@@ -358,7 +367,7 @@ static char* get_tag(struct mp3entry* id3, | |||
358 | 367 | ||
359 | case 'a': /* ID3 Artist */ | 368 | case 'a': /* ID3 Artist */ |
360 | return id3->artist; | 369 | return id3->artist; |
361 | 370 | ||
362 | case 'n': /* ID3 Track Number */ | 371 | case 'n': /* ID3 Track Number */ |
363 | if (id3->track_string) | 372 | if (id3->track_string) |
364 | return id3->track_string; | 373 | return id3->track_string; |
@@ -368,13 +377,13 @@ static char* get_tag(struct mp3entry* id3, | |||
368 | return buf; | 377 | return buf; |
369 | } | 378 | } |
370 | return NULL; | 379 | return NULL; |
371 | 380 | ||
372 | case 'd': /* ID3 Album/Disc */ | 381 | case 'd': /* ID3 Album/Disc */ |
373 | return id3->album; | 382 | return id3->album; |
374 | 383 | ||
375 | case 'c': /* ID3 Composer */ | 384 | case 'c': /* ID3 Composer */ |
376 | return id3->composer; | 385 | return id3->composer; |
377 | 386 | ||
378 | case 'y': /* year */ | 387 | case 'y': /* year */ |
379 | if( id3->year_string ) | 388 | if( id3->year_string ) |
380 | return id3->year_string; | 389 | return id3->year_string; |
@@ -411,6 +420,11 @@ static char* get_tag(struct mp3entry* id3, | |||
411 | } | 420 | } |
412 | break; | 421 | break; |
413 | 422 | ||
423 | case 'F': /* File Information */ | ||
424 | id3 = nid3; | ||
425 | if(!id3) | ||
426 | return NULL; /* no such info (yet) */ | ||
427 | /* fall-through */ | ||
414 | case 'f': /* File Information */ | 428 | case 'f': /* File Information */ |
415 | *flags |= WPS_REFRESH_STATIC; | 429 | *flags |= WPS_REFRESH_STATIC; |
416 | switch(tag[1]) | 430 | switch(tag[1]) |
@@ -511,7 +525,7 @@ static char* get_tag(struct mp3entry* id3, | |||
511 | 525 | ||
512 | case 'r': /* Remaining Time in Song */ | 526 | case 'r': /* Remaining Time in Song */ |
513 | *flags |= WPS_REFRESH_DYNAMIC; | 527 | *flags |= WPS_REFRESH_DYNAMIC; |
514 | format_time(buf, buf_size, | 528 | format_time(buf, buf_size, |
515 | id3->length - id3->elapsed - ff_rewind_count); | 529 | id3->length - id3->elapsed - ff_rewind_count); |
516 | return buf; | 530 | return buf; |
517 | 531 | ||
@@ -565,6 +579,11 @@ static char* get_tag(struct mp3entry* id3, | |||
565 | } | 579 | } |
566 | break; | 580 | break; |
567 | 581 | ||
582 | case 'D': /* Directory path information */ | ||
583 | id3 = nid3; /* next song please! */ | ||
584 | if(!id3) | ||
585 | return NULL; /* no such info (yet) */ | ||
586 | /* fall-through */ | ||
568 | case 'd': /* Directory path information */ | 587 | case 'd': /* Directory path information */ |
569 | { | 588 | { |
570 | int level = tag[1] - '0'; | 589 | int level = tag[1] - '0'; |
@@ -578,38 +597,38 @@ static char* get_tag(struct mp3entry* id3, | |||
578 | break; | 597 | break; |
579 | 598 | ||
580 | case 't': /* set sub line time multiplier */ | 599 | case 't': /* set sub line time multiplier */ |
581 | { | 600 | { |
582 | int d = 1; | 601 | int d = 1; |
583 | int time_mult = 0; | 602 | int time_mult = 0; |
584 | bool have_point = false; | 603 | bool have_point = false; |
585 | bool have_tenth = false; | 604 | bool have_tenth = false; |
586 | 605 | ||
587 | while (((tag[d] >= '0') && | 606 | while (((tag[d] >= '0') && |
588 | (tag[d] <= '9')) || | 607 | (tag[d] <= '9')) || |
589 | (tag[d] == '.')) | 608 | (tag[d] == '.')) |
590 | { | 609 | { |
591 | if (tag[d] != '.') | 610 | if (tag[d] != '.') |
592 | { | 611 | { |
593 | time_mult = time_mult * 10; | 612 | time_mult = time_mult * 10; |
594 | time_mult = time_mult + tag[d] - '0'; | 613 | time_mult = time_mult + tag[d] - '0'; |
595 | if (have_point) | 614 | if (have_point) |
596 | { | 615 | { |
597 | have_tenth = true; | 616 | have_tenth = true; |
598 | d++; | 617 | d++; |
599 | break; | 618 | break; |
600 | } | 619 | } |
601 | } | 620 | } |
602 | else | 621 | else |
603 | { | 622 | { |
604 | have_point = true; | 623 | have_point = true; |
605 | } | 624 | } |
606 | d++; | 625 | d++; |
607 | } | 626 | } |
608 | 627 | ||
609 | if (have_tenth == false) | 628 | if (have_tenth == false) |
610 | time_mult *= 10; | 629 | time_mult *= 10; |
611 | 630 | ||
612 | *subline_time_mult = time_mult; | 631 | *subline_time_mult = time_mult; |
613 | *tag_len = d; | 632 | *tag_len = d; |
614 | 633 | ||
615 | buf[0] = 0; | 634 | buf[0] = 0; |
@@ -617,13 +636,13 @@ static char* get_tag(struct mp3entry* id3, | |||
617 | } | 636 | } |
618 | break; | 637 | break; |
619 | } | 638 | } |
620 | 639 | ||
621 | return NULL; | 640 | return NULL; |
622 | } | 641 | } |
623 | 642 | ||
624 | /* Skip to the end of the current %? conditional. | 643 | /* Skip to the end of the current %? conditional. |
625 | * | 644 | * |
626 | * fmt - string to skip it. Should point to somewhere after the leading | 645 | * fmt - string to skip it. Should point to somewhere after the leading |
627 | * "<" char (and before or at the last ">"). | 646 | * "<" char (and before or at the last ">"). |
628 | * to_else - if true, skip to the else part (after the "|", if any), else skip | 647 | * to_else - if true, skip to the else part (after the "|", if any), else skip |
629 | * to the end (the ">"). | 648 | * to the end (the ">"). |
@@ -640,19 +659,19 @@ static char* skip_conditional(char* fmt, bool to_else) | |||
640 | { | 659 | { |
641 | case '%': | 660 | case '%': |
642 | break; | 661 | break; |
643 | 662 | ||
644 | case '|': | 663 | case '|': |
645 | if (to_else && (1 == level)) | 664 | if (to_else && (1 == level)) |
646 | return fmt; | 665 | return fmt; |
647 | 666 | ||
648 | continue; | 667 | continue; |
649 | 668 | ||
650 | case '>': | 669 | case '>': |
651 | if (0 == --level) | 670 | if (0 == --level) |
652 | { | 671 | { |
653 | if (to_else) | 672 | if (to_else) |
654 | fmt--; | 673 | fmt--; |
655 | 674 | ||
656 | return fmt; | 675 | return fmt; |
657 | } | 676 | } |
658 | continue; | 677 | continue; |
@@ -660,7 +679,7 @@ static char* skip_conditional(char* fmt, bool to_else) | |||
660 | default: | 679 | default: |
661 | continue; | 680 | continue; |
662 | } | 681 | } |
663 | 682 | ||
664 | switch (*fmt++) | 683 | switch (*fmt++) |
665 | { | 684 | { |
666 | case 0: | 685 | case 0: |
@@ -669,22 +688,22 @@ static char* skip_conditional(char* fmt, bool to_else) | |||
669 | case '<': | 688 | case '<': |
670 | case '>': | 689 | case '>': |
671 | break; | 690 | break; |
672 | 691 | ||
673 | case '?': | 692 | case '?': |
674 | while (*fmt && ('<' != *fmt)) | 693 | while (*fmt && ('<' != *fmt)) |
675 | fmt++; | 694 | fmt++; |
676 | 695 | ||
677 | if ('<' == *fmt) | 696 | if ('<' == *fmt) |
678 | fmt++; | 697 | fmt++; |
679 | 698 | ||
680 | level++; | 699 | level++; |
681 | break; | 700 | break; |
682 | 701 | ||
683 | default: | 702 | default: |
684 | break; | 703 | break; |
685 | } | 704 | } |
686 | } | 705 | } |
687 | 706 | ||
688 | return fmt; | 707 | return fmt; |
689 | } | 708 | } |
690 | 709 | ||
@@ -693,14 +712,16 @@ static char* skip_conditional(char* fmt, bool to_else) | |||
693 | * buf - char buffer to write the display to. | 712 | * buf - char buffer to write the display to. |
694 | * buf_size - the size of buffer. | 713 | * buf_size - the size of buffer. |
695 | * id3 - the ID3 data to format with. | 714 | * id3 - the ID3 data to format with. |
715 | * nid3 - the ID3 data of the next song (might by NULL) | ||
696 | * fmt - format description. | 716 | * fmt - format description. |
697 | * flags - returns the type of the line. See constants i wps-display.h | 717 | * flags - returns the type of the line. See constants i wps-display.h |
698 | */ | 718 | */ |
699 | static void format_display(char* buf, | 719 | static void format_display(char* buf, |
700 | int buf_size, | 720 | int buf_size, |
701 | struct mp3entry* id3, | 721 | struct mp3entry* id3, |
702 | char* fmt, | 722 | struct mp3entry* nid3, /* next song's id3 */ |
703 | unsigned char* subline_time_mult, | 723 | char* fmt, |
724 | unsigned char* subline_time_mult, | ||
704 | unsigned char* flags) | 725 | unsigned char* flags) |
705 | { | 726 | { |
706 | char temp_buf[128]; | 727 | char temp_buf[128]; |
@@ -719,10 +740,10 @@ static void format_display(char* buf, | |||
719 | case '%': | 740 | case '%': |
720 | ++fmt; | 741 | ++fmt; |
721 | break; | 742 | break; |
722 | 743 | ||
723 | case '|': | 744 | case '|': |
724 | case '>': | 745 | case '>': |
725 | if (level > 0) | 746 | if (level > 0) |
726 | { | 747 | { |
727 | fmt = skip_conditional(fmt, false); | 748 | fmt = skip_conditional(fmt, false); |
728 | level--; | 749 | level--; |
@@ -734,18 +755,18 @@ static void format_display(char* buf, | |||
734 | *buf++ = *fmt++; | 755 | *buf++ = *fmt++; |
735 | continue; | 756 | continue; |
736 | } | 757 | } |
737 | 758 | ||
738 | switch (*fmt) | 759 | switch (*fmt) |
739 | { | 760 | { |
740 | case 0: | 761 | case 0: |
741 | *buf++ = '%'; | 762 | *buf++ = '%'; |
742 | break; | 763 | break; |
743 | 764 | ||
744 | case 's': | 765 | case 's': |
745 | *flags |= WPS_REFRESH_SCROLL; | 766 | *flags |= WPS_REFRESH_SCROLL; |
746 | ++fmt; | 767 | ++fmt; |
747 | break; | 768 | break; |
748 | 769 | ||
749 | case '%': | 770 | case '%': |
750 | case '|': | 771 | case '|': |
751 | case '<': | 772 | case '<': |
@@ -753,30 +774,30 @@ static void format_display(char* buf, | |||
753 | case ';': | 774 | case ';': |
754 | *buf++ = *fmt++; | 775 | *buf++ = *fmt++; |
755 | break; | 776 | break; |
756 | 777 | ||
757 | case '?': | 778 | case '?': |
758 | fmt++; | 779 | fmt++; |
759 | value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf), | 780 | value = get_tag(id3, nid3, fmt, temp_buf, sizeof(temp_buf), |
760 | &tag_length, subline_time_mult, flags); | 781 | &tag_length, subline_time_mult, flags); |
761 | 782 | ||
762 | while (*fmt && ('<' != *fmt)) | 783 | while (*fmt && ('<' != *fmt)) |
763 | fmt++; | 784 | fmt++; |
764 | 785 | ||
765 | if ('<' == *fmt) | 786 | if ('<' == *fmt) |
766 | fmt++; | 787 | fmt++; |
767 | 788 | ||
768 | /* No value, so skip to else part */ | 789 | /* No value, so skip to else part */ |
769 | if ((!value) || (!strlen(value))) | 790 | if ((!value) || (!strlen(value))) |
770 | fmt = skip_conditional(fmt, true); | 791 | fmt = skip_conditional(fmt, true); |
771 | 792 | ||
772 | level++; | 793 | level++; |
773 | break; | 794 | break; |
774 | 795 | ||
775 | default: | 796 | default: |
776 | value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf), | 797 | value = get_tag(id3, nid3, fmt, temp_buf, sizeof(temp_buf), |
777 | &tag_length, subline_time_mult, flags); | 798 | &tag_length, subline_time_mult, flags); |
778 | fmt += tag_length; | 799 | fmt += tag_length; |
779 | 800 | ||
780 | if (value) | 801 | if (value) |
781 | { | 802 | { |
782 | while (*value && (buf < buf_end)) | 803 | while (*value && (buf < buf_end)) |
@@ -784,7 +805,7 @@ static void format_display(char* buf, | |||
784 | } | 805 | } |
785 | } | 806 | } |
786 | } | 807 | } |
787 | 808 | ||
788 | *buf = 0; | 809 | *buf = 0; |
789 | 810 | ||
790 | /* if resulting line is an empty line, set the subline time to 0 */ | 811 | /* if resulting line is an empty line, set the subline time to 0 */ |
@@ -797,7 +818,9 @@ static void format_display(char* buf, | |||
797 | *flags = WPS_REFRESH_STATIC; | 818 | *flags = WPS_REFRESH_STATIC; |
798 | } | 819 | } |
799 | 820 | ||
800 | bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | 821 | bool wps_refresh(struct mp3entry* id3, |
822 | struct mp3entry* nid3, | ||
823 | int ffwd_offset, | ||
801 | unsigned char refresh_mode) | 824 | unsigned char refresh_mode) |
802 | { | 825 | { |
803 | char buf[MAX_PATH]; | 826 | char buf[MAX_PATH]; |
@@ -814,8 +837,8 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
814 | /* to find out wether the peak meter is enabled we | 837 | /* to find out wether the peak meter is enabled we |
815 | assume it wasn't until we find a line that contains | 838 | assume it wasn't until we find a line that contains |
816 | the peak meter. We can't use peak_meter_enabled itself | 839 | the peak meter. We can't use peak_meter_enabled itself |
817 | because that would mean to turn off the meter thread | 840 | because that would mean to turn off the meter thread |
818 | temporarily. (That shouldn't matter unless yield | 841 | temporarily. (That shouldn't matter unless yield |
819 | or sleep is called but who knows...) | 842 | or sleep is called but who knows...) |
820 | */ | 843 | */ |
821 | bool enable_pm = false; | 844 | bool enable_pm = false; |
@@ -852,7 +875,7 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
852 | 875 | ||
853 | /* if time to advance to next sub-line */ | 876 | /* if time to advance to next sub-line */ |
854 | if (TIME_AFTER(current_tick, subline_expire_time[i] - 1) || | 877 | if (TIME_AFTER(current_tick, subline_expire_time[i] - 1) || |
855 | (curr_subline[i] == SUBLINE_RESET)) | 878 | (curr_subline[i] == SUBLINE_RESET)) |
856 | { | 879 | { |
857 | /* search all sublines until the next subline with time > 0 | 880 | /* search all sublines until the next subline with time > 0 |
858 | is found or we get back to the subline we started with */ | 881 | is found or we get back to the subline we started with */ |
@@ -860,7 +883,7 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
860 | search_start = 0; | 883 | search_start = 0; |
861 | else | 884 | else |
862 | search_start = curr_subline[i]; | 885 | search_start = curr_subline[i]; |
863 | for (search=0; search<MAX_SUBLINES; search++) | 886 | for (search=0; search<MAX_SUBLINES; search++) |
864 | { | 887 | { |
865 | curr_subline[i]++; | 888 | curr_subline[i]++; |
866 | 889 | ||
@@ -884,37 +907,37 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
884 | } | 907 | } |
885 | else | 908 | else |
886 | { | 909 | { |
887 | /* get initial time multiplier and | 910 | /* get initial time multiplier and |
888 | line type flags for this subline */ | 911 | line type flags for this subline */ |
889 | format_display(buf, sizeof(buf), id3, | 912 | format_display(buf, sizeof(buf), id3, nid3, |
890 | format_lines[i][curr_subline[i]], | 913 | format_lines[i][curr_subline[i]], |
891 | &time_mult[i][curr_subline[i]], | 914 | &time_mult[i][curr_subline[i]], |
892 | &line_type[i][curr_subline[i]]); | 915 | &line_type[i][curr_subline[i]]); |
893 | 916 | ||
894 | /* only use this subline if subline time > 0 */ | 917 | /* only use this subline if subline time > 0 */ |
895 | if (time_mult[i][curr_subline[i]] > 0) | 918 | if (time_mult[i][curr_subline[i]] > 0) |
896 | { | 919 | { |
897 | new_subline_refresh = true; | 920 | new_subline_refresh = true; |
898 | subline_expire_time[i] = current_tick + | 921 | subline_expire_time[i] = current_tick + |
899 | BASE_SUBLINE_TIME * time_mult[i][curr_subline[i]]; | 922 | BASE_SUBLINE_TIME * time_mult[i][curr_subline[i]]; |
900 | break; | 923 | break; |
901 | } | 924 | } |
902 | } | 925 | } |
903 | } | 926 | } |
904 | 927 | ||
905 | } | 928 | } |
906 | 929 | ||
907 | update_line = false; | 930 | update_line = false; |
908 | 931 | ||
909 | if ( !format_lines[i][curr_subline[i]] ) | 932 | if ( !format_lines[i][curr_subline[i]] ) |
910 | break; | 933 | break; |
911 | 934 | ||
912 | if ((line_type[i][curr_subline[i]] & refresh_mode) || | 935 | if ((line_type[i][curr_subline[i]] & refresh_mode) || |
913 | (refresh_mode == WPS_REFRESH_ALL) || | 936 | (refresh_mode == WPS_REFRESH_ALL) || |
914 | new_subline_refresh) | 937 | new_subline_refresh) |
915 | { | 938 | { |
916 | flags = 0; | 939 | flags = 0; |
917 | format_display(buf, sizeof(buf), id3, | 940 | format_display(buf, sizeof(buf), id3, nid3, |
918 | format_lines[i][curr_subline[i]], | 941 | format_lines[i][curr_subline[i]], |
919 | &time_mult[i][curr_subline[i]], | 942 | &time_mult[i][curr_subline[i]], |
920 | &flags); | 943 | &flags); |
@@ -926,7 +949,7 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
926 | int percent= | 949 | int percent= |
927 | id3->length? | 950 | id3->length? |
928 | (id3->elapsed + ff_rewind_count) * 100 / id3->length:0; | 951 | (id3->elapsed + ff_rewind_count) * 100 / id3->length:0; |
929 | slidebar(0, i*h + offset + 1, LCD_WIDTH, 6, | 952 | slidebar(0, i*h + offset + 1, LCD_WIDTH, 6, |
930 | percent, Grow_Right); | 953 | percent, Grow_Right); |
931 | update_line = true; | 954 | update_line = true; |
932 | } | 955 | } |
@@ -937,8 +960,8 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
937 | update_line = true; | 960 | update_line = true; |
938 | peak_meter_y = i * h + offset; | 961 | peak_meter_y = i * h + offset; |
939 | 962 | ||
940 | /* The user might decide to have the peak meter in the last | 963 | /* The user might decide to have the peak meter in the last |
941 | line so that it is only displayed if no status bar is | 964 | line so that it is only displayed if no status bar is |
942 | visible. If so we neither want do draw nor enable the | 965 | visible. If so we neither want do draw nor enable the |
943 | peak meter. */ | 966 | peak meter. */ |
944 | if (peak_meter_y + h <= LCD_HEIGHT) { | 967 | if (peak_meter_y + h <= LCD_HEIGHT) { |
@@ -987,7 +1010,7 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
987 | #endif | 1010 | #endif |
988 | } | 1011 | } |
989 | #ifdef HAVE_LCD_BITMAP | 1012 | #ifdef HAVE_LCD_BITMAP |
990 | /* Now we know wether the peak meter is used. | 1013 | /* Now we know wether the peak meter is used. |
991 | So we can enable / disable the peak meter thread */ | 1014 | So we can enable / disable the peak meter thread */ |
992 | peak_meter_enabled = enable_pm; | 1015 | peak_meter_enabled = enable_pm; |
993 | #endif | 1016 | #endif |
@@ -996,12 +1019,12 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
996 | if (global_settings.caption_backlight && id3) { | 1019 | if (global_settings.caption_backlight && id3) { |
997 | /* turn on backlight n seconds before track ends, and turn it off n | 1020 | /* turn on backlight n seconds before track ends, and turn it off n |
998 | seconds into the new track. n == backlight_timeout, or 5s */ | 1021 | seconds into the new track. n == backlight_timeout, or 5s */ |
999 | int n = | 1022 | int n = |
1000 | backlight_timeout_value[global_settings.backlight_timeout] * 1000; | 1023 | backlight_timeout_value[global_settings.backlight_timeout] * 1000; |
1001 | 1024 | ||
1002 | if ( n < 1000 ) | 1025 | if ( n < 1000 ) |
1003 | n = 5000; /* use 5s if backlight is always on or off */ | 1026 | n = 5000; /* use 5s if backlight is always on or off */ |
1004 | 1027 | ||
1005 | if ((id3->elapsed < 1000) || | 1028 | if ((id3->elapsed < 1000) || |
1006 | ((id3->length - id3->elapsed) < (unsigned)n)) | 1029 | ((id3->length - id3->elapsed) < (unsigned)n)) |
1007 | backlight_on(); | 1030 | backlight_on(); |
@@ -1010,7 +1033,8 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, | |||
1010 | return true; | 1033 | return true; |
1011 | } | 1034 | } |
1012 | 1035 | ||
1013 | bool wps_display(struct mp3entry* id3) | 1036 | bool wps_display(struct mp3entry* id3, |
1037 | struct mp3entry* nid3) | ||
1014 | { | 1038 | { |
1015 | lcd_clear_display(); | 1039 | lcd_clear_display(); |
1016 | 1040 | ||
@@ -1049,7 +1073,7 @@ bool wps_display(struct mp3entry* id3) | |||
1049 | } | 1073 | } |
1050 | } | 1074 | } |
1051 | yield(); | 1075 | yield(); |
1052 | wps_refresh(id3, 0, WPS_REFRESH_ALL); | 1076 | wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL); |
1053 | status_draw(true); | 1077 | status_draw(true); |
1054 | lcd_update(); | 1078 | lcd_update(); |
1055 | return false; | 1079 | return false; |
@@ -1115,10 +1139,10 @@ static void draw_player_fullbar(char* buf, int buf_size, | |||
1115 | int digits[6]; | 1139 | int digits[6]; |
1116 | int time; | 1140 | int time; |
1117 | char timestr[7]; | 1141 | char timestr[7]; |
1118 | 1142 | ||
1119 | for (i=0; i < buf_size; i++) | 1143 | for (i=0; i < buf_size; i++) |
1120 | buf[i] = ' '; | 1144 | buf[i] = ' '; |
1121 | 1145 | ||
1122 | if(id3->elapsed >= id3->length) | 1146 | if(id3->elapsed >= id3->length) |
1123 | songpos = 55; | 1147 | songpos = 55; |
1124 | else { | 1148 | else { |
@@ -1129,7 +1153,7 @@ static void draw_player_fullbar(char* buf, int buf_size, | |||
1129 | } | 1153 | } |
1130 | 1154 | ||
1131 | time=(id3->elapsed + ff_rewind_count); | 1155 | time=(id3->elapsed + ff_rewind_count); |
1132 | 1156 | ||
1133 | memset(timestr, 0, sizeof(timestr)); | 1157 | memset(timestr, 0, sizeof(timestr)); |
1134 | format_time(timestr, sizeof(timestr), time); | 1158 | format_time(timestr, sizeof(timestr), time); |
1135 | for(lcd_char_pos=0; lcd_char_pos<6; lcd_char_pos++) { | 1159 | for(lcd_char_pos=0; lcd_char_pos<6; lcd_char_pos++) { |
@@ -1166,22 +1190,22 @@ static void draw_player_fullbar(char* buf, int buf_size, | |||
1166 | } | 1190 | } |
1167 | } | 1191 | } |
1168 | } | 1192 | } |
1169 | 1193 | ||
1170 | for (i=0; i<=6; i++) { | 1194 | for (i=0; i<=6; i++) { |
1171 | for (j=0;j<5;j++) { | 1195 | for (j=0;j<5;j++) { |
1172 | player_progressbar[i] <<= 1; | 1196 | player_progressbar[i] <<= 1; |
1173 | player_progressbar[i] += binline[i*5+j]; | 1197 | player_progressbar[i] += binline[i*5+j]; |
1174 | } | 1198 | } |
1175 | } | 1199 | } |
1176 | 1200 | ||
1177 | lcd_define_pattern(wps_progress_pat[lcd_char_pos+1],player_progressbar); | 1201 | lcd_define_pattern(wps_progress_pat[lcd_char_pos+1],player_progressbar); |
1178 | buf[lcd_char_pos]=wps_progress_pat[lcd_char_pos+1]; | 1202 | buf[lcd_char_pos]=wps_progress_pat[lcd_char_pos+1]; |
1179 | 1203 | ||
1180 | } | 1204 | } |
1181 | 1205 | ||
1182 | /* make rest of the progressbar if necessary */ | 1206 | /* make rest of the progressbar if necessary */ |
1183 | if (songpos/5>5) { | 1207 | if (songpos/5>5) { |
1184 | 1208 | ||
1185 | /* set the characters positions that use the full 5 pixel wide bar */ | 1209 | /* set the characters positions that use the full 5 pixel wide bar */ |
1186 | for (lcd_char_pos=6; lcd_char_pos < (songpos/5); lcd_char_pos++) | 1210 | for (lcd_char_pos=6; lcd_char_pos < (songpos/5); lcd_char_pos++) |
1187 | buf[lcd_char_pos] = 0x86; /* '_' */ | 1211 | buf[lcd_char_pos] = 0x86; /* '_' */ |
@@ -1197,16 +1221,16 @@ static void draw_player_fullbar(char* buf, int buf_size, | |||
1197 | } | 1221 | } |
1198 | } | 1222 | } |
1199 | } | 1223 | } |
1200 | 1224 | ||
1201 | for (i=0; i<7; i++) { | 1225 | for (i=0; i<7; i++) { |
1202 | for (j=0;j<5;j++) { | 1226 | for (j=0;j<5;j++) { |
1203 | player_progressbar[i] <<= 1; | 1227 | player_progressbar[i] <<= 1; |
1204 | player_progressbar[i] += binline[i*5+j]; | 1228 | player_progressbar[i] += binline[i*5+j]; |
1205 | } | 1229 | } |
1206 | } | 1230 | } |
1207 | 1231 | ||
1208 | lcd_define_pattern(wps_progress_pat[7],player_progressbar); | 1232 | lcd_define_pattern(wps_progress_pat[7],player_progressbar); |
1209 | 1233 | ||
1210 | buf[songpos/5]=wps_progress_pat[7]; | 1234 | buf[songpos/5]=wps_progress_pat[7]; |
1211 | } | 1235 | } |
1212 | } | 1236 | } |
diff --git a/apps/wps-display.h b/apps/wps-display.h index 12eed07c8f..7e5df59b5e 100644 --- a/apps/wps-display.h +++ b/apps/wps-display.h | |||
@@ -33,8 +33,9 @@ | |||
33 | #define WPS_REFRESH_NON_STATIC (WPS_REFRESH_ALL & ~WPS_REFRESH_STATIC & ~WPS_REFRESH_SCROLL) | 33 | #define WPS_REFRESH_NON_STATIC (WPS_REFRESH_ALL & ~WPS_REFRESH_STATIC & ~WPS_REFRESH_SCROLL) |
34 | 34 | ||
35 | 35 | ||
36 | bool wps_refresh(struct mp3entry* id3, int ffwd_offset, unsigned char refresh_mode); | 36 | bool wps_refresh(struct mp3entry* id3, struct mp3entry* nid3, |
37 | bool wps_display(struct mp3entry* id3); | 37 | int ffwd_offset, unsigned char refresh_mode); |
38 | bool wps_display(struct mp3entry* id3, struct mp3entry* nid3); | ||
38 | bool wps_load(char* file, bool display); | 39 | bool wps_load(char* file, bool display); |
39 | void wps_reset(void); | 40 | void wps_reset(void); |
40 | char* wps_get_genre(struct mp3entry* id3); | 41 | char* wps_get_genre(struct mp3entry* id3); |
diff --git a/apps/wps.c b/apps/wps.c index 858a93c934..18de01956c 100644 --- a/apps/wps.c +++ b/apps/wps.c | |||
@@ -54,6 +54,7 @@ bool keys_locked = false; | |||
54 | static bool ff_rewind = false; | 54 | static bool ff_rewind = false; |
55 | static bool paused = false; | 55 | static bool paused = false; |
56 | static struct mp3entry* id3 = NULL; | 56 | static struct mp3entry* id3 = NULL; |
57 | static struct mp3entry* nid3 = NULL; | ||
57 | static char current_track_path[MAX_PATH+1]; | 58 | static char current_track_path[MAX_PATH+1]; |
58 | 59 | ||
59 | #if defined(HAVE_PLAYER_KEYPAD) || defined(HAVE_NEO_KEYPAD) | 60 | #if defined(HAVE_PLAYER_KEYPAD) || defined(HAVE_NEO_KEYPAD) |
@@ -383,11 +384,11 @@ static bool ffwd_rew(int button) | |||
383 | } | 384 | } |
384 | 385 | ||
385 | if(wps_time_countup == false) | 386 | if(wps_time_countup == false) |
386 | wps_refresh(id3, -ff_rewind_count, | 387 | wps_refresh(id3, nid3, -ff_rewind_count, |
387 | WPS_REFRESH_PLAYER_PROGRESS | | 388 | WPS_REFRESH_PLAYER_PROGRESS | |
388 | WPS_REFRESH_DYNAMIC); | 389 | WPS_REFRESH_DYNAMIC); |
389 | else | 390 | else |
390 | wps_refresh(id3, ff_rewind_count, | 391 | wps_refresh(id3, nid3, ff_rewind_count, |
391 | WPS_REFRESH_PLAYER_PROGRESS | | 392 | WPS_REFRESH_PLAYER_PROGRESS | |
392 | WPS_REFRESH_DYNAMIC); | 393 | WPS_REFRESH_DYNAMIC); |
393 | 394 | ||
@@ -423,7 +424,7 @@ static bool ffwd_rew(int button) | |||
423 | 424 | ||
424 | /* let mpeg thread update id3->elapsed before calling wps_refresh */ | 425 | /* let mpeg thread update id3->elapsed before calling wps_refresh */ |
425 | yield(); | 426 | yield(); |
426 | wps_refresh(id3, 0, WPS_REFRESH_ALL); | 427 | wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL); |
427 | return usb; | 428 | return usb; |
428 | } | 429 | } |
429 | 430 | ||
@@ -436,17 +437,18 @@ static bool update(void) | |||
436 | { | 437 | { |
437 | lcd_stop_scroll(); | 438 | lcd_stop_scroll(); |
438 | id3 = mpeg_current_track(); | 439 | id3 = mpeg_current_track(); |
439 | if (wps_display(id3)) | 440 | nid3 = mpeg_next_track(); |
441 | if (wps_display(id3, nid3)) | ||
440 | retcode = true; | 442 | retcode = true; |
441 | else | 443 | else |
442 | wps_refresh(id3, 0, WPS_REFRESH_ALL); | 444 | wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL); |
443 | 445 | ||
444 | if (id3) | 446 | if (id3) |
445 | memcpy(current_track_path, id3->path, sizeof(current_track_path)); | 447 | memcpy(current_track_path, id3->path, sizeof(current_track_path)); |
446 | } | 448 | } |
447 | 449 | ||
448 | if (id3) | 450 | if (id3) |
449 | wps_refresh(id3, 0, WPS_REFRESH_NON_STATIC); | 451 | wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC); |
450 | 452 | ||
451 | status_draw(false); | 453 | status_draw(false); |
452 | 454 | ||
@@ -632,7 +634,7 @@ int wps_show(void) | |||
632 | bool exit = false; | 634 | bool exit = false; |
633 | bool update_track = false; | 635 | bool update_track = false; |
634 | 636 | ||
635 | id3 = NULL; | 637 | id3 = nid3 = NULL; |
636 | current_track_path[0] = '\0'; | 638 | current_track_path[0] = '\0'; |
637 | 639 | ||
638 | #ifdef HAVE_LCD_CHARCELLS | 640 | #ifdef HAVE_LCD_CHARCELLS |
@@ -650,10 +652,11 @@ int wps_show(void) | |||
650 | if(mpeg_status() & MPEG_STATUS_PLAY) | 652 | if(mpeg_status() & MPEG_STATUS_PLAY) |
651 | { | 653 | { |
652 | id3 = mpeg_current_track(); | 654 | id3 = mpeg_current_track(); |
655 | nid3 = mpeg_next_track(); | ||
653 | if (id3) { | 656 | if (id3) { |
654 | if (wps_display(id3)) | 657 | if (wps_display(id3, nid3)) |
655 | return 0; | 658 | return 0; |
656 | wps_refresh(id3, 0, WPS_REFRESH_ALL); | 659 | wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL); |
657 | 660 | ||
658 | memcpy(current_track_path, id3->path, sizeof(current_track_path)); | 661 | memcpy(current_track_path, id3->path, sizeof(current_track_path)); |
659 | } | 662 | } |
@@ -703,7 +706,7 @@ int wps_show(void) | |||
703 | sleep(1); | 706 | sleep(1); |
704 | 707 | ||
705 | if (TIME_AFTER(current_tick, next_refresh)) { | 708 | if (TIME_AFTER(current_tick, next_refresh)) { |
706 | wps_refresh(id3, 0, WPS_REFRESH_PEAK_METER); | 709 | wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER); |
707 | next_refresh = current_tick + HZ / peak_meter_fps; | 710 | next_refresh = current_tick + HZ / peak_meter_fps; |
708 | } | 711 | } |
709 | } | 712 | } |
@@ -712,12 +715,12 @@ int wps_show(void) | |||
712 | /* In energy saver mode the cpu may sleep a | 715 | /* In energy saver mode the cpu may sleep a |
713 | little bit while waiting for buttons */ | 716 | little bit while waiting for buttons */ |
714 | else { | 717 | else { |
715 | for (i = 0; i < 4; i++) { | 718 | for (i = 0; i < 4; i++) { |
716 | button = button_get_w_tmo(HZ / peak_meter_fps); | 719 | button = button_get_w_tmo(HZ / peak_meter_fps); |
717 | if (button != 0) { | 720 | if (button != 0) { |
718 | break; | 721 | break; |
719 | } | 722 | } |
720 | wps_refresh(id3, 0, WPS_REFRESH_PEAK_METER); | 723 | wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER); |
721 | } | 724 | } |
722 | } | 725 | } |
723 | } | 726 | } |
@@ -1008,7 +1011,7 @@ int wps_show(void) | |||
1008 | 1011 | ||
1009 | if (restore) { | 1012 | if (restore) { |
1010 | restore = false; | 1013 | restore = false; |
1011 | if (wps_display(id3)) | 1014 | if (wps_display(id3, nid3)) |
1012 | { | 1015 | { |
1013 | /* set dir browser to current playing song */ | 1016 | /* set dir browser to current playing song */ |
1014 | if (global_settings.browse_current && | 1017 | if (global_settings.browse_current && |
@@ -1019,7 +1022,7 @@ int wps_show(void) | |||
1019 | } | 1022 | } |
1020 | 1023 | ||
1021 | if (id3) | 1024 | if (id3) |
1022 | wps_refresh(id3, 0, WPS_REFRESH_NON_STATIC); | 1025 | wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC); |
1023 | } | 1026 | } |
1024 | if(button != BUTTON_NONE) | 1027 | if(button != BUTTON_NONE) |
1025 | lastbutton = button; | 1028 | lastbutton = button; |
diff --git a/docs/CUSTOM_WPS_FORMAT b/docs/CUSTOM_WPS_FORMAT index 11d53859a8..171a7d5906 100644 --- a/docs/CUSTOM_WPS_FORMAT +++ b/docs/CUSTOM_WPS_FORMAT | |||
@@ -76,6 +76,19 @@ Conditional Tags (If/Else block): | |||
76 | so the text in the if and else part can contain all % | 76 | so the text in the if and else part can contain all % |
77 | commands, including conditionals. | 77 | commands, including conditionals. |
78 | 78 | ||
79 | Next Song Info | ||
80 | -------------- | ||
81 | You can display information about the next song - the song that is about to | ||
82 | play after the one currently playing (unless you change the plan). | ||
83 | |||
84 | If you use the uppercase versions of the three tags: F, I and D, they will | ||
85 | instead refer to the next song instead of the current one. Example: %Ig is | ||
86 | the genre name used in the next song and %Ff is the mp3 frequency. | ||
87 | |||
88 | Take note that the next song information WILL NOT be available at all times, | ||
89 | but will most likely be available at the end of a song. We suggest you use the | ||
90 | conditional display tag a lot when displaying information about the next song! | ||
91 | |||
79 | Alternating Sublines | 92 | Alternating Sublines |
80 | -------------------- | 93 | -------------------- |
81 | It is possible to group items on each line into 2 or more groups or "sublines". | 94 | It is possible to group items on each line into 2 or more groups or "sublines". |