Fix some quotation marks. Thanks to Alexander Levin for pointing it out.
[Rockbox.git] / apps / plugins / minesweeper.c
blob5066844347c5e7eee68ae174e7325a4c2157c98a
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2004-2006 Antoine Cellerier <dionoea -at- videolan -dot- org>
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 #include "plugin.h"
22 #ifdef HAVE_LCD_BITMAP
24 PLUGIN_HEADER
26 /* what the minesweeper() function can return */
27 enum minesweeper_status {
28 MINESWEEPER_WIN,
29 MINESWEEPER_LOSE,
30 MINESWEEPER_QUIT,
31 MINESWEEPER_USB
34 /* variable button definitions */
35 #if CONFIG_KEYPAD == RECORDER_PAD
36 # define MINESWP_LEFT BUTTON_LEFT
37 # define MINESWP_RIGHT BUTTON_RIGHT
38 # define MINESWP_UP BUTTON_UP
39 # define MINESWP_DOWN BUTTON_DOWN
40 # define MINESWP_QUIT BUTTON_OFF
41 # define MINESWP_TOGGLE BUTTON_ON
42 # define MINESWP_TOGGLE2 BUTTON_F1
43 # define MINESWP_DISCOVER BUTTON_PLAY
44 # define MINESWP_DISCOVER2 BUTTON_F2
45 # define MINESWP_INFO BUTTON_F3
47 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
48 # define MINESWP_LEFT BUTTON_LEFT
49 # define MINESWP_RIGHT BUTTON_RIGHT
50 # define MINESWP_UP BUTTON_UP
51 # define MINESWP_DOWN BUTTON_DOWN
52 # define MINESWP_QUIT BUTTON_OFF
53 # define MINESWP_TOGGLE BUTTON_ON
54 # define MINESWP_TOGGLE2 BUTTON_F1
55 # define MINESWP_DISCOVER BUTTON_SELECT
56 # define MINESWP_DISCOVER2 BUTTON_F2
57 # define MINESWP_INFO BUTTON_F3
59 #elif CONFIG_KEYPAD == ONDIO_PAD
60 # define MINESWP_LEFT BUTTON_LEFT
61 # define MINESWP_RIGHT BUTTON_RIGHT
62 # define MINESWP_UP BUTTON_UP
63 # define MINESWP_DOWN BUTTON_DOWN
64 # define MINESWP_QUIT BUTTON_OFF
65 # define MINESWP_TOGGLE_PRE BUTTON_MENU
66 # define MINESWP_TOGGLE (BUTTON_MENU | BUTTON_REL)
67 # define MINESWP_DISCOVER (BUTTON_MENU | BUTTON_REPEAT)
68 # define MINESWP_INFO (BUTTON_MENU | BUTTON_OFF)
70 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
71 (CONFIG_KEYPAD == IRIVER_H300_PAD)
72 # define MINESWP_LEFT BUTTON_LEFT
73 # define MINESWP_RIGHT BUTTON_RIGHT
74 # define MINESWP_UP BUTTON_UP
75 # define MINESWP_DOWN BUTTON_DOWN
76 # define MINESWP_QUIT BUTTON_OFF
77 # define MINESWP_TOGGLE BUTTON_ON
78 # define MINESWP_TOGGLE2 BUTTON_REC
79 # define MINESWP_DISCOVER BUTTON_SELECT
80 # define MINESWP_INFO BUTTON_MODE
82 # define MINESWP_RC_QUIT BUTTON_RC_STOP
84 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
85 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
86 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
87 # define MINESWP_SCROLLWHEEL
88 # define MINESWP_LEFT BUTTON_LEFT
89 # define MINESWP_RIGHT BUTTON_RIGHT
90 # define MINESWP_UP BUTTON_MENU
91 # define MINESWP_DOWN BUTTON_PLAY
92 # define MINESWP_NEXT BUTTON_SCROLL_FWD
93 # define MINESWP_PREV BUTTON_SCROLL_BACK
94 # define MINESWP_QUIT (BUTTON_SELECT | BUTTON_MENU)
95 # define MINESWP_TOGGLE_PRE BUTTON_SELECT
96 # define MINESWP_TOGGLE (BUTTON_SELECT | BUTTON_REL)
97 # define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_REPEAT)
98 # define MINESWP_INFO (BUTTON_SELECT | BUTTON_PLAY)
100 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
101 # define MINESWP_LEFT BUTTON_LEFT
102 # define MINESWP_RIGHT BUTTON_RIGHT
103 # define MINESWP_UP BUTTON_UP
104 # define MINESWP_DOWN BUTTON_DOWN
105 # define MINESWP_QUIT BUTTON_POWER
106 # define MINESWP_TOGGLE BUTTON_PLAY
107 # define MINESWP_DISCOVER BUTTON_SELECT
108 # define MINESWP_INFO BUTTON_REC
110 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
111 # define MINESWP_LEFT BUTTON_LEFT
112 # define MINESWP_RIGHT BUTTON_RIGHT
113 # define MINESWP_UP BUTTON_UP
114 # define MINESWP_DOWN BUTTON_DOWN
115 # define MINESWP_QUIT BUTTON_POWER
116 # define MINESWP_TOGGLE BUTTON_A
117 # define MINESWP_DISCOVER BUTTON_SELECT
118 # define MINESWP_INFO BUTTON_MENU
120 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
121 # define MINESWP_SCROLLWHEEL
122 # define MINESWP_LEFT BUTTON_LEFT
123 # define MINESWP_RIGHT BUTTON_RIGHT
124 # define MINESWP_UP BUTTON_UP
125 # define MINESWP_DOWN BUTTON_DOWN
126 # define MINESWP_QUIT BUTTON_POWER
127 # define MINESWP_NEXT BUTTON_SCROLL_FWD
128 # define MINESWP_PREV BUTTON_SCROLL_BACK
129 # define MINESWP_TOGGLE BUTTON_REC
130 # define MINESWP_DISCOVER BUTTON_SELECT
131 # define MINESWP_INFO (BUTTON_REC|BUTTON_REPEAT)
133 #elif (CONFIG_KEYPAD == SANSA_C200_PAD)
134 # define MINESWP_LEFT BUTTON_LEFT
135 # define MINESWP_RIGHT BUTTON_RIGHT
136 # define MINESWP_UP BUTTON_UP
137 # define MINESWP_DOWN BUTTON_DOWN
138 # define MINESWP_QUIT BUTTON_POWER
139 # define MINESWP_TOGGLE_PRE BUTTON_SELECT
140 # define MINESWP_TOGGLE (BUTTON_SELECT | BUTTON_REL)
141 # define MINESWP_TOGGLE2 BUTTON_VOL_DOWN
142 # define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_REPEAT)
143 # define MINESWP_DISCOVER2 BUTTON_VOL_UP
144 # define MINESWP_INFO BUTTON_REC
146 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
147 # define MINESWP_LEFT BUTTON_LEFT
148 # define MINESWP_RIGHT BUTTON_RIGHT
149 # define MINESWP_UP BUTTON_SCROLL_UP
150 # define MINESWP_DOWN BUTTON_SCROLL_DOWN
151 # define MINESWP_QUIT BUTTON_POWER
152 # define MINESWP_TOGGLE BUTTON_PLAY
153 # define MINESWP_DISCOVER BUTTON_REW
154 # define MINESWP_INFO (BUTTON_REW | BUTTON_PLAY)
156 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
157 # define MINESWP_LEFT BUTTON_LEFT
158 # define MINESWP_RIGHT BUTTON_RIGHT
159 # define MINESWP_UP BUTTON_UP
160 # define MINESWP_DOWN BUTTON_DOWN
161 # define MINESWP_QUIT BUTTON_BACK
162 # define MINESWP_TOGGLE BUTTON_PLAY
163 # define MINESWP_DISCOVER BUTTON_SELECT
164 # define MINESWP_INFO BUTTON_MENU
166 #elif (CONFIG_KEYPAD == MROBE100_PAD)
167 # define MINESWP_LEFT BUTTON_LEFT
168 # define MINESWP_RIGHT BUTTON_RIGHT
169 # define MINESWP_UP BUTTON_UP
170 # define MINESWP_DOWN BUTTON_DOWN
171 # define MINESWP_QUIT BUTTON_POWER
172 # define MINESWP_TOGGLE BUTTON_DISPLAY
173 # define MINESWP_DISCOVER BUTTON_SELECT
174 # define MINESWP_INFO BUTTON_MENU
176 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
177 # define MINESWP_LEFT BUTTON_RC_REW
178 # define MINESWP_RIGHT BUTTON_RC_FF
179 # define MINESWP_UP BUTTON_RC_VOL_UP
180 # define MINESWP_DOWN BUTTON_RC_VOL_DOWN
181 # define MINESWP_QUIT BUTTON_RC_REC
182 # define MINESWP_TOGGLE BUTTON_RC_MODE
183 # define MINESWP_DISCOVER BUTTON_RC_PLAY
184 # define MINESWP_INFO BUTTON_RC_MENU
186 #elif (CONFIG_KEYPAD == COWOND2_PAD)
187 # define MINESWP_LEFT BUTTON_LEFT
188 # define MINESWP_RIGHT BUTTON_RIGHT
189 # define MINESWP_UP BUTTON_UP
190 # define MINESWP_DOWN BUTTON_DOWN
191 # define MINESWP_QUIT BUTTON_POWER
192 # define MINESWP_TOGGLE BUTTON_SELECT
193 # define MINESWP_DISCOVER BUTTON_MENU
194 # define MINESWP_INFO (BUTTON_MENU | BUTTON_SELECT)
196 #else
197 #error No keymap defined!
198 #endif
200 /* here is a global api struct pointer. while not strictly necessary,
201 * it's nice not to have to pass the api pointer in all function calls
202 * in the plugin
204 static struct plugin_api *rb;
206 extern const fb_data minesweeper_tiles[];
208 #ifdef HAVE_LCD_COLOR
209 # if ( LCD_HEIGHT * LCD_WIDTH ) / ( 16 * 16 ) >= 130
210 /* We want to have at least 130 tiles on the screen */
211 # define TileSize 16
212 # elif ( LCD_HEIGHT * LCD_WIDTH ) / ( 12 * 12 ) >= 130
213 # define TileSize 12
214 # else
215 # define TileSize 10
216 # endif
217 # define BackgroundColor LCD_RGBPACK( 128, 128, 128 )
218 #elif LCD_DEPTH > 1
219 # define TileSize 12
220 #else
221 # define TileSize 8
222 #endif
224 #define Mine 9
225 #define Flag 10
226 #define Unknown 11
227 #define ExplodedMine 12
229 #define draw_tile( num, x, y ) \
230 rb->lcd_bitmap_part( minesweeper_tiles, 0, num * TileSize, \
231 TileSize, left+x*TileSize, top+y*TileSize, \
232 TileSize, TileSize )
234 #define invert_tile( x, y ) \
235 rb->lcd_set_drawmode(DRMODE_COMPLEMENT); \
236 rb->lcd_fillrect( left+x*TileSize, top+y*TileSize, TileSize, TileSize ); \
237 rb->lcd_set_drawmode(DRMODE_SOLID);
240 /* the tile struct
241 * if there is a mine, mine is true
242 * if tile is known by player, known is true
243 * if tile has a flag, flag is true
244 * neighbors is the total number of mines arround tile
246 typedef struct tile
248 unsigned char mine : 1;
249 unsigned char known : 1;
250 unsigned char flag : 1;
251 unsigned char neighbors : 4;
252 } tile;
254 /* the height and width of the field */
255 #define MAX_HEIGHT (LCD_HEIGHT/TileSize)
256 #define MAX_WIDTH (LCD_WIDTH/TileSize)
257 int height = MAX_HEIGHT;
258 int width = MAX_WIDTH;
259 int top;
260 int left;
262 /* The Minefield. Caution it is defined as Y, X! Not the opposite. */
263 tile minefield[MAX_HEIGHT][MAX_WIDTH];
265 /* total number of mines on the game */
266 int mine_num = 0;
268 /* percentage of mines on minefield used during generation */
269 int p = 16;
271 /* number of tiles left on the game */
272 int tiles_left;
274 /* number of used flags on the game */
275 int flags_used;
277 /* Because mines are set after the first move... */
278 bool no_mines = true;
280 /* We need a stack (created on discover()) for the cascade algorithm. */
281 int stack_pos = 0;
283 /* a usefull string for snprintf */
284 char str[30];
287 void push( int *stack, int y, int x )
289 if( stack_pos <= height*width )
291 stack[++stack_pos] = y;
292 stack[++stack_pos] = x;
296 /* Unveil tiles and push them to stack if they are empty. */
297 void unveil( int *stack, int y, int x )
299 if( x < 0 || y < 0 || x > width - 1 || y > height - 1
300 || minefield[y][x].known
301 || minefield[y][x].mine || minefield[y][x].flag ) return;
303 minefield[y][x].known = 1;
305 if( minefield[y][x].neighbors == 0 )
306 push( stack, y, x );
309 void discover( int y, int x )
311 int stack[height*width];
313 /* Selected tile. */
314 if( x < 0 || y < 0 || x > width - 1 || y > height - 1
315 || minefield[y][x].known
316 || minefield[y][x].mine || minefield[y][x].flag ) return;
318 minefield[y][x].known = 1;
319 /* Exit if the tile is not empty. (no mines nearby) */
320 if( minefield[y][x].neighbors ) return;
322 push( stack, y, x );
324 /* Scan all nearby tiles. If we meet a tile with a number we just unveil
325 * it. If we meet an empty tile, we push the location in stack. For each
326 * location in stack we do the same thing. (scan again all nearby tiles)
328 while( stack_pos )
330 /* Pop x, y from stack. */
331 x = stack[stack_pos--];
332 y = stack[stack_pos--];
334 unveil( stack, y-1, x-1 );
335 unveil( stack, y-1, x );
336 unveil( stack, y-1, x+1 );
337 unveil( stack, y, x+1 );
338 unveil( stack, y+1, x+1 );
339 unveil( stack, y+1, x );
340 unveil( stack, y+1, x-1 );
341 unveil( stack, y, x-1 );
345 /* Reset the whole board for a new game. */
346 void minesweeper_init( void )
348 int i,j;
350 for( i = 0; i < MAX_HEIGHT; i++ )
352 for( j = 0; j < MAX_WIDTH; j++ )
354 minefield[i][j].known = 0;
355 minefield[i][j].flag = 0;
356 minefield[i][j].mine = 0;
357 minefield[i][j].neighbors = 0;
360 no_mines = true;
361 tiles_left = width*height;
365 /* put mines on the mine field */
366 /* there is p% chance that a tile is a mine */
367 /* if the tile has coordinates (x,y), then it can't be a mine */
368 void minesweeper_putmines( int p, int x, int y )
370 int i,j;
372 mine_num = 0;
373 for( i = 0; i < height; i++ )
375 for( j = 0; j < width; j++ )
377 if( rb->rand()%100 < p && !( y==i && x==j ) )
379 minefield[i][j].mine = 1;
380 mine_num++;
382 else
384 minefield[i][j].mine = 0;
386 minefield[i][j].neighbors = 0;
390 /* we need to compute the neighbor element for each tile */
391 for( i = 0; i < height; i++ )
393 for( j = 0; j < width; j++ )
395 if( i > 0 )
397 if( j > 0 )
398 minefield[i][j].neighbors += minefield[i-1][j-1].mine;
399 minefield[i][j].neighbors += minefield[i-1][j].mine;
400 if( j < width - 1 )
401 minefield[i][j].neighbors += minefield[i-1][j+1].mine;
403 if( j > 0 )
404 minefield[i][j].neighbors += minefield[i][j-1].mine;
405 if( j < width - 1 )
406 minefield[i][j].neighbors += minefield[i][j+1].mine;
407 if( i < height - 1 )
409 if( j > 0 )
410 minefield[i][j].neighbors += minefield[i+1][j-1].mine;
411 minefield[i][j].neighbors += minefield[i+1][j].mine;
412 if( j < width - 1 )
413 minefield[i][j].neighbors += minefield[i+1][j+1].mine;
418 no_mines = false;
420 /* In case the user is lucky and there are no mines positioned. */
421 if( !mine_num && height*width != 1 )
423 minesweeper_putmines(p, x, y);
427 /* A function that will uncover all the board, when the user wins or loses.
428 can easily be expanded, (just a call assigned to a button) as a solver. */
429 void mine_show( void )
431 int i, j, button;
433 for( i = 0; i < height; i++ )
435 for( j = 0; j < width; j++ )
437 if( minefield[i][j].mine )
439 if( minefield[i][j].known )
441 draw_tile( ExplodedMine, j, i );
443 else
445 draw_tile( Mine, j, i );
448 else
450 draw_tile( minefield[i][j].neighbors, j, i );
454 rb->lcd_update();
457 button = rb->button_get(true);
458 while( ( button == BUTTON_NONE )
459 || ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
462 int count_tiles_left( void )
464 int tiles_left = 0;
465 int i, j;
466 for( i = 0; i < height; i++ )
467 for( j = 0; j < width; j++ )
468 if( minefield[i][j].known == 0 )
469 tiles_left++;
470 return tiles_left;
473 int count_flags( void )
475 int flags_used = 0;
476 int i, j;
477 for( i = 0; i < height; i++ )
478 for( j = 0; j < width; j++ )
479 if( minefield[i][j].flag == 1 )
480 flags_used++;
481 return flags_used;
484 /* welcome screen where player can chose mine percentage */
485 enum minesweeper_status menu( void )
487 int selection, result = MINESWEEPER_QUIT;
488 bool menu_quit = false;
490 MENUITEM_STRINGLIST( menu, "Minesweeper Menu", NULL, "Play Minesweeper",
491 "Mine Percentage", "Number of Rows",
492 "Number of Columns", "Quit" );
494 #ifdef HAVE_LCD_COLOR
495 rb->lcd_set_foreground( rb->global_settings->fg_color );
496 rb->lcd_set_background( rb->global_settings->bg_color );
497 #endif
499 while( !menu_quit )
501 switch( rb->do_menu( &menu, &selection, NULL, false ) )
503 case 0:
504 result = MINESWEEPER_WIN; /* start playing */
505 menu_quit = true;
506 break;
508 case 1:
509 rb->set_int( "Mine Percentage", "%", UNIT_INT, &p, NULL,
510 1, 2, 98, NULL );
511 break;
513 case 2:
514 rb->set_int( "Number of Rows", "", UNIT_INT, &height, NULL,
515 1, 1, MAX_HEIGHT, NULL );
516 break;
518 case 3:
519 rb->set_int( "Number of Columns", "", UNIT_INT, &width, NULL,
520 1, 1, MAX_WIDTH, NULL );
521 break;
523 default:
524 result = MINESWEEPER_QUIT; /* quit program */
525 menu_quit = true;
526 break;
530 return result;
533 /* the big and ugly game function */
534 enum minesweeper_status minesweeper( void )
536 int i, j;
537 int button;
538 int lastbutton = BUTTON_NONE;
540 /* the cursor coordinates */
541 int x=0, y=0;
544 * Show the menu
546 if( ( i = menu() ) != MINESWEEPER_WIN ) return i;
549 * Init game
551 top = (LCD_HEIGHT-height*TileSize)/2;
552 left = (LCD_WIDTH-width*TileSize)/2;
554 rb->srand( *rb->current_tick );
555 minesweeper_init();
556 x = 0;
557 y = 0;
560 * Play
562 while( true )
565 /* clear the screen buffer */
566 #ifdef HAVE_LCD_COLOR
567 rb->lcd_set_background( BackgroundColor );
568 #endif
569 rb->lcd_clear_display();
571 /* display the mine field */
572 for( i = 0; i < height; i++ )
574 for( j = 0; j < width; j++ )
576 if( minefield[i][j].known )
578 draw_tile( minefield[i][j].neighbors, j, i );
580 else if(minefield[i][j].flag)
582 draw_tile( Flag, j, i );
584 else
586 draw_tile( Unknown, j, i );
591 /* display the cursor */
592 invert_tile( x, y );
594 /* update the screen */
595 rb->lcd_update();
597 switch( button = rb->button_get( true ) )
599 /* quit minesweeper (you really shouldn't use this button ...) */
600 #ifdef MINESWP_RC_QUIT
601 case MINESWP_RC_QUIT:
602 #endif
603 case MINESWP_QUIT:
604 return MINESWEEPER_QUIT;
606 /* move cursor left */
607 case MINESWP_LEFT:
608 case MINESWP_LEFT|BUTTON_REPEAT:
609 x = ( x + width - 1 )%width;
610 break;
612 /* move cursor right */
613 case MINESWP_RIGHT:
614 case MINESWP_RIGHT|BUTTON_REPEAT:
615 x = ( x + 1 )%width;
616 break;
618 /* move cursor down */
619 case MINESWP_DOWN:
620 case MINESWP_DOWN|BUTTON_REPEAT:
621 y = ( y + 1 )%height;
622 break;
624 /* move cursor up */
625 case MINESWP_UP:
626 case MINESWP_UP|BUTTON_REPEAT:
627 y = ( y + height - 1 )%height;
628 break;
630 /*move cursor though the entire field*/
631 #ifdef MINESWP_SCROLLWHEEL
632 case MINESWP_NEXT:
633 case MINESWP_NEXT|BUTTON_REPEAT:
634 if (x == width -1 ) {
635 y = ( y + 1 )%height;
637 x = ( x + 1 )%width;
638 break;
640 case MINESWP_PREV:
641 case MINESWP_PREV|BUTTON_REPEAT:
642 if (x == 0) {
643 y = ( y + height - 1 )%height;
645 x = ( x + width - 1 )%width;
646 break;
647 #endif
648 /* discover a tile (and it's neighbors if .neighbors == 0) */
649 case MINESWP_DISCOVER:
650 #ifdef MINESWP_DISCOVER2
651 case MINESWP_DISCOVER2:
652 #endif
653 if( minefield[y][x].flag ) break;
654 /* we put the mines on the first "click" so that you don't
655 * lose on the first "click" */
656 if( tiles_left == width*height && no_mines )
657 minesweeper_putmines(p,x,y);
659 discover(y, x);
661 if( minefield[y][x].mine )
663 minefield[y][x].known = 1;
664 return MINESWEEPER_LOSE;
666 tiles_left = count_tiles_left();
667 if( tiles_left == mine_num )
669 return MINESWEEPER_WIN;
671 break;
673 /* toggle flag under cursor */
674 case MINESWP_TOGGLE:
675 #ifdef MINESWP_TOGGLE_PRE
676 if( lastbutton != MINESWP_TOGGLE_PRE )
677 break;
678 #endif
679 #ifdef MINESWP_TOGGLE2
680 case MINESWP_TOGGLE2:
681 #endif
682 minefield[y][x].flag = ( minefield[y][x].flag + 1 )%2;
683 break;
685 /* show how many mines you think you have found and how many
686 * there really are on the game */
687 case MINESWP_INFO:
688 if( no_mines )
689 break;
690 flags_used = count_flags();
691 if (flags_used == 1) {
692 rb->splash( HZ*2, "You marked 1 field. There are %d mines.",
693 mine_num );
695 else
697 rb->splash( HZ*2, "You marked %d fields. There are %d mines.",
698 flags_used, mine_num );
700 break;
702 default:
703 if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
704 return MINESWEEPER_USB;
705 break;
707 if( button != BUTTON_NONE )
708 lastbutton = button;
713 /* plugin entry point */
714 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
716 bool exit = false;
718 (void)parameter;
719 rb = api;
720 #if LCD_DEPTH > 1
721 rb->lcd_set_backdrop(NULL);
722 #endif
724 while( !exit )
726 switch( minesweeper() )
728 case MINESWEEPER_WIN:
729 rb->splash( HZ, "You Win!" );
730 rb->lcd_clear_display();
731 mine_show();
732 break;
734 case MINESWEEPER_LOSE:
735 rb->splash( HZ, "You Lose!" );
736 rb->lcd_clear_display();
737 mine_show();
738 break;
740 case MINESWEEPER_USB:
741 return PLUGIN_USB_CONNECTED;
743 case MINESWEEPER_QUIT:
744 exit = true;
745 break;
747 default:
748 break;
752 return PLUGIN_OK;
755 #endif