summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-09-26 09:23:18 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-10-09 22:07:46 +0100
commit4f9e4ddb9914ff73259f006a4cbcf520656f06e0 (patch)
treea2e9bc09589316ffe2f7a9748369dadbe15662fa
parent4b8fe8acd1c079e75bb9229791170c549188fc08 (diff)
downloadrockbox-4f9e4ddb9914ff73259f006a4cbcf520656f06e0.tar.gz
rockbox-4f9e4ddb9914ff73259f006a4cbcf520656f06e0.zip
lcd: Consolidate drawpixel, drawline, and drawrect functions
All three functions are nearly identical regardless of the LCD pixel format. Consolidate them into a generic version in lcd-bitmap-common.c. Change-Id: Iab13429ea27ea2b0150b9004535bd27d4a4121a0
-rw-r--r--firmware/drivers/lcd-1bit-vert.c111
-rw-r--r--firmware/drivers/lcd-2bit-horz.c111
-rw-r--r--firmware/drivers/lcd-2bit-vert.c111
-rw-r--r--firmware/drivers/lcd-2bit-vi.c111
-rw-r--r--firmware/drivers/lcd-bitmap-common.c128
-rw-r--r--firmware/drivers/lcd-color-common.c114
6 files changed, 127 insertions, 559 deletions
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c
index e1b65ca9c0..ed66ee7e0c 100644
--- a/firmware/drivers/lcd-1bit-vert.c
+++ b/firmware/drivers/lcd-1bit-vert.c
@@ -271,102 +271,6 @@ void LCDFN(clear_viewport)(void)
271 CURRENT_VP->flags &= ~(VP_FLAG_VP_SET_CLEAN); 271 CURRENT_VP->flags &= ~(VP_FLAG_VP_SET_CLEAN);
272} 272}
273 273
274/* Set a single pixel */
275void LCDFN(drawpixel)(int x, int y)
276{
277 if (LCDFN(clip_viewport_pixel)(&x, &y))
278 LCDFN(pixelfuncs)[CURRENT_VP->drawmode](x, y);
279}
280
281/* Draw a line */
282void LCDFN(drawline)(int x1, int y1, int x2, int y2)
283{
284 int numpixels;
285 int i;
286 int deltax, deltay;
287 int d, dinc1, dinc2;
288 int x, xinc1, xinc2;
289 int y, yinc1, yinc2;
290 int x_vp, y_vp, w_vp, h_vp;
291 LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode];
292
293 deltax = abs(x2 - x1);
294 if (deltax == 0)
295 {
296 /* DEBUGF(LCDNAME "drawline() called for vertical line - optimisation.\n"); */
297 LCDFN(vline)(x1, y1, y2);
298 return;
299 }
300 deltay = abs(y2 - y1);
301 if (deltay == 0)
302 {
303 /* DEBUGF(LCDNAME "drawline() called for horizontal line - optimisation.\n"); */
304 LCDFN(hline)(x1, x2, y1);
305 return;
306 }
307 xinc2 = 1;
308 yinc2 = 1;
309
310 if (deltax >= deltay)
311 {
312 numpixels = deltax;
313 d = 2 * deltay - deltax;
314 dinc1 = deltay * 2;
315 dinc2 = (deltay - deltax) * 2;
316 xinc1 = 1;
317 yinc1 = 0;
318 }
319 else
320 {
321 numpixels = deltay;
322 d = 2 * deltax - deltay;
323 dinc1 = deltax * 2;
324 dinc2 = (deltax - deltay) * 2;
325 xinc1 = 0;
326 yinc1 = 1;
327 }
328 numpixels++; /* include endpoints */
329
330 if (x1 > x2)
331 {
332 xinc1 = -xinc1;
333 xinc2 = -xinc2;
334 }
335
336 if (y1 > y2)
337 {
338 yinc1 = -yinc1;
339 yinc2 = -yinc2;
340 }
341
342 x = x1;
343 y = y1;
344
345 x_vp = CURRENT_VP->x;
346 y_vp = CURRENT_VP->y;
347 w_vp = CURRENT_VP->width;
348 h_vp = CURRENT_VP->height;
349
350 for (i = 0; i < numpixels; i++)
351 {
352 if (x >= 0 && y >= 0 && x < w_vp && y < h_vp)
353 pfunc(x + x_vp, y + y_vp);
354
355 if (d < 0)
356 {
357 d += dinc1;
358 x += xinc1;
359 y += yinc1;
360 }
361 else
362 {
363 d += dinc2;
364 x += xinc2;
365 y += yinc2;
366 }
367 }
368}
369
370/* Draw a horizontal line (optimised) */ 274/* Draw a horizontal line (optimised) */
371void LCDFN(hline)(int x1, int x2, int y) 275void LCDFN(hline)(int x1, int x2, int y)
372{ 276{
@@ -419,21 +323,6 @@ void LCDFN(vline)(int x, int y1, int y2)
419 bfunc(dst, mask, 0xFFu); 323 bfunc(dst, mask, 0xFFu);
420} 324}
421 325
422/* Draw a rectangular box */
423void LCDFN(drawrect)(int x, int y, int width, int height)
424{
425 if ((width <= 0) || (height <= 0))
426 return;
427
428 int x2 = x + width - 1;
429 int y2 = y + height - 1;
430
431 LCDFN(vline)(x, y, y2);
432 LCDFN(vline)(x2, y, y2);
433 LCDFN(hline)(x, x2, y);
434 LCDFN(hline)(x, x2, y2);
435}
436
437/* Fill a rectangular area */ 326/* Fill a rectangular area */
438void LCDFN(fillrect)(int x, int y, int width, int height) 327void LCDFN(fillrect)(int x, int y, int width, int height)
439{ 328{
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index 37125679ad..1b192377f6 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -417,102 +417,6 @@ void lcd_clear_viewport(void)
417 lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN); 417 lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN);
418} 418}
419 419
420/* Set a single pixel */
421void lcd_drawpixel(int x, int y)
422{
423 if (lcd_clip_viewport_pixel(&x, &y))
424 lcd_pixelfuncs[lcd_current_viewport->drawmode](x, y);
425}
426
427/* Draw a line */
428void lcd_drawline(int x1, int y1, int x2, int y2)
429{
430 int numpixels;
431 int i;
432 int deltax, deltay;
433 int d, dinc1, dinc2;
434 int x, xinc1, xinc2;
435 int y, yinc1, yinc2;
436 int x_vp, y_vp, w_vp, h_vp;
437 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode];
438
439 deltay = abs(y2 - y1);
440 if (deltay == 0)
441 {
442 /* DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); */
443 lcd_hline(x1, x2, y1);
444 return;
445 }
446 deltax = abs(x2 - x1);
447 if (deltax == 0)
448 {
449 /* DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); */
450 lcd_vline(x1, y1, y2);
451 return;
452 }
453 xinc2 = 1;
454 yinc2 = 1;
455
456 if (deltax >= deltay)
457 {
458 numpixels = deltax;
459 d = 2 * deltay - deltax;
460 dinc1 = deltay * 2;
461 dinc2 = (deltay - deltax) * 2;
462 xinc1 = 1;
463 yinc1 = 0;
464 }
465 else
466 {
467 numpixels = deltay;
468 d = 2 * deltax - deltay;
469 dinc1 = deltax * 2;
470 dinc2 = (deltax - deltay) * 2;
471 xinc1 = 0;
472 yinc1 = 1;
473 }
474 numpixels++; /* include endpoints */
475
476 if (x1 > x2)
477 {
478 xinc1 = -xinc1;
479 xinc2 = -xinc2;
480 }
481
482 if (y1 > y2)
483 {
484 yinc1 = -yinc1;
485 yinc2 = -yinc2;
486 }
487
488 x = x1;
489 y = y1;
490
491 x_vp = lcd_current_viewport->x;
492 y_vp = lcd_current_viewport->y;
493 w_vp = lcd_current_viewport->width;
494 h_vp = lcd_current_viewport->height;
495
496 for (i = 0; i < numpixels; i++)
497 {
498 if (x >= 0 && y >= 0 && x < w_vp && y < h_vp)
499 pfunc(x + x_vp, y + y_vp);
500
501 if (d < 0)
502 {
503 d += dinc1;
504 x += xinc1;
505 y += yinc1;
506 }
507 else
508 {
509 d += dinc2;
510 x += xinc2;
511 y += yinc2;
512 }
513 }
514}
515
516/* Draw a horizontal line (optimised) */ 420/* Draw a horizontal line (optimised) */
517void lcd_hline(int x1, int x2, int y) 421void lcd_hline(int x1, int x2, int y)
518{ 422{
@@ -564,21 +468,6 @@ void lcd_vline(int x, int y1, int y2)
564 while (dst <= dst_end); 468 while (dst <= dst_end);
565} 469}
566 470
567/* Draw a rectangular box */
568void lcd_drawrect(int x, int y, int width, int height)
569{
570 if ((width <= 0) || (height <= 0))
571 return;
572
573 int x2 = x + width - 1;
574 int y2 = y + height - 1;
575
576 lcd_vline(x, y, y2);
577 lcd_vline(x2, y, y2);
578 lcd_hline(x, x2, y);
579 lcd_hline(x, x2, y2);
580}
581
582/* Fill a rectangular area */ 471/* Fill a rectangular area */
583void lcd_fillrect(int x, int y, int width, int height) 472void lcd_fillrect(int x, int y, int width, int height)
584{ 473{
diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c
index 5fd86c409a..9e1eb0ed37 100644
--- a/firmware/drivers/lcd-2bit-vert.c
+++ b/firmware/drivers/lcd-2bit-vert.c
@@ -419,102 +419,6 @@ void lcd_clear_viewport(void)
419 lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN); 419 lcd_current_viewport->flags &= ~(VP_FLAG_VP_SET_CLEAN);
420} 420}
421 421
422/* Set a single pixel */
423void lcd_drawpixel(int x, int y)
424{
425 if (lcd_clip_viewport_pixel(&x, &y))
426 lcd_pixelfuncs[lcd_current_viewport->drawmode](x, y);
427}
428
429/* Draw a line */
430void lcd_drawline(int x1, int y1, int x2, int y2)
431{
432 int numpixels;
433 int i;
434 int deltax, deltay;
435 int d, dinc1, dinc2;
436 int x, xinc1, xinc2;
437 int y, yinc1, yinc2;
438 int x_vp, y_vp, w_vp, h_vp;
439 lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[lcd_current_viewport->drawmode];
440
441 deltax = abs(x2 - x1);
442 if (deltax == 0)
443 {
444 /* DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); */
445 lcd_vline(x1, y1, y2);
446 return;
447 }
448 deltay = abs(y2 - y1);
449 if (deltay == 0)
450 {
451 /* DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); */
452 lcd_hline(x1, x2, y1);
453 return;
454 }
455 xinc2 = 1;
456 yinc2 = 1;
457
458 if (deltax >= deltay)
459 {
460 numpixels = deltax;
461 d = 2 * deltay - deltax;
462 dinc1 = deltay * 2;
463 dinc2 = (deltay - deltax) * 2;
464 xinc1 = 1;
465 yinc1 = 0;
466 }
467 else
468 {
469 numpixels = deltay;
470 d = 2 * deltax - deltay;
471 dinc1 = deltax * 2;
472 dinc2 = (deltax - deltay) * 2;
473 xinc1 = 0;
474 yinc1 = 1;
475 }
476 numpixels++; /* include endpoints */
477
478 if (x1 > x2)
479 {
480 xinc1 = -xinc1;
481 xinc2 = -xinc2;
482 }
483
484 if (y1 > y2)
485 {
486 yinc1 = -yinc1;
487 yinc2 = -yinc2;
488 }
489
490 x = x1;
491 y = y1;
492
493 x_vp = lcd_current_viewport->x;
494 y_vp = lcd_current_viewport->y;
495 w_vp = lcd_current_viewport->width;
496 h_vp = lcd_current_viewport->height;
497
498 for (i = 0; i < numpixels; i++)
499 {
500 if (x >= 0 && y >= 0 && x < w_vp && y < h_vp)
501 pfunc(x + x_vp, y + y_vp);
502
503 if (d < 0)
504 {
505 d += dinc1;
506 x += xinc1;
507 y += yinc1;
508 }
509 else
510 {
511 d += dinc2;
512 x += xinc2;
513 y += yinc2;
514 }
515 }
516}
517
518/* Draw a horizontal line (optimised) */ 422/* Draw a horizontal line (optimised) */
519void lcd_hline(int x1, int x2, int y) 423void lcd_hline(int x1, int x2, int y)
520{ 424{
@@ -567,21 +471,6 @@ void lcd_vline(int x, int y1, int y2)
567 bfunc(dst, mask, 0xFFu); 471 bfunc(dst, mask, 0xFFu);
568} 472}
569 473
570/* Draw a rectangular box */
571void lcd_drawrect(int x, int y, int width, int height)
572{
573 if ((width <= 0) || (height <= 0))
574 return;
575
576 int x2 = x + width - 1;
577 int y2 = y + height - 1;
578
579 lcd_vline(x, y, y2);
580 lcd_vline(x2, y, y2);
581 lcd_hline(x, x2, y);
582 lcd_hline(x, x2, y2);
583}
584
585/* Fill a rectangular area */ 474/* Fill a rectangular area */
586void lcd_fillrect(int x, int y, int width, int height) 475void lcd_fillrect(int x, int y, int width, int height)
587{ 476{
diff --git a/firmware/drivers/lcd-2bit-vi.c b/firmware/drivers/lcd-2bit-vi.c
index b19fdba266..976af8f62d 100644
--- a/firmware/drivers/lcd-2bit-vi.c
+++ b/firmware/drivers/lcd-2bit-vi.c
@@ -452,102 +452,6 @@ void LCDFN(clear_viewport)(void)
452 CURRENT_VP->flags &= ~(VP_FLAG_VP_SET_CLEAN); 452 CURRENT_VP->flags &= ~(VP_FLAG_VP_SET_CLEAN);
453} 453}
454 454
455/* Set a single pixel */
456void LCDFN(drawpixel)(int x, int y)
457{
458 if (LCDFN(clip_viewport_pixel)(&x, &y))
459 LCDFN(pixelfuncs)[CURRENT_VP->drawmode](x, y);
460}
461
462/* Draw a line */
463void LCDFN(drawline)(int x1, int y1, int x2, int y2)
464{
465 int numpixels;
466 int i;
467 int deltax, deltay;
468 int d, dinc1, dinc2;
469 int x, xinc1, xinc2;
470 int y, yinc1, yinc2;
471 int x_vp, y_vp, w_vp, h_vp;
472 LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[CURRENT_VP->drawmode];
473
474 deltax = abs(x2 - x1);
475 if (deltax == 0)
476 {
477 /* DEBUGF(LCDNAME "drawline() called for vertical line - optimisation.\n"); */
478 LCDFN(vline)(x1, y1, y2);
479 return;
480 }
481 deltay = abs(y2 - y1);
482 if (deltay == 0)
483 {
484 /* DEBUGF(LCDNAME "drawline() called for horizontal line - optimisation.\n"); */
485 LCDFN(hline)(x1, x2, y1);
486 return;
487 }
488 xinc2 = 1;
489 yinc2 = 1;
490
491 if (deltax >= deltay)
492 {
493 numpixels = deltax;
494 d = 2 * deltay - deltax;
495 dinc1 = deltay * 2;
496 dinc2 = (deltay - deltax) * 2;
497 xinc1 = 1;
498 yinc1 = 0;
499 }
500 else
501 {
502 numpixels = deltay;
503 d = 2 * deltax - deltay;
504 dinc1 = deltax * 2;
505 dinc2 = (deltax - deltay) * 2;
506 xinc1 = 0;
507 yinc1 = 1;
508 }
509 numpixels++; /* include endpoints */
510
511 if (x1 > x2)
512 {
513 xinc1 = -xinc1;
514 xinc2 = -xinc2;
515 }
516
517 if (y1 > y2)
518 {
519 yinc1 = -yinc1;
520 yinc2 = -yinc2;
521 }
522
523 x = x1;
524 y = y1;
525
526 x_vp = CURRENT_VP->x;
527 y_vp = CURRENT_VP->y;
528 w_vp = CURRENT_VP->width;
529 h_vp = CURRENT_VP->height;
530
531 for (i = 0; i < numpixels; i++)
532 {
533 if (x >= 0 && y >= 0 && x < w_vp && y < h_vp)
534 pfunc(x + x_vp, y + y_vp);
535
536 if (d < 0)
537 {
538 d += dinc1;
539 x += xinc1;
540 y += yinc1;
541 }
542 else
543 {
544 d += dinc2;
545 x += xinc2;
546 y += yinc2;
547 }
548 }
549}
550
551/* Draw a horizontal line (optimised) */ 455/* Draw a horizontal line (optimised) */
552void LCDFN(hline)(int x1, int x2, int y) 456void LCDFN(hline)(int x1, int x2, int y)
553{ 457{
@@ -602,21 +506,6 @@ void LCDFN(vline)(int x, int y1, int y2)
602 bfunc(dst, mask, 0xFFFFu); 506 bfunc(dst, mask, 0xFFFFu);
603} 507}
604 508
605/* Draw a rectangular box */
606void LCDFN(drawrect)(int x, int y, int width, int height)
607{
608 if ((width <= 0) || (height <= 0))
609 return;
610
611 int x2 = x + width - 1;
612 int y2 = y + height - 1;
613
614 LCDFN(vline)(x, y, y2);
615 LCDFN(vline)(x2, y, y2);
616 LCDFN(hline)(x, x2, y);
617 LCDFN(hline)(x, x2, y2);
618}
619
620/* Fill a rectangular area */ 509/* Fill a rectangular area */
621void LCDFN(fillrect)(int x, int y, int width, int height) 510void LCDFN(fillrect)(int x, int y, int width, int height)
622{ 511{
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index c867b214b5..bd6efa167c 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -67,7 +67,8 @@ static bool LCDFN(clip_viewport_pixel)(int *x, int *y)
67{ 67{
68 struct viewport *vp = LCDFN(current_viewport); 68 struct viewport *vp = LCDFN(current_viewport);
69 69
70 if(*x >= vp->width || *y >= vp->height) 70 if (*x < 0 || *x >= vp->width ||
71 *y < 0 || *y >= vp->height)
71 return false; 72 return false;
72 73
73 *x += vp->x; 74 *x += vp->x;
@@ -805,3 +806,128 @@ void LCDFN(nine_segment_bmp)(const struct bitmap* bm, int x, int y,
805 LCDFN(bmp_part)(bm, bm->width - corner_w, bm->width - corner_h, 806 LCDFN(bmp_part)(bm, bm->width - corner_w, bm->width - corner_h,
806 width - corner_w, height - corner_h, corner_w, corner_h); 807 width - corner_w, height - corner_h, corner_w, corner_h);
807} 808}
809
810void LCDFN(drawpixel)(int x, int y)
811{
812 struct viewport *vp = LCDFN(current_viewport);
813 if (LCDFN(clip_viewport_pixel(&x, &y)))
814 {
815#if LCDM(DEPTH) >= 8
816 LCDFN(fastpixelfunc_type) *pfunc = LCDFN(fastpixelfuncs)[vp->drawmode];
817 void *(*fbaddr)(int x, int y) = vp->buffer->get_address_fn;
818 pfunc(fbaddr(x, y));
819#else
820 LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[vp->drawmode];
821 pfunc(x, y);
822#endif
823 }
824}
825
826void LCDFN(drawline)(int x1, int y1, int x2, int y2)
827{
828 struct viewport *vp = LCDFN(current_viewport);
829 int numpixels;
830 int i;
831 int deltax, deltay;
832 int d, dinc1, dinc2;
833 int x, xinc1, xinc2;
834 int y, yinc1, yinc2;
835
836 deltay = abs(y2 - y1);
837 if (deltay == 0)
838 {
839 lcd_hline(x1, x2, y1);
840 return;
841 }
842
843 deltax = abs(x2 - x1);
844 if (deltax == 0)
845 {
846 lcd_vline(x1, y1, y2);
847 return;
848 }
849
850 xinc2 = 1;
851 yinc2 = 1;
852
853 if (deltax >= deltay)
854 {
855 numpixels = deltax;
856 d = 2 * deltay - deltax;
857 dinc1 = deltay * 2;
858 dinc2 = (deltay - deltax) * 2;
859 xinc1 = 1;
860 yinc1 = 0;
861 }
862 else
863 {
864 numpixels = deltay;
865 d = 2 * deltax - deltay;
866 dinc1 = deltax * 2;
867 dinc2 = (deltax - deltay) * 2;
868 xinc1 = 0;
869 yinc1 = 1;
870 }
871 numpixels++; /* include endpoints */
872
873 if (x1 > x2)
874 {
875 xinc1 = -xinc1;
876 xinc2 = -xinc2;
877 }
878
879 if (y1 > y2)
880 {
881 yinc1 = -yinc1;
882 yinc2 = -yinc2;
883 }
884
885 x = x1;
886 y = y1;
887
888#if LCDM(DEPTH) >= 8
889 LCDFN(fastpixelfunc_type) *pfunc = LCDFN(fastpixelfuncs)[vp->drawmode];
890 void *(*fbaddr)(int x, int y) = vp->buffer->get_address_fn;
891#else
892 LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[vp->drawmode];
893#endif
894
895 for (i = 0; i < numpixels; i++)
896 {
897 if (x >= 0 && y >= 0 && x < vp->width && y < vp->height)
898 {
899#if LCDM(DEPTH) >= 8
900 pfunc(fbaddr(x + vp->x, y + vp->y));
901#else
902 pfunc(x + vp->x, y + vp->y);
903#endif
904 }
905
906 if (d < 0)
907 {
908 d += dinc1;
909 x += xinc1;
910 y += yinc1;
911 }
912 else
913 {
914 d += dinc2;
915 x += xinc2;
916 y += yinc2;
917 }
918 }
919}
920
921void LCDFN(drawrect)(int x, int y, int width, int height)
922{
923 if ((width <= 0) || (height <= 0))
924 return;
925
926 int x2 = x + width - 1;
927 int y2 = y + height - 1;
928
929 LCDFN(vline)(x, y, y2);
930 LCDFN(vline)(x2, y, y2);
931 LCDFN(hline)(x, x2, y);
932 LCDFN(hline)(x, x2, y2);
933}
diff --git a/firmware/drivers/lcd-color-common.c b/firmware/drivers/lcd-color-common.c
index 8a9ef64cea..a1d2f47c22 100644
--- a/firmware/drivers/lcd-color-common.c
+++ b/firmware/drivers/lcd-color-common.c
@@ -40,7 +40,6 @@ 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 41
42static void *lcd_frameaddress_default(int x, int y); 42static void *lcd_frameaddress_default(int x, int y);
43static bool lcd_clip_viewport_pixel(int *x, int *y);
44 43
45static fb_data* lcd_backdrop = NULL; 44static fb_data* lcd_backdrop = NULL;
46static long lcd_backdrop_offset IDATA_ATTR = 0; 45static long lcd_backdrop_offset IDATA_ATTR = 0;
@@ -194,119 +193,6 @@ fb_data* lcd_get_backdrop(void)
194 return lcd_backdrop; 193 return lcd_backdrop;
195} 194}
196 195
197/* Set a single pixel */
198void lcd_drawpixel(int x, int y)
199{
200 if (lcd_clip_viewport_pixel(&x, &y))
201 lcd_fastpixelfuncs[lcd_current_viewport->drawmode](FBADDR(x, y));
202}
203
204/* Draw a line */
205void lcd_drawline(int x1, int y1, int x2, int y2)
206{
207 int numpixels;
208 int i;
209 int deltax, deltay;
210 int d, dinc1, dinc2;
211 int x, xinc1, xinc2;
212 int y, yinc1, yinc2;
213 int x_vp, y_vp, w_vp, h_vp;
214 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[lcd_current_viewport->drawmode];
215
216 deltay = abs(y2 - y1);
217 if (deltay == 0)
218 {
219 /* DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); */
220 lcd_hline(x1, x2, y1);
221 return;
222 }
223 deltax = abs(x2 - x1);
224 if (deltax == 0)
225 {
226 /* DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); */
227 lcd_vline(x1, y1, y2);
228 return;
229 }
230 xinc2 = 1;
231 yinc2 = 1;
232
233 if (deltax >= deltay)
234 {
235 numpixels = deltax;
236 d = 2 * deltay - deltax;
237 dinc1 = deltay * 2;
238 dinc2 = (deltay - deltax) * 2;
239 xinc1 = 1;
240 yinc1 = 0;
241 }
242 else
243 {
244 numpixels = deltay;
245 d = 2 * deltax - deltay;
246 dinc1 = deltax * 2;
247 dinc2 = (deltax - deltay) * 2;
248 xinc1 = 0;
249 yinc1 = 1;
250 }
251 numpixels++; /* include endpoints */
252
253 if (x1 > x2)
254 {
255 xinc1 = -xinc1;
256 xinc2 = -xinc2;
257 }
258
259 if (y1 > y2)
260 {
261 yinc1 = -yinc1;
262 yinc2 = -yinc2;
263 }
264
265 x = x1;
266 y = y1;
267
268 void *(*fbaddr)(int x, int y) = FB_CURRENTVP_BUFFER->get_address_fn;
269 x_vp = lcd_current_viewport->x;
270 y_vp = lcd_current_viewport->y;
271 w_vp = lcd_current_viewport->width;
272 h_vp = lcd_current_viewport->height;
273
274 for (i = 0; i < numpixels; i++)
275 {
276 if (x >= 0 && y >= 0 && x < w_vp && y < h_vp)
277 pfunc(fbaddr(x + x_vp, y + y_vp));
278
279 if (d < 0)
280 {
281 d += dinc1;
282 x += xinc1;
283 y += yinc1;
284 }
285 else
286 {
287 d += dinc2;
288 x += xinc2;
289 y += yinc2;
290 }
291 }
292}
293
294/* Draw a rectangular box */
295void lcd_drawrect(int x, int y, int width, int height)
296{
297 if ((width <= 0) || (height <= 0))
298 return;
299
300 int x2 = x + width - 1;
301 int y2 = y + height - 1;
302
303 lcd_vline(x, y, y2);
304 lcd_vline(x2, y, y2);
305 lcd_hline(x, x2, y);
306 lcd_hline(x, x2, y2);
307}
308
309
310/* Draw a full native bitmap */ 196/* Draw a full native bitmap */
311void lcd_bitmap(const fb_data *src, int x, int y, int width, int height) 197void lcd_bitmap(const fb_data *src, int x, int y, int width, int height)
312{ 198{