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 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
26 #ifdef HAVE_LCD_BITMAP
29 #include "lib/pluginlib_actions.h"
30 #include "lib/fixedpoint.h"
31 #include "lib/playback_control.h"
32 #include "lib/highscore.h"
37 #define SCORE_FILE PLUGIN_GAMES_DIR "/bubbles.score"
38 #define SAVE_FILE PLUGIN_GAMES_DIR "/bubbles.save"
40 /* final game return status */
48 /* play board dimension */
51 #define BB_LEVEL_HEIGHT 10
55 #define NUM_LEVELS 100
60 #define NUM_COMPRESS 9
61 #define MAX_SHOTTIME 1000
63 /* keyboard layouts */
65 #if (CONFIG_KEYPAD != SANSA_E200_PAD) && \
66 (CONFIG_KEYPAD != SANSA_FUZE_PAD)
67 /* sansas use the wheel instead of left/right if available */
68 #define BUBBLES_LEFT PLA_LEFT
69 #define BUBBLES_LEFT_REP PLA_LEFT_REPEAT
70 #define BUBBLES_RIGHT PLA_RIGHT
71 #define BUBBLES_RIGHT_REP PLA_RIGHT_REPEAT
73 #define ANGLE_STEP_REP 4
75 #define BUBBLES_LEFT PLA_UP
76 #define BUBBLES_LEFT_REP PLA_UP_REPEAT
77 #define BUBBLES_RIGHT PLA_DOWN
78 #define BUBBLES_RIGHT_REP PLA_DOWN_REPEAT
80 #define ANGLE_STEP_REP 4
83 #define BUBBLES_QUIT PLA_QUIT
84 #define BUBBLES_START PLA_START
85 #define BUBBLES_SELECT PLA_FIRE
86 #define BUBBLES_RESUME PLA_MENU
88 #if CONFIG_KEYPAD != ONDIO_PAD
90 #define BUBBLES_LVLINC PLA_UP
91 #define BUBBLES_LVLINC_REP PLA_UP_REPEAT
92 #define BUBBLES_LVLDEC PLA_DOWN
93 #define BUBBLES_LVLDEC_REP PLA_DOWN_REPEAT
95 #else /* ondio keys */
97 #define BUBBLES_LVLINC PLA_RIGHT
98 #define BUBBLES_LVLINC_REP PLA_RIGHT_REPEAT
99 #define BUBBLES_LVLDEC PLA_LEFT
100 #define BUBBLES_LVLDEC_REP PLA_LEFT_REPEAT
104 /* external bitmaps */
105 #ifdef HAVE_LCD_COLOR
106 #include "pluginbitmaps/bubbles_background.h"
108 #include "pluginbitmaps/bubbles_bubble.h"
109 #include "pluginbitmaps/bubbles_emblem.h"
111 #define BUBBLE_WIDTH BMPWIDTH_bubbles_bubble
112 #define BUBBLE_HEIGHT BMPHEIGHT_bubbles_bubble
113 #define EMBLEM_WIDTH BMPWIDTH_bubbles_emblem
114 #define EMBLEM_HEIGHT (BMPHEIGHT_bubbles_emblem/8)
116 /* bubbles will consume height of ROW_HEIGHT*(BB_HEIGHT-1)+BUBBLE_HEIGHT*3/2 */
117 /* 22x22 bubbles (iPod Video) */
118 #if (LCD_HEIGHT == 240) && (LCD_WIDTH == 320)
120 #define ROW_HEIGHT 18
121 #define ROW_INDENT 11
124 /* 22x22 bubbles (Gigabeat, Onda VX747) */
125 #elif ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400)) && (LCD_WIDTH == 240)
127 #define ROW_HEIGHT 18
128 #define ROW_INDENT 11
131 /* 16x16 bubbles (H300, iPod Color) */
132 #elif (LCD_HEIGHT == 176) && (LCD_WIDTH == 220)
134 #define ROW_HEIGHT 14
138 /* 16x16 bubbles (Sansa E200) */
139 #elif (LCD_HEIGHT == 220) && (LCD_WIDTH == 176)
141 #define ROW_HEIGHT 14
145 /* 12x12 bubbles (iPod Nano) */
146 #elif (LCD_HEIGHT == 132) && (LCD_WIDTH == 176)
148 #define ROW_HEIGHT 10
152 /* 12x12 bubbles (H100, H10, iAudio X5, iPod 3G, iPod 4G grayscale) */
153 #elif (LCD_HEIGHT == 128) && ((LCD_WIDTH == 160) || (LCD_WIDTH == 128))
155 #define ROW_HEIGHT 10
159 /* 10x10 bubbles (iPod Mini) */
160 #elif (LCD_HEIGHT == 110) && (LCD_WIDTH == 138)
166 /* 9x9 bubbles (iAudio M3) */
167 #elif (LCD_HEIGHT == 96) && (LCD_WIDTH == 128)
173 /* 8x8 bubbles (Sansa C200) */
174 #elif ((LCD_HEIGHT == 80) && (LCD_WIDTH == 132))
180 /* 7x7 bubbles (Sansa Clip/m200) */
181 #elif (LCD_HEIGHT == 64 && LCD_WIDTH == 128)
187 /* 8x7 bubbles (Archos recorder, Ondio) */
188 #elif (LCD_HEIGHT == 64) && (LCD_WIDTH == 112)
195 #error BUBBLES: Unsupported LCD type
198 #define TEXT_LINES (LCD_HEIGHT/8)
201 #define SHOTX XOFS+ROW_INDENT+BUBBLE_WIDTH*3
202 #define SHOTY ROW_HEIGHT*(BB_HEIGHT-1)+BUBBLE_HEIGHT/2
204 /* collision distance squared */
205 #define MIN_DISTANCE ((BUBBLE_WIDTH*8)/10)*((BUBBLE_HEIGHT*8)/10)
208 char level
[NUM_LEVELS
][BB_LEVEL_HEIGHT
][BB_WIDTH
] = {
209 {{ 6, 6, 4, 4, 2, 2, 3, 3},
210 { 6, 6, 4, 4, 2, 2, 3, -1},
211 { 2, 2, 3, 3, 6, 6, 4, 4},
212 { 2, 3, 3, 6, 6, 4, 4, -1},
213 {-1, -1, -1, -1, -1, -1, -1, -1},
214 {-1, -1, -1, -1, -1, -1, -1, -1},
215 {-1, -1, -1, -1, -1, -1, -1, -1},
216 {-1, -1, -1, -1, -1, -1, -1, -1},
217 {-1, -1, -1, -1, -1, -1, -1, -1},
218 {-1, -1, -1, -1, -1, -1, -1, -1}},
219 {{-1, 7, 7, 7, 7, 7, 7, -1},
220 {-1, 1, 1, 1, 1, 1, -1, -1},
221 {-1, -1, 2, 2, 2, 2, -1, -1},
222 {-1, -1, -1, 2, -1, -1, -1, -1},
223 {-1, -1, -1, 2, 2, -1, -1, -1},
224 {-1, -1, -1, 5, -1, -1, -1, -1},
225 {-1, -1, -1, 5, 5, -1, -1, -1},
226 {-1, -1, -1, -1, -1, -1, -1, -1},
227 {-1, -1, -1, -1, -1, -1, -1, -1},
228 {-1, -1, -1, -1, -1, -1, -1, -1}},
229 {{-1, -1, 7, -1, -1, 7, -1, -1},
230 {-1, -1, 7, 1, 7, -1, -1, -1},
231 {-1, -1, -1, 1, 2, -1, -1, -1},
232 {-1, -1, 1, 2, 1, -1, -1, -1},
233 {-1, -1, -1, 2, 5, -1, -1, -1},
234 {-1, -1, 3, 5, 3, -1, -1, -1},
235 {-1, -1, -1, 5, 3, -1, -1, -1},
236 {-1, -1, -1, 3, -1, -1, -1, -1},
237 {-1, -1, -1, -1, -1, -1, -1, -1},
238 {-1, -1, -1, -1, -1, -1, -1, -1}},
239 {{-1, -1, -1, 0, 0, -1, -1, -1},
240 {-1, -1, 5, 0, 1, -1, -1, -1},
241 {-1, -1, 3, 5, 1, 6, -1, -1},
242 {-1, 4, 3, -1, 6, 7, -1, -1},
243 {-1, 7, 4, -1, -1, 7, 4, -1},
244 { 6, 7, -1, -1, -1, 4, 3, -1},
245 { 1, 6, -1, -1, -1, -1, 3, 5},
246 { 1, -1, -1, -1, -1, -1, 5, -1},
247 {-1, -1, -1, -1, -1, -1, -1, -1},
248 {-1, -1, -1, -1, -1, -1, -1, -1}},
249 {{-1, -1, 0, 0, 0, 0, -1, -1},
250 {-1, 0, 1, 1, 1, 0, -1, -1},
251 {-1, 0, 1, 0, 0, 1, 0, -1},
252 {-1, 0, 1, 1, 1, 0, -1, -1},
253 {-1, -1, 0, 0, 0, 0, -1, -1},
254 {-1, -1, 7, -1, 7, -1, -1, -1},
255 {-1, -1, 7, 7, 7, 7, -1, -1},
256 {-1, -1, -1, -1, -1, -1, -1, -1},
257 {-1, -1, -1, -1, -1, -1, -1, -1},
258 {-1, -1, -1, -1, -1, -1, -1, -1}},
259 {{-1, 4, 4, 4, 6, 6, 6, -1},
260 { 4, -1, -1, -1, -1, -1, 6, -1},
261 {-1, 4, -1, -1, -1, -1, 6, -1},
262 { 4, 2, 3, 1, 2, 3, 6, -1},
263 {-1, 3, 1, 2, 3, 1, 2, -1},
264 {-1, -1, -1, -1, -1, -1, -1, -1},
265 {-1, -1, -1, -1, -1, -1, -1, -1},
266 {-1, -1, -1, -1, -1, -1, -1, -1},
267 {-1, -1, -1, -1, -1, -1, -1, -1},
268 {-1, -1, -1, -1, -1, -1, -1, -1}},
269 {{-1, 4, 4, 4, 6, 6, 6, -1},
270 { 4, -1, -1, -1, -1, -1, 6, -1},
271 {-1, 4, -1, -1, -1, -1, 6, -1},
272 { 4, 2, 3, 1, 2, 3, 6, -1},
273 {-1, 3, 1, 2, 3, 1, 2, -1},
274 {-1, 2, 3, 1, 2, 3, -1, -1},
275 {-1, -1, -1, -1, -1, -1, -1, -1},
276 {-1, -1, -1, -1, -1, -1, -1, -1},
277 {-1, -1, -1, -1, -1, -1, -1, -1},
278 {-1, -1, -1, -1, -1, -1, -1, -1}},
279 {{-1, 0, 0, -1, -1, 2, 2, -1},
280 {-1, 5, -1, -1, -1, 3, -1, -1},
281 {-1, 0, -1, -1, -1, 6, -1, -1},
282 {-1, 3, -1, -1, -1, 0, -1, -1},
283 {-1, 4, -1, -1, -1, 5, -1, -1},
284 {-1, 2, -1, -1, -1, 3, -1, -1},
285 {-1, 2, -1, -1, -1, 1, -1, -1},
286 {-1, 3, -1, -1, -1, 4, -1, -1},
287 {-1, -1, -1, -1, -1, -1, -1, -1},
288 {-1, -1, -1, -1, -1, -1, -1, -1}},
289 {{ 3, -1, -1, -1, -1, -1, -1, 3},
290 { 6, 3, 2, 4, 6, 3, 2, -1},
291 { 4, -1, -1, -1, -1, -1, -1, 4},
292 { 2, 4, 6, 3, 2, 4, 6, -1},
293 {-1, -1, -1, 6, -1, -1, -1, -1},
294 {-1, -1, -1, 3, -1, -1, -1, -1},
295 {-1, -1, -1, -1, -1, -1, -1, -1},
296 {-1, -1, -1, -1, -1, -1, -1, -1},
297 {-1, -1, -1, -1, -1, -1, -1, -1},
298 {-1, -1, -1, -1, -1, -1, -1, -1}},
299 {{-1, 2, -1, 1, -1, 1, -1, 2},
300 { 1, 2, -1, 2, 1, -1, 1, -1},
301 { 1, -1, 1, -1, 2, -1, 2, -1},
302 { 2, 1, -1, 1, 2, -1, 2, -1},
303 {-1, 2, -1, 2, -1, 2, -1, 2},
304 { 1, 2, -1, 2, 1, -1, 1, -1},
305 { 1, -1, 1, -1, 2, -1, 1, -1},
306 { 2, 2, -1, 1, 1, -1, 2, -1},
307 {-1, 2, -1, 1, -1, 1, -1, 1},
308 {-1, -1, -1, -1, -1, -1, -1, -1}},
309 {{-1, 7, 7, -1, -1, 5, 5, -1},
310 { 1, -1, -1, -1, -1, -1, 4, -1},
311 { 2, 1, -1, -1, -1, -1, 4, 3},
312 { 2, -1, -1, -1, -1, -1, 3, -1},
313 { 1, 2, -1, -1, -1, -1, 3, 4},
314 { 1, -1, -1, -1, -1, -1, 4, -1},
315 { 7, 1, -1, -1, -1, -1, 4, 5},
316 { 7, 7, -1, -1, -1, 5, 5, -1},
317 {-1, -1, -1, -1, -1, -1, -1, -1},
318 {-1, -1, -1, -1, -1, -1, -1, -1}},
319 {{ 7, 7, -1, -1, -1, -1, 5, 5},
320 { 1, 5, -1, -1, -1, 7, 4, -1},
321 { 2, 1, -1, -1, -1, -1, 4, 3},
322 { 2, -1, -1, -1, -1, -1, 3, -1},
323 { 1, 5, -1, -1, -1, -1, 7, 4},
324 { 1, -1, -1, -1, -1, -1, 4, -1},
325 { 7, 1, -1, -1, -1, -1, 4, 5},
326 { 7, 5, -1, -1, -1, 7, 5, -1},
327 {-1, -1, -1, -1, -1, -1, -1, -1},
328 {-1, -1, -1, -1, -1, -1, -1, -1}},
329 {{-1, -1, -1, 0, 0, -1, -1, -1},
330 {-1, -1, 5, 0, 1, -1, -1, -1},
331 {-1, -1, 3, 5, 1, 6, -1, -1},
332 {-1, 4, 3, 2, 6, 2, -1, -1},
333 {-1, 7, 4, 7, 2, 2, 4, -1},
334 { 6, 7, 7, 3, 3, 4, 3, -1},
335 { 1, 6, 1, 1, 1, 3, 3, 5},
336 { 1, 1, -1, -1, -1, -1, 5, -1},
337 {-1, -1, -1, -1, -1, -1, -1, -1},
338 {-1, -1, -1, -1, -1, -1, -1, -1}},
339 {{-1, -1, 0, -1, -1, 0, -1, -1},
340 {-1, 3, 3, -1, 3, 3, -1, -1},
341 {-1, 0, 2, 0, 0, 2, 0, -1},
342 {-1, 3, 3, -1, 3, 3, -1, -1},
343 {-1, -1, 0, -1, -1, 0, -1, -1},
344 {-1, -1, -1, -1, -1, -1, -1, -1},
345 {-1, -1, -1, -1, -1, -1, -1, -1},
346 {-1, -1, -1, -1, -1, -1, -1, -1},
347 {-1, -1, -1, -1, -1, -1, -1, -1},
348 {-1, -1, -1, -1, -1, -1, -1, -1}},
349 {{-1, -1, -1, 1, 1, -1, -1, -1},
350 {-1, -1, 2, 2, 2, -1, -1, -1},
351 {-1, -1, 3, 3, 3, 3, -1, -1},
352 {-1, 4, 4, 4, 4, 4, -1, -1},
353 {-1, 5, 5, 5, 5, 5, 5, -1},
354 {-1, -1, -1, 6, -1, -1, -1, -1},
355 {-1, -1, -1, 7, 7, -1, -1, -1},
356 {-1, -1, -1, 0, -1, -1, -1, -1},
357 {-1, -1, -1, -1, -1, -1, -1, -1},
358 {-1, -1, -1, -1, -1, -1, -1, -1}},
359 {{-1, -1, -1, 2, 5, -1, -1, -1},
360 {-1, 4, 3, -1, -1, -1, -1, -1},
361 { 6, 7, -1, 5, 2, -1, -1, -1},
362 {-1, -1, -1, -1, 3, 4, -1, -1},
363 {-1, -1, -1, 2, 5, -1, 7, 6},
364 {-1, 4, 3, -1, -1, -1, -1, -1},
365 { 6, 7, -1, 5, 2, -1, -1, -1},
366 {-1, -1, -1, -1, 3, 4, -1, -1},
367 {-1, -1, -1, -1, -1, -1, 7, 6},
368 {-1, -1, -1, -1, -1, -1, -1, -1}},
369 {{-1, -1, -1, 5, 5, -1, -1, -1},
370 {-1, -1, -1, 3, -1, -1, -1, -1},
371 {-1, -1, -1, 1, -1, -1, -1, -1},
372 {-1, -1, -1, 7, -1, -1, -1, -1},
373 {-1, -1, -1, 2, -1, -1, -1, -1},
374 {-1, -1, -1, 4, -1, -1, -1, -1},
375 {-1, -1, -1, 5, -1, -1, -1, -1},
376 {-1, -1, -1, 3, -1, -1, -1, -1},
377 {-1, -1, -1, -1, -1, -1, -1, -1},
378 {-1, -1, -1, -1, -1, -1, -1, -1}},
379 {{-1, -1, -1, 0, 1, -1, -1, -1},
380 {-1, -1, 0, 2, 7, 7, -1, -1},
381 {-1, -1, -1, 0, 1, 7, -1, -1},
382 {-1, 0, 0, 0, 0, -1, -1, -1},
383 {-1, 0, 0, 0, 1, 1, -1, -1},
384 { 0, 0, 0, 1, 1, 1, -1, -1},
385 {-1, 0, 0, 1, 1, 1, -1, -1},
386 {-1, 0, 0, 0, 7, 7, -1, -1},
387 {-1, -1, 7, 7, -1, -1, -1, -1},
388 {-1, -1, -1, -1, -1, -1, -1, -1}},
389 {{-1, 1, -1, -1, -1, -1, -1, -1},
390 { 1, -1, -1, -1, -1, -1, -1, -1},
391 {-1, 2, 3, 4, 7, 6, 5, -1},
392 {-1, -1, -1, -1, -1, -1, 1, -1},
393 {-1, -1, -1, -1, -1, -1, 1, -1},
394 {-1, 2, 3, 4, 7, 6, -1, -1},
395 {-1, 1, -1, -1, -1, -1, -1, -1},
396 { 1, -1, -1, -1, -1, -1, -1, -1},
397 {-1, 2, 3, 4, 7, 6, 5, -1},
398 {-1, -1, -1, -1, -1, -1, -1, -1}},
399 {{-1, 6, -1, -1, -1, -1, -1, -1},
400 { 5, -1, -1, -1, -1, -1, -1, -1},
401 { 2, 3, 4, 7, 6, 5, 2, 3},
402 {-1, -1, -1, -1, -1, -1, 4, -1},
403 {-1, -1, -1, -1, -1, -1, 7, -1},
404 {-1, 4, 3, 2, 5, 6, -1, -1},
405 {-1, 7, -1, -1, -1, -1, -1, -1},
406 { 6, -1, -1, -1, -1, -1, -1, -1},
407 { 5, 2, 3, 4, 7, 6, 5, -1},
408 {-1, -1, -1, -1, -1, -1, -1, -1}},
409 {{ 3, 2, 1, 0, 0, 1, 2, 3},
410 { 3, 2, 1, 0, 1, 2, 3, -1},
411 { 4, 3, 2, 1, 1, 2, 3, 4},
412 { 4, 3, 2, 1, 2, 3, 4, -1},
413 { 5, 4, 3, 2, 2, 3, 4, 5},
414 { 5, 4, 3, 2, 3, 4, 5, -1},
415 { 6, 5, 4, 3, 3, 4, 5, 6},
416 { 6, 5, 4, 3, 4, 5, 6, -1},
417 { 7, 6, 5, 4, 4, 5, 6, 7},
418 {-1, -1, -1, -1, -1, -1, -1, -1}},
419 {{-1, -1, -1, 5, 5, -1, -1, -1},
420 {-1, -1, -1, 3, -1, -1, -1, -1},
421 {-1, -1, -1, 2, 4, -1, -1, -1},
422 {-1, -1, -1, 6, -1, -1, -1, -1},
423 {-1, -1, -1, 2, 4, -1, -1, -1},
424 {-1, 2, -1, 5, -1, 4, -1, -1},
425 { 1, 0, 1, 0, 1, 0, 1, 0},
426 { 3, -1, 3, -1, 2, -1, 6, -1},
427 {-1, -1, -1, -1, -1, -1, -1, -1},
428 {-1, -1, -1, -1, -1, -1, -1, -1}},
429 {{-1, -1, -1, -1, 1, -1, -1, -1},
430 { 7, 4, 3, 5, -1, -1, -1, -1},
431 { 6, -1, -1, 1, -1, -1, -1, -1},
432 {-1, -1, -1, 5, 3, 4, 7, -1},
433 { 6, -1, -1, -1, 1, -1, -1, 6},
434 { 7, 4, 3, 5, -1, -1, -1, -1},
435 {-1, -1, -1, 1, -1, -1, -1, 6},
436 {-1, -1, -1, 5, 3, 4, 7, -1},
437 {-1, -1, -1, -1, -1, -1, -1, -1},
438 {-1, -1, -1, -1, -1, -1, -1, -1}},
439 {{-1, -1, -1, -1, 7, 3, 6, -1},
440 {-1, -1, 3, 7, 3, 6, 3, -1},
441 {-1, -1, 5, 7, 3, 6, 3, -1},
442 {-1, 6, 7, 3, 6, 7, -1, -1},
443 {-1, 7, 7, 3, 6, 1, -1, -1},
444 { 3, 7, 3, 6, 3, -1, -1, -1},
445 { 5, 6, 2, 7, 1, -1, -1, -1},
446 {-1, -1, -1, -1, -1, -1, -1, -1},
447 {-1, -1, -1, -1, -1, -1, -1, -1},
448 {-1, -1, -1, -1, -1, -1, -1, -1}},
449 {{ 5, -1, -1, -1, -1, -1, -1, 5},
450 { 5, -1, 6, 6, 6, -1, 5, -1},
451 {-1, 5, 4, -1, -1, 4, 5, -1},
452 {-1, 3, -1, -1, -1, 3, -1, -1},
453 {-1, 6, 0, -1, -1, 0, 6, -1},
454 {-1, 3, -1, -1, -1, 3, -1, -1},
455 {-1, -1, 4, -1, -1, 4, -1, -1},
456 {-1, -1, 6, 6, 6, -1, -1, -1},
457 {-1, -1, -1, -1, -1, -1, -1, -1},
458 {-1, -1, -1, -1, -1, -1, -1, -1}},
459 {{-1, 7, 0, -1, -1, 0, 7, -1},
460 { 7, -1, 0, -1, 0, -1, 7, -1},
461 { 7, 1, -1, 0, 0, -1, 1, 7},
462 { 7, 1, 2, 0, 2, 1, 7, -1},
463 { 7, 6, 3, 2, 2, 3, 6, 7},
464 { 7, -1, 3, 2, 3, -1, 7, -1},
465 {-1, 7, 7, 3, 3, 7, 7, -1},
466 {-1, -1, -1, 3, -1, -1, -1, -1},
467 {-1, -1, -1, -1, -1, -1, -1, -1},
468 {-1, -1, -1, -1, -1, -1, -1, -1}},
469 {{-1, 3, -1, 1, -1, 7, -1, 6},
470 { 5, -1, 7, -1, 7, -1, 6, -1},
471 { 6, -1, 0, -1, 5, -1, 3, -1},
472 {-1, 2, -1, 1, -1, 5, -1, -1},
473 {-1, 4, -1, 3, -1, 4, -1, -1},
474 { 2, -1, 3, -1, 2, -1, -1, -1},
475 {-1, -1, 4, -1, 6, -1, -1, -1},
476 {-1, -1, -1, 5, -1, -1, -1, -1},
477 {-1, -1, -1, -1, -1, -1, -1, -1},
478 {-1, -1, -1, -1, -1, -1, -1, -1}},
479 {{-1, -1, -1, -1, 1, -1, -1, -1},
480 {-1, -1, -1, -1, 3, -1, -1, -1},
481 { 6, 1, 3, 1, 2, 1, 4, 1},
482 {-1, -1, -1, -1, 6, -1, -1, -1},
483 {-1, -1, -1, 4, 1, -1, -1, -1},
484 {-1, -1, 1, -1, 3, -1, -1, -1},
485 {-1, -1, -1, 2, 1, -1, -1, -1},
486 {-1, -1, -1, -1, 4, -1, -1, -1},
487 {-1, -1, -1, 6, 1, -1, -1, -1},
488 {-1, -1, -1, 6, -1, -1, -1, -1}},
489 {{-1, -1, -1, 5, 4, -1, -1, -1},
490 {-1, -1, 4, 1, 0, -1, -1, -1},
491 {-1, -1, -1, 2, 3, -1, -1, -1},
492 {-1, 1, 4, -1, 2, 2, -1, -1},
493 {-1, 3, 1, 2, 5, 1, 4, -1},
494 {-1, 4, 2, -1, 0, 4, -1, -1},
495 {-1, -1, -1, -1, -1, -1, -1, -1},
496 {-1, -1, -1, -1, -1, -1, -1, -1},
497 {-1, -1, -1, -1, -1, -1, -1, -1},
498 {-1, -1, -1, -1, -1, -1, -1, -1}},
499 {{-1, -1, -1, -1, 1, -1, -1, -1},
500 {-1, -1, -1, 1, -1, -1, -1, -1},
501 {-1, 2, -1, -1, 1, -1, 5, -1},
502 { 5, -1, -1, 1, -1, -1, 0, -1},
503 {-1, 6, -1, -1, 1, -1, 4, -1},
504 {-1, 0, -1, 1, -1, 5, -1, -1},
505 {-1, -1, 5, 5, 0, 1, -1, -1},
506 {-1, -1, -1, -1, -1, -1, -1, -1},
507 {-1, -1, -1, -1, -1, -1, -1, -1},
508 {-1, -1, -1, -1, -1, -1, -1, -1}},
509 {{-1, -1, -1, 6, 3, -1, -1, -1},
510 {-1, -1, 3, 2, 6, -1, -1, -1},
511 {-1, -1, 2, 6, 3, 2, -1, -1},
512 {-1, 6, 3, 2, 6, 3, -1, -1},
513 {-1, 3, 2, 6, 3, 2, 6, -1},
514 { 2, 6, 3, 2, 6, 3, 2, -1},
515 { 6, 3, 2, 6, 3, 2, 6, 3},
516 {-1, -1, -1, -1, -1, -1, -1, -1},
517 {-1, -1, -1, -1, -1, -1, -1, -1},
518 {-1, -1, -1, -1, -1, -1, -1, -1}},
519 {{ 6, 6, 6, 6, 6, 6, 6, 6},
520 { 4, -1, -1, -1, -1, -1, -1, -1},
521 {-1, 3, 2, 5, 7, 6, 4, 3},
522 {-1, 5, -1, -1, -1, -1, -1, -1},
523 {-1, -1, 7, 6, 4, 3, 2, 5},
524 {-1, -1, 4, -1, -1, -1, -1, -1},
525 {-1, -1, -1, 3, 2, 5, 7, 6},
526 {-1, -1, -1, -1, -1, -1, -1, -1},
527 {-1, -1, -1, -1, -1, -1, -1, -1},
528 {-1, -1, -1, -1, -1, -1, -1, -1}},
529 {{ 1, -1, 7, -1, -1, 6, -1, 2},
530 { 6, -1, 1, -1, 6, 1, 3, -1},
531 {-1, 4, -1, 7, 2, -1, 7, -1},
532 { 2, 7, -1, -1, -1, 4, -1, -1},
533 { 6, -1, 3, 5, 0, 2, -1, 7},
534 { 1, -1, -1, -1, -1, -1, 1, -1},
535 {-1, 1, 4, 5, 7, 5, 1, -1},
536 {-1, -1, -1, -1, -1, -1, -1, -1},
537 {-1, -1, -1, -1, -1, -1, -1, -1},
538 {-1, -1, -1, -1, -1, -1, -1, -1}},
539 {{ 6, 6, 6, -1, -1, 6, 6, 6},
540 {-1, -1, 6, -1, 6, -1, -1, -1},
541 {-1, -1, 2, 3, 3, 2, -1, -1},
542 {-1, 3, -1, 5, -1, 3, -1, -1},
543 {-1, -1, 5, 3, 3, 5, -1, -1},
544 {-1, -1, 6, 1, 6, -1, -1, -1},
545 {-1, 4, 2, -1, -1, 2, 4, -1},
546 {-1, -1, -1, -1, -1, -1, -1, -1},
547 {-1, -1, -1, -1, -1, -1, -1, -1},
548 {-1, -1, -1, -1, -1, -1, -1, -1}},
549 {{-1, -1, -1, 5, 5, -1, -1, -1},
550 {-1, -1, 5, -1, -1, -1, -1, -1},
551 {-1, 3, 4, 6, 6, -1, -1, 5},
552 { 3, 3, 4, 6, 5, -1, 5, -1},
553 { 3, 2, 3, 6, 6, 5, 5, -1},
554 { 3, 3, 4, 6, 5, -1, 5, -1},
555 {-1, 3, 4, 6, 6, -1, -1, 5},
556 {-1, -1, 5, -1, -1, -1, -1, -1},
557 {-1, -1, -1, 5, 5, -1, -1, -1},
558 {-1, -1, -1, -1, -1, -1, -1, -1}},
559 {{ 1, -1, -1, -1, -1, -1, -1, 1},
560 { 1, -1, 2, 2, 2, -1, 1, -1},
561 {-1, 1, 2, 3, 3, 2, 1, -1},
562 { 6, 2, 3, -1, 3, 2, 6, -1},
563 { 6, 2, 3, -1, -1, 3, 2, 6},
564 { 6, 2, 3, -1, 3, 2, 6, -1},
565 { 3, 3, 3, 7, 7, 3, 3, 3},
566 { 0, 5, 0, 2, 0, 5, 0, -1},
567 {-1, -1, -1, -1, -1, -1, -1, -1},
568 {-1, -1, -1, -1, -1, -1, -1, -1}},
569 {{-1, -1, 7, 7, 7, -1, -1, -1},
570 {-1, 7, 2, 2, 7, -1, -1, -1},
571 {-1, 7, 5, 5, 5, 7, -1, -1},
572 { 7, 7, 7, 7, 7, 7, -1, -1},
573 {-1, -1, 6, -1, 6, -1, -1, -1},
574 {-1, 6, -1, -1, 6, -1, -1, -1},
575 {-1, 6, 4, 4, -1, 6, 4, 4},
576 {-1, -1, -1, -1, -1, -1, -1, -1},
577 {-1, -1, -1, -1, -1, -1, -1, -1},
578 {-1, -1, -1, -1, -1, -1, -1, -1}},
579 {{-1, 3, 3, -1, 3, 3, 3, -1},
580 { 3, 7, 5, 4, 6, 5, 3, -1},
581 { 1, 3, 3, 3, -1, 3, 3, 1},
582 { 2, 1, 2, 1, 2, 1, 2, -1},
583 { 1, 3, 3, -1, 3, 3, 3, 1},
584 { 3, 5, 6, 4, 5, 7, 3, -1},
585 { 2, 3, 3, 3, -1, 3, 3, 2},
586 { 1, 1, 2, 2, 2, 1, 1, -1},
587 {-1, -1, -1, -1, -1, -1, -1, -1},
588 {-1, -1, -1, -1, -1, -1, -1, -1}},
589 {{-1, 6, 5, -1, -1, -1, -1, -1},
590 { 3, 1, 3, -1, -1, -1, -1, -1},
591 {-1, 5, 6, -1, -1, -1, -1, -1},
592 {-1, -1, 5, 3, -1, -1, -1, -1},
593 {-1, -1, 6, 1, 6, -1, -1, -1},
594 {-1, -1, 3, 5, -1, -1, -1, -1},
595 {-1, -1, -1, -1, 3, 6, -1, -1},
596 {-1, -1, -1, 5, 6, 5, -1, -1},
597 {-1, -1, -1, -1, 6, 3, -1, -1},
598 {-1, -1, -1, -1, -1, -1, -1, -1}},
599 {{ 6, 3, 7, 4, 5, 1, 6, 3},
600 { 5, 1, 6, 3, 7, 4, 5, -1},
601 { 6, 3, 7, 4, 5, 1, 6, 3},
602 {-1, -1, -1, -1, -1, -1, -1, -1},
603 {-1, -1, -1, -1, -1, -1, -1, -1},
604 {-1, -1, -1, -1, -1, -1, -1, -1},
605 {-1, -1, -1, -1, -1, -1, -1, -1},
606 {-1, -1, -1, -1, -1, -1, -1, -1},
607 {-1, -1, -1, -1, -1, -1, -1, -1},
608 {-1, -1, -1, -1, -1, -1, -1, -1}},
609 {{-1, -1, -1, -1, -1, -1, 4, 4},
610 {-1, -1, 7, 7, 7, 4, 4, -1},
611 {-1, -1, -1, -1, -1, -1, 4, 4},
612 {-1, 1, -1, -1, -1, 7, -1, -1},
613 {-1, 1, 1, -1, -1, 7, -1, -1},
614 { 3, 3, 3, -1, 7, -1, -1, -1},
615 { 3, -1, 2, 3, 3, 3, -1, 3},
616 {-1, 2, -1, 3, -1, 3, 3, -1},
617 {-1, 2, -1, -1, -1, -1, -1, -1},
618 {-1, -1, -1, -1, -1, -1, -1, -1}},
619 {{-1, -1, 4, -1, -1, -1, -1, -1},
620 {-1, 7, 4, -1, -1, -1, -1, -1},
621 {-1, -1, 7, 4, -1, -1, -1, -1},
622 {-1, 4, 7, 4, -1, -1, -1, -1},
623 { 1, 1, 1, 1, 1, 1, 1, -1},
624 { 1, 2, 1, 2, 1, 1, -1, -1},
625 { 2, 2, 2, 2, 2, 2, 2, 2},
626 {-1, -1, -1, -1, -1, -1, -1, -1},
627 {-1, -1, -1, -1, -1, -1, -1, -1},
628 {-1, -1, -1, -1, -1, -1, -1, -1}},
629 {{ 0, -1, -1, -1, -1, -1, -1, 6},
630 { 6, 1, 4, 3, 7, 5, 0, -1},
631 { 0, -1, -1, -1, -1, -1, -1, 6},
632 { 6, 1, 4, 3, 7, 5, 0, -1},
633 { 0, -1, -1, -1, -1, -1, -1, 6},
634 { 6, 1, 4, 3, 7, 5, 0, -1},
635 {-1, -1, -1, -1, -1, -1, -1, -1},
636 {-1, -1, -1, -1, -1, -1, -1, -1},
637 {-1, -1, -1, -1, -1, -1, -1, -1},
638 {-1, -1, -1, -1, -1, -1, -1, -1}},
639 {{ 3, 3, 4, 6, 6, 4, 3, 3},
640 { 0, 3, 4, 6, 4, 3, 1, -1},
641 { 5, 1, 3, 4, 4, 3, 0, 1},
642 { 0, 1, 3, 4, 3, 1, 0, -1},
643 { 2, 1, 6, 3, 3, 0, 0, 1},
644 { 0, 3, 4, 3, 6, 1, 5, -1},
645 { 6, 1, 2, 6, 4, 0, 0, 2},
646 {-1, -1, -1, -1, -1, -1, -1, -1},
647 {-1, -1, -1, -1, -1, -1, -1, -1},
648 {-1, -1, -1, -1, -1, -1, -1, -1}},
649 {{ 6, 6, -1, -1, -1, -1, 4, 4},
650 { 4, 0, -1, -1, -1, 3, 6, -1},
651 { 0, 6, -1, -1, -1, -1, 4, 2},
652 { 7, -1, -1, -1, -1, -1, 7, -1},
653 { 4, 4, -1, -1, -1, -1, 5, 6},
654 { 6, 4, 7, 7, 5, 6, 4, -1},
655 {-1, 7, 6, 4, 6, 4, 7, -1},
656 {-1, 0, -1, 7, -1, 7, -1, -1},
657 {-1, -1, -1, -1, -1, -1, -1, -1},
658 {-1, -1, -1, -1, -1, -1, -1, -1}},
659 {{-1, 5, -1, -1, -1, -1, 4, -1},
660 {-1, 5, -1, -1, -1, 4, -1, -1},
661 {-1, -1, 5, 6, 6, 4, -1, -1},
662 {-1, -1, 2, -1, 2, -1, -1, -1},
663 { 0, 0, 6, -1, -1, 6, 1, 1},
664 {-1, -1, 2, -1, 2, -1, -1, -1},
665 {-1, -1, 7, 6, 6, 3, -1, -1},
666 {-1, 7, -1, -1, -1, 3, -1, -1},
667 {-1, 7, -1, -1, -1, -1, 3, -1},
668 {-1, -1, -1, -1, -1, -1, -1, -1}},
669 {{-1, 6, -1, -1, -1, -1, 2, -1},
670 { 1, 7, 1, 1, 1, 3, 1, -1},
671 {-1, -1, 4, 1, 1, 4, -1, -1},
672 {-1, 1, 3, 1, 7, 1, -1, -1},
673 {-1, -1, -1, 2, 6, -1, -1, -1},
674 {-1, -1, 1, 5, 1, -1, -1, -1},
675 {-1, -1, -1, -1, -1, -1, -1, -1},
676 {-1, -1, -1, -1, -1, -1, -1, -1},
677 {-1, -1, -1, -1, -1, -1, -1, -1},
678 {-1, -1, -1, -1, -1, -1, -1, -1}},
679 {{ 7, 7, 7, 7, 7, 7, 7, 7},
680 { 7, -1, -1, -1, -1, -1, 7, -1},
681 { 7, -1, -1, 2, 0, 5, 2, 2},
682 { 7, -1, -1, -1, 0, 3, 6, -1},
683 { 7, -1, -1, -1, -1, -1, 4, 0},
684 { 5, 5, -1, -1, -1, -1, -1, -1},
685 { 4, 3, 6, 2, -1, -1, -1, -1},
686 { 0, 2, 0, 4, -1, -1, -1, -1},
687 {-1, -1, -1, -1, -1, -1, -1, -1},
688 {-1, -1, -1, -1, -1, -1, -1, -1}},
689 {{-1, -1, 1, -1, -1, 1, -1, -1},
690 {-1, 4, -1, -1, 5, -1, -1, -1},
691 {-1, 7, -1, -1, 1, 1, 1, -1},
692 { 6, -1, -1, -1, -1, 7, -1, -1},
693 { 1, 1, 1, 1, -1, 4, -1, -1},
694 {-1, -1, 5, -1, -1, -1, -1, -1},
695 {-1, -1, 0, -1, -1, -1, -1, -1},
696 {-1, 3, -1, -1, -1, -1, -1, -1},
697 {-1, 1, -1, -1, -1, -1, -1, -1},
698 {-1, -1, -1, -1, -1, -1, -1, -1}},
699 {{-1, 7, 7, -1, -1, 7, 7, -1},
700 { 6, -1, 4, -1, 4, -1, 6, -1},
701 { 5, -1, -1, 3, 3, -1, -1, 5},
702 { 6, -1, -1, -1, -1, -1, 6, -1},
703 {-1, 7, -1, -1, -1, -1, 7, -1},
704 {-1, 4, -1, -1, -1, 4, -1, -1},
705 {-1, -1, 3, -1, -1, 3, -1, -1},
706 {-1, -1, 2, -1, 2, -1, -1, -1},
707 {-1, -1, -1, 5, 5, -1, -1, -1},
708 {-1, -1, -1, -1, -1, -1, -1, -1}},
709 {{-1, 0, 0, -1, -1, 0, 0, -1},
710 { 7, 4, 6, 6, 6, 4, 3, -1},
711 { 5, 6, 6, 6, 2, 6, 6, 3},
712 { 7, 4, 6, 6, 6, 4, 3, -1},
713 {-1, 0, 0, -1, -1, 0, 0, -1},
714 {-1, -1, -1, -1, -1, -1, -1, -1},
715 {-1, -1, -1, -1, -1, -1, -1, -1},
716 {-1, -1, -1, -1, -1, -1, -1, -1},
717 {-1, -1, -1, -1, -1, -1, -1, -1},
718 {-1, -1, -1, -1, -1, -1, -1, -1}},
719 {{-1, -1, -1, -1, -1, 7, 7, 7},
720 {-1, -1, -1, -1, 2, 7, 7, -1},
721 {-1, 0, 7, 7, 7, -1, 7, 7},
722 { 6, 7, 7, 7, -1, -1, -1, -1},
723 { 6, -1, -1, -1, 7, 7, 7, 7},
724 { 6, -1, -1, -1, -1, -1, -1, -1},
725 { 4, 2, 2, 2, 4, -1, 3, -1},
726 { 4, 4, 4, 4, 3, 3, 3, -1},
727 {-1, -1, -1, -1, -1, -1, -1, -1},
728 {-1, -1, -1, -1, -1, -1, -1, -1}},
729 {{ 4, -1, -1, 7, -1, 6, -1, 7},
730 { 7, 6, 7, -1, -1, 7, 4, -1},
731 {-1, -1, 7, -1, -1, 7, -1, -1},
732 {-1, 0, 0, 0, 0, 0, 3, -1},
733 {-1, -1, 0, 2, 2, 0, 6, 4},
734 {-1, -1, 0, 0, 0, 1, 3, -1},
735 {-1, -1, -1, 0, 0, -1, 3, 4},
736 {-1, -1, -1, 6, -1, 5, 6, -1},
737 {-1, -1, -1, -1, -1, -1, 1, 0},
738 {-1, -1, -1, -1, -1, -1, -1, -1}},
739 {{-1, 5, -1, -1, -1, -1, 5, -1},
740 { 0, -1, -1, 0, -1, -1, 0, -1},
741 { 0, 0, 0, 2, 2, 0, 0, 0},
742 { 0, -1, -1, 0, -1, -1, 0, -1},
743 {-1, 7, -1, 3, -1, -1, 7, -1},
744 {-1, -1, 3, 6, -1, -1, -1, -1},
745 {-1, -1, -1, 6, -1, -1, -1, -1},
746 {-1, 3, 6, -1, -1, -1, -1, -1},
747 {-1, 3, -1, -1, -1, -1, -1, -1},
748 {-1, -1, -1, -1, -1, -1, -1, -1}},
749 {{-1, -1, -1, 6, 5, -1, -1, -1},
750 {-1, -1, 2, 6, 3, -1, -1, -1},
751 {-1, -1, 5, 4, 7, 1, -1, -1},
752 {-1, 6, 2, 2, 3, 4, -1, -1},
753 {-1, -1, 3, 7, 3, 6, -1, -1},
754 {-1, -1, 1, 3, 2, -1, -1, -1},
755 {-1, -1, -1, 4, 5, -1, -1, -1},
756 {-1, -1, -1, 4, -1, -1, -1, -1},
757 {-1, -1, -1, -1, -1, -1, -1, -1},
758 {-1, -1, -1, -1, -1, -1, -1, -1}},
759 {{ 7, 7, -1, 2, 2, -1, 6, 6},
760 { 6, -1, -1, 6, -1, -1, 3, -1},
761 { 2, -1, -1, 1, -1, -1, 2, -1},
762 { 5, -1, -1, 3, -1, -1, 2, -1},
763 { 1, -1, -1, 2, -1, -1, 1, -1},
764 { 5, -1, -1, 2, -1, -1, 2, -1},
765 { 6, -1, -1, 1, -1, -1, 7, -1},
766 { 5, -1, -1, 5, -1, -1, 4, -1},
767 {-1, -1, -1, -1, -1, -1, -1, -1},
768 {-1, -1, -1, -1, -1, -1, -1, -1}},
769 {{-1, -1, -1, 6, 6, -1, -1, -1},
770 {-1, 0, 4, 4, 4, 0, -1, -1},
771 {-1, -1, -1, 6, 6, -1, -1, -1},
772 {-1, -1, 2, 7, 2, -1, -1, -1},
773 {-1, -1, -1, 6, 6, -1, -1, -1},
774 {-1, 0, 5, 5, 5, 0, -1, -1},
775 {-1, -1, -1, 3, 3, -1, -1, -1},
776 {-1, -1, -1, -1, -1, -1, -1, -1},
777 {-1, -1, -1, -1, -1, -1, -1, -1},
778 {-1, -1, -1, -1, -1, -1, -1, -1}},
779 {{-1, -1, 4, 1, 3, -1, -1, -1},
780 {-1, 1, -1, -1, 1, -1, -1, -1},
781 {-1, -1, 4, 1, 3, 4, 1, -1},
782 {-1, 1, 3, 4, -1, -1, 4, -1},
783 {-1, 3, -1, -1, 3, 4, 1, -1},
784 {-1, 1, 3, 4, 1, 3, -1, -1},
785 {-1, -1, 4, 1, -1, -1, -1, -1},
786 {-1, -1, -1, -1, -1, -1, -1, -1},
787 {-1, -1, -1, -1, -1, -1, -1, -1},
788 {-1, -1, -1, -1, -1, -1, -1, -1}},
789 {{-1, 6, 4, -1, 3, 2, 5, -1},
790 { 0, -1, -1, -1, -1, -1, 1, -1},
791 {-1, 2, 3, 5, -1, 4, 6, -1},
792 { 0, -1, -1, -1, -1, -1, 1, -1},
793 {-1, 4, 6, -1, 2, 5, 3, -1},
794 { 0, -1, -1, -1, -1, -1, 1, -1},
795 {-1, 5, 2, 3, -1, 4, 6, -1},
796 {-1, -1, -1, -1, -1, -1, -1, -1},
797 {-1, -1, -1, -1, -1, -1, -1, -1},
798 {-1, -1, -1, -1, -1, -1, -1, -1}},
799 {{-1, -1, -1, 6, 6, -1, -1, -1},
800 {-1, -1, 7, 6, 4, -1, -1, -1},
801 {-1, 2, 1, 7, 4, 1, 3, -1},
802 { 2, 1, 1, 1, 1, 1, 3, -1},
803 {-1, 2, 2, 2, 3, 3, 3, -1},
804 {-1, -1, -1, 5, -1, -1, -1, -1},
805 {-1, -1, -1, 2, 3, -1, -1, -1},
806 {-1, -1, -1, 5, -1, -1, -1, -1},
807 {-1, -1, 2, 2, 3, 3, -1, -1},
808 {-1, -1, -1, -1, -1, -1, -1, -1}},
809 {{ 4, -1, 5, -1, -1, 3, -1, 6},
810 { 2, -1, 3, -1, 2, -1, 4, -1},
811 { 4, -1, -1, 1, 0, -1, -1, 6},
812 { 6, -1, 2, 3, 5, -1, 4, -1},
813 { 4, -1, -1, 0, 1, -1, -1, 6},
814 { 2, -1, 5, -1, 3, -1, 4, -1},
815 { 4, -1, 3, -1, -1, 2, -1, 6},
816 { 6, -1, -1, -1, -1, -1, 4, -1},
817 {-1, -1, -1, -1, -1, -1, -1, -1},
818 {-1, -1, -1, -1, -1, -1, -1, -1}},
819 {{ 2, 6, 0, 5, 5, 1, 3, 4},
820 { 1, -1, -1, 2, -1, -1, 0, -1},
821 { 4, -1, -1, 3, 6, -1, -1, 2},
822 {-1, -1, -1, 0, -1, -1, -1, -1},
823 {-1, -1, -1, 1, 4, -1, -1, -1},
824 {-1, -1, -1, 2, -1, -1, -1, -1},
825 {-1, -1, -1, 6, 3, -1, -1, -1},
826 {-1, -1, -1, 5, -1, -1, -1, -1},
827 {-1, -1, -1, 4, 1, -1, -1, -1},
828 {-1, -1, -1, -1, -1, -1, -1, -1}},
829 {{-1, -1, -1, -1, 5, 1, 1, 3},
830 { 0, 5, 1, 0, 5, 3, 3, -1},
831 { 5, 1, 0, 5, 1, 0, 5, 1},
832 { 0, 5, 1, 0, 5, 1, 6, -1},
833 {-1, -1, -1, -1, 1, 6, 5, 1},
834 {-1, -1, -1, -1, 5, 1, 6, -1},
835 {-1, -1, -1, -1, 1, 0, 5, 1},
836 {-1, -1, -1, -1, 5, 1, 0, -1},
837 {-1, -1, -1, -1, -1, -1, -1, -1},
838 {-1, -1, -1, -1, -1, -1, -1, -1}},
839 {{-1, 0, 7, 3, -1, -1, 2, 2},
840 {-1, 0, 7, 3, -1, -1, 2, -1},
841 {-1, 0, 7, 3, -1, -1, 2, 2},
842 {-1, 0, 7, 3, -1, 3, 1, -1},
843 {-1, 0, 7, 3, -1, 6, 4, 5},
844 {-1, 0, 7, 3, -1, 7, 0, -1},
845 {-1, 0, 7, 3, -1, 2, 3, 4},
846 {-1, 0, 7, 3, -1, 5, 6, -1},
847 {-1, -1, -1, -1, -1, 7, 0, 1},
848 {-1, -1, -1, -1, -1, -1, -1, -1}},
849 {{-1, -1, -1, 7, 7, 7, 7, -1},
850 { 3, 4, 5, -1, -1, -1, 7, -1},
851 { 2, -1, -1, -1, -1, -1, -1, 3},
852 { 7, -1, -1, -1, -1, -1, 4, -1},
853 { 7, -1, -1, -1, 3, 4, 5, 6},
854 { 7, -1, -1, 2, 0, 1, 2, -1},
855 { 6, -1, -1, -1, 3, 4, 5, 6},
856 { 0, 1, -1, -1, -1, -1, -1, -1},
857 { 2, 3, 4, -1, -1, -1, -1, -1},
858 { 5, 6, 0, -1, -1, -1, -1, -1}},
859 {{-1, 7, -1, -1, -1, -1, 2, -1},
860 { 1, 1, -1, -1, -1, 3, 3, -1},
861 {-1, 2, -1, -1, -1, -1, 4, -1},
862 { 3, 3, -1, -1, -1, 5, 5, -1},
863 {-1, 4, -1, -1, -1, -1, 6, -1},
864 { 5, 5, -1, -1, -1, 1, 1, -1},
865 {-1, 6, -1, -1, -1, -1, 7, -1},
866 {-1, -1, -1, -1, -1, -1, -1, -1},
867 {-1, -1, -1, -1, -1, -1, -1, -1},
868 {-1, -1, -1, -1, -1, -1, -1, -1}},
869 {{-1, 4, -1, -1, -1, -1, 4, -1},
870 { 2, -1, -1, 1, -1, -1, 2, -1},
871 { 5, -1, -1, 0, 0, -1, -1, 5},
872 { 5, -1, -1, 1, -1, -1, 6, -1},
873 {-1, 4, 2, 7, 7, 5, 4, -1},
874 {-1, -1, -1, 6, -1, -1, -1, -1},
875 {-1, -1, -1, 3, 3, -1, -1, -1},
876 {-1, -1, -1, 7, -1, -1, -1, -1},
877 {-1, -1, -1, -1, -1, -1, -1, -1},
878 {-1, -1, -1, -1, -1, -1, -1, -1}},
879 {{-1, 1, -1, -1, 2, 3, 4, -1},
880 { 2, -1, -1, 3, 0, 4, -1, -1},
881 { 4, -1, -1, 2, 3, 1, -1, -1},
882 { 3, -1, 4, 3, 0, -1, -1, -1},
883 { 4, -1, -1, 2, 5, 1, -1, -1},
884 { 3, -1, 4, 5, 0, 4, -1, -1},
885 {-1, -1, -1, -1, -1, -1, -1, -1},
886 {-1, -1, -1, -1, -1, -1, -1, -1},
887 {-1, -1, -1, -1, -1, -1, -1, -1},
888 {-1, -1, -1, -1, -1, -1, -1, -1}},
889 {{ 2, -1, -1, 1, 1, -1, -1, 2},
890 { 2, -1, 3, 3, 3, -1, 2, -1},
891 {-1, 2, -1, 4, 4, -1, 2, -1},
892 {-1, 7, 7, 0, 7, 7, -1, -1},
893 {-1, -1, -1, 4, 4, -1, -1, -1},
894 {-1, -1, 5, 7, 5, -1, -1, -1},
895 { 6, 3, 2, 6, 4, 2, 3, 6},
896 { 5, -1, -1, -1, -1, -1, 1, -1},
897 {-1, -1, -1, -1, -1, -1, -1, -1},
898 {-1, -1, -1, -1, -1, -1, -1, -1}},
899 {{ 4, 2, 3, 5, 7, 1, 3, 6},
900 { 1, -1, -1, 1, -1, -1, 1, -1},
901 { 3, 0, 1, 3, 2, 4, 3, 5},
902 { 4, -1, -1, 4, -1, -1, 4, -1},
903 {-1, 5, -1, -1, 5, -1, -1, 5},
904 { 0, 3, 2, 0, 4, 5, 0, -1},
905 {-1, 6, -1, -1, 6, -1, -1, 6},
906 { 7, -1, -1, 7, -1, -1, 7, -1},
907 {-1, -1, -1, -1, -1, -1, -1, -1},
908 {-1, -1, -1, -1, -1, -1, -1, -1}},
909 {{-1, 5, 4, -1, 1, 1, -1, -1},
910 { 5, -1, 4, 1, -1, 1, -1, -1},
911 { 0, -1, -1, -1, -1, -1, 0, -1},
912 { 0, 6, 4, -1, -1, 4, 2, -1},
913 {-1, 4, 3, 5, 2, 6, 3, 6},
914 {-1, 2, 6, -1, -1, 5, 4, -1},
915 {-1, -1, -1, -1, -1, -1, -1, -1},
916 {-1, -1, -1, -1, -1, -1, -1, -1},
917 {-1, -1, -1, -1, -1, -1, -1, -1},
918 {-1, -1, -1, -1, -1, -1, -1, -1}},
919 {{-1, -1, -1, 6, 6, -1, -1, -1},
920 {-1, -1, 5, 5, 4, -1, -1, -1},
921 {-1, -1, 1, 6, 6, 4, -1, -1},
922 {-1, 1, 7, 2, 5, 3, -1, -1},
923 {-1, 2, 7, 2, 1, 5, 3, -1},
924 { 2, 1, 3, 1, 4, 2, 7, -1},
925 {-1, 3, 1, 3, 4, 2, 7, -1},
926 {-1, 3, 5, 5, 6, 6, -1, -1},
927 {-1, -1, -1, -1, -1, -1, -1, -1},
928 {-1, -1, -1, -1, -1, -1, -1, -1}},
929 {{-1, -1, 7, 3, -1, -1, -1, -1},
930 {-1, 1, 7, 6, -1, -1, -1, -1},
931 {-1, 3, 7, 5, 1, 5, -1, -1},
932 { 7, 7, 0, 2, 4, 0, 4, -1},
933 { 7, 1, 4, 6, 5, 6, 5, 7},
934 { 1, 7, 7, 1, 7, 7, 1, -1},
935 {-1, -1, -1, -1, -1, -1, -1, -1},
936 {-1, -1, -1, -1, -1, -1, -1, -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, 5, 6, 1, 5, 6, -1, -1},
941 {-1, 1, 1, 2, 2, 1, 1, -1},
942 { 4, 7, 1, 0, 1, 7, 4, -1},
943 {-1, 3, 7, 5, 7, 5, 3, -1},
944 {-1, 1, 1, 1, 1, 1, -1, -1},
945 {-1, -1, -1, -1, -1, -1, -1, -1},
946 {-1, -1, -1, -1, -1, -1, -1, -1},
947 {-1, -1, -1, -1, -1, -1, -1, -1},
948 {-1, -1, -1, -1, -1, -1, -1, -1}},
949 {{ 4, -1, -1, -1, 5, -1, -1, 4},
950 { 6, 6, 7, 6, -1, 4, 5, -1},
951 { 4, 2, 7, 5, 2, 2, 6, 4},
952 {-1, -1, 4, 1, -1, 5, 2, -1},
953 {-1, 5, 2, 7, 7, -1, 7, 4},
954 { 4, 6, 5, 4, -1, 4, 2, -1},
955 {-1, -1, -1, 4, -1, 4, 1, -1},
956 { 0, 0, 0, 5, -1, -1, -1, -1},
957 {-1, -1, -1, -1, 0, 0, 0, 0},
958 {-1, -1, -1, -1, -1, -1, -1, -1}},
959 {{ 1, -1, -1, -1, 0, 0, -1, -1},
960 { 2, -1, -1, 0, 1, 0, -1, -1},
961 { 3, -1, -1, 0, 2, 2, 0, -1},
962 { 4, -1, 0, 1, 1, 1, 0, -1},
963 { 5, -1, -1, 0, 4, 4, 0, -1},
964 { 6, -1, -1, 4, 4, 4, -1, -1},
965 { 7, -1, -1, -1, 4, 4, -1, -1},
966 {-1, -1, -1, 0, 1, 0, -1, -1},
967 {-1, -1, -1, 0, 1, 1, 0, -1},
968 {-1, -1, -1, -1, -1, -1, -1, -1}},
969 {{-1, -1, 3, -1, -1, 1, 7, -1},
970 {-1, 7, 4, -1, -1, 4, 3, -1},
971 { 1, -1, -1, 0, 2, 0, -1, -1},
972 { 5, 4, -1, 3, -1, -1, -1, -1},
973 { 4, -1, 3, 6, 1, 1, 6, -1},
974 {-1, 1, -1, -1, 4, -1, 1, -1},
975 {-1, 7, 5, -1, -1, -1, 3, -1},
976 {-1, -1, 3, -1, -1, -1, -1, -1},
977 {-1, -1, -1, -1, -1, -1, -1, -1},
978 {-1, -1, -1, -1, -1, -1, -1, -1}},
979 {{ 1, -1, -1, -1, 1, -1, -1, -1},
980 { 2, -1, -1, -1, 2, -1, -1, -1},
981 {-1, 3, -1, -1, 3, 3, -1, -1},
982 {-1, 4, -1, 4, -1, 4, -1, -1},
983 {-1, 5, -1, -1, 5, 5, -1, -1},
984 { 6, -1, -1, 7, 1, 7, -1, -1},
985 { 7, -1, -1, -1, 6, 6, -1, -1},
986 {-1, -1, -1, -1, -1, -1, -1, -1},
987 {-1, -1, -1, -1, -1, -1, -1, -1},
988 {-1, -1, -1, -1, -1, -1, -1, -1}},
989 {{ 2, -1, -1, 6, -1, 2, 5, 1},
990 { 5, -1, 4, -1, 4, -1, 4, -1},
991 { 6, -1, -1, 3, -1, -1, -1, 3},
992 { 4, 2, 0, -1, -1, -1, 5, -1},
993 {-1, -1, -1, 6, -1, 3, 6, -1},
994 {-1, -1, 5, -1, 5, -1, -1, -1},
995 {-1, -1, -1, 3, -1, 4, 2, 5},
996 {-1, -1, -1, -1, -1, -1, -1, -1},
997 {-1, -1, -1, -1, -1, -1, -1, -1},
998 {-1, -1, -1, -1, -1, -1, -1, -1}},
999 {{ 6, -1, -1, -1, 4, -1, -1, 3},
1000 { 0, 3, -1, -1, 6, -1, 0, -1},
1001 {-1, -1, 7, -1, 1, -1, 3, -1},
1002 { 7, -1, 4, 7, -1, 2, -1, -1},
1003 { 5, 2, 3, 2, 1, 6, -1, 3},
1004 {-1, -1, 0, 4, 3, 5, 4, -1},
1005 {-1, 7, 6, -1, -1, 0, -1, -1},
1006 { 4, 3, -1, -1, -1, 4, 2, -1},
1007 { 0, -1, -1, -1, -1, -1, 6, -1},
1008 {-1, -1, -1, -1, -1, -1, -1, -1}},
1009 {{ 6, 1, 2, 5, 1, 6, 3, 0},
1010 {-1, -1, -1, -1, -1, -1, 4, -1},
1011 { 0, 5, 2, 7, 1, 6, 2, -1},
1012 { 3, -1, -1, -1, -1, -1, -1, -1},
1013 { 6, 7, 6, 4, 0, 5, 2, 6},
1014 {-1, -1, -1, -1, -1, -1, 1, -1},
1015 { 6, 1, 4, 0, 6, 2, 3, -1},
1016 { 0, -1, -1, -1, -1, -1, -1, -1},
1017 {-1, 0, 4, 5, 3, 7, 6, 0},
1018 {-1, -1, -1, -1, -1, -1, -1, -1}},
1019 {{-1, -1, -1, 0, 1, -1, -1, -1},
1020 {-1, -1, 0, 7, 0, -1, -1, -1},
1021 {-1, -1, 1, 2, 2, 0, -1, -1},
1022 {-1, 0, 7, 0, 7, 0, -1, -1},
1023 {-1, 6, -1, 7, 7, -1, 6, -1},
1024 { 4, 1, 6, 6, 6, 4, 1, -1},
1025 {-1, 5, -1, 7, 7, -1, 5, -1},
1026 {-1, -1, -1, -1, -1, -1, -1, -1},
1027 {-1, -1, -1, -1, -1, -1, -1, -1},
1028 {-1, -1, -1, -1, -1, -1, -1, -1}},
1029 {{-1, -1, -1, 5, 6, -1, -1, -1},
1030 {-1, -1, 3, 3, 3, -1, -1, -1},
1031 {-1, -1, 7, 5, 3, 7, -1, -1},
1032 {-1, 3, -1, 6, -1, 3, -1, -1},
1033 { 2, -1, -1, 3, 7, -1, -1, 1},
1034 { 2, 2, -1, 3, -1, 1, 1, -1},
1035 {-1, 0, 2, 5, 6, 1, 0, -1},
1036 {-1, -1, -1, 3, -1, -1, -1, -1},
1037 {-1, -1, -1, 3, 7, -1, -1, -1},
1038 {-1, -1, -1, -1, -1, -1, -1, -1}},
1039 {{-1, 6, -1, -1, -1, -1, 2, -1},
1040 {-1, 2, 6, 0, 6, 0, -1, -1},
1041 {-1, 0, -1, -1, -1, -1, -1, -1},
1042 { 6, -1, -1, -1, -1, -1, -1, -1},
1043 {-1, 3, 3, 2, 0, 6, 0, 0},
1044 {-1, 6, -1, -1, -1, -1, 0, -1},
1045 {-1, -1, -1, 6, 0, 2, 6, -1},
1046 {-1, 2, 0, -1, -1, -1, -1, -1},
1047 {-1, -1, -1, -1, -1, -1, -1, -1},
1048 {-1, -1, -1, -1, -1, -1, -1, -1}},
1049 {{ 0, 7, -1, -1, -1, -1, -1, -1},
1050 { 1, 5, -1, -1, -1, -1, -1, -1},
1051 { 7, 2, 5, -1, -1, -1, -1, -1},
1052 { 6, 3, 4, -1, -1, -1, -1, -1},
1053 { 5, 5, 4, 4, -1, -1, -1, -1},
1054 { 3, 3, 5, 3, -1, -1, -1, -1},
1055 { 1, 2, 2, 5, 3, -1, -1, -1},
1056 { 1, 0, 0, 7, 6, -1, -1, -1},
1057 { 3, 3, 5, 5, 7, 6, -1, -1},
1058 {-1, -1, -1, -1, -1, -1, -1, -1}},
1059 {{-1, -1, 2, 6, 6, 2, -1, -1},
1060 {-1, 2, 1, 1, 0, 2, -1, -1},
1061 {-1, 2, 3, 2, 2, 0, 2, -1},
1062 { 2, 3, 2, 5, 2, 7, 2, -1},
1063 { 2, 4, 2, 5, 2, 7, 2, 0},
1064 { 2, 4, 2, 6, 6, 2, 0, -1},
1065 {-1, 2, 5, 2, 2, 2, 7, 2},
1066 {-1, 2, 5, 6, 6, 7, 2, -1},
1067 {-1, -1, 2, 2, 2, 2, 2, -1},
1068 {-1, -1, -1, -1, -1, -1, -1, -1}},
1069 {{-1, -1, 0, -1, -1, 0, -1, -1},
1070 { 1, 0, 0, 1, 0, 0, 1, -1},
1071 { 1, 7, 7, 5, 5, 7, 7, 1},
1072 { 3, 2, -1, 2, -1, 2, 3, -1},
1073 { 3, 7, -1, 6, 6, -1, 7, 3},
1074 { 7, -1, -1, 6, -1, -1, 7, -1},
1075 { 4, 4, 5, -1, -1, 5, 4, 4},
1076 {-1, -1, -1, -1, -1, -1, -1, -1},
1077 {-1, -1, -1, -1, -1, -1, -1, -1},
1078 {-1, -1, -1, -1, -1, -1, -1, -1}},
1079 {{-1, 6, 3, -1, -1, 3, 6, -1},
1080 { 6, -1, 2, -1, 2, -1, 6, -1},
1081 { 2, -1, 0, 1, 1, 0, -1, 2},
1082 { 5, 0, -1, 7, -1, 0, 5, -1},
1083 {-1, 5, -1, 6, 6, -1, 5, -1},
1084 { 7, 1, 4, -1, 4, 1, 7, -1},
1085 { 7, -1, 4, -1, -1, 4, -1, 7},
1086 { 2, 0, -1, -1, -1, 0, 2, -1},
1087 {-1, 2, -1, -1, -1, -1, 2, -1},
1088 {-1, -1, -1, -1, -1, -1, -1, -1}},
1089 {{ 6, 1, -1, -1, -1, -1, 4, 0},
1090 { 2, 7, 5, 5, 5, 7, 3, -1},
1091 { 6, 1, -1, -1, -1, -1, 4, 0},
1092 { 2, 5, 7, 7, 7, 5, 3, -1},
1093 { 6, 1, -1, -1, -1, -1, 4, 0},
1094 { 2, 0, 6, 6, 6, 0, 3, -1},
1095 { 6, 1, -1, -1, -1, -1, 4, 0},
1096 {-1, -1, -1, -1, -1, -1, -1, -1},
1097 {-1, -1, -1, -1, -1, -1, -1, -1},
1098 {-1, -1, -1, -1, -1, -1, -1, -1}},
1099 {{ 5, -1, -1, 1, 1, -1, -1, 5},
1100 { 5, -1, 4, -1, 4, -1, 5, -1},
1101 {-1, 2, 4, -1, -1, 4, 2, -1},
1102 { 7, 2, -1, -1, -1, 2, 7, -1},
1103 { 0, -1, 0, 4, 4, 0, -1, 0},
1104 { 7, 2, -1, -1, -1, 2, 7, -1},
1105 {-1, 2, 3, -1, -1, 3, 2, -1},
1106 { 5, -1, 3, -1, 3, -1, 5, -1},
1107 { 5, -1, -1, 6, 6, -1, -1, 5},
1108 {-1, -1, -1, -1, -1, -1, -1, -1}},
1109 {{ 2, 2, -1, -1, -1, -1, 5, 5},
1110 { 5, -1, -1, -1, -1, -1, 2, -1},
1111 { 5, -1, -1, -1, -1, -1, -1, 2},
1112 { 1, -1, 1, 5, 1, -1, 3, -1},
1113 { 5, 2, 5, 3, 1, 2, 5, 2},
1114 { 2, 0, 5, -1, 2, 0, 5, -1},
1115 {-1, 3, 7, -1, -1, 3, 7, -1},
1116 {-1, -1, 2, 0, 5, -1, -1, -1},
1117 {-1, -1, -1, -1, -1, -1, -1, -1},
1118 {-1, -1, -1, -1, -1, -1, -1, -1}},
1119 {{ 0, 6, 5, 2, 3, 4, 1, 7},
1120 {-1, -1, -1, -1, 1, -1, -1, -1},
1121 {-1, -1, -1, 1, 1, -1, -1, -1},
1122 {-1, -1, 1, -1, -1, -1, -1, -1},
1123 { 7, 1, 4, 3, 2, 5, 6, 0},
1124 {-1, -1, -1, -1, 1, -1, -1, -1},
1125 {-1, -1, -1, 1, 1, -1, -1, -1},
1126 {-1, -1, 1, -1, -1, -1, -1, -1},
1127 { 0, 6, 5, 2, 3, 4, 1, 7},
1128 {-1, -1, -1, -1, -1, -1, -1, -1}},
1129 {{-1, -1, 1, -1, -1, 1, -1, -1},
1130 {-1, 2, 4, -1, 2, 4, -1, -1},
1131 {-1, 2, 3, 6, 5, 3, 2, -1},
1132 {-1, 6, 5, -1, 6, 5, -1, -1},
1133 {-1, -1, -1, 7, 7, -1, -1, -1},
1134 {-1, -1, -1, 7, -1, -1, -1, -1},
1135 { 1, -1, -1, 7, 7, -1, -1, 3},
1136 { 2, -1, -1, 7, -1, -1, 2, -1},
1137 {-1, 3, 4, 5, 6, 4, 1, -1},
1138 {-1, -1, -1, -1, -1, -1, -1, -1}},
1139 {{ 1, -1, -1, 2, 2, -1, -1, 2},
1140 { 1, 3, 7, 3, 7, 4, 2, -1},
1141 {-1, 1, 6, -1, -1, 6, 2, -1},
1142 { 6, -1, 7, 3, 7, -1, 6, -1},
1143 {-1, 4, 2, -1, -1, 1, 3, -1},
1144 {-1, -1, 2, 6, 1, -1, -1, -1},
1145 {-1, 4, 3, 3, 4, 4, 3, -1},
1146 {-1, -1, -1, -1, -1, -1, -1, -1},
1147 {-1, -1, -1, -1, -1, -1, -1, -1},
1148 {-1, -1, -1, -1, -1, -1, -1, -1}},
1149 {{-1, -1, -1, 5, 6, -1, -1, -1},
1150 {-1, -1, -1, 3, -1, -1, -1, -1},
1151 {-1, -1, -1, 1, 2, -1, -1, -1},
1152 {-1, -1, -1, 4, -1, -1, -1, -1},
1153 {-1, -1, -1, 5, 7, -1, -1, -1},
1154 {-1, -1, -1, 2, -1, -1, -1, -1},
1155 { 6, 5, 4, 3, 2, 1, 7, 5},
1156 {-1, -1, -1, -1, -1, -1, -1, -1},
1157 {-1, -1, -1, -1, -1, -1, -1, -1},
1158 {-1, -1, -1, -1, -1, -1, -1, -1}},
1159 {{-1, 0, -1, 1, -1, 2, -1, -1},
1160 {-1, 4, -1, 5, -1, 6, -1, -1},
1161 {-1, 7, -1, 0, -1, 2, -1, -1},
1162 {-1, 6, -1, 3, -1, 6, -1, -1},
1163 {-1, 1, -1, 1, -1, 2, -1, -1},
1164 {-1, 3, -1, 5, -1, 0, -1, -1},
1165 {-1, 2, -1, 4, -1, 6, -1, -1},
1166 {-1, 3, -1, 6, -1, 7, -1, -1},
1167 {-1, -1, -1, -1, -1, -1, -1, -1},
1168 {-1, -1, -1, -1, -1, -1, -1, -1}},
1169 {{ 1, 1, 2, 2, 3, 3, 4, 4},
1170 { 5, 5, 6, 7, 6, 5, 5, -1},
1171 { 6, 4, 3, 3, 2, 2, 1, 6},
1172 { 4, 6, 5, 7, 6, 3, 1, -1},
1173 {-1, -1, -1, -1, -1, -1, -1, -1},
1174 {-1, -1, -1, -1, -1, -1, -1, -1},
1175 {-1, -1, -1, -1, -1, -1, -1, -1},
1176 {-1, -1, -1, -1, -1, -1, -1, -1},
1177 {-1, -1, -1, -1, -1, -1, -1, -1},
1178 {-1, -1, -1, -1, -1, -1, -1, -1}},
1179 {{ 7, 4, -1, 1, 2, -1, 4, 7},
1180 { 5, 5, -1, 2, -1, 4, 4, -1},
1181 {-1, 5, -1, 7, 7, -1, 4, -1},
1182 { 1, 0, 6, 7, 6, 0, 2, -1},
1183 {-1, 2, -1, 5, 3, -1, 1, -1},
1184 { 1, 1, -1, -1, -1, 2, 2, -1},
1185 { 6, 1, 4, -1, -1, 4, 2, 6},
1186 { 5, 3, -1, -1, -1, 3, 5, -1},
1187 {-1, -1, -1, -1, -1, -1, -1, -1},
1188 {-1, -1, -1, -1, -1, -1, -1, -1}},
1189 {{ 1, 5, 1, 0, 0, 1, 5, 1},
1190 { 1, 2, 5, -1, 5, 2, 1, -1},
1191 { 3, 6, 1, 2, 2, 1, 6, 3},
1192 { 4, 3, 4, -1, 4, 3, 4, -1},
1193 { 3, 4, 6, 5, 5, 6, 4, 3},
1194 { 0, 2, 3, -1, 3, 2, 0, -1},
1195 { 2, 3, 1, 5, 5, 1, 3, 2},
1196 {-1, -1, -1, -1, -1, -1, -1, -1},
1197 {-1, -1, -1, -1, -1, -1, -1, -1},
1198 {-1, -1, -1, -1, -1, -1, -1, -1}},
1199 {{ 3, 0, 2, 7, 5, 7, 6, 5},
1200 { 6, -1, 1, -1, 2, -1, 1, -1},
1201 {-1, 6, 4, 0, 3, 4, 5, -1},
1202 {-1, 5, -1, 1, -1, 4, -1, -1},
1203 {-1, 7, 3, 5, 6, 5, 3, -1},
1204 { 1, -1, 2, -1, 4, -1, 2, -1},
1205 { 6, 4, 4, 6, 6, 5, 5, 1},
1206 {-1, -1, -1, -1, -1, -1, -1, -1},
1207 {-1, -1, -1, -1, -1, -1, -1, -1},
1208 {-1, -1, -1, -1, -1, -1, -1, -1}}
1212 * type is the bubble number 0-7
1213 * fallx is the x axis movement for the falling bubble
1214 * fallvel is the initial upward velocity for the falling bubble
1215 * ingroup denotes a bubble that is part of a group to be removed
1216 * anchored denotes a bubble that is anchored to the ceiling
1227 /* the game context struct
1228 * score is the current score
1229 * level is the current level
1230 * highlevel is the highest level beaten
1231 * highscores is the list of high scores
1232 * angle is the current cannon direction
1233 * shots is the number of shots fired since last compression
1234 * compress is the height of the compressor
1235 * onboardcnt is the number of unique bubbles on the playing board
1236 * onboard is the unique bubbles on the playing board
1237 * nextinq is the pointer to the next bubble in the firing queue
1238 * queue is the circular buffer of bubbles to be fired
1239 * elapsedlvl is level elapsed time in 1/100s of seconds
1240 * elapsedshot is the shot elapsed time in 1/100s of seconds
1241 * startedshot is when the current shot began
1242 * resume denotes whether to resume the currently loaded game
1243 * dirty denotes whether the high scores are out of sync with the saved file
1244 * playboard is the game playing board
1246 struct game_context
{
1249 struct highscore highlevel
;
1250 struct highscore highscores
[NUM_SCORES
];
1255 int onboard
[NUM_BUBBLES
];
1257 int queue
[NUM_QUEUE
];
1263 struct tile playboard
[BB_HEIGHT
][BB_WIDTH
];
1266 static void bubbles_init(struct game_context
* bb
);
1267 static bool bubbles_nextlevel(struct game_context
* bb
);
1268 static void bubbles_getonboard(struct game_context
* bb
);
1269 static void bubbles_drawboard(struct game_context
* bb
);
1270 static int bubbles_fire(struct game_context
* bb
);
1271 static bool bubbles_collision(struct game_context
* bb
, int y
, int x
,
1272 int nearrow
, int nearcol
);
1273 static bool bubbles_ingroup(struct game_context
* bb
, int row
, int col
);
1274 static int bubbles_searchgroup(struct game_context
* bb
, int row
, int col
);
1275 static int bubbles_remove(struct game_context
* bb
);
1276 static void bubbles_anchored(struct game_context
* bb
, int row
, int col
);
1277 static int bubbles_fall(struct game_context
* bb
);
1278 static int bubbles_checklevel(struct game_context
* bb
);
1279 static void bubbles_recordscore(struct game_context
* bb
);
1280 static void bubbles_displayscores(struct game_context
* bb
, int position
);
1281 static void bubbles_savescores(struct game_context
* bb
);
1282 static bool bubbles_loadgame(struct game_context
* bb
);
1283 static void bubbles_savegame(struct game_context
* bb
);
1284 static inline void bubbles_setcolors(void);
1285 static void bubbles_callback(void* param
);
1286 static int bubbles_handlebuttons(struct game_context
* bb
, bool animblock
,
1288 static int bubbles(struct game_context
* bb
);
1290 /*****************************************************************************
1291 * bubbles_init() initializes bubbles data structures.
1292 ******************************************************************************/
1293 static void bubbles_init(struct game_context
* bb
) {
1294 /* seed the rand generator */
1295 rb
->srand(*rb
->current_tick
);
1297 /* check for resumed game */
1304 bubbles_nextlevel(bb
);
1307 /*****************************************************************************
1308 * bubbles_nextlevel() sets up the game for the next level, returns false if
1309 * there are no more levels.
1310 ******************************************************************************/
1311 static bool bubbles_nextlevel(struct game_context
* bb
) {
1316 /* check if there are no more levels */
1317 if(bb
->level
> NUM_LEVELS
) return false;
1319 /* set up the play board */
1320 rb
->memset(bb
->playboard
, 0, sizeof(bb
->playboard
));
1321 for(i
=0; i
<BB_LEVEL_HEIGHT
; i
++) {
1322 for(j
=0; j
<BB_WIDTH
; j
++) {
1323 pos
= (int)level
[bb
->level
-1][i
][j
];
1324 if(pos
>=0 && pos
< NUM_BUBBLES
) {
1325 bb
->playboard
[i
][j
].type
= pos
;
1327 bb
->playboard
[i
][j
].type
= -1;
1331 for(i
=BB_LEVEL_HEIGHT
; i
<BB_HEIGHT
; i
++) {
1332 for(j
=0; j
<BB_WIDTH
; j
++) {
1333 bb
->playboard
[i
][j
].type
= -1;
1337 /* fill first bubbles in shot queue */
1338 bubbles_getonboard(bb
);
1339 for(i
=0; i
<NUM_QUEUE
; i
++) {
1340 bb
->queue
[i
] = bb
->onboard
[rb
->rand()%bb
->onboardcnt
];
1348 bb
->elapsedshot
= 0;
1353 /*****************************************************************************
1354 * bubbles_getonboard() determines which bubble types are on the play board.
1355 ******************************************************************************/
1356 static void bubbles_getonboard(struct game_context
* bb
) {
1361 rb
->memset(bb
->onboard
, -1, sizeof(bb
->onboard
));
1363 for(i
=0; i
<BB_HEIGHT
; i
++) {
1364 for(j
=0; j
<BB_WIDTH
; j
++) {
1365 if(bb
->playboard
[i
][j
].type
>= 0) {
1368 for(k
=0; k
<bb
->onboardcnt
; k
++) {
1369 if(bb
->playboard
[i
][j
].type
== bb
->onboard
[k
]) {
1376 bb
->onboard
[bb
->onboardcnt
] = bb
->playboard
[i
][j
].type
;
1380 if(bb
->onboardcnt
== NUM_BUBBLES
) return;
1386 /*****************************************************************************
1387 * bubbles_drawboard() draws the game board to the buffer but does not update
1389 ******************************************************************************/
1390 static void bubbles_drawboard(struct game_context
* bb
) {
1395 bool evenline
= false;
1396 char *level
= "Level";
1397 char *score
= "Score";
1398 char *next
= "Next";
1399 char *hurry
= "HURRY!";
1403 rb
->lcd_clear_display();
1405 /* draw background */
1406 #ifdef HAVE_LCD_COLOR
1407 rb
->lcd_bitmap(bubbles_background
, 0, 0, LCD_WIDTH
, LCD_HEIGHT
);
1410 /* display play board */
1411 for(i
=0; i
<BB_HEIGHT
; i
++) {
1415 indent
= ROW_INDENT
;
1419 evenline
= !evenline
;
1421 for(j
=0; j
<colmax
; j
++) {
1422 if(bb
->playboard
[i
][j
].type
>= 0 && !bb
->playboard
[i
][j
].delete) {
1423 rb
->lcd_bitmap_part(bubbles_emblem
,
1424 0, EMBLEM_HEIGHT
*bb
->playboard
[i
][j
].type
, EMBLEM_WIDTH
,
1425 XOFS
+indent
+BUBBLE_WIDTH
*j
+(BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2,
1426 ROW_HEIGHT
*i
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2+bb
->compress
*ROW_HEIGHT
,
1427 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
1428 rb
->lcd_set_drawmode(DRMODE_FG
);
1429 rb
->lcd_mono_bitmap((const unsigned char *)bubbles_bubble
,
1430 XOFS
+indent
+BUBBLE_WIDTH
*j
,
1431 ROW_HEIGHT
*i
+bb
->compress
*ROW_HEIGHT
,
1432 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
1433 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1438 /* display bubble to be shot */
1439 rb
->lcd_bitmap_part(bubbles_emblem
,
1440 0, EMBLEM_HEIGHT
*bb
->queue
[bb
->nextinq
], EMBLEM_WIDTH
,
1441 SHOTX
+(BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2,
1442 SHOTY
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2,
1443 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
1444 rb
->lcd_set_drawmode(DRMODE_FG
);
1445 rb
->lcd_mono_bitmap((const unsigned char *)bubbles_bubble
,
1447 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
1448 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1450 /* display next bubble to be shot */
1451 rb
->lcd_bitmap_part(bubbles_emblem
,
1452 0, EMBLEM_HEIGHT
*bb
->queue
[(bb
->nextinq
+1)%NUM_QUEUE
], EMBLEM_WIDTH
,
1453 XOFS
/2-BUBBLE_WIDTH
/2+(BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2,
1454 SHOTY
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2,
1455 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
1456 rb
->lcd_set_drawmode(DRMODE_FG
);
1457 rb
->lcd_mono_bitmap((const unsigned char *)bubbles_bubble
,
1458 XOFS
/2-BUBBLE_WIDTH
/2, SHOTY
,
1459 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
1460 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1462 /* draw bounding lines */
1463 #ifndef HAVE_LCD_COLOR
1464 rb
->lcd_vline(XOFS
-1, 0, LCD_HEIGHT
);
1465 rb
->lcd_vline(XOFS
+BUBBLE_WIDTH
*BB_WIDTH
, 0, LCD_HEIGHT
);
1467 rb
->lcd_hline(XOFS
, XOFS
+BUBBLE_WIDTH
*BB_WIDTH
-1, bb
->compress
*ROW_HEIGHT
-1);
1468 rb
->lcd_hline(XOFS
, XOFS
+BUBBLE_WIDTH
*BB_WIDTH
-1,
1469 ROW_HEIGHT
*(BB_HEIGHT
-2)+BUBBLE_HEIGHT
);
1472 tipx
= SHOTX
+BUBBLE_WIDTH
/2+(((fp14_sin(bb
->angle
)>>4)*BUBBLE_WIDTH
*3/2)>>10);
1473 tipy
= SHOTY
+BUBBLE_HEIGHT
/2-(((fp14_cos(bb
->angle
)>>4)*BUBBLE_HEIGHT
*3/2)>>10);
1475 rb
->lcd_drawline(SHOTX
+BUBBLE_WIDTH
/2+(((fp14_sin(bb
->angle
)>>4)*BUBBLE_WIDTH
/2)>>10),
1476 SHOTY
+BUBBLE_HEIGHT
/2-(((fp14_cos(bb
->angle
)>>4)*BUBBLE_HEIGHT
/2)>>10),
1478 xlcd_filltriangle(tipx
, tipy
,
1479 tipx
+(((fp14_sin(bb
->angle
-135)>>4)*BUBBLE_WIDTH
/3)>>10),
1480 tipy
-(((fp14_cos(bb
->angle
-135)>>4)*BUBBLE_HEIGHT
/3)>>10),
1481 tipx
+(((fp14_sin(bb
->angle
+135)>>4)*BUBBLE_WIDTH
/3)>>10),
1482 tipy
-(((fp14_cos(bb
->angle
+135)>>4)*BUBBLE_HEIGHT
/3)>>10));
1485 rb
->lcd_getstringsize(level
, &w
, &h
);
1486 rb
->lcd_putsxy(XOFS
/2-w
/2, 2, level
);
1488 rb
->snprintf(str
, 4, "%d", bb
->level
);
1489 rb
->lcd_getstringsize(str
, &w
, &h
);
1490 rb
->lcd_putsxy(XOFS
/2-w
/2, 11, str
);
1492 rb
->lcd_getstringsize(score
, &w
, &h
);
1493 rb
->lcd_putsxy(XOFS
/2-w
/2, 29, score
);
1495 rb
->snprintf(str
, 10, "%d", bb
->score
);
1496 rb
->lcd_getstringsize(str
, &w
, &h
);
1497 rb
->lcd_putsxy(XOFS
/2-w
/2, 38, str
);
1499 rb
->lcd_getstringsize(next
, &w
, &h
);
1500 rb
->lcd_putsxy(XOFS
/2-w
/2, SHOTY
-9, next
);
1502 if(bb
->elapsedshot
>= (MAX_SHOTTIME
*7)/10) {
1503 rb
->lcd_getstringsize(hurry
, &w
, &h
);
1504 rb
->lcd_putsxy(LCD_WIDTH
/2-w
/2, LCD_HEIGHT
/2-h
/2, hurry
);
1508 /*****************************************************************************
1509 * bubbles_fire() fires the current bubble, reloads the cannon, attaches
1510 * bubble to playboard, removes appropriate bubbles, and advances the
1512 ******************************************************************************/
1513 static int bubbles_fire(struct game_context
* bb
) {
1515 long shotxinc
, shotyinc
;
1516 long shotxofs
, shotyofs
;
1518 long tempxofs
, tempyofs
;
1519 int nearrow
, nearcol
;
1520 int lastrow
= BB_HEIGHT
-1;
1521 int lastcol
= (BB_WIDTH
-1)/2;
1523 long lasttick
, currenttick
;
1525 /* get current bubble */
1526 bubblecur
= bb
->queue
[bb
->nextinq
];
1527 shotxinc
= ((fp14_sin(bb
->angle
)>>4)*BUBBLE_WIDTH
)/3;
1528 shotyinc
= ((-1*(fp14_cos(bb
->angle
)>>4))*BUBBLE_HEIGHT
)/3;
1529 shotxofs
= shotyofs
= 0;
1531 /* advance the queue */
1532 bb
->queue
[bb
->nextinq
] = bb
->onboard
[rb
->rand()%bb
->onboardcnt
];
1533 bb
->nextinq
= (bb
->nextinq
+1)%NUM_QUEUE
;
1534 bubbles_drawboard(bb
);
1535 rb
->lcd_update_rect(0, 0, XOFS
, LCD_HEIGHT
);
1537 /* move the bubble across the play board */
1538 lasttick
= *rb
->current_tick
;
1541 /* move the bubble one step */
1542 shotyofs
+= shotyinc
;
1543 shotxofs
+= shotxinc
*shotxdirec
;
1545 /* check for bounce off sides */
1546 if(SHOTX
+(shotxofs
>>10) < XOFS
) {
1547 shotxofs
+= 2*((XOFS
<<10)-(((SHOTX
)<<10)+shotxofs
));
1549 } else if(SHOTX
+(shotxofs
>>10) > XOFS
+(BB_WIDTH
-1)*BUBBLE_WIDTH
) {
1550 shotxofs
-= 2*((((SHOTX
)<<10)+shotxofs
)-
1551 ((XOFS
<<10)+(((BB_WIDTH
-1)*BUBBLE_WIDTH
)<<10)));
1555 tempxofs
= shotxofs
>>10;
1556 tempyofs
= shotyofs
>>10;
1559 bubbles_drawboard(bb
);
1560 rb
->lcd_bitmap_part(bubbles_emblem
, 0, EMBLEM_HEIGHT
*bubblecur
, EMBLEM_WIDTH
,
1561 SHOTX
+tempxofs
+(BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2,
1562 SHOTY
+tempyofs
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2,
1563 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
1564 rb
->lcd_set_drawmode(DRMODE_FG
);
1565 rb
->lcd_mono_bitmap((const unsigned char *)bubbles_bubble
,
1566 SHOTX
+tempxofs
, SHOTY
+tempyofs
,
1567 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
1568 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1569 rb
->lcd_update_rect(XOFS
, 0, BB_WIDTH
*BUBBLE_WIDTH
, LCD_HEIGHT
);
1571 /* find nearest position */
1572 nearrow
= ((SHOTY
+tempyofs
)-
1573 (bb
->compress
*ROW_HEIGHT
)+
1574 (ROW_HEIGHT
/2))/ROW_HEIGHT
;
1575 if(nearrow
>= BB_HEIGHT
) nearrow
= BB_HEIGHT
-1;
1577 if(nearrow
%2) { /* odd row */
1578 nearcol
= ((SHOTX
+tempxofs
)-
1580 (BUBBLE_WIDTH
/2))/BUBBLE_WIDTH
;
1581 if(nearcol
>= BB_WIDTH
-1) nearcol
= BB_WIDTH
-2;
1582 } else { /* even row */
1583 nearcol
= ((SHOTX
+tempxofs
)-XOFS
+(BUBBLE_WIDTH
/2))/BUBBLE_WIDTH
;
1584 if(nearcol
>= BB_WIDTH
) nearcol
= BB_WIDTH
-1;
1586 if(nearcol
< 0) nearcol
= 0;
1588 /* if nearest position is occupied attach to last position */
1589 if(bb
->playboard
[nearrow
][nearcol
].type
>= 0) {
1590 bb
->playboard
[lastrow
][lastcol
].type
= bubblecur
;
1594 /* save last position */
1598 /* if collision with neighbor then attach shot */
1599 if(bubbles_collision(bb
, SHOTY
+tempyofs
, SHOTX
+tempxofs
,
1600 nearrow
, nearcol
)) {
1601 bb
->playboard
[nearrow
][nearcol
].type
= bubblecur
;
1605 /* if at top then attach shot to the ceiling */
1606 if(nearrow
== 0 && SHOTY
+tempyofs
<= bb
->compress
*ROW_HEIGHT
) {
1607 bb
->playboard
[nearrow
][nearcol
].type
= bubblecur
;
1611 /* handle button events */
1612 buttonres
= bubbles_handlebuttons(bb
, true, 0);
1613 if(buttonres
!= BB_NONE
) return buttonres
;
1615 /* framerate limiting */
1616 currenttick
= *rb
->current_tick
;
1617 if(currenttick
-lasttick
< HZ
/MAX_FPS
) {
1618 rb
->sleep((HZ
/MAX_FPS
)-(currenttick
-lasttick
));
1622 lasttick
= currenttick
;
1625 bubbles_drawboard(bb
);
1628 /* clear appropriate bubbles from playing board */
1629 if(bubbles_ingroup(bb
, lastrow
, lastcol
)) {
1630 buttonres
= bubbles_remove(bb
);
1631 if(buttonres
!= BB_NONE
) return buttonres
;
1634 /* update shots and compress amount */
1636 if(bb
->shots
>= NUM_COMPRESS
) {
1644 /*****************************************************************************
1645 * bubbles_collision() determines if a fired bubble has collided with another
1647 ******************************************************************************/
1648 static bool bubbles_collision(struct game_context
* bb
, int y
, int x
,
1649 int nearrow
, int nearcol
) {
1651 int adj
= nearrow
%2;
1653 /* check neighbors */
1654 if(nearcol
-1 >= 0) {
1655 if(bb
->playboard
[nearrow
][nearcol
-1].type
>= 0) {
1656 nx
= XOFS
+(nearrow
%2 ? ROW_INDENT
: 0)+BUBBLE_WIDTH
*(nearcol
-1);
1657 ny
= ROW_HEIGHT
*nearrow
+bb
->compress
*ROW_HEIGHT
;
1658 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1662 if(nearcol
-1+adj
>= 0) {
1663 if(nearrow
-1 >= 0) {
1664 if(bb
->playboard
[nearrow
-1][nearcol
-1+adj
].type
>= 0) {
1665 nx
= XOFS
+((nearrow
-1)%2 ? ROW_INDENT
: 0)+
1666 BUBBLE_WIDTH
*(nearcol
-1+adj
);
1667 ny
= ROW_HEIGHT
*(nearrow
-1)+bb
->compress
*ROW_HEIGHT
;
1668 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1672 if(nearrow
+1 < BB_HEIGHT
) {
1673 if(bb
->playboard
[nearrow
+1][nearcol
-1+adj
].type
>= 0) {
1674 nx
= XOFS
+((nearrow
+1)%2 ? ROW_INDENT
: 0)+
1675 BUBBLE_WIDTH
*(nearcol
-1+adj
);
1676 ny
= ROW_HEIGHT
*(nearrow
+1)+bb
->compress
*ROW_HEIGHT
;
1677 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1682 if(nearcol
+adj
>= 0) {
1683 if(nearrow
-1 >= 0) {
1684 if(bb
->playboard
[nearrow
-1][nearcol
+adj
].type
>= 0) {
1685 nx
= XOFS
+((nearrow
-1)%2 ? ROW_INDENT
: 0)+
1686 BUBBLE_WIDTH
*(nearcol
+adj
);
1687 ny
= ROW_HEIGHT
*(nearrow
-1)+bb
->compress
*ROW_HEIGHT
;
1688 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1692 if(nearrow
+1 < BB_HEIGHT
) {
1693 if(bb
->playboard
[nearrow
+1][nearcol
+adj
].type
>= 0) {
1694 nx
= XOFS
+((nearrow
+1)%2 ? ROW_INDENT
: 0)+
1695 BUBBLE_WIDTH
*(nearcol
+adj
);
1696 ny
= ROW_HEIGHT
*(nearrow
+1)+bb
->compress
*ROW_HEIGHT
;
1697 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1702 if(nearcol
+1 < BB_WIDTH
-adj
) {
1703 if(bb
->playboard
[nearrow
][nearcol
+1].type
>= 0) {
1704 nx
= XOFS
+(nearrow
%2 ? ROW_INDENT
: 0)+BUBBLE_WIDTH
*(nearcol
+1);
1705 ny
= ROW_HEIGHT
*nearrow
+bb
->compress
*ROW_HEIGHT
;
1706 if((x
-nx
)*(x
-nx
)+(y
-ny
)*(y
-ny
) < MIN_DISTANCE
) return true;
1713 /*****************************************************************************
1714 * bubbles_ingroup() marks all bubbles that form the current group.
1715 ******************************************************************************/
1716 static bool bubbles_ingroup(struct game_context
* bb
, int row
, int col
) {
1720 count
= bubbles_searchgroup(bb
, row
, col
);
1722 /* unmark group if too small */
1724 for(i
=0; i
<BB_HEIGHT
; i
++) {
1725 for(j
=0; j
<BB_WIDTH
; j
++) {
1726 bb
->playboard
[i
][j
].ingroup
= false;
1736 /*****************************************************************************
1737 * bubbles_searchgroup() return the size of the group of bubbles of the same
1738 * type that the current bubble belongs to.
1739 ******************************************************************************/
1740 static int bubbles_searchgroup(struct game_context
* bb
, int row
, int col
) {
1742 int myrow
, mycol
, mytype
;
1748 } search
[(2*BB_WIDTH
-1)*(BB_HEIGHT
/2)];
1750 /* search initial bubble */
1751 bb
->playboard
[row
][col
].ingroup
= true;
1752 search
[count
].row
= row
;
1753 search
[count
].col
= col
;
1756 /* breadth-first search neighbors */
1757 for(i
=0; i
<count
; i
++) {
1758 myrow
= search
[i
].row
;
1759 mycol
= search
[i
].col
;
1760 mytype
= bb
->playboard
[myrow
][mycol
].type
;
1764 if(bb
->playboard
[myrow
][mycol
-1].type
== mytype
&&
1765 !bb
->playboard
[myrow
][mycol
-1].ingroup
) {
1766 bb
->playboard
[myrow
][mycol
-1].ingroup
= true;
1767 search
[count
].row
= myrow
;
1768 search
[count
].col
= mycol
-1;
1773 if(mycol
-1+adj
>= 0) {
1775 if(bb
->playboard
[myrow
-1][mycol
-1+adj
].type
== mytype
&&
1776 !bb
->playboard
[myrow
-1][mycol
-1+adj
].ingroup
) {
1777 bb
->playboard
[myrow
-1][mycol
-1+adj
].ingroup
= true;
1778 search
[count
].row
= myrow
-1;
1779 search
[count
].col
= mycol
-1+adj
;
1784 if(myrow
+1 < BB_HEIGHT
) {
1785 if(bb
->playboard
[myrow
+1][mycol
-1+adj
].type
== mytype
&&
1786 !bb
->playboard
[myrow
+1][mycol
-1+adj
].ingroup
) {
1787 bb
->playboard
[myrow
+1][mycol
-1+adj
].ingroup
= true;
1788 search
[count
].row
= myrow
+1;
1789 search
[count
].col
= mycol
-1+adj
;
1795 if(mycol
+adj
>= 0) {
1797 if(bb
->playboard
[myrow
-1][mycol
+adj
].type
== mytype
&&
1798 !bb
->playboard
[myrow
-1][mycol
+adj
].ingroup
) {
1799 bb
->playboard
[myrow
-1][mycol
+adj
].ingroup
= true;
1800 search
[count
].row
= myrow
-1;
1801 search
[count
].col
= mycol
+adj
;
1806 if(myrow
+1 < BB_HEIGHT
) {
1807 if(bb
->playboard
[myrow
+1][mycol
+adj
].type
== mytype
&&
1808 !bb
->playboard
[myrow
+1][mycol
+adj
].ingroup
) {
1809 bb
->playboard
[myrow
+1][mycol
+adj
].ingroup
= true;
1810 search
[count
].row
= myrow
+1;
1811 search
[count
].col
= mycol
+adj
;
1817 if(mycol
+1 < BB_WIDTH
-adj
) {
1818 if(bb
->playboard
[myrow
][mycol
+1].type
== mytype
&&
1819 !bb
->playboard
[myrow
][mycol
+1].ingroup
) {
1820 bb
->playboard
[myrow
][mycol
+1].ingroup
= true;
1821 search
[count
].row
= myrow
;
1822 search
[count
].col
= mycol
+1;
1831 /*****************************************************************************
1832 * bubbles_remove() removes all bubbles in the current group and all
1833 * unanchored bubbles from the play board.
1834 ******************************************************************************/
1835 static int bubbles_remove(struct game_context
* bb
) {
1839 /* determine all anchored bubbles */
1840 for(j
=0; j
<BB_WIDTH
; j
++) {
1841 if(bb
->playboard
[0][j
].type
>= 0 && !bb
->playboard
[0][j
].ingroup
) {
1842 bubbles_anchored(bb
, 0, j
);
1846 /* mark bubbles to be deleted */
1847 for(i
=0; i
<BB_HEIGHT
; i
++) {
1848 for(j
=0; j
<BB_WIDTH
; j
++) {
1849 if(bb
->playboard
[i
][j
].type
>= 0 &&
1850 (!bb
->playboard
[i
][j
].anchored
|| bb
->playboard
[i
][j
].ingroup
)) {
1851 bb
->playboard
[i
][j
].delete = true;
1856 /* animate falling bubbles */
1857 buttonres
= bubbles_fall(bb
);
1858 if(buttonres
!= BB_NONE
) return buttonres
;
1860 /* remove bubbles */
1861 for(i
=0; i
<BB_HEIGHT
; i
++) {
1862 for(j
=0; j
<BB_WIDTH
; j
++) {
1863 if(bb
->playboard
[i
][j
].delete) {
1864 bb
->playboard
[i
][j
].ingroup
= false;
1865 bb
->playboard
[i
][j
].type
= -1;
1866 bb
->playboard
[i
][j
].delete = false;
1868 bb
->playboard
[i
][j
].anchored
= false;
1873 bubbles_getonboard(bb
);
1878 /*****************************************************************************
1879 * bubbles_anchored() marks all bubbles that are anchored in some way to the
1881 ******************************************************************************/
1882 static void bubbles_anchored(struct game_context
* bb
, int row
, int col
) {
1884 int myrow
, mycol
, mytype
;
1890 } search
[(2*BB_WIDTH
-1)*(BB_HEIGHT
/2)];
1892 /* search initial bubble */
1893 bb
->playboard
[row
][col
].anchored
= true;
1894 search
[count
].row
= row
;
1895 search
[count
].col
= col
;
1898 /* breadth-first search neighbors */
1899 for(i
=0; i
<count
; i
++) {
1900 myrow
= search
[i
].row
;
1901 mycol
= search
[i
].col
;
1902 mytype
= bb
->playboard
[myrow
][mycol
].type
;
1906 if(bb
->playboard
[myrow
][mycol
-1].type
>= 0 &&
1907 !bb
->playboard
[myrow
][mycol
-1].ingroup
&&
1908 !bb
->playboard
[myrow
][mycol
-1].anchored
) {
1909 bb
->playboard
[myrow
][mycol
-1].anchored
= true;
1910 search
[count
].row
= myrow
;
1911 search
[count
].col
= mycol
-1;
1916 if(mycol
-1+adj
>= 0) {
1918 if(bb
->playboard
[myrow
-1][mycol
-1+adj
].type
>= 0 &&
1919 !bb
->playboard
[myrow
-1][mycol
-1+adj
].ingroup
&&
1920 !bb
->playboard
[myrow
-1][mycol
-1+adj
].anchored
) {
1921 bb
->playboard
[myrow
-1][mycol
-1+adj
].anchored
= true;
1922 search
[count
].row
= myrow
-1;
1923 search
[count
].col
= mycol
-1+adj
;
1928 if(myrow
+1 < BB_HEIGHT
) {
1929 if(bb
->playboard
[myrow
+1][mycol
-1+adj
].type
>= 0 &&
1930 !bb
->playboard
[myrow
+1][mycol
-1+adj
].ingroup
&&
1931 !bb
->playboard
[myrow
+1][mycol
-1+adj
].anchored
) {
1932 bb
->playboard
[myrow
+1][mycol
-1+adj
].anchored
= true;
1933 search
[count
].row
= myrow
+1;
1934 search
[count
].col
= mycol
-1+adj
;
1940 if(mycol
+adj
>= 0) {
1942 if(bb
->playboard
[myrow
-1][mycol
+adj
].type
>= 0 &&
1943 !bb
->playboard
[myrow
-1][mycol
+adj
].ingroup
&&
1944 !bb
->playboard
[myrow
-1][mycol
+adj
].anchored
) {
1945 bb
->playboard
[myrow
-1][mycol
+adj
].anchored
= true;
1946 search
[count
].row
= myrow
-1;
1947 search
[count
].col
= mycol
+adj
;
1952 if(myrow
+1 < BB_HEIGHT
) {
1953 if(bb
->playboard
[myrow
+1][mycol
+adj
].type
>= 0 &&
1954 !bb
->playboard
[myrow
+1][mycol
+adj
].ingroup
&&
1955 !bb
->playboard
[myrow
+1][mycol
+adj
].anchored
) {
1956 bb
->playboard
[myrow
+1][mycol
+adj
].anchored
= true;
1957 search
[count
].row
= myrow
+1;
1958 search
[count
].col
= mycol
+adj
;
1964 if(mycol
+1 < BB_WIDTH
-adj
) {
1965 if(bb
->playboard
[myrow
][mycol
+1].type
>= 0 &&
1966 !bb
->playboard
[myrow
][mycol
+1].ingroup
&&
1967 !bb
->playboard
[myrow
][mycol
+1].anchored
) {
1968 bb
->playboard
[myrow
][mycol
+1].anchored
= true;
1969 search
[count
].row
= myrow
;
1970 search
[count
].col
= mycol
+1;
1977 /*****************************************************************************
1978 * bubbles_fall() makes removed bubbles fall from the screen.
1979 ******************************************************************************/
1980 static int bubbles_fall(struct game_context
* bb
) {
1987 long lasttick
, currenttick
;
1989 /* give all falling bubbles an x axis movement */
1990 for(i
=0; i
<BB_HEIGHT
; i
++) {
1991 for(j
=0; j
<BB_WIDTH
; j
++) {
1992 if(bb
->playboard
[i
][j
].delete) {
1993 bb
->playboard
[i
][j
].fallx
= rb
->rand()%25 - 12;
1994 bb
->playboard
[i
][j
].fallvel
= rb
->rand()%5 + 6;
1999 /* draw bubbles falling off the screen
2000 * follows y=x^2-8x scaled to bubble size
2002 lasttick
= *rb
->current_tick
;
2004 for(count
=1; ;count
++) {
2006 bubbles_drawboard(bb
);
2008 for(i
=0; i
<BB_HEIGHT
; i
++) {
2009 for(j
=0; j
<BB_WIDTH
; j
++) {
2010 if(bb
->playboard
[i
][j
].delete) {
2011 indent
= (i
%2 ? ROW_INDENT
: 0);
2012 xofs
= ((bb
->playboard
[i
][j
].fallx
*count
)*BUBBLE_WIDTH
)/48;
2013 yofs
= ((count
*count
- bb
->playboard
[i
][j
].fallvel
*count
)*
2016 /* draw bubble if it is still on the screen */
2017 if(ROW_HEIGHT
*i
+bb
->compress
*ROW_HEIGHT
+yofs
2021 rb
->lcd_bitmap_part(bubbles_emblem
, 0,
2022 EMBLEM_HEIGHT
*bb
->playboard
[i
][j
].type
, EMBLEM_WIDTH
,
2023 XOFS
+indent
+BUBBLE_WIDTH
*j
+
2024 (BUBBLE_WIDTH
-EMBLEM_WIDTH
)/2+xofs
,
2025 ROW_HEIGHT
*i
+(BUBBLE_HEIGHT
-EMBLEM_HEIGHT
)/2+
2026 bb
->compress
*ROW_HEIGHT
+yofs
,
2027 EMBLEM_WIDTH
, EMBLEM_HEIGHT
);
2028 rb
->lcd_set_drawmode(DRMODE_FG
);
2029 rb
->lcd_mono_bitmap(
2030 (const unsigned char *)bubbles_bubble
,
2031 XOFS
+indent
+BUBBLE_WIDTH
*j
+xofs
,
2032 ROW_HEIGHT
*i
+bb
->compress
*ROW_HEIGHT
+yofs
,
2033 BUBBLE_WIDTH
, BUBBLE_HEIGHT
);
2034 rb
->lcd_set_drawmode(DRMODE_SOLID
);
2042 /* break out if all bubbles are off the screen */
2043 if(!onscreen
) break;
2045 /* handle button events */
2046 buttonres
= bubbles_handlebuttons(bb
, true, 0);
2047 if(buttonres
!= BB_NONE
) return buttonres
;
2049 /* framerate limiting */
2050 currenttick
= *rb
->current_tick
;
2051 if(currenttick
-lasttick
< HZ
/MAX_FPS
) {
2052 rb
->sleep((HZ
/MAX_FPS
)-(currenttick
-lasttick
));
2056 lasttick
= currenttick
;
2062 /*****************************************************************************
2063 * bubbles_checklevel() checks the state of the playboard for a win or loss.
2064 ******************************************************************************/
2065 static int bubbles_checklevel(struct game_context
* bb
) {
2070 bubbles_drawboard(bb
);
2073 /* check for bubbles below cut off point */
2074 for(i
=0; i
<=bb
->compress
; i
++) {
2075 for(j
=0; j
<BB_WIDTH
; j
++) {
2076 if(bb
->playboard
[BB_HEIGHT
-1-i
][j
].type
>= 0) return BB_LOSE
;
2080 /* check for bubbles above cut off point */
2081 for(i
=0; i
<BB_HEIGHT
-1-bb
->compress
; i
++) {
2082 for(j
=0; j
<BB_WIDTH
; j
++) {
2083 if(bb
->playboard
[i
][j
].type
>= 0) return BB_NONE
;
2087 /* level complete, record score */
2088 points
= 100 - bb
->elapsedlvl
/100;
2090 bb
->score
+= points
;
2095 rb
->snprintf(str
, 12, "%d points", points
);
2096 rb
->splash(HZ
, str
);
2098 /* advance to the next level */
2099 if(!bubbles_nextlevel(bb
)) {
2103 bubbles_drawboard(bb
);
2105 rb
->snprintf(str
, 12, "Level %d", bb
->level
);
2106 rb
->splash(HZ
, str
);
2107 bubbles_drawboard(bb
);
2113 /*****************************************************************************
2114 * bubbles_recordscore() inserts a high score into the high scores list and
2115 * returns the high score position.
2116 ******************************************************************************/
2117 static void bubbles_recordscore(struct game_context
* bb
) {
2121 if (highscore_would_update(bb
->score
, bb
->highscores
, NUM_SCORES
)) {
2123 position
= highscore_update(bb
->score
, bb
->level
, "",
2124 bb
->highscores
, NUM_SCORES
);
2126 rb
->splash(HZ
*2, "New High Score");
2128 bubbles_displayscores(bb
, position
);
2132 /*****************************************************************************
2133 * bubbles_loadscores() loads the high scores saved file.
2134 ******************************************************************************/
2135 static void bubbles_loadscores(struct game_context
* bb
) {
2139 /* highlevel and highscores */
2140 highscore_load(SCORE_FILE
, &bb
->highlevel
, NUM_SCORES
+1);
2142 if( bb
->highlevel
.level
>= NUM_LEVELS
)
2143 bb
->highlevel
.level
= NUM_LEVELS
- 1;
2146 /*****************************************************************************
2147 * bubbles_savescores() saves the high scores saved file.
2148 ******************************************************************************/
2149 static void bubbles_savescores(struct game_context
* bb
) {
2151 /* highlevel and highscores */
2152 highscore_save(SCORE_FILE
, &bb
->highlevel
, NUM_SCORES
+1);
2156 /*****************************************************************************
2157 * bubbles_displayscores() displays the high scores
2158 ******************************************************************************/
2160 static void bubbles_displayscores(struct game_context
* bb
, int position
) {
2164 #ifdef HAVE_LCD_COLOR
2165 rb
->lcd_set_background(LCD_BLACK
);
2166 rb
->lcd_set_foreground(LCD_WHITE
);
2168 rb
->button_clear_queue();
2169 rb
->lcd_clear_display();
2171 rb
->lcd_setfont(FONT_UI
);
2172 rb
->lcd_getstringsize("High Scores", &w
, &h
);
2173 /* check wether it fits on screen */
2174 if ((4*h
+ h
*(NUM_SCORES
-1) + MARGIN
) > LCD_HEIGHT
) {
2175 rb
->lcd_setfont(FONT_SYSFIXED
);
2176 rb
->lcd_getstringsize("High Scores", &w
, &h
);
2178 rb
->lcd_putsxy(LCD_WIDTH
/2-w
/2, MARGIN
, "High Scores");
2179 rb
->lcd_putsxy(LCD_WIDTH
/4-w
/4,2*h
, "Score");
2180 rb
->lcd_putsxy(LCD_WIDTH
*3/4-w
/4,2*h
, "Level");
2182 for (i
= 0; i
<NUM_SCORES
; i
++)
2184 #ifdef HAVE_LCD_COLOR
2186 rb
->lcd_set_foreground(LCD_RGBPACK(245,0,0));
2189 rb
->snprintf (str
, sizeof (str
), "%d)", i
+1);
2190 rb
->lcd_putsxy (MARGIN
,3*h
+ h
*i
, str
);
2191 rb
->snprintf (str
, sizeof (str
), "%d", bb
->highscores
[i
].score
);
2192 rb
->lcd_putsxy (LCD_WIDTH
/4-w
/4,3*h
+ h
*i
, str
);
2193 rb
->snprintf (str
, sizeof (str
), "%d", bb
->highscores
[i
].level
);
2194 rb
->lcd_putsxy (LCD_WIDTH
*3/4-w
/4,3*h
+ h
*i
, str
);
2196 #ifdef HAVE_LCD_COLOR
2197 rb
->lcd_set_foreground(LCD_WHITE
);
2199 rb
->lcd_hline(MARGIN
, LCD_WIDTH
-MARGIN
, 3*h
+ h
*(i
+1)-1);
2204 rb
->button_get(true);
2205 rb
->lcd_setfont(FONT_SYSFIXED
);
2206 bubbles_setcolors();
2209 /*****************************************************************************
2210 * bubbles_loadgame() loads the saved game and returns load success.
2211 ******************************************************************************/
2212 static bool bubbles_loadgame(struct game_context
* bb
) {
2214 bool loaded
= false;
2216 /* open game file */
2217 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
2218 if(fd
< 0) return loaded
;
2220 /* read in saved game */
2222 if(rb
->read(fd
, &bb
->score
, sizeof(bb
->score
)) <= 0) break;
2223 if(rb
->read(fd
, &bb
->level
, sizeof(bb
->level
)) <= 0) break;
2224 if(rb
->read(fd
, &bb
->angle
, sizeof(bb
->angle
)) <= 0) break;
2225 if(rb
->read(fd
, &bb
->shots
, sizeof(bb
->shots
)) <= 0) break;
2226 if(rb
->read(fd
, &bb
->compress
, sizeof(bb
->compress
)) <= 0) break;
2227 if(rb
->read(fd
, &bb
->onboardcnt
, sizeof(bb
->onboardcnt
)) <= 0) break;
2228 if(rb
->read(fd
, bb
->onboard
, sizeof(bb
->onboard
)) <= 0) break;
2229 if(rb
->read(fd
, &bb
->nextinq
, sizeof(bb
->nextinq
)) <= 0) break;
2230 if(rb
->read(fd
, bb
->queue
, sizeof(bb
->queue
)) <= 0) break;
2231 if(rb
->read(fd
, &bb
->elapsedlvl
, sizeof(bb
->elapsedlvl
)) <= 0) break;
2232 if(rb
->read(fd
, bb
->playboard
, sizeof(bb
->playboard
)) <= 0) break;
2240 /* delete saved file */
2241 rb
->remove(SAVE_FILE
);
2245 /*****************************************************************************
2246 * bubbles_savegame() saves the current game state.
2247 ******************************************************************************/
2248 static void bubbles_savegame(struct game_context
* bb
) {
2251 /* write out the game state to the save file */
2252 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
2253 rb
->write(fd
, &bb
->score
, sizeof(bb
->score
));
2254 rb
->write(fd
, &bb
->level
, sizeof(bb
->level
));
2255 rb
->write(fd
, &bb
->angle
, sizeof(bb
->angle
));
2256 rb
->write(fd
, &bb
->shots
, sizeof(bb
->shots
));
2257 rb
->write(fd
, &bb
->compress
, sizeof(bb
->compress
));
2258 rb
->write(fd
, &bb
->onboardcnt
, sizeof(bb
->onboardcnt
));
2259 rb
->write(fd
, bb
->onboard
, sizeof(bb
->onboard
));
2260 rb
->write(fd
, &bb
->nextinq
, sizeof(bb
->nextinq
));
2261 rb
->write(fd
, bb
->queue
, sizeof(bb
->queue
));
2262 rb
->write(fd
, &bb
->elapsedlvl
, sizeof(bb
->elapsedlvl
));
2263 rb
->write(fd
, bb
->playboard
, sizeof(bb
->playboard
));
2269 /*****************************************************************************
2270 * bubbles_setcolors() set the foreground and background colors.
2271 ******************************************************************************/
2272 static inline void bubbles_setcolors(void) {
2273 #ifdef HAVE_LCD_COLOR
2274 rb
->lcd_set_background(LCD_RGBPACK(181,181,222));
2275 rb
->lcd_set_foreground(LCD_BLACK
);
2279 /*****************************************************************************
2280 * bubbles_callback() is the default event handler callback which is called
2281 * on usb connect and shutdown.
2282 ******************************************************************************/
2283 static void bubbles_callback(void* param
) {
2284 struct game_context
* bb
= (struct game_context
*) param
;
2286 rb
->splash(HZ
/2, "Saving high scores...");
2287 bubbles_savescores(bb
);
2291 /*****************************************************************************
2292 * bubbles_handlebuttons() handles button events during a game.
2293 ******************************************************************************/
2294 static int bubbles_handlebuttons(struct game_context
* bb
, bool animblock
,
2299 const struct button_mapping
*plugin_contexts
[]
2300 #if (CONFIG_KEYPAD != SANSA_E200_PAD) && \
2301 (CONFIG_KEYPAD != SANSA_FUZE_PAD)
2302 = {generic_left_right_fire
,generic_actions
};
2304 = {generic_directions
,generic_actions
};
2309 button
= pluginlib_getaction(timeout
,plugin_contexts
,2);
2310 #if defined(HAS_BUTTON_HOLD) && !defined(HAVE_REMOTE_LCD_AS_MAIN)
2311 /* FIXME: Should probably check remote hold here */
2312 if (rb
->button_hold())
2313 button
= BUBBLES_START
;
2317 case BUBBLES_LEFT_REP
:
2318 if(bb
->angle
> MIN_ANGLE
) bb
->angle
-= ANGLE_STEP_REP
;
2319 case BUBBLES_LEFT
: /* change angle to the left */
2320 if(bb
->angle
> MIN_ANGLE
) bb
->angle
-= ANGLE_STEP
;
2323 case BUBBLES_RIGHT_REP
:
2324 if(bb
->angle
< MAX_ANGLE
) bb
->angle
+= ANGLE_STEP_REP
;
2325 case BUBBLES_RIGHT
: /* change angle to the right */
2326 if(bb
->angle
< MAX_ANGLE
) bb
->angle
+= ANGLE_STEP
;
2329 case BUBBLES_SELECT
: /* fire the shot */
2331 bb
->elapsedlvl
+= bb
->elapsedshot
;
2332 bb
->elapsedshot
= 0;
2333 buttonres
= bubbles_fire(bb
);
2334 if(buttonres
!= BB_NONE
) return buttonres
;
2335 buttonres
= bubbles_checklevel(bb
);
2336 if(buttonres
!= BB_NONE
) return buttonres
;
2337 bb
->startedshot
= *rb
->current_tick
;
2341 case BUBBLES_START
: /* pause the game */
2342 start
= *rb
->current_tick
;
2343 rb
->splash(0, "Paused");
2344 while(pluginlib_getaction(TIMEOUT_BLOCK
,plugin_contexts
,2)
2345 != (BUBBLES_START
));
2346 bb
->startedshot
+= *rb
->current_tick
-start
;
2347 bubbles_drawboard(bb
);
2351 case BUBBLES_RESUME
: /* save and end the game */
2353 rb
->splash(HZ
/2, "Saving game...");
2354 bubbles_savegame(bb
);
2358 case BUBBLES_QUIT
: /* end the game */
2361 case ACTION_UNKNOWN
:
2362 case ACTION_NONE
: /* no button pressed */
2366 if(rb
->default_event_handler_ex(button
, bubbles_callback
,
2367 (void*) bb
) == SYS_USB_CONNECTED
)
2375 /*****************************************************************************
2376 * bubbles() is the main game subroutine, it returns the final game status.
2377 ******************************************************************************/
2378 static int bubbles(struct game_context
* bb
) {
2380 unsigned int startlevel
= 0;
2381 bool startgame
= false;
2384 bubbles_setcolors();
2386 /* don't resume by default */
2389 /********************
2391 ********************/
2392 MENUITEM_STRINGLIST(menu
,"Bubbles Menu",NULL
,
2393 "Start New Game", "Resume Game",
2394 "Level", "High Scores", "Playback Control",
2397 switch (rb
->do_menu(&menu
, NULL
, NULL
, false))
2399 case 0: /* new game */
2400 bb
->level
= startlevel
;
2403 case 1: /* resume game */
2404 if(!bubbles_loadgame(bb
)) {
2405 rb
->splash(HZ
*2, "Nothing to resume");
2410 case 2: /* choose level */
2412 rb
->set_int("Choose start level", "", UNIT_INT
, &startlevel
,
2413 NULL
, 1, 1, bb
->highlevel
.level
+1, NULL
);
2416 case 3: /* High scores */
2417 bubbles_displayscores(bb
, 0);
2419 case 4: /* Playback Control */
2420 playback_control(NULL
);
2424 case MENU_ATTACHED_USB
:
2425 bubbles_callback(bb
);
2429 /********************
2431 ********************/
2433 bubbles_drawboard(bb
);
2436 /**********************
2438 **********************/
2439 bb
->startedshot
= *rb
->current_tick
;
2442 /* refresh the board */
2443 bubbles_drawboard(bb
);
2446 /* manange idle framerate */
2447 bb
->elapsedshot
= *rb
->current_tick
-bb
->startedshot
;
2449 if(MAX_SHOTTIME
-bb
->elapsedshot
< HZ
/2) {
2450 timeout
= MAX_SHOTTIME
-bb
->elapsedshot
;
2455 /* handle button events */
2456 buttonres
= bubbles_handlebuttons(bb
, false, timeout
);
2457 if(buttonres
!= BB_NONE
) return buttonres
;
2460 bb
->elapsedshot
= *rb
->current_tick
-bb
->startedshot
;
2462 if(bb
->elapsedshot
> MAX_SHOTTIME
) {
2463 bb
->elapsedlvl
+= bb
->elapsedshot
;
2464 bb
->elapsedshot
= 0;
2465 buttonres
= bubbles_fire(bb
);
2466 if(buttonres
!= BB_NONE
) return buttonres
;
2467 buttonres
= bubbles_checklevel(bb
);
2468 if(buttonres
!= BB_NONE
) return buttonres
;
2469 bb
->startedshot
= *rb
->current_tick
;
2474 /*****************************************************************************
2475 * plugin entry point.
2476 ******************************************************************************/
2477 enum plugin_status
plugin_start(const void* parameter
) {
2478 struct game_context bb
;
2483 /* end of plugin init */
2486 bubbles_loadscores(&bb
);
2487 rb
->lcd_clear_display();
2491 rb
->lcd_set_backdrop(NULL
);
2493 rb
->lcd_setfont(FONT_SYSFIXED
);
2496 switch(bubbles(&bb
)){
2498 rb
->splash(HZ
*2, "You Win!");
2499 /* record high level */
2500 if( NUM_LEVELS
-1 > bb
.highlevel
.level
) {
2501 bb
.highlevel
.level
= NUM_LEVELS
-1;
2504 /* record high score */
2505 bubbles_recordscore(&bb
);
2509 rb
->splash(HZ
*2, "Game Over");
2510 /* fall through to BB_END */
2514 /* record high level */
2515 if((int)bb
.level
-1 > bb
.highlevel
.level
) {
2516 bb
.highlevel
.level
= bb
.level
-1;
2519 /* record high score */
2520 bubbles_recordscore(&bb
);
2525 rb
->lcd_setfont(FONT_UI
);
2526 return PLUGIN_USB_CONNECTED
;
2530 rb
->splash(HZ
/2, "Saving high scores...");
2531 bubbles_savescores(&bb
);
2541 rb
->lcd_setfont(FONT_UI
);