f45b333842
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9336 a1c6a512-1295-4272-9138-f99709370657
2630 lines
92 KiB
C
Executable file
2630 lines
92 KiB
C
Executable file
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2005 Adam Boot
|
|
*
|
|
* Color graphics from Frozen Bubble (http://www.frozen-bubble.org/)
|
|
*
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "plugin.h"
|
|
#include "xlcd.h"
|
|
|
|
#ifdef HAVE_LCD_BITMAP
|
|
|
|
PLUGIN_HEADER
|
|
|
|
/* files */
|
|
#define SCORE_FILE PLUGIN_DIR "/bubbles.score"
|
|
#define SAVE_FILE PLUGIN_DIR "/bubbles.save"
|
|
|
|
/* final game return status */
|
|
#define BB_NONE 5
|
|
#define BB_WIN 4
|
|
#define BB_END 3
|
|
#define BB_USB 2
|
|
#define BB_QUIT 1
|
|
#define BB_LOSE 0
|
|
|
|
/* play board dimension */
|
|
#define BB_HEIGHT 12
|
|
#define BB_WIDTH 8
|
|
#define BB_LEVEL_HEIGHT 10
|
|
|
|
/* various amounts */
|
|
#define NUM_SCORES 10
|
|
#define NUM_LEVELS 100
|
|
#define NUM_QUEUE 2
|
|
#define NUM_BUBBLES 8
|
|
#define MIN_ANGLE -76
|
|
#define MAX_ANGLE 76
|
|
#define NUM_COMPRESS 9
|
|
#define MAX_SHOTTIME 1000
|
|
|
|
/* button definitions */
|
|
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
|
|
#define BUBBLES_LEFT BUTTON_LEFT
|
|
#define BUBBLES_RIGHT BUTTON_RIGHT
|
|
#define BUBBLES_UP BUTTON_UP
|
|
#define BUBBLES_DOWN BUTTON_DOWN
|
|
#define BUBBLES_QUIT BUTTON_OFF
|
|
#define BUBBLES_START BUTTON_ON
|
|
#define BUBBLES_SELECT BUTTON_SELECT
|
|
#define BUBBLES_RESUME BUTTON_MODE
|
|
|
|
#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
|
|
#define BUBBLES_LEFT BUTTON_SCROLL_BACK
|
|
#define BUBBLES_RIGHT BUTTON_SCROLL_FWD
|
|
#define BUBBLES_UP BUTTON_SCROLL_FWD
|
|
#define BUBBLES_DOWN BUTTON_SCROLL_BACK
|
|
#define BUBBLES_QUIT BUTTON_MENU|BUTTON_REL
|
|
#define BUBBLES_START BUTTON_PLAY|BUTTON_REL
|
|
#define BUBBLES_SELECT BUTTON_SELECT
|
|
#define BUBBLES_RESUME BUTTON_RIGHT|BUTTON_LEFT
|
|
|
|
#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
|
|
#define BUBBLES_LEFT BUTTON_LEFT
|
|
#define BUBBLES_RIGHT BUTTON_RIGHT
|
|
#define BUBBLES_UP BUTTON_UP
|
|
#define BUBBLES_DOWN BUTTON_DOWN
|
|
#define BUBBLES_QUIT BUTTON_POWER
|
|
#define BUBBLES_START BUTTON_PLAY
|
|
#define BUBBLES_SELECT BUTTON_SELECT
|
|
#define BUBBLES_RESUME BUTTON_REC
|
|
|
|
#elif CONFIG_KEYPAD == GIGABEAT_PAD
|
|
#define BUBBLES_LEFT BUTTON_LEFT
|
|
#define BUBBLES_RIGHT BUTTON_RIGHT
|
|
#define BUBBLES_UP BUTTON_UP
|
|
#define BUBBLES_DOWN BUTTON_DOWN
|
|
#define BUBBLES_QUIT BUTTON_A
|
|
#define BUBBLES_START BUTTON_POWER
|
|
#define BUBBLES_SELECT BUTTON_SELECT
|
|
#define BUBBLES_RESUME BUTTON_MENU
|
|
|
|
#else
|
|
#error BUBBLES: Unsupported keypad
|
|
#endif
|
|
|
|
/* bubbles will consume height of 10*ROW_HEIGHT+2*(BUBBLE_SZ-1)+BUBBLE_SZ/2 */
|
|
/* 24x24 bubbles (iPod Video) */
|
|
#if (LCD_HEIGHT == 240) && (LCD_WIDTH == 320)
|
|
#define BUBBLE_SZ 22
|
|
#define EMBLEM_SZ 16
|
|
#define XOFS 72
|
|
#define ROW_HEIGHT 18
|
|
#define ROW_INDENT 11
|
|
#define MAX_FPS 40
|
|
|
|
/* 16x16 bubbles (H300, iPod Color) */
|
|
#elif (LCD_HEIGHT == 176) && (LCD_WIDTH == 220)
|
|
#define BUBBLE_SZ 16
|
|
#define EMBLEM_SZ 12
|
|
#define XOFS 46
|
|
#define ROW_HEIGHT 14
|
|
#define ROW_INDENT 8
|
|
#define MAX_FPS 30
|
|
|
|
/* 16x16 bubbles (Gigabeat) */
|
|
#elif (LCD_HEIGHT == 320) && (LCD_WIDTH == 240)
|
|
#define BUBBLE_SZ 16
|
|
#define EMBLEM_SZ 12
|
|
#define XOFS 56
|
|
#define ROW_HEIGHT 14
|
|
#define ROW_INDENT 8
|
|
#define MAX_FPS 20
|
|
|
|
/* 12x12 bubbles (iPod Nano) */
|
|
#elif (LCD_HEIGHT == 132) && (LCD_WIDTH == 176)
|
|
#define BUBBLE_SZ 12
|
|
#define EMBLEM_SZ 8
|
|
#define XOFS 40
|
|
#define ROW_HEIGHT 10
|
|
#define ROW_INDENT 6
|
|
#define MAX_FPS 40
|
|
|
|
/* 12x12 bubbles (H100, iAudio X5, iPod 3G, iPod 4G grayscale) */
|
|
#elif (LCD_HEIGHT == 128) && (LCD_WIDTH == 160)
|
|
#define BUBBLE_SZ 12
|
|
#define EMBLEM_SZ 8
|
|
#define XOFS 33
|
|
#define ROW_HEIGHT 10
|
|
#define ROW_INDENT 6
|
|
#define MAX_FPS 30
|
|
|
|
#else
|
|
#error BUBBLES: Unsupported LCD type
|
|
#endif
|
|
|
|
/* shot position */
|
|
#define SHOTX XOFS+ROW_INDENT+BUBBLE_SZ*3
|
|
#define SHOTY ROW_HEIGHT*(BB_HEIGHT-1)+BUBBLE_SZ/2
|
|
|
|
/* collision distance squared */
|
|
#define MIN_DISTANCE ((BUBBLE_SZ*8)/10)*((BUBBLE_SZ*8)/10)
|
|
|
|
/* external bitmaps */
|
|
extern const fb_data bubbles_bubble[];
|
|
extern const fb_data bubbles_emblem[];
|
|
#ifdef HAVE_LCD_COLOR
|
|
extern const fb_data bubbles_left[];
|
|
extern const fb_data bubbles_right[];
|
|
#endif
|
|
|
|
/* global rockbox api */
|
|
static struct plugin_api* rb;
|
|
|
|
/* levels */
|
|
char level[NUM_LEVELS][BB_LEVEL_HEIGHT][BB_WIDTH] = {
|
|
{{ 6, 6, 4, 4, 2, 2, 3, 3},
|
|
{ 6, 6, 4, 4, 2, 2, 3, -1},
|
|
{ 2, 2, 3, 3, 6, 6, 4, 4},
|
|
{ 2, 3, 3, 6, 6, 4, 4, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 7, 7, 7, 7, 7, 7, -1},
|
|
{-1, 1, 1, 1, 1, 1, -1, -1},
|
|
{-1, -1, 2, 2, 2, 2, -1, -1},
|
|
{-1, -1, -1, 2, -1, -1, -1, -1},
|
|
{-1, -1, -1, 2, 2, -1, -1, -1},
|
|
{-1, -1, -1, 5, -1, -1, -1, -1},
|
|
{-1, -1, -1, 5, 5, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 7, -1, -1, 7, -1, -1},
|
|
{-1, -1, 7, 1, 7, -1, -1, -1},
|
|
{-1, -1, -1, 1, 2, -1, -1, -1},
|
|
{-1, -1, 1, 2, 1, -1, -1, -1},
|
|
{-1, -1, -1, 2, 5, -1, -1, -1},
|
|
{-1, -1, 3, 5, 3, -1, -1, -1},
|
|
{-1, -1, -1, 5, 3, -1, -1, -1},
|
|
{-1, -1, -1, 3, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 0, 0, -1, -1, -1},
|
|
{-1, -1, 5, 0, 1, -1, -1, -1},
|
|
{-1, -1, 3, 5, 1, 6, -1, -1},
|
|
{-1, 4, 3, -1, 6, 7, -1, -1},
|
|
{-1, 7, 4, -1, -1, 7, 4, -1},
|
|
{ 6, 7, -1, -1, -1, 4, 3, -1},
|
|
{ 1, 6, -1, -1, -1, -1, 3, 5},
|
|
{ 1, -1, -1, -1, -1, -1, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 0, 0, 0, 0, -1, -1},
|
|
{-1, 0, 1, 1, 1, 0, -1, -1},
|
|
{-1, 0, 1, 0, 0, 1, 0, -1},
|
|
{-1, 0, 1, 1, 1, 0, -1, -1},
|
|
{-1, -1, 0, 0, 0, 0, -1, -1},
|
|
{-1, -1, 7, -1, 7, -1, -1, -1},
|
|
{-1, -1, 7, 7, 7, 7, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 4, 4, 4, 6, 6, 6, -1},
|
|
{ 4, -1, -1, -1, -1, -1, 6, -1},
|
|
{-1, 4, -1, -1, -1, -1, 6, -1},
|
|
{ 4, 2, 3, 1, 2, 3, 6, -1},
|
|
{-1, 3, 1, 2, 3, 1, 2, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 4, 4, 4, 6, 6, 6, -1},
|
|
{ 4, -1, -1, -1, -1, -1, 6, -1},
|
|
{-1, 4, -1, -1, -1, -1, 6, -1},
|
|
{ 4, 2, 3, 1, 2, 3, 6, -1},
|
|
{-1, 3, 1, 2, 3, 1, 2, -1},
|
|
{-1, 2, 3, 1, 2, 3, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 0, 0, -1, -1, 2, 2, -1},
|
|
{-1, 5, -1, -1, -1, 3, -1, -1},
|
|
{-1, 0, -1, -1, -1, 6, -1, -1},
|
|
{-1, 3, -1, -1, -1, 0, -1, -1},
|
|
{-1, 4, -1, -1, -1, 5, -1, -1},
|
|
{-1, 2, -1, -1, -1, 3, -1, -1},
|
|
{-1, 2, -1, -1, -1, 1, -1, -1},
|
|
{-1, 3, -1, -1, -1, 4, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 3, -1, -1, -1, -1, -1, -1, 3},
|
|
{ 6, 3, 2, 4, 6, 3, 2, -1},
|
|
{ 4, -1, -1, -1, -1, -1, -1, 4},
|
|
{ 2, 4, 6, 3, 2, 4, 6, -1},
|
|
{-1, -1, -1, 6, -1, -1, -1, -1},
|
|
{-1, -1, -1, 3, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 2, -1, 1, -1, 1, -1, 2},
|
|
{ 1, 2, -1, 2, 1, -1, 1, -1},
|
|
{ 1, -1, 1, -1, 2, -1, 2, -1},
|
|
{ 2, 1, -1, 1, 2, -1, 2, -1},
|
|
{-1, 2, -1, 2, -1, 2, -1, 2},
|
|
{ 1, 2, -1, 2, 1, -1, 1, -1},
|
|
{ 1, -1, 1, -1, 2, -1, 1, -1},
|
|
{ 2, 2, -1, 1, 1, -1, 2, -1},
|
|
{-1, 2, -1, 1, -1, 1, -1, 1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 7, 7, -1, -1, 5, 5, -1},
|
|
{ 1, -1, -1, -1, -1, -1, 4, -1},
|
|
{ 2, 1, -1, -1, -1, -1, 4, 3},
|
|
{ 2, -1, -1, -1, -1, -1, 3, -1},
|
|
{ 1, 2, -1, -1, -1, -1, 3, 4},
|
|
{ 1, -1, -1, -1, -1, -1, 4, -1},
|
|
{ 7, 1, -1, -1, -1, -1, 4, 5},
|
|
{ 7, 7, -1, -1, -1, 5, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 7, 7, -1, -1, -1, -1, 5, 5},
|
|
{ 1, 5, -1, -1, -1, 7, 4, -1},
|
|
{ 2, 1, -1, -1, -1, -1, 4, 3},
|
|
{ 2, -1, -1, -1, -1, -1, 3, -1},
|
|
{ 1, 5, -1, -1, -1, -1, 7, 4},
|
|
{ 1, -1, -1, -1, -1, -1, 4, -1},
|
|
{ 7, 1, -1, -1, -1, -1, 4, 5},
|
|
{ 7, 5, -1, -1, -1, 7, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 0, 0, -1, -1, -1},
|
|
{-1, -1, 5, 0, 1, -1, -1, -1},
|
|
{-1, -1, 3, 5, 1, 6, -1, -1},
|
|
{-1, 4, 3, 2, 6, 2, -1, -1},
|
|
{-1, 7, 4, 7, 2, 2, 4, -1},
|
|
{ 6, 7, 7, 3, 3, 4, 3, -1},
|
|
{ 1, 6, 1, 1, 1, 3, 3, 5},
|
|
{ 1, 1, -1, -1, -1, -1, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 0, -1, -1, 0, -1, -1},
|
|
{-1, 3, 3, -1, 3, 3, -1, -1},
|
|
{-1, 0, 2, 0, 0, 2, 0, -1},
|
|
{-1, 3, 3, -1, 3, 3, -1, -1},
|
|
{-1, -1, 0, -1, -1, 0, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 1, 1, -1, -1, -1},
|
|
{-1, -1, 2, 2, 2, -1, -1, -1},
|
|
{-1, -1, 3, 3, 3, 3, -1, -1},
|
|
{-1, 4, 4, 4, 4, 4, -1, -1},
|
|
{-1, 5, 5, 5, 5, 5, 5, -1},
|
|
{-1, -1, -1, 6, -1, -1, -1, -1},
|
|
{-1, -1, -1, 7, 7, -1, -1, -1},
|
|
{-1, -1, -1, 0, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 2, 5, -1, -1, -1},
|
|
{-1, 4, 3, -1, -1, -1, -1, -1},
|
|
{ 6, 7, -1, 5, 2, -1, -1, -1},
|
|
{-1, -1, -1, -1, 3, 4, -1, -1},
|
|
{-1, -1, -1, 2, 5, -1, 7, 6},
|
|
{-1, 4, 3, -1, -1, -1, -1, -1},
|
|
{ 6, 7, -1, 5, 2, -1, -1, -1},
|
|
{-1, -1, -1, -1, 3, 4, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, 7, 6},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 5, 5, -1, -1, -1},
|
|
{-1, -1, -1, 3, -1, -1, -1, -1},
|
|
{-1, -1, -1, 1, -1, -1, -1, -1},
|
|
{-1, -1, -1, 7, -1, -1, -1, -1},
|
|
{-1, -1, -1, 2, -1, -1, -1, -1},
|
|
{-1, -1, -1, 4, -1, -1, -1, -1},
|
|
{-1, -1, -1, 5, -1, -1, -1, -1},
|
|
{-1, -1, -1, 3, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 0, 1, -1, -1, -1},
|
|
{-1, -1, 0, 2, 7, 7, -1, -1},
|
|
{-1, -1, -1, 0, 1, 7, -1, -1},
|
|
{-1, 0, 0, 0, 0, -1, -1, -1},
|
|
{-1, 0, 0, 0, 1, 1, -1, -1},
|
|
{ 0, 0, 0, 1, 1, 1, -1, -1},
|
|
{-1, 0, 0, 1, 1, 1, -1, -1},
|
|
{-1, 0, 0, 0, 7, 7, -1, -1},
|
|
{-1, -1, 7, 7, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 1, -1, -1, -1, -1, -1, -1},
|
|
{ 1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, 2, 3, 4, 7, 6, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, 1, -1},
|
|
{-1, -1, -1, -1, -1, -1, 1, -1},
|
|
{-1, 2, 3, 4, 7, 6, -1, -1},
|
|
{-1, 1, -1, -1, -1, -1, -1, -1},
|
|
{ 1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, 2, 3, 4, 7, 6, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 6, -1, -1, -1, -1, -1, -1},
|
|
{ 5, -1, -1, -1, -1, -1, -1, -1},
|
|
{ 2, 3, 4, 7, 6, 5, 2, 3},
|
|
{-1, -1, -1, -1, -1, -1, 4, -1},
|
|
{-1, -1, -1, -1, -1, -1, 7, -1},
|
|
{-1, 4, 3, 2, 5, 6, -1, -1},
|
|
{-1, 7, -1, -1, -1, -1, -1, -1},
|
|
{ 6, -1, -1, -1, -1, -1, -1, -1},
|
|
{ 5, 2, 3, 4, 7, 6, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 3, 2, 1, 0, 0, 1, 2, 3},
|
|
{ 3, 2, 1, 0, 1, 2, 3, -1},
|
|
{ 4, 3, 2, 1, 1, 2, 3, 4},
|
|
{ 4, 3, 2, 1, 2, 3, 4, -1},
|
|
{ 5, 4, 3, 2, 2, 3, 4, 5},
|
|
{ 5, 4, 3, 2, 3, 4, 5, -1},
|
|
{ 6, 5, 4, 3, 3, 4, 5, 6},
|
|
{ 6, 5, 4, 3, 4, 5, 6, -1},
|
|
{ 7, 6, 5, 4, 4, 5, 6, 7},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 5, 5, -1, -1, -1},
|
|
{-1, -1, -1, 3, -1, -1, -1, -1},
|
|
{-1, -1, -1, 2, 4, -1, -1, -1},
|
|
{-1, -1, -1, 6, -1, -1, -1, -1},
|
|
{-1, -1, -1, 2, 4, -1, -1, -1},
|
|
{-1, 2, -1, 5, -1, 4, -1, -1},
|
|
{ 1, 0, 1, 0, 1, 0, 1, 0},
|
|
{ 3, -1, 3, -1, 2, -1, 6, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, -1, 1, -1, -1, -1},
|
|
{ 7, 4, 3, 5, -1, -1, -1, -1},
|
|
{ 6, -1, -1, 1, -1, -1, -1, -1},
|
|
{-1, -1, -1, 5, 3, 4, 7, -1},
|
|
{ 6, -1, -1, -1, 1, -1, -1, 6},
|
|
{ 7, 4, 3, 5, -1, -1, -1, -1},
|
|
{-1, -1, -1, 1, -1, -1, -1, 6},
|
|
{-1, -1, -1, 5, 3, 4, 7, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, -1, 7, 3, 6, -1},
|
|
{-1, -1, 3, 7, 3, 6, 3, -1},
|
|
{-1, -1, 5, 7, 3, 6, 3, -1},
|
|
{-1, 6, 7, 3, 6, 7, -1, -1},
|
|
{-1, 7, 7, 3, 6, 1, -1, -1},
|
|
{ 3, 7, 3, 6, 3, -1, -1, -1},
|
|
{ 5, 6, 2, 7, 1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 5, -1, -1, -1, -1, -1, -1, 5},
|
|
{ 5, -1, 6, 6, 6, -1, 5, -1},
|
|
{-1, 5, 4, -1, -1, 4, 5, -1},
|
|
{-1, 3, -1, -1, -1, 3, -1, -1},
|
|
{-1, 6, 0, -1, -1, 0, 6, -1},
|
|
{-1, 3, -1, -1, -1, 3, -1, -1},
|
|
{-1, -1, 4, -1, -1, 4, -1, -1},
|
|
{-1, -1, 6, 6, 6, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 7, 0, -1, -1, 0, 7, -1},
|
|
{ 7, -1, 0, -1, 0, -1, 7, -1},
|
|
{ 7, 1, -1, 0, 0, -1, 1, 7},
|
|
{ 7, 1, 2, 0, 2, 1, 7, -1},
|
|
{ 7, 6, 3, 2, 2, 3, 6, 7},
|
|
{ 7, -1, 3, 2, 3, -1, 7, -1},
|
|
{-1, 7, 7, 3, 3, 7, 7, -1},
|
|
{-1, -1, -1, 3, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 3, -1, 1, -1, 7, -1, 6},
|
|
{ 5, -1, 7, -1, 7, -1, 6, -1},
|
|
{ 6, -1, 0, -1, 5, -1, 3, -1},
|
|
{-1, 2, -1, 1, -1, 5, -1, -1},
|
|
{-1, 4, -1, 3, -1, 4, -1, -1},
|
|
{ 2, -1, 3, -1, 2, -1, -1, -1},
|
|
{-1, -1, 4, -1, 6, -1, -1, -1},
|
|
{-1, -1, -1, 5, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, -1, 1, -1, -1, -1},
|
|
{-1, -1, -1, -1, 3, -1, -1, -1},
|
|
{ 6, 1, 3, 1, 2, 1, 4, 1},
|
|
{-1, -1, -1, -1, 6, -1, -1, -1},
|
|
{-1, -1, -1, 4, 1, -1, -1, -1},
|
|
{-1, -1, 1, -1, 3, -1, -1, -1},
|
|
{-1, -1, -1, 2, 1, -1, -1, -1},
|
|
{-1, -1, -1, -1, 4, -1, -1, -1},
|
|
{-1, -1, -1, 6, 1, -1, -1, -1},
|
|
{-1, -1, -1, 6, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 5, 4, -1, -1, -1},
|
|
{-1, -1, 4, 1, 0, -1, -1, -1},
|
|
{-1, -1, -1, 2, 3, -1, -1, -1},
|
|
{-1, 1, 4, -1, 2, 2, -1, -1},
|
|
{-1, 3, 1, 2, 5, 1, 4, -1},
|
|
{-1, 4, 2, -1, 0, 4, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, -1, 1, -1, -1, -1},
|
|
{-1, -1, -1, 1, -1, -1, -1, -1},
|
|
{-1, 2, -1, -1, 1, -1, 5, -1},
|
|
{ 5, -1, -1, 1, -1, -1, 0, -1},
|
|
{-1, 6, -1, -1, 1, -1, 4, -1},
|
|
{-1, 0, -1, 1, -1, 5, -1, -1},
|
|
{-1, -1, 5, 5, 0, 1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 6, 3, -1, -1, -1},
|
|
{-1, -1, 3, 2, 6, -1, -1, -1},
|
|
{-1, -1, 2, 6, 3, 2, -1, -1},
|
|
{-1, 6, 3, 2, 6, 3, -1, -1},
|
|
{-1, 3, 2, 6, 3, 2, 6, -1},
|
|
{ 2, 6, 3, 2, 6, 3, 2, -1},
|
|
{ 6, 3, 2, 6, 3, 2, 6, 3},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 6, 6, 6, 6, 6, 6, 6, 6},
|
|
{ 4, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, 3, 2, 5, 7, 6, 4, 3},
|
|
{-1, 5, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, 7, 6, 4, 3, 2, 5},
|
|
{-1, -1, 4, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, 3, 2, 5, 7, 6},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 1, -1, 7, -1, -1, 6, -1, 2},
|
|
{ 6, -1, 1, -1, 6, 1, 3, -1},
|
|
{-1, 4, -1, 7, 2, -1, 7, -1},
|
|
{ 2, 7, -1, -1, -1, 4, -1, -1},
|
|
{ 6, -1, 3, 5, 0, 2, -1, 7},
|
|
{ 1, -1, -1, -1, -1, -1, 1, -1},
|
|
{-1, 1, 4, 5, 7, 5, 1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 6, 6, 6, -1, -1, 6, 6, 6},
|
|
{-1, -1, 6, -1, 6, -1, -1, -1},
|
|
{-1, -1, 2, 3, 3, 2, -1, -1},
|
|
{-1, 3, -1, 5, -1, 3, -1, -1},
|
|
{-1, -1, 5, 3, 3, 5, -1, -1},
|
|
{-1, -1, 6, 1, 6, -1, -1, -1},
|
|
{-1, 4, 2, -1, -1, 2, 4, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 5, 5, -1, -1, -1},
|
|
{-1, -1, 5, -1, -1, -1, -1, -1},
|
|
{-1, 3, 4, 6, 6, -1, -1, 5},
|
|
{ 3, 3, 4, 6, 5, -1, 5, -1},
|
|
{ 3, 2, 3, 6, 6, 5, 5, -1},
|
|
{ 3, 3, 4, 6, 5, -1, 5, -1},
|
|
{-1, 3, 4, 6, 6, -1, -1, 5},
|
|
{-1, -1, 5, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, 5, 5, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 1, -1, -1, -1, -1, -1, -1, 1},
|
|
{ 1, -1, 2, 2, 2, -1, 1, -1},
|
|
{-1, 1, 2, 3, 3, 2, 1, -1},
|
|
{ 6, 2, 3, -1, 3, 2, 6, -1},
|
|
{ 6, 2, 3, -1, -1, 3, 2, 6},
|
|
{ 6, 2, 3, -1, 3, 2, 6, -1},
|
|
{ 3, 3, 3, 7, 7, 3, 3, 3},
|
|
{ 0, 5, 0, 2, 0, 5, 0, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 7, 7, 7, -1, -1, -1},
|
|
{-1, 7, 2, 2, 7, -1, -1, -1},
|
|
{-1, 7, 5, 5, 5, 7, -1, -1},
|
|
{ 7, 7, 7, 7, 7, 7, -1, -1},
|
|
{-1, -1, 6, -1, 6, -1, -1, -1},
|
|
{-1, 6, -1, -1, 6, -1, -1, -1},
|
|
{-1, 6, 4, 4, -1, 6, 4, 4},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 3, 3, -1, 3, 3, 3, -1},
|
|
{ 3, 7, 5, 4, 6, 5, 3, -1},
|
|
{ 1, 3, 3, 3, -1, 3, 3, 1},
|
|
{ 2, 1, 2, 1, 2, 1, 2, -1},
|
|
{ 1, 3, 3, -1, 3, 3, 3, 1},
|
|
{ 3, 5, 6, 4, 5, 7, 3, -1},
|
|
{ 2, 3, 3, 3, -1, 3, 3, 2},
|
|
{ 1, 1, 2, 2, 2, 1, 1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 6, 5, -1, -1, -1, -1, -1},
|
|
{ 3, 1, 3, -1, -1, -1, -1, -1},
|
|
{-1, 5, 6, -1, -1, -1, -1, -1},
|
|
{-1, -1, 5, 3, -1, -1, -1, -1},
|
|
{-1, -1, 6, 1, 6, -1, -1, -1},
|
|
{-1, -1, 3, 5, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, 3, 6, -1, -1},
|
|
{-1, -1, -1, 5, 6, 5, -1, -1},
|
|
{-1, -1, -1, -1, 6, 3, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 6, 3, 7, 4, 5, 1, 6, 3},
|
|
{ 5, 1, 6, 3, 7, 4, 5, -1},
|
|
{ 6, 3, 7, 4, 5, 1, 6, 3},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, -1, -1, -1, 4, 4},
|
|
{-1, -1, 7, 7, 7, 4, 4, -1},
|
|
{-1, -1, -1, -1, -1, -1, 4, 4},
|
|
{-1, 1, -1, -1, -1, 7, -1, -1},
|
|
{-1, 1, 1, -1, -1, 7, -1, -1},
|
|
{ 3, 3, 3, -1, 7, -1, -1, -1},
|
|
{ 3, -1, 2, 3, 3, 3, -1, 3},
|
|
{-1, 2, -1, 3, -1, 3, 3, -1},
|
|
{-1, 2, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 4, -1, -1, -1, -1, -1},
|
|
{-1, 7, 4, -1, -1, -1, -1, -1},
|
|
{-1, -1, 7, 4, -1, -1, -1, -1},
|
|
{-1, 4, 7, 4, -1, -1, -1, -1},
|
|
{ 1, 1, 1, 1, 1, 1, 1, -1},
|
|
{ 1, 2, 1, 2, 1, 1, -1, -1},
|
|
{ 2, 2, 2, 2, 2, 2, 2, 2},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 0, -1, -1, -1, -1, -1, -1, 6},
|
|
{ 6, 1, 4, 3, 7, 5, 0, -1},
|
|
{ 0, -1, -1, -1, -1, -1, -1, 6},
|
|
{ 6, 1, 4, 3, 7, 5, 0, -1},
|
|
{ 0, -1, -1, -1, -1, -1, -1, 6},
|
|
{ 6, 1, 4, 3, 7, 5, 0, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 3, 3, 4, 6, 6, 4, 3, 3},
|
|
{ 0, 3, 4, 6, 4, 3, 1, -1},
|
|
{ 5, 1, 3, 4, 4, 3, 0, 1},
|
|
{ 0, 1, 3, 4, 3, 1, 0, -1},
|
|
{ 2, 1, 6, 3, 3, 0, 0, 1},
|
|
{ 0, 3, 4, 3, 6, 1, 5, -1},
|
|
{ 6, 1, 2, 6, 4, 0, 0, 2},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 6, 6, -1, -1, -1, -1, 4, 4},
|
|
{ 4, 0, -1, -1, -1, 3, 6, -1},
|
|
{ 0, 6, -1, -1, -1, -1, 4, 2},
|
|
{ 7, -1, -1, -1, -1, -1, 7, -1},
|
|
{ 4, 4, -1, -1, -1, -1, 5, 6},
|
|
{ 6, 4, 7, 7, 5, 6, 4, -1},
|
|
{-1, 7, 6, 4, 6, 4, 7, -1},
|
|
{-1, 0, -1, 7, -1, 7, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 5, -1, -1, -1, -1, 4, -1},
|
|
{-1, 5, -1, -1, -1, 4, -1, -1},
|
|
{-1, -1, 5, 6, 6, 4, -1, -1},
|
|
{-1, -1, 2, -1, 2, -1, -1, -1},
|
|
{ 0, 0, 6, -1, -1, 6, 1, 1},
|
|
{-1, -1, 2, -1, 2, -1, -1, -1},
|
|
{-1, -1, 7, 6, 6, 3, -1, -1},
|
|
{-1, 7, -1, -1, -1, 3, -1, -1},
|
|
{-1, 7, -1, -1, -1, -1, 3, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 6, -1, -1, -1, -1, 2, -1},
|
|
{ 1, 7, 1, 1, 1, 3, 1, -1},
|
|
{-1, -1, 4, 1, 1, 4, -1, -1},
|
|
{-1, 1, 3, 1, 7, 1, -1, -1},
|
|
{-1, -1, -1, 2, 6, -1, -1, -1},
|
|
{-1, -1, 1, 5, 1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 7, 7, 7, 7, 7, 7, 7, 7},
|
|
{ 7, -1, -1, -1, -1, -1, 7, -1},
|
|
{ 7, -1, -1, 2, 0, 5, 2, 2},
|
|
{ 7, -1, -1, -1, 0, 3, 6, -1},
|
|
{ 7, -1, -1, -1, -1, -1, 4, 0},
|
|
{ 5, 5, -1, -1, -1, -1, -1, -1},
|
|
{ 4, 3, 6, 2, -1, -1, -1, -1},
|
|
{ 0, 2, 0, 4, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 1, -1, -1, 1, -1, -1},
|
|
{-1, 4, -1, -1, 5, -1, -1, -1},
|
|
{-1, 7, -1, -1, 1, 1, 1, -1},
|
|
{ 6, -1, -1, -1, -1, 7, -1, -1},
|
|
{ 1, 1, 1, 1, -1, 4, -1, -1},
|
|
{-1, -1, 5, -1, -1, -1, -1, -1},
|
|
{-1, -1, 0, -1, -1, -1, -1, -1},
|
|
{-1, 3, -1, -1, -1, -1, -1, -1},
|
|
{-1, 1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 7, 7, -1, -1, 7, 7, -1},
|
|
{ 6, -1, 4, -1, 4, -1, 6, -1},
|
|
{ 5, -1, -1, 3, 3, -1, -1, 5},
|
|
{ 6, -1, -1, -1, -1, -1, 6, -1},
|
|
{-1, 7, -1, -1, -1, -1, 7, -1},
|
|
{-1, 4, -1, -1, -1, 4, -1, -1},
|
|
{-1, -1, 3, -1, -1, 3, -1, -1},
|
|
{-1, -1, 2, -1, 2, -1, -1, -1},
|
|
{-1, -1, -1, 5, 5, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 0, 0, -1, -1, 0, 0, -1},
|
|
{ 7, 4, 6, 6, 6, 4, 3, -1},
|
|
{ 5, 6, 6, 6, 2, 6, 6, 3},
|
|
{ 7, 4, 6, 6, 6, 4, 3, -1},
|
|
{-1, 0, 0, -1, -1, 0, 0, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, -1, -1, 7, 7, 7},
|
|
{-1, -1, -1, -1, 2, 7, 7, -1},
|
|
{-1, 0, 7, 7, 7, -1, 7, 7},
|
|
{ 6, 7, 7, 7, -1, -1, -1, -1},
|
|
{ 6, -1, -1, -1, 7, 7, 7, 7},
|
|
{ 6, -1, -1, -1, -1, -1, -1, -1},
|
|
{ 4, 2, 2, 2, 4, -1, 3, -1},
|
|
{ 4, 4, 4, 4, 3, 3, 3, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 4, -1, -1, 7, -1, 6, -1, 7},
|
|
{ 7, 6, 7, -1, -1, 7, 4, -1},
|
|
{-1, -1, 7, -1, -1, 7, -1, -1},
|
|
{-1, 0, 0, 0, 0, 0, 3, -1},
|
|
{-1, -1, 0, 2, 2, 0, 6, 4},
|
|
{-1, -1, 0, 0, 0, 1, 3, -1},
|
|
{-1, -1, -1, 0, 0, -1, 3, 4},
|
|
{-1, -1, -1, 6, -1, 5, 6, -1},
|
|
{-1, -1, -1, -1, -1, -1, 1, 0},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 5, -1, -1, -1, -1, 5, -1},
|
|
{ 0, -1, -1, 0, -1, -1, 0, -1},
|
|
{ 0, 0, 0, 2, 2, 0, 0, 0},
|
|
{ 0, -1, -1, 0, -1, -1, 0, -1},
|
|
{-1, 7, -1, 3, -1, -1, 7, -1},
|
|
{-1, -1, 3, 6, -1, -1, -1, -1},
|
|
{-1, -1, -1, 6, -1, -1, -1, -1},
|
|
{-1, 3, 6, -1, -1, -1, -1, -1},
|
|
{-1, 3, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 6, 5, -1, -1, -1},
|
|
{-1, -1, 2, 6, 3, -1, -1, -1},
|
|
{-1, -1, 5, 4, 7, 1, -1, -1},
|
|
{-1, 6, 2, 2, 3, 4, -1, -1},
|
|
{-1, -1, 3, 7, 3, 6, -1, -1},
|
|
{-1, -1, 1, 3, 2, -1, -1, -1},
|
|
{-1, -1, -1, 4, 5, -1, -1, -1},
|
|
{-1, -1, -1, 4, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 7, 7, -1, 2, 2, -1, 6, 6},
|
|
{ 6, -1, -1, 6, -1, -1, 3, -1},
|
|
{ 2, -1, -1, 1, -1, -1, 2, -1},
|
|
{ 5, -1, -1, 3, -1, -1, 2, -1},
|
|
{ 1, -1, -1, 2, -1, -1, 1, -1},
|
|
{ 5, -1, -1, 2, -1, -1, 2, -1},
|
|
{ 6, -1, -1, 1, -1, -1, 7, -1},
|
|
{ 5, -1, -1, 5, -1, -1, 4, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 6, 6, -1, -1, -1},
|
|
{-1, 0, 4, 4, 4, 0, -1, -1},
|
|
{-1, -1, -1, 6, 6, -1, -1, -1},
|
|
{-1, -1, 2, 7, 2, -1, -1, -1},
|
|
{-1, -1, -1, 6, 6, -1, -1, -1},
|
|
{-1, 0, 5, 5, 5, 0, -1, -1},
|
|
{-1, -1, -1, 3, 3, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 4, 1, 3, -1, -1, -1},
|
|
{-1, 1, -1, -1, 1, -1, -1, -1},
|
|
{-1, -1, 4, 1, 3, 4, 1, -1},
|
|
{-1, 1, 3, 4, -1, -1, 4, -1},
|
|
{-1, 3, -1, -1, 3, 4, 1, -1},
|
|
{-1, 1, 3, 4, 1, 3, -1, -1},
|
|
{-1, -1, 4, 1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 6, 4, -1, 3, 2, 5, -1},
|
|
{ 0, -1, -1, -1, -1, -1, 1, -1},
|
|
{-1, 2, 3, 5, -1, 4, 6, -1},
|
|
{ 0, -1, -1, -1, -1, -1, 1, -1},
|
|
{-1, 4, 6, -1, 2, 5, 3, -1},
|
|
{ 0, -1, -1, -1, -1, -1, 1, -1},
|
|
{-1, 5, 2, 3, -1, 4, 6, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 6, 6, -1, -1, -1},
|
|
{-1, -1, 7, 6, 4, -1, -1, -1},
|
|
{-1, 2, 1, 7, 4, 1, 3, -1},
|
|
{ 2, 1, 1, 1, 1, 1, 3, -1},
|
|
{-1, 2, 2, 2, 3, 3, 3, -1},
|
|
{-1, -1, -1, 5, -1, -1, -1, -1},
|
|
{-1, -1, -1, 2, 3, -1, -1, -1},
|
|
{-1, -1, -1, 5, -1, -1, -1, -1},
|
|
{-1, -1, 2, 2, 3, 3, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 4, -1, 5, -1, -1, 3, -1, 6},
|
|
{ 2, -1, 3, -1, 2, -1, 4, -1},
|
|
{ 4, -1, -1, 1, 0, -1, -1, 6},
|
|
{ 6, -1, 2, 3, 5, -1, 4, -1},
|
|
{ 4, -1, -1, 0, 1, -1, -1, 6},
|
|
{ 2, -1, 5, -1, 3, -1, 4, -1},
|
|
{ 4, -1, 3, -1, -1, 2, -1, 6},
|
|
{ 6, -1, -1, -1, -1, -1, 4, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 2, 6, 0, 5, 5, 1, 3, 4},
|
|
{ 1, -1, -1, 2, -1, -1, 0, -1},
|
|
{ 4, -1, -1, 3, 6, -1, -1, 2},
|
|
{-1, -1, -1, 0, -1, -1, -1, -1},
|
|
{-1, -1, -1, 1, 4, -1, -1, -1},
|
|
{-1, -1, -1, 2, -1, -1, -1, -1},
|
|
{-1, -1, -1, 6, 3, -1, -1, -1},
|
|
{-1, -1, -1, 5, -1, -1, -1, -1},
|
|
{-1, -1, -1, 4, 1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, -1, 5, 1, 1, 3},
|
|
{ 0, 5, 1, 0, 5, 3, 3, -1},
|
|
{ 5, 1, 0, 5, 1, 0, 5, 1},
|
|
{ 0, 5, 1, 0, 5, 1, 6, -1},
|
|
{-1, -1, -1, -1, 1, 6, 5, 1},
|
|
{-1, -1, -1, -1, 5, 1, 6, -1},
|
|
{-1, -1, -1, -1, 1, 0, 5, 1},
|
|
{-1, -1, -1, -1, 5, 1, 0, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 0, 7, 3, -1, -1, 2, 2},
|
|
{-1, 0, 7, 3, -1, -1, 2, -1},
|
|
{-1, 0, 7, 3, -1, -1, 2, 2},
|
|
{-1, 0, 7, 3, -1, 3, 1, -1},
|
|
{-1, 0, 7, 3, -1, 6, 4, 5},
|
|
{-1, 0, 7, 3, -1, 7, 0, -1},
|
|
{-1, 0, 7, 3, -1, 2, 3, 4},
|
|
{-1, 0, 7, 3, -1, 5, 6, -1},
|
|
{-1, -1, -1, -1, -1, 7, 0, 1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 7, 7, 7, 7, -1},
|
|
{ 3, 4, 5, -1, -1, -1, 7, -1},
|
|
{ 2, -1, -1, -1, -1, -1, -1, 3},
|
|
{ 7, -1, -1, -1, -1, -1, 4, -1},
|
|
{ 7, -1, -1, -1, 3, 4, 5, 6},
|
|
{ 7, -1, -1, 2, 0, 1, 2, -1},
|
|
{ 6, -1, -1, -1, 3, 4, 5, 6},
|
|
{ 0, 1, -1, -1, -1, -1, -1, -1},
|
|
{ 2, 3, 4, -1, -1, -1, -1, -1},
|
|
{ 5, 6, 0, -1, -1, -1, -1, -1}},
|
|
{{-1, 7, -1, -1, -1, -1, 2, -1},
|
|
{ 1, 1, -1, -1, -1, 3, 3, -1},
|
|
{-1, 2, -1, -1, -1, -1, 4, -1},
|
|
{ 3, 3, -1, -1, -1, 5, 5, -1},
|
|
{-1, 4, -1, -1, -1, -1, 6, -1},
|
|
{ 5, 5, -1, -1, -1, 1, 1, -1},
|
|
{-1, 6, -1, -1, -1, -1, 7, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 4, -1, -1, -1, -1, 4, -1},
|
|
{ 2, -1, -1, 1, -1, -1, 2, -1},
|
|
{ 5, -1, -1, 0, 0, -1, -1, 5},
|
|
{ 5, -1, -1, 1, -1, -1, 6, -1},
|
|
{-1, 4, 2, 7, 7, 5, 4, -1},
|
|
{-1, -1, -1, 6, -1, -1, -1, -1},
|
|
{-1, -1, -1, 3, 3, -1, -1, -1},
|
|
{-1, -1, -1, 7, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 1, -1, -1, 2, 3, 4, -1},
|
|
{ 2, -1, -1, 3, 0, 4, -1, -1},
|
|
{ 4, -1, -1, 2, 3, 1, -1, -1},
|
|
{ 3, -1, 4, 3, 0, -1, -1, -1},
|
|
{ 4, -1, -1, 2, 5, 1, -1, -1},
|
|
{ 3, -1, 4, 5, 0, 4, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 2, -1, -1, 1, 1, -1, -1, 2},
|
|
{ 2, -1, 3, 3, 3, -1, 2, -1},
|
|
{-1, 2, -1, 4, 4, -1, 2, -1},
|
|
{-1, 7, 7, 0, 7, 7, -1, -1},
|
|
{-1, -1, -1, 4, 4, -1, -1, -1},
|
|
{-1, -1, 5, 7, 5, -1, -1, -1},
|
|
{ 6, 3, 2, 6, 4, 2, 3, 6},
|
|
{ 5, -1, -1, -1, -1, -1, 1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 4, 2, 3, 5, 7, 1, 3, 6},
|
|
{ 1, -1, -1, 1, -1, -1, 1, -1},
|
|
{ 3, 0, 1, 3, 2, 4, 3, 5},
|
|
{ 4, -1, -1, 4, -1, -1, 4, -1},
|
|
{-1, 5, -1, -1, 5, -1, -1, 5},
|
|
{ 0, 3, 2, 0, 4, 5, 0, -1},
|
|
{-1, 6, -1, -1, 6, -1, -1, 6},
|
|
{ 7, -1, -1, 7, -1, -1, 7, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 5, 4, -1, 1, 1, -1, -1},
|
|
{ 5, -1, 4, 1, -1, 1, -1, -1},
|
|
{ 0, -1, -1, -1, -1, -1, 0, -1},
|
|
{ 0, 6, 4, -1, -1, 4, 2, -1},
|
|
{-1, 4, 3, 5, 2, 6, 3, 6},
|
|
{-1, 2, 6, -1, -1, 5, 4, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 6, 6, -1, -1, -1},
|
|
{-1, -1, 5, 5, 4, -1, -1, -1},
|
|
{-1, -1, 1, 6, 6, 4, -1, -1},
|
|
{-1, 1, 7, 2, 5, 3, -1, -1},
|
|
{-1, 2, 7, 2, 1, 5, 3, -1},
|
|
{ 2, 1, 3, 1, 4, 2, 7, -1},
|
|
{-1, 3, 1, 3, 4, 2, 7, -1},
|
|
{-1, 3, 5, 5, 6, 6, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 7, 3, -1, -1, -1, -1},
|
|
{-1, 1, 7, 6, -1, -1, -1, -1},
|
|
{-1, 3, 7, 5, 1, 5, -1, -1},
|
|
{ 7, 7, 0, 2, 4, 0, 4, -1},
|
|
{ 7, 1, 4, 6, 5, 6, 5, 7},
|
|
{ 1, 7, 7, 1, 7, 7, 1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 1, -1, -1, 1, -1, -1},
|
|
{-1, 5, 6, 1, 5, 6, -1, -1},
|
|
{-1, 1, 1, 2, 2, 1, 1, -1},
|
|
{ 4, 7, 1, 0, 1, 7, 4, -1},
|
|
{-1, 3, 7, 5, 7, 5, 3, -1},
|
|
{-1, 1, 1, 1, 1, 1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 4, -1, -1, -1, 5, -1, -1, 4},
|
|
{ 6, 6, 7, 6, -1, 4, 5, -1},
|
|
{ 4, 2, 7, 5, 2, 2, 6, 4},
|
|
{-1, -1, 4, 1, -1, 5, 2, -1},
|
|
{-1, 5, 2, 7, 7, -1, 7, 4},
|
|
{ 4, 6, 5, 4, -1, 4, 2, -1},
|
|
{-1, -1, -1, 4, -1, 4, 1, -1},
|
|
{ 0, 0, 0, 5, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, 0, 0, 0, 0},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 1, -1, -1, -1, 0, 0, -1, -1},
|
|
{ 2, -1, -1, 0, 1, 0, -1, -1},
|
|
{ 3, -1, -1, 0, 2, 2, 0, -1},
|
|
{ 4, -1, 0, 1, 1, 1, 0, -1},
|
|
{ 5, -1, -1, 0, 4, 4, 0, -1},
|
|
{ 6, -1, -1, 4, 4, 4, -1, -1},
|
|
{ 7, -1, -1, -1, 4, 4, -1, -1},
|
|
{-1, -1, -1, 0, 1, 0, -1, -1},
|
|
{-1, -1, -1, 0, 1, 1, 0, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 3, -1, -1, 1, 7, -1},
|
|
{-1, 7, 4, -1, -1, 4, 3, -1},
|
|
{ 1, -1, -1, 0, 2, 0, -1, -1},
|
|
{ 5, 4, -1, 3, -1, -1, -1, -1},
|
|
{ 4, -1, 3, 6, 1, 1, 6, -1},
|
|
{-1, 1, -1, -1, 4, -1, 1, -1},
|
|
{-1, 7, 5, -1, -1, -1, 3, -1},
|
|
{-1, -1, 3, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 1, -1, -1, -1, 1, -1, -1, -1},
|
|
{ 2, -1, -1, -1, 2, -1, -1, -1},
|
|
{-1, 3, -1, -1, 3, 3, -1, -1},
|
|
{-1, 4, -1, 4, -1, 4, -1, -1},
|
|
{-1, 5, -1, -1, 5, 5, -1, -1},
|
|
{ 6, -1, -1, 7, 1, 7, -1, -1},
|
|
{ 7, -1, -1, -1, 6, 6, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 2, -1, -1, 6, -1, 2, 5, 1},
|
|
{ 5, -1, 4, -1, 4, -1, 4, -1},
|
|
{ 6, -1, -1, 3, -1, -1, -1, 3},
|
|
{ 4, 2, 0, -1, -1, -1, 5, -1},
|
|
{-1, -1, -1, 6, -1, 3, 6, -1},
|
|
{-1, -1, 5, -1, 5, -1, -1, -1},
|
|
{-1, -1, -1, 3, -1, 4, 2, 5},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 6, -1, -1, -1, 4, -1, -1, 3},
|
|
{ 0, 3, -1, -1, 6, -1, 0, -1},
|
|
{-1, -1, 7, -1, 1, -1, 3, -1},
|
|
{ 7, -1, 4, 7, -1, 2, -1, -1},
|
|
{ 5, 2, 3, 2, 1, 6, -1, 3},
|
|
{-1, -1, 0, 4, 3, 5, 4, -1},
|
|
{-1, 7, 6, -1, -1, 0, -1, -1},
|
|
{ 4, 3, -1, -1, -1, 4, 2, -1},
|
|
{ 0, -1, -1, -1, -1, -1, 6, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 6, 1, 2, 5, 1, 6, 3, 0},
|
|
{-1, -1, -1, -1, -1, -1, 4, -1},
|
|
{ 0, 5, 2, 7, 1, 6, 2, -1},
|
|
{ 3, -1, -1, -1, -1, -1, -1, -1},
|
|
{ 6, 7, 6, 4, 0, 5, 2, 6},
|
|
{-1, -1, -1, -1, -1, -1, 1, -1},
|
|
{ 6, 1, 4, 0, 6, 2, 3, -1},
|
|
{ 0, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, 0, 4, 5, 3, 7, 6, 0},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 0, 1, -1, -1, -1},
|
|
{-1, -1, 0, 7, 0, -1, -1, -1},
|
|
{-1, -1, 1, 2, 2, 0, -1, -1},
|
|
{-1, 0, 7, 0, 7, 0, -1, -1},
|
|
{-1, 6, -1, 7, 7, -1, 6, -1},
|
|
{ 4, 1, 6, 6, 6, 4, 1, -1},
|
|
{-1, 5, -1, 7, 7, -1, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 5, 6, -1, -1, -1},
|
|
{-1, -1, 3, 3, 3, -1, -1, -1},
|
|
{-1, -1, 7, 5, 3, 7, -1, -1},
|
|
{-1, 3, -1, 6, -1, 3, -1, -1},
|
|
{ 2, -1, -1, 3, 7, -1, -1, 1},
|
|
{ 2, 2, -1, 3, -1, 1, 1, -1},
|
|
{-1, 0, 2, 5, 6, 1, 0, -1},
|
|
{-1, -1, -1, 3, -1, -1, -1, -1},
|
|
{-1, -1, -1, 3, 7, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 6, -1, -1, -1, -1, 2, -1},
|
|
{-1, 2, 6, 0, 6, 0, -1, -1},
|
|
{-1, 0, -1, -1, -1, -1, -1, -1},
|
|
{ 6, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, 3, 3, 2, 0, 6, 0, 0},
|
|
{-1, 6, -1, -1, -1, -1, 0, -1},
|
|
{-1, -1, -1, 6, 0, 2, 6, -1},
|
|
{-1, 2, 0, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 0, 7, -1, -1, -1, -1, -1, -1},
|
|
{ 1, 5, -1, -1, -1, -1, -1, -1},
|
|
{ 7, 2, 5, -1, -1, -1, -1, -1},
|
|
{ 6, 3, 4, -1, -1, -1, -1, -1},
|
|
{ 5, 5, 4, 4, -1, -1, -1, -1},
|
|
{ 3, 3, 5, 3, -1, -1, -1, -1},
|
|
{ 1, 2, 2, 5, 3, -1, -1, -1},
|
|
{ 1, 0, 0, 7, 6, -1, -1, -1},
|
|
{ 3, 3, 5, 5, 7, 6, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 2, 6, 6, 2, -1, -1},
|
|
{-1, 2, 1, 1, 0, 2, -1, -1},
|
|
{-1, 2, 3, 2, 2, 0, 2, -1},
|
|
{ 2, 3, 2, 5, 2, 7, 2, -1},
|
|
{ 2, 4, 2, 5, 2, 7, 2, 0},
|
|
{ 2, 4, 2, 6, 6, 2, 0, -1},
|
|
{-1, 2, 5, 2, 2, 2, 7, 2},
|
|
{-1, 2, 5, 6, 6, 7, 2, -1},
|
|
{-1, -1, 2, 2, 2, 2, 2, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 0, -1, -1, 0, -1, -1},
|
|
{ 1, 0, 0, 1, 0, 0, 1, -1},
|
|
{ 1, 7, 7, 5, 5, 7, 7, 1},
|
|
{ 3, 2, -1, 2, -1, 2, 3, -1},
|
|
{ 3, 7, -1, 6, 6, -1, 7, 3},
|
|
{ 7, -1, -1, 6, -1, -1, 7, -1},
|
|
{ 4, 4, 5, -1, -1, 5, 4, 4},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 6, 3, -1, -1, 3, 6, -1},
|
|
{ 6, -1, 2, -1, 2, -1, 6, -1},
|
|
{ 2, -1, 0, 1, 1, 0, -1, 2},
|
|
{ 5, 0, -1, 7, -1, 0, 5, -1},
|
|
{-1, 5, -1, 6, 6, -1, 5, -1},
|
|
{ 7, 1, 4, -1, 4, 1, 7, -1},
|
|
{ 7, -1, 4, -1, -1, 4, -1, 7},
|
|
{ 2, 0, -1, -1, -1, 0, 2, -1},
|
|
{-1, 2, -1, -1, -1, -1, 2, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 6, 1, -1, -1, -1, -1, 4, 0},
|
|
{ 2, 7, 5, 5, 5, 7, 3, -1},
|
|
{ 6, 1, -1, -1, -1, -1, 4, 0},
|
|
{ 2, 5, 7, 7, 7, 5, 3, -1},
|
|
{ 6, 1, -1, -1, -1, -1, 4, 0},
|
|
{ 2, 0, 6, 6, 6, 0, 3, -1},
|
|
{ 6, 1, -1, -1, -1, -1, 4, 0},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 5, -1, -1, 1, 1, -1, -1, 5},
|
|
{ 5, -1, 4, -1, 4, -1, 5, -1},
|
|
{-1, 2, 4, -1, -1, 4, 2, -1},
|
|
{ 7, 2, -1, -1, -1, 2, 7, -1},
|
|
{ 0, -1, 0, 4, 4, 0, -1, 0},
|
|
{ 7, 2, -1, -1, -1, 2, 7, -1},
|
|
{-1, 2, 3, -1, -1, 3, 2, -1},
|
|
{ 5, -1, 3, -1, 3, -1, 5, -1},
|
|
{ 5, -1, -1, 6, 6, -1, -1, 5},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 2, 2, -1, -1, -1, -1, 5, 5},
|
|
{ 5, -1, -1, -1, -1, -1, 2, -1},
|
|
{ 5, -1, -1, -1, -1, -1, -1, 2},
|
|
{ 1, -1, 1, 5, 1, -1, 3, -1},
|
|
{ 5, 2, 5, 3, 1, 2, 5, 2},
|
|
{ 2, 0, 5, -1, 2, 0, 5, -1},
|
|
{-1, 3, 7, -1, -1, 3, 7, -1},
|
|
{-1, -1, 2, 0, 5, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 0, 6, 5, 2, 3, 4, 1, 7},
|
|
{-1, -1, -1, -1, 1, -1, -1, -1},
|
|
{-1, -1, -1, 1, 1, -1, -1, -1},
|
|
{-1, -1, 1, -1, -1, -1, -1, -1},
|
|
{ 7, 1, 4, 3, 2, 5, 6, 0},
|
|
{-1, -1, -1, -1, 1, -1, -1, -1},
|
|
{-1, -1, -1, 1, 1, -1, -1, -1},
|
|
{-1, -1, 1, -1, -1, -1, -1, -1},
|
|
{ 0, 6, 5, 2, 3, 4, 1, 7},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, 1, -1, -1, 1, -1, -1},
|
|
{-1, 2, 4, -1, 2, 4, -1, -1},
|
|
{-1, 2, 3, 6, 5, 3, 2, -1},
|
|
{-1, 6, 5, -1, 6, 5, -1, -1},
|
|
{-1, -1, -1, 7, 7, -1, -1, -1},
|
|
{-1, -1, -1, 7, -1, -1, -1, -1},
|
|
{ 1, -1, -1, 7, 7, -1, -1, 3},
|
|
{ 2, -1, -1, 7, -1, -1, 2, -1},
|
|
{-1, 3, 4, 5, 6, 4, 1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 1, -1, -1, 2, 2, -1, -1, 2},
|
|
{ 1, 3, 7, 3, 7, 4, 2, -1},
|
|
{-1, 1, 6, -1, -1, 6, 2, -1},
|
|
{ 6, -1, 7, 3, 7, -1, 6, -1},
|
|
{-1, 4, 2, -1, -1, 1, 3, -1},
|
|
{-1, -1, 2, 6, 1, -1, -1, -1},
|
|
{-1, 4, 3, 3, 4, 4, 3, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, -1, -1, 5, 6, -1, -1, -1},
|
|
{-1, -1, -1, 3, -1, -1, -1, -1},
|
|
{-1, -1, -1, 1, 2, -1, -1, -1},
|
|
{-1, -1, -1, 4, -1, -1, -1, -1},
|
|
{-1, -1, -1, 5, 7, -1, -1, -1},
|
|
{-1, -1, -1, 2, -1, -1, -1, -1},
|
|
{ 6, 5, 4, 3, 2, 1, 7, 5},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{-1, 0, -1, 1, -1, 2, -1, -1},
|
|
{-1, 4, -1, 5, -1, 6, -1, -1},
|
|
{-1, 7, -1, 0, -1, 2, -1, -1},
|
|
{-1, 6, -1, 3, -1, 6, -1, -1},
|
|
{-1, 1, -1, 1, -1, 2, -1, -1},
|
|
{-1, 3, -1, 5, -1, 0, -1, -1},
|
|
{-1, 2, -1, 4, -1, 6, -1, -1},
|
|
{-1, 3, -1, 6, -1, 7, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 1, 1, 2, 2, 3, 3, 4, 4},
|
|
{ 5, 5, 6, 7, 6, 5, 5, -1},
|
|
{ 6, 4, 3, 3, 2, 2, 1, 6},
|
|
{ 4, 6, 5, 7, 6, 3, 1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 7, 4, -1, 1, 2, -1, 4, 7},
|
|
{ 5, 5, -1, 2, -1, 4, 4, -1},
|
|
{-1, 5, -1, 7, 7, -1, 4, -1},
|
|
{ 1, 0, 6, 7, 6, 0, 2, -1},
|
|
{-1, 2, -1, 5, 3, -1, 1, -1},
|
|
{ 1, 1, -1, -1, -1, 2, 2, -1},
|
|
{ 6, 1, 4, -1, -1, 4, 2, 6},
|
|
{ 5, 3, -1, -1, -1, 3, 5, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 1, 5, 1, 0, 0, 1, 5, 1},
|
|
{ 1, 2, 5, -1, 5, 2, 1, -1},
|
|
{ 3, 6, 1, 2, 2, 1, 6, 3},
|
|
{ 4, 3, 4, -1, 4, 3, 4, -1},
|
|
{ 3, 4, 6, 5, 5, 6, 4, 3},
|
|
{ 0, 2, 3, -1, 3, 2, 0, -1},
|
|
{ 2, 3, 1, 5, 5, 1, 3, 2},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}},
|
|
{{ 3, 0, 2, 7, 5, 7, 6, 5},
|
|
{ 6, -1, 1, -1, 2, -1, 1, -1},
|
|
{-1, 6, 4, 0, 3, 4, 5, -1},
|
|
{-1, 5, -1, 1, -1, 4, -1, -1},
|
|
{-1, 7, 3, 5, 6, 5, 3, -1},
|
|
{ 1, -1, 2, -1, 4, -1, 2, -1},
|
|
{ 6, 4, 4, 6, 6, 5, 5, 1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1},
|
|
{-1, -1, -1, -1, -1, -1, -1, -1}}
|
|
};
|
|
|
|
/* the tile struct
|
|
* type is the bubble number 0-7
|
|
* fallx is the x axis movement for the falling bubble
|
|
* fallvel is the initial upward velocity for the falling bubble
|
|
* ingroup denotes a bubble that is part of a group to be removed
|
|
* anchored denotes a bubble that is anchored to the ceiling
|
|
*/
|
|
struct tile {
|
|
int type;
|
|
int fallx;
|
|
int fallvel;
|
|
bool ingroup;
|
|
bool anchored;
|
|
bool delete;
|
|
};
|
|
|
|
/* the highscore struct
|
|
* level is the highscore level
|
|
* score is the highscore score
|
|
*/
|
|
struct highscore {
|
|
unsigned int level;
|
|
unsigned int score;
|
|
};
|
|
|
|
/* the game context struct
|
|
* score is the current score
|
|
* level is the current level
|
|
* highlevel is the highest level beaten
|
|
* highscores is the list of high scores
|
|
* angle is the current cannon direction
|
|
* shots is the number of shots fired since last compression
|
|
* compress is the height of the compressor
|
|
* onboardcnt is the number of unique bubbles on the playing board
|
|
* onboard is the unique bubbles on the playing board
|
|
* nextinq is the pointer to the next bubble in the firing queue
|
|
* queue is the circular buffer of bubbles to be fired
|
|
* elapsedlvl is level elapsed time in 1/100s of seconds
|
|
* elapsedshot is the shot elapsed time in 1/100s of seconds
|
|
* startedshot is when the current shot began
|
|
* resume denotes whether to resume the currently loaded game
|
|
* dirty denotes whether the high scores are out of sync with the saved file
|
|
* playboard is the game playing board
|
|
*/
|
|
struct game_context {
|
|
unsigned int score;
|
|
unsigned int level;
|
|
unsigned int highlevel;
|
|
struct highscore highscores[NUM_SCORES];
|
|
int angle;
|
|
int shots;
|
|
int compress;
|
|
int onboardcnt;
|
|
int onboard[NUM_BUBBLES];
|
|
int nextinq;
|
|
int queue[NUM_QUEUE];
|
|
long elapsedlvl;
|
|
long elapsedshot;
|
|
long startedshot;
|
|
bool resume;
|
|
bool dirty;
|
|
struct tile playboard[BB_HEIGHT][BB_WIDTH];
|
|
};
|
|
|
|
/*
|
|
* Precalculated sine and cosine * 16384 (fixed point 18.14)
|
|
* Borrowed from cube.c plugin
|
|
*/
|
|
static const short sin_table[91] = {
|
|
0, 285, 571, 857, 1142, 1427, 1712, 1996, 2280, 2563,
|
|
2845, 3126, 3406, 3685, 3963, 4240, 4516, 4790, 5062, 5334,
|
|
5603, 5871, 6137, 6401, 6663, 6924, 7182, 7438, 7691, 7943,
|
|
8191, 8438, 8682, 8923, 9161, 9397, 9630, 9860, 10086, 10310,
|
|
10531, 10748, 10963, 11173, 11381, 11585, 11785, 11982, 12175, 12365,
|
|
12550, 12732, 12910, 13084, 13254, 13420, 13582, 13740, 13894, 14043,
|
|
14188, 14329, 14466, 14598, 14725, 14848, 14967, 15081, 15190, 15295,
|
|
15395, 15491, 15582, 15668, 15749, 15825, 15897, 15964, 16025, 16082,
|
|
16135, 16182, 16224, 16261, 16294, 16321, 16344, 16361, 16374, 16381,
|
|
16384
|
|
};
|
|
|
|
static long sin(int val) {
|
|
val = (val+360)%360;
|
|
|
|
if(val < 181) {
|
|
if(val < 91) {
|
|
/* phase 0-90 degree */
|
|
return (long)sin_table[val];
|
|
} else {
|
|
/* phase 91-180 degree */
|
|
return (long)sin_table[180-val];
|
|
}
|
|
} else {
|
|
if(val < 271) {
|
|
/* phase 181-270 degree */
|
|
return -(long)sin_table[val-180];
|
|
} else {
|
|
/* phase 270-359 degree */
|
|
return -(long)sin_table[360-val];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static long cos(int val) {
|
|
val = (val+360)%360;
|
|
|
|
if(val < 181) {
|
|
if(val < 91) {
|
|
/* phase 0-90 degree */
|
|
return (long)sin_table[90-val];
|
|
} else {
|
|
/* phase 91-180 degree */
|
|
return -(long)sin_table[val-90];
|
|
}
|
|
} else {
|
|
if(val < 271) {
|
|
/* phase 181-270 degree */
|
|
return -(long)sin_table[270-val];
|
|
} else {
|
|
/* phase 270-359 degree */
|
|
return (long)sin_table[val-270];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
static void bubbles_init(struct game_context* bb);
|
|
static bool bubbles_nextlevel(struct game_context* bb);
|
|
static void bubbles_getonboard(struct game_context* bb);
|
|
static void bubbles_drawboard(struct game_context* bb);
|
|
static int bubbles_fire(struct game_context* bb);
|
|
static bool bubbles_collision(struct game_context* bb, int y, int x,
|
|
int nearrow, int nearcol);
|
|
static bool bubbles_ingroup(struct game_context* bb, int row, int col);
|
|
static int bubbles_searchgroup(struct game_context* bb, int row, int col);
|
|
static int bubbles_remove(struct game_context* bb);
|
|
static void bubbles_anchored(struct game_context* bb, int row, int col);
|
|
static int bubbles_fall(struct game_context* bb);
|
|
static int bubbles_checklevel(struct game_context* bb);
|
|
static int bubbles_recordscore(struct game_context* bb);
|
|
static void bubbles_savescores(struct game_context* bb);
|
|
static bool bubbles_loadgame(struct game_context* bb);
|
|
static void bubbles_savegame(struct game_context* bb);
|
|
static void bubbles_setcolors(void);
|
|
static void bubbles_callback(void* param);
|
|
static int bubbles_handlebuttons(struct game_context* bb, bool animblock,
|
|
int timeout);
|
|
static int bubbles(struct game_context* bb);
|
|
|
|
/*****************************************************************************
|
|
* bubbles_init() initializes bubbles data structures.
|
|
******************************************************************************/
|
|
static void bubbles_init(struct game_context* bb) {
|
|
/* seed the rand generator */
|
|
rb->srand(*rb->current_tick);
|
|
|
|
/* check for resumed game */
|
|
if(bb->resume) {
|
|
bb->resume = false;
|
|
return;
|
|
}
|
|
|
|
bb->score = 0;
|
|
bubbles_nextlevel(bb);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_nextlevel() sets up the game for the next level, returns false if
|
|
* there are no more levels.
|
|
******************************************************************************/
|
|
static bool bubbles_nextlevel(struct game_context* bb) {
|
|
int i, j, pos;
|
|
|
|
bb->level++;
|
|
|
|
/* check if there are no more levels */
|
|
if(bb->level > NUM_LEVELS) return false;
|
|
|
|
/* set up the play board */
|
|
rb->memset(bb->playboard, 0, sizeof(bb->playboard));
|
|
for(i=0; i<BB_LEVEL_HEIGHT; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
pos = (int)level[bb->level-1][i][j];
|
|
if(pos >=0 && pos < NUM_BUBBLES) {
|
|
bb->playboard[i][j].type = pos;
|
|
} else {
|
|
bb->playboard[i][j].type = -1;
|
|
}
|
|
}
|
|
}
|
|
for(i=BB_LEVEL_HEIGHT; i<BB_HEIGHT; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
bb->playboard[i][j].type = -1;
|
|
}
|
|
}
|
|
|
|
/* fill first bubbles in shot queue */
|
|
bubbles_getonboard(bb);
|
|
for(i=0; i<NUM_QUEUE; i++) {
|
|
bb->queue[i] = bb->onboard[rb->rand()%bb->onboardcnt];
|
|
}
|
|
|
|
bb->angle = 0;
|
|
bb->shots = 0;
|
|
bb->compress = 0;
|
|
bb->nextinq = 0;
|
|
bb->elapsedlvl = 0;
|
|
bb->elapsedshot = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_getonboard() determines which bubble types are on the play board.
|
|
******************************************************************************/
|
|
static void bubbles_getonboard(struct game_context* bb) {
|
|
int i, j, k;
|
|
bool found;
|
|
|
|
bb->onboardcnt = 0;
|
|
rb->memset(bb->onboard, -1, sizeof(bb->onboard));
|
|
|
|
for(i=0; i<BB_HEIGHT; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
if(bb->playboard[i][j].type >= 0) {
|
|
found = false;
|
|
|
|
for(k=0; k<bb->onboardcnt; k++) {
|
|
if(bb->playboard[i][j].type == bb->onboard[k]) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!found) {
|
|
bb->onboard[bb->onboardcnt] = bb->playboard[i][j].type;
|
|
bb->onboardcnt++;
|
|
}
|
|
|
|
if(bb->onboardcnt == NUM_BUBBLES) return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_drawboard() draws the game board to the buffer but does not update
|
|
* the lcd.
|
|
******************************************************************************/
|
|
static void bubbles_drawboard(struct game_context* bb) {
|
|
int i, j;
|
|
int w, h;
|
|
int colmax, indent;
|
|
int tipx, tipy;
|
|
bool evenline = false;
|
|
char *level = "Level";
|
|
char *score = "Score";
|
|
char *next = "Next";
|
|
char *hurry = "HURRY!";
|
|
char str[11];
|
|
|
|
/* clear screen */
|
|
rb->lcd_clear_display();
|
|
|
|
/* draw sidebars */
|
|
#ifdef HAVE_LCD_COLOR
|
|
rb->lcd_bitmap(bubbles_left, 0, 0, XOFS, LCD_HEIGHT);
|
|
rb->lcd_bitmap(bubbles_right, XOFS-1+BB_WIDTH*BUBBLE_SZ, 0,
|
|
LCD_WIDTH-(XOFS-1+BB_WIDTH*BUBBLE_SZ), LCD_HEIGHT);
|
|
#endif
|
|
|
|
/* display play board */
|
|
for(i=0; i<BB_HEIGHT; i++) {
|
|
colmax = BB_WIDTH;
|
|
if(evenline) {
|
|
colmax--;
|
|
indent = ROW_INDENT;
|
|
} else {
|
|
indent = 0;
|
|
}
|
|
evenline = !evenline;
|
|
|
|
for(j=0; j<colmax; j++) {
|
|
if(bb->playboard[i][j].type >= 0 && !bb->playboard[i][j].delete) {
|
|
rb->lcd_bitmap_part(bubbles_emblem,
|
|
0, EMBLEM_SZ*bb->playboard[i][j].type, EMBLEM_SZ,
|
|
XOFS+indent+BUBBLE_SZ*j+(BUBBLE_SZ-EMBLEM_SZ)/2,
|
|
ROW_HEIGHT*i+(BUBBLE_SZ-EMBLEM_SZ)/2+bb->compress*ROW_HEIGHT,
|
|
EMBLEM_SZ, EMBLEM_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_FG);
|
|
rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble,
|
|
XOFS+indent+BUBBLE_SZ*j,
|
|
ROW_HEIGHT*i+bb->compress*ROW_HEIGHT,
|
|
BUBBLE_SZ, BUBBLE_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* display bubble to be shot */
|
|
rb->lcd_bitmap_part(bubbles_emblem,
|
|
0, EMBLEM_SZ*bb->queue[bb->nextinq], EMBLEM_SZ,
|
|
SHOTX+(BUBBLE_SZ-EMBLEM_SZ)/2,
|
|
SHOTY+(BUBBLE_SZ-EMBLEM_SZ)/2,
|
|
EMBLEM_SZ, EMBLEM_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_FG);
|
|
rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble,
|
|
SHOTX, SHOTY,
|
|
BUBBLE_SZ, BUBBLE_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
|
|
/* display next bubble to be shot */
|
|
rb->lcd_bitmap_part(bubbles_emblem,
|
|
0, EMBLEM_SZ*bb->queue[(bb->nextinq+1)%NUM_QUEUE], EMBLEM_SZ,
|
|
XOFS/2-BUBBLE_SZ/2+(BUBBLE_SZ-EMBLEM_SZ)/2,
|
|
SHOTY+(BUBBLE_SZ-EMBLEM_SZ)/2,
|
|
EMBLEM_SZ, EMBLEM_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_FG);
|
|
rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble,
|
|
XOFS/2-BUBBLE_SZ/2, SHOTY,
|
|
BUBBLE_SZ, BUBBLE_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
|
|
/* draw bounding lines */
|
|
#ifndef HAVE_LCD_COLOR
|
|
rb->lcd_vline(XOFS-1, 0, LCD_HEIGHT);
|
|
rb->lcd_vline(XOFS+BUBBLE_SZ*BB_WIDTH, 0, LCD_HEIGHT);
|
|
#endif
|
|
rb->lcd_hline(XOFS, XOFS+BUBBLE_SZ*BB_WIDTH-1, bb->compress*ROW_HEIGHT-1);
|
|
rb->lcd_hline(XOFS, XOFS+BUBBLE_SZ*BB_WIDTH-1,
|
|
ROW_HEIGHT*(BB_HEIGHT-2)+BUBBLE_SZ);
|
|
|
|
/* draw arrow */
|
|
tipx = SHOTX+BUBBLE_SZ/2+(((sin(bb->angle)>>4)*BUBBLE_SZ*3/2)>>10);
|
|
tipy = SHOTY+BUBBLE_SZ/2-(((cos(bb->angle)>>4)*BUBBLE_SZ*3/2)>>10);
|
|
|
|
rb->lcd_drawline(SHOTX+BUBBLE_SZ/2+(((sin(bb->angle)>>4)*BUBBLE_SZ/2)>>10),
|
|
SHOTY+BUBBLE_SZ/2-(((cos(bb->angle)>>4)*BUBBLE_SZ/2)>>10),
|
|
tipx, tipy);
|
|
xlcd_filltriangle(tipx, tipy,
|
|
tipx+(((sin(bb->angle-135)>>4)*BUBBLE_SZ/3)>>10),
|
|
tipy-(((cos(bb->angle-135)>>4)*BUBBLE_SZ/3)>>10),
|
|
tipx+(((sin(bb->angle+135)>>4)*BUBBLE_SZ/3)>>10),
|
|
tipy-(((cos(bb->angle+135)>>4)*BUBBLE_SZ/3)>>10));
|
|
|
|
/* draw text */
|
|
rb->lcd_getstringsize(level, &w, &h);
|
|
rb->lcd_putsxy(XOFS/2-w/2, 2, level);
|
|
|
|
rb->snprintf(str, 4, "%d", bb->level);
|
|
rb->lcd_getstringsize(str, &w, &h);
|
|
rb->lcd_putsxy(XOFS/2-w/2, 11, str);
|
|
|
|
rb->lcd_getstringsize(score, &w, &h);
|
|
rb->lcd_putsxy(XOFS/2-w/2, 29, score);
|
|
|
|
rb->snprintf(str, 10, "%d", bb->score);
|
|
rb->lcd_getstringsize(str, &w, &h);
|
|
rb->lcd_putsxy(XOFS/2-w/2, 38, str);
|
|
|
|
rb->lcd_getstringsize(next, &w, &h);
|
|
rb->lcd_putsxy(XOFS/2-w/2, SHOTY-9, next);
|
|
|
|
if(bb->elapsedshot >= (MAX_SHOTTIME*7)/10) {
|
|
rb->lcd_getstringsize(hurry, &w, &h);
|
|
rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-h/2, hurry);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_fire() fires the current bubble, reloads the cannon, attaches
|
|
* bubble to playboard, removes appropriate bubbles, and advances the
|
|
* the compressor.
|
|
******************************************************************************/
|
|
static int bubbles_fire(struct game_context* bb) {
|
|
int bubblecur;
|
|
long shotxinc, shotyinc;
|
|
long shotxofs, shotyofs;
|
|
int shotxdirec = 1;
|
|
long tempxofs, tempyofs;
|
|
int nearrow, nearcol;
|
|
int lastrow = BB_HEIGHT-1;
|
|
int lastcol = (BB_WIDTH-1)/2;
|
|
int buttonres;
|
|
long lasttick, currenttick;
|
|
|
|
/* get current bubble */
|
|
bubblecur = bb->queue[bb->nextinq];
|
|
shotxinc = ((sin(bb->angle)>>4)*BUBBLE_SZ)/3;
|
|
shotyinc = ((-1*(cos(bb->angle)>>4))*BUBBLE_SZ)/3;
|
|
shotxofs = shotyofs = 0;
|
|
|
|
/* advance the queue */
|
|
bb->queue[bb->nextinq] = bb->onboard[rb->rand()%bb->onboardcnt];
|
|
bb->nextinq = (bb->nextinq+1)%NUM_QUEUE;
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_update_rect(0, 0, XOFS, LCD_HEIGHT);
|
|
|
|
/* move the bubble across the play board */
|
|
lasttick = *rb->current_tick;
|
|
|
|
while(true) {
|
|
/* move the bubble one step */
|
|
shotyofs += shotyinc;
|
|
shotxofs += shotxinc*shotxdirec;
|
|
|
|
/* check for bounce off sides */
|
|
if(SHOTX+(shotxofs>>10) < XOFS) {
|
|
shotxofs += 2*((XOFS<<10)-(((SHOTX)<<10)+shotxofs));
|
|
shotxdirec *= -1;
|
|
} else if(SHOTX+(shotxofs>>10) > XOFS+(BB_WIDTH-1)*BUBBLE_SZ) {
|
|
shotxofs -= 2*((((SHOTX)<<10)+shotxofs)-
|
|
((XOFS<<10)+(((BB_WIDTH-1)*BUBBLE_SZ)<<10)));
|
|
shotxdirec *= -1;
|
|
}
|
|
|
|
tempxofs = shotxofs>>10;
|
|
tempyofs = shotyofs>>10;
|
|
|
|
/* display shot */
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_bitmap_part(bubbles_emblem, 0, EMBLEM_SZ*bubblecur, EMBLEM_SZ,
|
|
SHOTX+tempxofs+(BUBBLE_SZ-EMBLEM_SZ)/2,
|
|
SHOTY+tempyofs+(BUBBLE_SZ-EMBLEM_SZ)/2,
|
|
EMBLEM_SZ, EMBLEM_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_FG);
|
|
rb->lcd_mono_bitmap((const unsigned char *)bubbles_bubble,
|
|
SHOTX+tempxofs, SHOTY+tempyofs,
|
|
BUBBLE_SZ, BUBBLE_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
rb->lcd_update_rect(XOFS, 0, BB_WIDTH*BUBBLE_SZ, LCD_HEIGHT);
|
|
|
|
/* find nearest position */
|
|
nearrow = ((SHOTY+tempyofs)-
|
|
(bb->compress*ROW_HEIGHT)+
|
|
(ROW_HEIGHT/2))/ROW_HEIGHT;
|
|
if(nearrow >= BB_HEIGHT) nearrow = BB_HEIGHT-1;
|
|
|
|
if(nearrow%2) { /* odd row */
|
|
nearcol = ((SHOTX+tempxofs)-
|
|
(XOFS+ROW_INDENT)+
|
|
(BUBBLE_SZ/2))/BUBBLE_SZ;
|
|
if(nearcol >= BB_WIDTH-1) nearcol = BB_WIDTH-2;
|
|
} else { /* even row */
|
|
nearcol = ((SHOTX+tempxofs)-XOFS+(BUBBLE_SZ/2))/BUBBLE_SZ;
|
|
if(nearcol >= BB_WIDTH) nearcol = BB_WIDTH-1;
|
|
}
|
|
if(nearcol < 0) nearcol = 0;
|
|
|
|
/* if nearest position is occupied attach to last position */
|
|
if(bb->playboard[nearrow][nearcol].type >= 0) {
|
|
bb->playboard[lastrow][lastcol].type = bubblecur;
|
|
break;
|
|
}
|
|
|
|
/* save last position */
|
|
lastrow = nearrow;
|
|
lastcol = nearcol;
|
|
|
|
/* if collision with neighbor then attach shot */
|
|
if(bubbles_collision(bb, SHOTY+tempyofs, SHOTX+tempxofs,
|
|
nearrow, nearcol)) {
|
|
bb->playboard[nearrow][nearcol].type = bubblecur;
|
|
break;
|
|
}
|
|
|
|
/* if at top then attach shot to the ceiling */
|
|
if(nearrow == 0 && SHOTY+tempyofs <= bb->compress*ROW_HEIGHT) {
|
|
bb->playboard[nearrow][nearcol].type = bubblecur;
|
|
break;
|
|
}
|
|
|
|
/* handle button events */
|
|
buttonres = bubbles_handlebuttons(bb, true, 0);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
|
|
/* framerate limiting */
|
|
currenttick = *rb->current_tick;
|
|
if(currenttick-lasttick < HZ/MAX_FPS) {
|
|
rb->sleep((HZ/MAX_FPS)-(currenttick-lasttick));
|
|
} else {
|
|
rb->yield();
|
|
}
|
|
lasttick = currenttick;
|
|
}
|
|
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_update();
|
|
|
|
/* clear appropriate bubbles from playing board */
|
|
if(bubbles_ingroup(bb, lastrow, lastcol)) {
|
|
buttonres = bubbles_remove(bb);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
}
|
|
|
|
/* update shots and compress amount */
|
|
bb->shots++;
|
|
if(bb->shots >= NUM_COMPRESS) {
|
|
bb->shots = 0;
|
|
bb->compress++;
|
|
}
|
|
|
|
return BB_NONE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_collision() determines if a fired bubble has collided with another
|
|
* bubble.
|
|
******************************************************************************/
|
|
static bool bubbles_collision(struct game_context* bb, int y, int x,
|
|
int nearrow, int nearcol) {
|
|
int nx, ny;
|
|
int adj = nearrow%2;
|
|
|
|
/* check neighbors */
|
|
if(nearcol-1 >= 0) {
|
|
if(bb->playboard[nearrow][nearcol-1].type >= 0) {
|
|
nx = XOFS+(nearrow%2 ? ROW_INDENT : 0)+BUBBLE_SZ*(nearcol-1);
|
|
ny = ROW_HEIGHT*nearrow+bb->compress*ROW_HEIGHT;
|
|
if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true;
|
|
}
|
|
}
|
|
|
|
if(nearcol-1+adj >= 0) {
|
|
if(nearrow-1 >= 0) {
|
|
if(bb->playboard[nearrow-1][nearcol-1+adj].type >= 0) {
|
|
nx = XOFS+((nearrow-1)%2 ? ROW_INDENT : 0)+
|
|
BUBBLE_SZ*(nearcol-1+adj);
|
|
ny = ROW_HEIGHT*(nearrow-1)+bb->compress*ROW_HEIGHT;
|
|
if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true;
|
|
}
|
|
}
|
|
|
|
if(nearrow+1 < BB_HEIGHT) {
|
|
if(bb->playboard[nearrow+1][nearcol-1+adj].type >= 0) {
|
|
nx = XOFS+((nearrow+1)%2 ? ROW_INDENT : 0)+
|
|
BUBBLE_SZ*(nearcol-1+adj);
|
|
ny = ROW_HEIGHT*(nearrow+1)+bb->compress*ROW_HEIGHT;
|
|
if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(nearcol+adj >= 0) {
|
|
if(nearrow-1 >= 0) {
|
|
if(bb->playboard[nearrow-1][nearcol+adj].type >= 0) {
|
|
nx = XOFS+((nearrow-1)%2 ? ROW_INDENT : 0)+
|
|
BUBBLE_SZ*(nearcol+adj);
|
|
ny = ROW_HEIGHT*(nearrow-1)+bb->compress*ROW_HEIGHT;
|
|
if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true;
|
|
}
|
|
}
|
|
|
|
if(nearrow+1 < BB_HEIGHT) {
|
|
if(bb->playboard[nearrow+1][nearcol+adj].type >= 0) {
|
|
nx = XOFS+((nearrow+1)%2 ? ROW_INDENT : 0)+
|
|
BUBBLE_SZ*(nearcol+adj);
|
|
ny = ROW_HEIGHT*(nearrow+1)+bb->compress*ROW_HEIGHT;
|
|
if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(nearcol+1 < BB_WIDTH-adj) {
|
|
if(bb->playboard[nearrow][nearcol+1].type >= 0) {
|
|
nx = XOFS+(nearrow%2 ? ROW_INDENT : 0)+BUBBLE_SZ*(nearcol+1);
|
|
ny = ROW_HEIGHT*nearrow+bb->compress*ROW_HEIGHT;
|
|
if((x-nx)*(x-nx)+(y-ny)*(y-ny) < MIN_DISTANCE) return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_ingroup() marks all bubbles that form the current group.
|
|
******************************************************************************/
|
|
static bool bubbles_ingroup(struct game_context* bb, int row, int col) {
|
|
int i, j;
|
|
int count;
|
|
|
|
count = bubbles_searchgroup(bb, row, col);
|
|
|
|
/* unmark group if too small */
|
|
if(count < 3) {
|
|
for(i=0; i<BB_HEIGHT; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
bb->playboard[i][j].ingroup = false;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_searchgroup() return the size of the group of bubbles of the same
|
|
* type that the current bubble belongs to.
|
|
******************************************************************************/
|
|
static int bubbles_searchgroup(struct game_context* bb, int row, int col) {
|
|
int i, adj;
|
|
int myrow, mycol, mytype;
|
|
int count = 0;
|
|
|
|
struct coord {
|
|
int row;
|
|
int col;
|
|
} search[(2*BB_WIDTH-1)*(BB_HEIGHT/2)];
|
|
|
|
/* search initial bubble */
|
|
bb->playboard[row][col].ingroup = true;
|
|
search[count].row = row;
|
|
search[count].col = col;
|
|
count++;
|
|
|
|
/* breadth-first search neighbors */
|
|
for(i=0; i<count; i++) {
|
|
myrow = search[i].row;
|
|
mycol = search[i].col;
|
|
mytype = bb->playboard[myrow][mycol].type;
|
|
adj = myrow%2;
|
|
|
|
if(mycol-1 >= 0) {
|
|
if(bb->playboard[myrow][mycol-1].type == mytype &&
|
|
!bb->playboard[myrow][mycol-1].ingroup) {
|
|
bb->playboard[myrow][mycol-1].ingroup = true;
|
|
search[count].row = myrow;
|
|
search[count].col = mycol-1;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(mycol-1+adj >= 0) {
|
|
if(myrow-1 >= 0) {
|
|
if(bb->playboard[myrow-1][mycol-1+adj].type == mytype &&
|
|
!bb->playboard[myrow-1][mycol-1+adj].ingroup) {
|
|
bb->playboard[myrow-1][mycol-1+adj].ingroup = true;
|
|
search[count].row = myrow-1;
|
|
search[count].col = mycol-1+adj;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(myrow+1 < BB_HEIGHT) {
|
|
if(bb->playboard[myrow+1][mycol-1+adj].type == mytype &&
|
|
!bb->playboard[myrow+1][mycol-1+adj].ingroup) {
|
|
bb->playboard[myrow+1][mycol-1+adj].ingroup = true;
|
|
search[count].row = myrow+1;
|
|
search[count].col = mycol-1+adj;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(mycol+adj >= 0) {
|
|
if(myrow-1 >= 0) {
|
|
if(bb->playboard[myrow-1][mycol+adj].type == mytype &&
|
|
!bb->playboard[myrow-1][mycol+adj].ingroup) {
|
|
bb->playboard[myrow-1][mycol+adj].ingroup = true;
|
|
search[count].row = myrow-1;
|
|
search[count].col = mycol+adj;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(myrow+1 < BB_HEIGHT) {
|
|
if(bb->playboard[myrow+1][mycol+adj].type == mytype &&
|
|
!bb->playboard[myrow+1][mycol+adj].ingroup) {
|
|
bb->playboard[myrow+1][mycol+adj].ingroup = true;
|
|
search[count].row = myrow+1;
|
|
search[count].col = mycol+adj;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(mycol+1 < BB_WIDTH-adj) {
|
|
if(bb->playboard[myrow][mycol+1].type == mytype &&
|
|
!bb->playboard[myrow][mycol+1].ingroup) {
|
|
bb->playboard[myrow][mycol+1].ingroup = true;
|
|
search[count].row = myrow;
|
|
search[count].col = mycol+1;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_remove() removes all bubbles in the current group and all
|
|
* unanchored bubbles from the play board.
|
|
******************************************************************************/
|
|
static int bubbles_remove(struct game_context* bb) {
|
|
int i, j;
|
|
int buttonres;
|
|
|
|
/* determine all anchored bubbles */
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
if(bb->playboard[0][j].type >= 0 && !bb->playboard[0][j].ingroup) {
|
|
bubbles_anchored(bb, 0, j);
|
|
}
|
|
}
|
|
|
|
/* mark bubbles to be deleted */
|
|
for(i=0; i<BB_HEIGHT; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
if(bb->playboard[i][j].type >= 0 &&
|
|
(!bb->playboard[i][j].anchored || bb->playboard[i][j].ingroup)) {
|
|
bb->playboard[i][j].delete = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* animate falling bubbles */
|
|
buttonres = bubbles_fall(bb);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
|
|
/* remove bubbles */
|
|
for(i=0; i<BB_HEIGHT; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
if(bb->playboard[i][j].delete) {
|
|
bb->playboard[i][j].ingroup = false;
|
|
bb->playboard[i][j].type = -1;
|
|
bb->playboard[i][j].delete = false;
|
|
} else {
|
|
bb->playboard[i][j].anchored = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
bubbles_getonboard(bb);
|
|
|
|
return BB_NONE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_anchored() marks all bubbles that are anchored in some way to the
|
|
* current bubble.
|
|
******************************************************************************/
|
|
static void bubbles_anchored(struct game_context* bb, int row, int col) {
|
|
int i, adj;
|
|
int myrow, mycol, mytype;
|
|
int count = 0;
|
|
|
|
struct coord {
|
|
int row;
|
|
int col;
|
|
} search[(2*BB_WIDTH-1)*(BB_HEIGHT/2)];
|
|
|
|
/* search initial bubble */
|
|
bb->playboard[row][col].anchored = true;
|
|
search[count].row = row;
|
|
search[count].col = col;
|
|
count++;
|
|
|
|
/* breadth-first search neighbors */
|
|
for(i=0; i<count; i++) {
|
|
myrow = search[i].row;
|
|
mycol = search[i].col;
|
|
mytype = bb->playboard[myrow][mycol].type;
|
|
adj = myrow%2;
|
|
|
|
if(mycol-1 >= 0) {
|
|
if(bb->playboard[myrow][mycol-1].type >= 0 &&
|
|
!bb->playboard[myrow][mycol-1].ingroup &&
|
|
!bb->playboard[myrow][mycol-1].anchored) {
|
|
bb->playboard[myrow][mycol-1].anchored = true;
|
|
search[count].row = myrow;
|
|
search[count].col = mycol-1;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(mycol-1+adj >= 0) {
|
|
if(myrow-1 >= 0) {
|
|
if(bb->playboard[myrow-1][mycol-1+adj].type >= 0 &&
|
|
!bb->playboard[myrow-1][mycol-1+adj].ingroup &&
|
|
!bb->playboard[myrow-1][mycol-1+adj].anchored) {
|
|
bb->playboard[myrow-1][mycol-1+adj].anchored = true;
|
|
search[count].row = myrow-1;
|
|
search[count].col = mycol-1+adj;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(myrow+1 < BB_HEIGHT) {
|
|
if(bb->playboard[myrow+1][mycol-1+adj].type >= 0 &&
|
|
!bb->playboard[myrow+1][mycol-1+adj].ingroup &&
|
|
!bb->playboard[myrow+1][mycol-1+adj].anchored) {
|
|
bb->playboard[myrow+1][mycol-1+adj].anchored = true;
|
|
search[count].row = myrow+1;
|
|
search[count].col = mycol-1+adj;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(mycol+adj >= 0) {
|
|
if(myrow-1 >= 0) {
|
|
if(bb->playboard[myrow-1][mycol+adj].type >= 0 &&
|
|
!bb->playboard[myrow-1][mycol+adj].ingroup &&
|
|
!bb->playboard[myrow-1][mycol+adj].anchored) {
|
|
bb->playboard[myrow-1][mycol+adj].anchored = true;
|
|
search[count].row = myrow-1;
|
|
search[count].col = mycol+adj;
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if(myrow+1 < BB_HEIGHT) {
|
|
if(bb->playboard[myrow+1][mycol+adj].type >= 0 &&
|
|
!bb->playboard[myrow+1][mycol+adj].ingroup &&
|
|
!bb->playboard[myrow+1][mycol+adj].anchored) {
|
|
bb->playboard[myrow+1][mycol+adj].anchored = true;
|
|
search[count].row = myrow+1;
|
|
search[count].col = mycol+adj;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(mycol+1 < BB_WIDTH-adj) {
|
|
if(bb->playboard[myrow][mycol+1].type >= 0 &&
|
|
!bb->playboard[myrow][mycol+1].ingroup &&
|
|
!bb->playboard[myrow][mycol+1].anchored) {
|
|
bb->playboard[myrow][mycol+1].anchored = true;
|
|
search[count].row = myrow;
|
|
search[count].col = mycol+1;
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_fall() makes removed bubbles fall from the screen.
|
|
******************************************************************************/
|
|
static int bubbles_fall(struct game_context* bb) {
|
|
int i, j;
|
|
int count;
|
|
int indent;
|
|
int xofs, yofs;
|
|
int buttonres;
|
|
bool onscreen;
|
|
long lasttick, currenttick;
|
|
|
|
/* give all falling bubbles an x axis movement */
|
|
for(i=0; i<BB_HEIGHT; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
if(bb->playboard[i][j].delete) {
|
|
bb->playboard[i][j].fallx = rb->rand()%25 - 12;
|
|
bb->playboard[i][j].fallvel = rb->rand()%5 + 6;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* draw bubbles falling off the screen
|
|
* follows y=x^2-8x scaled to bubble size
|
|
*/
|
|
lasttick = *rb->current_tick;
|
|
|
|
for(count=1; ;count++) {
|
|
onscreen = false;
|
|
bubbles_drawboard(bb);
|
|
|
|
for(i=0; i<BB_HEIGHT; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
if(bb->playboard[i][j].delete) {
|
|
indent = (i%2 ? ROW_INDENT : 0);
|
|
xofs = ((bb->playboard[i][j].fallx*count)*BUBBLE_SZ)/48;
|
|
yofs = ((count*count - bb->playboard[i][j].fallvel*count)*
|
|
BUBBLE_SZ)/20;
|
|
|
|
/* draw bubble if it is still on the screen */
|
|
if(ROW_HEIGHT*i+bb->compress*ROW_HEIGHT+yofs
|
|
<= LCD_HEIGHT) {
|
|
onscreen = true;
|
|
|
|
rb->lcd_bitmap_part(bubbles_emblem, 0,
|
|
EMBLEM_SZ*bb->playboard[i][j].type, EMBLEM_SZ,
|
|
XOFS+indent+BUBBLE_SZ*j+
|
|
(BUBBLE_SZ-EMBLEM_SZ)/2+xofs,
|
|
ROW_HEIGHT*i+(BUBBLE_SZ-EMBLEM_SZ)/2+
|
|
bb->compress*ROW_HEIGHT+yofs,
|
|
EMBLEM_SZ, EMBLEM_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_FG);
|
|
rb->lcd_mono_bitmap(
|
|
(const unsigned char *)bubbles_bubble,
|
|
XOFS+indent+BUBBLE_SZ*j+xofs,
|
|
ROW_HEIGHT*i+bb->compress*ROW_HEIGHT+yofs,
|
|
BUBBLE_SZ, BUBBLE_SZ);
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
rb->lcd_update();
|
|
|
|
/* break out if all bubbles are off the screen */
|
|
if(!onscreen) break;
|
|
|
|
/* handle button events */
|
|
buttonres = bubbles_handlebuttons(bb, true, 0);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
|
|
/* framerate limiting */
|
|
currenttick = *rb->current_tick;
|
|
if(currenttick-lasttick < HZ/MAX_FPS) {
|
|
rb->sleep((HZ/MAX_FPS)-(currenttick-lasttick));
|
|
} else {
|
|
rb->yield();
|
|
}
|
|
lasttick = currenttick;
|
|
}
|
|
|
|
return BB_NONE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_checklevel() checks the state of the playboard for a win or loss.
|
|
******************************************************************************/
|
|
static int bubbles_checklevel(struct game_context* bb) {
|
|
int i, j;
|
|
int points;
|
|
char str[13];
|
|
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_update();
|
|
|
|
/* check for bubbles below cut off point */
|
|
for(i=0; i<=bb->compress; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
if(bb->playboard[BB_HEIGHT-1-i][j].type >= 0) return BB_LOSE;
|
|
}
|
|
}
|
|
|
|
/* check for bubbles above cut off point */
|
|
for(i=0; i<BB_HEIGHT-1-bb->compress; i++) {
|
|
for(j=0; j<BB_WIDTH; j++) {
|
|
if(bb->playboard[i][j].type >= 0) return BB_NONE;
|
|
}
|
|
}
|
|
|
|
/* level complete, record score */
|
|
points = 100 - bb->elapsedlvl/100;
|
|
if(points > 0) {
|
|
bb->score += points;
|
|
} else {
|
|
points = 0;
|
|
}
|
|
|
|
rb->snprintf(str, 12, "%d points", points);
|
|
rb->splash(HZ, true, str);
|
|
|
|
/* advance to the next level */
|
|
if(!bubbles_nextlevel(bb)) {
|
|
return BB_WIN;
|
|
}
|
|
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_update();
|
|
rb->snprintf(str, 12, "Level %d", bb->level);
|
|
rb->splash(HZ, true, str);
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_update();
|
|
|
|
return BB_NONE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_recordscore() inserts a high score into the high scores list and
|
|
* returns the high score position.
|
|
******************************************************************************/
|
|
static int bubbles_recordscore(struct game_context* bb) {
|
|
int i;
|
|
int position = 0;
|
|
unsigned int currentscore, currentlevel;
|
|
unsigned int tempscore, templevel;
|
|
|
|
if(bb->score > 0) {
|
|
currentlevel = bb->level-1;
|
|
currentscore = bb->score;
|
|
|
|
for(i=0; i<NUM_SCORES; i++) {
|
|
if(currentscore >= bb->highscores[i].score) {
|
|
if(!position) {
|
|
position = i+1;
|
|
bb->dirty = true;
|
|
}
|
|
templevel = bb->highscores[i].level;
|
|
tempscore = bb->highscores[i].score;
|
|
bb->highscores[i].level = currentlevel;
|
|
bb->highscores[i].score = currentscore;
|
|
currentlevel = templevel;
|
|
currentscore = tempscore;
|
|
}
|
|
}
|
|
}
|
|
|
|
return position;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_loadscores() loads the high scores saved file.
|
|
******************************************************************************/
|
|
static void bubbles_loadscores(struct game_context* bb) {
|
|
int fd;
|
|
|
|
bb->dirty = false;
|
|
|
|
/* clear high scores */
|
|
bb->highlevel = 0;
|
|
rb->memset(bb->highscores, 0, sizeof(bb->highscores));
|
|
|
|
/* open scores file */
|
|
fd = rb->open(SCORE_FILE, O_RDONLY);
|
|
if(fd < 0) return;
|
|
|
|
/* read in high scores */
|
|
rb->read(fd, &bb->highlevel, sizeof(bb->highlevel));
|
|
if(rb->read(fd, bb->highscores, sizeof(bb->highscores)) <= 0) {
|
|
/* scores are bad, reset */
|
|
rb->memset(bb->highscores, 0, sizeof(bb->highscores));
|
|
}
|
|
|
|
rb->close(fd);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_savescores() saves the high scores saved file.
|
|
******************************************************************************/
|
|
static void bubbles_savescores(struct game_context* bb) {
|
|
int fd;
|
|
|
|
/* write out the high scores to the save file */
|
|
fd = rb->open(SCORE_FILE, O_WRONLY|O_CREAT);
|
|
rb->write(fd, &bb->highlevel, sizeof(bb->highlevel));
|
|
rb->write(fd, bb->highscores, sizeof(bb->highscores));
|
|
rb->close(fd);
|
|
bb->dirty = false;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_loadgame() loads the saved game and returns load success.
|
|
******************************************************************************/
|
|
static bool bubbles_loadgame(struct game_context* bb) {
|
|
int fd;
|
|
bool loaded = false;
|
|
|
|
/* open game file */
|
|
fd = rb->open(SAVE_FILE, O_RDONLY);
|
|
if(fd < 0) return loaded;
|
|
|
|
/* read in saved game */
|
|
while(true) {
|
|
if(rb->read(fd, &bb->score, sizeof(bb->score)) <= 0) break;
|
|
if(rb->read(fd, &bb->level, sizeof(bb->level)) <= 0) break;
|
|
if(rb->read(fd, &bb->angle, sizeof(bb->angle)) <= 0) break;
|
|
if(rb->read(fd, &bb->shots, sizeof(bb->shots)) <= 0) break;
|
|
if(rb->read(fd, &bb->compress, sizeof(bb->compress)) <= 0) break;
|
|
if(rb->read(fd, &bb->onboardcnt, sizeof(bb->onboardcnt)) <= 0) break;
|
|
if(rb->read(fd, bb->onboard, sizeof(bb->onboard)) <= 0) break;
|
|
if(rb->read(fd, &bb->nextinq, sizeof(bb->nextinq)) <= 0) break;
|
|
if(rb->read(fd, bb->queue, sizeof(bb->queue)) <= 0) break;
|
|
if(rb->read(fd, &bb->elapsedlvl, sizeof(bb->elapsedlvl)) <= 0) break;
|
|
if(rb->read(fd, bb->playboard, sizeof(bb->playboard)) <= 0) break;
|
|
bb->resume = true;
|
|
loaded = true;
|
|
break;
|
|
}
|
|
|
|
rb->close(fd);
|
|
|
|
/* delete saved file */
|
|
rb->remove(SAVE_FILE);
|
|
return loaded;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_savegame() saves the current game state.
|
|
******************************************************************************/
|
|
static void bubbles_savegame(struct game_context* bb) {
|
|
int fd;
|
|
|
|
/* write out the game state to the save file */
|
|
fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT);
|
|
rb->write(fd, &bb->score, sizeof(bb->score));
|
|
rb->write(fd, &bb->level, sizeof(bb->level));
|
|
rb->write(fd, &bb->angle, sizeof(bb->angle));
|
|
rb->write(fd, &bb->shots, sizeof(bb->shots));
|
|
rb->write(fd, &bb->compress, sizeof(bb->compress));
|
|
rb->write(fd, &bb->onboardcnt, sizeof(bb->onboardcnt));
|
|
rb->write(fd, bb->onboard, sizeof(bb->onboard));
|
|
rb->write(fd, &bb->nextinq, sizeof(bb->nextinq));
|
|
rb->write(fd, bb->queue, sizeof(bb->queue));
|
|
rb->write(fd, &bb->elapsedlvl, sizeof(bb->elapsedlvl));
|
|
rb->write(fd, bb->playboard, sizeof(bb->playboard));
|
|
rb->close(fd);
|
|
|
|
bb->resume = true;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_setcolors() set the foreground and background colors.
|
|
******************************************************************************/
|
|
static inline void bubbles_setcolors(void) {
|
|
#ifdef HAVE_LCD_COLOR
|
|
rb->lcd_set_background(LCD_RGBPACK(181,181,222));
|
|
rb->lcd_set_foreground(LCD_BLACK);
|
|
#endif
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_callback() is the default event handler callback which is called
|
|
* on usb connect and shutdown.
|
|
******************************************************************************/
|
|
static void bubbles_callback(void* param) {
|
|
struct game_context* bb = (struct game_context*) param;
|
|
if(bb->dirty) {
|
|
rb->splash(HZ/2, true, "Saving high scores...");
|
|
bubbles_savescores(bb);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles_handlebuttons() handles button events during a game.
|
|
******************************************************************************/
|
|
static int bubbles_handlebuttons(struct game_context* bb, bool animblock,
|
|
int timeout) {
|
|
int button;
|
|
int buttonres;
|
|
|
|
button = rb->button_get_w_tmo(timeout);
|
|
switch(button){
|
|
case (BUBBLES_LEFT|BUTTON_REPEAT):
|
|
if(bb->angle > MIN_ANGLE) bb->angle -= 4;
|
|
case BUBBLES_LEFT: /* change angle to the left */
|
|
if(bb->angle > MIN_ANGLE) bb->angle -= 2;
|
|
break;
|
|
|
|
case (BUBBLES_RIGHT|BUTTON_REPEAT):
|
|
if(bb->angle < MAX_ANGLE) bb->angle += 4;
|
|
case BUBBLES_RIGHT: /* change angle to the right */
|
|
if(bb->angle < MAX_ANGLE) bb->angle += 2;
|
|
break;
|
|
|
|
case BUBBLES_SELECT: /* fire the shot */
|
|
if(!animblock) {
|
|
bb->elapsedlvl += bb->elapsedshot;
|
|
bb->elapsedshot = 0;
|
|
buttonres = bubbles_fire(bb);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
buttonres = bubbles_checklevel(bb);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
bb->startedshot = *rb->current_tick;
|
|
}
|
|
break;
|
|
|
|
case BUBBLES_START: /* pause the game */
|
|
rb->splash(1, true, "Paused");
|
|
while(rb->button_get(true) != (BUBBLES_START));
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_update();
|
|
break;
|
|
|
|
case BUBBLES_RESUME: /* save and end the game */
|
|
if(!animblock) {
|
|
rb->splash(HZ/2, true, "Saving game...");
|
|
bubbles_savegame(bb);
|
|
return BB_END;
|
|
}
|
|
break;
|
|
|
|
case BUBBLES_QUIT: /* end the game */
|
|
return BB_END;
|
|
|
|
case BUTTON_NONE: /* no button pressed */
|
|
break;
|
|
|
|
default:
|
|
if(rb->default_event_handler_ex(button, bubbles_callback,
|
|
(void*) bb) == SYS_USB_CONNECTED)
|
|
return BB_USB;
|
|
break;
|
|
}
|
|
|
|
return BB_NONE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* bubbles() is the main game subroutine, it returns the final game status.
|
|
******************************************************************************/
|
|
static int bubbles(struct game_context* bb) {
|
|
int i;
|
|
int w, h;
|
|
int button;
|
|
int buttonres;
|
|
unsigned int startlevel = 0;
|
|
char *title = "Bubbles";
|
|
bool startgame = false;
|
|
bool showscores = false;
|
|
long timeout;
|
|
|
|
bubbles_setcolors();
|
|
|
|
/* don't resume by default */
|
|
bb->resume = false;
|
|
|
|
/********************
|
|
* menu *
|
|
********************/
|
|
while(!startgame){
|
|
char str[30];
|
|
rb->lcd_clear_display();
|
|
|
|
if(!showscores) {
|
|
/* welcome screen to display key bindings */
|
|
rb->lcd_getstringsize(title, &w, &h);
|
|
rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, title);
|
|
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
|
|
rb->lcd_puts(0, 2, "ON to start/pause");
|
|
rb->lcd_puts(0, 3, "MODE to save/resume");
|
|
rb->lcd_puts(0, 4, "OFF to exit");
|
|
rb->lcd_puts(0, 5, "SELECT to fire");
|
|
rb->lcd_puts(0, 6, " and show high scores");
|
|
rb->lcd_puts(0, 7, "LEFT/RIGHT to aim");
|
|
rb->lcd_puts(0, 8, "UP/DOWN to change level");
|
|
#elif (CONFIG_KEYPAD == IPOD_3G_PAD) || (CONFIG_KEYPAD == IPOD_4G_PAD)
|
|
rb->lcd_puts(0, 2, "PLAY to start/pause");
|
|
rb->lcd_puts(0, 3, "LEFT+RIGHT to save/resume");
|
|
rb->lcd_puts(0, 4, "MENU to exit");
|
|
rb->lcd_puts(0, 5, "SELECT to fire");
|
|
rb->lcd_puts(0, 6, " and show high scores");
|
|
rb->lcd_puts(0, 7, "SCROLL to aim");
|
|
rb->lcd_puts(0, 8, " and to change level");
|
|
#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
|
|
rb->lcd_puts(0, 2, "PLAY to start/pause");
|
|
rb->lcd_puts(0, 3, "REC to save/resume");
|
|
rb->lcd_puts(0, 4, "POWER to exit");
|
|
rb->lcd_puts(0, 5, "SELECT to fire");
|
|
rb->lcd_puts(0, 6, " and show high scores");
|
|
rb->lcd_puts(0, 7, "LEFT/RIGHT to aim");
|
|
rb->lcd_puts(0, 8, "UP/DOWN to change level");
|
|
#elif CONFIG_KEYPAD == GIGABEAT_PAD
|
|
rb->lcd_puts(0, 2, "POWER to start/pause");
|
|
rb->lcd_puts(0, 3, "MENU to save/resume");
|
|
rb->lcd_puts(0, 4, "A to exit");
|
|
rb->lcd_puts(0, 5, "SELECT to fire");
|
|
rb->lcd_puts(0, 6, " and show high scores");
|
|
rb->lcd_puts(0, 7, "LEFT/RIGHT to aim");
|
|
rb->lcd_puts(0, 8, "UP/DOWN to change level");
|
|
#endif
|
|
rb->snprintf(str, 28, "Start on level %d of %d", startlevel+1,
|
|
bb->highlevel+1);
|
|
rb->lcd_puts(0, 10, str);
|
|
rb->lcd_puts(0, 12, "High Score:");
|
|
rb->snprintf(str, 30, "%d, Lvl %d",
|
|
bb->highscores[0].score, bb->highscores[0].level);
|
|
rb->lcd_puts(2, 13, str);
|
|
} else {
|
|
/* show high scores */
|
|
rb->snprintf(str, 12, "%s", "High Scores");
|
|
rb->lcd_getstringsize(str, &w, &h);
|
|
rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, str);
|
|
|
|
for(i=0; i<NUM_SCORES; i++) {
|
|
rb->snprintf(str, 30, "#%02d: %d, Lvl %d", i+1,
|
|
bb->highscores[i].score, bb->highscores[i].level);
|
|
rb->lcd_puts(0, i+2, str);
|
|
}
|
|
}
|
|
|
|
rb->lcd_update();
|
|
|
|
/* handle menu button presses */
|
|
button = rb->button_get(true);
|
|
switch(button){
|
|
case BUBBLES_START: /* start playing */
|
|
bb->level = startlevel;
|
|
startgame = true;
|
|
break;
|
|
|
|
case BUBBLES_QUIT: /* quit program */
|
|
if(showscores) {
|
|
showscores = false;
|
|
break;
|
|
}
|
|
return BB_QUIT;
|
|
|
|
case BUBBLES_RESUME: /* resume game */
|
|
if(!bubbles_loadgame(bb)) {
|
|
rb->splash(HZ*2, true, "Nothing to resume");
|
|
} else {
|
|
startgame = true;
|
|
}
|
|
break;
|
|
|
|
case BUBBLES_SELECT: /* toggle high scores */
|
|
showscores = !showscores;
|
|
break;
|
|
|
|
case (BUBBLES_UP|BUTTON_REPEAT):
|
|
case BUBBLES_UP: /* increase starting level */
|
|
if(startlevel >= bb->highlevel) {
|
|
startlevel = 0;
|
|
} else {
|
|
startlevel++;
|
|
}
|
|
break;
|
|
|
|
case (BUBBLES_DOWN|BUTTON_REPEAT):
|
|
case BUBBLES_DOWN: /* decrease starting level */
|
|
if(startlevel <= 0) {
|
|
startlevel = bb->highlevel;
|
|
} else {
|
|
startlevel--;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if(rb->default_event_handler_ex(button, bubbles_callback,
|
|
(void*) bb) == SYS_USB_CONNECTED)
|
|
return BB_USB;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/********************
|
|
* init *
|
|
********************/
|
|
bubbles_init(bb);
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_update();
|
|
|
|
/**********************
|
|
* play *
|
|
**********************/
|
|
bb->startedshot = *rb->current_tick;
|
|
|
|
while(true) {
|
|
/* refresh the board */
|
|
bubbles_drawboard(bb);
|
|
rb->lcd_update();
|
|
|
|
/* manange idle framerate */
|
|
bb->elapsedshot = *rb->current_tick-bb->startedshot;
|
|
|
|
if(MAX_SHOTTIME-bb->elapsedshot < HZ/2) {
|
|
timeout = MAX_SHOTTIME-bb->elapsedshot;
|
|
} else {
|
|
timeout = HZ/2;
|
|
}
|
|
|
|
/* handle button events */
|
|
buttonres = bubbles_handlebuttons(bb, false, timeout);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
|
|
/* handle timing */
|
|
bb->elapsedshot = *rb->current_tick-bb->startedshot;
|
|
|
|
if(bb->elapsedshot > MAX_SHOTTIME) {
|
|
bb->elapsedlvl += bb->elapsedshot;
|
|
bb->elapsedshot = 0;
|
|
buttonres = bubbles_fire(bb);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
buttonres = bubbles_checklevel(bb);
|
|
if(buttonres != BB_NONE) return buttonres;
|
|
bb->startedshot = *rb->current_tick;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* plugin entry point.
|
|
******************************************************************************/
|
|
enum plugin_status plugin_start(struct plugin_api* api, void* parameter) {
|
|
struct game_context bb;
|
|
bool exit = false;
|
|
int position;
|
|
|
|
/* plugin init */
|
|
(void)parameter;
|
|
rb = api;
|
|
/* end of plugin init */
|
|
|
|
/* more init */
|
|
xlcd_init(rb);
|
|
|
|
/* load files */
|
|
rb->splash(0, true, "Loading...");
|
|
bubbles_loadscores(&bb);
|
|
rb->lcd_clear_display();
|
|
|
|
/* start app */
|
|
rb->lcd_setfont(FONT_SYSFIXED);
|
|
|
|
while(!exit) {
|
|
switch(bubbles(&bb)){
|
|
char str[19];
|
|
case BB_WIN:
|
|
rb->splash(HZ*2, true, "You Win!");
|
|
|
|
if((position = bubbles_recordscore(&bb))) {
|
|
rb->snprintf(str, 19, "New high score #%d!", position);
|
|
rb->splash(HZ*2, true, str);
|
|
}
|
|
break;
|
|
|
|
case BB_LOSE:
|
|
rb->splash(HZ*2, true, "Game Over");
|
|
/* fall through to BB_END */
|
|
|
|
case BB_END:
|
|
if(!bb.resume) {
|
|
/* record high level */
|
|
if(bb.level-1 > bb.highlevel) {
|
|
bb.highlevel = bb.level-1;
|
|
bb.dirty = true;
|
|
}
|
|
|
|
/* record high score */
|
|
if((position = bubbles_recordscore(&bb))) {
|
|
rb->snprintf(str, 19, "New high score #%d!", position);
|
|
rb->splash(HZ*2, true, str);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case BB_USB:
|
|
rb->lcd_setfont(FONT_UI);
|
|
return PLUGIN_USB_CONNECTED;
|
|
|
|
case BB_QUIT:
|
|
if(bb.dirty) {
|
|
rb->splash(HZ/2, true, "Saving high scores...");
|
|
bubbles_savescores(&bb);
|
|
}
|
|
exit = true;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
rb->lcd_setfont(FONT_UI);
|
|
return PLUGIN_OK;
|
|
}
|
|
|
|
#endif
|