From ab450a81ec1d81d3ea92a5b14edd2265fc2227ea Mon Sep 17 00:00:00 2001 From: Tomer Shalev Date: Sun, 17 Jan 2010 21:15:56 +0000 Subject: Fractals: Prevent zooming more than deepest possible zoom This prevent the mandelbrost set from being trashed if zooming too much git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24264 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/fractals/fractal.c | 8 ++++---- apps/plugins/fractals/fractal_sets.h | 2 +- apps/plugins/fractals/mandelbrot_set.c | 27 ++++++++++++++++++++------- 3 files changed, 25 insertions(+), 12 deletions(-) (limited to 'apps/plugins/fractals') diff --git a/apps/plugins/fractals/fractal.c b/apps/plugins/fractals/fractal.c index aa8f39853c..7543963ded 100644 --- a/apps/plugins/fractals/fractal.c +++ b/apps/plugins/fractals/fractal.c @@ -167,8 +167,8 @@ enum plugin_status plugin_start(const void* parameter) if (lastbutton != FRACTAL_ZOOM_OUT_PRE) break; #endif - ops->zoom(-1); - redraw = REDRAW_FULL; + if (!ops->zoom(-1)) + redraw = REDRAW_FULL; break; @@ -180,8 +180,8 @@ enum plugin_status plugin_start(const void* parameter) #ifdef FRACTAL_ZOOM_IN2 case FRACTAL_ZOOM_IN2: #endif - ops->zoom(1); - redraw = REDRAW_FULL; + if (!ops->zoom(1)) + redraw = REDRAW_FULL; break; case FRACTAL_UP: diff --git a/apps/plugins/fractals/fractal_sets.h b/apps/plugins/fractals/fractal_sets.h index a41de45c14..3b5e3c7856 100644 --- a/apps/plugins/fractals/fractal_sets.h +++ b/apps/plugins/fractals/fractal_sets.h @@ -47,7 +47,7 @@ struct fractal_ops int (*calc)(struct fractal_rect *rect, int (*button_yield_cb)(void *ctx), void *button_yield_ctx); void (*move)(int dx, int dy); - void (*zoom)(int factor); + int (*zoom)(int factor); int (*precision)(int d); }; diff --git a/apps/plugins/fractals/mandelbrot_set.c b/apps/plugins/fractals/mandelbrot_set.c index b8a65d6787..ab20512b15 100644 --- a/apps/plugins/fractals/mandelbrot_set.c +++ b/apps/plugins/fractals/mandelbrot_set.c @@ -96,7 +96,7 @@ static int mandelbrot_calc_high_prec(struct fractal_rect *rect, static void mandelbrot_move(int dx, int dy); -static void mandelbrot_zoom(int factor); +static int mandelbrot_zoom(int factor); static int mandelbrot_precision(int d); @@ -109,13 +109,15 @@ struct fractal_ops mandelbrot_ops = .precision = mandelbrot_precision, }; +#define LOG2_OUT_OF_BOUNDS -32767 + static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */ { int i = 0; if (value <= 0) { - return -32767; + return LOG2_OUT_OF_BOUNDS; } else if (value > (1L << 26)) { @@ -136,18 +138,24 @@ static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */ return i; } -static void recalc_parameters(void) +static int recalc_parameters(void) { ctx.x_step = (ctx.x_max - ctx.x_min) / LCD_WIDTH; - ctx.x_delta = X_DELTA(ctx.x_step); ctx.y_step = (ctx.y_max - ctx.y_min) / LCD_HEIGHT; + ctx.step_log2 = ilog2_fp(MIN(ctx.x_step, ctx.y_step)); + + if (ctx.step_log2 == LOG2_OUT_OF_BOUNDS) + return 1; /* out of bounds */ + + ctx.x_delta = X_DELTA(ctx.x_step); ctx.y_delta = Y_DELTA(ctx.y_step); ctx.y_delta = (ctx.y_step * LCD_HEIGHT) / 8; - ctx.step_log2 = ilog2_fp(MIN(ctx.x_step, ctx.y_step)); ctx.max_iter = MAX(15, -15 * ctx.step_log2 - 45); ctx.ops->calc = (ctx.step_log2 <= -10) ? mandelbrot_calc_high_prec : mandelbrot_calc_low_prec; + + return 0; } static void mandelbrot_init(void) @@ -368,8 +376,9 @@ static void mandelbrot_move(int dx, int dy) ctx.y_max += d_y; } -static void mandelbrot_zoom(int factor) +static int mandelbrot_zoom(int factor) { + int res; long factor_x = (long)factor * ctx.x_delta; long factor_y = (long)factor * ctx.y_delta; @@ -378,7 +387,11 @@ static void mandelbrot_zoom(int factor) ctx.y_min += factor_y; ctx.y_max -= factor_y; - recalc_parameters(); + res = recalc_parameters(); + if (res) /* zoom not possible, revert */ + mandelbrot_zoom(-factor); + + return res; } static int mandelbrot_precision(int d) -- cgit