Prepare new maemo release
[maemo-rb.git] / apps / plugins / plasma.c
blob88afb858f5ac9a1124078883ce12ccb316c280a3
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 static 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 static 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, x, y;
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;
160 int delay;
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 if (!grey_init(gbuf, gbuf_size, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL))
185 rb->splash(HZ, "Couldn't init greyscale display");
186 return PLUGIN_ERROR;
188 /* switch on greyscale overlay */
189 grey_show(true);
190 #endif
191 atexit(cleanup);
192 sp1 = 4;
193 sp2 = 2;
194 sp3 = 4;
195 sp4 = 2;
196 p1=p2=p3=p4=0;
197 while (true)
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;
203 #else
204 ptr = rb->lcd_framebuffer;
205 #endif
207 #else
208 ptr = greybuffer;
209 #endif
210 t1=p1;
211 t2=p2;
212 for(y = 0; y < LCD_HEIGHT; ++y)
214 t3=p3;
215 t4=p4;
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)
221 *ptr++ = z;
222 #else
223 *ptr++ = colours[z];
224 #endif
225 t3+=1;
226 t4+=2;
228 t1+=2;
229 t2+=1;
230 rb->yield();
232 p1+=sp1;
233 p2-=sp2;
234 p3+=sp3;
235 p4-=sp4;
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);
240 #else
241 rb->lcd_update();
242 #endif
243 #else
244 grey_ub_gray_bitmap(greybuffer, 0, 0, LCD_WIDTH, LCD_HEIGHT);
245 #endif
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;
261 #endif
262 action = pluginlib_getaction(0, plugin_contexts,
263 ARRAYLEN(plugin_contexts));
265 switch(action)
267 case PLA_EXIT:
268 case PLA_CANCEL:
269 return PLUGIN_OK;
270 break;
272 #ifdef HAVE_SCROLLWHEEL
273 case PLA_SCROLL_FWD:
274 case PLA_SCROLL_FWD_REPEAT:
275 #endif
276 case PLA_UP:
277 case PLA_UP_REPEAT:
278 ++plasma_frequency;
279 wave_table_generate();
280 break;
282 #ifdef HAVE_SCROLLWHEEL
283 case PLA_SCROLL_BACK:
284 case PLA_SCROLL_BACK_REPEAT:
285 #endif
286 case PLA_DOWN:
287 case PLA_DOWN_REPEAT:
288 if(plasma_frequency>1)
290 --plasma_frequency;
291 wave_table_generate();
293 break;
294 #ifdef HAVE_LCD_COLOR
295 case PLA_SELECT:
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;
302 break;
303 #endif
305 default:
306 exit_on_usb(action);
307 break;
312 /*************************** Plugin entry point ****************************/
314 enum plugin_status plugin_start(const void* parameter)
316 (void)parameter;
317 #if LCD_DEPTH > 1
318 rb->lcd_set_backdrop(NULL);
319 #endif
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);
325 #endif
326 return main();