forked from len0rd/rockbox
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
This commit is contained in:
parent
5b94d44cc0
commit
ab450a81ec
3 changed files with 25 additions and 12 deletions
|
@ -167,7 +167,7 @@ enum plugin_status plugin_start(const void* parameter)
|
||||||
if (lastbutton != FRACTAL_ZOOM_OUT_PRE)
|
if (lastbutton != FRACTAL_ZOOM_OUT_PRE)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
ops->zoom(-1);
|
if (!ops->zoom(-1))
|
||||||
redraw = REDRAW_FULL;
|
redraw = REDRAW_FULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ enum plugin_status plugin_start(const void* parameter)
|
||||||
#ifdef FRACTAL_ZOOM_IN2
|
#ifdef FRACTAL_ZOOM_IN2
|
||||||
case FRACTAL_ZOOM_IN2:
|
case FRACTAL_ZOOM_IN2:
|
||||||
#endif
|
#endif
|
||||||
ops->zoom(1);
|
if (!ops->zoom(1))
|
||||||
redraw = REDRAW_FULL;
|
redraw = REDRAW_FULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct fractal_ops
|
||||||
int (*calc)(struct fractal_rect *rect, int (*button_yield_cb)(void *ctx),
|
int (*calc)(struct fractal_rect *rect, int (*button_yield_cb)(void *ctx),
|
||||||
void *button_yield_ctx);
|
void *button_yield_ctx);
|
||||||
void (*move)(int dx, int dy);
|
void (*move)(int dx, int dy);
|
||||||
void (*zoom)(int factor);
|
int (*zoom)(int factor);
|
||||||
int (*precision)(int d);
|
int (*precision)(int d);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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_move(int dx, int dy);
|
||||||
|
|
||||||
static void mandelbrot_zoom(int factor);
|
static int mandelbrot_zoom(int factor);
|
||||||
|
|
||||||
static int mandelbrot_precision(int d);
|
static int mandelbrot_precision(int d);
|
||||||
|
|
||||||
|
@ -109,13 +109,15 @@ struct fractal_ops mandelbrot_ops =
|
||||||
.precision = mandelbrot_precision,
|
.precision = mandelbrot_precision,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LOG2_OUT_OF_BOUNDS -32767
|
||||||
|
|
||||||
static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */
|
static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
if (value <= 0)
|
if (value <= 0)
|
||||||
{
|
{
|
||||||
return -32767;
|
return LOG2_OUT_OF_BOUNDS;
|
||||||
}
|
}
|
||||||
else if (value > (1L << 26))
|
else if (value > (1L << 26))
|
||||||
{
|
{
|
||||||
|
@ -136,18 +138,24 @@ static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */
|
||||||
return i;
|
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_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.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 = Y_DELTA(ctx.y_step);
|
||||||
ctx.y_delta = (ctx.y_step * LCD_HEIGHT) / 8;
|
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.max_iter = MAX(15, -15 * ctx.step_log2 - 45);
|
||||||
|
|
||||||
ctx.ops->calc = (ctx.step_log2 <= -10) ?
|
ctx.ops->calc = (ctx.step_log2 <= -10) ?
|
||||||
mandelbrot_calc_high_prec : mandelbrot_calc_low_prec;
|
mandelbrot_calc_high_prec : mandelbrot_calc_low_prec;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mandelbrot_init(void)
|
static void mandelbrot_init(void)
|
||||||
|
@ -368,8 +376,9 @@ static void mandelbrot_move(int dx, int dy)
|
||||||
ctx.y_max += d_y;
|
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_x = (long)factor * ctx.x_delta;
|
||||||
long factor_y = (long)factor * ctx.y_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_min += factor_y;
|
||||||
ctx.y_max -= 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)
|
static int mandelbrot_precision(int d)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue