diff options
Diffstat (limited to 'firmware/drivers/lcd-16bit.c')
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 478 |
1 files changed, 290 insertions, 188 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index b990f556d3..cc5a6c5ab7 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c | |||
@@ -49,25 +49,31 @@ fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] | |||
49 | static fb_data* lcd_backdrop = NULL; | 49 | static fb_data* lcd_backdrop = NULL; |
50 | static long lcd_backdrop_offset IDATA_ATTR = 0; | 50 | static long lcd_backdrop_offset IDATA_ATTR = 0; |
51 | 51 | ||
52 | static struct viewport default_vp = | ||
53 | { | ||
54 | .x = 0, | ||
55 | .y = 0, | ||
56 | .width = LCD_WIDTH, | ||
57 | .height = LCD_HEIGHT, | ||
58 | .font = FONT_SYSFIXED, | ||
59 | .drawmode = DRMODE_SOLID, | ||
60 | .xmargin = 0, | ||
61 | .ymargin = 0, | ||
62 | .fg_pattern = LCD_DEFAULT_FG, | ||
63 | .bg_pattern = LCD_DEFAULT_BG, | ||
64 | .lss_pattern = LCD_DEFAULT_BG, | ||
65 | .lse_pattern = LCD_DEFAULT_BG, | ||
66 | .lst_pattern = LCD_DEFAULT_BG, | ||
67 | }; | ||
68 | |||
69 | /* The Gigabeat target build requires access to the current fg_pattern | ||
70 | in lcd-meg-fx.c */ | ||
52 | #if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR) | 71 | #if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR) |
53 | static unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; | 72 | static struct viewport* current_vp IDATA_ATTR = &default_vp; |
54 | static unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG; | ||
55 | static unsigned lss_pattern IDATA_ATTR = LCD_DEFAULT_LS; | ||
56 | static unsigned lse_pattern IDATA_ATTR = LCD_DEFAULT_BG; | ||
57 | static unsigned lst_pattern IDATA_ATTR = LCD_DEFAULT_FG; | ||
58 | #else | 73 | #else |
59 | unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; | 74 | struct viewport* current_vp IDATA_ATTR = &default_vp; |
60 | unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG; | ||
61 | unsigned lss_pattern IDATA_ATTR = LCD_DEFAULT_LS; | ||
62 | unsigned lse_pattern IDATA_ATTR = LCD_DEFAULT_BG; | ||
63 | unsigned lst_pattern IDATA_ATTR = LCD_DEFAULT_FG; | ||
64 | #endif | 75 | #endif |
65 | 76 | ||
66 | static int drawmode = DRMODE_SOLID; | ||
67 | static int xmargin = 0; | ||
68 | static int ymargin = 0; | ||
69 | static int curfont = FONT_SYSFIXED; | ||
70 | |||
71 | /* LCD init */ | 77 | /* LCD init */ |
72 | void lcd_init(void) | 78 | void lcd_init(void) |
73 | { | 79 | { |
@@ -78,84 +84,115 @@ void lcd_init(void) | |||
78 | scroll_init(); | 84 | scroll_init(); |
79 | } | 85 | } |
80 | 86 | ||
87 | /*** Viewports ***/ | ||
88 | |||
89 | void lcd_set_viewport(struct viewport* vp) | ||
90 | { | ||
91 | if (vp == NULL) | ||
92 | current_vp = &default_vp; | ||
93 | else | ||
94 | current_vp = vp; | ||
95 | } | ||
96 | |||
97 | void lcd_update_viewport(void) | ||
98 | { | ||
99 | lcd_update_rect(current_vp->x, current_vp->y, | ||
100 | current_vp->width, current_vp->height); | ||
101 | } | ||
102 | |||
103 | void lcd_update_viewport_rect(int x, int y, int width, int height) | ||
104 | { | ||
105 | lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height); | ||
106 | } | ||
107 | |||
81 | /*** parameter handling ***/ | 108 | /*** parameter handling ***/ |
82 | 109 | ||
83 | void lcd_set_drawmode(int mode) | 110 | void lcd_set_drawmode(int mode) |
84 | { | 111 | { |
85 | drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | 112 | current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); |
86 | } | 113 | } |
87 | 114 | ||
88 | int lcd_get_drawmode(void) | 115 | int lcd_get_drawmode(void) |
89 | { | 116 | { |
90 | return drawmode; | 117 | return current_vp->drawmode; |
91 | } | 118 | } |
92 | 119 | ||
93 | void lcd_set_foreground(unsigned color) | 120 | void lcd_set_foreground(unsigned color) |
94 | { | 121 | { |
95 | fg_pattern = color; | 122 | current_vp->fg_pattern = color; |
96 | } | 123 | } |
97 | 124 | ||
98 | unsigned lcd_get_foreground(void) | 125 | unsigned lcd_get_foreground(void) |
99 | { | 126 | { |
100 | return fg_pattern; | 127 | return current_vp->fg_pattern; |
101 | } | 128 | } |
102 | 129 | ||
103 | void lcd_set_background(unsigned color) | 130 | void lcd_set_background(unsigned color) |
104 | { | 131 | { |
105 | bg_pattern = color; | 132 | current_vp->bg_pattern = color; |
106 | } | 133 | } |
107 | 134 | ||
108 | unsigned lcd_get_background(void) | 135 | unsigned lcd_get_background(void) |
109 | { | 136 | { |
110 | return bg_pattern; | 137 | return current_vp->bg_pattern; |
111 | } | 138 | } |
112 | 139 | ||
113 | void lcd_set_selector_start(unsigned color) | 140 | void lcd_set_selector_start(unsigned color) |
114 | { | 141 | { |
115 | lss_pattern = color; | 142 | current_vp->lss_pattern = color; |
116 | } | 143 | } |
117 | 144 | ||
118 | void lcd_set_selector_end(unsigned color) | 145 | void lcd_set_selector_end(unsigned color) |
119 | { | 146 | { |
120 | lse_pattern = color; | 147 | current_vp->lse_pattern = color; |
121 | } | 148 | } |
122 | 149 | ||
123 | void lcd_set_selector_text(unsigned color) | 150 | void lcd_set_selector_text(unsigned color) |
124 | { | 151 | { |
125 | lst_pattern = color; | 152 | current_vp->lst_pattern = color; |
126 | } | 153 | } |
127 | 154 | ||
128 | void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) | 155 | void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) |
129 | { | 156 | { |
130 | lcd_set_drawmode(mode); | 157 | lcd_set_drawmode(mode); |
131 | fg_pattern = fg_color; | 158 | current_vp->fg_pattern = fg_color; |
132 | bg_pattern = bg_color; | 159 | current_vp->bg_pattern = bg_color; |
133 | } | 160 | } |
134 | 161 | ||
135 | void lcd_setmargins(int x, int y) | 162 | void lcd_setmargins(int x, int y) |
136 | { | 163 | { |
137 | xmargin = x; | 164 | current_vp->xmargin = x; |
138 | ymargin = y; | 165 | current_vp->ymargin = y; |
166 | } | ||
167 | |||
168 | int lcd_getwidth(void) | ||
169 | { | ||
170 | return current_vp->width; | ||
171 | } | ||
172 | |||
173 | int lcd_getheight(void) | ||
174 | { | ||
175 | return current_vp->height; | ||
139 | } | 176 | } |
140 | 177 | ||
141 | int lcd_getxmargin(void) | 178 | int lcd_getxmargin(void) |
142 | { | 179 | { |
143 | return xmargin; | 180 | return current_vp->xmargin; |
144 | } | 181 | } |
145 | 182 | ||
146 | int lcd_getymargin(void) | 183 | int lcd_getymargin(void) |
147 | { | 184 | { |
148 | return ymargin; | 185 | return current_vp->ymargin; |
149 | } | 186 | } |
150 | 187 | ||
151 | void lcd_setfont(int newfont) | 188 | void lcd_setfont(int newfont) |
152 | { | 189 | { |
153 | curfont = newfont; | 190 | current_vp->font = newfont; |
154 | } | 191 | } |
155 | 192 | ||
156 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 193 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) |
157 | { | 194 | { |
158 | return font_getstringsize(str, w, h, curfont); | 195 | return font_getstringsize(str, w, h, current_vp->font); |
159 | } | 196 | } |
160 | 197 | ||
161 | /*** low-level drawing functions ***/ | 198 | /*** low-level drawing functions ***/ |
@@ -165,13 +202,13 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h) | |||
165 | static void setpixel(fb_data *address) ICODE_ATTR; | 202 | static void setpixel(fb_data *address) ICODE_ATTR; |
166 | static void setpixel(fb_data *address) | 203 | static void setpixel(fb_data *address) |
167 | { | 204 | { |
168 | *address = fg_pattern; | 205 | *address = current_vp->fg_pattern; |
169 | } | 206 | } |
170 | 207 | ||
171 | static void clearpixel(fb_data *address) ICODE_ATTR; | 208 | static void clearpixel(fb_data *address) ICODE_ATTR; |
172 | static void clearpixel(fb_data *address) | 209 | static void clearpixel(fb_data *address) |
173 | { | 210 | { |
174 | *address = bg_pattern; | 211 | *address = current_vp->bg_pattern; |
175 | } | 212 | } |
176 | 213 | ||
177 | static void clearimgpixel(fb_data *address) ICODE_ATTR; | 214 | static void clearimgpixel(fb_data *address) ICODE_ATTR; |
@@ -226,31 +263,74 @@ fb_data* lcd_get_backdrop(void) | |||
226 | 263 | ||
227 | /*** drawing functions ***/ | 264 | /*** drawing functions ***/ |
228 | 265 | ||
229 | /* Clear the whole display */ | 266 | /* Clear the current viewport */ |
230 | void lcd_clear_display(void) | 267 | void lcd_clear_viewport(void) |
231 | { | 268 | { |
232 | fb_data *dst = LCDADDR(0, 0); | 269 | fb_data *dst, *dst_end; |
270 | |||
271 | dst = LCDADDR(current_vp->x, current_vp->y); | ||
272 | dst_end = dst + current_vp->height * LCD_WIDTH; | ||
233 | 273 | ||
234 | if (drawmode & DRMODE_INVERSEVID) | 274 | if (current_vp->drawmode & DRMODE_INVERSEVID) |
235 | { | 275 | { |
236 | memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT); | 276 | do |
277 | { | ||
278 | memset16(dst, current_vp->fg_pattern, current_vp->width); | ||
279 | dst += LCD_WIDTH; | ||
280 | } | ||
281 | while (dst < dst_end); | ||
237 | } | 282 | } |
238 | else | 283 | else |
239 | { | 284 | { |
240 | if (!lcd_backdrop) | 285 | if (!lcd_backdrop) |
241 | memset16(dst, bg_pattern, LCD_WIDTH*LCD_HEIGHT); | 286 | { |
287 | do | ||
288 | { | ||
289 | memset16(dst, current_vp->bg_pattern, current_vp->width); | ||
290 | dst += LCD_WIDTH; | ||
291 | } | ||
292 | while (dst < dst_end); | ||
293 | } | ||
242 | else | 294 | else |
243 | memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); | 295 | { |
296 | do | ||
297 | { | ||
298 | memcpy(dst, (void *)((long)dst + lcd_backdrop_offset), | ||
299 | current_vp->width * sizeof(fb_data)); | ||
300 | dst += LCD_WIDTH; | ||
301 | } | ||
302 | while (dst < dst_end); | ||
303 | } | ||
244 | } | 304 | } |
245 | 305 | ||
246 | lcd_scroll_info.lines = 0; | 306 | if (current_vp == &default_vp) |
307 | { | ||
308 | lcd_scroll_info.lines = 0; | ||
309 | } | ||
310 | else | ||
311 | { | ||
312 | lcd_scroll_stop(current_vp); | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* Clear the whole display */ | ||
317 | void lcd_clear_display(void) | ||
318 | { | ||
319 | struct viewport* old_vp = current_vp; | ||
320 | |||
321 | current_vp = &default_vp; | ||
322 | |||
323 | lcd_clear_viewport(); | ||
324 | |||
325 | current_vp = old_vp; | ||
247 | } | 326 | } |
248 | 327 | ||
249 | /* Set a single pixel */ | 328 | /* Set a single pixel */ |
250 | void lcd_drawpixel(int x, int y) | 329 | void lcd_drawpixel(int x, int y) |
251 | { | 330 | { |
252 | if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) | 331 | if (((unsigned)x < (unsigned)current_vp->width) && |
253 | lcd_fastpixelfuncs[drawmode](LCDADDR(x, y)); | 332 | ((unsigned)y < (unsigned)current_vp->height)) |
333 | lcd_fastpixelfuncs[current_vp->drawmode](LCDADDR(current_vp->x+x, current_vp->y+y)); | ||
254 | } | 334 | } |
255 | 335 | ||
256 | /* Draw a line */ | 336 | /* Draw a line */ |
@@ -262,7 +342,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
262 | int d, dinc1, dinc2; | 342 | int d, dinc1, dinc2; |
263 | int x, xinc1, xinc2; | 343 | int x, xinc1, xinc2; |
264 | int y, yinc1, yinc2; | 344 | int y, yinc1, yinc2; |
265 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; | 345 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; |
266 | 346 | ||
267 | deltax = abs(x2 - x1); | 347 | deltax = abs(x2 - x1); |
268 | deltay = abs(y2 - y1); | 348 | deltay = abs(y2 - y1); |
@@ -306,8 +386,8 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
306 | 386 | ||
307 | for (i = 0; i < numpixels; i++) | 387 | for (i = 0; i < numpixels; i++) |
308 | { | 388 | { |
309 | if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) | 389 | if (((unsigned)x < (unsigned)current_vp->width) && ((unsigned)y < (unsigned)current_vp->height)) |
310 | pfunc(LCDADDR(x, y)); | 390 | pfunc(LCDADDR(x + current_vp->x, y + current_vp->y)); |
311 | 391 | ||
312 | if (d < 0) | 392 | if (d < 0) |
313 | { | 393 | { |
@@ -331,7 +411,7 @@ void lcd_hline(int x1, int x2, int y) | |||
331 | unsigned bits = 0; | 411 | unsigned bits = 0; |
332 | enum fill_opt fillopt = OPT_NONE; | 412 | enum fill_opt fillopt = OPT_NONE; |
333 | fb_data *dst, *dst_end; | 413 | fb_data *dst, *dst_end; |
334 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; | 414 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; |
335 | 415 | ||
336 | /* direction flip */ | 416 | /* direction flip */ |
337 | if (x2 < x1) | 417 | if (x2 < x1) |
@@ -342,23 +422,31 @@ void lcd_hline(int x1, int x2, int y) | |||
342 | } | 422 | } |
343 | 423 | ||
344 | /* nothing to draw? */ | 424 | /* nothing to draw? */ |
345 | if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) | 425 | if (((unsigned)y >= (unsigned)current_vp->height) || |
426 | (x1 >= current_vp->width) || | ||
427 | (x2 < 0)) | ||
346 | return; | 428 | return; |
347 | 429 | ||
348 | /* clipping */ | 430 | /* clipping */ |
349 | if (x1 < 0) | 431 | if (x1 < 0) |
350 | x1 = 0; | 432 | x1 = 0; |
351 | if (x2 >= LCD_WIDTH) | 433 | if (x2 >= current_vp->width) |
352 | x2 = LCD_WIDTH-1; | 434 | x2 = current_vp->width-1; |
435 | |||
436 | width = x2 - x1 + 1; | ||
353 | 437 | ||
354 | if (drawmode & DRMODE_INVERSEVID) | 438 | /* Adjust x1 and y to viewport */ |
439 | x1 += current_vp->x; | ||
440 | y += current_vp->y; | ||
441 | |||
442 | if (current_vp->drawmode & DRMODE_INVERSEVID) | ||
355 | { | 443 | { |
356 | if (drawmode & DRMODE_BG) | 444 | if (current_vp->drawmode & DRMODE_BG) |
357 | { | 445 | { |
358 | if (!lcd_backdrop) | 446 | if (!lcd_backdrop) |
359 | { | 447 | { |
360 | fillopt = OPT_SET; | 448 | fillopt = OPT_SET; |
361 | bits = bg_pattern; | 449 | bits = current_vp->bg_pattern; |
362 | } | 450 | } |
363 | else | 451 | else |
364 | fillopt = OPT_COPY; | 452 | fillopt = OPT_COPY; |
@@ -366,14 +454,13 @@ void lcd_hline(int x1, int x2, int y) | |||
366 | } | 454 | } |
367 | else | 455 | else |
368 | { | 456 | { |
369 | if (drawmode & DRMODE_FG) | 457 | if (current_vp->drawmode & DRMODE_FG) |
370 | { | 458 | { |
371 | fillopt = OPT_SET; | 459 | fillopt = OPT_SET; |
372 | bits = fg_pattern; | 460 | bits = current_vp->fg_pattern; |
373 | } | 461 | } |
374 | } | 462 | } |
375 | dst = LCDADDR(x1, y); | 463 | dst = LCDADDR(x1, y); |
376 | width = x2 - x1 + 1; | ||
377 | 464 | ||
378 | switch (fillopt) | 465 | switch (fillopt) |
379 | { | 466 | { |
@@ -400,7 +487,7 @@ void lcd_vline(int x, int y1, int y2) | |||
400 | { | 487 | { |
401 | int y; | 488 | int y; |
402 | fb_data *dst, *dst_end; | 489 | fb_data *dst, *dst_end; |
403 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; | 490 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; |
404 | 491 | ||
405 | /* direction flip */ | 492 | /* direction flip */ |
406 | if (y2 < y1) | 493 | if (y2 < y1) |
@@ -411,16 +498,18 @@ void lcd_vline(int x, int y1, int y2) | |||
411 | } | 498 | } |
412 | 499 | ||
413 | /* nothing to draw? */ | 500 | /* nothing to draw? */ |
414 | if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) | 501 | if ((x >= current_vp->width) || |
502 | (y1 >= current_vp->height) || | ||
503 | (y2 < 0)) | ||
415 | return; | 504 | return; |
416 | 505 | ||
417 | /* clipping */ | 506 | /* clipping */ |
418 | if (y1 < 0) | 507 | if (y1 < 0) |
419 | y1 = 0; | 508 | y1 = 0; |
420 | if (y2 >= LCD_HEIGHT) | 509 | if (y2 >= current_vp->height) |
421 | y2 = LCD_HEIGHT-1; | 510 | y2 = current_vp->height-1; |
422 | 511 | ||
423 | dst = LCDADDR(x, y1); | 512 | dst = LCDADDR(x + current_vp->x, y1 + current_vp->y); |
424 | dst_end = dst + (y2 - y1) * LCD_WIDTH; | 513 | dst_end = dst + (y2 - y1) * LCD_WIDTH; |
425 | 514 | ||
426 | do | 515 | do |
@@ -452,11 +541,11 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
452 | unsigned bits = 0; | 541 | unsigned bits = 0; |
453 | enum fill_opt fillopt = OPT_NONE; | 542 | enum fill_opt fillopt = OPT_NONE; |
454 | fb_data *dst, *dst_end; | 543 | fb_data *dst, *dst_end; |
455 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; | 544 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; |
456 | 545 | ||
457 | /* nothing to draw? */ | 546 | /* nothing to draw? */ |
458 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 547 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
459 | || (x + width <= 0) || (y + height <= 0)) | 548 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
460 | return; | 549 | return; |
461 | 550 | ||
462 | /* clipping */ | 551 | /* clipping */ |
@@ -470,19 +559,19 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
470 | height += y; | 559 | height += y; |
471 | y = 0; | 560 | y = 0; |
472 | } | 561 | } |
473 | if (x + width > LCD_WIDTH) | 562 | if (x + width > current_vp->width) |
474 | width = LCD_WIDTH - x; | 563 | width = current_vp->width - x; |
475 | if (y + height > LCD_HEIGHT) | 564 | if (y + height > current_vp->height) |
476 | height = LCD_HEIGHT - y; | 565 | height = current_vp->height - y; |
477 | 566 | ||
478 | if (drawmode & DRMODE_INVERSEVID) | 567 | if (current_vp->drawmode & DRMODE_INVERSEVID) |
479 | { | 568 | { |
480 | if (drawmode & DRMODE_BG) | 569 | if (current_vp->drawmode & DRMODE_BG) |
481 | { | 570 | { |
482 | if (!lcd_backdrop) | 571 | if (!lcd_backdrop) |
483 | { | 572 | { |
484 | fillopt = OPT_SET; | 573 | fillopt = OPT_SET; |
485 | bits = bg_pattern; | 574 | bits = current_vp->bg_pattern; |
486 | } | 575 | } |
487 | else | 576 | else |
488 | fillopt = OPT_COPY; | 577 | fillopt = OPT_COPY; |
@@ -490,13 +579,13 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
490 | } | 579 | } |
491 | else | 580 | else |
492 | { | 581 | { |
493 | if (drawmode & DRMODE_FG) | 582 | if (current_vp->drawmode & DRMODE_FG) |
494 | { | 583 | { |
495 | fillopt = OPT_SET; | 584 | fillopt = OPT_SET; |
496 | bits = fg_pattern; | 585 | bits = current_vp->fg_pattern; |
497 | } | 586 | } |
498 | } | 587 | } |
499 | dst = LCDADDR(x, y); | 588 | dst = LCDADDR(current_vp->x + x, current_vp->y + y); |
500 | dst_end = dst + height * LCD_WIDTH; | 589 | dst_end = dst + height * LCD_WIDTH; |
501 | 590 | ||
502 | do | 591 | do |
@@ -530,24 +619,28 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
530 | /* Fill a rectangle with a gradient */ | 619 | /* Fill a rectangle with a gradient */ |
531 | void lcd_gradient_rect(int x1, int x2, int y, int h) | 620 | void lcd_gradient_rect(int x1, int x2, int y, int h) |
532 | { | 621 | { |
622 | int old_pattern = current_vp->fg_pattern; | ||
623 | |||
533 | if (h == 0) return; | 624 | if (h == 0) return; |
534 | 625 | ||
535 | int h_r = RGB_UNPACK_RED(lss_pattern) << 16; | 626 | int h_r = RGB_UNPACK_RED(current_vp->lss_pattern) << 16; |
536 | int h_b = RGB_UNPACK_BLUE(lss_pattern) << 16; | 627 | int h_b = RGB_UNPACK_BLUE(current_vp->lss_pattern) << 16; |
537 | int h_g = RGB_UNPACK_GREEN(lss_pattern) << 16; | 628 | int h_g = RGB_UNPACK_GREEN(current_vp->lss_pattern) << 16; |
538 | int rstep = (h_r - ((signed)RGB_UNPACK_RED(lse_pattern) << 16)) / h; | 629 | int rstep = (h_r - ((signed)RGB_UNPACK_RED(current_vp->lse_pattern) << 16)) / h; |
539 | int gstep = (h_g - ((signed)RGB_UNPACK_GREEN(lse_pattern) << 16)) / h; | 630 | int gstep = (h_g - ((signed)RGB_UNPACK_GREEN(current_vp->lse_pattern) << 16)) / h; |
540 | int bstep = (h_b - ((signed)RGB_UNPACK_BLUE(lse_pattern) << 16)) / h; | 631 | int bstep = (h_b - ((signed)RGB_UNPACK_BLUE(current_vp->lse_pattern) << 16)) / h; |
541 | int count; | 632 | int count; |
542 | 633 | ||
543 | fg_pattern = lss_pattern; | 634 | current_vp->fg_pattern = current_vp->lss_pattern; |
544 | for(count = 0; count < h; count++) { | 635 | for(count = 0; count < h; count++) { |
545 | lcd_hline(x1, x2, y + count); | 636 | lcd_hline(x1, x2, y + count); |
546 | h_r -= rstep; | 637 | h_r -= rstep; |
547 | h_g -= gstep; | 638 | h_g -= gstep; |
548 | h_b -= bstep; | 639 | h_b -= bstep; |
549 | fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); | 640 | current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); |
550 | } | 641 | } |
642 | |||
643 | current_vp->fg_pattern = old_pattern; | ||
551 | } | 644 | } |
552 | 645 | ||
553 | #define H_COLOR(lss, lse, cur_line, max_line) \ | 646 | #define H_COLOR(lss, lse, cur_line, max_line) \ |
@@ -562,14 +655,14 @@ void lcd_gradient_rect_scroll(int x1, int x2, int y, int h, | |||
562 | { | 655 | { |
563 | if (h == 0 || num_lines == 0) return; | 656 | if (h == 0 || num_lines == 0) return; |
564 | 657 | ||
565 | unsigned tmp_lss = lss_pattern; | 658 | unsigned tmp_lss = current_vp->lss_pattern; |
566 | unsigned tmp_lse = lse_pattern; | 659 | unsigned tmp_lse = current_vp->lse_pattern; |
567 | int lss_r = (signed)RGB_UNPACK_RED(lss_pattern); | 660 | int lss_r = (signed)RGB_UNPACK_RED(current_vp->lss_pattern); |
568 | int lss_b = (signed)RGB_UNPACK_BLUE(lss_pattern); | 661 | int lss_b = (signed)RGB_UNPACK_BLUE(current_vp->lss_pattern); |
569 | int lss_g = (signed)RGB_UNPACK_GREEN(lss_pattern); | 662 | int lss_g = (signed)RGB_UNPACK_GREEN(current_vp->lss_pattern); |
570 | int lse_r = (signed)RGB_UNPACK_RED(lse_pattern); | 663 | int lse_r = (signed)RGB_UNPACK_RED(current_vp->lse_pattern); |
571 | int lse_b = (signed)RGB_UNPACK_BLUE(lse_pattern); | 664 | int lse_b = (signed)RGB_UNPACK_BLUE(current_vp->lse_pattern); |
572 | int lse_g = (signed)RGB_UNPACK_GREEN(lse_pattern); | 665 | int lse_g = (signed)RGB_UNPACK_GREEN(current_vp->lse_pattern); |
573 | 666 | ||
574 | int h_r = H_COLOR(lss_r, lse_r, cur_line, num_lines); | 667 | int h_r = H_COLOR(lss_r, lse_r, cur_line, num_lines); |
575 | int h_g = H_COLOR(lss_g, lse_g, cur_line, num_lines); | 668 | int h_g = H_COLOR(lss_g, lse_g, cur_line, num_lines); |
@@ -583,8 +676,8 @@ void lcd_gradient_rect_scroll(int x1, int x2, int y, int h, | |||
583 | 676 | ||
584 | lcd_gradient_rect(x1, x2, y, h); | 677 | lcd_gradient_rect(x1, x2, y, h); |
585 | 678 | ||
586 | lcd_set_selector_start(tmp_lss); | 679 | current_vp->lss_pattern = tmp_lss; |
587 | lcd_set_selector_end(tmp_lse); | 680 | current_vp->lse_pattern = tmp_lse; |
588 | } | 681 | } |
589 | 682 | ||
590 | /* About Rockbox' internal monochrome bitmap format: | 683 | /* About Rockbox' internal monochrome bitmap format: |
@@ -613,8 +706,8 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
613 | lcd_fastpixelfunc_type *fgfunc, *bgfunc; | 706 | lcd_fastpixelfunc_type *fgfunc, *bgfunc; |
614 | 707 | ||
615 | /* nothing to draw? */ | 708 | /* nothing to draw? */ |
616 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 709 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
617 | || (x + width <= 0) || (y + height <= 0)) | 710 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
618 | return; | 711 | return; |
619 | 712 | ||
620 | /* clipping */ | 713 | /* clipping */ |
@@ -630,20 +723,20 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
630 | src_y -= y; | 723 | src_y -= y; |
631 | y = 0; | 724 | y = 0; |
632 | } | 725 | } |
633 | if (x + width > LCD_WIDTH) | 726 | if (x + width > current_vp->width) |
634 | width = LCD_WIDTH - x; | 727 | width = current_vp->width - x; |
635 | if (y + height > LCD_HEIGHT) | 728 | if (y + height > current_vp->height) |
636 | height = LCD_HEIGHT - y; | 729 | height = current_vp->height - y; |
637 | 730 | ||
638 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 731 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
639 | src_y &= 7; | 732 | src_y &= 7; |
640 | src_end = src + width; | 733 | src_end = src + width; |
641 | 734 | ||
642 | dst = LCDADDR(x, y); | 735 | dst = LCDADDR(current_vp->x + x, current_vp->y + y); |
643 | has_backdrop = (lcd_backdrop != NULL); | 736 | has_backdrop = (lcd_backdrop != NULL); |
644 | backdrop = lcd_backdrop + y * LCD_WIDTH + x; | 737 | backdrop = lcd_backdrop + (current_vp->y + y) * LCD_WIDTH + current_vp->x + x; |
645 | fgfunc = lcd_fastpixelfuncs[drawmode]; | 738 | fgfunc = lcd_fastpixelfuncs[current_vp->drawmode]; |
646 | bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID]; | 739 | bgfunc = lcd_fastpixelfuncs[current_vp->drawmode ^ DRMODE_INVERSEVID]; |
647 | do | 740 | do |
648 | { | 741 | { |
649 | const unsigned char *src_col = src++; | 742 | const unsigned char *src_col = src++; |
@@ -654,23 +747,23 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
654 | dst_end = dst_col + height * LCD_WIDTH; | 747 | dst_end = dst_col + height * LCD_WIDTH; |
655 | do | 748 | do |
656 | { | 749 | { |
657 | switch (drawmode) | 750 | switch (current_vp->drawmode) |
658 | { | 751 | { |
659 | case DRMODE_SOLID: | 752 | case DRMODE_SOLID: |
660 | if (data & 0x01) | 753 | if (data & 0x01) |
661 | *dst_col = fg_pattern; | 754 | *dst_col = current_vp->fg_pattern; |
662 | else | 755 | else |
663 | *dst_col = has_backdrop ? *backdrop_col : bg_pattern; | 756 | *dst_col = has_backdrop ? *backdrop_col : current_vp->bg_pattern; |
664 | break; | 757 | break; |
665 | case DRMODE_FG: | 758 | case DRMODE_FG: |
666 | if (data & 0x01) | 759 | if (data & 0x01) |
667 | *dst_col = fg_pattern; | 760 | *dst_col = current_vp->fg_pattern; |
668 | break; | 761 | break; |
669 | case (DRMODE_SOLID|DRMODE_INVERSEVID): | 762 | case (DRMODE_SOLID|DRMODE_INVERSEVID): |
670 | if (data & 0x01) | 763 | if (data & 0x01) |
671 | *dst_col = has_backdrop ? *backdrop_col : bg_pattern; | 764 | *dst_col = has_backdrop ? *backdrop_col : current_vp->bg_pattern; |
672 | else | 765 | else |
673 | *dst_col = fg_pattern; | 766 | *dst_col = current_vp->fg_pattern; |
674 | break; | 767 | break; |
675 | default: | 768 | default: |
676 | if (data & 0x01) | 769 | if (data & 0x01) |
@@ -709,8 +802,8 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
709 | fb_data *dst, *dst_end; | 802 | fb_data *dst, *dst_end; |
710 | 803 | ||
711 | /* nothing to draw? */ | 804 | /* nothing to draw? */ |
712 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 805 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
713 | || (x + width <= 0) || (y + height <= 0)) | 806 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
714 | return; | 807 | return; |
715 | 808 | ||
716 | /* clipping */ | 809 | /* clipping */ |
@@ -726,13 +819,13 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
726 | src_y -= y; | 819 | src_y -= y; |
727 | y = 0; | 820 | y = 0; |
728 | } | 821 | } |
729 | if (x + width > LCD_WIDTH) | 822 | if (x + width > current_vp->width) |
730 | width = LCD_WIDTH - x; | 823 | width = current_vp->width - x; |
731 | if (y + height > LCD_HEIGHT) | 824 | if (y + height > current_vp->height) |
732 | height = LCD_HEIGHT - y; | 825 | height = current_vp->height - y; |
733 | 826 | ||
734 | src += stride * src_y + src_x; /* move starting point */ | 827 | src += stride * src_y + src_x; /* move starting point */ |
735 | dst = LCDADDR(x, y); | 828 | dst = LCDADDR(current_vp->x + x, current_vp->y + y); |
736 | dst_end = dst + height * LCD_WIDTH; | 829 | dst_end = dst + height * LCD_WIDTH; |
737 | 830 | ||
738 | do | 831 | do |
@@ -763,8 +856,8 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | |||
763 | fb_data *dst, *dst_end; | 856 | fb_data *dst, *dst_end; |
764 | 857 | ||
765 | /* nothing to draw? */ | 858 | /* nothing to draw? */ |
766 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 859 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
767 | || (x + width <= 0) || (y + height <= 0)) | 860 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
768 | return; | 861 | return; |
769 | 862 | ||
770 | /* clipping */ | 863 | /* clipping */ |
@@ -780,13 +873,13 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | |||
780 | src_y -= y; | 873 | src_y -= y; |
781 | y = 0; | 874 | y = 0; |
782 | } | 875 | } |
783 | if (x + width > LCD_WIDTH) | 876 | if (x + width > current_vp->width) |
784 | width = LCD_WIDTH - x; | 877 | width = current_vp->width - x; |
785 | if (y + height > LCD_HEIGHT) | 878 | if (y + height > current_vp->height) |
786 | height = LCD_HEIGHT - y; | 879 | height = current_vp->height - y; |
787 | 880 | ||
788 | src += stride * src_y + src_x; /* move starting point */ | 881 | src += stride * src_y + src_x; /* move starting point */ |
789 | dst = LCDADDR(x, y); | 882 | dst = LCDADDR(current_vp->x + x, current_vp->y + y); |
790 | dst_end = dst + height * LCD_WIDTH; | 883 | dst_end = dst + height * LCD_WIDTH; |
791 | 884 | ||
792 | do | 885 | do |
@@ -795,7 +888,7 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | |||
795 | for(i = 0;i < width;i++) | 888 | for(i = 0;i < width;i++) |
796 | { | 889 | { |
797 | if (src[i] == REPLACEWITHFG_COLOR) | 890 | if (src[i] == REPLACEWITHFG_COLOR) |
798 | dst[i] = fg_pattern; | 891 | dst[i] = current_vp->fg_pattern; |
799 | else if(src[i] != TRANSPARENT_COLOR) | 892 | else if(src[i] != TRANSPARENT_COLOR) |
800 | dst[i] = src[i]; | 893 | dst[i] = src[i]; |
801 | } | 894 | } |
@@ -818,11 +911,11 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
818 | { | 911 | { |
819 | unsigned short ch; | 912 | unsigned short ch; |
820 | unsigned short *ucs; | 913 | unsigned short *ucs; |
821 | struct font* pf = font_get(curfont); | 914 | struct font* pf = font_get(current_vp->font); |
822 | 915 | ||
823 | ucs = bidi_l2v(str, 1); | 916 | ucs = bidi_l2v(str, 1); |
824 | 917 | ||
825 | while ((ch = *ucs++) != 0 && x < LCD_WIDTH) | 918 | while ((ch = *ucs++) != 0 && x < current_vp->width) |
826 | { | 919 | { |
827 | int width; | 920 | int width; |
828 | const unsigned char *bits; | 921 | const unsigned char *bits; |
@@ -875,51 +968,51 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, | |||
875 | int offset) | 968 | int offset) |
876 | { | 969 | { |
877 | int xpos,ypos,w,h,xrect; | 970 | int xpos,ypos,w,h,xrect; |
878 | int lastmode = drawmode; | 971 | int lastmode = current_vp->drawmode; |
879 | int oldfgcolor = fg_pattern; | 972 | int oldfgcolor = current_vp->fg_pattern; |
880 | int oldbgcolor = bg_pattern; | 973 | int oldbgcolor = current_vp->bg_pattern; |
881 | 974 | ||
882 | /* make sure scrolling is turned off on the line we are updating */ | 975 | /* make sure scrolling is turned off on the line we are updating */ |
883 | lcd_scroll_info.lines &= ~(1 << y); | 976 | lcd_scroll_stop_line(current_vp, y); |
884 | 977 | ||
885 | if(!str || !str[0]) | 978 | if(!str || !str[0]) |
886 | return; | 979 | return; |
887 | 980 | ||
888 | lcd_getstringsize(str, &w, &h); | 981 | lcd_getstringsize(str, &w, &h); |
889 | xpos = xmargin + x*w / utf8length(str); | 982 | xpos = current_vp->xmargin + x*w / utf8length(str); |
890 | ypos = ymargin + y*h; | 983 | ypos = current_vp->ymargin + y*h; |
891 | drawmode = (style & STYLE_INVERT) ? | 984 | current_vp->drawmode = (style & STYLE_INVERT) ? |
892 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 985 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
893 | if (style & STYLE_COLORED) { | 986 | if (style & STYLE_COLORED) { |
894 | if (drawmode == DRMODE_SOLID) | 987 | if (current_vp->drawmode == DRMODE_SOLID) |
895 | fg_pattern = style & STYLE_COLOR_MASK; | 988 | current_vp->fg_pattern = style & STYLE_COLOR_MASK; |
896 | else | 989 | else |
897 | bg_pattern = style & STYLE_COLOR_MASK; | 990 | current_vp->bg_pattern = style & STYLE_COLOR_MASK; |
898 | } | 991 | } |
899 | drawmode ^= DRMODE_INVERSEVID; | 992 | current_vp->drawmode ^= DRMODE_INVERSEVID; |
900 | xrect = xpos + MAX(w - offset, 0); | 993 | xrect = xpos + MAX(w - offset, 0); |
901 | 994 | ||
902 | if (style & STYLE_GRADIENT) { | 995 | if (style & STYLE_GRADIENT) { |
903 | drawmode = DRMODE_FG; | 996 | current_vp->drawmode = DRMODE_FG; |
904 | if (CURLN_UNPACK(style) == 0) | 997 | if (CURLN_UNPACK(style) == 0) |
905 | lcd_gradient_rect(xpos, LCD_WIDTH, ypos, h*NUMLN_UNPACK(style)); | 998 | lcd_gradient_rect(xpos, current_vp->width, ypos, h*NUMLN_UNPACK(style)); |
906 | fg_pattern = lst_pattern; | 999 | current_vp->fg_pattern = current_vp->lst_pattern; |
907 | } | 1000 | } |
908 | else if (style & STYLE_COLORBAR) { | 1001 | else if (style & STYLE_COLORBAR) { |
909 | drawmode = DRMODE_FG; | 1002 | current_vp->drawmode = DRMODE_FG; |
910 | fg_pattern = lss_pattern; | 1003 | current_vp->fg_pattern = current_vp->lss_pattern; |
911 | lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); | 1004 | lcd_fillrect(xpos, ypos, current_vp->width - xpos, h); |
912 | fg_pattern = lst_pattern; | 1005 | current_vp->fg_pattern = current_vp->lst_pattern; |
913 | } | 1006 | } |
914 | else { | 1007 | else { |
915 | lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h); | 1008 | lcd_fillrect(xrect, ypos, current_vp->width - xrect, h); |
916 | drawmode = (style & STYLE_INVERT) ? | 1009 | current_vp->drawmode = (style & STYLE_INVERT) ? |
917 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 1010 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
918 | } | 1011 | } |
919 | lcd_putsxyofs(xpos, ypos, offset, str); | 1012 | lcd_putsxyofs(xpos, ypos, offset, str); |
920 | drawmode = lastmode; | 1013 | current_vp->drawmode = lastmode; |
921 | fg_pattern = oldfgcolor; | 1014 | current_vp->fg_pattern = oldfgcolor; |
922 | bg_pattern = oldbgcolor; | 1015 | current_vp->bg_pattern = oldbgcolor; |
923 | } | 1016 | } |
924 | 1017 | ||
925 | /*** scrolling ***/ | 1018 | /*** scrolling ***/ |
@@ -938,15 +1031,23 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, int offse | |||
938 | lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); | 1031 | lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); |
939 | } | 1032 | } |
940 | 1033 | ||
1034 | /* Initialise a scrolling line at (x,y) in current viewport */ | ||
1035 | |||
941 | void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | 1036 | void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, |
942 | int style, int offset) | 1037 | int style, int offset) |
943 | { | 1038 | { |
944 | struct scrollinfo* s; | 1039 | struct scrollinfo* s; |
945 | int w, h; | 1040 | int w, h; |
946 | 1041 | ||
947 | if(y>=LCD_SCROLLABLE_LINES) return; | 1042 | if ((unsigned)y >= (unsigned)current_vp->height) |
1043 | return; | ||
1044 | |||
1045 | /* remove any previously scrolling line at the same location */ | ||
1046 | lcd_scroll_stop_line(current_vp, y); | ||
1047 | |||
1048 | if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return; | ||
948 | 1049 | ||
949 | s = &lcd_scroll_info.scroll[y]; | 1050 | s = &lcd_scroll_info.scroll[lcd_scroll_info.lines]; |
950 | 1051 | ||
951 | s->start_tick = current_tick + lcd_scroll_info.delay; | 1052 | s->start_tick = current_tick + lcd_scroll_info.delay; |
952 | s->style = style; | 1053 | s->style = style; |
@@ -954,7 +1055,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
954 | 1055 | ||
955 | lcd_getstringsize(string, &w, &h); | 1056 | lcd_getstringsize(string, &w, &h); |
956 | 1057 | ||
957 | if (LCD_WIDTH - x * 8 - xmargin < w) { | 1058 | if (current_vp->width - x * 8 - current_vp->xmargin < w) { |
958 | /* prepare scroll line */ | 1059 | /* prepare scroll line */ |
959 | char *end; | 1060 | char *end; |
960 | 1061 | ||
@@ -967,7 +1068,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
967 | /* scroll bidirectional or forward only depending on the string | 1068 | /* scroll bidirectional or forward only depending on the string |
968 | width */ | 1069 | width */ |
969 | if ( lcd_scroll_info.bidir_limit ) { | 1070 | if ( lcd_scroll_info.bidir_limit ) { |
970 | s->bidir = s->width < (LCD_WIDTH - xmargin) * | 1071 | s->bidir = s->width < (current_vp->width - current_vp->xmargin) * |
971 | (100 + lcd_scroll_info.bidir_limit) / 100; | 1072 | (100 + lcd_scroll_info.bidir_limit) / 100; |
972 | } | 1073 | } |
973 | else | 1074 | else |
@@ -980,17 +1081,16 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
980 | } | 1081 | } |
981 | 1082 | ||
982 | end = strchr(s->line, '\0'); | 1083 | end = strchr(s->line, '\0'); |
983 | strncpy(end, string, LCD_WIDTH/2); | 1084 | strncpy(end, string, current_vp->width/2); |
984 | 1085 | ||
1086 | s->vp = current_vp; | ||
1087 | s->y = y; | ||
985 | s->len = utf8length(string); | 1088 | s->len = utf8length(string); |
986 | s->offset = offset; | 1089 | s->offset = offset; |
987 | s->startx = xmargin + x * s->width / s->len; | 1090 | s->startx = current_vp->xmargin + x * s->width / s->len; |
988 | s->backward = false; | 1091 | s->backward = false; |
989 | lcd_scroll_info.lines |= (1<<y); | 1092 | lcd_scroll_info.lines++; |
990 | } | 1093 | } |
991 | else | ||
992 | /* force a bit switch-off since it doesn't scroll */ | ||
993 | lcd_scroll_info.lines &= ~(1<<y); | ||
994 | } | 1094 | } |
995 | 1095 | ||
996 | void lcd_scroll_fn(void) | 1096 | void lcd_scroll_fn(void) |
@@ -1000,28 +1100,29 @@ void lcd_scroll_fn(void) | |||
1000 | int index; | 1100 | int index; |
1001 | int xpos, ypos; | 1101 | int xpos, ypos; |
1002 | int lastmode; | 1102 | int lastmode; |
1003 | unsigned old_fgcolor = fg_pattern; | 1103 | unsigned old_fgcolor; |
1004 | unsigned old_bgcolor = bg_pattern; | 1104 | unsigned old_bgcolor; |
1005 | 1105 | struct viewport* old_vp = current_vp; | |
1006 | for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) { | ||
1007 | /* really scroll? */ | ||
1008 | if ((lcd_scroll_info.lines & (1 << index)) == 0) | ||
1009 | continue; | ||
1010 | 1106 | ||
1107 | for ( index = 0; index < lcd_scroll_info.lines; index++ ) { | ||
1011 | s = &lcd_scroll_info.scroll[index]; | 1108 | s = &lcd_scroll_info.scroll[index]; |
1012 | 1109 | ||
1013 | /* check pause */ | 1110 | /* check pause */ |
1014 | if (TIME_BEFORE(current_tick, s->start_tick)) | 1111 | if (TIME_BEFORE(current_tick, s->start_tick)) |
1015 | continue; | 1112 | continue; |
1016 | 1113 | ||
1114 | lcd_set_viewport(s->vp); | ||
1115 | old_fgcolor = current_vp->fg_pattern; | ||
1116 | old_bgcolor = current_vp->bg_pattern; | ||
1117 | |||
1017 | if (s->style&STYLE_COLORED) { | 1118 | if (s->style&STYLE_COLORED) { |
1018 | if (s->style&STYLE_MODE_MASK) { | 1119 | if (s->style&STYLE_MODE_MASK) { |
1019 | fg_pattern = old_fgcolor; | 1120 | current_vp->fg_pattern = old_fgcolor; |
1020 | bg_pattern = s->style&STYLE_COLOR_MASK; | 1121 | current_vp->bg_pattern = s->style&STYLE_COLOR_MASK; |
1021 | } | 1122 | } |
1022 | else { | 1123 | else { |
1023 | fg_pattern = s->style&STYLE_COLOR_MASK; | 1124 | current_vp->fg_pattern = s->style&STYLE_COLOR_MASK; |
1024 | bg_pattern = old_bgcolor; | 1125 | current_vp->bg_pattern = old_bgcolor; |
1025 | } | 1126 | } |
1026 | } | 1127 | } |
1027 | 1128 | ||
@@ -1030,9 +1131,9 @@ void lcd_scroll_fn(void) | |||
1030 | else | 1131 | else |
1031 | s->offset += lcd_scroll_info.step; | 1132 | s->offset += lcd_scroll_info.step; |
1032 | 1133 | ||
1033 | pf = font_get(curfont); | 1134 | pf = font_get(current_vp->font); |
1034 | xpos = s->startx; | 1135 | xpos = s->startx; |
1035 | ypos = ymargin + index * pf->height; | 1136 | ypos = current_vp->ymargin + s->y * pf->height; |
1036 | 1137 | ||
1037 | if (s->bidir) { /* scroll bidirectional */ | 1138 | if (s->bidir) { /* scroll bidirectional */ |
1038 | if (s->offset <= 0) { | 1139 | if (s->offset <= 0) { |
@@ -1041,9 +1142,9 @@ void lcd_scroll_fn(void) | |||
1041 | s->backward = false; | 1142 | s->backward = false; |
1042 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | 1143 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; |
1043 | } | 1144 | } |
1044 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { | 1145 | if (s->offset >= s->width - (current_vp->width - xpos)) { |
1045 | /* at end of line */ | 1146 | /* at end of line */ |
1046 | s->offset = s->width - (LCD_WIDTH - xpos); | 1147 | s->offset = s->width - (current_vp->width - xpos); |
1047 | s->backward = true; | 1148 | s->backward = true; |
1048 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | 1149 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; |
1049 | } | 1150 | } |
@@ -1054,35 +1155,36 @@ void lcd_scroll_fn(void) | |||
1054 | s->offset %= s->width; | 1155 | s->offset %= s->width; |
1055 | } | 1156 | } |
1056 | 1157 | ||
1057 | lastmode = drawmode; | 1158 | lastmode = current_vp->drawmode; |
1058 | switch (s->style&STYLE_MODE_MASK) { | 1159 | switch (s->style&STYLE_MODE_MASK) { |
1059 | case STYLE_INVERT: | 1160 | case STYLE_INVERT: |
1060 | drawmode = DRMODE_SOLID|DRMODE_INVERSEVID; | 1161 | current_vp->drawmode = DRMODE_SOLID|DRMODE_INVERSEVID; |
1061 | break; | 1162 | break; |
1062 | case STYLE_COLORBAR: | 1163 | case STYLE_COLORBAR: |
1063 | /* Solid colour line selector */ | 1164 | /* Solid colour line selector */ |
1064 | drawmode = DRMODE_FG; | 1165 | current_vp->drawmode = DRMODE_FG; |
1065 | fg_pattern = lss_pattern; | 1166 | current_vp->fg_pattern = current_vp->lss_pattern; |
1066 | lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 1167 | lcd_fillrect(xpos, ypos, current_vp->width - xpos, pf->height); |
1067 | fg_pattern = lst_pattern; | 1168 | current_vp->fg_pattern = current_vp->lst_pattern; |
1068 | break; | 1169 | break; |
1069 | case STYLE_GRADIENT: | 1170 | case STYLE_GRADIENT: |
1070 | /* Gradient line selector */ | 1171 | /* Gradient line selector */ |
1071 | drawmode = DRMODE_FG; | 1172 | current_vp->drawmode = DRMODE_FG; |
1072 | lcd_gradient_rect_scroll(xpos, LCD_WIDTH, ypos, (signed)pf->height, | 1173 | lcd_gradient_rect_scroll(xpos, current_vp->width, ypos, (signed)pf->height, |
1073 | NUMLN_UNPACK(s->style), | 1174 | NUMLN_UNPACK(s->style), |
1074 | CURLN_UNPACK(s->style)); | 1175 | CURLN_UNPACK(s->style)); |
1075 | fg_pattern = lst_pattern; | 1176 | current_vp->fg_pattern = current_vp->lst_pattern; |
1076 | break; | 1177 | break; |
1077 | default: | 1178 | default: |
1078 | drawmode = DRMODE_SOLID; | 1179 | current_vp->drawmode = DRMODE_SOLID; |
1079 | break; | 1180 | break; |
1080 | } | 1181 | } |
1081 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 1182 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); |
1082 | drawmode = lastmode; | 1183 | current_vp->drawmode = lastmode; |
1083 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 1184 | current_vp->fg_pattern = old_fgcolor; |
1185 | current_vp->bg_pattern = old_bgcolor; | ||
1186 | lcd_update_viewport_rect(xpos, ypos, current_vp->width - xpos, pf->height); | ||
1084 | } | 1187 | } |
1085 | 1188 | ||
1086 | fg_pattern = old_fgcolor; | 1189 | lcd_set_viewport(old_vp); |
1087 | bg_pattern = old_bgcolor; | ||
1088 | } | 1190 | } |