Pass plugin api pointer to funtion directly, fixes crashes when doing incremental...
[kugel-rb.git] / apps / plugins / starfield.c
blob278d24fbc7e34c3572e3bf08e832e1d1dea3e1df
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * Copyright (C) 2005 Kevin Ferrare
10 * All files in this archive are subject to the GNU General Public License.
11 * See the file COPYING in the source tree root for full license agreement.
13 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
14 * KIND, either express or implied.
16 ****************************************************************************/
18 #include "plugin.h"
19 #include "helper.h"
21 #ifdef HAVE_LCD_BITMAP /* and also not for the Player */
23 PLUGIN_HEADER
25 /******************************* Globals ***********************************/
27 static struct plugin_api* rb; /* global api struct pointer */
29 /* Key assignement */
30 #if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
31 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
32 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
33 #define STARFIELD_QUIT BUTTON_MENU
34 #define STARFIELD_INCREASE_ZMOVE BUTTON_SCROLL_FWD
35 #define STARFIELD_DECREASE_ZMOVE BUTTON_SCROLL_BACK
36 #define STARFIELD_INCREASE_NB_STARS BUTTON_RIGHT
37 #define STARFIELD_DECREASE_NB_STARS BUTTON_LEFT
38 #define STARFIELD_TOGGLE_COLOR BUTTON_PLAY
39 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
40 #define STARFIELD_QUIT BUTTON_POWER
41 #define STARFIELD_INCREASE_ZMOVE BUTTON_UP
42 #define STARFIELD_DECREASE_ZMOVE BUTTON_DOWN
43 #define STARFIELD_INCREASE_NB_STARS BUTTON_RIGHT
44 #define STARFIELD_DECREASE_NB_STARS BUTTON_LEFT
45 #define STARFIELD_TOGGLE_COLOR BUTTON_PLAY
46 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
47 #define STARFIELD_QUIT BUTTON_POWER
48 #define STARFIELD_INCREASE_ZMOVE BUTTON_SCROLL_UP
49 #define STARFIELD_DECREASE_ZMOVE BUTTON_SCROLL_DOWN
50 #define STARFIELD_INCREASE_NB_STARS BUTTON_RIGHT
51 #define STARFIELD_DECREASE_NB_STARS BUTTON_LEFT
52 #define STARFIELD_TOGGLE_COLOR BUTTON_PLAY
53 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
54 #define STARFIELD_QUIT BUTTON_POWER
55 #define STARFIELD_INCREASE_ZMOVE BUTTON_UP
56 #define STARFIELD_DECREASE_ZMOVE BUTTON_DOWN
57 #define STARFIELD_INCREASE_NB_STARS BUTTON_RIGHT
58 #define STARFIELD_DECREASE_NB_STARS BUTTON_LEFT
59 #define STARFIELD_TOGGLE_COLOR BUTTON_SELECT
60 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
61 #define STARFIELD_QUIT BUTTON_POWER
62 #define STARFIELD_INCREASE_ZMOVE BUTTON_UP
63 #define STARFIELD_DECREASE_ZMOVE BUTTON_DOWN
64 #define STARFIELD_INCREASE_NB_STARS BUTTON_RIGHT
65 #define STARFIELD_DECREASE_NB_STARS BUTTON_LEFT
66 #define STARFIELD_TOGGLE_COLOR BUTTON_SELECT
68 #else
69 #define STARFIELD_QUIT BUTTON_OFF
70 #define STARFIELD_INCREASE_ZMOVE BUTTON_UP
71 #define STARFIELD_DECREASE_ZMOVE BUTTON_DOWN
72 #define STARFIELD_INCREASE_NB_STARS BUTTON_RIGHT
73 #define STARFIELD_DECREASE_NB_STARS BUTTON_LEFT
74 #ifdef BUTTON_SELECT
75 #define STARFIELD_TOGGLE_COLOR BUTTON_SELECT
76 #else
77 #define STARFIELD_TOGGLE_COLOR BUTTON_PLAY
78 #endif
79 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
80 #define STARFIELD_RC_QUIT BUTTON_RC_STOP
81 #endif
83 #endif
85 #define LCD_CENTER_X (LCD_WIDTH/2)
86 #define LCD_CENTER_Y (LCD_HEIGHT/2)
87 #define Z_MAX_DIST 100
90 #define MAX_STARS (LCD_WIDTH*LCD_HEIGHT*20)/100
91 #define INIT_STARS 200
92 #define STARFIELD_INCREASE_STEP 50
93 #define INIT_SPACE_SPEED 1
94 #define STAR_MAX_VELOCITY 2
96 * max 3d coord in the 2d screen :
97 * example with x
98 * x2d=x3d/z+LCD_CENTER_X (+LCD_CENTER_X to center ...)
99 * so
100 * max_x2d=max_x3d/max_z+LCD_CENTER_X
101 * max_x3d=(max_x2d-LCD_CENTER_X)*max_z
102 * with
103 * max_x2d = LCD_WIDTH
104 * max_z = Z_MAX_DIST
105 * we have now
106 * max_x3d=(LCD_WIDTH-LCD_CENTER_X)*Z_MAX_DIST
107 * max_x3d=LCD_CENTER_X*Z_MAX_DIST
110 #define MAX_INIT_STAR_X LCD_CENTER_X*Z_MAX_DIST
111 #define MAX_INIT_STAR_Y LCD_CENTER_Y*Z_MAX_DIST
113 #define MSG_DISP_TIME 30
115 static struct plugin_api* rb; /* global api struct pointer */
118 * Each star's stuffs
120 struct star
122 int x,y,z;
123 int velocity;
124 #ifdef HAVE_LCD_COLOR
125 int color;
126 #endif
129 static inline void star_init(struct star * star, int z_move, bool color)
131 star->velocity=rb->rand() % STAR_MAX_VELOCITY+1;
132 /* choose x between -MAX_INIT_STAR_X and MAX_INIT_STAR_X */
133 star->x=rb->rand() % (2*MAX_INIT_STAR_X)-MAX_INIT_STAR_X;
134 star->y=rb->rand() % (2*MAX_INIT_STAR_Y)-MAX_INIT_STAR_Y;
135 #ifdef HAVE_LCD_COLOR
136 if(color)
137 star->color=LCD_RGBPACK(rb->rand()%128+128,rb->rand()%128+128,
138 rb->rand()%128+128);
139 else
140 star->color=LCD_WHITE;
141 #else
142 (void)color;
143 #endif
144 if(z_move>=0)
145 star->z=Z_MAX_DIST;
146 else
147 star->z=rb->rand() %Z_MAX_DIST/2+1;
150 static inline void star_move(struct star * star, int z_move, bool color)
152 star->z -= z_move*star->velocity;
153 if (star->z <= 0 || star->z > Z_MAX_DIST)
154 star_init(star, z_move, color);
157 static inline void star_draw(struct star * star, int z_move, bool color)
159 int x_draw, y_draw;
161 * 3d -> 2d : projection on the screen : x2d=x3d/z (thales theorem)
162 * we put the star in the center of the screen
164 x_draw = star->x / star->z + LCD_CENTER_X;
165 if (x_draw < 1 || x_draw >= LCD_WIDTH)
167 star_init(star, z_move, color);
168 return;
170 y_draw = star->y / star->z + LCD_CENTER_Y;
171 if (y_draw < 1 || y_draw >= LCD_HEIGHT)
173 star_init(star, z_move, color);
174 return;
177 #ifdef HAVE_LCD_COLOR
178 rb->lcd_set_foreground(star->color);
179 #endif
181 rb->lcd_drawpixel(x_draw, y_draw);
182 if(star->z<5*Z_MAX_DIST/6)
184 rb->lcd_drawpixel(x_draw, y_draw - 1);
185 rb->lcd_drawpixel(x_draw - 1, y_draw);
186 if(star->z<Z_MAX_DIST/2)
188 rb->lcd_drawpixel(x_draw + 1, y_draw);
189 rb->lcd_drawpixel(x_draw, y_draw + 1);
195 * Whole starfield operations
197 struct starfield
199 struct star tab[MAX_STARS];
200 int nb_stars;
201 int z_move;
202 bool color;
205 static inline void starfield_init(struct starfield * starfield)
207 starfield->nb_stars=0;
208 starfield->z_move=INIT_SPACE_SPEED;
209 starfield->color=false;
212 static inline void starfield_add_stars(struct starfield * starfield,
213 int nb_to_add)
215 int i, old_nb_stars;
216 old_nb_stars=starfield->nb_stars;
217 starfield->nb_stars+=nb_to_add;
219 if(starfield->nb_stars > MAX_STARS)
220 starfield->nb_stars=MAX_STARS;
222 for( i=old_nb_stars ; i < starfield->nb_stars ; ++i )
224 star_init( &(starfield->tab[i]), starfield->z_move, starfield->color );
228 static inline void starfield_del_stars(struct starfield * starfield,
229 int nb_to_add)
231 starfield->nb_stars-=nb_to_add;
232 if(starfield->nb_stars<0)
233 starfield->nb_stars=0;
236 static inline void starfield_move_and_draw(struct starfield * starfield)
238 int i;
239 for(i=0;i<starfield->nb_stars;++i)
241 star_move(&(starfield->tab[i]), starfield->z_move, starfield->color);
242 star_draw(&(starfield->tab[i]), starfield->z_move, starfield->color);
246 static struct starfield starfield;
248 int plugin_main(void)
250 char str_buffer[40];
251 int button, avg_peak, t_disp=0;
252 int font_h, font_w;
253 bool pulse=true;
254 rb->lcd_getstringsize("A", &font_w, &font_h);
255 starfield_init(&starfield);
256 starfield_add_stars(&starfield, INIT_STARS);
258 #if LCD_DEPTH > 1
259 rb->lcd_set_backdrop(NULL);
260 #endif
261 #ifdef HAVE_LCD_COLOR
262 rb->lcd_set_background(LCD_BLACK);
263 rb->lcd_set_foreground(LCD_WHITE);
264 #endif
266 while (true)
268 rb->sleep(1);
269 rb->lcd_clear_display();
271 #if ((CONFIG_CODEC == SWCODEC) || !defined(SIMULATOR) && \
272 ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)))
274 /* This will make the stars pulse to the music */
275 if(pulse==true){
277 /* Get the peaks. ( Borrowed from vu_meter ) */
278 #if (CONFIG_CODEC == SWCODEC)
279 int left_peak, right_peak;
280 rb->pcm_calculate_peaks(&left_peak, &right_peak);
281 #else
282 int left_peak = rb->mas_codec_readreg(0xC);
283 int right_peak = rb->mas_codec_readreg(0xD);
284 #endif
285 /* Devide peak data by 4098 to bring the max
286 value down from ~32k to 8 */
287 left_peak = left_peak/0x1000;
288 right_peak = right_peak/0x1000;
290 /* Make sure they dont stop */
291 if(left_peak<0x1)
292 left_peak = 0x1;
293 if(right_peak<0x1)
294 right_peak = 0x1;
296 /* And make sure they dont go over 8 */
297 if(left_peak>0x8)
298 left_peak = 0x8;
299 if(right_peak>0x8)
300 right_peak = 0x8;
302 /* We need the average of both chanels */
303 avg_peak = ( left_peak + right_peak )/2;
305 /* Set the speed to the peak meter */
306 starfield.z_move = avg_peak;
308 } /* if pulse */
309 #else
310 (void) avg_peak;
311 #endif
312 starfield_move_and_draw(&starfield);
314 #ifdef HAVE_LCD_COLOR
315 rb->lcd_set_foreground(LCD_WHITE);
316 #endif
318 /* if a parameter is updated (by the user), we must print it */
319 if (t_disp > 0)
321 --t_disp;
322 rb->snprintf(str_buffer, sizeof(str_buffer),
323 "star:%d speed:%d",
324 starfield.nb_stars,
325 starfield.z_move);
326 #if LCD_DEPTH > 1
327 rb->lcd_set_foreground(LCD_WHITE);
328 #endif
329 rb->lcd_putsxy(0, LCD_HEIGHT-font_h, str_buffer);
331 rb->lcd_update();
333 button = rb->button_get(false);
334 switch(button)
336 case (STARFIELD_INCREASE_ZMOVE):
337 case (STARFIELD_INCREASE_ZMOVE | BUTTON_REPEAT):
338 ++(starfield.z_move);
339 pulse=false;
340 t_disp=MSG_DISP_TIME;
341 break;
342 case (STARFIELD_DECREASE_ZMOVE):
343 case (STARFIELD_DECREASE_ZMOVE | BUTTON_REPEAT):
344 --(starfield.z_move);
345 pulse=false;
346 t_disp=MSG_DISP_TIME;
347 break;
348 case(STARFIELD_INCREASE_NB_STARS):
349 case(STARFIELD_INCREASE_NB_STARS | BUTTON_REPEAT):
350 starfield_add_stars(&starfield, STARFIELD_INCREASE_STEP);
351 t_disp=MSG_DISP_TIME;
352 break;
353 case(STARFIELD_DECREASE_NB_STARS):
354 case(STARFIELD_DECREASE_NB_STARS | BUTTON_REPEAT):
355 starfield_del_stars(&starfield, STARFIELD_INCREASE_STEP);
356 t_disp=MSG_DISP_TIME;
357 break;
358 #ifdef HAVE_LCD_COLOR
359 case(STARFIELD_TOGGLE_COLOR):
360 starfield.color=!starfield.color;
361 break;
362 #endif
363 #ifdef STARFIELD_RC_QUIT
364 case STARFIELD_RC_QUIT:
365 #endif
366 case(STARFIELD_QUIT):
367 case(SYS_USB_CONNECTED):
368 /* Turn on backlight timeout (revert to settings) */
369 backlight_use_settings(rb); /* backlight control in lib/helper.c*/
370 return PLUGIN_OK;
371 break;
376 /*************************** Plugin entry point ****************************/
378 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
380 int ret;
382 rb = api; /* copy to global api pointer */
383 (void)parameter;
384 /* Turn off backlight timeout */
385 backlight_force_on(rb); /* backlight control in lib/helper.c */
387 ret = plugin_main();
389 return ret;
392 #endif /* #ifdef HAVE_LCD_BITMAP */