1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Kevin Ferrare
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
26 #ifdef HAVE_LCD_BITMAP
27 #include "lib/pluginlib_actions.h"
28 #include "lib/helper.h"
31 #define DEFAULT_WAIT_TIME 3
32 #define DEFAULT_NB_POLYGONS 7
34 #define MAX_STEP_RANGE 7
35 #define MIN_STEP_RANGE 3
36 #define MAX_POLYGONS 40
37 #define MIN_POLYGONS 1
40 #define DEMYSTIFY_QUIT PLA_CANCEL
42 #ifdef HAVE_SCROLLWHEEL
44 #define DEMYSTIFY_INCREASE_SPEED PLA_SCROLL_FWD
45 #define DEMYSTIFY_DECREASE_SPEED PLA_SCROLL_BACK
46 #define DEMYSTIFY_INCREASE_SPEED_REPEAT PLA_SCROLL_FWD_REPEAT
47 #define DEMYSTIFY_DECREASE_SPEED_REPEAT PLA_SCROLL_BACK_REPEAT
49 #define DEMYSTIFY_INCREASE_SPEED PLA_RIGHT
50 #define DEMYSTIFY_DECREASE_SPEED PLA_LEFT
51 #define DEMYSTIFY_INCREASE_SPEED_REPEAT PLA_RIGHT_REPEAT
52 #define DEMYSTIFY_DECREASE_SPEED_REPEAT PLA_LEFT_REPEAT
55 #define DEMYSTIFY_ADD_POLYGON PLA_UP
56 #define DEMYSTIFY_REMOVE_POLYGON PLA_DOWN
57 #define DEMYSTIFY_ADD_POLYGON_REPEAT PLA_UP_REPEAT
58 #define DEMYSTIFY_REMOVE_POLYGON_REPEAT PLA_DOWN_REPEAT
60 const struct button_mapping
*plugin_contexts
[]
62 #if defined(HAVE_REMOTE_LCD)
71 int current_r
,current_g
,current_b
;
75 /******************************* Globals ***********************************/
78 * Compute a new random step to make the point bounce the borders of the screen
81 int get_new_step(int step
)
84 return -(MIN_STEP_RANGE
+ rb
->rand() % (MAX_STEP_RANGE
-MIN_STEP_RANGE
));
86 return (MIN_STEP_RANGE
+ rb
->rand() % (MAX_STEP_RANGE
-MIN_STEP_RANGE
));
105 struct point points
[NB_POINTS
];
109 * Generates a random polygon (which fits the screen size though)
111 void polygon_init(struct polygon
* polygon
, struct screen
* display
)
114 for(i
=0;i
<NB_POINTS
;++i
)
116 polygon
->points
[i
].x
=(rb
->rand() % (display
->getwidth()));
117 polygon
->points
[i
].y
=(rb
->rand() % (display
->getheight()));
122 * Draw the given polygon onto the screen
125 void polygon_draw(struct polygon
* polygon
, struct screen
* display
)
128 for(i
=0;i
<NB_POINTS
-1;++i
)
130 display
->drawline(polygon
->points
[i
].x
, polygon
->points
[i
].y
,
131 polygon
->points
[i
+1].x
, polygon
->points
[i
+1].y
);
133 display
->drawline(polygon
->points
[0].x
, polygon
->points
[0].y
,
134 polygon
->points
[NB_POINTS
-1].x
,
135 polygon
->points
[NB_POINTS
-1].y
);
139 * Polygon moving data Stuffs
144 struct point move_steps
[NB_POINTS
];
147 void polygon_move_init(struct polygon_move
* polygon_move
)
150 for(i
=0;i
<NB_POINTS
;++i
)
152 polygon_move
->move_steps
[i
].x
=get_new_step(-1);
153 /* -1 because we want a positive random step */
154 polygon_move
->move_steps
[i
].y
=get_new_step(-1);
159 * Update the given polygon's position according to the given informations in
160 * polygon_move (polygon_move may be updated)
162 void polygon_update(struct polygon
*polygon
, struct screen
* display
, struct polygon_move
*polygon_move
)
165 for(i
=0;i
<NB_POINTS
;++i
)
167 x
=polygon
->points
[i
].x
;
168 step
=polygon_move
->move_steps
[i
].x
;
173 polygon_move
->move_steps
[i
].x
=get_new_step(step
);
175 else if(x
>=display
->getwidth())
177 x
=display
->getwidth()-1;
178 polygon_move
->move_steps
[i
].x
=get_new_step(step
);
180 polygon
->points
[i
].x
=x
;
182 y
=polygon
->points
[i
].y
;
183 step
=polygon_move
->move_steps
[i
].y
;
188 polygon_move
->move_steps
[i
].y
=get_new_step(step
);
190 else if(y
>=display
->getheight())
192 y
=display
->getheight()-1;
193 polygon_move
->move_steps
[i
].y
=get_new_step(step
);
195 polygon
->points
[i
].y
=y
;
200 * Polygon fifo Stuffs
208 struct polygon tab
[MAX_POLYGONS
];
211 void fifo_init(struct polygon_fifo
* fifo
)
218 void fifo_push(struct polygon_fifo
* fifo
, struct polygon
* polygon
)
220 if(fifo
->nb_items
>=MAX_POLYGONS
)
225 * Workaround for gcc (which uses memcpy internally) to avoid link error
226 * fifo->tab[fifo->fifo_head]=polygon
228 rb
->memcpy(&(fifo
->tab
[fifo
->fifo_head
]), polygon
, sizeof(struct polygon
));
230 if(fifo
->fifo_head
>=MAX_POLYGONS
)
234 struct polygon
* fifo_pop(struct polygon_fifo
* fifo
)
237 if(fifo
->nb_items
==0)
240 index
=fifo
->fifo_tail
;
242 if(fifo
->fifo_tail
>=MAX_POLYGONS
)
244 return(&(fifo
->tab
[index
]));
251 void polygons_draw(struct polygon_fifo
* polygons
, struct screen
* display
)
254 for(i
=0, j
=polygons
->fifo_tail
;i
<polygons
->nb_items
;++i
, ++j
)
258 polygon_draw(&(polygons
->tab
[j
]), display
);
262 void cleanup(void *parameter
)
266 backlight_use_settings();
267 #ifdef HAVE_REMOTE_LCD
268 remote_backlight_use_settings();
272 #ifdef HAVE_LCD_COLOR
273 void color_randomize(struct line_color
* color
)
275 color
->r
= rb
->rand()%255;
276 color
->g
= rb
->rand()%255;
277 color
->b
= rb
->rand()%255;
280 void color_init(struct line_color
* color
)
282 color_randomize(color
);
283 color
->current_r
=color
->r
;
284 color
->current_g
=color
->g
;
285 color
->current_b
=color
->b
;
288 void color_change(struct line_color
* color
)
290 if(color
->current_r
<color
->r
)
292 else if(color
->current_r
>color
->r
)
294 if(color
->current_g
<color
->g
)
296 else if(color
->current_g
>color
->g
)
298 if(color
->current_b
<color
->b
)
300 else if(color
->current_b
>color
->b
)
303 if(color
->current_r
==color
->r
&&
304 color
->current_g
==color
->g
&&
305 color
->current_b
==color
->b
)
306 color_randomize(color
);
309 #define COLOR_RGBPACK(color) \
310 LCD_RGBPACK((color)->current_r, (color)->current_g, (color)->current_b)
312 void color_apply(struct line_color
* color
, struct screen
* display
)
314 if (display
->is_color
){
316 SCREEN_COLOR_TO_NATIVE(display
,COLOR_RGBPACK(color
));
317 display
->set_foreground(foreground
);
326 int plugin_main(void)
329 int sleep_time
=DEFAULT_WAIT_TIME
;
330 int nb_wanted_polygons
=DEFAULT_NB_POLYGONS
;
332 struct polygon_fifo polygons
[NB_SCREENS
];
333 struct polygon_move move
[NB_SCREENS
]; /* This describes the movement of the leading
334 polygon, the others just follow */
335 struct polygon leading_polygon
[NB_SCREENS
];
338 #ifdef HAVE_LCD_COLOR
339 struct screen
*display
= rb
->screens
[i
];
340 if (display
->is_color
)
341 display
->set_background(LCD_BLACK
);
343 fifo_init(&polygons
[i
]);
344 polygon_move_init(&move
[i
]);
345 polygon_init(&leading_polygon
[i
], rb
->screens
[i
]);
348 #ifdef HAVE_LCD_COLOR
349 struct line_color color
;
357 struct screen
* display
=rb
->screens
[i
];
358 if(polygons
[i
].nb_items
>nb_wanted_polygons
)
359 { /* We have too many polygons, we must drop some of them */
360 fifo_pop(&polygons
[i
]);
362 if(nb_wanted_polygons
==polygons
[i
].nb_items
)
363 { /* We have the good number of polygons, we can safely drop
364 the last one to add the new one later */
365 fifo_pop(&polygons
[i
]);
367 fifo_push(&polygons
[i
], &leading_polygon
[i
]);
370 * Then we update the leading polygon for the next round acording to
371 * current move (the move may be altered in case of sreen border
374 polygon_update(&leading_polygon
[i
], display
, &move
[i
]);
376 /* Now the drawing part */
377 #ifdef HAVE_LCD_COLOR
378 color_apply(&color
, display
);
380 display
->clear_display();
381 polygons_draw(&polygons
[i
], display
);
384 #ifdef HAVE_LCD_COLOR
385 color_change(&color
);
388 if (sleep_time
<0)/* full speed */
391 rb
->sleep(sleep_time
);
392 action
= pluginlib_getaction(TIMEOUT_NOBLOCK
,
393 plugin_contexts
, ARRAYLEN(plugin_contexts
));
400 case DEMYSTIFY_ADD_POLYGON
:
401 case DEMYSTIFY_ADD_POLYGON_REPEAT
:
402 if(nb_wanted_polygons
<MAX_POLYGONS
)
403 ++nb_wanted_polygons
;
406 case DEMYSTIFY_REMOVE_POLYGON
:
407 case DEMYSTIFY_REMOVE_POLYGON_REPEAT
:
408 if(nb_wanted_polygons
>MIN_POLYGONS
)
409 --nb_wanted_polygons
;
412 case DEMYSTIFY_INCREASE_SPEED
:
413 case DEMYSTIFY_INCREASE_SPEED_REPEAT
:
418 case DEMYSTIFY_DECREASE_SPEED
:
419 case DEMYSTIFY_DECREASE_SPEED_REPEAT
:
424 if (rb
->default_event_handler_ex(action
, cleanup
, NULL
)
425 == SYS_USB_CONNECTED
)
426 return PLUGIN_USB_CONNECTED
;
432 /*************************** Plugin entry point ****************************/
434 enum plugin_status
plugin_start(const void* parameter
)
440 rb
->lcd_set_backdrop(NULL
);
442 backlight_force_on(); /* backlight control in lib/helper.c */
443 #ifdef HAVE_REMOTE_LCD
444 remote_backlight_force_on(); /* remote backlight control in lib/helper.c */
451 #endif /* #ifdef HAVE_LCD_BITMAP */