diff options
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/wps-display.c | 290 |
1 files changed, 243 insertions, 47 deletions
diff --git a/apps/wps-display.c b/apps/wps-display.c index 68d3eb5..6553e9b 100644 --- a/apps/wps-display.c +++ b/apps/wps-display.c @@ -54,11 +54,16 @@ #ifdef HAVE_LCD_BITMAP #define MAX_LINES 10 +#define FORMAT_BUFFER_SIZE 800 #else #define MAX_LINES 2 +#define FORMAT_BUFFER_SIZE 400 #endif - -#define FORMAT_BUFFER_SIZE 300 +#define MAX_SUBLINES 12 +#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* (10ths of sec) */ +#define BASE_SUBLINE_TIME 10 /* base time that multiplier is applied to + (1/HZ sec, or 100ths of sec) */ +#define SUBLINE_RESET -1 #ifdef HAVE_LCD_CHARCELLS static 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); #endif static char format_buffer[FORMAT_BUFFER_SIZE]; -static char* format_lines[MAX_LINES]; -static unsigned char line_type[MAX_LINES]; +static char* format_lines[MAX_LINES][MAX_SUBLINES]; +static unsigned char line_type[MAX_LINES][MAX_SUBLINES]; +static unsigned char time_mult[MAX_LINES][MAX_SUBLINES]; +static long subline_expire_time[MAX_LINES]; +static int curr_subline[MAX_LINES]; + static int ff_rewind_count; bool wps_time_countup = true; static bool wps_loaded = false; @@ -115,49 +124,76 @@ static void wps_format(char* fmt) char* buf = format_buffer; char* start_of_line = format_buffer; int line = 0; + int subline; strncpy(format_buffer, fmt, sizeof(format_buffer)); format_buffer[sizeof(format_buffer) - 1] = 0; - format_lines[line] = buf; + for (line=0; line<MAX_LINES; line++) + { + for (subline=0; subline<MAX_SUBLINES; subline++) + { + format_lines[line][subline] = 0; + time_mult[line][subline] = 0; + } + subline_expire_time[line] = 0; + curr_subline[line] = SUBLINE_RESET; + } + + line = 0; + subline = 0; + format_lines[line][subline] = buf; + while ((*buf) && (line < MAX_LINES)) { switch (*buf) { - case '\r': + /* skip % sequences so "%;" doesn't start a new subline */ + case '%': + buf++; + break; + + case '\r': /* CR */ *buf = 0; break; case '\n': /* LF */ *buf = 0; - if(*start_of_line != '#') /* A comment? */ + if (*start_of_line != '#') /* A comment? */ line++; if (line < MAX_LINES) { /* the next line starts on the next byte */ - format_lines[line] = buf+1; - start_of_line = format_lines[line]; + subline = 0; + format_lines[line][subline] = buf+1; + start_of_line = format_lines[line][subline]; } break; - } - buf++; - } - - /* if supplied input didn't define a format line - for each line on the wps, set the rest to null */ - if (line < MAX_LINES) - { - /* if the final line didn't terminate with a newline, - the line index wasn't incremented */ - if (buf != format_lines[line]) - line++; - for (; line < MAX_LINES; line++) - { - format_lines[line] = NULL; + case ';': /* start a new subline */ + *buf = 0; + subline++; + if (subline < MAX_SUBLINES) + { + format_lines[line][subline] = buf+1; + } + else /* exceeded max sublines, skip rest of line */ + { + while (*(++buf)) + { + if ((*buf == '\r') || (*buf == '\n')) + { + break; + } + } + buf--; + subline = 0; + } + break; } + buf++; } } @@ -169,6 +205,7 @@ void wps_reset(void) bool wps_load(char* file, bool display) { + int i, s; char buffer[FORMAT_BUFFER_SIZE]; int fd; @@ -187,17 +224,36 @@ bool wps_load(char* file, bool display) close(fd); if ( display ) { - int i; + bool any_defined_line; lcd_clear_display(); #ifdef HAVE_LCD_BITMAP lcd_setmargins(0,0); #endif - for (i=0; i<MAX_LINES && format_lines[i]; i++) - lcd_puts(0,i,format_lines[i]); - lcd_update(); - sleep(HZ); + for (s=0; s<MAX_SUBLINES; s++) + { + any_defined_line = false; + for (i=0; i<MAX_LINES; i++) + { + if (format_lines[i][s]) + { + if (*format_lines[i][s] == 0) + lcd_puts(0,i," "); + else + lcd_puts(0,i,format_lines[i][s]); + any_defined_line = true; + } + else + { + lcd_puts(0,i," "); + } + } + if (any_defined_line) + { + lcd_update(); + sleep(HZ/2); + } + } } - wps_loaded = true; return numread > 0; @@ -276,13 +332,18 @@ static char* get_tag(struct mp3entry* id3, char* tag, char* buf, int buf_size, + unsigned char* tag_len, + unsigned char* subline_time_mult, unsigned char* flags) { if ((0 == tag[0]) || (0 == tag[1])) { + *tag_len = 0; return NULL; } + *tag_len = 2; + switch (tag[0]) { case 'i': /* ID3 Information */ @@ -510,6 +571,46 @@ static char* get_tag(struct mp3entry* id3, } } break; + + case 't': /* set sub line time multiplier */ + { + int d = 1; + int time_mult = 0; + bool have_point = false; + bool have_tenth = false; + + while (((tag[d] >= '0') && + (tag[d] <= '9')) || + (tag[d] == '.')) + { + if (tag[d] != '.') + { + time_mult = time_mult * 10; + time_mult = time_mult + tag[d] - '0'; + if (have_point) + { + have_tenth = true; + d++; + break; + } + } + else + { + have_point = true; + } + d++; + } + + if (have_tenth == false) + time_mult *= 10; + + *subline_time_mult = time_mult; + *tag_len = d; + + buf[0] = 0; + return buf; + } + break; } return NULL; @@ -594,13 +695,18 @@ static void format_display(char* buf, int buf_size, struct mp3entry* id3, char* fmt, + unsigned char* subline_time_mult, unsigned char* flags) { char temp_buf[128]; + char* buf_start = buf; char* buf_end = buf + buf_size - 1; /* Leave room for end null */ char* value = NULL; int level = 0; - + unsigned char tag_length; + + *subline_time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; + while (fmt && *fmt && buf < buf_end) { switch (*fmt) @@ -639,12 +745,14 @@ static void format_display(char* buf, case '|': case '<': case '>': + case ';': *buf++ = *fmt++; break; case '?': fmt++; - value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf), flags); + value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf), + &tag_length, subline_time_mult, flags); while (*fmt && ('<' != *fmt)) fmt++; @@ -660,8 +768,9 @@ static void format_display(char* buf, break; default: - value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf), flags); - fmt += 2; + value = get_tag(id3, fmt, temp_buf, sizeof(temp_buf), + &tag_length, subline_time_mult, flags); + fmt += tag_length; if (value) { @@ -673,18 +782,27 @@ static void format_display(char* buf, *buf = 0; + /* if resulting line is an empty line, set the subline time to 0 */ + if (*buf_start == 0) + *subline_time_mult = 0; + /* If no flags have been set, the line didn't contain any format codes. We still want to refresh it. */ if(*flags == 0) *flags = WPS_REFRESH_STATIC; } -bool wps_refresh(struct mp3entry* id3, int ffwd_offset, unsigned char refresh_mode) +bool wps_refresh(struct mp3entry* id3, int ffwd_offset, + unsigned char refresh_mode) { char buf[MAX_PATH]; unsigned char flags; int i; bool update_line; + bool only_one_subline; + bool new_subline_refresh; + int search; + int search_start; #ifdef HAVE_LCD_BITMAP int h = font_get(FONT_UI)->height; 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 */ bool enable_pm = false; #endif + + /* reset to first subline if refresh all flag is set */ + if (refresh_mode == WPS_REFRESH_ALL) + { + for (i=0; i<MAX_LINES; i++) + { + curr_subline[i] = SUBLINE_RESET; + } + } + #ifdef HAVE_LCD_CHARCELLS for (i=0; i<8; i++) { if (wps_progress_pat[i]==0) @@ -714,17 +842,79 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, unsigned char refresh_mo for (i = 0; i < MAX_LINES; i++) { + new_subline_refresh = false; + only_one_subline = false; + + /* if time to advance to next sub-line */ + if (TIME_AFTER(current_tick, subline_expire_time[i] - 1) || + (curr_subline[i] == SUBLINE_RESET)) + { + /* search all sublines until the next subline with time > 0 + is found or we get back to the subline we started with */ + if (curr_subline[i] == SUBLINE_RESET) + search_start = 0; + else + search_start = curr_subline[i]; + for (search=0; search<MAX_SUBLINES; search++) + { + curr_subline[i]++; + + /* wrap around if beyond last defined subline or MAX_SUBLINES */ + if ((!format_lines[i][curr_subline[i]]) || + (curr_subline[i] == MAX_SUBLINES)) + { + if (curr_subline[i] == 1) + only_one_subline = true; + curr_subline[i] = 0; + } + + /* if back where we started after search or + only one subline is defined on the line */ + if (((search > 0) && (curr_subline[i] == search_start)) || + only_one_subline) + { + /* no other subline with a time > 0 exists */ + subline_expire_time[i] = current_tick + 100 * HZ; + break; + } + else + { + /* get initial time multiplier and + line type flags for this subline */ + format_display(buf, sizeof(buf), id3, + format_lines[i][curr_subline[i]], + &time_mult[i][curr_subline[i]], + &line_type[i][curr_subline[i]]); + + /* only use this subline if subline time > 0 */ + if (time_mult[i][curr_subline[i]] > 0) + { + new_subline_refresh = true; + subline_expire_time[i] = current_tick + + BASE_SUBLINE_TIME * time_mult[i][curr_subline[i]]; + break; + } + } + } + + } + update_line = false; - if ( !format_lines[i] ) + + if ( !format_lines[i][curr_subline[i]] ) break; - if ((line_type[i] & refresh_mode) || - (refresh_mode == WPS_REFRESH_ALL)) + if ((line_type[i][curr_subline[i]] & refresh_mode) || + (refresh_mode == WPS_REFRESH_ALL) || + new_subline_refresh) { flags = 0; - format_display(buf, sizeof(buf), id3, format_lines[i], &flags); - line_type[i] = flags; - + format_display(buf, sizeof(buf), id3, + format_lines[i][curr_subline[i]], + &time_mult[i][curr_subline[i]], + &flags); + line_type[i][curr_subline[i]] = flags; + #ifdef HAVE_LCD_BITMAP /* progress */ 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 draw_player_progress(id3, ff_rewind_count); } #endif + if (flags & WPS_REFRESH_SCROLL) { + /* scroll line */ - if (refresh_mode & WPS_REFRESH_SCROLL) { + if ((refresh_mode & WPS_REFRESH_SCROLL) || + new_subline_refresh) { lcd_puts_scroll(0, i, buf); update_line = true; } } - /* dynamic / static line */ - else if ((flags & refresh_mode & WPS_REFRESH_DYNAMIC) || - (flags & refresh_mode & WPS_REFRESH_STATIC)) + else if (flags & (WPS_REFRESH_DYNAMIC | WPS_REFRESH_STATIC)) { - update_line = true; - lcd_puts(0, i, buf); + /* dynamic / static line */ + if ((refresh_mode & (WPS_REFRESH_DYNAMIC|WPS_REFRESH_STATIC)) || + new_subline_refresh) + { + update_line = true; + lcd_puts(0, i, buf); + } } } #ifdef HAVE_LCD_BITMAP |