diff options
author | Tomer Shalev <shalev.tomer@gmail.com> | 2010-01-15 05:53:15 +0000 |
---|---|---|
committer | Tomer Shalev <shalev.tomer@gmail.com> | 2010-01-15 05:53:15 +0000 |
commit | 7719d297f2a1da0e45fd39cad21e99e23fd695c8 (patch) | |
tree | ae2b97d1b372340627ca3537554cd45310bace92 /apps/plugins/fractals/fractal_rect.c | |
parent | 51630cbac1dcb04345fb1384812f1576f0ea29db (diff) | |
download | rockbox-7719d297f2a1da0e45fd39cad21e99e23fd695c8.tar.gz rockbox-7719d297f2a1da0e45fd39cad21e99e23fd695c8.zip |
FS#10911 - Plugins: Fractals (formerly Mandelbrot)
- Rename the mandelbrot plugin to fractals
- Update manual accordingly
- Separate plugin's functionality into separate files
- Lay the ground for having fractals sets other than the Mandelbrot set.
For that the following will need to be implemented:
- Create a new file for the new fracral set
- Provide key mapping to switch between sets
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24230 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/fractals/fractal_rect.c')
-rw-r--r-- | apps/plugins/fractals/fractal_rect.c | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/apps/plugins/fractals/fractal_rect.c b/apps/plugins/fractals/fractal_rect.c new file mode 100644 index 0000000000..af846d3f7a --- /dev/null +++ b/apps/plugins/fractals/fractal_rect.c | |||
@@ -0,0 +1,209 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2009 Tomer Shalev | ||
11 | * | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #include "fractal_rect.h" | ||
23 | |||
24 | #define RECT_QUEUE_LEN 32 | ||
25 | |||
26 | #define QUEUE_NEXT(i) (((i) + 1) % RECT_QUEUE_LEN) | ||
27 | #define QUEUE_PREV(i) (((i) - 1) % RECT_QUEUE_LEN) | ||
28 | #define QUEUE_IS_EMPTY (QUEUE_NEXT(rectq.head) == rectq.tail) | ||
29 | #define QUEUE_TAIL \ | ||
30 | (&rectq.rects[rectq.tail]); | ||
31 | #define QUEUE_ITEM(i) &rectq.rects[(i)] | ||
32 | |||
33 | struct rect_queue | ||
34 | { | ||
35 | struct fractal_rect rects[RECT_QUEUE_LEN]; | ||
36 | unsigned head; | ||
37 | unsigned tail; | ||
38 | }; | ||
39 | |||
40 | static struct rect_queue rectq; | ||
41 | |||
42 | /*#define FRACTAL_RECT_DEBUG*/ | ||
43 | #if defined(FRACTAL_RECT_DEBUG) && defined(SIMULATOR) | ||
44 | #include <stdio.h> | ||
45 | |||
46 | static void rectq_print(void) | ||
47 | { | ||
48 | unsigned i = rectq.head; | ||
49 | |||
50 | printf("Rects queue:\n"); | ||
51 | for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV(i)) | ||
52 | { | ||
53 | printf("\tItem %d/%d; idx %d; (%d,%d),(%d,%d),%svalid%s%s\n", | ||
54 | (i - rectq.head + 1) % RECT_QUEUE_LEN, | ||
55 | (rectq.head - rectq.tail) % RECT_QUEUE_LEN, | ||
56 | i, | ||
57 | rectq.rects[(i)].px_min, | ||
58 | rectq.rects[(i)].py_min, | ||
59 | rectq.rects[(i)].px_max, | ||
60 | rectq.rects[(i)].py_max, | ||
61 | (rectq.rects[(i)].valid ? "" : "in"), | ||
62 | ((i == rectq.head) ? ",head" : ""), | ||
63 | ((i == rectq.tail) ? ",tail" : "")); | ||
64 | } | ||
65 | } | ||
66 | #else | ||
67 | #define rectq_print(...) | ||
68 | #endif | ||
69 | |||
70 | static int rects_add(int px_min, int py_min, int px_max, int py_max) | ||
71 | { | ||
72 | struct fractal_rect *rect = &rectq.rects[rectq.tail]; | ||
73 | |||
74 | if (rectq.head == QUEUE_PREV(rectq.tail)) /* queue is full */ | ||
75 | return 1; | ||
76 | |||
77 | rect->px_min = px_min; | ||
78 | rect->py_min = py_min; | ||
79 | rect->px_max = px_max; | ||
80 | rect->py_max = py_max; | ||
81 | rect->valid = 1; | ||
82 | rectq.tail = QUEUE_PREV(rectq.tail); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static void rects_queue_reset(void) | ||
88 | { | ||
89 | rectq.tail = 0; | ||
90 | rectq.head = 0; | ||
91 | } | ||
92 | |||
93 | void rects_queue_init(void) | ||
94 | { | ||
95 | rects_queue_reset(); | ||
96 | rects_add(0, 0, LCD_WIDTH, LCD_HEIGHT); | ||
97 | } | ||
98 | |||
99 | void rects_calc_all(int (*calc)(struct fractal_rect *, int (*)(void *), void *), | ||
100 | int (*button_yield_cb)(void *), void *ctx) | ||
101 | { | ||
102 | while (rectq.head != rectq.tail) /* queue is not empty */ | ||
103 | { | ||
104 | struct fractal_rect *rect = &rectq.rects[rectq.head]; | ||
105 | |||
106 | rectq_print(); | ||
107 | if (rect->valid) | ||
108 | { | ||
109 | if (calc(rect, button_yield_cb, ctx)) | ||
110 | return; /* interrupted by key-press */ | ||
111 | } | ||
112 | |||
113 | rectq.head = QUEUE_PREV(rectq.head); /* dequeue */ | ||
114 | } | ||
115 | rects_queue_reset(); | ||
116 | } | ||
117 | |||
118 | int rects_move_up(void) | ||
119 | { | ||
120 | unsigned i; | ||
121 | |||
122 | /* move current regions up */ | ||
123 | for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i))) | ||
124 | { | ||
125 | struct fractal_rect *rect = QUEUE_ITEM(i); | ||
126 | |||
127 | rect->py_min -= LCD_SHIFT_Y; | ||
128 | rect->py_max -= LCD_SHIFT_Y; | ||
129 | |||
130 | if (rect->py_min < 0) | ||
131 | rect->py_min = 0; | ||
132 | |||
133 | if (rect->py_max < 0) | ||
134 | rect->valid = 0; | ||
135 | } | ||
136 | |||
137 | /* add bottom region */ | ||
138 | return rects_add(0, LCD_HEIGHT - LCD_SHIFT_Y, LCD_WIDTH, LCD_HEIGHT); | ||
139 | } | ||
140 | |||
141 | int rects_move_down(void) | ||
142 | { | ||
143 | unsigned i; | ||
144 | |||
145 | /* move current regions down */ | ||
146 | for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i))) | ||
147 | { | ||
148 | struct fractal_rect *rect = QUEUE_ITEM(i); | ||
149 | |||
150 | rect->py_min += LCD_SHIFT_Y; | ||
151 | rect->py_max += LCD_SHIFT_Y; | ||
152 | |||
153 | if (rect->py_max > LCD_HEIGHT) | ||
154 | rect->py_max = LCD_HEIGHT; | ||
155 | |||
156 | if (LCD_HEIGHT <= rect->py_min) | ||
157 | rect->valid = 0; | ||
158 | } | ||
159 | |||
160 | /* add top region */ | ||
161 | return rects_add(0, 0, LCD_WIDTH, LCD_SHIFT_Y); | ||
162 | } | ||
163 | |||
164 | int rects_move_left(void) | ||
165 | { | ||
166 | unsigned i; | ||
167 | |||
168 | /* move current regions left */ | ||
169 | for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i))) | ||
170 | { | ||
171 | struct fractal_rect *rect = QUEUE_ITEM(i); | ||
172 | |||
173 | rect->px_min -= LCD_SHIFT_X; | ||
174 | rect->px_max -= LCD_SHIFT_X; | ||
175 | |||
176 | if (rect->px_min < 0) | ||
177 | rect->px_min = 0; | ||
178 | |||
179 | if (rect->px_max < 0) | ||
180 | rect->valid = 0; | ||
181 | } | ||
182 | |||
183 | /* add right region */ | ||
184 | return rects_add(LCD_WIDTH - LCD_SHIFT_X, 0, LCD_WIDTH, LCD_HEIGHT); | ||
185 | } | ||
186 | |||
187 | int rects_move_right(void) | ||
188 | { | ||
189 | unsigned i; | ||
190 | |||
191 | /* move current regions right */ | ||
192 | for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i))) | ||
193 | { | ||
194 | struct fractal_rect *rect = QUEUE_ITEM(i); | ||
195 | |||
196 | rect->px_min += LCD_SHIFT_X; | ||
197 | rect->px_max += LCD_SHIFT_X; | ||
198 | |||
199 | if (rect->px_max > LCD_WIDTH) | ||
200 | rect->px_max = LCD_WIDTH; | ||
201 | |||
202 | if (LCD_WIDTH <= rect->px_min) | ||
203 | rect->valid = 0; | ||
204 | } | ||
205 | |||
206 | /* add left region */ | ||
207 | return rects_add(0, 0, LCD_SHIFT_X, LCD_HEIGHT); | ||
208 | } | ||
209 | |||