diff options
Diffstat (limited to 'apps/plugins/fractals/fractal.c')
-rw-r--r-- | apps/plugins/fractals/fractal.c | 260 |
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 | ||
45 | GREY_INFO_STRUCT | ||
46 | static unsigned char *gbuf; | ||
47 | static size_t gbuf_size = 0; | ||
48 | unsigned char imgbuffer[LCD_HEIGHT]; | ||
49 | #else | ||
50 | fb_data imgbuffer[LCD_HEIGHT]; | ||
51 | #endif | ||
52 | |||
53 | #define REDRAW_NONE 0 | ||
54 | #define REDRAW_PARTIAL 1 | ||
55 | #define REDRAW_FULL 2 | ||
56 | |||
57 | PLUGIN_HEADER | ||
58 | |||
59 | /* returns 1 if a button has been pressed, 0 otherwise */ | ||
60 | static 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 | |||
90 | static void cleanup(void *parameter) | ||
91 | { | ||
92 | (void)parameter; | ||
93 | #ifdef USEGSLIB | ||
94 | grey_release(); | ||
95 | #endif | ||
96 | } | ||
97 | |||
98 | enum 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 | ||