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"
30 #include "lib/pluginlib_exit.h"
32 #ifndef HAVE_LCD_COLOR
35 #include "lib/fixedpoint.h"
38 /******************************* Globals ***********************************/
40 static unsigned char wave_array
[256]; /* Pre calculated wave array */
42 static fb_data colours
[256]; /* Smooth transition of shades */
43 static int redfactor
= 1, greenfactor
= 2, bluefactor
= 3;
44 static int redphase
= 0, greenphase
= 50, bluephase
= 100;
45 /* lower chance of gray at regular intervals */
48 static unsigned char colours
[256]; /* Smooth transition of shades */
49 static unsigned char greybuffer
[LCD_HEIGHT
*LCD_WIDTH
]; /* off screen buffer */
50 static unsigned char *gbuf
;
51 static size_t gbuf_size
= 0;
53 static unsigned char sp1
, sp2
, sp3
, sp4
; /* Speed of plasma */
54 static int plasma_frequency
;
55 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
56 static bool boosted
= false;
59 static const struct button_mapping
* plugin_contexts
[]= {
61 #if defined(HAVE_REMOTE_LCD)
69 * Main wave function so we don't have to re-calc the sine
70 * curve every time. Mess around WAV_AMP and FREQ to make slighlty
71 * weirder looking plasmas!
74 static void wave_table_generate(void)
79 wave_array
[i
] = (unsigned char)((WAV_AMP
80 * (fp14_sin((i
* 360 * plasma_frequency
) / 256))) / 16384);
85 /* Make a smooth colour cycle. */
86 static void shades_generate(int time
)
89 unsigned red
, green
, blue
;
90 unsigned r
= time
* redfactor
+ redphase
;
91 unsigned g
= time
* greenfactor
+ greenphase
;
92 unsigned b
= time
* bluefactor
+ bluephase
;
94 for(i
=0; i
< 256; ++i
)
96 r
&= 0xFF; g
&= 0xFF; b
&= 0xFF;
108 colours
[i
] = LCD_RGBPACK(red
, green
, blue
);
112 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
113 rb
->lcd_pal256_update_pal(colours
);
117 /* Make a smooth shade from black into white and back into black again. */
118 static void shades_generate(void)
122 for(i
=0; i
< 256; ++i
)
132 static void cleanup(void)
134 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
136 rb
->cpu_boost(false);
138 #ifndef HAVE_LCD_COLOR
141 /* Turn on backlight timeout (revert to settings) */
142 backlight_use_settings();
143 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
144 rb
->lcd_set_mode(LCD_MODE_RGB565
);
149 * Main function that also contain the main plasma
155 plasma_frequency
= 1;
157 unsigned char p1
,p2
,p3
,p4
,t1
,t2
,t3
,t4
, z
,z0
;
158 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
159 long last_tick
= *rb
->current_tick
;
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 if (!grey_init(gbuf
, gbuf_size
, GREY_ON_COP
, LCD_WIDTH
, LCD_HEIGHT
, NULL
))
185 rb
->splash(HZ
, "Couldn't init greyscale display");
188 /* switch on greyscale overlay */
199 #ifdef HAVE_LCD_COLOR
200 shades_generate(time
++); /* dynamically */
201 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
202 ptr
= (unsigned char*)rb
->lcd_framebuffer
;
204 ptr
= rb
->lcd_framebuffer
;
212 for(y
= 0; y
< LCD_HEIGHT
; ++y
)
216 z0
= wave_array
[t1
] + wave_array
[t2
];
217 for(x
= 0; x
< LCD_WIDTH
; ++x
)
219 z
= z0
+ wave_array
[t3
] + wave_array
[t4
];
220 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
236 #ifdef HAVE_LCD_COLOR
237 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
238 rb
->lcd_blit_pal256( (unsigned char*)rb
->lcd_framebuffer
,
239 0,0,0,0,LCD_WIDTH
,LCD_HEIGHT
);
244 grey_ub_gray_bitmap(greybuffer
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
247 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
248 delay
= last_tick
- *rb
->current_tick
+ HZ
/33;
249 if (!boosted
&& delay
< 0)
251 cumulated_lag
-= delay
; /* proportional increase */
252 if (cumulated_lag
>= HZ
)
253 rb
->cpu_boost(boosted
= true);
255 else if (boosted
&& delay
> 1) /* account for jitter */
257 if (--cumulated_lag
<= 0) /* slow decrease */
258 rb
->cpu_boost(boosted
= false);
260 last_tick
= *rb
->current_tick
;
262 action
= pluginlib_getaction(0, plugin_contexts
,
263 ARRAYLEN(plugin_contexts
));
272 #ifdef HAVE_SCROLLWHEEL
274 case PLA_SCROLL_FWD_REPEAT
:
279 wave_table_generate();
282 #ifdef HAVE_SCROLLWHEEL
283 case PLA_SCROLL_BACK
:
284 case PLA_SCROLL_BACK_REPEAT
:
287 case PLA_DOWN_REPEAT
:
288 if(plasma_frequency
>1)
291 wave_table_generate();
294 #ifdef HAVE_LCD_COLOR
296 redfactor
=rb
->rand()%4;
297 greenfactor
=rb
->rand()%4;
298 bluefactor
=rb
->rand()%4;
299 redphase
=rb
->rand()%256;
300 greenphase
=rb
->rand()%256;
301 bluephase
=rb
->rand()%256;
312 /*************************** Plugin entry point ****************************/
314 enum plugin_status
plugin_start(const void* parameter
)
318 rb
->lcd_set_backdrop(NULL
);
320 /* Turn off backlight timeout */
321 backlight_ignore_timeout();
323 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
324 rb
->lcd_set_mode(LCD_MODE_PAL256
);