summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-2bit-vi.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-2bit-vi.c')
-rw-r--r--firmware/drivers/lcd-2bit-vi.c202
1 files changed, 121 insertions, 81 deletions
diff --git a/firmware/drivers/lcd-2bit-vi.c b/firmware/drivers/lcd-2bit-vi.c
index 0608dfaa46..035e8b6d0d 100644
--- a/firmware/drivers/lcd-2bit-vi.c
+++ b/firmware/drivers/lcd-2bit-vi.c
@@ -46,17 +46,32 @@
46#define MAIN_LCD 46#define MAIN_LCD
47#endif 47#endif
48 48
49/*** globals ***/ 49#ifdef MAIN_LCD
50#define THIS_STRIDE STRIDE_MAIN
51#else
52#define THIS_STRIDE STRIDE_REMOTE
53#endif
50 54
51FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER; 55#define CURRENT_VP LCDFN(current_viewport)
52FBFN(data) *LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0]; 56/*** globals ***/
53 57
58static FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER;
59static void *LCDFN(frameaddress_default)(int x, int y);
54 60
55static const FBFN(data) patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000}; 61static const FBFN(data) patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
56 62
57static FBFN(data) *backdrop = NULL; 63static FBFN(data) *backdrop = NULL;
58static long backdrop_offset IDATA_ATTR = 0; 64static long backdrop_offset IDATA_ATTR = 0;
59 65
66/* shouldn't be changed unless you want system-wide framebuffer changes! */
67struct frame_buffer_t LCDFN(framebuffer_default) =
68{
69 .FBFN(ptr) = &LCDFN(static_framebuffer)[0][0],
70 .get_address_fn = &LCDFN(frameaddress_default),
71 .stride = THIS_STRIDE(LCDM(WIDTH), LCDM(HEIGHT)),
72 .elems = (LCDM(FBWIDTH)*LCDM(FBHEIGHT)),
73};
74
60static struct viewport default_vp = 75static struct viewport default_vp =
61{ 76{
62 .x = 0, 77 .x = 0,
@@ -65,19 +80,34 @@ static struct viewport default_vp =
65 .height = LCDM(HEIGHT), 80 .height = LCDM(HEIGHT),
66 .font = FONT_SYSFIXED, 81 .font = FONT_SYSFIXED,
67 .drawmode = DRMODE_SOLID, 82 .drawmode = DRMODE_SOLID,
83 .buffer = NULL,
68 .fg_pattern = LCDM(DEFAULT_FG), 84 .fg_pattern = LCDM(DEFAULT_FG),
69 .bg_pattern = LCDM(DEFAULT_BG) 85 .bg_pattern = LCDM(DEFAULT_BG)
70}; 86};
71 87
72static struct viewport * current_vp IBSS_ATTR; 88struct viewport * CURRENT_VP IBSS_ATTR;
73 89
74static unsigned fg_pattern IBSS_ATTR; 90static unsigned fg_pattern IBSS_ATTR;
75static unsigned bg_pattern IBSS_ATTR; 91static unsigned bg_pattern IBSS_ATTR;
76 92
93static void *LCDFN(frameaddress_default)(int x, int y)
94{
95 /* the default expects a buffer the same size as the screen */
96 struct frame_buffer_t *fb = CURRENT_VP->buffer;
97#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
98 size_t element = (x * LCDM(NATIVE_STRIDE)(fb->stride)) + y;
99#else
100 size_t element = (y * LCDM(NATIVE_STRIDE)(fb->stride)) + x;
101#endif
102 return fb->FBFN(ptr) + element;/*(element % fb->elems);*/
103}
104
77/* LCD init */ 105/* LCD init */
78void LCDFN(init)(void) 106void LCDFN(init)(void)
79{ 107{
108 /* Initialize the viewport */
80 LCDFN(set_viewport)(NULL); 109 LCDFN(set_viewport)(NULL);
110
81 LCDFN(clear_display)(); 111 LCDFN(clear_display)();
82 LCDFN(init_device)(); 112 LCDFN(init_device)();
83#ifdef MAIN_LCD 113#ifdef MAIN_LCD
@@ -105,34 +135,34 @@ unsigned lcd_remote_color_to_native(unsigned color)
105 135
106void LCDFN(set_drawmode)(int mode) 136void LCDFN(set_drawmode)(int mode)
107{ 137{
108 current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); 138 CURRENT_VP->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
109} 139}
110 140
111int LCDFN(get_drawmode)(void) 141int LCDFN(get_drawmode)(void)
112{ 142{
113 return current_vp->drawmode; 143 return CURRENT_VP->drawmode;
114} 144}
115 145
116void LCDFN(set_foreground)(unsigned brightness) 146void LCDFN(set_foreground)(unsigned brightness)
117{ 147{
118 current_vp->fg_pattern = brightness; 148 CURRENT_VP->fg_pattern = brightness;
119 fg_pattern = patterns[brightness & 3]; 149 fg_pattern = patterns[brightness & 3];
120} 150}
121 151
122unsigned LCDFN(get_foreground)(void) 152unsigned LCDFN(get_foreground)(void)
123{ 153{
124 return current_vp->fg_pattern; 154 return CURRENT_VP->fg_pattern;
125} 155}
126 156
127void LCDFN(set_background)(unsigned brightness) 157void LCDFN(set_background)(unsigned brightness)
128{ 158{
129 current_vp->bg_pattern = brightness; 159 CURRENT_VP->bg_pattern = brightness;
130 bg_pattern = patterns[brightness & 3]; 160 bg_pattern = patterns[brightness & 3];
131} 161}
132 162
133unsigned LCDFN(get_background)(void) 163unsigned LCDFN(get_background)(void)
134{ 164{
135 return current_vp->bg_pattern; 165 return CURRENT_VP->bg_pattern;
136} 166}
137 167
138void LCDFN(set_drawinfo)(int mode, unsigned fg_brightness, 168void LCDFN(set_drawinfo)(int mode, unsigned fg_brightness,
@@ -145,26 +175,26 @@ void LCDFN(set_drawinfo)(int mode, unsigned fg_brightness,
145 175
146int LCDFN(getwidth)(void) 176int LCDFN(getwidth)(void)
147{ 177{
148 return current_vp->width; 178 return CURRENT_VP->width;
149} 179}
150 180
151int LCDFN(getheight)(void) 181int LCDFN(getheight)(void)
152{ 182{
153 return current_vp->height; 183 return CURRENT_VP->height;
154} 184}
155void LCDFN(setfont)(int newfont) 185void LCDFN(setfont)(int newfont)
156{ 186{
157 current_vp->font = newfont; 187 CURRENT_VP->font = newfont;
158} 188}
159 189
160int LCDFN(getfont)(void) 190int LCDFN(getfont)(void)
161{ 191{
162 return current_vp->font; 192 return CURRENT_VP->font;
163} 193}
164 194
165int LCDFN(getstringsize)(const unsigned char *str, int *w, int *h) 195int LCDFN(getstringsize)(const unsigned char *str, int *w, int *h)
166{ 196{
167 return font_getstringsize(str, w, h, current_vp->font); 197 return font_getstringsize(str, w, h, CURRENT_VP->font);
168} 198}
169 199
170/*** low-level drawing functions ***/ 200/*** low-level drawing functions ***/
@@ -345,7 +375,7 @@ void LCDFN(set_backdrop)(FBFN(data) *bd)
345 backdrop = bd; 375 backdrop = bd;
346 if (bd) 376 if (bd)
347 { 377 {
348 backdrop_offset = (long)bd - (long)LCDFN(framebuffer); 378 backdrop_offset = (long)bd - (long)LCDFB(0, 0);
349 LCDFN(pixelfuncs) = LCDFN(pixelfuncs_backdrop); 379 LCDFN(pixelfuncs) = LCDFN(pixelfuncs_backdrop);
350 LCDFN(blockfuncs) = LCDFN(blockfuncs_backdrop); 380 LCDFN(blockfuncs) = LCDFN(blockfuncs_backdrop);
351 } 381 }
@@ -377,15 +407,15 @@ void LCDFN(clear_display)(void)
377{ 407{
378 if (default_vp.drawmode & DRMODE_INVERSEVID) 408 if (default_vp.drawmode & DRMODE_INVERSEVID)
379 { 409 {
380 memset(LCDFN(framebuffer), patterns[default_vp.fg_pattern & 3], 410 memset(LCDFB(0, 0), patterns[default_vp.fg_pattern & 3],
381 FBSIZE); 411 FBSIZE);
382 } 412 }
383 else 413 else
384 { 414 {
385 if (backdrop) 415 if (backdrop)
386 memcpy(LCDFN(framebuffer), backdrop, FBSIZE); 416 memcpy(LCDFB(0, 0), backdrop, FBSIZE);
387 else 417 else
388 memset(LCDFN(framebuffer), patterns[default_vp.bg_pattern & 3], 418 memset(LCDFB(0, 0), patterns[default_vp.bg_pattern & 3],
389 FBSIZE); 419 FBSIZE);
390 } 420 }
391 421
@@ -397,37 +427,39 @@ void LCDFN(clear_viewport)(void)
397{ 427{
398 int lastmode; 428 int lastmode;
399 429
400 if (current_vp == &default_vp) 430 if (CURRENT_VP == &default_vp &&
431 default_vp.buffer == &LCDFN(framebuffer_default))
401 { 432 {
402 LCDFN(clear_display)(); 433 LCDFN(clear_display)();
403 } 434 }
404 else 435 else
405 { 436 {
406 lastmode = current_vp->drawmode; 437 lastmode = CURRENT_VP->drawmode;
407 438
408 /* Invert the INVERSEVID bit and set basic mode to SOLID */ 439 /* Invert the INVERSEVID bit and set basic mode to SOLID */
409 current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) | 440 CURRENT_VP->drawmode = (~lastmode & DRMODE_INVERSEVID) |
410 DRMODE_SOLID; 441 DRMODE_SOLID;
411 442
412 LCDFN(fillrect)(0, 0, current_vp->width, current_vp->height); 443 LCDFN(fillrect)(0, 0, CURRENT_VP->width, CURRENT_VP->height);
413 444
414 current_vp->drawmode = lastmode; 445 CURRENT_VP->drawmode = lastmode;
415 446
416 LCDFN(scroll_stop_viewport)(current_vp); 447 LCDFN(scroll_stop_viewport)(CURRENT_VP);
417 } 448 }
449 CURRENT_VP->flags &= ~(VP_FLAG_VP_SET_CLEAN);
418} 450}
419 451
420/* Set a single pixel */ 452/* Set a single pixel */
421void LCDFN(drawpixel)(int x, int y) 453void LCDFN(drawpixel)(int x, int y)
422{ 454{
423 if ( ((unsigned)x < (unsigned)current_vp->width) 455 if ( ((unsigned)x < (unsigned)CURRENT_VP->width)
424 && ((unsigned)y < (unsigned)current_vp->height) 456 && ((unsigned)y < (unsigned)CURRENT_VP->height)
425#if defined(HAVE_VIEWPORT_CLIP) 457#if defined(HAVE_VIEWPORT_CLIP)
426 && ((unsigned)x < (unsigned)LCDM(WIDTH)) 458 && ((unsigned)x < (unsigned)LCDM(WIDTH))
427 && ((unsigned)y < (unsigned)LCDM(HEIGHT)) 459 && ((unsigned)y < (unsigned)LCDM(HEIGHT))
428#endif 460#endif
429 ) 461 )
430 LCDFN(pixelfuncs)[current_vp->drawmode](current_vp->x+x, current_vp->y+y); 462 LCDFN(pixelfuncs)[CURRENT_VP->drawmode](CURRENT_VP->x+x, CURRENT_VP->y+y);
431} 463}
432 464
433/* Draw a line */ 465/* Draw a line */
@@ -439,7 +471,7 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2)
439 int d, dinc1, dinc2; 471 int d, dinc1, dinc2;
440 int x, xinc1, xinc2; 472 int x, xinc1, xinc2;
441 int y, yinc1, yinc2; 473 int y, yinc1, yinc2;
442 LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[current_vp->drawmode]; 474 LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode];
443 475
444 deltax = abs(x2 - x1); 476 deltax = abs(x2 - x1);
445 if (deltax == 0) 477 if (deltax == 0)
@@ -495,14 +527,14 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2)
495 527
496 for (i = 0; i < numpixels; i++) 528 for (i = 0; i < numpixels; i++)
497 { 529 {
498 if ( ((unsigned)x < (unsigned)current_vp->width) 530 if ( ((unsigned)x < (unsigned)CURRENT_VP->width)
499 && ((unsigned)y < (unsigned)current_vp->height) 531 && ((unsigned)y < (unsigned)CURRENT_VP->height)
500#if defined(HAVE_VIEWPORT_CLIP) 532#if defined(HAVE_VIEWPORT_CLIP)
501 && ((unsigned)x < (unsigned)LCDM(WIDTH)) 533 && ((unsigned)x < (unsigned)LCDM(WIDTH))
502 && ((unsigned)y < (unsigned)LCDM(HEIGHT)) 534 && ((unsigned)y < (unsigned)LCDM(HEIGHT))
503#endif 535#endif
504 ) 536 )
505 pfunc(current_vp->x + x, current_vp->y + y); 537 pfunc(CURRENT_VP->x + x, CURRENT_VP->y + y);
506 538
507 if (d < 0) 539 if (d < 0)
508 { 540 {
@@ -538,19 +570,19 @@ void LCDFN(hline)(int x1, int x2, int y)
538 570
539 /******************** In viewport clipping **********************/ 571 /******************** In viewport clipping **********************/
540 /* nothing to draw? */ 572 /* nothing to draw? */
541 if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) 573 if (((unsigned)y >= (unsigned)CURRENT_VP->height) || (x1 >= CURRENT_VP->width)
542 || (x2 < 0)) 574 || (x2 < 0))
543 return; 575 return;
544 576
545 if (x1 < 0) 577 if (x1 < 0)
546 x1 = 0; 578 x1 = 0;
547 if (x2 >= current_vp->width) 579 if (x2 >= CURRENT_VP->width)
548 x2 = current_vp->width-1; 580 x2 = CURRENT_VP->width-1;
549 581
550 /* adjust x1 and y to viewport */ 582 /* adjust x1 and y to viewport */
551 x1 += current_vp->x; 583 x1 += CURRENT_VP->x;
552 x2 += current_vp->x; 584 x2 += CURRENT_VP->x;
553 y += current_vp->y; 585 y += CURRENT_VP->y;
554 586
555#if defined(HAVE_VIEWPORT_CLIP) 587#if defined(HAVE_VIEWPORT_CLIP)
556 /********************* Viewport on screen clipping ********************/ 588 /********************* Viewport on screen clipping ********************/
@@ -568,7 +600,7 @@ void LCDFN(hline)(int x1, int x2, int y)
568 600
569 width = x2 - x1 + 1; 601 width = x2 - x1 + 1;
570 602
571 bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; 603 bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
572 dst = LCDFB(x1,y>>3); 604 dst = LCDFB(x1,y>>3);
573 mask = 0x0101 << (y & 7); 605 mask = 0x0101 << (y & 7);
574 606
@@ -583,6 +615,7 @@ void LCDFN(vline)(int x, int y1, int y2)
583{ 615{
584 int ny; 616 int ny;
585 FBFN(data) *dst; 617 FBFN(data) *dst;
618 int stride_dst;
586 unsigned mask, mask_bottom; 619 unsigned mask, mask_bottom;
587 LCDFN(blockfunc_type) *bfunc; 620 LCDFN(blockfunc_type) *bfunc;
588 621
@@ -596,19 +629,19 @@ void LCDFN(vline)(int x, int y1, int y2)
596 629
597 /******************** In viewport clipping **********************/ 630 /******************** In viewport clipping **********************/
598 /* nothing to draw? */ 631 /* nothing to draw? */
599 if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) 632 if (((unsigned)x >= (unsigned)CURRENT_VP->width) || (y1 >= CURRENT_VP->height)
600 || (y2 < 0)) 633 || (y2 < 0))
601 return; 634 return;
602 635
603 if (y1 < 0) 636 if (y1 < 0)
604 y1 = 0; 637 y1 = 0;
605 if (y2 >= current_vp->height) 638 if (y2 >= CURRENT_VP->height)
606 y2 = current_vp->height-1; 639 y2 = CURRENT_VP->height-1;
607 640
608 /* adjust for viewport */ 641 /* adjust for viewport */
609 y1 += current_vp->y; 642 y1 += CURRENT_VP->y;
610 y2 += current_vp->y; 643 y2 += CURRENT_VP->y;
611 x += current_vp->x; 644 x += CURRENT_VP->x;
612 645
613#if defined(HAVE_VIEWPORT_CLIP) 646#if defined(HAVE_VIEWPORT_CLIP)
614 /********************* Viewport on screen clipping ********************/ 647 /********************* Viewport on screen clipping ********************/
@@ -624,8 +657,9 @@ void LCDFN(vline)(int x, int y1, int y2)
624 y2 = LCDM(HEIGHT)-1; 657 y2 = LCDM(HEIGHT)-1;
625#endif 658#endif
626 659
627 bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; 660 bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
628 dst = LCDFB(x,y1>>3); 661 dst = LCDFB(x,y1>>3);
662 stride_dst = CURRENT_VP->buffer->stride;
629 ny = y2 - (y1 & ~7); 663 ny = y2 - (y1 & ~7);
630 mask = (0xFFu << (y1 & 7)) & 0xFFu; 664 mask = (0xFFu << (y1 & 7)) & 0xFFu;
631 mask |= mask << 8; 665 mask |= mask << 8;
@@ -635,7 +669,7 @@ void LCDFN(vline)(int x, int y1, int y2)
635 for (; ny >= 8; ny -= 8) 669 for (; ny >= 8; ny -= 8)
636 { 670 {
637 bfunc(dst, mask, 0xFFFFu); 671 bfunc(dst, mask, 0xFFFFu);
638 dst += LCDM(WIDTH); 672 dst += stride_dst;
639 mask = 0xFFFFu; 673 mask = 0xFFFFu;
640 } 674 }
641 mask &= mask_bottom; 675 mask &= mask_bottom;
@@ -662,6 +696,7 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
662{ 696{
663 int ny; 697 int ny;
664 FBFN(data) *dst, *dst_end; 698 FBFN(data) *dst, *dst_end;
699 int stride_dst;
665 unsigned mask, mask_bottom; 700 unsigned mask, mask_bottom;
666 unsigned bits = 0; 701 unsigned bits = 0;
667 LCDFN(blockfunc_type) *bfunc; 702 LCDFN(blockfunc_type) *bfunc;
@@ -669,8 +704,8 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
669 704
670 /******************** In viewport clipping **********************/ 705 /******************** In viewport clipping **********************/
671 /* nothing to draw? */ 706 /* nothing to draw? */
672 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) 707 if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width)
673 || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 708 || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0))
674 return; 709 return;
675 710
676 if (x < 0) 711 if (x < 0)
@@ -683,14 +718,14 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
683 height += y; 718 height += y;
684 y = 0; 719 y = 0;
685 } 720 }
686 if (x + width > current_vp->width) 721 if (x + width > CURRENT_VP->width)
687 width = current_vp->width - x; 722 width = CURRENT_VP->width - x;
688 if (y + height > current_vp->height) 723 if (y + height > CURRENT_VP->height)
689 height = current_vp->height - y; 724 height = CURRENT_VP->height - y;
690 725
691 /* adjust for viewport */ 726 /* adjust for viewport */
692 x += current_vp->x; 727 x += CURRENT_VP->x;
693 y += current_vp->y; 728 y += CURRENT_VP->y;
694 729
695#if defined(HAVE_VIEWPORT_CLIP) 730#if defined(HAVE_VIEWPORT_CLIP)
696 /********************* Viewport on screen clipping ********************/ 731 /********************* Viewport on screen clipping ********************/
@@ -717,9 +752,9 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
717#endif 752#endif
718 753
719 754
720 if (current_vp->drawmode & DRMODE_INVERSEVID) 755 if (CURRENT_VP->drawmode & DRMODE_INVERSEVID)
721 { 756 {
722 if ((current_vp->drawmode & DRMODE_BG) && !backdrop) 757 if ((CURRENT_VP->drawmode & DRMODE_BG) && !backdrop)
723 { 758 {
724 fillopt = true; 759 fillopt = true;
725 bits = bg_pattern; 760 bits = bg_pattern;
@@ -727,14 +762,15 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
727 } 762 }
728 else 763 else
729 { 764 {
730 if (current_vp->drawmode & DRMODE_FG) 765 if (CURRENT_VP->drawmode & DRMODE_FG)
731 { 766 {
732 fillopt = true; 767 fillopt = true;
733 bits = fg_pattern; 768 bits = fg_pattern;
734 } 769 }
735 } 770 }
736 bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; 771 bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
737 dst = LCDFB(x,y>>3); 772 dst = LCDFB(x,y>>3);
773 stride_dst = CURRENT_VP->buffer->stride;
738 ny = height - 1 + (y & 7); 774 ny = height - 1 + (y & 7);
739 mask = (0xFFu << (y & 7)) & 0xFFu; 775 mask = (0xFFu << (y & 7)) & 0xFFu;
740 mask |= mask << 8; 776 mask |= mask << 8;
@@ -755,7 +791,7 @@ void LCDFN(fillrect)(int x, int y, int width, int height)
755 while (dst_row < dst_end); 791 while (dst_row < dst_end);
756 } 792 }
757 793
758 dst += LCDM(WIDTH); 794 dst += stride_dst;
759 mask = 0xFFFFu; 795 mask = 0xFFFFu;
760 } 796 }
761 mask &= mask_bottom; 797 mask &= mask_bottom;
@@ -789,13 +825,14 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
789{ 825{
790 int shift, ny; 826 int shift, ny;
791 FBFN(data) *dst, *dst_end; 827 FBFN(data) *dst, *dst_end;
828 int stride_dst;
792 unsigned data, mask, mask_bottom; 829 unsigned data, mask, mask_bottom;
793 LCDFN(blockfunc_type) *bfunc; 830 LCDFN(blockfunc_type) *bfunc;
794 831
795 /******************** Image in viewport clipping **********************/ 832 /******************** Image in viewport clipping **********************/
796 /* nothing to draw? */ 833 /* nothing to draw? */
797 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 834 if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) ||
798 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 835 (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0))
799 return; 836 return;
800 837
801 if (x < 0) 838 if (x < 0)
@@ -810,14 +847,14 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
810 src_y -= y; 847 src_y -= y;
811 y = 0; 848 y = 0;
812 } 849 }
813 if (x + width > current_vp->width) 850 if (x + width > CURRENT_VP->width)
814 width = current_vp->width - x; 851 width = CURRENT_VP->width - x;
815 if (y + height > current_vp->height) 852 if (y + height > CURRENT_VP->height)
816 height = current_vp->height - y; 853 height = CURRENT_VP->height - y;
817 854
818 /* adjust for viewport */ 855 /* adjust for viewport */
819 x += current_vp->x; 856 x += CURRENT_VP->x;
820 y += current_vp->y; 857 y += CURRENT_VP->y;
821 858
822#if defined(HAVE_VIEWPORT_CLIP) 859#if defined(HAVE_VIEWPORT_CLIP)
823 /********************* Viewport on screen clipping ********************/ 860 /********************* Viewport on screen clipping ********************/
@@ -849,10 +886,11 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
849 src_y &= 7; 886 src_y &= 7;
850 y -= src_y; 887 y -= src_y;
851 dst = LCDFB(x,y>>3); 888 dst = LCDFB(x,y>>3);
889 stride_dst = CURRENT_VP->buffer->stride;
852 shift = y & 7; 890 shift = y & 7;
853 ny = height - 1 + shift + src_y; 891 ny = height - 1 + shift + src_y;
854 892
855 bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; 893 bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode];
856 mask = 0xFFu << (shift + src_y); 894 mask = 0xFFu << (shift + src_y);
857 /* not byte-doubled here because shift+src_y can be > 7 */ 895 /* not byte-doubled here because shift+src_y can be > 7 */
858 mask_bottom = 0xFFu >> (~ny & 7); 896 mask_bottom = 0xFFu >> (~ny & 7);
@@ -877,7 +915,7 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
877 while (dst_row < dst_end); 915 while (dst_row < dst_end);
878 916
879 src += stride; 917 src += stride;
880 dst += LCDM(WIDTH); 918 dst += stride_dst;
881 mask = 0xFFFFu; 919 mask = 0xFFFFu;
882 } 920 }
883 mask &= mask_bottom; 921 mask &= mask_bottom;
@@ -921,7 +959,7 @@ void ICODE_ATTR LCDFN(mono_bitmap_part)(const unsigned char *src, int src_x,
921 } 959 }
922 960
923 src_col += stride; 961 src_col += stride;
924 dst_col += LCDM(WIDTH); 962 dst_col += stride_dst;
925 data >>= 8; 963 data >>= 8;
926 } 964 }
927 data |= *src_col << shift; 965 data |= *src_col << shift;
@@ -958,12 +996,13 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
958{ 996{
959 int shift, ny; 997 int shift, ny;
960 FBFN(data) *dst, *dst_end; 998 FBFN(data) *dst, *dst_end;
999 int stride_dst;
961 unsigned mask, mask_bottom; 1000 unsigned mask, mask_bottom;
962 1001
963 /******************** Image in viewport clipping **********************/ 1002 /******************** Image in viewport clipping **********************/
964 /* nothing to draw? */ 1003 /* nothing to draw? */
965 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) 1004 if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width)
966 || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 1005 || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0))
967 return; 1006 return;
968 1007
969 if (x < 0) 1008 if (x < 0)
@@ -978,14 +1017,14 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
978 src_y -= y; 1017 src_y -= y;
979 y = 0; 1018 y = 0;
980 } 1019 }
981 if (x + width > current_vp->width) 1020 if (x + width > CURRENT_VP->width)
982 width = current_vp->width - x; 1021 width = CURRENT_VP->width - x;
983 if (y + height > current_vp->height) 1022 if (y + height > CURRENT_VP->height)
984 height = current_vp->height - y; 1023 height = CURRENT_VP->height - y;
985 1024
986 /* adjust for viewport */ 1025 /* adjust for viewport */
987 x += current_vp->x; 1026 x += CURRENT_VP->x;
988 y += current_vp->y; 1027 y += CURRENT_VP->y;
989 1028
990#if defined(HAVE_VIEWPORT_CLIP) 1029#if defined(HAVE_VIEWPORT_CLIP)
991 /********************* Viewport on screen clipping ********************/ 1030 /********************* Viewport on screen clipping ********************/
@@ -1017,6 +1056,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
1017 src_y &= 7; 1056 src_y &= 7;
1018 y -= src_y; 1057 y -= src_y;
1019 dst = LCDFB(x,y>>3); 1058 dst = LCDFB(x,y>>3);
1059 stride_dst = CURRENT_VP->buffer->stride;
1020 shift = y & 7; 1060 shift = y & 7;
1021 ny = height - 1 + shift + src_y; 1061 ny = height - 1 + shift + src_y;
1022 1062
@@ -1045,7 +1085,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
1045 while (dst_row < dst_end); 1085 while (dst_row < dst_end);
1046 } 1086 }
1047 src += stride; 1087 src += stride;
1048 dst += LCDM(WIDTH); 1088 dst += stride_dst;
1049 mask = 0xFFFFu; 1089 mask = 0xFFFFu;
1050 } 1090 }
1051 mask &= mask_bottom; 1091 mask &= mask_bottom;
@@ -1092,7 +1132,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const FBFN(data) *src, int src_x,
1092 mask_col |= mask_col << 8; 1132 mask_col |= mask_col << 8;
1093 } 1133 }
1094 src_col += stride; 1134 src_col += stride;
1095 dst_col += LCDM(WIDTH); 1135 dst_col += stride_dst;
1096 olddata = data >> 8; 1136 olddata = data >> 8;
1097 } 1137 }
1098 data = *src_col << shift; 1138 data = *src_col << shift;