1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Kevin Ferrare
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
25 #ifdef HAVE_LCD_BITMAP /* and also not for the Player */
26 #ifndef HAVE_LCD_COLOR
32 /******************************* Globals ***********************************/
34 static struct plugin_api
* rb
; /* global api struct pointer */
36 static unsigned char fire
[LCD_HEIGHT
+3][LCD_WIDTH
];
37 static unsigned char cooling_map
[LCD_HEIGHT
][LCD_WIDTH
];
39 #ifndef HAVE_LCD_COLOR
40 static unsigned char *gbuf
;
41 static size_t gbuf_size
= 0;
42 static unsigned char draw_buffer
[8*LCD_WIDTH
];
47 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
48 #define FIRE_QUIT BUTTON_OFF
49 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_MODE
50 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_REC
51 #define FIRE_INCREASE_MULT BUTTON_UP
52 #define FIRE_DECREASE_MULT BUTTON_DOWN
54 #define FIRE_RC_QUIT BUTTON_RC_STOP
56 #elif CONFIG_KEYPAD == RECORDER_PAD
57 #define FIRE_QUIT BUTTON_OFF
58 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_ON
59 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_PLAY
60 #define FIRE_INCREASE_MULT BUTTON_UP
61 #define FIRE_DECREASE_MULT BUTTON_DOWN
63 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
64 #define FIRE_QUIT BUTTON_OFF
65 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_ON
66 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_SELECT
67 #define FIRE_INCREASE_MULT BUTTON_UP
68 #define FIRE_DECREASE_MULT BUTTON_DOWN
70 #elif CONFIG_KEYPAD == ONDIO_PAD
71 #define FIRE_QUIT BUTTON_OFF
72 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_MENU
73 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_RIGHT
74 #define FIRE_INCREASE_MULT BUTTON_UP
75 #define FIRE_DECREASE_MULT BUTTON_DOWN
77 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
78 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
79 #define FIRE_QUIT BUTTON_MENU
80 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_SELECT
81 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_RIGHT
82 #define FIRE_INCREASE_MULT BUTTON_SCROLL_FWD
83 #define FIRE_DECREASE_MULT BUTTON_SCROLL_BACK
85 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
86 #define FIRE_QUIT BUTTON_POWER
87 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_LEFT
88 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_RIGHT
89 #define FIRE_INCREASE_MULT BUTTON_UP
90 #define FIRE_DECREASE_MULT BUTTON_DOWN
92 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
93 #define FIRE_QUIT BUTTON_POWER
94 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_LEFT
95 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_RIGHT
96 #define FIRE_INCREASE_MULT BUTTON_UP
97 #define FIRE_DECREASE_MULT BUTTON_DOWN
99 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
100 (CONFIG_KEYPAD == SANSA_C200_PAD)
101 #define FIRE_QUIT BUTTON_POWER
102 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_LEFT
103 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_RIGHT
104 #define FIRE_INCREASE_MULT BUTTON_UP
105 #define FIRE_DECREASE_MULT BUTTON_DOWN
107 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
108 #define FIRE_QUIT BUTTON_POWER
109 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_LEFT
110 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_RIGHT
111 #define FIRE_INCREASE_MULT BUTTON_SCROLL_UP
112 #define FIRE_DECREASE_MULT BUTTON_SCROLL_DOWN
114 #elif (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD)
115 #define FIRE_QUIT BUTTON_PLAY
116 #define FIRE_SWITCH_FLAMES_TYPE BUTTON_MODE
117 #define FIRE_SWITCH_FLAMES_MOVING BUTTON_EQ
118 #define FIRE_INCREASE_MULT BUTTON_UP
119 #define FIRE_DECREASE_MULT BUTTON_DOWN
123 #define MIN_FLAME_VALUE 0
124 #define COOL_MAX (440/LCD_HEIGHT+2)
126 /* fast unsigned multiplication (16x16bit->32bit or 32x32bit->32bit,
127 * whichever is faster for the architecture) */
129 #define FMULU(a, b) ((uint32_t) (((uint32_t) (a)) * ((uint32_t) (b))))
130 #else /* SH1, coldfire */
131 #define FMULU(a, b) ((uint32_t) (((uint16_t) (a)) * ((uint16_t) (b))))
134 #ifndef HAVE_LCD_COLOR
135 static const unsigned char palette
[256] = {
136 0, 1, 3, 4, 6, 7, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22,
137 24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43, 45, 46,
138 48, 49, 51, 52, 54, 55, 57, 59, 60, 61, 63, 64, 66, 67, 69, 70,
139 72, 73, 75, 76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91, 93, 94,
140 96, 97, 99, 100, 102, 103, 105, 106, 108, 109, 111, 112, 114, 115, 117, 118,
141 120, 121, 123, 124, 126, 127, 129, 130, 132, 133, 135, 136, 138, 139, 141, 142,
142 144, 145, 147, 148, 150, 151, 153, 154, 156, 157, 159, 160, 162, 163, 165, 166,
143 168, 169, 171, 172, 174, 175, 177, 178, 180, 181, 183, 184, 186, 187, 189, 190,
144 192, 193, 195, 196, 198, 199, 201, 202, 204, 205, 207, 208, 210, 211, 213, 214,
145 216, 217, 219, 220, 222, 223, 225, 226, 228, 229, 231, 232, 234, 235, 237, 238,
146 /* 'regular' fire doesn't exceed this value */
147 240, 240, 240, 240, 240, 240, 241, 241, 241, 241, 241, 241, 242, 242, 242, 242,
148 242, 242, 243, 243, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 245, 245,
149 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 247, 247,
150 248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 249, 249, 250, 250, 250, 250,
151 250, 250, 251, 251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 253, 253,
152 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255
155 #define L(r,g,b) LCD_RGBPACK(r,g,b)
157 static const fb_data colorpalette
[256] = {
158 L( 0, 0, 0), L( 5, 0, 0), L( 10, 0, 0), L( 15, 0, 0), L( 20, 0, 0),
159 L( 25, 0, 0), L( 30, 0, 0), L( 35, 0, 0), L( 40, 0, 0), L( 45, 0, 0),
160 L( 50, 0, 0), L( 55, 0, 0), L( 60, 0, 0), L( 65, 0, 0), L( 70, 0, 0),
161 L( 75, 0, 0), L( 80, 0, 0), L( 85, 0, 0), L( 90, 0, 0), L( 95, 0, 0),
162 L(100, 0, 0), L(105, 0, 0), L(110, 0, 0), L(115, 0, 0), L(120, 0, 0),
163 L(125, 0, 0), L(130, 0, 0), L(135, 0, 0), L(140, 0, 0), L(145, 0, 0),
164 L(150, 0, 0), L(155, 0, 0), L(160, 0, 0), L(165, 0, 0), L(170, 0, 0),
165 L(175, 0, 0), L(180, 0, 0), L(185, 0, 0), L(186, 2, 0), L(187, 5, 1),
166 L(188, 6, 2), L(189, 8, 3), L(190, 10, 4), L(191, 12, 4), L(192, 14, 5),
167 L(193, 15, 6), L(194, 17, 7), L(195, 19, 8), L(196, 21, 8), L(197, 22, 9),
168 L(198, 24, 10), L(198, 26, 10), L(199, 28, 10), L(200, 29, 11), L(201, 32, 11),
169 L(202, 34, 12), L(203, 36, 13), L(204, 39, 13), L(205, 40, 14), L(206, 42, 14),
170 L(207, 43, 15), L(208, 46, 16), L(208, 48, 17), L(209, 50, 18), L(210, 51, 18),
171 L(212, 53, 19), L(213, 55, 20), L(214, 57, 21), L(215, 59, 22), L(216, 61, 22),
172 L(217, 63, 23), L(217, 65, 24), L(218, 67, 24), L(219, 69, 25), L(220, 70, 25),
173 L(222, 72, 26), L(223, 74, 27), L(224, 76, 28), L(225, 78, 28), L(225, 80, 29),
174 L(226, 82, 29), L(227, 84, 30), L(228, 86, 31), L(228, 88, 32), L(229, 90, 32),
175 L(230, 92, 32), L(231, 94, 33), L(232, 96, 34), L(233, 98, 35), L(234, 99, 36),
176 L(235,101, 37), L(236,103, 37), L(237,105, 38), L(238,107, 39), L(240,109, 39),
177 L(240,111, 40), L(241,113, 40), L(242,114, 41), L(242,116, 42), L(243,119, 43),
178 L(245,120, 43), L(246,122, 44), L(247,124, 44), L(248,126, 46), L(248,128, 47),
179 L(249,130, 47), L(251,131, 47), L(252,133, 48), L(253,135, 49), L(253,138, 49),
180 L(253,140, 50), L(254,143, 49), L(254,145, 48), L(253,148, 47), L(253,151, 46),
181 L(253,154, 45), L(253,156, 44), L(253,158, 44), L(252,162, 42), L(252,165, 41),
182 L(252,167, 41), L(252,170, 40), L(251,173, 40), L(252,175, 38), L(252,178, 37),
183 L(251,181, 37), L(251,183, 36), L(251,186, 35), L(250,189, 34), L(250,192, 33),
184 L(250,194, 33), L(249,198, 31), L(249,200, 31), L(249,203, 30), L(249,206, 29),
185 L(249,209, 28), L(249,211, 27), L(249,214, 26), L(248,216, 25), L(248,219, 25),
186 L(248,222, 24), L(248,224, 23), L(248,227, 22), L(248,230, 21), L(248,232, 21),
187 L(247,236, 19), L(247,238, 23), L(247,239, 31), L(247,239, 45), L(247,240, 55),
188 L(248,240, 68), L(247,241, 78), L(248,241, 90), L(247,242,102), L(248,242,114),
189 L(247,243,125), L(248,243,138), L(248,243,153), L(248,244,162), L(248,245,174),
190 /* 'regular' fire doesn't exceed this value */
191 L(247,245,182), L(247,245,182), L(247,245,183), L(247,245,183), L(247,245,184),
192 L(247,245,184), L(247,245,185), L(247,245,185), L(247,245,186), L(247,245,186),
193 L(247,245,187), L(247,245,187), L(247,245,188), L(247,245,188), L(247,245,189),
194 L(247,245,189), L(248,245,190), L(248,245,190), L(248,245,191), L(248,245,191),
195 L(248,245,192), L(248,245,192), L(248,245,193), L(248,245,193), L(248,245,194),
196 L(248,245,194), L(248,245,195), L(248,245,195), L(248,245,196), L(248,245,196),
197 L(248,245,197), L(248,245,197), L(248,245,198), L(248,245,198), L(248,245,199),
198 L(248,245,199), L(248,245,200), L(248,245,200), L(248,245,201), L(248,245,201),
199 L(248,245,202), L(248,245,202), L(248,245,203), L(248,245,203), L(248,245,204),
200 L(248,245,204), L(248,245,205), L(248,245,205), L(248,246,206), L(248,246,206),
201 L(248,246,207), L(248,246,207), L(248,246,208), L(248,246,208), L(248,246,209),
202 L(248,246,209), L(248,246,210), L(248,246,210), L(248,246,211), L(248,246,211),
203 L(248,246,212), L(248,246,212), L(248,246,213), L(248,246,213), L(248,246,214),
204 L(248,246,214), L(248,246,215), L(248,246,215), L(248,246,216), L(248,246,216),
205 L(248,246,217), L(248,246,217), L(248,246,218), L(248,246,218), L(248,246,219),
206 L(248,246,219), L(248,246,220), L(248,246,220), L(248,246,221), L(248,246,221),
207 L(248,246,222), L(248,246,222), L(248,246,223), L(248,246,223), L(248,246,224),
208 L(248,246,224), L(248,246,225), L(248,246,225), L(248,246,226), L(248,246,226),
209 L(248,246,227), L(248,246,227), L(248,246,228), L(248,246,228), L(248,246,229),
214 static inline void tab_init_rand(unsigned char *tab
, unsigned int tab_size
,
217 unsigned char *end
= tab
+ tab_size
;
220 *tab
++ = (unsigned char)rb
->rand() % rand_max
;
223 static inline void fire_generate(int mult
, int flames_type
, bool moving
)
225 unsigned int pixel_value
= 0; /* stop the compiler complaining */
226 unsigned int cooling_value
;
227 unsigned char *ptr
, *end
, *cool
;
229 /* Randomize the bottom line */
231 {/* moving must be true the first time the function is called */
232 ptr
= &fire
[LCD_HEIGHT
][0];
233 end
= ptr
+ LCD_WIDTH
;
237 *ptr
++ = (MIN_FLAME_VALUE
+ rb
->rand() % (256-MIN_FLAME_VALUE
));
243 /* Convolve the pixels and handle cooling (to add nice shapes effects later) */
244 cool
= &cooling_map
[0][0];
246 end
= ptr
+ LCD_HEIGHT
*LCD_WIDTH
;
253 pixel_value
= ptr
[LCD_WIDTH
-1] /* fire[y+1][x-1] */
254 + ptr
[2*LCD_WIDTH
] /* fire[y+2][x] */
255 + ptr
[LCD_WIDTH
+1] /* fire[y+1][x+1] */
256 + ptr
[3*LCD_WIDTH
]; /* fire[y+3][x] */
257 pixel_value
= FMULU(pixel_value
, mult
) >> 10;
259 cooling_value
= *cool
++;
260 if (cooling_value
<= pixel_value
)
261 pixel_value
-= cooling_value
;
262 /* else it's too cold, don't frost the pixels !!! */
264 if (pixel_value
> 255)
267 *ptr
++ = pixel_value
;
276 pixel_value
= ptr
[LCD_WIDTH
-1] /* fire[y+1][x-1] */
277 + ptr
[LCD_WIDTH
] /* fire[y+1][x] */
278 + ptr
[LCD_WIDTH
+1] /* fire[y+1][x+1] */
279 + ptr
[2*LCD_WIDTH
]; /* fire[y+2][x] */
280 pixel_value
= FMULU(pixel_value
, mult
) >> 10;
282 cooling_value
= *cool
++;
283 if (cooling_value
<= pixel_value
)
284 pixel_value
-= cooling_value
;
285 /* else it's too cold, don't frost the pixels !!! */
287 if (pixel_value
> 255)
290 *ptr
++ = pixel_value
;
295 default: /* We should never reach this */
301 static inline void fire_draw(void)
303 #ifndef HAVE_LCD_COLOR
305 unsigned char *dest
, *end
;
306 unsigned char *src
= &fire
[0][0];
308 for (block
= 0; block
< LCD_HEIGHT
; block
+= 8)
311 end
= dest
+ 8*LCD_WIDTH
;
314 *dest
++ = palette
[*src
++];
317 gray_ub_gray_bitmap(draw_buffer
, 0, block
, LCD_WIDTH
, 8);
320 fb_data
* dest
= rb
->lcd_framebuffer
;
321 fb_data
* end
= rb
->lcd_framebuffer
+(LCD_WIDTH
*LCD_HEIGHT
);
322 unsigned char* src
= &fire
[0][0];
325 *dest
++ = colorpalette
[*src
++];
332 void cleanup(void *parameter
)
336 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
337 rb
->cpu_boost(false);
339 #ifndef HAVE_LCD_COLOR
342 /* Turn on backlight timeout (revert to settings) */
343 backlight_use_settings(rb
); /* backlight control in lib/helper.c */
347 * Main function that also contain the main plasma
357 #ifndef HAVE_LCD_COLOR
360 /* get the remainder of the plugin buffer */
361 gbuf
= (unsigned char *) rb
->plugin_get_buffer(&gbuf_size
);
362 shades
= gray_init(rb
, gbuf
, gbuf_size
, false, LCD_WIDTH
, LCD_HEIGHT
,
366 rb
->splash(HZ
, "not enough memory");
369 /* switch on grayscale overlay */
373 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
376 rb
->memset(&fire
[0][0], 0, sizeof(fire
));
377 tab_init_rand(&cooling_map
[0][0], LCD_HEIGHT
*LCD_WIDTH
, COOL_MAX
);
380 fire_generate(mult
, flames_type
, moving
);
384 button
= rb
->button_get(false);
396 case (FIRE_INCREASE_MULT
):
400 case (FIRE_DECREASE_MULT
):
405 case (FIRE_SWITCH_FLAMES_TYPE
):
406 flames_type
= (flames_type
+ 1) % 2;
409 case (FIRE_SWITCH_FLAMES_MOVING
):
414 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
415 == SYS_USB_CONNECTED
)
416 return PLUGIN_USB_CONNECTED
;
422 /*************************** Plugin entry point ****************************/
424 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
428 rb
= api
; // copy to global api pointer
431 rb
->lcd_set_backdrop(NULL
);
433 /* Turn off backlight timeout */
434 backlight_force_on(rb
); /* backlight control in lib/helper.c */
441 #endif /* #ifdef HAVE_LCD_BITMAP */