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-1bit-vert.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-1bit-vert.c')
-rw-r--r-- | firmware/drivers/lcd-1bit-vert.c | 250 |
1 files changed, 171 insertions, 79 deletions
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index bd62e105cb..5c651a9613 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c | |||
@@ -35,10 +35,40 @@ | |||
35 | 35 | ||
36 | unsigned char lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; | 36 | unsigned char lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]; |
37 | 37 | ||
38 | static int drawmode = DRMODE_SOLID; | 38 | static struct viewport default_vp = |
39 | static int xmargin = 0; | 39 | { |
40 | static int ymargin = 0; | 40 | .x = 0, |
41 | static int curfont = FONT_SYSFIXED; | 41 | .y = 0, |
42 | .width = LCD_WIDTH, | ||
43 | .height = LCD_HEIGHT, | ||
44 | .font = FONT_SYSFIXED, | ||
45 | .drawmode = DRMODE_SOLID, | ||
46 | .xmargin = 0, | ||
47 | .ymargin = 0, | ||
48 | }; | ||
49 | |||
50 | static struct viewport* current_vp = &default_vp; | ||
51 | |||
52 | /*** Viewports ***/ | ||
53 | |||
54 | void lcd_set_viewport(struct viewport* vp) | ||
55 | { | ||
56 | if (vp == NULL) | ||
57 | current_vp = &default_vp; | ||
58 | else | ||
59 | current_vp = vp; | ||
60 | } | ||
61 | |||
62 | void lcd_update_viewport(void) | ||
63 | { | ||
64 | lcd_update_rect(current_vp->x, current_vp->y, | ||
65 | current_vp->width, current_vp->height); | ||
66 | } | ||
67 | |||
68 | void lcd_update_viewport_rect(int x, int y, int width, int height) | ||
69 | { | ||
70 | lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height); | ||
71 | } | ||
42 | 72 | ||
43 | /* LCD init */ | 73 | /* LCD init */ |
44 | void lcd_init(void) | 74 | void lcd_init(void) |
@@ -53,38 +83,48 @@ void lcd_init(void) | |||
53 | 83 | ||
54 | void lcd_set_drawmode(int mode) | 84 | void lcd_set_drawmode(int mode) |
55 | { | 85 | { |
56 | drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | 86 | current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); |
57 | } | 87 | } |
58 | 88 | ||
59 | int lcd_get_drawmode(void) | 89 | int lcd_get_drawmode(void) |
60 | { | 90 | { |
61 | return drawmode; | 91 | return current_vp->drawmode; |
62 | } | 92 | } |
63 | 93 | ||
64 | void lcd_setmargins(int x, int y) | 94 | void lcd_setmargins(int x, int y) |
65 | { | 95 | { |
66 | xmargin = x; | 96 | current_vp->xmargin = x; |
67 | ymargin = y; | 97 | current_vp->ymargin = y; |
68 | } | 98 | } |
69 | 99 | ||
70 | int lcd_getxmargin(void) | 100 | int lcd_getxmargin(void) |
71 | { | 101 | { |
72 | return xmargin; | 102 | return current_vp->xmargin; |
73 | } | 103 | } |
74 | 104 | ||
75 | int lcd_getymargin(void) | 105 | int lcd_getymargin(void) |
76 | { | 106 | { |
77 | return ymargin; | 107 | return current_vp->ymargin; |
108 | } | ||
109 | |||
110 | int lcd_getwidth(void) | ||
111 | { | ||
112 | return current_vp->width; | ||
113 | } | ||
114 | |||
115 | int lcd_getheight(void) | ||
116 | { | ||
117 | return current_vp->height; | ||
78 | } | 118 | } |
79 | 119 | ||
80 | void lcd_setfont(int newfont) | 120 | void lcd_setfont(int newfont) |
81 | { | 121 | { |
82 | curfont = newfont; | 122 | current_vp->font = newfont; |
83 | } | 123 | } |
84 | 124 | ||
85 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 125 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) |
86 | { | 126 | { |
87 | return font_getstringsize(str, w, h, curfont); | 127 | return font_getstringsize(str, w, h, current_vp->font); |
88 | } | 128 | } |
89 | 129 | ||
90 | /*** low-level drawing functions ***/ | 130 | /*** low-level drawing functions ***/ |
@@ -187,17 +227,42 @@ lcd_blockfunc_type* const lcd_blockfuncs[8] = { | |||
187 | /* Clear the whole display */ | 227 | /* Clear the whole display */ |
188 | void lcd_clear_display(void) | 228 | void lcd_clear_display(void) |
189 | { | 229 | { |
190 | unsigned bits = (drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; | 230 | unsigned bits = (current_vp->drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; |
191 | 231 | ||
192 | memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); | 232 | memset(lcd_framebuffer, bits, sizeof lcd_framebuffer); |
193 | lcd_scroll_info.lines = 0; | 233 | lcd_scroll_info.lines = 0; |
194 | } | 234 | } |
195 | 235 | ||
236 | void lcd_clear_viewport(void) | ||
237 | { | ||
238 | int oldmode; | ||
239 | |||
240 | if (current_vp == &default_vp) | ||
241 | { | ||
242 | lcd_clear_display(); | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | oldmode = current_vp->drawmode; | ||
247 | |||
248 | /* Invert the INVERSEVID bit and set basic mode to SOLID */ | ||
249 | current_vp->drawmode = (~current_vp->drawmode & DRMODE_INVERSEVID) | | ||
250 | DRMODE_SOLID; | ||
251 | |||
252 | lcd_fillrect(0, 0, current_vp->width, current_vp->height); | ||
253 | |||
254 | current_vp->drawmode = oldmode; | ||
255 | |||
256 | lcd_scroll_stop(current_vp); | ||
257 | } | ||
258 | } | ||
259 | |||
196 | /* Set a single pixel */ | 260 | /* Set a single pixel */ |
197 | void lcd_drawpixel(int x, int y) | 261 | void lcd_drawpixel(int x, int y) |
198 | { | 262 | { |
199 | if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) | 263 | if (((unsigned)x < (unsigned)current_vp->width) && |
200 | lcd_pixelfuncs[drawmode](x, y); | 264 | ((unsigned)y < (unsigned)current_vp->height)) |
265 | lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y); | ||
201 | } | 266 | } |
202 | 267 | ||
203 | /* Draw a line */ | 268 | /* Draw a line */ |
@@ -209,7 +274,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
209 | int d, dinc1, dinc2; | 274 | int d, dinc1, dinc2; |
210 | int x, xinc1, xinc2; | 275 | int x, xinc1, xinc2; |
211 | int y, yinc1, yinc2; | 276 | int y, yinc1, yinc2; |
212 | lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[drawmode]; | 277 | lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode]; |
213 | 278 | ||
214 | deltax = abs(x2 - x1); | 279 | deltax = abs(x2 - x1); |
215 | deltay = abs(y2 - y1); | 280 | deltay = abs(y2 - y1); |
@@ -253,8 +318,9 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
253 | 318 | ||
254 | for (i = 0; i < numpixels; i++) | 319 | for (i = 0; i < numpixels; i++) |
255 | { | 320 | { |
256 | if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) | 321 | if (((unsigned)x < (unsigned)current_vp->width) && |
257 | pfunc(x, y); | 322 | ((unsigned)y < (unsigned)current_vp->height)) |
323 | pfunc(current_vp->x + x, current_vp->y + y); | ||
258 | 324 | ||
259 | if (d < 0) | 325 | if (d < 0) |
260 | { | 326 | { |
@@ -288,16 +354,22 @@ void lcd_hline(int x1, int x2, int y) | |||
288 | } | 354 | } |
289 | 355 | ||
290 | /* nothing to draw? */ | 356 | /* nothing to draw? */ |
291 | if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) | 357 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) |
358 | || (x2 < 0)) | ||
292 | return; | 359 | return; |
293 | 360 | ||
294 | /* clipping */ | 361 | /* clipping */ |
295 | if (x1 < 0) | 362 | if (x1 < 0) |
296 | x1 = 0; | 363 | x1 = 0; |
297 | if (x2 >= LCD_WIDTH) | 364 | if (x2 >= current_vp->width) |
298 | x2 = LCD_WIDTH-1; | 365 | x2 = current_vp->width-1; |
299 | 366 | ||
300 | bfunc = lcd_blockfuncs[drawmode]; | 367 | /* adjust for viewport */ |
368 | y += current_vp->y; | ||
369 | x1 += current_vp->x; | ||
370 | x2 += current_vp->x; | ||
371 | |||
372 | bfunc = lcd_blockfuncs[current_vp->drawmode]; | ||
301 | dst = &lcd_framebuffer[y>>3][x1]; | 373 | dst = &lcd_framebuffer[y>>3][x1]; |
302 | mask = 1 << (y & 7); | 374 | mask = 1 << (y & 7); |
303 | 375 | ||
@@ -324,16 +396,22 @@ void lcd_vline(int x, int y1, int y2) | |||
324 | } | 396 | } |
325 | 397 | ||
326 | /* nothing to draw? */ | 398 | /* nothing to draw? */ |
327 | if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) | 399 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) |
400 | || (y2 < 0)) | ||
328 | return; | 401 | return; |
329 | 402 | ||
330 | /* clipping */ | 403 | /* clipping */ |
331 | if (y1 < 0) | 404 | if (y1 < 0) |
332 | y1 = 0; | 405 | y1 = 0; |
333 | if (y2 >= LCD_HEIGHT) | 406 | if (y2 >= current_vp->height) |
334 | y2 = LCD_HEIGHT-1; | 407 | y2 = current_vp->height-1; |
335 | 408 | ||
336 | bfunc = lcd_blockfuncs[drawmode]; | 409 | /* adjust for viewport */ |
410 | y1 += current_vp->y; | ||
411 | y2 += current_vp->y; | ||
412 | x += current_vp->x; | ||
413 | |||
414 | bfunc = lcd_blockfuncs[current_vp->drawmode]; | ||
337 | dst = &lcd_framebuffer[y1>>3][x]; | 415 | dst = &lcd_framebuffer[y1>>3][x]; |
338 | ny = y2 - (y1 & ~7); | 416 | ny = y2 - (y1 & ~7); |
339 | mask = 0xFFu << (y1 & 7); | 417 | mask = 0xFFu << (y1 & 7); |
@@ -375,8 +453,8 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
375 | bool fillopt = false; | 453 | bool fillopt = false; |
376 | 454 | ||
377 | /* nothing to draw? */ | 455 | /* nothing to draw? */ |
378 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 456 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
379 | || (x + width <= 0) || (y + height <= 0)) | 457 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
380 | return; | 458 | return; |
381 | 459 | ||
382 | /* clipping */ | 460 | /* clipping */ |
@@ -390,27 +468,31 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
390 | height += y; | 468 | height += y; |
391 | y = 0; | 469 | y = 0; |
392 | } | 470 | } |
393 | if (x + width > LCD_WIDTH) | 471 | if (x + width > current_vp->width) |
394 | width = LCD_WIDTH - x; | 472 | width = current_vp->width - x; |
395 | if (y + height > LCD_HEIGHT) | 473 | if (y + height > current_vp->height) |
396 | height = LCD_HEIGHT - y; | 474 | height = current_vp->height - y; |
397 | 475 | ||
398 | if (drawmode & DRMODE_INVERSEVID) | 476 | /* adjust for viewport */ |
477 | x += current_vp->x; | ||
478 | y += current_vp->y; | ||
479 | |||
480 | if (current_vp->drawmode & DRMODE_INVERSEVID) | ||
399 | { | 481 | { |
400 | if (drawmode & DRMODE_BG) | 482 | if (current_vp->drawmode & DRMODE_BG) |
401 | { | 483 | { |
402 | fillopt = true; | 484 | fillopt = true; |
403 | } | 485 | } |
404 | } | 486 | } |
405 | else | 487 | else |
406 | { | 488 | { |
407 | if (drawmode & DRMODE_FG) | 489 | if (current_vp->drawmode & DRMODE_FG) |
408 | { | 490 | { |
409 | fillopt = true; | 491 | fillopt = true; |
410 | bits = 0xFFu; | 492 | bits = 0xFFu; |
411 | } | 493 | } |
412 | } | 494 | } |
413 | bfunc = lcd_blockfuncs[drawmode]; | 495 | bfunc = lcd_blockfuncs[current_vp->drawmode]; |
414 | dst = &lcd_framebuffer[y>>3][x]; | 496 | dst = &lcd_framebuffer[y>>3][x]; |
415 | ny = height - 1 + (y & 7); | 497 | ny = height - 1 + (y & 7); |
416 | mask = 0xFFu << (y & 7); | 498 | mask = 0xFFu << (y & 7); |
@@ -470,8 +552,8 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
470 | lcd_blockfunc_type *bfunc; | 552 | lcd_blockfunc_type *bfunc; |
471 | 553 | ||
472 | /* nothing to draw? */ | 554 | /* nothing to draw? */ |
473 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | 555 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
474 | || (x + width <= 0) || (y + height <= 0)) | 556 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
475 | return; | 557 | return; |
476 | 558 | ||
477 | /* clipping */ | 559 | /* clipping */ |
@@ -487,10 +569,14 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
487 | src_y -= y; | 569 | src_y -= y; |
488 | y = 0; | 570 | y = 0; |
489 | } | 571 | } |
490 | if (x + width > LCD_WIDTH) | 572 | if (x + width > current_vp->width) |
491 | width = LCD_WIDTH - x; | 573 | width = current_vp->width - x; |
492 | if (y + height > LCD_HEIGHT) | 574 | if (y + height > current_vp->height) |
493 | height = LCD_HEIGHT - y; | 575 | height = current_vp->height - y; |
576 | |||
577 | /* adjust for viewport */ | ||
578 | x += current_vp->x; | ||
579 | y += current_vp->y; | ||
494 | 580 | ||
495 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 581 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
496 | src_y &= 7; | 582 | src_y &= 7; |
@@ -499,13 +585,13 @@ void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
499 | shift = y & 7; | 585 | shift = y & 7; |
500 | ny = height - 1 + shift + src_y; | 586 | ny = height - 1 + shift + src_y; |
501 | 587 | ||
502 | bfunc = lcd_blockfuncs[drawmode]; | 588 | bfunc = lcd_blockfuncs[current_vp->drawmode]; |
503 | mask = 0xFFu << (shift + src_y); | 589 | mask = 0xFFu << (shift + src_y); |
504 | mask_bottom = 0xFFu >> (~ny & 7); | 590 | mask_bottom = 0xFFu >> (~ny & 7); |
505 | 591 | ||
506 | if (shift == 0) | 592 | if (shift == 0) |
507 | { | 593 | { |
508 | bool copyopt = (drawmode == DRMODE_SOLID); | 594 | bool copyopt = (current_vp->drawmode == DRMODE_SOLID); |
509 | 595 | ||
510 | for (; ny >= 8; ny -= 8) | 596 | for (; ny >= 8; ny -= 8) |
511 | { | 597 | { |
@@ -582,11 +668,11 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
582 | { | 668 | { |
583 | unsigned short ch; | 669 | unsigned short ch; |
584 | unsigned short *ucs; | 670 | unsigned short *ucs; |
585 | struct font* pf = font_get(curfont); | 671 | struct font* pf = font_get(current_vp->font); |
586 | 672 | ||
587 | ucs = bidi_l2v(str, 1); | 673 | ucs = bidi_l2v(str, 1); |
588 | 674 | ||
589 | while ((ch = *ucs++) != 0 && x < LCD_WIDTH) | 675 | while ((ch = *ucs++) != 0 && x < current_vp->width) |
590 | { | 676 | { |
591 | int width; | 677 | int width; |
592 | const unsigned char *bits; | 678 | const unsigned char *bits; |
@@ -639,24 +725,24 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, | |||
639 | int style, int offset) | 725 | int style, int offset) |
640 | { | 726 | { |
641 | int xpos,ypos,w,h,xrect; | 727 | int xpos,ypos,w,h,xrect; |
642 | int lastmode = drawmode; | 728 | int lastmode = current_vp->drawmode; |
643 | 729 | ||
644 | /* 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 */ |
645 | lcd_scroll_info.lines &= ~(1 << y); | 731 | lcd_scroll_stop_line(current_vp, y); |
646 | 732 | ||
647 | if(!str || !str[0]) | 733 | if(!str || !str[0]) |
648 | return; | 734 | return; |
649 | 735 | ||
650 | lcd_getstringsize(str, &w, &h); | 736 | lcd_getstringsize(str, &w, &h); |
651 | xpos = xmargin + x*w / utf8length(str); | 737 | xpos = current_vp->xmargin + x*w / utf8length(str); |
652 | ypos = ymargin + y*h; | 738 | ypos = current_vp->ymargin + y*h; |
653 | drawmode = (style & STYLE_INVERT) ? | 739 | current_vp->drawmode = (style & STYLE_INVERT) ? |
654 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 740 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
655 | lcd_putsxyofs(xpos, ypos, offset, str); | 741 | lcd_putsxyofs(xpos, ypos, offset, str); |
656 | drawmode ^= DRMODE_INVERSEVID; | 742 | current_vp->drawmode ^= DRMODE_INVERSEVID; |
657 | xrect = xpos + MAX(w - offset, 0); | 743 | xrect = xpos + MAX(w - offset, 0); |
658 | lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h); | 744 | lcd_fillrect(xrect, ypos, current_vp->width - xrect, h); |
659 | drawmode = lastmode; | 745 | current_vp->drawmode = lastmode; |
660 | } | 746 | } |
661 | 747 | ||
662 | /*** scrolling ***/ | 748 | /*** scrolling ***/ |
@@ -682,9 +768,15 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
682 | struct scrollinfo* s; | 768 | struct scrollinfo* s; |
683 | int w, h; | 769 | int w, h; |
684 | 770 | ||
685 | if(y>=LCD_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_scroll_stop_line(current_vp, y); | ||
776 | |||
777 | if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return; | ||
686 | 778 | ||
687 | s = &lcd_scroll_info.scroll[y]; | 779 | s = &lcd_scroll_info.scroll[lcd_scroll_info.lines]; |
688 | 780 | ||
689 | s->start_tick = current_tick + lcd_scroll_info.delay; | 781 | s->start_tick = current_tick + lcd_scroll_info.delay; |
690 | s->style = style; | 782 | s->style = style; |
@@ -696,7 +788,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
696 | 788 | ||
697 | lcd_getstringsize(string, &w, &h); | 789 | lcd_getstringsize(string, &w, &h); |
698 | 790 | ||
699 | if (LCD_WIDTH - x * 8 - xmargin < w) { | 791 | if (current_vp->width - x * 8 - current_vp->xmargin < w) { |
700 | /* prepare scroll line */ | 792 | /* prepare scroll line */ |
701 | char *end; | 793 | char *end; |
702 | 794 | ||
@@ -709,7 +801,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
709 | /* scroll bidirectional or forward only depending on the string | 801 | /* scroll bidirectional or forward only depending on the string |
710 | width */ | 802 | width */ |
711 | if ( lcd_scroll_info.bidir_limit ) { | 803 | if ( lcd_scroll_info.bidir_limit ) { |
712 | s->bidir = s->width < (LCD_WIDTH - xmargin) * | 804 | s->bidir = s->width < (current_vp->width - current_vp->xmargin) * |
713 | (100 + lcd_scroll_info.bidir_limit) / 100; | 805 | (100 + lcd_scroll_info.bidir_limit) / 100; |
714 | } | 806 | } |
715 | else | 807 | else |
@@ -722,17 +814,16 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, | |||
722 | } | 814 | } |
723 | 815 | ||
724 | end = strchr(s->line, '\0'); | 816 | end = strchr(s->line, '\0'); |
725 | strncpy(end, string, LCD_WIDTH/2); | 817 | strncpy(end, string, current_vp->width/2); |
726 | 818 | ||
819 | s->vp = current_vp; | ||
820 | s->y = y; | ||
727 | s->len = utf8length(string); | 821 | s->len = utf8length(string); |
728 | s->offset = offset; | 822 | s->offset = offset; |
729 | s->startx = xmargin + x * s->width / s->len;; | 823 | s->startx = current_vp->xmargin + x * s->width / s->len;; |
730 | s->backward = false; | 824 | s->backward = false; |
731 | lcd_scroll_info.lines |= (1<<y); | 825 | lcd_scroll_info.lines++; |
732 | } | 826 | } |
733 | else | ||
734 | /* force a bit switch-off since it doesn't scroll */ | ||
735 | lcd_scroll_info.lines &= ~(1<<y); | ||
736 | } | 827 | } |
737 | 828 | ||
738 | void lcd_scroll_fn(void) | 829 | void lcd_scroll_fn(void) |
@@ -742,26 +833,25 @@ void lcd_scroll_fn(void) | |||
742 | int index; | 833 | int index; |
743 | int xpos, ypos; | 834 | int xpos, ypos; |
744 | int lastmode; | 835 | int lastmode; |
836 | struct viewport* old_vp = current_vp; | ||
745 | 837 | ||
746 | for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) { | 838 | for ( index = 0; index < lcd_scroll_info.lines; index++ ) { |
747 | /* really scroll? */ | ||
748 | if ((lcd_scroll_info.lines & (1 << index)) == 0) | ||
749 | continue; | ||
750 | |||
751 | s = &lcd_scroll_info.scroll[index]; | 839 | s = &lcd_scroll_info.scroll[index]; |
752 | 840 | ||
753 | /* check pause */ | 841 | /* check pause */ |
754 | if (TIME_BEFORE(current_tick, s->start_tick)) | 842 | if (TIME_BEFORE(current_tick, s->start_tick)) |
755 | continue; | 843 | continue; |
756 | 844 | ||
845 | lcd_set_viewport(s->vp); | ||
846 | |||
757 | if (s->backward) | 847 | if (s->backward) |
758 | s->offset -= lcd_scroll_info.step; | 848 | s->offset -= lcd_scroll_info.step; |
759 | else | 849 | else |
760 | s->offset += lcd_scroll_info.step; | 850 | s->offset += lcd_scroll_info.step; |
761 | 851 | ||
762 | pf = font_get(curfont); | 852 | pf = font_get(current_vp->font); |
763 | xpos = s->startx; | 853 | xpos = s->startx; |
764 | ypos = ymargin + index * pf->height; | 854 | ypos = current_vp->ymargin + s->y * pf->height; |
765 | 855 | ||
766 | if (s->bidir) { /* scroll bidirectional */ | 856 | if (s->bidir) { /* scroll bidirectional */ |
767 | if (s->offset <= 0) { | 857 | if (s->offset <= 0) { |
@@ -770,9 +860,9 @@ void lcd_scroll_fn(void) | |||
770 | s->backward = false; | 860 | s->backward = false; |
771 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | 861 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; |
772 | } | 862 | } |
773 | if (s->offset >= s->width - (LCD_WIDTH - xpos)) { | 863 | if (s->offset >= s->width - (current_vp->width - xpos)) { |
774 | /* at end of line */ | 864 | /* at end of line */ |
775 | s->offset = s->width - (LCD_WIDTH - xpos); | 865 | s->offset = s->width - (current_vp->width - xpos); |
776 | s->backward = true; | 866 | s->backward = true; |
777 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; | 867 | s->start_tick = current_tick + lcd_scroll_info.delay * 2; |
778 | } | 868 | } |
@@ -783,11 +873,13 @@ void lcd_scroll_fn(void) | |||
783 | s->offset %= s->width; | 873 | s->offset %= s->width; |
784 | } | 874 | } |
785 | 875 | ||
786 | lastmode = drawmode; | 876 | lastmode = current_vp->drawmode; |
787 | drawmode = (s->style&STYLE_INVERT) ? | 877 | current_vp->drawmode = (s->style&STYLE_INVERT) ? |
788 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 878 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
789 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 879 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); |
790 | drawmode = lastmode; | 880 | current_vp->drawmode = lastmode; |
791 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 881 | lcd_update_viewport_rect(xpos, ypos, current_vp->width - xpos, pf->height); |
792 | } | 882 | } |
883 | |||
884 | lcd_set_viewport(old_vp); | ||
793 | } | 885 | } |