diff options
Diffstat (limited to 'apps/plugins/lib/xlcd_draw.c')
-rw-r--r-- | apps/plugins/lib/xlcd_draw.c | 135 |
1 files changed, 68 insertions, 67 deletions
diff --git a/apps/plugins/lib/xlcd_draw.c b/apps/plugins/lib/xlcd_draw.c index 3ccdea9139..accf3b4f4b 100644 --- a/apps/plugins/lib/xlcd_draw.c +++ b/apps/plugins/lib/xlcd_draw.c | |||
@@ -25,46 +25,58 @@ | |||
25 | #ifdef HAVE_LCD_BITMAP | 25 | #ifdef HAVE_LCD_BITMAP |
26 | #include "xlcd.h" | 26 | #include "xlcd.h" |
27 | 27 | ||
28 | #if (LCD_DEPTH >= 8) || (LCD_PIXELFORMAT == HORIZONTAL_PACKING) | 28 | /* sort the given coordinates by increasing x value */ |
29 | /* draw a filled triangle, using horizontal lines for speed */ | 29 | void sort_points_by_increasing_x(int* x1, int* y1, |
30 | void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) | 30 | int* x2, int* y2, |
31 | int* x3, int* y3) | ||
31 | { | 32 | { |
32 | int x, y; | 33 | int x, y; |
33 | long fp_x1, fp_x2, fp_dx1, fp_dx2; | 34 | if (*x1 > *x3) |
34 | |||
35 | /* sort vertices by increasing y value */ | ||
36 | if (y1 > y3) | ||
37 | { | 35 | { |
38 | if (y2 < y3) /* y2 < y3 < y1 */ | 36 | if (*x2 < *x3) /* x2 < x3 < x1 */ |
39 | { | 37 | { |
40 | x = x1; x1 = x2; x2 = x3; x3 = x; | 38 | x = *x1; *x1 = *x2; *x2 = *x3; *x3 = x; |
41 | y = y1; y1 = y2; y2 = y3; y3 = y; | 39 | y = *y1; *y1 = *y2; *y2 = *y3; *y3 = y; |
42 | } | 40 | } |
43 | else if (y2 > y1) /* y3 < y1 < y2 */ | 41 | else if (*x2 > *x1) /* x3 < x1 < x2 */ |
44 | { | 42 | { |
45 | x = x1; x1 = x3; x3 = x2; x2 = x; | 43 | x = *x1; *x1 = *x3; *x3 = *x2; *x2 = x; |
46 | y = y1; y1 = y3; y3 = y2; y2 = y; | 44 | y = *y1; *y1 = *y3; *y3 = *y2; *y2 = y; |
47 | } | 45 | } |
48 | else /* y3 <= y2 <= y1 */ | 46 | else /* x3 <= x2 <= x1 */ |
49 | { | 47 | { |
50 | x = x1; x1 = x3; x3 = x; | 48 | x = *x1; *x1 = *x3; *x3 = x; |
51 | y = y1; y1 = y3; y3 = y; | 49 | y = *y1; *y1 = *y3; *y3 = y; |
52 | } | 50 | } |
53 | } | 51 | } |
54 | else | 52 | else |
55 | { | 53 | { |
56 | if (y2 < y1) /* y2 < y1 <= y3 */ | 54 | if (*x2 < *x1) /* x2 < x1 <= x3 */ |
57 | { | 55 | { |
58 | x = x1; x1 = x2; x2 = x; | 56 | x = *x1; *x1 = *x2; *x2 = x; |
59 | y = y1; y1 = y2; y2 = y; | 57 | y = *y1; *y1 = *y2; *y2 = y; |
60 | } | 58 | } |
61 | else if (y2 > y3) /* y1 <= y3 < y2 */ | 59 | else if (*x2 > *x3) /* x1 <= x3 < x2 */ |
62 | { | 60 | { |
63 | x = x2; x2 = x3; x3 = x; | 61 | x = *x2; *x2 = *x3; *x3 = x; |
64 | y = y2; y2 = y3; y3 = y; | 62 | y = *y2; *y2 = *y3; *y3 = y; |
65 | } | 63 | } |
66 | /* else already sorted */ | 64 | /* else already sorted */ |
67 | } | 65 | } |
66 | } | ||
67 | |||
68 | #define sort_points_by_increasing_y(x1, y1, x2, y2, x3, y3) \ | ||
69 | sort_points_by_increasing_x(y1, x1, y2, x2, y3, x3) | ||
70 | |||
71 | /* draw a filled triangle, using horizontal lines for speed */ | ||
72 | void xlcd_filltriangle_horizontal(struct screen* display, | ||
73 | int x1, int y1, | ||
74 | int x2, int y2, | ||
75 | int x3, int y3) | ||
76 | { | ||
77 | long fp_x1, fp_x2, fp_dx1, fp_dx2; | ||
78 | int y; | ||
79 | sort_points_by_increasing_y(&x1, &y1, &x2, &y2, &x3, &y3); | ||
68 | 80 | ||
69 | if (y1 < y3) /* draw */ | 81 | if (y1 < y3) /* draw */ |
70 | { | 82 | { |
@@ -72,12 +84,12 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) | |||
72 | fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1); | 84 | fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1); |
73 | 85 | ||
74 | if (y1 < y2) /* first part */ | 86 | if (y1 < y2) /* first part */ |
75 | { | 87 | { |
76 | fp_dx2 = ((x2 - x1) << 16) / (y2 - y1); | 88 | fp_dx2 = ((x2 - x1) << 16) / (y2 - y1); |
77 | fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1); | 89 | fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1); |
78 | for (y = y1; y < y2; y++) | 90 | for (y = y1; y < y2; y++) |
79 | { | 91 | { |
80 | _xlcd_rb->lcd_hline(fp_x1 >> 16, fp_x2 >> 16, y); | 92 | display->hline(fp_x1 >> 16, fp_x2 >> 16, y); |
81 | fp_x1 += fp_dx1; | 93 | fp_x1 += fp_dx1; |
82 | fp_x2 += fp_dx2; | 94 | fp_x2 += fp_dx2; |
83 | } | 95 | } |
@@ -88,53 +100,23 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) | |||
88 | fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1); | 100 | fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1); |
89 | for (y = y2; y < y3; y++) | 101 | for (y = y2; y < y3; y++) |
90 | { | 102 | { |
91 | _xlcd_rb->lcd_hline(fp_x1 >> 16, fp_x2 >> 16, y); | 103 | display->hline(fp_x1 >> 16, fp_x2 >> 16, y); |
92 | fp_x1 += fp_dx1; | 104 | fp_x1 += fp_dx1; |
93 | fp_x2 += fp_dx2; | 105 | fp_x2 += fp_dx2; |
94 | } | 106 | } |
95 | } | 107 | } |
96 | } | 108 | } |
97 | } | 109 | } |
98 | #else /* (LCD_DEPTH < 8) && (LCD_PIXELFORMAT == VERTICAL_PACKING) */ | 110 | |
99 | /* draw a filled triangle, using vertical lines for speed */ | 111 | /* draw a filled triangle, using vertical lines for speed */ |
100 | void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) | 112 | void xlcd_filltriangle_vertical(struct screen* display, |
113 | int x1, int y1, | ||
114 | int x2, int y2, | ||
115 | int x3, int y3) | ||
101 | { | 116 | { |
102 | int x, y; | ||
103 | long fp_y1, fp_y2, fp_dy1, fp_dy2; | 117 | long fp_y1, fp_y2, fp_dy1, fp_dy2; |
104 | 118 | int x; | |
105 | /* sort vertices by increasing x value */ | 119 | sort_points_by_increasing_x(&x1, &y1, &x2, &y2, &x3, &y3); |
106 | if (x1 > x3) | ||
107 | { | ||
108 | if (x2 < x3) /* x2 < x3 < x1 */ | ||
109 | { | ||
110 | x = x1; x1 = x2; x2 = x3; x3 = x; | ||
111 | y = y1; y1 = y2; y2 = y3; y3 = y; | ||
112 | } | ||
113 | else if (x2 > x1) /* x3 < x1 < x2 */ | ||
114 | { | ||
115 | x = x1; x1 = x3; x3 = x2; x2 = x; | ||
116 | y = y1; y1 = y3; y3 = y2; y2 = y; | ||
117 | } | ||
118 | else /* x3 <= x2 <= x1 */ | ||
119 | { | ||
120 | x = x1; x1 = x3; x3 = x; | ||
121 | y = y1; y1 = y3; y3 = y; | ||
122 | } | ||
123 | } | ||
124 | else | ||
125 | { | ||
126 | if (x2 < x1) /* x2 < x1 <= x3 */ | ||
127 | { | ||
128 | x = x1; x1 = x2; x2 = x; | ||
129 | y = y1; y1 = y2; y2 = y; | ||
130 | } | ||
131 | else if (x2 > x3) /* x1 <= x3 < x2 */ | ||
132 | { | ||
133 | x = x2; x2 = x3; x3 = x; | ||
134 | y = y2; y2 = y3; y3 = y; | ||
135 | } | ||
136 | /* else already sorted */ | ||
137 | } | ||
138 | 120 | ||
139 | if (x1 < x3) /* draw */ | 121 | if (x1 < x3) /* draw */ |
140 | { | 122 | { |
@@ -142,12 +124,12 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) | |||
142 | fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1); | 124 | fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1); |
143 | 125 | ||
144 | if (x1 < x2) /* first part */ | 126 | if (x1 < x2) /* first part */ |
145 | { | 127 | { |
146 | fp_dy2 = ((y2 - y1) << 16) / (x2 - x1); | 128 | fp_dy2 = ((y2 - y1) << 16) / (x2 - x1); |
147 | fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1); | 129 | fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1); |
148 | for (x = x1; x < x2; x++) | 130 | for (x = x1; x < x2; x++) |
149 | { | 131 | { |
150 | _xlcd_rb->lcd_vline(x, fp_y1 >> 16, fp_y2 >> 16); | 132 | display->vline(x, fp_y1 >> 16, fp_y2 >> 16); |
151 | fp_y1 += fp_dy1; | 133 | fp_y1 += fp_dy1; |
152 | fp_y2 += fp_dy2; | 134 | fp_y2 += fp_dy2; |
153 | } | 135 | } |
@@ -158,14 +140,33 @@ void xlcd_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) | |||
158 | fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1); | 140 | fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1); |
159 | for (x = x2; x < x3; x++) | 141 | for (x = x2; x < x3; x++) |
160 | { | 142 | { |
161 | _xlcd_rb->lcd_vline(x, fp_y1 >> 16, fp_y2 >> 16); | 143 | display->vline(x, fp_y1 >> 16, fp_y2 >> 16); |
162 | fp_y1 += fp_dy1; | 144 | fp_y1 += fp_dy1; |
163 | fp_y2 += fp_dy2; | 145 | fp_y2 += fp_dy2; |
164 | } | 146 | } |
165 | } | 147 | } |
166 | } | 148 | } |
167 | } | 149 | } |
168 | #endif /* LCD_DEPTH, LCD_PIXELFORMAT */ | 150 | |
151 | void xlcd_filltriangle(int x1, int y1, | ||
152 | int x2, int y2, | ||
153 | int x3, int y3) | ||
154 | { | ||
155 | /* default is main screen */ | ||
156 | xlcd_filltriangle_screen(_xlcd_rb->screens[SCREEN_MAIN], | ||
157 | x1, y1, x2, y2, x3, y3); | ||
158 | } | ||
159 | |||
160 | void xlcd_filltriangle_screen(struct screen* display, | ||
161 | int x1, int y1, | ||
162 | int x2, int y2, | ||
163 | int x3, int y3) | ||
164 | { | ||
165 | if(display->pixel_format==HORIZONTAL_PACKING || display->depth>=8) | ||
166 | xlcd_filltriangle_horizontal(display, x1, y1, x2, y2, x3, y3); | ||
167 | else | ||
168 | xlcd_filltriangle_vertical(display, x1, y1, x2, y2, x3, y3); | ||
169 | } | ||
169 | 170 | ||
170 | #if LCD_DEPTH >= 8 | 171 | #if LCD_DEPTH >= 8 |
171 | 172 | ||