diff options
author | Dave Chapman <dave@dchapman.com> | 2008-01-07 20:34:11 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2008-01-07 20:34:11 +0000 |
commit | 945c8a221ade41c462a93f8452320a806e5645b3 (patch) | |
tree | 2a17823e286e6252e60c44c7f4753d5c18ef5172 /firmware/drivers/lcd-remote-1bit-v.c | |
parent | 2a8f39820b49f116820356c2ca224f82f2106c21 (diff) | |
download | rockbox-945c8a221ade41c462a93f8452320a806e5645b3.tar.gz rockbox-945c8a221ade41c462a93f8452320a806e5645b3.zip |
Add viewport capabilities to all the LCD drivers, and adapt scrolling code. This is the firmware/ part of FS#8385 - the changes to the WPS code still need more work and will be committed at a later date. NOTE: There are no user-visible changes with this commit - just the infrastructure.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16018 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-remote-1bit-v.c')
-rw-r--r-- | firmware/drivers/lcd-remote-1bit-v.c | 260 |
1 files changed, 178 insertions, 82 deletions
diff --git a/firmware/drivers/lcd-remote-1bit-v.c b/firmware/drivers/lcd-remote-1bit-v.c index 9bfbf580d9..a33648b76a 100644 --- a/firmware/drivers/lcd-remote-1bit-v.c +++ b/firmware/drivers/lcd-remote-1bit-v.c | |||
@@ -38,47 +38,88 @@ | |||
38 | fb_remote_data lcd_remote_framebuffer[LCD_REMOTE_FBHEIGHT][LCD_REMOTE_FBWIDTH] | 38 | fb_remote_data lcd_remote_framebuffer[LCD_REMOTE_FBHEIGHT][LCD_REMOTE_FBWIDTH] |
39 | IBSS_ATTR; | 39 | IBSS_ATTR; |
40 | 40 | ||
41 | static int drawmode = DRMODE_SOLID; | 41 | static struct viewport default_vp = |
42 | static int xmargin = 0; | 42 | { |
43 | static int ymargin = 0; | 43 | .x = 0, |
44 | static int curfont = FONT_SYSFIXED; | 44 | .y = 0, |
45 | .width = LCD_REMOTE_WIDTH, | ||
46 | .height = LCD_REMOTE_HEIGHT, | ||
47 | .font = FONT_SYSFIXED, | ||
48 | .drawmode = DRMODE_SOLID, | ||
49 | .xmargin = 0, | ||
50 | .ymargin = 0, | ||
51 | }; | ||
52 | |||
53 | static struct viewport* current_vp IDATA_ATTR = &default_vp; | ||
54 | |||
55 | /*** Viewports ***/ | ||
56 | |||
57 | void lcd_remote_set_viewport(struct viewport* vp) | ||
58 | { | ||
59 | if (vp == NULL) | ||
60 | current_vp = &default_vp; | ||
61 | else | ||
62 | current_vp = vp; | ||
63 | } | ||
64 | |||
65 | void lcd_remote_update_viewport(void) | ||
66 | { | ||
67 | lcd_remote_update_rect(current_vp->x, current_vp->y, | ||
68 | current_vp->width, current_vp->height); | ||
69 | } | ||
70 | |||
71 | void lcd_remote_update_viewport_rect(int x, int y, int width, int height) | ||
72 | { | ||
73 | lcd_remote_update_rect(current_vp->x + x, current_vp->y + y, width, height); | ||
74 | } | ||
75 | |||
45 | 76 | ||
46 | /*** parameter handling ***/ | 77 | /*** parameter handling ***/ |
47 | 78 | ||
48 | void lcd_remote_set_drawmode(int mode) | 79 | void lcd_remote_set_drawmode(int mode) |
49 | { | 80 | { |
50 | drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | 81 | current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); |
51 | } | 82 | } |
52 | 83 | ||
53 | int lcd_remote_get_drawmode(void) | 84 | int lcd_remote_get_drawmode(void) |
54 | { | 85 | { |
55 | return drawmode; | 86 | return current_vp->drawmode; |
56 | } | 87 | } |
57 | 88 | ||
58 | void lcd_remote_setmargins(int x, int y) | 89 | void lcd_remote_setmargins(int x, int y) |
59 | { | 90 | { |
60 | xmargin = x; | 91 | current_vp->xmargin = x; |
61 | ymargin = y; | 92 | current_vp->ymargin = y; |
93 | } | ||
94 | |||
95 | int lcd_remote_getwidth(void) | ||
96 | { | ||
97 | return current_vp->width; | ||
98 | } | ||
99 | |||
100 | int lcd_remote_getheight(void) | ||
101 | { | ||
102 | return current_vp->height; | ||
62 | } | 103 | } |
63 | 104 | ||
64 | int lcd_remote_getxmargin(void) | 105 | int lcd_remote_getxmargin(void) |
65 | { | 106 | { |
66 | return xmargin; | 107 | return current_vp->xmargin; |
67 | } | 108 | } |
68 | 109 | ||
69 | int lcd_remote_getymargin(void) | 110 | int lcd_remote_getymargin(void) |
70 | { | 111 | { |
71 | return ymargin; | 112 | return current_vp->ymargin; |
72 | } | 113 | } |
73 | 114 | ||
74 | void lcd_remote_setfont(int newfont) | 115 | void lcd_remote_setfont(int newfont) |
75 | { | 116 | { |
76 | curfont = newfont; | 117 | current_vp->font = newfont; |
77 | } | 118 | } |
78 | 119 | ||
79 | int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) | 120 | int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) |
80 | { | 121 | { |
81 | return font_getstringsize(str, w, h, curfont); | 122 | return font_getstringsize(str, w, h, current_vp->font); |
82 | } | 123 | } |
83 | 124 | ||
84 | /*** low-level drawing functions ***/ | 125 | /*** low-level drawing functions ***/ |
@@ -181,17 +222,44 @@ lcd_remote_blockfunc_type* const lcd_remote_blockfuncs[8] = { | |||
181 | /* Clear the whole display */ | 222 | /* Clear the whole display */ |
182 | void lcd_remote_clear_display(void) | 223 | void lcd_remote_clear_display(void) |
183 | { | 224 | { |
184 | unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; | 225 | unsigned bits = (current_vp->drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; |
185 | 226 | ||
186 | memset(lcd_remote_framebuffer, bits, sizeof lcd_remote_framebuffer); | 227 | memset(lcd_remote_framebuffer, bits, sizeof lcd_remote_framebuffer); |
228 | |||
187 | lcd_remote_scroll_info.lines = 0; | 229 | lcd_remote_scroll_info.lines = 0; |
188 | } | 230 | } |
189 | 231 | ||
232 | /* Clear the current viewport */ | ||
233 | void lcd_remote_clear_viewport(void) | ||
234 | { | ||
235 | int oldmode; | ||
236 | |||
237 | if (current_vp == &default_vp) | ||
238 | { | ||
239 | lcd_remote_clear_display(); | ||
240 | } | ||
241 | else | ||
242 | { | ||
243 | oldmode = current_vp->drawmode; | ||
244 | |||
245 | /* Invert the INVERSEVID bit and set basic mode to SOLID */ | ||
246 | current_vp->drawmode = (~current_vp->drawmode & DRMODE_INVERSEVID) | | ||
247 | DRMODE_SOLID; | ||
248 | |||
249 | lcd_remote_fillrect(0, 0, current_vp->width, current_vp->height); | ||
250 | |||
251 | current_vp->drawmode = oldmode; | ||
252 | |||
253 | lcd_remote_scroll_stop(current_vp); | ||
254 | } | ||
255 | } | ||
256 | |||
190 | /* Set a single pixel */ | 257 | /* Set a single pixel */ |
191 | void lcd_remote_drawpixel(int x, int y) | 258 | void lcd_remote_drawpixel(int x, int y) |
192 | { | 259 | { |
193 | if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT)) | 260 | if (((unsigned)x < (unsigned)current_vp->width) && |
194 | lcd_remote_pixelfuncs[drawmode](x, y); | 261 | ((unsigned)y < (unsigned)current_vp->height)) |
262 | lcd_remote_pixelfuncs[current_vp->drawmode](current_vp->x+x, current_vp->y+y); | ||
195 | } | 263 | } |
196 | 264 | ||
197 | /* Draw a line */ | 265 | /* Draw a line */ |
@@ -203,7 +271,7 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2) | |||
203 | int d, dinc1, dinc2; | 271 | int d, dinc1, dinc2; |
204 | int x, xinc1, xinc2; | 272 | int x, xinc1, xinc2; |
205 | int y, yinc1, yinc2; | 273 | int y, yinc1, yinc2; |
206 | lcd_remote_pixelfunc_type *pfunc = lcd_remote_pixelfuncs[drawmode]; | 274 | lcd_remote_pixelfunc_type *pfunc = lcd_remote_pixelfuncs[current_vp->drawmode]; |
207 | 275 | ||
208 | deltax = abs(x2 - x1); | 276 | deltax = abs(x2 - x1); |
209 | deltay = abs(y2 - y1); | 277 | deltay = abs(y2 - y1); |
@@ -247,8 +315,8 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2) | |||
247 | 315 | ||
248 | for (i = 0; i < numpixels; i++) | 316 | for (i = 0; i < numpixels; i++) |
249 | { | 317 | { |
250 | if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT)) | 318 | if (((unsigned)x < (unsigned)current_vp->width) && ((unsigned)y < (unsigned)current_vp->height)) |
251 | pfunc(x, y); | 319 | pfunc(x + current_vp->x, y + current_vp->y); |
252 | 320 | ||
253 | if (d < 0) | 321 | if (d < 0) |
254 | { | 322 | { |
@@ -268,7 +336,7 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2) | |||
268 | /* Draw a horizontal line (optimised) */ | 336 | /* Draw a horizontal line (optimised) */ |
269 | void lcd_remote_hline(int x1, int x2, int y) | 337 | void lcd_remote_hline(int x1, int x2, int y) |
270 | { | 338 | { |
271 | int x; | 339 | int x, width; |
272 | fb_remote_data *dst, *dst_end; | 340 | fb_remote_data *dst, *dst_end; |
273 | unsigned mask; | 341 | unsigned mask; |
274 | lcd_remote_blockfunc_type *bfunc; | 342 | lcd_remote_blockfunc_type *bfunc; |
@@ -282,24 +350,30 @@ void lcd_remote_hline(int x1, int x2, int y) | |||
282 | } | 350 | } |
283 | 351 | ||
284 | /* nothing to draw? */ | 352 | /* nothing to draw? */ |
285 | if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH) | 353 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) |
286 | || (x2 < 0)) | 354 | || (x2 < 0)) |
287 | return; | 355 | return; |
288 | 356 | ||
289 | /* clipping */ | 357 | /* clipping */ |
290 | if (x1 < 0) | 358 | if (x1 < 0) |
291 | x1 = 0; | 359 | x1 = 0; |
292 | if (x2 >= LCD_REMOTE_WIDTH) | 360 | if (x2 >= current_vp->width) |
293 | x2 = LCD_REMOTE_WIDTH-1; | 361 | x2 = current_vp->width-1; |
294 | 362 | ||
295 | bfunc = lcd_remote_blockfuncs[drawmode]; | 363 | width = x2 - x1 + 1; |
364 | |||
365 | /* Adjust x1 and y to viewport */ | ||
366 | x1 += current_vp->x; | ||
367 | y += current_vp->y; | ||
368 | |||
369 | bfunc = lcd_remote_blockfuncs[current_vp->drawmode]; | ||
296 | dst = &lcd_remote_framebuffer[y>>3][x1]; | 370 | dst = &lcd_remote_framebuffer[y>>3][x1]; |
297 | mask = 1 << (y & 7); | 371 | mask = 1 << (y & 7); |
298 | 372 | ||
299 | dst_end = dst + x2 - x1; | 373 | dst_end = dst + width; |
300 | do | 374 | do |
301 | bfunc(dst++, mask, 0xFFu); | 375 | bfunc(dst++, mask, 0xFFu); |
302 | while (dst <= dst_end); | 376 | while (dst < dst_end); |
303 | } | 377 | } |
304 | 378 | ||
305 | /* Draw a vertical line (optimised) */ | 379 | /* Draw a vertical line (optimised) */ |
@@ -319,17 +393,22 @@ void lcd_remote_vline(int x, int y1, int y2) | |||
319 | } | 393 | } |
320 | 394 | ||
321 | /* nothing to draw? */ | 395 | /* nothing to draw? */ |
322 | if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT) | 396 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) |
323 | || (y2 < 0)) | 397 | || (y2 < 0)) |
324 | return; | 398 | return; |
325 | 399 | ||
326 | /* clipping */ | 400 | /* clipping */ |
327 | if (y1 < 0) | 401 | if (y1 < 0) |
328 | y1 = 0; | 402 | y1 = 0; |
329 | if (y2 >= LCD_REMOTE_HEIGHT) | 403 | if (y2 >= current_vp->height) |
330 | y2 = LCD_REMOTE_HEIGHT-1; | 404 | y2 = current_vp->height-1; |
405 | |||
406 | /* adjust for viewport */ | ||
407 | y1 += current_vp->y; | ||
408 | y2 += current_vp->y; | ||
409 | x += current_vp->x; | ||
331 | 410 | ||
332 | bfunc = lcd_remote_blockfuncs[drawmode]; | 411 | bfunc = lcd_remote_blockfuncs[current_vp->drawmode]; |
333 | dst = &lcd_remote_framebuffer[y1>>3][x]; | 412 | dst = &lcd_remote_framebuffer[y1>>3][x]; |
334 | ny = y2 - (y1 & ~7); | 413 | ny = y2 - (y1 & ~7); |
335 | mask = 0xFFu << (y1 & 7); | 414 | mask = 0xFFu << (y1 & 7); |
@@ -371,8 +450,8 @@ void lcd_remote_fillrect(int x, int y, int width, int height) | |||
371 | bool fillopt = false; | 450 | bool fillopt = false; |
372 | 451 | ||
373 | /* nothing to draw? */ | 452 | /* nothing to draw? */ |
374 | if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) | 453 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
375 | || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) | 454 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
376 | return; | 455 | return; |
377 | 456 | ||
378 | /* clipping */ | 457 | /* clipping */ |
@@ -386,27 +465,32 @@ void lcd_remote_fillrect(int x, int y, int width, int height) | |||
386 | height += y; | 465 | height += y; |
387 | y = 0; | 466 | y = 0; |
388 | } | 467 | } |
389 | if (x + width > LCD_REMOTE_WIDTH) | 468 | if (x + width > current_vp->width) |
390 | width = LCD_REMOTE_WIDTH - x; | 469 | width = current_vp->width - x; |
391 | if (y + height > LCD_REMOTE_HEIGHT) | 470 | if (y + height > current_vp->height) |
392 | height = LCD_REMOTE_HEIGHT - y; | 471 | height = current_vp->height - y; |
393 | 472 | ||
394 | if (drawmode & DRMODE_INVERSEVID) | 473 | /* adjust for viewport */ |
474 | x += current_vp->x; | ||
475 | y += current_vp->y; | ||
476 | |||
477 | if (current_vp->drawmode & DRMODE_INVERSEVID) | ||
395 | { | 478 | { |
396 | if (drawmode & DRMODE_BG) | 479 | if (current_vp->drawmode & DRMODE_BG) |
397 | { | 480 | { |
398 | fillopt = true; | 481 | fillopt = true; |
399 | } | 482 | } |
400 | } | 483 | } |
401 | else | 484 | else |
402 | { | 485 | { |
403 | if (drawmode & DRMODE_FG) | 486 | if (current_vp->drawmode & DRMODE_FG) |
404 | { | 487 | { |
405 | fillopt = true; | 488 | fillopt = true; |
406 | bits = 0xFFu; | 489 | bits = 0xFFu; |
407 | } | 490 | } |
408 | } | 491 | } |
409 | bfunc = lcd_remote_blockfuncs[drawmode]; | 492 | |
493 | bfunc = lcd_remote_blockfuncs[current_vp->drawmode]; | ||
410 | dst = &lcd_remote_framebuffer[y>>3][x]; | 494 | dst = &lcd_remote_framebuffer[y>>3][x]; |
411 | ny = height - 1 + (y & 7); | 495 | ny = height - 1 + (y & 7); |
412 | mask = 0xFFu << (y & 7); | 496 | mask = 0xFFu << (y & 7); |
@@ -466,8 +550,8 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
466 | lcd_remote_blockfunc_type *bfunc; | 550 | lcd_remote_blockfunc_type *bfunc; |
467 | 551 | ||
468 | /* nothing to draw? */ | 552 | /* nothing to draw? */ |
469 | if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) | 553 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
470 | || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) | 554 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
471 | return; | 555 | return; |
472 | 556 | ||
473 | /* clipping */ | 557 | /* clipping */ |
@@ -483,10 +567,14 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
483 | src_y -= y; | 567 | src_y -= y; |
484 | y = 0; | 568 | y = 0; |
485 | } | 569 | } |
486 | if (x + width > LCD_REMOTE_WIDTH) | 570 | if (x + width > current_vp->width) |
487 | width = LCD_REMOTE_WIDTH - x; | 571 | width = current_vp->width - x; |
488 | if (y + height > LCD_REMOTE_HEIGHT) | 572 | if (y + height > current_vp->height) |
489 | height = LCD_REMOTE_HEIGHT - y; | 573 | height = current_vp->height - y; |
574 | |||
575 | /* adjust for viewports */ | ||
576 | x += current_vp->x; | ||
577 | y += current_vp->y; | ||
490 | 578 | ||
491 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 579 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
492 | src_y &= 7; | 580 | src_y &= 7; |
@@ -495,13 +583,13 @@ void lcd_remote_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
495 | shift = y & 7; | 583 | shift = y & 7; |
496 | ny = height - 1 + shift + src_y; | 584 | ny = height - 1 + shift + src_y; |
497 | 585 | ||
498 | bfunc = lcd_remote_blockfuncs[drawmode]; | 586 | bfunc = lcd_remote_blockfuncs[current_vp->drawmode]; |
499 | mask = 0xFFu << (shift + src_y); | 587 | mask = 0xFFu << (shift + src_y); |
500 | mask_bottom = 0xFFu >> (~ny & 7); | 588 | mask_bottom = 0xFFu >> (~ny & 7); |
501 | 589 | ||
502 | if (shift == 0) | 590 | if (shift == 0) |
503 | { | 591 | { |
504 | bool copyopt = (drawmode == DRMODE_SOLID); | 592 | bool copyopt = (current_vp->drawmode == DRMODE_SOLID); |
505 | 593 | ||
506 | for (; ny >= 8; ny -= 8) | 594 | for (; ny >= 8; ny -= 8) |
507 | { | 595 | { |
@@ -579,11 +667,11 @@ void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
579 | { | 667 | { |
580 | unsigned short ch; | 668 | unsigned short ch; |
581 | unsigned short *ucs; | 669 | unsigned short *ucs; |
582 | struct font* pf = font_get(curfont); | 670 | struct font* pf = font_get(current_vp->font); |
583 | 671 | ||
584 | ucs = bidi_l2v(str, 1); | 672 | ucs = bidi_l2v(str, 1); |
585 | 673 | ||
586 | while ((ch = *ucs++) != 0 && x < LCD_REMOTE_WIDTH) | 674 | while ((ch = *ucs++) != 0 && x < current_vp->width) |
587 | { | 675 | { |
588 | int width; | 676 | int width; |
589 | const unsigned char *bits; | 677 | const unsigned char *bits; |
@@ -637,24 +725,24 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, | |||
637 | int style, int offset) | 725 | int style, int offset) |
638 | { | 726 | { |
639 | int xpos,ypos,w,h,xrect; | 727 | int xpos,ypos,w,h,xrect; |
640 | int lastmode = drawmode; | 728 | int lastmode = current_vp->drawmode; |
641 | 729 | ||
642 | /* make sure scrolling is turned off on the line we are updating */ | 730 | /* make sure scrolling is turned off on the line we are updating */ |
643 | lcd_remote_scroll_info.lines &= ~(1 << y); | 731 | lcd_remote_scroll_stop_line(current_vp, y); |
644 | 732 | ||
645 | if(!str || !str[0]) | 733 | if(!str || !str[0]) |
646 | return; | 734 | return; |
647 | 735 | ||
648 | lcd_remote_getstringsize(str, &w, &h); | 736 | lcd_remote_getstringsize(str, &w, &h); |
649 | xpos = xmargin + x*w / utf8length((char *)str); | 737 | xpos = current_vp->xmargin + x*w / utf8length((char *)str); |
650 | ypos = ymargin + y*h; | 738 | ypos = current_vp->ymargin + y*h; |
651 | drawmode = (style & STYLE_INVERT) ? | 739 | current_vp->drawmode = (style & STYLE_INVERT) ? |
652 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 740 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
653 | lcd_remote_putsxyofs(xpos, ypos, offset, str); | 741 | lcd_remote_putsxyofs(xpos, ypos, offset, str); |
654 | drawmode ^= DRMODE_INVERSEVID; | 742 | current_vp->drawmode ^= DRMODE_INVERSEVID; |
655 | xrect = xpos + MAX(w - offset, 0); | 743 | xrect = xpos + MAX(w - offset, 0); |
656 | lcd_remote_fillrect(xrect, ypos, LCD_REMOTE_WIDTH - xrect, h); | 744 | lcd_remote_fillrect(xrect, ypos, current_vp->width - xrect, h); |
657 | drawmode = lastmode; | 745 | current_vp->drawmode = lastmode; |
658 | } | 746 | } |
659 | 747 | ||
660 | /*** scrolling ***/ | 748 | /*** scrolling ***/ |
@@ -680,9 +768,15 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
680 | struct scrollinfo* s; | 768 | struct scrollinfo* s; |
681 | int w, h; | 769 | int w, h; |
682 | 770 | ||
683 | if(y>=LCD_REMOTE_SCROLLABLE_LINES) return; | 771 | if ((unsigned)y >= (unsigned)current_vp->height) |
772 | return; | ||
773 | |||
774 | /* remove any previously scrolling line at the same location */ | ||
775 | lcd_remote_scroll_stop_line(current_vp, y); | ||
776 | |||
777 | if (lcd_remote_scroll_info.lines >= LCD_REMOTE_SCROLLABLE_LINES) return; | ||
684 | 778 | ||
685 | s = &lcd_remote_scroll_info.scroll[y]; | 779 | s = &lcd_remote_scroll_info.scroll[lcd_remote_scroll_info.lines]; |
686 | 780 | ||
687 | s->start_tick = current_tick + lcd_remote_scroll_info.delay; | 781 | s->start_tick = current_tick + lcd_remote_scroll_info.delay; |
688 | s->style = style; | 782 | s->style = style; |
@@ -694,7 +788,7 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
694 | 788 | ||
695 | lcd_remote_getstringsize(string, &w, &h); | 789 | lcd_remote_getstringsize(string, &w, &h); |
696 | 790 | ||
697 | if (LCD_REMOTE_WIDTH - x * 8 - xmargin < w) { | 791 | if (current_vp->width - x * 8 - current_vp->xmargin < w) { |
698 | /* prepare scroll line */ | 792 | /* prepare scroll line */ |
699 | char *end; | 793 | char *end; |
700 | 794 | ||
@@ -707,7 +801,7 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
707 | /* scroll bidirectional or forward only depending on the string | 801 | /* scroll bidirectional or forward only depending on the string |
708 | width */ | 802 | width */ |
709 | if ( lcd_remote_scroll_info.bidir_limit ) { | 803 | if ( lcd_remote_scroll_info.bidir_limit ) { |
710 | s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * | 804 | s->bidir = s->width < (current_vp->width - current_vp->xmargin) * |
711 | (100 + lcd_remote_scroll_info.bidir_limit) / 100; | 805 | (100 + lcd_remote_scroll_info.bidir_limit) / 100; |
712 | } | 806 | } |
713 | else | 807 | else |
@@ -720,17 +814,17 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
720 | } | 814 | } |
721 | 815 | ||
722 | end = strchr(s->line, '\0'); | 816 | end = strchr(s->line, '\0'); |
723 | strncpy(end, (char *)string, LCD_REMOTE_WIDTH/2); | 817 | strncpy(end, (char *)string, current_vp->width/2); |
724 | 818 | ||
819 | s->vp = current_vp; | ||
820 | s->y = y; | ||
725 | s->len = utf8length((char *)string); | 821 | s->len = utf8length((char *)string); |
726 | s->offset = offset; | 822 | s->offset = offset; |
727 | s->startx = xmargin + x * s->width / s->len;; | 823 | s->startx = current_vp->xmargin + x * s->width / s->len; |
728 | s->backward = false; | 824 | s->backward = false; |
729 | lcd_remote_scroll_info.lines |= (1<<y); | 825 | |
826 | lcd_remote_scroll_info.lines++; | ||
730 | } | 827 | } |
731 | else | ||
732 | /* force a bit switch-off since it doesn't scroll */ | ||
733 | lcd_remote_scroll_info.lines &= ~(1<<y); | ||
734 | } | 828 | } |
735 | 829 | ||
736 | void lcd_remote_scroll_fn(void) | 830 | void lcd_remote_scroll_fn(void) |
@@ -740,26 +834,25 @@ void lcd_remote_scroll_fn(void) | |||
740 | int index; | 834 | int index; |
741 | int xpos, ypos; | 835 | int xpos, ypos; |
742 | int lastmode; | 836 | int lastmode; |
837 | struct viewport* old_vp = current_vp; | ||
743 | 838 | ||
744 | for ( index = 0; index < LCD_REMOTE_SCROLLABLE_LINES; index++ ) { | 839 | for ( index = 0; index < lcd_remote_scroll_info.lines; index++ ) { |
745 | /* really scroll? */ | ||
746 | if ((lcd_remote_scroll_info.lines & (1 << index)) == 0) | ||
747 | continue; | ||
748 | |||
749 | s = &lcd_remote_scroll_info.scroll[index]; | 840 | s = &lcd_remote_scroll_info.scroll[index]; |
750 | 841 | ||
751 | /* check pause */ | 842 | /* check pause */ |
752 | if (TIME_BEFORE(current_tick, s->start_tick)) | 843 | if (TIME_BEFORE(current_tick, s->start_tick)) |
753 | continue; | 844 | continue; |
754 | 845 | ||
846 | lcd_remote_set_viewport(s->vp); | ||
847 | |||
755 | if (s->backward) | 848 | if (s->backward) |
756 | s->offset -= lcd_remote_scroll_info.step; | 849 | s->offset -= lcd_remote_scroll_info.step; |
757 | else | 850 | else |
758 | s->offset += lcd_remote_scroll_info.step; | 851 | s->offset += lcd_remote_scroll_info.step; |
759 | 852 | ||
760 | pf = font_get(curfont); | 853 | pf = font_get(current_vp->font); |
761 | xpos = s->startx; | 854 | xpos = s->startx; |
762 | ypos = ymargin + index * pf->height; | 855 | ypos = current_vp->ymargin + s->y * pf->height; |
763 | 856 | ||
764 | if (s->bidir) { /* scroll bidirectional */ | 857 | if (s->bidir) { /* scroll bidirectional */ |
765 | if (s->offset <= 0) { | 858 | if (s->offset <= 0) { |
@@ -768,9 +861,9 @@ void lcd_remote_scroll_fn(void) | |||
768 | s->backward = false; | 861 | s->backward = false; |
769 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; | 862 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; |
770 | } | 863 | } |
771 | if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) { | 864 | if (s->offset >= s->width - (current_vp->width - xpos)) { |
772 | /* at end of line */ | 865 | /* at end of line */ |
773 | s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); | 866 | s->offset = s->width - (current_vp->width - xpos); |
774 | s->backward = true; | 867 | s->backward = true; |
775 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; | 868 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; |
776 | } | 869 | } |
@@ -781,13 +874,16 @@ void lcd_remote_scroll_fn(void) | |||
781 | s->offset %= s->width; | 874 | s->offset %= s->width; |
782 | } | 875 | } |
783 | 876 | ||
784 | lastmode = drawmode; | 877 | lastmode = current_vp->drawmode; |
785 | drawmode = (s->style&STYLE_INVERT) ? | 878 | current_vp->drawmode = (s->style&STYLE_INVERT) ? |
786 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 879 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
787 | lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); | 880 | lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); |
788 | drawmode = lastmode; | 881 | current_vp->drawmode = lastmode; |
789 | lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); | 882 | lcd_remote_update_viewport_rect(xpos, ypos, |
883 | current_vp->width - xpos, pf->height); | ||
790 | } | 884 | } |
885 | |||
886 | lcd_remote_set_viewport(old_vp); | ||
791 | } | 887 | } |
792 | 888 | ||
793 | /* LCD init */ | 889 | /* LCD init */ |