From a2e98c1cd926efdbfd0fd9f43005068b7684efbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Stenberg?= Date: Thu, 12 Dec 2002 15:20:37 +0000 Subject: [PATCH] Merged Uwe Freese's bidirectional scrolling patch. Added configurable scroll step size and scroll start delay. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2974 a1c6a512-1295-4272-9138-f99709370657 --- apps/lang/english.lang | 20 +++++++ apps/settings.c | 25 ++++++++ apps/settings.h | 4 ++ apps/settings_menu.c | 39 +++++++++++- firmware/drivers/lcd-player.c | 11 +++- firmware/drivers/lcd-recorder.c | 103 +++++++++++++++++++++++--------- firmware/drivers/lcd.h | 4 ++ firmware/id3.c | 11 ++-- 8 files changed, 178 insertions(+), 39 deletions(-) diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 595e4cc358..a6f1705f2b 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -1176,3 +1176,23 @@ id: LANG_MP3BUFFER_MARGIN desc: MP3 buffer margin time eng: "Anti-skip buffer" new: + +id: LANG_BIDIR_SCROLL +desc: Bidirectional scroll limit +eng: "Bidirectional Scroll Limit" +new: + +id: LANG_SCROLL_DELAY +desc: Delay before scrolling +eng: "Scroll Start Delay" +new: + +id: LANG_SCROLL_STEP +desc: Pixels to advance per scroll +eng: "Scroll Step Size" +new: + +id: LANG_SCROLL_STEP_EXAMPLE +desc: Pixels to advance per scroll +eng: "Scroll Step Size Setting Example Text" +new: diff --git a/apps/settings.c b/apps/settings.c index 2c97e20ba1..8f3bbbce34 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -125,6 +125,9 @@ modified unless the header & checksum test fails. Rest of config block, only saved to disk: +0xB5 scroll step in pixels +0xB6 scroll start and endpoint delay +0xB7 bidir scroll setting (bidi if 0-200% longer than screen width) 0xB8 (char[20]) WPS file 0xCC (char[20]) Lang file 0xE0 (char[20]) Font file @@ -363,6 +366,10 @@ int settings_save( void ) config_block[0x29]=(unsigned char)(global_settings.topruntime >> 8); } + config_block[0xb5]=(unsigned char)global_settings.scroll_step; + config_block[0xb6]=(unsigned char)global_settings.scroll_delay; + config_block[0xb7]=(unsigned char)global_settings.bidir_limit; + strncpy(&config_block[0xb8], global_settings.wps_file, MAX_FILENAME); strncpy(&config_block[0xcc], global_settings.lang_file, MAX_FILENAME); strncpy(&config_block[0xe0], global_settings.font_file, MAX_FILENAME); @@ -481,7 +488,11 @@ void settings_apply(void) } else font_reset(); + + lcd_bidir_scroll(global_settings.bidir_limit); + lcd_scroll_step(global_settings.scroll_step); #endif + lcd_scroll_delay(global_settings.scroll_delay * (HZ/10)); if ( global_settings.lang_file[0] && global_settings.lang_file[0] != 0xff ) { @@ -489,6 +500,8 @@ void settings_apply(void) global_settings.lang_file); lang_load(buf); } + + } /* @@ -633,6 +646,15 @@ void settings_load(void) global_settings.topruntime = config_block[0x28] | (config_block[0x29] << 8); + if (config_block[0xb5] != 0xff) + global_settings.scroll_step = config_block[0xb5]; + + if (config_block[0xb6] != 0xff) + global_settings.scroll_delay = config_block[0xb6]; + + if (config_block[0xb7] != 0xff) + global_settings.bidir_limit = config_block[0xb7]; + memcpy(&global_settings.resume_first_index, &config_block[0xF4], 4); memcpy(&global_settings.resume_seed, &config_block[0xF8], 4); @@ -818,6 +840,9 @@ void settings_reset(void) { global_settings.volume_type = 0; global_settings.battery_type = 0; global_settings.scroll_speed = 8; + global_settings.bidir_limit = 50; + global_settings.scroll_delay = 500; + global_settings.scroll_step = 6; global_settings.ff_rewind_min_step = DEFAULT_FF_REWIND_MIN_STEP; global_settings.ff_rewind_accel = DEFAULT_FF_REWIND_ACCEL_SETTING; global_settings.resume_index = -1; diff --git a/apps/settings.h b/apps/settings.h index 012131e528..b42b68a87c 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -134,6 +134,10 @@ struct user_settings int runtime; /* current runtime since last charge */ int topruntime; /* top known runtime */ + + int bidir_limit; /* bidir scroll length limit */ + int scroll_delay; /* delay (in 1/10s) before starting scroll */ + int scroll_step; /* pixels to advance per update */ }; /* prototypes */ diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 4342e9b2d5..95d3feaf25 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -399,10 +399,36 @@ static bool poweroff_idle_timer(void) static bool scroll_speed(void) { - return set_int(str(LANG_SCROLL), "", &global_settings.scroll_speed, - &lcd_scroll_speed, 1, 1, 30 ); + return set_int(str(LANG_SCROLL), "Hz", &global_settings.scroll_speed, + &lcd_scroll_speed, 1, 1, 10 ); } +#ifdef HAVE_LCD_BITMAP +static bool scroll_step(void) +{ + return set_int(str(LANG_SCROLL_STEP_EXAMPLE), "pixels", + &global_settings.scroll_step, + &lcd_scroll_step, 1, 1, LCD_WIDTH ); +} +#endif + +static bool scroll_delay(void) +{ + int dummy = global_settings.scroll_delay * (HZ/10); + int rc = set_int(str(LANG_SCROLL_DELAY), "ms", &dummy, + &lcd_scroll_delay, 100, 0, 2500 ); + global_settings.scroll_delay = dummy / (HZ/10); + return rc; +} + +#ifdef HAVE_LCD_BITMAP +static bool bidir_limit(void) +{ + return set_int(str(LANG_BIDIR_SCROLL), "%", &global_settings.bidir_limit, + &lcd_bidir_scroll, 25, 0, 200 ); +} +#endif + #ifdef HAVE_CHARGE_CTRL static bool deep_discharge(void) { @@ -636,7 +662,14 @@ static bool display_settings_menu(void) bool result; struct menu_items items[] = { - { str(LANG_SCROLL_MENU), scroll_speed }, + { str(LANG_SCROLL_MENU), scroll_speed }, +#ifdef HAVE_LCD_BITMAP + { str(LANG_SCROLL_STEP), scroll_step }, +#endif + { str(LANG_SCROLL_DELAY), scroll_delay }, +#ifdef HAVE_LCD_BITMAP + { str(LANG_BIDIR_SCROLL), bidir_limit }, +#endif { str(LANG_BACKLIGHT), backlight_timer }, { str(LANG_BACKLIGHT_ON_WHEN_CHARGING), backlight_on_when_charging }, { str(LANG_CONTRAST), contrast }, diff --git a/firmware/drivers/lcd-player.c b/firmware/drivers/lcd-player.c index 0d0be69119..fd5bf552c9 100644 --- a/firmware/drivers/lcd-player.c +++ b/firmware/drivers/lcd-player.c @@ -69,6 +69,7 @@ static void scroll_thread(void); static char scroll_stack[DEFAULT_STACK_SIZE]; static char scroll_name[] = "scroll"; static char scroll_speed = 8; /* updates per second */ +static char scroll_delay = HZ/2; /* delay before starting scroll */ static char scroll_spacing = 3; /* spaces between end and start of text */ static long scroll_start_tick; @@ -282,7 +283,7 @@ void lcd_puts_scroll(int x, int y, unsigned char* string ) struct scrollinfo* s; int index; - scroll_start_tick = current_tick + HZ/2; + scroll_start_tick = current_tick + scroll_delay; /* search for the next free entry */ for (index = 0; index < SCROLLABLE_LINES; index++) { @@ -381,7 +382,7 @@ void lcd_scroll_resume(void) struct scrollinfo* s; int index; - scroll_start_tick = current_tick + HZ/2; + scroll_start_tick = current_tick + scroll_delay; for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; @@ -396,7 +397,7 @@ void lcd_scroll_resume_line(int line) struct scrollinfo* s; int index; - scroll_start_tick = current_tick + HZ/2; + scroll_start_tick = current_tick + scroll_delay; for ( index = 0; index < SCROLLABLE_LINES; index++ ) { s = &scroll[index]; @@ -412,6 +413,10 @@ void lcd_scroll_speed(int speed) scroll_speed = speed; } +void lcd_scroll_delay(int ms) +{ + scroll_delay = ms / (HZ / 10); +} static void scroll_thread(void) { struct scrollinfo* s; diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c index 16729464fc..24c481144f 100644 --- a/firmware/drivers/lcd-recorder.c +++ b/firmware/drivers/lcd-recorder.c @@ -84,14 +84,18 @@ struct scrollinfo { int offset; int startx; int starty; + bool backward; /* scroll presently forward or backward? */ + bool bidir; + long start_tick; }; static void scroll_thread(void); static char scroll_stack[DEFAULT_STACK_SIZE]; static char scroll_name[] = "scroll"; static char scroll_speed = 8; /* updates per second */ +static int scroll_delay = HZ/2; /* ticks delay before start */ static char scroll_step = 6; /* pixels per scroll step */ -static long scroll_start_tick; +static int bidir_limit = 50; /* percent */ static struct scrollinfo scroll[SCROLLABLE_LINES]; static int xmargin = 0; static int ymargin = 0; @@ -669,8 +673,6 @@ void lcd_puts_scroll(int x, int y, unsigned char* string) 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]; @@ -678,6 +680,7 @@ void lcd_puts_scroll(int x, int y, unsigned char* string) break; } } + s->start_tick = current_tick + scroll_delay; lcd_puts(x,y,string); lcd_getstringsize(string, &w, &h); @@ -688,10 +691,24 @@ void lcd_puts_scroll(int x, int y, unsigned char* string) memset(s->line, 0, sizeof s->line); strcpy(s->line, string); - strcat(s->line, " "); - /* get new width incl. spaces */ + + /* get width */ s->width = lcd_getstringsize(s->line, &w, &h); + /* scroll bidirectional or forward only depending on the string width */ + if ( bidir_limit ) { + s->bidir = s->width < (LCD_WIDTH - xmargin) * + (100 + bidir_limit) / 100; + } + else + s->bidir = false; + + if (!s->bidir) { /* add spaces if scrolling in the round */ + strcat(s->line, " "); + /* get new width incl. spaces */ + s->width = lcd_getstringsize(s->line, &w, &h); + } + for (end = s->line; *end; end++); strncpy(end, string, LCD_WIDTH/2); @@ -700,6 +717,7 @@ void lcd_puts_scroll(int x, int y, unsigned char* string) s->offset = 0; s->startx = x; s->starty = y; + s->backward = false; } } @@ -786,8 +804,6 @@ void lcd_scroll_resume(void) 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 ) { @@ -801,8 +817,6 @@ 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 && @@ -814,9 +828,23 @@ void lcd_scroll_resume_line(int line) void lcd_scroll_speed(int speed) { - scroll_step = speed; + scroll_speed = speed; } +void lcd_scroll_step(int step) +{ + scroll_step = step; +} + +void lcd_scroll_delay(int ms) +{ + scroll_delay = ms / (HZ / 10); +} + +void lcd_bidir_scroll(int percent) +{ + bidir_limit = percent; +} static void scroll_thread(void) { struct scrollinfo* s; @@ -829,31 +857,50 @@ static void scroll_thread(void) scroll[index].mode = SCROLL_MODE_OFF; } - scroll_start_tick = current_tick; - while ( 1 ) { + for ( index = 0; index < SCROLLABLE_LINES; index++ ) { + s = &scroll[index]; - /* wait 0.5s before starting scroll */ - if ( TIME_AFTER(current_tick, scroll_start_tick) ) { + /* really scroll? */ + if ( s->mode != SCROLL_MODE_RUN ) + continue; - for ( index = 0; index < SCROLLABLE_LINES; index++ ) { - s = &scroll[index]; - if ( s->mode == SCROLL_MODE_RUN ) { + /* check pause */ + if (TIME_BEFORE(current_tick, s->start_tick)) + continue; - s->offset += scroll_step; + if (s->backward) + s->offset -= scroll_step; + else + s->offset += scroll_step; - 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_update_rect(xpos, ypos, LCD_WIDTH - xmargin, h); + if (s->bidir) { /* scroll bidirectional */ + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + scroll_delay * 2; + } + if (s->offset >= s->width - (LCD_WIDTH - xmargin)) { + /* at end of line */ + s->offset = s->width - (LCD_WIDTH - xmargin); + s->backward = true; + s->start_tick = current_tick + scroll_delay * 2; } } + else { + /* scroll forward the whole time */ + 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_update_rect(xpos, ypos, LCD_WIDTH - xmargin, h); } sleep(HZ/scroll_speed); diff --git a/firmware/drivers/lcd.h b/firmware/drivers/lcd.h index d5621881fb..5e1d8f4d07 100644 --- a/firmware/drivers/lcd.h +++ b/firmware/drivers/lcd.h @@ -39,6 +39,7 @@ 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_scroll_delay( int ms ); extern void lcd_set_contrast(int val); extern void lcd_write( bool command, int byte ); @@ -121,9 +122,12 @@ extern void lcd_clearpixel(int x, int y); extern void lcd_invertpixel(int x, int y); extern void lcd_roll(int pixels); +extern void lcd_bidir_scroll(int threshold); +extern void lcd_scroll_step(int pixels); extern void lcd_setfont(int font); extern void lcd_putsxy(int x, int y, unsigned char *string); extern int lcd_getstringsize(unsigned char *str, int *w, int *h); +extern int lcd_getstringsize(unsigned char *str, int *w, int *h); #endif /* CHARCELLS / BITMAP */ diff --git a/firmware/id3.c b/firmware/id3.c index 2dd03c19eb..be39aefd5e 100644 --- a/firmware/id3.c +++ b/firmware/id3.c @@ -255,17 +255,17 @@ static void setid3v2title(int fd, struct mp3entry *entry) version = header[3]; switch ( version ) { case 2: - entry->id3version = ID3_VER_2_2; + version = ID3_VER_2_2; minframesize = 8; break; case 3: - entry->id3version = ID3_VER_2_3; + version = ID3_VER_2_3; minframesize = 12; break; case 4: - entry->id3version = ID3_VER_2_4; + version = ID3_VER_2_4; minframesize = 12; break; @@ -273,6 +273,7 @@ static void setid3v2title(int fd, struct mp3entry *entry) /* unsupported id3 version */ return; } + entry->id3version = version; /* * We must have at least minframesize bytes left for the @@ -280,13 +281,13 @@ static void setid3v2title(int fd, struct mp3entry *entry) */ while(size > minframesize) { /* Read frame header and check length */ - if(version > 2) { + if(version >= ID3_VER_2_3) { if(10 != read(fd, header, 10)) return; /* Adjust for the 10 bytes we read */ size -= 10; - if (version > 3) { + if (version >= ID3_VER_2_4) { framelen = UNSYNC(header[4], header[5], header[6], header[7]); } else {