summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-2bit-horz.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-2bit-horz.c')
-rw-r--r--firmware/drivers/lcd-2bit-horz.c215
1 files changed, 124 insertions, 91 deletions
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index 1d256e5f58..35a2be5b2c 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -39,8 +39,8 @@
39 39
40/*** globals ***/ 40/*** globals ***/
41 41
42unsigned char lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER; 42static unsigned char lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER;
43unsigned char *lcd_framebuffer = &lcd_static_framebuffer[0][0]; 43static void *lcd_frameaddress_default(int x, int y);
44 44
45static const unsigned char pixmask[4] ICONST_ATTR = { 45static const unsigned char pixmask[4] ICONST_ATTR = {
46 0xC0, 0x30, 0x0C, 0x03 46 0xC0, 0x30, 0x0C, 0x03
@@ -49,6 +49,15 @@ static const unsigned char pixmask[4] ICONST_ATTR = {
49static fb_data* lcd_backdrop = NULL; 49static fb_data* lcd_backdrop = NULL;
50static long lcd_backdrop_offset IDATA_ATTR = 0; 50static long lcd_backdrop_offset IDATA_ATTR = 0;
51 51
52/* shouldn't be changed unless you want system-wide framebuffer changes! */
53struct frame_buffer_t lcd_framebuffer_default =
54{
55 .fb_ptr = &lcd_static_framebuffer[0][0],
56 .get_address_fn = &lcd_frameaddress_default,
57 .stride = STRIDE_MAIN(LCD_WIDTH, LCD_HEIGHT),
58 .elems = (LCD_FBWIDTH*LCD_FBHEIGHT),
59};
60
52static struct viewport default_vp = 61static struct viewport default_vp =
53{ 62{
54 .x = 0, 63 .x = 0,
@@ -57,18 +66,32 @@ static struct viewport default_vp =
57 .height = LCD_HEIGHT, 66 .height = LCD_HEIGHT,
58 .font = FONT_SYSFIXED, 67 .font = FONT_SYSFIXED,
59 .drawmode = DRMODE_SOLID, 68 .drawmode = DRMODE_SOLID,
69 .buffer = NULL,
60 .fg_pattern = LCD_DEFAULT_FG, 70 .fg_pattern = LCD_DEFAULT_FG,
61 .bg_pattern = LCD_DEFAULT_BG 71 .bg_pattern = LCD_DEFAULT_BG
62}; 72};
63 73
64static struct viewport* current_vp IBSS_ATTR; 74struct viewport* lcd_current_viewport IBSS_ATTR;
65static unsigned fg_pattern IBSS_ATTR; 75static unsigned fg_pattern IBSS_ATTR;
66static unsigned bg_pattern IBSS_ATTR; 76static unsigned bg_pattern IBSS_ATTR;
67 77
78static void *lcd_frameaddress_default(int x, int y)
79{
80 /* the default expects a buffer the same size as the screen */
81 struct frame_buffer_t *fb = lcd_current_viewport->buffer;
82
83#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
84 size_t element = (x * LCD_NATIVE_STRIDE(fb->stride)) + y;
85#else
86 size_t element = (y * LCD_NATIVE_STRIDE(fb->stride)) + x;
87#endif
88 return fb->fb_ptr + element;/*(element % fb->elems);*/
89}
90
68/* LCD init */ 91/* LCD init */
69void lcd_init(void) 92void lcd_init(void)
70{ 93{
71 /* Initialise the viewport */ 94 /* Initialize the viewport */
72 lcd_set_viewport(NULL); 95 lcd_set_viewport(NULL);
73 96
74 lcd_clear_display(); 97 lcd_clear_display();
@@ -81,34 +104,34 @@ void lcd_init(void)
81 104
82void lcd_set_drawmode(int mode) 105void lcd_set_drawmode(int mode)
83{ 106{
84 current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); 107 lcd_current_viewport->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
85} 108}
86 109
87int lcd_get_drawmode(void) 110int lcd_get_drawmode(void)
88{ 111{
89 return current_vp->drawmode; 112 return lcd_current_viewport->drawmode;
90} 113}
91 114
92void lcd_set_foreground(unsigned brightness) 115void lcd_set_foreground(unsigned brightness)
93{ 116{
94 current_vp->fg_pattern = brightness; 117 lcd_current_viewport->fg_pattern = brightness;
95 fg_pattern = 0x55 * (~brightness & 3); 118 fg_pattern = 0x55 * (~brightness & 3);
96} 119}
97 120
98unsigned lcd_get_foreground(void) 121unsigned lcd_get_foreground(void)
99{ 122{
100 return current_vp->fg_pattern; 123 return lcd_current_viewport->fg_pattern;
101} 124}
102 125
103void lcd_set_background(unsigned brightness) 126void lcd_set_background(unsigned brightness)
104{ 127{
105 current_vp->bg_pattern = brightness; 128 lcd_current_viewport->bg_pattern = brightness;
106 bg_pattern = 0x55 * (~brightness & 3); 129 bg_pattern = 0x55 * (~brightness & 3);
107} 130}
108 131
109unsigned lcd_get_background(void) 132unsigned lcd_get_background(void)
110{ 133{
111 return current_vp->bg_pattern; 134 return lcd_current_viewport->bg_pattern;
112} 135}
113 136
114void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness) 137void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
@@ -120,27 +143,27 @@ void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness)
120 143
121int lcd_getwidth(void) 144int lcd_getwidth(void)
122{ 145{
123 return current_vp->width; 146 return lcd_current_viewport->width;
124} 147}
125 148
126int lcd_getheight(void) 149int lcd_getheight(void)
127{ 150{
128 return current_vp->height; 151 return lcd_current_viewport->height;
129} 152}
130 153
131void lcd_setfont(int newfont) 154void lcd_setfont(int newfont)
132{ 155{
133 current_vp->font = newfont; 156 lcd_current_viewport->font = newfont;
134} 157}
135 158
136int lcd_getfont(void) 159int lcd_getfont(void)
137{ 160{
138 return current_vp->font; 161 return lcd_current_viewport->font;
139} 162}
140 163
141int lcd_getstringsize(const unsigned char *str, int *w, int *h) 164int lcd_getstringsize(const unsigned char *str, int *w, int *h)
142{ 165{
143 return font_getstringsize(str, w, h, current_vp->font); 166 return font_getstringsize(str, w, h, lcd_current_viewport->font);
144} 167}
145 168
146/*** low-level drawing functions ***/ 169/*** low-level drawing functions ***/
@@ -318,7 +341,7 @@ void lcd_set_backdrop(fb_data* backdrop)
318 lcd_backdrop = backdrop; 341 lcd_backdrop = backdrop;
319 if (backdrop) 342 if (backdrop)
320 { 343 {
321 lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer; 344 lcd_backdrop_offset = (long)backdrop - (long)FBADDR(0,0);
322 lcd_pixelfuncs = lcd_pixelfuncs_backdrop; 345 lcd_pixelfuncs = lcd_pixelfuncs_backdrop;
323 lcd_blockfuncs = lcd_blockfuncs_backdrop; 346 lcd_blockfuncs = lcd_blockfuncs_backdrop;
324 } 347 }
@@ -349,16 +372,16 @@ static inline void setblock(fb_data *address, unsigned mask, unsigned bits)
349/* Clear the whole display */ 372/* Clear the whole display */
350void lcd_clear_display(void) 373void lcd_clear_display(void)
351{ 374{
352 if (current_vp->drawmode & DRMODE_INVERSEVID) 375 if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID)
353 { 376 {
354 memset(lcd_framebuffer, fg_pattern, FRAMEBUFFER_SIZE); 377 memset(FBADDR(0,0), fg_pattern, FRAMEBUFFER_SIZE);
355 } 378 }
356 else 379 else
357 { 380 {
358 if (lcd_backdrop) 381 if (lcd_backdrop)
359 memcpy(lcd_framebuffer, lcd_backdrop, FRAMEBUFFER_SIZE); 382 memcpy(FBADDR(0,0), lcd_backdrop, FRAMEBUFFER_SIZE);
360 else 383 else
361 memset(lcd_framebuffer, bg_pattern, FRAMEBUFFER_SIZE); 384 memset(FBADDR(0,0), bg_pattern, FRAMEBUFFER_SIZE);
362 } 385 }
363 386
364 lcd_scroll_info.lines = 0; 387 lcd_scroll_info.lines = 0;
@@ -369,37 +392,39 @@ void lcd_clear_viewport(void)
369{ 392{
370 int lastmode; 393 int lastmode;
371 394
372 if (current_vp == &default_vp) 395 if (lcd_current_viewport == &default_vp &&
396 default_vp.buffer == &lcd_framebuffer_default)
373 { 397 {
374 lcd_clear_display(); 398 lcd_clear_display();
375 } 399 }
376 else 400 else
377 { 401 {
378 lastmode = current_vp->drawmode; 402 lastmode = lcd_current_viewport->drawmode;
379 403
380 /* Invert the INVERSEVID bit and set basic mode to SOLID */ 404 /* Invert the INVERSEVID bit and set basic mode to SOLID */
381 current_vp->drawmode = (~lastmode & DRMODE_INVERSEVID) | 405 lcd_current_viewport->drawmode = (~lastmode & DRMODE_INVERSEVID) |
382 DRMODE_SOLID; 406 DRMODE_SOLID;
383 407
384 lcd_fillrect(0, 0, current_vp->width, current_vp->height); 408 lcd_fillrect(0, 0, lcd_current_viewport->width, lcd_current_viewport->height);
385 409
386 current_vp->drawmode = lastmode; 410 lcd_current_viewport->drawmode = lastmode;
387 411
388 lcd_scroll_stop_viewport(current_vp); 412 lcd_scroll_stop_viewport(lcd_current_viewport);
389 } 413 }
414 lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN);
390} 415}
391 416
392/* Set a single pixel */ 417/* Set a single pixel */
393void lcd_drawpixel(int x, int y) 418void lcd_drawpixel(int x, int y)
394{ 419{
395 if ( ((unsigned)x < (unsigned)current_vp->width) 420 if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
396 && ((unsigned)y < (unsigned)current_vp->height) 421 && ((unsigned)y < (unsigned)lcd_current_viewport->height)
397#if defined(HAVE_VIEWPORT_CLIP) 422#if defined(HAVE_VIEWPORT_CLIP)
398 && ((unsigned)x < (unsigned)LCD_WIDTH) 423 && ((unsigned)x < (unsigned)LCD_WIDTH)
399 && ((unsigned)y < (unsigned)LCD_HEIGHT) 424 && ((unsigned)y < (unsigned)LCD_HEIGHT)
400#endif 425#endif
401 ) 426 )
402 lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y); 427 lcd_pixelfuncs[lcd_current_viewport->drawmode](lcd_current_viewport->x + x, lcd_current_viewport->y + y);
403} 428}
404 429
405/* Draw a line */ 430/* Draw a line */
@@ -411,7 +436,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
411 int d, dinc1, dinc2; 436 int d, dinc1, dinc2;
412 int x, xinc1, xinc2; 437 int x, xinc1, xinc2;
413 int y, yinc1, yinc2; 438 int y, yinc1, yinc2;
414 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode]; 439 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode];
415 440
416 deltay = abs(y2 - y1); 441 deltay = abs(y2 - y1);
417 if (deltay == 0) 442 if (deltay == 0)
@@ -467,14 +492,14 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
467 492
468 for (i = 0; i < numpixels; i++) 493 for (i = 0; i < numpixels; i++)
469 { 494 {
470 if ( ((unsigned)x < (unsigned)current_vp->width) 495 if ( ((unsigned)x < (unsigned)lcd_current_viewport->width)
471 && ((unsigned)y < (unsigned)current_vp->height) 496 && ((unsigned)y < (unsigned)lcd_current_viewport->height)
472#if defined(HAVE_VIEWPORT_CLIP) 497#if defined(HAVE_VIEWPORT_CLIP)
473 && ((unsigned)x < (unsigned)LCD_WIDTH) 498 && ((unsigned)x < (unsigned)LCD_WIDTH)
474 && ((unsigned)y < (unsigned)LCD_HEIGHT) 499 && ((unsigned)y < (unsigned)LCD_HEIGHT)
475#endif 500#endif
476 ) 501 )
477 pfunc(current_vp->x + x, current_vp->y + y); 502 pfunc(lcd_current_viewport->x + x, lcd_current_viewport->y + y);
478 503
479 if (d < 0) 504 if (d < 0)
480 { 505 {
@@ -509,19 +534,19 @@ void lcd_hline(int x1, int x2, int y)
509 534
510 /******************** In viewport clipping **********************/ 535 /******************** In viewport clipping **********************/
511 /* nothing to draw? */ 536 /* nothing to draw? */
512 if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) 537 if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || (x1 >= lcd_current_viewport->width)
513 || (x2 < 0)) 538 || (x2 < 0))
514 return; 539 return;
515 540
516 if (x1 < 0) 541 if (x1 < 0)
517 x1 = 0; 542 x1 = 0;
518 if (x2 >= current_vp->width) 543 if (x2 >= lcd_current_viewport->width)
519 x2 = current_vp->width-1; 544 x2 = lcd_current_viewport->width-1;
520 545
521 /* adjust to viewport */ 546 /* adjust to viewport */
522 x1 += current_vp->x; 547 x1 += lcd_current_viewport->x;
523 x2 += current_vp->x; 548 x2 += lcd_current_viewport->x;
524 y += current_vp->y; 549 y += lcd_current_viewport->y;
525 550
526#if defined(HAVE_VIEWPORT_CLIP) 551#if defined(HAVE_VIEWPORT_CLIP)
527 /********************* Viewport on screen clipping ********************/ 552 /********************* Viewport on screen clipping ********************/
@@ -537,7 +562,7 @@ void lcd_hline(int x1, int x2, int y)
537 x2 = LCD_WIDTH-1; 562 x2 = LCD_WIDTH-1;
538#endif 563#endif
539 564
540 bfunc = lcd_blockfuncs[current_vp->drawmode]; 565 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
541 dst = FBADDR(x1>>2,y); 566 dst = FBADDR(x1>>2,y);
542 nx = x2 - (x1 & ~3); 567 nx = x2 - (x1 & ~3);
543 mask = 0xFFu >> (2 * (x1 & 3)); 568 mask = 0xFFu >> (2 * (x1 & 3));
@@ -557,6 +582,7 @@ void lcd_vline(int x, int y1, int y2)
557{ 582{
558 int y; 583 int y;
559 unsigned char *dst, *dst_end; 584 unsigned char *dst, *dst_end;
585 int stride_dst;
560 unsigned mask; 586 unsigned mask;
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,15 +624,16 @@ 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>>2,y1); 628 dst = FBADDR(x>>2,y1);
629 stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
603 mask = pixmask[x & 3]; 630 mask = pixmask[x & 3];
604 631
605 dst_end = dst + (y2 - y1) * LCD_FBWIDTH; 632 dst_end = dst + (y2 - y1) * stride_dst;
606 do 633 do
607 { 634 {
608 bfunc(dst, mask, 0xFFu); 635 bfunc(dst, mask, 0xFFu);
609 dst += LCD_FBWIDTH; 636 dst += stride_dst;
610 } 637 }
611 while (dst <= dst_end); 638 while (dst <= dst_end);
612} 639}
@@ -631,12 +658,13 @@ void lcd_fillrect(int x, int y, int width, int height)
631{ 658{
632 int nx; 659 int nx;
633 unsigned char *dst, *dst_end; 660 unsigned char *dst, *dst_end;
661 int stride_dst;
634 unsigned mask, mask_right; 662 unsigned mask, mask_right;
635 lcd_blockfunc_type *bfunc; 663 lcd_blockfunc_type *bfunc;
636 664
637 /******************** In viewport clipping **********************/ 665 /******************** In viewport clipping **********************/
638 /* nothing to draw? */ 666 /* nothing to draw? */
639 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || (y >= current_vp->height) 667 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || (y >= lcd_current_viewport->height)
640 || (x + width <= 0) || (y + height <= 0)) 668 || (x + width <= 0) || (y + height <= 0))
641 return; 669 return;
642 670
@@ -650,14 +678,14 @@ void lcd_fillrect(int x, int y, int width, int height)
650 height += y; 678 height += y;
651 y = 0; 679 y = 0;
652 } 680 }
653 if (x + width > current_vp->width) 681 if (x + width > lcd_current_viewport->width)
654 width = current_vp->width - x; 682 width = lcd_current_viewport->width - x;
655 if (y + height > current_vp->height) 683 if (y + height > lcd_current_viewport->height)
656 height = current_vp->height - y; 684 height = lcd_current_viewport->height - y;
657 685
658 /* adjust for viewport */ 686 /* adjust for viewport */
659 x += current_vp->x; 687 x += lcd_current_viewport->x;
660 y += current_vp->y; 688 y += lcd_current_viewport->y;
661 689
662#if defined(HAVE_VIEWPORT_CLIP) 690#if defined(HAVE_VIEWPORT_CLIP)
663 /********************* Viewport on screen clipping ********************/ 691 /********************* Viewport on screen clipping ********************/
@@ -683,21 +711,22 @@ void lcd_fillrect(int x, int y, int width, int height)
683 height = LCD_HEIGHT - y; 711 height = LCD_HEIGHT - y;
684#endif 712#endif
685 713
686 bfunc = lcd_blockfuncs[current_vp->drawmode]; 714 bfunc = lcd_blockfuncs[lcd_current_viewport->drawmode];
687 dst = FBADDR(x>>2,y); 715 dst = FBADDR(x>>2,y);
688 nx = width - 1 + (x & 3); 716 stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
689 mask = 0xFFu >> (2 * (x & 3)); 717 nx = width - 1 + (x & 3);
718 mask = 0xFFu >> (2 * (x & 3));
690 mask_right = 0xFFu << (2 * (~nx & 3)); 719 mask_right = 0xFFu << (2 * (~nx & 3));
691 720
692 for (; nx >= 4; nx -= 4) 721 for (; nx >= 4; nx -= 4)
693 { 722 {
694 unsigned char *dst_col = dst; 723 unsigned char *dst_col = dst;
695 724
696 dst_end = dst_col + height * LCD_FBWIDTH; 725 dst_end = dst_col + height * stride_dst;
697 do 726 do
698 { 727 {
699 bfunc(dst_col, mask, 0xFFu); 728 bfunc(dst_col, mask, 0xFFu);
700 dst_col += LCD_FBWIDTH; 729 dst_col += stride_dst;
701 } 730 }
702 while (dst_col < dst_end); 731 while (dst_col < dst_end);
703 732
@@ -706,11 +735,11 @@ void lcd_fillrect(int x, int y, int width, int height)
706 } 735 }
707 mask &= mask_right; 736 mask &= mask_right;
708 737
709 dst_end = dst + height * LCD_FBWIDTH; 738 dst_end = dst + height * stride_dst;
710 do 739 do
711 { 740 {
712 bfunc(dst, mask, 0xFFu); 741 bfunc(dst, mask, 0xFFu);
713 dst += LCD_FBWIDTH; 742 dst += stride_dst;
714 } 743 }
715 while (dst < dst_end); 744 while (dst < dst_end);
716} 745}
@@ -731,14 +760,15 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
731{ 760{
732 const unsigned char *src_end; 761 const unsigned char *src_end;
733 fb_data *dst, *dst_end; 762 fb_data *dst, *dst_end;
763 int stride_dst;
734 unsigned dmask = 0x100; /* bit 8 == sentinel */ 764 unsigned dmask = 0x100; /* bit 8 == sentinel */
735 unsigned dst_mask; 765 unsigned dst_mask;
736 int drmode = current_vp->drawmode; 766 int drmode = lcd_current_viewport->drawmode;
737 767
738 /******************** Image in viewport clipping **********************/ 768 /******************** Image in viewport clipping **********************/
739 /* nothing to draw? */ 769 /* nothing to draw? */
740 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 770 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
741 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 771 (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
742 return; 772 return;
743 773
744 if (x < 0) 774 if (x < 0)
@@ -753,13 +783,13 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
753 src_y -= y; 783 src_y -= y;
754 y = 0; 784 y = 0;
755 } 785 }
756 if (x + width > current_vp->width) 786 if (x + width > lcd_current_viewport->width)
757 width = current_vp->width - x; 787 width = lcd_current_viewport->width - x;
758 if (y + height > current_vp->height) 788 if (y + height > lcd_current_viewport->height)
759 height = current_vp->height - y; 789 height = lcd_current_viewport->height - y;
760 790
761 x += current_vp->x; /* adjust for viewport */ 791 x += lcd_current_viewport->x; /* adjust for viewport */
762 y += current_vp->y; /* adjust for viewport */ 792 y += lcd_current_viewport->y; /* adjust for viewport */
763 793
764#if defined(HAVE_VIEWPORT_CLIP) 794#if defined(HAVE_VIEWPORT_CLIP)
765 /********************* Viewport on screen clipping ********************/ 795 /********************* Viewport on screen clipping ********************/
@@ -792,7 +822,8 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
792 src_end = src + width; 822 src_end = src + width;
793 823
794 dst = FBADDR(x >> 2,y); 824 dst = FBADDR(x >> 2,y);
795 dst_end = dst + height * LCD_FBWIDTH; 825 stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
826 dst_end = dst + height * stride_dst;
796 dst_mask = pixmask[x & 3]; 827 dst_mask = pixmask[x & 3];
797 828
798 if (drmode & DRMODE_INVERSEVID) 829 if (drmode & DRMODE_INVERSEVID)
@@ -825,7 +856,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
825 if (data & 0x01) 856 if (data & 0x01)
826 *dst_col ^= dst_mask; 857 *dst_col ^= dst_mask;
827 858
828 dst_col += LCD_FBWIDTH; 859 dst_col += stride_dst;
829 UPDATE_SRC; 860 UPDATE_SRC;
830 } 861 }
831 while (dst_col < dst_end); 862 while (dst_col < dst_end);
@@ -843,7 +874,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
843 *dst_col = block 874 *dst_col = block
844 ^ ((block ^ *(dst_col + bo)) & dst_mask); 875 ^ ((block ^ *(dst_col + bo)) & dst_mask);
845 } 876 }
846 dst_col += LCD_FBWIDTH; 877 dst_col += stride_dst;
847 UPDATE_SRC; 878 UPDATE_SRC;
848 } 879 }
849 while (dst_col < dst_end); 880 while (dst_col < dst_end);
@@ -858,7 +889,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
858 unsigned block = *dst_col; 889 unsigned block = *dst_col;
859 *dst_col = block ^ ((block ^ bg) & dst_mask); 890 *dst_col = block ^ ((block ^ bg) & dst_mask);
860 } 891 }
861 dst_col += LCD_FBWIDTH; 892 dst_col += stride_dst;
862 UPDATE_SRC; 893 UPDATE_SRC;
863 } 894 }
864 while (dst_col < dst_end); 895 while (dst_col < dst_end);
@@ -874,7 +905,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
874 unsigned block = *dst_col; 905 unsigned block = *dst_col;
875 *dst_col = block ^ ((block ^ fg) & dst_mask); 906 *dst_col = block ^ ((block ^ fg) & dst_mask);
876 } 907 }
877 dst_col += LCD_FBWIDTH; 908 dst_col += stride_dst;
878 UPDATE_SRC; 909 UPDATE_SRC;
879 } 910 }
880 while (dst_col < dst_end); 911 while (dst_col < dst_end);
@@ -891,7 +922,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
891 *dst_col = block ^ ((block ^ ((data & 0x01) ? 922 *dst_col = block ^ ((block ^ ((data & 0x01) ?
892 fg : *(dst_col + bo))) & dst_mask); 923 fg : *(dst_col + bo))) & dst_mask);
893 924
894 dst_col += LCD_FBWIDTH; 925 dst_col += stride_dst;
895 UPDATE_SRC; 926 UPDATE_SRC;
896 } 927 }
897 while (dst_col < dst_end); 928 while (dst_col < dst_end);
@@ -905,7 +936,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
905 *dst_col = block ^ ((block ^ ((data & 0x01) ? 936 *dst_col = block ^ ((block ^ ((data & 0x01) ?
906 fg : bg)) & dst_mask); 937 fg : bg)) & dst_mask);
907 938
908 dst_col += LCD_FBWIDTH; 939 dst_col += stride_dst;
909 UPDATE_SRC; 940 UPDATE_SRC;
910 } 941 }
911 while (dst_col < dst_end); 942 while (dst_col < dst_end);
@@ -945,12 +976,13 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
945{ 976{
946 int shift, nx; 977 int shift, nx;
947 unsigned char *dst, *dst_end; 978 unsigned char *dst, *dst_end;
979 int stride_dst;
948 unsigned mask, mask_right; 980 unsigned mask, mask_right;
949 981
950 /******************** Image in viewport clipping **********************/ 982 /******************** Image in viewport clipping **********************/
951 /* nothing to draw? */ 983 /* nothing to draw? */
952 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 984 if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) ||
953 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 985 (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0))
954 return; 986 return;
955 987
956 if (x < 0) 988 if (x < 0)
@@ -965,14 +997,14 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
965 src_y -= y; 997 src_y -= y;
966 y = 0; 998 y = 0;
967 } 999 }
968 if (x + width > current_vp->width) 1000 if (x + width > lcd_current_viewport->width)
969 width = current_vp->width - x; 1001 width = lcd_current_viewport->width - x;
970 if (y + height > current_vp->height) 1002 if (y + height > lcd_current_viewport->height)
971 height = current_vp->height - y; 1003 height = lcd_current_viewport->height - y;
972 1004
973 /* adjust for viewport */ 1005 /* adjust for viewport */
974 x += current_vp->x; 1006 x += lcd_current_viewport->x;
975 y += current_vp->y; 1007 y += lcd_current_viewport->y;
976 1008
977#if defined(HAVE_VIEWPORT_CLIP) 1009#if defined(HAVE_VIEWPORT_CLIP)
978 /********************* Viewport on screen clipping ********************/ 1010 /********************* Viewport on screen clipping ********************/
@@ -1000,12 +1032,13 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
1000 height = LCD_HEIGHT - y; 1032 height = LCD_HEIGHT - y;
1001#endif 1033#endif
1002 1034
1003 stride = (stride + 3) >> 2; /* convert to no. of bytes */ 1035 stride = LCD_FBSTRIDE(stride, 0); /* convert to no. of bytes */
1004 1036
1005 src += stride * src_y + (src_x >> 2); /* move starting point */ 1037 src += stride * src_y + (src_x >> 2); /* move starting point */
1006 src_x &= 3; 1038 src_x &= 3;
1007 x -= src_x; 1039 x -= src_x;
1008 dst = FBADDR(x>>2,y); 1040 dst = FBADDR(x>>2,y);
1041 stride_dst = LCD_FBSTRIDE(lcd_current_viewport->buffer->stride, 0);
1009 shift = x & 3; 1042 shift = x & 3;
1010 nx = width - 1 + shift + src_x; 1043 nx = width - 1 + shift + src_x;
1011 1044
@@ -1013,7 +1046,7 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
1013 mask_right = 0xFFu << (2 * (~nx & 3)); 1046 mask_right = 0xFFu << (2 * (~nx & 3));
1014 1047
1015 shift *= 2; 1048 shift *= 2;
1016 dst_end = dst + height * LCD_FBWIDTH; 1049 dst_end = dst + height * stride_dst;
1017 do 1050 do
1018 { 1051 {
1019 const unsigned char *src_row = src; 1052 const unsigned char *src_row = src;
@@ -1039,7 +1072,7 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
1039 setblock(dst_row, mask_row & mask_right, data >> shift); 1072 setblock(dst_row, mask_row & mask_right, data >> shift);
1040 1073
1041 src += stride; 1074 src += stride;
1042 dst += LCD_FBWIDTH; 1075 dst += stride_dst;
1043 } 1076 }
1044 while (dst < dst_end); 1077 while (dst < dst_end);
1045} 1078}