diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-07-12 23:57:06 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-07-12 23:57:06 +0000 |
commit | 6a8cf45052e7e5cad627628cd02bc949dbb60aa8 (patch) | |
tree | f0f0ffe8840f358e86b99172fa16b06fd06708f3 | |
parent | 937725f6749bced2526a13ebb8772233986917e3 (diff) | |
download | rockbox-6a8cf45052e7e5cad627628cd02bc949dbb60aa8.tar.gz rockbox-6a8cf45052e7e5cad627628cd02bc949dbb60aa8.zip |
Cube.rock extension and rework: (1) Solid 4-greylevel mode on iriver H1xx. (2) Restructured internal handling of corners and edges. Added handling of faces for (1). (3) Small button handling changes for better response.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7129 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/cube.c | 198 |
1 files changed, 143 insertions, 55 deletions
diff --git a/apps/plugins/cube.c b/apps/plugins/cube.c index f4e0e01c41..7f6924ab95 100644 --- a/apps/plugins/cube.c +++ b/apps/plugins/cube.c @@ -9,7 +9,7 @@ * * Copyright (C) 2002 Damien Teney * modified to use int instead of float math by Andreas Zwirtes -* binary fixed point format and LCD aspect handling by Jens Arnold +* binary fixed point format, LCD aspect handling and solid mode by Jens Arnold * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. @@ -20,13 +20,14 @@ ***************************************************************************/ #include "plugin.h" #include "playergfx.h" +#include "xlcd.h" /* Loops that the values are displayed */ #define DISP_TIME 30 /* variable button definitions */ #if CONFIG_KEYPAD == RECORDER_PAD -#define CUBE_QUIT (BUTTON_OFF | BUTTON_REL) +#define CUBE_QUIT BUTTON_OFF #define CUBE_X_INC BUTTON_RIGHT #define CUBE_X_DEC BUTTON_LEFT #define CUBE_Y_INC BUTTON_UP @@ -36,7 +37,7 @@ #define CUBE_HIGHSPEED BUTTON_PLAY #elif CONFIG_KEYPAD == PLAYER_PAD -#define CUBE_QUIT (BUTTON_STOP | BUTTON_REL) +#define CUBE_QUIT BUTTON_STOP #define CUBE_X_INC BUTTON_RIGHT #define CUBE_X_DEC BUTTON_LEFT #define CUBE_Y_INC (BUTTON_ON | BUTTON_RIGHT) @@ -46,7 +47,7 @@ #define CUBE_HIGHSPEED BUTTON_PLAY #elif CONFIG_KEYPAD == ONDIO_PAD -#define CUBE_QUIT (BUTTON_OFF | BUTTON_REL) +#define CUBE_QUIT BUTTON_OFF #define CUBE_X_INC BUTTON_RIGHT #define CUBE_X_DEC BUTTON_LEFT #define CUBE_Y_INC BUTTON_UP @@ -58,34 +59,18 @@ #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ (CONFIG_KEYPAD == IRIVER_H300_PAD) -#define CUBE_QUIT (BUTTON_OFF | BUTTON_REL) +#define CUBE_QUIT BUTTON_OFF #define CUBE_X_INC BUTTON_RIGHT #define CUBE_X_DEC BUTTON_LEFT #define CUBE_Y_INC BUTTON_UP #define CUBE_Y_DEC BUTTON_DOWN #define CUBE_Z_INC (BUTTON_ON | BUTTON_UP) #define CUBE_Z_DEC (BUTTON_ON | BUTTON_DOWN) -#define CUBE_HIGHSPEED_PRE BUTTON_SELECT -#define CUBE_HIGHSPEED (BUTTON_SELECT | BUTTON_REL) +#define CUBE_MODE BUTTON_MODE +#define CUBE_HIGHSPEED BUTTON_SELECT #endif -struct point_3D { - long x, y, z; -}; - -struct point_2D { - long x, y; -}; - -static struct point_3D sommet[8]; -static struct point_3D point3D[8]; -static struct point_2D point2D[8]; - -static long matrice[3][3]; - -static int nb_points = 8; - #ifdef HAVE_LCD_BITMAP #define MYLCD(fn) rb->lcd_ ## fn #define DIST (10*LCD_HEIGHT/16) @@ -104,11 +89,72 @@ static int y_off = 7; #define ASPECT 300 /* = 1.175 */ #endif /* !LCD_BITMAP */ +struct point_3D { + long x, y, z; +}; + +struct point_2D { + long x, y; +}; + +struct line { + int start, end; +}; + +#if LCD_DEPTH > 1 +struct face { + int corner1, corner2, corner3, corner4; +}; + +struct zsort { + int place; + long sum; +}; +#endif + +/* initial, unrotated cube corners */ +static const struct point_3D sommet[8] = +{ + {-DIST, -DIST, -DIST}, + { DIST, -DIST, -DIST}, + { DIST, DIST, -DIST}, + {-DIST, DIST, -DIST}, + {-DIST, -DIST, DIST}, + { DIST, -DIST, DIST}, + { DIST, DIST, DIST}, + {-DIST, DIST, DIST} +}; + +/* The 12 lines forming the edges */ +static const struct line lines[12] = +{ + {0, 1}, {1, 2}, {2, 3}, {3, 0}, + {4, 5}, {5, 6}, {6, 7}, {7, 4}, + {0, 4}, {1, 5}, {2, 6}, {3, 7} +}; + +#if LCD_DEPTH > 1 +/* The 6 faces of the cube */ +static const struct face faces[6] = +{ + {0, 1, 2, 3}, {4, 5, 6, 7}, + {0, 1, 5, 4}, {3, 2, 6, 7}, + {0, 3, 7, 4}, {1, 2, 6, 5} +}; + +static bool solid = true; +#endif + +static struct point_3D point3D[8]; +static struct point_2D point2D[8]; + +static long matrice[3][3]; +static int nb_points = 8; static long z_off = 600; /* Precalculated sine and cosine * 16384 (fixed point 18.14) */ -static short sin_table[91] = +static const short sin_table[91] = { 0, 285, 571, 857, 1142, 1427, 1712, 1996, 2280, 2563, 2845, 3126, 3406, 3685, 3963, 4240, 4516, 4790, 5062, 5334, @@ -248,39 +294,75 @@ static void cube_viewport(void) } } -static void cube_init(void) -{ - /* Original 3D-position of cube's corners */ - sommet[0].x = -DIST; sommet[0].y = -DIST; sommet[0].z = -DIST; - sommet[1].x = DIST; sommet[1].y = -DIST; sommet[1].z = -DIST; - sommet[2].x = DIST; sommet[2].y = DIST; sommet[2].z = -DIST; - sommet[3].x = -DIST; sommet[3].y = DIST; sommet[3].z = -DIST; - sommet[4].x = DIST; sommet[4].y = -DIST; sommet[4].z = DIST; - sommet[5].x = -DIST; sommet[5].y = -DIST; sommet[5].z = DIST; - sommet[6].x = -DIST; sommet[6].y = DIST; sommet[6].z = DIST; - sommet[7].x = DIST; sommet[7].y = DIST; sommet[7].z = DIST; -} - -static void line(int a, int b) +#if LCD_DEPTH > 1 +static int compfunc(const void * a, const void * b) { - MYLCD(drawline)(point2D[a].x, point2D[a].y, point2D[b].x, point2D[b].y); + return ((struct zsort *)b)->sum - ((struct zsort *)a)->sum; } +#endif static void cube_draw(void) { - /* Draws front face */ - line(0,1); line(1,2); - line(2,3); line(3,0); - - /* Draws rear face */ - line(4,5); line(5,6); - line(6,7); line(7,4); - - /* Draws the other edges */ - line(0,5); - line(1,4); - line(2,7); - line(3,6); + int i; +#if LCD_DEPTH > 1 + int place; + struct zsort z_avgs_f[6]; + + if (solid) + { + for (i = 0; i < 6; i++) + { + z_avgs_f[i].place = i; + z_avgs_f[i].sum = point3D[faces[i].corner1].z + + point3D[faces[i].corner2].z + + point3D[faces[i].corner3].z + + point3D[faces[i].corner4].z; + } + + rb->qsort(z_avgs_f, 6, sizeof(struct zsort), compfunc); + + for (i = 3; i < 6; i++) + { /* we can only see the front 3 faces at best */ + switch(z_avgs_f[i].place) + { + case 0: + case 1: + rb->lcd_set_foreground(2*MAX_LEVEL/3); + break; + case 2: + case 3: + rb->lcd_set_foreground(MAX_LEVEL/3); + break; + case 4: + case 5: + rb->lcd_set_foreground(0); + break; + } + place = z_avgs_f[i].place; + xlcd_filltriangle(point2D[faces[place].corner1].x, + point2D[faces[place].corner1].y, + point2D[faces[place].corner2].x, + point2D[faces[place].corner2].y, + point2D[faces[place].corner3].x, + point2D[faces[place].corner3].y); + xlcd_filltriangle(point2D[faces[place].corner1].x, + point2D[faces[place].corner1].y, + point2D[faces[place].corner3].x, + point2D[faces[place].corner3].y, + point2D[faces[place].corner4].x, + point2D[faces[place].corner4].y); + } + rb->lcd_set_foreground(0); + } + else +#endif /* LCD_DEPTH > 1 */ + { + for (i = 0; i < 12; i++) + MYLCD(drawline)(point2D[lines[i].start].x, + point2D[lines[i].start].y, + point2D[lines[i].end].x, + point2D[lines[i].end].y); + } } @@ -305,6 +387,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) rb = api; #ifdef HAVE_LCD_BITMAP +#if LCD_DEPTH > 1 + xlcd_init(rb); +#endif rb->lcd_setfont(FONT_SYSFIXED); #else if (!pgfx_init(rb, 4, 2)) @@ -315,11 +400,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) pgfx_display(3, 0); #endif - cube_init(); - while(!exit) { - if (highspeed) + if (highspeed) rb->yield(); else rb->sleep(4); @@ -416,6 +499,11 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) zs=-10; t_disp=DISP_TIME; break; +#ifdef CUBE_MODE + case CUBE_MODE: + solid = !solid; + break; +#endif case CUBE_HIGHSPEED: #ifdef CUBE_HIGHSPEED_PRE if (lastbutton!=CUBE_HIGHSPEED_PRE) |