diff options
Diffstat (limited to 'firmware/drivers/lcd-remote-2bit-vi.c')
-rw-r--r-- | firmware/drivers/lcd-remote-2bit-vi.c | 294 |
1 files changed, 202 insertions, 92 deletions
diff --git a/firmware/drivers/lcd-remote-2bit-vi.c b/firmware/drivers/lcd-remote-2bit-vi.c index d5757f4dbb..9ab98c69aa 100644 --- a/firmware/drivers/lcd-remote-2bit-vi.c +++ b/firmware/drivers/lcd-remote-2bit-vi.c | |||
@@ -46,12 +46,48 @@ static const fb_remote_data patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000}; | |||
46 | static fb_remote_data* remote_backdrop = NULL; | 46 | static fb_remote_data* remote_backdrop = NULL; |
47 | static long remote_backdrop_offset IDATA_ATTR = 0; | 47 | static long remote_backdrop_offset IDATA_ATTR = 0; |
48 | 48 | ||
49 | static unsigned fg_pattern IDATA_ATTR = 0xFFFF; /* initially black */ | 49 | static struct viewport default_vp = |
50 | static unsigned bg_pattern IDATA_ATTR = 0x0000; /* initially white */ | 50 | { |
51 | static int drawmode = DRMODE_SOLID; | 51 | .x = 0, |
52 | static int xmargin = 0; | 52 | .y = 0, |
53 | static int ymargin = 0; | 53 | .width = LCD_REMOTE_WIDTH, |
54 | static int curfont = FONT_SYSFIXED; | 54 | .height = LCD_REMOTE_HEIGHT, |
55 | .font = FONT_SYSFIXED, | ||
56 | .drawmode = DRMODE_SOLID, | ||
57 | .xmargin = 0, | ||
58 | .ymargin = 0, | ||
59 | .fg_pattern = LCD_REMOTE_DEFAULT_FG, | ||
60 | .bg_pattern = LCD_REMOTE_DEFAULT_BG | ||
61 | }; | ||
62 | |||
63 | static unsigned fg_pattern IBSS_ATTR; | ||
64 | static unsigned bg_pattern IBSS_ATTR; | ||
65 | |||
66 | static struct viewport* current_vp IBSS_ATTR;; | ||
67 | |||
68 | /*** Viewports ***/ | ||
69 | |||
70 | void lcd_remote_set_viewport(struct viewport* vp) | ||
71 | { | ||
72 | if (vp == NULL) | ||
73 | current_vp = &default_vp; | ||
74 | else | ||
75 | current_vp = vp; | ||
76 | |||
77 | fg_pattern = patterns[current_vp->fg_pattern & 3]; | ||
78 | bg_pattern = patterns[current_vp->bg_pattern & 3]; | ||
79 | } | ||
80 | |||
81 | void lcd_remote_update_viewport(void) | ||
82 | { | ||
83 | lcd_remote_update_rect(current_vp->x, current_vp->y, | ||
84 | current_vp->width, current_vp->height); | ||
85 | } | ||
86 | |||
87 | void lcd_remote_update_viewport_rect(int x, int y, int width, int height) | ||
88 | { | ||
89 | lcd_remote_update_rect(current_vp->x + x, current_vp->y + y, width, height); | ||
90 | } | ||
55 | 91 | ||
56 | /*** parameter handling ***/ | 92 | /*** parameter handling ***/ |
57 | unsigned lcd_remote_color_to_native(unsigned color) | 93 | unsigned lcd_remote_color_to_native(unsigned color) |
@@ -69,32 +105,34 @@ unsigned lcd_remote_color_to_native(unsigned color) | |||
69 | 105 | ||
70 | void lcd_remote_set_drawmode(int mode) | 106 | void lcd_remote_set_drawmode(int mode) |
71 | { | 107 | { |
72 | drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | 108 | current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); |
73 | } | 109 | } |
74 | 110 | ||
75 | int lcd_remote_get_drawmode(void) | 111 | int lcd_remote_get_drawmode(void) |
76 | { | 112 | { |
77 | return drawmode; | 113 | return current_vp->drawmode; |
78 | } | 114 | } |
79 | 115 | ||
80 | void lcd_remote_set_foreground(unsigned brightness) | 116 | void lcd_remote_set_foreground(unsigned brightness) |
81 | { | 117 | { |
118 | current_vp->fg_pattern = brightness; | ||
82 | fg_pattern = patterns[brightness & 3]; | 119 | fg_pattern = patterns[brightness & 3]; |
83 | } | 120 | } |
84 | 121 | ||
85 | unsigned lcd_remote_get_foreground(void) | 122 | unsigned lcd_remote_get_foreground(void) |
86 | { | 123 | { |
87 | return (~fg_pattern >> 7) & 3; | 124 | return current_vp->fg_pattern; |
88 | } | 125 | } |
89 | 126 | ||
90 | void lcd_remote_set_background(unsigned brightness) | 127 | void lcd_remote_set_background(unsigned brightness) |
91 | { | 128 | { |
129 | current_vp->bg_pattern = brightness; | ||
92 | bg_pattern = patterns[brightness & 3]; | 130 | bg_pattern = patterns[brightness & 3]; |
93 | } | 131 | } |
94 | 132 | ||
95 | unsigned lcd_remote_get_background(void) | 133 | unsigned lcd_remote_get_background(void) |
96 | { | 134 | { |
97 | return (~bg_pattern >> 7) & 3; | 135 | return current_vp->bg_pattern; |
98 | } | 136 | } |
99 | 137 | ||
100 | void lcd_remote_set_drawinfo(int mode, unsigned fg_brightness, | 138 | void lcd_remote_set_drawinfo(int mode, unsigned fg_brightness, |
@@ -105,30 +143,40 @@ void lcd_remote_set_drawinfo(int mode, unsigned fg_brightness, | |||
105 | lcd_remote_set_background(bg_brightness); | 143 | lcd_remote_set_background(bg_brightness); |
106 | } | 144 | } |
107 | 145 | ||
146 | int lcd_remote_getwidth(void) | ||
147 | { | ||
148 | return current_vp->width; | ||
149 | } | ||
150 | |||
151 | int lcd_remote_getheight(void) | ||
152 | { | ||
153 | return current_vp->height; | ||
154 | } | ||
155 | |||
108 | void lcd_remote_setmargins(int x, int y) | 156 | void lcd_remote_setmargins(int x, int y) |
109 | { | 157 | { |
110 | xmargin = x; | 158 | current_vp->xmargin = x; |
111 | ymargin = y; | 159 | current_vp->ymargin = y; |
112 | } | 160 | } |
113 | 161 | ||
114 | int lcd_remote_getxmargin(void) | 162 | int lcd_remote_getxmargin(void) |
115 | { | 163 | { |
116 | return xmargin; | 164 | return current_vp->xmargin; |
117 | } | 165 | } |
118 | 166 | ||
119 | int lcd_remote_getymargin(void) | 167 | int lcd_remote_getymargin(void) |
120 | { | 168 | { |
121 | return ymargin; | 169 | return current_vp->ymargin; |
122 | } | 170 | } |
123 | 171 | ||
124 | void lcd_remote_setfont(int newfont) | 172 | void lcd_remote_setfont(int newfont) |
125 | { | 173 | { |
126 | curfont = newfont; | 174 | current_vp->font = newfont; |
127 | } | 175 | } |
128 | 176 | ||
129 | int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) | 177 | int lcd_remote_getstringsize(const unsigned char *str, int *w, int *h) |
130 | { | 178 | { |
131 | return font_getstringsize(str, w, h, curfont); | 179 | return font_getstringsize(str, w, h, current_vp->font); |
132 | } | 180 | } |
133 | 181 | ||
134 | /*** low-level drawing functions ***/ | 182 | /*** low-level drawing functions ***/ |
@@ -351,9 +399,9 @@ static inline void setblock(fb_remote_data *address, unsigned mask, unsigned bit | |||
351 | /* Clear the whole display */ | 399 | /* Clear the whole display */ |
352 | void lcd_remote_clear_display(void) | 400 | void lcd_remote_clear_display(void) |
353 | { | 401 | { |
354 | if (drawmode & DRMODE_INVERSEVID) | 402 | if (default_vp.drawmode & DRMODE_INVERSEVID) |
355 | { | 403 | { |
356 | memset(lcd_remote_framebuffer, fg_pattern, | 404 | memset(lcd_remote_framebuffer, patterns[default_vp.fg_pattern & 3], |
357 | sizeof lcd_remote_framebuffer); | 405 | sizeof lcd_remote_framebuffer); |
358 | } | 406 | } |
359 | else | 407 | else |
@@ -362,18 +410,44 @@ void lcd_remote_clear_display(void) | |||
362 | memcpy(lcd_remote_framebuffer, remote_backdrop, | 410 | memcpy(lcd_remote_framebuffer, remote_backdrop, |
363 | sizeof lcd_remote_framebuffer); | 411 | sizeof lcd_remote_framebuffer); |
364 | else | 412 | else |
365 | memset(lcd_remote_framebuffer, bg_pattern, | 413 | memset(lcd_remote_framebuffer, patterns[default_vp.bg_pattern & 3], |
366 | sizeof lcd_remote_framebuffer); | 414 | sizeof lcd_remote_framebuffer); |
367 | } | 415 | } |
368 | 416 | ||
369 | lcd_remote_scroll_info.lines = 0; | 417 | lcd_remote_scroll_info.lines = 0; |
370 | } | 418 | } |
371 | 419 | ||
420 | /* Clear the current viewport */ | ||
421 | void lcd_remote_clear_viewport(void) | ||
422 | { | ||
423 | int lastmode; | ||
424 | |||
425 | if (current_vp == &default_vp) | ||
426 | { | ||
427 | lcd_remote_clear_display(); | ||
428 | } | ||
429 | else | ||
430 | { | ||
431 | lastmode = current_vp->drawmode; | ||
432 | |||
433 | /* Invert the INVERSEVID bit and set basic mode to SOLID */ | ||
434 | current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) | | ||
435 | DRMODE_SOLID; | ||
436 | |||
437 | lcd_remote_fillrect(0, 0, current_vp->width, current_vp->height); | ||
438 | |||
439 | current_vp->drawmode = lastmode; | ||
440 | |||
441 | lcd_remote_scroll_stop(current_vp); | ||
442 | } | ||
443 | } | ||
444 | |||
372 | /* Set a single pixel */ | 445 | /* Set a single pixel */ |
373 | void lcd_remote_drawpixel(int x, int y) | 446 | void lcd_remote_drawpixel(int x, int y) |
374 | { | 447 | { |
375 | if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT)) | 448 | if (((unsigned)x < (unsigned)current_vp->width) && |
376 | lcd_remote_pixelfuncs[drawmode](x, y); | 449 | ((unsigned)y < (unsigned)current_vp->height)) |
450 | lcd_remote_pixelfuncs[current_vp->drawmode](current_vp->x+x, current_vp->y+y); | ||
377 | } | 451 | } |
378 | 452 | ||
379 | /* Draw a line */ | 453 | /* Draw a line */ |
@@ -385,7 +459,7 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2) | |||
385 | int d, dinc1, dinc2; | 459 | int d, dinc1, dinc2; |
386 | int x, xinc1, xinc2; | 460 | int x, xinc1, xinc2; |
387 | int y, yinc1, yinc2; | 461 | int y, yinc1, yinc2; |
388 | lcd_remote_pixelfunc_type *pfunc = lcd_remote_pixelfuncs[drawmode]; | 462 | lcd_remote_pixelfunc_type *pfunc = lcd_remote_pixelfuncs[current_vp->drawmode]; |
389 | 463 | ||
390 | deltax = abs(x2 - x1); | 464 | deltax = abs(x2 - x1); |
391 | deltay = abs(y2 - y1); | 465 | deltay = abs(y2 - y1); |
@@ -429,8 +503,9 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2) | |||
429 | 503 | ||
430 | for (i = 0; i < numpixels; i++) | 504 | for (i = 0; i < numpixels; i++) |
431 | { | 505 | { |
432 | if (((unsigned)x < LCD_REMOTE_WIDTH) && ((unsigned)y < LCD_REMOTE_HEIGHT)) | 506 | if (((unsigned)x < (unsigned)current_vp->width) && |
433 | pfunc(x, y); | 507 | ((unsigned)y < (unsigned)current_vp->height)) |
508 | pfunc(current_vp->x + x, current_vp->y + y); | ||
434 | 509 | ||
435 | if (d < 0) | 510 | if (d < 0) |
436 | { | 511 | { |
@@ -451,6 +526,7 @@ void lcd_remote_drawline(int x1, int y1, int x2, int y2) | |||
451 | void lcd_remote_hline(int x1, int x2, int y) | 526 | void lcd_remote_hline(int x1, int x2, int y) |
452 | { | 527 | { |
453 | int x; | 528 | int x; |
529 | int width; | ||
454 | fb_remote_data *dst, *dst_end; | 530 | fb_remote_data *dst, *dst_end; |
455 | unsigned mask; | 531 | unsigned mask; |
456 | lcd_remote_blockfunc_type *bfunc; | 532 | lcd_remote_blockfunc_type *bfunc; |
@@ -464,24 +540,30 @@ void lcd_remote_hline(int x1, int x2, int y) | |||
464 | } | 540 | } |
465 | 541 | ||
466 | /* nothing to draw? */ | 542 | /* nothing to draw? */ |
467 | if (((unsigned)y >= LCD_REMOTE_HEIGHT) || (x1 >= LCD_REMOTE_WIDTH) | 543 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) |
468 | || (x2 < 0)) | 544 | || (x2 < 0)) |
469 | return; | 545 | return; |
470 | 546 | ||
471 | /* clipping */ | 547 | /* clipping */ |
472 | if (x1 < 0) | 548 | if (x1 < 0) |
473 | x1 = 0; | 549 | x1 = 0; |
474 | if (x2 >= LCD_REMOTE_WIDTH) | 550 | if (x2 >= current_vp->width) |
475 | x2 = LCD_REMOTE_WIDTH-1; | 551 | x2 = current_vp->width-1; |
476 | 552 | ||
477 | bfunc = lcd_remote_blockfuncs[drawmode]; | 553 | width = x2 - x1 + 1; |
554 | |||
555 | /* adjust x1 and y to viewport */ | ||
556 | x1 += current_vp->x; | ||
557 | y += current_vp->y; | ||
558 | |||
559 | bfunc = lcd_remote_blockfuncs[current_vp->drawmode]; | ||
478 | dst = &lcd_remote_framebuffer[y>>3][x1]; | 560 | dst = &lcd_remote_framebuffer[y>>3][x1]; |
479 | mask = 0x0101 << (y & 7); | 561 | mask = 0x0101 << (y & 7); |
480 | 562 | ||
481 | dst_end = dst + x2 - x1; | 563 | dst_end = dst + width; |
482 | do | 564 | do |
483 | bfunc(dst++, mask, 0xFFFFu); | 565 | bfunc(dst++, mask, 0xFFFFu); |
484 | while (dst <= dst_end); | 566 | while (dst < dst_end); |
485 | } | 567 | } |
486 | 568 | ||
487 | /* Draw a vertical line (optimised) */ | 569 | /* Draw a vertical line (optimised) */ |
@@ -501,17 +583,22 @@ void lcd_remote_vline(int x, int y1, int y2) | |||
501 | } | 583 | } |
502 | 584 | ||
503 | /* nothing to draw? */ | 585 | /* nothing to draw? */ |
504 | if (((unsigned)x >= LCD_REMOTE_WIDTH) || (y1 >= LCD_REMOTE_HEIGHT) | 586 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) |
505 | || (y2 < 0)) | 587 | || (y2 < 0)) |
506 | return; | 588 | return; |
507 | 589 | ||
508 | /* clipping */ | 590 | /* clipping */ |
509 | if (y1 < 0) | 591 | if (y1 < 0) |
510 | y1 = 0; | 592 | y1 = 0; |
511 | if (y2 >= LCD_REMOTE_HEIGHT) | 593 | if (y2 >= current_vp->height) |
512 | y2 = LCD_REMOTE_HEIGHT-1; | 594 | y2 = current_vp->height-1; |
595 | |||
596 | /* adjust for viewport */ | ||
597 | y1 += current_vp->y; | ||
598 | y2 += current_vp->y; | ||
599 | x += current_vp->x; | ||
513 | 600 | ||
514 | bfunc = lcd_remote_blockfuncs[drawmode]; | 601 | bfunc = lcd_remote_blockfuncs[current_vp->drawmode]; |
515 | dst = &lcd_remote_framebuffer[y1>>3][x]; | 602 | dst = &lcd_remote_framebuffer[y1>>3][x]; |
516 | ny = y2 - (y1 & ~7); | 603 | ny = y2 - (y1 & ~7); |
517 | mask = (0xFFu << (y1 & 7)) & 0xFFu; | 604 | mask = (0xFFu << (y1 & 7)) & 0xFFu; |
@@ -555,8 +642,8 @@ void lcd_remote_fillrect(int x, int y, int width, int height) | |||
555 | bool fillopt = false; | 642 | bool fillopt = false; |
556 | 643 | ||
557 | /* nothing to draw? */ | 644 | /* nothing to draw? */ |
558 | if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) | 645 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
559 | || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) | 646 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
560 | return; | 647 | return; |
561 | 648 | ||
562 | /* clipping */ | 649 | /* clipping */ |
@@ -570,14 +657,18 @@ void lcd_remote_fillrect(int x, int y, int width, int height) | |||
570 | height += y; | 657 | height += y; |
571 | y = 0; | 658 | y = 0; |
572 | } | 659 | } |
573 | if (x + width > LCD_REMOTE_WIDTH) | 660 | if (x + width > current_vp->width) |
574 | width = LCD_REMOTE_WIDTH - x; | 661 | width = current_vp->width - x; |
575 | if (y + height > LCD_REMOTE_HEIGHT) | 662 | if (y + height > current_vp->height) |
576 | height = LCD_REMOTE_HEIGHT - y; | 663 | height = current_vp->height - y; |
577 | 664 | ||
578 | if (drawmode & DRMODE_INVERSEVID) | 665 | /* adjust for viewport */ |
666 | x += current_vp->x; | ||
667 | y += current_vp->y; | ||
668 | |||
669 | if (current_vp->drawmode & DRMODE_INVERSEVID) | ||
579 | { | 670 | { |
580 | if ((drawmode & DRMODE_BG) && !remote_backdrop) | 671 | if ((current_vp->drawmode & DRMODE_BG) && !remote_backdrop) |
581 | { | 672 | { |
582 | fillopt = true; | 673 | fillopt = true; |
583 | bits = bg_pattern; | 674 | bits = bg_pattern; |
@@ -585,13 +676,13 @@ void lcd_remote_fillrect(int x, int y, int width, int height) | |||
585 | } | 676 | } |
586 | else | 677 | else |
587 | { | 678 | { |
588 | if (drawmode & DRMODE_FG) | 679 | if (current_vp->drawmode & DRMODE_FG) |
589 | { | 680 | { |
590 | fillopt = true; | 681 | fillopt = true; |
591 | bits = fg_pattern; | 682 | bits = fg_pattern; |
592 | } | 683 | } |
593 | } | 684 | } |
594 | bfunc = lcd_remote_blockfuncs[drawmode]; | 685 | bfunc = lcd_remote_blockfuncs[current_vp->drawmode]; |
595 | dst = &lcd_remote_framebuffer[y>>3][x]; | 686 | dst = &lcd_remote_framebuffer[y>>3][x]; |
596 | ny = height - 1 + (y & 7); | 687 | ny = height - 1 + (y & 7); |
597 | mask = (0xFFu << (y & 7)) & 0xFFu; | 688 | mask = (0xFFu << (y & 7)) & 0xFFu; |
@@ -653,8 +744,8 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
653 | lcd_remote_blockfunc_type *bfunc; | 744 | lcd_remote_blockfunc_type *bfunc; |
654 | 745 | ||
655 | /* nothing to draw? */ | 746 | /* nothing to draw? */ |
656 | if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) | 747 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
657 | || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) | 748 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
658 | return; | 749 | return; |
659 | 750 | ||
660 | /* clipping */ | 751 | /* clipping */ |
@@ -670,10 +761,14 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
670 | src_y -= y; | 761 | src_y -= y; |
671 | y = 0; | 762 | y = 0; |
672 | } | 763 | } |
673 | if (x + width > LCD_REMOTE_WIDTH) | 764 | if (x + width > current_vp->width) |
674 | width = LCD_REMOTE_WIDTH - x; | 765 | width = current_vp->width - x; |
675 | if (y + height > LCD_REMOTE_HEIGHT) | 766 | if (y + height > current_vp->height) |
676 | height = LCD_REMOTE_HEIGHT - y; | 767 | height = current_vp->height - y; |
768 | |||
769 | /* adjust for viewport */ | ||
770 | x += current_vp->x; | ||
771 | y += current_vp->y; | ||
677 | 772 | ||
678 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 773 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
679 | src_y &= 7; | 774 | src_y &= 7; |
@@ -682,7 +777,7 @@ void lcd_remote_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
682 | shift = y & 7; | 777 | shift = y & 7; |
683 | ny = height - 1 + shift + src_y; | 778 | ny = height - 1 + shift + src_y; |
684 | 779 | ||
685 | bfunc = lcd_remote_blockfuncs[drawmode]; | 780 | bfunc = lcd_remote_blockfuncs[current_vp->drawmode]; |
686 | mask = 0xFFu << (shift + src_y); | 781 | mask = 0xFFu << (shift + src_y); |
687 | /* not byte-doubled here because shift+src_y can be > 7 */ | 782 | /* not byte-doubled here because shift+src_y can be > 7 */ |
688 | mask_bottom = 0xFFu >> (~ny & 7); | 783 | mask_bottom = 0xFFu >> (~ny & 7); |
@@ -793,8 +888,8 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y, | |||
793 | unsigned mask, mask_bottom; | 888 | unsigned mask, mask_bottom; |
794 | 889 | ||
795 | /* nothing to draw? */ | 890 | /* nothing to draw? */ |
796 | if ((width <= 0) || (height <= 0) || (x >= LCD_REMOTE_WIDTH) | 891 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
797 | || (y >= LCD_REMOTE_HEIGHT) || (x + width <= 0) || (y + height <= 0)) | 892 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
798 | return; | 893 | return; |
799 | 894 | ||
800 | /* clipping */ | 895 | /* clipping */ |
@@ -810,10 +905,14 @@ void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x, int src_y, | |||
810 | src_y -= y; | 905 | src_y -= y; |
811 | y = 0; | 906 | y = 0; |
812 | } | 907 | } |
813 | if (x + width > LCD_REMOTE_WIDTH) | 908 | if (x + width > current_vp->width) |
814 | width = LCD_REMOTE_WIDTH - x; | 909 | width = current_vp->width - x; |
815 | if (y + height > LCD_REMOTE_HEIGHT) | 910 | if (y + height > current_vp->height) |
816 | height = LCD_REMOTE_HEIGHT - y; | 911 | height = current_vp->height - y; |
912 | |||
913 | /* adjust for viewport */ | ||
914 | x += current_vp->x; | ||
915 | y += current_vp->y; | ||
817 | 916 | ||
818 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 917 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
819 | src_y &= 7; | 918 | src_y &= 7; |
@@ -917,11 +1016,11 @@ void lcd_remote_putsxyofs(int x, int y, int ofs, const unsigned char *str) | |||
917 | { | 1016 | { |
918 | unsigned short ch; | 1017 | unsigned short ch; |
919 | unsigned short *ucs; | 1018 | unsigned short *ucs; |
920 | struct font* pf = font_get(curfont); | 1019 | struct font* pf = font_get(current_vp->font); |
921 | 1020 | ||
922 | ucs = bidi_l2v(str, 1); | 1021 | ucs = bidi_l2v(str, 1); |
923 | 1022 | ||
924 | while ((ch = *ucs++) != 0 && x < LCD_REMOTE_WIDTH) | 1023 | while ((ch = *ucs++) != 0 && x < current_vp->width) |
925 | { | 1024 | { |
926 | int width; | 1025 | int width; |
927 | const unsigned char *bits; | 1026 | const unsigned char *bits; |
@@ -975,24 +1074,24 @@ void lcd_remote_puts_style_offset(int x, int y, const unsigned char *str, | |||
975 | int style, int offset) | 1074 | int style, int offset) |
976 | { | 1075 | { |
977 | int xpos,ypos,w,h,xrect; | 1076 | int xpos,ypos,w,h,xrect; |
978 | int lastmode = drawmode; | 1077 | int lastmode = current_vp->drawmode; |
979 | 1078 | ||
980 | /* make sure scrolling is turned off on the line we are updating */ | 1079 | /* make sure scrolling is turned off on the line we are updating */ |
981 | lcd_remote_scroll_info.lines &= ~(1 << y); | 1080 | lcd_remote_scroll_stop_line(current_vp, y); |
982 | 1081 | ||
983 | if(!str || !str[0]) | 1082 | if(!str || !str[0]) |
984 | return; | 1083 | return; |
985 | 1084 | ||
986 | lcd_remote_getstringsize(str, &w, &h); | 1085 | lcd_remote_getstringsize(str, &w, &h); |
987 | xpos = xmargin + x*w / utf8length((char *)str); | 1086 | xpos = current_vp->xmargin + x*w / utf8length((char *)str); |
988 | ypos = ymargin + y*h; | 1087 | ypos = current_vp->ymargin + y*h; |
989 | drawmode = (style & STYLE_INVERT) ? | 1088 | current_vp->drawmode = (style & STYLE_INVERT) ? |
990 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 1089 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
991 | lcd_remote_putsxyofs(xpos, ypos, offset, str); | 1090 | lcd_remote_putsxyofs(xpos, ypos, offset, str); |
992 | drawmode ^= DRMODE_INVERSEVID; | 1091 | current_vp->drawmode ^= DRMODE_INVERSEVID; |
993 | xrect = xpos + MAX(w - offset, 0); | 1092 | xrect = xpos + MAX(w - offset, 0); |
994 | lcd_remote_fillrect(xrect, ypos, LCD_REMOTE_WIDTH - xrect, h); | 1093 | lcd_remote_fillrect(xrect, ypos, current_vp->width - xrect, h); |
995 | drawmode = lastmode; | 1094 | current_vp->drawmode = lastmode; |
996 | } | 1095 | } |
997 | 1096 | ||
998 | /*** scrolling ***/ | 1097 | /*** scrolling ***/ |
@@ -1017,9 +1116,15 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
1017 | struct scrollinfo* s; | 1116 | struct scrollinfo* s; |
1018 | int w, h; | 1117 | int w, h; |
1019 | 1118 | ||
1020 | if(y>=LCD_REMOTE_SCROLLABLE_LINES) return; | 1119 | if ((unsigned)y >= (unsigned)current_vp->height) |
1120 | return; | ||
1021 | 1121 | ||
1022 | s = &lcd_remote_scroll_info.scroll[y]; | 1122 | /* remove any previously scrolling line at the same location */ |
1123 | lcd_remote_scroll_stop_line(current_vp, y); | ||
1124 | |||
1125 | if (lcd_remote_scroll_info.lines >= LCD_REMOTE_SCROLLABLE_LINES) return; | ||
1126 | |||
1127 | s = &lcd_remote_scroll_info.scroll[lcd_remote_scroll_info.lines]; | ||
1023 | 1128 | ||
1024 | s->start_tick = current_tick + lcd_remote_scroll_info.delay; | 1129 | s->start_tick = current_tick + lcd_remote_scroll_info.delay; |
1025 | s->style = style; | 1130 | s->style = style; |
@@ -1031,7 +1136,7 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
1031 | 1136 | ||
1032 | lcd_remote_getstringsize(string, &w, &h); | 1137 | lcd_remote_getstringsize(string, &w, &h); |
1033 | 1138 | ||
1034 | if (LCD_REMOTE_WIDTH - x * 8 - xmargin < w) { | 1139 | if (current_vp->width - x * 8 - current_vp->xmargin < w) { |
1035 | /* prepare scroll line */ | 1140 | /* prepare scroll line */ |
1036 | char *end; | 1141 | char *end; |
1037 | 1142 | ||
@@ -1044,7 +1149,7 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
1044 | /* scroll bidirectional or forward only depending on the string | 1149 | /* scroll bidirectional or forward only depending on the string |
1045 | width */ | 1150 | width */ |
1046 | if ( lcd_remote_scroll_info.bidir_limit ) { | 1151 | if ( lcd_remote_scroll_info.bidir_limit ) { |
1047 | s->bidir = s->width < (LCD_REMOTE_WIDTH - xmargin) * | 1152 | s->bidir = s->width < (current_vp->width - current_vp->xmargin) * |
1048 | (100 + lcd_remote_scroll_info.bidir_limit) / 100; | 1153 | (100 + lcd_remote_scroll_info.bidir_limit) / 100; |
1049 | } | 1154 | } |
1050 | else | 1155 | else |
@@ -1057,17 +1162,17 @@ void lcd_remote_puts_scroll_style_offset(int x, int y, const unsigned char *stri | |||
1057 | } | 1162 | } |
1058 | 1163 | ||
1059 | end = strchr(s->line, '\0'); | 1164 | end = strchr(s->line, '\0'); |
1060 | strncpy(end, (char *)string, LCD_REMOTE_WIDTH/2); | 1165 | strncpy(end, (char *)string, current_vp->width/2); |
1061 | 1166 | ||
1167 | s->vp = current_vp; | ||
1168 | s->y = y; | ||
1062 | s->len = utf8length((char *)string); | 1169 | s->len = utf8length((char *)string); |
1063 | s->offset = offset; | 1170 | s->offset = offset; |
1064 | s->startx = xmargin + x * s->width / s->len;; | 1171 | s->startx = current_vp->xmargin + x * s->width / s->len; |
1065 | s->backward = false; | 1172 | s->backward = false; |
1066 | lcd_remote_scroll_info.lines |= (1<<y); | 1173 | |
1174 | lcd_remote_scroll_info.lines++; | ||
1067 | } | 1175 | } |
1068 | else | ||
1069 | /* force a bit switch-off since it doesn't scroll */ | ||
1070 | lcd_remote_scroll_info.lines &= ~(1<<y); | ||
1071 | } | 1176 | } |
1072 | 1177 | ||
1073 | void lcd_remote_scroll_fn(void) | 1178 | void lcd_remote_scroll_fn(void) |
@@ -1077,26 +1182,25 @@ void lcd_remote_scroll_fn(void) | |||
1077 | int index; | 1182 | int index; |
1078 | int xpos, ypos; | 1183 | int xpos, ypos; |
1079 | int lastmode; | 1184 | int lastmode; |
1185 | struct viewport* old_vp = current_vp; | ||
1080 | 1186 | ||
1081 | for ( index = 0; index < LCD_REMOTE_SCROLLABLE_LINES; index++ ) { | 1187 | for ( index = 0; index < lcd_remote_scroll_info.lines; index++ ) { |
1082 | /* really scroll? */ | ||
1083 | if ((lcd_remote_scroll_info.lines & (1 << index)) == 0) | ||
1084 | continue; | ||
1085 | |||
1086 | s = &lcd_remote_scroll_info.scroll[index]; | 1188 | s = &lcd_remote_scroll_info.scroll[index]; |
1087 | 1189 | ||
1088 | /* check pause */ | 1190 | /* check pause */ |
1089 | if (TIME_BEFORE(current_tick, s->start_tick)) | 1191 | if (TIME_BEFORE(current_tick, s->start_tick)) |
1090 | continue; | 1192 | continue; |
1091 | 1193 | ||
1194 | lcd_remote_set_viewport(s->vp); | ||
1195 | |||
1092 | if (s->backward) | 1196 | if (s->backward) |
1093 | s->offset -= lcd_remote_scroll_info.step; | 1197 | s->offset -= lcd_remote_scroll_info.step; |
1094 | else | 1198 | else |
1095 | s->offset += lcd_remote_scroll_info.step; | 1199 | s->offset += lcd_remote_scroll_info.step; |
1096 | 1200 | ||
1097 | pf = font_get(curfont); | 1201 | pf = font_get(current_vp->font); |
1098 | xpos = s->startx; | 1202 | xpos = s->startx; |
1099 | ypos = ymargin + index * pf->height; | 1203 | ypos = current_vp->ymargin + s->y * pf->height; |
1100 | 1204 | ||
1101 | if (s->bidir) { /* scroll bidirectional */ | 1205 | if (s->bidir) { /* scroll bidirectional */ |
1102 | if (s->offset <= 0) { | 1206 | if (s->offset <= 0) { |
@@ -1105,9 +1209,9 @@ void lcd_remote_scroll_fn(void) | |||
1105 | s->backward = false; | 1209 | s->backward = false; |
1106 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; | 1210 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; |
1107 | } | 1211 | } |
1108 | if (s->offset >= s->width - (LCD_REMOTE_WIDTH - xpos)) { | 1212 | if (s->offset >= s->width - (current_vp->width - xpos)) { |
1109 | /* at end of line */ | 1213 | /* at end of line */ |
1110 | s->offset = s->width - (LCD_REMOTE_WIDTH - xpos); | 1214 | s->offset = s->width - (current_vp->width - xpos); |
1111 | s->backward = true; | 1215 | s->backward = true; |
1112 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; | 1216 | s->start_tick = current_tick + lcd_remote_scroll_info.delay*2; |
1113 | } | 1217 | } |
@@ -1118,18 +1222,24 @@ void lcd_remote_scroll_fn(void) | |||
1118 | s->offset %= s->width; | 1222 | s->offset %= s->width; |
1119 | } | 1223 | } |
1120 | 1224 | ||
1121 | lastmode = drawmode; | 1225 | lastmode = current_vp->drawmode; |
1122 | drawmode = (s->style&STYLE_INVERT) ? | 1226 | current_vp->drawmode = (s->style&STYLE_INVERT) ? |
1123 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; | 1227 | (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; |
1124 | lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); | 1228 | lcd_remote_putsxyofs(xpos, ypos, s->offset, s->line); |
1125 | drawmode = lastmode; | 1229 | current_vp->drawmode = lastmode; |
1126 | lcd_remote_update_rect(xpos, ypos, LCD_REMOTE_WIDTH - xpos, pf->height); | 1230 | lcd_remote_update_viewport_rect(xpos, ypos, |
1231 | current_vp->width - xpos, pf->height); | ||
1127 | } | 1232 | } |
1233 | |||
1234 | lcd_remote_set_viewport(old_vp); | ||
1128 | } | 1235 | } |
1129 | 1236 | ||
1130 | /* LCD init */ | 1237 | /* LCD init */ |
1131 | void lcd_remote_init(void) | 1238 | void lcd_remote_init(void) |
1132 | { | 1239 | { |
1240 | /* Initialise the viewport */ | ||
1241 | lcd_remote_set_viewport(NULL); | ||
1242 | |||
1133 | #ifndef SIMULATOR | 1243 | #ifndef SIMULATOR |
1134 | /* Call device specific init */ | 1244 | /* Call device specific init */ |
1135 | lcd_remote_init_device(); | 1245 | lcd_remote_init_device(); |