blob: 44b658e87805f52be5f1e06e8bad5d0b33a9cc9a [file] [log] [blame]
Jens Arnoldf23ab032005-10-07 22:22:07 +00001/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2005 Kevin Ferrare
11*
12* Mystify demo plugin
13*
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.
16*
17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* KIND, either express or implied.
19*
20****************************************************************************/
21
22#include "plugin.h"
23
24#ifdef HAVE_LCD_BITMAP
25
Jens Arnolda36b1d42006-01-15 18:20:18 +000026PLUGIN_HEADER
27
Jens Arnoldf23ab032005-10-07 22:22:07 +000028/* Key assignement */
Dave Chapmanfb4e3842006-02-24 20:54:09 +000029#if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
30 (CONFIG_KEYPAD == IPOD_3G_PAD)
Dave Chapman54d44c82005-12-14 01:31:37 +000031#define DEMYSTIFY_QUIT BUTTON_MENU
32#define DEMYSTIFY_ADD_POLYGON BUTTON_RIGHT
33#define DEMYSTIFY_REMOVE_POLYGON BUTTON_LEFT
34#define DEMYSTIFY_INCREASE_SPEED BUTTON_SCROLL_FWD
35#define DEMYSTIFY_DECREASE_SPEED BUTTON_SCROLL_BACK
Barry Wardell24f4a2a2006-10-26 13:38:09 +000036#elif (CONFIG_KEYPAD == SANSA_E200_PAD)
37#define DEMYSTIFY_QUIT BUTTON_POWER
38#define DEMYSTIFY_ADD_POLYGON BUTTON_RIGHT
39#define DEMYSTIFY_REMOVE_POLYGON BUTTON_LEFT
40#define DEMYSTIFY_INCREASE_SPEED BUTTON_SCROLL_UP
41#define DEMYSTIFY_DECREASE_SPEED BUTTON_SCROLL_DOWN
Daniel Stenberg1e88be52006-08-03 20:17:25 +000042#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
43#define DEMYSTIFY_QUIT BUTTON_POWER
44#define DEMYSTIFY_ADD_POLYGON BUTTON_RIGHT
45#define DEMYSTIFY_REMOVE_POLYGON BUTTON_LEFT
46#define DEMYSTIFY_INCREASE_SPEED BUTTON_SCROLL_UP
47#define DEMYSTIFY_DECREASE_SPEED BUTTON_SCROLL_DOWN
Daniel Stenbergcedba882006-01-18 11:09:06 +000048#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
49#define DEMYSTIFY_QUIT BUTTON_POWER
50#define DEMYSTIFY_ADD_POLYGON BUTTON_RIGHT
51#define DEMYSTIFY_REMOVE_POLYGON BUTTON_LEFT
52#define DEMYSTIFY_INCREASE_SPEED BUTTON_UP
53#define DEMYSTIFY_DECREASE_SPEED BUTTON_DOWN
Marcoen Hirschberg338e2bb2006-02-24 15:42:52 +000054#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
55#define DEMYSTIFY_QUIT BUTTON_A
56#define DEMYSTIFY_ADD_POLYGON BUTTON_RIGHT
57#define DEMYSTIFY_REMOVE_POLYGON BUTTON_LEFT
58#define DEMYSTIFY_INCREASE_SPEED BUTTON_UP
59#define DEMYSTIFY_DECREASE_SPEED BUTTON_DOWN
Dave Chapman54d44c82005-12-14 01:31:37 +000060#else
Jens Arnoldf23ab032005-10-07 22:22:07 +000061#define DEMYSTIFY_QUIT BUTTON_OFF
62#define DEMYSTIFY_ADD_POLYGON BUTTON_UP
63#define DEMYSTIFY_REMOVE_POLYGON BUTTON_DOWN
64#define DEMYSTIFY_INCREASE_SPEED BUTTON_RIGHT
65#define DEMYSTIFY_DECREASE_SPEED BUTTON_LEFT
Kevin Ferrare0e027bd2006-06-30 16:43:47 +000066#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
67 (CONFIG_KEYPAD == IRIVER_H300_PAD)
68#define DEMYSTIFY_RC_QUIT BUTTON_RC_STOP
Kevin Ferrare0028b052006-07-01 10:14:27 +000069#define DEMYSTIFY_RC_ADD_POLYGON BUTTON_RC_BITRATE
70#define DEMYSTIFY_RC_REMOVE_POLYGON BUTTON_RC_SOURCE
71#define DEMYSTIFY_RC_INCREASE_SPEED BUTTON_RC_VOL_UP
72#define DEMYSTIFY_RC_DECREASE_SPEED BUTTON_RC_VOL_DOWN
Kevin Ferrare0e027bd2006-06-30 16:43:47 +000073#endif
Dave Chapman54d44c82005-12-14 01:31:37 +000074#endif
Jens Arnoldf23ab032005-10-07 22:22:07 +000075
76#define DEFAULT_WAIT_TIME 3
77#define DEFAULT_NB_POLYGONS 7
78#define NB_POINTS 4
79#define MAX_STEP_RANGE 7
80#define MIN_STEP_RANGE 3
81#define MAX_POLYGONS 40
82#define MIN_POLYGONS 1
83
Jens Arnold5421e862006-10-30 01:31:32 +000084#ifdef HAVE_LCD_COLOR
85int r,g,b,rc,gc,bc;
86#endif
87
Jens Arnoldf23ab032005-10-07 22:22:07 +000088/******************************* Globals ***********************************/
89
90static struct plugin_api* rb; /* global api struct pointer */
91
92/*
93 * Compute a new random step to make the point bounce the borders of the screen
94 */
95
96int get_new_step(int step)
97{
98 if(step>0)
99 return -(MIN_STEP_RANGE + rb->rand() % (MAX_STEP_RANGE-MIN_STEP_RANGE));
100 else
101 return (MIN_STEP_RANGE + rb->rand() % (MAX_STEP_RANGE-MIN_STEP_RANGE));
102}
103
104/*
105 * Point Stuffs
106 */
107
108struct point
109{
110 int x;
111 int y;
112};
113
114/*
115 * Polygon Stuffs
116 */
117
118struct polygon
119{
120 struct point points[NB_POINTS];
121};
122
123/*
124 * Generates a random polygon (which fits the screen size though)
125 */
Kevin Ferrare0028b052006-07-01 10:14:27 +0000126void polygon_init(struct polygon * polygon, struct screen * display)
Jens Arnoldf23ab032005-10-07 22:22:07 +0000127{
128 int i;
129 for(i=0;i<NB_POINTS;++i)
130 {
Kevin Ferrare0028b052006-07-01 10:14:27 +0000131 polygon->points[i].x=(rb->rand() % (display->width));
132 polygon->points[i].y=(rb->rand() % (display->height));
Jens Arnoldf23ab032005-10-07 22:22:07 +0000133 }
134}
135
136/*
137 * Draw the given polygon onto the screen
138 */
139
Kevin Ferrare0028b052006-07-01 10:14:27 +0000140void polygon_draw(struct polygon * polygon, struct screen * display)
Jens Arnoldf23ab032005-10-07 22:22:07 +0000141{
142 int i;
143 for(i=0;i<NB_POINTS-1;++i)
144 {
Kevin Ferrare0028b052006-07-01 10:14:27 +0000145 display->drawline(polygon->points[i].x, polygon->points[i].y,
Jens Arnoldf23ab032005-10-07 22:22:07 +0000146 polygon->points[i+1].x, polygon->points[i+1].y);
147 }
Kevin Ferrare0028b052006-07-01 10:14:27 +0000148 display->drawline(polygon->points[0].x, polygon->points[0].y,
Jens Arnoldf23ab032005-10-07 22:22:07 +0000149 polygon->points[NB_POINTS-1].x,
150 polygon->points[NB_POINTS-1].y);
151}
152
153/*
154 * Polygon moving data Stuffs
155 */
156
157struct polygon_move
158{
159 struct point move_steps[NB_POINTS];
160};
161
162void polygon_move_init(struct polygon_move * polygon_move)
163{
164 int i;
165 for(i=0;i<NB_POINTS;++i)
166 {
167 polygon_move->move_steps[i].x=get_new_step(-1);
168 /* -1 because we want a positive random step */
169 polygon_move->move_steps[i].y=get_new_step(-1);
170 }
171}
172
173/*
174 * Update the given polygon's position according to the given informations in
175 * polygon_move (polygon_move may be updated)
176 */
Kevin Ferrare0028b052006-07-01 10:14:27 +0000177void polygon_update(struct polygon *polygon, struct screen * display, struct polygon_move *polygon_move)
Jens Arnoldf23ab032005-10-07 22:22:07 +0000178{
179 int i, x, y, step;
180 for(i=0;i<NB_POINTS;++i)
181 {
182 x=polygon->points[i].x;
183 step=polygon_move->move_steps[i].x;
184 x+=step;
185 if(x<=0)
186 {
187 x=1;
188 polygon_move->move_steps[i].x=get_new_step(step);
189 }
Kevin Ferrare0028b052006-07-01 10:14:27 +0000190 else if(x>=display->width)
Jens Arnoldf23ab032005-10-07 22:22:07 +0000191 {
Kevin Ferrare0028b052006-07-01 10:14:27 +0000192 x=display->width-1;
Jens Arnoldf23ab032005-10-07 22:22:07 +0000193 polygon_move->move_steps[i].x=get_new_step(step);
194 }
195 polygon->points[i].x=x;
196
197 y=polygon->points[i].y;
198 step=polygon_move->move_steps[i].y;
199 y+=step;
200 if(y<=0)
201 {
202 y=1;
203 polygon_move->move_steps[i].y=get_new_step(step);
204 }
Kevin Ferrare0028b052006-07-01 10:14:27 +0000205 else if(y>=display->height)
Jens Arnoldf23ab032005-10-07 22:22:07 +0000206 {
Kevin Ferrare0028b052006-07-01 10:14:27 +0000207 y=display->height-1;
Jens Arnoldf23ab032005-10-07 22:22:07 +0000208 polygon_move->move_steps[i].y=get_new_step(step);
209 }
210 polygon->points[i].y=y;
211 }
212}
213
214/*
215 * Polygon fifo Stuffs
216 */
217
218struct polygon_fifo
219{
220 int fifo_tail;
221 int fifo_head;
222 int nb_items;
223 struct polygon tab[MAX_POLYGONS];
224};
225
226void fifo_init(struct polygon_fifo * fifo)
227{
228 fifo->fifo_tail=0;
229 fifo->fifo_head=0;
230 fifo->nb_items=0;
231}
232
233void fifo_push(struct polygon_fifo * fifo, struct polygon * polygon)
234{
235 if(fifo->nb_items>=MAX_POLYGONS)
236 return;
237 ++(fifo->nb_items);
238
239 /*
240 * Workaround for gcc (which uses memcpy internally) to avoid link error
241 * fifo->tab[fifo->fifo_head]=polygon
242 */
243 rb->memcpy(&(fifo->tab[fifo->fifo_head]), polygon, sizeof(struct polygon));
244 ++(fifo->fifo_head);
245 if(fifo->fifo_head>=MAX_POLYGONS)
246 fifo->fifo_head=0;
247}
248
249struct polygon * fifo_pop(struct polygon_fifo * fifo)
250{
251 int index;
252 if(fifo->nb_items==0)
253 return(NULL);
254 --(fifo->nb_items);
255 index=fifo->fifo_tail;
256 ++(fifo->fifo_tail);
257 if(fifo->fifo_tail>=MAX_POLYGONS)
258 fifo->fifo_tail=0;
259 return(&(fifo->tab[index]));
260}
261
262/*
263 * Drawing stuffs
264 */
265
Kevin Ferrare0028b052006-07-01 10:14:27 +0000266void polygons_draw(struct polygon_fifo * polygons, struct screen * display)
Jens Arnoldf23ab032005-10-07 22:22:07 +0000267{
268 int i, j;
269 for(i=0, j=polygons->fifo_tail;i<polygons->nb_items;++i, ++j)
270 {
271 if(j>=MAX_POLYGONS)
272 j=0;
Kevin Ferrare0028b052006-07-01 10:14:27 +0000273 polygon_draw(&(polygons->tab[j]), display);
Jens Arnoldf23ab032005-10-07 22:22:07 +0000274 }
275}
276
Jens Arnoldf23ab032005-10-07 22:22:07 +0000277void cleanup(void *parameter)
278{
279 (void)parameter;
Kevin Ferrare0028b052006-07-01 10:14:27 +0000280
281 rb->screens[SCREEN_MAIN]->backlight_set_timeout(rb->global_settings->backlight_timeout);
282#if NB_SCREENS==2
283 rb->screens[SCREEN_REMOTE]->backlight_set_timeout(rb->global_settings->remote_backlight_timeout);
284#endif
Jens Arnoldf23ab032005-10-07 22:22:07 +0000285}
286
Jens Arnold5421e862006-10-30 01:31:32 +0000287#ifdef HAVE_LCD_COLOR
288void new_color(void)
289{
290 r = rb->rand()%255;
291 g = rb->rand()%255;
292 b = rb->rand()%255;
293}
294
295void change_color(void)
296{
297 if(rc<r)
298 ++rc;
299 else if(rc>r)
300 --rc;
301 if(gc<g)
302 ++gc;
303 else if(gc>g)
304 --gc;
305 if(bc<b)
306 ++bc;
307 else if(bc>b)
308 --bc;
309 rb->lcd_set_foreground(LCD_RGBPACK(rc,gc,bc));
310 if(rc==r && gc==g && bc==b)
311 new_color();
312}
313#endif
314
Jens Arnoldf23ab032005-10-07 22:22:07 +0000315/*
316 * Main function
317 */
318
319int plugin_main(void)
320{
321 int button;
322 int sleep_time=DEFAULT_WAIT_TIME;
323 int nb_wanted_polygons=DEFAULT_NB_POLYGONS;
Kevin Ferrare0028b052006-07-01 10:14:27 +0000324 int i;
325 struct polygon_fifo polygons[NB_SCREENS];
326 struct polygon_move move[NB_SCREENS]; /* This describes the movement of the leading
327 polygon, the others just follow */
328 struct polygon leading_polygon[NB_SCREENS];
329 FOR_NB_SCREENS(i)
330 {
Jens Arnold5421e862006-10-30 01:31:32 +0000331#ifdef HAVE_LCD_COLOR
332 struct screen *display = rb->screens[i];
333 if (display->depth > 8)
334 display->set_background(LCD_BLACK);
335#endif
Kevin Ferrare0028b052006-07-01 10:14:27 +0000336 fifo_init(&polygons[i]);
337 polygon_move_init(&move[i]);
338 polygon_init(&leading_polygon[i], rb->screens[i]);
339 }
Jens Arnold5421e862006-10-30 01:31:32 +0000340
341#ifdef HAVE_LCD_COLOR
342 new_color();
343 rc = r;
344 gc = g;
345 bc = b;
346#endif
347
Jens Arnoldf23ab032005-10-07 22:22:07 +0000348 while (true)
349 {
Kevin Ferrare0028b052006-07-01 10:14:27 +0000350 FOR_NB_SCREENS(i)
351 {
352 struct screen * display=rb->screens[i];
353 if(polygons[i].nb_items>nb_wanted_polygons)
354 { /* We have too many polygons, we must drop some of them */
355 fifo_pop(&polygons[i]);
356 }
357 if(nb_wanted_polygons==polygons[i].nb_items)
358 { /* We have the good number of polygons, we can safely drop
359 the last one to add the new one later */
360 fifo_pop(&polygons[i]);
361 }
362 fifo_push(&polygons[i], &leading_polygon[i]);
363
364 /*
365 * Then we update the leading polygon for the next round acording to
366 * current move (the move may be altered in case of sreen border
367 * collision)
368 */
369 polygon_update(&leading_polygon[i], display, &move[i]);
370
371 /* Now the drawing part */
372
Jens Arnold5421e862006-10-30 01:31:32 +0000373#ifdef HAVE_LCD_COLOR
374 if (display->depth > 8)
375 display->set_foreground(SCREEN_COLOR_TO_NATIVE(display,
376 LCD_RGBPACK(rc, gc, bc)));
377#endif
Kevin Ferrare0028b052006-07-01 10:14:27 +0000378 display->clear_display();
379 polygons_draw(&polygons[i], display);
380 display->update();
Jens Arnoldf23ab032005-10-07 22:22:07 +0000381 }
Jens Arnold5421e862006-10-30 01:31:32 +0000382#ifdef HAVE_LCD_COLOR
383 change_color();
384#endif
Jens Arnoldf23ab032005-10-07 22:22:07 +0000385 /* Speed handling*/
386 if (sleep_time<0)/* full speed */
387 rb->yield();
388 else
389 rb->sleep(sleep_time);
390
391 /* Handle the user events */
392 button = rb->button_get(false);
393 switch(button)
394 {
Kevin Ferrare0e027bd2006-06-30 16:43:47 +0000395#ifdef DEMYSTIFY_RC_QUIT
396 case DEMYSTIFY_RC_QUIT :
397#endif
Kevin Ferrare0028b052006-07-01 10:14:27 +0000398 case DEMYSTIFY_QUIT:
Jens Arnoldf23ab032005-10-07 22:22:07 +0000399 cleanup(NULL);
400 return PLUGIN_OK;
Kevin Ferrare0028b052006-07-01 10:14:27 +0000401#ifdef DEMYSTIFY_RC_ADD_POLYGON
402 case DEMYSTIFY_RC_ADD_POLYGON:
403#endif
404 case DEMYSTIFY_ADD_POLYGON:
Jens Arnoldf23ab032005-10-07 22:22:07 +0000405 if(nb_wanted_polygons<MAX_POLYGONS)
406 ++nb_wanted_polygons;
407 break;
408
Kevin Ferrare0028b052006-07-01 10:14:27 +0000409#ifdef DEMYSTIFY_RC_REMOVE_POLYGON
410 case DEMYSTIFY_RC_REMOVE_POLYGON:
411#endif
412 case DEMYSTIFY_REMOVE_POLYGON:
Jens Arnoldf23ab032005-10-07 22:22:07 +0000413 if(nb_wanted_polygons>MIN_POLYGONS)
414 --nb_wanted_polygons;
415 break;
416
Kevin Ferrare0028b052006-07-01 10:14:27 +0000417#ifdef DEMYSTIFY_RC_INCREASE_SPEED
418 case DEMYSTIFY_RC_INCREASE_SPEED:
419#endif
420 case DEMYSTIFY_INCREASE_SPEED:
Jens Arnoldf23ab032005-10-07 22:22:07 +0000421 if(sleep_time>=0)
422 --sleep_time;
423 break;
424
Kevin Ferrare0028b052006-07-01 10:14:27 +0000425#ifdef DEMYSTIFY_RC_DECREASE_SPEED
426 case DEMYSTIFY_RC_DECREASE_SPEED:
427#endif
428 case DEMYSTIFY_DECREASE_SPEED:
Jens Arnoldf23ab032005-10-07 22:22:07 +0000429 ++sleep_time;
430 break;
431
432 default:
433 if (rb->default_event_handler_ex(button, cleanup, NULL)
434 == SYS_USB_CONNECTED)
435 return PLUGIN_USB_CONNECTED;
436 break;
437 }
438 }
439}
440
441/*************************** Plugin entry point ****************************/
442
443enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
444{
445 int ret;
Jens Arnoldf23ab032005-10-07 22:22:07 +0000446
447 rb = api; /* copy to global api pointer */
448 (void)parameter;
449 if (rb->global_settings->backlight_timeout > 0)
Kevin Ferrare0028b052006-07-01 10:14:27 +0000450 {
451 int i;
452 FOR_NB_SCREENS(i)
453 rb->screens[i]->backlight_set_timeout(1);/* keep the light on */
454 }
Jens Arnoldf23ab032005-10-07 22:22:07 +0000455 ret = plugin_main();
456
457 return ret;
458}
459
460#endif /* #ifdef HAVE_LCD_BITMAP */