1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2004 Matthias Wientapper
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
23 #ifdef HAVE_LCD_BITMAP // this is not fun on the player
26 /* variable button definitions */
27 #if CONFIG_KEYPAD == RECORDER_PAD
28 #define MANDELBROT_QUIT BUTTON_OFF
29 #define MANDELBROT_ZOOM_IN BUTTON_PLAY
30 #define MANDELBROT_ZOOM_OUT BUTTON_ON
31 #define MANDELBROT_MAXITER_INC BUTTON_F2
32 #define MANDELBROT_MAXITER_DEC BUTTON_F1
33 #define MANDELBROT_RESET BUTTON_F3
35 #elif CONFIG_KEYPAD == ONDIO_PAD
36 #define MANDELBROT_QUIT BUTTON_OFF
37 #define MANDELBROT_ZOOM_IN_PRE BUTTON_MENU
38 #define MANDELBROT_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
39 #define MANDELBROT_ZOOM_IN2 (BUTTON_MENU | BUTTON_UP)
40 #define MANDELBROT_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
41 #define MANDELBROT_MAXITER_INC (BUTTON_MENU | BUTTON_RIGHT)
42 #define MANDELBROT_MAXITER_DEC (BUTTON_MENU | BUTTON_LEFT)
43 #define MANDELBROT_RESET (BUTTON_MENU | BUTTON_OFF)
47 static struct plugin_api
* rb
;
49 static int lcd_aspect_ratio
;
56 static unsigned char *gbuf
;
57 static unsigned int gbuf_size
= 0;
58 static unsigned char graybuffer
[LCD_HEIGHT
];
61 void init_mandelbrot_set(void){
62 x_min
= -5<<25; // -2.0<<26
63 x_max
= 1<<26; // 1.0<<26
64 y_min
= -1<<26; // -1.0<<26
65 y_max
= 1<<26; // 1.0<<26
66 delta
= (x_max
- x_min
) >> 3; // /8
70 void calc_mandelbrot_set(void){
72 long start_tick
, last_yield
;
75 int x
, x2
, y
, y2
, a
, b
;
79 start_tick
= last_yield
= *rb
->current_tick
;
83 x_fact
= (x_max
- x_min
) / LCD_WIDTH
;
84 y_fact
= (y_max
- y_min
) / LCD_HEIGHT
;
86 for (x_pixel
= 0; x_pixel
<LCD_WIDTH
; x_pixel
++){
87 a
= (x_pixel
* x_fact
) + x_min
;
88 for(y_pixel
= LCD_HEIGHT
-1; y_pixel
>=0; y_pixel
--){
89 b
= (y_pixel
* y_fact
) + y_min
;
94 while (++n_iter
<=max_iter
) {
100 if (x2
+ y2
> (4<<26)) break;
108 if (n_iter
> max_iter
){
109 brightness
= 0; // black
111 brightness
= 255 - (31 * (n_iter
& 7));
113 graybuffer
[y_pixel
]=brightness
;
114 /* be nice to other threads:
115 * if at least one tick has passed, yield */
116 if (*rb
->current_tick
> last_yield
){
118 last_yield
= *rb
->current_tick
;
121 gray_drawgraymap(graybuffer
, x_pixel
, 0, 1, LCD_HEIGHT
, 1);
125 void cleanup(void *parameter
)
129 gray_release_buffer();
132 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
135 int lastbutton
= BUTTON_NONE
;
139 TEST_PLUGIN_API(api
);
143 /* This plugin uses the grayscale framework, so initialize */
146 /* get the remainder of the plugin buffer */
147 gbuf
= (unsigned char *) rb
->plugin_get_buffer(&gbuf_size
);
149 /* initialize the grayscale buffer:
150 * 112 pixels wide, 8 rows (64 pixels) high, (try to) reserve
151 * 16 bitplanes for 17 shades of gray.*/
152 grayscales
= gray_init_buffer(gbuf
, gbuf_size
, 112, 8, 16, NULL
) + 1;
153 if (grayscales
!= 17){
154 rb
->snprintf(buff
, sizeof(buff
), "%d", grayscales
);
155 rb
->lcd_puts(0, 1, buff
);
161 gray_show_display(true); /* switch on grayscale overlay */
163 init_mandelbrot_set();
164 lcd_aspect_ratio
= ((LCD_WIDTH
<<13) / LCD_HEIGHT
)<<13;
169 calc_mandelbrot_set();
173 button
= rb
->button_get(true);
175 case MANDELBROT_QUIT
:
176 gray_release_buffer();
179 case MANDELBROT_ZOOM_OUT
:
180 x_min
-= ((delta
>>13)*(lcd_aspect_ratio
>>13));
181 x_max
+= ((delta
>>13)*(lcd_aspect_ratio
>>13));
184 delta
= (x_max
- x_min
) >> 3;
189 case MANDELBROT_ZOOM_IN
:
190 #ifdef MANDELBROT_ZOOM_IN_PRE
191 if (lastbutton
!= MANDELBROT_ZOOM_IN_PRE
)
194 #ifdef MANDELBROT_ZOOM_IN2
195 case MANDELBROT_ZOOM_IN2
:
197 x_min
+= ((delta
>>13)*(lcd_aspect_ratio
>>13));
198 x_max
-= ((delta
>>13)*(lcd_aspect_ratio
>>13));
201 delta
= (x_max
- x_min
) >> 3;
229 case MANDELBROT_MAXITER_DEC
:
236 case MANDELBROT_MAXITER_INC
:
243 case MANDELBROT_RESET
:
244 init_mandelbrot_set();
249 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
250 == SYS_USB_CONNECTED
)
251 return PLUGIN_USB_CONNECTED
;
254 if (button
!= BUTTON_NONE
)
257 gray_release_buffer();