1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
20 #ifdef HAVE_LCD_BITMAP
22 static struct plugin_api
* rb
;
24 static int toggle
[20];
25 static int cursor_pos
, moves
;
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);
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) {
56 i
= (cursor_pos
%5)*16;
57 j
= (cursor_pos
/5)*16;
59 rb
->lcd_bitmap (ptr
, i
, j
, 16, 8, false);
61 rb
->lcd_bitmap (ptr
, i
, j
+8, 16, 8, false);
64 /* clear the cursor where it is */
65 static void clear_cursor(void) {
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) {
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);
107 rb
->snprintf(s
, sizeof(s
), "%d", moves
);
108 rb
->lcd_putsxy(85, 20, s
);
109 if (flipit_finished())
113 /* move the cursor in any direction */
114 static void move_cursor(int x
, int y
) {
115 if (!(flipit_finished())) {
117 cursor_pos
+= (x
+5*y
);
123 /* initialize the board */
124 static void flipit_init(void) {
126 rb
->lcd_clear_display();
128 rb
->lcd_drawrect(80, 0, 32, 64);
129 rb
->lcd_putsxy(81, 10, "Flips");
130 for (i
=0; i
<20; i
++) {
136 for (i
=0; i
<20; i
++) {
137 cursor_pos
= (rb
->rand() % 20);
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
);
152 /* the main game loop */
153 static bool flipit_loop(void) {
157 switch (rb
->button_get(true)) {
159 /* get out of here */
163 /* mix up the pieces */
168 /* solve the puzzle */
169 if (!flipit_finished()) {
183 if (!flipit_finished()) {
197 /* toggle the pieces */
198 if (!flipit_finished()) {
205 if ((cursor_pos
%5)>0)
210 if ((cursor_pos
%5)<4)
215 if ((cursor_pos
/5)>0)
220 if ((cursor_pos
/5)<3)
224 case SYS_USB_CONNECTED
:
226 return PLUGIN_USB_CONNECTED
;
231 /* called function from outside */
232 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
236 TEST_PLUGIN_API(api
);
241 rb
->lcd_getstringsize("FlipIt!", &w
, &h
);
244 rb
->lcd_clear_display();
245 rb
->lcd_putsxy(LCD_WIDTH
/2-w
, (LCD_HEIGHT
/2)-h
, "FlipIt!");
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");
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
++) {
269 rb
->srand(*rb
->current_tick
);
271 return flipit_loop();