diff -Nau ref-2.5/firmware/export/lcd.h jumpback-5-2.5/firmware/export/lcd.h --- ref-2.5/firmware/export/lcd.h 2005-09-22 03:53:14.000000000 -0400 +++ jumpback-5-2.5/firmware/export/lcd.h 2005-10-16 01:02:28.000000000 -0400 @@ -182,6 +182,17 @@ extern void lcd_bidir_scroll(int threshold); extern void lcd_scroll_step(int pixels); +/* scroll types */ +enum +{ + SCROLL_TYPE_AUTO=0, + SCROLL_TYPE_BIDI, + SCROLL_TYPE_JUMPBACK, + SCROLL_TYPE_CONT, + NUM_SCROLL_TYPES +}; +extern void lcd_scroll_type(int type); + #if LCD_DEPTH > 1 #ifdef HAVE_LCD_COLOR extern void lcd_set_foreground(struct rgb color); @@ -214,13 +225,14 @@ struct scrollinfo { char line[MAX_PATH + LCD_WIDTH/2 + SCROLL_SPACING + 2]; + int type; /* scroll type being used */ int len; /* length of line in chars */ int width; /* length of line in pixels */ int offset; int startx; bool backward; /* scroll presently forward or backward? */ - bool bidir; bool invert; /* invert the scrolled text */ + bool jump_back; long start_tick; }; #else /* !HAVE_LCD_BITMAP */ diff -Nau ref-2.5/firmware/drivers/lcd-recorder.c jumpback-5-2.5/firmware/drivers/lcd-recorder.c --- ref-2.5/firmware/drivers/lcd-recorder.c 2005-09-22 03:53:14.000000000 -0400 +++ jumpback-5-2.5/firmware/drivers/lcd-recorder.c 2005-10-16 01:02:28.000000000 -0400 @@ -76,7 +76,10 @@ /*** globals ***/ -unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH]; +#define DISPLAY_WIDTH LCD_WIDTH +#define DISPLAY_HEIGHT LCD_HEIGHT + +unsigned char lcd_framebuffer[DISPLAY_HEIGHT/8][DISPLAY_WIDTH]; static int drawmode = DRMODE_SOLID; static int xmargin = 0; @@ -93,6 +96,7 @@ 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_type = SCROLL_TYPE_AUTO; static int scroll_step = 6; /* pixels per scroll step */ static int bidir_limit = 50; /* percent */ static struct scrollinfo scroll[SCROLLABLE_LINES]; @@ -177,7 +181,7 @@ { lcd_write_command(LCD_SET_SEGMENT_REMAP | 0x01); lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION | 0x08); - xoffset = 132 - LCD_WIDTH; + xoffset = 132 - DISPLAY_WIDTH; } else { @@ -190,7 +194,7 @@ { lcd_write_command(LCD_SET_SEGMENT_REMAP); lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION); - xoffset = 132 - LCD_WIDTH; /* 132 colums minus the 112 we have */ + xoffset = 132 - DISPLAY_WIDTH; /* 132 colums minus the 112 we have */ } else { @@ -207,10 +211,10 @@ * remapping only and all operations on the lcd are affected. * -> * @param int lines - The number of lines that are rolled. - * The value must be 0 <= pixels < LCD_HEIGHT. */ + * The value must be 0 <= pixels < DISPLAY_HEIGHT. */ void lcd_roll(int lines) { - lcd_write_command(LCD_SET_DISPLAY_START_LINE | (lines & (LCD_HEIGHT-1))); + lcd_write_command(LCD_SET_DISPLAY_START_LINE | (lines & (DISPLAY_HEIGHT-1))); } #endif /* !SIMULATOR */ @@ -291,13 +295,13 @@ int y; /* Copy display bitmap to hardware */ - for (y = 0; y < LCD_HEIGHT/8; y++) + for (y = 0; y < DISPLAY_HEIGHT/8; y++) { lcd_write_command (LCD_CNTL_PAGE | (y & 0xf)); lcd_write_command (LCD_CNTL_HIGHCOL | ((xoffset >> 4) & 0xf)); lcd_write_command (LCD_CNTL_LOWCOL | (xoffset & 0xf)); - lcd_write_data (lcd_framebuffer[y], LCD_WIDTH); + lcd_write_data (lcd_framebuffer[y], DISPLAY_WIDTH); } } @@ -311,12 +315,12 @@ ymax = (y + height-1) >> 3; y >>= 3; - if(x + width > LCD_WIDTH) - width = LCD_WIDTH - x; + if(x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; if (width <= 0) return; /* nothing left to do, 0 is harmful to lcd_write_data() */ - if(ymax >= LCD_HEIGHT/8) - ymax = LCD_HEIGHT/8-1; + if(ymax >= DISPLAY_HEIGHT/8) + ymax = DISPLAY_HEIGHT/8-1; /* Copy specified rectange bitmap to hardware */ for (; y <= ymax; y++) @@ -471,7 +475,7 @@ /* Set a single pixel */ void lcd_drawpixel(int x, int y) { - if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) + if (((unsigned)x < DISPLAY_WIDTH) && ((unsigned)y < DISPLAY_HEIGHT)) lcd_pixelfuncs[drawmode](x, y); } @@ -528,7 +532,7 @@ for (i = 0; i < numpixels; i++) { - if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) + if (((unsigned)x < DISPLAY_WIDTH) && ((unsigned)y < DISPLAY_HEIGHT)) pfunc(x, y); if (d < 0) @@ -563,14 +567,14 @@ } /* nothing to draw? */ - if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) + if (((unsigned)y >= DISPLAY_HEIGHT) || (x1 >= DISPLAY_WIDTH) || (x2 < 0)) return; /* clipping */ if (x1 < 0) x1 = 0; - if (x2 >= LCD_WIDTH) - x2 = LCD_WIDTH-1; + if (x2 >= DISPLAY_WIDTH) + x2 = DISPLAY_WIDTH-1; bfunc = lcd_blockfuncs[drawmode]; dst = &lcd_framebuffer[y>>3][x1]; @@ -599,14 +603,14 @@ } /* nothing to draw? */ - if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) + if (((unsigned)x >= DISPLAY_WIDTH) || (y1 >= DISPLAY_HEIGHT) || (y2 < 0)) return; /* clipping */ if (y1 < 0) y1 = 0; - if (y2 >= LCD_HEIGHT) - y2 = LCD_HEIGHT-1; + if (y2 >= DISPLAY_HEIGHT) + y2 = DISPLAY_HEIGHT-1; bfunc = lcd_blockfuncs[drawmode]; dst = &lcd_framebuffer[y1>>3][x]; @@ -617,7 +621,7 @@ for (; ny >= 8; ny -= 8) { bfunc(dst, mask, 0xFFu); - dst += LCD_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -650,7 +654,7 @@ bool fillopt; /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + if ((width <= 0) || (height <= 0) || (x >= DISPLAY_WIDTH) || (y >= DISPLAY_HEIGHT) || (x + width <= 0) || (y + height <= 0)) return; @@ -665,10 +669,10 @@ height += y; y = 0; } - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; + if (x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; + if (y + height > DISPLAY_HEIGHT) + height = DISPLAY_HEIGHT - y; fillopt = (drawmode & DRMODE_INVERSEVID) ? (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG); @@ -694,7 +698,7 @@ while (dst_row < dst_end); } - dst += LCD_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -734,7 +738,7 @@ lcd_blockfunc_type *bfunc; /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + if ((width <= 0) || (height <= 0) || (x >= DISPLAY_WIDTH) || (y >= DISPLAY_HEIGHT) || (x + width <= 0) || (y + height <= 0)) return; @@ -751,10 +755,10 @@ src_y -= y; y = 0; } - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; + if (x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; + if (y + height > DISPLAY_HEIGHT) + height = DISPLAY_HEIGHT - y; src += stride * (src_y >> 3) + src_x; /* move starting point */ src_y &= 7; @@ -787,7 +791,7 @@ } src += stride; - dst += LCD_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -825,7 +829,7 @@ mask_col >>= 8; src_col += stride; - dst_col += LCD_WIDTH; + dst_col += DISPLAY_WIDTH; data >>= 8; } data |= *src_col << shift; @@ -850,7 +854,7 @@ if (bidi_support_enabled) str = bidi_l2v(str, 1); - while ((ch = *str++) != '\0' && x < LCD_WIDTH) + while ((ch = *str++) != '\0' && x < DISPLAY_WIDTH) { int width; const unsigned char *bits; @@ -902,11 +906,11 @@ ypos = ymargin + y*h; lcd_putsxy(xpos, ypos, str); drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); - lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); + lcd_fillrect(xpos + w, ypos, DISPLAY_WIDTH - (xpos + w), h); if (style & STYLE_INVERT) { drawmode = DRMODE_COMPLEMENT; - lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); + lcd_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, h); } drawmode = lastmode; } @@ -951,6 +955,11 @@ scroll_delay = ms / (HZ / 10); } +void lcd_scroll_type(int type) +{ + scroll_type = type; +} + void lcd_bidir_scroll(int percent) { bidir_limit = percent; @@ -963,59 +972,82 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style) { - struct scrollinfo* s; - int w, h; + struct scrollinfo *s = &scroll[y]; + scrolling_lines &= ~(1<start_tick = current_tick + scroll_delay; - s->invert = false; - if (style & STYLE_INVERT) { + /* set style and draw initial text */ + if (style & STYLE_INVERT) + { s->invert = true; lcd_puts_style(x,y,string,STYLE_INVERT); } else + { + s->invert = false; lcd_puts(x,y,string); + } - lcd_getstringsize(string, &w, &h); - - if (LCD_WIDTH - x * 8 - xmargin < w) { - /* prepare scroll line */ - char *end; - - memset(s->line, 0, sizeof s->line); - strcpy(s->line, string); - - /* 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; - } + /* is line long enough to scroll? */ + s->len = strlen(string); + s->width = lcd_getstringsize(string,0,0); + int dispw = DISPLAY_WIDTH - x * 8 - xmargin; + if ( s->width <= dispw ) + return; /* nah */ + + /* store the string */ + strcpy(s->line, string); + + /* determine correct scroll type for 'auto' */ + s->type = scroll_type; + if (s->type == SCROLL_TYPE_AUTO) + { + int upper_limit = (DISPLAY_WIDTH - xmargin) * (100 + bidir_limit) / 100; + int lower_limit = upper_limit / 2; + if ( s->width < lower_limit ) + s->type = SCROLL_TYPE_BIDI; + else if ( s->width > upper_limit ) + s->type = SCROLL_TYPE_CONT; else - s->bidir = false; + s->type = SCROLL_TYPE_JUMPBACK; + } - 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); - } - - end = strchr(s->line, '\0'); - strncpy(end, string, LCD_WIDTH/2); - - s->len = strlen(string); - s->offset = 0; - s->startx = x; - s->backward = false; - scrolling_lines |= (1<type ) + { + case SCROLL_TYPE_CONT: + { + /* add spaces to enhance wrap-around effect */ + static const char spacing[] = " ... "; + strcat(s->line, spacing); + /* add-in width of spacing */ + s->len += strlen(spacing); + s->width += lcd_getstringsize(spacing,0,0); + /* (safely) add extra text for wrap-around effect */ + int wantch = (dispw / 8) * 2; /* the '8' is fudgey, init? */ + int maxstr = (sizeof(s->line) - s->len); + if (wantch > maxstr) + wantch = maxstr; + strncpy(&s->line[s->len], string, wantch); + s->line[s->len+wantch] = '\0'; + /* intentional fall-through: get bidi init too */ + } + case SCROLL_TYPE_BIDI: + { + s->backward = false; + break; + } + case SCROLL_TYPE_JUMPBACK: + { + s->jump_back = false; + break; + } } - else - /* force a bit switch-off since it doesn't scroll */ - scrolling_lines &= ~(1<startx = x; + s->offset = 0; + s->start_tick = current_tick + scroll_delay; + scrolling_lines |= (1<start_tick)) continue; - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; - pf = font_get(curfont); xpos = xmargin + s->startx * s->width / s->len; 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; + switch( s->type ) + { + case SCROLL_TYPE_BIDI: + { + if (s->backward) + s->offset -= scroll_step; + else + s->offset += scroll_step; + + if (s->offset <= 0) + { + /* at beginning of line */ + s->offset = 0; + s->start_tick = current_tick + scroll_delay * 2; + s->backward = false; + } + if (s->offset >= s->width - (DISPLAY_WIDTH - xpos)) + { + /* at end of line */ + s->offset = s->width - (DISPLAY_WIDTH - xpos); + s->start_tick = current_tick + scroll_delay * 2; + s->backward = true; + } + break; } - 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; + case SCROLL_TYPE_CONT: + { + s->offset += scroll_step; + if (s->offset >= s->width) + s->offset %= s->width; + break; + } + default: + case SCROLL_TYPE_JUMPBACK: + { + if (s->jump_back) + { + /* jump back to beginning of line and delay again */ + s->jump_back = false; + s->offset = 0; + s->start_tick = current_tick + scroll_delay; + } + else + { + s->offset += scroll_step; + if (s->offset >= s->width - (DISPLAY_WIDTH - xpos)) + { + /* at end of line */ + s->offset = s->width - (DISPLAY_WIDTH - xpos); + s->start_tick = current_tick + scroll_delay * 2; + s->jump_back = true; + } + } + break; } - } - else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; } lastmode = drawmode; drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); - lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lcd_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); drawmode = DRMODE_SOLID; lcd_putsxyofs(xpos, ypos, s->offset, s->line); if (s->invert) { drawmode = DRMODE_COMPLEMENT; - lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lcd_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); } drawmode = lastmode; - lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lcd_update_rect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); } sleep(scroll_ticks); diff -Nau ref-2.5/firmware/drivers/lcd-h100.c jumpback-5-2.5/firmware/drivers/lcd-h100.c --- ref-2.5/firmware/drivers/lcd-h100.c 2005-09-22 03:53:14.000000000 -0400 +++ jumpback-5-2.5/firmware/drivers/lcd-h100.c 2005-10-16 01:02:28.000000000 -0400 @@ -61,7 +61,10 @@ /*** globals ***/ -unsigned char lcd_framebuffer[LCD_HEIGHT/4][LCD_WIDTH] IDATA_ATTR; +#define DISPLAY_WIDTH LCD_WIDTH +#define DISPLAY_HEIGHT LCD_HEIGHT + +unsigned char lcd_framebuffer[DISPLAY_HEIGHT/4][DISPLAY_WIDTH] IDATA_ATTR; /* should be 'const', but this causes a section type conflict */ static unsigned char dibits[16] IDATA_ATTR = { @@ -83,6 +86,7 @@ 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_type = SCROLL_TYPE_AUTO; static int scroll_step = 6; /* pixels per scroll step */ static int bidir_limit = 50; /* percent */ static struct scrollinfo scroll[SCROLLABLE_LINES]; @@ -137,10 +141,10 @@ * remapping only and all operations on the lcd are affected. * -> * @param int lines - The number of lines that are rolled. - * The value must be 0 <= pixels < LCD_HEIGHT. */ + * The value must be 0 <= pixels < DISPLAY_HEIGHT. */ void lcd_roll(int lines) { - lines &= LCD_HEIGHT-1; + lines &= DISPLAY_HEIGHT-1; lcd_write_command_ex(LCD_CNTL_DISPLAY_START_LINE, lines, -1); } @@ -232,13 +236,13 @@ int y; /* Copy display bitmap to hardware */ - for (y = 0; y < LCD_HEIGHT/4; y++) + for (y = 0; y < DISPLAY_HEIGHT/4; y++) { lcd_write_command_ex(LCD_CNTL_PAGE, y, -1); lcd_write_command_ex(LCD_CNTL_COLUMN, 0, -1); lcd_write_command(LCD_CNTL_DATA_WRITE); - lcd_write_data (lcd_framebuffer[y], LCD_WIDTH); + lcd_write_data (lcd_framebuffer[y], DISPLAY_WIDTH); } } @@ -252,12 +256,12 @@ ymax = (y + height-1) >> 2; y >>= 2; - if(x + width > LCD_WIDTH) - width = LCD_WIDTH - x; + if(x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; if (width <= 0) return; /* nothing left to do, 0 is harmful to lcd_write_data() */ - if(ymax >= LCD_HEIGHT/4) - ymax = LCD_HEIGHT/4-1; + if(ymax >= DISPLAY_HEIGHT/4) + ymax = DISPLAY_HEIGHT/4-1; /* Copy specified rectange bitmap to hardware */ for (; y <= ymax; y++) @@ -450,7 +454,7 @@ /* Set a single pixel */ void lcd_drawpixel(int x, int y) { - if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) + if (((unsigned)x < DISPLAY_WIDTH) && ((unsigned)y < DISPLAY_HEIGHT)) lcd_pixelfuncs[drawmode](x, y); } @@ -507,7 +511,7 @@ for (i = 0; i < numpixels; i++) { - if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) + if (((unsigned)x < DISPLAY_WIDTH) && ((unsigned)y < DISPLAY_HEIGHT)) pfunc(x, y); if (d < 0) @@ -542,14 +546,14 @@ } /* nothing to draw? */ - if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) + if (((unsigned)y >= DISPLAY_HEIGHT) || (x1 >= DISPLAY_WIDTH) || (x2 < 0)) return; /* clipping */ if (x1 < 0) x1 = 0; - if (x2 >= LCD_WIDTH) - x2 = LCD_WIDTH-1; + if (x2 >= DISPLAY_WIDTH) + x2 = DISPLAY_WIDTH-1; bfunc = lcd_blockfuncs[drawmode]; dst = &lcd_framebuffer[y>>2][x1]; @@ -578,14 +582,14 @@ } /* nothing to draw? */ - if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) + if (((unsigned)x >= DISPLAY_WIDTH) || (y1 >= DISPLAY_HEIGHT) || (y2 < 0)) return; /* clipping */ if (y1 < 0) y1 = 0; - if (y2 >= LCD_HEIGHT) - y2 = LCD_HEIGHT-1; + if (y2 >= DISPLAY_HEIGHT) + y2 = DISPLAY_HEIGHT-1; bfunc = lcd_blockfuncs[drawmode]; dst = &lcd_framebuffer[y1>>2][x]; @@ -596,7 +600,7 @@ for (; ny >= 4; ny -= 4) { bfunc(dst, mask, 0xFFu); - dst += LCD_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -629,7 +633,7 @@ bool fillopt; /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + if ((width <= 0) || (height <= 0) || (x >= DISPLAY_WIDTH) || (y >= DISPLAY_HEIGHT) || (x + width <= 0) || (y + height <= 0)) return; @@ -644,10 +648,10 @@ height += y; y = 0; } - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; + if (x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; + if (y + height > DISPLAY_HEIGHT) + height = DISPLAY_HEIGHT - y; fillopt = (drawmode & DRMODE_INVERSEVID) ? (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG); @@ -673,7 +677,7 @@ while (dst_row < dst_end); } - dst += LCD_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -713,7 +717,7 @@ lcd_blockfunc_type *bfunc; /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + if ((width <= 0) || (height <= 0) || (x >= DISPLAY_WIDTH) || (y >= DISPLAY_HEIGHT) || (x + width <= 0) || (y + height <= 0)) return; @@ -730,10 +734,10 @@ src_y -= y; y = 0; } - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; + if (x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; + if (y + height > DISPLAY_HEIGHT) + height = DISPLAY_HEIGHT - y; src += stride * (src_y >> 3) + src_x; /* move starting point */ src_y &= 7; @@ -753,7 +757,7 @@ for (; ny >= 8; ny -= 8) { const unsigned char *src_row = src; - unsigned char *dst_row = dst + LCD_WIDTH; + unsigned char *dst_row = dst + DISPLAY_WIDTH; dmask1 = dibits[mask&0x0F]; dmask2 = dibits[(mask>>4)&0x0F]; @@ -764,7 +768,7 @@ do { data = *src_row++; - bfunc(dst_row - LCD_WIDTH, dmask1, dibits[data&0x0F]); + bfunc(dst_row - DISPLAY_WIDTH, dmask1, dibits[data&0x0F]); bfunc(dst_row++, dmask2, dibits[(data>>4)&0x0F]); } while (dst_row < dst_end); @@ -776,7 +780,7 @@ while (dst_row < dst_end); } src += stride; - dst += 2*LCD_WIDTH; + dst += 2*DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -792,7 +796,7 @@ { data = *src++; bfunc(dst, dmask1, dibits[data&0x0F]); - bfunc((dst++) + LCD_WIDTH, dmask2, dibits[(data>>4)&0x0F]); + bfunc((dst++) + DISPLAY_WIDTH, dmask2, dibits[(data>>4)&0x0F]); } while (dst < dst_end); } @@ -806,7 +810,7 @@ else { do - bfunc((dst++) + LCD_WIDTH, dmask2, dibits[((*src++)>>4)&0x0F]); + bfunc((dst++) + DISPLAY_WIDTH, dmask2, dibits[((*src++)>>4)&0x0F]); while (dst < dst_end); } } @@ -828,7 +832,7 @@ { if (mask_col & 0x0F) bfunc(dst_col, dibits[mask_col&0x0F], dibits[data&0x0F]); - bfunc(dst_col + LCD_WIDTH, dibits[(mask_col>>4)&0x0F], + bfunc(dst_col + DISPLAY_WIDTH, dibits[(mask_col>>4)&0x0F], dibits[(data>>4)&0x0F]); mask_col = 0xFFu; } @@ -836,7 +840,7 @@ mask_col >>= 8; src_col += stride; - dst_col += 2*LCD_WIDTH; + dst_col += 2*DISPLAY_WIDTH; data >>= 8; } data |= *src_col << shift; @@ -844,7 +848,7 @@ if (mask_bottom & 0x0F) bfunc(dst_col, dibits[mask_bottom&0x0F], dibits[data&0x0F]); if (mask_bottom & 0xF0) - bfunc(dst_col + LCD_WIDTH, dibits[(mask_bottom&0xF0)>>4], + bfunc(dst_col + DISPLAY_WIDTH, dibits[(mask_bottom&0xF0)>>4], dibits[(data>>4)&0x0F]); } while (dst < dst_end); @@ -881,7 +885,7 @@ lcd_blockfunc_type *bfunc; /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) + if ((width <= 0) || (height <= 0) || (x >= DISPLAY_WIDTH) || (y >= DISPLAY_HEIGHT) || (x + width <= 0) || (y + height <= 0)) return; @@ -898,10 +902,10 @@ src_y -= y; y = 0; } - if (x + width > LCD_WIDTH) - width = LCD_WIDTH - x; - if (y + height > LCD_HEIGHT) - height = LCD_HEIGHT - y; + if (x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; + if (y + height > DISPLAY_HEIGHT) + height = DISPLAY_HEIGHT - y; src += stride * (src_y >> 2) + src_x; /* move starting point */ src_y &= 3; @@ -932,7 +936,7 @@ } src += stride; - dst += LCD_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -971,7 +975,7 @@ mask_col >>= 8; src_col += stride; - dst_col += LCD_WIDTH; + dst_col += DISPLAY_WIDTH; data >>= 8; } data |= *src_col << shift; @@ -996,7 +1000,7 @@ if (bidi_support_enabled) str = bidi_l2v(str, 1); - while ((ch = *str++) != '\0' && x < LCD_WIDTH) + while ((ch = *str++) != '\0' && x < DISPLAY_WIDTH) { int width; const unsigned char *bits; @@ -1049,11 +1053,11 @@ ypos = ymargin + y*h; lcd_putsxy(xpos, ypos, str); drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); - lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); + lcd_fillrect(xpos + w, ypos, DISPLAY_WIDTH - (xpos + w), h); if (style & STYLE_INVERT) { drawmode = DRMODE_COMPLEMENT; - lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); + lcd_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, h); } drawmode = lastmode; } @@ -1098,6 +1102,11 @@ scroll_delay = ms / (HZ / 10); } +void lcd_scroll_type(int type) +{ + scroll_type = type; +} + void lcd_bidir_scroll(int percent) { bidir_limit = percent; @@ -1110,59 +1119,82 @@ void lcd_puts_scroll_style(int x, int y, const unsigned char *string, int style) { - struct scrollinfo* s; - int w, h; + struct scrollinfo *s = &scroll[y]; + scrolling_lines &= ~(1<start_tick = current_tick + scroll_delay; - s->invert = false; - if (style & STYLE_INVERT) { + /* set style and draw initial text */ + if (style & STYLE_INVERT) + { s->invert = true; lcd_puts_style(x,y,string,STYLE_INVERT); } else + { + s->invert = false; lcd_puts(x,y,string); + } - lcd_getstringsize(string, &w, &h); - - if (LCD_WIDTH - x * 8 - xmargin < w) { - /* prepare scroll line */ - char *end; - - memset(s->line, 0, sizeof s->line); - strcpy(s->line, string); - - /* 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; - } + /* is line long enough to scroll? */ + s->len = strlen(string); + s->width = lcd_getstringsize(string,0,0); + int dispw = DISPLAY_WIDTH - x * 8 - xmargin; + if ( s->width <= dispw ) + return; /* nah */ + + /* store the string */ + strcpy(s->line, string); + + /* determine correct scroll type for 'auto' */ + s->type = scroll_type; + if (s->type == SCROLL_TYPE_AUTO) + { + int upper_limit = (DISPLAY_WIDTH - xmargin) * (100 + bidir_limit) / 100; + int lower_limit = upper_limit / 2; + if ( s->width < lower_limit ) + s->type = SCROLL_TYPE_BIDI; + else if ( s->width > upper_limit ) + s->type = SCROLL_TYPE_CONT; else - s->bidir = false; + s->type = SCROLL_TYPE_JUMPBACK; + } - 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); + /* scroll type-specific init */ + switch( s->type ) + { + case SCROLL_TYPE_CONT: + { + /* add spaces to enhance wrap-around effect */ + static const char spacing[] = " ... "; + strcat(s->line, spacing); + /* add-in width of spacing */ + s->len += strlen(spacing); + s->width += lcd_getstringsize(spacing,0,0); + /* (safely) add extra text for wrap-around effect */ + int wantch = (dispw / 8) * 2; /* the '8' is fudgey, init? */ + int maxstr = (sizeof(s->line) - s->len); + if (wantch > maxstr) + wantch = maxstr; + strncpy(&s->line[s->len], string, wantch); + s->line[s->len+wantch] = '\0'; + /* intentional fall-through: get bidi init too */ + } + case SCROLL_TYPE_BIDI: + { + s->backward = false; + break; + } + case SCROLL_TYPE_JUMPBACK: + { + s->jump_back = false; + break; } - - end = strchr(s->line, '\0'); - strncpy(end, string, LCD_WIDTH/2); - - s->len = strlen(string); - s->offset = 0; - s->startx = x; - s->backward = false; - scrolling_lines |= (1<startx = x; + s->offset = 0; + s->start_tick = current_tick + scroll_delay; + scrolling_lines |= (1<start_tick)) continue; - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; - pf = font_get(curfont); xpos = xmargin + s->startx * s->width / s->len; 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; + switch( s->type ) + { + case SCROLL_TYPE_BIDI: + { + if (s->backward) + s->offset -= scroll_step; + else + s->offset += scroll_step; + + if (s->offset <= 0) + { + /* at beginning of line */ + s->offset = 0; + s->start_tick = current_tick + scroll_delay * 2; + s->backward = false; + } + if (s->offset >= s->width - (DISPLAY_WIDTH - xpos)) + { + /* at end of line */ + s->offset = s->width - (DISPLAY_WIDTH - xpos); + s->start_tick = current_tick + scroll_delay * 2; + s->backward = true; + } + break; } - 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; + case SCROLL_TYPE_CONT: + { + s->offset += scroll_step; + if (s->offset >= s->width) + s->offset %= s->width; + break; + } + default: + case SCROLL_TYPE_JUMPBACK: + { + if (s->jump_back) + { + /* jump back to beginning of line and delay again */ + s->jump_back = false; + s->offset = 0; + s->start_tick = current_tick + scroll_delay; + } + else + { + s->offset += scroll_step; + if (s->offset >= s->width - (DISPLAY_WIDTH - xpos)) + { + /* at end of line */ + s->offset = s->width - (DISPLAY_WIDTH - xpos); + s->start_tick = current_tick + scroll_delay * 2; + s->jump_back = true; + } + } + break; } - } - else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; } lastmode = drawmode; drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); - lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lcd_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); drawmode = DRMODE_SOLID; lcd_putsxyofs(xpos, ypos, s->offset, s->line); if (s->invert) { drawmode = DRMODE_COMPLEMENT; - lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lcd_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); } drawmode = lastmode; - lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); + lcd_update_rect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); } sleep(scroll_ticks); diff -Nau ref-2.5/firmware/drivers/lcd-h100-remote.c jumpback-5-2.5/firmware/drivers/lcd-h100-remote.c --- ref-2.5/firmware/drivers/lcd-h100-remote.c 2005-09-22 03:53:14.000000000 -0400 +++ jumpback-5-2.5/firmware/drivers/lcd-h100-remote.c 2005-10-16 01:02:28.000000000 -0400 @@ -7,7 +7,7 @@ * \/ \/ \/ \/ \/ * $Id: lcd-h100-remote.c,v 1.25 2005/07/28 08:36:24 amiconn Exp $ * - * Copyright (C) 2005 by Richard S. La Charité III + * Copyright (C) 2005 by Richard S. La Charit�III * * 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. @@ -66,7 +66,10 @@ /*** globals ***/ -unsigned char lcd_remote_framebuffer[LCD_REMOTE_HEIGHT/8][LCD_REMOTE_WIDTH] +#define DISPLAY_WIDTH LCD_REMOTE_WIDTH +#define DISPLAY_HEIGHT LCD_REMOTE_HEIGHT + +unsigned char lcd_remote_framebuffer[DISPLAY_HEIGHT/8][DISPLAY_WIDTH] IDATA_ATTR; static int drawmode = DRMODE_SOLID; @@ -95,6 +98,7 @@ 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_type = SCROLL_TYPE_AUTO; static int scroll_step = 6; /* pixels per scroll step */ static int bidir_limit = 50; /* percent */ static struct scrollinfo scroll[SCROLLABLE_LINES]; @@ -258,7 +262,7 @@ } else { - xoffset = 132 - LCD_REMOTE_WIDTH; + xoffset = 132 - DISPLAY_WIDTH; if (remote_initialized) { lcd_remote_write_command(LCD_REMOTE_CNTL_ADC_REVERSE); @@ -273,7 +277,7 @@ * remapping only and all operations on the lcd are affected. * -> * @param int lines - The number of lines that are rolled. - * The value must be 0 <= pixels < LCD_REMOTE_HEIGHT. */ + * The value must be 0 <= pixels < DISPLAY_HEIGHT. */ void lcd_remote_roll(int lines) { char data[2]; @@ -282,7 +286,7 @@ if (remote_initialized) { - lines &= LCD_REMOTE_HEIGHT-1; + lines &= DISPLAY_HEIGHT-1; data[0] = lines & 0xff; data[1] = lines >> 8; @@ -398,12 +402,12 @@ return; /* Copy display bitmap to hardware */ - for (y = 0; y < LCD_REMOTE_HEIGHT/8; y++) + for (y = 0; y < DISPLAY_HEIGHT/8; y++) { lcd_remote_write_command(LCD_REMOTE_CNTL_SET_PAGE_ADDRESS | y); lcd_remote_write_command(LCD_REMOTE_CNTL_HIGHCOL | ((xoffset >> 4) & 0xf)); lcd_remote_write_command(LCD_REMOTE_CNTL_LOWCOL | (xoffset & 0xf)); - lcd_remote_write_data(lcd_remote_framebuffer[y], LCD_REMOTE_WIDTH); + lcd_remote_write_data(lcd_remote_framebuffer[y], DISPLAY_WIDTH); } } @@ -420,12 +424,12 @@ ymax = (y + height-1) >> 3; y >>= 3; - if(x + width > LCD_REMOTE_WIDTH) - width = LCD_REMOTE_WIDTH - x; + if(x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; if (width <= 0) return; /* nothing left to do, 0 is harmful to lcd_write_data() */ - if(ymax >= LCD_REMOTE_HEIGHT/8) - ymax = LCD_REMOTE_HEIGHT/8-1; + if(ymax >= DISPLAY_HEIGHT/8) + ymax = DISPLAY_HEIGHT/8-1; /* Copy specified rectange bitmap to hardware */ for (; y <= ymax; y++) @@ -580,7 +584,7 @@ /* Set a single pixel */ void lcd_remote_drawpixel(int x, int y) { - if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT)) + if (((unsigned)x < DISPLAY_WIDTH) && ((unsigned)y < DISPLAY_HEIGHT)) lcd_remote_pixelfuncs[drawmode](x, y); } @@ -637,7 +641,7 @@ for (i = 0; i < numpixels; i++) { - if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT)) + if (((unsigned)x < DISPLAY_WIDTH) && ((unsigned)y < DISPLAY_HEIGHT)) pfunc(x, y); if (d < 0) @@ -672,15 +676,15 @@ } /* nothing to draw? */ - if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH) + if (((unsigned)y >= DISPLAY_HEIGHT) || (x1 >= DISPLAY_WIDTH) || (x2 < 0)) return; /* clipping */ if (x1 < 0) x1 = 0; - if (x2 >= LCD_REMOTE_WIDTH) - x2 = LCD_REMOTE_WIDTH-1; + if (x2 >= DISPLAY_WIDTH) + x2 = DISPLAY_WIDTH-1; bfunc = lcd_remote_blockfuncs[drawmode]; dst = &lcd_remote_framebuffer[y>>3][x1]; @@ -709,15 +713,15 @@ } /* nothing to draw? */ - if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT) + if (((unsigned)x >= DISPLAY_WIDTH) || (y1 >= DISPLAY_HEIGHT) || (y2 < 0)) return; /* clipping */ if (y1 < 0) y1 = 0; - if (y2 >= LCD_REMOTE_HEIGHT) - y2 = LCD_REMOTE_HEIGHT-1; + if (y2 >= DISPLAY_HEIGHT) + y2 = DISPLAY_HEIGHT-1; bfunc = lcd_remote_blockfuncs[drawmode]; dst = &lcd_remote_framebuffer[y1>>3][x]; @@ -728,7 +732,7 @@ for (; ny >= 8; ny -= 8) { bfunc(dst, mask, 0xFFu); - dst += LCD_REMOTE_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -761,8 +765,8 @@ bool fillopt; /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) - || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) + if ((width <= 0) || (height <= 0) || (x >= DISPLAY_WIDTH) + || (y >= DISPLAY_HEIGHT) || (x + width <= 0) || (y + height <= 0)) return; /* clipping */ @@ -776,10 +780,10 @@ height += y; y = 0; } - if (x + width > LCD_REMOTE_WIDTH) - width = LCD_REMOTE_WIDTH - x; - if (y + height > LCD_REMOTE_HEIGHT) - height = LCD_REMOTE_HEIGHT - y; + if (x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; + if (y + height > DISPLAY_HEIGHT) + height = DISPLAY_HEIGHT - y; fillopt = (drawmode & DRMODE_INVERSEVID) ? (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG); @@ -805,7 +809,7 @@ while (dst_row < dst_end); } - dst += LCD_REMOTE_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -845,8 +849,8 @@ lcd_blockfunc_type *bfunc; /* nothing to draw? */ - if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) - || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) + if ((width <= 0) || (height <= 0) || (x >= DISPLAY_WIDTH) + || (y >= DISPLAY_HEIGHT) || (x + width <= 0) || (y + height <= 0)) return; /* clipping */ @@ -862,10 +866,10 @@ src_y -= y; y = 0; } - if (x + width > LCD_REMOTE_WIDTH) - width = LCD_REMOTE_WIDTH - x; - if (y + height > LCD_REMOTE_HEIGHT) - height = LCD_REMOTE_HEIGHT - y; + if (x + width > DISPLAY_WIDTH) + width = DISPLAY_WIDTH - x; + if (y + height > DISPLAY_HEIGHT) + height = DISPLAY_HEIGHT - y; src += stride * (src_y >> 3) + src_x; /* move starting point */ src_y &= 7; @@ -898,7 +902,7 @@ } src += stride; - dst += LCD_REMOTE_WIDTH; + dst += DISPLAY_WIDTH; mask = 0xFFu; } mask &= mask_bottom; @@ -936,7 +940,7 @@ mask_col >>= 8; src_col += stride; - dst_col += LCD_REMOTE_WIDTH; + dst_col += DISPLAY_WIDTH; data >>= 8; } data |= *src_col << shift; @@ -959,7 +963,7 @@ int ch; struct font* pf = font_get(curfont); - while ((ch = *str++) != '\0' && x < LCD_REMOTE_WIDTH) + while ((ch = *str++) != '\0' && x < DISPLAY_WIDTH) { int width; const unsigned char *bits; @@ -1019,11 +1023,11 @@ ypos = ymargin + y*h; lcd_remote_putsxy(xpos, ypos, str); drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); - lcd_remote_fillrect(xpos + w, ypos, LCD_REMOTE_WIDTH - (xpos + w), h); + lcd_remote_fillrect(xpos + w, ypos, DISPLAY_WIDTH - (xpos + w), h); if (style & STYLE_INVERT) { drawmode = DRMODE_COMPLEMENT; - lcd_remote_fillrect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, h); + lcd_remote_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, h); } drawmode = lastmode; } @@ -1062,6 +1066,11 @@ scroll_delay = ms / (HZ / 10); } +void lcd_remote_scroll_type(int type) +{ + scroll_type = type; +} + void lcd_remote_bidir_scroll(int percent) { bidir_limit = percent; @@ -1074,59 +1083,82 @@ void lcd_remote_puts_scroll_style(int x, int y, const unsigned char *string, int style) { - struct scrollinfo* s; - int w, h; + struct scrollinfo *s = &scroll[y]; + scrolling_lines &= ~(1<start_tick = current_tick + scroll_delay; - s->invert = false; - if (style & STYLE_INVERT) { + /* set style and draw initial text */ + if (style & STYLE_INVERT) + { s->invert = true; lcd_remote_puts_style(x,y,string,STYLE_INVERT); } else + { + s->invert = false; lcd_remote_puts(x,y,string); + } - lcd_remote_getstringsize(string, &w, &h); - - if (LCD_REMOTE_WIDTH - x * 8 - xmargin < w) { - /* prepare scroll line */ - char *end; - - memset(s->line, 0, sizeof s->line); - strcpy(s->line, string); - - /* get width */ - s->width = lcd_remote_getstringsize(s->line, &w, &h); - - /* scroll bidirectional or forward only depending on the string - width */ - if ( bidir_limit ) { - s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * - (100 + bidir_limit) / 100; - } + /* is line long enough to scroll? */ + s->len = strlen(string); + s->width = lcd_remote_getstringsize(string,0,0); + int dispw = DISPLAY_WIDTH - x * 8 - xmargin; + if ( s->width <= dispw ) + return; /* nah */ + + /* store the string */ + strcpy(s->line, string); + + /* determine correct scroll type for 'auto' */ + s->type = scroll_type; + if (s->type == SCROLL_TYPE_AUTO) + { + int upper_limit = (DISPLAY_WIDTH - xmargin) * (100 + bidir_limit) / 100; + int lower_limit = upper_limit / 2; + if ( s->width < lower_limit ) + s->type = SCROLL_TYPE_BIDI; + else if ( s->width > upper_limit ) + s->type = SCROLL_TYPE_CONT; else - s->bidir = false; + s->type = SCROLL_TYPE_JUMPBACK; + } - if (!s->bidir) { /* add spaces if scrolling in the round */ - strcat(s->line, " "); - /* get new width incl. spaces */ - s->width = lcd_remote_getstringsize(s->line, &w, &h); + /* scroll type-specific init */ + switch( s->type ) + { + case SCROLL_TYPE_CONT: + { + /* add spaces to enhance wrap-around effect */ + static const char spacing[] = " ... "; + strcat(s->line, spacing); + /* add-in width of spacing */ + s->len += strlen(spacing); + s->width += lcd_remote_getstringsize(spacing,0,0); + /* (safely) add extra text for wrap-around effect */ + int wantch = (dispw / 8) * 2; /* the '8' is fudgey, init? */ + int maxstr = (sizeof(s->line) - s->len); + if (wantch > maxstr) + wantch = maxstr; + strncpy(&s->line[s->len], string, wantch); + s->line[s->len+wantch] = '\0'; + /* intentional fall-through: get bidi init too */ + } + case SCROLL_TYPE_BIDI: + { + s->backward = false; + break; + } + case SCROLL_TYPE_JUMPBACK: + { + s->jump_back = false; + break; } - - end = strchr(s->line, '\0'); - strncpy(end, string, LCD_REMOTE_WIDTH/2); - - s->len = strlen(string); - s->offset = 0; - s->startx = x; - s->backward = false; - scrolling_lines |= (1<startx = x; + s->offset = 0; + s->start_tick = current_tick + scroll_delay; + scrolling_lines |= (1<start_tick)) continue; - if (s->backward) - s->offset -= scroll_step; - else - s->offset += scroll_step; - pf = font_get(curfont); xpos = xmargin + s->startx * s->width / s->len; 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; + switch( s->type ) + { + case SCROLL_TYPE_BIDI: + { + if (s->backward) + s->offset -= scroll_step; + else + s->offset += scroll_step; + + if (s->offset <= 0) + { + /* at beginning of line */ + s->offset = 0; + s->start_tick = current_tick + scroll_delay * 2; + s->backward = false; + } + if (s->offset >= s->width - (DISPLAY_WIDTH - xpos)) + { + /* at end of line */ + s->offset = s->width - (DISPLAY_WIDTH - xpos); + s->start_tick = current_tick + scroll_delay * 2; + s->backward = true; + } + break; } - 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; + case SCROLL_TYPE_CONT: + { + s->offset += scroll_step; + if (s->offset >= s->width) + s->offset %= s->width; + break; + } + default: + case SCROLL_TYPE_JUMPBACK: + { + if (s->jump_back) + { + /* jump back to beginning of line and delay again */ + s->jump_back = false; + s->offset = 0; + s->start_tick = current_tick + scroll_delay; + } + else + { + s->offset += scroll_step; + if (s->offset >= s->width - (DISPLAY_WIDTH - xpos)) + { + /* at end of line */ + s->offset = s->width - (DISPLAY_WIDTH - xpos); + s->start_tick = current_tick + scroll_delay * 2; + s->jump_back = true; + } + } + break; } - } - else { - /* scroll forward the whole time */ - if (s->offset >= s->width) - s->offset %= s->width; } lastmode = drawmode; drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); - lcd_remote_fillrect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); + lcd_remote_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); drawmode = DRMODE_SOLID; lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); if (s->invert) { drawmode = DRMODE_COMPLEMENT; - lcd_remote_fillrect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); + lcd_remote_fillrect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); } drawmode = lastmode; - lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); + lcd_remote_update_rect(xpos, ypos, DISPLAY_WIDTH - xpos, pf->height); } sleep(scroll_ticks); diff -Nau ref-2.5/apps/settings_menu.c jumpback-5-2.5/apps/settings_menu.c --- ref-2.5/apps/settings_menu.c 2005-09-22 03:53:08.000000000 -0400 +++ jumpback-5-2.5/apps/settings_menu.c 2005-10-16 01:02:28.000000000 -0400 @@ -747,10 +747,36 @@ &dummy, &lcd_scroll_delay, 100, 0, 2500, NULL ); global_settings.scroll_delay = dummy / (HZ/10); + lcd_scroll_delay(dummy); +#ifdef HAVE_REMOTE_LCD + lcd_remote_scroll_delay(dummy); +#endif return rc; } #ifdef HAVE_LCD_BITMAP +static bool scroll_type(void) +{ + static const struct opt_items names[] = + { + { STR(LANG_SCROLL_TYPE_AUTO) }, + { STR(LANG_SCROLL_TYPE_BIDI) }, + { STR(LANG_SCROLL_TYPE_JUMPBACK) }, + { STR(LANG_SCROLL_TYPE_CONT) } + }; + int old_type = global_settings.scroll_type; + bool rc = set_option( str(LANG_SCROLL_TYPE), &global_settings.scroll_type, INT, + names, 4, NULL ); + if ( global_settings.scroll_type != old_type ) + { + lcd_scroll_type(global_settings.scroll_type); +#ifdef HAVE_REMOTE_LCD + lcd_remote_scroll_type(global_settings.scroll_type); +#endif + } + return rc; +} + static bool scroll_step(void) { return set_int(str(LANG_SCROLL_STEP_EXAMPLE), "pixels", UNIT_PIXEL, @@ -761,9 +787,18 @@ static bool bidir_limit(void) { - return set_int(str(LANG_BIDIR_SCROLL), "%", UNIT_PERCENT, - &global_settings.bidir_limit, + int old_value = global_settings.bidir_limit; + bool rc = set_int(str(LANG_BIDIR_SCROLL), "%", UNIT_PERCENT, + &global_settings.bidir_limit, &lcd_bidir_scroll, 25, 0, 200, NULL ); + if ( global_settings.bidir_limit != old_value ) + { + lcd_bidir_scroll(global_settings.bidir_limit); +#ifdef HAVE_REMOTE_LCD + lcd_remote_bidir_scroll(global_settings.bidir_limit); +#endif + } + return rc; } #ifdef HAVE_LCD_CHARCELLS @@ -1400,6 +1435,9 @@ bool result; static const struct menu_item items[] = { +#ifdef HAVE_LCD_BITMAP + { ID2P(LANG_SCROLL_TYPE), scroll_type }, +#endif { ID2P(LANG_SCROLL_SPEED), scroll_speed }, { ID2P(LANG_SCROLL_DELAY), scroll_delay }, #ifdef HAVE_LCD_BITMAP diff -Nau ref-2.5/apps/settings.h jumpback-5-2.5/apps/settings.h --- ref-2.5/apps/settings.h 2005-09-22 03:53:08.000000000 -0400 +++ jumpback-5-2.5/apps/settings.h 2005-10-16 01:02:28.000000000 -0400 @@ -274,6 +274,7 @@ 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 */ + int scroll_type; /* type of scrolling to use 0=auto, 1=bidi, 2=jumpback, 3=continuous*/ /* auto bookmark settings */ int autoloadbookmark; /* auto load option: 0=off, 1=ask, 2=on */ diff -Nau ref-2.5/apps/settings.c jumpback-5-2.5/apps/settings.c --- ref-2.5/apps/settings.c 2005-09-22 03:53:08.000000000 -0400 +++ jumpback-5-2.5/apps/settings.c 2005-10-16 01:02:28.000000000 -0400 @@ -79,7 +79,7 @@ #include "pcm_playback.h" #endif -#define CONFIG_BLOCK_VERSION 27 +#define CONFIG_BLOCK_VERSION 28 #define CONFIG_BLOCK_SIZE 512 #define RTC_BLOCK_SIZE 44 @@ -293,6 +293,7 @@ #ifdef CONFIG_BACKLIGHT {1, S_O(caption_backlight), false, "caption backlight", off_on }, #endif + {2, S_O(scroll_type), SCROLL_TYPE_AUTO, "scroll type", "auto,bidi,jumpback,continuous" }, {4, S_O(scroll_speed), 9, "scroll speed", NULL }, /* 0...15 */ #ifdef HAVE_LCD_BITMAP #if LCD_WIDTH > 127 @@ -807,6 +808,7 @@ lcd_remote_set_invert_display(global_settings.remote_invert); lcd_remote_set_flip(global_settings.remote_flip_display); remote_backlight_set_timeout(global_settings.remote_backlight_timeout); + lcd_remote_scroll_type(global_settings.scroll_type); #endif backlight_set_timeout(global_settings.backlight_timeout); backlight_set_on_when_charging(global_settings.backlight_on_when_charging); @@ -862,6 +864,7 @@ font_reset(); lcd_scroll_step(global_settings.scroll_step); + lcd_scroll_type(global_settings.scroll_type); #else lcd_jump_scroll(global_settings.jump_scroll); lcd_jump_scroll_delay(global_settings.jump_scroll_delay * (HZ/10)); diff -Nau ref-2.5/apps/lang/english.lang jumpback-5-2.5/apps/lang/english.lang --- ref-2.5/apps/lang/english.lang 2005-09-22 03:53:09.000000000 -0400 +++ jumpback-5-2.5/apps/lang/english.lang 2005-10-16 01:02:28.000000000 -0400 @@ -3292,3 +3292,33 @@ eng: "A-B" voice: "A-B" new: + +id: LANG_SCROLL_TYPE +desc: scroll type +eng: "Scroll Type" +voice "Scroll type" +new: + +id: LANG_SCROLL_TYPE_AUTO +desc: scroll type auto +eng: "Auto" +voice "Auto" +new: + +id: LANG_SCROLL_TYPE_BIDI +desc: scroll type bidirectional +eng: "Bidirectional" +voice "Bidirectional" +new: + +id: LANG_SCROLL_TYPE_JUMPBACK +desc: scroll type jump-back +eng: "Jump-back" +voice "Jump-back" +new: + +id: LANG_SCROLL_TYPE_CONT +desc: scroll type continuous +eng: "Continuous" +voice "Continuous" +new: