1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * Copyright (C) 2005 Kevin Ferrare
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
21 #include "lib/helper.h"
22 #include "lib/pluginlib_exit.h"
23 #include "lib/pluginlib_actions.h"
24 /******************************* Globals ***********************************/
25 /* this set the context to use with PLA */
26 static const struct button_mapping
*plugin_contexts
[] = { pla_main_ctx
};
29 #define STARFIELD_QUIT PLA_EXIT
30 #define STARFIELD_QUIT2 PLA_CANCEL
31 #define STARFIELD_INCREASE_ZMOVE PLA_UP
32 #define STARFIELD_INCREASE_ZMOVE_REPEAT PLA_UP_REPEAT
33 #define STARFIELD_DECREASE_ZMOVE PLA_DOWN
34 #define STARFIELD_DECREASE_ZMOVE_REPEAT PLA_DOWN_REPEAT
35 #define STARFIELD_INCREASE_NB_STARS PLA_RIGHT
36 #define STARFIELD_INCREASE_NB_STARS_REPEAT PLA_RIGHT_REPEAT
37 #define STARFIELD_DECREASE_NB_STARS PLA_LEFT
38 #define STARFIELD_DECREASE_NB_STARS_REPEAT PLA_LEFT_REPEAT
39 #define STARFIELD_TOGGLE_COLOR PLA_SELECT
41 #define LCD_CENTER_X (LCD_WIDTH/2)
42 #define LCD_CENTER_Y (LCD_HEIGHT/2)
43 #define Z_MAX_DIST 100
45 #define MAX_STARS (LCD_WIDTH*LCD_HEIGHT*20)/100
46 #define INIT_STARS 200
47 #define STARFIELD_INCREASE_STEP 50
48 #define INIT_SPACE_SPEED 1
49 #define STAR_MAX_VELOCITY 2
51 * max 3d coord in the 2d screen :
53 * x2d=x3d/z+LCD_CENTER_X (+LCD_CENTER_X to center ...)
55 * max_x2d=max_x3d/max_z+LCD_CENTER_X
56 * max_x3d=(max_x2d-LCD_CENTER_X)*max_z
61 * max_x3d=(LCD_WIDTH-LCD_CENTER_X)*Z_MAX_DIST
62 * max_x3d=LCD_CENTER_X*Z_MAX_DIST
65 #define MAX_INIT_STAR_X LCD_CENTER_X*Z_MAX_DIST
66 #define MAX_INIT_STAR_Y LCD_CENTER_Y*Z_MAX_DIST
68 #define MSG_DISP_TIME 30
82 static inline void star_init(struct star
* star
, int z_move
, bool color
)
84 star
->velocity
=rb
->rand() % STAR_MAX_VELOCITY
+1;
85 /* choose x between -MAX_INIT_STAR_X and MAX_INIT_STAR_X */
86 star
->x
=rb
->rand() % (2*MAX_INIT_STAR_X
)-MAX_INIT_STAR_X
;
87 star
->y
=rb
->rand() % (2*MAX_INIT_STAR_Y
)-MAX_INIT_STAR_Y
;
90 star
->color
=LCD_RGBPACK(rb
->rand()%128+128,rb
->rand()%128+128,
93 star
->color
=LCD_WHITE
;
100 star
->z
=rb
->rand() %Z_MAX_DIST
/2+1;
103 static inline void star_move(struct star
* star
, int z_move
, bool color
)
105 star
->z
-= z_move
*star
->velocity
;
106 if (star
->z
<= 0 || star
->z
> Z_MAX_DIST
)
107 star_init(star
, z_move
, color
);
110 static inline void star_draw(struct star
* star
, int z_move
, bool color
)
114 * 3d -> 2d : projection on the screen : x2d=x3d/z (thales theorem)
115 * we put the star in the center of the screen
117 x_draw
= star
->x
/ star
->z
+ LCD_CENTER_X
;
118 if (x_draw
< 1 || x_draw
>= LCD_WIDTH
)
120 star_init(star
, z_move
, color
);
123 y_draw
= star
->y
/ star
->z
+ LCD_CENTER_Y
;
124 if (y_draw
< 1 || y_draw
>= LCD_HEIGHT
)
126 star_init(star
, z_move
, color
);
130 #ifdef HAVE_LCD_COLOR
131 rb
->lcd_set_foreground(star
->color
);
134 rb
->lcd_drawpixel(x_draw
, y_draw
);
135 if(star
->z
<5*Z_MAX_DIST
/6)
137 rb
->lcd_drawpixel(x_draw
, y_draw
- 1);
138 rb
->lcd_drawpixel(x_draw
- 1, y_draw
);
139 if(star
->z
<Z_MAX_DIST
/2)
141 rb
->lcd_drawpixel(x_draw
+ 1, y_draw
);
142 rb
->lcd_drawpixel(x_draw
, y_draw
+ 1);
148 * Whole starfield operations
152 struct star tab
[MAX_STARS
];
158 static inline void starfield_init(struct starfield
* starfield
)
160 starfield
->nb_stars
=0;
161 starfield
->z_move
=INIT_SPACE_SPEED
;
162 starfield
->color
=false;
165 static inline void starfield_add_stars(struct starfield
* starfield
,
169 old_nb_stars
=starfield
->nb_stars
;
170 starfield
->nb_stars
+=nb_to_add
;
172 if(starfield
->nb_stars
> MAX_STARS
)
173 starfield
->nb_stars
=MAX_STARS
;
175 for( i
=old_nb_stars
; i
< starfield
->nb_stars
; ++i
)
177 star_init( &(starfield
->tab
[i
]), starfield
->z_move
, starfield
->color
);
181 static inline void starfield_del_stars(struct starfield
* starfield
,
184 starfield
->nb_stars
-=nb_to_add
;
185 if(starfield
->nb_stars
<0)
186 starfield
->nb_stars
=0;
189 static inline void starfield_move_and_draw(struct starfield
* starfield
)
192 for(i
=0;i
<starfield
->nb_stars
;++i
)
194 star_move(&(starfield
->tab
[i
]), starfield
->z_move
, starfield
->color
);
195 star_draw(&(starfield
->tab
[i
]), starfield
->z_move
, starfield
->color
);
199 static struct starfield starfield
;
201 static int plugin_main(void)
203 int button
, avg_peak
, t_disp
=0;
205 bool pulse
__attribute__ ((unused
)) = true; /* 'unused' resolves warnings */
206 rb
->lcd_getstringsize("A", &font_w
, &font_h
);
207 starfield_init(&starfield
);
208 starfield_add_stars(&starfield
, INIT_STARS
);
211 rb
->lcd_set_backdrop(NULL
);
213 #ifdef HAVE_LCD_COLOR
214 rb
->lcd_set_background(LCD_BLACK
);
215 rb
->lcd_set_foreground(LCD_WHITE
);
221 rb
->lcd_clear_display();
223 #if ((CONFIG_CODEC == SWCODEC) || !defined(SIMULATOR) && \
224 ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)))
226 /* This will make the stars pulse to the music */
229 /* Get the peaks. ( Borrowed from vu_meter ) */
230 #if (CONFIG_CODEC == SWCODEC)
231 static struct pcm_peaks peaks
;
232 rb
->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK
,
234 #define left_peak peaks.left
235 #define right_peak peaks.right
237 int left_peak
= rb
->mas_codec_readreg(0xC);
238 int right_peak
= rb
->mas_codec_readreg(0xD);
240 /* Devide peak data by 4098 to bring the max
241 value down from ~32k to 8 */
242 left_peak
= left_peak
/0x1000;
243 right_peak
= right_peak
/0x1000;
245 /* Make sure they dont stop */
251 /* And make sure they dont go over 8 */
257 /* We need the average of both chanels */
258 avg_peak
= ( left_peak
+ right_peak
)/2;
260 /* Set the speed to the peak meter */
261 starfield
.z_move
= avg_peak
;
267 starfield_move_and_draw(&starfield
);
269 #ifdef HAVE_LCD_COLOR
270 rb
->lcd_set_foreground(LCD_WHITE
);
273 /* if a parameter is updated (by the user), we must print it */
277 #ifdef HAVE_LCD_COLOR
278 rb
->lcd_set_foreground(LCD_WHITE
);
280 rb
->lcd_putsxyf(0, LCD_HEIGHT
-font_h
, "star:%d speed:%d",
281 starfield
.nb_stars
, starfield
.z_move
);
285 /*We get button from PLA this way */
286 button
= pluginlib_getaction(TIMEOUT_NOBLOCK
, plugin_contexts
,
287 ARRAYLEN(plugin_contexts
));
291 case (STARFIELD_INCREASE_ZMOVE
):
292 case (STARFIELD_INCREASE_ZMOVE_REPEAT
):
293 ++(starfield
.z_move
);
295 t_disp
=MSG_DISP_TIME
;
297 case (STARFIELD_DECREASE_ZMOVE
):
298 case (STARFIELD_DECREASE_ZMOVE_REPEAT
):
299 --(starfield
.z_move
);
301 t_disp
=MSG_DISP_TIME
;
303 case(STARFIELD_INCREASE_NB_STARS
):
304 case(STARFIELD_INCREASE_NB_STARS_REPEAT
):
305 starfield_add_stars(&starfield
, STARFIELD_INCREASE_STEP
);
306 t_disp
=MSG_DISP_TIME
;
308 case(STARFIELD_DECREASE_NB_STARS
):
309 case(STARFIELD_DECREASE_NB_STARS_REPEAT
):
310 starfield_del_stars(&starfield
, STARFIELD_INCREASE_STEP
);
311 t_disp
=MSG_DISP_TIME
;
313 #ifdef HAVE_LCD_COLOR
314 case(STARFIELD_TOGGLE_COLOR
):
315 starfield
.color
=!starfield
.color
;
318 case(STARFIELD_QUIT
):
319 case(STARFIELD_QUIT2
):
329 /*************************** Plugin entry point ****************************/
331 enum plugin_status
plugin_start(const void* parameter
)
336 /* Turn off backlight timeout */
337 backlight_ignore_timeout();
341 /* Turn on backlight timeout (revert to settings) */
342 backlight_use_settings();