summaryrefslogtreecommitdiff
path: root/apps/plugins/fractals/fractal.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/fractals/fractal.c')
-rw-r--r--apps/plugins/fractals/fractal.c260
1 files changed, 260 insertions, 0 deletions
diff --git a/apps/plugins/fractals/fractal.c b/apps/plugins/fractals/fractal.c
new file mode 100644
index 0000000000..3a0c785bdd
--- /dev/null
+++ b/apps/plugins/fractals/fractal.c
@@ -0,0 +1,260 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2004 Matthias Wientapper
11 * Heavily extended 2005 Jens Arnold
12 * Extended 2009 Tomer Shalev
13 *
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24#include "plugin.h"
25
26#ifdef HAVE_LCD_BITMAP
27
28#include "fractal.h"
29#include "fractal_rect.h"
30#include "fractal_sets.h"
31#include "mandelbrot_set.h"
32
33#if (LCD_DEPTH < 8)
34#define USEGSLIB
35#define MYLCD(fn) grey_ub_ ## fn
36#define MYLCD_UPDATE()
37#define MYXLCD(fn) grey_ub_ ## fn
38#else
39#define MYLCD(fn) rb->lcd_ ## fn
40#define MYLCD_UPDATE() rb->lcd_update();
41#define MYXLCD(fn) xlcd_ ## fn
42#endif
43
44#ifdef USEGSLIB
45GREY_INFO_STRUCT
46static unsigned char *gbuf;
47static size_t gbuf_size = 0;
48unsigned char imgbuffer[LCD_HEIGHT];
49#else
50fb_data imgbuffer[LCD_HEIGHT];
51#endif
52
53#define REDRAW_NONE 0
54#define REDRAW_PARTIAL 1
55#define REDRAW_FULL 2
56
57PLUGIN_HEADER
58
59/* returns 1 if a button has been pressed, 0 otherwise */
60static int button_yield(void *ctx)
61{
62 long *button = (long *)ctx;
63
64 *button = rb->button_get(false);
65 switch (*button)
66 {
67 case FRACTAL_QUIT:
68 case FRACTAL_UP:
69 case FRACTAL_DOWN:
70 case FRACTAL_LEFT:
71 case FRACTAL_RIGHT:
72 case FRACTAL_ZOOM_IN:
73 case FRACTAL_ZOOM_OUT:
74 case FRACTAL_PRECISION_INC:
75 case FRACTAL_PRECISION_DEC:
76 case FRACTAL_RESET:
77#ifdef FRACTAL_ZOOM_IN2
78 case FRACTAL_ZOOM_IN2:
79#endif
80#ifdef FRACTAL_ZOOM_IN_PRE
81 case FRACTAL_ZOOM_IN_PRE:
82#endif
83 return 1;
84 default:
85 *button = BUTTON_NONE;
86 return 0;
87 }
88}
89
90static void cleanup(void *parameter)
91{
92 (void)parameter;
93#ifdef USEGSLIB
94 grey_release();
95#endif
96}
97
98enum plugin_status plugin_start(const void* parameter)
99{
100 long lastbutton = BUTTON_NONE;
101 int redraw = REDRAW_FULL;
102 struct fractal_ops *ops = &mandelbrot_ops;
103
104 (void)parameter;
105
106#ifdef USEGSLIB
107 /* get the remainder of the plugin buffer */
108 gbuf = (unsigned char *)rb->plugin_get_buffer(&gbuf_size);
109
110 /* initialize the greyscale buffer.*/
111 if (!grey_init(gbuf, gbuf_size, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL))
112 {
113 rb->splash(HZ, "Couldn't init greyscale display");
114 return 0;
115 }
116 grey_show(true); /* switch on greyscale overlay */
117#endif
118
119#if LCD_DEPTH > 1
120 rb->lcd_set_backdrop(NULL);
121#endif
122
123 ops->init();
124
125 /* main loop */
126 while (true)
127 {
128 long button = BUTTON_NONE;
129
130 if (redraw != REDRAW_NONE)
131 {
132#ifdef HAVE_ADJUSTABLE_CPU_FREQ
133 rb->cpu_boost(true);
134#endif
135 if (redraw == REDRAW_FULL)
136 {
137 MYLCD(clear_display)();
138 MYLCD_UPDATE();
139 rects_queue_init();
140 }
141
142 /* paint all rects */
143 rects_calc_all(ops->calc, button_yield, (void *)&button);
144#ifdef HAVE_ADJUSTABLE_CPU_FREQ
145 rb->cpu_boost(false);
146#endif
147 /* not interrupted by button press - screen is fully drawn */
148 redraw = (button == BUTTON_NONE) ? REDRAW_NONE : REDRAW_PARTIAL;
149 }
150
151 if (button == BUTTON_NONE)
152 button = rb->button_get(true);
153
154 switch (button)
155 {
156#ifdef FRACTAL_RC_QUIT
157 case FRACTAL_RC_QUIT:
158#endif
159 case FRACTAL_QUIT:
160#ifdef USEGSLIB
161 grey_release();
162#endif
163 return PLUGIN_OK;
164
165 case FRACTAL_ZOOM_OUT:
166#ifdef FRACTAL_ZOOM_OUT_PRE
167 if (lastbutton != FRACTAL_ZOOM_OUT_PRE)
168 break;
169#endif
170 ops->zoom(-1);
171 redraw = REDRAW_FULL;
172 break;
173
174
175 case FRACTAL_ZOOM_IN:
176#ifdef FRACTAL_ZOOM_IN_PRE
177 if (lastbutton != FRACTAL_ZOOM_IN_PRE)
178 break;
179#endif
180#ifdef FRACTAL_ZOOM_IN2
181 case FRACTAL_ZOOM_IN2:
182#endif
183 ops->zoom(1);
184 redraw = REDRAW_FULL;
185 break;
186
187 case FRACTAL_UP:
188 ops->move(0, +1);
189 MYXLCD(scroll_down)(LCD_SHIFT_Y);
190 MYLCD_UPDATE();
191 if (redraw != REDRAW_FULL)
192 redraw = rects_move_down() ? REDRAW_FULL : REDRAW_PARTIAL;
193 break;
194
195 case FRACTAL_DOWN:
196 ops->move(0, -1);
197 MYXLCD(scroll_up)(LCD_SHIFT_Y);
198 MYLCD_UPDATE();
199 if (redraw != REDRAW_FULL)
200 redraw = rects_move_up() ? REDRAW_FULL : REDRAW_PARTIAL;
201 break;
202
203 case FRACTAL_LEFT:
204 ops->move(-1, 0);
205 MYXLCD(scroll_right)(LCD_SHIFT_X);
206 MYLCD_UPDATE();
207 if (redraw != REDRAW_FULL)
208 redraw = rects_move_right() ? REDRAW_FULL : REDRAW_PARTIAL;
209 break;
210
211 case FRACTAL_RIGHT:
212 ops->move(+1, 0);
213 MYXLCD(scroll_left)(LCD_SHIFT_X);
214 MYLCD_UPDATE();
215 if (redraw != REDRAW_FULL)
216 redraw = rects_move_left() ? REDRAW_FULL : REDRAW_PARTIAL;
217 break;
218
219 case FRACTAL_PRECISION_DEC:
220#ifdef FRACTAL_PRECISION_DEC_PRE
221 if (lastbutton != FRACTAL_PRECISION_DEC_PRE)
222 break;
223#endif
224 if (ops->precision(-1))
225 redraw = REDRAW_FULL;
226
227 break;
228
229 case FRACTAL_PRECISION_INC:
230#ifdef FRACTAL_PRECISION_INC_PRE
231 if (lastbutton != FRACTAL_PRECISION_INC_PRE)
232 break;
233#endif
234 if (ops->precision(+1))
235 redraw = REDRAW_FULL;
236
237 break;
238
239 case FRACTAL_RESET:
240 ops->init();
241 redraw = REDRAW_FULL;
242 break;
243
244 default:
245 if (rb->default_event_handler_ex(button, cleanup, NULL)
246 == SYS_USB_CONNECTED)
247 return PLUGIN_USB_CONNECTED;
248 break;
249 }
250
251 if (button != BUTTON_NONE)
252 lastbutton = button;
253 }
254#ifdef USEGSLIB
255 grey_release();
256#endif
257 return PLUGIN_OK;
258}
259
260#endif