2004-08-17 06:50:14 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
2006-07-27 20:53:57 +00:00
|
|
|
* Copyright (C) 2004-2006 Antoine Cellerier <dionoea -at- videolan -dot- org>
|
2004-08-17 06:50:14 +00:00
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2004-08-17 06:50:14 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "plugin.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
|
2009-02-26 17:10:27 +00:00
|
|
|
#include "lib/playback_control.h"
|
|
|
|
|
2006-01-15 18:20:18 +00:00
|
|
|
PLUGIN_HEADER
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* what the minesweeper() function can return */
|
|
|
|
enum minesweeper_status {
|
|
|
|
MINESWEEPER_WIN,
|
|
|
|
MINESWEEPER_LOSE,
|
|
|
|
MINESWEEPER_QUIT,
|
|
|
|
MINESWEEPER_USB
|
|
|
|
};
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2004-10-18 21:45:00 +00:00
|
|
|
/* variable button definitions */
|
|
|
|
#if CONFIG_KEYPAD == RECORDER_PAD
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_OFF
|
2007-06-25 18:18:07 +00:00
|
|
|
# define MINESWP_TOGGLE BUTTON_ON
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_TOGGLE2 BUTTON_F1
|
2007-06-25 18:18:07 +00:00
|
|
|
# define MINESWP_DISCOVER BUTTON_PLAY
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_DISCOVER2 BUTTON_F2
|
|
|
|
# define MINESWP_INFO BUTTON_F3
|
2004-10-18 21:45:00 +00:00
|
|
|
|
2007-01-14 13:48:09 +00:00
|
|
|
#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2007-01-14 13:48:09 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_OFF
|
2007-06-25 18:18:07 +00:00
|
|
|
# define MINESWP_TOGGLE BUTTON_ON
|
2007-01-14 13:48:09 +00:00
|
|
|
# define MINESWP_TOGGLE2 BUTTON_F1
|
2007-06-25 18:18:07 +00:00
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
2007-01-14 13:48:09 +00:00
|
|
|
# define MINESWP_DISCOVER2 BUTTON_F2
|
|
|
|
# define MINESWP_INFO BUTTON_F3
|
|
|
|
|
2004-10-18 21:45:00 +00:00
|
|
|
#elif CONFIG_KEYPAD == ONDIO_PAD
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_OFF
|
|
|
|
# define MINESWP_TOGGLE_PRE BUTTON_MENU
|
|
|
|
# define MINESWP_TOGGLE (BUTTON_MENU | BUTTON_REL)
|
|
|
|
# define MINESWP_DISCOVER (BUTTON_MENU | BUTTON_REPEAT)
|
|
|
|
# define MINESWP_INFO (BUTTON_MENU | BUTTON_OFF)
|
2004-10-18 21:45:00 +00:00
|
|
|
|
2005-06-29 12:47:24 +00:00
|
|
|
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_OFF
|
|
|
|
# define MINESWP_TOGGLE BUTTON_ON
|
2007-06-25 18:18:07 +00:00
|
|
|
# define MINESWP_TOGGLE2 BUTTON_REC
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
|
|
|
# define MINESWP_INFO BUTTON_MODE
|
|
|
|
|
|
|
|
# define MINESWP_RC_QUIT BUTTON_RC_STOP
|
2006-06-30 16:43:47 +00:00
|
|
|
|
2006-02-24 20:54:09 +00:00
|
|
|
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
|
2007-07-27 09:57:27 +00:00
|
|
|
(CONFIG_KEYPAD == IPOD_3G_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
|
2007-06-25 18:18:07 +00:00
|
|
|
# define MINESWP_SCROLLWHEEL
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2007-06-25 18:18:07 +00:00
|
|
|
# define MINESWP_UP BUTTON_MENU
|
|
|
|
# define MINESWP_DOWN BUTTON_PLAY
|
|
|
|
# define MINESWP_NEXT BUTTON_SCROLL_FWD
|
|
|
|
# define MINESWP_PREV BUTTON_SCROLL_BACK
|
|
|
|
# define MINESWP_QUIT (BUTTON_SELECT | BUTTON_MENU)
|
|
|
|
# define MINESWP_TOGGLE_PRE BUTTON_SELECT
|
|
|
|
# define MINESWP_TOGGLE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define MINESWP_INFO (BUTTON_SELECT | BUTTON_PLAY)
|
2005-12-14 01:31:37 +00:00
|
|
|
|
2007-03-16 23:02:39 +00:00
|
|
|
#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
|
|
|
# define MINESWP_TOGGLE BUTTON_PLAY
|
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
|
|
|
# define MINESWP_INFO BUTTON_REC
|
2006-01-18 11:09:06 +00:00
|
|
|
|
2006-02-24 15:42:52 +00:00
|
|
|
#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
2007-05-19 23:38:09 +00:00
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
|
|
|
# define MINESWP_TOGGLE BUTTON_A
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
|
|
|
# define MINESWP_INFO BUTTON_MENU
|
2006-02-24 15:42:52 +00:00
|
|
|
|
2006-10-26 13:38:09 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_E200_PAD)
|
2009-01-04 23:33:15 +00:00
|
|
|
|
2007-06-25 18:18:07 +00:00
|
|
|
# define MINESWP_SCROLLWHEEL
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2006-10-26 13:38:09 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
2008-01-10 08:08:31 +00:00
|
|
|
# define MINESWP_NEXT BUTTON_SCROLL_FWD
|
|
|
|
# define MINESWP_PREV BUTTON_SCROLL_BACK
|
2006-10-26 13:38:09 +00:00
|
|
|
# define MINESWP_TOGGLE BUTTON_REC
|
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
|
|
|
# define MINESWP_INFO (BUTTON_REC|BUTTON_REPEAT)
|
|
|
|
|
2009-01-04 23:33:15 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
|
|
|
|
|
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
2009-04-10 17:28:26 +00:00
|
|
|
# define MINESWP_QUIT (BUTTON_HOME|BUTTON_REPEAT)
|
2009-01-04 23:33:15 +00:00
|
|
|
# define MINESWP_TOGGLE BUTTON_SCROLL_FWD
|
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
|
|
|
# define MINESWP_INFO BUTTON_SCROLL_BACK
|
|
|
|
|
2008-12-12 19:50:49 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_C200_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == SANSA_M200_PAD)
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2007-10-03 17:09:06 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
|
|
|
# define MINESWP_TOGGLE_PRE BUTTON_SELECT
|
|
|
|
# define MINESWP_TOGGLE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define MINESWP_TOGGLE2 BUTTON_VOL_DOWN
|
|
|
|
# define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define MINESWP_DISCOVER2 BUTTON_VOL_UP
|
2008-11-28 00:37:28 +00:00
|
|
|
# define MINESWP_INFO (BUTTON_SELECT | BUTTON_UP)
|
2007-10-03 17:09:06 +00:00
|
|
|
|
2006-08-03 20:17:25 +00:00
|
|
|
#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2006-08-13 20:44:53 +00:00
|
|
|
# define MINESWP_UP BUTTON_SCROLL_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_SCROLL_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
|
|
|
# define MINESWP_TOGGLE BUTTON_PLAY
|
|
|
|
# define MINESWP_DISCOVER BUTTON_REW
|
|
|
|
# define MINESWP_INFO (BUTTON_REW | BUTTON_PLAY)
|
2006-08-03 20:17:25 +00:00
|
|
|
|
2008-02-17 12:23:02 +00:00
|
|
|
#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2008-02-17 12:23:02 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_BACK
|
|
|
|
# define MINESWP_TOGGLE BUTTON_PLAY
|
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
|
|
|
# define MINESWP_INFO BUTTON_MENU
|
|
|
|
|
2008-03-01 22:55:09 +00:00
|
|
|
#elif (CONFIG_KEYPAD == MROBE100_PAD)
|
2008-03-22 10:24:28 +00:00
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
2008-03-01 22:55:09 +00:00
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
|
|
|
# define MINESWP_TOGGLE BUTTON_DISPLAY
|
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
|
|
|
# define MINESWP_INFO BUTTON_MENU
|
|
|
|
|
2008-03-22 10:24:28 +00:00
|
|
|
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
|
|
|
|
# define MINESWP_LEFT BUTTON_RC_REW
|
|
|
|
# define MINESWP_RIGHT BUTTON_RC_FF
|
|
|
|
# define MINESWP_UP BUTTON_RC_VOL_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_RC_VOL_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_RC_REC
|
|
|
|
# define MINESWP_TOGGLE BUTTON_RC_MODE
|
|
|
|
# define MINESWP_DISCOVER BUTTON_RC_PLAY
|
|
|
|
# define MINESWP_INFO BUTTON_RC_MENU
|
|
|
|
|
2008-03-22 22:03:34 +00:00
|
|
|
#elif (CONFIG_KEYPAD == COWOND2_PAD)
|
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
|
|
|
|
2008-12-04 21:28:56 +00:00
|
|
|
#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
|
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_BACK
|
2008-12-08 09:51:42 +00:00
|
|
|
# define MINESWP_TOGGLE BUTTON_SELECT
|
|
|
|
# define MINESWP_DISCOVER BUTTON_PLAY
|
2008-12-04 21:28:56 +00:00
|
|
|
# define MINESWP_INFO BUTTON_MENU
|
|
|
|
|
2009-01-24 22:41:55 +00:00
|
|
|
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
|
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
|
|
|
# define MINESWP_TOGGLE BUTTON_VIEW
|
|
|
|
# define MINESWP_DISCOVER BUTTON_SELECT
|
|
|
|
# define MINESWP_INFO BUTTON_MENU
|
|
|
|
|
2009-08-31 21:11:32 +00:00
|
|
|
#elif (CONFIG_KEYPAD == ONDAVX747_PAD) || \
|
|
|
|
CONFIG_KEYPAD == ONDAVX777_PAD || \
|
|
|
|
CONFIG_KEYPAD == MROBE500_PAD
|
2009-04-07 23:41:44 +00:00
|
|
|
# define MINESWP_QUIT BUTTON_POWER
|
|
|
|
|
2009-08-04 03:08:32 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
|
|
|
|
# define MINESWP_LEFT BUTTON_LEFT
|
|
|
|
# define MINESWP_RIGHT BUTTON_RIGHT
|
|
|
|
# define MINESWP_UP BUTTON_UP
|
|
|
|
# define MINESWP_DOWN BUTTON_DOWN
|
|
|
|
# define MINESWP_QUIT BUTTON_REC
|
|
|
|
# define MINESWP_TOGGLE BUTTON_PLAY
|
|
|
|
# define MINESWP_DISCOVER BUTTON_REW
|
|
|
|
# define MINESWP_INFO BUTTON_FFWD
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
#else
|
2008-03-01 22:55:09 +00:00
|
|
|
#error No keymap defined!
|
2004-10-18 21:45:00 +00:00
|
|
|
#endif
|
|
|
|
|
2008-08-23 09:46:38 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2008-04-27 15:30:19 +00:00
|
|
|
#ifndef MINESWP_QUIT
|
|
|
|
# define MINESWP_QUIT BUTTON_TOPLEFT
|
|
|
|
#endif
|
|
|
|
#ifndef MINESWP_LEFT
|
|
|
|
# define MINESWP_LEFT BUTTON_MIDLEFT
|
|
|
|
#endif
|
|
|
|
#ifndef MINESWP_RIGHT
|
|
|
|
# define MINESWP_RIGHT BUTTON_MIDRIGHT
|
|
|
|
#endif
|
|
|
|
#ifndef MINESWP_UP
|
|
|
|
# define MINESWP_UP BUTTON_TOPMIDDLE
|
|
|
|
#endif
|
|
|
|
#ifndef MINESWP_DOWN
|
|
|
|
# define MINESWP_DOWN BUTTON_BOTTOMMIDDLE
|
|
|
|
#endif
|
|
|
|
#ifndef MINESWP_TOGGLE
|
|
|
|
# define MINESWP_TOGGLE BUTTON_CENTER
|
|
|
|
#endif
|
|
|
|
#ifndef MINESWP_DISCOVER
|
|
|
|
# define MINESWP_DISCOVER BUTTON_BOTTOMLEFT
|
|
|
|
#endif
|
|
|
|
#ifndef MINESWP_INFO
|
|
|
|
# define MINESWP_INFO BUTTON_BOTTOMRIGHT
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
extern const fb_data minesweeper_tiles[];
|
|
|
|
|
|
|
|
#ifdef HAVE_LCD_COLOR
|
|
|
|
# if ( LCD_HEIGHT * LCD_WIDTH ) / ( 16 * 16 ) >= 130
|
|
|
|
/* We want to have at least 130 tiles on the screen */
|
|
|
|
# define TileSize 16
|
2007-10-03 17:09:06 +00:00
|
|
|
# elif ( LCD_HEIGHT * LCD_WIDTH ) / ( 12 * 12 ) >= 130
|
2006-08-13 20:44:53 +00:00
|
|
|
# define TileSize 12
|
2007-10-03 17:09:06 +00:00
|
|
|
# else
|
|
|
|
# define TileSize 10
|
2006-08-13 20:44:53 +00:00
|
|
|
# endif
|
|
|
|
# define BackgroundColor LCD_RGBPACK( 128, 128, 128 )
|
|
|
|
#elif LCD_DEPTH > 1
|
|
|
|
# define TileSize 12
|
|
|
|
#else
|
|
|
|
# define TileSize 8
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define Mine 9
|
|
|
|
#define Flag 10
|
|
|
|
#define Unknown 11
|
|
|
|
#define ExplodedMine 12
|
|
|
|
|
|
|
|
#define draw_tile( num, x, y ) \
|
|
|
|
rb->lcd_bitmap_part( minesweeper_tiles, 0, num * TileSize, \
|
|
|
|
TileSize, left+x*TileSize, top+y*TileSize, \
|
|
|
|
TileSize, TileSize )
|
|
|
|
|
|
|
|
#define invert_tile( x, y ) \
|
|
|
|
rb->lcd_set_drawmode(DRMODE_COMPLEMENT); \
|
|
|
|
rb->lcd_fillrect( left+x*TileSize, top+y*TileSize, TileSize, TileSize ); \
|
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
2006-05-20 14:01:00 +00:00
|
|
|
|
2004-08-17 06:50:14 +00:00
|
|
|
|
|
|
|
/* the tile struct
|
2006-08-13 20:44:53 +00:00
|
|
|
* if there is a mine, mine is true
|
|
|
|
* if tile is known by player, known is true
|
|
|
|
* if tile has a flag, flag is true
|
|
|
|
* neighbors is the total number of mines arround tile
|
|
|
|
*/
|
|
|
|
typedef struct tile
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
unsigned char mine : 1;
|
|
|
|
unsigned char known : 1;
|
|
|
|
unsigned char flag : 1;
|
|
|
|
unsigned char neighbors : 4;
|
|
|
|
} tile;
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* the height and width of the field */
|
2006-08-13 20:44:53 +00:00
|
|
|
#define MAX_HEIGHT (LCD_HEIGHT/TileSize)
|
|
|
|
#define MAX_WIDTH (LCD_WIDTH/TileSize)
|
|
|
|
int height = MAX_HEIGHT;
|
|
|
|
int width = MAX_WIDTH;
|
|
|
|
int top;
|
|
|
|
int left;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* The Minefield. Caution it is defined as Y, X! Not the opposite. */
|
2006-08-13 20:44:53 +00:00
|
|
|
tile minefield[MAX_HEIGHT][MAX_WIDTH];
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* total number of mines on the game */
|
2004-08-17 06:50:14 +00:00
|
|
|
int mine_num = 0;
|
|
|
|
|
2006-07-08 13:19:23 +00:00
|
|
|
/* percentage of mines on minefield used during generation */
|
2006-08-13 20:44:53 +00:00
|
|
|
int p = 16;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* number of tiles left on the game */
|
|
|
|
int tiles_left;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2007-06-25 18:18:07 +00:00
|
|
|
/* number of used flags on the game */
|
|
|
|
int flags_used;
|
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* Because mines are set after the first move... */
|
|
|
|
bool no_mines = true;
|
|
|
|
|
|
|
|
/* We need a stack (created on discover()) for the cascade algorithm. */
|
|
|
|
int stack_pos = 0;
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* a usefull string for snprintf */
|
|
|
|
char str[30];
|
2006-05-20 14:01:00 +00:00
|
|
|
|
2008-08-23 09:46:38 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2008-06-06 18:29:46 +00:00
|
|
|
|
2009-08-02 07:05:30 +00:00
|
|
|
#include "lib/pluginlib_touchscreen.h"
|
2008-06-06 18:29:46 +00:00
|
|
|
static struct ts_raster mine_raster = { 0, 0, MAX_WIDTH, MAX_HEIGHT, TileSize, TileSize };
|
|
|
|
#endif
|
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
void push( int *stack, int y, int x )
|
|
|
|
{
|
|
|
|
if( stack_pos <= height*width )
|
|
|
|
{
|
|
|
|
stack[++stack_pos] = y;
|
|
|
|
stack[++stack_pos] = x;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* Unveil tiles and push them to stack if they are empty. */
|
2006-08-13 20:44:53 +00:00
|
|
|
void unveil( int *stack, int y, int x )
|
|
|
|
{
|
|
|
|
if( x < 0 || y < 0 || x > width - 1 || y > height - 1
|
|
|
|
|| minefield[y][x].known
|
|
|
|
|| minefield[y][x].mine || minefield[y][x].flag ) return;
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
minefield[y][x].known = 1;
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
if( minefield[y][x].neighbors == 0 )
|
|
|
|
push( stack, y, x );
|
2006-05-20 14:01:00 +00:00
|
|
|
}
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
void discover( int y, int x )
|
|
|
|
{
|
2006-05-20 14:01:00 +00:00
|
|
|
int stack[height*width];
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* Selected tile. */
|
2006-08-13 20:44:53 +00:00
|
|
|
if( x < 0 || y < 0 || x > width - 1 || y > height - 1
|
|
|
|
|| minefield[y][x].known
|
|
|
|
|| minefield[y][x].mine || minefield[y][x].flag ) return;
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
minefield[y][x].known = 1;
|
|
|
|
/* Exit if the tile is not empty. (no mines nearby) */
|
2006-08-13 20:44:53 +00:00
|
|
|
if( minefield[y][x].neighbors ) return;
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
push( stack, y, x );
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* Scan all nearby tiles. If we meet a tile with a number we just unveil
|
2006-08-13 20:44:53 +00:00
|
|
|
* it. If we meet an empty tile, we push the location in stack. For each
|
|
|
|
* location in stack we do the same thing. (scan again all nearby tiles)
|
|
|
|
*/
|
|
|
|
while( stack_pos )
|
|
|
|
{
|
|
|
|
/* Pop x, y from stack. */
|
|
|
|
x = stack[stack_pos--];
|
|
|
|
y = stack[stack_pos--];
|
|
|
|
|
|
|
|
unveil( stack, y-1, x-1 );
|
|
|
|
unveil( stack, y-1, x );
|
|
|
|
unveil( stack, y-1, x+1 );
|
|
|
|
unveil( stack, y, x+1 );
|
|
|
|
unveil( stack, y+1, x+1 );
|
|
|
|
unveil( stack, y+1, x );
|
|
|
|
unveil( stack, y+1, x-1 );
|
|
|
|
unveil( stack, y, x-1 );
|
2006-07-27 20:53:57 +00:00
|
|
|
}
|
2006-05-20 14:01:00 +00:00
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* Reset the whole board for a new game. */
|
2006-08-13 20:44:53 +00:00
|
|
|
void minesweeper_init( void )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
int i,j;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
for( i = 0; i < MAX_HEIGHT; i++ )
|
|
|
|
{
|
|
|
|
for( j = 0; j < MAX_WIDTH; j++ )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
minefield[i][j].known = 0;
|
|
|
|
minefield[i][j].flag = 0;
|
2006-05-20 14:01:00 +00:00
|
|
|
minefield[i][j].mine = 0;
|
|
|
|
minefield[i][j].neighbors = 0;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
2006-05-20 14:01:00 +00:00
|
|
|
no_mines = true;
|
|
|
|
tiles_left = width*height;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* put mines on the mine field */
|
|
|
|
/* there is p% chance that a tile is a mine */
|
|
|
|
/* if the tile has coordinates (x,y), then it can't be a mine */
|
2006-08-13 20:44:53 +00:00
|
|
|
void minesweeper_putmines( int p, int x, int y )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
int i,j;
|
|
|
|
|
2004-10-25 12:28:57 +00:00
|
|
|
mine_num = 0;
|
2006-08-13 20:44:53 +00:00
|
|
|
for( i = 0; i < height; i++ )
|
|
|
|
{
|
|
|
|
for( j = 0; j < width; j++ )
|
|
|
|
{
|
|
|
|
if( rb->rand()%100 < p && !( y==i && x==j ) )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
minefield[i][j].mine = 1;
|
|
|
|
mine_num++;
|
2006-08-13 20:44:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
minefield[i][j].mine = 0;
|
|
|
|
}
|
|
|
|
minefield[i][j].neighbors = 0;
|
|
|
|
}
|
|
|
|
}
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* we need to compute the neighbor element for each tile */
|
2006-08-13 20:44:53 +00:00
|
|
|
for( i = 0; i < height; i++ )
|
|
|
|
{
|
|
|
|
for( j = 0; j < width; j++ )
|
|
|
|
{
|
|
|
|
if( i > 0 )
|
|
|
|
{
|
|
|
|
if( j > 0 )
|
2004-08-18 12:06:10 +00:00
|
|
|
minefield[i][j].neighbors += minefield[i-1][j-1].mine;
|
2004-08-17 06:50:14 +00:00
|
|
|
minefield[i][j].neighbors += minefield[i-1][j].mine;
|
2006-08-13 20:44:53 +00:00
|
|
|
if( j < width - 1 )
|
2004-08-18 12:06:10 +00:00
|
|
|
minefield[i][j].neighbors += minefield[i-1][j+1].mine;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-13 20:44:53 +00:00
|
|
|
if( j > 0 )
|
2004-08-18 12:06:10 +00:00
|
|
|
minefield[i][j].neighbors += minefield[i][j-1].mine;
|
2006-08-13 20:44:53 +00:00
|
|
|
if( j < width - 1 )
|
2004-08-18 12:06:10 +00:00
|
|
|
minefield[i][j].neighbors += minefield[i][j+1].mine;
|
2006-08-13 20:44:53 +00:00
|
|
|
if( i < height - 1 )
|
|
|
|
{
|
|
|
|
if( j > 0 )
|
2004-08-18 12:06:10 +00:00
|
|
|
minefield[i][j].neighbors += minefield[i+1][j-1].mine;
|
2004-08-17 06:50:14 +00:00
|
|
|
minefield[i][j].neighbors += minefield[i+1][j].mine;
|
2006-08-13 20:44:53 +00:00
|
|
|
if( j < width - 1 )
|
2004-08-18 12:06:10 +00:00
|
|
|
minefield[i][j].neighbors += minefield[i+1][j+1].mine;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
no_mines = false;
|
2006-08-13 20:44:53 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* In case the user is lucky and there are no mines positioned. */
|
2006-08-13 20:44:53 +00:00
|
|
|
if( !mine_num && height*width != 1 )
|
|
|
|
{
|
|
|
|
minesweeper_putmines(p, x, y);
|
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
/* A function that will uncover all the board, when the user wins or loses.
|
|
|
|
can easily be expanded, (just a call assigned to a button) as a solver. */
|
2006-08-13 20:44:53 +00:00
|
|
|
void mine_show( void )
|
|
|
|
{
|
2006-05-25 14:05:47 +00:00
|
|
|
int i, j, button;
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
for( i = 0; i < height; i++ )
|
|
|
|
{
|
|
|
|
for( j = 0; j < width; j++ )
|
|
|
|
{
|
|
|
|
if( minefield[i][j].mine )
|
|
|
|
{
|
|
|
|
if( minefield[i][j].known )
|
|
|
|
{
|
|
|
|
draw_tile( ExplodedMine, j, i );
|
2006-05-20 14:01:00 +00:00
|
|
|
}
|
2006-08-13 20:44:53 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
draw_tile( Mine, j, i );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
draw_tile( minefield[i][j].neighbors, j, i );
|
2006-05-20 14:01:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rb->lcd_update();
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-05-25 14:05:47 +00:00
|
|
|
do
|
|
|
|
button = rb->button_get(true);
|
2006-08-13 20:44:53 +00:00
|
|
|
while( ( button == BUTTON_NONE )
|
|
|
|
|| ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
|
2008-08-23 09:46:38 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2008-06-06 18:29:46 +00:00
|
|
|
button = BUTTON_NONE;
|
|
|
|
#endif
|
2006-05-20 14:01:00 +00:00
|
|
|
}
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
int count_tiles_left( void )
|
|
|
|
{
|
|
|
|
int tiles_left = 0;
|
|
|
|
int i, j;
|
|
|
|
for( i = 0; i < height; i++ )
|
|
|
|
for( j = 0; j < width; j++ )
|
|
|
|
if( minefield[i][j].known == 0 )
|
|
|
|
tiles_left++;
|
|
|
|
return tiles_left;
|
|
|
|
}
|
2006-05-20 14:01:00 +00:00
|
|
|
|
2007-06-25 18:18:07 +00:00
|
|
|
int count_flags( void )
|
|
|
|
{
|
|
|
|
int flags_used = 0;
|
|
|
|
int i, j;
|
|
|
|
for( i = 0; i < height; i++ )
|
|
|
|
for( j = 0; j < width; j++ )
|
|
|
|
if( minefield[i][j].flag == 1 )
|
|
|
|
flags_used++;
|
|
|
|
return flags_used;
|
|
|
|
}
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* welcome screen where player can chose mine percentage */
|
|
|
|
enum minesweeper_status menu( void )
|
2004-08-18 12:06:10 +00:00
|
|
|
{
|
2009-07-02 23:29:59 +00:00
|
|
|
int selection = 0, result = MINESWEEPER_QUIT;
|
2007-03-28 07:33:18 +00:00
|
|
|
bool menu_quit = false;
|
2007-06-03 22:00:48 +00:00
|
|
|
|
|
|
|
MENUITEM_STRINGLIST( menu, "Minesweeper Menu", NULL, "Play Minesweeper",
|
|
|
|
"Mine Percentage", "Number of Rows",
|
2009-02-26 17:10:27 +00:00
|
|
|
"Number of Columns", "Playback Control", "Quit" );
|
2007-06-03 22:00:48 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
#ifdef HAVE_LCD_COLOR
|
2007-06-03 22:00:48 +00:00
|
|
|
rb->lcd_set_foreground( rb->global_settings->fg_color );
|
|
|
|
rb->lcd_set_background( rb->global_settings->bg_color );
|
2004-10-18 21:45:00 +00:00
|
|
|
#endif
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2007-06-03 22:00:48 +00:00
|
|
|
while( !menu_quit )
|
|
|
|
{
|
2008-03-26 03:35:24 +00:00
|
|
|
switch( rb->do_menu( &menu, &selection, NULL, false ) )
|
2006-08-13 20:44:53 +00:00
|
|
|
{
|
2007-03-28 07:33:18 +00:00
|
|
|
case 0:
|
|
|
|
result = MINESWEEPER_WIN; /* start playing */
|
|
|
|
menu_quit = true;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
|
|
|
|
2007-03-28 07:33:18 +00:00
|
|
|
case 1:
|
2007-06-03 22:00:48 +00:00
|
|
|
rb->set_int( "Mine Percentage", "%", UNIT_INT, &p, NULL,
|
|
|
|
1, 2, 98, NULL );
|
2005-06-26 20:42:53 +00:00
|
|
|
break;
|
|
|
|
|
2007-03-28 07:33:18 +00:00
|
|
|
case 2:
|
2007-06-03 22:00:48 +00:00
|
|
|
rb->set_int( "Number of Rows", "", UNIT_INT, &height, NULL,
|
|
|
|
1, 1, MAX_HEIGHT, NULL );
|
2005-06-26 20:42:53 +00:00
|
|
|
break;
|
2007-06-03 22:00:48 +00:00
|
|
|
|
2007-03-28 07:33:18 +00:00
|
|
|
case 3:
|
2007-06-03 22:00:48 +00:00
|
|
|
rb->set_int( "Number of Columns", "", UNIT_INT, &width, NULL,
|
|
|
|
1, 1, MAX_WIDTH, NULL );
|
2006-05-20 14:01:00 +00:00
|
|
|
break;
|
2007-06-03 22:00:48 +00:00
|
|
|
|
2009-02-26 17:10:27 +00:00
|
|
|
case 4:
|
|
|
|
playback_control( NULL );
|
|
|
|
break;
|
|
|
|
|
2004-10-18 21:45:00 +00:00
|
|
|
default:
|
2007-03-28 07:33:18 +00:00
|
|
|
result = MINESWEEPER_QUIT; /* quit program */
|
|
|
|
menu_quit = true;
|
2004-10-18 21:45:00 +00:00
|
|
|
break;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-28 07:33:18 +00:00
|
|
|
|
|
|
|
return result;
|
2006-08-13 20:44:53 +00:00
|
|
|
}
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* the big and ugly game function */
|
|
|
|
enum minesweeper_status minesweeper( void )
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
int button;
|
|
|
|
int lastbutton = BUTTON_NONE;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* the cursor coordinates */
|
|
|
|
int x=0, y=0;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/**
|
|
|
|
* Show the menu
|
|
|
|
*/
|
|
|
|
if( ( i = menu() ) != MINESWEEPER_WIN ) return i;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/**
|
|
|
|
* Init game
|
|
|
|
*/
|
|
|
|
top = (LCD_HEIGHT-height*TileSize)/2;
|
|
|
|
left = (LCD_WIDTH-width*TileSize)/2;
|
2008-06-06 18:29:46 +00:00
|
|
|
|
2008-08-23 09:46:38 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2008-06-06 18:29:46 +00:00
|
|
|
mine_raster.tl_x = left;
|
|
|
|
mine_raster.tl_y = top;
|
|
|
|
mine_raster.width = width*TileSize;
|
|
|
|
mine_raster.height = height*TileSize;
|
|
|
|
#endif
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
rb->srand( *rb->current_tick );
|
|
|
|
minesweeper_init();
|
|
|
|
x = 0;
|
|
|
|
y = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Play
|
|
|
|
*/
|
|
|
|
while( true )
|
|
|
|
{
|
|
|
|
|
|
|
|
/* clear the screen buffer */
|
|
|
|
#ifdef HAVE_LCD_COLOR
|
|
|
|
rb->lcd_set_background( BackgroundColor );
|
|
|
|
#endif
|
2004-08-17 06:50:14 +00:00
|
|
|
rb->lcd_clear_display();
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* display the mine field */
|
|
|
|
for( i = 0; i < height; i++ )
|
|
|
|
{
|
|
|
|
for( j = 0; j < width; j++ )
|
|
|
|
{
|
|
|
|
if( minefield[i][j].known )
|
|
|
|
{
|
|
|
|
draw_tile( minefield[i][j].neighbors, j, i );
|
|
|
|
}
|
|
|
|
else if(minefield[i][j].flag)
|
|
|
|
{
|
|
|
|
draw_tile( Flag, j, i );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
draw_tile( Unknown, j, i );
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* display the cursor */
|
2006-08-13 20:44:53 +00:00
|
|
|
invert_tile( x, y );
|
2005-06-24 22:33:21 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* update the screen */
|
2004-08-17 06:50:14 +00:00
|
|
|
rb->lcd_update();
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2008-06-06 18:29:46 +00:00
|
|
|
button = rb->button_get(true);
|
2008-08-23 09:46:38 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
|
|
|
if(button & BUTTON_TOUCHSCREEN)
|
2008-06-06 18:29:46 +00:00
|
|
|
{
|
|
|
|
struct ts_raster_result res;
|
|
|
|
if(touchscreen_map_raster(&mine_raster, rb->button_get_data() >> 16, rb->button_get_data() & 0xffff, &res) == 1)
|
|
|
|
{
|
2008-08-23 09:46:38 +00:00
|
|
|
button &= ~BUTTON_TOUCHSCREEN;
|
|
|
|
lastbutton &= ~BUTTON_TOUCHSCREEN;
|
2008-06-06 18:29:46 +00:00
|
|
|
|
|
|
|
if(button & BUTTON_REPEAT && lastbutton != MINESWP_TOGGLE && lastbutton ^ BUTTON_REPEAT)
|
|
|
|
button = MINESWP_TOGGLE;
|
|
|
|
else if(button == BUTTON_REL && lastbutton ^ BUTTON_REPEAT)
|
|
|
|
button = MINESWP_DISCOVER;
|
|
|
|
else
|
2008-08-23 09:46:38 +00:00
|
|
|
button |= BUTTON_TOUCHSCREEN;
|
2008-06-06 18:29:46 +00:00
|
|
|
|
|
|
|
x = res.x;
|
|
|
|
y = res.y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
switch(button)
|
2006-08-13 20:44:53 +00:00
|
|
|
{
|
2004-08-18 12:06:10 +00:00
|
|
|
/* quit minesweeper (you really shouldn't use this button ...) */
|
2006-06-30 16:43:47 +00:00
|
|
|
#ifdef MINESWP_RC_QUIT
|
|
|
|
case MINESWP_RC_QUIT:
|
|
|
|
#endif
|
2004-10-18 21:45:00 +00:00
|
|
|
case MINESWP_QUIT:
|
2004-08-17 06:50:14 +00:00
|
|
|
return MINESWEEPER_QUIT;
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* move cursor left */
|
2008-03-22 10:24:28 +00:00
|
|
|
case MINESWP_LEFT:
|
|
|
|
case MINESWP_LEFT|BUTTON_REPEAT:
|
2006-08-13 20:44:53 +00:00
|
|
|
x = ( x + width - 1 )%width;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* move cursor right */
|
2008-03-22 10:24:28 +00:00
|
|
|
case MINESWP_RIGHT:
|
|
|
|
case MINESWP_RIGHT|BUTTON_REPEAT:
|
2006-08-13 20:44:53 +00:00
|
|
|
x = ( x + 1 )%width;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* move cursor down */
|
2005-12-14 01:31:37 +00:00
|
|
|
case MINESWP_DOWN:
|
2006-08-13 20:44:53 +00:00
|
|
|
case MINESWP_DOWN|BUTTON_REPEAT:
|
|
|
|
y = ( y + 1 )%height;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* move cursor up */
|
2005-12-14 01:31:37 +00:00
|
|
|
case MINESWP_UP:
|
2006-08-13 20:44:53 +00:00
|
|
|
case MINESWP_UP|BUTTON_REPEAT:
|
|
|
|
y = ( y + height - 1 )%height;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
|
|
|
|
2007-06-25 18:18:07 +00:00
|
|
|
/*move cursor though the entire field*/
|
|
|
|
#ifdef MINESWP_SCROLLWHEEL
|
|
|
|
case MINESWP_NEXT:
|
|
|
|
case MINESWP_NEXT|BUTTON_REPEAT:
|
|
|
|
if (x == width -1 ) {
|
|
|
|
y = ( y + 1 )%height;
|
|
|
|
}
|
|
|
|
x = ( x + 1 )%width;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MINESWP_PREV:
|
|
|
|
case MINESWP_PREV|BUTTON_REPEAT:
|
|
|
|
if (x == 0) {
|
|
|
|
y = ( y + height - 1 )%height;
|
|
|
|
}
|
|
|
|
x = ( x + width - 1 )%width;
|
|
|
|
break;
|
|
|
|
#endif
|
2006-08-13 20:44:53 +00:00
|
|
|
/* discover a tile (and it's neighbors if .neighbors == 0) */
|
2004-10-18 21:45:00 +00:00
|
|
|
case MINESWP_DISCOVER:
|
|
|
|
#ifdef MINESWP_DISCOVER2
|
|
|
|
case MINESWP_DISCOVER2:
|
|
|
|
#endif
|
2006-08-13 20:44:53 +00:00
|
|
|
if( minefield[y][x].flag ) break;
|
|
|
|
/* we put the mines on the first "click" so that you don't
|
|
|
|
* lose on the first "click" */
|
|
|
|
if( tiles_left == width*height && no_mines )
|
2006-05-20 14:01:00 +00:00
|
|
|
minesweeper_putmines(p,x,y);
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-05-20 14:01:00 +00:00
|
|
|
discover(y, x);
|
2006-07-27 20:53:57 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
if( minefield[y][x].mine )
|
|
|
|
{
|
|
|
|
minefield[y][x].known = 1;
|
2004-08-17 06:50:14 +00:00
|
|
|
return MINESWEEPER_LOSE;
|
|
|
|
}
|
2006-08-13 20:44:53 +00:00
|
|
|
tiles_left = count_tiles_left();
|
|
|
|
if( tiles_left == mine_num )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
return MINESWEEPER_WIN;
|
|
|
|
}
|
2005-06-26 20:42:53 +00:00
|
|
|
break;
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* toggle flag under cursor */
|
2004-10-18 21:45:00 +00:00
|
|
|
case MINESWP_TOGGLE:
|
|
|
|
#ifdef MINESWP_TOGGLE_PRE
|
2006-08-13 20:44:53 +00:00
|
|
|
if( lastbutton != MINESWP_TOGGLE_PRE )
|
2004-10-18 21:45:00 +00:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef MINESWP_TOGGLE2
|
|
|
|
case MINESWP_TOGGLE2:
|
|
|
|
#endif
|
2006-08-13 20:44:53 +00:00
|
|
|
minefield[y][x].flag = ( minefield[y][x].flag + 1 )%2;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
/* show how many mines you think you have found and how many
|
|
|
|
* there really are on the game */
|
2004-10-18 21:45:00 +00:00
|
|
|
case MINESWP_INFO:
|
2006-08-13 20:44:53 +00:00
|
|
|
if( no_mines )
|
|
|
|
break;
|
2007-06-25 18:18:07 +00:00
|
|
|
flags_used = count_flags();
|
|
|
|
if (flags_used == 1) {
|
2008-08-15 08:27:39 +00:00
|
|
|
rb->splashf( HZ*2, "You marked 1 field. There are %d mines.",
|
2007-06-25 18:18:07 +00:00
|
|
|
mine_num );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-15 08:27:39 +00:00
|
|
|
rb->splashf( HZ*2, "You marked %d fields. There are %d mines.",
|
2007-06-25 18:18:07 +00:00
|
|
|
flags_used, mine_num );
|
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2004-10-18 21:45:00 +00:00
|
|
|
|
|
|
|
default:
|
2006-08-13 20:44:53 +00:00
|
|
|
if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
|
2004-10-18 21:45:00 +00:00
|
|
|
return MINESWEEPER_USB;
|
|
|
|
break;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-13 20:44:53 +00:00
|
|
|
if( button != BUTTON_NONE )
|
2004-10-18 21:45:00 +00:00
|
|
|
lastbutton = button;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* plugin entry point */
|
2009-01-16 10:34:40 +00:00
|
|
|
enum plugin_status plugin_start(const void* parameter)
|
2004-08-17 06:50:14 +00:00
|
|
|
{
|
2004-10-25 12:28:57 +00:00
|
|
|
bool exit = false;
|
2006-08-13 20:44:53 +00:00
|
|
|
|
2004-08-17 06:50:14 +00:00
|
|
|
(void)parameter;
|
2006-11-15 06:46:35 +00:00
|
|
|
#if LCD_DEPTH > 1
|
2006-11-15 06:14:27 +00:00
|
|
|
rb->lcd_set_backdrop(NULL);
|
2006-11-15 06:46:35 +00:00
|
|
|
#endif
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-08-13 20:44:53 +00:00
|
|
|
while( !exit )
|
|
|
|
{
|
|
|
|
switch( minesweeper() )
|
|
|
|
{
|
2004-10-25 12:28:57 +00:00
|
|
|
case MINESWEEPER_WIN:
|
2007-03-16 21:56:08 +00:00
|
|
|
rb->splash( HZ, "You Win!" );
|
2006-05-20 14:01:00 +00:00
|
|
|
rb->lcd_clear_display();
|
|
|
|
mine_show();
|
2004-10-25 12:28:57 +00:00
|
|
|
break;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2004-10-25 12:28:57 +00:00
|
|
|
case MINESWEEPER_LOSE:
|
2007-03-16 21:56:08 +00:00
|
|
|
rb->splash( HZ, "You Lose!" );
|
2006-05-20 14:01:00 +00:00
|
|
|
rb->lcd_clear_display();
|
|
|
|
mine_show();
|
2004-10-25 12:28:57 +00:00
|
|
|
break;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2004-10-25 12:28:57 +00:00
|
|
|
case MINESWEEPER_USB:
|
|
|
|
return PLUGIN_USB_CONNECTED;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2004-10-25 12:28:57 +00:00
|
|
|
case MINESWEEPER_QUIT:
|
|
|
|
exit = true;
|
|
|
|
break;
|
2005-06-26 20:42:53 +00:00
|
|
|
|
2004-10-25 12:28:57 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return PLUGIN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|