1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2004 Matthias Wientapper
11 * Heavily extended 2005 Jens Arnold
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 ****************************************************************************/
23 #ifdef HAVE_LCD_BITMAP
29 /* variable button definitions */
30 #if CONFIG_KEYPAD == RECORDER_PAD
31 #define MANDELBROT_QUIT BUTTON_OFF
32 #define MANDELBROT_UP BUTTON_UP
33 #define MANDELBROT_DOWN BUTTON_DOWN
34 #define MANDELBROT_LEFT BUTTON_LEFT
35 #define MANDELBROT_RIGHT BUTTON_RIGHT
36 #define MANDELBROT_ZOOM_IN BUTTON_PLAY
37 #define MANDELBROT_ZOOM_OUT BUTTON_ON
38 #define MANDELBROT_MAXITER_INC BUTTON_F2
39 #define MANDELBROT_MAXITER_DEC BUTTON_F1
40 #define MANDELBROT_RESET BUTTON_F3
42 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
43 #define MANDELBROT_QUIT BUTTON_OFF
44 #define MANDELBROT_UP BUTTON_UP
45 #define MANDELBROT_DOWN BUTTON_DOWN
46 #define MANDELBROT_LEFT BUTTON_LEFT
47 #define MANDELBROT_RIGHT BUTTON_RIGHT
48 #define MANDELBROT_ZOOM_IN BUTTON_SELECT
49 #define MANDELBROT_ZOOM_OUT BUTTON_ON
50 #define MANDELBROT_MAXITER_INC BUTTON_F2
51 #define MANDELBROT_MAXITER_DEC BUTTON_F1
52 #define MANDELBROT_RESET BUTTON_F3
54 #elif CONFIG_KEYPAD == ONDIO_PAD
55 #define MANDELBROT_QUIT BUTTON_OFF
56 #define MANDELBROT_UP BUTTON_UP
57 #define MANDELBROT_DOWN BUTTON_DOWN
58 #define MANDELBROT_LEFT BUTTON_LEFT
59 #define MANDELBROT_RIGHT BUTTON_RIGHT
60 #define MANDELBROT_ZOOM_IN_PRE BUTTON_MENU
61 #define MANDELBROT_ZOOM_IN (BUTTON_MENU | BUTTON_REL)
62 #define MANDELBROT_ZOOM_IN2 (BUTTON_MENU | BUTTON_UP)
63 #define MANDELBROT_ZOOM_OUT (BUTTON_MENU | BUTTON_DOWN)
64 #define MANDELBROT_MAXITER_INC (BUTTON_MENU | BUTTON_RIGHT)
65 #define MANDELBROT_MAXITER_DEC (BUTTON_MENU | BUTTON_LEFT)
66 #define MANDELBROT_RESET (BUTTON_MENU | BUTTON_OFF)
68 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
69 (CONFIG_KEYPAD == IRIVER_H300_PAD)
70 #define MANDELBROT_QUIT BUTTON_OFF
71 #define MANDELBROT_UP BUTTON_UP
72 #define MANDELBROT_DOWN BUTTON_DOWN
73 #define MANDELBROT_LEFT BUTTON_LEFT
74 #define MANDELBROT_RIGHT BUTTON_RIGHT
75 #define MANDELBROT_ZOOM_IN BUTTON_SELECT
76 #define MANDELBROT_ZOOM_OUT BUTTON_MODE
77 #define MANDELBROT_MAXITER_INC (BUTTON_ON | BUTTON_RIGHT)
78 #define MANDELBROT_MAXITER_DEC (BUTTON_ON | BUTTON_LEFT)
79 #define MANDELBROT_RESET BUTTON_REC
81 #define MANDELBROT_RC_QUIT BUTTON_RC_STOP
83 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
84 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
85 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
86 #define MANDELBROT_QUIT (BUTTON_SELECT | BUTTON_MENU)
87 #define MANDELBROT_UP BUTTON_MENU
88 #define MANDELBROT_DOWN BUTTON_PLAY
89 #define MANDELBROT_LEFT BUTTON_LEFT
90 #define MANDELBROT_RIGHT BUTTON_RIGHT
91 #define MANDELBROT_ZOOM_IN BUTTON_SCROLL_FWD
92 #define MANDELBROT_ZOOM_OUT BUTTON_SCROLL_BACK
93 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
94 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
95 #define MANDELBROT_RESET (BUTTON_SELECT | BUTTON_PLAY)
97 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
98 #define MANDELBROT_QUIT BUTTON_POWER
99 #define MANDELBROT_UP BUTTON_UP
100 #define MANDELBROT_DOWN BUTTON_DOWN
101 #define MANDELBROT_LEFT BUTTON_LEFT
102 #define MANDELBROT_RIGHT BUTTON_RIGHT
103 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
104 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
105 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
106 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
107 #define MANDELBROT_MAXITER_INC_PRE BUTTON_PLAY
108 #define MANDELBROT_MAXITER_INC (BUTTON_PLAY | BUTTON_REL)
109 #define MANDELBROT_MAXITER_DEC_PRE BUTTON_PLAY
110 #define MANDELBROT_MAXITER_DEC (BUTTON_PLAY | BUTTON_REPEAT)
111 #define MANDELBROT_RESET BUTTON_REC
113 #elif CONFIG_KEYPAD == GIGABEAT_PAD
114 #define MANDELBROT_QUIT BUTTON_POWER
115 #define MANDELBROT_UP BUTTON_UP
116 #define MANDELBROT_DOWN BUTTON_DOWN
117 #define MANDELBROT_LEFT BUTTON_LEFT
118 #define MANDELBROT_RIGHT BUTTON_RIGHT
119 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
120 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
121 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
122 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
123 #define MANDELBROT_MAXITER_INC BUTTON_VOL_UP
124 #define MANDELBROT_MAXITER_DEC BUTTON_VOL_DOWN
125 #define MANDELBROT_RESET BUTTON_A
127 #elif CONFIG_KEYPAD == SANSA_E200_PAD
128 #define MANDELBROT_QUIT BUTTON_POWER
129 #define MANDELBROT_UP BUTTON_UP
130 #define MANDELBROT_DOWN BUTTON_DOWN
131 #define MANDELBROT_LEFT BUTTON_LEFT
132 #define MANDELBROT_RIGHT BUTTON_RIGHT
133 #define MANDELBROT_ZOOM_IN BUTTON_SCROLL_FWD
134 #define MANDELBROT_ZOOM_OUT BUTTON_SCROLL_BACK
135 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
136 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
137 #define MANDELBROT_RESET BUTTON_REC
139 #elif CONFIG_KEYPAD == SANSA_C200_PAD
140 #define MANDELBROT_QUIT BUTTON_POWER
141 #define MANDELBROT_UP BUTTON_UP
142 #define MANDELBROT_DOWN BUTTON_DOWN
143 #define MANDELBROT_LEFT BUTTON_LEFT
144 #define MANDELBROT_RIGHT BUTTON_RIGHT
145 #define MANDELBROT_ZOOM_IN BUTTON_VOL_UP
146 #define MANDELBROT_ZOOM_OUT BUTTON_VOL_DOWN
147 #define MANDELBROT_MAXITER_INC (BUTTON_SELECT | BUTTON_RIGHT)
148 #define MANDELBROT_MAXITER_DEC (BUTTON_SELECT | BUTTON_LEFT)
149 #define MANDELBROT_RESET BUTTON_REC
151 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
152 #define MANDELBROT_QUIT BUTTON_POWER
153 #define MANDELBROT_UP BUTTON_SCROLL_UP
154 #define MANDELBROT_DOWN BUTTON_SCROLL_DOWN
155 #define MANDELBROT_LEFT BUTTON_LEFT
156 #define MANDELBROT_RIGHT BUTTON_RIGHT
157 #define MANDELBROT_ZOOM_IN_PRE BUTTON_PLAY
158 #define MANDELBROT_ZOOM_IN (BUTTON_PLAY | BUTTON_REL)
159 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_PLAY
160 #define MANDELBROT_ZOOM_OUT (BUTTON_PLAY | BUTTON_REPEAT)
161 #define MANDELBROT_MAXITER_INC BUTTON_FF
162 #define MANDELBROT_MAXITER_DEC BUTTON_REW
163 #define MANDELBROT_RESET (BUTTON_PLAY | BUTTON_REW)
165 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
166 #define MANDELBROT_QUIT BUTTON_EQ
167 #define MANDELBROT_UP BUTTON_UP
168 #define MANDELBROT_DOWN BUTTON_DOWN
169 #define MANDELBROT_LEFT BUTTON_LEFT
170 #define MANDELBROT_RIGHT BUTTON_RIGHT
171 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
172 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
173 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
174 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
175 #define MANDELBROT_MAXITER_INC (BUTTON_PLAY | BUTTON_RIGHT)
176 #define MANDELBROT_MAXITER_DEC (BUTTON_PLAY | BUTTON_LEFT)
177 #define MANDELBROT_RESET BUTTON_MODE
179 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
180 #define MANDELBROT_QUIT BUTTON_BACK
181 #define MANDELBROT_UP BUTTON_UP
182 #define MANDELBROT_DOWN BUTTON_DOWN
183 #define MANDELBROT_LEFT BUTTON_LEFT
184 #define MANDELBROT_RIGHT BUTTON_RIGHT
185 #define MANDELBROT_ZOOM_IN BUTTON_VOL_UP
186 #define MANDELBROT_ZOOM_OUT BUTTON_VOL_DOWN
187 #define MANDELBROT_MAXITER_INC BUTTON_PREV
188 #define MANDELBROT_MAXITER_DEC BUTTON_NEXT
189 #define MANDELBROT_RESET BUTTON_MENU
191 #elif CONFIG_KEYPAD == MROBE100_PAD
192 #define MANDELBROT_QUIT BUTTON_POWER
193 #define MANDELBROT_UP BUTTON_UP
194 #define MANDELBROT_DOWN BUTTON_DOWN
195 #define MANDELBROT_LEFT BUTTON_LEFT
196 #define MANDELBROT_RIGHT BUTTON_RIGHT
197 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
198 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_REL)
199 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
200 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_REPEAT)
201 #define MANDELBROT_MAXITER_INC BUTTON_MENU
202 #define MANDELBROT_MAXITER_DEC BUTTON_PLAY
203 #define MANDELBROT_RESET BUTTON_DISPLAY
205 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
206 #define MANDELBROT_QUIT BUTTON_RC_REC
207 #define MANDELBROT_UP BUTTON_RC_VOL_UP
208 #define MANDELBROT_DOWN BUTTON_RC_VOL_DOWN
209 #define MANDELBROT_LEFT BUTTON_RC_REW
210 #define MANDELBROT_RIGHT BUTTON_RC_FF
211 #define MANDELBROT_ZOOM_IN_PRE BUTTON_RC_PLAY
212 #define MANDELBROT_ZOOM_IN (BUTTON_RC_PLAY | BUTTON_REL)
213 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_RC_PLAY
214 #define MANDELBROT_ZOOM_OUT (BUTTON_RC_PLAY | BUTTON_REPEAT)
215 #define MANDELBROT_MAXITER_INC_PRE BUTTON_RC_MODE
216 #define MANDELBROT_MAXITER_INC (BUTTON_RC_MODE|BUTTON_REL)
217 #define MANDELBROT_MAXITER_DEC_PRE BUTTON_RC_MODE
218 #define MANDELBROT_MAXITER_DEC (BUTTON_RC_MODE|BUTTON_REPEAT)
219 #define MANDELBROT_RESET BUTTON_RC_MENU
221 #elif CONFIG_KEYPAD == COWOND2_PAD
222 #define MANDELBROT_QUIT BUTTON_POWER
223 #define MANDELBROT_UP BUTTON_UP
224 #define MANDELBROT_DOWN BUTTON_DOWN
225 #define MANDELBROT_LEFT BUTTON_LEFT
226 #define MANDELBROT_RIGHT BUTTON_RIGHT
227 #define MANDELBROT_ZOOM_IN_PRE BUTTON_SELECT
228 #define MANDELBROT_ZOOM_IN (BUTTON_SELECT | BUTTON_PLUS)
229 #define MANDELBROT_ZOOM_OUT_PRE BUTTON_SELECT
230 #define MANDELBROT_ZOOM_OUT (BUTTON_SELECT | BUTTON_MINUS)
231 #define MANDELBROT_MAXITER_INC BUTTON_PLUS
232 #define MANDELBROT_MAXITER_DEC BUTTON_MINUS
233 #define MANDELBROT_RESET BUTTON_MENU
236 #error No keymap defined!
241 #define MYLCD(fn) grey_ub_ ## fn
242 #define MYLCD_UPDATE()
243 #define MYXLCD(fn) grey_ub_ ## fn
245 #define UPDATE_FREQ (HZ/50)
246 #define MYLCD(fn) rb->lcd_ ## fn
247 #define MYLCD_UPDATE() rb->lcd_update();
248 #define MYXLCD(fn) xlcd_ ## fn
251 static struct plugin_api
* rb
;
253 /* Fixed point format s5.26: sign, 5 bits integer part, 26 bits fractional part */
263 static int px_min
= 0;
264 static int px_max
= LCD_WIDTH
;
265 static int py_min
= 0;
266 static int py_max
= LCD_HEIGHT
;
268 static int step_log2
;
269 static unsigned max_iter
;
273 static unsigned char *gbuf
;
274 static size_t gbuf_size
= 0;
275 static unsigned char imgbuffer
[LCD_HEIGHT
];
277 static fb_data imgbuffer
[LCD_HEIGHT
];
280 /* 8 entries cyclical, last entry is black (convergence) */
281 #ifdef HAVE_LCD_COLOR
282 static const fb_data color
[9] = {
283 LCD_RGBPACK(255, 0, 159), LCD_RGBPACK(159, 0, 255), LCD_RGBPACK(0, 0, 255),
284 LCD_RGBPACK(0, 159, 255), LCD_RGBPACK(0, 255, 128), LCD_RGBPACK(128, 255, 0),
285 LCD_RGBPACK(255, 191, 0), LCD_RGBPACK(255, 0, 0), LCD_RGBPACK(0, 0, 0)
287 #else /* greyscale */
288 static const fb_data color
[9] = {
289 255, 223, 191, 159, 128, 96, 64, 32, 0
293 #if CONFIG_CPU == SH7034
295 #define MULS16_ASR10(a, b) muls16_asr10(a, b)
296 static inline short muls16_asr10(short a
, short b
)
313 #define MULS32_ASR26(a, b) muls32_asr26(a, b)
314 static inline long muls32_asr26(long a
, long b
)
318 /* Signed 32bit * 32bit -> 64bit multiplication.
319 Notation: xxab * xxcd, where each letter represents 16 bits.
320 xx is the 64 bit sign extension. */
321 "swap.w %[a],%[t1] \n" /* t1 = ba */
322 "mulu %[t1],%[b] \n" /* a * d */
323 "swap.w %[b],%[t3] \n" /* t3 = dc */
324 "sts macl,%[t2] \n" /* t2 = a * d */
325 "mulu %[t1],%[t3] \n" /* a * c */
326 "sts macl,%[r] \n" /* hi = a * c */
327 "mulu %[a],%[t3] \n" /* b * c */
329 "sts macl,%[t3] \n" /* t3 = b * c */
330 "addc %[t2],%[t3] \n" /* t3 += t2, carry -> t2 */
332 "mulu %[a],%[b] \n" /* b * d */
333 "mov %[t3],%[t1] \n" /* t2t3 <<= 16 */
334 "xtrct %[t2],%[t1] \n"
337 "sts macl,%[t1] \n" /* lo = b * d */
338 "clrt \n" /* hi.lo += t2t3 */
339 "addc %[t3],%[t1] \n"
341 "cmp/pz %[a] \n" /* ab >= 0 ? */
343 "sub %[b],%[r] \n" /* no: hi -= cd (sign extension of ab is -1) */
345 "cmp/pz %[b] \n" /* cd >= 0 ? */
347 "sub %[a],%[r] \n" /* no: hi -= ab (sign extension of cd is -1) */
349 /* Shift right by 26 and return low 32 bits */
350 "shll2 %[r] \n" /* hi <<= 6 */
353 "shlr16 %[t1] \n" /* (unsigned)lo >>= 26 */
356 "or %[t1],%[r] \n" /* combine result */
369 #elif defined CPU_COLDFIRE
371 #define MULS16_ASR10(a, b) muls16_asr10(a, b)
372 static inline short muls16_asr10(short a
, short b
)
375 "muls.w %[a],%[b] \n"
386 /* Needs the EMAC initialised to fractional mode w/o rounding and saturation */
387 #define MULS32_INIT() coldfire_set_macsr(EMAC_FRACTIONAL)
388 #define MULS32_ASR26(a, b) muls32_asr26(a, b)
389 static inline long muls32_asr26(long a
, long b
)
393 "mac.l %[a], %[b], %%acc0 \n" /* multiply */
394 "move.l %%accext01, %[t1] \n" /* get low part */
395 "movclr.l %%acc0, %[r] \n" /* get high part */
396 "asl.l #5, %[r] \n" /* hi <<= 5, plus one free */
397 "lsr.l #3, %[t1] \n" /* lo >>= 3 */
398 "and.l #0x1f, %[t1] \n" /* mask out unrelated bits */
399 "or.l %[t1], %[r] \n" /* combine result */
410 #elif defined CPU_ARM
412 #define MULS32_ASR26(a, b) muls32_asr26(a, b)
413 static inline long muls32_asr26(long a
, long b
)
417 "smull %[r], %[t1], %[a], %[b] \n"
418 "mov %[r], %[r], lsr #26 \n"
419 "orr %[r], %[r], %[t1], lsl #6 \n"
434 #define MULS16_ASR10(a, b) ((short)(((long)(a) * (long)(b)) >> 10))
437 #define MULS32_ASR26(a, b) ((long)(((long long)(a) * (long long)(b)) >> 26))
440 #define MULS32_INIT()
443 int ilog2_fp(long value
) /* calculate integer log2(value_fp_6.26) */
449 } else if (value
> (1L<<26)) {
450 while (value
>= (2L<<26)) {
455 while (value
< (1L<<26)) {
463 void recalc_parameters(void)
465 x_step
= (x_max
- x_min
) / LCD_WIDTH
;
466 x_delta
= (x_step
* LCD_WIDTH
) / 8;
467 y_step
= (y_max
- y_min
) / LCD_HEIGHT
;
468 y_delta
= (y_step
* LCD_HEIGHT
) / 8;
469 step_log2
= ilog2_fp(MIN(x_step
, y_step
));
470 max_iter
= MAX(15, -15 * step_log2
- 45);
473 #if CONFIG_LCD == LCD_SSD1815
474 /* Recorder, Ondio: pixel_height == 1.25 * pixel_width */
475 #define MB_HEIGHT (LCD_HEIGHT*5/4)
478 #define MB_HEIGHT LCD_HEIGHT
481 #define MB_XOFS (-0x03000000L) /* -0.75 (s5.26) */
482 #if 3000*MB_HEIGHT/LCD_WIDTH >= 2400 /* width is limiting factor */
483 #define MB_XFAC (0x06000000LL) /* 1.5 (s5.26) */
484 #define MB_YFAC (MB_XFAC*MB_HEIGHT/LCD_WIDTH)
485 #else /* height is limiting factor */
486 #define MB_YFAC (0x04cccccdLL) /* 1.2 (s5.26) */
487 #define MB_XFAC (MB_YFAC*LCD_WIDTH/MB_HEIGHT)
490 void init_mandelbrot_set(void)
492 x_min
= MB_XOFS
-MB_XFAC
;
493 x_max
= MB_XOFS
+MB_XFAC
;
499 void calc_mandelbrot_low_prec(void)
501 long start_tick
, last_yield
;
503 long next_update
= *rb
->current_tick
;
504 int last_px
= px_min
;
508 short x
, x2
, y
, y2
, a
, b
;
511 start_tick
= last_yield
= *rb
->current_tick
;
513 for (p_x
= 0, a32
= x_min
; p_x
< px_max
; p_x
++, a32
+= x_step
) {
517 for (p_y
= LCD_HEIGHT
-1, b32
= y_min
; p_y
>= py_min
; p_y
--, b32
+= y_step
) {
525 while (++n_iter
<= max_iter
) {
526 x2
= MULS16_ASR10(x
, x
);
527 y2
= MULS16_ASR10(y
, y
);
529 if (x2
+ y2
> (4<<10)) break;
531 y
= 2 * MULS16_ASR10(x
, y
) + b
;
535 if (n_iter
> max_iter
)
536 imgbuffer
[p_y
] = color
[8];
538 imgbuffer
[p_y
] = color
[n_iter
& 7];
540 /* be nice to other threads:
541 * if at least one tick has passed, yield */
542 if (*rb
->current_tick
> last_yield
) {
544 last_yield
= *rb
->current_tick
;
548 grey_ub_gray_bitmap_part(imgbuffer
, 0, py_min
, 1,
549 p_x
, py_min
, 1, py_max
- py_min
);
551 rb
->lcd_bitmap_part(imgbuffer
, 0, py_min
, 1,
552 p_x
, py_min
, 1, py_max
- py_min
);
553 if ((p_x
== px_max
- 1) || TIME_AFTER(*rb
->current_tick
, next_update
))
555 next_update
= *rb
->current_tick
+ UPDATE_FREQ
;
556 rb
->lcd_update_rect(last_px
, py_min
, p_x
- last_px
+ 1,
564 void calc_mandelbrot_high_prec(void)
566 long start_tick
, last_yield
;
568 long next_update
= *rb
->current_tick
;
569 int last_px
= px_min
;
572 long x
, x2
, y
, y2
, a
, b
;
576 start_tick
= last_yield
= *rb
->current_tick
;
578 for (p_x
= 0, a
= x_min
; p_x
< px_max
; p_x
++, a
+= x_step
) {
581 for (p_y
= LCD_HEIGHT
-1, b
= y_min
; p_y
>= py_min
; p_y
--, b
+= y_step
) {
588 while (++n_iter
<= max_iter
) {
589 x2
= MULS32_ASR26(x
, x
);
590 y2
= MULS32_ASR26(y
, y
);
592 if (x2
+ y2
> (4L<<26)) break;
594 y
= 2 * MULS32_ASR26(x
, y
) + b
;
598 if (n_iter
> max_iter
)
599 imgbuffer
[p_y
] = color
[8];
601 imgbuffer
[p_y
] = color
[n_iter
& 7];
603 /* be nice to other threads:
604 * if at least one tick has passed, yield */
605 if (*rb
->current_tick
> last_yield
) {
607 last_yield
= *rb
->current_tick
;
611 grey_ub_gray_bitmap_part(imgbuffer
, 0, py_min
, 1,
612 p_x
, py_min
, 1, py_max
- py_min
);
614 rb
->lcd_bitmap_part(imgbuffer
, 0, py_min
, 1,
615 p_x
, py_min
, 1, py_max
-py_min
);
616 if ((p_x
== px_max
- 1) || TIME_AFTER(*rb
->current_tick
, next_update
))
618 next_update
= *rb
->current_tick
+ UPDATE_FREQ
;
619 rb
->lcd_update_rect(last_px
, py_min
, p_x
- last_px
+ 1,
627 void cleanup(void *parameter
)
635 #define REDRAW_NONE 0
636 #define REDRAW_PARTIAL 1
637 #define REDRAW_FULL 2
639 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
642 int lastbutton
= BUTTON_NONE
;
643 int redraw
= REDRAW_FULL
;
649 /* get the remainder of the plugin buffer */
650 gbuf
= (unsigned char *) rb
->plugin_get_buffer(&gbuf_size
);
652 /* initialize the greyscale buffer.*/
653 if (!grey_init(rb
, gbuf
, gbuf_size
, GREY_ON_COP
,
654 LCD_WIDTH
, LCD_HEIGHT
, NULL
))
656 rb
->splash(HZ
, "Couldn't init greyscale display");
659 grey_show(true); /* switch on greyscale overlay */
665 rb
->lcd_set_backdrop(NULL
);
668 init_mandelbrot_set();
672 if (redraw
> REDRAW_NONE
) {
673 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
676 if (redraw
== REDRAW_FULL
) {
677 MYLCD(clear_display
)();
681 if (step_log2
<= -10) /* select precision */
682 calc_mandelbrot_high_prec();
684 calc_mandelbrot_low_prec();
686 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
687 rb
->cpu_boost(false);
693 redraw
= REDRAW_NONE
;
696 button
= rb
->button_get(true);
698 #ifdef MANDELBROT_RC_QUIT
699 case MANDELBROT_RC_QUIT
:
701 case MANDELBROT_QUIT
:
707 case MANDELBROT_ZOOM_OUT
:
708 #ifdef MANDELBROT_ZOOM_OUT_PRE
709 if (lastbutton
!= MANDELBROT_ZOOM_OUT_PRE
)
717 redraw
= REDRAW_FULL
;
721 case MANDELBROT_ZOOM_IN
:
722 #ifdef MANDELBROT_ZOOM_IN_PRE
723 if (lastbutton
!= MANDELBROT_ZOOM_IN_PRE
)
726 #ifdef MANDELBROT_ZOOM_IN2
727 case MANDELBROT_ZOOM_IN2
:
734 redraw
= REDRAW_FULL
;
740 MYXLCD(scroll_down
)(LCD_HEIGHT
/8);
742 py_max
= (LCD_HEIGHT
/8);
743 redraw
= REDRAW_PARTIAL
;
746 case MANDELBROT_DOWN
:
749 MYXLCD(scroll_up
)(LCD_HEIGHT
/8);
751 py_min
= (LCD_HEIGHT
-LCD_HEIGHT
/8);
752 redraw
= REDRAW_PARTIAL
;
755 case MANDELBROT_LEFT
:
758 MYXLCD(scroll_right
)(LCD_WIDTH
/8);
760 px_max
= (LCD_WIDTH
/8);
761 redraw
= REDRAW_PARTIAL
;
764 case MANDELBROT_RIGHT
:
767 MYXLCD(scroll_left
)(LCD_WIDTH
/8);
769 px_min
= (LCD_WIDTH
-LCD_WIDTH
/8);
770 redraw
= REDRAW_PARTIAL
;
773 case MANDELBROT_MAXITER_DEC
:
774 #ifdef MANDELBROT_MAXITER_DEC_PRE
775 if (lastbutton
!= MANDELBROT_MAXITER_DEC_PRE
)
778 if (max_iter
>= 15) {
779 max_iter
-= max_iter
/ 3;
780 redraw
= REDRAW_FULL
;
784 case MANDELBROT_MAXITER_INC
:
785 #ifdef MANDELBROT_MAXITER_INC_PRE
786 if (lastbutton
!= MANDELBROT_MAXITER_INC_PRE
)
789 max_iter
+= max_iter
/ 2;
790 redraw
= REDRAW_FULL
;
793 case MANDELBROT_RESET
:
794 init_mandelbrot_set();
795 redraw
= REDRAW_FULL
;
799 if (rb
->default_event_handler_ex(button
, cleanup
, NULL
)
800 == SYS_USB_CONNECTED
)
801 return PLUGIN_USB_CONNECTED
;
804 if (button
!= BUTTON_NONE
)