Don't rebuild the dependency file on 'make reconf'. Build type and target won't chang...
[kugel-rb.git] / apps / plugins / cube.c
blob2ad25508da3edeed484477c65eae78c858302d50
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 (CONFIG_KEYPAD == SANSA_FUZE_PAD)
135 #define CUBE_QUIT BUTTON_POWER
136 #define CUBE_NEXT BUTTON_RIGHT
137 #define CUBE_PREV BUTTON_LEFT
138 #define CUBE_INC BUTTON_SCROLL_FWD
139 #define CUBE_DEC BUTTON_SCROLL_BACK
140 #define CUBE_MODE BUTTON_DOWN
141 #define CUBE_PAUSE BUTTON_UP
142 #define CUBE_HIGHSPEED BUTTON_SELECT
144 #elif (CONFIG_KEYPAD == SANSA_C200_PAD) || \
145 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
146 (CONFIG_KEYPAD == SANSA_M200_PAD)
147 #define CUBE_QUIT BUTTON_POWER
148 #define CUBE_NEXT BUTTON_RIGHT
149 #define CUBE_PREV BUTTON_LEFT
150 #define CUBE_INC BUTTON_VOL_UP
151 #define CUBE_DEC BUTTON_VOL_DOWN
152 #define CUBE_MODE BUTTON_DOWN
153 #define CUBE_PAUSE BUTTON_UP
154 #define CUBE_HIGHSPEED BUTTON_SELECT
157 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
158 #define CUBE_QUIT BUTTON_POWER
159 #define CUBE_NEXT BUTTON_RIGHT
160 #define CUBE_PREV BUTTON_LEFT
161 #define CUBE_INC BUTTON_SCROLL_UP
162 #define CUBE_DEC BUTTON_SCROLL_DOWN
163 #define CUBE_MODE BUTTON_REW
164 #define CUBE_PAUSE BUTTON_PLAY
165 #define CUBE_HIGHSPEED BUTTON_FF
167 #elif CONFIG_KEYPAD == MROBE500_PAD
168 #define CUBE_QUIT BUTTON_POWER
169 #define CUBE_NEXT BUTTON_RIGHT
170 #define CUBE_PREV BUTTON_LEFT
171 #define CUBE_INC BUTTON_RC_VOL_UP
172 #define CUBE_DEC BUTTON_RC_VOL_DOWN
173 #define CUBE_MODE BUTTON_RC_MODE
174 #define CUBE_PAUSE_PRE BUTTON_RC_HEART
175 #define CUBE_PAUSE (BUTTON_RC_HEART | BUTTON_REL)
176 #define CUBE_HIGHSPEED BUTTON_RC_HEART /* fixme: clashes with pause */
178 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
179 #define CUBE_QUIT BUTTON_BACK
180 #define CUBE_NEXT BUTTON_RIGHT
181 #define CUBE_PREV BUTTON_LEFT
182 #define CUBE_INC BUTTON_UP
183 #define CUBE_DEC BUTTON_DOWN
184 #define CUBE_MODE BUTTON_MENU
185 #define CUBE_PAUSE BUTTON_PLAY
186 #define CUBE_HIGHSPEED BUTTON_SELECT
188 #elif (CONFIG_KEYPAD == MROBE100_PAD)
189 #define CUBE_QUIT BUTTON_POWER
190 #define CUBE_NEXT BUTTON_RIGHT
191 #define CUBE_PREV BUTTON_LEFT
192 #define CUBE_INC BUTTON_UP
193 #define CUBE_DEC BUTTON_DOWN
194 #define CUBE_MODE BUTTON_MENU
195 #define CUBE_PAUSE BUTTON_PLAY
196 #define CUBE_HIGHSPEED BUTTON_SELECT
198 #elif (CONFIG_KEYPAD == IAUDIO_M3_PAD)
199 #define CUBE_QUIT BUTTON_RC_REC
200 #define CUBE_NEXT BUTTON_RC_FF
201 #define CUBE_PREV BUTTON_RC_REW
202 #define CUBE_INC BUTTON_RC_VOL_UP
203 #define CUBE_DEC BUTTON_RC_VOL_DOWN
204 #define CUBE_MODE BUTTON_RC_MODE
205 #define CUBE_PAUSE BUTTON_RC_PLAY
206 #define CUBE_HIGHSPEED BUTTON_RC_MENU
208 #elif CONFIG_KEYPAD == COWOND2_PAD
209 #define CUBE_QUIT BUTTON_POWER
211 #elif (CONFIG_KEYPAD == IAUDIO67_PAD)
212 #define CUBE_QUIT BUTTON_POWER
213 #define CUBE_NEXT BUTTON_RIGHT
214 #define CUBE_PREV BUTTON_LEFT
215 #define CUBE_INC BUTTON_VOLUP
216 #define CUBE_DEC BUTTON_VOLDOWN
217 #define CUBE_MODE BUTTON_MENU
218 #define CUBE_PAUSE BUTTON_PLAY
219 #define CUBE_HIGHSPEED BUTTON_STOP
221 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
222 #define CUBE_QUIT BUTTON_BACK
223 #define CUBE_NEXT BUTTON_RIGHT
224 #define CUBE_PREV BUTTON_LEFT
225 #define CUBE_INC BUTTON_UP
226 #define CUBE_DEC BUTTON_DOWN
227 #define CUBE_MODE BUTTON_MENU
228 #define CUBE_PAUSE BUTTON_PLAY
229 #define CUBE_HIGHSPEED BUTTON_SELECT
231 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
232 #define CUBE_QUIT BUTTON_POWER
233 #define CUBE_NEXT BUTTON_RIGHT
234 #define CUBE_PREV BUTTON_LEFT
235 #define CUBE_INC BUTTON_UP
236 #define CUBE_DEC BUTTON_DOWN
237 #define CUBE_MODE BUTTON_MENU
238 #define CUBE_PAUSE BUTTON_SELECT
239 #define CUBE_HIGHSPEED BUTTON_VIEW
240 #else
241 #error No keymap defined!
242 #endif
244 #ifdef HAVE_TOUCHSCREEN
245 #ifndef CUBE_QUIT
246 #define CUBE_QUIT BUTTON_TOPLEFT
247 #endif
248 #ifndef CUBE_NEXT
249 #define CUBE_NEXT BUTTON_MIDRIGHT
250 #endif
251 #ifndef CUBE_PREV
252 #define CUBE_PREV BUTTON_MIDLEFT
253 #endif
254 #ifndef CUBE_INC
255 #define CUBE_INC BUTTON_TOPMIDDLE
256 #endif
257 #ifndef CUBE_DEC
258 #define CUBE_DEC BUTTON_BOTTOMMIDDLE
259 #endif
260 #ifndef CUBE_MODE
261 #define CUBE_MODE BUTTON_TOPRIGHT
262 #endif
263 #ifndef CUBE_PAUSE
264 #define CUBE_PAUSE BUTTON_CENTER
265 #endif
266 #ifndef CUBE_HIGHSPEED
267 #define CUBE_HIGHSPEED BUTTON_BOTTOMRIGHT
268 #endif
269 #endif
272 #ifdef HAVE_LCD_BITMAP
274 #define DIST (10 * MIN(LCD_HEIGHT, LCD_WIDTH) / 16)
275 static int x_off = LCD_WIDTH/2;
276 static int y_off = LCD_HEIGHT/2;
278 #if LCD_DEPTH == 1
279 #define USE_GSLIB
280 GREY_INFO_STRUCT
281 struct my_lcd {
282 void (*update)(void);
283 void (*clear_display)(void);
284 void (*drawline)(int x1, int y1, int x2, int y2);
285 void (*putsxy)(int x, int y, const unsigned char *string);
288 static struct my_lcd greyfuncs = {
289 grey_update, grey_clear_display, grey_drawline, grey_putsxy
291 static struct my_lcd lcdfuncs; /* initialised at runtime */
292 static struct my_lcd *mylcd = &greyfuncs;
294 #define MYLCD(fn) mylcd->fn
295 #define MY_FILLTRIANGLE(x1, y1, x2, y2, x3, y3) grey_filltriangle(x1, y1, x2, y2, x3, y3)
296 #define MY_SET_FOREGROUND(fg) grey_set_foreground(fg)
297 #define MY_GET_FOREGROUND() grey_get_foreground()
299 #else
300 #define MYLCD(fn) rb->lcd_ ## fn
301 #define MY_FILLTRIANGLE(x1, y1, x2, y2, x3, y3) xlcd_filltriangle(x1, y1, x2, y2, x3, y3)
302 #define MY_SET_FOREGROUND(fg) rb->lcd_set_foreground(fg)
303 #define MY_GET_FOREGROUND() rb->lcd_get_foreground()
304 #endif
306 #if CONFIG_LCD == LCD_SSD1815
307 #define ASPECT 320 /* = 1.25 (fixed point 24.8) */
308 #else
309 #define ASPECT 256 /* = 1.00 */
310 #endif
312 #else /* !LCD_BITMAP */
314 #define MYLCD(fn) pgfx_ ## fn
315 #define DIST 9
316 static int x_off = 10;
317 static int y_off = 7;
318 #define ASPECT 300 /* = 1.175 */
320 #endif /* !LCD_BITMAP */
322 struct point_3D {
323 long x, y, z;
326 struct point_2D {
327 long x, y;
330 struct line {
331 int start, end;
334 struct face {
335 int corner[4];
336 int line[4];
339 /* initial, unrotated cube corners */
340 static const struct point_3D sommet[8] =
342 {-DIST, -DIST, -DIST},
343 { DIST, -DIST, -DIST},
344 { DIST, DIST, -DIST},
345 {-DIST, DIST, -DIST},
346 {-DIST, -DIST, DIST},
347 { DIST, -DIST, DIST},
348 { DIST, DIST, DIST},
349 {-DIST, DIST, DIST}
352 /* The 12 lines forming the edges */
353 static const struct line lines[12] =
355 {0, 1}, {1, 2}, {2, 3}, {3, 0},
356 {4, 7}, {7, 6}, {6, 5}, {5, 4},
357 {0, 4}, {1, 5}, {2, 6}, {3, 7}
360 static bool lines_drawn[12];
362 /* The 6 faces of the cube; points are in clockwise order when viewed
363 from the outside */
364 static const struct face faces[6] =
366 {{0, 1, 2, 3}, {0, 1, 2, 3}},
367 {{4, 7, 6, 5}, {4, 5, 6, 7}},
368 {{0, 4, 5, 1}, {8, 7, 9, 0}},
369 {{2, 6, 7, 3}, {10, 5, 11, 2}},
370 {{0, 3, 7, 4}, {3, 11, 4, 8}},
371 {{1, 5, 6, 2}, {9, 6, 10, 1}}
374 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
375 static const unsigned face_colors[6] =
377 #ifdef HAVE_LCD_COLOR
378 LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(0, 255, 0),
379 LCD_RGBPACK(0, 255, 0), LCD_RGBPACK(0, 0, 255), LCD_RGBPACK(0, 0, 255)
380 #elif defined(USE_GSLIB)
381 #ifdef MROBE_100
382 GREY_LIGHTGRAY, GREY_LIGHTGRAY, GREY_DARKGRAY,
383 GREY_DARKGRAY, GREY_WHITE, GREY_WHITE
384 #else
385 GREY_LIGHTGRAY, GREY_LIGHTGRAY, GREY_DARKGRAY,
386 GREY_DARKGRAY, GREY_BLACK, GREY_BLACK
387 #endif
388 #else
389 LCD_LIGHTGRAY, LCD_LIGHTGRAY, LCD_DARKGRAY,
390 LCD_DARKGRAY, LCD_BLACK, LCD_BLACK
391 #endif
393 #endif
395 enum {
396 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
397 SOLID,
398 #endif
399 HIDDEN_LINES,
400 WIREFRAME,
401 NUM_MODES
404 static int mode = 0;
406 struct counter {
407 const char *label;
408 short speed;
409 short angle;
412 static struct counter axes[] = {
413 {"x-axis", 1, 0},
414 {"y-axis", 3, 0},
415 {"z-axis", 2, 0}
418 static struct point_3D point3D[8];
419 static struct point_2D point2D[8];
420 static long matrice[3][3];
422 static const int nb_points = 8;
423 static long z_off = 600;
425 static void cube_rotate(int xa, int ya, int za)
427 int i;
428 /* Just to prevent unnecessary lookups */
429 long sxa, cxa, sya, cya, sza, cza;
431 sxa = sin_int(xa);
432 cxa = cos_int(xa);
433 sya = sin_int(ya);
434 cya = cos_int(ya);
435 sza = sin_int(za);
436 cza = cos_int(za);
438 /* calculate overall translation matrix */
439 matrice[0][0] = (cza * cya) >> 14;
440 matrice[1][0] = (sza * cya) >> 14;
441 matrice[2][0] = -sya;
443 matrice[0][1] = (((cza * sya) >> 14) * sxa - sza * cxa) >> 14;
444 matrice[1][1] = (((sza * sya) >> 14) * sxa + cxa * cza) >> 14;
445 matrice[2][1] = (sxa * cya) >> 14;
447 matrice[0][2] = (((cza * sya) >> 14) * cxa + sza * sxa) >> 14;
448 matrice[1][2] = (((sza * sya) >> 14) * cxa - cza * sxa) >> 14;
449 matrice[2][2] = (cxa * cya) >> 14;
451 /* apply translation matrix to all points */
452 for (i = 0; i < nb_points; i++)
454 point3D[i].x = matrice[0][0] * sommet[i].x + matrice[1][0] * sommet[i].y
455 + matrice[2][0] * sommet[i].z;
457 point3D[i].y = matrice[0][1] * sommet[i].x + matrice[1][1] * sommet[i].y
458 + matrice[2][1] * sommet[i].z;
460 point3D[i].z = matrice[0][2] * sommet[i].x + matrice[1][2] * sommet[i].y
461 + matrice[2][2] * sommet[i].z;
465 static void cube_viewport(void)
467 int i;
469 /* Do viewport transformation for all points */
470 for (i = 0; i < nb_points; i++)
472 #if ASPECT != 256
473 point2D[i].x = (point3D[i].x * ASPECT) / (point3D[i].z + (z_off << 14))
474 + x_off;
475 #else
476 point2D[i].x = (point3D[i].x << 8) / (point3D[i].z + (z_off << 14))
477 + x_off;
478 #endif
479 point2D[i].y = (point3D[i].y << 8) / (point3D[i].z + (z_off << 14))
480 + y_off;
484 static void cube_draw(void)
486 int i, j, line;
487 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
488 unsigned old_foreground;
489 #endif
491 switch (mode)
493 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
494 case SOLID:
496 old_foreground = MY_GET_FOREGROUND();
497 for (i = 0; i < 6; i++)
499 /* backface culling; if the shape winds counter-clockwise, we are
500 * looking at the backface, and the (simplified) cross product
501 * is < 0. Do not draw it. */
502 if (0 >= (point2D[faces[i].corner[1]].x - point2D[faces[i].corner[0]].x)
503 * (point2D[faces[i].corner[2]].y - point2D[faces[i].corner[1]].y)
504 - (point2D[faces[i].corner[1]].y - point2D[faces[i].corner[0]].y)
505 * (point2D[faces[i].corner[2]].x - point2D[faces[i].corner[1]].x))
506 continue;
508 MY_SET_FOREGROUND(face_colors[i]);
509 MY_FILLTRIANGLE(point2D[faces[i].corner[0]].x,
510 point2D[faces[i].corner[0]].y,
511 point2D[faces[i].corner[1]].x,
512 point2D[faces[i].corner[1]].y,
513 point2D[faces[i].corner[2]].x,
514 point2D[faces[i].corner[2]].y);
515 MY_FILLTRIANGLE(point2D[faces[i].corner[0]].x,
516 point2D[faces[i].corner[0]].y,
517 point2D[faces[i].corner[2]].x,
518 point2D[faces[i].corner[2]].y,
519 point2D[faces[i].corner[3]].x,
520 point2D[faces[i].corner[3]].y);
523 MY_SET_FOREGROUND(old_foreground);
524 break;
525 #endif /* (LCD_DEPTH > 1) || GSLIB */
527 case HIDDEN_LINES:
529 rb->memset(lines_drawn, 0, sizeof(lines_drawn));
530 for (i = 0; i < 6; i++)
532 /* backface culling; if the shape winds counter-clockwise, we are
533 * looking at the backface, and the (simplified) cross product
534 * is < 0. Do not draw it. */
535 if (0 >= (point2D[faces[i].corner[1]].x - point2D[faces[i].corner[0]].x)
536 * (point2D[faces[i].corner[2]].y - point2D[faces[i].corner[1]].y)
537 - (point2D[faces[i].corner[1]].y - point2D[faces[i].corner[0]].y)
538 * (point2D[faces[i].corner[2]].x - point2D[faces[i].corner[1]].x))
539 continue;
541 for (j = 0; j < 4; j++)
543 line = faces[i].line[j];
544 if (!lines_drawn[line])
546 lines_drawn[line] = true;
547 MYLCD(drawline)(point2D[lines[line].start].x,
548 point2D[lines[line].start].y,
549 point2D[lines[line].end].x,
550 point2D[lines[line].end].y);
554 break;
556 case WIREFRAME:
558 for (i = 0; i < 12; i++)
559 MYLCD(drawline)(point2D[lines[i].start].x,
560 point2D[lines[i].start].y,
561 point2D[lines[i].end].x,
562 point2D[lines[i].end].y);
563 break;
567 void cleanup(void *parameter)
569 (void)parameter;
571 #ifdef USE_GSLIB
572 grey_release();
573 #elif defined HAVE_LCD_CHARCELLS
574 pgfx_release();
575 #endif
578 enum plugin_status plugin_start(const void* parameter)
580 char buffer[30];
581 int t_disp = 0;
582 #ifdef USE_GSLIB
583 unsigned char *gbuf;
584 size_t gbuf_size = 0;
585 bool mode_switch = true;
586 #endif
588 int button;
589 int lastbutton = BUTTON_NONE;
590 int curr = 0;
591 bool highspeed = false;
592 bool paused = false;
593 bool redraw = true;
594 bool exit = false;
596 (void)(parameter);
598 #ifdef HAVE_LCD_BITMAP
599 #if defined(USE_GSLIB)
600 gbuf = (unsigned char *)rb->plugin_get_buffer(&gbuf_size);
601 if (!grey_init(gbuf, gbuf_size, GREY_BUFFERED,
602 LCD_WIDTH, LCD_HEIGHT, NULL))
604 rb->splash(HZ, "Couldn't init greyscale display");
605 return PLUGIN_ERROR;
607 /* init lcd_ function pointers */
608 lcdfuncs.update = rb->lcd_update;
609 lcdfuncs.clear_display = rb->lcd_clear_display;
610 lcdfuncs.drawline = rb->lcd_drawline;
611 lcdfuncs.putsxy = rb->lcd_putsxy;
613 #ifdef MROBE_100
614 grey_set_background(GREY_BLACK);
615 #endif
617 grey_setfont(FONT_SYSFIXED);
618 #endif
619 rb->lcd_setfont(FONT_SYSFIXED);
620 #else /* LCD_CHARCELLS */
621 if (!pgfx_init(4, 2))
623 rb->splash(HZ*2, "Old LCD :(");
624 return PLUGIN_OK;
626 pgfx_display(0, 0);
627 #endif
629 while(!exit)
631 if (redraw)
633 MYLCD(clear_display)();
634 cube_rotate(axes[0].angle, axes[1].angle, axes[2].angle);
635 cube_viewport();
636 cube_draw();
637 redraw = false;
640 #ifdef HAVE_LCD_BITMAP
641 if (t_disp > 0)
643 t_disp--;
644 rb->snprintf(buffer, sizeof(buffer), "%s: %d %s",
645 axes[curr].label,
646 paused ? axes[curr].angle : axes[curr].speed,
647 highspeed ? "(hs)" : "");
648 MYLCD(putsxy)(0, LCD_HEIGHT-8, buffer);
649 if (t_disp == 0)
650 redraw = true;
652 #else
653 if (t_disp > 0)
655 if (t_disp == DISP_TIME)
657 rb->lcd_puts(5, 0, axes[curr].label);
658 rb->snprintf(buffer, sizeof(buffer), "%d %c",
659 paused ? axes[curr].angle : axes[curr].speed,
660 highspeed ? 'H' : ' ');
661 rb->lcd_puts(5, 1, buffer);
663 t_disp--;
664 if (t_disp == 0)
666 rb->lcd_clear_display();
667 pgfx_display(0, 0);
670 #endif
671 #ifdef USE_GSLIB
672 if (mode_switch)
674 grey_show(mode == SOLID);
675 mode_switch = false;
677 #endif
678 MYLCD(update)();
680 if (!paused)
682 int i;
684 for (i = 0; i < 3; i++)
686 axes[i].angle += axes[i].speed;
687 if (axes[i].angle > 359)
688 axes[i].angle -= 360;
689 else if (axes[i].angle < 0)
690 axes[i].angle += 360;
692 redraw = true;
694 if (highspeed)
695 rb->yield();
696 else
697 rb->sleep(HZ/25);
698 button = rb->button_get(false);
700 else
702 button = rb->button_get_w_tmo(HZ/25);
705 switch (button)
707 case CUBE_INC:
708 case CUBE_INC|BUTTON_REPEAT:
709 if (!paused)
711 if (axes[curr].speed < 10)
712 axes[curr].speed++;
714 else
716 if (++axes[curr].angle > 359)
717 axes[curr].angle -= 360;
719 t_disp = DISP_TIME;
720 redraw = true;
721 break;
723 case CUBE_DEC:
724 case CUBE_DEC|BUTTON_REPEAT:
725 if (!paused)
727 if (axes[curr].speed > -10)
728 axes[curr].speed--;
730 else
732 if (--axes[curr].angle < 0)
733 axes[curr].angle += 360;
735 t_disp = DISP_TIME;
736 redraw = true;
737 break;
739 case CUBE_NEXT:
740 if (++curr > 2)
741 curr = 0;
742 t_disp = DISP_TIME;
743 break;
745 case CUBE_PREV:
746 if (--curr < 0)
747 curr = 2;
748 t_disp = DISP_TIME;
749 break;
751 case CUBE_MODE:
752 #ifdef CUBE_MODE_PRE
753 if (lastbutton != CUBE_MODE_PRE)
754 break;
755 #endif
756 if (++mode >= NUM_MODES)
757 mode = 0;
758 #ifdef USE_GSLIB
759 mylcd = (mode == SOLID) ? &greyfuncs : &lcdfuncs;
760 mode_switch = true;
761 #endif
762 redraw = true;
763 break;
765 case CUBE_PAUSE:
766 #ifdef CUBE_PAUSE_PRE
767 if (lastbutton != CUBE_PAUSE_PRE)
768 break;
769 #endif
770 paused = !paused;
771 break;
773 case CUBE_HIGHSPEED:
774 #ifdef CUBE_HIGHSPEED_PRE
775 if (lastbutton != CUBE_HIGHSPEED_PRE)
776 break;
777 #endif
778 highspeed = !highspeed;
779 t_disp = DISP_TIME;
780 break;
782 #ifdef CUBE_RC_QUIT
783 case CUBE_RC_QUIT:
784 #endif
785 case CUBE_QUIT:
786 exit = true;
787 break;
789 default:
790 if (rb->default_event_handler_ex(button, cleanup, NULL)
791 == SYS_USB_CONNECTED)
792 return PLUGIN_USB_CONNECTED;
793 break;
795 if (button != BUTTON_NONE)
796 lastbutton = button;
799 #ifdef USE_GSLIB
800 grey_release();
801 #elif defined(HAVE_LCD_CHARCELLS)
802 pgfx_release();
803 #endif
804 return PLUGIN_OK;