From e48e60b3e072d9c6974343db07ebda24e1bcb123 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Mon, 20 Feb 2006 19:15:46 +0000 Subject: Faster filled triangle drawing for colour targets and greyscale iPods. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8751 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/lib/xlcd.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/apps/plugins/lib/xlcd.c b/apps/plugins/lib/xlcd.c index 8f26330470..9b03a16b6a 100644 --- a/apps/plugins/lib/xlcd.c +++ b/apps/plugins/lib/xlcd.c @@ -35,7 +35,78 @@ void xlcd_init(struct plugin_api* newrb) local_rb = newrb; } -/* draw a filled triangle */ +#if (LCD_DEPTH >= 8) || (LCD_PIXELFORMAT == HORIZONTAL_PACKING) +/* draw a filled triangle, using horizontal lines for speed */ +void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) +{ + int x, y; + long fp_x1, fp_x2, fp_dx1, fp_dx2; + + /* sort vertices by increasing y value */ + if (y1 > y3) + { + if (y2 < y3) /* y2 < y3 < y1 */ + { + x = x1; x1 = x2; x2 = x3; x3 = x; + y = y1; y1 = y2; y2 = y3; y3 = y; + } + else if (y2 > y1) /* y3 < y1 < y2 */ + { + x = x1; x1 = x3; x3 = x2; x2 = x; + y = y1; y1 = y3; y3 = y2; y2 = y; + } + else /* y3 <= y2 <= y1 */ + { + x = x1; x1 = x3; x3 = x; + y = y1; y1 = y3; y3 = y; + } + } + else + { + if (y2 < y1) /* y2 < y1 <= y3 */ + { + x = x1; x1 = x2; x2 = x; + y = y1; y1 = y2; y2 = y; + } + else if (y2 > y3) /* y1 <= y3 < y2 */ + { + x = x2; x2 = x3; x3 = x; + y = y2; y2 = y3; y3 = y; + } + /* else already sorted */ + } + + if (y1 < y3) /* draw */ + { + fp_dx1 = ((x3 - x1) << 16) / (y3 - y1); + fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1); + + if (y1 < y2) /* first part */ + { + fp_dx2 = ((x2 - x1) << 16) / (y2 - y1); + fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1); + for (y = y1; y < y2; y++) + { + local_rb->lcd_hline(fp_x1 >> 16, fp_x2 >> 16, y); + fp_x1 += fp_dx1; + fp_x2 += fp_dx2; + } + } + if (y2 < y3) /* second part */ + { + fp_dx2 = ((x3 - x2) << 16) / (y3 - y2); + fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1); + for (y = y2; y < y3; y++) + { + local_rb->lcd_hline(fp_x1 >> 16, fp_x2 >> 16, y); + fp_x1 += fp_dx1; + fp_x2 += fp_dx2; + } + } + } +} +#else /* (LCD_DEPTH < 8) && (LCD_PIXELFORMAT == VERTICAL_PACKING) */ +/* draw a filled triangle, using vertical lines for speed */ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) { int x, y; @@ -104,6 +175,7 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) } } } +#endif /* LCD_DEPTH, LCD_PIXELFORMAT */ #if LCD_DEPTH >= 8 -- cgit