1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Adam Boot
12 * Color graphics from Frozen Bubble (http://www.frozen-bubble.org/)
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
24 #include "pluginlib_actions.h"
26 #ifdef HAVE_LCD_BITMAP
31 #define SCORE_FILE PLUGIN_DIR "/bubbles.score"
32 #define SAVE_FILE PLUGIN_DIR "/bubbles.save"
34 /* final game return status */
42 /* play board dimension */
45 #define BB_LEVEL_HEIGHT 10
49 #define NUM_LEVELS 100
54 #define NUM_COMPRESS 9
55 #define MAX_SHOTTIME 1000
57 /* keyboard layouts */
58 #define BUBBLES_LEFT PLA_LEFT
59 #define BUBBLES_LEFT_REP PLA_LEFT_REPEAT
60 #define BUBBLES_RIGHT PLA_RIGHT
61 #define BUBBLES_RIGHT_REP PLA_RIGHT_REPEAT
62 #define BUBBLES_QUIT PLA_QUIT
63 #define BUBBLES_START PLA_START
64 #define BUBBLES_SELECT PLA_FIRE
65 #define BUBBLES_RESUME PLA_MENU
67 #if CONFIG_KEYPAD != ONDIO_PAD
69 #define BUBBLES_LVLINC PLA_UP
70 #define BUBBLES_LVLINC_REP PLA_UP_REPEAT
71 #define BUBBLES_LVLDEC PLA_DOWN
72 #define BUBBLES_LVLDEC_REP PLA_DOWN_REPEAT
74 #else /* ondio keys */
76 #define BUBBLES_LVLINC PLA_RIGHT
77 #define BUBBLES_LVLINC_REP PLA_RIGHT_REPEAT
78 #define BUBBLES_LVLDEC PLA_LEFT
79 #define BUBBLES_LVLDEC_REP PLA_LEFT_REPEAT
84 /* bubbles will consume height of ROW_HEIGHT*(BB_HEIGHT-1)+BUBBLE_HEIGHT*3/2 */
85 /* 22x22 bubbles (iPod Video) */
86 #if (LCD_HEIGHT == 240) && (LCD_WIDTH == 320)
87 #define BUBBLE_WIDTH 22
88 #define BUBBLE_HEIGHT 22
89 #define EMBLEM_WIDTH 16
90 #define EMBLEM_HEIGHT 16
96 /* 22x22 bubbles (Gigabeat) */
97 #elif (LCD_HEIGHT == 320) && (LCD_WIDTH == 240)
98 #define BUBBLE_WIDTH 22
99 #define BUBBLE_HEIGHT 22
100 #define EMBLEM_WIDTH 16
101 #define EMBLEM_HEIGHT 16
103 #define ROW_HEIGHT 18
104 #define ROW_INDENT 11
107 /* 16x16 bubbles (H300, iPod Color) */
108 #elif (LCD_HEIGHT == 176) && (LCD_WIDTH == 220)
109 #define BUBBLE_WIDTH 16
110 #define BUBBLE_HEIGHT 16
111 #define EMBLEM_WIDTH 12
112 #define EMBLEM_HEIGHT 12
114 #define ROW_HEIGHT 14
118 /* 16x16 bubbles (Sansa E200) */
119 #elif (LCD_HEIGHT == 220) && (LCD_WIDTH == 176)
120 #define BUBBLE_WIDTH 16
121 #define BUBBLE_HEIGHT 16
122 #define EMBLEM_WIDTH 12
123 #define EMBLEM_HEIGHT 12
125 #define ROW_HEIGHT 14
129 /* 12x12 bubbles (iPod Nano) */
130 #elif (LCD_HEIGHT == 132) && (LCD_WIDTH == 176)
131 #define BUBBLE_WIDTH 12
132 #define BUBBLE_HEIGHT 12
133 #define EMBLEM_WIDTH 8
134 #define EMBLEM_HEIGHT 8
136 #define ROW_HEIGHT 10
140 /* 12x12 bubbles (H100, H10, iAudio X5, iPod 3G, iPod 4G grayscale) */
141 #elif (LCD_HEIGHT == 128) && ((LCD_WIDTH == 160) || (LCD_WIDTH == 128))
142 #define BUBBLE_WIDTH 12
143 #define BUBBLE_HEIGHT 12
144 #define EMBLEM_WIDTH 8
145 #define EMBLEM_HEIGHT 8
147 #define ROW_HEIGHT 10
151 /* 10x10 bubbles (iPod Mini) */
152 #elif (LCD_HEIGHT == 110) && (LCD_WIDTH == 138)
153 #define BUBBLE_WIDTH 10
154 #define BUBBLE_HEIGHT 10
155 #define EMBLEM_WIDTH 6
156 #define EMBLEM_HEIGHT 6
162 /* 8x7 bubbles (Archos recorder, Ondio) */
163 #elif (LCD_HEIGHT == 64) && (LCD_WIDTH == 112)
164 #define BUBBLE_WIDTH 8
165 #define BUBBLE_HEIGHT 7
166 #define EMBLEM_WIDTH 7
167 #define EMBLEM_HEIGHT 5
174 #error BUBBLES: Unsupported LCD type
177 #define TEXT_LINES (LCD_HEIGHT/8)
180 #define SHOTX XOFS+ROW_INDENT+BUBBLE_WIDTH*3
181 #define SHOTY ROW_HEIGHT*(BB_HEIGHT-1)+BUBBLE_HEIGHT/2
183 /* collision distance squared */
184 #define MIN_DISTANCE ((BUBBLE_WIDTH*8)/10)*((BUBBLE_HEIGHT*8)/10)
186 /* external bitmaps */
187 extern const fb_data bubbles_bubble
[];
188 extern const fb_data bubbles_emblem
[];
189 #ifdef HAVE_LCD_COLOR
190 extern const fb_data bubbles_left
[];
191 /* skip right border for square screens */
192 #if (LCD_WIDTH > LCD_HEIGHT)
193 extern const fb_data bubbles_right
[];
197 /* global rockbox api */
198 static struct plugin_api
* rb
;
201 char level
[NUM_LEVELS
][BB_LEVEL_HEIGHT
][BB_WIDTH
] = {
202 {{ 6, 6, 4, 4, 2, 2, 3, 3},
203 { 6, 6, 4, 4, 2, 2, 3, -1},
204 { 2, 2, 3, 3, 6, 6, 4, 4},
205 { 2, 3, 3, 6, 6, 4, 4, -1},
206 {-1, -1, -1, -1, -1, -1, -1, -1},
207 {-1, -1, -1, -1, -1, -1, -1, -1},
208 {-1, -1, -1, -1, -1, -1, -1, -1},
209 {-1, -1, -1, -1, -1, -1, -1, -1},
210 {-1, -1, -1, -1, -1, -1, -1, -1},
211 {-1, -1, -1, -1, -1, -1, -1, -1}},
212 {{-1, 7, 7, 7, 7, 7, 7, -1},
213 {-1, 1, 1, 1, 1, 1, -1, -1},
214 {-1, -1, 2, 2, 2, 2, -1, -1},
215 {-1, -1, -1, 2, -1, -1, -1, -1},
216 {-1, -1, -1, 2, 2, -1, -1, -1},
217 {-1, -1, -1, 5, -1, -1, -1, -1},
218 {-1, -1, -1, 5, 5, -1, -1, -1},
219 {-1, -1, -1, -1, -1, -1, -1, -1},
220 {-1, -1, -1, -1, -1, -1, -1, -1},
221 {-1, -1, -1, -1, -1, -1, -1, -1}},
222 {{-1, -1, 7, -1, -1, 7, -1, -1},
223 {-1, -1, 7, 1, 7, -1, -1, -1},
224 {-1, -1, -1, 1, 2, -1, -1, -1},
225 {-1, -1, 1, 2, 1, -1, -1, -1},
226 {-1, -1, -1, 2, 5, -1, -1, -1},
227 {-1, -1, 3, 5, 3, -1, -1, -1},
228 {-1, -1, -1, 5, 3, -1, -1, -1},
229 {-1, -1, -1, 3, -1, -1, -1, -1},
230 {-1, -1, -1, -1, -1, -1, -1, -1},
231 {-1, -1, -1, -1, -1, -1, -1, -1}},
232 {{-1, -1, -1, 0, 0, -1, -1, -1},
233 {-1, -1, 5, 0, 1, -1, -1, -1},
234 {-1, -1, 3, 5, 1, 6, -1, -1},
235 {-1, 4, 3, -1, 6, 7, -1, -1},
236 {-1, 7, 4, -1, -1, 7, 4, -1},
237 { 6, 7, -1, -1, -1, 4, 3, -1},
238 { 1, 6, -1, -1, -1, -1, 3, 5},
239 { 1, -1, -1, -1, -1, -1, 5, -1},
240 {-1, -1, -1, -1, -1, -1, -1, -1},
241 {-1, -1, -1, -1, -1, -1, -1, -1}},
242 {{-1, -1, 0, 0, 0, 0, -1, -1},
243 {-1, 0, 1, 1, 1, 0, -1, -1},
244 {-1, 0, 1, 0, 0, 1, 0, -1},
245 {-1, 0, 1, 1, 1, 0, -1, -1},
246 {-1, -1, 0, 0, 0, 0, -1, -1},
247 {-1, -1, 7, -1, 7, -1, -1, -1},
248 {-1, -1, 7, 7, 7, 7, -1, -1},
249 {-1, -1, -1, -1, -1, -1, -1, -1},
250 {-1, -1, -1, -1, -1, -1, -1, -1},
251 {-1, -1, -1, -1, -1, -1, -1, -1}},
252 {{-1, 4, 4, 4, 6, 6, 6, -1},
253 { 4, -1, -1, -1, -1, -1, 6, -1},
254 {-1, 4, -1, -1, -1, -1, 6, -1},
255 { 4, 2, 3, 1, 2, 3, 6, -1},
256 {-1, 3, 1, 2, 3, 1, 2, -1},
257 {-1, -1, -1, -1, -1, -1, -1, -1},
258 {-1, -1, -1, -1, -1, -1, -1, -1},
259 {-1, -1, -1, -1, -1, -1, -1, -1},
260 {-1, -1, -1, -1, -1, -1, -1, -1},
261 {-1, -1, -1, -1, -1, -1, -1, -1}},
262 {{-1, 4, 4, 4, 6, 6, 6, -1},
263 { 4, -1, -1, -1, -1, -1, 6, -1},
264 {-1, 4, -1, -1, -1, -1, 6, -1},
265 { 4, 2, 3, 1, 2, 3, 6, -1},
266 {-1, 3, 1, 2, 3, 1, 2, -1},
267 {-1, 2, 3, 1, 2, 3, -1, -1},
268 {-1, -1, -1, -1, -1, -1, -1, -1},
269 {-1, -1, -1, -1, -1, -1, -1, -1},
270 {-1, -1, -1, -1, -1, -1, -1, -1},
271 {-1, -1, -1, -1, -1, -1, -1, -1}},
272 {{-1, 0, 0, -1, -1, 2, 2, -1},
273 {-1, 5, -1, -1, -1, 3, -1, -1},
274 {-1, 0, -1, -1, -1, 6, -1, -1},
275 {-1, 3, -1, -1, -1, 0, -1, -1},
276 {-1, 4, -1, -1, -1, 5, -1, -1},
277 {-1, 2, -1, -1, -1, 3, -1, -1},
278 {-1, 2, -1, -1, -1, 1, -1, -1},
279 {-1, 3, -1, -1, -1, 4, -1, -1},
280 {-1, -1, -1, -1, -1, -1, -1, -1},
281 {-1, -1, -1, -1, -1, -1, -1, -1}},
282 {{ 3, -1, -1, -1, -1, -1, -1, 3},
283 { 6, 3, 2, 4, 6, 3, 2, -1},
284 { 4, -1, -1, -1, -1, -1, -1, 4},
285 { 2, 4, 6, 3, 2, 4, 6, -1},
286 {-1, -1, -1, 6, -1, -1, -1, -1},
287 {-1, -1, -1, 3, -1, -1, -1, -1},
288 {-1, -1, -1, -1, -1, -1, -1, -1},
289 {-1, -1, -1, -1, -1, -1, -1, -1},
290 {-1, -1, -1, -1, -1, -1, -1, -1},
291 {-1, -1, -1, -1, -1, -1, -1, -1}},
292 {{-1, 2, -1, 1, -1, 1, -1, 2},
293 { 1, 2, -1, 2, 1, -1, 1, -1},
294 { 1, -1, 1, -1, 2, -1, 2, -1},
295 { 2, 1, -1, 1, 2, -1, 2, -1},
296 {-1, 2, -1, 2, -1, 2, -1, 2},
297 { 1, 2, -1, 2, 1, -1, 1, -1},
298 { 1, -1, 1, -1, 2, -1, 1, -1},
299 { 2, 2, -1, 1, 1, -1, 2, -1},
300 {-1, 2, -1, 1, -1, 1, -1, 1},
301 {-1, -1, -1, -1, -1, -1, -1, -1}},
302 {{-1, 7, 7, -1, -1, 5, 5, -1},
303 { 1, -1, -1, -1, -1, -1, 4, -1},
304 { 2, 1, -1, -1, -1, -1, 4, 3},
305 { 2, -1, -1, -1, -1, -1, 3, -1},
306 { 1, 2, -1, -1, -1, -1, 3, 4},
307 { 1, -1, -1, -1, -1, -1, 4, -1},
308 { 7, 1, -1, -1, -1, -1, 4, 5},
309 { 7, 7, -1, -1, -1, 5, 5, -1},
310 {-1, -1, -1, -1, -1, -1, -1, -1},
311 {-1, -1, -1, -1, -1, -1, -1, -1}},
312 {{ 7, 7, -1, -1, -1, -1, 5, 5},
313 { 1, 5, -1, -1, -1, 7, 4, -1},
314 { 2, 1, -1, -1, -1, -1, 4, 3},
315 { 2, -1, -1, -1, -1, -1, 3, -1},
316 { 1, 5, -1, -1, -1, -1, 7, 4},
317 { 1, -1, -1, -1, -1, -1, 4, -1},
318 { 7, 1, -1, -1, -1, -1, 4, 5},
319 { 7, 5, -1, -1, -1, 7, 5, -1},
320 {-1, -1, -1, -1, -1, -1, -1, -1},
321 {-1, -1, -1, -1, -1, -1, -1, -1}},
322 {{-1, -1, -1, 0, 0, -1, -1, -1},
323 {-1, -1, 5, 0, 1, -1, -1, -1},
324 {-1, -1, 3, 5, 1, 6, -1, -1},
325 {-1, 4, 3, 2, 6, 2, -1, -1},
326 {-1, 7, 4, 7, 2, 2, 4, -1},
327 { 6, 7, 7, 3, 3, 4, 3, -1},
328 { 1, 6, 1, 1, 1, 3, 3, 5},
329 { 1, 1, -1, -1, -1, -1, 5, -1},
330 {-1, -1, -1, -1, -1, -1, -1, -1},
331 {-1, -1, -1, -1, -1, -1, -1, -1}},
332 {{-1, -1, 0, -1, -1, 0, -1, -1},
333 {-1, 3, 3, -1, 3, 3, -1, -1},
334 {-1, 0, 2, 0, 0, 2, 0, -1},
335 {-1, 3, 3, -1, 3, 3, -1, -1},
336 {-1, -1, 0, -1, -1, 0, -1, -1},
337 {-1, -1, -1, -1, -1, -1, -1, -1},
338 {-1, -1, -1, -1, -1, -1, -1, -1},
339 {-1, -1, -1, -1, -1, -1, -1, -1},
340 {-1, -1, -1, -1, -1, -1, -1, -1},
341 {-1, -1, -1, -1, -1, -1, -1, -1}},
342 {{-1, -1, -1, 1, 1, -1, -1, -1},
343 {-1, -1, 2, 2, 2, -1, -1, -1},
344 {-1, -1, 3, 3, 3, 3, -1, -1},
345 {-1, 4, 4, 4, 4, 4, -1, -1},
346 {-1, 5, 5, 5, 5, 5, 5, -1},
347 {-1, -1, -1, 6, -1, -1, -1, -1},
348 {-1, -1, -1, 7, 7, -1, -1, -1},
349 {-1, -1, -1, 0, -1, -1, -1, -1},
350 {-1, -1, -1, -1, -1, -1, -1, -1},
351 {-1, -1, -1, -1, -1, -1, -1, -1}},
352 {{-1, -1, -1, 2, 5, -1, -1, -1},
353 {-1, 4, 3, -1, -1, -1, -1, -1},
354 { 6, 7, -1, 5, 2, -1, -1, -1},
355 {-1, -1, -1, -1, 3, 4, -1, -1},
356 {-1, -1, -1, 2, 5, -1, 7, 6},
357 {-1, 4, 3, -1, -1, -1, -1, -1},
358 { 6, 7, -1, 5, 2, -1, -1, -1},
359 {-1, -1, -1, -1, 3, 4, -1, -1},
360 {-1, -1, -1, -1, -1, -1, 7, 6},
361 {-1, -1, -1, -1, -1, -1, -1, -1}},
362 {{-1, -1, -1, 5, 5, -1, -1, -1},
363 {-1, -1, -1, 3, -1, -1, -1, -1},
364 {-1, -1, -1, 1, -1, -1, -1, -1},
365 {-1, -1, -1, 7, -1, -1, -1, -1},
366 {-1, -1, -1, 2, -1, -1, -1, -1},
367 {-1, -1, -1, 4, -1, -1, -1, -1},
368 {-1, -1, -1, 5, -1, -1, -1, -1},
369 {-1, -1, -1, 3, -1, -1, -1, -1},
370 {-1, -1, -1, -1, -1, -1, -1, -1},
371 {-1, -1, -1, -1, -1, -1, -1, -1}},
372 {{-1, -1, -1, 0, 1, -1, -1, -1},
373 {-1, -1, 0, 2, 7, 7, -1, -1},
374 {-1, -1, -1, 0, 1, 7, -1, -1},
375 {-1, 0, 0, 0, 0, -1, -1, -1},
376 {-1, 0, 0, 0, 1, 1, -1, -1},
377 { 0, 0, 0, 1, 1, 1, -1, -1},
378 {-1, 0, 0, 1, 1, 1, -1, -1},
379 {-1, 0, 0, 0, 7, 7, -1, -1},
380 {-1, -1, 7, 7, -1, -1, -1, -1},
381 {-1, -1, -1, -1, -1, -1, -1, -1}},
382 {{-1, 1, -1, -1, -1, -1, -1, -1},
383 { 1, -1, -1, -1, -1, -1, -1, -1},
384 {-1, 2, 3, 4, 7, 6, 5, -1},
385 {-1, -1, -1, -1, -1, -1, 1, -1},
386 {-1, -1, -1, -1, -1, -1, 1, -1},
387 {-1, 2, 3, 4, 7, 6, -1, -1},
388 {-1, 1, -1, -1, -1, -1, -1, -1},
389 { 1, -1, -1, -1, -1, -1, -1, -1},
390 {-1, 2, 3, 4, 7, 6, 5, -1},
391 {-1, -1, -1, -1, -1, -1, -1, -1}},
392 {{-1, 6, -1, -1, -1, -1, -1, -1},
393 { 5, -1, -1, -1, -1, -1, -1, -1},
394 { 2, 3, 4, 7, 6, 5, 2, 3},
395 {-1, -1, -1, -1, -1, -1, 4, -1},
396 {-1, -1, -1, -1, -1, -1, 7, -1},
397 {-1, 4, 3, 2, 5, 6, -1, -1},
398 {-1, 7, -1, -1, -1, -1, -1, -1},
399 { 6, -1, -1, -1, -1, -1, -1, -1},
400 { 5, 2, 3, 4, 7, 6, 5, -1},
401 {-1, -1, -1, -1, -1, -1, -1, -1}},
402 {{ 3, 2, 1, 0, 0, 1, 2, 3},
403 { 3, 2, 1, 0, 1, 2, 3, -1},
404 { 4, 3, 2, 1, 1, 2, 3, 4},
405 { 4, 3, 2, 1, 2, 3, 4, -1},
406 { 5, 4, 3, 2, 2, 3, 4, 5},
407 { 5, 4, 3, 2, 3, 4, 5, -1},
408 { 6, 5, 4, 3, 3, 4, 5, 6},
409 { 6, 5, 4, 3, 4, 5, 6, -1},
410 { 7, 6, 5, 4, 4, 5, 6, 7},
411 {-1, -1, -1, -1, -1, -1, -1, -1}},
412 {{-1, -1, -1, 5, 5, -1, -1, -1},
413 {-1, -1, -1, 3, -1, -1, -1, -1},
414 {-1, -1, -1, 2, 4, -1, -1, -1},
415 {-1, -1, -1, 6, -1, -1, -1, -1},
416 {-1, -1, -1, 2, 4, -1, -1, -1},
417 {-1, 2, -1, 5, -1, 4, -1, -1},
418 { 1, 0, 1, 0, 1, 0, 1, 0},
419 { 3, -1, 3, -1, 2, -1, 6, -1},
420 {-1, -1, -1, -1, -1, -1, -1, -1},
421 {-1, -1, -1, -1, -1, -1, -1, -1}},
422 {{-1, -1, -1, -1, 1, -1, -1, -1},
423 { 7, 4, 3, 5, -1, -1, -1, -1},
424 { 6, -1, -1, 1, -1, -1, -1, -1},
425 {-1, -1, -1, 5, 3, 4, 7, -1},
426 { 6, -1, -1, -1, 1, -1, -1, 6},
427 { 7, 4, 3, 5, -1, -1, -1, -1},
428 {-1, -1, -1, 1, -1, -1, -1, 6},
429 {-1, -1, -1, 5, 3, 4, 7, -1},
430 {-1, -1, -1, -1, -1, -1, -1, -1},
431 {-1, -1, -1, -1, -1, -1, -1, -1}},
432 {{-1, -1, -1, -1, 7, 3, 6, -1},
433 {-1, -1, 3, 7, 3, 6, 3, -1},
434 {-1, -1, 5, 7, 3, 6, 3, -1},
435 {-1, 6, 7, 3, 6, 7, -1, -1},
436 {-1, 7, 7, 3, 6, 1, -1, -1},
437 { 3, 7, 3, 6, 3, -1, -1, -1},
438 { 5, 6, 2, 7, 1, -1, -1, -1},
439 {-1, -1, -1, -1, -1, -1, -1, -1},
440 {-1, -1, -1, -1, -1, -1, -1, -1},
441 {-1, -1, -1, -1, -1, -1, -1, -1}},
442 {{ 5, -1, -1, -1, -1, -1, -1, 5},
443 { 5, -1, 6, 6, 6, -1, 5, -1},
444 {-1, 5, 4, -1, -1, 4, 5, -1},
445 {-1, 3, -1, -1, -1, 3, -1, -1},
446 {-1, 6, 0, -1, -1, 0, 6, -1},
447 {-1, 3, -1, -1, -1, 3, -1, -1},
448 {-1, -1, 4, -1, -1, 4, -1, -1},
449 {-1, -1, 6, 6, 6, -1, -1, -1},
450 {-1, -1, -1, -1, -1, -1, -1, -1},
451 {-1, -1, -1, -1, -1, -1, -1, -1}},
452 {{-1, 7, 0, -1, -1, 0, 7, -1},
453 { 7, -1, 0, -1, 0, -1, 7, -1},
454 { 7, 1, -1, 0, 0, -1, 1, 7},
455 { 7, 1, 2, 0, 2, 1, 7, -1},
456 { 7, 6, 3, 2, 2, 3, 6, 7},
457 { 7, -1, 3, 2, 3, -1, 7, -1},
458 {-1, 7, 7, 3, 3, 7, 7, -1},
459 {-1, -1, -1, 3, -1, -1, -1, -1},
460 {-1, -1, -1, -1, -1, -1, -1, -1},
461 {-1, -1, -1, -1, -1, -1, -1, -1}},
462 {{-1, 3, -1, 1, -1, 7, -1, 6},
463 { 5, -1, 7, -1, 7, -1, 6, -1},
464 { 6, -1, 0, -1, 5, -1, 3, -1},
465 {-1, 2, -1, 1, -1, 5, -1, -1},
466 {-1, 4, -1, 3, -1, 4, -1, -1},
467 { 2, -1, 3, -1, 2, -1, -1, -1},
468 {-1, -1, 4, -1, 6, -1, -1, -1},
469 {-1, -1, -1, 5, -1, -1, -1, -1},
470 {-1, -1, -1, -1, -1, -1, -1, -1},
471 {-1, -1, -1, -1, -1, -1, -1, -1}},
472 {{-1, -1, -1, -1, 1, -1, -1, -1},
473 {-1, -1, -1, -1, 3, -1, -1, -1},
474 { 6, 1, 3, 1, 2, 1, 4, 1},
475 {-1, -1, -1, -1, 6, -1, -1, -1},
476 {-1, -1, -1, 4, 1, -1, -1, -1},
477 {-1, -1, 1, -1, 3, -1, -1, -1},
478 {-1, -1, -1, 2, 1, -1, -1, -1},
479 {-1, -1, -1, -1, 4, -1, -1, -1},
480 {-1, -1, -1, 6, 1, -1, -1, -1},
481 {-1, -1, -1, 6, -1, -1, -1, -1}},
482 {{-1, -1, -1, 5, 4, -1, -1, -1},
483 {-1, -1, 4, 1, 0, -1, -1, -1},
484 {-1, -1, -1, 2, 3, -1, -1, -1},
485 {-1, 1, 4, -1, 2, 2, -1, -1},
486 {-1, 3, 1, 2, 5, 1, 4, -1},
487 {-1, 4, 2, -1, 0, 4, -1, -1},
488 {-1, -1, -1, -1, -1, -1, -1, -1},
489 {-1, -1, -1, -1, -1, -1, -1, -1},
490 {-1, -1, -1, -1, -1, -1, -1, -1},
491 {-1, -1, -1, -1, -1, -1, -1, -1}},
492 {{-1, -1, -1, -1, 1, -1, -1, -1},
493 {-1, -1, -1, 1, -1, -1, -1, -1},
494 {-1, 2, -1, -1, 1, -1, 5, -1},
495 { 5, -1, -1, 1, -1, -1, 0, -1},
496 {-1, 6, -1, -1, 1, -1, 4, -1},
497 {-1, 0, -1, 1, -1, 5, -1, -1},
498 {-1, -1, 5, 5, 0, 1, -1, -1},
499 {-1, -1, -1, -1, -1, -1, -1, -1},
500 {-1, -1, -1, -1, -1, -1, -1, -1},
501 {-1, -1, -1, -1, -1, -1, -1, -1}},
502 {{-1, -1, -1, 6, 3, -1, -1, -1},
503 {-1, -1, 3, 2, 6, -1, -1, -1},
504 {-1, -1, 2, 6, 3, 2, -1, -1},
505 {-1, 6, 3, 2, 6, 3, -1, -1},
506 {-1, 3, 2, 6, 3, 2, 6, -1},
507 { 2, 6, 3, 2, 6, 3, 2, -1},
508 { 6, 3, 2, 6, 3, 2, 6, 3},
509 {-1, -1, -1, -1, -1, -1, -1, -1},
510 {-1, -1, -1, -1, -1, -1, -1, -1},
511 {-1, -1, -1, -1, -1, -1, -1, -1}},
512 {{ 6, 6, 6, 6, 6, 6, 6, 6},
513 { 4, -1, -1, -1, -1, -1, -1, -1},
514 {-1, 3, 2, 5, 7, 6, 4, 3},
515 {-1, 5, -1, -1, -1, -1, -1, -1},
516 {-1, -1, 7, 6, 4, 3, 2, 5},
517 {-1, -1, 4, -1, -1, -1, -1, -1},
518 {-1, -1, -1, 3, 2, 5, 7, 6},
519 {-1, -1, -1, -1, -1, -1, -1, -1},
520 {-1, -1, -1, -1, -1, -1, -1, -1},
521 {-1, -1, -1, -1, -1, -1, -1, -1}},
522 {{ 1, -1, 7, -1, -1, 6, -1, 2},
523 { 6, -1, 1, -1, 6, 1, 3, -1},
524 {-1, 4, -1, 7, 2, -1, 7, -1},
525 { 2, 7, -1, -1, -1, 4, -1, -1},
526 { 6, -1, 3, 5, 0, 2, -1, 7},
527 { 1, -1, -1, -1, -1, -1, 1, -1},
528 {-1, 1, 4, 5, 7, 5, 1, -1},
529 {-1, -1, -1, -1, -1, -1, -1, -1},
530 {-1, -1, -1, -1, -1, -1, -1, -1},
531 {-1, -1, -1, -1, -1, -1, -1, -1}},
532 {{ 6, 6, 6, -1, -1, 6, 6, 6},
533 {-1, -1, 6, -1, 6, -1, -1, -1},
534 {-1, -1, 2, 3, 3, 2, -1, -1},
535 {-1, 3, -1, 5, -1, 3, -1, -1},
536 {-1, -1, 5, 3, 3, 5, -1, -1},
537 {-1, -1, 6, 1, 6, -1, -1, -1},
538 {-1, 4, 2, -1, -1, 2, 4, -1},
539 {-1, -1, -1, -1, -1, -1, -1, -1},
540 {-1, -1, -1, -1, -1, -1, -1, -1},
541 {-1, -1, -1, -1, -1, -1, -1, -1}},
542 {{-1, -1, -1, 5, 5, -1, -1, -1},
543 {-1, -1, 5, -1, -1, -1, -1, -1},
544 {-1, 3, 4, 6, 6, -1, -1, 5},
545 { 3, 3, 4, 6, 5, -1, 5, -1},
546 { 3, 2, 3, 6, 6, 5, 5, -1},
547 { 3, 3, 4, 6, 5, -1, 5, -1},
548 {-1, 3, 4, 6, 6, -1, -1, 5},
549 {-1, -1, 5, -1, -1, -1, -1, -1},
550 {-1, -1, -1, 5, 5, -1, -1, -1},
551 {-1, -1, -1, -1, -1, -1, -1, -1}},
552 {{ 1, -1, -1, -1, -1, -1, -1, 1},
553 { 1, -1, 2, 2, 2, -1, 1, -1},
554 {-1, 1, 2, 3, 3, 2, 1, -1},
555 { 6, 2, 3, -1, 3, 2, 6, -1},
556 { 6, 2, 3, -1, -1, 3, 2, 6},
557 { 6, 2, 3, -1, 3, 2, 6, -1},
558 { 3, 3, 3, 7, 7, 3, 3, 3},
559 { 0, 5, 0, 2, 0, 5, 0, -1},
560 {-1, -1, -1, -1, -1, -1, -1, -1},
561 {-1, -1, -1, -1, -1, -1, -1, -1}},
562 {{-1, -1, 7, 7, 7, -1, -1, -1},
563 {-1, 7, 2, 2, 7, -1, -1, -1},
564 {-1, 7, 5, 5, 5, 7, -1, -1},
565 { 7, 7, 7, 7, 7, 7, -1, -1},
566 {-1, -1, 6, -1, 6, -1, -1, -1},
567 {-1, 6, -1, -1, 6, -1, -1, -1},
568 {-1, 6, 4, 4, -1, 6, 4, 4},
569 {-1, -1, -1, -1, -1, -1, -1, -1},
570 {-1, -1, -1, -1, -1, -1, -1, -1},
571 {-1, -1, -1, -1, -1, -1, -1, -1}},
572 {{-1, 3, 3, -1, 3, 3, 3, -1},
573 { 3, 7, 5, 4, 6, 5, 3, -1},
574 { 1, 3, 3, 3, -1, 3, 3, 1},
575 { 2, 1, 2, 1, 2, 1, 2, -1},
576 { 1, 3, 3, -1, 3, 3, 3, 1},
577 { 3, 5, 6, 4, 5, 7, 3, -1},
578 { 2, 3, 3, 3, -1, 3, 3, 2},
579 { 1, 1, 2, 2, 2, 1, 1, -1},
580 {-1, -1, -1, -1, -1, -1, -1, -1},
581 {-1, -1, -1, -1, -1, -1, -1, -1}},
582 {{-1, 6, 5, -1, -1, -1, -1, -1},
583 { 3, 1, 3, -1, -1, -1, -1, -1},
584 {-1, 5, 6, -1, -1, -1, -1, -1},
585 {-1, -1, 5, 3, -1, -1, -1, -1},
586 {-1, -1, 6, 1, 6, -1, -1, -1},
587 {-1, -1, 3, 5, -1, -1, -1, -1},
588 {-1, -1, -1, -1, 3, 6, -1, -1},
589 {-1, -1, -1, 5, 6, 5, -1, -1},
590 {-1, -1, -1, -1, 6, 3, -1, -1},
591 {-1, -1, -1, -1, -1, -1, -1, -1}},
592 {{ 6, 3, 7, 4, 5, 1, 6, 3},
593 { 5, 1, 6, 3, 7, 4, 5, -1},
594 { 6, 3, 7, 4, 5, 1, 6, 3},
595 {-1, -1, -1, -1, -1, -1, -1, -1},
596 {-1, -1, -1, -1, -1, -1, -1, -1},
597 {-1, -1, -1, -1, -1, -1, -1, -1},
598 {-1, -1, -1, -1, -1, -1, -1, -1},
599 {-1, -1, -1, -1, -1, -1, -1, -1},
600 {-1, -1, -1, -1, -1, -1, -1, -1},
601 {-1, -1, -1, -1, -1, -1, -1, -1}},
602 {{-1, -1, -1, -1, -1, -1, 4, 4},
603 {-1, -1, 7, 7, 7, 4, 4, -1},
604 {-1, -1, -1, -1, -1, -1, 4, 4},
605 {-1, 1, -1, -1, -1, 7, -1, -1},
606 {-1, 1, 1, -1, -1, 7, -1, -1},
607 { 3, 3, 3, -1, 7, -1, -1, -1},
608 { 3, -1, 2, 3, 3, 3, -1, 3},
609 {-1, 2, -1, 3, -1, 3, 3, -1},
610 {-1, 2, -1, -1, -1, -1, -1, -1},
611 {-1, -1, -1, -1, -1, -1, -1, -1}},
612 {{-1, -1, 4, -1, -1, -1, -1, -1},
613 {-1, 7, 4, -1, -1, -1, -1, -1},
614 {-1, -1, 7, 4, -1, -1, -1, -1},
615 {-1, 4, 7, 4, -1, -1, -1, -1},
616 { 1, 1, 1, 1, 1, 1, 1, -1},
617 { 1, 2, 1, 2, 1, 1, -1, -1},
618 { 2, 2, 2, 2, 2, 2, 2, 2},
619 {-1, -1, -1, -1, -1, -1, -1, -1},
620 {-1, -1, -1, -1, -1, -1, -1, -1},
621 {-1, -1, -1, -1, -1, -1, -1, -1}},
622 {{ 0, -1, -1, -1, -1, -1, -1, 6},
623 { 6, 1, 4, 3, 7, 5, 0, -1},
624 { 0, -1, -1, -1, -1, -1, -1, 6},
625 { 6, 1, 4, 3, 7, 5, 0, -1},
626 { 0, -1, -1, -1, -1, -1, -1, 6},
627 { 6, 1, 4, 3, 7, 5, 0, -1},
628 {-1, -1, -1, -1, -1, -1, -1, -1},
629 {-1, -1, -1, -1, -1, -1, -1, -1},
630 {-1, -1, -1, -1, -1, -1, -1, -1},
631 {-1, -1, -1, -1, -1, -1, -1, -1}},
632 {{ 3, 3, 4, 6, 6, 4, 3, 3},
633 { 0, 3, 4, 6, 4, 3, 1, -1},
634 { 5, 1, 3, 4, 4, 3, 0, 1},
635 { 0, 1, 3, 4, 3, 1, 0, -1},
636 { 2, 1, 6, 3, 3, 0, 0, 1},
637 { 0, 3, 4, 3, 6, 1, 5, -1},
638 { 6, 1, 2, 6, 4, 0, 0, 2},
639 {-1, -1, -1, -1, -1, -1, -1, -1},
640 {-1, -1, -1, -1, -1, -1, -1, -1},
641 {-1, -1, -1, -1, -1, -1, -1, -1}},
642 {{ 6, 6, -1, -1, -1, -1, 4, 4},
643 { 4, 0, -1, -1, -1, 3, 6, -1},
644 { 0, 6, -1, -1, -1, -1, 4, 2},
645 { 7, -1, -1, -1, -1, -1, 7, -1},
646 { 4, 4, -1, -1, -1, -1, 5, 6},
647 { 6, 4, 7, 7, 5, 6, 4, -1},
648 {-1, 7, 6, 4, 6, 4, 7, -1},
649 {-1, 0, -1, 7, -1, 7, -1, -1},
650 {-1, -1, -1, -1, -1, -1, -1, -1},
651 {-1, -1, -1, -1, -1, -1, -1, -1}},
652 {{-1, 5, -1, -1, -1, -1, 4, -1},
653 {-1, 5, -1, -1, -1, 4, -1, -1},
654 {-1, -1, 5, 6, 6, 4, -1, -1},
655 {-1, -1, 2, -1, 2, -1, -1, -1},
656 { 0, 0, 6, -1, -1, 6, 1, 1},
657 {-1, -1, 2, -1, 2, -1, -1, -1},
658 {-1, -1, 7, 6, 6, 3, -1, -1},
659 {-1, 7, -1, -1, -1, 3, -1, -1},
660 {-1, 7, -1, -1, -1, -1, 3, -1},
661 {-1, -1, -1, -1, -1, -1, -1, -1}},
662 {{-1, 6, -1, -1, -1, -1, 2, -1},
663 { 1, 7, 1, 1, 1, 3, 1, -1},
664 {-1, -1, 4, 1, 1, 4, -1, -1},
665 {-1, 1, 3, 1, 7, 1, -1, -1},
666 {-1, -1, -1, 2, 6, -1, -1, -1},
667 {-1, -1, 1, 5, 1, -1, -1, -1},
668 {-1, -1, -1, -1, -1, -1, -1, -1},
669 {-1, -1, -1, -1, -1, -1, -1, -1},
670 {-1, -1, -1, -1, -1, -1, -1, -1},
671 {-1, -1, -1, -1, -1, -1, -1, -1}},
672 {{ 7, 7, 7, 7, 7, 7, 7, 7},
673 { 7, -1, -1, -1, -1, -1, 7, -1},
674 { 7, -1, -1, 2, 0, 5, 2, 2},
675 { 7, -1, -1, -1, 0, 3, 6, -1},
676 { 7, -1, -1, -1, -1, -1, 4, 0},
677 { 5, 5, -1, -1, -1, -1, -1, -1},
678 { 4, 3, 6, 2, -1, -1, -1, -1},
679 { 0, 2, 0, 4, -1, -1, -1, -1},
680 {-1, -1, -1, -1, -1, -1, -1, -1},
681 {-1, -1, -1, -1, -1, -1, -1, -1}},
682 {{-1, -1, 1, -1, -1, 1, -1, -1},
683 {-1, 4, -1, -1, 5, -1, -1, -1},
684 {-1, 7, -1, -1, 1, 1, 1, -1},
685 { 6, -1, -1, -1, -1, 7, -1, -1},
686 { 1, 1, 1, 1, -1, 4, -1, -1},
687 {-1, -1, 5, -1, -1, -1, -1, -1},
688 {-1, -1, 0, -1, -1, -1, -1, -1},
689 {-1, 3, -1, -1, -1, -1, -1, -1},
690 {-1, 1, -1, -1, -1, -1, -1, -1},
691 {-1, -1, -1, -1, -1, -1, -1, -1}},
692 {{-1, 7, 7, -1, -1, 7, 7, -1},
693 { 6, -1, 4, -1, 4, -1, 6, -1},
694 { 5, -1, -1, 3, 3, -1, -1, 5},
695 { 6, -1, -1, -1, -1, -1, 6, -1},
696 {-1, 7, -1, -1, -1, -1, 7, -1},
697 {-1, 4, -1, -1, -1, 4, -1, -1},
698 {-1, -1, 3, -1, -1, 3, -1, -1},
699 {-1, -1, 2, -1, 2, -1, -1, -1},
700 {-1, -1, -1, 5, 5, -1, -1, -1},
701 {-1, -1, -1, -1, -1, -1, -1, -1}},
702 {{-1, 0, 0, -1, -1, 0, 0, -1},
703 { 7, 4, 6, 6, 6, 4, 3, -1},
704 { 5, 6, 6, 6, 2, 6, 6, 3},
705 { 7, 4, 6, 6, 6, 4, 3, -1},
706 {-1, 0, 0, -1, -1, 0, 0, -1},
707 {-1, -1, -1, -1, -1, -1, -1, -1},
708 {-1, -1, -1, -1, -1, -1, -1, -1},
709 {-1, -1, -1, -1, -1, -1, -1, -1},
710 {-1, -1, -1, -1, -1, -1, -1, -1},
711 {-1, -1, -1, -1, -1, -1, -1, -1}},
712 {{-1, -1, -1, -1, -1, 7, 7, 7},
713 {-1, -1, -1, -1, 2, 7, 7, -1},
714 {-1, 0, 7, 7, 7, -1, 7, 7},
715 { 6, 7, 7, 7, -1, -1, -1, -1},
716 { 6, -1, -1, -1, 7, 7, 7, 7},
717 { 6, -1, -1, -1, -1, -1, -1, -1},
718 { 4, 2, 2, 2, 4, -1, 3, -1},
719 { 4, 4, 4, 4, 3, 3, 3, -1},
720 {-1, -1, -1, -1, -1, -1, -1, -1},
721 {-1, -1, -1, -1, -1, -1, -1, -1}},
722 {{ 4, -1, -1, 7, -1, 6, -1, 7},
723 { 7, 6, 7, -1, -1, 7, 4, -1},
724 {-1, -1, 7, -1, -1, 7, -1, -1},
725 {-1, 0, 0, 0, 0, 0, 3, -1},
726 {-1, -1, 0, 2, 2, 0, 6, 4},
727 {-1, -1, 0, 0, 0, 1, 3, -1},
728 {-1, -1, -1, 0, 0, -1, 3, 4},
729 {-1, -1, -1, 6, -1, 5, 6, -1},
730 {-1, -1, -1, -1, -1, -1, 1, 0},
731 {-1, -1, -1, -1, -1, -1, -1, -1}},
732 {{-1, 5, -1, -1, -1, -1, 5, -1},
733 { 0, -1, -1, 0, -1, -1, 0, -1},
734 { 0, 0, 0, 2, 2, 0, 0, 0},
735 { 0, -1, -1, 0, -1, -1, 0, -1},
736 {-1, 7, -1, 3, -1, -1, 7, -1},
737 {-1, -1, 3, 6, -1, -1, -1, -1},
738 {-1, -1, -1, 6, -1, -1, -1, -1},
739 {-1, 3, 6, -1, -1, -1, -1, -1},
740 {-1, 3, -1, -1, -1, -1, -1, -1},
741 {-1, -1, -1, -1, -1, -1, -1, -1}},
742 {{-1, -1, -1, 6, 5, -1, -1, -1},
743 {-1, -1, 2, 6, 3, -1, -1, -1},
744 {-1, -1, 5, 4, 7, 1, -1, -1},
745 {-1, 6, 2, 2, 3, 4, -1, -1},
746 {-1, -1, 3, 7, 3, 6, -1, -1},
747 {-1, -1, 1, 3, 2, -1, -1, -1},
748 {-1, -1, -1, 4, 5, -1, -1, -1},
749 {-1, -1, -1, 4, -1, -1, -1, -1},
750 {-1, -1, -1, -1, -1, -1, -1, -1},
751 {-1, -1, -1, -1, -1, -1, -1, -1}},
752 {{ 7, 7, -1, 2, 2, -1, 6, 6},
753 { 6, -1, -1, 6, -1, -1, 3, -1},
754 { 2, -1, -1, 1, -1, -1, 2, -1},
755 { 5, -1, -1, 3, -1, -1, 2, -1},
756 { 1, -1, -1, 2, -1, -1, 1, -1},
757 { 5, -1, -1, 2, -1, -1, 2, -1},
758 { 6, -1, -1, 1, -1, -1, 7, -1},
759 { 5, -1, -1, 5, -1, -1, 4, -1},
760 {-1, -1, -1, -1, -1, -1, -1, -1},
761 {-1, -1, -1, -1, -1, -1, -1, -1}},
762 {{-1, -1, -1, 6, 6, -1, -1, -1},
763 {-1, 0, 4, 4, 4, 0, -1, -1},
764 {-1, -1, -1, 6, 6, -1, -1, -1},
765 {-1, -1, 2, 7, 2, -1, -1, -1},
766 {-1, -1, -1, 6, 6, -1, -1, -1},
767 {-1, 0, 5, 5, 5, 0, -1, -1},
768 {-1, -1, -1, 3, 3, -1, -1, -1},
769 {-1, -1, -1, -1, -1, -1, -1, -1},
770 {-1, -1, -1, -1, -1, -1, -1, -1},
771 {-1, -1, -1, -1, -1, -1, -1, -1}},
772 {{-1, -1, 4, 1, 3, -1, -1, -1},
773 {-1, 1, -1, -1, 1, -1, -1, -1},
774 {-1, -1, 4, 1, 3, 4, 1, -1},
775 {-1, 1, 3, 4, -1, -1, 4, -1},
776 {-1, 3, -1, -1, 3, 4, 1, -1},
777 {-1, 1, 3, 4, 1, 3, -1, -1},
778 {-1, -1, 4, 1, -1, -1, -1, -1},
779 {-1, -1, -1, -1, -1, -1, -1, -1},
780 {-1, -1, -1, -1, -1, -1, -1, -1},
781 {-1, -1, -1, -1, -1, -1, -1, -1}},
782 {{-1, 6, 4, -1, 3, 2, 5, -1},
783 { 0, -1, -1, -1, -1, -1, 1, -1},
784 {-1, 2, 3, 5, -1, 4, 6, -1},
785 { 0, -1, -1, -1, -1, -1, 1, -1},
786 {-1, 4, 6, -1, 2, 5, 3, -1},
787 { 0, -1, -1, -1, -1, -1, 1, -1},
788 {-1, 5, 2, 3, -1, 4, 6, -1},
789 {-1, -1, -1, -1, -1, -1, -1, -1},
790 {-1, -1, -1, -1, -1, -1, -1, -1},
791 {-1, -1, -1, -1, -1, -1, -1, -1}},
792 {{-1, -1, -1, 6, 6, -1, -1, -1},
793 {-1, -1, 7, 6, 4, -1, -1, -1},
794 {-1, 2, 1, 7, 4, 1, 3, -1},
795 { 2, 1, 1, 1, 1, 1, 3, -1},
796 {-1, 2, 2, 2, 3, 3, 3, -1},
797 {-1, -1, -1, 5, -1, -1, -1, -1},
798 {-1, -1, -1, 2, 3, -1, -1, -1},
799 {-1, -1, -1, 5, -1, -1, -1, -1},
800 {-1, -1, 2, 2, 3, 3, -1, -1},
801 {-1, -1, -1, -1, -1, -1, -1, -1}},
802 {{ 4, -1, 5, -1, -1, 3, -1, 6},
803 { 2, -1, 3, -1, 2, -1, 4, -1},
804 { 4, -1, -1, 1, 0, -1, -1, 6},
805 { 6, -1, 2, 3, 5, -1, 4, -1},
806 { 4, -1, -1, 0, 1, -1, -1, 6},
807 { 2, -1, 5, -1, 3, -1, 4, -1},
808 { 4, -1, 3, -1, -1, 2, -1, 6},
809 { 6, -1, -1, -1, -1, -1, 4, -1},
810 {-1, -1, -1, -1, -1, -1, -1, -1},
811 {-1, -1, -1, -1, -1, -1, -1, -1}},
812 {{ 2, 6, 0, 5, 5, 1, 3, 4},
813 { 1, -1, -1, 2, -1, -1, 0, -1},
814 { 4, -1, -1, 3, 6, -1, -1, 2},
815 {-1, -1, -1, 0, -1, -1, -1, -1},
816 {-1, -1, -1, 1, 4, -1, -1, -1},
817 {-1, -1, -1, 2, -1, -1, -1, -1},
818 {-1, -1, -1, 6, 3, -1, -1, -1},
819 {-1, -1, -1, 5, -1, -1, -1, -1},
820 {-1, -1, -1, 4, 1, -1, -1, -1},
821 {-1, -1, -1, -1, -1, -1, -1, -1}},
822 {{-1, -1, -1, -1, 5, 1, 1, 3},
823 { 0, 5, 1, 0, 5, 3, 3, -1},
824 { 5, 1, 0, 5, 1, 0, 5, 1},
825 { 0, 5, 1, 0, 5, 1, 6, -1},
826 {-1, -1, -1, -1, 1, 6, 5, 1},
827 {-1, -1, -1, -1, 5, 1, 6, -1},
828 {-1, -1, -1, -1, 1, 0, 5, 1},
829 {-1, -1, -1, -1, 5, 1, 0, -1},
830 {-1, -1, -1, -1, -1, -1, -1, -1},
831 {-1, -1, -1, -1, -1, -1, -1, -1}},
832 {{-1, 0, 7, 3, -1, -1, 2, 2},
833 {-1, 0, 7, 3, -1, -1, 2, -1},
834 {-1, 0, 7, 3, -1, -1, 2, 2},
835 {-1, 0, 7, 3, -1, 3, 1, -1},
836 {-1, 0, 7, 3, -1, 6, 4, 5},
837 {-1, 0, 7, 3, -1, 7, 0, -1},
838 {-1, 0, 7, 3, -1, 2, 3, 4},
839 {-1, 0, 7, 3, -1, 5, 6, -1},
840 {-1, -1, -1, -1, -1, 7, 0, 1},
841 {-1, -1, -1, -1, -1, -1, -1, -1}},
842 {{-1, -1, -1, 7, 7, 7, 7, -1},
843 { 3, 4, 5, -1, -1, -1, 7, -1},
844 { 2, -1, -1, -1, -1, -1, -1, 3},
845 { 7, -1, -1, -1, -1, -1, 4, -1},
846 { 7, -1, -1, -1, 3, 4, 5, 6},
847 { 7, -1, -1, 2, 0, 1, 2, -1},
848 { 6, -1, -1, -1, 3, 4, 5, 6},
849 { 0, 1, -1, -1, -1, -1, -1, -1},
850 { 2, 3, 4, -1, -1, -1, -1, -1},
851 { 5, 6, 0, -1, -1, -1, -1, -1}},
852 {{-1, 7, -1, -1, -1, -1, 2, -1},
853 { 1, 1, -1, -1, -1, 3, 3, -1},
854 {-1, 2, -1, -1, -1, -1, 4, -1},
855 { 3, 3, -1, -1, -1, 5, 5, -1},
856 {-1, 4, -1, -1, -1, -1, 6, -1},
857 { 5, 5, -1, -1, -1, 1, 1, -1},
858 {-1, 6, -1, -1, -1, -1, 7, -1},
859 {-1, -1, -1, -1, -1, -1, -1, -1},
860 {-1, -1, -1, -1, -1, -1, -1, -1},
861 {-1, -1, -1, -1, -1, -1, -1, -1}},
862 {{-1, 4, -1, -1, -1, -1, 4, -1},
863 { 2, -1, -1, 1, -1, -1, 2, -1},
864 { 5, -1, -1, 0, 0, -1, -1, 5},
865 { 5, -1, -1, 1, -1, -1, 6, -1},
866 {-1, 4, 2, 7, 7, 5, 4, -1},
867 {-1, -1, -1, 6, -1, -1, -1, -1},
868 {-1, -1, -1, 3, 3, -1, -1, -1},
869 {-1, -1, -1, 7, -1, -1, -1, -1},
870 {-1, -1, -1, -1, -1, -1, -1, -1},
871 {-1, -1, -1, -1, -1, -1, -1, -1}},
872 {{-1, 1, -1, -1, 2, 3, 4, -1},
873 { 2, -1, -1, 3, 0, 4, -1, -1},
874 { 4, -1, -1, 2, 3, 1, -1, -1},
875 { 3, -1, 4, 3, 0, -1, -1, -1},
876 { 4, -1, -1, 2, 5, 1, -1, -1},
877 { 3, -1, 4, 5, 0, 4, -1, -1},
878 {-1, -1, -1, -1, -1, -1, -1, -1},
879 {-1, -1, -1, -1, -1, -1, -1, -1},
880 {-1, -1, -1, -1, -1, -1, -1, -1},
881 {-1, -1, -1, -1, -1, -1, -1, -1}},
882 {{ 2, -1, -1, 1, 1, -1, -1, 2},
883 { 2, -1, 3, 3, 3, -1, 2, -1},
884 {-1, 2, -1, 4, 4, -1, 2, -1},
885 {-1, 7, 7, 0, 7, 7, -1, -1},
886 {-1, -1, -1, 4, 4, -1, -1, -1},
887 {-1, -1, 5, 7, 5, -1, -1, -1},
888 { 6, 3, 2, 6, 4, 2, 3, 6},
889 { 5, -1, -1, -1, -1, -1, 1, -1},
890 {-1, -1, -1, -1, -1, -1, -1, -1},
891 {-1, -1, -1, -1, -1, -1, -1, -1}},
892 {{ 4, 2, 3, 5, 7, 1, 3, 6},
893 { 1, -1, -1, 1, -1, -1, 1, -1},
894 { 3, 0, 1, 3, 2, 4, 3, 5},
895 { 4, -1, -1, 4, -1, -1, 4, -1},
896 {-1, 5, -1, -1, 5, -1, -1, 5},
897 { 0, 3, 2, 0, 4, 5, 0, -1},
898 {-1, 6, -1, -1, 6, -1, -1, 6},
899 { 7, -1, -1, 7, -1, -1, 7, -1},
900 {-1, -1, -1, -1, -1, -1, -1, -1},
901 {-1, -1, -1, -1, -1, -1, -1, -1}},
902 {{-1, 5, 4, -1, 1, 1, -1, -1},
903 { 5, -1, 4, 1, -1, 1, -1, -1},
904 { 0, -1, -1, -1, -1, -1, 0, -1},
905 { 0, 6, 4, -1, -1, 4, 2, -1},
906 {-1, 4, 3, 5, 2, 6, 3, 6},
907 {-1, 2, 6, -1, -1, 5, 4, -1},
908 {-1, -1, -1, -1, -1, -1, -1, -1},
909 {-1, -1, -1, -1, -1, -1, -1, -1},
910 {-1, -1, -1, -1, -1, -1, -1, -1},
911 {-1, -1, -1, -1, -1, -1, -1, -1}},
912 {{-1, -1, -1, 6, 6, -1, -1, -1},
913 {-1, -1, 5, 5, 4, -1, -1, -1},
914 {-1, -1, 1, 6, 6, 4, -1, -1},
915 {-1, 1, 7, 2, 5, 3, -1, -1},
916 {-1, 2, 7, 2, 1, 5, 3, -1},
917 { 2, 1, 3, 1, 4, 2, 7, -1},
918 {-1, 3, 1, 3, 4, 2, 7, -1},
919 {-1, 3, 5, 5, 6, 6, -1, -1},
920 {-1, -1, -1, -1, -1, -1, -1, -1},
921 {-1, -1, -1, -1, -1, -1, -1, -1}},
922 {{-1, -1, 7, 3, -1, -1, -1, -1},
923 {-1, 1, 7, 6, -1, -1, -1, -1},
924 {-1, 3, 7, 5, 1, 5, -1, -1},
925 { 7, 7, 0, 2, 4, 0, 4, -1},
926 { 7, 1, 4, 6, 5, 6, 5, 7},
927 { 1, 7, 7, 1, 7, 7, 1, -1},
928 {-1, -1, -1, -1, -1, -1, -1, -1},
929 {-1, -1, -1, -1, -1, -1, -1, -1},
930 {-1, -1, -1, -1, -1, -1, -1, -1},
931 {-1, -1, -1, -1, -1, -1, -1, -1}},
932 {{-1, -1, 1, -1, -1, 1, -1, -1},
933 {-1, 5, 6, 1, 5, 6, -1, -1},
934 {-1, 1, 1, 2, 2, 1, 1, -1},
935 { 4, 7, 1, 0, 1, 7, 4, -1},
936 {-1, 3, 7, 5, 7, 5, 3, -1},
937 {-1, 1, 1, 1, 1, 1, -1, -1},
938 {-1, -1, -1, -1, -1, -1, -1, -1},
939 {-1, -1, -1, -1, -1, -1, -1, -1},
940 {-1, -1, -1, -1, -1, -1, -1, -1},
941 {-1, -1, -1, -1, -1, -1, -1, -1}},
942 {{ 4, -1, -1, -1, 5, -1, -1, 4},
943 { 6, 6, 7, 6, -1, 4, 5, -1},
944 { 4, 2, 7, 5, 2, 2, 6, 4},
945 {-1, -1, 4, 1, -1, 5, 2, -1},
946 {-1, 5, 2, 7, 7, -1, 7, 4},
947 { 4, 6, 5, 4, -1, 4, 2, -1},
948 {-1, -1, -1, 4, -1, 4, 1, -1},
949 { 0, 0, 0, 5, -1, -1, -1, -1},
950 {-1, -1, -1, -1, 0, 0, 0, 0},
951 {-1, -1, -1, -1, -1, -1, -1, -1}},
952 {{ 1, -1, -1, -1, 0, 0, -1, -1},
953 { 2, -1, -1, 0, 1, 0, -1, -1},
954 { 3, -1, -1, 0, 2, 2, 0, -1},
955 { 4, -1, 0, 1, 1, 1, 0, -1},
956 { 5, -1, -1, 0, 4, 4, 0, -1},
957 { 6, -1, -1, 4, 4, 4, -1, -1},
958 { 7, -1, -1, -1, 4, 4, -1, -1},
959 {-1, -1, -1, 0, 1, 0, -1, -1},
960 {-1, -1, -1, 0, 1, 1, 0, -1},
961 {-1, -1, -1, -1, -1, -1, -1, -1}},
962 {{-1, -1, 3, -1, -1, 1, 7, -1},
963 {-1, 7, 4, -1, -1, 4, 3, -1},
964 { 1, -1, -1, 0, 2, 0, -1, -1},
965 { 5, 4, -1, 3, -1, -1, -1, -1},
966 { 4, -1, 3, 6, 1, 1, 6, -1},
967 {-1, 1, -1, -1, 4, -1, 1, -1},
968 {-1, 7, 5, -1, -1, -1, 3, -1},
969 {-1, -1, 3, -1, -1, -1, -1, -1},
970 {-1, -1, -1, -1, -1, -1, -1, -1},
971 {-1, -1, -1, -1, -1, -1, -1, -1}},
972 {{ 1, -1, -1, -1, 1, -1, -1, -1},
973 { 2, -1, -1, -1, 2, -1, -1, -1},
974 {-1, 3, -1, -1, 3, 3, -1, -1},
975 {-1, 4, -1, 4, -1, 4, -1, -1},
976 {-1, 5, -1, -1, 5, 5, -1, -1},
977 { 6, -1, -1, 7, 1, 7, -1, -1},
978 { 7, -1, -1, -1, 6, 6, -1, -1},
979 {-1, -1, -1, -1, -1, -1, -1, -1},
980 {-1, -1, -1, -1, -1, -1, -1, -1},
981 {-1, -1, -1, -1, -1, -1, -1, -1}},
982 {{ 2, -1, -1, 6, -1, 2, 5, 1},
983 { 5, -1, 4, -1, 4, -1, 4, -1},
984 { 6, -1, -1, 3, -1, -1, -1, 3},
985 { 4, 2, 0, -1, -1, -1, 5, -1},
986 {-1, -1, -1, 6, -1, 3, 6, -1},
987 {-1, -1, 5, -1, 5, -1, -1, -1},
988 {-1, -1, -1, 3, -1, 4, 2, 5},
989 {-1, -1, -1, -1, -1, -1, -1, -1},
990 {-1, -1, -1, -1, -1, -1, -1, -1},
991 {-1, -1, -1, -1, -1, -1, -1, -1}},
992 {{ 6, -1, -1, -1, 4, -1, -1, 3},
993 { 0, 3, -1, -1, 6, -1, 0, -1},
994 {-1, -1, 7, -1, 1, -1, 3, -1},
995 { 7, -1, 4, 7, -1, 2, -1, -1},
996 { 5, 2, 3, 2, 1, 6, -1, 3},
997 {-1, -1, 0, 4, 3, 5, 4, -1},
998 {-1, 7, 6, -1, -1, 0, -1, -1},
999 { 4, 3, -1, -1, -1, 4, 2, -1},
1000 { 0, -1, -1, -1, -1, -1, 6, -1},
1001 {-1, -1, -1, -1, -1, -1, -1, -1}},
1002 {{ 6, 1, 2, 5, 1, 6, 3, 0},
1003 {-1, -1, -1, -1, -1, -1, 4, -1},
1004 { 0, 5, 2, 7, 1, 6, 2, -1},
1005 { 3, -1, -1, -1, -1, -1, -1, -1},
1006 { 6, 7, 6, 4, 0, 5, 2, 6},
1007 {-1, -1, -1, -1, -1, -1, 1, -1},
1008 { 6, 1, 4, 0, 6, 2, 3, -1},
1009 { 0, -1, -1, -1, -1, -1, -1, -1},
1010 {-1, 0, 4, 5, 3, 7, 6, 0},
1011 {-1, -1, -1, -1, -1, -1, -1, -1}},
1012 {{-1, -1, -1, 0, 1, -1, -1, -1},
1013 {-1, -1, 0, 7, 0, -1, -1, -1},
1014 {-1, -1, 1, 2, 2, 0, -1, -1},
1015 {-1, 0, 7, 0, 7, 0, -1, -1},
1016 {-1, 6, -1, 7, 7, -1, 6, -1},
1017 { 4, 1, 6, 6, 6, 4, 1, -1},
1018 {-1, 5, -1, 7, 7, -1, 5, -1},
1019 {-1, -1, -1, -1, -1, -1, -1, -1},
1020 {-1, -1, -1, -1, -1, -1, -1, -1},
1021 {-1, -1, -1, -1, -1, -1, -1, -1}},
1022 {{-1, -1, -1, 5, 6, -1, -1, -1},
1023 {-1, -1, 3, 3, 3, -1, -1, -1},
1024 {-1, -1, 7, 5, 3, 7, -1, -1},
1025 {-1, 3, -1, 6, -1, 3, -1, -1},
1026 { 2, -1, -1, 3, 7, -1, -1, 1},
1027 { 2, 2, -1, 3, -1, 1, 1, -1},
1028 {-1, 0, 2, 5, 6, 1, 0, -1},
1029 {-1, -1, -1, 3, -1, -1, -1, -1},
1030 {-1, -1, -1, 3, 7, -1, -1, -1},
1031 {-1, -1, -1, -1, -1, -1, -1, -1}},
1032 {{-1, 6, -1, -1, -1, -1, 2, -1},
1033 {-1, 2, 6, 0, 6, 0, -1, -1},
1034 {-1, 0, -1, -1, -1, -1, -1, -1},
1035 { 6, -1, -1, -1, -1, -1, -1, -1},
1036 {-1, 3, 3, 2, 0, 6, 0, 0},
1037 {-1, 6, -1, -1, -1, -1, 0, -1},
1038 {-1, -1, -1, 6, 0, 2, 6, -1},
1039 {-1, 2, 0, -1, -1, -1, -1, -1},
1040 {-1, -1, -1, -1, -1, -1, -1, -1},
1041 {-1, -1, -1, -1, -1, -1, -1, -1}},
1042 {{ 0, 7, -1, -1, -1, -1, -1, -1},
1043 { 1, 5, -1, -1, -1, -1, -1, -1},
1044 { 7, 2, 5, -1, -1, -1, -1, -1},
1045 { 6, 3, 4, -1, -1, -1, -1, -1},
1046 { 5, 5, 4, 4, -1, -1, -1, -1},
1047 { 3, 3, 5, 3, -1, -1, -1, -1},
1048 { 1, 2, 2, 5, 3, -1, -1, -1},
1049 { 1, 0, 0, 7, 6, -1, -1, -1},
1050 { 3, 3, 5, 5, 7, 6, -1, -1},
1051 {-1, -1, -1, -1, -1, -1, -1, -1}},
1052 {{-1, -1, 2, 6, 6, 2, -1, -1},
1053 {-1, 2, 1, 1, 0, 2, -1, -1},
1054 {-1, 2, 3, 2, 2, 0, 2, -1},
1055 { 2, 3, 2, 5, 2, 7, 2, -1},
1056 { 2, 4, 2, 5, 2, 7, 2, 0},
1057 { 2, 4, 2, 6, 6, 2, 0, -1},
1058 {-1, 2, 5, 2, 2, 2, 7, 2},
1059 {-1, 2, 5, 6, 6, 7, 2, -1},
1060 {-1, -1, 2, 2, 2, 2, 2, -1},
1061 {-1, -1, -1, -1, -1, -1, -1, -1}},
1062 {{-1, -1, 0, -1, -1, 0, -1, -1},
1063 { 1, 0, 0, 1, 0, 0, 1, -1},
1064 { 1, 7, 7, 5, 5, 7, 7, 1},
1065 { 3, 2, -1, 2, -1, 2, 3, -1},
1066 { 3, 7, -1, 6, 6, -1, 7, 3},
1067 { 7, -1, -1, 6, -1, -1, 7, -1},
1068 { 4, 4, 5, -1, -1, 5, 4, 4},
1069 {-1, -1, -1, -1, -1, -1, -1, -1},
1070 {-1, -1, -1, -1, -1, -1, -1, -1},
1071 {-1, -1, -1, -1, -1, -1, -1, -1}},
1072 {{-1, 6, 3, -1, -1, 3, 6, -1},
1073 { 6, -1, 2, -1, 2, -1, 6, -1},
1074 { 2, -1, 0, 1, 1, 0, -1, 2},
1075 { 5, 0, -1, 7, -1, 0, 5, -1},
1076 {-1, 5, -1, 6, 6, -1, 5, -1},
1077 { 7, 1, 4, -1, 4, 1, 7, -1},
1078 { 7, -1, 4, -1, -1, 4, -1, 7},
1079 { 2, 0, -1, -1, -1, 0, 2, -1},
1080 {-1, 2, -1, -1, -1, -1, 2, -1},
1081 {-1, -1, -1, -1, -1, -1, -1, -1}},
1082 {{ 6, 1, -1, -1, -1, -1, 4, 0},
1083 { 2, 7, 5, 5, 5, 7, 3, -1},
1084 { 6, 1, -1, -1, -1, -1, 4, 0},
1085 { 2, 5, 7, 7, 7, 5, 3, -1},
1086 { 6, 1, -1, -1, -1, -1, 4, 0},
1087 { 2, 0, 6, 6, 6, 0, 3, -1},
1088 { 6, 1, -1, -1, -1, -1, 4, 0},
1089 {-1, -1, -1, -1, -1, -1, -1, -1},
1090 {-1, -1, -1, -1, -1, -1, -1, -1},
1091 {-1, -1, -1, -1, -1, -1, -1, -1}},
1092 {{ 5, -1, -1, 1, 1, -1, -1, 5},
1093 { 5, -1, 4, -1, 4, -1, 5, -1},
1094 {-1, 2, 4, -1, -1, 4, 2, -1},
1095 { 7, 2, -1, -1, -1, 2, 7, -1},
1096 { 0, -1, 0, 4, 4, 0, -1, 0},
1097 { 7, 2, -1, -1, -1, 2, 7, -1},
1098 {-1, 2, 3, -1, -1, 3, 2, -1},
1099 { 5, -1, 3, -1, 3, -1, 5, -1},
1100 { 5, -1, -1, 6, 6, -1, -1, 5},
1101 {-1, -1, -1, -1, -1, -1, -1, -1}},
1102 {{ 2, 2, -1, -1, -1, -1, 5, 5},
1103 { 5, -1, -1, -1, -1, -1, 2, -1},
1104 { 5, -1, -1, -1, -1, -1, -1, 2},
1105 { 1, -1, 1, 5, 1, -1, 3, -1},
1106 { 5, 2, 5, 3, 1, 2, 5, 2},
1107 { 2, 0, 5, -1, 2, 0, 5, -1},
1108 {-1, 3, 7, -1, -1, 3, 7, -1},
1109 {-1, -1, 2, 0, 5, -1, -1, -1},
1110 {-1, -1, -1, -1, -1, -1, -1, -1},
1111 {-1, -1, -1, -1, -1, -1, -1, -1}},
1112 {{ 0, 6, 5, 2, 3, 4, 1, 7},
1113 {-1, -1, -1, -1, 1, -1, -1, -1},
1114 {-1, -1, -1, 1, 1, -1, -1, -1},
1115 {-1, -1, 1, -1, -1, -1, -1, -1},
1116 { 7, 1, 4, 3, 2, 5, 6, 0},
1117 {-1, -1, -1, -1, 1, -1, -1, -1},
1118 {-1, -1, -1, 1, 1, -1, -1, -1},
1119 {-1, -1, 1, -1, -1, -1, -1, -1},
1120 { 0, 6, 5, 2, 3, 4, 1, 7},
1121 {-1, -1, -1, -1, -1, -1, -1, -1}},
1122 {{-1, -1, 1, -1, -1, 1, -1, -1},
1123 {-1, 2, 4, -1, 2, 4, -1, -1},
1124 {-1, 2, 3, 6, 5, 3, 2, -1},
1125 {-1, 6, 5, -1, 6, 5, -1, -1},
1126 {-1, -1, -1, 7, 7, -1, -1, -1},
1127 {-1, -1, -1, 7, -1, -1, -1, -1},
1128 { 1, -1, -1, 7, 7, -1, -1, 3},
1129 { 2, -1, -1, 7, -1, -1, 2, -1},
1130 {-1, 3, 4, 5, 6, 4, 1, -1},
1131 {-1, -1, -1, -1, -1, -1, -1, -1}},
1132 {{ 1, -1, -1, 2, 2, -1, -1, 2},
1133 { 1, 3, 7, 3, 7, 4, 2, -1},
1134 {-1, 1, 6, -1, -1, 6, 2, -1},
1135 { 6, -1, 7, 3, 7, -1, 6, -1},
1136 {-1, 4, 2, -1, -1, 1, 3, -1},
1137 {-1, -1, 2, 6, 1, -1, -1, -1},
1138 {-1, 4, 3, 3, 4, 4, 3, -1},
1139 {-1, -1, -1, -1, -1, -1, -1, -1},
1140 {-1, -1, -1, -1, -1, -1, -1, -1},
1141 {-1, -1, -1, -1, -1, -1, -1, -1}},
1142 {{-1, -1, -1, 5, 6, -1, -1, -1},
1143 {-1, -1, -1, 3, -1, -1, -1, -1},
1144 {-1, -1, -1, 1, 2, -1, -1, -1},
1145 {-1, -1, -1, 4, -1, -1, -1, -1},
1146 {-1, -1, -1, 5, 7, -1, -1, -1},
1147 {-1, -1, -1, 2, -1, -1, -1, -1},
1148 { 6, 5, 4, 3, 2, 1, 7, 5},
1149 {-1, -1, -1, -1, -1, -1, -1, -1},
1150 {-1, -1, -1, -1, -1, -1, -1, -1},
1151 {-1, -1, -1, -1, -1, -1, -1, -1}},
1152 {{-1, 0, -1, 1, -1, 2, -1, -1},
1153 {-1, 4, -1, 5, -1, 6, -1, -1},
1154 {-1, 7, -1, 0, -1, 2, -1, -1},
1155 {-1, 6, -1, 3, -1, 6, -1, -1},
1156 {-1, 1, -1, 1, -1, 2, -1, -1},
1157 {-1, 3, -1, 5, -1, 0, -1, -1},
1158 {-1, 2, -1, 4, -1, 6, -1, -1},
1159 {-1, 3, -1, 6, -1, 7, -1, -1},
1160 {-1, -1, -1, -1, -1, -1, -1, -1},
1161 {-1, -1, -1, -1, -1, -1, -1, -1}},
1162 {{ 1, 1, 2, 2, 3, 3, 4, 4},
1163 { 5, 5, 6, 7, 6, 5, 5, -1},
1164 { 6, 4, 3, 3, 2, 2, 1, 6},
1165 { 4, 6, 5, 7, 6, 3, 1, -1},
1166 {-1, -1, -1, -1, -1, -1, -1, -1},
1167 {-1, -1, -1, -1, -1, -1, -1, -1},
1168 {-1, -1, -1, -1, -1, -1, -1, -1},
1169 {-1, -1, -1, -1, -1, -1, -1, -1},
1170 {-1, -1, -1, -1, -1, -1, -1, -1},
1171 {-1, -1, -1, -1, -1, -1, -1, -1}},
1172 {{ 7, 4, -1, 1, 2, -1, 4, 7},
1173 { 5, 5, -1, 2, -1, 4, 4, -1},
1174 {-1, 5, -1, 7, 7, -1, 4, -1},
1175 { 1, 0, 6, 7, 6, 0, 2, -1},
1176 {-1, 2, -1, 5, 3, -1, 1, -1},
1177 { 1, 1, -1, -1, -1, 2, 2, -1},
1178 { 6, 1, 4, -1, -1, 4, 2, 6},
1179 { 5, 3, -1, -1, -1, 3, 5, -1},
1180 {-1, -1, -1, -1, -1, -1, -1, -1},
1181 {-1, -1, -1, -1, -1, -1, -1, -1}},
1182 {{ 1, 5, 1, 0, 0, 1, 5, 1},
1183 { 1, 2, 5, -1, 5, 2, 1, -1},
1184 { 3, 6, 1, 2, 2, 1, 6, 3},
1185 { 4, 3, 4, -1, 4, 3, 4, -1},
1186 { 3, 4, 6, 5, 5, 6, 4, 3},
1187 { 0, 2, 3, -1, 3, 2, 0, -1},
1188 { 2, 3, 1, 5, 5, 1, 3, 2},
1189 {-1, -1, -1, -1, -1, -1, -1, -1},
1190 {-1, -1, -1, -1, -1, -1, -1, -1},
1191 {-1, -1, -1, -1, -1, -1, -1, -1}},
1192 {{ 3, 0, 2, 7, 5, 7, 6, 5},
1193 { 6, -1, 1, -1, 2, -1, 1, -1},
1194 {-1, 6, 4, 0, 3, 4, 5, -1},
1195 {-1, 5, -1, 1, -1, 4, -1, -1},
1196 {-1, 7, 3, 5, 6, 5, 3, -1},
1197 { 1, -1, 2, -1, 4, -1, 2, -1},
1198 { 6, 4, 4, 6, 6, 5, 5, 1},
1199 {-1, -1, -1, -1, -1, -1, -1, -1},
1200 {-1, -1, -1, -1, -1, -1, -1, -1},
1201 {-1, -1, -1, -1, -1, -1, -1, -1}}
1205 * type is the bubble number 0-7
1206 * fallx is the x axis movement for the falling bubble
1207 * fallvel is the initial upward velocity for the falling bubble
1208 * ingroup denotes a bubble that is part of a group to be removed
1209 * anchored denotes a bubble that is anchored to the ceiling
1220 /* the highscore struct
1221 * level is the highscore level
1222 * score is the highscore score
1229 /* the game context struct
1230 * score is the current score
1231 * level is the current level
1232 * highlevel is the highest level beaten
1233 * highscores is the list of high scores
1234 * angle is the current cannon direction
1235 * shots is the number of shots fired since last compression
1236 * compress is the height of the compressor
1237 * onboardcnt is the number of unique bubbles on the playing board
1238 * onboard is the unique bubbles on the playing board
1239 * nextinq is the pointer to the next bubble in the firing queue
1240 * queue is the circular buffer of bubbles to be fired
1241 * elapsedlvl is level elapsed time in 1/100s of seconds
1242 * elapsedshot is the shot elapsed time in 1/100s of seconds
1243 * startedshot is when the current shot began
1244 * resume denotes whether to resume the currently loaded game
1245 * dirty denotes whether the high scores are out of sync with the saved file
1246 * playboard is the game playing board
1248 struct game_context
{
1251 unsigned int highlevel
;
1252 struct highscore highscores
[NUM_SCORES
];
1257 int onboard
[NUM_BUBBLES
];
1259 int queue
[NUM_QUEUE
];
1265 struct tile playboard
[BB_HEIGHT
][BB_WIDTH
];
1269 * Precalculated sine and cosine * 16384 (fixed point 18.14)
1270 * Borrowed from cube.c plugin
1272 static const short sin_table
[91] = {
1273 0, 285, 571, 857, 1142, 1427, 1712, 1996, 2280, 2563,
1274 2845, 3126, 3406, 3685, 3963, 4240, 4516, 4790, 5062, 5334,
1275 5603, 5871, 6137, 6401, 6663, 6924, 7182, 7438, 7691, 7943,
1276 8191, 8438, 8682, 8923, 9161, 9397, 9630, 9860, 10086, 10310,
1277 10531, 10748, 10963, 11173, 11381, 11585, 11785, 11982, 12175, 12365,
1278 12550, 12732, 12910, 13084, 13254, 13420, 13582, 13740, 13894, 14043,
1279 14188, 14329, 14466, 14598, 14725, 14848, 14967, 15081, 15190, 15295,
1280 15395, 15491, 15582, 15668, 15749, 15825, 15897, 15964, 16025, 16082,
1281 16135, 16182, 16224, 16261, 16294, 16321, 16344, 16361, 16374, 16381,
1285 static long sin(int val
) {
1286 val
= (val
+360)%360;
1290 /* phase 0-90 degree */
1291 return (long)sin_table
[val
];
1293 /* phase 91-180 degree */
1294 return (long)sin_table
[180-val
];
1298 /* phase 181-270 degree */
1299 return -(long)sin_table
[val
-180];
1301 /* phase 270-359 degree */
1302 return -(long)sin_table
[360-val
];
1308 static long cos(int val
) {
1309 val
= (val
+360)%360;
1313 /* phase 0-90 degree */
1314 return (long)sin_table
[90-val
];
1316 /* phase 91-180 degree */
1317 return -(long)sin_table
[val
-90];
1321 /* phase 181-270 degree */
1322 return -(long)sin_table
[270-val
];
1324 /* phase 270-359 degree */
1325 return (long)sin_table
[val
-270];
1333 static void bubbles_init(struct game_context
* bb
);
1334 static bool bubbles_nextlevel(struct game_context
* bb
);
1335 static void bubbles_getonboard(struct game_context
* bb
);
1336 static void bubbles_drawboard(struct game_context
* bb
);
1337 static int bubbles_fire(struct game_context
* bb
);
1338 static bool bubbles_collision(struct game_context
* bb
, int y
, int x
,
1339 int nearrow
, int nearcol
);
1340 static bool bubbles_ingroup(struct game_context
* bb
, int row
, int col
);
1341 static int bubbles_searchgroup(struct game_context
* bb
, int row
, int col
);
1342 static int bubbles_remove(struct game_context
* bb
);
1343 static void bubbles_anchored(struct game_context
* bb
, int row
, int col
);
1344 static int bubbles_fall(struct game_context
* bb
);
1345 static int bubbles_checklevel(struct game_context
* bb
);
1346 static int bubbles_recordscore(struct game_context
* bb
);
1347 static void bubbles_savescores(struct game_context
* bb
);
1348 static bool bubbles_loadgame(struct game_context
* bb
);
1349 static void bubbles_savegame(struct game_context
* bb
);
1350 static void bubbles_setcolors(void);
1351 static void bubbles_callback(void* param
);
1352 static int bubbles_handlebuttons(struct game_context
* bb
, bool animblock
,
1354 static int bubbles(struct game_context
* bb
);
1356 /*****************************************************************************
1357 * bubbles_init() initializes bubbles data structures.
1358 ******************************************************************************/
1359 static void bubbles_init(struct game_context
* bb
) {
1360 /* seed the rand generator */
1361 rb
->srand(*rb
->current_tick
);
1363 /* check for resumed game */
1370 bubbles_nextlevel(bb
);
1373 /*****************************************************************************
1374 * bubbles_nextlevel() sets up the game for the next level, returns false if
1375 * there are no more levels.
1376 ******************************************************************************/
1377 static bool bubbles_nextlevel(struct game_context
* bb
) {
1382 /* check if there are no more levels */
1383 if(bb
->level
> NUM_LEVELS
) return false;
1385 /* set up the play board */
1386 rb
->memset(bb
->playboard
, 0, sizeof(bb
->playboard
));
1387 for(i
=0; i
<BB_LEVEL_HEIGHT
; i
++) {
1388 for(j
=0; j
<BB_WIDTH
; j
++) {
1389 pos
= (int)level
[bb
->level
-1][i
][j
];
1390 if(pos
>=0 && pos
< NUM_BUBBLES
) {
1391 bb
->playboard
[i
][j
].type
= pos
;
1393 bb
->playboard
[i
][j
].type
= -1;
1397 for(i
=BB_LEVEL_HEIGHT
; i
<BB_HEIGHT
; i
++) {
1398 for(j
=0; j
<BB_WIDTH
; j
++) {
1399 bb
->playboard
[i
][j
].type
= -1;
1403 /* fill first bubbles in shot queue */
1404 bubbles_getonboard(bb
);
1405 for(i
=0; i
<NUM_QUEUE
; i
++) {
1406 bb
->queue
[i
] = bb
->onboard
[rb
->rand()%bb
->onboardcnt
];
1414 bb
->elapsedshot
= 0;
1419 /*****************************************************************************
1420 * bubbles_getonboard() determines which bubble types are on the play board.
1421 ******************************************************************************/
1422 static void bubbles_getonboard(struct game_context
* bb
) {
1427 rb
->memset(bb
->onboard
, -1, sizeof(bb
->onboard
));
1429 for(i
=0; i
<BB_HEIGHT
; i
++) {
1430 for(j
=0; j
<BB_WIDTH
; j
++) {
1431 if(bb
->playboard
[i
][j
].type
>= 0) {
1434 for(k
=0; k
<bb
->onboardcnt
; k
++) {
1435 if(bb
->playboard
[i
][j
].type
== bb
->onboard
[k
]) {
1442 bb
->onboard
[bb
->onboardcnt
] = bb
->playboard
[i
][j
].type
;
1446 if(bb
->onboardcnt
== NUM_BUBBLES
) return;
1452 /*****************************************************************************
1453 * bubbles_drawboard() draws the game board to the buffer but does not update
1455 ******************************************************************************/
1456 static void bubbles_drawboard(struct game_context
* bb
) {
1461 bool evenline
= false;
1462 char *level
= "Level";
1463 char *score
= "Score";
1464 char *next
= "Next";
1465 char *hurry
= "HURRY!";
1469 rb
->lcd_clear_display();
1472 #ifdef HAVE_LCD_COLOR
1473 rb
->lcd_bitmap(bubbles_left
, 0, 0, XOFS
, LCD_HEIGHT
);
1474 /* skip right border for square screens */
1475 #if (LCD_WIDTH > LCD_HEIGHT)
1476 rb
->lcd_bitmap(bubbles_right
, XOFS
-1+BB_WIDTH
*BUBBLE_WIDTH
, 0,
1477 LCD_WIDTH
-(XOFS
-1+BB_WIDTH
*BUBBLE_WIDTH
), LCD_HEIGHT
);
1481 /* display play board */
1482 for(i
=0; i
<BB_HEIGHT
; i
++) {
1486 indent
= ROW_INDENT
;
1490 evenline
= !evenline
;
1492 for(j
=0; j
<colmax
; j
++) {
1493 if(bb
->playboard
[i
][j
].type
>= 0 && !bb
->playboard
[i
][j
].delete) {
1494 rb
->lcd_bitmap_part(bubbles_emblem
,
1495 0, EMBLEM_HEIGHT
*bb
->playboard
[i
][j
].type
, EMBLEM_WIDTH
,
1496 XOFS
+indent
+BUBBLE_WIDTH
*j
+(BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2,
1497 ROW_HEIGHT
*i
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2+bb
->compress
*ROW_HEIGHT
,
1498 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
1499 rb
->lcd_set_drawmode(DRMODE_FG
);
1500 rb
->lcd_mono_bitmap((const unsigned char *)bubbles_bubble
,
1501 XOFS
+indent
+BUBBLE_WIDTH
*j
,
1502 ROW_HEIGHT
*i
+bb
->compress
*ROW_HEIGHT
,
1503 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
1504 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1509 /* display bubble to be shot */
1510 rb
->lcd_bitmap_part(bubbles_emblem
,
1511 0, EMBLEM_HEIGHT
*bb
->queue
[bb
->nextinq
], EMBLEM_WIDTH
,
1512 SHOTX
+(BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2,
1513 SHOTY
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2,
1514 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
1515 rb
->lcd_set_drawmode(DRMODE_FG
);
1516 rb
->lcd_mono_bitmap((const unsigned char *)bubbles_bubble
,
1518 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
1519 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1521 /* display next bubble to be shot */
1522 rb
->lcd_bitmap_part(bubbles_emblem
,
1523 0, EMBLEM_HEIGHT
*bb
->queue
[(bb
->nextinq
+1)%NUM_QUEUE
], EMBLEM_WIDTH
,
1524 XOFS
/2-BUBBLE_WIDTH
/2+(BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2,
1525 SHOTY
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2,
1526 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
1527 rb
->lcd_set_drawmode(DRMODE_FG
);
1528 rb
->lcd_mono_bitmap((const unsigned char *)bubbles_bubble
,
1529 XOFS
/2-BUBBLE_WIDTH
/2, SHOTY
,
1530 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
1531 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1533 /* draw bounding lines */
1534 #ifndef HAVE_LCD_COLOR
1535 rb
->lcd_vline(XOFS
-1, 0, LCD_HEIGHT
);
1536 rb
->lcd_vline(XOFS
+BUBBLE_WIDTH
*BB_WIDTH
, 0, LCD_HEIGHT
);
1538 rb
->lcd_hline(XOFS
, XOFS
+BUBBLE_WIDTH
*BB_WIDTH
-1, bb
->compress
*ROW_HEIGHT
-1);
1539 rb
->lcd_hline(XOFS
, XOFS
+BUBBLE_WIDTH
*BB_WIDTH
-1,
1540 ROW_HEIGHT
*(BB_HEIGHT
-2)+BUBBLE_HEIGHT
);
1543 tipx
= SHOTX
+BUBBLE_WIDTH
/2+(((sin(bb
->angle
)>>4)*BUBBLE_WIDTH
*3/2)>>10);
1544 tipy
= SHOTY
+BUBBLE_HEIGHT
/2-(((cos(bb
->angle
)>>4)*BUBBLE_HEIGHT
*3/2)>>10);
1546 rb
->lcd_drawline(SHOTX
+BUBBLE_WIDTH
/2+(((sin(bb
->angle
)>>4)*BUBBLE_WIDTH
/2)>>10),
1547 SHOTY
+BUBBLE_HEIGHT
/2-(((cos(bb
->angle
)>>4)*BUBBLE_HEIGHT
/2)>>10),
1549 xlcd_filltriangle(tipx
, tipy
,
1550 tipx
+(((sin(bb
->angle
-135)>>4)*BUBBLE_WIDTH
/3)>>10),
1551 tipy
-(((cos(bb
->angle
-135)>>4)*BUBBLE_HEIGHT
/3)>>10),
1552 tipx
+(((sin(bb
->angle
+135)>>4)*BUBBLE_WIDTH
/3)>>10),
1553 tipy
-(((cos(bb
->angle
+135)>>4)*BUBBLE_HEIGHT
/3)>>10));
1556 rb
->lcd_getstringsize(level
, &w
, &h
);
1557 rb
->lcd_putsxy(XOFS
/2-w
/2, 2, level
);
1559 rb
->snprintf(str
, 4, "%d", bb
->level
);
1560 rb
->lcd_getstringsize(str
, &w
, &h
);
1561 rb
->lcd_putsxy(XOFS
/2-w
/2, 11, str
);
1563 rb
->lcd_getstringsize(score
, &w
, &h
);
1564 rb
->lcd_putsxy(XOFS
/2-w
/2, 29, score
);
1566 rb
->snprintf(str
, 10, "%d", bb
->score
);
1567 rb
->lcd_getstringsize(str
, &w
, &h
);
1568 rb
->lcd_putsxy(XOFS
/2-w
/2, 38, str
);
1570 rb
->lcd_getstringsize(next
, &w
, &h
);
1571 rb
->lcd_putsxy(XOFS
/2-w
/2, SHOTY
-9, next
);
1573 if(bb
->elapsedshot
>= (MAX_SHOTTIME
*7)/10) {
1574 rb
->lcd_getstringsize(hurry
, &w
, &h
);
1575 rb
->lcd_putsxy(LCD_WIDTH
/2-w
/2, LCD_HEIGHT
/2-h
/2, hurry
);
1579 /*****************************************************************************
1580 * bubbles_fire() fires the current bubble, reloads the cannon, attaches
1581 * bubble to playboard, removes appropriate bubbles, and advances the
1583 ******************************************************************************/
1584 static int bubbles_fire(struct game_context
* bb
) {
1586 long shotxinc
, shotyinc
;
1587 long shotxofs
, shotyofs
;
1589 long tempxofs
, tempyofs
;
1590 int nearrow
, nearcol
;
1591 int lastrow
= BB_HEIGHT
-1;
1592 int lastcol
= (BB_WIDTH
-1)/2;
1594 long lasttick
, currenttick
;
1596 /* get current bubble */
1597 bubblecur
= bb
->queue
[bb
->nextinq
];
1598 shotxinc
= ((sin(bb
->angle
)>>4)*BUBBLE_WIDTH
)/3;
1599 shotyinc
= ((-1*(cos(bb
->angle
)>>4))*BUBBLE_HEIGHT
)/3;
1600 shotxofs
= shotyofs
= 0;
1602 /* advance the queue */
1603 bb
->queue
[bb
->nextinq
] = bb
->onboard
[rb
->rand()%bb
->onboardcnt
];
1604 bb
->nextinq
= (bb
->nextinq
+1)%NUM_QUEUE
;
1605 bubbles_drawboard(bb
);
1606 rb
->lcd_update_rect(0, 0, XOFS
, LCD_HEIGHT
);
1608 /* move the bubble across the play board */
1609 lasttick
= *rb
->current_tick
;
1612 /* move the bubble one step */
1613 shotyofs
+= shotyinc
;
1614 shotxofs
+= shotxinc
*shotxdirec
;
1616 /* check for bounce off sides */
1617 if(SHOTX
+(shotxofs
>>10) < XOFS
) {
1618 shotxofs
+= 2*((XOFS
<<10)-(((SHOTX
)<<10)+shotxofs
));
1620 } else if(SHOTX
+(shotxofs
>>10) > XOFS
+(BB_WIDTH
-1)*BUBBLE_WIDTH
) {
1621 shotxofs
-= 2*((((SHOTX
)<<10)+shotxofs
)-
1622 ((XOFS
<<10)+(((BB_WIDTH
-1)*BUBBLE_WIDTH
)<<10)));
1626 tempxofs
= shotxofs
>>10;
1627 tempyofs
= shotyofs
>>10;
1630 bubbles_drawboard(bb
);
1631 rb
->lcd_bitmap_part(bubbles_emblem
, 0, EMBLEM_HEIGHT
*bubblecur
, EMBLEM_WIDTH
,
1632 SHOTX
+tempxofs
+(BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2,
1633 SHOTY
+tempyofs
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2,
1634 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
1635 rb
->lcd_set_drawmode(DRMODE_FG
);
1636 rb
->lcd_mono_bitmap((const unsigned char *)bubbles_bubble
,
1637 SHOTX
+tempxofs
, SHOTY
+tempyofs
,
1638 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
1639 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1640 rb
->lcd_update_rect(XOFS
, 0, BB_WIDTH
*BUBBLE_WIDTH
, LCD_HEIGHT
);
1642 /* find nearest position */
1643 nearrow
= ((SHOTY
+tempyofs
)-
1644 (bb
->compress
*ROW_HEIGHT
)+
1645 (ROW_HEIGHT
/2))/ROW_HEIGHT
;
1646 if(nearrow
>= BB_HEIGHT
) nearrow
= BB_HEIGHT
-1;
1648 if(nearrow
%2) { /* odd row */
1649 nearcol
= ((SHOTX
+tempxofs
)-
1651 (BUBBLE_WIDTH
/2))/BUBBLE_WIDTH
;
1652 if(nearcol
>= BB_WIDTH
-1) nearcol
= BB_WIDTH
-2;
1653 } else { /* even row */
1654 nearcol
= ((SHOTX
+tempxofs
)-XOFS
+(BUBBLE_WIDTH
/2))/BUBBLE_WIDTH
;
1655 if(nearcol
>= BB_WIDTH
) nearcol
= BB_WIDTH
-1;
1657 if(nearcol
< 0) nearcol
= 0;
1659 /* if nearest position is occupied attach to last position */
1660 if(bb
->playboard
[nearrow
][nearcol
].type
>= 0) {
1661 bb
->playboard
[lastrow
][lastcol
].type
= bubblecur
;
1665 /* save last position */
1669 /* if collision with neighbor then attach shot */
1670 if(bubbles_collision(bb
, SHOTY
+tempyofs
, SHOTX
+tempxofs
,
1671 nearrow
, nearcol
)) {
1672 bb
->playboard
[nearrow
][nearcol
].type
= bubblecur
;
1676 /* if at top then attach shot to the ceiling */
1677 if(nearrow
== 0 && SHOTY
+tempyofs
<= bb
->compress
*ROW_HEIGHT
) {
1678 bb
->playboard
[nearrow
][nearcol
].type
= bubblecur
;
1682 /* handle button events */
1683 buttonres
= bubbles_handlebuttons(bb
, true, 0);
1684 if(buttonres
!= BB_NONE
) return buttonres
;
1686 /* framerate limiting */
1687 currenttick
= *rb
->current_tick
;
1688 if(currenttick
-lasttick
< HZ
/MAX_FPS
) {
1689 rb
->sleep((HZ
/MAX_FPS
)-(currenttick
-lasttick
));
1693 lasttick
= currenttick
;
1696 bubbles_drawboard(bb
);
1699 /* clear appropriate bubbles from playing board */
1700 if(bubbles_ingroup(bb
, lastrow
, lastcol
)) {
1701 buttonres
= bubbles_remove(bb
);
1702 if(buttonres
!= BB_NONE
) return buttonres
;
1705 /* update shots and compress amount */
1707 if(bb
->shots
>= NUM_COMPRESS
) {
1715 /*****************************************************************************
1716 * bubbles_collision() determines if a fired bubble has collided with another
1718 ******************************************************************************/
1719 static bool bubbles_collision(struct game_context
* bb
, int y
, int x
,
1720 int nearrow
, int nearcol
) {
1722 int adj
= nearrow
%2;
1724 /* check neighbors */
1725 if(nearcol
-1 >= 0) {
1726 if(bb
->playboard
[nearrow
][nearcol
-1].type
>= 0) {
1727 nx
= XOFS
+(nearrow
%2 ? ROW_INDENT
: 0)+BUBBLE_WIDTH
*(nearcol
-1);
1728 ny
= ROW_HEIGHT
*nearrow
+bb
->compress
*ROW_HEIGHT
;
1729 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1733 if(nearcol
-1+adj
>= 0) {
1734 if(nearrow
-1 >= 0) {
1735 if(bb
->playboard
[nearrow
-1][nearcol
-1+adj
].type
>= 0) {
1736 nx
= XOFS
+((nearrow
-1)%2 ? ROW_INDENT
: 0)+
1737 BUBBLE_WIDTH
*(nearcol
-1+adj
);
1738 ny
= ROW_HEIGHT
*(nearrow
-1)+bb
->compress
*ROW_HEIGHT
;
1739 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1743 if(nearrow
+1 < BB_HEIGHT
) {
1744 if(bb
->playboard
[nearrow
+1][nearcol
-1+adj
].type
>= 0) {
1745 nx
= XOFS
+((nearrow
+1)%2 ? ROW_INDENT
: 0)+
1746 BUBBLE_WIDTH
*(nearcol
-1+adj
);
1747 ny
= ROW_HEIGHT
*(nearrow
+1)+bb
->compress
*ROW_HEIGHT
;
1748 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1753 if(nearcol
+adj
>= 0) {
1754 if(nearrow
-1 >= 0) {
1755 if(bb
->playboard
[nearrow
-1][nearcol
+adj
].type
>= 0) {
1756 nx
= XOFS
+((nearrow
-1)%2 ? ROW_INDENT
: 0)+
1757 BUBBLE_WIDTH
*(nearcol
+adj
);
1758 ny
= ROW_HEIGHT
*(nearrow
-1)+bb
->compress
*ROW_HEIGHT
;
1759 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1763 if(nearrow
+1 < BB_HEIGHT
) {
1764 if(bb
->playboard
[nearrow
+1][nearcol
+adj
].type
>= 0) {
1765 nx
= XOFS
+((nearrow
+1)%2 ? ROW_INDENT
: 0)+
1766 BUBBLE_WIDTH
*(nearcol
+adj
);
1767 ny
= ROW_HEIGHT
*(nearrow
+1)+bb
->compress
*ROW_HEIGHT
;
1768 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1773 if(nearcol
+1 < BB_WIDTH
-adj
) {
1774 if(bb
->playboard
[nearrow
][nearcol
+1].type
>= 0) {
1775 nx
= XOFS
+(nearrow
%2 ? ROW_INDENT
: 0)+BUBBLE_WIDTH
*(nearcol
+1);
1776 ny
= ROW_HEIGHT
*nearrow
+bb
->compress
*ROW_HEIGHT
;
1777 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1784 /*****************************************************************************
1785 * bubbles_ingroup() marks all bubbles that form the current group.
1786 ******************************************************************************/
1787 static bool bubbles_ingroup(struct game_context
* bb
, int row
, int col
) {
1791 count
= bubbles_searchgroup(bb
, row
, col
);
1793 /* unmark group if too small */
1795 for(i
=0; i
<BB_HEIGHT
; i
++) {
1796 for(j
=0; j
<BB_WIDTH
; j
++) {
1797 bb
->playboard
[i
][j
].ingroup
= false;
1807 /*****************************************************************************
1808 * bubbles_searchgroup() return the size of the group of bubbles of the same
1809 * type that the current bubble belongs to.
1810 ******************************************************************************/
1811 static int bubbles_searchgroup(struct game_context
* bb
, int row
, int col
) {
1813 int myrow
, mycol
, mytype
;
1819 } search
[(2*BB_WIDTH
-1)*(BB_HEIGHT
/2)];
1821 /* search initial bubble */
1822 bb
->playboard
[row
][col
].ingroup
= true;
1823 search
[count
].row
= row
;
1824 search
[count
].col
= col
;
1827 /* breadth-first search neighbors */
1828 for(i
=0; i
<count
; i
++) {
1829 myrow
= search
[i
].row
;
1830 mycol
= search
[i
].col
;
1831 mytype
= bb
->playboard
[myrow
][mycol
].type
;
1835 if(bb
->playboard
[myrow
][mycol
-1].type
== mytype
&&
1836 !bb
->playboard
[myrow
][mycol
-1].ingroup
) {
1837 bb
->playboard
[myrow
][mycol
-1].ingroup
= true;
1838 search
[count
].row
= myrow
;
1839 search
[count
].col
= mycol
-1;
1844 if(mycol
-1+adj
>= 0) {
1846 if(bb
->playboard
[myrow
-1][mycol
-1+adj
].type
== mytype
&&
1847 !bb
->playboard
[myrow
-1][mycol
-1+adj
].ingroup
) {
1848 bb
->playboard
[myrow
-1][mycol
-1+adj
].ingroup
= true;
1849 search
[count
].row
= myrow
-1;
1850 search
[count
].col
= mycol
-1+adj
;
1855 if(myrow
+1 < BB_HEIGHT
) {
1856 if(bb
->playboard
[myrow
+1][mycol
-1+adj
].type
== mytype
&&
1857 !bb
->playboard
[myrow
+1][mycol
-1+adj
].ingroup
) {
1858 bb
->playboard
[myrow
+1][mycol
-1+adj
].ingroup
= true;
1859 search
[count
].row
= myrow
+1;
1860 search
[count
].col
= mycol
-1+adj
;
1866 if(mycol
+adj
>= 0) {
1868 if(bb
->playboard
[myrow
-1][mycol
+adj
].type
== mytype
&&
1869 !bb
->playboard
[myrow
-1][mycol
+adj
].ingroup
) {
1870 bb
->playboard
[myrow
-1][mycol
+adj
].ingroup
= true;
1871 search
[count
].row
= myrow
-1;
1872 search
[count
].col
= mycol
+adj
;
1877 if(myrow
+1 < BB_HEIGHT
) {
1878 if(bb
->playboard
[myrow
+1][mycol
+adj
].type
== mytype
&&
1879 !bb
->playboard
[myrow
+1][mycol
+adj
].ingroup
) {
1880 bb
->playboard
[myrow
+1][mycol
+adj
].ingroup
= true;
1881 search
[count
].row
= myrow
+1;
1882 search
[count
].col
= mycol
+adj
;
1888 if(mycol
+1 < BB_WIDTH
-adj
) {
1889 if(bb
->playboard
[myrow
][mycol
+1].type
== mytype
&&
1890 !bb
->playboard
[myrow
][mycol
+1].ingroup
) {
1891 bb
->playboard
[myrow
][mycol
+1].ingroup
= true;
1892 search
[count
].row
= myrow
;
1893 search
[count
].col
= mycol
+1;
1902 /*****************************************************************************
1903 * bubbles_remove() removes all bubbles in the current group and all
1904 * unanchored bubbles from the play board.
1905 ******************************************************************************/
1906 static int bubbles_remove(struct game_context
* bb
) {
1910 /* determine all anchored bubbles */
1911 for(j
=0; j
<BB_WIDTH
; j
++) {
1912 if(bb
->playboard
[0][j
].type
>= 0 && !bb
->playboard
[0][j
].ingroup
) {
1913 bubbles_anchored(bb
, 0, j
);
1917 /* mark bubbles to be deleted */
1918 for(i
=0; i
<BB_HEIGHT
; i
++) {
1919 for(j
=0; j
<BB_WIDTH
; j
++) {
1920 if(bb
->playboard
[i
][j
].type
>= 0 &&
1921 (!bb
->playboard
[i
][j
].anchored
|| bb
->playboard
[i
][j
].ingroup
)) {
1922 bb
->playboard
[i
][j
].delete = true;
1927 /* animate falling bubbles */
1928 buttonres
= bubbles_fall(bb
);
1929 if(buttonres
!= BB_NONE
) return buttonres
;
1931 /* remove bubbles */
1932 for(i
=0; i
<BB_HEIGHT
; i
++) {
1933 for(j
=0; j
<BB_WIDTH
; j
++) {
1934 if(bb
->playboard
[i
][j
].delete) {
1935 bb
->playboard
[i
][j
].ingroup
= false;
1936 bb
->playboard
[i
][j
].type
= -1;
1937 bb
->playboard
[i
][j
].delete = false;
1939 bb
->playboard
[i
][j
].anchored
= false;
1944 bubbles_getonboard(bb
);
1949 /*****************************************************************************
1950 * bubbles_anchored() marks all bubbles that are anchored in some way to the
1952 ******************************************************************************/
1953 static void bubbles_anchored(struct game_context
* bb
, int row
, int col
) {
1955 int myrow
, mycol
, mytype
;
1961 } search
[(2*BB_WIDTH
-1)*(BB_HEIGHT
/2)];
1963 /* search initial bubble */
1964 bb
->playboard
[row
][col
].anchored
= true;
1965 search
[count
].row
= row
;
1966 search
[count
].col
= col
;
1969 /* breadth-first search neighbors */
1970 for(i
=0; i
<count
; i
++) {
1971 myrow
= search
[i
].row
;
1972 mycol
= search
[i
].col
;
1973 mytype
= bb
->playboard
[myrow
][mycol
].type
;
1977 if(bb
->playboard
[myrow
][mycol
-1].type
>= 0 &&
1978 !bb
->playboard
[myrow
][mycol
-1].ingroup
&&
1979 !bb
->playboard
[myrow
][mycol
-1].anchored
) {
1980 bb
->playboard
[myrow
][mycol
-1].anchored
= true;
1981 search
[count
].row
= myrow
;
1982 search
[count
].col
= mycol
-1;
1987 if(mycol
-1+adj
>= 0) {
1989 if(bb
->playboard
[myrow
-1][mycol
-1+adj
].type
>= 0 &&
1990 !bb
->playboard
[myrow
-1][mycol
-1+adj
].ingroup
&&
1991 !bb
->playboard
[myrow
-1][mycol
-1+adj
].anchored
) {
1992 bb
->playboard
[myrow
-1][mycol
-1+adj
].anchored
= true;
1993 search
[count
].row
= myrow
-1;
1994 search
[count
].col
= mycol
-1+adj
;
1999 if(myrow
+1 < BB_HEIGHT
) {
2000 if(bb
->playboard
[myrow
+1][mycol
-1+adj
].type
>= 0 &&
2001 !bb
->playboard
[myrow
+1][mycol
-1+adj
].ingroup
&&
2002 !bb
->playboard
[myrow
+1][mycol
-1+adj
].anchored
) {
2003 bb
->playboard
[myrow
+1][mycol
-1+adj
].anchored
= true;
2004 search
[count
].row
= myrow
+1;
2005 search
[count
].col
= mycol
-1+adj
;
2011 if(mycol
+adj
>= 0) {
2013 if(bb
->playboard
[myrow
-1][mycol
+adj
].type
>= 0 &&
2014 !bb
->playboard
[myrow
-1][mycol
+adj
].ingroup
&&
2015 !bb
->playboard
[myrow
-1][mycol
+adj
].anchored
) {
2016 bb
->playboard
[myrow
-1][mycol
+adj
].anchored
= true;
2017 search
[count
].row
= myrow
-1;
2018 search
[count
].col
= mycol
+adj
;
2023 if(myrow
+1 < BB_HEIGHT
) {
2024 if(bb
->playboard
[myrow
+1][mycol
+adj
].type
>= 0 &&
2025 !bb
->playboard
[myrow
+1][mycol
+adj
].ingroup
&&
2026 !bb
->playboard
[myrow
+1][mycol
+adj
].anchored
) {
2027 bb
->playboard
[myrow
+1][mycol
+adj
].anchored
= true;
2028 search
[count
].row
= myrow
+1;
2029 search
[count
].col
= mycol
+adj
;
2035 if(mycol
+1 < BB_WIDTH
-adj
) {
2036 if(bb
->playboard
[myrow
][mycol
+1].type
>= 0 &&
2037 !bb
->playboard
[myrow
][mycol
+1].ingroup
&&
2038 !bb
->playboard
[myrow
][mycol
+1].anchored
) {
2039 bb
->playboard
[myrow
][mycol
+1].anchored
= true;
2040 search
[count
].row
= myrow
;
2041 search
[count
].col
= mycol
+1;
2048 /*****************************************************************************
2049 * bubbles_fall() makes removed bubbles fall from the screen.
2050 ******************************************************************************/
2051 static int bubbles_fall(struct game_context
* bb
) {
2058 long lasttick
, currenttick
;
2060 /* give all falling bubbles an x axis movement */
2061 for(i
=0; i
<BB_HEIGHT
; i
++) {
2062 for(j
=0; j
<BB_WIDTH
; j
++) {
2063 if(bb
->playboard
[i
][j
].delete) {
2064 bb
->playboard
[i
][j
].fallx
= rb
->rand()%25 - 12;
2065 bb
->playboard
[i
][j
].fallvel
= rb
->rand()%5 + 6;
2070 /* draw bubbles falling off the screen
2071 * follows y=x^2-8x scaled to bubble size
2073 lasttick
= *rb
->current_tick
;
2075 for(count
=1; ;count
++) {
2077 bubbles_drawboard(bb
);
2079 for(i
=0; i
<BB_HEIGHT
; i
++) {
2080 for(j
=0; j
<BB_WIDTH
; j
++) {
2081 if(bb
->playboard
[i
][j
].delete) {
2082 indent
= (i
%2 ? ROW_INDENT
: 0);
2083 xofs
= ((bb
->playboard
[i
][j
].fallx
*count
)*BUBBLE_WIDTH
)/48;
2084 yofs
= ((count
*count
- bb
->playboard
[i
][j
].fallvel
*count
)*
2087 /* draw bubble if it is still on the screen */
2088 if(ROW_HEIGHT
*i
+bb
->compress
*ROW_HEIGHT
+yofs
2092 rb
->lcd_bitmap_part(bubbles_emblem
, 0,
2093 EMBLEM_HEIGHT
*bb
->playboard
[i
][j
].type
, EMBLEM_WIDTH
,
2094 XOFS
+indent
+BUBBLE_WIDTH
*j
+
2095 (BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2+xofs
,
2096 ROW_HEIGHT
*i
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2+
2097 bb
->compress
*ROW_HEIGHT
+yofs
,
2098 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
2099 rb
->lcd_set_drawmode(DRMODE_FG
);
2100 rb
->lcd_mono_bitmap(
2101 (const unsigned char *)bubbles_bubble
,
2102 XOFS
+indent
+BUBBLE_WIDTH
*j
+xofs
,
2103 ROW_HEIGHT
*i
+bb
->compress
*ROW_HEIGHT
+yofs
,
2104 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
2105 rb
->lcd_set_drawmode(DRMODE_SOLID
);
2113 /* break out if all bubbles are off the screen */
2114 if(!onscreen
) break;
2116 /* handle button events */
2117 buttonres
= bubbles_handlebuttons(bb
, true, 0);
2118 if(buttonres
!= BB_NONE
) return buttonres
;
2120 /* framerate limiting */
2121 currenttick
= *rb
->current_tick
;
2122 if(currenttick
-lasttick
< HZ
/MAX_FPS
) {
2123 rb
->sleep((HZ
/MAX_FPS
)-(currenttick
-lasttick
));
2127 lasttick
= currenttick
;
2133 /*****************************************************************************
2134 * bubbles_checklevel() checks the state of the playboard for a win or loss.
2135 ******************************************************************************/
2136 static int bubbles_checklevel(struct game_context
* bb
) {
2141 bubbles_drawboard(bb
);
2144 /* check for bubbles below cut off point */
2145 for(i
=0; i
<=bb
->compress
; i
++) {
2146 for(j
=0; j
<BB_WIDTH
; j
++) {
2147 if(bb
->playboard
[BB_HEIGHT
-1-i
][j
].type
>= 0) return BB_LOSE
;
2151 /* check for bubbles above cut off point */
2152 for(i
=0; i
<BB_HEIGHT
-1-bb
->compress
; i
++) {
2153 for(j
=0; j
<BB_WIDTH
; j
++) {
2154 if(bb
->playboard
[i
][j
].type
>= 0) return BB_NONE
;
2158 /* level complete, record score */
2159 points
= 100 - bb
->elapsedlvl
/100;
2161 bb
->score
+= points
;
2166 rb
->snprintf(str
, 12, "%d points", points
);
2167 rb
->splash(HZ
, str
);
2169 /* advance to the next level */
2170 if(!bubbles_nextlevel(bb
)) {
2174 bubbles_drawboard(bb
);
2176 rb
->snprintf(str
, 12, "Level %d", bb
->level
);
2177 rb
->splash(HZ
, str
);
2178 bubbles_drawboard(bb
);
2184 /*****************************************************************************
2185 * bubbles_recordscore() inserts a high score into the high scores list and
2186 * returns the high score position.
2187 ******************************************************************************/
2188 static int bubbles_recordscore(struct game_context
* bb
) {
2191 unsigned int currentscore
, currentlevel
;
2192 unsigned int tempscore
, templevel
;
2195 currentlevel
= bb
->level
-1;
2196 currentscore
= bb
->score
;
2198 for(i
=0; i
<NUM_SCORES
; i
++) {
2199 if(currentscore
>= bb
->highscores
[i
].score
) {
2204 templevel
= bb
->highscores
[i
].level
;
2205 tempscore
= bb
->highscores
[i
].score
;
2206 bb
->highscores
[i
].level
= currentlevel
;
2207 bb
->highscores
[i
].score
= currentscore
;
2208 currentlevel
= templevel
;
2209 currentscore
= tempscore
;
2217 /*****************************************************************************
2218 * bubbles_loadscores() loads the high scores saved file.
2219 ******************************************************************************/
2220 static void bubbles_loadscores(struct game_context
* bb
) {
2225 /* clear high scores */
2227 rb
->memset(bb
->highscores
, 0, sizeof(bb
->highscores
));
2229 /* open scores file */
2230 fd
= rb
->open(SCORE_FILE
, O_RDONLY
);
2233 /* read in high scores */
2234 rb
->read(fd
, &bb
->highlevel
, sizeof(bb
->highlevel
));
2235 if(rb
->read(fd
, bb
->highscores
, sizeof(bb
->highscores
)) <= 0) {
2236 /* scores are bad, reset */
2237 rb
->memset(bb
->highscores
, 0, sizeof(bb
->highscores
));
2240 if( bb
->highlevel
>= NUM_LEVELS
)
2241 bb
->highlevel
= NUM_LEVELS
- 1;
2246 /*****************************************************************************
2247 * bubbles_savescores() saves the high scores saved file.
2248 ******************************************************************************/
2249 static void bubbles_savescores(struct game_context
* bb
) {
2252 /* write out the high scores to the save file */
2253 fd
= rb
->open(SCORE_FILE
, O_WRONLY
|O_CREAT
);
2254 rb
->write(fd
, &bb
->highlevel
, sizeof(bb
->highlevel
));
2255 rb
->write(fd
, bb
->highscores
, sizeof(bb
->highscores
));
2260 /*****************************************************************************
2261 * bubbles_loadgame() loads the saved game and returns load success.
2262 ******************************************************************************/
2263 static bool bubbles_loadgame(struct game_context
* bb
) {
2265 bool loaded
= false;
2267 /* open game file */
2268 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
2269 if(fd
< 0) return loaded
;
2271 /* read in saved game */
2273 if(rb
->read(fd
, &bb
->score
, sizeof(bb
->score
)) <= 0) break;
2274 if(rb
->read(fd
, &bb
->level
, sizeof(bb
->level
)) <= 0) break;
2275 if(rb
->read(fd
, &bb
->angle
, sizeof(bb
->angle
)) <= 0) break;
2276 if(rb
->read(fd
, &bb
->shots
, sizeof(bb
->shots
)) <= 0) break;
2277 if(rb
->read(fd
, &bb
->compress
, sizeof(bb
->compress
)) <= 0) break;
2278 if(rb
->read(fd
, &bb
->onboardcnt
, sizeof(bb
->onboardcnt
)) <= 0) break;
2279 if(rb
->read(fd
, bb
->onboard
, sizeof(bb
->onboard
)) <= 0) break;
2280 if(rb
->read(fd
, &bb
->nextinq
, sizeof(bb
->nextinq
)) <= 0) break;
2281 if(rb
->read(fd
, bb
->queue
, sizeof(bb
->queue
)) <= 0) break;
2282 if(rb
->read(fd
, &bb
->elapsedlvl
, sizeof(bb
->elapsedlvl
)) <= 0) break;
2283 if(rb
->read(fd
, bb
->playboard
, sizeof(bb
->playboard
)) <= 0) break;
2291 /* delete saved file */
2292 rb
->remove(SAVE_FILE
);
2296 /*****************************************************************************
2297 * bubbles_savegame() saves the current game state.
2298 ******************************************************************************/
2299 static void bubbles_savegame(struct game_context
* bb
) {
2302 /* write out the game state to the save file */
2303 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
2304 rb
->write(fd
, &bb
->score
, sizeof(bb
->score
));
2305 rb
->write(fd
, &bb
->level
, sizeof(bb
->level
));
2306 rb
->write(fd
, &bb
->angle
, sizeof(bb
->angle
));
2307 rb
->write(fd
, &bb
->shots
, sizeof(bb
->shots
));
2308 rb
->write(fd
, &bb
->compress
, sizeof(bb
->compress
));
2309 rb
->write(fd
, &bb
->onboardcnt
, sizeof(bb
->onboardcnt
));
2310 rb
->write(fd
, bb
->onboard
, sizeof(bb
->onboard
));
2311 rb
->write(fd
, &bb
->nextinq
, sizeof(bb
->nextinq
));
2312 rb
->write(fd
, bb
->queue
, sizeof(bb
->queue
));
2313 rb
->write(fd
, &bb
->elapsedlvl
, sizeof(bb
->elapsedlvl
));
2314 rb
->write(fd
, bb
->playboard
, sizeof(bb
->playboard
));
2320 /*****************************************************************************
2321 * bubbles_setcolors() set the foreground and background colors.
2322 ******************************************************************************/
2323 static inline void bubbles_setcolors(void) {
2324 #ifdef HAVE_LCD_COLOR
2325 rb
->lcd_set_background(LCD_RGBPACK(181,181,222));
2326 rb
->lcd_set_foreground(LCD_BLACK
);
2330 /*****************************************************************************
2331 * bubbles_callback() is the default event handler callback which is called
2332 * on usb connect and shutdown.
2333 ******************************************************************************/
2334 static void bubbles_callback(void* param
) {
2335 struct game_context
* bb
= (struct game_context
*) param
;
2337 rb
->splash(HZ
/2, "Saving high scores...");
2338 bubbles_savescores(bb
);
2342 /*****************************************************************************
2343 * bubbles_handlebuttons() handles button events during a game.
2344 ******************************************************************************/
2345 static int bubbles_handlebuttons(struct game_context
* bb
, bool animblock
,
2350 const struct button_mapping
*plugin_contexts
[]
2351 = {generic_left_right_fire
,generic_actions
};
2355 button
= pluginlib_getaction(rb
,timeout
,plugin_contexts
,2);
2356 #ifdef HAS_BUTTON_HOLD
2357 if (rb
->button_hold())
2358 button
= BUBBLES_START
;
2362 case BUBBLES_LEFT_REP
:
2363 if(bb
->angle
> MIN_ANGLE
) bb
->angle
-= 4;
2364 case BUBBLES_LEFT
: /* change angle to the left */
2365 if(bb
->angle
> MIN_ANGLE
) bb
->angle
-= 2;
2368 case BUBBLES_RIGHT_REP
:
2369 if(bb
->angle
< MAX_ANGLE
) bb
->angle
+= 4;
2370 case BUBBLES_RIGHT
: /* change angle to the right */
2371 if(bb
->angle
< MAX_ANGLE
) bb
->angle
+= 2;
2374 case BUBBLES_SELECT
: /* fire the shot */
2376 bb
->elapsedlvl
+= bb
->elapsedshot
;
2377 bb
->elapsedshot
= 0;
2378 buttonres
= bubbles_fire(bb
);
2379 if(buttonres
!= BB_NONE
) return buttonres
;
2380 buttonres
= bubbles_checklevel(bb
);
2381 if(buttonres
!= BB_NONE
) return buttonres
;
2382 bb
->startedshot
= *rb
->current_tick
;
2386 case BUBBLES_START
: /* pause the game */
2387 start
= *rb
->current_tick
;
2388 rb
->splash(1, "Paused");
2389 while(pluginlib_getaction(rb
,TIMEOUT_BLOCK
,plugin_contexts
,2)
2390 != (BUBBLES_START
));
2391 bb
->startedshot
+= *rb
->current_tick
-start
;
2392 bubbles_drawboard(bb
);
2396 case BUBBLES_RESUME
: /* save and end the game */
2398 rb
->splash(HZ
/2, "Saving game...");
2399 bubbles_savegame(bb
);
2403 case BUBBLES_QUIT
: /* end the game */
2406 case ACTION_UNKNOWN
:
2407 case ACTION_NONE
: /* no button pressed */
2411 if(rb
->default_event_handler_ex(button
, bubbles_callback
,
2412 (void*) bb
) == SYS_USB_CONNECTED
)
2420 /*****************************************************************************
2421 * bubbles() is the main game subroutine, it returns the final game status.
2422 ******************************************************************************/
2423 static int bubbles(struct game_context
* bb
) {
2428 unsigned int startlevel
= 0;
2429 char *title
= "Bubbles";
2430 bool startgame
= false;
2431 bool showscores
= false;
2433 const struct button_mapping
*plugin_contexts
[]
2434 = {generic_actions
,generic_directions
};
2436 bubbles_setcolors();
2438 /* don't resume by default */
2441 /********************
2443 ********************/
2446 rb
->lcd_clear_display();
2449 /* welcome screen to display key bindings */
2450 rb
->lcd_getstringsize(title
, &w
, &h
);
2451 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, title
);
2452 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
2453 rb
->lcd_puts(0, 2, "ON to start/pause");
2454 rb
->lcd_puts(0, 3, "MODE to save/resume");
2455 rb
->lcd_puts(0, 4, "OFF to exit");
2456 rb
->lcd_puts(0, 5, "SELECT to fire");
2457 rb
->lcd_puts(0, 6, " and show high scores");
2458 rb
->lcd_puts(0, 7, "LEFT/RIGHT to aim");
2459 rb
->lcd_puts(0, 8, "UP/DOWN to change level");
2460 #elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
2461 rb
->lcd_puts(0, 2, "PLAY to start/pause");
2462 rb
->lcd_puts(0, 3, "MENU to save/resume");
2463 rb
->lcd_puts(0, 4, "MENU+SELECT to exit");
2464 rb
->lcd_puts(0, 5, "SELECT to fire");
2465 rb
->lcd_puts(0, 6, " and show high scores");
2466 rb
->lcd_puts(0, 7, "SCROLL to aim");
2467 rb
->lcd_puts(0, 8, " and to change level");
2468 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
2469 rb
->lcd_puts(0, 2, "PLAY to start/pause");
2470 rb
->lcd_puts(0, 3, "REC to save/resume");
2471 rb
->lcd_puts(0, 4, "POWER to exit");
2472 rb
->lcd_puts(0, 5, "SELECT to fire");
2473 rb
->lcd_puts(0, 6, " and show high scores");
2474 rb
->lcd_puts(0, 7, "LEFT/RIGHT to aim");
2475 rb
->lcd_puts(0, 8, "UP/DOWN to change level");
2476 #elif CONFIG_KEYPAD == GIGABEAT_PAD
2477 rb
->lcd_puts(0, 2, "POWER to start/pause");
2478 rb
->lcd_puts(0, 3, "MENU to save/resume");
2479 rb
->lcd_puts(0, 4, "A to exit");
2480 rb
->lcd_puts(0, 5, "SELECT to fire");
2481 rb
->lcd_puts(0, 6, " and show high scores");
2482 rb
->lcd_puts(0, 7, "LEFT/RIGHT to aim");
2483 rb
->lcd_puts(0, 8, "UP/DOWN to change level");
2484 #elif CONFIG_KEYPAD == RECORDER_PAD
2485 rb
->lcd_puts_scroll(0, 2, "ON to start/pause, "
2486 "F1 to save/resume, "
2488 "PLAY to fire and show high scores, "
2489 "LEFT/RIGHT to aim, "
2490 "UP/DOWN to change level.");
2491 #elif CONFIG_KEYPAD == ONDIO_PAD
2492 rb
->lcd_puts_scroll(0, 2, "MODE to start/pause, "
2493 "DOWN to save/resume, "
2495 "UP to fire and show high scores, "
2496 "LEFT/RIGHT to aim and to change level.");
2497 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
2498 rb
->lcd_puts(0, 2, "PLAY to start/pause");
2499 rb
->lcd_puts(0, 3, "FF to save/resume");
2500 rb
->lcd_puts(0, 4, "POWER to exit");
2501 rb
->lcd_puts(0, 5, "REW/UP to fire");
2502 rb
->lcd_puts(0, 6, " and show high scores");
2503 rb
->lcd_puts(0, 7, "LEFT/RIGHT to aim");
2504 rb
->lcd_puts(0, 8, "UP/DOWN to change level");
2505 #elif CONFIG_KEYPAD == SANSA_E200_PAD
2506 rb
->lcd_puts(0, 2, "PLAY to start/pause");
2507 rb
->lcd_puts(0, 3, "SUBMENU to save/resume");
2508 rb
->lcd_puts(0, 4, "POWER to exit");
2509 rb
->lcd_puts(0, 5, "SELECT to fire");
2510 rb
->lcd_puts(0, 6, " and show high scores");
2511 rb
->lcd_puts(0, 7, "LEFT/RIGHT to aim");
2512 rb
->lcd_puts(0, 8, "SCROLL to change level");
2514 #if LCD_WIDTH >= 138
2515 rb
->snprintf(str
, 28, "Start on level %d of %d", startlevel
+1,
2518 rb
->snprintf(str
, 28, "Start on lvl %d/%d", startlevel
+1,
2521 rb
->lcd_puts(0, MIN(TEXT_LINES
-3,10), str
);
2522 rb
->lcd_puts(0, MIN(TEXT_LINES
-2,12), "High Score:");
2523 rb
->snprintf(str
, 30, "%d, Lvl %d",
2524 bb
->highscores
[0].score
, bb
->highscores
[0].level
);
2525 rb
->lcd_puts(2, MIN(TEXT_LINES
-1,13), str
);
2527 /* show high scores */
2528 rb
->snprintf(str
, 12, "High Scores");
2529 rb
->lcd_getstringsize(str
, &w
, &h
);
2530 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, str
);
2532 for(i
=0; i
<NUM_SCORES
; i
++) {
2533 rb
->snprintf(str
, 30, "#%02d: %d, Lvl %d", i
+1,
2534 bb
->highscores
[i
].score
, bb
->highscores
[i
].level
);
2535 rb
->lcd_puts(0, i
+2, str
);
2541 /* handle menu button presses */
2542 button
= pluginlib_getaction(rb
,TIMEOUT_BLOCK
,plugin_contexts
,2);
2544 case BUBBLES_START
: /* start playing */
2545 bb
->level
= startlevel
;
2548 case BUBBLES_QUIT
: /* quit program */
2555 case BUBBLES_RESUME
: /* resume game */
2556 if(!bubbles_loadgame(bb
)) {
2557 rb
->splash(HZ
*2, "Nothing to resume");
2563 case BUBBLES_SELECT
: /* toggle high scores */
2564 showscores
= !showscores
;
2567 case BUBBLES_LVLINC
: /* increase starting level */
2568 case BUBBLES_LVLINC_REP
:
2569 if(startlevel
>= bb
->highlevel
) {
2576 case BUBBLES_LVLDEC
: /* decrease starting level */
2577 case BUBBLES_LVLDEC_REP
:
2578 if(startlevel
<= 0) {
2579 startlevel
= bb
->highlevel
;
2586 if(rb
->default_event_handler_ex(button
, bubbles_callback
,
2587 (void*) bb
) == SYS_USB_CONNECTED
)
2593 /********************
2595 ********************/
2597 bubbles_drawboard(bb
);
2600 /**********************
2602 **********************/
2603 bb
->startedshot
= *rb
->current_tick
;
2606 /* refresh the board */
2607 bubbles_drawboard(bb
);
2610 /* manange idle framerate */
2611 bb
->elapsedshot
= *rb
->current_tick
-bb
->startedshot
;
2613 if(MAX_SHOTTIME
-bb
->elapsedshot
< HZ
/2) {
2614 timeout
= MAX_SHOTTIME
-bb
->elapsedshot
;
2619 /* handle button events */
2620 buttonres
= bubbles_handlebuttons(bb
, false, timeout
);
2621 if(buttonres
!= BB_NONE
) return buttonres
;
2624 bb
->elapsedshot
= *rb
->current_tick
-bb
->startedshot
;
2626 if(bb
->elapsedshot
> MAX_SHOTTIME
) {
2627 bb
->elapsedlvl
+= bb
->elapsedshot
;
2628 bb
->elapsedshot
= 0;
2629 buttonres
= bubbles_fire(bb
);
2630 if(buttonres
!= BB_NONE
) return buttonres
;
2631 buttonres
= bubbles_checklevel(bb
);
2632 if(buttonres
!= BB_NONE
) return buttonres
;
2633 bb
->startedshot
= *rb
->current_tick
;
2638 /*****************************************************************************
2639 * plugin entry point.
2640 ******************************************************************************/
2641 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
) {
2642 struct game_context bb
;
2649 /* end of plugin init */
2655 rb
->splash(0, "Loading...");
2656 bubbles_loadscores(&bb
);
2657 rb
->lcd_clear_display();
2661 rb
->lcd_set_backdrop(NULL
);
2663 rb
->lcd_setfont(FONT_SYSFIXED
);
2666 switch(bubbles(&bb
)){
2669 rb
->splash(HZ
*2, "You Win!");
2670 /* record high level */
2671 if( NUM_LEVELS
-1 > bb
.highlevel
) {
2672 bb
.highlevel
= NUM_LEVELS
-1;
2676 /* record high score */
2677 if((position
= bubbles_recordscore(&bb
))) {
2678 rb
->snprintf(str
, 19, "New high score #%d!", position
);
2679 rb
->splash(HZ
*2, str
);
2684 rb
->splash(HZ
*2, "Game Over");
2685 /* fall through to BB_END */
2689 /* record high level */
2690 if(bb
.level
-1 > bb
.highlevel
) {
2691 bb
.highlevel
= bb
.level
-1;
2695 /* record high score */
2696 if((position
= bubbles_recordscore(&bb
))) {
2697 rb
->snprintf(str
, 19, "New high score #%d!", position
);
2698 rb
->splash(HZ
*2, str
);
2704 rb
->lcd_setfont(FONT_UI
);
2705 return PLUGIN_USB_CONNECTED
;
2709 rb
->splash(HZ
/2, "Saving high scores...");
2710 bubbles_savescores(&bb
);
2720 rb
->lcd_setfont(FONT_UI
);