diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/lcd-16bit-common.c | 112 | ||||
-rw-r--r-- | firmware/drivers/lcd-16bit-vert.c | 98 | ||||
-rw-r--r-- | firmware/drivers/lcd-16bit.c | 93 | ||||
-rw-r--r-- | firmware/drivers/lcd-1bit-vert.c | 176 | ||||
-rw-r--r-- | firmware/drivers/lcd-24bit.c | 180 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-horz.c | 215 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-vert.c | 210 | ||||
-rw-r--r-- | firmware/drivers/lcd-2bit-vi.c | 202 | ||||
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 166 | ||||
-rw-r--r-- | firmware/drivers/lcd-color-common.c | 95 | ||||
-rw-r--r-- | firmware/drivers/lcd-scroll.c | 8 |
11 files changed, 906 insertions, 649 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c index a7e80c7244..7c766dab8a 100644 --- a/firmware/drivers/lcd-16bit-common.c +++ b/firmware/drivers/lcd-16bit-common.c | |||
@@ -35,10 +35,10 @@ void lcd_clear_viewport(void) | |||
35 | int x, y, width, height; | 35 | int x, y, width, height; |
36 | int len, step; | 36 | int len, step; |
37 | 37 | ||
38 | x = current_vp->x; | 38 | x = lcd_current_viewport->x; |
39 | y = current_vp->y; | 39 | y = lcd_current_viewport->y; |
40 | width = current_vp->width; | 40 | width = lcd_current_viewport->width; |
41 | height = current_vp->height; | 41 | height = lcd_current_viewport->height; |
42 | 42 | ||
43 | #if defined(HAVE_VIEWPORT_CLIP) | 43 | #if defined(HAVE_VIEWPORT_CLIP) |
44 | /********************* Viewport on screen clipping ********************/ | 44 | /********************* Viewport on screen clipping ********************/ |
@@ -70,11 +70,11 @@ void lcd_clear_viewport(void) | |||
70 | dst = FBADDR(x, y); | 70 | dst = FBADDR(x, y); |
71 | dst_end = FBADDR(x + width - 1 , y + height - 1); | 71 | dst_end = FBADDR(x + width - 1 , y + height - 1); |
72 | 72 | ||
73 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 73 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
74 | { | 74 | { |
75 | do | 75 | do |
76 | { | 76 | { |
77 | memset16(dst, current_vp->fg_pattern, len); | 77 | memset16(dst, lcd_current_viewport->fg_pattern, len); |
78 | dst += step; | 78 | dst += step; |
79 | } | 79 | } |
80 | while (dst <= dst_end); | 80 | while (dst <= dst_end); |
@@ -85,7 +85,7 @@ void lcd_clear_viewport(void) | |||
85 | { | 85 | { |
86 | do | 86 | do |
87 | { | 87 | { |
88 | memset16(dst, current_vp->bg_pattern, len); | 88 | memset16(dst, lcd_current_viewport->bg_pattern, len); |
89 | dst += step; | 89 | dst += step; |
90 | } | 90 | } |
91 | while (dst <= dst_end); | 91 | while (dst <= dst_end); |
@@ -102,22 +102,24 @@ void lcd_clear_viewport(void) | |||
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | if (current_vp == &default_vp) | 105 | if (lcd_current_viewport == &default_vp) |
106 | lcd_scroll_stop(); | 106 | lcd_scroll_stop(); |
107 | else | 107 | else |
108 | lcd_scroll_stop_viewport(current_vp); | 108 | lcd_scroll_stop_viewport(lcd_current_viewport); |
109 | |||
110 | lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN); | ||
109 | } | 111 | } |
110 | 112 | ||
111 | /*** low-level drawing functions ***/ | 113 | /*** low-level drawing functions ***/ |
112 | 114 | ||
113 | static void ICODE_ATTR setpixel(fb_data *address) | 115 | static void ICODE_ATTR setpixel(fb_data *address) |
114 | { | 116 | { |
115 | *address = current_vp->fg_pattern; | 117 | *address = lcd_current_viewport->fg_pattern; |
116 | } | 118 | } |
117 | 119 | ||
118 | static void ICODE_ATTR clearpixel(fb_data *address) | 120 | static void ICODE_ATTR clearpixel(fb_data *address) |
119 | { | 121 | { |
120 | *address = current_vp->bg_pattern; | 122 | *address = lcd_current_viewport->bg_pattern; |
121 | } | 123 | } |
122 | 124 | ||
123 | static void ICODE_ATTR clearimgpixel(fb_data *address) | 125 | static void ICODE_ATTR clearimgpixel(fb_data *address) |
@@ -157,8 +159,8 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
157 | 159 | ||
158 | /******************** In viewport clipping **********************/ | 160 | /******************** In viewport clipping **********************/ |
159 | /* nothing to draw? */ | 161 | /* nothing to draw? */ |
160 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 162 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
161 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 163 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
162 | return; | 164 | return; |
163 | 165 | ||
164 | if (x < 0) | 166 | if (x < 0) |
@@ -171,14 +173,14 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
171 | height += y; | 173 | height += y; |
172 | y = 0; | 174 | y = 0; |
173 | } | 175 | } |
174 | if (x + width > current_vp->width) | 176 | if (x + width > lcd_current_viewport->width) |
175 | width = current_vp->width - x; | 177 | width = lcd_current_viewport->width - x; |
176 | if (y + height > current_vp->height) | 178 | if (y + height > lcd_current_viewport->height) |
177 | height = current_vp->height - y; | 179 | height = lcd_current_viewport->height - y; |
178 | 180 | ||
179 | /* adjust for viewport */ | 181 | /* adjust for viewport */ |
180 | x += current_vp->x; | 182 | x += lcd_current_viewport->x; |
181 | y += current_vp->y; | 183 | y += lcd_current_viewport->y; |
182 | 184 | ||
183 | #if defined(HAVE_VIEWPORT_CLIP) | 185 | #if defined(HAVE_VIEWPORT_CLIP) |
184 | /********************* Viewport on screen clipping ********************/ | 186 | /********************* Viewport on screen clipping ********************/ |
@@ -205,14 +207,14 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
205 | #endif | 207 | #endif |
206 | 208 | ||
207 | /* drawmode and optimisation */ | 209 | /* drawmode and optimisation */ |
208 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 210 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
209 | { | 211 | { |
210 | if (current_vp->drawmode & DRMODE_BG) | 212 | if (lcd_current_viewport->drawmode & DRMODE_BG) |
211 | { | 213 | { |
212 | if (!lcd_backdrop) | 214 | if (!lcd_backdrop) |
213 | { | 215 | { |
214 | fillopt = OPT_SET; | 216 | fillopt = OPT_SET; |
215 | bits = current_vp->bg_pattern; | 217 | bits = lcd_current_viewport->bg_pattern; |
216 | } | 218 | } |
217 | else | 219 | else |
218 | fillopt = OPT_COPY; | 220 | fillopt = OPT_COPY; |
@@ -220,13 +222,13 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
220 | } | 222 | } |
221 | else | 223 | else |
222 | { | 224 | { |
223 | if (current_vp->drawmode & DRMODE_FG) | 225 | if (lcd_current_viewport->drawmode & DRMODE_FG) |
224 | { | 226 | { |
225 | fillopt = OPT_SET; | 227 | fillopt = OPT_SET; |
226 | bits = current_vp->fg_pattern; | 228 | bits = lcd_current_viewport->fg_pattern; |
227 | } | 229 | } |
228 | } | 230 | } |
229 | if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) | 231 | if (fillopt == OPT_NONE && lcd_current_viewport->drawmode != DRMODE_COMPLEMENT) |
230 | return; | 232 | return; |
231 | 233 | ||
232 | dst = FBADDR(x, y); | 234 | dst = FBADDR(x, y); |
@@ -284,13 +286,13 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
284 | const unsigned char *src_end; | 286 | const unsigned char *src_end; |
285 | fb_data *dst, *dst_col; | 287 | fb_data *dst, *dst_col; |
286 | unsigned dmask = 0x100; /* bit 8 == sentinel */ | 288 | unsigned dmask = 0x100; /* bit 8 == sentinel */ |
287 | int drmode = current_vp->drawmode; | 289 | int drmode = lcd_current_viewport->drawmode; |
288 | int row; | 290 | int row; |
289 | 291 | ||
290 | /******************** Image in viewport clipping **********************/ | 292 | /******************** Image in viewport clipping **********************/ |
291 | /* nothing to draw? */ | 293 | /* nothing to draw? */ |
292 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 294 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
293 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 295 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
294 | return; | 296 | return; |
295 | 297 | ||
296 | if (x < 0) | 298 | if (x < 0) |
@@ -305,14 +307,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
305 | src_y -= y; | 307 | src_y -= y; |
306 | y = 0; | 308 | y = 0; |
307 | } | 309 | } |
308 | if (x + width > current_vp->width) | 310 | if (x + width > lcd_current_viewport->width) |
309 | width = current_vp->width - x; | 311 | width = lcd_current_viewport->width - x; |
310 | if (y + height > current_vp->height) | 312 | if (y + height > lcd_current_viewport->height) |
311 | height = current_vp->height - y; | 313 | height = lcd_current_viewport->height - y; |
312 | 314 | ||
313 | /* adjust for viewport */ | 315 | /* adjust for viewport */ |
314 | x += current_vp->x; | 316 | x += lcd_current_viewport->x; |
315 | y += current_vp->y; | 317 | y += lcd_current_viewport->y; |
316 | 318 | ||
317 | #if defined(HAVE_VIEWPORT_CLIP) | 319 | #if defined(HAVE_VIEWPORT_CLIP) |
318 | /********************* Viewport on screen clipping ********************/ | 320 | /********************* Viewport on screen clipping ********************/ |
@@ -404,7 +406,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
404 | break; | 406 | break; |
405 | 407 | ||
406 | case DRMODE_BG: | 408 | case DRMODE_BG: |
407 | bg = current_vp->bg_pattern; | 409 | bg = lcd_current_viewport->bg_pattern; |
408 | do | 410 | do |
409 | { | 411 | { |
410 | if (!(data & 0x01)) | 412 | if (!(data & 0x01)) |
@@ -417,7 +419,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
417 | break; | 419 | break; |
418 | 420 | ||
419 | case DRMODE_FG: | 421 | case DRMODE_FG: |
420 | fg = current_vp->fg_pattern; | 422 | fg = lcd_current_viewport->fg_pattern; |
421 | do | 423 | do |
422 | { | 424 | { |
423 | if (data & 0x01) | 425 | if (data & 0x01) |
@@ -430,7 +432,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
430 | break; | 432 | break; |
431 | 433 | ||
432 | case DRMODE_SOLID|DRMODE_INT_BD: | 434 | case DRMODE_SOLID|DRMODE_INT_BD: |
433 | fg = current_vp->fg_pattern; | 435 | fg = lcd_current_viewport->fg_pattern; |
434 | bo = lcd_backdrop_offset; | 436 | bo = lcd_backdrop_offset; |
435 | do | 437 | do |
436 | { | 438 | { |
@@ -443,8 +445,8 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
443 | break; | 445 | break; |
444 | 446 | ||
445 | case DRMODE_SOLID: | 447 | case DRMODE_SOLID: |
446 | fg = current_vp->fg_pattern; | 448 | fg = lcd_current_viewport->fg_pattern; |
447 | bg = current_vp->bg_pattern; | 449 | bg = lcd_current_viewport->bg_pattern; |
448 | do | 450 | do |
449 | { | 451 | { |
450 | *dst = (data & 0x01) ? fg : bg; | 452 | *dst = (data & 0x01) ? fg : bg; |
@@ -549,10 +551,10 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
549 | { | 551 | { |
550 | fb_data *dst, *dst_row; | 552 | fb_data *dst, *dst_row; |
551 | unsigned dmask = 0x00000000; | 553 | unsigned dmask = 0x00000000; |
552 | int drmode = current_vp->drawmode; | 554 | int drmode = lcd_current_viewport->drawmode; |
553 | /* nothing to draw? */ | 555 | /* nothing to draw? */ |
554 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 556 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
555 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 557 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
556 | return; | 558 | return; |
557 | /* initialize blending */ | 559 | /* initialize blending */ |
558 | BLEND_INIT; | 560 | BLEND_INIT; |
@@ -570,14 +572,14 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
570 | src_y -= y; | 572 | src_y -= y; |
571 | y = 0; | 573 | y = 0; |
572 | } | 574 | } |
573 | if (x + width > current_vp->width) | 575 | if (x + width > lcd_current_viewport->width) |
574 | width = current_vp->width - x; | 576 | width = lcd_current_viewport->width - x; |
575 | if (y + height > current_vp->height) | 577 | if (y + height > lcd_current_viewport->height) |
576 | height = current_vp->height - y; | 578 | height = lcd_current_viewport->height - y; |
577 | 579 | ||
578 | /* adjust for viewport */ | 580 | /* adjust for viewport */ |
579 | x += current_vp->x; | 581 | x += lcd_current_viewport->x; |
580 | y += current_vp->y; | 582 | y += lcd_current_viewport->y; |
581 | 583 | ||
582 | #if defined(HAVE_VIEWPORT_CLIP) | 584 | #if defined(HAVE_VIEWPORT_CLIP) |
583 | /********************* Viewport on screen clipping ********************/ | 585 | /********************* Viewport on screen clipping ********************/ |
@@ -668,7 +670,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
668 | /* go through the rows and update each pixel */ | 670 | /* go through the rows and update each pixel */ |
669 | do | 671 | do |
670 | { | 672 | { |
671 | /* saving current_vp->fg/bg_pattern and lcd_backdrop_offset into these | 673 | /* saving lcd_current_viewport->fg/bg_pattern and lcd_backdrop_offset into these |
672 | * temp vars just before the loop helps gcc to opimize the loop better | 674 | * temp vars just before the loop helps gcc to opimize the loop better |
673 | * (testing showed ~15% speedup) */ | 675 | * (testing showed ~15% speedup) */ |
674 | unsigned fg, bg; | 676 | unsigned fg, bg; |
@@ -727,7 +729,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
727 | while (--col); | 729 | while (--col); |
728 | break; | 730 | break; |
729 | case DRMODE_BG: | 731 | case DRMODE_BG: |
730 | bg = current_vp->bg_pattern; | 732 | bg = lcd_current_viewport->bg_pattern; |
731 | do | 733 | do |
732 | { | 734 | { |
733 | *dst = blend_two_colors(bg, *dst, data & ALPHA_COLOR_LOOKUP_SIZE ); | 735 | *dst = blend_two_colors(bg, *dst, data & ALPHA_COLOR_LOOKUP_SIZE ); |
@@ -747,7 +749,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
747 | while (--col); | 749 | while (--col); |
748 | break; | 750 | break; |
749 | case DRMODE_FG: | 751 | case DRMODE_FG: |
750 | fg = current_vp->fg_pattern; | 752 | fg = lcd_current_viewport->fg_pattern; |
751 | do | 753 | do |
752 | { | 754 | { |
753 | *dst = blend_two_colors(*dst, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); | 755 | *dst = blend_two_colors(*dst, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); |
@@ -758,7 +760,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
758 | break; | 760 | break; |
759 | case DRMODE_SOLID|DRMODE_INT_BD: | 761 | case DRMODE_SOLID|DRMODE_INT_BD: |
760 | bo = lcd_backdrop_offset; | 762 | bo = lcd_backdrop_offset; |
761 | fg = current_vp->fg_pattern; | 763 | fg = lcd_current_viewport->fg_pattern; |
762 | do | 764 | do |
763 | { | 765 | { |
764 | fb_data *c = (fb_data *)((uintptr_t)dst + bo); | 766 | fb_data *c = (fb_data *)((uintptr_t)dst + bo); |
@@ -769,7 +771,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
769 | while (--col); | 771 | while (--col); |
770 | break; | 772 | break; |
771 | case DRMODE_SOLID|DRMODE_INT_IMG: | 773 | case DRMODE_SOLID|DRMODE_INT_IMG: |
772 | bg = current_vp->bg_pattern; | 774 | bg = lcd_current_viewport->bg_pattern; |
773 | img_offset = image - dst; | 775 | img_offset = image - dst; |
774 | do | 776 | do |
775 | { | 777 | { |
@@ -792,8 +794,8 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
792 | while (--col); | 794 | while (--col); |
793 | break; | 795 | break; |
794 | case DRMODE_SOLID: | 796 | case DRMODE_SOLID: |
795 | bg = current_vp->bg_pattern; | 797 | bg = lcd_current_viewport->bg_pattern; |
796 | fg = current_vp->fg_pattern; | 798 | fg = lcd_current_viewport->fg_pattern; |
797 | do | 799 | do |
798 | { | 800 | { |
799 | *dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); | 801 | *dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); |
diff --git a/firmware/drivers/lcd-16bit-vert.c b/firmware/drivers/lcd-16bit-vert.c index ffe2b85b3c..b336e78c78 100644 --- a/firmware/drivers/lcd-16bit-vert.c +++ b/firmware/drivers/lcd-16bit-vert.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include "scroll_engine.h" | 39 | #include "scroll_engine.h" |
40 | 40 | ||
41 | #define ROW_INC 1 | 41 | #define ROW_INC 1 |
42 | #define COL_INC LCD_HEIGHT | 42 | #define COL_INC lcd_current_viewport->buffer->stride |
43 | 43 | ||
44 | extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[]; | 44 | extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[]; |
45 | extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_bgcolor[]; | 45 | extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_bgcolor[]; |
@@ -61,7 +61,9 @@ void lcd_hline(int x1, int x2, int y) | |||
61 | { | 61 | { |
62 | int x; | 62 | int x; |
63 | fb_data *dst, *dst_end; | 63 | fb_data *dst, *dst_end; |
64 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; | 64 | int stride_dst; |
65 | |||
66 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; | ||
65 | 67 | ||
66 | /* direction flip */ | 68 | /* direction flip */ |
67 | if (x2 < x1) | 69 | if (x2 < x1) |
@@ -73,20 +75,20 @@ void lcd_hline(int x1, int x2, int y) | |||
73 | 75 | ||
74 | /******************** In viewport clipping **********************/ | 76 | /******************** In viewport clipping **********************/ |
75 | /* nothing to draw? */ | 77 | /* nothing to draw? */ |
76 | if (((unsigned)y >= (unsigned)current_vp->height) || | 78 | if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || |
77 | (x1 >= current_vp->width) || | 79 | (x1 >= lcd_current_viewport->width) || |
78 | (x2 < 0)) | 80 | (x2 < 0)) |
79 | return; | 81 | return; |
80 | 82 | ||
81 | if (x1 < 0) | 83 | if (x1 < 0) |
82 | x1 = 0; | 84 | x1 = 0; |
83 | if (x2 >= current_vp->width) | 85 | if (x2 >= lcd_current_viewport->width) |
84 | x2 = current_vp->width-1; | 86 | x2 = lcd_current_viewport->width-1; |
85 | 87 | ||
86 | /* Adjust x1 and y to viewport */ | 88 | /* Adjust x1 and y to viewport */ |
87 | x1 += current_vp->x; | 89 | x1 += lcd_current_viewport->x; |
88 | x2 += current_vp->x; | 90 | x2 += lcd_current_viewport->x; |
89 | y += current_vp->y; | 91 | y += lcd_current_viewport->y; |
90 | 92 | ||
91 | #if defined(HAVE_VIEWPORT_CLIP) | 93 | #if defined(HAVE_VIEWPORT_CLIP) |
92 | /********************* Viewport on screen clipping ********************/ | 94 | /********************* Viewport on screen clipping ********************/ |
@@ -103,12 +105,13 @@ void lcd_hline(int x1, int x2, int y) | |||
103 | #endif | 105 | #endif |
104 | 106 | ||
105 | dst = FBADDR(x1 , y ); | 107 | dst = FBADDR(x1 , y ); |
106 | dst_end = dst + (x2 - x1) * LCD_HEIGHT; | 108 | stride_dst = lcd_current_viewport->buffer->stride; |
109 | dst_end = dst + (x2 - x1) * stride_dst; | ||
107 | 110 | ||
108 | do | 111 | do |
109 | { | 112 | { |
110 | pfunc(dst); | 113 | pfunc(dst); |
111 | dst += LCD_HEIGHT; | 114 | dst += stride_dst; |
112 | } | 115 | } |
113 | while (dst <= dst_end); | 116 | while (dst <= dst_end); |
114 | } | 117 | } |
@@ -131,20 +134,20 @@ void lcd_vline(int x, int y1, int y2) | |||
131 | 134 | ||
132 | /******************** In viewport clipping **********************/ | 135 | /******************** In viewport clipping **********************/ |
133 | /* nothing to draw? */ | 136 | /* nothing to draw? */ |
134 | if (((unsigned)x >= (unsigned)current_vp->width) || | 137 | if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || |
135 | (y1 >= current_vp->height) || | 138 | (y1 >= lcd_current_viewport->height) || |
136 | (y2 < 0)) | 139 | (y2 < 0)) |
137 | return; | 140 | return; |
138 | 141 | ||
139 | if (y1 < 0) | 142 | if (y1 < 0) |
140 | y1 = 0; | 143 | y1 = 0; |
141 | if (y2 >= current_vp->height) | 144 | if (y2 >= lcd_current_viewport->height) |
142 | y2 = current_vp->height-1; | 145 | y2 = lcd_current_viewport->height-1; |
143 | 146 | ||
144 | /* adjust for viewport */ | 147 | /* adjust for viewport */ |
145 | x += current_vp->x; | 148 | x += lcd_current_viewport->x; |
146 | y1 += current_vp->y; | 149 | y1 += lcd_current_viewport->y; |
147 | y2 += current_vp->y; | 150 | y2 += lcd_current_viewport->y; |
148 | 151 | ||
149 | #if defined(HAVE_VIEWPORT_CLIP) | 152 | #if defined(HAVE_VIEWPORT_CLIP) |
150 | /********************* Viewport on screen clipping ********************/ | 153 | /********************* Viewport on screen clipping ********************/ |
@@ -163,14 +166,14 @@ void lcd_vline(int x, int y1, int y2) | |||
163 | height = y2 - y1 + 1; | 166 | height = y2 - y1 + 1; |
164 | 167 | ||
165 | /* drawmode and optimisation */ | 168 | /* drawmode and optimisation */ |
166 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 169 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
167 | { | 170 | { |
168 | if (current_vp->drawmode & DRMODE_BG) | 171 | if (lcd_current_viewport->drawmode & DRMODE_BG) |
169 | { | 172 | { |
170 | if (!lcd_backdrop) | 173 | if (!lcd_backdrop) |
171 | { | 174 | { |
172 | fillopt = OPT_SET; | 175 | fillopt = OPT_SET; |
173 | bits = current_vp->bg_pattern; | 176 | bits = lcd_current_viewport->bg_pattern; |
174 | } | 177 | } |
175 | else | 178 | else |
176 | fillopt = OPT_COPY; | 179 | fillopt = OPT_COPY; |
@@ -178,13 +181,13 @@ void lcd_vline(int x, int y1, int y2) | |||
178 | } | 181 | } |
179 | else | 182 | else |
180 | { | 183 | { |
181 | if (current_vp->drawmode & DRMODE_FG) | 184 | if (lcd_current_viewport->drawmode & DRMODE_FG) |
182 | { | 185 | { |
183 | fillopt = OPT_SET; | 186 | fillopt = OPT_SET; |
184 | bits = current_vp->fg_pattern; | 187 | bits = lcd_current_viewport->fg_pattern; |
185 | } | 188 | } |
186 | } | 189 | } |
187 | if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) | 190 | if (fillopt == OPT_NONE && lcd_current_viewport->drawmode != DRMODE_COMPLEMENT) |
188 | return; | 191 | return; |
189 | 192 | ||
190 | dst = FBADDR(x, y1); | 193 | dst = FBADDR(x, y1); |
@@ -215,11 +218,11 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
215 | int height) | 218 | int height) |
216 | { | 219 | { |
217 | fb_data *dst; | 220 | fb_data *dst; |
218 | 221 | int stride_dst; | |
219 | /******************** Image in viewport clipping **********************/ | 222 | /******************** Image in viewport clipping **********************/ |
220 | /* nothing to draw? */ | 223 | /* nothing to draw? */ |
221 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 224 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
222 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 225 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
223 | return; | 226 | return; |
224 | 227 | ||
225 | if (x < 0) | 228 | if (x < 0) |
@@ -235,14 +238,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
235 | y = 0; | 238 | y = 0; |
236 | } | 239 | } |
237 | 240 | ||
238 | if (x + width > current_vp->width) | 241 | if (x + width > lcd_current_viewport->width) |
239 | width = current_vp->width - x; | 242 | width = lcd_current_viewport->width - x; |
240 | if (y + height > current_vp->height) | 243 | if (y + height > lcd_current_viewport->height) |
241 | height = current_vp->height - y; | 244 | height = lcd_current_viewport->height - y; |
242 | 245 | ||
243 | /* adjust for viewport */ | 246 | /* adjust for viewport */ |
244 | x += current_vp->x; | 247 | x += lcd_current_viewport->x; |
245 | y += current_vp->y; | 248 | y += lcd_current_viewport->y; |
246 | 249 | ||
247 | #if defined(HAVE_VIEWPORT_CLIP) | 250 | #if defined(HAVE_VIEWPORT_CLIP) |
248 | /********************* Viewport on screen clipping ********************/ | 251 | /********************* Viewport on screen clipping ********************/ |
@@ -272,13 +275,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
272 | 275 | ||
273 | src += stride * src_x + src_y; /* move starting point */ | 276 | src += stride * src_x + src_y; /* move starting point */ |
274 | dst = FBADDR(x, y); | 277 | dst = FBADDR(x, y); |
275 | fb_data *dst_end = dst + width * LCD_HEIGHT; | 278 | stride_dst = lcd_current_viewport->buffer->stride; |
279 | fb_data *dst_end = dst + width * stride_dst; | ||
276 | 280 | ||
277 | do | 281 | do |
278 | { | 282 | { |
279 | memcpy(dst, src, height * sizeof(fb_data)); | 283 | memcpy(dst, src, height * sizeof(fb_data)); |
280 | src += stride; | 284 | src += stride; |
281 | dst += LCD_HEIGHT; | 285 | dst += stride_dst; |
282 | } | 286 | } |
283 | while (dst < dst_end); | 287 | while (dst < dst_end); |
284 | } | 288 | } |
@@ -289,11 +293,12 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
289 | int y, int width, int height) | 293 | int y, int width, int height) |
290 | { | 294 | { |
291 | fb_data *dst, *dst_end; | 295 | fb_data *dst, *dst_end; |
296 | int stride_dst; | ||
292 | 297 | ||
293 | /******************** Image in viewport clipping **********************/ | 298 | /******************** Image in viewport clipping **********************/ |
294 | /* nothing to draw? */ | 299 | /* nothing to draw? */ |
295 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 300 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
296 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 301 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
297 | return; | 302 | return; |
298 | 303 | ||
299 | if (x < 0) | 304 | if (x < 0) |
@@ -309,14 +314,14 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
309 | y = 0; | 314 | y = 0; |
310 | } | 315 | } |
311 | 316 | ||
312 | if (x + width > current_vp->width) | 317 | if (x + width > lcd_current_viewport->width) |
313 | width = current_vp->width - x; | 318 | width = lcd_current_viewport->width - x; |
314 | if (y + height > current_vp->height) | 319 | if (y + height > lcd_current_viewport->height) |
315 | height = current_vp->height - y; | 320 | height = lcd_current_viewport->height - y; |
316 | 321 | ||
317 | /* adjust for viewport */ | 322 | /* adjust for viewport */ |
318 | x += current_vp->x; | 323 | x += lcd_current_viewport->x; |
319 | y += current_vp->y; | 324 | y += lcd_current_viewport->y; |
320 | 325 | ||
321 | #if defined(HAVE_VIEWPORT_CLIP) | 326 | #if defined(HAVE_VIEWPORT_CLIP) |
322 | /********************* Viewport on screen clipping ********************/ | 327 | /********************* Viewport on screen clipping ********************/ |
@@ -346,7 +351,8 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
346 | 351 | ||
347 | src += stride * src_x + src_y; /* move starting point */ | 352 | src += stride * src_x + src_y; /* move starting point */ |
348 | dst = FBADDR(x, y); | 353 | dst = FBADDR(x, y); |
349 | dst_end = dst + width * LCD_HEIGHT; | 354 | stride_dst = lcd_current_viewport->buffer->stride; |
355 | dst_end = dst + width * stride_dst; | ||
350 | 356 | ||
351 | do | 357 | do |
352 | { | 358 | { |
@@ -354,12 +360,12 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
354 | for(i = 0;i < height;i++) | 360 | for(i = 0;i < height;i++) |
355 | { | 361 | { |
356 | if (src[i] == REPLACEWITHFG_COLOR) | 362 | if (src[i] == REPLACEWITHFG_COLOR) |
357 | dst[i] = current_vp->fg_pattern; | 363 | dst[i] = lcd_current_viewport->fg_pattern; |
358 | else if(src[i] != TRANSPARENT_COLOR) | 364 | else if(src[i] != TRANSPARENT_COLOR) |
359 | dst[i] = src[i]; | 365 | dst[i] = src[i]; |
360 | } | 366 | } |
361 | src += stride; | 367 | src += stride; |
362 | dst += LCD_HEIGHT; | 368 | dst += stride_dst; |
363 | } | 369 | } |
364 | while (dst < dst_end); | 370 | while (dst < dst_end); |
365 | } | 371 | } |
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index b792be4e02..03c50f8ebf 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "bidi.h" | 38 | #include "bidi.h" |
39 | #include "scroll_engine.h" | 39 | #include "scroll_engine.h" |
40 | 40 | ||
41 | #define ROW_INC LCD_WIDTH | 41 | #define ROW_INC lcd_current_viewport->buffer->stride |
42 | #define COL_INC 1 | 42 | #define COL_INC 1 |
43 | 43 | ||
44 | extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[]; | 44 | extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[]; |
@@ -74,20 +74,20 @@ void lcd_hline(int x1, int x2, int y) | |||
74 | 74 | ||
75 | /******************** In viewport clipping **********************/ | 75 | /******************** In viewport clipping **********************/ |
76 | /* nothing to draw? */ | 76 | /* nothing to draw? */ |
77 | if (((unsigned)y >= (unsigned)current_vp->height) || | 77 | if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || |
78 | (x1 >= current_vp->width) || | 78 | (x1 >= lcd_current_viewport->width) || |
79 | (x2 < 0)) | 79 | (x2 < 0)) |
80 | return; | 80 | return; |
81 | 81 | ||
82 | if (x1 < 0) | 82 | if (x1 < 0) |
83 | x1 = 0; | 83 | x1 = 0; |
84 | if (x2 >= current_vp->width) | 84 | if (x2 >= lcd_current_viewport->width) |
85 | x2 = current_vp->width-1; | 85 | x2 = lcd_current_viewport->width-1; |
86 | 86 | ||
87 | /* Adjust x1 and y to viewport */ | 87 | /* Adjust x1 and y to viewport */ |
88 | x1 += current_vp->x; | 88 | x1 += lcd_current_viewport->x; |
89 | x2 += current_vp->x; | 89 | x2 += lcd_current_viewport->x; |
90 | y += current_vp->y; | 90 | y += lcd_current_viewport->y; |
91 | 91 | ||
92 | #if defined(HAVE_VIEWPORT_CLIP) | 92 | #if defined(HAVE_VIEWPORT_CLIP) |
93 | /********************* Viewport on screen clipping ********************/ | 93 | /********************* Viewport on screen clipping ********************/ |
@@ -106,14 +106,14 @@ void lcd_hline(int x1, int x2, int y) | |||
106 | width = x2 - x1 + 1; | 106 | width = x2 - x1 + 1; |
107 | 107 | ||
108 | /* drawmode and optimisation */ | 108 | /* drawmode and optimisation */ |
109 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 109 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
110 | { | 110 | { |
111 | if (current_vp->drawmode & DRMODE_BG) | 111 | if (lcd_current_viewport->drawmode & DRMODE_BG) |
112 | { | 112 | { |
113 | if (!lcd_backdrop) | 113 | if (!lcd_backdrop) |
114 | { | 114 | { |
115 | fillopt = OPT_SET; | 115 | fillopt = OPT_SET; |
116 | bits = current_vp->bg_pattern; | 116 | bits = lcd_current_viewport->bg_pattern; |
117 | } | 117 | } |
118 | else | 118 | else |
119 | fillopt = OPT_COPY; | 119 | fillopt = OPT_COPY; |
@@ -121,13 +121,13 @@ void lcd_hline(int x1, int x2, int y) | |||
121 | } | 121 | } |
122 | else | 122 | else |
123 | { | 123 | { |
124 | if (current_vp->drawmode & DRMODE_FG) | 124 | if (lcd_current_viewport->drawmode & DRMODE_FG) |
125 | { | 125 | { |
126 | fillopt = OPT_SET; | 126 | fillopt = OPT_SET; |
127 | bits = current_vp->fg_pattern; | 127 | bits = lcd_current_viewport->fg_pattern; |
128 | } | 128 | } |
129 | } | 129 | } |
130 | if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) | 130 | if (fillopt == OPT_NONE && lcd_current_viewport->drawmode != DRMODE_COMPLEMENT) |
131 | return; | 131 | return; |
132 | 132 | ||
133 | dst = FBADDR(x1, y); | 133 | dst = FBADDR(x1, y); |
@@ -157,7 +157,8 @@ void lcd_vline(int x, int y1, int y2) | |||
157 | { | 157 | { |
158 | int y; | 158 | int y; |
159 | fb_data *dst, *dst_end; | 159 | fb_data *dst, *dst_end; |
160 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; | 160 | int stride_dst; |
161 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; | ||
161 | 162 | ||
162 | /* direction flip */ | 163 | /* direction flip */ |
163 | if (y2 < y1) | 164 | if (y2 < y1) |
@@ -169,20 +170,20 @@ void lcd_vline(int x, int y1, int y2) | |||
169 | 170 | ||
170 | /******************** In viewport clipping **********************/ | 171 | /******************** In viewport clipping **********************/ |
171 | /* nothing to draw? */ | 172 | /* nothing to draw? */ |
172 | if (((unsigned)x >= (unsigned)current_vp->width) || | 173 | if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || |
173 | (y1 >= current_vp->height) || | 174 | (y1 >= lcd_current_viewport->height) || |
174 | (y2 < 0)) | 175 | (y2 < 0)) |
175 | return; | 176 | return; |
176 | 177 | ||
177 | if (y1 < 0) | 178 | if (y1 < 0) |
178 | y1 = 0; | 179 | y1 = 0; |
179 | if (y2 >= current_vp->height) | 180 | if (y2 >= lcd_current_viewport->height) |
180 | y2 = current_vp->height-1; | 181 | y2 = lcd_current_viewport->height-1; |
181 | 182 | ||
182 | /* adjust for viewport */ | 183 | /* adjust for viewport */ |
183 | x += current_vp->x; | 184 | x += lcd_current_viewport->x; |
184 | y1 += current_vp->y; | 185 | y1 += lcd_current_viewport->y; |
185 | y2 += current_vp->y; | 186 | y2 += lcd_current_viewport->y; |
186 | 187 | ||
187 | #if defined(HAVE_VIEWPORT_CLIP) | 188 | #if defined(HAVE_VIEWPORT_CLIP) |
188 | /********************* Viewport on screen clipping ********************/ | 189 | /********************* Viewport on screen clipping ********************/ |
@@ -199,12 +200,13 @@ void lcd_vline(int x, int y1, int y2) | |||
199 | #endif | 200 | #endif |
200 | 201 | ||
201 | dst = FBADDR(x , y1); | 202 | dst = FBADDR(x , y1); |
202 | dst_end = dst + (y2 - y1) * LCD_WIDTH; | 203 | stride_dst = lcd_current_viewport->buffer->stride; |
204 | dst_end = dst + (y2 - y1) * stride_dst; | ||
203 | 205 | ||
204 | do | 206 | do |
205 | { | 207 | { |
206 | pfunc(dst); | 208 | pfunc(dst); |
207 | dst += LCD_WIDTH; | 209 | dst += stride_dst; |
208 | } | 210 | } |
209 | while (dst <= dst_end); | 211 | while (dst <= dst_end); |
210 | } | 212 | } |
@@ -215,11 +217,12 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
215 | int height) | 217 | int height) |
216 | { | 218 | { |
217 | fb_data *dst; | 219 | fb_data *dst; |
220 | int stride_dst; | ||
218 | 221 | ||
219 | /******************** Image in viewport clipping **********************/ | 222 | /******************** Image in viewport clipping **********************/ |
220 | /* nothing to draw? */ | 223 | /* nothing to draw? */ |
221 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 224 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
222 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 225 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
223 | return; | 226 | return; |
224 | 227 | ||
225 | if (x < 0) | 228 | if (x < 0) |
@@ -235,14 +238,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
235 | y = 0; | 238 | y = 0; |
236 | } | 239 | } |
237 | 240 | ||
238 | if (x + width > current_vp->width) | 241 | if (x + width > lcd_current_viewport->width) |
239 | width = current_vp->width - x; | 242 | width = lcd_current_viewport->width - x; |
240 | if (y + height > current_vp->height) | 243 | if (y + height > lcd_current_viewport->height) |
241 | height = current_vp->height - y; | 244 | height = lcd_current_viewport->height - y; |
242 | 245 | ||
243 | /* adjust for viewport */ | 246 | /* adjust for viewport */ |
244 | x += current_vp->x; | 247 | x += lcd_current_viewport->x; |
245 | y += current_vp->y; | 248 | y += lcd_current_viewport->y; |
246 | 249 | ||
247 | #if defined(HAVE_VIEWPORT_CLIP) | 250 | #if defined(HAVE_VIEWPORT_CLIP) |
248 | /********************* Viewport on screen clipping ********************/ | 251 | /********************* Viewport on screen clipping ********************/ |
@@ -272,12 +275,13 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
272 | 275 | ||
273 | src += stride * src_y + src_x; /* move starting point */ | 276 | src += stride * src_y + src_x; /* move starting point */ |
274 | dst = FBADDR(x, y); | 277 | dst = FBADDR(x, y); |
278 | stride_dst = lcd_current_viewport->buffer->stride; | ||
275 | 279 | ||
276 | do | 280 | do |
277 | { | 281 | { |
278 | memcpy(dst, src, width * sizeof(fb_data)); | 282 | memcpy(dst, src, width * sizeof(fb_data)); |
279 | src += stride; | 283 | src += stride; |
280 | dst += LCD_WIDTH; | 284 | dst += stride_dst; |
281 | } | 285 | } |
282 | while (--height > 0); | 286 | while (--height > 0); |
283 | } | 287 | } |
@@ -288,12 +292,13 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
288 | int y, int width, int height) | 292 | int y, int width, int height) |
289 | { | 293 | { |
290 | fb_data *dst; | 294 | fb_data *dst; |
291 | unsigned fg = current_vp->fg_pattern; | 295 | unsigned fg = lcd_current_viewport->fg_pattern; |
296 | int stride_dst = lcd_current_viewport->buffer->stride; | ||
292 | 297 | ||
293 | /******************** Image in viewport clipping **********************/ | 298 | /******************** Image in viewport clipping **********************/ |
294 | /* nothing to draw? */ | 299 | /* nothing to draw? */ |
295 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 300 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
296 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 301 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
297 | return; | 302 | return; |
298 | 303 | ||
299 | if (x < 0) | 304 | if (x < 0) |
@@ -309,14 +314,14 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
309 | y = 0; | 314 | y = 0; |
310 | } | 315 | } |
311 | 316 | ||
312 | if (x + width > current_vp->width) | 317 | if (x + width > lcd_current_viewport->width) |
313 | width = current_vp->width - x; | 318 | width = lcd_current_viewport->width - x; |
314 | if (y + height > current_vp->height) | 319 | if (y + height > lcd_current_viewport->height) |
315 | height = current_vp->height - y; | 320 | height = lcd_current_viewport->height - y; |
316 | 321 | ||
317 | /* adjust for viewport */ | 322 | /* adjust for viewport */ |
318 | x += current_vp->x; | 323 | x += lcd_current_viewport->x; |
319 | y += current_vp->y; | 324 | y += lcd_current_viewport->y; |
320 | 325 | ||
321 | #if defined(HAVE_VIEWPORT_CLIP) | 326 | #if defined(HAVE_VIEWPORT_CLIP) |
322 | /********************* Viewport on screen clipping ********************/ | 327 | /********************* Viewport on screen clipping ********************/ |
@@ -371,7 +376,7 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
371 | [s]"+&r"(src), [d]"+&r"(dst) | 376 | [s]"+&r"(src), [d]"+&r"(dst) |
372 | : [width]"r"(width), | 377 | : [width]"r"(width), |
373 | [sstp]"r"(stride - width), | 378 | [sstp]"r"(stride - width), |
374 | [dstp]"r"(LCD_WIDTH - width), | 379 | [dstp]"r"(stride_dst - width), |
375 | [transcolor]"r"(TRANSPARENT_COLOR), | 380 | [transcolor]"r"(TRANSPARENT_COLOR), |
376 | [fgcolor]"r"(REPLACEWITHFG_COLOR), | 381 | [fgcolor]"r"(REPLACEWITHFG_COLOR), |
377 | [fgpat]"r"(fg) | 382 | [fgpat]"r"(fg) |
@@ -395,7 +400,7 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
395 | } | 400 | } |
396 | while (++dst_row < row_end); | 401 | while (++dst_row < row_end); |
397 | src += stride; | 402 | src += stride; |
398 | dst += LCD_WIDTH; | 403 | dst += stride_dst; |
399 | } | 404 | } |
400 | while (--height > 0); | 405 | while (--height > 0); |
401 | #endif | 406 | #endif |
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index 668c685187..57abdb91a6 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c | |||
@@ -44,9 +44,26 @@ | |||
44 | #define MAIN_LCD | 44 | #define MAIN_LCD |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | #ifdef MAIN_LCD | ||
48 | #define THIS_STRIDE STRIDE_MAIN | ||
49 | #else | ||
50 | #define THIS_STRIDE STRIDE_REMOTE | ||
51 | #endif | ||
52 | |||
53 | #define CURRENT_VP LCDFN(current_viewport) | ||
47 | /*** globals ***/ | 54 | /*** globals ***/ |
48 | FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER; | 55 | static FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER; |
49 | FBFN(data) *LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0]; | 56 | |
57 | static void *LCDFN(frameaddress_default)(int x, int y); | ||
58 | |||
59 | /* shouldn't be changed unless you want system-wide framebuffer changes! */ | ||
60 | struct frame_buffer_t LCDFN(framebuffer_default) = | ||
61 | { | ||
62 | .FBFN(ptr) = &LCDFN(static_framebuffer)[0][0], | ||
63 | .get_address_fn = &LCDFN(frameaddress_default), | ||
64 | .stride = THIS_STRIDE(LCDM(WIDTH), LCDM(HEIGHT)), | ||
65 | .elems = (LCDM(FBWIDTH)*LCDM(FBHEIGHT)), | ||
66 | }; | ||
50 | 67 | ||
51 | static struct viewport default_vp = | 68 | static struct viewport default_vp = |
52 | { | 69 | { |
@@ -56,55 +73,73 @@ static struct viewport default_vp = | |||
56 | .height = LCDM(HEIGHT), | 73 | .height = LCDM(HEIGHT), |
57 | .font = FONT_SYSFIXED, | 74 | .font = FONT_SYSFIXED, |
58 | .drawmode = DRMODE_SOLID, | 75 | .drawmode = DRMODE_SOLID, |
76 | .buffer = NULL, | ||
59 | }; | 77 | }; |
60 | 78 | ||
61 | static struct viewport* current_vp = &default_vp; | 79 | struct viewport* CURRENT_VP; |
80 | |||
81 | static void *LCDFN(frameaddress_default)(int x, int y) | ||
82 | { | ||
83 | /* the default expects a buffer the same size as the screen */ | ||
84 | struct frame_buffer_t *fb = CURRENT_VP->buffer; | ||
85 | #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE | ||
86 | size_t element = (x * LCDM(NATIVE_STRIDE)(fb->stride)) + y; | ||
87 | #else | ||
88 | size_t element = (y * LCDM(NATIVE_STRIDE)(fb->stride)) + x; | ||
89 | #endif | ||
90 | |||
91 | return fb->FBFN(ptr) + element;/*(element % fb->elems);*/ | ||
92 | } | ||
62 | 93 | ||
63 | /* LCD init */ | 94 | /* LCD init */ |
64 | void LCDFN(init)(void) | 95 | void LCDFN(init)(void) |
65 | { | 96 | { |
97 | |||
98 | /* Initialize the viewport */ | ||
99 | LCDFN(set_viewport)(NULL); | ||
66 | LCDFN(clear_display)(); | 100 | LCDFN(clear_display)(); |
67 | LCDFN(init_device)(); | 101 | LCDFN(init_device)(); |
68 | #ifdef MAIN_LCD | 102 | #ifdef MAIN_LCD |
69 | scroll_init(); | 103 | scroll_init(); |
70 | #endif | 104 | #endif |
105 | |||
71 | } | 106 | } |
72 | 107 | ||
73 | /*** parameter handling ***/ | 108 | /*** parameter handling ***/ |
74 | 109 | ||
75 | void LCDFN(set_drawmode)(int mode) | 110 | void LCDFN(set_drawmode)(int mode) |
76 | { | 111 | { |
77 | current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | 112 | CURRENT_VP->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); |
78 | } | 113 | } |
79 | 114 | ||
80 | int LCDFN(get_drawmode)(void) | 115 | int LCDFN(get_drawmode)(void) |
81 | { | 116 | { |
82 | return current_vp->drawmode; | 117 | return CURRENT_VP->drawmode; |
83 | } | 118 | } |
84 | 119 | ||
85 | int LCDFN(getwidth)(void) | 120 | int LCDFN(getwidth)(void) |
86 | { | 121 | { |
87 | return current_vp->width; | 122 | return CURRENT_VP->width; |
88 | } | 123 | } |
89 | 124 | ||
90 | int LCDFN(getheight)(void) | 125 | int LCDFN(getheight)(void) |
91 | { | 126 | { |
92 | return current_vp->height; | 127 | return CURRENT_VP->height; |
93 | } | 128 | } |
94 | 129 | ||
95 | void LCDFN(setfont)(int newfont) | 130 | void LCDFN(setfont)(int newfont) |
96 | { | 131 | { |
97 | current_vp->font = newfont; | 132 | CURRENT_VP->font = newfont; |
98 | } | 133 | } |
99 | 134 | ||
100 | int LCDFN(getfont)(void) | 135 | int LCDFN(getfont)(void) |
101 | { | 136 | { |
102 | return current_vp->font; | 137 | return CURRENT_VP->font; |
103 | } | 138 | } |
104 | 139 | ||
105 | int LCDFN(getstringsize)(const unsigned char *str, int *w, int *h) | 140 | int LCDFN(getstringsize)(const unsigned char *str, int *w, int *h) |
106 | { | 141 | { |
107 | return font_getstringsize(str, w, h, current_vp->font); | 142 | return font_getstringsize(str, w, h, CURRENT_VP->font); |
108 | } | 143 | } |
109 | 144 | ||
110 | /*** low-level drawing functions ***/ | 145 | /*** low-level drawing functions ***/ |
@@ -134,7 +169,7 @@ LCDFN(pixelfunc_type)* const LCDFN(pixelfuncs)[8] = { | |||
134 | flippixel, nopixel, setpixel, setpixel, | 169 | flippixel, nopixel, setpixel, setpixel, |
135 | nopixel, clearpixel, nopixel, clearpixel | 170 | nopixel, clearpixel, nopixel, clearpixel |
136 | }; | 171 | }; |
137 | 172 | ||
138 | static void ICODE_ATTR flipblock(FBFN(data) *address, unsigned mask, | 173 | static void ICODE_ATTR flipblock(FBFN(data) *address, unsigned mask, |
139 | unsigned bits) | 174 | unsigned bits) |
140 | { | 175 | { |
@@ -199,9 +234,9 @@ LCDFN(blockfunc_type)* const LCDFN(blockfuncs)[8] = { | |||
199 | /* Clear the whole display */ | 234 | /* Clear the whole display */ |
200 | void LCDFN(clear_display)(void) | 235 | void LCDFN(clear_display)(void) |
201 | { | 236 | { |
202 | unsigned bits = (current_vp->drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; | 237 | unsigned bits = (CURRENT_VP->drawmode & DRMODE_INVERSEVID) ? 0xFFu : 0; |
203 | 238 | ||
204 | memset(LCDFN(framebuffer), bits, FBSIZE); | 239 | memset(LCDFB(0, 0), bits, FBSIZE); |
205 | LCDFN(scroll_info).lines = 0; | 240 | LCDFN(scroll_info).lines = 0; |
206 | } | 241 | } |
207 | 242 | ||
@@ -210,37 +245,40 @@ void LCDFN(clear_viewport)(void) | |||
210 | { | 245 | { |
211 | int oldmode; | 246 | int oldmode; |
212 | 247 | ||
213 | if (current_vp == &default_vp) | 248 | if (CURRENT_VP == &default_vp && |
249 | default_vp.buffer == &LCDFN(framebuffer_default)) | ||
214 | { | 250 | { |
215 | LCDFN(clear_display)(); | 251 | LCDFN(clear_display)(); |
216 | } | 252 | } |
217 | else | 253 | else |
218 | { | 254 | { |
219 | oldmode = current_vp->drawmode; | 255 | oldmode = CURRENT_VP->drawmode; |
220 | 256 | ||
221 | /* Invert the INVERSEVID bit and set basic mode to SOLID */ | 257 | /* Invert the INVERSEVID bit and set basic mode to SOLID */ |
222 | current_vp->drawmode = (~current_vp->drawmode & DRMODE_INVERSEVID) | | 258 | CURRENT_VP->drawmode = (~CURRENT_VP->drawmode & DRMODE_INVERSEVID) | |
223 | DRMODE_SOLID; | 259 | DRMODE_SOLID; |
224 | 260 | ||
225 | LCDFN(fillrect)(0, 0, current_vp->width, current_vp->height); | 261 | LCDFN(fillrect)(0, 0, CURRENT_VP->width, CURRENT_VP->height); |
226 | 262 | ||
227 | current_vp->drawmode = oldmode; | 263 | CURRENT_VP->drawmode = oldmode; |
228 | 264 | ||
229 | LCDFN(scroll_stop_viewport)(current_vp); | 265 | LCDFN(scroll_stop_viewport)(CURRENT_VP); |
230 | } | 266 | } |
267 | |||
268 | CURRENT_VP->flags &= ~(VP_FLAG_VP_SET_CLEAN); | ||
231 | } | 269 | } |
232 | 270 | ||
233 | /* Set a single pixel */ | 271 | /* Set a single pixel */ |
234 | void LCDFN(drawpixel)(int x, int y) | 272 | void LCDFN(drawpixel)(int x, int y) |
235 | { | 273 | { |
236 | if ( ((unsigned)x < (unsigned)current_vp->width) | 274 | if ( ((unsigned)x < (unsigned)CURRENT_VP->width) |
237 | && ((unsigned)y < (unsigned)current_vp->height) | 275 | && ((unsigned)y < (unsigned)CURRENT_VP->height) |
238 | #if defined(HAVE_VIEWPORT_CLIP) | 276 | #if defined(HAVE_VIEWPORT_CLIP) |
239 | && ((unsigned)x < (unsigned)LCDM(WIDTH)) | 277 | && ((unsigned)x < (unsigned)LCDM(WIDTH)) |
240 | && ((unsigned)y < (unsigned)LCDM(HEIGHT)) | 278 | && ((unsigned)y < (unsigned)LCDM(HEIGHT)) |
241 | #endif | 279 | #endif |
242 | ) | 280 | ) |
243 | LCDFN(pixelfuncs)[current_vp->drawmode](current_vp->x + x, current_vp->y + y); | 281 | LCDFN(pixelfuncs)[CURRENT_VP->drawmode](CURRENT_VP->x + x, CURRENT_VP->y + y); |
244 | } | 282 | } |
245 | 283 | ||
246 | /* Draw a line */ | 284 | /* Draw a line */ |
@@ -252,7 +290,7 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
252 | int d, dinc1, dinc2; | 290 | int d, dinc1, dinc2; |
253 | int x, xinc1, xinc2; | 291 | int x, xinc1, xinc2; |
254 | int y, yinc1, yinc2; | 292 | int y, yinc1, yinc2; |
255 | LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[current_vp->drawmode]; | 293 | LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode]; |
256 | 294 | ||
257 | deltax = abs(x2 - x1); | 295 | deltax = abs(x2 - x1); |
258 | if (deltax == 0) | 296 | if (deltax == 0) |
@@ -308,14 +346,14 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
308 | 346 | ||
309 | for (i = 0; i < numpixels; i++) | 347 | for (i = 0; i < numpixels; i++) |
310 | { | 348 | { |
311 | if ( ((unsigned)x < (unsigned)current_vp->width) | 349 | if ( ((unsigned)x < (unsigned)CURRENT_VP->width) |
312 | && ((unsigned)y < (unsigned)current_vp->height) | 350 | && ((unsigned)y < (unsigned)CURRENT_VP->height) |
313 | #if defined(HAVE_VIEWPORT_CLIP) | 351 | #if defined(HAVE_VIEWPORT_CLIP) |
314 | && ((unsigned)x < (unsigned)LCDM(WIDTH)) | 352 | && ((unsigned)x < (unsigned)LCDM(WIDTH)) |
315 | && ((unsigned)y < (unsigned)LCDM(HEIGHT)) | 353 | && ((unsigned)y < (unsigned)LCDM(HEIGHT)) |
316 | #endif | 354 | #endif |
317 | ) | 355 | ) |
318 | pfunc(current_vp->x + x, current_vp->y + y); | 356 | pfunc(CURRENT_VP->x + x, CURRENT_VP->y + y); |
319 | 357 | ||
320 | if (d < 0) | 358 | if (d < 0) |
321 | { | 359 | { |
@@ -350,19 +388,19 @@ void LCDFN(hline)(int x1, int x2, int y) | |||
350 | 388 | ||
351 | /******************** In viewport clipping **********************/ | 389 | /******************** In viewport clipping **********************/ |
352 | /* nothing to draw? */ | 390 | /* nothing to draw? */ |
353 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) | 391 | if (((unsigned)y >= (unsigned)CURRENT_VP->height) || (x1 >= CURRENT_VP->width) |
354 | || (x2 < 0)) | 392 | || (x2 < 0)) |
355 | return; | 393 | return; |
356 | 394 | ||
357 | if (x1 < 0) | 395 | if (x1 < 0) |
358 | x1 = 0; | 396 | x1 = 0; |
359 | if (x2 >= current_vp->width) | 397 | if (x2 >= CURRENT_VP->width) |
360 | x2 = current_vp->width-1; | 398 | x2 = CURRENT_VP->width-1; |
361 | 399 | ||
362 | /* adjust to viewport */ | 400 | /* adjust to viewport */ |
363 | x1 += current_vp->x; | 401 | x1 += CURRENT_VP->x; |
364 | x2 += current_vp->x; | 402 | x2 += CURRENT_VP->x; |
365 | y += current_vp->y; | 403 | y += CURRENT_VP->y; |
366 | 404 | ||
367 | #if defined(HAVE_VIEWPORT_CLIP) | 405 | #if defined(HAVE_VIEWPORT_CLIP) |
368 | /********************* Viewport on screen clipping ********************/ | 406 | /********************* Viewport on screen clipping ********************/ |
@@ -380,7 +418,7 @@ void LCDFN(hline)(int x1, int x2, int y) | |||
380 | 418 | ||
381 | width = x2 - x1 + 1; | 419 | width = x2 - x1 + 1; |
382 | 420 | ||
383 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; | 421 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; |
384 | dst = LCDFB(x1,y>>3); | 422 | dst = LCDFB(x1,y>>3); |
385 | mask = BIT_N(y & 7); | 423 | mask = BIT_N(y & 7); |
386 | 424 | ||
@@ -395,6 +433,7 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
395 | { | 433 | { |
396 | int ny; | 434 | int ny; |
397 | FBFN(data) *dst; | 435 | FBFN(data) *dst; |
436 | int stride_dst; | ||
398 | unsigned mask, mask_bottom; | 437 | unsigned mask, mask_bottom; |
399 | LCDFN(blockfunc_type) *bfunc; | 438 | LCDFN(blockfunc_type) *bfunc; |
400 | 439 | ||
@@ -408,19 +447,19 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
408 | 447 | ||
409 | /******************** In viewport clipping **********************/ | 448 | /******************** In viewport clipping **********************/ |
410 | /* nothing to draw? */ | 449 | /* nothing to draw? */ |
411 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) | 450 | if (((unsigned)x >= (unsigned)CURRENT_VP->width) || (y1 >= CURRENT_VP->height) |
412 | || (y2 < 0)) | 451 | || (y2 < 0)) |
413 | return; | 452 | return; |
414 | 453 | ||
415 | if (y1 < 0) | 454 | if (y1 < 0) |
416 | y1 = 0; | 455 | y1 = 0; |
417 | if (y2 >= current_vp->height) | 456 | if (y2 >= CURRENT_VP->height) |
418 | y2 = current_vp->height-1; | 457 | y2 = CURRENT_VP->height-1; |
419 | 458 | ||
420 | /* adjust for viewport */ | 459 | /* adjust for viewport */ |
421 | y1 += current_vp->y; | 460 | y1 += CURRENT_VP->y; |
422 | y2 += current_vp->y; | 461 | y2 += CURRENT_VP->y; |
423 | x += current_vp->x; | 462 | x += CURRENT_VP->x; |
424 | 463 | ||
425 | #if defined(HAVE_VIEWPORT_CLIP) | 464 | #if defined(HAVE_VIEWPORT_CLIP) |
426 | /********************* Viewport on screen clipping ********************/ | 465 | /********************* Viewport on screen clipping ********************/ |
@@ -436,16 +475,17 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
436 | y2 = LCDM(HEIGHT)-1; | 475 | y2 = LCDM(HEIGHT)-1; |
437 | #endif | 476 | #endif |
438 | 477 | ||
439 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; | 478 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; |
440 | dst = LCDFB(x,y1>>3); | 479 | dst = LCDFB(x,y1>>3); |
441 | ny = y2 - (y1 & ~7); | 480 | ny = y2 - (y1 & ~7); |
442 | mask = 0xFFu << (y1 & 7); | 481 | mask = 0xFFu << (y1 & 7); |
443 | mask_bottom = 0xFFu >> (~ny & 7); | 482 | mask_bottom = 0xFFu >> (~ny & 7); |
483 | stride_dst = CURRENT_VP->buffer->stride; | ||
444 | 484 | ||
445 | for (; ny >= 8; ny -= 8) | 485 | for (; ny >= 8; ny -= 8) |
446 | { | 486 | { |
447 | bfunc(dst, mask, 0xFFu); | 487 | bfunc(dst, mask, 0xFFu); |
448 | dst += LCDM(WIDTH); | 488 | dst += stride_dst; |
449 | mask = 0xFFu; | 489 | mask = 0xFFu; |
450 | } | 490 | } |
451 | mask &= mask_bottom; | 491 | mask &= mask_bottom; |
@@ -472,6 +512,7 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
472 | { | 512 | { |
473 | int ny; | 513 | int ny; |
474 | FBFN(data) *dst, *dst_end; | 514 | FBFN(data) *dst, *dst_end; |
515 | int stride_dst; | ||
475 | unsigned mask, mask_bottom; | 516 | unsigned mask, mask_bottom; |
476 | unsigned bits = 0; | 517 | unsigned bits = 0; |
477 | LCDFN(blockfunc_type) *bfunc; | 518 | LCDFN(blockfunc_type) *bfunc; |
@@ -479,8 +520,8 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
479 | 520 | ||
480 | /******************** In viewport clipping **********************/ | 521 | /******************** In viewport clipping **********************/ |
481 | /* nothing to draw? */ | 522 | /* nothing to draw? */ |
482 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) | 523 | if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) |
483 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 524 | || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0)) |
484 | return; | 525 | return; |
485 | 526 | ||
486 | if (x < 0) | 527 | if (x < 0) |
@@ -493,14 +534,14 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
493 | height += y; | 534 | height += y; |
494 | y = 0; | 535 | y = 0; |
495 | } | 536 | } |
496 | if (x + width > current_vp->width) | 537 | if (x + width > CURRENT_VP->width) |
497 | width = current_vp->width - x; | 538 | width = CURRENT_VP->width - x; |
498 | if (y + height > current_vp->height) | 539 | if (y + height > CURRENT_VP->height) |
499 | height = current_vp->height - y; | 540 | height = CURRENT_VP->height - y; |
500 | 541 | ||
501 | /* adjust for viewport */ | 542 | /* adjust for viewport */ |
502 | x += current_vp->x; | 543 | x += CURRENT_VP->x; |
503 | y += current_vp->y; | 544 | y += CURRENT_VP->y; |
504 | 545 | ||
505 | #if defined(HAVE_VIEWPORT_CLIP) | 546 | #if defined(HAVE_VIEWPORT_CLIP) |
506 | /********************* Viewport on screen clipping ********************/ | 547 | /********************* Viewport on screen clipping ********************/ |
@@ -526,26 +567,27 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
526 | height = LCDM(HEIGHT) - y; | 567 | height = LCDM(HEIGHT) - y; |
527 | #endif | 568 | #endif |
528 | 569 | ||
529 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 570 | if (CURRENT_VP->drawmode & DRMODE_INVERSEVID) |
530 | { | 571 | { |
531 | if (current_vp->drawmode & DRMODE_BG) | 572 | if (CURRENT_VP->drawmode & DRMODE_BG) |
532 | { | 573 | { |
533 | fillopt = true; | 574 | fillopt = true; |
534 | } | 575 | } |
535 | } | 576 | } |
536 | else | 577 | else |
537 | { | 578 | { |
538 | if (current_vp->drawmode & DRMODE_FG) | 579 | if (CURRENT_VP->drawmode & DRMODE_FG) |
539 | { | 580 | { |
540 | fillopt = true; | 581 | fillopt = true; |
541 | bits = 0xFFu; | 582 | bits = 0xFFu; |
542 | } | 583 | } |
543 | } | 584 | } |
544 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; | 585 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; |
545 | dst = LCDFB(x,y>>3); | 586 | dst = LCDFB(x,y>>3); |
546 | ny = height - 1 + (y & 7); | 587 | ny = height - 1 + (y & 7); |
547 | mask = 0xFFu << (y & 7); | 588 | mask = 0xFFu << (y & 7); |
548 | mask_bottom = 0xFFu >> (~ny & 7); | 589 | mask_bottom = 0xFFu >> (~ny & 7); |
590 | stride_dst = CURRENT_VP->buffer->stride; | ||
549 | 591 | ||
550 | for (; ny >= 8; ny -= 8) | 592 | for (; ny >= 8; ny -= 8) |
551 | { | 593 | { |
@@ -561,7 +603,7 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
561 | while (dst_row < dst_end); | 603 | while (dst_row < dst_end); |
562 | } | 604 | } |
563 | 605 | ||
564 | dst += LCDM(WIDTH); | 606 | dst += stride_dst; |
565 | mask = 0xFFu; | 607 | mask = 0xFFu; |
566 | } | 608 | } |
567 | mask &= mask_bottom; | 609 | mask &= mask_bottom; |
@@ -595,13 +637,14 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x, | |||
595 | { | 637 | { |
596 | int shift, ny; | 638 | int shift, ny; |
597 | FBFN(data) *dst, *dst_end; | 639 | FBFN(data) *dst, *dst_end; |
640 | int stride_dst; | ||
598 | unsigned mask, mask_bottom; | 641 | unsigned mask, mask_bottom; |
599 | LCDFN(blockfunc_type) *bfunc; | 642 | LCDFN(blockfunc_type) *bfunc; |
600 | 643 | ||
601 | /******************** Image in viewport clipping **********************/ | 644 | /******************** Image in viewport clipping **********************/ |
602 | /* nothing to draw? */ | 645 | /* nothing to draw? */ |
603 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) | 646 | if ((width <= 0) || (height <= 0) || (x >= CURRENT_VP->width) |
604 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 647 | || (y >= CURRENT_VP->height) || (x + width <= 0) || (y + height <= 0)) |
605 | return; | 648 | return; |
606 | 649 | ||
607 | /* clip image in viewport */ | 650 | /* clip image in viewport */ |
@@ -617,14 +660,14 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x, | |||
617 | src_y -= y; | 660 | src_y -= y; |
618 | y = 0; | 661 | y = 0; |
619 | } | 662 | } |
620 | if (x + width > current_vp->width) | 663 | if (x + width > CURRENT_VP->width) |
621 | width = current_vp->width - x; | 664 | width = CURRENT_VP->width - x; |
622 | if (y + height > current_vp->height) | 665 | if (y + height > CURRENT_VP->height) |
623 | height = current_vp->height - y; | 666 | height = CURRENT_VP->height - y; |
624 | 667 | ||
625 | /* adjust for viewport */ | 668 | /* adjust for viewport */ |
626 | x += current_vp->x; | 669 | x += CURRENT_VP->x; |
627 | y += current_vp->y; | 670 | y += CURRENT_VP->y; |
628 | 671 | ||
629 | #if defined(HAVE_VIEWPORT_CLIP) | 672 | #if defined(HAVE_VIEWPORT_CLIP) |
630 | /********************* Viewport on screen clipping ********************/ | 673 | /********************* Viewport on screen clipping ********************/ |
@@ -656,16 +699,17 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x, | |||
656 | src_y &= 7; | 699 | src_y &= 7; |
657 | y -= src_y; | 700 | y -= src_y; |
658 | dst = LCDFB(x,y>>3); | 701 | dst = LCDFB(x,y>>3); |
702 | stride_dst = CURRENT_VP->buffer->stride; | ||
659 | shift = y & 7; | 703 | shift = y & 7; |
660 | ny = height - 1 + shift + src_y; | 704 | ny = height - 1 + shift + src_y; |
661 | 705 | ||
662 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; | 706 | bfunc = LCDFN(blockfuncs)[CURRENT_VP->drawmode]; |
663 | mask = 0xFFu << (shift + src_y); | 707 | mask = 0xFFu << (shift + src_y); |
664 | mask_bottom = 0xFFu >> (~ny & 7); | 708 | mask_bottom = 0xFFu >> (~ny & 7); |
665 | 709 | ||
666 | if (shift == 0) | 710 | if (shift == 0) |
667 | { | 711 | { |
668 | bool copyopt = (current_vp->drawmode == DRMODE_SOLID); | 712 | bool copyopt = (CURRENT_VP->drawmode == DRMODE_SOLID); |
669 | 713 | ||
670 | for (; ny >= 8; ny -= 8) | 714 | for (; ny >= 8; ny -= 8) |
671 | { | 715 | { |
@@ -683,7 +727,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x, | |||
683 | } | 727 | } |
684 | 728 | ||
685 | src += stride; | 729 | src += stride; |
686 | dst += LCDM(WIDTH); | 730 | dst += stride_dst; |
687 | mask = 0xFFu; | 731 | mask = 0xFFu; |
688 | } | 732 | } |
689 | mask &= mask_bottom; | 733 | mask &= mask_bottom; |
@@ -721,7 +765,7 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x, | |||
721 | mask_col >>= 8; | 765 | mask_col >>= 8; |
722 | 766 | ||
723 | src_col += stride; | 767 | src_col += stride; |
724 | dst_col += LCDM(WIDTH); | 768 | dst_col += stride_dst; |
725 | data >>= 8; | 769 | data >>= 8; |
726 | } | 770 | } |
727 | data |= *src_col << shift; | 771 | data |= *src_col << shift; |
diff --git a/firmware/drivers/lcd-24bit.c b/firmware/drivers/lcd-24bit.c index 8820e632d4..65fa01f37f 100644 --- a/firmware/drivers/lcd-24bit.c +++ b/firmware/drivers/lcd-24bit.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include "bidi.h" | 39 | #include "bidi.h" |
40 | #include "scroll_engine.h" | 40 | #include "scroll_engine.h" |
41 | 41 | ||
42 | #define ROW_INC LCD_WIDTH | 42 | #define ROW_INC lcd_current_viewport->buffer->stride |
43 | #define COL_INC 1 | 43 | #define COL_INC 1 |
44 | 44 | ||
45 | extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[]; | 45 | extern lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[]; |
@@ -62,10 +62,10 @@ void lcd_clear_viewport(void) | |||
62 | int x, y, width, height; | 62 | int x, y, width, height; |
63 | int len, step; | 63 | int len, step; |
64 | 64 | ||
65 | x = current_vp->x; | 65 | x = lcd_current_viewport->x; |
66 | y = current_vp->y; | 66 | y = lcd_current_viewport->y; |
67 | width = current_vp->width; | 67 | width = lcd_current_viewport->width; |
68 | height = current_vp->height; | 68 | height = lcd_current_viewport->height; |
69 | 69 | ||
70 | #if defined(HAVE_VIEWPORT_CLIP) | 70 | #if defined(HAVE_VIEWPORT_CLIP) |
71 | /********************* Viewport on screen clipping ********************/ | 71 | /********************* Viewport on screen clipping ********************/ |
@@ -97,9 +97,9 @@ void lcd_clear_viewport(void) | |||
97 | dst = FBADDR(x, y); | 97 | dst = FBADDR(x, y); |
98 | dst_end = FBADDR(x + width - 1 , y + height - 1); | 98 | dst_end = FBADDR(x + width - 1 , y + height - 1); |
99 | 99 | ||
100 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 100 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
101 | { | 101 | { |
102 | fb_data px = FB_SCALARPACK(current_vp->fg_pattern); | 102 | fb_data px = FB_SCALARPACK(lcd_current_viewport->fg_pattern); |
103 | do | 103 | do |
104 | { | 104 | { |
105 | fb_data *end = dst + len; | 105 | fb_data *end = dst + len; |
@@ -114,7 +114,7 @@ void lcd_clear_viewport(void) | |||
114 | { | 114 | { |
115 | if (!lcd_backdrop) | 115 | if (!lcd_backdrop) |
116 | { | 116 | { |
117 | fb_data px = FB_SCALARPACK(current_vp->bg_pattern); | 117 | fb_data px = FB_SCALARPACK(lcd_current_viewport->bg_pattern); |
118 | do | 118 | do |
119 | { | 119 | { |
120 | fb_data *end = dst + len; | 120 | fb_data *end = dst + len; |
@@ -137,22 +137,24 @@ void lcd_clear_viewport(void) | |||
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | if (current_vp == &default_vp) | 140 | if (lcd_current_viewport == &default_vp) |
141 | lcd_scroll_stop(); | 141 | lcd_scroll_stop(); |
142 | else | 142 | else |
143 | lcd_scroll_stop_viewport(current_vp); | 143 | lcd_scroll_stop_viewport(lcd_current_viewport); |
144 | |||
145 | lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN); | ||
144 | } | 146 | } |
145 | 147 | ||
146 | /*** low-level drawing functions ***/ | 148 | /*** low-level drawing functions ***/ |
147 | 149 | ||
148 | static void ICODE_ATTR setpixel(fb_data *address) | 150 | static void ICODE_ATTR setpixel(fb_data *address) |
149 | { | 151 | { |
150 | *address = FB_SCALARPACK(current_vp->fg_pattern); | 152 | *address = FB_SCALARPACK(lcd_current_viewport->fg_pattern); |
151 | } | 153 | } |
152 | 154 | ||
153 | static void ICODE_ATTR clearpixel(fb_data *address) | 155 | static void ICODE_ATTR clearpixel(fb_data *address) |
154 | { | 156 | { |
155 | *address = FB_SCALARPACK(current_vp->bg_pattern); | 157 | *address = FB_SCALARPACK(lcd_current_viewport->bg_pattern); |
156 | } | 158 | } |
157 | 159 | ||
158 | static void ICODE_ATTR clearimgpixel(fb_data *address) | 160 | static void ICODE_ATTR clearimgpixel(fb_data *address) |
@@ -194,8 +196,8 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
194 | 196 | ||
195 | /******************** In viewport clipping **********************/ | 197 | /******************** In viewport clipping **********************/ |
196 | /* nothing to draw? */ | 198 | /* nothing to draw? */ |
197 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 199 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
198 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 200 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
199 | return; | 201 | return; |
200 | 202 | ||
201 | if (x < 0) | 203 | if (x < 0) |
@@ -208,14 +210,14 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
208 | height += y; | 210 | height += y; |
209 | y = 0; | 211 | y = 0; |
210 | } | 212 | } |
211 | if (x + width > current_vp->width) | 213 | if (x + width > lcd_current_viewport->width) |
212 | width = current_vp->width - x; | 214 | width = lcd_current_viewport->width - x; |
213 | if (y + height > current_vp->height) | 215 | if (y + height > lcd_current_viewport->height) |
214 | height = current_vp->height - y; | 216 | height = lcd_current_viewport->height - y; |
215 | 217 | ||
216 | /* adjust for viewport */ | 218 | /* adjust for viewport */ |
217 | x += current_vp->x; | 219 | x += lcd_current_viewport->x; |
218 | y += current_vp->y; | 220 | y += lcd_current_viewport->y; |
219 | 221 | ||
220 | #if defined(HAVE_VIEWPORT_CLIP) | 222 | #if defined(HAVE_VIEWPORT_CLIP) |
221 | /********************* Viewport on screen clipping ********************/ | 223 | /********************* Viewport on screen clipping ********************/ |
@@ -242,14 +244,14 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
242 | #endif | 244 | #endif |
243 | 245 | ||
244 | /* drawmode and optimisation */ | 246 | /* drawmode and optimisation */ |
245 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 247 | if (lcd_current_viewport->drawmode & DRMODE_INVERSEVID) |
246 | { | 248 | { |
247 | if (current_vp->drawmode & DRMODE_BG) | 249 | if (lcd_current_viewport->drawmode & DRMODE_BG) |
248 | { | 250 | { |
249 | if (!lcd_backdrop) | 251 | if (!lcd_backdrop) |
250 | { | 252 | { |
251 | fillopt = OPT_SET; | 253 | fillopt = OPT_SET; |
252 | bits = FB_SCALARPACK(current_vp->bg_pattern); | 254 | bits = FB_SCALARPACK(lcd_current_viewport->bg_pattern); |
253 | } | 255 | } |
254 | else | 256 | else |
255 | fillopt = OPT_COPY; | 257 | fillopt = OPT_COPY; |
@@ -257,13 +259,13 @@ void lcd_fillrect(int x, int y, int width, int height) | |||
257 | } | 259 | } |
258 | else | 260 | else |
259 | { | 261 | { |
260 | if (current_vp->drawmode & DRMODE_FG) | 262 | if (lcd_current_viewport->drawmode & DRMODE_FG) |
261 | { | 263 | { |
262 | fillopt = OPT_SET; | 264 | fillopt = OPT_SET; |
263 | bits = FB_SCALARPACK(current_vp->fg_pattern); | 265 | bits = FB_SCALARPACK(lcd_current_viewport->fg_pattern); |
264 | } | 266 | } |
265 | } | 267 | } |
266 | if (fillopt == OPT_NONE && current_vp->drawmode != DRMODE_COMPLEMENT) | 268 | if (fillopt == OPT_NONE && lcd_current_viewport->drawmode != DRMODE_COMPLEMENT) |
267 | return; | 269 | return; |
268 | 270 | ||
269 | dst = FBADDR(x, y); | 271 | dst = FBADDR(x, y); |
@@ -327,13 +329,13 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
327 | const unsigned char *src_end; | 329 | const unsigned char *src_end; |
328 | fb_data *dst, *dst_col; | 330 | fb_data *dst, *dst_col; |
329 | unsigned dmask = 0x100; /* bit 8 == sentinel */ | 331 | unsigned dmask = 0x100; /* bit 8 == sentinel */ |
330 | int drmode = current_vp->drawmode; | 332 | int drmode = lcd_current_viewport->drawmode; |
331 | int row; | 333 | int row; |
332 | 334 | ||
333 | /******************** Image in viewport clipping **********************/ | 335 | /******************** Image in viewport clipping **********************/ |
334 | /* nothing to draw? */ | 336 | /* nothing to draw? */ |
335 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 337 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
336 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 338 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
337 | return; | 339 | return; |
338 | 340 | ||
339 | if (x < 0) | 341 | if (x < 0) |
@@ -348,14 +350,14 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
348 | src_y -= y; | 350 | src_y -= y; |
349 | y = 0; | 351 | y = 0; |
350 | } | 352 | } |
351 | if (x + width > current_vp->width) | 353 | if (x + width > lcd_current_viewport->width) |
352 | width = current_vp->width - x; | 354 | width = lcd_current_viewport->width - x; |
353 | if (y + height > current_vp->height) | 355 | if (y + height > lcd_current_viewport->height) |
354 | height = current_vp->height - y; | 356 | height = lcd_current_viewport->height - y; |
355 | 357 | ||
356 | /* adjust for viewport */ | 358 | /* adjust for viewport */ |
357 | x += current_vp->x; | 359 | x += lcd_current_viewport->x; |
358 | y += current_vp->y; | 360 | y += lcd_current_viewport->y; |
359 | 361 | ||
360 | #if defined(HAVE_VIEWPORT_CLIP) | 362 | #if defined(HAVE_VIEWPORT_CLIP) |
361 | /********************* Viewport on screen clipping ********************/ | 363 | /********************* Viewport on screen clipping ********************/ |
@@ -447,7 +449,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
447 | break; | 449 | break; |
448 | 450 | ||
449 | case DRMODE_BG: | 451 | case DRMODE_BG: |
450 | bg = FB_SCALARPACK(current_vp->bg_pattern); | 452 | bg = FB_SCALARPACK(lcd_current_viewport->bg_pattern); |
451 | do | 453 | do |
452 | { | 454 | { |
453 | if (!(data & 0x01)) | 455 | if (!(data & 0x01)) |
@@ -460,7 +462,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
460 | break; | 462 | break; |
461 | 463 | ||
462 | case DRMODE_FG: | 464 | case DRMODE_FG: |
463 | fg = FB_SCALARPACK(current_vp->fg_pattern); | 465 | fg = FB_SCALARPACK(lcd_current_viewport->fg_pattern); |
464 | do | 466 | do |
465 | { | 467 | { |
466 | if (data & 0x01) | 468 | if (data & 0x01) |
@@ -473,7 +475,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
473 | break; | 475 | break; |
474 | 476 | ||
475 | case DRMODE_SOLID|DRMODE_INT_BD: | 477 | case DRMODE_SOLID|DRMODE_INT_BD: |
476 | fg = FB_SCALARPACK(current_vp->fg_pattern); | 478 | fg = FB_SCALARPACK(lcd_current_viewport->fg_pattern); |
477 | bo = lcd_backdrop_offset; | 479 | bo = lcd_backdrop_offset; |
478 | do | 480 | do |
479 | { | 481 | { |
@@ -486,8 +488,8 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, | |||
486 | break; | 488 | break; |
487 | 489 | ||
488 | case DRMODE_SOLID: | 490 | case DRMODE_SOLID: |
489 | fg = FB_SCALARPACK(current_vp->fg_pattern); | 491 | fg = FB_SCALARPACK(lcd_current_viewport->fg_pattern); |
490 | bg = FB_SCALARPACK(current_vp->bg_pattern); | 492 | bg = FB_SCALARPACK(lcd_current_viewport->bg_pattern); |
491 | do | 493 | do |
492 | { | 494 | { |
493 | *dst = (data & 0x01) ? fg : bg; | 495 | *dst = (data & 0x01) ? fg : bg; |
@@ -559,10 +561,10 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
559 | { | 561 | { |
560 | fb_data *dst, *dst_row; | 562 | fb_data *dst, *dst_row; |
561 | unsigned dmask = 0x00000000; | 563 | unsigned dmask = 0x00000000; |
562 | int drmode = current_vp->drawmode; | 564 | int drmode = lcd_current_viewport->drawmode; |
563 | /* nothing to draw? */ | 565 | /* nothing to draw? */ |
564 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 566 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
565 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 567 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
566 | return; | 568 | return; |
567 | 569 | ||
568 | /* clipping */ | 570 | /* clipping */ |
@@ -578,14 +580,14 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
578 | src_y -= y; | 580 | src_y -= y; |
579 | y = 0; | 581 | y = 0; |
580 | } | 582 | } |
581 | if (x + width > current_vp->width) | 583 | if (x + width > lcd_current_viewport->width) |
582 | width = current_vp->width - x; | 584 | width = lcd_current_viewport->width - x; |
583 | if (y + height > current_vp->height) | 585 | if (y + height > lcd_current_viewport->height) |
584 | height = current_vp->height - y; | 586 | height = lcd_current_viewport->height - y; |
585 | 587 | ||
586 | /* adjust for viewport */ | 588 | /* adjust for viewport */ |
587 | x += current_vp->x; | 589 | x += lcd_current_viewport->x; |
588 | y += current_vp->y; | 590 | y += lcd_current_viewport->y; |
589 | 591 | ||
590 | #if defined(HAVE_VIEWPORT_CLIP) | 592 | #if defined(HAVE_VIEWPORT_CLIP) |
591 | /********************* Viewport on screen clipping ********************/ | 593 | /********************* Viewport on screen clipping ********************/ |
@@ -673,7 +675,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
673 | /* go through the rows and update each pixel */ | 675 | /* go through the rows and update each pixel */ |
674 | do | 676 | do |
675 | { | 677 | { |
676 | /* saving current_vp->fg/bg_pattern and lcd_backdrop_offset into these | 678 | /* saving lcd_current_viewport->fg/bg_pattern and lcd_backdrop_offset into these |
677 | * temp vars just before the loop helps gcc to opimize the loop better | 679 | * temp vars just before the loop helps gcc to opimize the loop better |
678 | * (testing showed ~15% speedup) */ | 680 | * (testing showed ~15% speedup) */ |
679 | unsigned fg, bg; | 681 | unsigned fg, bg; |
@@ -734,7 +736,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
734 | while (--col); | 736 | while (--col); |
735 | break; | 737 | break; |
736 | case DRMODE_BG: | 738 | case DRMODE_BG: |
737 | bg = current_vp->bg_pattern; | 739 | bg = lcd_current_viewport->bg_pattern; |
738 | do | 740 | do |
739 | { | 741 | { |
740 | unsigned px = FB_UNPACK_SCALAR_LCD(*dst); | 742 | unsigned px = FB_UNPACK_SCALAR_LCD(*dst); |
@@ -757,7 +759,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
757 | while (--col); | 759 | while (--col); |
758 | break; | 760 | break; |
759 | case DRMODE_FG: | 761 | case DRMODE_FG: |
760 | fg = current_vp->fg_pattern; | 762 | fg = lcd_current_viewport->fg_pattern; |
761 | do | 763 | do |
762 | { | 764 | { |
763 | unsigned px = FB_UNPACK_SCALAR_LCD(*dst); | 765 | unsigned px = FB_UNPACK_SCALAR_LCD(*dst); |
@@ -769,7 +771,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
769 | break; | 771 | break; |
770 | case DRMODE_SOLID|DRMODE_INT_BD: | 772 | case DRMODE_SOLID|DRMODE_INT_BD: |
771 | bo = lcd_backdrop_offset; | 773 | bo = lcd_backdrop_offset; |
772 | fg = current_vp->fg_pattern; | 774 | fg = lcd_current_viewport->fg_pattern; |
773 | do | 775 | do |
774 | { | 776 | { |
775 | unsigned c = FB_UNPACK_SCALAR_LCD(*(fb_data *)((uintptr_t)dst + bo)); | 777 | unsigned c = FB_UNPACK_SCALAR_LCD(*(fb_data *)((uintptr_t)dst + bo)); |
@@ -780,7 +782,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
780 | while (--col); | 782 | while (--col); |
781 | break; | 783 | break; |
782 | case DRMODE_SOLID|DRMODE_INT_IMG: | 784 | case DRMODE_SOLID|DRMODE_INT_IMG: |
783 | bg = current_vp->bg_pattern; | 785 | bg = lcd_current_viewport->bg_pattern; |
784 | img_offset = image - dst; | 786 | img_offset = image - dst; |
785 | do | 787 | do |
786 | { | 788 | { |
@@ -805,8 +807,8 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | |||
805 | while (--col); | 807 | while (--col); |
806 | break; | 808 | break; |
807 | case DRMODE_SOLID: | 809 | case DRMODE_SOLID: |
808 | bg = current_vp->bg_pattern; | 810 | bg = lcd_current_viewport->bg_pattern; |
809 | fg = current_vp->fg_pattern; | 811 | fg = lcd_current_viewport->fg_pattern; |
810 | do | 812 | do |
811 | { | 813 | { |
812 | *dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); | 814 | *dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); |
@@ -855,7 +857,7 @@ void lcd_hline(int x1, int x2, int y) | |||
855 | { | 857 | { |
856 | int x, width; | 858 | int x, width; |
857 | fb_data *dst, *dst_end; | 859 | fb_data *dst, *dst_end; |
858 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; | 860 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; |
859 | 861 | ||
860 | /* direction flip */ | 862 | /* direction flip */ |
861 | if (x2 < x1) | 863 | if (x2 < x1) |
@@ -867,20 +869,20 @@ void lcd_hline(int x1, int x2, int y) | |||
867 | 869 | ||
868 | /******************** In viewport clipping **********************/ | 870 | /******************** In viewport clipping **********************/ |
869 | /* nothing to draw? */ | 871 | /* nothing to draw? */ |
870 | if (((unsigned)y >= (unsigned)current_vp->height) || | 872 | if (((unsigned)y >= (unsigned)lcd_current_viewport->height) || |
871 | (x1 >= current_vp->width) || | 873 | (x1 >= lcd_current_viewport->width) || |
872 | (x2 < 0)) | 874 | (x2 < 0)) |
873 | return; | 875 | return; |
874 | 876 | ||
875 | if (x1 < 0) | 877 | if (x1 < 0) |
876 | x1 = 0; | 878 | x1 = 0; |
877 | if (x2 >= current_vp->width) | 879 | if (x2 >= lcd_current_viewport->width) |
878 | x2 = current_vp->width-1; | 880 | x2 = lcd_current_viewport->width-1; |
879 | 881 | ||
880 | /* Adjust x1 and y to viewport */ | 882 | /* Adjust x1 and y to viewport */ |
881 | x1 += current_vp->x; | 883 | x1 += lcd_current_viewport->x; |
882 | x2 += current_vp->x; | 884 | x2 += lcd_current_viewport->x; |
883 | y += current_vp->y; | 885 | y += lcd_current_viewport->y; |
884 | 886 | ||
885 | #if defined(HAVE_VIEWPORT_CLIP) | 887 | #if defined(HAVE_VIEWPORT_CLIP) |
886 | /********************* Viewport on screen clipping ********************/ | 888 | /********************* Viewport on screen clipping ********************/ |
@@ -912,7 +914,7 @@ void lcd_vline(int x, int y1, int y2) | |||
912 | { | 914 | { |
913 | int y; | 915 | int y; |
914 | fb_data *dst, *dst_end; | 916 | fb_data *dst, *dst_end; |
915 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; | 917 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; |
916 | 918 | ||
917 | /* direction flip */ | 919 | /* direction flip */ |
918 | if (y2 < y1) | 920 | if (y2 < y1) |
@@ -924,20 +926,20 @@ void lcd_vline(int x, int y1, int y2) | |||
924 | 926 | ||
925 | /******************** In viewport clipping **********************/ | 927 | /******************** In viewport clipping **********************/ |
926 | /* nothing to draw? */ | 928 | /* nothing to draw? */ |
927 | if (((unsigned)x >= (unsigned)current_vp->width) || | 929 | if (((unsigned)x >= (unsigned)lcd_current_viewport->width) || |
928 | (y1 >= current_vp->height) || | 930 | (y1 >= lcd_current_viewport->height) || |
929 | (y2 < 0)) | 931 | (y2 < 0)) |
930 | return; | 932 | return; |
931 | 933 | ||
932 | if (y1 < 0) | 934 | if (y1 < 0) |
933 | y1 = 0; | 935 | y1 = 0; |
934 | if (y2 >= current_vp->height) | 936 | if (y2 >= lcd_current_viewport->height) |
935 | y2 = current_vp->height-1; | 937 | y2 = lcd_current_viewport->height-1; |
936 | 938 | ||
937 | /* adjust for viewport */ | 939 | /* adjust for viewport */ |
938 | x += current_vp->x; | 940 | x += lcd_current_viewport->x; |
939 | y1 += current_vp->y; | 941 | y1 += lcd_current_viewport->y; |
940 | y2 += current_vp->y; | 942 | y2 += lcd_current_viewport->y; |
941 | 943 | ||
942 | #if defined(HAVE_VIEWPORT_CLIP) | 944 | #if defined(HAVE_VIEWPORT_CLIP) |
943 | /********************* Viewport on screen clipping ********************/ | 945 | /********************* Viewport on screen clipping ********************/ |
@@ -973,8 +975,8 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
973 | 975 | ||
974 | /******************** Image in viewport clipping **********************/ | 976 | /******************** Image in viewport clipping **********************/ |
975 | /* nothing to draw? */ | 977 | /* nothing to draw? */ |
976 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 978 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
977 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 979 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
978 | return; | 980 | return; |
979 | 981 | ||
980 | if (x < 0) | 982 | if (x < 0) |
@@ -990,14 +992,14 @@ void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, | |||
990 | y = 0; | 992 | y = 0; |
991 | } | 993 | } |
992 | 994 | ||
993 | if (x + width > current_vp->width) | 995 | if (x + width > lcd_current_viewport->width) |
994 | width = current_vp->width - x; | 996 | width = lcd_current_viewport->width - x; |
995 | if (y + height > current_vp->height) | 997 | if (y + height > lcd_current_viewport->height) |
996 | height = current_vp->height - y; | 998 | height = lcd_current_viewport->height - y; |
997 | 999 | ||
998 | /* adjust for viewport */ | 1000 | /* adjust for viewport */ |
999 | x += current_vp->x; | 1001 | x += lcd_current_viewport->x; |
1000 | y += current_vp->y; | 1002 | y += lcd_current_viewport->y; |
1001 | 1003 | ||
1002 | #if defined(HAVE_VIEWPORT_CLIP) | 1004 | #if defined(HAVE_VIEWPORT_CLIP) |
1003 | /********************* Viewport on screen clipping ********************/ | 1005 | /********************* Viewport on screen clipping ********************/ |
@@ -1047,8 +1049,8 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
1047 | 1049 | ||
1048 | /******************** Image in viewport clipping **********************/ | 1050 | /******************** Image in viewport clipping **********************/ |
1049 | /* nothing to draw? */ | 1051 | /* nothing to draw? */ |
1050 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || | 1052 | if ((width <= 0) || (height <= 0) || (x >= lcd_current_viewport->width) || |
1051 | (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 1053 | (y >= lcd_current_viewport->height) || (x + width <= 0) || (y + height <= 0)) |
1052 | return; | 1054 | return; |
1053 | 1055 | ||
1054 | if (x < 0) | 1056 | if (x < 0) |
@@ -1064,14 +1066,14 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
1064 | y = 0; | 1066 | y = 0; |
1065 | } | 1067 | } |
1066 | 1068 | ||
1067 | if (x + width > current_vp->width) | 1069 | if (x + width > lcd_current_viewport->width) |
1068 | width = current_vp->width - x; | 1070 | width = lcd_current_viewport->width - x; |
1069 | if (y + height > current_vp->height) | 1071 | if (y + height > lcd_current_viewport->height) |
1070 | height = current_vp->height - y; | 1072 | height = lcd_current_viewport->height - y; |
1071 | 1073 | ||
1072 | /* adjust for viewport */ | 1074 | /* adjust for viewport */ |
1073 | x += current_vp->x; | 1075 | x += lcd_current_viewport->x; |
1074 | y += current_vp->y; | 1076 | y += lcd_current_viewport->y; |
1075 | 1077 | ||
1076 | #if defined(HAVE_VIEWPORT_CLIP) | 1078 | #if defined(HAVE_VIEWPORT_CLIP) |
1077 | /********************* Viewport on screen clipping ********************/ | 1079 | /********************* Viewport on screen clipping ********************/ |
@@ -1104,7 +1106,7 @@ void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, | |||
1104 | 1106 | ||
1105 | transparent = FB_SCALARPACK(TRANSPARENT_COLOR); | 1107 | transparent = FB_SCALARPACK(TRANSPARENT_COLOR); |
1106 | replacewithfg = FB_SCALARPACK(REPLACEWITHFG_COLOR); | 1108 | replacewithfg = FB_SCALARPACK(REPLACEWITHFG_COLOR); |
1107 | fg = FB_SCALARPACK(current_vp->fg_pattern); | 1109 | fg = FB_SCALARPACK(lcd_current_viewport->fg_pattern); |
1108 | #define CMP(c1, c2) (c1.r == c2.r && c1.g == c2.g && c1.b == c2.b) | 1110 | #define CMP(c1, c2) (c1.r == c2.r && c1.g == c2.g && c1.b == c2.b) |
1109 | 1111 | ||
1110 | do | 1112 | do |
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 | ||
42 | unsigned char lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER; | 42 | static unsigned char lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER; |
43 | unsigned char *lcd_framebuffer = &lcd_static_framebuffer[0][0]; | 43 | static void *lcd_frameaddress_default(int x, int y); |
44 | 44 | ||
45 | static const unsigned char pixmask[4] ICONST_ATTR = { | 45 | static 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 = { | |||
49 | static fb_data* lcd_backdrop = NULL; | 49 | static fb_data* lcd_backdrop = NULL; |
50 | static long lcd_backdrop_offset IDATA_ATTR = 0; | 50 | static long lcd_backdrop_offset IDATA_ATTR = 0; |
51 | 51 | ||
52 | /* shouldn't be changed unless you want system-wide framebuffer changes! */ | ||
53 | struct 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 | |||
52 | static struct viewport default_vp = | 61 | static 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 | ||
64 | static struct viewport* current_vp IBSS_ATTR; | 74 | struct viewport* lcd_current_viewport IBSS_ATTR; |
65 | static unsigned fg_pattern IBSS_ATTR; | 75 | static unsigned fg_pattern IBSS_ATTR; |
66 | static unsigned bg_pattern IBSS_ATTR; | 76 | static unsigned bg_pattern IBSS_ATTR; |
67 | 77 | ||
78 | static 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 */ |
69 | void lcd_init(void) | 92 | void 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 | ||
82 | void lcd_set_drawmode(int mode) | 105 | void 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 | ||
87 | int lcd_get_drawmode(void) | 110 | int lcd_get_drawmode(void) |
88 | { | 111 | { |
89 | return current_vp->drawmode; | 112 | return lcd_current_viewport->drawmode; |
90 | } | 113 | } |
91 | 114 | ||
92 | void lcd_set_foreground(unsigned brightness) | 115 | void 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 | ||
98 | unsigned lcd_get_foreground(void) | 121 | unsigned lcd_get_foreground(void) |
99 | { | 122 | { |
100 | return current_vp->fg_pattern; | 123 | return lcd_current_viewport->fg_pattern; |
101 | } | 124 | } |
102 | 125 | ||
103 | void lcd_set_background(unsigned brightness) | 126 | void 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 | ||
109 | unsigned lcd_get_background(void) | 132 | unsigned lcd_get_background(void) |
110 | { | 133 | { |
111 | return current_vp->bg_pattern; | 134 | return lcd_current_viewport->bg_pattern; |
112 | } | 135 | } |
113 | 136 | ||
114 | void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness) | 137 | void 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 | ||
121 | int lcd_getwidth(void) | 144 | int lcd_getwidth(void) |
122 | { | 145 | { |
123 | return current_vp->width; | 146 | return lcd_current_viewport->width; |
124 | } | 147 | } |
125 | 148 | ||
126 | int lcd_getheight(void) | 149 | int lcd_getheight(void) |
127 | { | 150 | { |
128 | return current_vp->height; | 151 | return lcd_current_viewport->height; |
129 | } | 152 | } |
130 | 153 | ||
131 | void lcd_setfont(int newfont) | 154 | void lcd_setfont(int newfont) |
132 | { | 155 | { |
133 | current_vp->font = newfont; | 156 | lcd_current_viewport->font = newfont; |
134 | } | 157 | } |
135 | 158 | ||
136 | int lcd_getfont(void) | 159 | int lcd_getfont(void) |
137 | { | 160 | { |
138 | return current_vp->font; | 161 | return lcd_current_viewport->font; |
139 | } | 162 | } |
140 | 163 | ||
141 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 164 | int 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 */ |
350 | void lcd_clear_display(void) | 373 | void 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 */ |
393 | void lcd_drawpixel(int x, int y) | 418 | void 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 | } |
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 | ||
39 | fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER; | 39 | static fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] IRAM_LCDFRAMEBUFFER; |
40 | fb_data *lcd_framebuffer = &lcd_static_framebuffer[0][0]; | 40 | static void *lcd_frameaddress_default(int x, int y); |
41 | 41 | ||
42 | const unsigned char lcd_dibits[16] ICONST_ATTR = { | 42 | const 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 = { | |||
51 | static fb_data* lcd_backdrop = NULL; | 51 | static fb_data* lcd_backdrop = NULL; |
52 | static long lcd_backdrop_offset IDATA_ATTR = 0; | 52 | static long lcd_backdrop_offset IDATA_ATTR = 0; |
53 | 53 | ||
54 | /* shouldn't be changed unless you want system-wide framebuffer changes! */ | ||
55 | struct 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 | |||
54 | static struct viewport default_vp = | 63 | static 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 | ||
66 | static struct viewport* current_vp IBSS_ATTR; | 76 | struct viewport* lcd_current_viewport IBSS_ATTR; |
67 | static unsigned fg_pattern IBSS_ATTR; | 77 | static unsigned fg_pattern IBSS_ATTR; |
68 | static unsigned bg_pattern IBSS_ATTR; | 78 | static unsigned bg_pattern IBSS_ATTR; |
69 | 79 | ||
80 | static 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 */ |
71 | void lcd_init(void) | 94 | void 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 | ||
84 | void lcd_set_drawmode(int mode) | 107 | void 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 | ||
89 | int lcd_get_drawmode(void) | 112 | int lcd_get_drawmode(void) |
90 | { | 113 | { |
91 | return current_vp->drawmode; | 114 | return lcd_current_viewport->drawmode; |
92 | } | 115 | } |
93 | 116 | ||
94 | void lcd_set_foreground(unsigned brightness) | 117 | void 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 | ||
100 | unsigned lcd_get_foreground(void) | 123 | unsigned lcd_get_foreground(void) |
101 | { | 124 | { |
102 | return current_vp->fg_pattern; | 125 | return lcd_current_viewport->fg_pattern; |
103 | } | 126 | } |
104 | 127 | ||
105 | void lcd_set_background(unsigned brightness) | 128 | void 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 | ||
111 | unsigned lcd_get_background(void) | 134 | unsigned lcd_get_background(void) |
112 | { | 135 | { |
113 | return current_vp->bg_pattern; | 136 | return lcd_current_viewport->bg_pattern; |
114 | } | 137 | } |
115 | 138 | ||
116 | void lcd_set_drawinfo(int mode, unsigned fg_brightness, unsigned bg_brightness) | 139 | void 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 | ||
123 | int lcd_getwidth(void) | 146 | int lcd_getwidth(void) |
124 | { | 147 | { |
125 | return current_vp->width; | 148 | return lcd_current_viewport->width; |
126 | } | 149 | } |
127 | 150 | ||
128 | int lcd_getheight(void) | 151 | int lcd_getheight(void) |
129 | { | 152 | { |
130 | return current_vp->height; | 153 | return lcd_current_viewport->height; |
131 | } | 154 | } |
132 | 155 | ||
133 | void lcd_setfont(int newfont) | 156 | void lcd_setfont(int newfont) |
134 | { | 157 | { |
135 | current_vp->font = newfont; | 158 | lcd_current_viewport->font = newfont; |
136 | } | 159 | } |
137 | 160 | ||
138 | int lcd_getfont(void) | 161 | int lcd_getfont(void) |
139 | { | 162 | { |
140 | return current_vp->font; | 163 | return lcd_current_viewport->font; |
141 | } | 164 | } |
142 | 165 | ||
143 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 166 | int 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 */ |
352 | void lcd_clear_display(void) | 375 | void 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 */ |
395 | void lcd_drawpixel(int x, int y) | 420 | void 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; |
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 | ||
51 | FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER; | 55 | #define CURRENT_VP LCDFN(current_viewport) |
52 | FBFN(data) *LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0]; | 56 | /*** globals ***/ |
53 | 57 | ||
58 | static FBFN(data) LCDFN(static_framebuffer)[LCDM(FBHEIGHT)][LCDM(FBWIDTH)] IRAM_LCDFRAMEBUFFER; | ||
59 | static void *LCDFN(frameaddress_default)(int x, int y); | ||
54 | 60 | ||
55 | static const FBFN(data) patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000}; | 61 | static const FBFN(data) patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000}; |
56 | 62 | ||
57 | static FBFN(data) *backdrop = NULL; | 63 | static FBFN(data) *backdrop = NULL; |
58 | static long backdrop_offset IDATA_ATTR = 0; | 64 | static long backdrop_offset IDATA_ATTR = 0; |
59 | 65 | ||
66 | /* shouldn't be changed unless you want system-wide framebuffer changes! */ | ||
67 | struct 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 | |||
60 | static struct viewport default_vp = | 75 | static 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 | ||
72 | static struct viewport * current_vp IBSS_ATTR; | 88 | struct viewport * CURRENT_VP IBSS_ATTR; |
73 | 89 | ||
74 | static unsigned fg_pattern IBSS_ATTR; | 90 | static unsigned fg_pattern IBSS_ATTR; |
75 | static unsigned bg_pattern IBSS_ATTR; | 91 | static unsigned bg_pattern IBSS_ATTR; |
76 | 92 | ||
93 | static 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 */ |
78 | void LCDFN(init)(void) | 106 | void 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 | ||
106 | void LCDFN(set_drawmode)(int mode) | 136 | void 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 | ||
111 | int LCDFN(get_drawmode)(void) | 141 | int LCDFN(get_drawmode)(void) |
112 | { | 142 | { |
113 | return current_vp->drawmode; | 143 | return CURRENT_VP->drawmode; |
114 | } | 144 | } |
115 | 145 | ||
116 | void LCDFN(set_foreground)(unsigned brightness) | 146 | void 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 | ||
122 | unsigned LCDFN(get_foreground)(void) | 152 | unsigned LCDFN(get_foreground)(void) |
123 | { | 153 | { |
124 | return current_vp->fg_pattern; | 154 | return CURRENT_VP->fg_pattern; |
125 | } | 155 | } |
126 | 156 | ||
127 | void LCDFN(set_background)(unsigned brightness) | 157 | void 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 | ||
133 | unsigned LCDFN(get_background)(void) | 163 | unsigned LCDFN(get_background)(void) |
134 | { | 164 | { |
135 | return current_vp->bg_pattern; | 165 | return CURRENT_VP->bg_pattern; |
136 | } | 166 | } |
137 | 167 | ||
138 | void LCDFN(set_drawinfo)(int mode, unsigned fg_brightness, | 168 | void LCDFN(set_drawinfo)(int mode, unsigned fg_brightness, |
@@ -145,26 +175,26 @@ void LCDFN(set_drawinfo)(int mode, unsigned fg_brightness, | |||
145 | 175 | ||
146 | int LCDFN(getwidth)(void) | 176 | int LCDFN(getwidth)(void) |
147 | { | 177 | { |
148 | return current_vp->width; | 178 | return CURRENT_VP->width; |
149 | } | 179 | } |
150 | 180 | ||
151 | int LCDFN(getheight)(void) | 181 | int LCDFN(getheight)(void) |
152 | { | 182 | { |
153 | return current_vp->height; | 183 | return CURRENT_VP->height; |
154 | } | 184 | } |
155 | void LCDFN(setfont)(int newfont) | 185 | void LCDFN(setfont)(int newfont) |
156 | { | 186 | { |
157 | current_vp->font = newfont; | 187 | CURRENT_VP->font = newfont; |
158 | } | 188 | } |
159 | 189 | ||
160 | int LCDFN(getfont)(void) | 190 | int LCDFN(getfont)(void) |
161 | { | 191 | { |
162 | return current_vp->font; | 192 | return CURRENT_VP->font; |
163 | } | 193 | } |
164 | 194 | ||
165 | int LCDFN(getstringsize)(const unsigned char *str, int *w, int *h) | 195 | int 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 */ |
421 | void LCDFN(drawpixel)(int x, int y) | 453 | void 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; |
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 8c38e513c6..94829b5d0c 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c | |||
@@ -40,43 +40,70 @@ | |||
40 | #define MAIN_LCD | 40 | #define MAIN_LCD |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | void LCDFN(set_framebuffer)(FBFN(data) *fb) | 43 | #ifdef MAIN_LCD |
44 | { | 44 | #define THIS_STRIDE STRIDE_MAIN |
45 | if (fb) | 45 | #else |
46 | LCDFN(framebuffer) = fb; | 46 | #define THIS_STRIDE STRIDE_REMOTE |
47 | else | 47 | #endif |
48 | LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0]; | ||
49 | } | ||
50 | 48 | ||
49 | extern void viewport_set_buffer(struct viewport *vp, | ||
50 | struct frame_buffer_t *buffer, | ||
51 | const enum screen_type screen); /* viewport.c */ | ||
51 | /* | 52 | /* |
52 | * draws the borders of the current viewport | 53 | * draws the borders of the current viewport |
53 | **/ | 54 | **/ |
54 | void LCDFN(draw_border_viewport)(void) | 55 | void LCDFN(draw_border_viewport)(void) |
55 | { | 56 | { |
56 | LCDFN(drawrect)(0, 0, current_vp->width, current_vp->height); | 57 | LCDFN(drawrect)(0, 0, LCDFN(current_viewport)->width, LCDFN(current_viewport)->height); |
57 | } | 58 | } |
58 | 59 | ||
59 | /* | 60 | /* |
60 | * fills the rectangle formed by current_vp | 61 | * fills the rectangle formed by LCDFN(current_viewport) |
61 | **/ | 62 | **/ |
62 | void LCDFN(fill_viewport)(void) | 63 | void LCDFN(fill_viewport)(void) |
63 | { | 64 | { |
64 | LCDFN(fillrect)(0, 0, current_vp->width, current_vp->height); | 65 | LCDFN(fillrect)(0, 0, LCDFN(current_viewport)->width, LCDFN(current_viewport)->height); |
65 | } | 66 | } |
66 | 67 | ||
67 | 68 | ||
68 | /*** Viewports ***/ | 69 | /*** Viewports ***/ |
69 | 70 | /* init_viewport Notes: When a viewport is initialized | |
70 | void LCDFN(set_viewport)(struct viewport* vp) | 71 | * if vp->buffer is NULL the default frame_buffer is assigned |
72 | * likewise the actual buffer, stride, get_address_fn | ||
73 | * are all filled with values from the default buffer if they are not set | ||
74 | * RETURNS either the viewport you passed or the default viewport if vp == NULL | ||
75 | */ | ||
76 | struct viewport* LCDFN(init_viewport)(struct viewport* vp) | ||
71 | { | 77 | { |
72 | if (vp == NULL) | 78 | struct frame_buffer_t *fb_default = &LCDFN(framebuffer_default); |
73 | current_vp = &default_vp; | 79 | if (!vp) /* NULL vp grabs default viewport */ |
80 | vp = &default_vp; | ||
81 | |||
82 | /* use defaults if no buffer is provided */ | ||
83 | if (vp->buffer == NULL || vp->buffer->elems == 0) | ||
84 | vp->buffer = fb_default; | ||
74 | else | 85 | else |
75 | current_vp = vp; | 86 | { |
87 | if (vp->buffer->stride == 0) | ||
88 | vp->buffer->stride = fb_default->stride; | ||
89 | |||
90 | if (vp->buffer->data == NULL) | ||
91 | vp->buffer->data = fb_default->data; | ||
92 | |||
93 | if (vp->buffer->get_address_fn == NULL) | ||
94 | vp->buffer->get_address_fn = fb_default->get_address_fn; | ||
95 | } | ||
96 | return vp; | ||
97 | } | ||
98 | struct viewport* LCDFN(set_viewport_ex)(struct viewport* vp, int flags) | ||
99 | { | ||
100 | vp = LCDFN(init_viewport)(vp); | ||
101 | struct viewport* last_vp = LCDFN(current_viewport); | ||
102 | LCDFN(current_viewport) = vp; | ||
76 | 103 | ||
77 | #if LCDM(DEPTH) > 1 | 104 | #if LCDM(DEPTH) > 1 |
78 | LCDFN(set_foreground)(current_vp->fg_pattern); | 105 | LCDFN(set_foreground)(vp->fg_pattern); |
79 | LCDFN(set_background)(current_vp->bg_pattern); | 106 | LCDFN(set_background)(vp->bg_pattern); |
80 | #endif | 107 | #endif |
81 | 108 | ||
82 | #if defined(SIMULATOR) | 109 | #if defined(SIMULATOR) |
@@ -84,10 +111,11 @@ void LCDFN(set_viewport)(struct viewport* vp) | |||
84 | * be considered an error - the viewport will not draw as it might be | 111 | * be considered an error - the viewport will not draw as it might be |
85 | * expected. | 112 | * expected. |
86 | */ | 113 | */ |
87 | if((unsigned) current_vp->x > (unsigned) LCDM(WIDTH) | 114 | |
88 | || (unsigned) current_vp->y > (unsigned) LCDM(HEIGHT) | 115 | if((unsigned) vp->x > (unsigned) LCDM(WIDTH) |
89 | || current_vp->x + current_vp->width > LCDM(WIDTH) | 116 | || (unsigned) vp->y > (unsigned) LCDM(HEIGHT) |
90 | || current_vp->y + current_vp->height > LCDM(HEIGHT)) | 117 | || vp->x + vp->width > LCDM(WIDTH) |
118 | || vp->y + vp->height > LCDM(HEIGHT)) | ||
91 | { | 119 | { |
92 | #if !defined(HAVE_VIEWPORT_CLIP) | 120 | #if !defined(HAVE_VIEWPORT_CLIP) |
93 | DEBUGF("ERROR: " | 121 | DEBUGF("ERROR: " |
@@ -95,27 +123,68 @@ void LCDFN(set_viewport)(struct viewport* vp) | |||
95 | DEBUGF("NOTE: " | 123 | DEBUGF("NOTE: " |
96 | #endif | 124 | #endif |
97 | "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", | 125 | "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", |
98 | current_vp->x, current_vp->y, | 126 | vp->x, vp->y, vp->width, vp->height); |
99 | current_vp->width, current_vp->height); | ||
100 | } | 127 | } |
101 | #endif | 128 | #endif |
129 | if(last_vp) | ||
130 | { | ||
131 | if ((flags & VP_FLAG_CLEAR_FLAG) == VP_FLAG_CLEAR_FLAG) | ||
132 | last_vp->flags &= ~flags; | ||
133 | else | ||
134 | last_vp->flags |= flags; | ||
135 | } | ||
136 | |||
137 | return last_vp; | ||
138 | } | ||
139 | |||
140 | struct viewport* LCDFN(set_viewport)(struct viewport* vp) | ||
141 | { | ||
142 | return LCDFN(set_viewport_ex)(vp, VP_FLAG_VP_DIRTY); | ||
102 | } | 143 | } |
103 | 144 | ||
104 | struct viewport *LCDFN(get_viewport)(bool *is_default) | 145 | struct viewport *LCDFN(get_viewport)(bool *is_default) |
105 | { | 146 | { |
106 | *is_default = (current_vp == &default_vp); | 147 | #if 0 |
107 | return current_vp; | 148 | *is_default = memcmp(LCDFN(current_viewport), |
149 | &default_vp, sizeof(struct viewport)) == 0; | ||
150 | #else | ||
151 | *is_default = LCDFN(current_viewport) == &default_vp; | ||
152 | #endif | ||
153 | |||
154 | return LCDFN(current_viewport); | ||
108 | } | 155 | } |
109 | 156 | ||
110 | void LCDFN(update_viewport)(void) | 157 | void LCDFN(update_viewport)(void) |
111 | { | 158 | { |
112 | LCDFN(update_rect)(current_vp->x, current_vp->y, | 159 | struct viewport* vp = LCDFN(current_viewport); |
113 | current_vp->width, current_vp->height); | 160 | if (vp->buffer->stride != LCDFN(framebuffer_default.stride)) |
161 | { | ||
162 | LCDFN(update_viewport_rect)(0,0, vp->width, vp->height); | ||
163 | return; | ||
164 | } | ||
165 | LCDFN(update_rect)(vp->x, vp->y, vp->width, vp->height); | ||
114 | } | 166 | } |
115 | 167 | ||
116 | void LCDFN(update_viewport_rect)(int x, int y, int width, int height) | 168 | void LCDFN(update_viewport_rect)(int x, int y, int width, int height) |
117 | { | 169 | { |
118 | LCDFN(update_rect)(current_vp->x + x, current_vp->y + y, width, height); | 170 | struct viewport* vp = LCDFN(current_viewport); |
171 | |||
172 | /* handle the case of viewport with differing stride from main screen */ | ||
173 | if (vp->buffer->stride != LCDFN(framebuffer_default.stride)) | ||
174 | { | ||
175 | struct frame_buffer_t *fb = vp->buffer; | ||
176 | viewport_set_buffer(vp, NULL, 0); | ||
177 | |||
178 | LCDFN(bitmap_part) | ||
179 | (fb->FBFN(ptr), vp->x, vp->y, fb->stride, | ||
180 | vp->x + x, vp->y + y, width, height); | ||
181 | |||
182 | LCDFN(update_rect)(vp->x + x, vp->y + y, width, height); | ||
183 | viewport_set_buffer(vp, fb, 0); | ||
184 | return; | ||
185 | } | ||
186 | |||
187 | LCDFN(update_rect)(vp->x + x, vp->y + y, width, height); | ||
119 | } | 188 | } |
120 | 189 | ||
121 | #ifndef BOOTLOADER | 190 | #ifndef BOOTLOADER |
@@ -123,9 +192,9 @@ void LCDFN(update_viewport_rect)(int x, int y, int width, int height) | |||
123 | static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | 192 | static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) |
124 | { | 193 | { |
125 | unsigned short *ucs; | 194 | unsigned short *ucs; |
126 | font_lock(current_vp->font, true); | 195 | font_lock(LCDFN(current_viewport)->font, true); |
127 | struct font* pf = font_get(current_vp->font); | 196 | struct font* pf = font_get(LCDFN(current_viewport)->font); |
128 | int vp_flags = current_vp->flags; | 197 | int vp_flags = LCDFN(current_viewport)->flags; |
129 | int rtl_next_non_diac_width, last_non_diacritic_width; | 198 | int rtl_next_non_diac_width, last_non_diacritic_width; |
130 | 199 | ||
131 | if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0) | 200 | if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0) |
@@ -136,13 +205,13 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | |||
136 | /* center takes precedence */ | 205 | /* center takes precedence */ |
137 | if (vp_flags & VP_FLAG_ALIGN_CENTER) | 206 | if (vp_flags & VP_FLAG_ALIGN_CENTER) |
138 | { | 207 | { |
139 | x = ((current_vp->width - w)/ 2) + x; | 208 | x = ((LCDFN(current_viewport)->width - w)/ 2) + x; |
140 | if (x < 0) | 209 | if (x < 0) |
141 | x = 0; | 210 | x = 0; |
142 | } | 211 | } |
143 | else | 212 | else |
144 | { | 213 | { |
145 | x = current_vp->width - w - x; | 214 | x = LCDFN(current_viewport)->width - w - x; |
146 | x += ofs; | 215 | x += ofs; |
147 | ofs = 0; | 216 | ofs = 0; |
148 | } | 217 | } |
@@ -158,7 +227,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | |||
158 | int width, base_width, drawmode = 0, base_ofs = 0; | 227 | int width, base_width, drawmode = 0, base_ofs = 0; |
159 | const unsigned short next_ch = ucs[1]; | 228 | const unsigned short next_ch = ucs[1]; |
160 | 229 | ||
161 | if (x >= current_vp->width) | 230 | if (x >= LCDFN(current_viewport)->width) |
162 | break; | 231 | break; |
163 | 232 | ||
164 | is_diac = is_diacritic(*ucs, &is_rtl); | 233 | is_diac = is_diacritic(*ucs, &is_rtl); |
@@ -219,8 +288,8 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | |||
219 | * buffer using OR, and then draw the final bitmap instead of the | 288 | * buffer using OR, and then draw the final bitmap instead of the |
220 | * chars, without touching the drawmode | 289 | * chars, without touching the drawmode |
221 | **/ | 290 | **/ |
222 | drawmode = current_vp->drawmode; | 291 | drawmode = LCDFN(current_viewport)->drawmode; |
223 | current_vp->drawmode = DRMODE_FG; | 292 | LCDFN(current_viewport)->drawmode = DRMODE_FG; |
224 | 293 | ||
225 | base_ofs = (base_width - width) / 2; | 294 | base_ofs = (base_width - width) / 2; |
226 | } | 295 | } |
@@ -237,7 +306,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | |||
237 | y, width - ofs, pf->height); | 306 | y, width - ofs, pf->height); |
238 | if (is_diac) | 307 | if (is_diac) |
239 | { | 308 | { |
240 | current_vp->drawmode = drawmode; | 309 | LCDFN(current_viewport)->drawmode = drawmode; |
241 | } | 310 | } |
242 | 311 | ||
243 | if (next_ch) | 312 | if (next_ch) |
@@ -256,7 +325,7 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | |||
256 | } | 325 | } |
257 | } | 326 | } |
258 | } | 327 | } |
259 | font_lock(current_vp->font, false); | 328 | font_lock(LCDFN(current_viewport)->font, false); |
260 | } | 329 | } |
261 | #else /* BOOTLOADER */ | 330 | #else /* BOOTLOADER */ |
262 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 331 | /* put a string at a given pixel position, skipping first ofs pixel columns */ |
@@ -375,7 +444,7 @@ static struct scrollinfo* find_scrolling_line(int x, int y) | |||
375 | for(i=0; i<LCDFN(scroll_info).lines; i++) | 444 | for(i=0; i<LCDFN(scroll_info).lines; i++) |
376 | { | 445 | { |
377 | s = &LCDFN(scroll_info).scroll[i]; | 446 | s = &LCDFN(scroll_info).scroll[i]; |
378 | if (s->x == x && s->y == y && s->vp == current_vp) | 447 | if (s->x == x && s->y == y && s->vp == LCDFN(current_viewport)) |
379 | return s; | 448 | return s; |
380 | } | 449 | } |
381 | return NULL; | 450 | return NULL; |
@@ -411,13 +480,13 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, | |||
411 | 480 | ||
412 | /* prepare rectangle for scrolling. x and y must be calculated early | 481 | /* prepare rectangle for scrolling. x and y must be calculated early |
413 | * for find_scrolling_line() to work */ | 482 | * for find_scrolling_line() to work */ |
414 | cwidth = font_get(current_vp->font)->maxwidth; | 483 | cwidth = font_get(LCDFN(current_viewport)->font)->maxwidth; |
415 | height = font_get(current_vp->font)->height; | 484 | height = font_get(LCDFN(current_viewport)->font)->height; |
416 | y = y * (linebased ? height : 1); | 485 | y = y * (linebased ? height : 1); |
417 | x = x * (linebased ? cwidth : 1); | 486 | x = x * (linebased ? cwidth : 1); |
418 | width = current_vp->width - x; | 487 | width = LCDFN(current_viewport)->width - x; |
419 | 488 | ||
420 | if (y >= current_vp->height) | 489 | if (y >= LCDFN(current_viewport)->height) |
421 | return false; | 490 | return false; |
422 | 491 | ||
423 | s = find_scrolling_line(x, y); | 492 | s = find_scrolling_line(x, y); |
@@ -430,7 +499,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, | |||
430 | * the string width is too small to scroll the scrolling line is | 499 | * the string width is too small to scroll the scrolling line is |
431 | * cleared as well */ | 500 | * cleared as well */ |
432 | if (w < width || restart) { | 501 | if (w < width || restart) { |
433 | LCDFN(scroll_stop_viewport_rect)(current_vp, x, y, width, height); | 502 | LCDFN(scroll_stop_viewport_rect)(LCDFN(current_viewport), x, y, width, height); |
434 | LCDFN(putsxyofs)(x, y, x_offset, string); | 503 | LCDFN(putsxyofs)(x, y, x_offset, string); |
435 | /* nothing to scroll, or out of scrolling lines. Either way, get out */ | 504 | /* nothing to scroll, or out of scrolling lines. Either way, get out */ |
436 | if (w < width || LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) | 505 | if (w < width || LCDFN(scroll_info).lines >= LCDM(SCROLLABLE_LINES)) |
@@ -443,7 +512,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, | |||
443 | strlcpy(s->linebuffer, string, sizeof(s->linebuffer)); | 512 | strlcpy(s->linebuffer, string, sizeof(s->linebuffer)); |
444 | /* scroll bidirectional or forward only depending on the string width */ | 513 | /* scroll bidirectional or forward only depending on the string width */ |
445 | if ( LCDFN(scroll_info).bidir_limit ) { | 514 | if ( LCDFN(scroll_info).bidir_limit ) { |
446 | s->bidir = w < (current_vp->width) * | 515 | s->bidir = w < (LCDFN(current_viewport)->width) * |
447 | (100 + LCDFN(scroll_info).bidir_limit) / 100; | 516 | (100 + LCDFN(scroll_info).bidir_limit) / 100; |
448 | } | 517 | } |
449 | else | 518 | else |
@@ -457,7 +526,7 @@ static bool LCDFN(puts_scroll_worker)(int x, int y, const unsigned char *string, | |||
457 | s->y = y; | 526 | s->y = y; |
458 | s->width = width; | 527 | s->width = width; |
459 | s->height = height; | 528 | s->height = height; |
460 | s->vp = current_vp; | 529 | s->vp = LCDFN(current_viewport); |
461 | s->start_tick = current_tick + LCDFN(scroll_info).delay; | 530 | s->start_tick = current_tick + LCDFN(scroll_info).delay; |
462 | LCDFN(scroll_info).lines++; | 531 | LCDFN(scroll_info).lines++; |
463 | } else { | 532 | } else { |
@@ -497,11 +566,6 @@ bool LCDFN(puts_scroll)(int x, int y, const unsigned char *string) | |||
497 | 566 | ||
498 | #if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD) | 567 | #if !defined(HAVE_LCD_COLOR) || !defined(MAIN_LCD) |
499 | /* see lcd-16bit-common.c for others */ | 568 | /* see lcd-16bit-common.c for others */ |
500 | #ifdef MAIN_LCD | ||
501 | #define THIS_STRIDE STRIDE_MAIN | ||
502 | #else | ||
503 | #define THIS_STRIDE STRIDE_REMOTE | ||
504 | #endif | ||
505 | 569 | ||
506 | void LCDFN(bmp_part)(const struct bitmap* bm, int src_x, int src_y, | 570 | void LCDFN(bmp_part)(const struct bitmap* bm, int src_x, int src_y, |
507 | int x, int y, int width, int height) | 571 | int x, int y, int width, int height) |
diff --git a/firmware/drivers/lcd-color-common.c b/firmware/drivers/lcd-color-common.c index c8bfd2d6b3..60e95a25ca 100644 --- a/firmware/drivers/lcd-color-common.c +++ b/firmware/drivers/lcd-color-common.c | |||
@@ -36,13 +36,23 @@ enum fill_opt { | |||
36 | }; | 36 | }; |
37 | 37 | ||
38 | /*** globals ***/ | 38 | /*** globals ***/ |
39 | fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] | 39 | static fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] |
40 | IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); | 40 | IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); |
41 | fb_data *lcd_framebuffer = &lcd_static_framebuffer[0][0]; | 41 | |
42 | static void *lcd_frameaddress_default(int x, int y); | ||
42 | 43 | ||
43 | static fb_data* lcd_backdrop = NULL; | 44 | static fb_data* lcd_backdrop = NULL; |
44 | static long lcd_backdrop_offset IDATA_ATTR = 0; | 45 | static long lcd_backdrop_offset IDATA_ATTR = 0; |
45 | 46 | ||
47 | /* shouldn't be changed unless you want system-wide framebuffer changes! */ | ||
48 | struct frame_buffer_t lcd_framebuffer_default = | ||
49 | { | ||
50 | .fb_ptr = &lcd_static_framebuffer[0][0], | ||
51 | .get_address_fn = &lcd_frameaddress_default, | ||
52 | .stride = STRIDE_MAIN(LCD_WIDTH, LCD_HEIGHT), | ||
53 | .elems = (LCD_FBWIDTH*LCD_FBHEIGHT), | ||
54 | }; | ||
55 | |||
46 | static struct viewport default_vp = | 56 | static struct viewport default_vp = |
47 | { | 57 | { |
48 | .x = 0, | 58 | .x = 0, |
@@ -51,15 +61,32 @@ static struct viewport default_vp = | |||
51 | .height = LCD_HEIGHT, | 61 | .height = LCD_HEIGHT, |
52 | .font = FONT_SYSFIXED, | 62 | .font = FONT_SYSFIXED, |
53 | .drawmode = DRMODE_SOLID, | 63 | .drawmode = DRMODE_SOLID, |
54 | .fg_pattern = LCD_DEFAULT_FG, | 64 | .buffer = NULL, |
55 | .bg_pattern = LCD_DEFAULT_BG, | 65 | .fg_pattern = LCD_DEFAULT_FG, |
66 | .bg_pattern = LCD_DEFAULT_BG, | ||
56 | }; | 67 | }; |
57 | 68 | ||
58 | static struct viewport* current_vp IDATA_ATTR = &default_vp; | 69 | struct viewport* lcd_current_viewport IDATA_ATTR; |
70 | |||
71 | static void *lcd_frameaddress_default(int x, int y) | ||
72 | { | ||
73 | /* the default expects a buffer the same size as the screen */ | ||
74 | struct frame_buffer_t *fb = lcd_current_viewport->buffer; | ||
75 | |||
76 | #if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE | ||
77 | size_t element = (x * LCD_NATIVE_STRIDE(fb->stride)) + y; | ||
78 | #else | ||
79 | size_t element = (y * LCD_NATIVE_STRIDE(fb->stride)) + x; | ||
80 | #endif | ||
81 | return fb->fb_ptr + element;/*(element % fb->elems);*/ | ||
82 | } | ||
59 | 83 | ||
60 | /* LCD init */ | 84 | /* LCD init */ |
61 | void lcd_init(void) | 85 | void lcd_init(void) |
62 | { | 86 | { |
87 | /* Initialize the viewport */ | ||
88 | lcd_set_viewport(NULL); | ||
89 | |||
63 | lcd_clear_display(); | 90 | lcd_clear_display(); |
64 | 91 | ||
65 | /* Call device specific init */ | 92 | /* Call device specific init */ |
@@ -70,77 +97,77 @@ void lcd_init(void) | |||
70 | /* Clear the whole display */ | 97 | /* Clear the whole display */ |
71 | void lcd_clear_display(void) | 98 | void lcd_clear_display(void) |
72 | { | 99 | { |
73 | struct viewport* old_vp = current_vp; | 100 | struct viewport* old_vp = lcd_current_viewport; |
74 | 101 | ||
75 | current_vp = &default_vp; | 102 | lcd_current_viewport = &default_vp; |
76 | 103 | ||
77 | lcd_clear_viewport(); | 104 | lcd_clear_viewport(); |
78 | 105 | ||
79 | current_vp = old_vp; | 106 | lcd_current_viewport = old_vp; |
80 | } | 107 | } |
81 | 108 | ||
82 | /*** parameter handling ***/ | 109 | /*** parameter handling ***/ |
83 | 110 | ||
84 | void lcd_set_drawmode(int mode) | 111 | void lcd_set_drawmode(int mode) |
85 | { | 112 | { |
86 | current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | 113 | lcd_current_viewport->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); |
87 | } | 114 | } |
88 | 115 | ||
89 | int lcd_get_drawmode(void) | 116 | int lcd_get_drawmode(void) |
90 | { | 117 | { |
91 | return current_vp->drawmode; | 118 | return lcd_current_viewport->drawmode; |
92 | } | 119 | } |
93 | 120 | ||
94 | void lcd_set_foreground(unsigned color) | 121 | void lcd_set_foreground(unsigned color) |
95 | { | 122 | { |
96 | current_vp->fg_pattern = color; | 123 | lcd_current_viewport->fg_pattern = color; |
97 | } | 124 | } |
98 | 125 | ||
99 | unsigned lcd_get_foreground(void) | 126 | unsigned lcd_get_foreground(void) |
100 | { | 127 | { |
101 | return current_vp->fg_pattern; | 128 | return lcd_current_viewport->fg_pattern; |
102 | } | 129 | } |
103 | 130 | ||
104 | void lcd_set_background(unsigned color) | 131 | void lcd_set_background(unsigned color) |
105 | { | 132 | { |
106 | current_vp->bg_pattern = color; | 133 | lcd_current_viewport->bg_pattern = color; |
107 | } | 134 | } |
108 | 135 | ||
109 | unsigned lcd_get_background(void) | 136 | unsigned lcd_get_background(void) |
110 | { | 137 | { |
111 | return current_vp->bg_pattern; | 138 | return lcd_current_viewport->bg_pattern; |
112 | } | 139 | } |
113 | 140 | ||
114 | void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) | 141 | void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) |
115 | { | 142 | { |
116 | lcd_set_drawmode(mode); | 143 | lcd_set_drawmode(mode); |
117 | current_vp->fg_pattern = fg_color; | 144 | lcd_current_viewport->fg_pattern = fg_color; |
118 | current_vp->bg_pattern = bg_color; | 145 | lcd_current_viewport->bg_pattern = bg_color; |
119 | } | 146 | } |
120 | 147 | ||
121 | int lcd_getwidth(void) | 148 | int lcd_getwidth(void) |
122 | { | 149 | { |
123 | return current_vp->width; | 150 | return lcd_current_viewport->width; |
124 | } | 151 | } |
125 | 152 | ||
126 | int lcd_getheight(void) | 153 | int lcd_getheight(void) |
127 | { | 154 | { |
128 | return current_vp->height; | 155 | return lcd_current_viewport->height; |
129 | } | 156 | } |
130 | 157 | ||
131 | void lcd_setfont(int newfont) | 158 | void lcd_setfont(int newfont) |
132 | { | 159 | { |
133 | current_vp->font = newfont; | 160 | lcd_current_viewport->font = newfont; |
134 | } | 161 | } |
135 | 162 | ||
136 | int lcd_getfont(void) | 163 | int lcd_getfont(void) |
137 | { | 164 | { |
138 | return current_vp->font; | 165 | return lcd_current_viewport->font; |
139 | } | 166 | } |
140 | 167 | ||
141 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) | 168 | int lcd_getstringsize(const unsigned char *str, int *w, int *h) |
142 | { | 169 | { |
143 | return font_getstringsize(str, w, h, current_vp->font); | 170 | return font_getstringsize(str, w, h, lcd_current_viewport->font); |
144 | } | 171 | } |
145 | 172 | ||
146 | void lcd_set_backdrop(fb_data* backdrop) | 173 | void lcd_set_backdrop(fb_data* backdrop) |
@@ -148,7 +175,7 @@ void lcd_set_backdrop(fb_data* backdrop) | |||
148 | lcd_backdrop = backdrop; | 175 | lcd_backdrop = backdrop; |
149 | if (backdrop) | 176 | if (backdrop) |
150 | { | 177 | { |
151 | lcd_backdrop_offset = (intptr_t)backdrop - (intptr_t)lcd_framebuffer; | 178 | lcd_backdrop_offset = (intptr_t)backdrop - (intptr_t)FBADDR(0,0); |
152 | lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; | 179 | lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; |
153 | } | 180 | } |
154 | else | 181 | else |
@@ -166,14 +193,14 @@ fb_data* lcd_get_backdrop(void) | |||
166 | /* Set a single pixel */ | 193 | /* Set a single pixel */ |
167 | void lcd_drawpixel(int x, int y) | 194 | void lcd_drawpixel(int x, int y) |
168 | { | 195 | { |
169 | if ( ((unsigned)x < (unsigned)current_vp->width) | 196 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) |
170 | && ((unsigned)y < (unsigned)current_vp->height) | 197 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) |
171 | #if defined(HAVE_VIEWPORT_CLIP) | 198 | #if defined(HAVE_VIEWPORT_CLIP) |
172 | && ((unsigned)x < (unsigned)LCD_WIDTH) | 199 | && ((unsigned)x < (unsigned)LCD_WIDTH) |
173 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | 200 | && ((unsigned)y < (unsigned)LCD_HEIGHT) |
174 | #endif | 201 | #endif |
175 | ) | 202 | ) |
176 | lcd_fastpixelfuncs[current_vp->drawmode](FBADDR(current_vp->x+x, current_vp->y+y)); | 203 | lcd_fastpixelfuncs[lcd_current_viewport->drawmode](FBADDR(lcd_current_viewport->x+x, lcd_current_viewport->y+y)); |
177 | } | 204 | } |
178 | 205 | ||
179 | /* Draw a line */ | 206 | /* Draw a line */ |
@@ -185,7 +212,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
185 | int d, dinc1, dinc2; | 212 | int d, dinc1, dinc2; |
186 | int x, xinc1, xinc2; | 213 | int x, xinc1, xinc2; |
187 | int y, yinc1, yinc2; | 214 | int y, yinc1, yinc2; |
188 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; | 215 | lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode]; |
189 | 216 | ||
190 | deltay = abs(y2 - y1); | 217 | deltay = abs(y2 - y1); |
191 | if (deltay == 0) | 218 | if (deltay == 0) |
@@ -241,14 +268,14 @@ void lcd_drawline(int x1, int y1, int x2, int y2) | |||
241 | 268 | ||
242 | for (i = 0; i < numpixels; i++) | 269 | for (i = 0; i < numpixels; i++) |
243 | { | 270 | { |
244 | if ( ((unsigned)x < (unsigned)current_vp->width) | 271 | if ( ((unsigned)x < (unsigned)lcd_current_viewport->width) |
245 | && ((unsigned)y < (unsigned)current_vp->height) | 272 | && ((unsigned)y < (unsigned)lcd_current_viewport->height) |
246 | #if defined(HAVE_VIEWPORT_CLIP) | 273 | #if defined(HAVE_VIEWPORT_CLIP) |
247 | && ((unsigned)x < (unsigned)LCD_WIDTH) | 274 | && ((unsigned)x < (unsigned)LCD_WIDTH) |
248 | && ((unsigned)y < (unsigned)LCD_HEIGHT) | 275 | && ((unsigned)y < (unsigned)LCD_HEIGHT) |
249 | #endif | 276 | #endif |
250 | ) | 277 | ) |
251 | pfunc(FBADDR(x + current_vp->x, y + current_vp->y)); | 278 | pfunc(FBADDR(x + lcd_current_viewport->x, y + lcd_current_viewport->y)); |
252 | 279 | ||
253 | if (d < 0) | 280 | if (d < 0) |
254 | { | 281 | { |
@@ -307,9 +334,9 @@ void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, | |||
307 | void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, | 334 | void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, |
308 | int x, int y, int width, int height) | 335 | int x, int y, int width, int height) |
309 | { | 336 | { |
310 | int bitmap_stride = STRIDE_MAIN(bm->width, bm->height); | 337 | int bitmap_stride = LCD_FBSTRIDE(bm->width, bm->height); |
311 | if (bm->format == FORMAT_MONO) | 338 | if (bm->format == FORMAT_MONO) |
312 | lcd_mono_bitmap_part(bm->data, src_x, src_y, bitmap_stride, x, y, width, height); | 339 | lcd_mono_bitmap_part(bm->data, src_x, src_y, bm->width, x, y, width, height); |
313 | else if (bm->alpha_offset > 0) | 340 | else if (bm->alpha_offset > 0) |
314 | lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset, | 341 | lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset, |
315 | src_x, src_y, x, y, width, height, | 342 | src_x, src_y, x, y, width, height, |
@@ -554,7 +581,7 @@ void lcd_blit_yuv(unsigned char * const src[3], | |||
554 | void lcd_gradient_fillrect_part(int x, int y, int width, int height, | 581 | void lcd_gradient_fillrect_part(int x, int y, int width, int height, |
555 | unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip) | 582 | unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip) |
556 | { | 583 | { |
557 | int old_pattern = current_vp->fg_pattern; | 584 | int old_pattern = lcd_current_viewport->fg_pattern; |
558 | int step_mul, i; | 585 | int step_mul, i; |
559 | int x1, x2; | 586 | int x1, x2; |
560 | x1 = x; | 587 | x1 = x; |
@@ -581,14 +608,14 @@ void lcd_gradient_fillrect_part(int x, int y, int width, int height, | |||
581 | } | 608 | } |
582 | 609 | ||
583 | for(i = y; i < y + height; i++) { | 610 | for(i = y; i < y + height; i++) { |
584 | current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); | 611 | lcd_current_viewport->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); |
585 | lcd_hline(x1, x2, i); | 612 | lcd_hline(x1, x2, i); |
586 | h_r -= rstep; | 613 | h_r -= rstep; |
587 | h_g -= gstep; | 614 | h_g -= gstep; |
588 | h_b -= bstep; | 615 | h_b -= bstep; |
589 | } | 616 | } |
590 | 617 | ||
591 | current_vp->fg_pattern = old_pattern; | 618 | lcd_current_viewport->fg_pattern = old_pattern; |
592 | } | 619 | } |
593 | 620 | ||
594 | /* Fill a rectangle with a gradient. The gradient's color will fade from | 621 | /* Fill a rectangle with a gradient. The gradient's color will fade from |
diff --git a/firmware/drivers/lcd-scroll.c b/firmware/drivers/lcd-scroll.c index 5d66788093..d8bfd72dde 100644 --- a/firmware/drivers/lcd-scroll.c +++ b/firmware/drivers/lcd-scroll.c | |||
@@ -156,8 +156,9 @@ bool LCDFN(scroll_now)(struct scrollinfo *s) | |||
156 | } | 156 | } |
157 | } | 157 | } |
158 | 158 | ||
159 | /* Stash and restore these three, so that the scroll_func | 159 | /* Stash and restore these four, so that the scroll_func |
160 | * can do whatever it likes without destroying the state */ | 160 | * can do whatever it likes without destroying the state */ |
161 | struct frame_buffer_t *framebuf = s->vp->buffer; | ||
161 | unsigned drawmode; | 162 | unsigned drawmode; |
162 | #if LCD_DEPTH > 1 | 163 | #if LCD_DEPTH > 1 |
163 | unsigned fg_pattern, bg_pattern; | 164 | unsigned fg_pattern, bg_pattern; |
@@ -174,6 +175,7 @@ bool LCDFN(scroll_now)(struct scrollinfo *s) | |||
174 | s->vp->bg_pattern = bg_pattern; | 175 | s->vp->bg_pattern = bg_pattern; |
175 | #endif | 176 | #endif |
176 | s->vp->drawmode = drawmode; | 177 | s->vp->drawmode = drawmode; |
178 | s->vp->buffer = framebuf; | ||
177 | 179 | ||
178 | return ended; | 180 | return ended; |
179 | } | 181 | } |
@@ -205,7 +207,7 @@ static void LCDFN(scroll_worker)(void) | |||
205 | * be switched early so that lcd_getstringsize() picks the | 207 | * be switched early so that lcd_getstringsize() picks the |
206 | * correct font */ | 208 | * correct font */ |
207 | vp = LCDFN(get_viewport)(&is_default); | 209 | vp = LCDFN(get_viewport)(&is_default); |
208 | LCDFN(set_viewport)(s->vp); | 210 | LCDFN(set_viewport_ex)(s->vp, 0); /* don't mark the last vp as dirty */ |
209 | 211 | ||
210 | makedelay = false; | 212 | makedelay = false; |
211 | step = si->step; | 213 | step = si->step; |
@@ -218,7 +220,7 @@ static void LCDFN(scroll_worker)(void) | |||
218 | /* put the line onto the display now */ | 220 | /* put the line onto the display now */ |
219 | makedelay = LCDFN(scroll_now(s)); | 221 | makedelay = LCDFN(scroll_now(s)); |
220 | 222 | ||
221 | LCDFN(set_viewport)(vp); | 223 | LCDFN(set_viewport_ex)(vp, 0); /* don't mark the last vp as dirty */ |
222 | 224 | ||
223 | if (makedelay) | 225 | if (makedelay) |
224 | s->start_tick += si->delay + si->ticks; | 226 | s->start_tick += si->delay + si->ticks; |