1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
12 * My crack at making a 80's style retro plasma effect for the fantastic
14 * Okay, I could've hard-coded the sine wave values, I just wanted the
15 * challange of calculating them! silly: maybe, fun: yes!
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23 * KIND, either express or implied.
25 ****************************************************************************/
28 #include "lib/helper.h"
29 #include "lib/pluginlib_actions.h"
31 #ifdef HAVE_LCD_BITMAP
33 #ifndef HAVE_LCD_COLOR
36 #include "lib/fixedpoint.h"
40 /******************************* Globals ***********************************/
42 static unsigned char wave_array
[256]; /* Pre calculated wave array */
44 static fb_data colours
[256]; /* Smooth transition of shades */
45 static int redfactor
= 1, greenfactor
= 2, bluefactor
= 3;
46 static int redphase
= 0, greenphase
= 50, bluephase
= 100;
47 /* lower chance of gray at regular intervals */
50 static unsigned char colours
[256]; /* Smooth transition of shades */
51 static unsigned char greybuffer
[LCD_HEIGHT
*LCD_WIDTH
]; /* off screen buffer */
52 static unsigned char *gbuf
;
53 static size_t gbuf_size
= 0;
55 static unsigned char sp1
, sp2
, sp3
, sp4
; /* Speed of plasma */
56 static int plasma_frequency
;
57 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
58 static bool boosted
= false;
61 static const struct button_mapping
* plugin_contexts
[]= {
63 #if defined(HAVE_REMOTE_LCD)
71 * Main wave function so we don't have to re-calc the sine
72 * curve every time. Mess around WAV_AMP and FREQ to make slighlty
73 * weirder looking plasmas!
76 static void wave_table_generate(void)
81 wave_array
[i
] = (unsigned char)((WAV_AMP
82 * (fp14_sin((i
* 360 * plasma_frequency
) / 256))) / 16384);
87 /* Make a smooth colour cycle. */
88 void shades_generate(int time
)
91 unsigned red
, green
, blue
;
92 unsigned r
= time
* redfactor
+ redphase
;
93 unsigned g
= time
* greenfactor
+ greenphase
;
94 unsigned b
= time
* bluefactor
+ bluephase
;
96 for(i
=0; i
< 256; ++i
)
98 r
&= 0xFF; g
&= 0xFF; b
&= 0xFF;
110 colours
[i
] = LCD_RGBPACK(red
, green
, blue
);
114 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
115 rb
->lcd_pal256_update_pal(colours
);
119 /* Make a smooth shade from black into white and back into black again. */
120 static void shades_generate(void)
124 for(i
=0; i
< 256; ++i
)
134 void cleanup(void *parameter
)
138 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
140 rb
->cpu_boost(false);
142 #ifndef HAVE_LCD_COLOR
145 /* Turn on backlight timeout (revert to settings) */
146 backlight_use_settings(); /* backlight control in lib/helper.c */
150 * Main function that also contain the main plasma
156 plasma_frequency
= 1;
157 int action
, delay
, x
, y
;
158 unsigned char p1
,p2
,p3
,p4
,t1
,t2
,t3
,t4
, z
,z0
;
159 long last_tick
= *rb
->current_tick
;
160 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
161 int cumulated_lag
= 0;
163 #ifdef HAVE_LCD_COLOR
164 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
174 /*Generate the neccesary pre calced stuff*/
175 wave_table_generate();
177 #ifndef HAVE_LCD_COLOR
178 shades_generate(); /* statically */
180 /* get the remainder of the plugin buffer */
181 gbuf
= (unsigned char *) rb
->plugin_get_buffer(&gbuf_size
);
183 grey_init(gbuf
, gbuf_size
, GREY_ON_COP
, LCD_WIDTH
, LCD_HEIGHT
, NULL
);
184 /* switch on greyscale overlay */
194 #ifdef HAVE_LCD_COLOR
195 shades_generate(time
++); /* dynamically */
196 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
197 ptr
= (unsigned char*)rb
->lcd_framebuffer
;
199 ptr
= rb
->lcd_framebuffer
;
207 for(y
= 0; y
< LCD_HEIGHT
; ++y
)
211 z0
= wave_array
[t1
] + wave_array
[t2
];
212 for(x
= 0; x
< LCD_WIDTH
; ++x
)
214 z
= z0
+ wave_array
[t3
] + wave_array
[t4
];
215 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
231 #ifdef HAVE_LCD_COLOR
232 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
233 rb
->lcd_blit_pal256( (unsigned char*)rb
->lcd_framebuffer
,
234 0,0,0,0,LCD_WIDTH
,LCD_HEIGHT
);
239 grey_ub_gray_bitmap(greybuffer
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
242 delay
= last_tick
- *rb
->current_tick
+ HZ
/33;
243 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
244 if (!boosted
&& delay
< 0)
246 cumulated_lag
-= delay
; /* proportional increase */
247 if (cumulated_lag
>= HZ
)
248 rb
->cpu_boost(boosted
= true);
250 else if (boosted
&& delay
> 1) /* account for jitter */
252 if (--cumulated_lag
<= 0) /* slow decrease */
253 rb
->cpu_boost(boosted
= false);
256 action
= pluginlib_getaction(0, plugin_contexts
,
257 ARRAYLEN(plugin_contexts
));
258 last_tick
= *rb
->current_tick
;
268 #ifdef HAVE_SCROLLWHEEL
270 case PLA_SCROLL_FWD_REPEAT
:
275 wave_table_generate();
278 #ifdef HAVE_SCROLLWHEEL
279 case PLA_SCROLL_BACK
:
280 case PLA_SCROLL_BACK_REPEAT
:
283 case PLA_DOWN_REPEAT
:
284 if(plasma_frequency
>1)
287 wave_table_generate();
290 #ifdef HAVE_LCD_COLOR
292 redfactor
=rb
->rand()%4;
293 greenfactor
=rb
->rand()%4;
294 bluefactor
=rb
->rand()%4;
295 redphase
=rb
->rand()%256;
296 greenphase
=rb
->rand()%256;
297 bluephase
=rb
->rand()%256;
302 if (rb
->default_event_handler_ex(action
, cleanup
, NULL
)
303 == SYS_USB_CONNECTED
)
304 return PLUGIN_USB_CONNECTED
;
310 /*************************** Plugin entry point ****************************/
312 enum plugin_status
plugin_start(const void* parameter
)
318 rb
->lcd_set_backdrop(NULL
);
320 /* Turn off backlight timeout */
321 backlight_force_on(); /* backlight control in lib/helper.c */
323 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
324 rb
->lcd_set_mode(LCD_MODE_PAL256
);
329 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
330 rb
->lcd_set_mode(LCD_MODE_RGB565
);
336 #endif /* HAVE_LCD_BITMAP */