Index: apps/plugins/mandelbrot.c =================================================================== --- apps/plugins/mandelbrot.c (revision 24050) +++ apps/plugins/mandelbrot.c (working copy) @@ -292,7 +292,7 @@ #define MANDELBROT_ZOOM_IN BUTTON_RIGHT #define MANDELBROT_ZOOM_OUT BUTTON_LEFT #define MANDELBROT_MAXITER_INC BUTTON_VOL_UP -#define MANDELBROT_MAXITER_DEV BUTTON_VOL_DOWN +#define MANDELBROT_MAXITER_DEC BUTTON_VOL_DOWN #define MANDELBROT_RESET BUTTON_MENU #elif CONFIG_KEYPAD == ONDAVX747_PAD || CONFIG_KEYPAD == MROBE500_PAD @@ -367,6 +367,8 @@ #define MYXLCD(fn) xlcd_ ## fn #endif +#define BUTTON_YIELD_TIMEOUT (HZ / 4) + /* Fixed point format s5.26: sign, 5 bits integer part, 26 bits fractional part */ static long x_min; static long x_max; @@ -612,9 +614,53 @@ recalc_parameters(); } -void calc_mandelbrot_low_prec(void) +static int button_yield(unsigned long *last_button_yield, long *button) { - long start_tick, last_yield; + int res; + long btn; + + if (!TIME_AFTER(*rb->current_tick, + *last_button_yield + BUTTON_YIELD_TIMEOUT)) + { + return 0; + } + + *last_button_yield = *rb->current_tick; + res = 0; + + btn = rb->button_get(false); + switch (btn) + { + case BUTTON_NONE: + break; + case MANDELBROT_QUIT: + case MANDELBROT_UP: + case MANDELBROT_DOWN: + case MANDELBROT_LEFT: + case MANDELBROT_RIGHT: + case MANDELBROT_ZOOM_IN: + case MANDELBROT_ZOOM_OUT: + case MANDELBROT_MAXITER_INC: + case MANDELBROT_MAXITER_DEC: + case MANDELBROT_RESET: +#ifdef MANDELBROT_ZOOM_IN2 + case MANDELBROT_ZOOM_IN2: +#endif +#ifdef MANDELBROT_ZOOM_IN_PRE + case MANDELBROT_ZOOM_IN_PRE: +#endif + *button = btn; + res = 1; + break; + default: + break; + } + + return res; +} + +long calc_mandelbrot_low_prec(void) +{ #ifndef USEGSLIB long next_update = *rb->current_tick; int last_px = px_min; @@ -623,14 +669,17 @@ long a32, b32; short x, x2, y, y2, a, b; int p_x, p_y; + unsigned long last_yield = *rb->current_tick; + unsigned long last_button_yield = *rb->current_tick; - start_tick = last_yield = *rb->current_tick; - for (p_x = 0, a32 = x_min; p_x < px_max; p_x++, a32 += x_step) { if (p_x < px_min) continue; a = a32 >> 16; - for (p_y = LCD_HEIGHT-1, b32 = y_min; p_y >= py_min; p_y--, b32 += y_step) { + for (p_y = LCD_HEIGHT-1, b32 = y_min; p_y >= py_min; p_y--, b32 += y_step) + { + long button; + if (p_y >= py_max) continue; b = b32 >> 16; @@ -659,6 +708,9 @@ rb->yield(); last_yield = *rb->current_tick; } + + if (button_yield(&last_button_yield, &button)) + return button; } #ifdef USEGSLIB grey_ub_gray_bitmap_part(imgbuffer, 0, py_min, 1, @@ -675,11 +727,12 @@ } #endif } + + return BUTTON_NONE; } -void calc_mandelbrot_high_prec(void) +long calc_mandelbrot_high_prec(void) { - long start_tick, last_yield; #ifndef USEGSLIB long next_update = *rb->current_tick; int last_px = px_min; @@ -687,14 +740,18 @@ unsigned n_iter; long x, x2, y, y2, a, b; int p_x, p_y; + unsigned long last_yield = *rb->current_tick; + unsigned long last_button_yield = *rb->current_tick; MULS32_INIT(); - start_tick = last_yield = *rb->current_tick; for (p_x = 0, a = x_min; p_x < px_max; p_x++, a += x_step) { if (p_x < px_min) continue; - for (p_y = LCD_HEIGHT-1, b = y_min; p_y >= py_min; p_y--, b += y_step) { + for (p_y = LCD_HEIGHT-1, b = y_min; p_y >= py_min; p_y--, b += y_step) + { + long button; + if (p_y >= py_max) continue; x = a; @@ -722,13 +779,16 @@ rb->yield(); last_yield = *rb->current_tick; } + + if (button_yield(&last_button_yield, &button)) + return button; } #ifdef USEGSLIB grey_ub_gray_bitmap_part(imgbuffer, 0, py_min, 1, p_x, py_min, 1, py_max - py_min); #else rb->lcd_bitmap_part(imgbuffer, 0, py_min, 1, - p_x, py_min, 1, py_max-py_min); + p_x, py_min, 1, py_max - py_min); if ((p_x == px_max - 1) || TIME_AFTER(*rb->current_tick, next_update)) { next_update = *rb->current_tick + UPDATE_FREQ; @@ -738,6 +798,8 @@ } #endif } + + return BUTTON_NONE; } void cleanup(void *parameter) @@ -754,8 +816,8 @@ enum plugin_status plugin_start(const void* parameter) { - int button; - int lastbutton = BUTTON_NONE; + long button; + long lastbutton = BUTTON_NONE; int redraw = REDRAW_FULL; (void)parameter; @@ -782,6 +844,8 @@ /* main loop */ while (true) { + button = BUTTON_NONE; + if (redraw > REDRAW_NONE) { #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(true); @@ -792,21 +856,29 @@ } if (step_log2 <= -10) /* select precision */ - calc_mandelbrot_high_prec(); + button = calc_mandelbrot_high_prec(); else - calc_mandelbrot_low_prec(); + button = calc_mandelbrot_low_prec(); #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(false); #endif - px_min = 0; - px_max = LCD_WIDTH; - py_min = 0; - py_max = LCD_HEIGHT; - redraw = REDRAW_NONE; + if (button == BUTTON_NONE) + { + px_min = 0; + px_max = LCD_WIDTH; + py_min = 0; + py_max = LCD_HEIGHT; + redraw = REDRAW_NONE; + } + else + { + redraw = REDRAW_FULL; + } } - button = rb->button_get(true); + if (button == BUTTON_NONE) + button = rb->button_get(true); switch (button) { #ifdef MANDELBROT_RC_QUIT case MANDELBROT_RC_QUIT: @@ -852,8 +924,11 @@ y_max += y_delta; MYXLCD(scroll_down)(LCD_HEIGHT/8); MYLCD_UPDATE(); - py_max = (LCD_HEIGHT/8); - redraw = REDRAW_PARTIAL; + if (redraw != REDRAW_FULL) + { + py_max = (LCD_HEIGHT/8); + redraw = REDRAW_PARTIAL; + } break; case MANDELBROT_DOWN: @@ -861,8 +936,11 @@ y_max -= y_delta; MYXLCD(scroll_up)(LCD_HEIGHT/8); MYLCD_UPDATE(); - py_min = (LCD_HEIGHT-LCD_HEIGHT/8); - redraw = REDRAW_PARTIAL; + if (redraw != REDRAW_FULL) + { + py_min = (LCD_HEIGHT-LCD_HEIGHT/8); + redraw = REDRAW_PARTIAL; + } break; case MANDELBROT_LEFT: @@ -870,8 +948,11 @@ x_max -= x_delta; MYXLCD(scroll_right)(LCD_WIDTH/8); MYLCD_UPDATE(); - px_max = (LCD_WIDTH/8); - redraw = REDRAW_PARTIAL; + if (redraw != REDRAW_FULL) + { + px_max = (LCD_WIDTH/8); + redraw = REDRAW_PARTIAL; + } break; case MANDELBROT_RIGHT: @@ -879,8 +960,11 @@ x_max += x_delta; MYXLCD(scroll_left)(LCD_WIDTH/8); MYLCD_UPDATE(); - px_min = (LCD_WIDTH-LCD_WIDTH/8); - redraw = REDRAW_PARTIAL; + if (redraw != REDRAW_FULL) + { + px_min = (LCD_WIDTH-LCD_WIDTH/8); + redraw = REDRAW_PARTIAL; + } break; case MANDELBROT_MAXITER_DEC: