diff --git a/firmware/SOURCES b/firmware/SOURCES index 6470528746..b73a82a15c 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -58,6 +58,8 @@ common/timefuncs.c common/unicode.c /* Display */ +scroll_engine.c + #ifdef HAVE_LCD_CHARCELLS drivers/lcd-charcell.c drivers/lcd-charset-player.c diff --git a/firmware/backlight.c b/firmware/backlight.c index 10894e5c70..9277f34681 100644 --- a/firmware/backlight.c +++ b/firmware/backlight.c @@ -545,6 +545,18 @@ void backlight_thread(void) break; #endif +#if defined(HAVE_REMOTE_LCD) && !defined(SIMULATOR) + /* Here for now or else the aggressive init messes up scrolling */ + case SYS_REMOTE_PLUGGED: + lcd_remote_on(); + lcd_remote_update(); + break; + + case SYS_REMOTE_UNPLUGGED: + lcd_remote_off(); + break; +#endif /* defined(HAVE_REMOTE_LCD) && !defined(SIMULATOR) */ + case SYS_USB_CONNECTED: /* Tell the USB thread that we are safe */ DEBUGF("backlight_thread got SYS_USB_CONNECTED\n"); diff --git a/firmware/bidi.c b/firmware/bidi.c index b5851f298e..336291f68d 100644 --- a/firmware/bidi.c +++ b/firmware/bidi.c @@ -26,6 +26,7 @@ #include "lcd.h" #include "rbunicode.h" #include "arabjoin.h" +#include "scroll_engine.h" //#define _HEB_BUFFER_LENGTH (MAX_PATH + LCD_WIDTH/2 + 3 + 2 + 2) * 2 #define _HEB_BLOCK_TYPE_ENG 1 diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index 96711248ff..bd5d09368c 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c @@ -33,8 +33,7 @@ #include "font.h" #include "rbunicode.h" #include "bidi.h" - -#define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) +#include "scroll_engine.h" enum fill_opt { OPT_NONE = 0, @@ -62,23 +61,6 @@ static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; -/* scrolling */ -static volatile int scrolling_lines = 0; /* Bitpattern of which lines are scrolling */ -static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; -static const char scroll_name[] = "scroll"; -static void scroll_thread(void); -static int scroll_ticks = 12; /* # of ticks between updates*/ -static int scroll_delay = HZ/2; /* ticks delay before start */ -static int scroll_step = 6; /* pixels per scroll step */ -static int bidir_limit = 50; /* percent */ -static struct scrollinfo scroll[SCROLLABLE_LINES]; - -static const char scroll_tick_table[16] = { - /* Hz values: - 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ - 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 -}; - /* LCD init */ void lcd_init(void) { @@ -86,12 +68,7 @@ void lcd_init(void) /* Call device specific init */ lcd_init_device(); - - - create_thread(scroll_thread, scroll_stack, - sizeof(scroll_stack), scroll_name - IF_PRIO(, PRIORITY_USER_INTERFACE) - IF_COP(, CPU, false)); + scroll_init(); } /*** parameter handling ***/ @@ -243,7 +220,8 @@ void lcd_clear_display(void) else memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); } - scrolling_lines = 0; + + lcd_scroll_info.lines = 0; } /* Set a single pixel */ @@ -819,7 +797,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, int oldbgcolor = bg_pattern; /* make sure scrolling is turned off on the line we are updating */ - scrolling_lines &= ~(1 << y); + lcd_scroll_info.lines &= ~(1 << y); if(!str || !str[0]) return; @@ -845,46 +823,6 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, } /*** scrolling ***/ - -/* Reverse the invert setting of the scrolling line (if any) at given char - position. Setting will go into affect next time line scrolls. */ -void lcd_invertscroll(int x, int y) -{ - struct scrollinfo* s; - - (void)x; - - if(y>=SCROLLABLE_LINES) return; - - s = &scroll[y]; - s->invert = !s->invert; -} - -void lcd_stop_scroll(void) -{ - scrolling_lines=0; -} - -void lcd_scroll_speed(int speed) -{ - scroll_ticks = scroll_tick_table[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; -} - void lcd_puts_scroll(int x, int y, const unsigned char *string) { lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); @@ -906,11 +844,11 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, struct scrollinfo* s; int w, h; - if(y>=SCROLLABLE_LINES) return; - - s = &scroll[y]; + if(y>=LCD_SCROLLABLE_LINES) return; - s->start_tick = current_tick + scroll_delay; + s = &lcd_scroll_info.scroll[y]; + + s->start_tick = current_tick + lcd_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { s->invert = true; @@ -931,9 +869,9 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, /* scroll bidirectional or forward only depending on the string width */ - if ( bidir_limit ) { + if ( lcd_scroll_info.bidir_limit ) { s->bidir = s->width < (LCD_WIDTH - xmargin) * - (100 + bidir_limit) / 100; + (100 + lcd_scroll_info.bidir_limit) / 100; } else s->bidir = false; @@ -951,95 +889,84 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, s->offset = offset; s->startx = xmargin + x * s->width / s->len; s->backward = false; - s->line_colour = (style&STYLE_COLORED)? + s->line_color = (style&STYLE_COLORED)? (style&STYLE_COLOR_MASK): -1; - scrolling_lines |= (1<start_tick)) - continue; - if (s->line_colour >= 0) - { - if (s->invert) - { - lcd_set_foreground(old_fgcolour); - lcd_set_background(s->line_colour); - } - else - { - lcd_set_foreground(s->line_colour); - lcd_set_background(old_bgcolour); - } - } - - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; + s = &lcd_scroll_info.scroll[index]; - pf = font_get(curfont); - xpos = s->startx; - ypos = ymargin + index * pf->height; + /* check pause */ + if (TIME_BEFORE(current_tick, s->start_tick)) + continue; - 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 - xpos)) { - /* at end of line */ - s->offset = s->width - (LCD_WIDTH - xpos); - s->backward = true; - s->start_tick = current_tick + scroll_delay * 2; - } + if (s->line_color >= 0) { + if (s->invert) { + fg_pattern = old_fgcolor; + bg_pattern = s->line_color; } else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; + fg_pattern = s->line_color; + bg_pattern = old_bgcolor; } - - lastmode = drawmode; - drawmode = s->invert ? - (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_putsxyofs(xpos, ypos, s->offset, s->line); - drawmode = lastmode; - lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); } - lcd_set_foreground(old_fgcolour); - lcd_set_background(old_bgcolour); - sleep(scroll_ticks); + + if (s->backward) + s->offset -= lcd_scroll_info.step; + else + s->offset += lcd_scroll_info.step; + + pf = font_get(curfont); + xpos = s->startx; + ypos = ymargin + index * pf->height; + + if (s->bidir) { /* scroll bidirectional */ + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; + } + if (s->offset >= s->width - (LCD_WIDTH - xpos)) { + /* at end of line */ + s->offset = s->width - (LCD_WIDTH - xpos); + s->backward = true; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; + } + } + else { + /* scroll forward the whole time */ + if (s->offset >= s->width) + s->offset %= s->width; + } + + lastmode = drawmode; + drawmode = s->invert ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_putsxyofs(xpos, ypos, s->offset, s->line); + drawmode = lastmode; + lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); } + + fg_pattern = old_fgcolor; + bg_pattern = old_bgcolor; } diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index b54238d085..ac50eff95c 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c @@ -29,10 +29,7 @@ #include "font.h" #include "rbunicode.h" #include "bidi.h" - -/*** definitions ***/ - -#define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) +#include "scroll_engine.h" /*** globals ***/ @@ -43,32 +40,13 @@ static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; -/* scrolling */ -static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ -static void scroll_thread(void); -static char scroll_stack[DEFAULT_STACK_SIZE]; -static const char scroll_name[] = "scroll"; -static int scroll_ticks = 12; /* # of ticks between updates*/ -static int scroll_delay = HZ/2; /* ticks delay before start */ -static int scroll_step = 6; /* pixels per scroll step */ -static int bidir_limit = 50; /* percent */ -static struct scrollinfo scroll[SCROLLABLE_LINES]; - -static const char scroll_tick_table[16] = { - /* Hz values: - 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ - 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 -}; - /* LCD init */ void lcd_init(void) { lcd_clear_display(); /* Call device specific init */ lcd_init_device(); - create_thread(scroll_thread, scroll_stack, - sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) - IF_COP(, CPU, false)); + scroll_init(); } /*** parameter handling ***/ @@ -104,6 +82,11 @@ void lcd_setfont(int newfont) curfont = newfont; } +int lcd_getfont(void) +{ + return curfont; +} + int lcd_getstringsize(const unsigned char *str, int *w, int *h) { return font_getstringsize(str, w, h, curfont); @@ -212,7 +195,7 @@ void lcd_clear_display(void) unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); - scrolling_lines = 0; + lcd_scroll_info.lines = 0; } /* Set a single pixel */ @@ -664,7 +647,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int lastmode = drawmode; /* make sure scrolling is turned off on the line we are updating */ - scrolling_lines &= ~(1 << y); + lcd_scroll_info.lines &= ~(1 << y); if(!str || !str[0]) return; @@ -682,46 +665,6 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, } /*** scrolling ***/ - -/* Reverse the invert setting of the scrolling line (if any) at given char - position. Setting will go into affect next time line scrolls. */ -void lcd_invertscroll(int x, int y) -{ - struct scrollinfo* s; - - (void)x; - - if(y>=SCROLLABLE_LINES) return; - - s = &scroll[y]; - s->invert = !s->invert; -} - -void lcd_stop_scroll(void) -{ - scrolling_lines=0; -} - -void lcd_scroll_speed(int speed) -{ - scroll_ticks = scroll_tick_table[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; -} - void lcd_puts_scroll(int x, int y, const unsigned char *string) { lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); @@ -744,11 +687,11 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, struct scrollinfo* s; int w, h; - if(y>=SCROLLABLE_LINES) return; + if(y>=LCD_SCROLLABLE_LINES) return; - s = &scroll[y]; + s = &lcd_scroll_info.scroll[y]; - s->start_tick = current_tick + scroll_delay; + s->start_tick = current_tick + lcd_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { s->invert = true; @@ -771,9 +714,9 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, /* scroll bidirectional or forward only depending on the string width */ - if ( bidir_limit ) { + if ( lcd_scroll_info.bidir_limit ) { s->bidir = s->width < (LCD_WIDTH - xmargin) * - (100 + bidir_limit) / 100; + (100 + lcd_scroll_info.bidir_limit) / 100; } else s->bidir = false; @@ -791,14 +734,14 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, s->offset = offset; s->startx = xmargin + x * s->width / s->len;; s->backward = false; - scrolling_lines |= (1<start_tick)) + continue; - /* check pause */ - if (TIME_BEFORE(current_tick, s->start_tick)) - continue; + if (s->backward) + s->offset -= lcd_scroll_info.step; + else + s->offset += lcd_scroll_info.step; - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; + pf = font_get(curfont); + xpos = s->startx; + ypos = ymargin + index * pf->height; - pf = font_get(curfont); - xpos = s->startx; - ypos = ymargin + index * pf->height; - - 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 - xpos)) { - /* at end of line */ - s->offset = s->width - (LCD_WIDTH - xpos); - s->backward = true; - s->start_tick = current_tick + scroll_delay * 2; - } + if (s->bidir) { /* scroll bidirectional */ + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; } - else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; + if (s->offset >= s->width - (LCD_WIDTH - xpos)) { + /* at end of line */ + s->offset = s->width - (LCD_WIDTH - xpos); + s->backward = true; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; } - - lastmode = drawmode; - drawmode = s->invert ? - (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_putsxyofs(xpos, ypos, s->offset, s->line); - drawmode = lastmode; - lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + } + else { + /* scroll forward the whole time */ + if (s->offset >= s->width) + s->offset %= s->width; } - sleep(scroll_ticks); + lastmode = drawmode; + drawmode = s->invert ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_putsxyofs(xpos, ypos, s->offset, s->line); + drawmode = lastmode; + lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); } } - diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index d3d086a9d2..48fd22f703 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c @@ -33,8 +33,7 @@ #include "font.h" #include "rbunicode.h" #include "bidi.h" - -#define SCROLLABLE_LINES (((LCD_HEIGHT+4)/5 < 32) ? (LCD_HEIGHT+4)/5 : 32) +#include "scroll_engine.h" /*** globals ***/ @@ -54,33 +53,13 @@ static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; -/* scrolling */ -static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ -static void scroll_thread(void); -static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; -static const char scroll_name[] = "scroll"; -static int scroll_ticks = 12; /* # of ticks between updates*/ -static int scroll_delay = HZ/2; /* ticks delay before start */ -static int scroll_step = 6; /* pixels per scroll step */ -static int bidir_limit = 50; /* percent */ -static struct scrollinfo scroll[SCROLLABLE_LINES]; - -static const char scroll_tick_table[16] = { - /* Hz values: - 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ - 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 -}; - - /* LCD init */ void lcd_init(void) { lcd_clear_display(); /* Call device specific init */ lcd_init_device(); - create_thread(scroll_thread, scroll_stack, - sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) - IF_COP(, CPU, false)); + scroll_init(); } /*** parameter handling ***/ @@ -143,6 +122,11 @@ void lcd_setfont(int newfont) curfont = newfont; } +int lcd_getfont(void) +{ + return curfont; +} + int lcd_getstringsize(const unsigned char *str, int *w, int *h) { return font_getstringsize(str, w, h, curfont); @@ -377,7 +361,8 @@ void lcd_clear_display(void) else memset(lcd_framebuffer, bg_pattern, sizeof lcd_framebuffer); } - scrolling_lines = 0; + + lcd_scroll_info.lines = 0; } /* Set a single pixel */ @@ -862,7 +847,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int lastmode = drawmode; /* make sure scrolling is turned off on the line we are updating */ - scrolling_lines &= ~(1 << y); + lcd_scroll_info.lines &= ~(1 << y); if(!str || !str[0]) return; @@ -880,46 +865,6 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, } /*** scrolling ***/ - -/* Reverse the invert setting of the scrolling line (if any) at given char - position. Setting will go into affect next time line scrolls. */ -void lcd_invertscroll(int x, int y) -{ - struct scrollinfo* s; - - (void)x; - - if(y>=SCROLLABLE_LINES) return; - - s = &scroll[y]; - s->invert = !s->invert; -} - -void lcd_stop_scroll(void) -{ - scrolling_lines=0; -} - -void lcd_scroll_speed(int speed) -{ - scroll_ticks = scroll_tick_table[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; -} - void lcd_puts_scroll(int x, int y, const unsigned char *string) { lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); @@ -941,11 +886,11 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, struct scrollinfo* s; int w, h; - if(y>=SCROLLABLE_LINES) return; + if(y>=LCD_SCROLLABLE_LINES) return; - s = &scroll[y]; + s = &lcd_scroll_info.scroll[y]; - s->start_tick = current_tick + scroll_delay; + s->start_tick = current_tick + lcd_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { s->invert = true; @@ -968,9 +913,9 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, /* scroll bidirectional or forward only depending on the string width */ - if ( bidir_limit ) { + if ( lcd_scroll_info.bidir_limit ) { s->bidir = s->width < (LCD_WIDTH - xmargin) * - (100 + bidir_limit) / 100; + (100 + lcd_scroll_info.bidir_limit) / 100; } else s->bidir = false; @@ -988,14 +933,14 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, s->offset = offset; s->startx = xmargin + x * s->width / s->len;; s->backward = false; - scrolling_lines |= (1<start_tick)) + continue; - /* check pause */ - if (TIME_BEFORE(current_tick, s->start_tick)) - continue; + if (s->backward) + s->offset -= lcd_scroll_info.step; + else + s->offset += lcd_scroll_info.step; - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; + pf = font_get(curfont); + xpos = s->startx; + ypos = ymargin + index * pf->height; - pf = font_get(curfont); - xpos = s->startx; - ypos = ymargin + index * pf->height; - - 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 - xpos)) { - /* at end of line */ - s->offset = s->width - (LCD_WIDTH - xpos); - s->backward = true; - s->start_tick = current_tick + scroll_delay * 2; - } + if (s->bidir) { /* scroll bidirectional */ + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; } - else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; + if (s->offset >= s->width - (LCD_WIDTH - xpos)) { + /* at end of line */ + s->offset = s->width - (LCD_WIDTH - xpos); + s->backward = true; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; } - - lastmode = drawmode; - drawmode = s->invert ? - (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_putsxyofs(xpos, ypos, s->offset, s->line); - drawmode = lastmode; - lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + } + else { + /* scroll forward the whole time */ + if (s->offset >= s->width) + s->offset %= s->width; } - sleep(scroll_ticks); + lastmode = drawmode; + drawmode = s->invert ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_putsxyofs(xpos, ypos, s->offset, s->line); + drawmode = lastmode; + lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); } } diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c index 37abf0496f..751d2a2ad9 100644 --- a/firmware/drivers/lcd-2bit-vert.c +++ b/firmware/drivers/lcd-2bit-vert.c @@ -30,10 +30,7 @@ #include "font.h" #include "rbunicode.h" #include "bidi.h" - -/*** definitions ***/ - -#define SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) +#include "scroll_engine.h" /*** globals ***/ @@ -58,32 +55,13 @@ static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; -/* scrolling */ -static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ -static void scroll_thread(void); -static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; -static const char scroll_name[] = "scroll"; -static int scroll_ticks = 12; /* # of ticks between updates*/ -static int scroll_delay = HZ/2; /* ticks delay before start */ -static int scroll_step = 6; /* pixels per scroll step */ -static int bidir_limit = 50; /* percent */ -static struct scrollinfo scroll[SCROLLABLE_LINES]; - -static const char scroll_tick_table[16] = { - /* Hz values: - 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ - 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 -}; - /* LCD init */ void lcd_init(void) { lcd_clear_display(); /* Call device specific init */ lcd_init_device(); - create_thread(scroll_thread, scroll_stack, - sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) - IF_COP(, CPU, false)); + scroll_init(); } /*** parameter handling ***/ @@ -146,6 +124,11 @@ void lcd_setfont(int newfont) curfont = newfont; } +int lcd_getfont(void) +{ + return curfont; +} + int lcd_getstringsize(const unsigned char *str, int *w, int *h) { return font_getstringsize(str, w, h, curfont); @@ -380,7 +363,8 @@ void lcd_clear_display(void) else memset(lcd_framebuffer, bg_pattern, sizeof lcd_framebuffer); } - scrolling_lines = 0; + + lcd_scroll_info.lines = 0; } /* Set a single pixel */ @@ -998,7 +982,7 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int lastmode = drawmode; /* make sure scrolling is turned off on the line we are updating */ - scrolling_lines &= ~(1 << y); + lcd_scroll_info.lines &= ~(1 << y); if(!str || !str[0]) return; @@ -1017,45 +1001,6 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, /*** scrolling ***/ -/* Reverse the invert setting of the scrolling line (if any) at given char - position. Setting will go into affect next time line scrolls. */ -void lcd_invertscroll(int x, int y) -{ - struct scrollinfo* s; - - (void)x; - - if(y>=SCROLLABLE_LINES) return; - - s = &scroll[y]; - s->invert = !s->invert; -} - -void lcd_stop_scroll(void) -{ - scrolling_lines=0; -} - -void lcd_scroll_speed(int speed) -{ - scroll_ticks = scroll_tick_table[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; -} - void lcd_puts_scroll(int x, int y, const unsigned char *string) { lcd_puts_scroll_style(x, y, string, STYLE_DEFAULT); @@ -1077,11 +1022,11 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, struct scrollinfo* s; int w, h; - if(y>=SCROLLABLE_LINES) return; + if(y>=LCD_SCROLLABLE_LINES) return; - s = &scroll[y]; + s = &lcd_scroll_info.scroll[y]; - s->start_tick = current_tick + scroll_delay; + s->start_tick = current_tick + lcd_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { s->invert = true; @@ -1104,9 +1049,9 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, /* scroll bidirectional or forward only depending on the string width */ - if ( bidir_limit ) { + if ( lcd_scroll_info.bidir_limit ) { s->bidir = s->width < (LCD_WIDTH - xmargin) * - (100 + bidir_limit) / 100; + (100 + lcd_scroll_info.bidir_limit) / 100; } else s->bidir = false; @@ -1124,14 +1069,14 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, s->offset = offset; s->startx = xmargin + x * s->width / s->len; s->backward = false; - scrolling_lines |= (1<start_tick)) + continue; - /* check pause */ - if (TIME_BEFORE(current_tick, s->start_tick)) - continue; + if (s->backward) + s->offset -= lcd_scroll_info.step; + else + s->offset += lcd_scroll_info.step; - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; + pf = font_get(curfont); + xpos = s->startx; + ypos = ymargin + index * pf->height; - pf = font_get(curfont); - xpos = s->startx; - ypos = ymargin + index * pf->height; - - 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 - xpos)) { - /* at end of line */ - s->offset = s->width - (LCD_WIDTH - xpos); - s->backward = true; - s->start_tick = current_tick + scroll_delay * 2; - } + if (s->bidir) { /* scroll bidirectional */ + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; } - else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; + if (s->offset >= s->width - (LCD_WIDTH - xpos)) { + /* at end of line */ + s->offset = s->width - (LCD_WIDTH - xpos); + s->backward = true; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; } - - lastmode = drawmode; - drawmode = s->invert ? - (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_putsxyofs(xpos, ypos, s->offset, s->line); - drawmode = lastmode; - lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + } + else { + /* scroll forward the whole time */ + if (s->offset >= s->width) + s->offset %= s->width; } - sleep(scroll_ticks); + lastmode = drawmode; + drawmode = s->invert ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_putsxyofs(xpos, ypos, s->offset, s->line); + drawmode = lastmode; + lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); } } diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c index efc9aa5b1f..0fd41481c5 100644 --- a/firmware/drivers/lcd-charcell.c +++ b/firmware/drivers/lcd-charcell.c @@ -29,10 +29,10 @@ #include "system.h" #include "lcd-charcell.h" #include "rbunicode.h" +#include "scroll_engine.h" /** definitions **/ -#define SCROLLABLE_LINES LCD_HEIGHT #define VARIABLE_XCHARS 16 /* number of software user-definable characters */ /* There must be mappings for this many characters in the 0xe000 unicode range * in lcd-charset-.c */ @@ -55,24 +55,6 @@ static int xspace; /* stores xhcar id of ' ' - often needed */ static int xmargin = 0; static int ymargin = 0; -/* scrolling */ -static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ -static void scroll_thread(void); -static char scroll_stack[DEFAULT_STACK_SIZE]; -static const char scroll_name[] = "scroll"; -static int scroll_ticks = 12; /* # of ticks between updates */ -static int scroll_delay = HZ/2; /* delay before starting scroll */ -static int bidir_limit = 50; /* percent */ -static int jump_scroll_delay = HZ/4; /* delay between jump scroll jumps */ -static int jump_scroll = 0; /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ -static struct scrollinfo scroll[SCROLLABLE_LINES]; - -static const char scroll_tick_table[16] = { - /* Hz values: - 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ - 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 -}; - /* LCD init */ void lcd_init (void) { @@ -81,11 +63,7 @@ void lcd_init (void) memset(lcd_patterns, 0, sizeof(lcd_patterns)); xspace = find_xchar(' '); memset(lcd_charbuffer, xchar_info[xspace].hw_char, sizeof(lcd_charbuffer)); - - create_thread(scroll_thread, scroll_stack, - sizeof(scroll_stack), scroll_name - IF_PRIO(, PRIORITY_USER_INTERFACE) - IF_COP(, CPU, false)); + scroll_init(); } /** parameter handling **/ @@ -336,7 +314,7 @@ void lcd_put_cursor(int x, int y, unsigned long cursor_ucs) lcd_cursor.x = x; lcd_cursor.y = y; lcd_cursor.downcount = 0; - lcd_cursor.divider = MAX((HZ/2) / scroll_ticks, 1); + lcd_cursor.divider = MAX((HZ/2) / lcd_scroll_info.ticks, 1); } /* Remove the cursor */ @@ -398,7 +376,7 @@ void lcd_puts_offset(int x, int y, const unsigned char *str, int offset) return; /* make sure scrolling is turned off on the line we are updating */ - scrolling_lines &= ~(1 << y); + lcd_scroll_info.lines &= ~(1 << y); x = lcd_putsxyofs(x, y, offset, str); while (x < LCD_WIDTH) @@ -406,37 +384,6 @@ void lcd_puts_offset(int x, int y, const unsigned char *str, int offset) } /** scrolling **/ - -void lcd_stop_scroll(void) -{ - scrolling_lines=0; -} - -void lcd_scroll_speed(int speed) -{ - scroll_ticks = scroll_tick_table[speed]; -} - -void lcd_scroll_delay(int ms) -{ - scroll_delay = ms / (HZ / 10); -} - -void lcd_bidir_scroll(int percent) -{ - bidir_limit = percent; -} - -void lcd_jump_scroll(int mode) /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ -{ - jump_scroll = mode; -} - -void lcd_jump_scroll_delay(int ms) -{ - jump_scroll_delay = ms / (HZ / 10); -} - void lcd_puts_scroll(int x, int y, const unsigned char *string) { lcd_puts_scroll_offset(x, y, string, 0); @@ -448,11 +395,11 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, struct scrollinfo* s; int len; - if(y>=SCROLLABLE_LINES) return; + if(y>=LCD_SCROLLABLE_LINES) return; - s = &scroll[y]; + s = &lcd_scroll_info.scroll[y]; - s->start_tick = current_tick + scroll_delay; + s->start_tick = current_tick + lcd_scroll_info.delay; lcd_puts_offset(x, y, string, offset); len = utf8length(string); @@ -469,9 +416,10 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, s->len = utf8length(s->line); /* scroll bidirectional or forward only depending on the string width */ - if (bidir_limit) + if (lcd_scroll_info.bidir_limit) { - s->bidir = s->len < (LCD_WIDTH - xmargin) * (100 + bidir_limit) / 100; + s->bidir = s->len < (LCD_WIDTH - xmargin) * + (100 + lcd_scroll_info.bidir_limit) / 100; } else s->bidir = false; @@ -489,83 +437,77 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, s->offset = offset; s->startx = xmargin + x; s->backward = false; - scrolling_lines |= (1<start_tick)) + continue; + + if (s->backward) + s->offset--; + else + s->offset++; + + xpos = s->startx; + ypos = ymargin + index; + + if (s->bidir) /* scroll bidirectional */ { - /* really scroll? */ - if (!(scrolling_lines&(1<start_tick)) - continue; - - if (s->backward) - s->offset--; - else - s->offset++; - - xpos = s->startx; - ypos = ymargin + index; - - 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->len - (LCD_WIDTH - xpos)) - { - /* at end of line */ - s->offset = s->len - (LCD_WIDTH - xpos); - s->backward = true; - s->start_tick = current_tick + scroll_delay * 2; - } + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; } - else /* scroll forward the whole time */ - { - if (s->offset >= s->len) - s->offset -= s->len; + if (s->offset >= s->len - (LCD_WIDTH - xpos)) { + /* at end of line */ + s->offset = s->len - (LCD_WIDTH - xpos); + s->backward = true; + s->start_tick = current_tick + lcd_scroll_info.delay * 2; } - lcd_putsxyofs(xpos, ypos, s->offset, s->line); + } + else /* scroll forward the whole time */ + { + if (s->offset >= s->len) + s->offset -= s->len; + } + + lcd_putsxyofs(xpos, ypos, s->offset, s->line); + update = true; + } + + if (lcd_cursor.enabled) + { + if (--lcd_cursor.downcount <= 0) + { + lcd_cursor.downcount = lcd_cursor.divider; + lcd_cursor.visible = !lcd_cursor.visible; update = true; } - if (lcd_cursor.enabled) - { - if (--lcd_cursor.downcount <= 0) - { - lcd_cursor.downcount = lcd_cursor.divider; - lcd_cursor.visible = !lcd_cursor.visible; - update = true; - } - } - if (update) - lcd_update(); - - sleep(scroll_ticks); } + + if (update) + lcd_update(); } + diff --git a/firmware/drivers/lcd-remote-1bit-v.c b/firmware/drivers/lcd-remote-1bit-v.c index 6b5b1fb42f..1ddd8e5071 100644 --- a/firmware/drivers/lcd-remote-1bit-v.c +++ b/firmware/drivers/lcd-remote-1bit-v.c @@ -31,8 +31,7 @@ #include "font.h" #include "rbunicode.h" #include "bidi.h" - -#define SCROLLABLE_LINES (((LCD_REMOTE_HEIGHT+4)/5 < 32) ? (LCD_REMOTE_HEIGHT+4)/5 : 32) +#include "scroll_engine.h" /*** globals ***/ @@ -44,28 +43,6 @@ static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; -/* scrolling */ -static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ -static void scroll_thread(void); -static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; -static const char scroll_name[] = "remote_scroll"; -static int scroll_ticks = 12; /* # of ticks between updates*/ -static int scroll_delay = HZ/2; /* ticks delay before start */ -static int scroll_step = 6; /* pixels per scroll step */ -static int bidir_limit = 50; /* percent */ -static struct scrollinfo scroll[SCROLLABLE_LINES]; - -static const char scroll_tick_table[16] = { - /* Hz values: - 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ - 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 -}; - -/* remote hotplug */ -#ifndef SIMULATOR -struct event_queue remote_scroll_queue; -#endif - /*** parameter handling ***/ void lcd_remote_set_drawmode(int mode) @@ -94,12 +71,16 @@ int lcd_remote_getymargin(void) return ymargin; } - void lcd_remote_setfont(int newfont) { curfont = newfont; } +int lcd_remote_getfont(void) +{ + return curfont; +} + int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) { return font_getstringsize(str, w, h, curfont); @@ -208,7 +189,7 @@ void lcd_remote_clear_display(void) unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; memset(lcd_remote_framebuffer, bits, sizeof lcd_remote_framebuffer); - scrolling_lines = 0; + lcd_remote_scroll_info.lines = 0; } /* Set a single pixel */ @@ -599,7 +580,7 @@ void lcd_remote_bitmap(const unsigned char *src, int x, int y, int width, } /* put a string at a given pixel position, skipping first ofs pixel columns */ -static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) +void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) { unsigned short ch; unsigned short *ucs; @@ -664,7 +645,7 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, int lastmode = drawmode; /* make sure scrolling is turned off on the line we are updating */ - scrolling_lines &= ~(1 << y); + lcd_remote_scroll_info.lines &= ~(1 << y); if(!str || !str[0]) return; @@ -683,45 +664,6 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, /*** scrolling ***/ -/* Reverse the invert setting of the scrolling line (if any) at given char - position. Setting will go into affect next time line scrolls. */ -void lcd_remote_invertscroll(int x, int y) -{ - struct scrollinfo* s; - - (void)x; - - if(y>=SCROLLABLE_LINES) return; - - s = &scroll[y]; - s->invert = !s->invert; -} - -void lcd_remote_stop_scroll(void) -{ - scrolling_lines=0; -} - -void lcd_remote_scroll_speed(int speed) -{ - scroll_ticks = scroll_tick_table[speed]; -} - -void lcd_remote_scroll_step(int step) -{ - scroll_step = step; -} - -void lcd_remote_scroll_delay(int ms) -{ - scroll_delay = ms / (HZ / 10); -} - -void lcd_remote_bidir_scroll(int percent) -{ - bidir_limit = percent; -} - void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) { lcd_remote_puts_scroll_style(x, y, string, STYLE_DEFAULT); @@ -743,11 +685,11 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri struct scrollinfo* s; int w, h; - if(y>=SCROLLABLE_LINES) return; + if(y>=LCD_REMOTE_SCROLLABLE_LINES) return; - s = &scroll[y]; + s = &lcd_remote_scroll_info.scroll[y]; - s->start_tick = current_tick + scroll_delay; + s->start_tick = current_tick + lcd_remote_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { s->invert = true; @@ -770,9 +712,9 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri /* scroll bidirectional or forward only depending on the string width */ - if ( bidir_limit ) { + if ( lcd_remote_scroll_info.bidir_limit ) { s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * - (100 + bidir_limit) / 100; + (100 + lcd_remote_scroll_info.bidir_limit) / 100; } else s->bidir = false; @@ -790,110 +732,67 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri s->offset = offset; s->startx = xmargin + x * s->width / s->len;; s->backward = false; - scrolling_lines |= (1<= 0) + for ( index = 0; index < LCD_REMOTE_SCROLLABLE_LINES; index++ ) { + /* really scroll? */ + if ((lcd_remote_scroll_info.lines & (1 << index)) == 0) continue; -#endif - for ( index = 0; index < SCROLLABLE_LINES; index++ ) { - /* really scroll? */ - if ( !(scrolling_lines&(1<start_tick)) - continue; + /* check pause */ + if (TIME_BEFORE(current_tick, s->start_tick)) + continue; - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; + if (s->backward) + s->offset -= lcd_remote_scroll_info.step; + else + s->offset += lcd_remote_scroll_info.step; - pf = font_get(curfont); - xpos = s->startx; - ypos = ymargin + index * pf->height; + pf = font_get(curfont); + xpos = s->startx; + ypos = ymargin + index * pf->height; - 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_REMOTE_WIDTH - xpos)) { - /* at end of line */ - s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); - s->backward = true; - s->start_tick = current_tick + scroll_delay * 2; - } + if (s->bidir) { /* scroll bidirectional */ + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; } - else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; + if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) { + /* at end of line */ + s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); + s->backward = true; + s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; } - - lastmode = drawmode; - drawmode = s->invert ? - (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); - drawmode = lastmode; - lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); + } + else { + /* scroll forward the whole time */ + if (s->offset >= s->width) + s->offset %= s->width; } - next_tick += scroll_ticks; - delay = next_tick - current_tick - 1; - if (delay < 0) - { - next_tick = current_tick + 1; - delay = 0; - } + lastmode = drawmode; + drawmode = s->invert ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); + drawmode = lastmode; + lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); } } @@ -903,10 +802,5 @@ void lcd_remote_init(void) #ifndef SIMULATOR /* Call device specific init */ lcd_remote_init_device(); - /* private queue */ - queue_init(&remote_scroll_queue, false); #endif - create_thread(scroll_thread, scroll_stack, - sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) - IF_COP(, CPU, false)); } diff --git a/firmware/drivers/lcd-remote-2bit-vi.c b/firmware/drivers/lcd-remote-2bit-vi.c index 65704f0bd3..21e3ee4aa0 100644 --- a/firmware/drivers/lcd-remote-2bit-vi.c +++ b/firmware/drivers/lcd-remote-2bit-vi.c @@ -34,8 +34,7 @@ #include "rbunicode.h" #include "bidi.h" #include "lcd-remote-target.h" - -#define SCROLLABLE_LINES (((LCD_REMOTE_HEIGHT+4)/5 < 32) ? (LCD_REMOTE_HEIGHT+4)/5 : 32) +#include "scroll_engine.h" /*** globals ***/ @@ -54,28 +53,6 @@ static int xmargin = 0; static int ymargin = 0; static int curfont = FONT_SYSFIXED; -/* scrolling */ -static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ -static void scroll_thread(void); -static long scroll_stack[DEFAULT_STACK_SIZE/sizeof(long)]; -static const char scroll_name[] = "remote_scroll"; -static int scroll_ticks = 12; /* # of ticks between updates*/ -static int scroll_delay = HZ/2; /* ticks delay before start */ -static int scroll_step = 6; /* pixels per scroll step */ -static int bidir_limit = 50; /* percent */ -static struct scrollinfo scroll[SCROLLABLE_LINES]; - -static const char scroll_tick_table[16] = { - /* Hz values: - 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ - 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 -}; - -/* remote hotplug */ -#ifndef SIMULATOR -struct event_queue remote_scroll_queue; -#endif - /*** parameter handling ***/ unsigned lcd_remote_color_to_native(unsigned color) { @@ -149,6 +126,11 @@ void lcd_remote_setfont(int newfont) curfont = newfont; } +int lcd_remote_getfont(void) +{ + return curfont; +} + int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) { return font_getstringsize(str, w, h, curfont); @@ -388,7 +370,8 @@ void lcd_remote_clear_display(void) memset(lcd_remote_framebuffer, bg_pattern, sizeof lcd_remote_framebuffer); } - scrolling_lines = 0; + + lcd_remote_scroll_info.lines = 0; } /* Set a single pixel */ @@ -935,7 +918,7 @@ void lcd_remote_bitmap(const fb_remote_data *src, int x, int y, int width, } /* put a string at a given pixel position, skipping first ofs pixel columns */ -static void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) +void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) { unsigned short ch; unsigned short *ucs; @@ -1000,7 +983,7 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, int lastmode = drawmode; /* make sure scrolling is turned off on the line we are updating */ - scrolling_lines &= ~(1 << y); + lcd_remote_scroll_info.lines &= ~(1 << y); if(!str || !str[0]) return; @@ -1018,46 +1001,6 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, } /*** scrolling ***/ - -/* Reverse the invert setting of the scrolling line (if any) at given char - position. Setting will go into affect next time line scrolls. */ -void lcd_remote_invertscroll(int x, int y) -{ - struct scrollinfo* s; - - (void)x; - - if(y>=SCROLLABLE_LINES) return; - - s = &scroll[y]; - s->invert = !s->invert; -} - -void lcd_remote_stop_scroll(void) -{ - scrolling_lines=0; -} - -void lcd_remote_scroll_speed(int speed) -{ - scroll_ticks = scroll_tick_table[speed]; -} - -void lcd_remote_scroll_step(int step) -{ - scroll_step = step; -} - -void lcd_remote_scroll_delay(int ms) -{ - scroll_delay = ms / (HZ / 10); -} - -void lcd_remote_bidir_scroll(int percent) -{ - bidir_limit = percent; -} - void lcd_remote_puts_scroll(int x, int y, const unsigned char *string) { lcd_remote_puts_scroll_style(x, y, string, STYLE_DEFAULT); @@ -1079,11 +1022,11 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri struct scrollinfo* s; int w, h; - if(y>=SCROLLABLE_LINES) return; + if(y>=LCD_REMOTE_SCROLLABLE_LINES) return; - s = &scroll[y]; + s = &lcd_remote_scroll_info.scroll[y]; - s->start_tick = current_tick + scroll_delay; + s->start_tick = current_tick + lcd_remote_scroll_info.delay; s->invert = false; if (style & STYLE_INVERT) { s->invert = true; @@ -1106,9 +1049,9 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri /* scroll bidirectional or forward only depending on the string width */ - if ( bidir_limit ) { + if ( lcd_remote_scroll_info.bidir_limit ) { s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * - (100 + bidir_limit) / 100; + (100 + lcd_remote_scroll_info.bidir_limit) / 100; } else s->bidir = false; @@ -1126,112 +1069,67 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri s->offset = offset; s->startx = xmargin + x * s->width / s->len;; s->backward = false; - scrolling_lines |= (1<= 0) + for ( index = 0; index < LCD_REMOTE_SCROLLABLE_LINES; index++ ) { + /* really scroll? */ + if ((lcd_remote_scroll_info.lines & (1 << index)) == 0) continue; -#endif - for ( index = 0; index < SCROLLABLE_LINES; index++ ) { - /* really scroll? */ - if ( !(scrolling_lines&(1<start_tick)) + continue; - /* check pause */ - if (TIME_BEFORE(current_tick, s->start_tick)) - continue; + if (s->backward) + s->offset -= lcd_remote_scroll_info.step; + else + s->offset += lcd_remote_scroll_info.step; - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; + pf = font_get(curfont); + xpos = s->startx; + ypos = ymargin + index * pf->height; - pf = font_get(curfont); - xpos = s->startx; - ypos = ymargin + index * pf->height; - - 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_REMOTE_WIDTH - xpos)) { - /* at end of line */ - s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); - s->backward = true; - s->start_tick = current_tick + scroll_delay * 2; - } + if (s->bidir) { /* scroll bidirectional */ + if (s->offset <= 0) { + /* at beginning of line */ + s->offset = 0; + s->backward = false; + s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; } - else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; + if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) { + /* at end of line */ + s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); + s->backward = true; + s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; } - - lastmode = drawmode; - drawmode = s->invert ? - (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; - lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); - drawmode = lastmode; - lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); + } + else { + /* scroll forward the whole time */ + if (s->offset >= s->width) + s->offset %= s->width; } - - next_tick += scroll_ticks; - delay = next_tick - current_tick - 1; - if (delay < 0) - { - next_tick = current_tick + 1; - delay = 0; - } + lastmode = drawmode; + drawmode = s->invert ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); + drawmode = lastmode; + lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); } } @@ -1241,10 +1139,5 @@ void lcd_remote_init(void) #ifndef SIMULATOR /* Call device specific init */ lcd_remote_init_device(); - /* private queue */ - queue_init(&remote_scroll_queue, false); #endif - create_thread(scroll_thread, scroll_stack, - sizeof(scroll_stack), scroll_name IF_PRIO(, PRIORITY_USER_INTERFACE) - IF_COP(, CPU, false)); } diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h index d5898a97f1..cb850d7af2 100644 --- a/firmware/export/kernel.h +++ b/firmware/export/kernel.h @@ -34,21 +34,40 @@ #define QUEUE_LENGTH 16 /* MUST be a power of 2 */ #define QUEUE_LENGTH_MASK (QUEUE_LENGTH - 1) -/* System defined message ID's, occupying the top 5 bits of the event ID */ -#define SYS_EVENT (long)0x80000000 /* SYS events are negative */ -#define SYS_USB_CONNECTED ((SYS_EVENT | ((long)1 << 27))) -#define SYS_USB_CONNECTED_ACK ((SYS_EVENT | ((long)2 << 27))) -#define SYS_USB_DISCONNECTED ((SYS_EVENT | ((long)3 << 27))) -#define SYS_USB_DISCONNECTED_ACK ((SYS_EVENT | ((long)4 << 27))) -#define SYS_TIMEOUT ((SYS_EVENT | ((long)5 << 27))) -#define SYS_HOTSWAP_INSERTED ((SYS_EVENT | ((long)6 << 27))) -#define SYS_HOTSWAP_EXTRACTED ((SYS_EVENT | ((long)7 << 27))) -#define SYS_POWEROFF ((SYS_EVENT | ((long)8 << 27))) -#define SYS_FS_CHANGED ((SYS_EVENT | ((long)9 << 27))) -#define SYS_CHARGER_CONNECTED ((SYS_EVENT | ((long)10 << 27))) -#define SYS_CHARGER_DISCONNECTED ((SYS_EVENT | ((long)11 << 27))) -#define SYS_PHONE_PLUGGED ((SYS_EVENT | ((long)12 << 27))) -#define SYS_PHONE_UNPLUGGED ((SYS_EVENT | ((long)13 << 27))) +/* System defined message ID's - |sign bit = 1|class|id| */ +/* Event class list */ +#define SYS_EVENT_CLS_QUEUE 0 +#define SYS_EVENT_CLS_USB 1 +#define SYS_EVENT_CLS_POWER 2 +#define SYS_EVENT_CLS_FILESYS 3 +#define SYS_EVENT_CLS_PLUG 4 +/* make sure SYS_EVENT_CLS_BITS has enough range */ + +/* MSb->|S|c...c|i...i| */ +#define SYS_EVENT ((long)(~0ul ^ (~0ul >> 1))) +#define SYS_EVENT_CLS_BITS (3) +#define SYS_EVENT_CLS_SHIFT (sizeof (long)*8-SYS_EVENT_CLS_BITS-1) +#define SYS_EVENT_CLS_MASK (((1l << SYS_EVENT_CLS_BITS)-1) << SYS_EVENT_SHIFT) +#define MAKE_SYS_EVENT(cls, id) (SYS_EVENT | ((long)(cls) << SYS_EVENT_CLS_SHIFT) | (long)(id)) +/* Macros for extracting codes */ +#define SYS_EVENT_CLS(e) (((e) & SYS_EVENT_CLS_MASK) >> SYS_EVENT_SHIFT) +#define SYS_EVENT_ID(e) ((e) & ~(SYS_EVENT|SYS_EVENT_CLS_MASK)) + +#define SYS_TIMEOUT MAKE_SYS_EVENT(SYS_EVENT_CLS_QUEUE, 0) +#define SYS_USB_CONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_USB, 0) +#define SYS_USB_CONNECTED_ACK MAKE_SYS_EVENT(SYS_EVENT_CLS_USB, 1) +#define SYS_USB_DISCONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_USB, 2) +#define SYS_USB_DISCONNECTED_ACK MAKE_SYS_EVENT(SYS_EVENT_CLS_USB, 3) +#define SYS_POWEROFF MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 0) +#define SYS_CHARGER_CONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 1) +#define SYS_CHARGER_DISCONNECTED MAKE_SYS_EVENT(SYS_EVENT_CLS_POWER, 2) +#define SYS_FS_CHANGED MAKE_SYS_EVENT(SYS_EVENT_CLS_FILESYS, 0) +#define SYS_HOTSWAP_INSERTED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 0) +#define SYS_HOTSWAP_EXTRACTED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 1) +#define SYS_PHONE_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 2) +#define SYS_PHONE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 3) +#define SYS_REMOTE_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 4) +#define SYS_REMOTE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 5) struct event { diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h index cfb643ff96..329edd5f27 100644 --- a/firmware/export/lcd-remote.h +++ b/firmware/export/lcd-remote.h @@ -39,10 +39,6 @@ int remote_type(void); #endif -#ifndef SIMULATOR -extern struct event_queue remote_scroll_queue; -#endif - #define STYLE_DEFAULT 0x00000000 #define STYLE_INVERT 0x20000000 @@ -146,6 +142,7 @@ extern void lcd_remote_setmargins(int xmargin, int ymargin); extern int lcd_remote_getxmargin(void); extern int lcd_remote_getymargin(void); extern void lcd_remote_setfont(int font); +extern int lcd_remote_getfont(void); extern int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h); /* low level drawing function pointer arrays */ diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 8f01ef5cab..608f9ffa0f 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -312,6 +312,7 @@ extern void lcd_set_flip(bool yesno); extern void lcd_set_drawmode(int mode); extern int lcd_get_drawmode(void); extern void lcd_setfont(int font); +extern int lcd_getfont(void); extern void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, int offset); @@ -376,29 +377,4 @@ extern void lcd_bitmap_transparent(const fb_data *src, int x, int y, #endif /* HAVE_LCD_BITMAP */ -/* internal usage, but in multiple drivers */ -#define SCROLL_SPACING 3 -#ifdef HAVE_LCD_BITMAP -#define SCROLL_LINE_SIZE (MAX_PATH + SCROLL_SPACING + 3*LCD_WIDTH/2 + 2) -#else -#define SCROLL_LINE_SIZE (MAX_PATH + SCROLL_SPACING + 3*LCD_WIDTH + 2) -#endif - -struct scrollinfo { - char line[SCROLL_LINE_SIZE]; - int len; /* length of line in chars */ - int offset; - int startx; -#ifdef HAVE_LCD_BITMAP - int width; /* length of line in pixels */ - bool invert; /* invert the scrolled text */ -#endif - bool backward; /* scroll presently forward or backward? */ - bool bidir; - long start_tick; -#ifdef HAVE_LCD_COLOR - int line_colour; -#endif -}; - #endif /* __LCD_H__ */ diff --git a/firmware/export/scroll_engine.h b/firmware/export/scroll_engine.h new file mode 100644 index 0000000000..aa11a9ba1f --- /dev/null +++ b/firmware/export/scroll_engine.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Michael Sevakis + * + * LCD scrolling driver and scheduler + * + * Much collected and combined from the various Rockbox LCD drivers. + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef __SCROLL_ENGINE_H__ +#define __SCROLL_ENGINE_H__ + +void scroll_init(void); +void lcd_scroll_fn(void); +void lcd_remote_scroll_fn(void); + +/* internal usage, but in multiple drivers */ +#define SCROLL_SPACING 3 +#ifdef HAVE_LCD_BITMAP +#define SCROLL_LINE_SIZE (MAX_PATH + SCROLL_SPACING + 3*LCD_WIDTH/2 + 2) +#else +#define SCROLL_LINE_SIZE (MAX_PATH + SCROLL_SPACING + 3*LCD_WIDTH + 2) +#endif + +struct scrollinfo +{ + char line[SCROLL_LINE_SIZE]; + int len; /* length of line in chars */ + int offset; + int startx; +#ifdef HAVE_LCD_BITMAP + int width; /* length of line in pixels */ + bool invert; /* invert the scrolled text */ +#endif + bool backward; /* scroll presently forward or backward? */ + bool bidir; + long start_tick; +#ifdef HAVE_LCD_COLOR + int line_color; +#endif +}; + +struct scroll_screen_info +{ + struct scrollinfo * const scroll; + const int num_scroll; /* number of scrollable lines (also number of scroll structs) */ + int lines; /* Bitpattern of which lines are scrolling */ + long ticks; /* # of ticks between updates*/ + long delay; /* ticks delay before start */ + int bidir_limit; /* percent */ +#ifdef HAVE_LCD_CHARCELLS + long jump_scroll_delay; /* delay between jump scroll jumps */ + int jump_scroll; /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ +#endif +#if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD) + int step; /* pixels per scroll step */ +#endif +#if defined(HAVE_REMOTE_LCD) + long last_scroll; +#endif +}; + +/** main lcd **/ +#ifdef HAVE_LCD_BITMAP +#define LCD_SCROLLABLE_LINES ((LCD_HEIGHT+4)/5 < 32 ? (LCD_HEIGHT+4)/5 : 32) +#else +#define LCD_SCROLLABLE_LINES LCD_HEIGHT +#endif + +extern struct scroll_screen_info lcd_scroll_info; + +/** remote lcd **/ +#ifdef HAVE_REMOTE_LCD +#define LCD_REMOTE_SCROLLABLE_LINES \ + (((LCD_REMOTE_HEIGHT+4)/5 < 32) ? (LCD_REMOTE_HEIGHT+4)/5 : 32) +extern struct scroll_screen_info lcd_remote_scroll_info; +#endif + +#endif /* __SCROLL_ENGINE_H__ */ diff --git a/firmware/scroll_engine.c b/firmware/scroll_engine.c new file mode 100644 index 0000000000..d4a2e174cc --- /dev/null +++ b/firmware/scroll_engine.c @@ -0,0 +1,302 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Michael Sevakis + * + * LCD scrolling driver and scheduler + * + * Much collected and combined from the various Rockbox LCD drivers. + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include "cpu.h" +#include "kernel.h" +#include "thread.h" +#include "usb.h" +#include "lcd.h" +#include "font.h" +#ifdef HAVE_REMOTE_LCD +#include "lcd-remote.h" +#endif +#include "scroll_engine.h" + +static const char scroll_tick_table[16] = { + /* Hz values: + 1, 1.25, 1.55, 2, 2.5, 3.12, 4, 5, 6.25, 8.33, 10, 12.5, 16.7, 20, 25, 33 */ + 100, 80, 64, 50, 40, 32, 25, 20, 16, 12, 10, 8, 6, 5, 4, 3 +}; + +static void scroll_thread(void); +static char scroll_stack[DEFAULT_STACK_SIZE*3]; +static const char scroll_name[] = "scroll"; + +struct scrollinfo lcd_scroll[LCD_SCROLLABLE_LINES]; + +#ifdef HAVE_REMOTE_LCD +struct scrollinfo lcd_remote_scroll[LCD_REMOTE_SCROLLABLE_LINES]; +struct event_queue scroll_queue; +#endif + +struct scroll_screen_info lcd_scroll_info = +{ + .scroll = lcd_scroll, + .lines = 0, + .ticks = 12, + .delay = HZ/2, + .bidir_limit = 50, +#ifdef HAVE_LCD_BITMAP + .step = 6, +#endif +#ifdef HAVE_LCD_CHARCELLS + .jump_scroll_delay = HZ/4, + .jump_scroll = 0, +#endif +}; + +#ifdef HAVE_REMOTE_LCD +struct scroll_screen_info lcd_remote_scroll_info = +{ + .scroll = lcd_remote_scroll, + .lines = 0, + .ticks = 12, + .delay = HZ/2, + .bidir_limit = 50, + .step = 6, +}; +#endif /* HAVE_REMOTE_LCD */ + +void lcd_stop_scroll(void) +{ + lcd_scroll_info.lines = 0; +} + +void lcd_scroll_speed(int speed) +{ + lcd_scroll_info.ticks = scroll_tick_table[speed]; +} + +#if defined(HAVE_LCD_BITMAP) +/* Reverse the invert setting of the scrolling line (if any) at given char + position. Setting will go into affect next time line scrolls. */ +void lcd_invertscroll(int x, int y) +{ + struct scrollinfo *s; + + (void)x; + + if((unsigned)y>=LCD_SCROLLABLE_LINES) return; + + s = &lcd_scroll_info.scroll[y]; + s->invert = !s->invert; +} + +void lcd_scroll_step(int step) +{ + lcd_scroll_info.step = step; +} +#endif + +void lcd_scroll_delay(int ms) +{ + lcd_scroll_info.delay = ms / (HZ / 10); +} + +void lcd_bidir_scroll(int percent) +{ + lcd_scroll_info.bidir_limit = percent; +} + +#ifdef HAVE_LCD_CHARCELLS +void lcd_jump_scroll(int mode) /* 0=off, 1=once, ..., JUMP_SCROLL_ALWAYS */ +{ + lcd_scroll_info.jump_scroll = mode; +} + +void lcd_jump_scroll_delay(int ms) +{ + lcd_scroll_info.jump_scroll_delay = ms / (HZ / 10); +} +#endif + +#ifdef HAVE_REMOTE_LCD +/* Reverse the invert setting of the scrolling line (if any) at given char + position. Setting will go into affect next time line scrolls. */ +void lcd_remote_invertscroll(int x, int y) +{ + struct scrollinfo *s; + + (void)x; + + if((unsigned)y>=LCD_REMOTE_SCROLLABLE_LINES) return; + + s = &lcd_remote_scroll_info.scroll[y]; + s->invert = !s->invert; +} + +void lcd_remote_stop_scroll(void) +{ + lcd_remote_scroll_info.lines = 0; +} + +void lcd_remote_scroll_speed(int speed) +{ + lcd_remote_scroll_info.ticks = scroll_tick_table[speed]; +} + +void lcd_remote_scroll_step(int step) +{ + lcd_remote_scroll_info.step = step; +} + +void lcd_remote_scroll_delay(int ms) +{ + lcd_remote_scroll_info.delay = ms / (HZ / 10); +} + +void lcd_remote_bidir_scroll(int percent) +{ + lcd_remote_scroll_info.bidir_limit = percent; +} + +static void sync_display_ticks(void) +{ + lcd_scroll_info.last_scroll = + lcd_remote_scroll_info.last_scroll = current_tick; +} + +static bool scroll_process_message(int delay) +{ + struct event ev; + + do + { + long tick = current_tick; + queue_wait_w_tmo(&scroll_queue, &ev, delay); + + switch (ev.id) + { + case SYS_TIMEOUT: + return false; + case SYS_USB_CONNECTED: + usb_acknowledge(SYS_USB_CONNECTED_ACK); + usb_wait_for_disconnect(&scroll_queue); + sync_display_ticks(); + return true; +#ifndef SIMULATOR + case SYS_REMOTE_PLUGGED: + if (!remote_initialized) + sync_display_ticks(); +#endif + } + + delay -= current_tick - tick; + } + while (delay > 0); + + return false; +} +#endif /* HAVE_REMOTE_LCD */ + +static void scroll_thread(void) __attribute__((noreturn)); +#ifdef HAVE_REMOTE_LCD + +static void scroll_thread(void) +{ + enum + { + SCROLL_LCD = 0x1, + SCROLL_LCD_REMOTE = 0x2, + }; + + sync_display_ticks(); + + while ( 1 ) + { + long delay; + int scroll; + long tick_lcd, tick_remote; + + tick_lcd = lcd_scroll_info.last_scroll + lcd_scroll_info.ticks; + delay = current_tick; + + if ( +#ifndef SIMULATOR + !remote_initialized || +#endif + (tick_remote = lcd_remote_scroll_info.last_scroll + + lcd_remote_scroll_info.ticks, + TIME_BEFORE(tick_lcd, tick_remote))) + { + scroll = SCROLL_LCD; + delay = tick_lcd - delay; + } + /* TIME_BEFORE(tick_remote, tick_lcd) */ + else if (tick_lcd != tick_remote) + { + scroll = SCROLL_LCD_REMOTE; + delay = tick_remote - delay; + } + else + { + scroll = SCROLL_LCD | SCROLL_LCD_REMOTE; + delay = tick_lcd - delay; + } + + if (scroll_process_message(delay)) + continue; + + if (scroll & SCROLL_LCD) + { +#ifdef HAVE_LCD_ENABLE + if (lcd_enabled()) +#endif + lcd_scroll_fn(); + lcd_scroll_info.last_scroll = current_tick; + } + + if (scroll == (SCROLL_LCD | SCROLL_LCD_REMOTE)) + yield(); + + if (scroll & SCROLL_LCD_REMOTE) + { + lcd_remote_scroll_fn(); + lcd_remote_scroll_info.last_scroll = current_tick; + } + } +} +#else +static void scroll_thread(void) +{ + while (1) + { + sleep(lcd_scroll_info.ticks); +#ifdef HAVE_LCD_ENABLE + if (lcd_enabled()) +#endif + lcd_scroll_fn(); + } +} +#endif /* HAVE_REMOTE_LCD */ + +void scroll_init(void) +{ +#ifdef HAVE_REMOTE_LCD + queue_init(&scroll_queue, true); +#endif + create_thread(scroll_thread, scroll_stack, + sizeof(scroll_stack), scroll_name + IF_PRIO(, PRIORITY_USER_INTERFACE) + IF_COP(, CPU, false)); +} diff --git a/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c b/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c index 939f7347c4..9940017dd9 100644 --- a/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c +++ b/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c @@ -18,8 +18,9 @@ ****************************************************************************/ #include "config.h" #include "system.h" -#include "kernel.h" +#include "file.h" #include "lcd-remote.h" +#include "scroll_engine.h" /* The LCD in the iAudio M3/M5/X5 remote control is a Tomato LSI 0350 */ @@ -397,7 +398,6 @@ static void remote_tick(void) { static bool last_status = false; static int countdown = 0; - static int init_delay = 0; bool current_status; current_status = remote_detect(); @@ -416,20 +416,16 @@ static void remote_tick(void) if (current_status) { - if (!(countdown % 8)) + if (!(countdown % 48)) { - if (--init_delay <= 0) - { - queue_post(&remote_scroll_queue, REMOTE_INIT_LCD, 0); - init_delay = 6; - } + queue_broadcast(SYS_REMOTE_PLUGGED, 0); } } else { if (countdown == 0) { - queue_post(&remote_scroll_queue, REMOTE_DEINIT_LCD, 0); + queue_broadcast(SYS_REMOTE_UNPLUGGED, 0); } } } diff --git a/firmware/target/coldfire/iriver/lcd-remote-iriver.c b/firmware/target/coldfire/iriver/lcd-remote-iriver.c index cdc5acacca..29dbfad3db 100644 --- a/firmware/target/coldfire/iriver/lcd-remote-iriver.c +++ b/firmware/target/coldfire/iriver/lcd-remote-iriver.c @@ -19,8 +19,9 @@ #include "config.h" #include "system.h" -#include "kernel.h" +#include "file.h" #include "lcd-remote.h" +#include "scroll_engine.h" /*** definitions ***/ @@ -521,7 +522,7 @@ static void remote_tick(void) if (--init_delay <= 0) { - queue_post(&remote_scroll_queue, REMOTE_INIT_LCD, 0); + queue_broadcast(SYS_REMOTE_PLUGGED, 0); init_delay = 6; } } @@ -537,7 +538,7 @@ static void remote_tick(void) { _remote_type = REMOTETYPE_UNPLUGGED; - queue_post(&remote_scroll_queue, REMOTE_DEINIT_LCD, 0); + queue_broadcast(SYS_REMOTE_UNPLUGGED, 0); } } }