From 0fd0d224c343fa0afe79384935cc98743d649ca4 Mon Sep 17 00:00:00 2001 From: malle Date: Mon, 21 Oct 2002 13:14:25 +0000 Subject: [PATCH] Added multiline scroll support. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2729 a1c6a512-1295-4272-9138-f99709370657 --- apps/wps-display.c | 4 +- apps/wps.c | 4 + docs/CUSTOM_WPS_FORMAT | 2 +- firmware/drivers/lcd-player.c | 183 +++++++++++++++++++++++++++++-------- firmware/drivers/lcd-recorder.c | 195 +++++++++++++++++++++++++++++++--------- firmware/drivers/lcd.h | 3 + 6 files changed, 309 insertions(+), 82 deletions(-) diff --git a/apps/wps-display.c b/apps/wps-display.c index 3ddbc974c..6bca8cb40 100644 --- a/apps/wps-display.c +++ b/apps/wps-display.c @@ -530,7 +530,6 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, bool refresh_all) { char buf[MAX_PATH]; struct format_flags flags; - bool scroll_active = false; int i; #ifdef HAVE_LCD_BITMAP /* to find out wether the peak meter is enabled we @@ -602,9 +601,8 @@ bool wps_refresh(struct mp3entry* id3, int ffwd_offset, bool refresh_all) } #endif - if (!scroll_active && flags.scroll && !flags.dynamic) + if (flags.scroll && !flags.dynamic) { - scroll_active = true; lcd_puts_scroll(0, i, buf); } else diff --git a/apps/wps.c b/apps/wps.c index 3c486b178..f0ba54f3a 100644 --- a/apps/wps.c +++ b/apps/wps.c @@ -700,6 +700,8 @@ int wps_show(void) status_set_record(false); status_set_audio(false); #endif + lcd_stop_scroll(); + /* set dir browser to current playing song */ if (global_settings.browse_current && id3) set_current_file(id3->path); @@ -833,6 +835,8 @@ int wps_show(void) status_set_record(false); status_set_audio(false); #endif + lcd_stop_scroll(); + /* set dir browser to current playing song */ if (global_settings.browse_current && id3) set_current_file(id3->path); diff --git a/docs/CUSTOM_WPS_FORMAT b/docs/CUSTOM_WPS_FORMAT index 108019853..29e584a1a 100644 --- a/docs/CUSTOM_WPS_FORMAT +++ b/docs/CUSTOM_WPS_FORMAT @@ -71,7 +71,7 @@ Other Tags: %> : Display a '>' %s : Indicate that the line should scroll. Can occur anywhere in a line (given that the text is displayed; see conditional - below). Only the first line with a %s will actually scroll. + below). You can specify up to 10 scrolling lines. %s is ignored if combined with %pb, %pc or %pr on the same line (the result wouldn't be good anyway). diff --git a/firmware/drivers/lcd-player.c b/firmware/drivers/lcd-player.c index 64587b531..54202a6f1 100644 --- a/firmware/drivers/lcd-player.c +++ b/firmware/drivers/lcd-player.c @@ -46,9 +46,16 @@ #define LCD_CURSOR(x,y) ((char)(lcd_cram+((y)*16+(x)))) #define LCD_ICON(i) ((char)(lcd_iram+i)) +#define SCROLLABLE_LINES 2 + +#define SCROLL_MODE_OFF 0 +#define SCROLL_MODE_PAUSE 1 +#define SCROLL_MODE_RUN 2 + /*** generic code ***/ struct scrollinfo { + int mode; char text[MAX_PATH]; char line[32]; int textlen; @@ -63,10 +70,10 @@ static char scroll_stack[DEFAULT_STACK_SIZE]; static char scroll_name[] = "scroll"; static char scroll_speed = 8; /* updates per second */ static char scroll_spacing = 3; /* spaces between end and start of text */ +static long scroll_start_tick; -static struct scrollinfo scroll; /* only one scroll line at the moment */ -static int scroll_count = 0; +static struct scrollinfo scroll[SCROLLABLE_LINES]; static const unsigned char new_lcd_ascii[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, @@ -272,13 +279,26 @@ void lcd_init (void) void lcd_puts_scroll(int x, int y, unsigned char* string ) { - struct scrollinfo* s = &scroll; + struct scrollinfo* s; + int index; + + scroll_start_tick = current_tick + HZ/2; + + /* search for the next free entry */ + for (index = 0; index < SCROLLABLE_LINES; index++) { + s = &scroll[index]; + if (s->mode == SCROLL_MODE_OFF) { + break; + } + } + s->space = 11 - x; lcd_puts(x,y,string); s->textlen = strlen(string); if ( s->textlen > s->space ) { + s->mode = SCROLL_MODE_RUN; s->offset=s->space; s->startx=x; s->starty=y; @@ -289,31 +309,102 @@ void lcd_puts_scroll(int x, int y, unsigned char* string ) s->space > (int)sizeof s->line ? (int)sizeof s->line : s->space ); s->line[sizeof s->line - 1] = 0; - scroll_count = 1; } } - void lcd_stop_scroll(void) { - if ( scroll_count ) { - struct scrollinfo* s = &scroll; - scroll_count = 0; + struct scrollinfo* s; + int index; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->mode == SCROLL_MODE_RUN || + s->mode == SCROLL_MODE_PAUSE ) { + /* restore scrolled row */ + lcd_puts(s->startx, s->starty, s->text); + s->mode = SCROLL_MODE_OFF; + } + } + + lcd_update(); +} - /* restore scrolled row */ - lcd_puts(s->startx,s->starty,s->text); - lcd_update(); +void lcd_stop_scroll_line(int line) +{ + struct scrollinfo* s; + int index; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->startx == line && + ( s->mode == SCROLL_MODE_RUN || + s->mode == SCROLL_MODE_PAUSE )) { + /* restore scrolled row */ + lcd_puts(s->startx, s->starty, s->text); + s->mode = SCROLL_MODE_OFF; + } } + + lcd_update(); } void lcd_scroll_pause(void) { - scroll_count = 0; + struct scrollinfo* s; + int index; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->mode == SCROLL_MODE_RUN ) { + s->mode = SCROLL_MODE_PAUSE; + } + } +} + +void lcd_scroll_pause_line(int line) +{ + struct scrollinfo* s; + int index; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->startx == line && + s->mode == SCROLL_MODE_RUN ) { + s->mode = SCROLL_MODE_PAUSE; + } + } } void lcd_scroll_resume(void) { - scroll_count = 1; + struct scrollinfo* s; + int index; + + scroll_start_tick = current_tick + HZ/2; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->mode == SCROLL_MODE_PAUSE ) { + s->mode = SCROLL_MODE_RUN; + } + } +} + +void lcd_scroll_resume_line(int line) +{ + struct scrollinfo* s; + int index; + + scroll_start_tick = current_tick + HZ/2; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->startx == line && + s->mode == SCROLL_MODE_PAUSE ) { + s->mode = SCROLL_MODE_RUN; + } + } } void lcd_scroll_speed(int speed) @@ -323,36 +414,54 @@ void lcd_scroll_speed(int speed) static void scroll_thread(void) { - struct scrollinfo* s = &scroll; + struct scrollinfo* s; + int index; + int i; + bool update; + + /* initialize scroll struct array */ + for (index = 0; index < SCROLLABLE_LINES; index++) { + scroll[index].mode = SCROLL_MODE_OFF; + } + + scroll_start_tick = current_tick; while ( 1 ) { - if ( !scroll_count ) { - yield(); - continue; - } + + update = false; + /* wait 0.5s before starting scroll */ - if ( scroll_count < scroll_speed/2 ) - scroll_count++; - else { - int i; - for ( i=0; ispace-1; i++ ) - s->line[i] = s->line[i+1]; - - if ( s->offset < s->textlen ) { - s->line[(int)s->space - 1] = s->text[(int)s->offset]; - s->offset++; - } - else { - s->line[s->space - 1] = ' '; - if ( s->offset < s->textlen + scroll_spacing - 1 ) - s->offset++; - else - s->offset = 0; + if ( TIME_AFTER(current_tick, scroll_start_tick) ) { + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->mode == SCROLL_MODE_RUN ) { + update = true; + + for ( i = 0; i < s->space - 1; i++ ) + s->line[i] = s->line[i+1]; + + if ( s->offset < s->textlen ) { + s->line[(int)s->space - 1] = s->text[(int)s->offset]; + s->offset++; + } + else { + s->line[s->space - 1] = ' '; + if ( s->offset < s->textlen + scroll_spacing - 1 ) + s->offset++; + else + s->offset = 0; + } + + lcd_puts(s->startx,s->starty,s->line); + } } - lcd_puts(s->startx,s->starty,s->line); - lcd_update(); + if (update) { + lcd_update(); + } } + sleep(HZ/scroll_speed); } } diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c index 1c899307e..10071dc3d 100644 --- a/firmware/drivers/lcd-recorder.c +++ b/firmware/drivers/lcd-recorder.c @@ -70,7 +70,14 @@ #define SCROLL_SPACING 3 +#define SCROLLABLE_LINES 10 + +#define SCROLL_MODE_OFF 0 +#define SCROLL_MODE_PAUSE 1 +#define SCROLL_MODE_RUN 2 + struct scrollinfo { + int mode; char line[MAX_PATH + LCD_WIDTH/2 + SCROLL_SPACING + 2]; int len; /* length of line in chars */ int width; /* length of line in pixels */ @@ -84,8 +91,8 @@ static char scroll_stack[DEFAULT_STACK_SIZE]; static char scroll_name[] = "scroll"; static char scroll_speed = 8; /* updates per second */ static char scroll_step = 6; /* pixels per scroll step */ -static struct scrollinfo scroll; /* only one scroll line at the moment */ -static int scroll_count = 0; +static long scroll_start_tick; +static struct scrollinfo scroll[SCROLLABLE_LINES]; static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; @@ -656,16 +663,26 @@ void lcd_invertpixel(int x, int y) INVERT_PIXEL(x,y); } -void lcd_puts_scroll(int x, int y, unsigned char* string ) +void lcd_puts_scroll(int x, int y, unsigned char* string) { - struct scrollinfo* s = &scroll; + struct scrollinfo* s; int w, h; + int index; + + scroll_start_tick = current_tick + HZ/2; + + /* search for the next free entry */ + for (index = 0; index < SCROLLABLE_LINES; index++) { + s = &scroll[index]; + if (s->mode == SCROLL_MODE_OFF) { + break; + } + } lcd_puts(x,y,string); lcd_getstringsize(string, &w, &h); - if (LCD_WIDTH - x*8 - xmargin < w) - { + if (LCD_WIDTH - x * 8 - xmargin < w) { /* prepare scroll line */ char *end; @@ -678,42 +695,121 @@ void lcd_puts_scroll(int x, int y, unsigned char* string ) for (end = s->line; *end; end++); strncpy(end, string, LCD_WIDTH/2); + s->mode = SCROLL_MODE_RUN; s->len = strlen(string); s->offset = 0; s->startx = x; s->starty = y; - scroll_count = 1; } } - void lcd_stop_scroll(void) { - if ( scroll_count ) { - int w,h; - struct scrollinfo* s = &scroll; - scroll_count = 0; + struct scrollinfo* s; + int w,h; + int index; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->mode == SCROLL_MODE_RUN || + s->mode == SCROLL_MODE_PAUSE ) { + lcd_getstringsize(s->line, &w, &h); + lcd_clearrect(xmargin + s->startx * w / s->len, + ymargin + s->starty * h, + LCD_WIDTH - xmargin, + h); + + /* restore scrolled row */ + lcd_puts(s->startx, s->starty, s->line); + s->mode = SCROLL_MODE_OFF; + } + } - lcd_getstringsize(s->line, &w, &h); - lcd_clearrect(xmargin + s->startx*w/s->len, - ymargin + s->starty*h, - LCD_WIDTH - xmargin, - h); + lcd_update(); +} - /* restore scrolled row */ - lcd_puts(s->startx,s->starty,s->line); - lcd_update(); +void lcd_stop_scroll_line(int line) +{ + struct scrollinfo* s; + int w,h; + int index; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->startx == line && + ( s->mode == SCROLL_MODE_RUN || + s->mode == SCROLL_MODE_PAUSE )) { + lcd_getstringsize(s->line, &w, &h); + lcd_clearrect(xmargin + s->startx * w / s->len, + ymargin + s->starty * h, + LCD_WIDTH - xmargin, + h); + + /* restore scrolled row */ + lcd_puts(s->startx, s->starty, s->line); + s->mode = SCROLL_MODE_OFF; + } } + + lcd_update(); } void lcd_scroll_pause(void) { - scroll_count = 0; + struct scrollinfo* s; + int index; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->mode == SCROLL_MODE_RUN ) { + s->mode = SCROLL_MODE_PAUSE; + } + } +} + +void lcd_scroll_pause_line(int line) +{ + struct scrollinfo* s; + int index; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->startx == line && + s->mode == SCROLL_MODE_RUN ) { + s->mode = SCROLL_MODE_PAUSE; + } + } } void lcd_scroll_resume(void) { - scroll_count = 1; + struct scrollinfo* s; + int index; + + scroll_start_tick = current_tick + HZ/2; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->mode == SCROLL_MODE_PAUSE ) { + s->mode = SCROLL_MODE_RUN; + } + } +} + +void lcd_scroll_resume_line(int line) +{ + struct scrollinfo* s; + int index; + + scroll_start_tick = current_tick + HZ/2; + + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->startx == line && + s->mode == SCROLL_MODE_PAUSE ) { + s->mode = SCROLL_MODE_RUN; + } + } } void lcd_scroll_speed(int speed) @@ -723,33 +819,50 @@ void lcd_scroll_speed(int speed) static void scroll_thread(void) { - struct scrollinfo* s = &scroll; + struct scrollinfo* s; + int index; + int w, h; + int xpos, ypos; + bool update; + + /* initialize scroll struct array */ + for (index = 0; index < SCROLLABLE_LINES; index++) { + scroll[index].mode = SCROLL_MODE_OFF; + } + + scroll_start_tick = current_tick; while ( 1 ) { - if ( !scroll_count ) { - yield(); - continue; - } + + update = false; + /* wait 0.5s before starting scroll */ - if ( scroll_count < scroll_speed/2 ) - scroll_count++; - else { - int w, h; - int xpos, ypos; + if ( TIME_AFTER(current_tick, scroll_start_tick) ) { - s->offset += scroll_step; + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; + if ( s->mode == SCROLL_MODE_RUN ) { + update = true; - if (s->offset >= s->width) - s->offset %= s->width; + s->offset += scroll_step; - lcd_getstringsize(s->line, &w, &h); - xpos = xmargin + s->startx * w / s->len; - ypos = ymargin + s->starty * h; + if (s->offset >= s->width) + s->offset %= s->width; + + lcd_getstringsize(s->line, &w, &h); + xpos = xmargin + s->startx * w / s->len; + ypos = ymargin + s->starty * h; + + lcd_clearrect(xpos, ypos, LCD_WIDTH - xmargin, h); + lcd_putsxyofs(xpos, ypos, s->offset, s->line); + } + } - lcd_clearrect(xpos, ypos, LCD_WIDTH - xmargin, h); - lcd_putsxyofs(xpos, ypos, s->offset, s->line); - lcd_update(); + if (update) { + lcd_update(); + } } + sleep(HZ/scroll_speed); } } diff --git a/firmware/drivers/lcd.h b/firmware/drivers/lcd.h index e0cc8d981..29f4362dc 100644 --- a/firmware/drivers/lcd.h +++ b/firmware/drivers/lcd.h @@ -31,10 +31,13 @@ extern void lcd_backlight(bool on); extern void lcd_puts(int x, int y, unsigned char *string); extern void lcd_putc(int x, int y, unsigned char ch); extern void lcd_scroll_pause(void); +extern void lcd_scroll_pause_line(int line); extern void lcd_scroll_resume(void); +extern void lcd_scroll_resume_line(int line); extern void lcd_puts_scroll(int x, int y, unsigned char* string ); extern void lcd_icon(int icon, bool enable); extern void lcd_stop_scroll(void); +extern void lcd_stop_scroll_line(int line); extern void lcd_scroll_speed( int speed ); extern void lcd_set_contrast(int val); extern void lcd_write( bool command, int byte ); -- 2.11.4.GIT