diff options
-rw-r--r-- | apps/plugins/fractals/fractal.c | 8 | ||||
-rw-r--r-- | apps/plugins/fractals/fractal_sets.h | 2 | ||||
-rw-r--r-- | apps/plugins/fractals/mandelbrot_set.c | 27 |
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) | |||
167 | if (lastbutton != FRACTAL_ZOOM_OUT_PRE) | 167 | if (lastbutton != FRACTAL_ZOOM_OUT_PRE) |
168 | break; | 168 | break; |
169 | #endif | 169 | #endif |
170 | ops->zoom(-1); | 170 | if (!ops->zoom(-1)) |
171 | redraw = REDRAW_FULL; | 171 | redraw = REDRAW_FULL; |
172 | break; | 172 | break; |
173 | 173 | ||
174 | 174 | ||
@@ -180,8 +180,8 @@ enum plugin_status plugin_start(const void* parameter) | |||
180 | #ifdef FRACTAL_ZOOM_IN2 | 180 | #ifdef FRACTAL_ZOOM_IN2 |
181 | case FRACTAL_ZOOM_IN2: | 181 | case FRACTAL_ZOOM_IN2: |
182 | #endif | 182 | #endif |
183 | ops->zoom(1); | 183 | if (!ops->zoom(1)) |
184 | redraw = REDRAW_FULL; | 184 | redraw = REDRAW_FULL; |
185 | break; | 185 | break; |
186 | 186 | ||
187 | case FRACTAL_UP: | 187 | 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 | |||
47 | int (*calc)(struct fractal_rect *rect, int (*button_yield_cb)(void *ctx), | 47 | int (*calc)(struct fractal_rect *rect, int (*button_yield_cb)(void *ctx), |
48 | void *button_yield_ctx); | 48 | void *button_yield_ctx); |
49 | void (*move)(int dx, int dy); | 49 | void (*move)(int dx, int dy); |
50 | void (*zoom)(int factor); | 50 | int (*zoom)(int factor); |
51 | int (*precision)(int d); | 51 | int (*precision)(int d); |
52 | }; | 52 | }; |
53 | 53 | ||
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, | |||
96 | 96 | ||
97 | static void mandelbrot_move(int dx, int dy); | 97 | static void mandelbrot_move(int dx, int dy); |
98 | 98 | ||
99 | static void mandelbrot_zoom(int factor); | 99 | static int mandelbrot_zoom(int factor); |
100 | 100 | ||
101 | static int mandelbrot_precision(int d); | 101 | static int mandelbrot_precision(int d); |
102 | 102 | ||
@@ -109,13 +109,15 @@ struct fractal_ops mandelbrot_ops = | |||
109 | .precision = mandelbrot_precision, | 109 | .precision = mandelbrot_precision, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #define LOG2_OUT_OF_BOUNDS -32767 | ||
113 | |||
112 | static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */ | 114 | static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */ |
113 | { | 115 | { |
114 | int i = 0; | 116 | int i = 0; |
115 | 117 | ||
116 | if (value <= 0) | 118 | if (value <= 0) |
117 | { | 119 | { |
118 | return -32767; | 120 | return LOG2_OUT_OF_BOUNDS; |
119 | } | 121 | } |
120 | else if (value > (1L << 26)) | 122 | else if (value > (1L << 26)) |
121 | { | 123 | { |
@@ -136,18 +138,24 @@ static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */ | |||
136 | return i; | 138 | return i; |
137 | } | 139 | } |
138 | 140 | ||
139 | static void recalc_parameters(void) | 141 | static int recalc_parameters(void) |
140 | { | 142 | { |
141 | ctx.x_step = (ctx.x_max - ctx.x_min) / LCD_WIDTH; | 143 | ctx.x_step = (ctx.x_max - ctx.x_min) / LCD_WIDTH; |
142 | ctx.x_delta = X_DELTA(ctx.x_step); | ||
143 | ctx.y_step = (ctx.y_max - ctx.y_min) / LCD_HEIGHT; | 144 | ctx.y_step = (ctx.y_max - ctx.y_min) / LCD_HEIGHT; |
145 | ctx.step_log2 = ilog2_fp(MIN(ctx.x_step, ctx.y_step)); | ||
146 | |||
147 | if (ctx.step_log2 == LOG2_OUT_OF_BOUNDS) | ||
148 | return 1; /* out of bounds */ | ||
149 | |||
150 | ctx.x_delta = X_DELTA(ctx.x_step); | ||
144 | ctx.y_delta = Y_DELTA(ctx.y_step); | 151 | ctx.y_delta = Y_DELTA(ctx.y_step); |
145 | ctx.y_delta = (ctx.y_step * LCD_HEIGHT) / 8; | 152 | ctx.y_delta = (ctx.y_step * LCD_HEIGHT) / 8; |
146 | ctx.step_log2 = ilog2_fp(MIN(ctx.x_step, ctx.y_step)); | ||
147 | ctx.max_iter = MAX(15, -15 * ctx.step_log2 - 45); | 153 | ctx.max_iter = MAX(15, -15 * ctx.step_log2 - 45); |
148 | 154 | ||
149 | ctx.ops->calc = (ctx.step_log2 <= -10) ? | 155 | ctx.ops->calc = (ctx.step_log2 <= -10) ? |
150 | mandelbrot_calc_high_prec : mandelbrot_calc_low_prec; | 156 | mandelbrot_calc_high_prec : mandelbrot_calc_low_prec; |
157 | |||
158 | return 0; | ||
151 | } | 159 | } |
152 | 160 | ||
153 | static void mandelbrot_init(void) | 161 | static void mandelbrot_init(void) |
@@ -368,8 +376,9 @@ static void mandelbrot_move(int dx, int dy) | |||
368 | ctx.y_max += d_y; | 376 | ctx.y_max += d_y; |
369 | } | 377 | } |
370 | 378 | ||
371 | static void mandelbrot_zoom(int factor) | 379 | static int mandelbrot_zoom(int factor) |
372 | { | 380 | { |
381 | int res; | ||
373 | long factor_x = (long)factor * ctx.x_delta; | 382 | long factor_x = (long)factor * ctx.x_delta; |
374 | long factor_y = (long)factor * ctx.y_delta; | 383 | long factor_y = (long)factor * ctx.y_delta; |
375 | 384 | ||
@@ -378,7 +387,11 @@ static void mandelbrot_zoom(int factor) | |||
378 | ctx.y_min += factor_y; | 387 | ctx.y_min += factor_y; |
379 | ctx.y_max -= factor_y; | 388 | ctx.y_max -= factor_y; |
380 | 389 | ||
381 | recalc_parameters(); | 390 | res = recalc_parameters(); |
391 | if (res) /* zoom not possible, revert */ | ||
392 | mandelbrot_zoom(-factor); | ||
393 | |||
394 | return res; | ||
382 | } | 395 | } |
383 | 396 | ||
384 | static int mandelbrot_precision(int d) | 397 | static int mandelbrot_precision(int d) |