summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-bitmap-common.c3
-rw-r--r--firmware/drivers/lcd-scroll.c125
2 files changed, 75 insertions, 53 deletions
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index a102eaea66..a71f5b2862 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -398,6 +398,9 @@ static void LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string,
398 s->height = height; 398 s->height = height;
399 s->vp = current_vp; 399 s->vp = current_vp;
400 LCDFN(scroll_info).lines++; 400 LCDFN(scroll_info).lines++;
401 } else {
402 /* if only the text was updated render immediately */
403 LCDFN(scroll_now(s));
401 } 404 }
402} 405}
403 406
diff --git a/firmware/drivers/lcd-scroll.c b/firmware/drivers/lcd-scroll.c
index d524ce81c8..a1bde9fe12 100644
--- a/firmware/drivers/lcd-scroll.c
+++ b/firmware/drivers/lcd-scroll.c
@@ -123,11 +123,78 @@ void LCDFN(jump_scroll_delay)(int ms)
123} 123}
124#endif 124#endif
125 125
126/* This renders the scrolling line described by s immediatly.
127 * This can be called to update a scrolling line if the text has changed
128 * without waiting for the next scroll tick
129 *
130 * Returns true if the text scrolled to the end */
131bool LCDFN(scroll_now)(struct scrollinfo *s)
132{
133 int width = LCDFN(getstringsize)(s->linebuffer, NULL, NULL);
134 bool ended = false;
135 /* assume s->scroll_func() don't yield; otherwise this buffer might need
136 * to be mutex'd (the worst case would be minor glitches though) */
137 static char line_buf[SCROLL_LINE_SIZE];
138
139 if (s->bidir)
140 { /* scroll bidirectional */
141 s->line = s->linebuffer;
142 if (s->offset <= 0) {
143 /* at beginning of line */
144 s->offset = 0;
145 s->backward = false;
146 ended = true;
147 }
148 else if (s->offset >= width - s->width) {
149 /* at end of line */
150 s->offset = width - s->width;
151 s->backward = true;
152 ended = true;
153 }
154 }
155 else
156 {
157 snprintf(line_buf, sizeof(line_buf)-1, "%s%s%s",
158 s->linebuffer, " ", s->linebuffer);
159 s->line = line_buf;
160 width += LCDFN(getstringsize)(" ", NULL, NULL);
161 /* scroll forward the whole time */
162 if (s->offset >= width) {
163 s->offset = 0;
164 ended = true;
165 }
166 }
167
168 /* Stash and restore these three, so that the scroll_func
169 * can do whatever it likes without destroying the state */
170#ifdef HAVE_LCD_BITMAP
171 unsigned drawmode;
172#if LCD_DEPTH > 1
173 unsigned fg_pattern, bg_pattern;
174 fg_pattern = s->vp->fg_pattern;
175 bg_pattern = s->vp->bg_pattern;
176#endif
177 drawmode = s->vp->drawmode;
178#endif
179 s->scroll_func(s);
180
181 LCDFN(update_viewport_rect)(s->x, s->y, s->width, s->height);
182
183#ifdef HAVE_LCD_BITMAP
184#if LCD_DEPTH > 1
185 s->vp->fg_pattern = fg_pattern;
186 s->vp->bg_pattern = bg_pattern;
187#endif
188 s->vp->drawmode = drawmode;
189#endif
190
191 return ended;
192}
193
126static void LCDFN(scroll_worker)(void) 194static void LCDFN(scroll_worker)(void)
127{ 195{
128 int index, width; 196 int index;
129 bool makedelay; 197 bool makedelay;
130 static char line_buf[SCROLL_LINE_SIZE];
131 bool is_default; 198 bool is_default;
132 struct scroll_screen_info *si = &LCDFN(scroll_info); 199 struct scroll_screen_info *si = &LCDFN(scroll_info);
133 struct scrollinfo *s; 200 struct scrollinfo *s;
@@ -152,7 +219,6 @@ static void LCDFN(scroll_worker)(void)
152 vp = LCDFN(get_viewport)(&is_default); 219 vp = LCDFN(get_viewport)(&is_default);
153 LCDFN(set_viewport)(s->vp); 220 LCDFN(set_viewport)(s->vp);
154 221
155 width = LCDFN(getstringsize)(s->linebuffer, NULL, NULL);
156 makedelay = false; 222 makedelay = false;
157#ifdef HAVE_LCD_BITMAP 223#ifdef HAVE_LCD_BITMAP
158 step = si->step; 224 step = si->step;
@@ -160,62 +226,15 @@ static void LCDFN(scroll_worker)(void)
160 step = 1; 226 step = 1;
161#endif 227#endif
162 228
229
163 if (s->backward) 230 if (s->backward)
164 s->offset -= step; 231 s->offset -= step;
165 else 232 else
166 s->offset += step; 233 s->offset += step;
167 234
168 if (s->bidir) 235 /* put the line onto the display now */
169 { /* scroll bidirectional */ 236 makedelay = LCDFN(scroll_now(s));
170 s->line = s->linebuffer;
171 if (s->offset <= 0) {
172 /* at beginning of line */
173 s->offset = 0;
174 s->backward = false;
175 makedelay = true;
176 }
177 else if (s->offset >= width - s->width) {
178 /* at end of line */
179 s->offset = width - s->width;
180 s->backward = true;
181 makedelay = true;
182 }
183 }
184 else
185 {
186 snprintf(line_buf, sizeof(line_buf)-1, "%s%s%s",
187 s->linebuffer, " ", s->linebuffer);
188 s->line = line_buf;
189 width += LCDFN(getstringsize)(" ", NULL, NULL);
190 /* scroll forward the whole time */
191 if (s->offset >= width) {
192 s->offset = 0;
193 makedelay = true;
194 }
195 }
196 237
197 /* Stash and restore these three, so that the scroll_func
198 * can do whatever it likes without destroying the state */
199#ifdef HAVE_LCD_BITMAP
200 unsigned drawmode;
201#if LCD_DEPTH > 1
202 unsigned fg_pattern, bg_pattern;
203 fg_pattern = s->vp->fg_pattern;
204 bg_pattern = s->vp->bg_pattern;
205#endif
206 drawmode = s->vp->drawmode;
207#endif
208 s->scroll_func(s);
209
210 LCDFN(update_viewport_rect)(s->x, s->y, s->width, s->height);
211
212#ifdef HAVE_LCD_BITMAP
213#if LCD_DEPTH > 1
214 s->vp->fg_pattern = fg_pattern;
215 s->vp->bg_pattern = bg_pattern;
216#endif
217 s->vp->drawmode = drawmode;
218#endif
219 LCDFN(set_viewport)(vp); 238 LCDFN(set_viewport)(vp);
220 239
221 if (makedelay) 240 if (makedelay)