summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/lcd-2bit-vert.c2
-rw-r--r--firmware/drivers/lcd-charcell.c156
-rw-r--r--firmware/drivers/lcd-scroll.c42
-rw-r--r--firmware/export/lcd.h2
-rw-r--r--firmware/export/scroll_engine.h3
-rw-r--r--firmware/rolo.c1
6 files changed, 81 insertions, 125 deletions
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c
index 08ec6cac79..501e568a69 100644
--- a/firmware/drivers/lcd-2bit-vert.c
+++ b/firmware/drivers/lcd-2bit-vert.c
@@ -387,7 +387,7 @@ void lcd_clear_viewport(void)
current_vp->drawmode = lastmode;
- lcd_scroll_stop(current_vp);
+ lcd_scroll_stop_viewport(current_vp);
}
}
diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c
index bdd02de1b6..db867cdb0a 100644
--- a/firmware/drivers/lcd-charcell.c
+++ b/firmware/drivers/lcd-charcell.c
@@ -110,11 +110,26 @@ void lcd_set_viewport(struct viewport* vp)
#endif
}
+struct viewport *lcd_get_viewport(bool *is_default)
+{
+ *is_default = (current_vp == &default_vp);
+ return current_vp;
+}
+
void lcd_update_viewport(void)
{
lcd_update();
}
+void lcd_update_viewport_rect(int x, int y, int width, int height)
+{
+ (void) x;
+ (void) y;
+ (void) width;
+ (void) height;
+ lcd_update();
+}
+
/** parameter handling **/
int lcd_getwidth(void)
@@ -486,7 +501,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 */
- lcd_scroll_stop_viewport_line(current_vp, y);
+ lcd_scroll_stop_viewport_rect(current_vp, x, y, current_vp->width - x, 1);
x = lcd_putsxyofs(x, y, offset, str);
while (x < current_vp->width)
@@ -499,8 +514,9 @@ void lcd_puts_scroll(int x, int y, const unsigned char *string)
lcd_puts_scroll_offset(x, y, string, 0);
}
-void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
- int offset)
+void lcd_puts_scroll_worker(int x, int y, const unsigned char *string,
+ int offset,
+ void (*scroll_func)(struct scrollinfo *), void *data)
{
struct scrollinfo* s;
int len;
@@ -509,7 +525,7 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
return;
/* remove any previously scrolling line at the same location */
- lcd_scroll_stop_viewport_line(current_vp, y);
+ lcd_scroll_stop_viewport_rect(current_vp, x, y, current_vp->width - x, 1);
if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
@@ -520,120 +536,48 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
lcd_puts_offset(x, y, string, offset);
len = utf8length(string);
- if (current_vp->width - x < len)
- {
- /* prepare scroll line */
- char *end;
- int count;
-
- memset(s->line, 0, sizeof s->line);
- strlcpy(s->line, string, sizeof s->line);
-
- /* get width */
- s->len = utf8length(s->line);
-
- /* scroll bidirectional or forward only depending on the string width */
- if (lcd_scroll_info.bidir_limit)
- {
- s->bidir = s->len < (current_vp->width) *
- (100 + lcd_scroll_info.bidir_limit) / 100;
- }
- else
- s->bidir = false;
-
- if (!s->bidir) /* add spaces if scrolling in the round */
- {
- strlcat(s->line, " ", sizeof s->line);
- /* get new width incl. spaces */
- s->len += SCROLL_SPACING;
- }
+ if (current_vp->width - x >= len)
+ return;
+ /* prepare scroll line */
+ strlcpy(s->linebuffer, string, sizeof s->linebuffer);
- end = strchr(s->line, '\0');
- len = sizeof s->line - (end - s->line);
- count = utf8seek(s->line, current_vp->width);
- strlcpy(end, string, MIN(count, len));
-
- s->vp = current_vp;
- s->y = y;
- s->offset = offset;
- s->startx = x;
- s->backward = false;
- lcd_scroll_info.lines++;
+ /* scroll bidirectional or forward only depending on the string width */
+ if (lcd_scroll_info.bidir_limit)
+ {
+ s->bidir = len < (current_vp->width) *
+ (100 + lcd_scroll_info.bidir_limit) / 100;
}
+ else
+ s->bidir = false;
+
+ s->scroll_func = scroll_func;
+ s->userdata = data;
+
+ s->vp = current_vp;
+ s->x = x;
+ s->y = y;
+ s->height = 1;
+ s->width = current_vp->width - x;
+ s->offset = offset;
+ s->backward = false;
+ lcd_scroll_info.lines++;
}
-void lcd_scroll_fn(void)
+void lcd_scroll_fn(struct scrollinfo* s)
{
- struct scrollinfo* s;
- int index;
- int xpos, ypos;
- bool update;
- struct viewport* old_vp = current_vp;
- bool makedelay;
-
- update = false;
- for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
- s = &lcd_scroll_info.scroll[index];
-
- /* check pause */
- if (TIME_BEFORE(current_tick, s->start_tick))
- continue;
-
- lcd_set_viewport(s->vp);
-
- if (s->backward)
- s->offset--;
- else
- s->offset++;
-
- xpos = s->startx;
- ypos = s->y;
-
- makedelay = false;
- if (s->bidir) /* scroll bidirectional */
- {
- if (s->offset <= 0) {
- /* at beginning of line */
- s->offset = 0;
- s->backward = false;
- makedelay = true;
- }
- else if (s->offset >= s->len - (current_vp->width - xpos)) {
- /* at end of line */
- s->offset = s->len - (current_vp->width - xpos);
- s->backward = true;
- makedelay = true;
- }
- }
- else /* scroll forward the whole time */
- {
- if (s->offset >= s->len) {
- s->offset = 0;
- makedelay = true;
- }
- }
-
- if (makedelay)
- s->start_tick = current_tick + lcd_scroll_info.delay +
- lcd_scroll_info.ticks;
-
- lcd_putsxyofs(xpos, ypos, s->offset, s->line);
- update = true;
- }
-
- lcd_set_viewport(old_vp);
-
+ lcd_putsxyofs(s->x, s->y, s->offset, s->line);
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();
}
+void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
+ int offset)
+{
+ lcd_puts_scroll_worker(x, y, string, offset, lcd_scroll_fn, NULL);
+}
diff --git a/firmware/drivers/lcd-scroll.c b/firmware/drivers/lcd-scroll.c
index 31c2cf20b0..d524ce81c8 100644
--- a/firmware/drivers/lcd-scroll.c
+++ b/firmware/drivers/lcd-scroll.c
@@ -132,10 +132,10 @@ static void LCDFN(scroll_worker)(void)
struct scroll_screen_info *si = &LCDFN(scroll_info);
struct scrollinfo *s;
struct viewport *vp;
+ int step;
- unsigned fg_pattern, bg_pattern, drawmode;
-
- for ( index = 0; index < si->lines; index++ ) {
+ for ( index = 0; index < si->lines; index++ )
+ {
s = &si->scroll[index];
/* check pause */
@@ -154,14 +154,19 @@ static void LCDFN(scroll_worker)(void)
width = LCDFN(getstringsize)(s->linebuffer, NULL, NULL);
makedelay = false;
-
+#ifdef HAVE_LCD_BITMAP
+ step = si->step;
+#else
+ step = 1;
+#endif
+
if (s->backward)
- s->offset -= si->step;
+ s->offset -= step;
else
- s->offset += si->step;
-
- if (s->bidir) { /* scroll bidirectional */
+ s->offset += step;
+ if (s->bidir)
+ { /* scroll bidirectional */
s->line = s->linebuffer;
if (s->offset <= 0) {
/* at beginning of line */
@@ -169,15 +174,15 @@ static void LCDFN(scroll_worker)(void)
s->backward = false;
makedelay = true;
}
- else if (s->offset >= width - (s->width - s->x)) {
+ else if (s->offset >= width - s->width) {
/* at end of line */
- s->offset = width - (s->width - s->x);
+ s->offset = width - s->width;
s->backward = true;
makedelay = true;
}
}
- else {
-
+ else
+ {
snprintf(line_buf, sizeof(line_buf)-1, "%s%s%s",
s->linebuffer, " ", s->linebuffer);
s->line = line_buf;
@@ -191,17 +196,26 @@ static void LCDFN(scroll_worker)(void)
/* Stash and restore these three, so that the scroll_func
* can do whatever it likes without destroying the state */
+#ifdef HAVE_LCD_BITMAP
+ unsigned drawmode;
+#if LCD_DEPTH > 1
+ unsigned fg_pattern, bg_pattern;
fg_pattern = s->vp->fg_pattern;
bg_pattern = s->vp->bg_pattern;
+#endif
drawmode = s->vp->drawmode;
-
+#endif
s->scroll_func(s);
+
LCDFN(update_viewport_rect)(s->x, s->y, s->width, s->height);
+#ifdef HAVE_LCD_BITMAP
+#if LCD_DEPTH > 1
s->vp->fg_pattern = fg_pattern;
s->vp->bg_pattern = bg_pattern;
+#endif
s->vp->drawmode = drawmode;
-
+#endif
LCDFN(set_viewport)(vp);
if (makedelay)
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 37e6bf4d16..f6b32a37ee 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -195,6 +195,7 @@ extern int lcd_getstringsize(const unsigned char *str, int *w, int *h);
extern void lcd_set_viewport(struct viewport* vp);
extern void lcd_update(void);
extern void lcd_update_viewport(void);
+extern void lcd_update_viewport_rect(int x, int y, int width, int height);
extern void lcd_clear_viewport(void);
extern void lcd_clear_display(void);
extern void lcd_putsxy(int x, int y, const unsigned char *string);
@@ -234,7 +235,6 @@ extern void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
/* update a fraction of the screen */
extern void lcd_update_rect(int x, int y, int width, int height);
-extern void lcd_update_viewport_rect(int x, int y, int width, int height);
#ifdef HAVE_REMOTE_LCD
extern void lcd_remote_update(void);
diff --git a/firmware/export/scroll_engine.h b/firmware/export/scroll_engine.h
index c7eb97aecc..5e4b744c59 100644
--- a/firmware/export/scroll_engine.h
+++ b/firmware/export/scroll_engine.h
@@ -62,9 +62,6 @@ struct scrollinfo
struct viewport* vp;
char linebuffer[9*MAX_PATH/10];
const char *line;
-#ifdef HAVE_LCD_CHARCELLS
- int len; /* length of line in chars */
-#endif
/* rectangle for the line */
int x, y; /* relative to the viewort */
int width, height;
diff --git a/firmware/rolo.c b/firmware/rolo.c
index 79969bbbcf..923199f9d4 100644
--- a/firmware/rolo.c
+++ b/firmware/rolo.c
@@ -24,6 +24,7 @@
#ifdef HAVE_REMOTE_LCD
#include "lcd-remote.h"
#endif
+#include "scroll_engine.h"
#include "thread.h"
#include "kernel.h"
#include "button.h"