summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/fractals/fractal.c8
-rw-r--r--apps/plugins/fractals/fractal_sets.h2
-rw-r--r--apps/plugins/fractals/mandelbrot_set.c27
3 files changed, 25 insertions, 12 deletions
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)