diff options
Diffstat (limited to 'firmware/drivers/lcd-2bit-horz.c')
-rw-r--r-- | firmware/drivers/lcd-2bit-horz.c | 148 |
1 files changed, 122 insertions, 26 deletions
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index 4dc82deae0..70f7261e35 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c | |||
@@ -690,10 +690,11 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
690 | int src_y, int stride, int x, int y, | 690 | int src_y, int stride, int x, int y, |
691 | int width, int height) | 691 | int width, int height) |
692 | { | 692 | { |
693 | int ny, nx, ymax; | 693 | const unsigned char *src_end; |
694 | const unsigned char * src_end; | 694 | fb_data *dst, *dst_end; |
695 | lcd_pixelfunc_type* fgfunc; | 695 | unsigned dmask = 0x100; /* bit 8 == sentinel */ |
696 | lcd_pixelfunc_type* bgfunc; | 696 | unsigned dst_mask; |
697 | int drmode = current_vp->drawmode; | ||
697 | 698 | ||
698 | /* nothing to draw? */ | 699 | /* nothing to draw? */ |
699 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 700 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || |
@@ -718,42 +719,137 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
718 | if (y + height > current_vp->height) | 719 | if (y + height > current_vp->height) |
719 | height = current_vp->height - y; | 720 | height = current_vp->height - y; |
720 | 721 | ||
721 | /* adjust for viewport */ | ||
722 | x += current_vp->x; | ||
723 | y += current_vp->y; | ||
724 | |||
725 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 722 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
726 | src_y &= 7; | 723 | src_y &= 7; |
727 | src_end = src + width; | 724 | src_end = src + width; |
725 | x += current_vp->x; /* adjust for viewport */ | ||
726 | dst = &lcd_framebuffer[current_vp->y + y][x >> 2]; | ||
727 | dst_end = dst + height * LCD_FBWIDTH; | ||
728 | dst_mask = pixmask[x & 3]; | ||
729 | |||
730 | if (drmode & DRMODE_INVERSEVID) | ||
731 | { | ||
732 | dmask = 0x1ff; /* bit 8 == sentinel */ | ||
733 | drmode &= DRMODE_SOLID; /* mask out inversevid */ | ||
734 | } | ||
728 | 735 | ||
729 | fgfunc = lcd_pixelfuncs[current_vp->drawmode]; | ||
730 | bgfunc = lcd_pixelfuncs[current_vp->drawmode ^ DRMODE_INVERSEVID]; | ||
731 | nx = x; | ||
732 | do | 736 | do |
733 | { | 737 | { |
734 | const unsigned char *src_col = src++; | 738 | const unsigned char *src_col = src++; |
735 | unsigned data = (*src_col | 0x100) >> src_y; /* bit 8 == sentinel */ | 739 | unsigned data = (*src_col ^ dmask) >> src_y; |
736 | 740 | fb_data *dst_col = dst; | |
737 | ymax = y + height; | 741 | int fg, bg; |
738 | ny = y; | 742 | long bo; |
739 | do | 743 | |
744 | #define UPDATE_SRC do { \ | ||
745 | data >>= 1; \ | ||
746 | if (data == 0x001) { \ | ||
747 | src_col += stride; \ | ||
748 | data = *src_col ^ dmask; \ | ||
749 | } \ | ||
750 | } while (0) | ||
751 | |||
752 | switch (drmode) | ||
740 | { | 753 | { |
741 | if (data & 0x01) | 754 | case DRMODE_COMPLEMENT: |
742 | fgfunc(nx,ny); | 755 | do |
756 | { | ||
757 | if (data & 0x01) | ||
758 | *dst_col ^= dst_mask; | ||
759 | |||
760 | dst_col += LCD_FBWIDTH; | ||
761 | UPDATE_SRC; | ||
762 | } | ||
763 | while (dst_col < dst_end); | ||
764 | break; | ||
765 | |||
766 | case DRMODE_BG: | ||
767 | if (lcd_backdrop) | ||
768 | { | ||
769 | bo = lcd_backdrop_offset; | ||
770 | do | ||
771 | { | ||
772 | if (!(data & 0x01)) | ||
773 | { | ||
774 | unsigned block = *dst_col; | ||
775 | *dst_col = block | ||
776 | ^ ((block ^ *(dst_col + bo)) & dst_mask); | ||
777 | } | ||
778 | dst_col += LCD_FBWIDTH; | ||
779 | UPDATE_SRC; | ||
780 | } | ||
781 | while (dst_col < dst_end); | ||
782 | } | ||
743 | else | 783 | else |
744 | bgfunc(nx,ny); | 784 | { |
785 | bg = bg_pattern; | ||
786 | do | ||
787 | { | ||
788 | if (!(data & 0x01)) | ||
789 | { | ||
790 | unsigned block = *dst_col; | ||
791 | *dst_col = block ^ ((block ^ bg) & dst_mask); | ||
792 | } | ||
793 | dst_col += LCD_FBWIDTH; | ||
794 | UPDATE_SRC; | ||
795 | } | ||
796 | while (dst_col < dst_end); | ||
797 | } | ||
798 | break; | ||
745 | 799 | ||
746 | ny++; | 800 | case DRMODE_FG: |
801 | fg = fg_pattern; | ||
802 | do | ||
803 | { | ||
804 | if (data & 0x01) | ||
805 | { | ||
806 | unsigned block = *dst_col; | ||
807 | *dst_col = block ^ ((block ^ fg) & dst_mask); | ||
808 | } | ||
809 | dst_col += LCD_FBWIDTH; | ||
810 | UPDATE_SRC; | ||
811 | } | ||
812 | while (dst_col < dst_end); | ||
813 | break; | ||
747 | 814 | ||
748 | data >>= 1; | 815 | case DRMODE_SOLID: |
749 | if (data == 0x001) | 816 | fg = fg_pattern; |
817 | if (lcd_backdrop) | ||
818 | { | ||
819 | bo = lcd_backdrop_offset; | ||
820 | do | ||
821 | { | ||
822 | unsigned block = *dst_col; | ||
823 | *dst_col = block ^ ((block ^ ((data & 0x01) ? | ||
824 | fg : *(dst_col + bo))) & dst_mask); | ||
825 | |||
826 | dst_col += LCD_FBWIDTH; | ||
827 | UPDATE_SRC; | ||
828 | } | ||
829 | while (dst_col < dst_end); | ||
830 | } | ||
831 | else | ||
750 | { | 832 | { |
751 | src_col += stride; | 833 | bg = bg_pattern; |
752 | data = *src_col | 0x100; | 834 | do |
835 | { | ||
836 | unsigned block = *dst_col; | ||
837 | *dst_col = block ^ ((block ^ ((data & 0x01) ? | ||
838 | fg : bg)) & dst_mask); | ||
839 | |||
840 | dst_col += LCD_FBWIDTH; | ||
841 | UPDATE_SRC; | ||
842 | } | ||
843 | while (dst_col < dst_end); | ||
753 | } | 844 | } |
845 | break; | ||
846 | } | ||
847 | dst_mask >>= 2; | ||
848 | if (dst_mask == 0) | ||
849 | { | ||
850 | dst++; | ||
851 | dst_mask = 0xC0; | ||
754 | } | 852 | } |
755 | while (ny < ymax); | ||
756 | nx++; | ||
757 | } | 853 | } |
758 | while (src < src_end); | 854 | while (src < src_end); |
759 | } | 855 | } |