PP502x: Add some important information about CPU/COP_CTL register to the header glean...
[Rockbox.git] / apps / plugins / cube.c
blobf5158e9b7a847c75590e4244a70d4a4adedb3502
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 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ***************************************************************************/
21 #include "plugin.h"
22 #include "gray.h"
23 #include "playergfx.h"
24 #include "xlcd.h"
25 #include "fixedpoint.h"
27 PLUGIN_HEADER
29 /* Loops that the values are displayed */
30 #define DISP_TIME 30
32 /* variable button definitions */
33 #if CONFIG_KEYPAD == RECORDER_PAD
34 #define CUBE_QUIT BUTTON_OFF
35 #define CUBE_X_INC BUTTON_RIGHT
36 #define CUBE_X_DEC BUTTON_LEFT
37 #define CUBE_Y_INC BUTTON_UP
38 #define CUBE_Y_DEC BUTTON_DOWN
39 #define CUBE_Z_INC BUTTON_F2
40 #define CUBE_Z_DEC BUTTON_F1
41 #define CUBE_MODE BUTTON_F3
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_X_INC BUTTON_RIGHT
48 #define CUBE_X_DEC BUTTON_LEFT
49 #define CUBE_Y_INC BUTTON_UP
50 #define CUBE_Y_DEC BUTTON_DOWN
51 #define CUBE_Z_INC BUTTON_F2
52 #define CUBE_Z_DEC BUTTON_F1
53 #define CUBE_MODE BUTTON_F3
54 #define CUBE_PAUSE BUTTON_SELECT
55 #define CUBE_HIGHSPEED BUTTON_ON
57 #elif CONFIG_KEYPAD == PLAYER_PAD
58 #define CUBE_QUIT BUTTON_STOP
59 #define CUBE_X_INC BUTTON_RIGHT
60 #define CUBE_X_DEC BUTTON_LEFT
61 #define CUBE_Y_INC (BUTTON_ON | BUTTON_RIGHT)
62 #define CUBE_Y_DEC (BUTTON_ON | BUTTON_LEFT)
63 #define CUBE_Z_INC (BUTTON_MENU | BUTTON_RIGHT)
64 #define CUBE_Z_DEC (BUTTON_MENU | BUTTON_LEFT)
65 #define CUBE_MODE_PRE BUTTON_MENU
66 #define CUBE_MODE (BUTTON_MENU | BUTTON_REL)
67 #define CUBE_PAUSE BUTTON_PLAY
68 #define CUBE_HIGHSPEED_PRE BUTTON_ON
69 #define CUBE_HIGHSPEED (BUTTON_ON | BUTTON_REL)
71 #elif CONFIG_KEYPAD == ONDIO_PAD
72 #define CUBE_QUIT BUTTON_OFF
73 #define CUBE_X_INC BUTTON_RIGHT
74 #define CUBE_X_DEC BUTTON_LEFT
75 #define CUBE_Y_INC BUTTON_UP
76 #define CUBE_Y_DEC BUTTON_DOWN
77 #define CUBE_Z_INC (BUTTON_MENU | BUTTON_UP)
78 #define CUBE_Z_DEC (BUTTON_MENU | BUTTON_DOWN)
79 #define CUBE_MODE_PRE BUTTON_MENU
80 #define CUBE_MODE (BUTTON_MENU | BUTTON_REL)
81 #define CUBE_PAUSE (BUTTON_MENU | BUTTON_LEFT)
82 #define CUBE_HIGHSPEED (BUTTON_MENU | BUTTON_RIGHT)
84 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
85 (CONFIG_KEYPAD == IRIVER_H300_PAD)
86 #define CUBE_QUIT BUTTON_OFF
87 #define CUBE_X_INC BUTTON_RIGHT
88 #define CUBE_X_DEC BUTTON_LEFT
89 #define CUBE_Y_INC BUTTON_UP
90 #define CUBE_Y_DEC BUTTON_DOWN
91 #define CUBE_Z_INC (BUTTON_ON | BUTTON_UP)
92 #define CUBE_Z_DEC (BUTTON_ON | BUTTON_DOWN)
93 #define CUBE_MODE BUTTON_MODE
94 #define CUBE_PAUSE_PRE BUTTON_ON
95 #define CUBE_PAUSE (BUTTON_ON | BUTTON_REL)
96 #define CUBE_HIGHSPEED BUTTON_SELECT
98 #define CUBE_RC_QUIT BUTTON_RC_STOP
100 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
101 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
102 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
103 #define CUBE_QUIT BUTTON_MENU
104 #define CUBE_X_INC BUTTON_RIGHT
105 #define CUBE_X_DEC BUTTON_LEFT
106 #define CUBE_Y_INC BUTTON_SCROLL_FWD
107 #define CUBE_Y_DEC BUTTON_SCROLL_BACK
108 #define CUBE_Z_INC (BUTTON_SELECT | BUTTON_RIGHT)
109 #define CUBE_Z_DEC (BUTTON_SELECT | BUTTON_LEFT)
110 #define CUBE_MODE (BUTTON_SELECT | BUTTON_MENU)
111 #define CUBE_PAUSE_PRE BUTTON_PLAY
112 #define CUBE_PAUSE (BUTTON_PLAY | BUTTON_REL)
113 #define CUBE_HIGHSPEED (BUTTON_SELECT | BUTTON_PLAY)
115 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
116 #define CUBE_QUIT BUTTON_PLAY
117 #define CUBE_X_INC BUTTON_RIGHT
118 #define CUBE_X_DEC BUTTON_LEFT
119 #define CUBE_Y_INC BUTTON_UP
120 #define CUBE_Y_DEC BUTTON_DOWN
121 #define CUBE_Z_INC BUTTON_MODE
122 #define CUBE_Z_DEC BUTTON_EQ
123 #define CUBE_MODE (BUTTON_SELECT | BUTTON_REPEAT)
124 #define CUBE_PAUSE (BUTTON_SELECT | BUTTON_REL)
125 #define CUBE_HIGHSPEED (BUTTON_MODE | BUTTON_EQ) /* TODO: this is impossible */
127 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
128 #define CUBE_QUIT BUTTON_POWER
129 #define CUBE_X_INC BUTTON_LEFT
130 #define CUBE_X_DEC BUTTON_RIGHT
131 #define CUBE_Y_INC BUTTON_UP
132 #define CUBE_Y_DEC BUTTON_DOWN
133 #define CUBE_Z_INC (BUTTON_PLAY | BUTTON_UP)
134 #define CUBE_Z_DEC (BUTTON_PLAY | BUTTON_DOWN)
135 #define CUBE_MODE BUTTON_SELECT
136 #define CUBE_PAUSE_PRE BUTTON_PLAY
137 #define CUBE_PAUSE (BUTTON_PLAY | BUTTON_REL)
138 #define CUBE_HIGHSPEED (BUTTON_REC | BUTTON_REL)
140 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
141 #define CUBE_QUIT BUTTON_POWER
142 #define CUBE_X_INC BUTTON_LEFT
143 #define CUBE_X_DEC BUTTON_RIGHT
144 #define CUBE_Y_INC BUTTON_UP
145 #define CUBE_Y_DEC BUTTON_DOWN
146 #define CUBE_Z_INC BUTTON_VOL_UP
147 #define CUBE_Z_DEC BUTTON_VOL_DOWN
148 #define CUBE_MODE BUTTON_MENU
149 #define CUBE_PAUSE BUTTON_SELECT
150 #define CUBE_HIGHSPEED BUTTON_A
152 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
153 #define CUBE_QUIT BUTTON_POWER
154 #define CUBE_X_INC BUTTON_LEFT
155 #define CUBE_X_DEC BUTTON_RIGHT
156 #define CUBE_Y_INC BUTTON_SCROLL_UP
157 #define CUBE_Y_DEC BUTTON_SCROLL_DOWN
158 #define CUBE_Z_INC BUTTON_UP
159 #define CUBE_Z_DEC BUTTON_DOWN
160 #define CUBE_MODE_PRE BUTTON_SELECT
161 #define CUBE_MODE (BUTTON_SELECT|BUTTON_REPEAT)
162 #define CUBE_PAUSE_PRE BUTTON_SELECT
163 #define CUBE_PAUSE (BUTTON_SELECT|BUTTON_REL)
164 #define CUBE_HIGHSPEED BUTTON_REC
166 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
167 #define CUBE_QUIT BUTTON_POWER
168 #define CUBE_X_INC BUTTON_LEFT
169 #define CUBE_X_DEC BUTTON_RIGHT
170 #define CUBE_Y_INC BUTTON_SCROLL_UP
171 #define CUBE_Y_DEC BUTTON_SCROLL_DOWN
172 #define CUBE_Z_INC (BUTTON_PLAY | BUTTON_SCROLL_UP)
173 #define CUBE_Z_DEC (BUTTON_PLAY | BUTTON_SCROLL_DOWN)
174 #define CUBE_MODE BUTTON_REW
175 #define CUBE_PAUSE_PRE BUTTON_PLAY
176 #define CUBE_PAUSE (BUTTON_PLAY | BUTTON_REL)
177 #define CUBE_HIGHSPEED (BUTTON_FF | BUTTON_REL)
179 #endif
181 #ifdef HAVE_LCD_BITMAP
183 #define DIST (10 * MIN(LCD_HEIGHT, LCD_WIDTH) / 16)
184 static int x_off = LCD_WIDTH/2;
185 static int y_off = LCD_HEIGHT/2;
187 #if LCD_DEPTH == 1
188 #define USE_GSLIB
189 struct my_lcd {
190 void (*update)(void);
191 void (*clear_display)(void);
192 void (*drawline)(int x1, int y1, int x2, int y2);
193 void (*putsxy)(int x, int y, const unsigned char *string);
196 static struct my_lcd grayfuncs = {
197 gray_update, gray_clear_display, gray_drawline, gray_putsxy
199 static struct my_lcd lcdfuncs; /* initialised at runtime */
200 static struct my_lcd *mylcd = &grayfuncs;
202 #define MYLCD(fn) mylcd->fn
203 #define MY_FILLTRIANGLE(x1, y1, x2, y2, x3, y3) gray_filltriangle(x1, y1, x2, y2, x3, y3)
204 #define MY_SET_FOREGROUND(fg) gray_set_foreground(fg)
205 #define MY_GET_FOREGROUND() gray_get_foreground()
207 #else
208 #define MYLCD(fn) rb->lcd_ ## fn
209 #define MY_FILLTRIANGLE(x1, y1, x2, y2, x3, y3) xlcd_filltriangle(x1, y1, x2, y2, x3, y3)
210 #define MY_SET_FOREGROUND(fg) rb->lcd_set_foreground(fg)
211 #define MY_GET_FOREGROUND() rb->lcd_get_foreground()
212 #endif
214 #if CONFIG_LCD == LCD_SSD1815
215 #define ASPECT 320 /* = 1.25 (fixed point 24.8) */
216 #else
217 #define ASPECT 256 /* = 1.00 */
218 #endif
220 #else /* !LCD_BITMAP */
222 #define MYLCD(fn) pgfx_ ## fn
223 #define DIST 9
224 static int x_off = 10;
225 static int y_off = 7;
226 #define ASPECT 300 /* = 1.175 */
228 #endif /* !LCD_BITMAP */
230 struct point_3D {
231 long x, y, z;
234 struct point_2D {
235 long x, y;
238 struct line {
239 int start, end;
242 struct face {
243 int corner[4];
244 int line[4];
247 /* initial, unrotated cube corners */
248 static const struct point_3D sommet[8] =
250 {-DIST, -DIST, -DIST},
251 { DIST, -DIST, -DIST},
252 { DIST, DIST, -DIST},
253 {-DIST, DIST, -DIST},
254 {-DIST, -DIST, DIST},
255 { DIST, -DIST, DIST},
256 { DIST, DIST, DIST},
257 {-DIST, DIST, DIST}
260 /* The 12 lines forming the edges */
261 static const struct line lines[12] =
263 {0, 1}, {1, 2}, {2, 3}, {3, 0},
264 {4, 7}, {7, 6}, {6, 5}, {5, 4},
265 {0, 4}, {1, 5}, {2, 6}, {3, 7}
268 static bool lines_drawn[12];
270 /* The 6 faces of the cube; points are in clockwise order when viewed
271 from the outside */
272 static const struct face faces[6] =
274 {{0, 1, 2, 3}, {0, 1, 2, 3}},
275 {{4, 7, 6, 5}, {4, 5, 6, 7}},
276 {{0, 4, 5, 1}, {8, 7, 9, 0}},
277 {{2, 6, 7, 3}, {10, 5, 11, 2}},
278 {{0, 3, 7, 4}, {3, 11, 4, 8}},
279 {{1, 5, 6, 2}, {9, 6, 10, 1}}
282 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
283 static const unsigned face_colors[6] =
285 #ifdef HAVE_LCD_COLOR
286 LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(0, 255, 0),
287 LCD_RGBPACK(0, 255, 0), LCD_RGBPACK(0, 0, 255), LCD_RGBPACK(0, 0, 255)
288 #elif defined(USE_GSLIB)
289 GRAY_LIGHTGRAY, GRAY_LIGHTGRAY, GRAY_DARKGRAY,
290 GRAY_DARKGRAY, GRAY_BLACK, GRAY_BLACK
291 #else
292 LCD_LIGHTGRAY, LCD_LIGHTGRAY, LCD_DARKGRAY,
293 LCD_DARKGRAY, LCD_BLACK, LCD_BLACK
294 #endif
296 #endif
298 enum {
299 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
300 SOLID,
301 #endif
302 HIDDEN_LINES,
303 WIREFRAME,
304 NUM_MODES
307 static int mode = 0;
309 static struct point_3D point3D[8];
310 static struct point_2D point2D[8];
311 static long matrice[3][3];
313 static const int nb_points = 8;
314 static long z_off = 600;
316 static struct plugin_api* rb;
318 static void cube_rotate(int xa, int ya, int za)
320 int i;
321 /* Just to prevent unnecessary lookups */
322 long sxa, cxa, sya, cya, sza, cza;
324 sxa = sin_int(xa);
325 cxa = cos_int(xa);
326 sya = sin_int(ya);
327 cya = cos_int(ya);
328 sza = sin_int(za);
329 cza = cos_int(za);
331 /* calculate overall translation matrix */
332 matrice[0][0] = (cza * cya) >> 14;
333 matrice[1][0] = (sza * cya) >> 14;
334 matrice[2][0] = -sya;
336 matrice[0][1] = (((cza * sya) >> 14) * sxa - sza * cxa) >> 14;
337 matrice[1][1] = (((sza * sya) >> 14) * sxa + cxa * cza) >> 14;
338 matrice[2][1] = (sxa * cya) >> 14;
340 matrice[0][2] = (((cza * sya) >> 14) * cxa + sza * sxa) >> 14;
341 matrice[1][2] = (((sza * sya) >> 14) * cxa - cza * sxa) >> 14;
342 matrice[2][2] = (cxa * cya) >> 14;
344 /* apply translation matrix to all points */
345 for (i = 0; i < nb_points; i++)
347 point3D[i].x = matrice[0][0] * sommet[i].x + matrice[1][0] * sommet[i].y
348 + matrice[2][0] * sommet[i].z;
350 point3D[i].y = matrice[0][1] * sommet[i].x + matrice[1][1] * sommet[i].y
351 + matrice[2][1] * sommet[i].z;
353 point3D[i].z = matrice[0][2] * sommet[i].x + matrice[1][2] * sommet[i].y
354 + matrice[2][2] * sommet[i].z;
358 static void cube_viewport(void)
360 int i;
362 /* Do viewport transformation for all points */
363 for (i = 0; i < nb_points; i++)
365 #if ASPECT != 256
366 point2D[i].x = (point3D[i].x * ASPECT) / (point3D[i].z + (z_off << 14))
367 + x_off;
368 #else
369 point2D[i].x = (point3D[i].x << 8) / (point3D[i].z + (z_off << 14))
370 + x_off;
371 #endif
372 point2D[i].y = (point3D[i].y << 8) / (point3D[i].z + (z_off << 14))
373 + y_off;
377 static void cube_draw(void)
379 int i, j, line;
380 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
381 unsigned old_foreground;
382 #endif
384 switch (mode)
386 #if LCD_DEPTH > 1 || defined(USE_GSLIB)
387 case SOLID:
389 old_foreground = MY_GET_FOREGROUND();
390 for (i = 0; i < 6; i++)
392 /* backface culling; if the shape winds counter-clockwise, we are
393 * looking at the backface, and the (simplified) cross product
394 * is < 0. Do not draw it. */
395 if (0 >= (point2D[faces[i].corner[1]].x - point2D[faces[i].corner[0]].x)
396 * (point2D[faces[i].corner[2]].y - point2D[faces[i].corner[1]].y)
397 - (point2D[faces[i].corner[1]].y - point2D[faces[i].corner[0]].y)
398 * (point2D[faces[i].corner[2]].x - point2D[faces[i].corner[1]].x))
399 continue;
401 MY_SET_FOREGROUND(face_colors[i]);
402 MY_FILLTRIANGLE(point2D[faces[i].corner[0]].x,
403 point2D[faces[i].corner[0]].y,
404 point2D[faces[i].corner[1]].x,
405 point2D[faces[i].corner[1]].y,
406 point2D[faces[i].corner[2]].x,
407 point2D[faces[i].corner[2]].y);
408 MY_FILLTRIANGLE(point2D[faces[i].corner[0]].x,
409 point2D[faces[i].corner[0]].y,
410 point2D[faces[i].corner[2]].x,
411 point2D[faces[i].corner[2]].y,
412 point2D[faces[i].corner[3]].x,
413 point2D[faces[i].corner[3]].y);
416 MY_SET_FOREGROUND(old_foreground);
417 break;
418 #endif /* (LCD_DEPTH > 1) || GSLIB */
420 case HIDDEN_LINES:
422 rb->memset(lines_drawn, 0, sizeof(lines_drawn));
423 for (i = 0; i < 6; i++)
425 /* backface culling; if the shape winds counter-clockwise, we are
426 * looking at the backface, and the (simplified) cross product
427 * is < 0. Do not draw it. */
428 if (0 >= (point2D[faces[i].corner[1]].x - point2D[faces[i].corner[0]].x)
429 * (point2D[faces[i].corner[2]].y - point2D[faces[i].corner[1]].y)
430 - (point2D[faces[i].corner[1]].y - point2D[faces[i].corner[0]].y)
431 * (point2D[faces[i].corner[2]].x - point2D[faces[i].corner[1]].x))
432 continue;
434 for (j = 0; j < 4; j++)
436 line = faces[i].line[j];
437 if (!lines_drawn[line])
439 lines_drawn[line] = true;
440 MYLCD(drawline)(point2D[lines[line].start].x,
441 point2D[lines[line].start].y,
442 point2D[lines[line].end].x,
443 point2D[lines[line].end].y);
447 break;
449 case WIREFRAME:
451 for (i = 0; i < 12; i++)
452 MYLCD(drawline)(point2D[lines[i].start].x,
453 point2D[lines[i].start].y,
454 point2D[lines[i].end].x,
455 point2D[lines[i].end].y);
456 break;
460 void cleanup(void *parameter)
462 (void)parameter;
464 #ifdef USE_GSLIB
465 gray_release();
466 #elif defined HAVE_LCD_CHARCELLS
467 pgfx_release();
468 #endif
471 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
473 char buffer[30];
474 int t_disp = 0;
475 #ifdef USE_GSLIB
476 unsigned char *gbuf;
477 size_t gbuf_size = 0;
478 bool mode_switch = true;
479 #endif
481 int button;
482 int lastbutton = BUTTON_NONE;
483 int xa = 0;
484 int ya = 0;
485 int za = 0;
486 int xs = 1;
487 int ys = 3;
488 int zs = 1;
489 bool highspeed = false;
490 bool paused = false;
491 bool redraw = true;
492 bool exit = false;
494 (void)(parameter);
495 rb = api;
497 #ifdef HAVE_LCD_BITMAP
498 #if LCD_DEPTH > 1
499 xlcd_init(rb);
500 #elif defined(USE_GSLIB)
501 gbuf = (unsigned char *)rb->plugin_get_buffer(&gbuf_size);
502 if (gray_init(rb, gbuf, gbuf_size, true, LCD_WIDTH, LCD_HEIGHT, 3, 0, NULL)
503 != 3)
505 rb->splash(HZ, "Couldn't get grayscale buffer");
506 return PLUGIN_ERROR;
508 /* init lcd_ function pointers */
509 lcdfuncs.update = rb->lcd_update;
510 lcdfuncs.clear_display = rb->lcd_clear_display;
511 lcdfuncs.drawline = rb->lcd_drawline;
512 lcdfuncs.putsxy = rb->lcd_putsxy;
514 gray_setfont(FONT_SYSFIXED);
515 #endif
516 rb->lcd_setfont(FONT_SYSFIXED);
517 #else /* LCD_CHARCELLS */
518 if (!pgfx_init(rb, 4, 2))
520 rb->splash(HZ*2, "Old LCD :(");
521 return PLUGIN_OK;
523 pgfx_display(3, 0);
524 #endif
526 while(!exit)
528 if (highspeed)
529 rb->yield();
530 else
531 rb->sleep(4);
533 if (redraw)
535 MYLCD(clear_display)();
536 cube_rotate(xa, ya, za);
537 cube_viewport();
538 cube_draw();
539 redraw = false;
542 #ifdef HAVE_LCD_BITMAP
543 if (t_disp > 0)
545 t_disp--;
546 rb->snprintf(buffer, sizeof(buffer), "x:%d y:%d z:%d h:%d",
547 xs, ys, zs, highspeed);
548 MYLCD(putsxy)(0, LCD_HEIGHT-8, buffer);
549 if (t_disp == 0)
550 redraw = true;
552 #else
553 if (t_disp > 0)
555 if (t_disp == DISP_TIME)
557 rb->snprintf(buffer, sizeof(buffer), "x%d", xs);
558 rb->lcd_puts(0, 0, buffer);
559 rb->snprintf(buffer, sizeof(buffer), "y%d", ys);
560 rb->lcd_puts(0, 1, buffer);
561 pgfx_display(3, 0);
562 rb->snprintf(buffer, sizeof(buffer), "z%d", zs);
563 rb->lcd_puts(8, 0, buffer);
564 rb->snprintf(buffer, sizeof(buffer), "h%d", highspeed);
565 rb->lcd_puts(8, 1, buffer);
567 t_disp--;
568 if (t_disp == 0)
570 rb->lcd_clear_display();
571 pgfx_display(3, 0);
574 #endif
575 #ifdef USE_GSLIB
576 if (mode_switch)
578 gray_show(mode == SOLID);
579 mode_switch = false;
581 #endif
582 MYLCD(update)();
584 if (!paused)
586 xa += xs;
587 if (xa > 359)
588 xa -= 360;
589 else if (xa < 0)
590 xa += 360;
592 ya += ys;
593 if (ya > 359)
594 ya -= 360;
595 else if (ya < 0)
596 ya += 360;
598 za += zs;
599 if (za > 359)
600 za -= 360;
601 else if (za < 0)
602 za += 360;
603 redraw = true;
606 button = rb->button_get(false);
607 switch (button)
609 case CUBE_X_INC:
610 case (CUBE_X_INC|BUTTON_REPEAT):
611 if( !paused )
613 if( xs < 10)
614 xs++;
616 else
618 xa++;
619 if( xa > 359 )
620 xa -= 360;
622 t_disp = DISP_TIME;
623 redraw = true;
624 break;
626 case CUBE_X_DEC:
627 case (CUBE_X_DEC|BUTTON_REPEAT):
628 if( !paused )
630 if (xs > -10)
631 xs--;
633 else
635 xa--;
636 if( xa < 0 )
637 xa += 360;
639 t_disp = DISP_TIME;
640 redraw = true;
641 break;
643 case CUBE_Y_INC:
644 case (CUBE_Y_INC|BUTTON_REPEAT):
645 if( !paused )
647 if (ys < 10)
648 ys++;
650 else
652 ya++;
653 if( ya > 359 )
654 ya -= 360;
656 t_disp = DISP_TIME;
657 redraw = true;
658 break;
660 case CUBE_Y_DEC:
661 case (CUBE_Y_DEC|BUTTON_REPEAT):
662 if( !paused )
664 if (ys > -10)
665 ys--;
667 else
669 ya--;
670 if( ya < 0 )
671 ya += 360;
673 t_disp = DISP_TIME;
674 redraw = true;
675 break;
677 case CUBE_Z_INC:
678 case (CUBE_Z_INC|BUTTON_REPEAT):
679 if( !paused )
681 if (zs < 10)
682 zs++;
684 else
686 za++;
687 if( za > 359 )
688 za -= 360;
690 t_disp = DISP_TIME;
691 redraw = true;
692 break;
694 case CUBE_Z_DEC:
695 case (CUBE_Z_DEC|BUTTON_REPEAT):
696 if( !paused )
698 if (zs > -10)
699 zs--;
701 else
703 za--;
704 if( za < 0 )
705 za += 360;
707 t_disp = DISP_TIME;
708 redraw = true;
709 break;
711 case CUBE_MODE:
712 #ifdef CUBE_MODE_PRE
713 if (lastbutton != CUBE_MODE_PRE)
714 break;
715 #endif
716 if (++mode >= NUM_MODES)
717 mode = 0;
718 #ifdef USE_GSLIB
719 mylcd = (mode == SOLID) ? &grayfuncs : &lcdfuncs;
720 mode_switch = true;
721 #endif
722 redraw = true;
723 break;
725 case CUBE_PAUSE:
726 #ifdef CUBE_PAUSE_PRE
727 if (lastbutton != CUBE_PAUSE_PRE)
728 break;
729 #endif
730 paused = !paused;
731 break;
733 case CUBE_HIGHSPEED:
734 #ifdef CUBE_HIGHSPEED_PRE
735 if (lastbutton != CUBE_HIGHSPEED_PRE)
736 break;
737 #endif
738 highspeed = !highspeed;
739 t_disp = DISP_TIME;
740 break;
742 #ifdef CUBE_RC_QUIT
743 case CUBE_RC_QUIT:
744 #endif
745 case CUBE_QUIT:
746 exit = true;
747 break;
749 default:
750 if (rb->default_event_handler_ex(button, cleanup, NULL)
751 == SYS_USB_CONNECTED)
752 return PLUGIN_USB_CONNECTED;
753 break;
755 if (button != BUTTON_NONE)
756 lastbutton = button;
759 #ifdef USE_GSLIB
760 gray_release();
761 #elif defined(HAVE_LCD_CHARCELLS)
762 pgfx_release();
763 #endif
764 return PLUGIN_OK;