summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-2bit-vert.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-2bit-vert.c')
-rw-r--r--firmware/drivers/lcd-2bit-vert.c210
1 files changed, 121 insertions, 89 deletions
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c
index 501e568a69..a099c45e98 100644
--- a/firmware/drivers/lcd-2bit-vert.c
+++ b/firmware/drivers/lcd-2bit-vert.c
@@ -36,8 +36,8 @@
36 36
37/*** globals ***/ 37/*** globals ***/
38 38
39fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER; 39static fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER;
40fb_data *lcd_framebuffer = &lcd_static_framebuffer[0][0]; 40static void *lcd_frameaddress_default(int x, int y);
41 41
42const unsigned char lcd_dibits[16] ICONST_ATTR = { 42const unsigned char lcd_dibits[16] ICONST_ATTR = {
43 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F, 43 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F,
@@ -51,6 +51,15 @@ static const unsigned char pixmask[4] ICONST_ATTR = {
51static fb_data* lcd_backdrop = NULL; 51static fb_data* lcd_backdrop = NULL;
52static long lcd_backdrop_offset IDATA_ATTR = 0; 52static long lcd_backdrop_offset IDATA_ATTR = 0;
53 53
54/* shouldn't be changed unless you want system-wide framebuffer changes! */
55struct frame_buffer_t lcd_framebuffer_default =
56{
57 .fb_ptr = &lcd_static_framebuffer[0][0],
58 .get_address_fn = &lcd_frameaddress_default,
59 .stride = STRIDE_MAIN(LCD_WIDTH, LCD_HEIGHT),
60 .elems = (LCD_FBWIDTH*LCD_FBHEIGHT),
61};
62
54static struct viewport default_vp = 63static struct viewport default_vp =
55{ 64{
56 .x = 0, 65 .x = 0,
@@ -59,18 +68,32 @@ static struct viewport default_vp =
59 .height = LCD_HEIGHT, 68 .height = LCD_HEIGHT,
60 .font = FONT_SYSFIXED, 69 .font = FONT_SYSFIXED,
61 .drawmode = DRMODE_SOLID, 70 .drawmode = DRMODE_SOLID,
71 .buffer = NULL,
62 .fg_pattern = LCD_DEFAULT_FG, 72 .fg_pattern = LCD_DEFAULT_FG,
63 .bg_pattern = LCD_DEFAULT_BG 73 .bg_pattern = LCD_DEFAULT_BG
64}; 74};
65 75
66static struct viewport* current_vp IBSS_ATTR; 76struct viewport* lcd_current_viewport IBSS_ATTR;
67static unsigned fg_pattern IBSS_ATTR; 77static unsigned fg_pattern IBSS_ATTR;
68static unsigned bg_pattern IBSS_ATTR; 78static unsigned bg_pattern IBSS_ATTR;
69 79
80static void *lcd_frameaddress_default(int x, int y)
81{
82 /* the default expects a buffer the same size as the screen */
83 struct frame_buffer_t *fb = lcd_current_viewport->buffer;
84
85#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
86 size_t element = (x * LCD_NATIVE_STRIDE(fb->stride)) + y;
87#else
88 size_t element = (y * LCD_NATIVE_STRIDE(fb->stride)) + x;
89#endif
90 return fb->fb_ptr + element; /*(element % fb->elems);*/
91}
92
70/* LCD init */ 93/* LCD init */
71void lcd_init(void) 94void lcd_init(void)
72{ 95{
73 /* Initialise the viewport */ 96 /* Initialize the viewport */
74 lcd_set_viewport(NULL); 97 lcd_set_viewport(NULL);
75 98
76 lcd_clear_display(); 99 lcd_clear_display();
@@ -83,34 +106,34 @@ void lcd_init(void)
83 106
84void lcd_set_drawmode(int mode) 107void lcd_set_drawmode(int mode)
85{ 108{
86 current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); 109 lcd_current_viewport->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
87} 110}
88 111
89int lcd_get_drawmode(void) 112int lcd_get_drawmode(void)
90{ 113{
91 return current_vp->drawmode; 114 return lcd_current_viewport->drawmode;
92} 115}
93 116
94void lcd_set_foreground(unsigned brightness) 117void lcd_set_foreground(unsigned brightness)
95{ 118{
96 current_vp->fg_pattern = brightness; 119 lcd_current_viewport->fg_pattern = brightness;
97 fg_pattern = 0x55 * (~brightness & 3); 120 fg_pattern = 0x55 * (~brightness & 3);
98} 121}
99 122
100unsigned lcd_get_foreground(void) 123unsigned lcd_get_foreground(void)
101{ 124{
102 return current_vp->fg_pattern; 125 return lcd_current_viewport->fg_pattern;
103} 126}
104 127
105void lcd_set_background(unsigned brightness) 128void lcd_set_background(unsigned brightness)
106{ 129{
107 current_vp->bg_pattern = brightness; 130 lcd_current_viewport->bg_pattern = brightness;
108 bg_pattern = 0x55 * (~brightness & 3); 131 bg_pattern = 0x55 * (~brightness & 3);
109} 132}
110 133
111unsigned lcd_get_background(void) 134unsigned lcd_get_background(void)
112{ 135{
113 return current_vp->bg_pattern; 136 return lcd_current_viewport->bg_pattern;
114} 137}
115 138
116void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness) 139void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
@@ -122,27 +145,27 @@ void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
122 145
123int lcd_getwidth(void) 146int lcd_getwidth(void)
124{ 147{
125 return current_vp->width; 148 return lcd_current_viewport->width;
126} 149}
127 150
128int lcd_getheight(void) 151int lcd_getheight(void)
129{ 152{
130 return current_vp->height; 153 return lcd_current_viewport->height;
131} 154}
132 155
133void lcd_setfont(int newfont) 156void lcd_setfont(int newfont)
134{ 157{
135 current_vp->font = newfont; 158 lcd_current_viewport->font = newfont;
136} 159}
137 160
138int lcd_getfont(void) 161int lcd_getfont(void)
139{ 162{
140 return current_vp->font; 163 return lcd_current_viewport->font;
141} 164}
142 165
143int lcd_getstringsize(const unsigned char *str, int *w, int *h) 166int lcd_getstringsize(const unsigned char *str, int *w, int *h)
144{ 167{
145 return font_getstringsize(str, w, h, current_vp->font); 168 return font_getstringsize(str, w, h, lcd_current_viewport->font);
146} 169}
147 170
148/*** low-level drawing functions ***/ 171/*** low-level drawing functions ***/
@@ -320,7 +343,7 @@ void lcd_set_backdrop(fb_data* backdrop)
320 lcd_backdrop = backdrop; 343 lcd_backdrop = backdrop;
321 if (backdrop) 344 if (backdrop)
322 { 345 {
323 lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer; 346 lcd_backdrop_offset = (long)backdrop - (long)FBADDR(0,0);
324 lcd_pixelfuncs = lcd_pixelfuncs_backdrop; 347 lcd_pixelfuncs = lcd_pixelfuncs_backdrop;
325 lcd_blockfuncs = lcd_blockfuncs_backdrop; 348 lcd_blockfuncs = lcd_blockfuncs_backdrop;
326 } 349 }
@@ -351,16 +374,16 @@ static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
351/* Clear the whole display */ 374/* Clear the whole display */
352void lcd_clear_display(void) 375void lcd_clear_display(void)
353{ 376{
354 if (current_vp->drawmode & DRMODE_INVERSEVID) 377 if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
355 { 378 {
356 memset(lcd_framebuffer, fg_pattern, FRAMEBUFFER_SIZE); 379 memset(FBADDR(0,0), fg_pattern, FRAMEBUFFER_SIZE);
357 } 380 }
358 else 381 else
359 { 382 {
360 if (lcd_backdrop) 383 if (lcd_backdrop)
361 memcpy(lcd_framebuffer, lcd_backdrop, FRAMEBUFFER_SIZE); 384 memcpy(FBADDR(0,0), lcd_backdrop, FRAMEBUFFER_SIZE);
362 else 385 else
363 memset(lcd_framebuffer, bg_pattern, FRAMEBUFFER_SIZE); 386 memset(FBADDR(0,0), bg_pattern, FRAMEBUFFER_SIZE);
364 } 387 }
365 388
366 lcd_scroll_info.lines = 0; 389 lcd_scroll_info.lines = 0;
@@ -371,37 +394,39 @@ void lcd_clear_viewport(void)
371{ 394{
372 int lastmode; 395 int lastmode;
373 396
374 if (current_vp == &default_vp) 397 if (lcd_current_viewport == &default_vp &&
398 default_vp.buffer == &lcd_framebuffer_default)
375 { 399 {
376 lcd_clear_display(); 400 lcd_clear_display();
377 } 401 }
378 else 402 else
379 { 403 {
380 lastmode = current_vp->drawmode; 404 lastmode = lcd_current_viewport->drawmode;
381 405
382 /* Invert the INVERSEVID bit and set basic mode to SOLID */ 406 /* Invert the INVERSEVID bit and set basic mode to SOLID */
383 current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) | 407 lcd_current_viewport->drawmode = (~lastmode & DRMODE_INVERSEVID) |
384 DRMODE_SOLID; 408 DRMODE_SOLID;
385 409
386 lcd_fillrect(0, 0, current_vp->width, current_vp->height); 410 lcd_fillrect(0, 0, lcd_current_viewport->width, lcd_current_viewport->height);
387 411
388 current_vp->drawmode = lastmode; 412 lcd_current_viewport->drawmode = lastmode;
389 413
390 lcd_scroll_stop_viewport(current_vp); 414 lcd_scroll_stop_viewport(lcd_current_viewport);
391 } 415 }
416 lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN);
392} 417}
393 418
394/* Set a single pixel */ 419/* Set a single pixel */
395void lcd_drawpixel(int x, int y) 420void lcd_drawpixel(int x, int y)
396{ 421{
397 if ( ((unsigned)x < (unsigned)current_vp->width) 422 if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
398 && ((unsigned)y < (unsigned)current_vp->height) 423 && ((unsigned)y < (unsigned)lcd_current_viewport->height)
399#if defined(HAVE_VIEWPORT_CLIP) 424#if defined(HAVE_VIEWPORT_CLIP)
400 && ((unsigned)x < (unsigned)LCD_WIDTH) 425 && ((unsigned)x < (unsigned)LCD_WIDTH)
401 && ((unsigned)y < (unsigned)LCD_HEIGHT) 426 && ((unsigned)y < (unsigned)LCD_HEIGHT)
402#endif 427#endif
403 ) 428 )
404 lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y); 429 lcd_pixelfuncs[lcd_current_viewport->drawmode](lcd_current_viewport->x + x, lcd_current_viewport->y + y);
405} 430}
406 431
407/* Draw a line */ 432/* Draw a line */
@@ -413,7 +438,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
413 int d, dinc1, dinc2; 438 int d, dinc1, dinc2;
414 int x, xinc1, xinc2; 439 int x, xinc1, xinc2;
415 int y, yinc1, yinc2; 440 int y, yinc1, yinc2;
416 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode]; 441 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode];
417 442
418 deltax = abs(x2 - x1); 443 deltax = abs(x2 - x1);
419 if (deltax == 0) 444 if (deltax == 0)
@@ -469,14 +494,14 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
469 494
470 for (i = 0; i < numpixels; i++) 495 for (i = 0; i < numpixels; i++)
471 { 496 {
472 if ( ((unsigned)x < (unsigned)current_vp->width) 497 if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
473 && ((unsigned)y < (unsigned)current_vp->height) 498 && ((unsigned)y < (unsigned)lcd_current_viewport->height)
474#if defined(HAVE_VIEWPORT_CLIP) 499#if defined(HAVE_VIEWPORT_CLIP)
475 && ((unsigned)x < (unsigned)LCD_WIDTH) 500 && ((unsigned)x < (unsigned)LCD_WIDTH)
476 && ((unsigned)y < (unsigned)LCD_HEIGHT) 501 && ((unsigned)y < (unsigned)LCD_HEIGHT)
477#endif 502#endif
478 ) 503 )
479 pfunc(current_vp->x + x, current_vp->y + y); 504 pfunc(lcd_current_viewport->x + x, lcd_current_viewport->y + y);
480 505
481 if (d < 0) 506 if (d < 0)
482 { 507 {
@@ -512,19 +537,19 @@ void lcd_hline(int x1, int x2, int y)
512 537
513 /******************** In viewport clipping **********************/ 538 /******************** In viewport clipping **********************/
514 /* nothing to draw? */ 539 /* nothing to draw? */
515 if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) 540 if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || (x1 >= lcd_current_viewport->width)
516 || (x2 < 0)) 541 || (x2 < 0))
517 return; 542 return;
518 543
519 if (x1 < 0) 544 if (x1 < 0)
520 x1 = 0; 545 x1 = 0;
521 if (x2 >= current_vp->width) 546 if (x2 >= lcd_current_viewport->width)
522 x2 = current_vp->width-1; 547 x2 = lcd_current_viewport->width-1;
523 548
524 /* adjust x1 and y to viewport */ 549 /* adjust x1 and y to viewport */
525 x1 += current_vp->x; 550 x1 += lcd_current_viewport->x;
526 x2 += current_vp->x; 551 x2 += lcd_current_viewport->x;
527 y += current_vp->y; 552 y += lcd_current_viewport->y;
528 553
529#if defined(HAVE_VIEWPORT_CLIP) 554#if defined(HAVE_VIEWPORT_CLIP)
530 /********************* Viewport on screen clipping ********************/ 555 /********************* Viewport on screen clipping ********************/
@@ -542,7 +567,7 @@ void lcd_hline(int x1, int x2, int y)
542 567
543 width = x2 - x1 + 1; 568 width = x2 - x1 + 1;
544 569
545 bfunc = lcd_blockfuncs[current_vp->drawmode]; 570 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
546 dst = FBADDR(x1,y>>2); 571 dst = FBADDR(x1,y>>2);
547 mask = pixmask[y & 3]; 572 mask = pixmask[y & 3];
548 573
@@ -557,6 +582,7 @@ void lcd_vline(int x, int y1, int y2)
557{ 582{
558 int ny; 583 int ny;
559 fb_data *dst; 584 fb_data *dst;
585 int stride_dst;
560 unsigned mask, mask_bottom; 586 unsigned mask, mask_bottom;
561 lcd_blockfunc_type *bfunc; 587 lcd_blockfunc_type *bfunc;
562 588
@@ -570,19 +596,19 @@ void lcd_vline(int x, int y1, int y2)
570 596
571 /******************** In viewport clipping **********************/ 597 /******************** In viewport clipping **********************/
572 /* nothing to draw? */ 598 /* nothing to draw? */
573 if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) 599 if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || (y1 >= lcd_current_viewport->height)
574 || (y2 < 0)) 600 || (y2 < 0))
575 return; 601 return;
576 602
577 if (y1 < 0) 603 if (y1 < 0)
578 y1 = 0; 604 y1 = 0;
579 if (y2 >= current_vp->height) 605 if (y2 >= lcd_current_viewport->height)
580 y2 = current_vp->height-1; 606 y2 = lcd_current_viewport->height-1;
581 607
582 /* adjust for viewport */ 608 /* adjust for viewport */
583 y1 += current_vp->y; 609 y1 += lcd_current_viewport->y;
584 y2 += current_vp->y; 610 y2 += lcd_current_viewport->y;
585 x += current_vp->x; 611 x += lcd_current_viewport->x;
586 612
587#if defined(HAVE_VIEWPORT_CLIP) 613#if defined(HAVE_VIEWPORT_CLIP)
588 /********************* Viewport on screen clipping ********************/ 614 /********************* Viewport on screen clipping ********************/
@@ -598,8 +624,9 @@ void lcd_vline(int x, int y1, int y2)
598 y2 = LCD_HEIGHT-1; 624 y2 = LCD_HEIGHT-1;
599#endif 625#endif
600 626
601 bfunc = lcd_blockfuncs[current_vp->drawmode]; 627 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
602 dst = FBADDR(x,y1>>2); 628 dst = FBADDR(x,y1>>2);
629 stride_dst = lcd_current_viewport->buffer->stride;
603 ny = y2 - (y1 & ~3); 630 ny = y2 - (y1 & ~3);
604 mask = 0xFFu << (2 * (y1 & 3)); 631 mask = 0xFFu << (2 * (y1 & 3));
605 mask_bottom = 0xFFu >> (2 * (~ny & 3)); 632 mask_bottom = 0xFFu >> (2 * (~ny & 3));
@@ -607,7 +634,7 @@ void lcd_vline(int x, int y1, int y2)
607 for (; ny >= 4; ny -= 4) 634 for (; ny >= 4; ny -= 4)
608 { 635 {
609 bfunc(dst, mask, 0xFFu); 636 bfunc(dst, mask, 0xFFu);
610 dst += LCD_WIDTH; 637 dst += stride_dst;
611 mask = 0xFFu; 638 mask = 0xFFu;
612 } 639 }
613 mask &= mask_bottom; 640 mask &= mask_bottom;
@@ -634,6 +661,7 @@ void lcd_fillrect(int x, int y, int width, int height)
634{ 661{
635 int ny; 662 int ny;
636 fb_data *dst, *dst_end; 663 fb_data *dst, *dst_end;
664 int stride_dst;
637 unsigned mask, mask_bottom; 665 unsigned mask, mask_bottom;
638 unsigned bits = 0; 666 unsigned bits = 0;
639 lcd_blockfunc_type *bfunc; 667 lcd_blockfunc_type *bfunc;
@@ -641,8 +669,8 @@ void lcd_fillrect(int x, int y, int width, int height)
641 669
642 /******************** In viewport clipping **********************/ 670 /******************** In viewport clipping **********************/
643 /* nothing to draw? */ 671 /* nothing to draw? */
644 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) 672 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width)
645 || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 673 || (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
646 return; 674 return;
647 675
648 if (x < 0) 676 if (x < 0)
@@ -655,14 +683,14 @@ void lcd_fillrect(int x, int y, int width, int height)
655 height += y; 683 height += y;
656 y = 0; 684 y = 0;
657 } 685 }
658 if (x + width > current_vp->width) 686 if (x + width > lcd_current_viewport->width)
659 width = current_vp->width - x; 687 width = lcd_current_viewport->width - x;
660 if (y + height > current_vp->height) 688 if (y + height > lcd_current_viewport->height)
661 height = current_vp->height - y; 689 height = lcd_current_viewport->height - y;
662 690
663 /* adjust for viewport */ 691 /* adjust for viewport */
664 x += current_vp->x; 692 x += lcd_current_viewport->x;
665 y += current_vp->y; 693 y += lcd_current_viewport->y;
666 694
667#if defined(HAVE_VIEWPORT_CLIP) 695#if defined(HAVE_VIEWPORT_CLIP)
668 /********************* Viewport on screen clipping ********************/ 696 /********************* Viewport on screen clipping ********************/
@@ -688,9 +716,9 @@ void lcd_fillrect(int x, int y, int width, int height)
688 height = LCD_HEIGHT - y; 716 height = LCD_HEIGHT - y;
689#endif 717#endif
690 718
691 if (current_vp->drawmode & DRMODE_INVERSEVID) 719 if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
692 { 720 {
693 if ((current_vp->drawmode & DRMODE_BG) && !lcd_backdrop) 721 if ((lcd_current_viewport->drawmode & DRMODE_BG) && !lcd_backdrop)
694 { 722 {
695 fillopt = true; 723 fillopt = true;
696 bits = bg_pattern; 724 bits = bg_pattern;
@@ -698,14 +726,15 @@ void lcd_fillrect(int x, int y, int width, int height)
698 } 726 }
699 else 727 else
700 { 728 {
701 if (current_vp->drawmode & DRMODE_FG) 729 if (lcd_current_viewport->drawmode & DRMODE_FG)
702 { 730 {
703 fillopt = true; 731 fillopt = true;
704 bits = fg_pattern; 732 bits = fg_pattern;
705 } 733 }
706 } 734 }
707 bfunc = lcd_blockfuncs[current_vp->drawmode]; 735 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
708 dst = FBADDR(x,y>>2); 736 dst = FBADDR(x,y>>2);
737 stride_dst = lcd_current_viewport->buffer->stride;
709 ny = height - 1 + (y & 3); 738 ny = height - 1 + (y & 3);
710 mask = 0xFFu << (2 * (y & 3)); 739 mask = 0xFFu << (2 * (y & 3));
711 mask_bottom = 0xFFu >> (2 * (~ny & 3)); 740 mask_bottom = 0xFFu >> (2 * (~ny & 3));
@@ -724,7 +753,7 @@ void lcd_fillrect(int x, int y, int width, int height)
724 while (dst_row < dst_end); 753 while (dst_row < dst_end);
725 } 754 }
726 755
727 dst += LCD_WIDTH; 756 dst += stride_dst;
728 mask = 0xFFu; 757 mask = 0xFFu;
729 } 758 }
730 mask &= mask_bottom; 759 mask &= mask_bottom;
@@ -758,13 +787,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
758{ 787{
759 int shift, ny; 788 int shift, ny;
760 fb_data *dst, *dst_end; 789 fb_data *dst, *dst_end;
790 int stride_dst;
761 unsigned mask, mask_bottom; 791 unsigned mask, mask_bottom;
762 lcd_blockfunc_type *bfunc; 792 lcd_blockfunc_type *bfunc;
763 793
764 /******************** Image in viewport clipping **********************/ 794 /******************** Image in viewport clipping **********************/
765 /* nothing to draw? */ 795 /* nothing to draw? */
766 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 796 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
767 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 797 (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
768 return; 798 return;
769 799
770 if (x < 0) 800 if (x < 0)
@@ -779,14 +809,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
779 src_y -= y; 809 src_y -= y;
780 y = 0; 810 y = 0;
781 } 811 }
782 if (x + width > current_vp->width) 812 if (x + width > lcd_current_viewport->width)
783 width = current_vp->width - x; 813 width = lcd_current_viewport->width - x;
784 if (y + height > current_vp->height) 814 if (y + height > lcd_current_viewport->height)
785 height = current_vp->height - y; 815 height = lcd_current_viewport->height - y;
786 816
787 /* adjust for viewport */ 817 /* adjust for viewport */
788 x += current_vp->x; 818 x += lcd_current_viewport->x;
789 y += current_vp->y; 819 y += lcd_current_viewport->y;
790 820
791#if defined(HAVE_VIEWPORT_CLIP) 821#if defined(HAVE_VIEWPORT_CLIP)
792 /********************* Viewport on screen clipping ********************/ 822 /********************* Viewport on screen clipping ********************/
@@ -818,13 +848,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
818 src_y &= 7; 848 src_y &= 7;
819 y -= src_y; 849 y -= src_y;
820 dst = FBADDR(x,y>>2); 850 dst = FBADDR(x,y>>2);
851 stride_dst = lcd_current_viewport->buffer->stride;
821 shift = y & 3; 852 shift = y & 3;
822 ny = height - 1 + shift + src_y; 853 ny = height - 1 + shift + src_y;
823 mask = 0xFFFFu << (2 * (shift + src_y)); 854 mask = 0xFFFFu << (2 * (shift + src_y));
824 /* Overflowing bits aren't important. */ 855 /* Overflowing bits aren't important. */
825 mask_bottom = 0xFFFFu >> (2 * (~ny & 7)); 856 mask_bottom = 0xFFFFu >> (2 * (~ny & 7));
826 857
827 bfunc = lcd_blockfuncs[current_vp->drawmode]; 858 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
828 859
829 if (shift == 0) 860 if (shift == 0)
830 { 861 {
@@ -836,7 +867,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
836 for (; ny >= 8; ny -= 8) 867 for (; ny >= 8; ny -= 8)
837 { 868 {
838 const unsigned char *src_row = src; 869 const unsigned char *src_row = src;
839 fb_data *dst_row = dst + LCD_WIDTH; 870 fb_data *dst_row = dst + stride_dst;
840 871
841 dst_end = dst_row + width; 872 dst_end = dst_row + width;
842 873
@@ -845,7 +876,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
845 do 876 do
846 { 877 {
847 data = *src_row++; 878 data = *src_row++;
848 bfunc(dst_row - LCD_WIDTH, dmask1, lcd_dibits[data&0x0F]); 879 bfunc(dst_row - stride_dst, dmask1, lcd_dibits[data&0x0F]);
849 bfunc(dst_row++, dmask2, lcd_dibits[(data>>4)&0x0F]); 880 bfunc(dst_row++, dmask2, lcd_dibits[(data>>4)&0x0F]);
850 } 881 }
851 while (dst_row < dst_end); 882 while (dst_row < dst_end);
@@ -857,7 +888,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
857 while (dst_row < dst_end); 888 while (dst_row < dst_end);
858 } 889 }
859 src += stride; 890 src += stride;
860 dst += 2*LCD_WIDTH; 891 dst += 2*stride_dst;
861 dmask1 = dmask2 = 0xFFu; 892 dmask1 = dmask2 = 0xFFu;
862 } 893 }
863 dmask1 &= mask_bottom; 894 dmask1 &= mask_bottom;
@@ -873,7 +904,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
873 { 904 {
874 data = *src++; 905 data = *src++;
875 bfunc(dst, dmask1, lcd_dibits[data&0x0F]); 906 bfunc(dst, dmask1, lcd_dibits[data&0x0F]);
876 bfunc((dst++) + LCD_WIDTH, dmask2, lcd_dibits[(data>>4)&0x0F]); 907 bfunc((dst++) + stride_dst, dmask2, lcd_dibits[(data>>4)&0x0F]);
877 } 908 }
878 while (dst < dst_end); 909 while (dst < dst_end);
879 } 910 }
@@ -887,7 +918,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
887 else 918 else
888 { 919 {
889 do 920 do
890 bfunc((dst++) + LCD_WIDTH, dmask2, lcd_dibits[((*src++)>>4)&0x0F]); 921 bfunc((dst++) + stride_dst, dmask2, lcd_dibits[((*src++)>>4)&0x0F]);
891 while (dst < dst_end); 922 while (dst < dst_end);
892 } 923 }
893 } 924 }
@@ -909,7 +940,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
909 { 940 {
910 if (mask_col & 0xFFu) 941 if (mask_col & 0xFFu)
911 bfunc(dst_col, mask_col, lcd_dibits[data&0x0F]); 942 bfunc(dst_col, mask_col, lcd_dibits[data&0x0F]);
912 bfunc(dst_col + LCD_WIDTH, mask_col >> 8, 943 bfunc(dst_col + stride_dst, mask_col >> 8,
913 lcd_dibits[(data>>4)&0x0F]); 944 lcd_dibits[(data>>4)&0x0F]);
914 mask_col = 0xFFFFu; 945 mask_col = 0xFFFFu;
915 } 946 }
@@ -917,7 +948,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
917 mask_col >>= 16; 948 mask_col >>= 16;
918 949
919 src_col += stride; 950 src_col += stride;
920 dst_col += 2*LCD_WIDTH; 951 dst_col += 2*stride_dst;
921 data >>= 8; 952 data >>= 8;
922 } 953 }
923 data |= *src_col << shift; 954 data |= *src_col << shift;
@@ -925,7 +956,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
925 if (mask_col & 0xFFu) 956 if (mask_col & 0xFFu)
926 bfunc(dst_col, mask_col, lcd_dibits[data&0x0F]); 957 bfunc(dst_col, mask_col, lcd_dibits[data&0x0F]);
927 if (mask_col & 0xFF00u) 958 if (mask_col & 0xFF00u)
928 bfunc(dst_col + LCD_WIDTH, mask_col >> 8, 959 bfunc(dst_col + stride_dst, mask_col >> 8,
929 lcd_dibits[(data>>4)&0x0F]); 960 lcd_dibits[(data>>4)&0x0F]);
930 } 961 }
931 while (dst < dst_end); 962 while (dst < dst_end);
@@ -956,12 +987,13 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
956{ 987{
957 int shift, ny; 988 int shift, ny;
958 fb_data *dst, *dst_end; 989 fb_data *dst, *dst_end;
990 int stride_dst;
959 unsigned mask, mask_bottom; 991 unsigned mask, mask_bottom;
960 992
961 /******************** Image in viewport clipping **********************/ 993 /******************** Image in viewport clipping **********************/
962 /* nothing to draw? */ 994 /* nothing to draw? */
963 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) 995 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width)
964 || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 996 || (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
965 return; 997 return;
966 998
967 if (x < 0) 999 if (x < 0)
@@ -976,14 +1008,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
976 src_y -= y; 1008 src_y -= y;
977 y = 0; 1009 y = 0;
978 } 1010 }
979 if (x + width > current_vp->width) 1011 if (x + width > lcd_current_viewport->width)
980 width = current_vp->width - x; 1012 width = lcd_current_viewport->width - x;
981 if (y + height > current_vp->height) 1013 if (y + height > lcd_current_viewport->height)
982 height = current_vp->height - y; 1014 height = lcd_current_viewport->height - y;
983 1015
984 /* adjust for viewport */ 1016 /* adjust for viewport */
985 x += current_vp->x; 1017 x += lcd_current_viewport->x;
986 y += current_vp->y; 1018 y += lcd_current_viewport->y;
987 1019
988#if defined(HAVE_VIEWPORT_CLIP) 1020#if defined(HAVE_VIEWPORT_CLIP)
989 /********************* Viewport on screen clipping ********************/ 1021 /********************* Viewport on screen clipping ********************/
@@ -1010,11 +1042,11 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
1010 if (y + height > LCD_HEIGHT) 1042 if (y + height > LCD_HEIGHT)
1011 height = LCD_HEIGHT - y; 1043 height = LCD_HEIGHT - y;
1012#endif 1044#endif
1013
1014 src += stride * (src_y >> 2) + src_x; /* move starting point */ 1045 src += stride * (src_y >> 2) + src_x; /* move starting point */
1015 src_y &= 3; 1046 src_y &= 3;
1016 y -= src_y; 1047 y -= src_y;
1017 dst = FBADDR(x,y>>2); 1048 dst = FBADDR(x,y>>2);
1049 stride_dst = lcd_current_viewport->buffer->stride;
1018 shift = y & 3; 1050 shift = y & 3;
1019 ny = height - 1 + shift + src_y; 1051 ny = height - 1 + shift + src_y;
1020 1052
@@ -1038,7 +1070,7 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
1038 while (dst_row < dst_end); 1070 while (dst_row < dst_end);
1039 } 1071 }
1040 src += stride; 1072 src += stride;
1041 dst += LCD_WIDTH; 1073 dst += stride_dst;
1042 mask = 0xFFu; 1074 mask = 0xFFu;
1043 } 1075 }
1044 mask &= mask_bottom; 1076 mask &= mask_bottom;
@@ -1077,7 +1109,7 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
1077 mask_col >>= 8; 1109 mask_col >>= 8;
1078 1110
1079 src_col += stride; 1111 src_col += stride;
1080 dst_col += LCD_WIDTH; 1112 dst_col += stride_dst;
1081 data >>= 8; 1113 data >>= 8;
1082 } 1114 }
1083 data |= *src_col << shift; 1115 data |= *src_col << shift;