1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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)
30 (&rectq.rects[rectq.tail]);
31 #define QUEUE_ITEM(i) &rectq.rects[(i)]
35 struct fractal_rect rects
[RECT_QUEUE_LEN
];
40 static struct rect_queue rectq
;
42 /*#define FRACTAL_RECT_DEBUG*/
43 #if defined(FRACTAL_RECT_DEBUG) && defined(SIMULATOR)
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" : ""));
67 #define rectq_print(...)
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 */
77 rect
->px_min
= px_min
;
78 rect
->py_min
= py_min
;
79 rect
->px_max
= px_max
;
80 rect
->py_max
= py_max
;
82 rectq
.tail
= QUEUE_PREV(rectq
.tail
);
87 static void rects_queue_reset(void)
93 void rects_queue_init(void)
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
];
109 if (calc(rect
, button_yield_cb
, ctx
))
110 return; /* interrupted by key-press */
113 rectq
.head
= QUEUE_PREV(rectq
.head
); /* dequeue */
118 int rects_move_up(void)
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)
133 if (rect
->py_max
< 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)
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
)
161 return rects_add(0, 0, LCD_WIDTH
, LCD_SHIFT_Y
);
164 int rects_move_left(void)
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)
179 if (rect
->px_max
< 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)
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
)
206 /* add left region */
207 return rects_add(0, 0, LCD_SHIFT_X
, LCD_HEIGHT
);