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.c165
1 files changed, 152 insertions, 13 deletions
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index f9a53ee20c..2e965b35fa 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -87,6 +87,28 @@ void lcd_set_viewport(struct viewport* vp)
87 87
88 fg_pattern = 0x55 * (~current_vp->fg_pattern & 3); 88 fg_pattern = 0x55 * (~current_vp->fg_pattern & 3);
89 bg_pattern = 0x55 * (~current_vp->bg_pattern & 3); 89 bg_pattern = 0x55 * (~current_vp->bg_pattern & 3);
90
91#if defined(SIMULATOR)
92 /* Force the viewport to be within bounds. If this happens it should
93 * be considered an error - the viewport will not draw as it might be
94 * expected.
95 */
96 if((unsigned) current_vp->x > (unsigned) LCD_WIDTH
97 || (unsigned) current_vp->y > (unsigned) LCD_HEIGHT
98 || current_vp->x + current_vp->width > LCD_WIDTH
99 || current_vp->y + current_vp->height > LCD_HEIGHT)
100 {
101#if !defined(HAVE_VIEWPORT_CLIP)
102 DEBUGF("ERROR: "
103#else
104 DEBUGF("NOTE: "
105#endif
106 "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n",
107 current_vp->x, current_vp->y,
108 current_vp->width, current_vp->height);
109 }
110
111#endif
90} 112}
91 113
92void lcd_update_viewport(void) 114void lcd_update_viewport(void)
@@ -415,8 +437,13 @@ void lcd_clear_viewport(void)
415/* Set a single pixel */ 437/* Set a single pixel */
416void lcd_drawpixel(int x, int y) 438void lcd_drawpixel(int x, int y)
417{ 439{
418 if (((unsigned)x < (unsigned)current_vp->width) && 440 if ( ((unsigned)x < (unsigned)current_vp->width)
419 ((unsigned)y < (unsigned)current_vp->height)) 441 && ((unsigned)y < (unsigned)current_vp->height)
442#if defined(HAVE_VIEWPORT_CLIP)
443 && ((unsigned)x < (unsigned)LCD_WIDTH)
444 && ((unsigned)y < (unsigned)LCD_HEIGHT)
445#endif
446 )
420 lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y); 447 lcd_pixelfuncs[current_vp->drawmode](current_vp->x + x, current_vp->y + y);
421} 448}
422 449
@@ -485,8 +512,13 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
485 512
486 for (i = 0; i < numpixels; i++) 513 for (i = 0; i < numpixels; i++)
487 { 514 {
488 if (((unsigned)x < (unsigned)current_vp->width) && 515 if ( ((unsigned)x < (unsigned)current_vp->width)
489 ((unsigned)y < (unsigned)current_vp->height)) 516 && ((unsigned)y < (unsigned)current_vp->height)
517#if defined(HAVE_VIEWPORT_CLIP)
518 && ((unsigned)x < (unsigned)LCD_WIDTH)
519 && ((unsigned)y < (unsigned)LCD_HEIGHT)
520#endif
521 )
490 pfunc(current_vp->x + x, current_vp->y + y); 522 pfunc(current_vp->x + x, current_vp->y + y);
491 523
492 if (d < 0) 524 if (d < 0)
@@ -520,12 +552,12 @@ void lcd_hline(int x1, int x2, int y)
520 x2 = nx; 552 x2 = nx;
521 } 553 }
522 554
555 /******************** In viewport clipping **********************/
523 /* nothing to draw? */ 556 /* nothing to draw? */
524 if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) 557 if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width)
525 || (x2 < 0)) 558 || (x2 < 0))
526 return; 559 return;
527 560
528 /* clipping */
529 if (x1 < 0) 561 if (x1 < 0)
530 x1 = 0; 562 x1 = 0;
531 if (x2 >= current_vp->width) 563 if (x2 >= current_vp->width)
@@ -535,6 +567,20 @@ void lcd_hline(int x1, int x2, int y)
535 x1 += current_vp->x; 567 x1 += current_vp->x;
536 x2 += current_vp->x; 568 x2 += current_vp->x;
537 y += current_vp->y; 569 y += current_vp->y;
570
571#if defined(HAVE_VIEWPORT_CLIP)
572 /********************* Viewport on screen clipping ********************/
573 /* nothing to draw? */
574 if (((unsigned)y >= (unsigned) LCD_HEIGHT) || (x1 >= LCD_WIDTH)
575 || (x2 < 0))
576 return;
577
578 /* clipping */
579 if (x1 < 0)
580 x1 = 0;
581 if (x2 >= LCD_WIDTH)
582 x2 = LCD_WIDTH-1;
583#endif
538 584
539 bfunc = lcd_blockfuncs[current_vp->drawmode]; 585 bfunc = lcd_blockfuncs[current_vp->drawmode];
540 dst = &lcd_framebuffer[y][x1>>2]; 586 dst = &lcd_framebuffer[y][x1>>2];
@@ -567,12 +613,12 @@ void lcd_vline(int x, int y1, int y2)
567 y2 = y; 613 y2 = y;
568 } 614 }
569 615
616 /******************** In viewport clipping **********************/
570 /* nothing to draw? */ 617 /* nothing to draw? */
571 if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) 618 if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height)
572 || (y2 < 0)) 619 || (y2 < 0))
573 return; 620 return;
574 621
575 /* clipping */
576 if (y1 < 0) 622 if (y1 < 0)
577 y1 = 0; 623 y1 = 0;
578 if (y2 >= current_vp->height) 624 if (y2 >= current_vp->height)
@@ -582,6 +628,20 @@ void lcd_vline(int x, int y1, int y2)
582 y1 += current_vp->y; 628 y1 += current_vp->y;
583 y2 += current_vp->y; 629 y2 += current_vp->y;
584 x += current_vp->x; 630 x += current_vp->x;
631
632#if defined(HAVE_VIEWPORT_CLIP)
633 /********************* Viewport on screen clipping ********************/
634 /* nothing to draw? */
635 if (( (unsigned) x >= (unsigned)LCD_WIDTH) || (y1 >= LCD_HEIGHT)
636 || (y2 < 0))
637 return;
638
639 /* clipping */
640 if (y1 < 0)
641 y1 = 0;
642 if (y2 >= LCD_HEIGHT)
643 y2 = LCD_HEIGHT-1;
644#endif
585 645
586 bfunc = lcd_blockfuncs[current_vp->drawmode]; 646 bfunc = lcd_blockfuncs[current_vp->drawmode];
587 dst = &lcd_framebuffer[y1][x>>2]; 647 dst = &lcd_framebuffer[y1][x>>2];
@@ -619,12 +679,12 @@ void lcd_fillrect(int x, int y, int width, int height)
619 unsigned mask, mask_right; 679 unsigned mask, mask_right;
620 lcd_blockfunc_type *bfunc; 680 lcd_blockfunc_type *bfunc;
621 681
682 /******************** In viewport clipping **********************/
622 /* nothing to draw? */ 683 /* nothing to draw? */
623 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || (y >= current_vp->height) 684 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || (y >= current_vp->height)
624 || (x + width <= 0) || (y + height <= 0)) 685 || (x + width <= 0) || (y + height <= 0))
625 return; 686 return;
626 687
627 /* clipping */
628 if (x < 0) 688 if (x < 0)
629 { 689 {
630 width += x; 690 width += x;
@@ -643,6 +703,30 @@ void lcd_fillrect(int x, int y, int width, int height)
643 /* adjust for viewport */ 703 /* adjust for viewport */
644 x += current_vp->x; 704 x += current_vp->x;
645 y += current_vp->y; 705 y += current_vp->y;
706
707#if defined(HAVE_VIEWPORT_CLIP)
708 /********************* Viewport on screen clipping ********************/
709 /* nothing to draw? */
710 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
711 || (x + width <= 0) || (y + height <= 0))
712 return;
713
714 /* clip image in viewport in screen */
715 if (x < 0)
716 {
717 width += x;
718 x = 0;
719 }
720 if (y < 0)
721 {
722 height += y;
723 y = 0;
724 }
725 if (x + width > LCD_WIDTH)
726 width = LCD_WIDTH - x;
727 if (y + height > LCD_HEIGHT)
728 height = LCD_HEIGHT - y;
729#endif
646 730
647 bfunc = lcd_blockfuncs[current_vp->drawmode]; 731 bfunc = lcd_blockfuncs[current_vp->drawmode];
648 dst = &lcd_framebuffer[y][x>>2]; 732 dst = &lcd_framebuffer[y][x>>2];
@@ -696,12 +780,12 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
696 unsigned dst_mask; 780 unsigned dst_mask;
697 int drmode = current_vp->drawmode; 781 int drmode = current_vp->drawmode;
698 782
783 /******************** Image in viewport clipping **********************/
699 /* nothing to draw? */ 784 /* nothing to draw? */
700 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 785 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
701 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 786 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
702 return; 787 return;
703 788
704 /* clipping */
705 if (x < 0) 789 if (x < 0)
706 { 790 {
707 width += x; 791 width += x;
@@ -718,12 +802,41 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
718 width = current_vp->width - x; 802 width = current_vp->width - x;
719 if (y + height > current_vp->height) 803 if (y + height > current_vp->height)
720 height = current_vp->height - y; 804 height = current_vp->height - y;
805
806 x += current_vp->x; /* adjust for viewport */
807 y += current_vp->y; /* adjust for viewport */
808
809#if defined(HAVE_VIEWPORT_CLIP)
810 /********************* Viewport on screen clipping ********************/
811 /* nothing to draw? */
812 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
813 || (x + width <= 0) || (y + height <= 0))
814 return;
815
816 /* clip image in viewport in screen */
817 if (x < 0)
818 {
819 width += x;
820 src_x -= x;
821 x = 0;
822 }
823 if (y < 0)
824 {
825 height += y;
826 src_y -= y;
827 y = 0;
828 }
829 if (x + width > LCD_WIDTH)
830 width = LCD_WIDTH - x;
831 if (y + height > LCD_HEIGHT)
832 height = LCD_HEIGHT - y;
833#endif
721 834
722 src += stride * (src_y >> 3) + src_x; /* move starting point */ 835 src += stride * (src_y >> 3) + src_x; /* move starting point */
723 src_y &= 7; 836 src_y &= 7;
724 src_end = src + width; 837 src_end = src + width;
725 x += current_vp->x; /* adjust for viewport */ 838
726 dst = &lcd_framebuffer[current_vp->y + y][x >> 2]; 839 dst = &lcd_framebuffer[y][x >> 2];
727 dst_end = dst + height * LCD_FBWIDTH; 840 dst_end = dst + height * LCD_FBWIDTH;
728 dst_mask = pixmask[x & 3]; 841 dst_mask = pixmask[x & 3];
729 842
@@ -879,12 +992,12 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
879 unsigned char *dst, *dst_end; 992 unsigned char *dst, *dst_end;
880 unsigned mask, mask_right; 993 unsigned mask, mask_right;
881 994
995 /******************** Image in viewport clipping **********************/
882 /* nothing to draw? */ 996 /* nothing to draw? */
883 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 997 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
884 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) 998 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
885 return; 999 return;
886 1000
887 /* clipping */
888 if (x < 0) 1001 if (x < 0)
889 { 1002 {
890 width += x; 1003 width += x;
@@ -905,6 +1018,32 @@ void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x,
905 /* adjust for viewport */ 1018 /* adjust for viewport */
906 x += current_vp->x; 1019 x += current_vp->x;
907 y += current_vp->y; 1020 y += current_vp->y;
1021
1022#if defined(HAVE_VIEWPORT_CLIP)
1023 /********************* Viewport on screen clipping ********************/
1024 /* nothing to draw? */
1025 if ((x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
1026 || (x + width <= 0) || (y + height <= 0))
1027 return;
1028
1029 /* clip image in viewport in screen */
1030 if (x < 0)
1031 {
1032 width += x;
1033 src_x -= x;
1034 x = 0;
1035 }
1036 if (y < 0)
1037 {
1038 height += y;
1039 src_y -= y;
1040 y = 0;
1041 }
1042 if (x + width > LCD_WIDTH)
1043 width = LCD_WIDTH - x;
1044 if (y + height > LCD_HEIGHT)
1045 height = LCD_HEIGHT - y;
1046#endif
908 1047
909 stride = (stride + 3) >> 2; /* convert to no. of bytes */ 1048 stride = (stride + 3) >> 2; /* convert to no. of bytes */
910 1049