fix red.
[kugel-rb.git] / apps / plugins / plasma.c
blob637d948f3dcd115f8dea006ee26194324c6cb57e
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"
31 #ifdef HAVE_LCD_BITMAP
33 #ifndef HAVE_LCD_COLOR
34 #include "lib/grey.h"
35 #endif
36 #include "lib/fixedpoint.h"
38 PLUGIN_HEADER
40 /******************************* Globals ***********************************/
42 static unsigned char wave_array[256]; /* Pre calculated wave array */
43 #ifdef HAVE_LCD_COLOR
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 */
48 #else
49 GREY_INFO_STRUCT
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;
54 #endif
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;
59 #endif
61 static const struct button_mapping* plugin_contexts[]= {
62 pla_main_ctx,
63 #if defined(HAVE_REMOTE_LCD)
64 pla_remote_ctx,
65 #endif
68 #define WAV_AMP 90
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)
78 int i;
79 for (i=0;i<256;++i)
81 wave_array[i] = (unsigned char)((WAV_AMP
82 * (fp14_sin((i * 360 * plasma_frequency) / 256))) / 16384);
86 #ifdef HAVE_LCD_COLOR
87 /* Make a smooth colour cycle. */
88 void shades_generate(int time)
90 int i;
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;
100 red = 2 * r;
101 if (red > 255)
102 red = 510 - red;
103 green = 2 * g;
104 if (green > 255)
105 green = 510 - green;
106 blue = 2 * b;
107 if (blue > 255)
108 blue= 510 - blue;
110 colours[i] = LCD_RGBPACK(red, green, blue);
112 r++; g++; b++;
114 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
115 rb->lcd_pal256_update_pal(colours);
116 #endif
118 #else
119 /* Make a smooth shade from black into white and back into black again. */
120 static void shades_generate(void)
122 int i, y;
124 for(i=0; i < 256; ++i)
126 y = 2 * i;
127 if (y > 255)
128 y = 510 - y;
129 colours[i] = y;
132 #endif
134 void cleanup(void *parameter)
136 (void)parameter;
138 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
139 if (boosted)
140 rb->cpu_boost(false);
141 #endif
142 #ifndef HAVE_LCD_COLOR
143 grey_release();
144 #endif
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
151 * algorithm.
154 int main(void)
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;
162 #endif
163 #ifdef HAVE_LCD_COLOR
164 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
165 unsigned char *ptr;
166 #else
167 fb_data *ptr;
168 #endif
169 int time=0;
170 #else
171 unsigned char *ptr;
172 #endif
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 */
185 grey_show(true);
186 #endif
187 sp1 = 4;
188 sp2 = 2;
189 sp3 = 4;
190 sp4 = 2;
191 p1=p2=p3=p4=0;
192 while (true)
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;
198 #else
199 ptr = rb->lcd_framebuffer;
200 #endif
202 #else
203 ptr = greybuffer;
204 #endif
205 t1=p1;
206 t2=p2;
207 for(y = 0; y < LCD_HEIGHT; ++y)
209 t3=p3;
210 t4=p4;
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)
216 *ptr++ = z;
217 #else
218 *ptr++ = colours[z];
219 #endif
220 t3+=1;
221 t4+=2;
223 t1+=2;
224 t2+=1;
225 rb->yield();
227 p1+=sp1;
228 p2-=sp2;
229 p3+=sp3;
230 p4-=sp4;
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);
235 #else
236 rb->lcd_update();
237 #endif
238 #else
239 grey_ub_gray_bitmap(greybuffer, 0, 0, LCD_WIDTH, LCD_HEIGHT);
240 #endif
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);
255 #endif
256 action = pluginlib_getaction(0, plugin_contexts,
257 ARRAYLEN(plugin_contexts));
258 last_tick = *rb->current_tick;
260 switch(action)
262 case PLA_EXIT:
263 case PLA_CANCEL:
264 cleanup(NULL);
265 return PLUGIN_OK;
266 break;
268 #ifdef HAVE_SCROLLWHEEL
269 case PLA_SCROLL_FWD:
270 case PLA_SCROLL_FWD_REPEAT:
271 #endif
272 case PLA_UP:
273 case PLA_UP_REPEAT:
274 ++plasma_frequency;
275 wave_table_generate();
276 break;
278 #ifdef HAVE_SCROLLWHEEL
279 case PLA_SCROLL_BACK:
280 case PLA_SCROLL_BACK_REPEAT:
281 #endif
282 case PLA_DOWN:
283 case PLA_DOWN_REPEAT:
284 if(plasma_frequency>1)
286 --plasma_frequency;
287 wave_table_generate();
289 break;
290 #ifdef HAVE_LCD_COLOR
291 case PLA_SELECT:
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;
298 break;
299 #endif
301 default:
302 if (rb->default_event_handler_ex(action, cleanup, NULL)
303 == SYS_USB_CONNECTED)
304 return PLUGIN_USB_CONNECTED;
305 break;
310 /*************************** Plugin entry point ****************************/
312 enum plugin_status plugin_start(const void* parameter)
314 int ret;
316 (void)parameter;
317 #if LCD_DEPTH > 1
318 rb->lcd_set_backdrop(NULL);
319 #endif
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);
325 #endif
327 ret = main();
329 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
330 rb->lcd_set_mode(LCD_MODE_RGB565);
331 #endif
333 return ret;
336 #endif /* HAVE_LCD_BITMAP */