Fix the pitch detector plugin for iaudioM3
[kugel-rb.git] / apps / plugins / cube.c
blob1c072a2edd14f247d2d692da3e0f2c672bd47ca8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Damien Teney
11 * modified to use int instead of float math by Andreas Zwirtes
12 * heavily extended by Jens Arnold
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ***************************************************************************/
23 #include "plugin.h"
24 #include "lib/grey.h"
25 #include "lib/playergfx.h"
26 #include "lib/xlcd.h"
27 #include "lib/fixedpoint.h"
29 PLUGIN_HEADER
31 /* Loops that the values are displayed */
32 #define DISP_TIME 30
34 /* variable button definitions */
35 #if CONFIG_KEYPAD == RECORDER_PAD
36 #define CUBE_QUIT BUTTON_OFF
37 #define CUBE_NEXT BUTTON_RIGHT
38 #define CUBE_PREV BUTTON_LEFT
39 #define CUBE_INC BUTTON_UP
40 #define CUBE_DEC BUTTON_DOWN
41 #define CUBE_MODE BUTTON_F1
42 #define CUBE_PAUSE BUTTON_PLAY
43 #define CUBE_HIGHSPEED BUTTON_ON
45 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
46 #define CUBE_QUIT BUTTON_OFF
47 #define CUBE_NEXT BUTTON_RIGHT
48 #define CUBE_PREV BUTTON_LEFT
49 #define CUBE_INC BUTTON_UP
50 #define CUBE_DEC BUTTON_DOWN
51 #define CUBE_MODE BUTTON_F1
52 #define CUBE_PAUSE BUTTON_SELECT
53 #define CUBE_HIGHSPEED BUTTON_ON
55 #elif CONFIG_KEYPAD == PLAYER_PAD
56 #define CUBE_QUIT BUTTON_STOP
57 #define CUBE_INC BUTTON_RIGHT
58 #define CUBE_DEC BUTTON_LEFT
59 #define CUBE_NEXT (BUTTON_ON | BUTTON_RIGHT)
60 #define CUBE_PREV (BUTTON_ON | BUTTON_LEFT)
61 #define CUBE_MODE BUTTON_MENU
62 #define CUBE_PAUSE BUTTON_PLAY
63 #define CUBE_HIGHSPEED_PRE BUTTON_ON
64 #define CUBE_HIGHSPEED (BUTTON_ON | BUTTON_REL)
66 #elif CONFIG_KEYPAD == ONDIO_PAD
67 #define CUBE_QUIT BUTTON_OFF
68 #define CUBE_NEXT BUTTON_RIGHT
69 #define CUBE_PREV BUTTON_LEFT
70 #define CUBE_INC BUTTON_UP
71 #define CUBE_DEC BUTTON_DOWN
72 #define CUBE_MODE_PRE BUTTON_MENU
73 #define CUBE_MODE (BUTTON_MENU | BUTTON_REL)
74 #define CUBE_PAUSE (BUTTON_MENU | BUTTON_LEFT)
75 #define CUBE_HIGHSPEED (BUTTON_MENU | BUTTON_RIGHT)
77 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
78 (CONFIG_KEYPAD == IRIVER_H300_PAD)
79 #define CUBE_QUIT BUTTON_OFF
80 #define CUBE_NEXT BUTTON_RIGHT
81 #define CUBE_PREV BUTTON_LEFT
82 #define CUBE_INC BUTTON_UP
83 #define CUBE_DEC BUTTON_DOWN
84 #define CUBE_MODE BUTTON_MODE
85 #define CUBE_PAUSE BUTTON_ON
86 #define CUBE_HIGHSPEED BUTTON_SELECT
88 #define CUBE_RC_QUIT BUTTON_RC_STOP
90 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
91 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
92 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
93 #define CUBE_QUIT (BUTTON_SELECT | BUTTON_MENU)
94 #define CUBE_NEXT BUTTON_RIGHT
95 #define CUBE_PREV BUTTON_LEFT
96 #define CUBE_INC BUTTON_SCROLL_FWD
97 #define CUBE_DEC BUTTON_SCROLL_BACK
98 #define CUBE_MODE BUTTON_MENU
99 #define CUBE_PAUSE BUTTON_PLAY
100 #define CUBE_HIGHSPEED_PRE BUTTON_SELECT
101 #define CUBE_HIGHSPEED (BUTTON_SELECT | BUTTON_REL)
103 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
104 #define CUBE_QUIT BUTTON_PLAY
105 #define CUBE_NEXT BUTTON_RIGHT
106 #define CUBE_PREV BUTTON_LEFT
107 #define CUBE_INC BUTTON_UP
108 #define CUBE_DEC BUTTON_DOWN
109 #define CUBE_MODE BUTTON_MODE
110 #define CUBE_PAUSE BUTTON_SELECT
111 #define CUBE_HIGHSPEED BUTTON_EQ
113 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
114 #define CUBE_QUIT BUTTON_POWER
115 #define CUBE_NEXT BUTTON_RIGHT
116 #define CUBE_PREV BUTTON_LEFT
117 #define CUBE_INC BUTTON_UP
118 #define CUBE_DEC BUTTON_DOWN
119 #define CUBE_MODE BUTTON_REC
120 #define CUBE_PAUSE BUTTON_PLAY
121 #define CUBE_HIGHSPEED BUTTON_SELECT
123 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
124 #define CUBE_QUIT BUTTON_POWER
125 #define CUBE_NEXT BUTTON_RIGHT
126 #define CUBE_PREV BUTTON_LEFT
127 #define CUBE_INC BUTTON_UP
128 #define CUBE_DEC BUTTON_DOWN
129 #define CUBE_MODE BUTTON_MENU
130 #define CUBE_PAUSE BUTTON_SELECT
131 #define CUBE_HIGHSPEED BUTTON_A
133 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
134 #define CUBE_QUIT BUTTON_POWER
135 #define CUBE_NEXT BUTTON_RIGHT
136 #define CUBE_PREV BUTTON_LEFT
137 #define CUBE_INC BUTTON_SCROLL_FWD
138 #define CUBE_DEC BUTTON_SCROLL_BACK
139 #define CUBE_MODE BUTTON_DOWN
140 #define CUBE_PAUSE BUTTON_UP
141 #define CUBE_HIGHSPEED BUTTON_SELECT
143 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
144 #define CUBE_QUIT (BUTTON_HOME|BUTTON_REPEAT)
145 #define CUBE_NEXT BUTTON_RIGHT
146 #define CUBE_PREV BUTTON_LEFT
147 #define CUBE_INC BUTTON_SCROLL_FWD
148 #define CUBE_DEC BUTTON_SCROLL_BACK
149 #define CUBE_MODE BUTTON_DOWN
150 #define CUBE_PAUSE BUTTON_UP
151 #define CUBE_HIGHSPEED BUTTON_SELECT
153 #elif (CONFIG_KEYPAD == SANSA_C200_PAD) || \
154 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
155 (CONFIG_KEYPAD == SANSA_M200_PAD)
156 #define CUBE_QUIT BUTTON_POWER
157 #define CUBE_NEXT BUTTON_RIGHT
158 #define CUBE_PREV BUTTON_LEFT
159 #define CUBE_INC BUTTON_VOL_UP
160 #define CUBE_DEC BUTTON_VOL_DOWN
161 #define CUBE_MODE BUTTON_DOWN
162 #define CUBE_PAUSE BUTTON_UP
163 #define CUBE_HIGHSPEED BUTTON_SELECT
166 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
167 #define CUBE_QUIT BUTTON_POWER
168 #define CUBE_NEXT BUTTON_RIGHT
169 #define CUBE_PREV BUTTON_LEFT
170 #define CUBE_INC BUTTON_SCROLL_UP
171 #define CUBE_DEC BUTTON_SCROLL_DOWN
172 #define CUBE_MODE BUTTON_REW
173 #define CUBE_PAUSE BUTTON_PLAY
174 #define CUBE_HIGHSPEED BUTTON_FF
176 #elif CONFIG_KEYPAD == MROBE500_PAD
177 #define CUBE_QUIT BUTTON_POWER
179 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
180 #define CUBE_QUIT BUTTON_BACK
181 #define CUBE_NEXT BUTTON_RIGHT
182 #define CUBE_PREV BUTTON_LEFT
183 #define CUBE_INC BUTTON_UP
184 #define CUBE_DEC BUTTON_DOWN
185 #define CUBE_MODE BUTTON_MENU
186 #define CUBE_PAUSE BUTTON_PLAY
187 #define CUBE_HIGHSPEED BUTTON_SELECT
189 #elif (CONFIG_KEYPAD == MROBE100_PAD)
190 #define CUBE_QUIT BUTTON_POWER
191 #define CUBE_NEXT BUTTON_RIGHT
192 #define CUBE_PREV BUTTON_LEFT
193 #define CUBE_INC BUTTON_UP
194 #define CUBE_DEC BUTTON_DOWN
195 #define CUBE_MODE BUTTON_MENU
196 #define CUBE_PAUSE BUTTON_PLAY
197 #define CUBE_HIGHSPEED BUTTON_SELECT
199 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
200 #define CUBE_QUIT BUTTON_RC_REC
201 #define CUBE_NEXT BUTTON_RC_FF
202 #define CUBE_PREV BUTTON_RC_REW
203 #define CUBE_INC BUTTON_RC_VOL_UP
204 #define CUBE_DEC BUTTON_RC_VOL_DOWN
205 #define CUBE_MODE BUTTON_RC_MODE
206 #define CUBE_PAUSE BUTTON_RC_PLAY
207 #define CUBE_HIGHSPEED BUTTON_RC_MENU
209 #elif CONFIG_KEYPAD == COWOND2_PAD
210 #define CUBE_QUIT BUTTON_POWER
212 #elif (CONFIG_KEYPAD == IAUDIO67_PAD)
213 #define CUBE_QUIT BUTTON_POWER
214 #define CUBE_NEXT BUTTON_RIGHT
215 #define CUBE_PREV BUTTON_LEFT
216 #define CUBE_INC BUTTON_VOLUP
217 #define CUBE_DEC BUTTON_VOLDOWN
218 #define CUBE_MODE BUTTON_MENU
219 #define CUBE_PAUSE BUTTON_PLAY
220 #define CUBE_HIGHSPEED BUTTON_STOP
222 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
223 #define CUBE_QUIT BUTTON_BACK
224 #define CUBE_NEXT BUTTON_RIGHT
225 #define CUBE_PREV BUTTON_LEFT
226 #define CUBE_INC BUTTON_UP
227 #define CUBE_DEC BUTTON_DOWN
228 #define CUBE_MODE BUTTON_MENU
229 #define CUBE_PAUSE BUTTON_PLAY
230 #define CUBE_HIGHSPEED BUTTON_SELECT
232 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
233 #define CUBE_QUIT BUTTON_POWER
234 #define CUBE_NEXT BUTTON_RIGHT
235 #define CUBE_PREV BUTTON_LEFT
236 #define CUBE_INC BUTTON_UP
237 #define CUBE_DEC BUTTON_DOWN
238 #define CUBE_MODE BUTTON_MENU
239 #define CUBE_PAUSE BUTTON_SELECT
240 #define CUBE_HIGHSPEED BUTTON_VIEW
242 #elif CONFIG_KEYPAD == ONDAVX747_PAD
243 #define CUBE_QUIT BUTTON_POWER
244 #elif CONFIG_KEYPAD == ONDAVX777_PAD
245 #define CUBE_QUIT BUTTON_POWER
247 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
248 #define CUBE_QUIT BUTTON_REC
249 #define CUBE_NEXT BUTTON_RIGHT
250 #define CUBE_PREV BUTTON_LEFT
251 #define CUBE_INC BUTTON_UP
252 #define CUBE_DEC BUTTON_DOWN
253 #define CUBE_MODE BUTTON_REW
254 #define CUBE_PAUSE BUTTON_PLAY
255 #define CUBE_HIGHSPEED BUTTON_FFWD
258 #else
259 #error No keymap defined!
260 #endif
262 #ifdef HAVE_TOUCHSCREEN
263 #ifndef CUBE_QUIT
264 #define CUBE_QUIT BUTTON_TOPLEFT
265 #endif
266 #ifndef CUBE_NEXT
267 #define CUBE_NEXT BUTTON_MIDRIGHT
268 #endif
269 #ifndef CUBE_PREV
270 #define CUBE_PREV BUTTON_MIDLEFT
271 #endif
272 #ifndef CUBE_INC
273 #define CUBE_INC BUTTON_TOPMIDDLE
274 #endif
275 #ifndef CUBE_DEC
276 #define CUBE_DEC BUTTON_BOTTOMMIDDLE
277 #endif
278 #ifndef CUBE_MODE
279 #define CUBE_MODE BUTTON_TOPRIGHT
280 #endif
281 #ifndef CUBE_PAUSE
282 #define CUBE_PAUSE BUTTON_CENTER
283 #endif
284 #ifndef CUBE_HIGHSPEED
285 #define CUBE_HIGHSPEED BUTTON_BOTTOMRIGHT
286 #endif
287 #endif
290 #ifdef HAVE_LCD_BITMAP
292 #define DIST (10 * MIN(LCD_HEIGHT, LCD_WIDTH) / 16)
293 static int x_off = LCD_WIDTH/2;
294 static int y_off = LCD_HEIGHT/2;
296 #if LCD_DEPTH == 1
297 #define USE_GSLIB
298 GREY_INFO_STRUCT
299 struct my_lcd {
300 void (*update)(void);
301 void (*clear_display)(void);
302 void (*drawline)(int x1, int y1, int x2, int y2);
303 void (*putsxy)(int x, int y, const unsigned char *string);
306 static struct my_lcd greyfuncs = {
307 grey_update, grey_clear_display, grey_drawline, grey_putsxy
309 static struct my_lcd lcdfuncs; /* initialised at runtime */
310 static struct my_lcd *mylcd = &greyfuncs;
312 #define MYLCD(fn) mylcd->fn
313 #define MY_FILLTRIANGLE(x1, y1, x2, y2, x3, y3) grey_filltriangle(x1, y1, x2, y2, x3, y3)
314 #define MY_SET_FOREGROUND(fg) grey_set_foreground(fg)
315 #define MY_GET_FOREGROUND() grey_get_foreground()
317 #else
318 #define MYLCD(fn) rb->lcd_ ## fn
319 #define MY_FILLTRIANGLE(x1, y1, x2, y2, x3, y3) xlcd_filltriangle(x1, y1, x2, y2, x3, y3)
320 #define MY_SET_FOREGROUND(fg) rb->lcd_set_foreground(fg)
321 #define MY_GET_FOREGROUND() rb->lcd_get_foreground()
322 #endif
324 #if CONFIG_LCD == LCD_SSD1815
325 #define ASPECT 320 /* = 1.25 (fixed point 24.8) */
326 #else
327 #define ASPECT 256 /* = 1.00 */
328 #endif
330 #else /* !LCD_BITMAP */
332 #define MYLCD(fn) pgfx_ ## fn
333 #define DIST 9
334 static int x_off = 10;
335 static int y_off = 7;
336 #define ASPECT 300 /* = 1.175 */
338 #endif /* !LCD_BITMAP */
340 struct point_3D {
341 long x, y, z;
344 struct point_2D {
345 long x, y;
348 struct line {
349 int start, end;
352 struct face {
353 int corner[4];
354 int line[4];
357 /* initial, unrotated cube corners */
358 static const struct point_3D sommet[8] =
360 {-DIST, -DIST, -DIST},
361 { DIST, -DIST, -DIST},
362 { DIST, DIST, -DIST},
363 {-DIST, DIST, -DIST},
364 {-DIST, -DIST, DIST},
365 { DIST, -DIST, DIST},
366 { DIST, DIST, DIST},
367 {-DIST, DIST, DIST}
370 /* The 12 lines forming the edges */
371 static const struct line lines[12] =
373 {0, 1}, {1, 2}, {2, 3}, {3, 0},
374 {4, 7}, {7, 6}, {6, 5}, {5, 4},
375 {0, 4}, {1, 5}, {2, 6}, {3, 7}
378 static bool lines_drawn[12];
380 /* The 6 faces of the cube; points are in clockwise order when viewed
381 from the outside */
382 static const struct face faces[6] =
384 {{0, 1, 2, 3}, {0, 1, 2, 3}},
385 {{4, 7, 6, 5}, {4, 5, 6, 7}},
386 {{0, 4, 5, 1}, {8, 7, 9, 0}},
387 {{2, 6, 7, 3}, {10, 5, 11, 2}},
388 {{0, 3, 7, 4}, {3, 11, 4, 8}},
389 {{1, 5, 6, 2}, {9, 6, 10, 1}}
392 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
393 static const unsigned face_colors[6] =
395 #ifdef HAVE_LCD_COLOR
396 LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(0, 255, 0),
397 LCD_RGBPACK(0, 255, 0), LCD_RGBPACK(0, 0, 255), LCD_RGBPACK(0, 0, 255)
398 #elif defined(USE_GSLIB)
399 #ifdef MROBE_100
400 GREY_LIGHTGRAY, GREY_LIGHTGRAY, GREY_DARKGRAY,
401 GREY_DARKGRAY, GREY_WHITE, GREY_WHITE
402 #else
403 GREY_LIGHTGRAY, GREY_LIGHTGRAY, GREY_DARKGRAY,
404 GREY_DARKGRAY, GREY_BLACK, GREY_BLACK
405 #endif
406 #else
407 LCD_LIGHTGRAY, LCD_LIGHTGRAY, LCD_DARKGRAY,
408 LCD_DARKGRAY, LCD_BLACK, LCD_BLACK
409 #endif
411 #endif
413 enum {
414 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
415 SOLID,
416 #endif
417 HIDDEN_LINES,
418 WIREFRAME,
419 NUM_MODES
422 static int mode = 0;
424 struct counter {
425 const char *label;
426 short speed;
427 short angle;
430 static struct counter axes[] = {
431 {"x-axis", 1, 0},
432 {"y-axis", 3, 0},
433 {"z-axis", 2, 0}
436 static struct point_3D point3D[8];
437 static struct point_2D point2D[8];
438 static long matrice[3][3];
440 static const int nb_points = 8;
441 static long z_off = 600;
443 static void cube_rotate(int xa, int ya, int za)
445 int i;
446 /* Just to prevent unnecessary lookups */
447 long sxa, cxa, sya, cya, sza, cza;
449 sxa = fp14_sin(xa);
450 cxa = fp14_cos(xa);
451 sya = fp14_sin(ya);
452 cya = fp14_cos(ya);
453 sza = fp14_sin(za);
454 cza = fp14_cos(za);
456 /* calculate overall translation matrix */
457 matrice[0][0] = (cza * cya) >> 14;
458 matrice[1][0] = (sza * cya) >> 14;
459 matrice[2][0] = -sya;
461 matrice[0][1] = (((cza * sya) >> 14) * sxa - sza * cxa) >> 14;
462 matrice[1][1] = (((sza * sya) >> 14) * sxa + cxa * cza) >> 14;
463 matrice[2][1] = (sxa * cya) >> 14;
465 matrice[0][2] = (((cza * sya) >> 14) * cxa + sza * sxa) >> 14;
466 matrice[1][2] = (((sza * sya) >> 14) * cxa - cza * sxa) >> 14;
467 matrice[2][2] = (cxa * cya) >> 14;
469 /* apply translation matrix to all points */
470 for (i = 0; i < nb_points; i++)
472 point3D[i].x = matrice[0][0] * sommet[i].x + matrice[1][0] * sommet[i].y
473 + matrice[2][0] * sommet[i].z;
475 point3D[i].y = matrice[0][1] * sommet[i].x + matrice[1][1] * sommet[i].y
476 + matrice[2][1] * sommet[i].z;
478 point3D[i].z = matrice[0][2] * sommet[i].x + matrice[1][2] * sommet[i].y
479 + matrice[2][2] * sommet[i].z;
483 static void cube_viewport(void)
485 int i;
487 /* Do viewport transformation for all points */
488 for (i = 0; i < nb_points; i++)
490 #if ASPECT != 256
491 point2D[i].x = (point3D[i].x * ASPECT) / (point3D[i].z + (z_off << 14))
492 + x_off;
493 #else
494 point2D[i].x = (point3D[i].x << 8) / (point3D[i].z + (z_off << 14))
495 + x_off;
496 #endif
497 point2D[i].y = (point3D[i].y << 8) / (point3D[i].z + (z_off << 14))
498 + y_off;
502 static void cube_draw(void)
504 int i, j, line;
505 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
506 unsigned old_foreground;
507 #endif
509 switch (mode)
511 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
512 case SOLID:
514 old_foreground = MY_GET_FOREGROUND();
515 for (i = 0; i < 6; i++)
517 /* backface culling; if the shape winds counter-clockwise, we are
518 * looking at the backface, and the (simplified) cross product
519 * is < 0. Do not draw it. */
520 if (0 >= (point2D[faces[i].corner[1]].x - point2D[faces[i].corner[0]].x)
521 * (point2D[faces[i].corner[2]].y - point2D[faces[i].corner[1]].y)
522 - (point2D[faces[i].corner[1]].y - point2D[faces[i].corner[0]].y)
523 * (point2D[faces[i].corner[2]].x - point2D[faces[i].corner[1]].x))
524 continue;
526 MY_SET_FOREGROUND(face_colors[i]);
527 MY_FILLTRIANGLE(point2D[faces[i].corner[0]].x,
528 point2D[faces[i].corner[0]].y,
529 point2D[faces[i].corner[1]].x,
530 point2D[faces[i].corner[1]].y,
531 point2D[faces[i].corner[2]].x,
532 point2D[faces[i].corner[2]].y);
533 MY_FILLTRIANGLE(point2D[faces[i].corner[0]].x,
534 point2D[faces[i].corner[0]].y,
535 point2D[faces[i].corner[2]].x,
536 point2D[faces[i].corner[2]].y,
537 point2D[faces[i].corner[3]].x,
538 point2D[faces[i].corner[3]].y);
541 MY_SET_FOREGROUND(old_foreground);
542 break;
543 #endif /* (LCD_DEPTH > 1) || GSLIB */
545 case HIDDEN_LINES:
547 rb->memset(lines_drawn, 0, sizeof(lines_drawn));
548 for (i = 0; i < 6; i++)
550 /* backface culling; if the shape winds counter-clockwise, we are
551 * looking at the backface, and the (simplified) cross product
552 * is < 0. Do not draw it. */
553 if (0 >= (point2D[faces[i].corner[1]].x - point2D[faces[i].corner[0]].x)
554 * (point2D[faces[i].corner[2]].y - point2D[faces[i].corner[1]].y)
555 - (point2D[faces[i].corner[1]].y - point2D[faces[i].corner[0]].y)
556 * (point2D[faces[i].corner[2]].x - point2D[faces[i].corner[1]].x))
557 continue;
559 for (j = 0; j < 4; j++)
561 line = faces[i].line[j];
562 if (!lines_drawn[line])
564 lines_drawn[line] = true;
565 MYLCD(drawline)(point2D[lines[line].start].x,
566 point2D[lines[line].start].y,
567 point2D[lines[line].end].x,
568 point2D[lines[line].end].y);
572 break;
574 case WIREFRAME:
576 for (i = 0; i < 12; i++)
577 MYLCD(drawline)(point2D[lines[i].start].x,
578 point2D[lines[i].start].y,
579 point2D[lines[i].end].x,
580 point2D[lines[i].end].y);
581 break;
585 void cleanup(void *parameter)
587 (void)parameter;
589 #ifdef USE_GSLIB
590 grey_release();
591 #elif defined HAVE_LCD_CHARCELLS
592 pgfx_release();
593 #endif
596 enum plugin_status plugin_start(const void* parameter)
598 char buffer[30];
599 int t_disp = 0;
600 #ifdef USE_GSLIB
601 unsigned char *gbuf;
602 size_t gbuf_size = 0;
603 bool mode_switch = true;
604 #endif
606 int button;
607 int lastbutton = BUTTON_NONE;
608 int curr = 0;
609 bool highspeed = false;
610 bool paused = false;
611 bool redraw = true;
612 bool exit = false;
614 (void)(parameter);
616 #ifdef HAVE_LCD_BITMAP
617 #if defined(USE_GSLIB)
618 gbuf = (unsigned char *)rb->plugin_get_buffer(&gbuf_size);
619 if (!grey_init(gbuf, gbuf_size, GREY_BUFFERED,
620 LCD_WIDTH, LCD_HEIGHT, NULL))
622 rb->splash(HZ, "Couldn't init greyscale display");
623 return PLUGIN_ERROR;
625 /* init lcd_ function pointers */
626 lcdfuncs.update = rb->lcd_update;
627 lcdfuncs.clear_display = rb->lcd_clear_display;
628 lcdfuncs.drawline = rb->lcd_drawline;
629 lcdfuncs.putsxy = rb->lcd_putsxy;
631 #ifdef MROBE_100
632 grey_set_background(GREY_BLACK);
633 #endif
635 grey_setfont(FONT_SYSFIXED);
636 #endif
637 rb->lcd_setfont(FONT_SYSFIXED);
638 #else /* LCD_CHARCELLS */
639 if (!pgfx_init(4, 2))
641 rb->splash(HZ*2, "Old LCD :(");
642 return PLUGIN_OK;
644 pgfx_display(0, 0);
645 #endif
647 while(!exit)
649 if (redraw)
651 MYLCD(clear_display)();
652 cube_rotate(axes[0].angle, axes[1].angle, axes[2].angle);
653 cube_viewport();
654 cube_draw();
655 redraw = false;
658 #ifdef HAVE_LCD_BITMAP
659 if (t_disp > 0)
661 t_disp--;
662 rb->snprintf(buffer, sizeof(buffer), "%s: %d %s",
663 axes[curr].label,
664 paused ? axes[curr].angle : axes[curr].speed,
665 highspeed ? "(hs)" : "");
666 MYLCD(putsxy)(0, LCD_HEIGHT-8, buffer);
667 if (t_disp == 0)
668 redraw = true;
670 #else
671 if (t_disp > 0)
673 if (t_disp == DISP_TIME)
675 rb->lcd_puts(5, 0, axes[curr].label);
676 rb->snprintf(buffer, sizeof(buffer), "%d %c",
677 paused ? axes[curr].angle : axes[curr].speed,
678 highspeed ? 'H' : ' ');
679 rb->lcd_puts(5, 1, buffer);
681 t_disp--;
682 if (t_disp == 0)
684 rb->lcd_clear_display();
685 pgfx_display(0, 0);
688 #endif
689 #ifdef USE_GSLIB
690 if (mode_switch)
692 grey_show(mode == SOLID);
693 mode_switch = false;
695 #endif
696 MYLCD(update)();
698 if (!paused)
700 int i;
702 for (i = 0; i < 3; i++)
704 axes[i].angle += axes[i].speed;
705 if (axes[i].angle > 359)
706 axes[i].angle -= 360;
707 else if (axes[i].angle < 0)
708 axes[i].angle += 360;
710 redraw = true;
712 if (highspeed)
713 rb->yield();
714 else
715 rb->sleep(HZ/25);
716 button = rb->button_get(false);
718 else
720 button = rb->button_get_w_tmo(HZ/25);
723 switch (button)
725 case CUBE_INC:
726 case CUBE_INC|BUTTON_REPEAT:
727 if (!paused)
729 if (axes[curr].speed < 10)
730 axes[curr].speed++;
732 else
734 if (++axes[curr].angle > 359)
735 axes[curr].angle -= 360;
737 t_disp = DISP_TIME;
738 redraw = true;
739 break;
741 case CUBE_DEC:
742 case CUBE_DEC|BUTTON_REPEAT:
743 if (!paused)
745 if (axes[curr].speed > -10)
746 axes[curr].speed--;
748 else
750 if (--axes[curr].angle < 0)
751 axes[curr].angle += 360;
753 t_disp = DISP_TIME;
754 redraw = true;
755 break;
757 case CUBE_NEXT:
758 if (++curr > 2)
759 curr = 0;
760 t_disp = DISP_TIME;
761 break;
763 case CUBE_PREV:
764 if (--curr < 0)
765 curr = 2;
766 t_disp = DISP_TIME;
767 break;
769 case CUBE_MODE:
770 #ifdef CUBE_MODE_PRE
771 if (lastbutton != CUBE_MODE_PRE)
772 break;
773 #endif
774 if (++mode >= NUM_MODES)
775 mode = 0;
776 #ifdef USE_GSLIB
777 mylcd = (mode == SOLID) ? &greyfuncs : &lcdfuncs;
778 mode_switch = true;
779 #endif
780 redraw = true;
781 break;
783 case CUBE_PAUSE:
784 #ifdef CUBE_PAUSE_PRE
785 if (lastbutton != CUBE_PAUSE_PRE)
786 break;
787 #endif
788 paused = !paused;
789 break;
791 case CUBE_HIGHSPEED:
792 #ifdef CUBE_HIGHSPEED_PRE
793 if (lastbutton != CUBE_HIGHSPEED_PRE)
794 break;
795 #endif
796 highspeed = !highspeed;
797 t_disp = DISP_TIME;
798 break;
800 #ifdef CUBE_RC_QUIT
801 case CUBE_RC_QUIT:
802 #endif
803 case CUBE_QUIT:
804 exit = true;
805 break;
807 default:
808 if (rb->default_event_handler_ex(button, cleanup, NULL)
809 == SYS_USB_CONNECTED)
810 return PLUGIN_USB_CONNECTED;
811 break;
813 if (button != BUTTON_NONE)
814 lastbutton = button;
817 #ifdef USE_GSLIB
818 grey_release();
819 #elif defined(HAVE_LCD_CHARCELLS)
820 pgfx_release();
821 #endif
822 return PLUGIN_OK;