diff options
Diffstat (limited to 'firmware/drivers/lcd-1bit-vert.c')
-rw-r--r-- | firmware/drivers/lcd-1bit-vert.c | 176 |
1 files changed, 110 insertions, 66 deletions
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; |