diff options
Diffstat (limited to 'apps/plugins/cube.c')
-rw-r--r-- | apps/plugins/cube.c | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/apps/plugins/cube.c b/apps/plugins/cube.c new file mode 100644 index 0000000000..996a1a81dd --- /dev/null +++ b/apps/plugins/cube.c | |||
@@ -0,0 +1,338 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Damien Teney | ||
11 | * modified to use int instead of float math by Andreas Zwirtes | ||
12 | * | ||
13 | * All files in this archive are subject to the GNU General Public License. | ||
14 | * See the file COPYING in the source tree root for full license agreement. | ||
15 | * | ||
16 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
17 | * KIND, either express or implied. | ||
18 | * | ||
19 | ***************************************************************************/ | ||
20 | #include "plugin.h" | ||
21 | |||
22 | #ifdef HAVE_LCD_BITMAP | ||
23 | |||
24 | /* Loops that the values are displayed */ | ||
25 | #define DISP_TIME 30 | ||
26 | |||
27 | struct point_3D { | ||
28 | long x, y, z; | ||
29 | }; | ||
30 | |||
31 | struct point_2D { | ||
32 | long x, y; | ||
33 | }; | ||
34 | |||
35 | static struct point_3D sommet[8]; | ||
36 | static struct point_3D point3D[8]; | ||
37 | static struct point_2D point2D[8]; | ||
38 | |||
39 | static long matrice[3][3]; | ||
40 | |||
41 | static int nb_points = 8; | ||
42 | |||
43 | static int x_off = 56; | ||
44 | static int y_off = 95; | ||
45 | static int z_off = 600; | ||
46 | |||
47 | /* Precalculated sine and cosine * 10000 (four digit fixed point math) */ | ||
48 | static int sin_table[91] = | ||
49 | { | ||
50 | 0, 174, 348, 523, 697, | ||
51 | 871,1045,1218,1391,1564, | ||
52 | 1736,1908,2079,2249,2419, | ||
53 | 2588,2756,2923,3090,3255, | ||
54 | 3420,3583,3746,3907,4067, | ||
55 | 4226,4383,4539,4694,4848, | ||
56 | 5000,5150,5299,5446,5591, | ||
57 | 5735,5877,6018,6156,6293, | ||
58 | 6427,6560,6691,6819,6946, | ||
59 | 7071,7193,7313,7431,7547, | ||
60 | 7660,7771,7880,7986,8090, | ||
61 | 8191,8290,8386,8480,8571, | ||
62 | 8660,8746,8829,8910,8987, | ||
63 | 9063,9135,9205,9271,9335, | ||
64 | 9396,9455,9510,9563,9612, | ||
65 | 9659,9702,9743,9781,9816, | ||
66 | 9848,9876,9902,9925,9945, | ||
67 | 9961,9975,9986,9993,9998, | ||
68 | 10000 | ||
69 | }; | ||
70 | |||
71 | static struct plugin_api* rb; | ||
72 | |||
73 | static long sin(int val) | ||
74 | { | ||
75 | /* Speed improvement through sukzessive lookup */ | ||
76 | if (val<181) | ||
77 | { | ||
78 | if (val<91) | ||
79 | { | ||
80 | /* phase 0-90 degree */ | ||
81 | return (long)sin_table[val]; | ||
82 | } | ||
83 | else | ||
84 | { | ||
85 | /* phase 91-180 degree */ | ||
86 | return (long)sin_table[180-val]; | ||
87 | } | ||
88 | } | ||
89 | else | ||
90 | { | ||
91 | if (val<271) | ||
92 | { | ||
93 | /* phase 181-270 degree */ | ||
94 | return (-1L)*(long)sin_table[val-180]; | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | /* phase 270-359 degree */ | ||
99 | return (-1L)*(long)sin_table[360-val]; | ||
100 | } | ||
101 | } | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static long cos(int val) | ||
106 | { | ||
107 | /* Speed improvement through sukzessive lookup */ | ||
108 | if (val<181) | ||
109 | { | ||
110 | if (val<91) | ||
111 | { | ||
112 | /* phase 0-90 degree */ | ||
113 | return (long)sin_table[90-val]; | ||
114 | } | ||
115 | else | ||
116 | { | ||
117 | /* phase 91-180 degree */ | ||
118 | return (-1L)*(long)sin_table[val-90]; | ||
119 | } | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | if (val<271) | ||
124 | { | ||
125 | /* phase 181-270 degree */ | ||
126 | return (-1L)*(long)sin_table[270-val]; | ||
127 | } | ||
128 | else | ||
129 | { | ||
130 | /* phase 270-359 degree */ | ||
131 | return (long)sin_table[val-270]; | ||
132 | } | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | |||
138 | static void cube_rotate(int xa, int ya, int za) | ||
139 | { | ||
140 | int i; | ||
141 | |||
142 | /* Just to prevent unnecessary lookups */ | ||
143 | long sxa,cxa,sya,cya,sza,cza; | ||
144 | sxa=sin(xa); | ||
145 | cxa=cos(xa); | ||
146 | sya=sin(ya); | ||
147 | cya=cos(ya); | ||
148 | sza=sin(za); | ||
149 | cza=cos(za); | ||
150 | |||
151 | /* calculate overall translation matrix */ | ||
152 | matrice[0][0] = cza*cya/10000L; | ||
153 | matrice[1][0] = sza*cya/10000L; | ||
154 | matrice[2][0] = -sya; | ||
155 | |||
156 | matrice[0][1] = cza*sya/10000L*sxa/10000L - sza*cxa/10000L; | ||
157 | matrice[1][1] = sza*sya/10000L*sxa/10000L + cxa*cza/10000L; | ||
158 | matrice[2][1] = sxa*cya/10000L; | ||
159 | |||
160 | matrice[0][2] = cza*sya/10000L*cxa/10000L + sza*sxa/10000L; | ||
161 | matrice[1][2] = sza*sya/10000L*cxa/10000L - cza*sxa/10000L; | ||
162 | matrice[2][2] = cxa*cya/10000L; | ||
163 | |||
164 | /* apply translation matrix to all points */ | ||
165 | for(i=0;i<nb_points;i++) | ||
166 | { | ||
167 | point3D[i].x = matrice[0][0]*sommet[i].x + matrice[1][0]*sommet[i].y | ||
168 | + matrice[2][0]*sommet[i].z; | ||
169 | |||
170 | point3D[i].y = matrice[0][1]*sommet[i].x + matrice[1][1]*sommet[i].y | ||
171 | + matrice[2][1]*sommet[i].z; | ||
172 | |||
173 | point3D[i].z = matrice[0][2]*sommet[i].x + matrice[1][2]*sommet[i].y | ||
174 | + matrice[2][2]*sommet[i].z; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | static void cube_viewport(void) | ||
179 | { | ||
180 | int i; | ||
181 | |||
182 | /* Do viewport transformation for all points */ | ||
183 | for(i=0;i<nb_points;i++) | ||
184 | { | ||
185 | point2D[i].x=(((point3D[i].x)<<8)/10000L)/ | ||
186 | (point3D[i].z/10000L+z_off)+x_off; | ||
187 | point2D[i].y=(((point3D[i].y)<<8)/10000L)/ | ||
188 | (point3D[i].z/10000L+z_off)+y_off; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | static void cube_init(void) | ||
193 | { | ||
194 | /* Original 3D-position of cube's corners */ | ||
195 | sommet[0].x = -40; sommet[0].y = -40; sommet[0].z = -40; | ||
196 | sommet[1].x = 40; sommet[1].y = -40; sommet[1].z = -40; | ||
197 | sommet[2].x = 40; sommet[2].y = 40; sommet[2].z = -40; | ||
198 | sommet[3].x = -40; sommet[3].y = 40; sommet[3].z = -40; | ||
199 | sommet[4].x = 40; sommet[4].y = -40; sommet[4].z = 40; | ||
200 | sommet[5].x = -40; sommet[5].y = -40; sommet[5].z = 40; | ||
201 | sommet[6].x = -40; sommet[6].y = 40; sommet[6].z = 40; | ||
202 | sommet[7].x = 40; sommet[7].y = 40; sommet[7].z = 40; | ||
203 | } | ||
204 | |||
205 | static void line(int a, int b) | ||
206 | { | ||
207 | rb->lcd_drawline(point2D[a].x, point2D[a].y, point2D[b].x, point2D[b].y); | ||
208 | } | ||
209 | |||
210 | static void cube_draw(void) | ||
211 | { | ||
212 | /* Draws front face */ | ||
213 | line(0,1); line(1,2); | ||
214 | line(2,3); line(3,0); | ||
215 | |||
216 | /* Draws rear face */ | ||
217 | line(4,5); line(5,6); | ||
218 | line(6,7); line(7,4); | ||
219 | |||
220 | /* Draws the other edges */ | ||
221 | line(0,5); | ||
222 | line(1,4); | ||
223 | line(2,7); | ||
224 | line(3,6); | ||
225 | } | ||
226 | |||
227 | |||
228 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
229 | { | ||
230 | int t_disp=0; | ||
231 | char buffer[30]; | ||
232 | |||
233 | int xa=0; | ||
234 | int ya=0; | ||
235 | int za=0; | ||
236 | int xs=1; | ||
237 | int ys=3; | ||
238 | int zs=1; | ||
239 | bool highspeed=0; | ||
240 | bool exit=0; | ||
241 | |||
242 | TEST_PLUGIN_API(api); | ||
243 | (void)(parameter); | ||
244 | rb = api; | ||
245 | |||
246 | rb->lcd_setfont(FONT_SYSFIXED); | ||
247 | |||
248 | cube_init(); | ||
249 | |||
250 | while(!exit) | ||
251 | { | ||
252 | if (!highspeed) | ||
253 | rb->sleep(4); | ||
254 | |||
255 | rb->lcd_clear_display(); | ||
256 | cube_rotate(xa,ya,za); | ||
257 | cube_viewport(); | ||
258 | cube_draw(); | ||
259 | if (t_disp>0) | ||
260 | { | ||
261 | t_disp--; | ||
262 | rb->snprintf(buffer, 30, "x:%d y:%d z:%d h:%d",xs,ys,zs,highspeed); | ||
263 | rb->lcd_putsxy(0, 56, buffer); | ||
264 | } | ||
265 | rb->lcd_update(); | ||
266 | |||
267 | xa+=xs; | ||
268 | if (xa>359) | ||
269 | xa-=360; | ||
270 | if (xa<0) | ||
271 | xa+=360; | ||
272 | ya+=ys; | ||
273 | if (ya>359) | ||
274 | ya-=360; | ||
275 | if (ya<0) | ||
276 | ya+=360; | ||
277 | za+=zs; | ||
278 | if (za>359) | ||
279 | za-=360; | ||
280 | if (za<0) | ||
281 | za+=360; | ||
282 | |||
283 | switch(rb->button_get(false)) | ||
284 | { | ||
285 | case BUTTON_RIGHT: | ||
286 | xs+=1; | ||
287 | if (xs>10) | ||
288 | xs=10; | ||
289 | t_disp=DISP_TIME; | ||
290 | break; | ||
291 | case BUTTON_LEFT: | ||
292 | xs-=1; | ||
293 | if (xs<-10) | ||
294 | xs=-10; | ||
295 | t_disp=DISP_TIME; | ||
296 | break; | ||
297 | case BUTTON_UP: | ||
298 | ys+=1; | ||
299 | if (ys>10) | ||
300 | ys=10; | ||
301 | t_disp=DISP_TIME; | ||
302 | break; | ||
303 | case BUTTON_DOWN: | ||
304 | ys-=1; | ||
305 | if (ys<-10) | ||
306 | ys=-10; | ||
307 | t_disp=DISP_TIME; | ||
308 | break; | ||
309 | case BUTTON_F2: | ||
310 | zs+=1; | ||
311 | if (zs>10) | ||
312 | zs=10; | ||
313 | t_disp=DISP_TIME; | ||
314 | break; | ||
315 | case BUTTON_F1: | ||
316 | zs-=1; | ||
317 | if (zs<-10) | ||
318 | zs=-10; | ||
319 | t_disp=DISP_TIME; | ||
320 | break; | ||
321 | case BUTTON_PLAY: | ||
322 | highspeed=!highspeed; | ||
323 | t_disp=DISP_TIME; | ||
324 | break; | ||
325 | case BUTTON_OFF|BUTTON_REL: | ||
326 | exit=1; | ||
327 | break; | ||
328 | |||
329 | case SYS_USB_CONNECTED: | ||
330 | rb->usb_screen(); | ||
331 | return PLUGIN_USB_CONNECTED; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | return PLUGIN_OK; | ||
336 | } | ||
337 | |||
338 | #endif | ||