summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomer Shalev <shalev.tomer@gmail.com>2010-01-17 21:15:56 +0000
committerTomer Shalev <shalev.tomer@gmail.com>2010-01-17 21:15:56 +0000
commitab450a81ec1d81d3ea92a5b14edd2265fc2227ea (patch)
treec6aa4d9bf18ec2b6558f18c82b6c213f9d87053a
parent5b94d44cc0b0bc7caceafff60131b633cc45c6bc (diff)
downloadrockbox-ab450a81ec1d81d3ea92a5b14edd2265fc2227ea.tar.gz
rockbox-ab450a81ec1d81d3ea92a5b14edd2265fc2227ea.zip
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
-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)
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
97static void mandelbrot_move(int dx, int dy); 97static void mandelbrot_move(int dx, int dy);
98 98
99static void mandelbrot_zoom(int factor); 99static int mandelbrot_zoom(int factor);
100 100
101static int mandelbrot_precision(int d); 101static 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
112static int ilog2_fp(long value) /* calculate integer log2(value_fp_6.26) */ 114static 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
139static void recalc_parameters(void) 141static 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
153static void mandelbrot_init(void) 161static 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
371static void mandelbrot_zoom(int factor) 379static 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
384static int mandelbrot_precision(int d) 397static int mandelbrot_precision(int d)