* removed some more unused stuff in the simulator makefile
[kugel-rb.git] / apps / plugins / flipit.c
blob0b7893c9690146f202ea7a49d36785a47cd1b631
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: flipit.c,v 1.0 2003/01/18 23:51:47
10 * Copyright (C) 2002 Vicentini Martin
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "plugin.h"
20 #ifdef HAVE_LCD_BITMAP
22 static struct plugin_api* rb;
23 static int spots[20];
24 static int toggle[20];
25 static int cursor_pos, moves;
26 static char s[5];
27 static char *ptr;
28 static 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 }
38 static 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 };
45 /* draw a spot at the coordinates (x,y), range of p is 0-19 */
46 static 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);
53 /* draw the cursor at the current cursor position */
54 static 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);
64 /* clear the cursor where it is */
65 static 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);
75 /* check if the puzzle is finished */
76 static 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;
85 /* draws the toggled spots */
86 static 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);
94 if (cursor_pos%5 < 4) {
95 spots[cursor_pos+1] = 1-spots[cursor_pos+1];
96 draw_spot(cursor_pos+1);
98 if (cursor_pos/5 > 0) {
99 spots[cursor_pos-5] = 1-spots[cursor_pos-5];
100 draw_spot(cursor_pos-5);
102 if (cursor_pos/5 < 3) {
103 spots[cursor_pos+5] = 1-spots[cursor_pos+5];
104 draw_spot(cursor_pos+5);
106 moves++;
107 rb->snprintf(s, sizeof(s), "%d", moves);
108 rb->lcd_putsxy(85, 20, s);
109 if (flipit_finished())
110 clear_cursor();
113 /* move the cursor in any direction */
114 static void move_cursor(int x, int y) {
115 if (!(flipit_finished())) {
116 clear_cursor();
117 cursor_pos += (x+5*y);
118 draw_cursor();
120 rb->lcd_update();
123 /* initialize the board */
124 static 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);
135 rb->lcd_update();
136 for (i=0; i<20; i++) {
137 cursor_pos = (rb->rand() % 20);
138 flipit_toggle();
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();
152 /* the main game loop */
153 static 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;
162 case BUTTON_F1:
163 /* mix up the pieces */
164 flipit_init();
165 break;
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);
180 break;
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;
194 break;
196 case BUTTON_PLAY:
197 /* toggle the pieces */
198 if (!flipit_finished()) {
199 flipit_toggle();
200 rb->lcd_update();
202 break;
204 case BUTTON_LEFT:
205 if ((cursor_pos%5)>0)
206 move_cursor(-1, 0);
207 break;
209 case BUTTON_RIGHT:
210 if ((cursor_pos%5)<4)
211 move_cursor(1, 0);
212 break;
214 case BUTTON_UP:
215 if ((cursor_pos/5)>0)
216 move_cursor(0, -1);
217 break;
219 case BUTTON_DOWN:
220 if ((cursor_pos/5)<3)
221 move_cursor(0, 1);
222 break;
224 case SYS_USB_CONNECTED:
225 rb->usb_screen();
226 return PLUGIN_USB_CONNECTED;
231 /* called function from outside */
232 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
234 int w, h, i;
236 TEST_PLUGIN_API(api);
237 (void)parameter;
238 rb = api;
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);
249 /* print instructions */
250 rb->lcd_clear_display();
251 rb->lcd_setfont(FONT_SYSFIXED);
252 rb->lcd_putsxy(2, 8, "[OFF] to stop");
253 rb->lcd_putsxy(2, 18, "[PLAY] toggle");
254 rb->lcd_putsxy(2, 28, "[F1] shuffle");
255 rb->lcd_putsxy(2, 38, "[F2] solution");
256 rb->lcd_putsxy(2, 48, "[F3] step by step");
257 rb->lcd_update();
258 rb->sleep(HZ*3);
260 rb->lcd_clear_display();
261 rb->lcd_drawrect(80, 0, 32, 64);
262 rb->lcd_putsxy(81, 10, "Flips");
263 for (i=0; i<20; i++) {
264 spots[i]=1;
265 draw_spot(i);
267 rb->lcd_update();
268 rb->sleep(HZ*3/2);
269 rb->srand(*rb->current_tick);
271 return flipit_loop();
273 #endif