From d2b625f818e8e04ace3c7532fe9c38eb0c0b1662 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 14 Jan 2004 07:59:06 +0000 Subject: 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 --- apps/wps-display.c | 290 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 243 insertions(+), 47 deletions(-) (limited to 'apps') 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 @@ #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 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 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 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 -- cgit v1.2.3