diff options
-rw-r--r-- | apps/plugins/bitmaps/native/SOURCES | 12 | ||||
-rw-r--r-- | apps/plugins/bitmaps/native/minesweeper_tiles.12x12x2.bmp | bin | 0 -> 2950 bytes | |||
-rw-r--r-- | apps/plugins/bitmaps/native/minesweeper_tiles.12x12x24.bmp | bin | 0 -> 5670 bytes | |||
-rw-r--r-- | apps/plugins/bitmaps/native/minesweeper_tiles.16x16x24.bmp | bin | 0 -> 10038 bytes | |||
-rw-r--r-- | apps/plugins/bitmaps/native/minesweeper_tiles.8x8x1.bmp | bin | 0 -> 2550 bytes | |||
-rw-r--r-- | apps/plugins/minesweeper.c | 806 |
6 files changed, 384 insertions, 434 deletions
diff --git a/apps/plugins/bitmaps/native/SOURCES b/apps/plugins/bitmaps/native/SOURCES index 98c3eef443..10e61fb97b 100644 --- a/apps/plugins/bitmaps/native/SOURCES +++ b/apps/plugins/bitmaps/native/SOURCES | |||
@@ -280,4 +280,16 @@ rockpaint.bmp | |||
280 | rockpaint_hsvrgb.bmp | 280 | rockpaint_hsvrgb.bmp |
281 | #endif | 281 | #endif |
282 | 282 | ||
283 | #if defined( HAVE_LCD_COLOR ) | ||
284 | #if ( LCD_HEIGHT * LCD_WIDTH ) / ( 16 * 16 ) >= 130 | ||
285 | minesweeper_tiles.16x16x24.bmp | ||
286 | #else | ||
287 | minesweeper_tiles.12x12x24.bmp | ||
288 | #endif | ||
289 | #elif LCD_DEPTH > 1 | ||
290 | minesweeper_tiles.12x12x2.bmp | ||
291 | #else | ||
292 | minesweeper_tiles.8x8x1.bmp | ||
293 | #endif | ||
294 | |||
283 | #endif /* HAVE_LCD_BITMAP */ | 295 | #endif /* HAVE_LCD_BITMAP */ |
diff --git a/apps/plugins/bitmaps/native/minesweeper_tiles.12x12x2.bmp b/apps/plugins/bitmaps/native/minesweeper_tiles.12x12x2.bmp new file mode 100644 index 0000000000..fddd366782 --- /dev/null +++ b/apps/plugins/bitmaps/native/minesweeper_tiles.12x12x2.bmp | |||
Binary files differ | |||
diff --git a/apps/plugins/bitmaps/native/minesweeper_tiles.12x12x24.bmp b/apps/plugins/bitmaps/native/minesweeper_tiles.12x12x24.bmp new file mode 100644 index 0000000000..28340760df --- /dev/null +++ b/apps/plugins/bitmaps/native/minesweeper_tiles.12x12x24.bmp | |||
Binary files differ | |||
diff --git a/apps/plugins/bitmaps/native/minesweeper_tiles.16x16x24.bmp b/apps/plugins/bitmaps/native/minesweeper_tiles.16x16x24.bmp new file mode 100644 index 0000000000..4e1191fad0 --- /dev/null +++ b/apps/plugins/bitmaps/native/minesweeper_tiles.16x16x24.bmp | |||
Binary files differ | |||
diff --git a/apps/plugins/bitmaps/native/minesweeper_tiles.8x8x1.bmp b/apps/plugins/bitmaps/native/minesweeper_tiles.8x8x1.bmp new file mode 100644 index 0000000000..610fbac1fb --- /dev/null +++ b/apps/plugins/bitmaps/native/minesweeper_tiles.8x8x1.bmp | |||
Binary files differ | |||
diff --git a/apps/plugins/minesweeper.c b/apps/plugins/minesweeper.c index 21e655671f..317a969fb0 100644 --- a/apps/plugins/minesweeper.c +++ b/apps/plugins/minesweeper.c | |||
@@ -17,230 +17,155 @@ | |||
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | ||
20 | /***************************************************************************** | ||
21 | Mine Sweeper by dionoea | ||
22 | *****************************************************************************/ | ||
23 | |||
24 | #include "plugin.h" | 20 | #include "plugin.h" |
25 | 21 | ||
26 | #ifdef HAVE_LCD_BITMAP | 22 | #ifdef HAVE_LCD_BITMAP |
27 | 23 | ||
28 | PLUGIN_HEADER | 24 | PLUGIN_HEADER |
29 | 25 | ||
30 | /*what the minesweeper() function can return */ | 26 | /* what the minesweeper() function can return */ |
31 | #define MINESWEEPER_USB 3 | 27 | enum minesweeper_status { |
32 | #define MINESWEEPER_QUIT 2 | 28 | MINESWEEPER_WIN, |
33 | #define MINESWEEPER_LOSE 1 | 29 | MINESWEEPER_LOSE, |
34 | #define MINESWEEPER_WIN 0 | 30 | MINESWEEPER_QUIT, |
31 | MINESWEEPER_USB | ||
32 | }; | ||
35 | 33 | ||
36 | /* variable button definitions */ | 34 | /* variable button definitions */ |
37 | #if CONFIG_KEYPAD == RECORDER_PAD | 35 | #if CONFIG_KEYPAD == RECORDER_PAD |
38 | #define MINESWP_UP BUTTON_UP | 36 | # define MINESWP_UP BUTTON_UP |
39 | #define MINESWP_DOWN BUTTON_DOWN | 37 | # define MINESWP_DOWN BUTTON_DOWN |
40 | #define MINESWP_QUIT BUTTON_OFF | 38 | # define MINESWP_QUIT BUTTON_OFF |
41 | #define MINESWP_START BUTTON_ON | 39 | # define MINESWP_START BUTTON_ON |
42 | #define MINESWP_TOGGLE BUTTON_PLAY | 40 | # define MINESWP_TOGGLE BUTTON_PLAY |
43 | #define MINESWP_TOGGLE2 BUTTON_F1 | 41 | # define MINESWP_TOGGLE2 BUTTON_F1 |
44 | #define MINESWP_DISCOVER BUTTON_ON | 42 | # define MINESWP_DISCOVER BUTTON_ON |
45 | #define MINESWP_DISCOVER2 BUTTON_F2 | 43 | # define MINESWP_DISCOVER2 BUTTON_F2 |
46 | #define MINESWP_INFO BUTTON_F3 | 44 | # define MINESWP_INFO BUTTON_F3 |
47 | #define MINESWP_RIGHT (BUTTON_F1 | BUTTON_RIGHT) | 45 | # define MINESWP_RIGHT (BUTTON_F1 | BUTTON_RIGHT) |
48 | #define MINESWP_LEFT (BUTTON_F1 | BUTTON_LEFT) | 46 | # define MINESWP_LEFT (BUTTON_F1 | BUTTON_LEFT) |
49 | 47 | ||
50 | #elif CONFIG_KEYPAD == ONDIO_PAD | 48 | #elif CONFIG_KEYPAD == ONDIO_PAD |
51 | #define MINESWP_UP BUTTON_UP | 49 | # define MINESWP_UP BUTTON_UP |
52 | #define MINESWP_DOWN BUTTON_DOWN | 50 | # define MINESWP_DOWN BUTTON_DOWN |
53 | #define MINESWP_QUIT BUTTON_OFF | 51 | # define MINESWP_QUIT BUTTON_OFF |
54 | #define MINESWP_START BUTTON_MENU | 52 | # define MINESWP_START BUTTON_MENU |
55 | #define MINESWP_TOGGLE_PRE BUTTON_MENU | 53 | # define MINESWP_TOGGLE_PRE BUTTON_MENU |
56 | #define MINESWP_TOGGLE (BUTTON_MENU | BUTTON_REL) | 54 | # define MINESWP_TOGGLE (BUTTON_MENU | BUTTON_REL) |
57 | #define MINESWP_DISCOVER (BUTTON_MENU | BUTTON_REPEAT) | 55 | # define MINESWP_DISCOVER (BUTTON_MENU | BUTTON_REPEAT) |
58 | #define MINESWP_INFO (BUTTON_MENU | BUTTON_OFF) | 56 | # define MINESWP_INFO (BUTTON_MENU | BUTTON_OFF) |
59 | #define MINESWP_RIGHT (BUTTON_MENU | BUTTON_RIGHT) | 57 | # define MINESWP_RIGHT (BUTTON_MENU | BUTTON_RIGHT) |
60 | #define MINESWP_LEFT (BUTTON_MENU | BUTTON_LEFT) | 58 | # define MINESWP_LEFT (BUTTON_MENU | BUTTON_LEFT) |
61 | 59 | ||
62 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ | 60 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ |
63 | (CONFIG_KEYPAD == IRIVER_H300_PAD) | 61 | (CONFIG_KEYPAD == IRIVER_H300_PAD) |
64 | #define MINESWP_UP BUTTON_UP | 62 | # define MINESWP_UP BUTTON_UP |
65 | #define MINESWP_DOWN BUTTON_DOWN | 63 | # define MINESWP_DOWN BUTTON_DOWN |
66 | #define MINESWP_QUIT BUTTON_OFF | 64 | # define MINESWP_QUIT BUTTON_OFF |
67 | #define MINESWP_START BUTTON_SELECT | 65 | # define MINESWP_START BUTTON_SELECT |
68 | #define MINESWP_TOGGLE BUTTON_ON | 66 | # define MINESWP_TOGGLE BUTTON_ON |
69 | #define MINESWP_DISCOVER BUTTON_SELECT | 67 | # define MINESWP_DISCOVER BUTTON_SELECT |
70 | #define MINESWP_INFO BUTTON_MODE | 68 | # define MINESWP_INFO BUTTON_MODE |
71 | #define MINESWP_RIGHT (BUTTON_ON | BUTTON_RIGHT) | 69 | # define MINESWP_RIGHT (BUTTON_ON | BUTTON_RIGHT) |
72 | #define MINESWP_LEFT (BUTTON_ON | BUTTON_LEFT) | 70 | # define MINESWP_LEFT (BUTTON_ON | BUTTON_LEFT) |
73 | 71 | ||
74 | #define MINESWP_RC_QUIT BUTTON_RC_STOP | 72 | # define MINESWP_RC_QUIT BUTTON_RC_STOP |
75 | 73 | ||
76 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ | 74 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ |
77 | (CONFIG_KEYPAD == IPOD_3G_PAD) | 75 | (CONFIG_KEYPAD == IPOD_3G_PAD) |
78 | #define MINESWP_UP BUTTON_SCROLL_BACK | 76 | # define MINESWP_UP BUTTON_SCROLL_BACK |
79 | #define MINESWP_DOWN BUTTON_SCROLL_FWD | 77 | # define MINESWP_DOWN BUTTON_SCROLL_FWD |
80 | #define MINESWP_QUIT BUTTON_MENU | 78 | # define MINESWP_QUIT BUTTON_MENU |
81 | #define MINESWP_START BUTTON_SELECT | 79 | # define MINESWP_START BUTTON_SELECT |
82 | #define MINESWP_TOGGLE BUTTON_PLAY | 80 | # define MINESWP_TOGGLE BUTTON_PLAY |
83 | #define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_PLAY) | 81 | # define MINESWP_DISCOVER (BUTTON_SELECT | BUTTON_PLAY) |
84 | #define MINESWP_INFO (BUTTON_SELECT | BUTTON_MENU) | 82 | # define MINESWP_INFO (BUTTON_SELECT | BUTTON_MENU) |
85 | #define MINESWP_RIGHT (BUTTON_SELECT | BUTTON_RIGHT) | 83 | # define MINESWP_RIGHT (BUTTON_SELECT | BUTTON_RIGHT) |
86 | #define MINESWP_LEFT (BUTTON_SELECT | BUTTON_LEFT) | 84 | # define MINESWP_LEFT (BUTTON_SELECT | BUTTON_LEFT) |
87 | 85 | ||
88 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) | 86 | #elif (CONFIG_KEYPAD == IAUDIO_X5_PAD) |
89 | #define MINESWP_UP BUTTON_UP | 87 | # define MINESWP_UP BUTTON_UP |
90 | #define MINESWP_DOWN BUTTON_DOWN | 88 | # define MINESWP_DOWN BUTTON_DOWN |
91 | #define MINESWP_QUIT BUTTON_POWER | 89 | # define MINESWP_QUIT BUTTON_POWER |
92 | #define MINESWP_START BUTTON_REC | 90 | # define MINESWP_START BUTTON_REC |
93 | #define MINESWP_TOGGLE BUTTON_PLAY | 91 | # define MINESWP_TOGGLE BUTTON_PLAY |
94 | #define MINESWP_DISCOVER BUTTON_SELECT | 92 | # define MINESWP_DISCOVER BUTTON_SELECT |
95 | #define MINESWP_INFO (BUTTON_REC | BUTTON_PLAY) | 93 | # define MINESWP_INFO (BUTTON_REC | BUTTON_PLAY) |
96 | #define MINESWP_RIGHT (BUTTON_PLAY | BUTTON_RIGHT) | 94 | # define MINESWP_RIGHT (BUTTON_PLAY | BUTTON_RIGHT) |
97 | #define MINESWP_LEFT (BUTTON_PLAY | BUTTON_LEFT) | 95 | # define MINESWP_LEFT (BUTTON_PLAY | BUTTON_LEFT) |
98 | 96 | ||
99 | #elif (CONFIG_KEYPAD == GIGABEAT_PAD) | 97 | #elif (CONFIG_KEYPAD == GIGABEAT_PAD) |
100 | #define MINESWP_UP BUTTON_UP | 98 | # define MINESWP_UP BUTTON_UP |
101 | #define MINESWP_DOWN BUTTON_DOWN | 99 | # define MINESWP_DOWN BUTTON_DOWN |
102 | #define MINESWP_QUIT BUTTON_A | 100 | # define MINESWP_QUIT BUTTON_A |
103 | #define MINESWP_START BUTTON_SELECT | 101 | # define MINESWP_START BUTTON_SELECT |
104 | #define MINESWP_TOGGLE BUTTON_POWER | 102 | # define MINESWP_TOGGLE BUTTON_POWER |
105 | #define MINESWP_DISCOVER BUTTON_SELECT | 103 | # define MINESWP_DISCOVER BUTTON_SELECT |
106 | #define MINESWP_INFO BUTTON_MENU | 104 | # define MINESWP_INFO BUTTON_MENU |
107 | #define MINESWP_RIGHT (BUTTON_SELECT | BUTTON_RIGHT) | 105 | # define MINESWP_RIGHT (BUTTON_SELECT | BUTTON_RIGHT) |
108 | #define MINESWP_LEFT (BUTTON_SELECT | BUTTON_LEFT) | 106 | # define MINESWP_LEFT (BUTTON_SELECT | BUTTON_LEFT) |
109 | 107 | ||
110 | #elif (CONFIG_KEYPAD == IRIVER_H10_PAD) | 108 | #elif (CONFIG_KEYPAD == IRIVER_H10_PAD) |
111 | #define MINESWP_UP BUTTON_SCROLL_UP | 109 | # define MINESWP_UP BUTTON_SCROLL_UP |
112 | #define MINESWP_DOWN BUTTON_SCROLL_DOWN | 110 | # define MINESWP_DOWN BUTTON_SCROLL_DOWN |
113 | #define MINESWP_QUIT BUTTON_POWER | 111 | # define MINESWP_QUIT BUTTON_POWER |
114 | #define MINESWP_START BUTTON_FF | 112 | # define MINESWP_START BUTTON_FF |
115 | #define MINESWP_TOGGLE BUTTON_PLAY | 113 | # define MINESWP_TOGGLE BUTTON_PLAY |
116 | #define MINESWP_DISCOVER BUTTON_REW | 114 | # define MINESWP_DISCOVER BUTTON_REW |
117 | #define MINESWP_INFO (BUTTON_REW | BUTTON_PLAY) | 115 | # define MINESWP_INFO (BUTTON_REW | BUTTON_PLAY) |
118 | #define MINESWP_RIGHT (BUTTON_RIGHT | BUTTON_PLAY) | 116 | # define MINESWP_RIGHT (BUTTON_RIGHT | BUTTON_PLAY) |
119 | #define MINESWP_LEFT (BUTTON_LEFT | BUTTON_PLAY) | 117 | # define MINESWP_LEFT (BUTTON_LEFT | BUTTON_PLAY) |
120 | 118 | ||
119 | #else | ||
120 | # warning Missing key definitions for this keypad | ||
121 | #endif | 121 | #endif |
122 | 122 | ||
123 | /* here is a global api struct pointer. while not strictly necessary, | 123 | /* here is a global api struct pointer. while not strictly necessary, |
124 | it's nice not to have to pass the api pointer in all function calls | 124 | * it's nice not to have to pass the api pointer in all function calls |
125 | in the plugin */ | 125 | * in the plugin |
126 | static struct plugin_api* rb; | 126 | */ |
127 | 127 | static struct plugin_api *rb; | |
128 | 128 | ||
129 | /* define how numbers are displayed (that way we don't have to */ | 129 | extern const fb_data minesweeper_tiles[]; |
130 | /* worry about fonts) */ | 130 | |
131 | static unsigned char num[10][8] = { | 131 | #ifdef HAVE_LCD_COLOR |
132 | /*reading the sprites: | 132 | # if ( LCD_HEIGHT * LCD_WIDTH ) / ( 16 * 16 ) >= 130 |
133 | on screen f123 | 133 | /* We want to have at least 130 tiles on the screen */ |
134 | 4567 | 134 | # define TileSize 16 |
135 | 890a | 135 | # else |
136 | bcde | 136 | # define TileSize 12 |
137 | 137 | # endif | |
138 | in binary b84f | 138 | # define BackgroundColor LCD_RGBPACK( 128, 128, 128 ) |
139 | c951 | 139 | #elif LCD_DEPTH > 1 |
140 | d062 | 140 | # define TileSize 12 |
141 | ea73 | 141 | #else |
142 | */ | 142 | # define TileSize 8 |
143 | 143 | #endif | |
144 | /* 0 */ | 144 | |
145 | {0x00, /* ........ */ | 145 | #define Mine 9 |
146 | 0x00, /* ........ */ | 146 | #define Flag 10 |
147 | 0x00, /* ........ */ | 147 | #define Unknown 11 |
148 | 0x00, /* ........ */ | 148 | #define ExplodedMine 12 |
149 | 0x00, /* ........ */ | 149 | |
150 | 0x00, /* ........ */ | 150 | #define draw_tile( num, x, y ) \ |
151 | 0x00, /* ........ */ | 151 | rb->lcd_bitmap_part( minesweeper_tiles, 0, num * TileSize, \ |
152 | 0x00},/* ........ */ | 152 | TileSize, left+x*TileSize, top+y*TileSize, \ |
153 | /* 1 */ | 153 | TileSize, TileSize ) |
154 | {0x00, /* ........ */ | 154 | |
155 | 0x00, /* ........ */ | 155 | #define invert_tile( x, y ) \ |
156 | 0x00, /* ...OO... */ | 156 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); \ |
157 | 0x44, /* ....O... */ | 157 | rb->lcd_fillrect( left+x*TileSize, top+y*TileSize, TileSize, TileSize ); \ |
158 | 0x7c, /* ....O... */ | 158 | rb->lcd_set_drawmode(DRMODE_SOLID); |
159 | 0x40, /* ....O... */ | ||
160 | 0x00, /* ...OOO.. */ | ||
161 | 0x00},/* ........ */ | ||
162 | /* 2 */ | ||
163 | {0x00, /* ........ */ | ||
164 | 0x00, /* ........ */ | ||
165 | 0x48, /* ...OO... */ | ||
166 | 0x64, /* ..O..O.. */ | ||
167 | 0x54, /* ....O... */ | ||
168 | 0x48, /* ...O.... */ | ||
169 | 0x00, /* ..OOOO.. */ | ||
170 | 0x00},/* ........ */ | ||
171 | /* 3 */ | ||
172 | {0x00, /* ........ */ | ||
173 | 0x00, /* ........ */ | ||
174 | 0x44, /* ..OOO... */ | ||
175 | 0x54, /* .....O.. */ | ||
176 | 0x54, /* ...OO... */ | ||
177 | 0x28, /* .....O.. */ | ||
178 | 0x00, /* ..OOO... */ | ||
179 | 0x00},/* ........ */ | ||
180 | /* 4 */ | ||
181 | {0x00, /* ........ */ | ||
182 | 0x00, /* ........ */ | ||
183 | 0x1c, /* ..O..... */ | ||
184 | 0x10, /* ..O..... */ | ||
185 | 0x70, /* ..OOOO.. */ | ||
186 | 0x10, /* ....O... */ | ||
187 | 0x00, /* ....O... */ | ||
188 | 0x00},/* ........ */ | ||
189 | /* 5 */ | ||
190 | {0x00, /* ........ */ | ||
191 | 0x00, /* ........ */ | ||
192 | 0x5c, /* ..OOOO.. */ | ||
193 | 0x54, /* ..O..... */ | ||
194 | 0x54, /* ..OOO... */ | ||
195 | 0x24, /* .....O.. */ | ||
196 | 0x00, /* ..OOO... */ | ||
197 | 0x00},/* ........ */ | ||
198 | /* 6 */ | ||
199 | {0x00, /* ........ */ | ||
200 | 0x00, /* ........ */ | ||
201 | 0x38, /* ...OOO.. */ | ||
202 | 0x54, /* ..O..... */ | ||
203 | 0x54, /* ..OOO... */ | ||
204 | 0x24, /* ..O..O.. */ | ||
205 | 0x00, /* ...OO... */ | ||
206 | 0x00},/* ........ */ | ||
207 | /* 7 */ | ||
208 | {0x00, /* ........ */ | ||
209 | 0x00, /* ........ */ | ||
210 | 0x44, /* ..OOOO.. */ | ||
211 | 0x24, /* .....O.. */ | ||
212 | 0x14, /* ....O... */ | ||
213 | 0x0c, /* ...O.... */ | ||
214 | 0x00, /* ..O..... */ | ||
215 | 0x00},/* ........ */ | ||
216 | /* 8 */ | ||
217 | {0x00, /* ........ */ | ||
218 | 0x00, /* ........ */ | ||
219 | 0x28, /* ...OO... */ | ||
220 | 0x54, /* ..O..O.. */ | ||
221 | 0x54, /* ...OO... */ | ||
222 | 0x28, /* ..O..O.. */ | ||
223 | 0x00, /* ...OO... */ | ||
224 | 0x00},/* ........ */ | ||
225 | /* mine */ | ||
226 | {0x00, /* ........ */ | ||
227 | 0x00, /* ........ */ | ||
228 | 0x18, /* ...OO... */ | ||
229 | 0x3c, /* ..OOOO.. */ | ||
230 | 0x3c, /* ..OOOO.. */ | ||
231 | 0x18, /* ...OO... */ | ||
232 | 0x00, /* ........ */ | ||
233 | 0x00},/* ........ */ | ||
234 | 159 | ||
235 | }; | ||
236 | 160 | ||
237 | /* the tile struct | 161 | /* the tile struct |
238 | if there is a mine, mine is true | 162 | * if there is a mine, mine is true |
239 | if tile is known by player, known is true | 163 | * if tile is known by player, known is true |
240 | if tile has a flag, flag is true | 164 | * if tile has a flag, flag is true |
241 | neighbors is the total number of mines arround tile | 165 | * neighbors is the total number of mines arround tile |
242 | */ | 166 | */ |
243 | typedef struct tile { | 167 | typedef struct tile |
168 | { | ||
244 | unsigned char mine : 1; | 169 | unsigned char mine : 1; |
245 | unsigned char known : 1; | 170 | unsigned char known : 1; |
246 | unsigned char flag : 1; | 171 | unsigned char flag : 1; |
@@ -248,17 +173,21 @@ typedef struct tile { | |||
248 | } tile; | 173 | } tile; |
249 | 174 | ||
250 | /* the height and width of the field */ | 175 | /* the height and width of the field */ |
251 | int height = LCD_HEIGHT/8; | 176 | #define MAX_HEIGHT (LCD_HEIGHT/TileSize) |
252 | int width = LCD_WIDTH/8; | 177 | #define MAX_WIDTH (LCD_WIDTH/TileSize) |
178 | int height = MAX_HEIGHT; | ||
179 | int width = MAX_WIDTH; | ||
180 | int top; | ||
181 | int left; | ||
253 | 182 | ||
254 | /* The Minefield. Caution it is defined as Y, X! Not the opposite. */ | 183 | /* The Minefield. Caution it is defined as Y, X! Not the opposite. */ |
255 | tile minefield[LCD_HEIGHT/8][LCD_WIDTH/8]; | 184 | tile minefield[MAX_HEIGHT][MAX_WIDTH]; |
256 | 185 | ||
257 | /* total number of mines on the game */ | 186 | /* total number of mines on the game */ |
258 | int mine_num = 0; | 187 | int mine_num = 0; |
259 | 188 | ||
260 | /* percentage of mines on minefield used during generation */ | 189 | /* percentage of mines on minefield used during generation */ |
261 | int p=16; | 190 | int p = 16; |
262 | 191 | ||
263 | /* number of tiles left on the game */ | 192 | /* number of tiles left on the game */ |
264 | int tiles_left; | 193 | int tiles_left; |
@@ -269,83 +198,77 @@ bool no_mines = true; | |||
269 | /* We need a stack (created on discover()) for the cascade algorithm. */ | 198 | /* We need a stack (created on discover()) for the cascade algorithm. */ |
270 | int stack_pos = 0; | 199 | int stack_pos = 0; |
271 | 200 | ||
272 | /* Functions to center the board on screen. */ | 201 | /* a usefull string for snprintf */ |
273 | int c_height(void){ | 202 | char str[30]; |
274 | return LCD_HEIGHT/16 - height/2; | ||
275 | } | ||
276 | |||
277 | int c_width(void){ | ||
278 | return LCD_WIDTH/16 - width/2; | ||
279 | } | ||
280 | 203 | ||
281 | void push (int *stack, int y, int x){ | ||
282 | 204 | ||
283 | if(stack_pos <= height*width){ | 205 | void push( int *stack, int y, int x ) |
284 | stack_pos++; | 206 | { |
285 | stack[stack_pos] = y; | 207 | if( stack_pos <= height*width ) |
286 | stack_pos++; | 208 | { |
287 | stack[stack_pos] = x; | 209 | stack[++stack_pos] = y; |
210 | stack[++stack_pos] = x; | ||
288 | } | 211 | } |
289 | } | 212 | } |
290 | 213 | ||
291 | /* Unveil tiles and push them to stack if they are empty. */ | 214 | /* Unveil tiles and push them to stack if they are empty. */ |
292 | void unveil(int *stack, int y, int x){ | 215 | void unveil( int *stack, int y, int x ) |
216 | { | ||
217 | if( x < 0 || y < 0 || x > width - 1 || y > height - 1 | ||
218 | || minefield[y][x].known | ||
219 | || minefield[y][x].mine || minefield[y][x].flag ) return; | ||
293 | 220 | ||
294 | if(x < c_width() || y < c_height() || x > c_width() + width-1 | 221 | minefield[y][x].known = 1; |
295 | || y > c_height() + height-1 || minefield[y][x].known | ||
296 | || minefield[y][x].mine || minefield[y][x].flag) return; | ||
297 | 222 | ||
298 | if(minefield[y][x].neighbors == 0){ | 223 | if( minefield[y][x].neighbors == 0 ) |
299 | minefield[y][x].known = 1; | 224 | push( stack, y, x ); |
300 | push(stack, y, x); | ||
301 | } else | ||
302 | minefield[y][x].known = 1; | ||
303 | } | 225 | } |
304 | 226 | ||
305 | void discover(int y, int x){ | 227 | void discover( int y, int x ) |
306 | 228 | { | |
307 | int stack[height*width]; | 229 | int stack[height*width]; |
308 | 230 | ||
309 | /* Selected tile. */ | 231 | /* Selected tile. */ |
310 | if(x < c_width() || y < c_height() || x > c_width() + width-1 | 232 | if( x < 0 || y < 0 || x > width - 1 || y > height - 1 |
311 | || y > c_height() + height-1 || minefield[y][x].known | 233 | || minefield[y][x].known |
312 | || minefield[y][x].mine || minefield[y][x].flag) return; | 234 | || minefield[y][x].mine || minefield[y][x].flag ) return; |
313 | 235 | ||
314 | minefield[y][x].known = 1; | 236 | minefield[y][x].known = 1; |
315 | /* Exit if the tile is not empty. (no mines nearby) */ | 237 | /* Exit if the tile is not empty. (no mines nearby) */ |
316 | if(minefield[y][x].neighbors) return; | 238 | if( minefield[y][x].neighbors ) return; |
317 | 239 | ||
318 | push(stack, y, x); | 240 | push( stack, y, x ); |
319 | 241 | ||
320 | /* Scan all nearby tiles. If we meet a tile with a number we just unveil | 242 | /* Scan all nearby tiles. If we meet a tile with a number we just unveil |
321 | it. If we meet an empty tile, we push the location in stack. For each | 243 | * it. If we meet an empty tile, we push the location in stack. For each |
322 | location in stack we do the same thing. (scan again all nearby tiles) */ | 244 | * location in stack we do the same thing. (scan again all nearby tiles) |
323 | while(stack_pos){ | 245 | */ |
324 | /* Retrieve x, y from stack. */ | 246 | while( stack_pos ) |
325 | x = stack[stack_pos]; | 247 | { |
326 | y = stack[stack_pos-1]; | 248 | /* Pop x, y from stack. */ |
327 | 249 | x = stack[stack_pos--]; | |
328 | /* Pop. */ | 250 | y = stack[stack_pos--]; |
329 | if(stack_pos > 0) stack_pos -= 2; | 251 | |
330 | else rb->splash(HZ,true,"ERROR"); | 252 | unveil( stack, y-1, x-1 ); |
331 | 253 | unveil( stack, y-1, x ); | |
332 | unveil(stack, y-1, x-1); | 254 | unveil( stack, y-1, x+1 ); |
333 | unveil(stack, y-1, x); | 255 | unveil( stack, y, x+1 ); |
334 | unveil(stack, y-1, x+1); | 256 | unveil( stack, y+1, x+1 ); |
335 | unveil(stack, y, x+1); | 257 | unveil( stack, y+1, x ); |
336 | unveil(stack, y+1, x+1); | 258 | unveil( stack, y+1, x-1 ); |
337 | unveil(stack, y+1, x); | 259 | unveil( stack, y, x-1 ); |
338 | unveil(stack, y+1, x-1); | ||
339 | unveil(stack, y, x-1); | ||
340 | } | 260 | } |
341 | } | 261 | } |
342 | 262 | ||
343 | /* Reset the whole board for a new game. */ | 263 | /* Reset the whole board for a new game. */ |
344 | void minesweeper_init(void){ | 264 | void minesweeper_init( void ) |
265 | { | ||
345 | int i,j; | 266 | int i,j; |
346 | 267 | ||
347 | for(i=0;i<LCD_HEIGHT/8;i++){ | 268 | for( i = 0; i < MAX_HEIGHT; i++ ) |
348 | for(j=0;j<LCD_WIDTH/8;j++){ | 269 | { |
270 | for( j = 0; j < MAX_WIDTH; j++ ) | ||
271 | { | ||
349 | minefield[i][j].known = 0; | 272 | minefield[i][j].known = 0; |
350 | minefield[i][j].flag = 0; | 273 | minefield[i][j].flag = 0; |
351 | minefield[i][j].mine = 0; | 274 | minefield[i][j].mine = 0; |
@@ -360,16 +283,22 @@ void minesweeper_init(void){ | |||
360 | /* put mines on the mine field */ | 283 | /* put mines on the mine field */ |
361 | /* there is p% chance that a tile is a mine */ | 284 | /* there is p% chance that a tile is a mine */ |
362 | /* if the tile has coordinates (x,y), then it can't be a mine */ | 285 | /* if the tile has coordinates (x,y), then it can't be a mine */ |
363 | void minesweeper_putmines(int p, int x, int y){ | 286 | void minesweeper_putmines( int p, int x, int y ) |
287 | { | ||
364 | int i,j; | 288 | int i,j; |
365 | 289 | ||
366 | mine_num = 0; | 290 | mine_num = 0; |
367 | for(i=c_height();i<c_height() + height;i++){ | 291 | for( i = 0; i < height; i++ ) |
368 | for(j=c_width();j<c_width() + width;j++){ | 292 | { |
369 | if(rb->rand()%100<p && !(y==i && x==j)){ | 293 | for( j = 0; j < width; j++ ) |
294 | { | ||
295 | if( rb->rand()%100 < p && !( y==i && x==j ) ) | ||
296 | { | ||
370 | minefield[i][j].mine = 1; | 297 | minefield[i][j].mine = 1; |
371 | mine_num++; | 298 | mine_num++; |
372 | } else { | 299 | } |
300 | else | ||
301 | { | ||
373 | minefield[i][j].mine = 0; | 302 | minefield[i][j].mine = 0; |
374 | } | 303 | } |
375 | minefield[i][j].neighbors = 0; | 304 | minefield[i][j].neighbors = 0; |
@@ -377,59 +306,66 @@ void minesweeper_putmines(int p, int x, int y){ | |||
377 | } | 306 | } |
378 | 307 | ||
379 | /* we need to compute the neighbor element for each tile */ | 308 | /* we need to compute the neighbor element for each tile */ |
380 | for(i=c_height();i<c_height() + height;i++){ | 309 | for( i = 0; i < height; i++ ) |
381 | for(j=c_width();j<c_width() + width;j++){ | 310 | { |
382 | if(i>0){ | 311 | for( j = 0; j < width; j++ ) |
383 | if(j>0) | 312 | { |
313 | if( i > 0 ) | ||
314 | { | ||
315 | if( j > 0 ) | ||
384 | minefield[i][j].neighbors += minefield[i-1][j-1].mine; | 316 | minefield[i][j].neighbors += minefield[i-1][j-1].mine; |
385 | minefield[i][j].neighbors += minefield[i-1][j].mine; | 317 | minefield[i][j].neighbors += minefield[i-1][j].mine; |
386 | if(j<c_width() + width-1) | 318 | if( j < width - 1 ) |
387 | minefield[i][j].neighbors += minefield[i-1][j+1].mine; | 319 | minefield[i][j].neighbors += minefield[i-1][j+1].mine; |
388 | } | 320 | } |
389 | if(j>0) | 321 | if( j > 0 ) |
390 | minefield[i][j].neighbors += minefield[i][j-1].mine; | 322 | minefield[i][j].neighbors += minefield[i][j-1].mine; |
391 | if(j<c_width() + width-1) | 323 | if( j < width - 1 ) |
392 | minefield[i][j].neighbors += minefield[i][j+1].mine; | 324 | minefield[i][j].neighbors += minefield[i][j+1].mine; |
393 | if(i<c_height() + height-1){ | 325 | if( i < height - 1 ) |
394 | if(j>0) | 326 | { |
327 | if( j > 0 ) | ||
395 | minefield[i][j].neighbors += minefield[i+1][j-1].mine; | 328 | minefield[i][j].neighbors += minefield[i+1][j-1].mine; |
396 | minefield[i][j].neighbors += minefield[i+1][j].mine; | 329 | minefield[i][j].neighbors += minefield[i+1][j].mine; |
397 | if(j<c_width() + width-1) | 330 | if( j < width - 1 ) |
398 | minefield[i][j].neighbors += minefield[i+1][j+1].mine; | 331 | minefield[i][j].neighbors += minefield[i+1][j+1].mine; |
399 | } | 332 | } |
400 | } | 333 | } |
401 | } | 334 | } |
402 | 335 | ||
403 | no_mines = false; | 336 | no_mines = false; |
337 | |||
404 | /* In case the user is lucky and there are no mines positioned. */ | 338 | /* In case the user is lucky and there are no mines positioned. */ |
405 | if(!mine_num && height*width != 1) minesweeper_putmines(p, x, y); | 339 | if( !mine_num && height*width != 1 ) |
340 | { | ||
341 | minesweeper_putmines(p, x, y); | ||
342 | } | ||
406 | } | 343 | } |
407 | 344 | ||
408 | /* A function that will uncover all the board, when the user wins or loses. | 345 | /* A function that will uncover all the board, when the user wins or loses. |
409 | can easily be expanded, (just a call assigned to a button) as a solver. */ | 346 | can easily be expanded, (just a call assigned to a button) as a solver. */ |
410 | void mine_show(void){ | 347 | void mine_show( void ) |
348 | { | ||
411 | int i, j, button; | 349 | int i, j, button; |
412 | 350 | ||
413 | for(i=c_height();i<c_height() + height;i++){ | 351 | for( i = 0; i < height; i++ ) |
414 | for(j=c_width();j<c_width() + width;j++){ | 352 | { |
415 | #if LCD_DEPTH > 1 | 353 | for( j = 0; j < width; j++ ) |
416 | rb->lcd_set_foreground(LCD_DARKGRAY); | 354 | { |
417 | rb->lcd_drawrect(j*8,i*8,8,8); | 355 | if( minefield[i][j].mine ) |
418 | rb->lcd_set_foreground(LCD_BLACK); | 356 | { |
419 | #else | 357 | if( minefield[i][j].known ) |
420 | rb->lcd_drawrect(j*8,i*8,8,8); | 358 | { |
421 | #endif | 359 | draw_tile( ExplodedMine, j, i ); |
422 | if(!minefield[i][j].known){ | ||
423 | if(minefield[i][j].mine){ | ||
424 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
425 | rb->lcd_mono_bitmap(num[9], j*8,i*8,8,8); | ||
426 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
427 | } else if(minefield[i][j].neighbors){ | ||
428 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
429 | rb->lcd_mono_bitmap(num[minefield[i][j].neighbors], | ||
430 | j*8,i*8,8,8); | ||
431 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
432 | } | 360 | } |
361 | else | ||
362 | { | ||
363 | draw_tile( Mine, j, i ); | ||
364 | } | ||
365 | } | ||
366 | else | ||
367 | { | ||
368 | draw_tile( minefield[i][j].neighbors, j, i ); | ||
433 | } | 369 | } |
434 | } | 370 | } |
435 | } | 371 | } |
@@ -437,90 +373,97 @@ void mine_show(void){ | |||
437 | 373 | ||
438 | do | 374 | do |
439 | button = rb->button_get(true); | 375 | button = rb->button_get(true); |
440 | while ((button == BUTTON_NONE) || (button & (BUTTON_REL|BUTTON_REPEAT))); | 376 | while( ( button == BUTTON_NONE ) |
377 | || ( button & (BUTTON_REL|BUTTON_REPEAT) ) ); | ||
441 | } | 378 | } |
442 | 379 | ||
380 | int count_tiles_left( void ) | ||
381 | { | ||
382 | int tiles_left = 0; | ||
383 | int i, j; | ||
384 | for( i = 0; i < height; i++ ) | ||
385 | for( j = 0; j < width; j++ ) | ||
386 | if( minefield[i][j].known == 0 ) | ||
387 | tiles_left++; | ||
388 | return tiles_left; | ||
389 | } | ||
443 | 390 | ||
444 | /* the big and ugly function that is the game */ | 391 | /* welcome screen where player can chose mine percentage */ |
445 | int minesweeper(void) | 392 | enum minesweeper_status menu( void ) |
446 | { | 393 | { |
447 | int i,j; | ||
448 | int button; | 394 | int button; |
449 | int lastbutton = BUTTON_NONE; | ||
450 | |||
451 | /* the cursor coordinates */ | ||
452 | int x=0, y=0; | ||
453 | 395 | ||
454 | /* a usefull string for snprintf */ | 396 | while( true ) |
455 | char str[30]; | 397 | { |
456 | 398 | #ifdef HAVE_LCD_COLOR | |
457 | /* welcome screen where player can chose mine percentage */ | 399 | rb->lcd_set_background( LCD_WHITE ); |
458 | i = 0; | 400 | rb->lcd_set_foreground( LCD_BLACK ); |
459 | while(true){ | 401 | #endif |
460 | rb->lcd_clear_display(); | 402 | rb->lcd_clear_display(); |
461 | 403 | ||
462 | rb->lcd_puts(0,0,"Mine Sweeper"); | 404 | rb->lcd_puts( 0, 0, "Mine Sweeper" ); |
463 | 405 | ||
464 | rb->snprintf(str, 20, "%d%% mines", p); | 406 | rb->snprintf( str, 20, "%d%% mines", p ); |
465 | rb->lcd_puts(0,2,str); | 407 | rb->lcd_puts( 0, 2, str ); |
466 | rb->lcd_puts(0,3,"down / up"); | 408 | rb->lcd_puts( 0, 3, "down / up" ); |
467 | rb->snprintf(str, 20, "%d cols x %d rows", width, height); | 409 | rb->snprintf( str, 20, "%d cols x %d rows", width, height ); |
468 | rb->lcd_puts(0,4,str); | 410 | rb->lcd_puts( 0, 4, str ); |
469 | rb->lcd_puts(0,5,"left x right "); | 411 | rb->lcd_puts( 0, 5, "left x right" ); |
412 | rb->lcd_puts( 0, 6, | ||
470 | #if CONFIG_KEYPAD == RECORDER_PAD | 413 | #if CONFIG_KEYPAD == RECORDER_PAD |
471 | rb->lcd_puts(0,6,"ON to start"); | 414 | "ON to start" |
472 | #elif CONFIG_KEYPAD == ONDIO_PAD | 415 | #elif CONFIG_KEYPAD == ONDIO_PAD |
473 | rb->lcd_puts(0,6,"MODE to start"); | 416 | "MODE to start" |
474 | #elif (CONFIG_KEYPAD==IRIVER_H100_PAD) || (CONFIG_KEYPAD==IPOD_4G_PAD) | 417 | #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) \ |
475 | rb->lcd_puts(0,6,"SELECT to start"); | 418 | || (CONFIG_KEYPAD == IRIVER_H300_PAD ) \ |
419 | || (CONFIG_KEYPAD == IPOD_4G_PAD) | ||
420 | "SELECT to start" | ||
476 | #elif CONFIG_KEYPAD == IAUDIO_X5_PAD | 421 | #elif CONFIG_KEYPAD == IAUDIO_X5_PAD |
477 | rb->lcd_puts(0,6,"REC to start"); | 422 | "REC to start" |
423 | #else | ||
424 | "" | ||
425 | # warning Please define help string for this keypad. | ||
478 | #endif | 426 | #endif |
427 | ); | ||
479 | rb->lcd_update(); | 428 | rb->lcd_update(); |
480 | 429 | ||
481 | button = rb->button_get(true); | 430 | switch( button = rb->button_get( true ) ) |
482 | switch(button){ | 431 | { |
483 | case MINESWP_DOWN: | 432 | case MINESWP_DOWN: |
484 | case (MINESWP_DOWN | BUTTON_REPEAT): | 433 | case MINESWP_DOWN|BUTTON_REPEAT: |
485 | p = (p + 98)%100; | 434 | p = (p + 94)%98 + 2; |
486 | /* Don't let the user play without mines. */ | ||
487 | if(!p) p = 98; | ||
488 | break; | 435 | break; |
489 | 436 | ||
490 | case MINESWP_UP: | 437 | case MINESWP_UP: |
491 | case (MINESWP_UP | BUTTON_REPEAT): | 438 | case MINESWP_UP|BUTTON_REPEAT: |
492 | p = (p + 2)%100; | 439 | p = p%98 + 2; |
493 | /* Don't let the user play without mines. */ | ||
494 | if(!p) p = 2; | ||
495 | break; | 440 | break; |
496 | 441 | ||
497 | case BUTTON_RIGHT: | 442 | case BUTTON_RIGHT: |
498 | case (BUTTON_RIGHT | BUTTON_REPEAT): | 443 | case BUTTON_RIGHT|BUTTON_REPEAT: |
499 | height = height%(LCD_HEIGHT/8)+1; | 444 | height = height%MAX_HEIGHT + 1; |
500 | break; | 445 | break; |
501 | 446 | ||
502 | case BUTTON_LEFT: | 447 | case BUTTON_LEFT: |
503 | case (BUTTON_LEFT | BUTTON_REPEAT): | 448 | case BUTTON_LEFT|BUTTON_REPEAT: |
504 | width = width%(LCD_WIDTH/8)+1; | 449 | width = width%MAX_WIDTH + 1; |
505 | break; | 450 | break; |
506 | 451 | ||
507 | case MINESWP_RIGHT: | 452 | case MINESWP_RIGHT: |
508 | case (MINESWP_RIGHT | BUTTON_REPEAT): | 453 | case MINESWP_RIGHT|BUTTON_REPEAT: |
509 | height--; | 454 | height--; |
510 | if(height < 1) height = LCD_HEIGHT/8; | 455 | if( height < 1 ) height = MAX_HEIGHT; |
511 | if(height > LCD_HEIGHT) height = 1; | ||
512 | break; | 456 | break; |
513 | 457 | ||
514 | case MINESWP_LEFT: | 458 | case MINESWP_LEFT: |
515 | case (MINESWP_LEFT | BUTTON_REPEAT): | 459 | case MINESWP_LEFT|BUTTON_REPEAT: |
516 | width--; | 460 | width--; |
517 | if(width < 1) width = LCD_WIDTH/8; | 461 | if( width < 1 ) width = MAX_WIDTH; |
518 | if(width > LCD_WIDTH) width = 1; | ||
519 | break; | 462 | break; |
520 | 463 | ||
521 | case MINESWP_START:/* start playing */ | 464 | case MINESWP_START:/* start playing */ |
522 | i = 1; | 465 | return MINESWEEPER_WIN; |
523 | break; | 466 | |
524 | #ifdef MINESWP_RC_QUIT | 467 | #ifdef MINESWP_RC_QUIT |
525 | case MINESWP_RC_QUIT: | 468 | case MINESWP_RC_QUIT: |
526 | #endif | 469 | #endif |
@@ -528,74 +471,79 @@ int minesweeper(void) | |||
528 | return MINESWEEPER_QUIT; | 471 | return MINESWEEPER_QUIT; |
529 | 472 | ||
530 | default: | 473 | default: |
531 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) | 474 | if( rb->default_event_handler(button) == SYS_USB_CONNECTED ) |
532 | return MINESWEEPER_USB; | 475 | return MINESWEEPER_USB; |
533 | break; | 476 | break; |
534 | } | 477 | } |
535 | if(i==1) | ||
536 | break; | ||
537 | } | 478 | } |
479 | } | ||
538 | 480 | ||
481 | /* the big and ugly game function */ | ||
482 | enum minesweeper_status minesweeper( void ) | ||
483 | { | ||
484 | int i, j; | ||
485 | int button; | ||
486 | int lastbutton = BUTTON_NONE; | ||
539 | 487 | ||
540 | /******************** | 488 | /* the cursor coordinates */ |
541 | * init * | 489 | int x=0, y=0; |
542 | ********************/ | ||
543 | |||
544 | minesweeper_init(); | ||
545 | x = c_width(); | ||
546 | y = c_height(); | ||
547 | 490 | ||
548 | /********************** | 491 | /** |
549 | * play * | 492 | * Show the menu |
550 | **********************/ | 493 | */ |
494 | if( ( i = menu() ) != MINESWEEPER_WIN ) return i; | ||
551 | 495 | ||
552 | while(true){ | 496 | /** |
497 | * Init game | ||
498 | */ | ||
499 | top = (LCD_HEIGHT-height*TileSize)/2; | ||
500 | left = (LCD_WIDTH-width*TileSize)/2; | ||
553 | 501 | ||
554 | /*clear the screen buffer */ | 502 | rb->srand( *rb->current_tick ); |
503 | minesweeper_init(); | ||
504 | x = 0; | ||
505 | y = 0; | ||
506 | |||
507 | /** | ||
508 | * Play | ||
509 | */ | ||
510 | while( true ) | ||
511 | { | ||
512 | |||
513 | /* clear the screen buffer */ | ||
514 | #ifdef HAVE_LCD_COLOR | ||
515 | rb->lcd_set_background( BackgroundColor ); | ||
516 | #endif | ||
555 | rb->lcd_clear_display(); | 517 | rb->lcd_clear_display(); |
556 | 518 | ||
557 | /*display the mine field */ | 519 | /* display the mine field */ |
558 | for(i=c_height();i<c_height() + height;i++){ | 520 | for( i = 0; i < height; i++ ) |
559 | for(j=c_width();j<c_width() + width;j++){ | 521 | { |
560 | #if LCD_DEPTH > 1 | 522 | for( j = 0; j < width; j++ ) |
561 | rb->lcd_set_foreground(LCD_DARKGRAY); | 523 | { |
562 | rb->lcd_drawrect(j*8,i*8,8,8); | 524 | if( minefield[i][j].known ) |
563 | rb->lcd_set_foreground(LCD_BLACK); | 525 | { |
564 | #else | 526 | draw_tile( minefield[i][j].neighbors, j, i ); |
565 | rb->lcd_drawrect(j*8,i*8,8,8); | 527 | } |
566 | #endif | 528 | else if(minefield[i][j].flag) |
567 | if(minefield[i][j].known){ | 529 | { |
568 | if(minefield[i][j].neighbors){ | 530 | draw_tile( Flag, j, i ); |
569 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | 531 | } |
570 | rb->lcd_mono_bitmap(num[minefield[i][j].neighbors], | 532 | else |
571 | j*8,i*8,8,8); | 533 | { |
572 | rb->lcd_set_drawmode(DRMODE_SOLID); | 534 | draw_tile( Unknown, j, i ); |
573 | } | ||
574 | } else if(minefield[i][j].flag) { | ||
575 | rb->lcd_drawline(j*8+2,i*8+2,j*8+5,i*8+5); | ||
576 | rb->lcd_drawline(j*8+2,i*8+5,j*8+5,i*8+2); | ||
577 | } else { | ||
578 | #if LCD_DEPTH > 1 | ||
579 | rb->lcd_set_foreground(LCD_LIGHTGRAY); | ||
580 | rb->lcd_fillrect(j*8+1,i*8+1,6,6); | ||
581 | rb->lcd_set_foreground(LCD_BLACK); | ||
582 | #else | ||
583 | rb->lcd_fillrect(j*8+2,i*8+2,4,4); | ||
584 | #endif | ||
585 | } | 535 | } |
586 | } | 536 | } |
587 | } | 537 | } |
588 | 538 | ||
589 | /* display the cursor */ | 539 | /* display the cursor */ |
590 | rb->lcd_set_drawmode(DRMODE_COMPLEMENT); | 540 | invert_tile( x, y ); |
591 | rb->lcd_fillrect(x*8,y*8,8,8); | ||
592 | rb->lcd_set_drawmode(DRMODE_SOLID); | ||
593 | 541 | ||
594 | /* update the screen */ | 542 | /* update the screen */ |
595 | rb->lcd_update(); | 543 | rb->lcd_update(); |
596 | 544 | ||
597 | button = rb->button_get(true); | 545 | switch( button = rb->button_get( true ) ) |
598 | switch(button){ | 546 | { |
599 | /* quit minesweeper (you really shouldn't use this button ...) */ | 547 | /* quit minesweeper (you really shouldn't use this button ...) */ |
600 | #ifdef MINESWP_RC_QUIT | 548 | #ifdef MINESWP_RC_QUIT |
601 | case MINESWP_RC_QUIT: | 549 | case MINESWP_RC_QUIT: |
@@ -603,94 +551,83 @@ int minesweeper(void) | |||
603 | case MINESWP_QUIT: | 551 | case MINESWP_QUIT: |
604 | return MINESWEEPER_QUIT; | 552 | return MINESWEEPER_QUIT; |
605 | 553 | ||
606 | /* move cursor left */ | 554 | /* move cursor left */ |
607 | case BUTTON_LEFT: | 555 | case BUTTON_LEFT: |
608 | case (BUTTON_LEFT | BUTTON_REPEAT): | 556 | case BUTTON_LEFT|BUTTON_REPEAT: |
609 | if(x<=c_width()) x = width + c_width(); | 557 | x = ( x + width - 1 )%width; |
610 | x = x-1; | ||
611 | break; | 558 | break; |
612 | 559 | ||
613 | /* move cursor right */ | 560 | /* move cursor right */ |
614 | case BUTTON_RIGHT: | 561 | case BUTTON_RIGHT: |
615 | case (BUTTON_RIGHT | BUTTON_REPEAT): | 562 | case BUTTON_RIGHT|BUTTON_REPEAT: |
616 | if(x>=width + c_width() - 1) x = c_width() - 1; | 563 | x = ( x + 1 )%width; |
617 | x = x+1; | ||
618 | break; | 564 | break; |
619 | 565 | ||
620 | /* move cursor down */ | 566 | /* move cursor down */ |
621 | case MINESWP_DOWN: | 567 | case MINESWP_DOWN: |
622 | case (MINESWP_DOWN | BUTTON_REPEAT): | 568 | case MINESWP_DOWN|BUTTON_REPEAT: |
623 | if(y>=height + c_height() - 1) y = c_height() - 1; | 569 | y = ( y + 1 )%height; |
624 | y = y+1; | ||
625 | break; | 570 | break; |
626 | 571 | ||
627 | /* move cursor up */ | 572 | /* move cursor up */ |
628 | case MINESWP_UP: | 573 | case MINESWP_UP: |
629 | case (MINESWP_UP | BUTTON_REPEAT): | 574 | case MINESWP_UP|BUTTON_REPEAT: |
630 | if(y<=c_height()) y = height + c_height(); | 575 | y = ( y + height - 1 )%height; |
631 | y = y-1; | ||
632 | break; | 576 | break; |
633 | 577 | ||
634 | /* discover a tile (and it's neighbors if .neighbors == 0) */ | 578 | /* discover a tile (and it's neighbors if .neighbors == 0) */ |
635 | case MINESWP_DISCOVER: | 579 | case MINESWP_DISCOVER: |
636 | #ifdef MINESWP_DISCOVER2 | 580 | #ifdef MINESWP_DISCOVER2 |
637 | case MINESWP_DISCOVER2: | 581 | case MINESWP_DISCOVER2: |
638 | #endif | 582 | #endif |
639 | if(minefield[y][x].flag) break; | 583 | if( minefield[y][x].flag ) break; |
640 | /* we put the mines on the first "click" so that you don't */ | 584 | /* we put the mines on the first "click" so that you don't |
641 | /* lose on the first "click" */ | 585 | * lose on the first "click" */ |
642 | if(tiles_left == width*height && no_mines) | 586 | if( tiles_left == width*height && no_mines ) |
643 | minesweeper_putmines(p,x,y); | 587 | minesweeper_putmines(p,x,y); |
644 | 588 | ||
645 | discover(y, x); | 589 | discover(y, x); |
646 | 590 | ||
647 | if(minefield[y][x].mine){ | 591 | if( minefield[y][x].mine ) |
592 | { | ||
593 | minefield[y][x].known = 1; | ||
648 | return MINESWEEPER_LOSE; | 594 | return MINESWEEPER_LOSE; |
649 | } | 595 | } |
650 | tiles_left = 0; | 596 | tiles_left = count_tiles_left(); |
651 | for(i=c_height();i<c_height() + height;i++){ | 597 | if( tiles_left == mine_num ) |
652 | for(j=c_width();j<c_width() + width;j++){ | 598 | { |
653 | if(minefield[i][j].known == 0) tiles_left++; | ||
654 | } | ||
655 | } | ||
656 | if(tiles_left == mine_num){ | ||
657 | return MINESWEEPER_WIN; | 599 | return MINESWEEPER_WIN; |
658 | } | 600 | } |
659 | break; | 601 | break; |
660 | 602 | ||
661 | /* toggle flag under cursor */ | 603 | /* toggle flag under cursor */ |
662 | case MINESWP_TOGGLE: | 604 | case MINESWP_TOGGLE: |
663 | #ifdef MINESWP_TOGGLE_PRE | 605 | #ifdef MINESWP_TOGGLE_PRE |
664 | if (lastbutton != MINESWP_TOGGLE_PRE) | 606 | if( lastbutton != MINESWP_TOGGLE_PRE ) |
665 | break; | 607 | break; |
666 | #endif | 608 | #endif |
667 | #ifdef MINESWP_TOGGLE2 | 609 | #ifdef MINESWP_TOGGLE2 |
668 | case MINESWP_TOGGLE2: | 610 | case MINESWP_TOGGLE2: |
669 | #endif | 611 | #endif |
670 | minefield[y][x].flag = (minefield[y][x].flag + 1)%2; | 612 | minefield[y][x].flag = ( minefield[y][x].flag + 1 )%2; |
671 | break; | 613 | break; |
672 | 614 | ||
673 | /* show how many mines you think you have found and how many */ | 615 | /* show how many mines you think you have found and how many |
674 | /* there really are on the game */ | 616 | * there really are on the game */ |
675 | case MINESWP_INFO: | 617 | case MINESWP_INFO: |
676 | if(no_mines) break; | 618 | if( no_mines ) |
677 | tiles_left = 0; | 619 | break; |
678 | for(i=c_height();i<c_height() + height;i++){ | 620 | tiles_left = count_tiles_left(); |
679 | for(j=c_width();j<c_width() + width;j++){ | 621 | rb->splash( HZ*2, true, "You found %d mines out of %d", |
680 | if(minefield[i][j].flag && !minefield[i][j].known) | 622 | tiles_left, mine_num ); |
681 | tiles_left++; | ||
682 | } | ||
683 | } | ||
684 | rb->splash(HZ*2, true, "You found %d mines out of %d", | ||
685 | tiles_left, mine_num); | ||
686 | break; | 623 | break; |
687 | 624 | ||
688 | default: | 625 | default: |
689 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) | 626 | if( rb->default_event_handler( button ) == SYS_USB_CONNECTED ) |
690 | return MINESWEEPER_USB; | 627 | return MINESWEEPER_USB; |
691 | break; | 628 | break; |
692 | } | 629 | } |
693 | if (button != BUTTON_NONE) | 630 | if( button != BUTTON_NONE ) |
694 | lastbutton = button; | 631 | lastbutton = button; |
695 | } | 632 | } |
696 | 633 | ||
@@ -700,21 +637,22 @@ int minesweeper(void) | |||
700 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | 637 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) |
701 | { | 638 | { |
702 | bool exit = false; | 639 | bool exit = false; |
703 | /* plugin init */ | 640 | |
704 | (void)parameter; | 641 | (void)parameter; |
705 | rb = api; | 642 | rb = api; |
706 | /* end of plugin init */ | ||
707 | 643 | ||
708 | while(!exit) { | 644 | while( !exit ) |
709 | switch(minesweeper()){ | 645 | { |
646 | switch( minesweeper() ) | ||
647 | { | ||
710 | case MINESWEEPER_WIN: | 648 | case MINESWEEPER_WIN: |
711 | rb->splash(HZ*2, true, "You Win! Press a key"); | 649 | rb->splash( HZ, true, "You Win!" ); |
712 | rb->lcd_clear_display(); | 650 | rb->lcd_clear_display(); |
713 | mine_show(); | 651 | mine_show(); |
714 | break; | 652 | break; |
715 | 653 | ||
716 | case MINESWEEPER_LOSE: | 654 | case MINESWEEPER_LOSE: |
717 | rb->splash(HZ*2, true, "You Lose! Press a key"); | 655 | rb->splash( HZ, true, "You Lose!" ); |
718 | rb->lcd_clear_display(); | 656 | rb->lcd_clear_display(); |
719 | mine_show(); | 657 | mine_show(); |
720 | break; | 658 | break; |