summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2006-02-20 19:15:46 +0000
committerJens Arnold <amiconn@rockbox.org>2006-02-20 19:15:46 +0000
commite48e60b3e072d9c6974343db07ebda24e1bcb123 (patch)
treed208a5ef9b163b5d93341f686fd9ec6e1eec9c6a
parent265d1a0936eafa90c6f466795fe1f7826fe4af9c (diff)
downloadrockbox-e48e60b3e072d9c6974343db07ebda24e1bcb123.tar.gz
rockbox-e48e60b3e072d9c6974343db07ebda24e1bcb123.zip
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
-rw-r--r--apps/plugins/lib/xlcd.c74
1 files changed, 73 insertions, 1 deletions
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