Submit FS#12081. Check validity of channel configuration, comment unneeded code that...
[kugel-rb.git] / apps / plugins / plasma.c
blob52f4204a176e2299b570da662cb741a52b2b8d28
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Plasma demo plugin
12 * My crack at making a 80's style retro plasma effect for the fantastic
13 * rockbox!
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 ****************************************************************************/
27 #include "plugin.h"
28 #include "lib/helper.h"
29 #include "lib/pluginlib_actions.h"
30 #include "lib/pluginlib_exit.h"
32 #ifndef HAVE_LCD_COLOR
33 #include "lib/grey.h"
34 #endif
35 #include "lib/fixedpoint.h"
38 /******************************* Globals ***********************************/
40 static unsigned char wave_array[256]; /* Pre calculated wave array */
41 #ifdef HAVE_LCD_COLOR
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 */
46 #else
47 GREY_INFO_STRUCT
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;
52 #endif
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;
57 #endif
59 static const struct button_mapping* plugin_contexts[]= {
60 pla_main_ctx,
61 #if defined(HAVE_REMOTE_LCD)
62 pla_remote_ctx,
63 #endif
66 #define WAV_AMP 90
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)
76 int i;
77 for (i=0;i<256;++i)
79 wave_array[i] = (unsigned char)((WAV_AMP
80 * (fp14_sin((i * 360 * plasma_frequency) / 256))) / 16384);
84 #ifdef HAVE_LCD_COLOR
85 /* Make a smooth colour cycle. */
86 void shades_generate(int time)
88 int i;
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;
98 red = 2 * r;
99 if (red > 255)
100 red = 510 - red;
101 green = 2 * g;
102 if (green > 255)
103 green = 510 - green;
104 blue = 2 * b;
105 if (blue > 255)
106 blue= 510 - blue;
108 colours[i] = LCD_RGBPACK(red, green, blue);
110 r++; g++; b++;
112 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
113 rb->lcd_pal256_update_pal(colours);
114 #endif
116 #else
117 /* Make a smooth shade from black into white and back into black again. */
118 static void shades_generate(void)
120 int i, y;
122 for(i=0; i < 256; ++i)
124 y = 2 * i;
125 if (y > 255)
126 y = 510 - y;
127 colours[i] = y;
130 #endif
132 void cleanup(void)
134 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
135 if (boosted)
136 rb->cpu_boost(false);
137 #endif
138 #ifndef HAVE_LCD_COLOR
139 grey_release();
140 #endif
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);
145 #endif
149 * Main function that also contain the main plasma
150 * algorithm.
153 int main(void)
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;
161 #endif
162 #ifdef HAVE_LCD_COLOR
163 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
164 unsigned char *ptr;
165 #else
166 fb_data *ptr;
167 #endif
168 int time=0;
169 #else
170 unsigned char *ptr;
171 #endif
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");
185 return PLUGIN_ERROR;
187 /* switch on greyscale overlay */
188 grey_show(true);
189 #endif
190 atexit(cleanup);
191 sp1 = 4;
192 sp2 = 2;
193 sp3 = 4;
194 sp4 = 2;
195 p1=p2=p3=p4=0;
196 while (true)
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;
202 #else
203 ptr = rb->lcd_framebuffer;
204 #endif
206 #else
207 ptr = greybuffer;
208 #endif
209 t1=p1;
210 t2=p2;
211 for(y = 0; y < LCD_HEIGHT; ++y)
213 t3=p3;
214 t4=p4;
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)
220 *ptr++ = z;
221 #else
222 *ptr++ = colours[z];
223 #endif
224 t3+=1;
225 t4+=2;
227 t1+=2;
228 t2+=1;
229 rb->yield();
231 p1+=sp1;
232 p2-=sp2;
233 p3+=sp3;
234 p4-=sp4;
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);
239 #else
240 rb->lcd_update();
241 #endif
242 #else
243 grey_ub_gray_bitmap(greybuffer, 0, 0, LCD_WIDTH, LCD_HEIGHT);
244 #endif
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);
259 #endif
260 action = pluginlib_getaction(0, plugin_contexts,
261 ARRAYLEN(plugin_contexts));
262 last_tick = *rb->current_tick;
264 switch(action)
266 case PLA_EXIT:
267 case PLA_CANCEL:
268 return PLUGIN_OK;
269 break;
271 #ifdef HAVE_SCROLLWHEEL
272 case PLA_SCROLL_FWD:
273 case PLA_SCROLL_FWD_REPEAT:
274 #endif
275 case PLA_UP:
276 case PLA_UP_REPEAT:
277 ++plasma_frequency;
278 wave_table_generate();
279 break;
281 #ifdef HAVE_SCROLLWHEEL
282 case PLA_SCROLL_BACK:
283 case PLA_SCROLL_BACK_REPEAT:
284 #endif
285 case PLA_DOWN:
286 case PLA_DOWN_REPEAT:
287 if(plasma_frequency>1)
289 --plasma_frequency;
290 wave_table_generate();
292 break;
293 #ifdef HAVE_LCD_COLOR
294 case PLA_SELECT:
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;
301 break;
302 #endif
304 default:
305 exit_on_usb(action);
306 break;
311 /*************************** Plugin entry point ****************************/
313 enum plugin_status plugin_start(const void* parameter)
315 (void)parameter;
316 #if LCD_DEPTH > 1
317 rb->lcd_set_backdrop(NULL);
318 #endif
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);
324 #endif
325 return main();