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 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
)
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;
156 int action
, delay
, x
, y
;
157 unsigned char p1
,p2
,p3
,p4
,t1
,t2
,t3
,t4
, z
,z0
;
158 long last_tick
= *rb
->current_tick
;
159 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
160 int cumulated_lag
= 0;
162 #ifdef HAVE_LCD_COLOR
163 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
173 /*Generate the neccesary pre calced stuff*/
174 wave_table_generate();
176 #ifndef HAVE_LCD_COLOR
177 shades_generate(); /* statically */
179 /* get the remainder of the plugin buffer */
180 gbuf
= (unsigned char *) rb
->plugin_get_buffer(&gbuf_size
);
182 if (!grey_init(gbuf
, gbuf_size
, GREY_ON_COP
, LCD_WIDTH
, LCD_HEIGHT
, NULL
))
184 rb
->splash(HZ
, "Couldn't init greyscale display");
187 /* switch on greyscale overlay */
198 #ifdef HAVE_LCD_COLOR
199 shades_generate(time
++); /* dynamically */
200 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
201 ptr
= (unsigned char*)rb
->lcd_framebuffer
;
203 ptr
= rb
->lcd_framebuffer
;
211 for(y
= 0; y
< LCD_HEIGHT
; ++y
)
215 z0
= wave_array
[t1
] + wave_array
[t2
];
216 for(x
= 0; x
< LCD_WIDTH
; ++x
)
218 z
= z0
+ wave_array
[t3
] + wave_array
[t4
];
219 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
235 #ifdef HAVE_LCD_COLOR
236 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
237 rb
->lcd_blit_pal256( (unsigned char*)rb
->lcd_framebuffer
,
238 0,0,0,0,LCD_WIDTH
,LCD_HEIGHT
);
243 grey_ub_gray_bitmap(greybuffer
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
246 delay
= last_tick
- *rb
->current_tick
+ HZ
/33;
247 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
248 if (!boosted
&& delay
< 0)
250 cumulated_lag
-= delay
; /* proportional increase */
251 if (cumulated_lag
>= HZ
)
252 rb
->cpu_boost(boosted
= true);
254 else if (boosted
&& delay
> 1) /* account for jitter */
256 if (--cumulated_lag
<= 0) /* slow decrease */
257 rb
->cpu_boost(boosted
= false);
260 action
= pluginlib_getaction(0, plugin_contexts
,
261 ARRAYLEN(plugin_contexts
));
262 last_tick
= *rb
->current_tick
;
271 #ifdef HAVE_SCROLLWHEEL
273 case PLA_SCROLL_FWD_REPEAT
:
278 wave_table_generate();
281 #ifdef HAVE_SCROLLWHEEL
282 case PLA_SCROLL_BACK
:
283 case PLA_SCROLL_BACK_REPEAT
:
286 case PLA_DOWN_REPEAT
:
287 if(plasma_frequency
>1)
290 wave_table_generate();
293 #ifdef HAVE_LCD_COLOR
295 redfactor
=rb
->rand()%4;
296 greenfactor
=rb
->rand()%4;
297 bluefactor
=rb
->rand()%4;
298 redphase
=rb
->rand()%256;
299 greenphase
=rb
->rand()%256;
300 bluephase
=rb
->rand()%256;
311 /*************************** Plugin entry point ****************************/
313 enum plugin_status
plugin_start(const void* parameter
)
317 rb
->lcd_set_backdrop(NULL
);
319 /* Turn off backlight timeout */
320 backlight_ignore_timeout();
322 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
323 rb
->lcd_set_mode(LCD_MODE_PAL256
);