diff options
Diffstat (limited to 'apps/plugins/lib')
| -rw-r--r-- | apps/plugins/lib/xlcd.c | 114 | ||||
| -rw-r--r-- | apps/plugins/lib/xlcd.h | 5 |
2 files changed, 119 insertions, 0 deletions
diff --git a/apps/plugins/lib/xlcd.c b/apps/plugins/lib/xlcd.c index a0dcc2a..33d807f 100644 --- a/apps/plugins/lib/xlcd.c +++ b/apps/plugins/lib/xlcd.c @@ -105,5 +105,119 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) } } +#if LCD_DEPTH >= 8 +/* FIXME: intermediate solution until we have properly optimised memmove() */ +static void *my_memmove(void *dst0, const void *src0, size_t len0) +{ + char *dst = (char *) dst0; + char *src = (char *) src0; + + if (dst <= src) + { + while (len0--) + *dst++ = *src++; + } + else + { + dst += len0; + src += len0; + + while (len0--) + *(--dst) = *(--src); + } + + return dst0; +} + +void xlcd_scroll_left(int count) +{ + fb_data *data, *data_end; + int length, oldmode; + + if ((unsigned)count >= LCD_WIDTH) + return; + + data = local_rb->lcd_framebuffer; + data_end = data + LCD_WIDTH*LCD_HEIGHT; + length = LCD_WIDTH - count; + + do + { + my_memmove(data, data + count, length * sizeof(fb_data)); + data += LCD_WIDTH; + } + while (data < data_end); + + oldmode = local_rb->lcd_get_drawmode(); + local_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + local_rb->lcd_fillrect(length, 0, count, LCD_HEIGHT); + local_rb->lcd_set_drawmode(oldmode); +} + +void xlcd_scroll_right(int count) +{ + fb_data *data, *data_end; + int length, oldmode; + + if ((unsigned)count >= LCD_WIDTH) + return; + + data = local_rb->lcd_framebuffer; + data_end = data + LCD_WIDTH*LCD_HEIGHT; + length = LCD_WIDTH - count; + + do + { + my_memmove(data + count, data, length * sizeof(fb_data)); + data += LCD_WIDTH; + } + while (data < data_end); + + oldmode = local_rb->lcd_get_drawmode(); + local_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + local_rb->lcd_fillrect(0, 0, count, LCD_HEIGHT); + local_rb->lcd_set_drawmode(oldmode); +} + +void xlcd_scroll_up(int count) +{ + long length, oldmode; + + if ((unsigned)count >= LCD_HEIGHT) + return; + + length = LCD_HEIGHT - count; + + my_memmove(local_rb->lcd_framebuffer, + local_rb->lcd_framebuffer + count * LCD_WIDTH, + length * LCD_WIDTH * sizeof(fb_data)); + + oldmode = local_rb->lcd_get_drawmode(); + local_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + local_rb->lcd_fillrect(0, length, LCD_WIDTH, count); + local_rb->lcd_set_drawmode(oldmode); +} + +void xlcd_scroll_down(int count) +{ + long length, oldmode; + + if ((unsigned)count >= LCD_HEIGHT) + return; + + length = LCD_HEIGHT - count; + + my_memmove(local_rb->lcd_framebuffer + count * LCD_WIDTH, + local_rb->lcd_framebuffer, + length * LCD_WIDTH * sizeof(fb_data)); + + oldmode = local_rb->lcd_get_drawmode(); + local_rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + local_rb->lcd_fillrect(0, 0, LCD_WIDTH, count); + local_rb->lcd_set_drawmode(oldmode); +} + +#endif /* LCD_DEPTH >= 8 */ + #endif /* HAVE_LCD_BITMAP */ diff --git a/apps/plugins/lib/xlcd.h b/apps/plugins/lib/xlcd.h index 3f54643..2eaa05c 100644 --- a/apps/plugins/lib/xlcd.h +++ b/apps/plugins/lib/xlcd.h @@ -29,6 +29,11 @@ void xlcd_init(struct plugin_api* newrb); void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3); +void xlcd_scroll_left(int count); +void xlcd_scroll_right(int count); +void xlcd_scroll_up(int count); +void xlcd_scroll_down(int count); + #endif /* HAVE_LCD_BITMAP */ #endif /* __XLCD_H__ */ |