Get sims.pl working again after target rename
[kugel-rb.git] / apps / plugins / flipit.c
blob21654860800934268bf0d3f556f40b0f1946e75f
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Vicentini Martin
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "plugin.h"
23 PLUGIN_HEADER
25 /* variable button definitions */
26 #if CONFIG_KEYPAD == RECORDER_PAD
27 #define FLIPIT_LEFT BUTTON_LEFT
28 #define FLIPIT_RIGHT BUTTON_RIGHT
29 #define FLIPIT_UP BUTTON_UP
30 #define FLIPIT_DOWN BUTTON_DOWN
31 #define FLIPIT_QUIT BUTTON_OFF
32 #define FLIPIT_SHUFFLE BUTTON_F1
33 #define FLIPIT_SOLVE BUTTON_F2
34 #define FLIPIT_STEP_BY_STEP BUTTON_F3
35 #define FLIPIT_TOGGLE BUTTON_PLAY
37 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
38 #define FLIPIT_LEFT BUTTON_LEFT
39 #define FLIPIT_RIGHT BUTTON_RIGHT
40 #define FLIPIT_UP BUTTON_UP
41 #define FLIPIT_DOWN BUTTON_DOWN
42 #define FLIPIT_QUIT BUTTON_OFF
43 #define FLIPIT_SHUFFLE BUTTON_F1
44 #define FLIPIT_SOLVE BUTTON_F2
45 #define FLIPIT_STEP_BY_STEP BUTTON_F3
46 #define FLIPIT_TOGGLE BUTTON_SELECT
48 #elif CONFIG_KEYPAD == PLAYER_PAD
49 #define FLIPIT_LEFT BUTTON_LEFT
50 #define FLIPIT_RIGHT BUTTON_RIGHT
51 #define FLIPIT_UP_PRE BUTTON_ON
52 #define FLIPIT_UP (BUTTON_ON | BUTTON_REL)
53 #define FLIPIT_DOWN BUTTON_MENU
54 #define FLIPIT_QUIT BUTTON_STOP
55 #define FLIPIT_SHUFFLE (BUTTON_ON | BUTTON_LEFT)
56 #define FLIPIT_SOLVE (BUTTON_ON | BUTTON_RIGHT)
57 #define FLIPIT_STEP_BY_STEP (BUTTON_ON | BUTTON_PLAY)
58 #define FLIPIT_TOGGLE BUTTON_PLAY
60 #elif CONFIG_KEYPAD == ONDIO_PAD
61 #define FLIPIT_LEFT BUTTON_LEFT
62 #define FLIPIT_RIGHT BUTTON_RIGHT
63 #define FLIPIT_UP BUTTON_UP
64 #define FLIPIT_DOWN BUTTON_DOWN
65 #define FLIPIT_QUIT BUTTON_OFF
66 #define FLIPIT_SHUFFLE (BUTTON_MENU | BUTTON_LEFT)
67 #define FLIPIT_SOLVE (BUTTON_MENU | BUTTON_UP)
68 #define FLIPIT_STEP_BY_STEP (BUTTON_MENU | BUTTON_RIGHT)
69 #define FLIPIT_TOGGLE_PRE BUTTON_MENU
70 #define FLIPIT_TOGGLE (BUTTON_MENU | BUTTON_REL)
72 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
73 (CONFIG_KEYPAD == IRIVER_H300_PAD)
74 #define FLIPIT_LEFT BUTTON_LEFT
75 #define FLIPIT_RIGHT BUTTON_RIGHT
76 #define FLIPIT_UP BUTTON_UP
77 #define FLIPIT_DOWN BUTTON_DOWN
78 #define FLIPIT_QUIT BUTTON_OFF
79 #define FLIPIT_SHUFFLE BUTTON_MODE
80 #define FLIPIT_SOLVE BUTTON_ON
81 #define FLIPIT_STEP_BY_STEP BUTTON_REC
82 #define FLIPIT_TOGGLE_PRE BUTTON_SELECT
83 #define FLIPIT_TOGGLE (BUTTON_SELECT | BUTTON_REL)
85 #define FLIPIT_RC_QUIT BUTTON_RC_STOP
87 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
88 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
89 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
91 #define FLIPIT_SCROLLWHEEL
92 #define FLIPIT_LEFT BUTTON_LEFT
93 #define FLIPIT_RIGHT BUTTON_RIGHT
94 #define FLIPIT_UP BUTTON_MENU
95 #define FLIPIT_DOWN BUTTON_PLAY
96 #define FLIPIT_NEXT BUTTON_SCROLL_FWD
97 #define FLIPIT_PREV BUTTON_SCROLL_BACK
98 #define FLIPIT_QUIT (BUTTON_SELECT | BUTTON_MENU)
99 #define FLIPIT_SHUFFLE (BUTTON_SELECT | BUTTON_LEFT)
100 #define FLIPIT_SOLVE (BUTTON_SELECT | BUTTON_PLAY)
101 #define FLIPIT_STEP_BY_STEP (BUTTON_SELECT | BUTTON_RIGHT)
102 #define FLIPIT_TOGGLE_PRE BUTTON_SELECT
103 #define FLIPIT_TOGGLE (BUTTON_SELECT | BUTTON_REL)
105 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
107 #define FLIPIT_LEFT BUTTON_LEFT
108 #define FLIPIT_RIGHT BUTTON_RIGHT
109 #define FLIPIT_UP BUTTON_UP
110 #define FLIPIT_DOWN BUTTON_DOWN
111 #define FLIPIT_QUIT BUTTON_POWER
112 #define FLIPIT_SHUFFLE BUTTON_REC
113 #define FLIPIT_SOLVE_PRE BUTTON_PLAY
114 #define FLIPIT_SOLVE (BUTTON_PLAY | BUTTON_REPEAT)
115 #define FLIPIT_STEP_PRE BUTTON_PLAY
116 #define FLIPIT_STEP_BY_STEP (BUTTON_PLAY | BUTTON_REL)
117 #define FLIPIT_TOGGLE BUTTON_SELECT
119 #elif CONFIG_KEYPAD == GIGABEAT_PAD
121 #define FLIPIT_LEFT BUTTON_LEFT
122 #define FLIPIT_RIGHT BUTTON_RIGHT
123 #define FLIPIT_UP BUTTON_UP
124 #define FLIPIT_DOWN BUTTON_DOWN
125 #define FLIPIT_QUIT BUTTON_POWER
126 #define FLIPIT_SHUFFLE BUTTON_MENU
127 #define FLIPIT_SOLVE BUTTON_VOL_UP
128 #define FLIPIT_STEP_BY_STEP BUTTON_VOL_DOWN
129 #define FLIPIT_TOGGLE BUTTON_SELECT
131 #elif CONFIG_KEYPAD == SANSA_E200_PAD
133 #define FLIPIT_SCROLLWHEEL
134 #define FLIPIT_LEFT BUTTON_LEFT
135 #define FLIPIT_RIGHT BUTTON_RIGHT
136 #define FLIPIT_UP BUTTON_UP
137 #define FLIPIT_DOWN BUTTON_DOWN
138 #define FLIPIT_NEXT BUTTON_SCROLL_FWD
139 #define FLIPIT_PREV BUTTON_SCROLL_BACK
140 #define FLIPIT_QUIT BUTTON_POWER
141 #define FLIPIT_SHUFFLE (BUTTON_REC | BUTTON_LEFT)
142 #define FLIPIT_SOLVE (BUTTON_REC | BUTTON_RIGHT)
143 #define FLIPIT_STEP_BY_STEP (BUTTON_REC | BUTTON_SELECT)
144 #define FLIPIT_TOGGLE BUTTON_SELECT
146 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
148 #define FLIPIT_SCROLLWHEEL
149 #define FLIPIT_LEFT BUTTON_LEFT
150 #define FLIPIT_RIGHT BUTTON_RIGHT
151 #define FLIPIT_UP BUTTON_UP
152 #define FLIPIT_DOWN BUTTON_DOWN
153 #define FLIPIT_NEXT BUTTON_SCROLL_FWD
154 #define FLIPIT_PREV BUTTON_SCROLL_BACK
155 #define FLIPIT_QUIT (BUTTON_HOME|BUTTON_REPEAT)
156 #define FLIPIT_SHUFFLE (BUTTON_SELECT | BUTTON_LEFT)
157 #define FLIPIT_SOLVE (BUTTON_SELECT | BUTTON_DOWN)
158 #define FLIPIT_STEP_BY_STEP (BUTTON_SELECT | BUTTON_RIGHT)
159 #define FLIPIT_TOGGLE_PRE BUTTON_SELECT
160 #define FLIPIT_TOGGLE (BUTTON_SELECT | BUTTON_REL)
162 #elif CONFIG_KEYPAD == SANSA_C200_PAD
164 #define FLIPIT_LEFT BUTTON_LEFT
165 #define FLIPIT_RIGHT BUTTON_RIGHT
166 #define FLIPIT_UP BUTTON_UP
167 #define FLIPIT_DOWN BUTTON_DOWN
168 #define FLIPIT_QUIT BUTTON_POWER
169 #define FLIPIT_SHUFFLE (BUTTON_REC | BUTTON_LEFT)
170 #define FLIPIT_SOLVE (BUTTON_REC | BUTTON_RIGHT)
171 #define FLIPIT_STEP_BY_STEP (BUTTON_REC | BUTTON_SELECT)
172 #define FLIPIT_TOGGLE BUTTON_SELECT
174 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
176 #define FLIPIT_LEFT BUTTON_LEFT
177 #define FLIPIT_RIGHT BUTTON_RIGHT
178 #define FLIPIT_UP BUTTON_UP
179 #define FLIPIT_DOWN BUTTON_DOWN
180 #define FLIPIT_QUIT BUTTON_POWER
181 #define FLIPIT_SHUFFLE (BUTTON_HOME | BUTTON_LEFT)
182 #define FLIPIT_SOLVE (BUTTON_HOME | BUTTON_RIGHT)
183 #define FLIPIT_STEP_BY_STEP (BUTTON_HOME | BUTTON_SELECT)
184 #define FLIPIT_TOGGLE BUTTON_SELECT
186 #elif CONFIG_KEYPAD == SANSA_M200_PAD
188 #define FLIPIT_LEFT BUTTON_LEFT
189 #define FLIPIT_RIGHT BUTTON_RIGHT
190 #define FLIPIT_UP BUTTON_UP
191 #define FLIPIT_DOWN BUTTON_DOWN
192 #define FLIPIT_QUIT BUTTON_POWER
193 #define FLIPIT_SHUFFLE (BUTTON_SELECT | BUTTON_LEFT)
194 #define FLIPIT_SOLVE (BUTTON_SELECT | BUTTON_RIGHT)
195 #define FLIPIT_STEP_BY_STEP (BUTTON_SELECT | BUTTON_UP)
196 #define FLIPIT_TOGGLE (BUTTON_SELECT | BUTTON_REL)
198 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
200 #define FLIPIT_LEFT BUTTON_LEFT
201 #define FLIPIT_RIGHT BUTTON_RIGHT
202 #define FLIPIT_UP BUTTON_SCROLL_UP
203 #define FLIPIT_DOWN BUTTON_SCROLL_DOWN
204 #define FLIPIT_QUIT BUTTON_POWER
205 #define FLIPIT_SHUFFLE (BUTTON_PLAY | BUTTON_LEFT)
206 #define FLIPIT_SOLVE (BUTTON_PLAY | BUTTON_RIGHT)
207 #define FLIPIT_STEP_BY_STEP (BUTTON_PLAY | BUTTON_SCROLL_UP)
208 #define FLIPIT_TOGGLE_PRE BUTTON_REW
209 #define FLIPIT_TOGGLE (BUTTON_REW | BUTTON_REL)
211 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
213 #define FLIPIT_LEFT BUTTON_LEFT
214 #define FLIPIT_RIGHT BUTTON_RIGHT
215 #define FLIPIT_UP BUTTON_UP
216 #define FLIPIT_DOWN BUTTON_DOWN
217 #define FLIPIT_QUIT BUTTON_BACK
218 #define FLIPIT_SHUFFLE BUTTON_MENU
219 #define FLIPIT_SOLVE BUTTON_VOL_UP
220 #define FLIPIT_STEP_BY_STEP BUTTON_VOL_DOWN
221 #define FLIPIT_TOGGLE BUTTON_SELECT
223 #elif CONFIG_KEYPAD == MROBE100_PAD
225 #define FLIPIT_LEFT BUTTON_LEFT
226 #define FLIPIT_RIGHT BUTTON_RIGHT
227 #define FLIPIT_UP BUTTON_UP
228 #define FLIPIT_DOWN BUTTON_DOWN
229 #define FLIPIT_QUIT BUTTON_POWER
230 #define FLIPIT_SHUFFLE BUTTON_MENU
231 #define FLIPIT_SOLVE BUTTON_PLAY
232 #define FLIPIT_STEP_BY_STEP BUTTON_DISPLAY
233 #define FLIPIT_TOGGLE BUTTON_SELECT
235 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
237 #define FLIPIT_LEFT BUTTON_RC_REW
238 #define FLIPIT_RIGHT BUTTON_RC_FF
239 #define FLIPIT_UP BUTTON_RC_VOL_UP
240 #define FLIPIT_DOWN BUTTON_RC_VOL_DOWN
241 #define FLIPIT_QUIT BUTTON_RC_REC
242 #define FLIPIT_SHUFFLE BUTTON_RC_MODE
243 #define FLIPIT_SOLVE_PRE BUTTON_RC_MENU
244 #define FLIPIT_SOLVE (BUTTON_RC_MENU|BUTTON_REPEAT)
245 #define FLIPIT_STEP_PRE BUTTON_RC_MENU
246 #define FLIPIT_STEP_BY_STEP (BUTTON_RC_MENU|BUTTON_REL)
247 #define FLIPIT_TOGGLE BUTTON_RC_PLAY
249 #define FLIPIT_RC_QUIT BUTTON_REC
251 #elif CONFIG_KEYPAD == COWOND2_PAD
253 #define FLIPIT_QUIT BUTTON_POWER
255 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
257 #define FLIPIT_LEFT BUTTON_LEFT
258 #define FLIPIT_RIGHT BUTTON_RIGHT
259 #define FLIPIT_UP BUTTON_UP
260 #define FLIPIT_DOWN BUTTON_DOWN
261 #define FLIPIT_QUIT BUTTON_BACK
262 #define FLIPIT_SHUFFLE BUTTON_CUSTOM
263 #define FLIPIT_SOLVE BUTTON_PLAY
264 #define FLIPIT_STEP_BY_STEP BUTTON_MENU
265 #define FLIPIT_TOGGLE BUTTON_SELECT
267 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
269 #define FLIPIT_LEFT BUTTON_LEFT
270 #define FLIPIT_RIGHT BUTTON_RIGHT
271 #define FLIPIT_UP BUTTON_UP
272 #define FLIPIT_DOWN BUTTON_DOWN
273 #define FLIPIT_QUIT BUTTON_POWER
274 #define FLIPIT_SHUFFLE BUTTON_MENU
275 #define FLIPIT_SOLVE BUTTON_VIEW
276 #define FLIPIT_STEP_BY_STEP BUTTON_PLAYLIST
277 #define FLIPIT_TOGGLE BUTTON_SELECT
279 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
281 #define FLIPIT_LEFT BUTTON_PREV
282 #define FLIPIT_RIGHT BUTTON_NEXT
283 #define FLIPIT_UP BUTTON_UP
284 #define FLIPIT_DOWN BUTTON_DOWN
285 #define FLIPIT_QUIT BUTTON_POWER
286 #define FLIPIT_SHUFFLE BUTTON_MENU
287 #define FLIPIT_SOLVE BUTTON_RIGHT
288 #define FLIPIT_STEP_BY_STEP BUTTON_LEFT
289 #define FLIPIT_TOGGLE BUTTON_PLAY
291 #elif CONFIG_KEYPAD == ONDAVX747_PAD || CONFIG_KEYPAD == MROBE500_PAD
293 #define FLIPIT_QUIT BUTTON_POWER
295 #elif CONFIG_KEYPAD == ONDAVX777_PAD
297 #define FLIPIT_QUIT BUTTON_POWER
299 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
301 #define FLIPIT_LEFT BUTTON_LEFT
302 #define FLIPIT_RIGHT BUTTON_RIGHT
303 #define FLIPIT_UP BUTTON_UP
304 #define FLIPIT_DOWN BUTTON_DOWN
305 #define FLIPIT_QUIT BUTTON_REC
306 #define FLIPIT_SHUFFLE BUTTON_PLAY
307 #define FLIPIT_SOLVE BUTTON_FFWD
308 #define FLIPIT_STEP_BY_STEP (BUTTON_PLAY|BUTTON_UP)
309 #define FLIPIT_TOGGLE (BUTTON_PLAY|BUTTON_DOWN)
312 #else
313 #error No keymap defined!
314 #endif
316 #ifdef HAVE_TOUCHSCREEN
317 #ifndef FLIPIT_LEFT
318 #define FLIPIT_LEFT BUTTON_MIDLEFT
319 #endif
320 #ifndef FLIPIT_RIGHT
321 #define FLIPIT_RIGHT BUTTON_MIDRIGHT
322 #endif
323 #ifndef FLIPIT_UP
324 #define FLIPIT_UP BUTTON_TOPMIDDLE
325 #endif
326 #ifndef FLIPIT_DOWN
327 #define FLIPIT_DOWN BUTTON_BOTTOMMIDDLE
328 #endif
329 #ifndef FLIPIT_QUIT
330 #define FLIPIT_QUIT BUTTON_TOPLEFT
331 #endif
332 #ifndef FLIPIT_SHUFFLE
333 #define FLIPIT_SHUFFLE BUTTON_TOPRIGHT
334 #endif
335 #ifndef FLIPIT_SOLVE
336 #define FLIPIT_SOLVE BUTTON_BOTTOMLEFT
337 #endif
338 #ifndef FLIPIT_STEP_BY_STEP
339 #define FLIPIT_STEP_BY_STEP BUTTON_BOTTOMRIGHT
340 #endif
341 #ifndef FLIPIT_TOGGLE
342 #define FLIPIT_TOGGLE BUTTON_CENTER
343 #endif
344 #endif
346 static int spots[20];
347 static int toggle[20];
348 static int cursor_pos, moves;
350 #ifdef HAVE_LCD_BITMAP
352 #include "pluginbitmaps/flipit_cursor.h"
353 #include "pluginbitmaps/flipit_tokens.h"
355 #define PANEL_HEIGHT 12
356 #define TK_WIDTH BMPWIDTH_flipit_cursor
357 #define TK_HEIGHT BMPHEIGHT_flipit_cursor
358 #define TK_SPACE MAX(0, MIN((LCD_WIDTH - 5*TK_WIDTH)/4, \
359 (LCD_HEIGHT - PANEL_HEIGHT - 4*TK_HEIGHT)/4))
360 #define GRID_WIDTH (5*TK_WIDTH + 4*TK_SPACE)
361 #define GRID_LEFT ((LCD_WIDTH - GRID_WIDTH)/2)
362 #define GRID_HEIGHT (4*TK_HEIGHT + 4*TK_SPACE) /* includes grid-panel space */
363 #define GRID_TOP MAX(0, ((LCD_HEIGHT - PANEL_HEIGHT - GRID_HEIGHT)/2))
365 /* draw a spot at the coordinates (x,y), range of p is 0-19 */
366 static void draw_spot(int p)
368 rb->lcd_bitmap_part( flipit_tokens, 0, spots[p] * TK_HEIGHT,
369 STRIDE(SCREEN_MAIN, BMPWIDTH_flipit_tokens,
370 BMPHEIGHT_flipit_tokens),
371 GRID_LEFT + (p%5) * (TK_WIDTH+TK_SPACE),
372 GRID_TOP + (p/5) * (TK_HEIGHT+TK_SPACE),
373 TK_WIDTH, TK_HEIGHT );
376 /* draw the cursor at the current cursor position */
377 static void draw_cursor(void)
379 #ifdef HAVE_LCD_COLOR
380 rb->lcd_bitmap_transparent( flipit_cursor,
381 GRID_LEFT + (cursor_pos%5) * (TK_WIDTH+TK_SPACE),
382 GRID_TOP + (cursor_pos/5) * (TK_HEIGHT+TK_SPACE),
383 TK_WIDTH, TK_HEIGHT );
384 #else
385 rb->lcd_set_drawmode(DRMODE_FG);
386 rb->lcd_mono_bitmap( flipit_cursor,
387 GRID_LEFT + (cursor_pos%5) * (TK_WIDTH+TK_SPACE),
388 GRID_TOP + (cursor_pos/5) * (TK_HEIGHT+TK_SPACE),
389 TK_WIDTH, TK_HEIGHT );
390 rb->lcd_set_drawmode(DRMODE_SOLID);
391 #endif
394 /* draw the info panel ... duh */
395 static void draw_info_panel(void)
397 char s[32];
399 rb->lcd_set_drawmode( DRMODE_SOLID|DRMODE_INVERSEVID );
400 rb->lcd_fillrect( GRID_LEFT, GRID_TOP + 4*(TK_HEIGHT+TK_SPACE),
401 GRID_WIDTH, PANEL_HEIGHT );
402 rb->lcd_set_drawmode( DRMODE_SOLID );
403 rb->lcd_drawrect( GRID_LEFT, GRID_TOP + 4*(TK_HEIGHT+TK_SPACE),
404 GRID_WIDTH, PANEL_HEIGHT );
406 rb->snprintf( s, sizeof(s), "Flips: %d", moves );
407 rb->lcd_putsxy( (LCD_WIDTH - rb->lcd_getstringsize(s, NULL, NULL)) / 2,
408 GRID_TOP + 4*(TK_HEIGHT+TK_SPACE) + 2, s );
411 #else /* HAVE_LCD_CHARCELLS */
413 static const unsigned char tk_pat[4][7] = {
414 { 0x0e, 0x11, 0x0e, 0x00, 0x0e, 0x11, 0x0e }, /* white - white */
415 { 0x0e, 0x11, 0x0e, 0x00, 0x0e, 0x1f, 0x0e }, /* white - black */
416 { 0x0e, 0x1f, 0x0e, 0x00, 0x0e, 0x11, 0x0e }, /* black - white */
417 { 0x0e, 0x1f, 0x0e, 0x00, 0x0e, 0x1f, 0x0e } /* black - black */
420 static unsigned char cur_pat[7];
421 static unsigned long gfx_chars[5];
423 static void release_gfx(void)
425 int i;
427 for (i = 0; i < 5; i++)
428 if (gfx_chars[i])
429 rb->lcd_unlock_pattern(gfx_chars[i]);
432 static bool init_gfx(void)
434 int i;
436 for (i = 0; i < 5; i++) {
437 if ((gfx_chars[i] = rb->lcd_get_locked_pattern()) == 0) {
438 release_gfx();
439 return false;
442 for (i = 0; i < 4; i++)
443 rb->lcd_define_pattern(gfx_chars[i], tk_pat[i]);
444 return true;
447 /* draw a spot at the coordinates (x,y), range of p is 0-19 */
448 static void draw_spot(int p)
450 if ((p/5) & 1)
451 p -= 5;
453 rb->lcd_putc (p%5, p/10, gfx_chars[2*spots[p]+spots[p+5]]);
456 /* draw the cursor at the current cursor position */
457 static void draw_cursor(void)
459 if ((cursor_pos/5) & 1) {
460 rb->memcpy( cur_pat, tk_pat[2*spots[cursor_pos-5]+spots[cursor_pos]], 7 );
461 cur_pat[4] ^= 0x15;
462 cur_pat[6] ^= 0x11;
464 else {
465 rb->memcpy( cur_pat, tk_pat[2*spots[cursor_pos]+spots[cursor_pos+5]], 7 );
466 cur_pat[0] ^= 0x15;
467 cur_pat[2] ^= 0x11;
469 rb->lcd_define_pattern(gfx_chars[4], cur_pat);
470 rb->lcd_putc( cursor_pos%5, cursor_pos/10, gfx_chars[4] );
473 /* draw the info panel ... duh */
474 static void draw_info_panel(void)
476 char s[16];
478 rb->lcd_puts( 6, 0, "Flips" );
479 rb->snprintf( s, sizeof(s), "%d", moves );
480 rb->lcd_puts( 6, 1, s );
483 #endif /* LCD */
485 /* clear the cursor where it is */
486 static inline void clear_cursor(void)
488 draw_spot( cursor_pos );
491 /* check if the puzzle is finished */
492 static bool flipit_finished(void)
494 int i;
495 for (i=0; i<20; i++)
496 if (!spots[i])
497 return false;
498 clear_cursor();
499 return true;
502 /* draws the toggled spots */
503 static void flipit_toggle(void)
505 spots[cursor_pos] = 1-spots[cursor_pos];
506 toggle[cursor_pos] = 1-toggle[cursor_pos];
507 draw_spot(cursor_pos);
508 if (cursor_pos%5 > 0) {
509 spots[cursor_pos-1] = 1-spots[cursor_pos-1];
510 draw_spot(cursor_pos-1);
512 if (cursor_pos%5 < 4) {
513 spots[cursor_pos+1] = 1-spots[cursor_pos+1];
514 draw_spot(cursor_pos+1);
516 if (cursor_pos/5 > 0) {
517 spots[cursor_pos-5] = 1-spots[cursor_pos-5];
518 draw_spot(cursor_pos-5);
520 if (cursor_pos/5 < 3) {
521 spots[cursor_pos+5] = 1-spots[cursor_pos+5];
522 draw_spot(cursor_pos+5);
524 moves++;
526 draw_info_panel();
528 if (flipit_finished())
529 clear_cursor();
532 /* move the cursor in any direction */
533 static void move_cursor(int x, int y)
535 if (!(flipit_finished())) {
536 clear_cursor();
537 cursor_pos = ( x + 5 + cursor_pos%5 )%5
538 + ( ( y + 4 + cursor_pos/5 )%4 )*5;
539 draw_cursor();
541 rb->lcd_update();
544 /* initialize the board */
545 static void flipit_init(void)
547 int i;
549 rb->lcd_clear_display();
550 for (i=0; i<20; i++) {
551 spots[i]=1;
552 toggle[i]=1;
553 draw_spot(i);
555 rb->lcd_update();
557 for (i=0; i<20; i++) {
558 cursor_pos = (rb->rand() % 20);
559 flipit_toggle();
562 cursor_pos = 0;
563 draw_cursor();
564 moves = 0;
565 draw_info_panel();
566 rb->lcd_update();
569 /* the main game loop */
570 static bool flipit_loop(void)
572 int i;
573 int button;
574 int lastbutton = BUTTON_NONE;
576 flipit_init();
577 while(true) {
578 button = rb->button_get(true);
579 switch (button) {
580 #ifdef FLIPIT_RC_QUIT
581 case FLIPIT_RC_QUIT:
582 #endif
583 case FLIPIT_QUIT:
584 /* get out of here */
585 return PLUGIN_OK;
587 case FLIPIT_SHUFFLE:
588 /* mix up the pieces */
589 flipit_init();
590 break;
592 case FLIPIT_SOLVE:
593 #ifdef FLIPIT_SOLVE_PRE
594 if (lastbutton != FLIPIT_SOLVE_PRE)
595 break;
596 #endif
597 /* solve the puzzle */
598 if (!flipit_finished()) {
599 for (i=0; i<20; i++)
600 if (!toggle[i]) {
601 clear_cursor();
602 cursor_pos = i;
603 flipit_toggle();
604 draw_cursor();
605 rb->lcd_update();
606 rb->sleep(HZ*2/3);
609 break;
611 case FLIPIT_STEP_BY_STEP:
612 #ifdef FLIPIT_STEP_PRE
613 if (lastbutton != FLIPIT_STEP_PRE)
614 break;
615 #endif
616 if (!flipit_finished()) {
617 for (i=0; i<20; i++)
618 if (!toggle[i]) {
619 clear_cursor();
620 cursor_pos = i;
621 flipit_toggle();
622 draw_cursor();
623 rb->lcd_update();
624 break;
627 break;
629 case FLIPIT_TOGGLE:
630 #ifdef FLIPIT_TOGGLE_PRE
631 if (lastbutton != FLIPIT_TOGGLE_PRE)
632 break;
633 #endif
634 /* toggle the pieces */
635 if (!flipit_finished()) {
636 flipit_toggle();
637 draw_cursor();
638 rb->lcd_update();
640 break;
642 case FLIPIT_LEFT:
643 move_cursor(-1, 0);
644 break;
646 case FLIPIT_RIGHT:
647 move_cursor(1, 0);
648 break;
649 /*move cursor though the entire field*/
650 #ifdef FLIPIT_SCROLLWHEEL
651 case FLIPIT_PREV:
652 case FLIPIT_PREV|BUTTON_REPEAT:
653 if ((cursor_pos)%5 == 0) {
654 move_cursor(-1, -1);
656 else {
657 move_cursor(-1, 0);
659 break;
661 case FLIPIT_NEXT:
662 case FLIPIT_NEXT|BUTTON_REPEAT:
663 if ((cursor_pos+1)%5 == 0) {
664 move_cursor(1, 1);
666 else {
667 move_cursor(1, 0);
669 break;
670 #endif
671 case FLIPIT_UP:
672 #ifdef FLIPIT_UP_PRE
673 if (lastbutton != FLIPIT_UP_PRE)
674 break;
675 #endif
676 move_cursor(0, -1);
677 break;
679 case FLIPIT_DOWN:
680 move_cursor(0, 1);
681 break;
683 default:
684 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
685 return PLUGIN_USB_CONNECTED;
686 break;
688 if (button != BUTTON_NONE)
689 lastbutton = button;
693 /* called function from outside */
694 enum plugin_status plugin_start(const void* parameter)
696 int i, rc;
698 (void)parameter;
700 #ifdef HAVE_LCD_COLOR
701 rb->lcd_set_background(LCD_WHITE);
702 rb->lcd_set_foreground(LCD_BLACK);
703 #endif
705 #if LCD_DEPTH > 1
706 rb->lcd_set_backdrop(NULL);
707 #endif
709 rb->splash(HZ, "FlipIt!");
711 #ifdef HAVE_LCD_BITMAP
712 /* print instructions */
713 rb->lcd_clear_display();
714 rb->lcd_setfont(FONT_SYSFIXED);
715 #if CONFIG_KEYPAD == RECORDER_PAD
716 rb->lcd_putsxy(2, 8, "[OFF] to stop");
717 rb->lcd_putsxy(2, 18, "[PLAY] toggle");
718 rb->lcd_putsxy(2, 28, "[F1] shuffle");
719 rb->lcd_putsxy(2, 38, "[F2] solution");
720 rb->lcd_putsxy(2, 48, "[F3] step by step");
721 #elif CONFIG_KEYPAD == ONDIO_PAD
722 rb->lcd_putsxy(2, 8, "[OFF] to stop");
723 rb->lcd_putsxy(2, 18, "[MODE] toggle");
724 rb->lcd_putsxy(2, 28, "[M-LEFT] shuffle");
725 rb->lcd_putsxy(2, 38, "[M-UP] solution");
726 rb->lcd_putsxy(2, 48, "[M-RIGHT] step by step");
727 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
728 (CONFIG_KEYPAD == IRIVER_H300_PAD)
729 rb->lcd_putsxy(2, 8, "[STOP] to stop");
730 rb->lcd_putsxy(2, 18, "[SELECT] toggle");
731 rb->lcd_putsxy(2, 28, "[MODE] shuffle");
732 rb->lcd_putsxy(2, 38, "[PLAY] solution");
733 rb->lcd_putsxy(2, 48, "[REC] step by step");
734 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
735 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
736 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
737 rb->lcd_putsxy(2, 8, "[S-MENU] to stop");
738 rb->lcd_putsxy(2, 18, "[SELECT] toggle");
739 rb->lcd_putsxy(2, 28, "[S-LEFT] shuffle");
740 rb->lcd_putsxy(2, 38, "[S-PLAY] solution");
741 rb->lcd_putsxy(2, 48, "[S-RIGHT] step by step");
742 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
743 rb->lcd_putsxy(2, 8, "[POWER] to stop");
744 rb->lcd_putsxy(2, 18, "[SELECT] toggle");
745 rb->lcd_putsxy(2, 28, "[REC] shuffle");
746 rb->lcd_putsxy(2, 38, "[PLAY..] solution");
747 rb->lcd_putsxy(2, 48, "[PLAY] step by step");
748 #elif CONFIG_KEYPAD == GIGABEAT_PAD
749 rb->lcd_putsxy(2, 8, "[POWER] to stop");
750 rb->lcd_putsxy(2, 18, "[SELECT] toggle");
751 rb->lcd_putsxy(2, 28, "[MENU] shuffle");
752 rb->lcd_putsxy(2, 38, "[VOL+] solution");
753 rb->lcd_putsxy(2, 48, "[VOL-] step by step");
754 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
755 rb->lcd_putsxy(2, 8, "[POWER] to stop");
756 rb->lcd_putsxy(2, 18, "[REW] toggle");
757 rb->lcd_putsxy(2, 28, "[PL-LEFT] shuffle");
758 rb->lcd_putsxy(2, 38, "[PL-RIGHT] solution");
759 rb->lcd_putsxy(2, 48, "[PL-UP] step by step");
760 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
761 rb->lcd_putsxy(2, 8, "[BACK] to stop");
762 rb->lcd_putsxy(2, 18, "[SELECT] toggle");
763 rb->lcd_putsxy(2, 28, "[MENU] shuffle");
764 rb->lcd_putsxy(2, 38, "[VOL+] solution");
765 rb->lcd_putsxy(2, 48, "[VOL-] step by step");
766 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
767 (CONFIG_KEYPAD == SANSA_C200_PAD)
768 rb->lcd_putsxy(2, 8, "[POWER] to stop");
769 rb->lcd_putsxy(2, 18, "[SELECT] toggle");
770 rb->lcd_putsxy(2, 28, "[REC-LEFT] shuffle");
771 rb->lcd_putsxy(2, 38, "[REC-RIGHT] solution");
772 rb->lcd_putsxy(2, 48, "[REC-SEL] step by step");
773 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
774 rb->lcd_putsxy(2, 8, "[REC] to stop");
775 rb->lcd_putsxy(2, 18, "[PLAY] toggle");
776 rb->lcd_putsxy(2, 28, "[MODE] shuffle");
777 rb->lcd_putsxy(2, 38, "[MENU..] solution");
778 rb->lcd_putsxy(2, 48, "[MENU] step by step");
779 #endif
781 #ifdef HAVE_TOUCHSCREEN
782 rb->lcd_putsxy(2, 8, "[BOTTOMLEFT] to stop");
783 rb->lcd_putsxy(2, 18, "[CENTRE] toggle");
784 rb->lcd_putsxy(2, 28, "[TOPRIGHT] shuffle");
785 rb->lcd_putsxy(2, 38, "[BOTTOMLEFT] solution");
786 rb->lcd_putsxy(2, 48, "[BOTTOMRIGHT] step by step");
787 #endif
789 rb->lcd_update();
790 #else /* HAVE_LCD_CHARCELLS */
791 if (!init_gfx())
792 return PLUGIN_ERROR;
793 #endif
794 rb->button_get_w_tmo(HZ*3);
796 rb->lcd_clear_display();
797 draw_info_panel();
798 for (i=0; i<20; i++) {
799 spots[i]=1;
800 draw_spot(i);
802 rb->lcd_update();
803 rb->sleep(HZ*3/2);
804 rb->srand(*rb->current_tick);
806 rc = flipit_loop();
807 #ifdef HAVE_LCD_CHARCELLS
808 release_gfx();
809 #endif
810 return rc;