Bump plugin API version. This should have been done in r24587. Also, because the...
[kugel-rb.git] / apps / plugins / fractals / fractal_rect.c
blobaf846d3f7ad2e239131c915dcfad6c3208864900
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2009 Tomer Shalev
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
22 #include "fractal_rect.h"
24 #define RECT_QUEUE_LEN 32
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)]
33 struct rect_queue
35 struct fractal_rect rects[RECT_QUEUE_LEN];
36 unsigned head;
37 unsigned tail;
40 static struct rect_queue rectq;
42 /*#define FRACTAL_RECT_DEBUG*/
43 #if defined(FRACTAL_RECT_DEBUG) && defined(SIMULATOR)
44 #include <stdio.h>
46 static void rectq_print(void)
48 unsigned i = rectq.head;
50 printf("Rects queue:\n");
51 for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV(i))
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,
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" : ""));
66 #else
67 #define rectq_print(...)
68 #endif
70 static int rects_add(int px_min, int py_min, int px_max, int py_max)
72 struct fractal_rect *rect = &rectq.rects[rectq.tail];
74 if (rectq.head == QUEUE_PREV(rectq.tail)) /* queue is full */
75 return 1;
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);
84 return 0;
87 static void rects_queue_reset(void)
89 rectq.tail = 0;
90 rectq.head = 0;
93 void rects_queue_init(void)
95 rects_queue_reset();
96 rects_add(0, 0, LCD_WIDTH, LCD_HEIGHT);
99 void rects_calc_all(int (*calc)(struct fractal_rect *, int (*)(void *), void *),
100 int (*button_yield_cb)(void *), void *ctx)
102 while (rectq.head != rectq.tail) /* queue is not empty */
104 struct fractal_rect *rect = &rectq.rects[rectq.head];
106 rectq_print();
107 if (rect->valid)
109 if (calc(rect, button_yield_cb, ctx))
110 return; /* interrupted by key-press */
113 rectq.head = QUEUE_PREV(rectq.head); /* dequeue */
115 rects_queue_reset();
118 int rects_move_up(void)
120 unsigned i;
122 /* move current regions up */
123 for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i)))
125 struct fractal_rect *rect = QUEUE_ITEM(i);
127 rect->py_min -= LCD_SHIFT_Y;
128 rect->py_max -= LCD_SHIFT_Y;
130 if (rect->py_min < 0)
131 rect->py_min = 0;
133 if (rect->py_max < 0)
134 rect->valid = 0;
137 /* add bottom region */
138 return rects_add(0, LCD_HEIGHT - LCD_SHIFT_Y, LCD_WIDTH, LCD_HEIGHT);
141 int rects_move_down(void)
143 unsigned i;
145 /* move current regions down */
146 for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i)))
148 struct fractal_rect *rect = QUEUE_ITEM(i);
150 rect->py_min += LCD_SHIFT_Y;
151 rect->py_max += LCD_SHIFT_Y;
153 if (rect->py_max > LCD_HEIGHT)
154 rect->py_max = LCD_HEIGHT;
156 if (LCD_HEIGHT <= rect->py_min)
157 rect->valid = 0;
160 /* add top region */
161 return rects_add(0, 0, LCD_WIDTH, LCD_SHIFT_Y);
164 int rects_move_left(void)
166 unsigned i;
168 /* move current regions left */
169 for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i)))
171 struct fractal_rect *rect = QUEUE_ITEM(i);
173 rect->px_min -= LCD_SHIFT_X;
174 rect->px_max -= LCD_SHIFT_X;
176 if (rect->px_min < 0)
177 rect->px_min = 0;
179 if (rect->px_max < 0)
180 rect->valid = 0;
183 /* add right region */
184 return rects_add(LCD_WIDTH - LCD_SHIFT_X, 0, LCD_WIDTH, LCD_HEIGHT);
187 int rects_move_right(void)
189 unsigned i;
191 /* move current regions right */
192 for (i = rectq.head; i != rectq.tail; i = QUEUE_PREV((i)))
194 struct fractal_rect *rect = QUEUE_ITEM(i);
196 rect->px_min += LCD_SHIFT_X;
197 rect->px_max += LCD_SHIFT_X;
199 if (rect->px_max > LCD_WIDTH)
200 rect->px_max = LCD_WIDTH;
202 if (LCD_WIDTH <= rect->px_min)
203 rect->valid = 0;
206 /* add left region */
207 return rects_add(0, 0, LCD_SHIFT_X, LCD_HEIGHT);