summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/flipit.c272
1 files changed, 272 insertions, 0 deletions
diff --git a/apps/plugins/flipit.c b/apps/plugins/flipit.c
new file mode 100644
index 0000000000..1f6843fc19
--- /dev/null
+++ b/apps/plugins/flipit.c
@@ -0,0 +1,272 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: flipit.c,v 1.0 2003/01/18 23:51:47
9 *
10 * Copyright (C) 2002 Vicentini Martin
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "plugin.h"
20#ifdef HAVE_LCD_BITMAP
21
22static struct plugin_api* rb;
23static int spots[20];
24static int toggle[20];
25static int cursor_pos, moves;
26static char s[5];
27static char *ptr;
28static unsigned char spot_pic[2][28] = {
29 { 0xe0, 0xf8, 0xfc, 0xfe, 0xfe, 0xff, 0xff,
30 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xf8, 0xe0,
31 0x01, 0x07, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f,
32 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x07, 0x01 },
33 { 0xe0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x01,
34 0x01, 0x01, 0x02, 0x02, 0x04, 0x18, 0xe0,
35 0x01, 0x06, 0x08, 0x10, 0x10, 0x20, 0x20,
36 0x20, 0x20, 0x10, 0x10, 0x08, 0x06, 0x01 }
37};
38static unsigned char cursor_pic[32] = {
39 0x55, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
40 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xaa,
41 0x55, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
42 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xaa };
43
44
45/* draw a spot at the coordinates (x,y), range of p is 0-19 */
46static void draw_spot(int p) {
47 ptr = spot_pic[spots[p]];
48 rb->lcd_bitmap (ptr, (p%5)*16+1, (p/5)*16+1, 14, 8, true);
49 ptr += 14;
50 rb->lcd_bitmap (ptr, (p%5)*16+1, (p/5)*16+9, 14, 6, true);
51}
52
53/* draw the cursor at the current cursor position */
54static void draw_cursor(void) {
55 int i,j;
56 i = (cursor_pos%5)*16;
57 j = (cursor_pos/5)*16;
58 ptr = cursor_pic;
59 rb->lcd_bitmap (ptr, i, j, 16, 8, false);
60 ptr += 16;
61 rb->lcd_bitmap (ptr, i, j+8, 16, 8, false);
62}
63
64/* clear the cursor where it is */
65static void clear_cursor(void) {
66 int i,j;
67 i = (cursor_pos%5)*16;
68 j = (cursor_pos/5)*16;
69 rb->lcd_clearline(i, j, i+15, j);
70 rb->lcd_clearline(i, j+15, i+15, j+15);
71 rb->lcd_clearline(i, j, i, j+15);
72 rb->lcd_clearline(i+15, j, i+15, j+15);
73}
74
75/* check if the puzzle is finished */
76static bool flipit_finished(void) {
77 int i;
78 for (i=0; i<20; i++)
79 if (!spots[i])
80 return false;
81 clear_cursor();
82 return true;
83}
84
85/* draws the toggled spots */
86static void flipit_toggle(void) {
87 spots[cursor_pos] = 1-spots[cursor_pos];
88 toggle[cursor_pos] = 1-toggle[cursor_pos];
89 draw_spot(cursor_pos);
90 if (cursor_pos%5 > 0) {
91 spots[cursor_pos-1] = 1-spots[cursor_pos-1];
92 draw_spot(cursor_pos-1);
93 }
94 if (cursor_pos%5 < 4) {
95 spots[cursor_pos+1] = 1-spots[cursor_pos+1];
96 draw_spot(cursor_pos+1);
97 }
98 if (cursor_pos/5 > 0) {
99 spots[cursor_pos-5] = 1-spots[cursor_pos-5];
100 draw_spot(cursor_pos-5);
101 }
102 if (cursor_pos/5 < 3) {
103 spots[cursor_pos+5] = 1-spots[cursor_pos+5];
104 draw_spot(cursor_pos+5);
105 }
106 moves++;
107 rb->snprintf(s, sizeof(s), "%d", moves);
108 rb->lcd_putsxy(85, 20, s);
109 if (flipit_finished())
110 clear_cursor();
111}
112
113/* move the cursor in any direction */
114static void move_cursor(int x, int y) {
115 if (!(flipit_finished())) {
116 clear_cursor();
117 cursor_pos += (x+5*y);
118 draw_cursor();
119 }
120 rb->lcd_update();
121}
122
123/* initialize the board */
124static void flipit_init(void) {
125 int i;
126 rb->lcd_clear_display();
127 moves = 0;
128 rb->lcd_drawrect(80, 0, 32, 64);
129 rb->lcd_putsxy(81, 10, "Flips");
130 for (i=0; i<20; i++) {
131 spots[i]=1;
132 toggle[i]=1;
133 draw_spot(i);
134 }
135 rb->lcd_update();
136 for (i=0; i<20; i++) {
137 cursor_pos = (rb->rand() % 20);
138 flipit_toggle();
139 }
140
141 cursor_pos = 0;
142 draw_cursor();
143 moves = 0;
144 rb->lcd_clearrect(80, 0, 32, 64);
145 rb->lcd_drawrect(80, 0, 32, 64);
146 rb->lcd_putsxy(81, 10, "Flips");
147 rb->snprintf(s, sizeof(s), "%d", moves);
148 rb->lcd_putsxy(85, 20, s);
149 rb->lcd_update();
150}
151
152/* the main game loop */
153static bool flipit_loop(void) {
154 int i;
155 flipit_init();
156 while(true) {
157 switch (rb->button_get(true)) {
158 case BUTTON_OFF:
159 /* get out of here */
160 return PLUGIN_OK;
161
162 case BUTTON_F1:
163 /* mix up the pieces */
164 flipit_init();
165 break;
166
167 case BUTTON_F2:
168 /* solve the puzzle */
169 if (!flipit_finished()) {
170 for (i=0; i<20; i++)
171 if (!toggle[i]) {
172 clear_cursor();
173 cursor_pos = i;
174 draw_cursor();
175 flipit_toggle();
176 rb->lcd_update();
177 rb->sleep(HZ*2/3);
178 }
179 }
180 break;
181
182 case BUTTON_F3:
183 if (!flipit_finished()) {
184 for (i=0; i<20; i++)
185 if (!toggle[i]) {
186 clear_cursor();
187 cursor_pos = i;
188 draw_cursor();
189 flipit_toggle();
190 rb->lcd_update();
191 break;
192 }
193 }
194 break;
195
196 case BUTTON_PLAY:
197 /* toggle the pieces */
198 if (!flipit_finished()) {
199 flipit_toggle();
200 rb->lcd_update();
201 }
202 break;
203
204 case BUTTON_LEFT:
205 if ((cursor_pos%5)>0)
206 move_cursor(-1, 0);
207 break;
208
209 case BUTTON_RIGHT:
210 if ((cursor_pos%5)<4)
211 move_cursor(1, 0);
212 break;
213
214 case BUTTON_UP:
215 if ((cursor_pos/5)>0)
216 move_cursor(0, -1);
217 break;
218
219 case BUTTON_DOWN:
220 if ((cursor_pos/5)<3)
221 move_cursor(0, 1);
222 break;
223
224 case SYS_USB_CONNECTED:
225 rb->usb_screen();
226 return PLUGIN_USB_CONNECTED;
227 }
228 }
229}
230
231/* called function from outside */
232enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
233{
234 int w, h, i;
235
236 TEST_PLUGIN_API(api);
237 (void)parameter;
238 rb = api;
239
240 /* print title */
241 rb->lcd_getstringsize("FlipIt!", &w, &h);
242 w = (w+1)/2;
243 h = (h+1)/2;
244 rb->lcd_clear_display();
245 rb->lcd_putsxy(LCD_WIDTH/2-w, (LCD_HEIGHT/2)-h, "FlipIt!");
246 rb->lcd_update();
247 rb->sleep(HZ);
248
249 /* print instructions */
250 rb->lcd_clear_display();
251 rb->lcd_putsxy(2, 8, "[OFF] to stop");
252 rb->lcd_putsxy(2, 18, "[PLAY] toggle");
253 rb->lcd_putsxy(2, 28, "[F1] shuffle");
254 rb->lcd_putsxy(2, 38, "[F2] solution");
255 rb->lcd_putsxy(2, 48, "[F3] step by step");
256 rb->lcd_update();
257 rb->sleep(HZ*3);
258
259 rb->lcd_clear_display();
260 rb->lcd_drawrect(80, 0, 32, 64);
261 rb->lcd_putsxy(81, 10, "Flips");
262 for (i=0; i<20; i++) {
263 spots[i]=1;
264 draw_spot(i);
265 }
266 rb->lcd_update();
267 rb->sleep(HZ*3/2);
268 rb->srand(*rb->current_tick);
269
270 return flipit_loop();
271}
272#endif