summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Braun <markus.braun@krawel.de>2002-10-21 13:14:25 +0000
committerMarkus Braun <markus.braun@krawel.de>2002-10-21 13:14:25 +0000
commitbc254fe95f255e779b716ceb5ded09bda3857a2b (patch)
treebb01dd6e67cc6fe41d8ff6e0cccdeca411cde29b
parentf45345edd9a8dd7b3c1dde4560fa59dbc4a387bf (diff)
downloadrockbox-bc254fe95f255e779b716ceb5ded09bda3857a2b.tar.gz
rockbox-bc254fe95f255e779b716ceb5ded09bda3857a2b.tar.bz2
rockbox-bc254fe95f255e779b716ceb5ded09bda3857a2b.zip
Added multiline scroll support.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2729 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/wps-display.c4
-rw-r--r--apps/wps.c4
-rw-r--r--docs/CUSTOM_WPS_FORMAT2
-rw-r--r--firmware/drivers/lcd-player.c183
-rw-r--r--firmware/drivers/lcd-recorder.c195
-rw-r--r--firmware/drivers/lcd.h3
6 files changed, 309 insertions, 82 deletions
diff --git a/apps/wps-display.c b/apps/wps-display.c
index 3ddbc974c1..6bca8cb40d 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 3c486b1786..f0ba54f3a3 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 108019853c..29e584a1a2 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 64587b5319..54202a6f10 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; 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;
+ 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 1c899307ed..10071dc3d7 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 e0cc8d9819..29f4362dcf 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 );