Tetrox renamed to Rockblox, to avoid trademark issues
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11005 a1c6a512-1295-4272-9138-f99709370657
|
@ -59,7 +59,7 @@ sokoban.c
|
|||
star.c
|
||||
starfield.c
|
||||
#if (LCD_WIDTH != 240) && ((LCD_WIDTH != 128) || (LCD_HEIGHT != 64))
|
||||
tetrox.c
|
||||
rockblox.c
|
||||
#endif
|
||||
#if CONFIG_LCD == LCD_SSD1815
|
||||
video.c
|
||||
|
|
|
@ -27,9 +27,9 @@ brickmania_powerups.112x64x1.bmp
|
|||
|
||||
#endif
|
||||
|
||||
/* Tetrox */
|
||||
/* Rockblox */
|
||||
#if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
|
||||
tetrox_background.112x64x1.bmp
|
||||
rockblox_background.112x64x1.bmp
|
||||
#endif
|
||||
|
||||
/* Solitaire */
|
||||
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -255,21 +255,21 @@ brickmania_break.176x132x16.bmp
|
|||
|
||||
#endif
|
||||
|
||||
/* Tetrox */
|
||||
/* Rockblox */
|
||||
#if (LCD_WIDTH == 320) && (LCD_HEIGHT == 240) && (LCD_DEPTH == 16)
|
||||
tetrox_background.320x240x16.bmp
|
||||
rockblox_background.320x240x16.bmp
|
||||
#elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176) && (LCD_DEPTH == 16)
|
||||
tetrox_background.220x176x16.bmp
|
||||
rockblox_background.220x176x16.bmp
|
||||
#elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132) && (LCD_DEPTH == 16)
|
||||
tetrox_background.176x132x16.bmp
|
||||
rockblox_background.176x132x16.bmp
|
||||
#elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128) && (LCD_DEPTH >= 16)
|
||||
tetrox_background.160x128x16.bmp
|
||||
rockblox_background.160x128x16.bmp
|
||||
#elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128) && (LCD_DEPTH == 16)
|
||||
tetrox_background.128x128x16.bmp
|
||||
rockblox_background.128x128x16.bmp
|
||||
#elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128) && (LCD_DEPTH == 2)
|
||||
tetrox_background.160x128x2.bmp
|
||||
rockblox_background.160x128x2.bmp
|
||||
#elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110) && (LCD_DEPTH == 2)
|
||||
tetrox_background.138x110x2.bmp
|
||||
rockblox_background.138x110x2.bmp
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
|
|
0
apps/plugins/bitmaps/native/tetrox_background.128x128x16.bmp → apps/plugins/bitmaps/native/rockblox_background.128x128x16.bmp
Executable file → Normal file
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
0
apps/plugins/bitmaps/native/tetrox_background.160x128x16.bmp → apps/plugins/bitmaps/native/rockblox_background.160x128x16.bmp
Executable file → Normal file
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
BIN
apps/plugins/bitmaps/native/rockblox_background.160x128x2.bmp
Normal file
After Width: | Height: | Size: 21 KiB |
0
apps/plugins/bitmaps/native/tetrox_background.176x132x16.bmp → apps/plugins/bitmaps/native/rockblox_background.176x132x16.bmp
Executable file → Normal file
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
0
apps/plugins/bitmaps/native/tetrox_background.220x176x16.bmp → apps/plugins/bitmaps/native/rockblox_background.220x176x16.bmp
Executable file → Normal file
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
0
apps/plugins/bitmaps/native/tetrox_background.320x240x16.bmp → apps/plugins/bitmaps/native/rockblox_background.320x240x16.bmp
Executable file → Normal file
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 225 KiB |
Before Width: | Height: | Size: 21 KiB |
870
apps/plugins/rockblox.c
Normal file
|
@ -0,0 +1,870 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2005 Eli Sherer
|
||||
*
|
||||
* Heavily modified for embedded use by Björn Stenberg (bjorn@haxx.se)
|
||||
*
|
||||
* 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 "highscore.h"
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
||||
PLUGIN_HEADER
|
||||
|
||||
extern const fb_data rockblox_background[];
|
||||
|
||||
#if (CONFIG_KEYPAD == IPOD_3G_PAD) || \
|
||||
(CONFIG_KEYPAD == IPOD_4G_PAD)
|
||||
|
||||
#define ROCKBLOX_OFF (BUTTON_MENU | BUTTON_SELECT)
|
||||
#define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_BACK
|
||||
#define ROCKBLOX_ROTATE_RIGHT2 (BUTTON_MENU | BUTTON_REL)
|
||||
#define ROCKBLOX_ROTATE_LEFT BUTTON_SCROLL_FWD
|
||||
#define ROCKBLOX_LEFT BUTTON_LEFT
|
||||
#define ROCKBLOX_RIGHT BUTTON_RIGHT
|
||||
#define ROCKBLOX_DOWN BUTTON_PLAY
|
||||
#define ROCKBLOX_RESTART (BUTTON_SELECT | BUTTON_PLAY)
|
||||
#define ROCKBLOX_DROP (BUTTON_SELECT | BUTTON_REL)
|
||||
|
||||
#define SCROLL_WHEEL
|
||||
|
||||
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
||||
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
||||
|
||||
#define ROCKBLOX_OFF BUTTON_OFF
|
||||
#define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
|
||||
#define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
|
||||
#define ROCKBLOX_DOWN BUTTON_DOWN
|
||||
#define ROCKBLOX_LEFT BUTTON_LEFT
|
||||
#define ROCKBLOX_RIGHT BUTTON_RIGHT
|
||||
#define ROCKBLOX_DROP BUTTON_MODE
|
||||
#define ROCKBLOX_RESTART BUTTON_ON
|
||||
|
||||
#define ROCKBLOX_RC_OFF BUTTON_RC_STOP
|
||||
#elif CONFIG_KEYPAD == RECORDER_PAD
|
||||
|
||||
#define ROCKBLOX_OFF BUTTON_OFF
|
||||
#define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
|
||||
#define ROCKBLOX_ROTATE_LEFT BUTTON_PLAY
|
||||
#define ROCKBLOX_DOWN BUTTON_DOWN
|
||||
#define ROCKBLOX_LEFT BUTTON_LEFT
|
||||
#define ROCKBLOX_RIGHT BUTTON_RIGHT
|
||||
#define ROCKBLOX_DROP BUTTON_ON
|
||||
#define ROCKBLOX_RESTART BUTTON_F1
|
||||
|
||||
#elif CONFIG_KEYPAD == ONDIO_PAD
|
||||
|
||||
#define ROCKBLOX_OFF BUTTON_OFF
|
||||
#define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
|
||||
#define ROCKBLOX_ROTATE_LEFT (BUTTON_MENU|BUTTON_UP)
|
||||
#define ROCKBLOX_DOWN BUTTON_DOWN
|
||||
#define ROCKBLOX_LEFT BUTTON_LEFT
|
||||
#define ROCKBLOX_RIGHT BUTTON_RIGHT
|
||||
#define ROCKBLOX_DROP_PRE BUTTON_MENU
|
||||
#define ROCKBLOX_DROP (BUTTON_MENU|BUTTON_REL)
|
||||
|
||||
#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
|
||||
|
||||
#define ROCKBLOX_OFF BUTTON_POWER
|
||||
#define ROCKBLOX_ROTATE_RIGHT BUTTON_UP
|
||||
#define ROCKBLOX_ROTATE_LEFT BUTTON_SELECT
|
||||
#define ROCKBLOX_DOWN BUTTON_DOWN
|
||||
#define ROCKBLOX_LEFT BUTTON_LEFT
|
||||
#define ROCKBLOX_RIGHT BUTTON_RIGHT
|
||||
#define ROCKBLOX_DROP BUTTON_REC
|
||||
#define ROCKBLOX_RESTART BUTTON_PLAY
|
||||
|
||||
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
|
||||
|
||||
#define ROCKBLOX_OFF BUTTON_POWER
|
||||
#define ROCKBLOX_ROTATE_RIGHT BUTTON_SCROLL_UP
|
||||
#define ROCKBLOX_ROTATE_LEFT BUTTON_REW
|
||||
#define ROCKBLOX_DOWN BUTTON_SCROLL_DOWN
|
||||
#define ROCKBLOX_LEFT BUTTON_LEFT
|
||||
#define ROCKBLOX_RIGHT BUTTON_RIGHT
|
||||
#define ROCKBLOX_DROP BUTTON_FF
|
||||
#define ROCKBLOX_RESTART BUTTON_PLAY
|
||||
|
||||
#endif
|
||||
|
||||
#define BLOCKS_NUM 7
|
||||
#define EMPTY_BLOCK 7
|
||||
|
||||
#define BOARD_WIDTH 10
|
||||
#define BOARD_HEIGHT 20
|
||||
|
||||
#if (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
|
||||
|
||||
#define BLOCK_WIDTH 12
|
||||
#define BLOCK_HEIGHT 12
|
||||
#define BOARD_X 86
|
||||
#define BOARD_Y 0
|
||||
#define PREVIEW_X 12
|
||||
#define PREVIEW_Y 11
|
||||
#define LABEL_X 242
|
||||
#define SCORE_Y 25
|
||||
#define LEVEL_Y 70
|
||||
#define LINES_Y 105
|
||||
|
||||
#elif (LCD_WIDTH == 220) && (LCD_HEIGHT == 176)
|
||||
|
||||
#define BLOCK_WIDTH 8
|
||||
#define BLOCK_HEIGHT 8
|
||||
#define BOARD_X 27
|
||||
#define BOARD_Y 5
|
||||
#define PREVIEW_X 158
|
||||
#define PREVIEW_Y 130
|
||||
#define LABEL_X 147
|
||||
#define SCORE_Y 20
|
||||
#define LEVEL_Y 65
|
||||
#define LINES_Y 100
|
||||
|
||||
#elif (LCD_WIDTH == 176) && (LCD_HEIGHT == 132)
|
||||
|
||||
#define BLOCK_WIDTH 6
|
||||
#define BLOCK_HEIGHT 6
|
||||
#define BOARD_X 25
|
||||
#define BOARD_Y 1
|
||||
#define PREVIEW_X 126
|
||||
#define PREVIEW_Y 102
|
||||
#define LABEL_X 112
|
||||
#define SCORE_Y 17
|
||||
#define LEVEL_Y 49
|
||||
#define LINES_Y 81
|
||||
|
||||
#elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
|
||||
|
||||
#define BLOCK_WIDTH 6
|
||||
#define BLOCK_HEIGHT 6
|
||||
#define BOARD_X 22
|
||||
#define BOARD_Y 3
|
||||
#define PREVIEW_X 114
|
||||
#define PREVIEW_Y 100
|
||||
#define LABEL_X 101
|
||||
#define SCORE_Y 17
|
||||
#define LEVEL_Y 49
|
||||
#define LINES_Y 82
|
||||
|
||||
#elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
|
||||
|
||||
#define BLOCK_WIDTH 6
|
||||
#define BLOCK_HEIGHT 6
|
||||
#define BOARD_X 4
|
||||
#define BOARD_Y 3
|
||||
#define PREVIEW_X 84
|
||||
#define PREVIEW_Y 100
|
||||
#define LABEL_X 71
|
||||
#define SCORE_Y 17
|
||||
#define LEVEL_Y 49
|
||||
#define LINES_Y 82
|
||||
|
||||
#elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
|
||||
|
||||
#define BLOCK_WIDTH 4
|
||||
#define BLOCK_HEIGHT 3
|
||||
#define BOARD_X 9
|
||||
#define BOARD_Y 3
|
||||
#define PREVIEW_X 59
|
||||
#define PREVIEW_Y 5
|
||||
#define LABEL_X 59
|
||||
#define SCORE_Y 32
|
||||
#define LEVEL_Y 13
|
||||
#define LEVEL_X 78
|
||||
#define LINES_Y 51
|
||||
|
||||
#elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
|
||||
|
||||
#define BLOCK_WIDTH 5
|
||||
#define BLOCK_HEIGHT 5
|
||||
#define BOARD_X 14
|
||||
#define BOARD_Y 0
|
||||
#define PREVIEW_X 98
|
||||
#define PREVIEW_Y 88
|
||||
#define LABEL_X 80
|
||||
#define SCORE_Y 15
|
||||
#define LEVEL_Y 45
|
||||
#define LINES_Y 74
|
||||
|
||||
#endif
|
||||
|
||||
/* Pictures */
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
#define SPLASH_SCREEN PLUGIN_DIR "/rockblox/splash.bmp"
|
||||
#define PIC_SCREEN PLUGIN_DIR "/rockblox/screen.bmp"
|
||||
#endif
|
||||
|
||||
/* <<Explanation on Rockblox shapes>>
|
||||
|
||||
%%
|
||||
%% - O has 1 orientation
|
||||
|
||||
%% %
|
||||
%% %% - Z has 2 orientations
|
||||
%
|
||||
|
||||
%% %
|
||||
%% %% - S has 2 orientations
|
||||
%
|
||||
%
|
||||
%
|
||||
% %%%% - I has 2 orientations
|
||||
%
|
||||
|
||||
% %%
|
||||
% % % %%% - L has 4 orientations
|
||||
%% %%% % %
|
||||
|
||||
% %%s
|
||||
% % % %%% - J has 4 orientations
|
||||
%% %%% % %
|
||||
|
||||
% % %%%
|
||||
%% % %% % - T has 4 orientations
|
||||
% %%% %
|
||||
*/
|
||||
|
||||
|
||||
/* must have variable */
|
||||
static struct plugin_api *rb;
|
||||
|
||||
static bool gameover = false;
|
||||
/* c=current f=figure o=orientation n=next */
|
||||
static int lines, level, score, cx, cy, cf, co, nf;
|
||||
static short board[BOARD_HEIGHT][BOARD_WIDTH]; /* 20 rows of 10 blocks */
|
||||
|
||||
#ifdef SCROLL_WHEEL
|
||||
int wheel_events = 0, last_wheel_event = 0;
|
||||
bool wheel_enabled = false;
|
||||
#endif
|
||||
|
||||
static const short scoring[4] = { /* scoring for each number of lines */
|
||||
40 /* single */ , 100 /* double */ , 300 /* triple */ , 1200 /* rockblox */
|
||||
};
|
||||
|
||||
struct figure
|
||||
{
|
||||
#if LCD_DEPTH >= 2
|
||||
unsigned short color[3]; /* color of figure (light,middle,shadow) */
|
||||
#endif
|
||||
unsigned short max_or; /* max orientations */
|
||||
signed short shapeX[4], shapeY[4]; /* implementation of figures */
|
||||
}
|
||||
|
||||
/* array of figures */
|
||||
figures[BLOCKS_NUM] = {
|
||||
/* O */
|
||||
{
|
||||
#if LCD_DEPTH >= 16
|
||||
{LCD_RGBPACK (153, 255, 255), LCD_RGBPACK(0, 255, 255),
|
||||
LCD_RGBPACK(0,153,153)},
|
||||
#elif LCD_DEPTH == 2
|
||||
{LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
|
||||
#endif
|
||||
1,
|
||||
{-1, 0, -1, 0},
|
||||
{0, 0, 1, 1}
|
||||
},
|
||||
/* I */
|
||||
{
|
||||
#if LCD_DEPTH >= 16
|
||||
{LCD_RGBPACK (255, 153, 128), LCD_RGBPACK (255, 0, 0),
|
||||
LCD_RGBPACK (153, 0, 0)},
|
||||
#elif LCD_DEPTH == 2
|
||||
{LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
|
||||
#endif
|
||||
2,
|
||||
{-2, -1, 0, 1},
|
||||
{0, 0, 0, 0}
|
||||
},
|
||||
/* 'Z' */
|
||||
{
|
||||
#if LCD_DEPTH >= 16
|
||||
{LCD_RGBPACK (153, 255, 153), LCD_RGBPACK (0, 255, 0),
|
||||
LCD_RGBPACK (0, 153, 0)},
|
||||
#elif LCD_DEPTH == 2
|
||||
{LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
|
||||
#endif
|
||||
2,
|
||||
{0, 1, -1, 0},
|
||||
{0, 0, 1, 1}
|
||||
},
|
||||
/* 'S' */
|
||||
{
|
||||
#if LCD_DEPTH >= 16
|
||||
{LCD_RGBPACK (153, 153, 255), LCD_RGBPACK (0, 0, 255),
|
||||
LCD_RGBPACK (0, 0, 153)},
|
||||
#elif LCD_DEPTH == 2
|
||||
{LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
|
||||
#endif
|
||||
2,
|
||||
{-1, 0, 0, 1},
|
||||
{0, 0, 1, 1}
|
||||
},
|
||||
/* 'L' */
|
||||
{
|
||||
#if LCD_DEPTH >= 16
|
||||
{LCD_RGBPACK (255, 255, 153), LCD_RGBPACK (255, 255, 0),
|
||||
LCD_RGBPACK (153, 153, 0)},
|
||||
#elif LCD_DEPTH == 2
|
||||
{LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
|
||||
#endif
|
||||
4,
|
||||
{-1, 0, 1, 1},
|
||||
{0, 0, 0, 1}
|
||||
},
|
||||
/* 'J' */
|
||||
{
|
||||
#if LCD_DEPTH >= 16
|
||||
{LCD_RGBPACK (255, 153, 255), LCD_RGBPACK (255, 0, 255),
|
||||
LCD_RGBPACK (153, 0, 153)},
|
||||
#elif LCD_DEPTH == 2
|
||||
{LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
|
||||
#endif
|
||||
4,
|
||||
{-1, 0, 1, -1},
|
||||
{0, 0, 0, 1}
|
||||
},
|
||||
/* 'T' */
|
||||
{
|
||||
#if LCD_DEPTH >= 16
|
||||
{LCD_RGBPACK (204, 204, 204), LCD_RGBPACK (153, 153, 153),
|
||||
LCD_RGBPACK (85, 85, 85)},
|
||||
#elif LCD_DEPTH == 2
|
||||
{LCD_WHITE, LCD_LIGHTGRAY, LCD_DARKGRAY},
|
||||
#endif
|
||||
4,
|
||||
{-1, 0, 1, 0},
|
||||
{0, 0, 0, 1}
|
||||
}
|
||||
};
|
||||
|
||||
/* get random number from (0) to (range-1) */
|
||||
static int t_rand (int range)
|
||||
{
|
||||
return rb->rand () % range;
|
||||
}
|
||||
|
||||
/* init the board array to have no blocks */
|
||||
static void init_board (void)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < BOARD_WIDTH; i++)
|
||||
for (j = 0; j < BOARD_HEIGHT; j++)
|
||||
board[j][i] = EMPTY_BLOCK;
|
||||
}
|
||||
|
||||
/* show the score, level and lines */
|
||||
static void show_details (void)
|
||||
{
|
||||
char str[25]; /* for strings */
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (LCD_BLACK);
|
||||
rb->lcd_set_background (LCD_WHITE);
|
||||
#endif
|
||||
rb->snprintf (str, sizeof (str), "%d", score);
|
||||
rb->lcd_putsxy (LABEL_X, SCORE_Y, str);
|
||||
rb->snprintf (str, sizeof (str), "%d", level);
|
||||
#ifdef LEVEL_X
|
||||
rb->lcd_putsxy (LEVEL_X, LEVEL_Y, str);
|
||||
#else
|
||||
rb->lcd_putsxy (LABEL_X, LEVEL_Y, str);
|
||||
#endif
|
||||
rb->snprintf (str, sizeof (str), "%d", lines);
|
||||
rb->lcd_putsxy (LABEL_X, LINES_Y, str);
|
||||
}
|
||||
|
||||
static void init_rockblox (void)
|
||||
{
|
||||
level = 1;
|
||||
lines = 0;
|
||||
score = 0;
|
||||
gameover = false;
|
||||
nf = t_rand (BLOCKS_NUM);
|
||||
init_board ();
|
||||
rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||
show_details ();
|
||||
}
|
||||
|
||||
static inline int level_speed(int level)
|
||||
{
|
||||
return (5*HZ) / (level + 9);
|
||||
}
|
||||
|
||||
static int getRelativeX (int figure, int square, int orientation)
|
||||
{
|
||||
switch (orientation) {
|
||||
case 0:
|
||||
return figures[figure].shapeX[square];
|
||||
case 1:
|
||||
return figures[figure].shapeY[square];
|
||||
case 2:
|
||||
return -figures[figure].shapeX[square];
|
||||
case 3:
|
||||
return -figures[figure].shapeY[square];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int getRelativeY (int figure, int square, int orientation)
|
||||
{
|
||||
switch (orientation) {
|
||||
case 0:
|
||||
return figures[figure].shapeY[square];
|
||||
case 1:
|
||||
return -figures[figure].shapeX[square];
|
||||
case 2:
|
||||
return -figures[figure].shapeY[square];
|
||||
case 3:
|
||||
return figures[figure].shapeX[square];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* redraw the while board on the screen */
|
||||
static void refresh_board (void)
|
||||
{
|
||||
int i, j, x, y, block;
|
||||
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (LCD_BLACK);
|
||||
#elif LCD_DEPTH == 1
|
||||
rb->lcd_set_drawmode (DRMODE_SOLID | DRMODE_INVERSEVID);
|
||||
#endif
|
||||
|
||||
rb->lcd_fillrect (BOARD_X, 1, BOARD_WIDTH * BLOCK_WIDTH, BOARD_Y);
|
||||
|
||||
#if LCD_DEPTH == 1
|
||||
rb->lcd_set_drawmode (DRMODE_SOLID);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < BOARD_WIDTH; i++)
|
||||
for (j = 0; j < BOARD_HEIGHT; j++) {
|
||||
block = board[j][i];
|
||||
if (block == EMPTY_BLOCK) {
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (LCD_BLACK);
|
||||
#elif LCD_DEPTH == 1
|
||||
rb->lcd_set_drawmode (DRMODE_SOLID | DRMODE_INVERSEVID);
|
||||
#endif
|
||||
|
||||
rb->lcd_fillrect (BOARD_X + i * BLOCK_WIDTH,
|
||||
BOARD_Y + j * BLOCK_HEIGHT, BLOCK_WIDTH,
|
||||
BLOCK_HEIGHT);
|
||||
|
||||
#if LCD_DEPTH == 1
|
||||
rb->lcd_set_drawmode (DRMODE_SOLID);
|
||||
#endif
|
||||
} else {
|
||||
#if LCD_DEPTH >= 2
|
||||
/* middle drawing */
|
||||
rb->lcd_set_foreground (figures[block].color[1]);
|
||||
#endif
|
||||
rb->lcd_fillrect (BOARD_X + i * BLOCK_WIDTH,
|
||||
BOARD_Y + j * BLOCK_HEIGHT,
|
||||
BLOCK_WIDTH, BLOCK_HEIGHT);
|
||||
#if LCD_DEPTH >= 2
|
||||
/* light drawing */
|
||||
rb->lcd_set_foreground (figures[block].color[0]);
|
||||
#endif
|
||||
rb->lcd_vline (BOARD_X + i * BLOCK_WIDTH,
|
||||
BOARD_Y + j * BLOCK_HEIGHT,
|
||||
BOARD_Y + (j + 1) * BLOCK_HEIGHT - 2);
|
||||
rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH,
|
||||
BOARD_X + (i + 1) * BLOCK_WIDTH - 2,
|
||||
BOARD_Y + j * BLOCK_HEIGHT);
|
||||
#if LCD_DEPTH >= 2
|
||||
/* shadow drawing */
|
||||
rb->lcd_set_foreground (figures[block].color[2]);
|
||||
#endif
|
||||
rb->lcd_vline (BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
|
||||
BOARD_Y + j * BLOCK_HEIGHT + 1,
|
||||
BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
|
||||
rb->lcd_hline (BOARD_X + i * BLOCK_WIDTH + 1,
|
||||
BOARD_X + (i + 1) * BLOCK_WIDTH - 1,
|
||||
BOARD_Y + (j + 1) * BLOCK_HEIGHT - 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
x = getRelativeX (cf, i, co) + cx;
|
||||
y = getRelativeY (cf, i, co) + cy;
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (figures[cf].color[1]); /* middle drawing */
|
||||
#endif
|
||||
rb->lcd_fillrect (BOARD_X + x * BLOCK_WIDTH,
|
||||
BOARD_Y + y * BLOCK_HEIGHT,
|
||||
BLOCK_WIDTH, BLOCK_HEIGHT);
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (figures[cf].color[0]); /* light drawing */
|
||||
#endif
|
||||
rb->lcd_vline (BOARD_X + x * BLOCK_WIDTH, BOARD_Y + y * BLOCK_HEIGHT,
|
||||
BOARD_Y + (y + 1) * BLOCK_HEIGHT - 2);
|
||||
rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH,
|
||||
BOARD_X + (x + 1) * BLOCK_WIDTH - 2,
|
||||
BOARD_Y + y * BLOCK_HEIGHT);
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (figures[cf].color[2]); /* shadow drawing */
|
||||
#endif
|
||||
rb->lcd_vline (BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
|
||||
BOARD_Y + y * BLOCK_HEIGHT + 1,
|
||||
BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
|
||||
rb->lcd_hline (BOARD_X + x * BLOCK_WIDTH + 1,
|
||||
BOARD_X + (x + 1) * BLOCK_WIDTH - 1,
|
||||
BOARD_Y + (y + 1) * BLOCK_HEIGHT - 1);
|
||||
}
|
||||
rb->lcd_update ();
|
||||
}
|
||||
|
||||
static bool canMoveTo (int x, int y, int newOrientation)
|
||||
{
|
||||
int i, rx, ry;
|
||||
for (i = 0; i < 4; i++) {
|
||||
ry = getRelativeY (cf, i, newOrientation) + y;
|
||||
rx = getRelativeX (cf, i, newOrientation) + x;
|
||||
if ((rx < 0 || rx >= BOARD_WIDTH) ||
|
||||
(ry < 0 || ry >= BOARD_HEIGHT) || (board[ry][rx] != EMPTY_BLOCK))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* draws the preview of next block in the preview window */
|
||||
static void draw_next_block (void)
|
||||
{
|
||||
int i, rx, ry;
|
||||
/* clear preview window first */
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (LCD_BLACK);
|
||||
#elif LCD_DEPTH == 1
|
||||
rb->lcd_set_drawmode (DRMODE_SOLID | DRMODE_INVERSEVID);
|
||||
#endif
|
||||
|
||||
/* 4x4 */
|
||||
rb->lcd_fillrect (PREVIEW_X, PREVIEW_Y, BLOCK_WIDTH * 4, BLOCK_HEIGHT * 4);
|
||||
|
||||
#if LCD_DEPTH == 1
|
||||
rb->lcd_set_drawmode (DRMODE_SOLID);
|
||||
#endif
|
||||
|
||||
/* draw the lightgray rectangles */
|
||||
#if LCD_DEPTH >= 16
|
||||
rb->lcd_set_foreground (LCD_RGBPACK (40, 40, 40));
|
||||
#elif LCD_DEPTH == 2
|
||||
rb->lcd_set_foreground (LCD_DARKGRAY);
|
||||
#endif
|
||||
|
||||
#if LCD_DEPTH >= 2
|
||||
for (rx = 0; rx < 4; rx++)
|
||||
for (ry = 0; ry < 4; ry++)
|
||||
rb->lcd_drawrect (PREVIEW_X + rx * BLOCK_WIDTH,
|
||||
PREVIEW_Y + ry * BLOCK_HEIGHT, BLOCK_WIDTH,
|
||||
BLOCK_HEIGHT);
|
||||
#endif
|
||||
|
||||
/* draw the figure */
|
||||
for (i = 0; i < 4; i++) {
|
||||
rx = getRelativeX (nf, i, 0) + 2;
|
||||
ry = getRelativeY (nf, i, 0) + 2;
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (figures[nf].color[1]); /* middle drawing */
|
||||
#endif
|
||||
rb->lcd_fillrect (PREVIEW_X + rx * BLOCK_WIDTH,
|
||||
PREVIEW_Y + ry * BLOCK_HEIGHT,
|
||||
BLOCK_WIDTH, BLOCK_HEIGHT);
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (figures[nf].color[0]); /* light drawing */
|
||||
#endif
|
||||
rb->lcd_vline (PREVIEW_X + rx * BLOCK_WIDTH,
|
||||
PREVIEW_Y + ry * BLOCK_HEIGHT,
|
||||
PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 2);
|
||||
rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH,
|
||||
PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 2,
|
||||
PREVIEW_Y + ry * BLOCK_HEIGHT);
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (figures[nf].color[2]); /* shadow drawing */
|
||||
#endif
|
||||
rb->lcd_vline (PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
|
||||
PREVIEW_Y + ry * BLOCK_HEIGHT + 1,
|
||||
PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
|
||||
rb->lcd_hline (PREVIEW_X + rx * BLOCK_WIDTH + 1,
|
||||
PREVIEW_X + (rx + 1) * BLOCK_WIDTH - 1,
|
||||
PREVIEW_Y + (ry + 1) * BLOCK_HEIGHT - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* move the block to a relative location */
|
||||
static void move_block (int x, int y, int o)
|
||||
{
|
||||
if (canMoveTo (cx + x, cy + y, o)) {
|
||||
cy += y;
|
||||
cx += x;
|
||||
co = o;
|
||||
}
|
||||
}
|
||||
|
||||
/* try to add a new block to play with (return true if gameover) */
|
||||
static void new_block (void)
|
||||
{
|
||||
cy = 1;
|
||||
cx = 5;
|
||||
cf = nf;
|
||||
co = 0; /* start at the same orientation all time */
|
||||
nf = t_rand (BLOCKS_NUM);
|
||||
gameover = !canMoveTo (cx, cy, co);
|
||||
|
||||
draw_next_block ();
|
||||
}
|
||||
|
||||
|
||||
/* check for filled lines and do what necessary */
|
||||
static int check_lines (void)
|
||||
{
|
||||
int i, j, y;
|
||||
int rockblox = 0;
|
||||
|
||||
for (j = 0; j < BOARD_HEIGHT; j++) {
|
||||
for (i = 0; ((i < BOARD_WIDTH) && (board[j][i] != EMPTY_BLOCK)); i++);
|
||||
if (i == BOARD_WIDTH) { /* woo hoo, we have a line */
|
||||
rockblox++;
|
||||
for (y = j; y > 0; y--)
|
||||
for (i = 0; i < BOARD_WIDTH; i++)
|
||||
board[y][i] = board[y - 1][i]; /* fall line */
|
||||
}
|
||||
}
|
||||
|
||||
return rockblox;
|
||||
}
|
||||
|
||||
/* moves down the figure and returns true if gameover */
|
||||
static void move_down (void)
|
||||
{
|
||||
int l, i, rx, ry;
|
||||
|
||||
if (!canMoveTo (cx, cy + 1, co)) {
|
||||
/* save figure to board */
|
||||
for (i = 0; i < 4; i++) {
|
||||
rx = getRelativeX (cf, i, co) + cx;
|
||||
ry = getRelativeY (cf, i, co) + cy;
|
||||
board[ry][rx] = cf;
|
||||
}
|
||||
/* check if formed some lines */
|
||||
l = check_lines ();
|
||||
if (l) {
|
||||
/* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */
|
||||
score += scoring[l - 1] * level;
|
||||
lines += l;
|
||||
level = (int) lines / 10 + 1;
|
||||
}
|
||||
|
||||
/* show details */
|
||||
show_details ();
|
||||
|
||||
/* generate a new figure */
|
||||
new_block ();
|
||||
} else
|
||||
move_block (0, 1, co);
|
||||
}
|
||||
|
||||
static int rockblox_loop (void)
|
||||
{
|
||||
int button;
|
||||
int lastbutton = BUTTON_NONE;
|
||||
long next_down_tick = *rb->current_tick + level_speed(level);
|
||||
|
||||
new_block ();
|
||||
|
||||
while (1) {
|
||||
#ifdef HAS_BUTTON_HOLD
|
||||
if (rb->button_hold ()) {
|
||||
/* Restore user's original backlight setting */
|
||||
rb->backlight_set_timeout (rb->global_settings->backlight_timeout);
|
||||
|
||||
rb->splash(0, true, "Paused");
|
||||
while (rb->button_hold ())
|
||||
rb->sleep(HZ/10);
|
||||
|
||||
/* Permanently enable the backlight (unless the user has
|
||||
turned it off) */
|
||||
if (rb->global_settings->backlight_timeout > 0)
|
||||
rb->backlight_set_timeout (1);
|
||||
|
||||
/* get rid of the splash text */
|
||||
rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT);
|
||||
show_details ();
|
||||
draw_next_block ();
|
||||
refresh_board ();
|
||||
}
|
||||
#endif
|
||||
|
||||
button = rb->button_get_w_tmo (MAX(next_down_tick - *rb->current_tick, 1));
|
||||
switch (button) {
|
||||
#ifdef ROCKBLOX_RC_OFF
|
||||
case ROCKBLOX_RC_OFF:
|
||||
#endif
|
||||
case ROCKBLOX_OFF:
|
||||
return PLUGIN_OK;
|
||||
|
||||
case ROCKBLOX_ROTATE_RIGHT:
|
||||
case ROCKBLOX_ROTATE_RIGHT | BUTTON_REPEAT:
|
||||
#ifdef SCROLL_WHEEL
|
||||
/* if the wheel is disabled, add an event to the stack. */
|
||||
if(wheel_enabled == false)
|
||||
wheel_events++;
|
||||
|
||||
/* if it's enabled, go ahead and rotate.. */
|
||||
if(wheel_enabled)
|
||||
#endif
|
||||
move_block (0, 0, (co + 1) % figures[cf].max_or);
|
||||
break;
|
||||
|
||||
case ROCKBLOX_ROTATE_LEFT:
|
||||
case ROCKBLOX_ROTATE_LEFT | BUTTON_REPEAT:
|
||||
#ifdef SCROLL_WHEEL
|
||||
if(wheel_enabled == false)
|
||||
wheel_events++;
|
||||
|
||||
if(wheel_enabled)
|
||||
#endif
|
||||
move_block (0, 0,
|
||||
(co + figures[cf].max_or -
|
||||
1) % figures[cf].max_or);
|
||||
break;
|
||||
|
||||
#ifdef ROCKBLOX_ROTATE_RIGHT2
|
||||
case ROCKBLOX_ROTATE_RIGHT2:
|
||||
move_block (0, 0, (co + 1) % figures[cf].max_or);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ROCKBLOX_DOWN:
|
||||
case ROCKBLOX_DOWN | BUTTON_REPEAT:
|
||||
move_block (0, 1, co);
|
||||
break;
|
||||
|
||||
case ROCKBLOX_RIGHT:
|
||||
case ROCKBLOX_RIGHT | BUTTON_REPEAT:
|
||||
move_block (1, 0, co);
|
||||
break;
|
||||
|
||||
case ROCKBLOX_LEFT:
|
||||
case ROCKBLOX_LEFT | BUTTON_REPEAT:
|
||||
move_block (-1, 0, co);
|
||||
break;
|
||||
|
||||
case ROCKBLOX_DROP:
|
||||
#ifdef ROCKBLOX_DROP_PRE
|
||||
if (lastbutton != ROCKBLOX_DROP_PRE)
|
||||
break;
|
||||
#endif
|
||||
while (canMoveTo (cx, cy + 1, co))
|
||||
move_block (0, 1, co);
|
||||
break;
|
||||
#ifdef ROCKBLOX_RESTART
|
||||
case ROCKBLOX_RESTART:
|
||||
rb->splash (HZ * 1, true, "Restarting...");
|
||||
init_rockblox ();
|
||||
new_block ();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
if (rb->default_event_handler (button) == SYS_USB_CONNECTED)
|
||||
return PLUGIN_USB_CONNECTED;
|
||||
break;
|
||||
}
|
||||
if (button != BUTTON_NONE)
|
||||
lastbutton = button;
|
||||
|
||||
#ifdef SCROLL_WHEEL
|
||||
/* check if we should enable the scroll wheel, if events
|
||||
* begin to stack up... */
|
||||
if(wheel_enabled == false)
|
||||
{
|
||||
/* stopped rotating the wheel, reset the count */
|
||||
if(wheel_events == last_wheel_event)
|
||||
{
|
||||
last_wheel_event = 0;
|
||||
wheel_events = 0;
|
||||
}
|
||||
/* rotated the wheel a while constantly, enable it. */
|
||||
else if(wheel_events > 3)
|
||||
{
|
||||
wheel_enabled = true;
|
||||
}
|
||||
|
||||
/* this evens out the last event and the "current" event.
|
||||
* if we get an event next time through button reading, it will
|
||||
* remain ahead of last_event. if we don't, they'll end up equaling
|
||||
* each other.. thus, the scroll count will be reset. */
|
||||
if(wheel_enabled == false && wheel_events > last_wheel_event)
|
||||
last_wheel_event++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TIME_AFTER(*rb->current_tick, next_down_tick)) {
|
||||
move_down ();
|
||||
next_down_tick += level_speed(level);
|
||||
if (TIME_AFTER(*rb->current_tick, next_down_tick))
|
||||
/* restart time "raster" when we had to wait longer than usual
|
||||
* (pause, game restart etc) */
|
||||
next_down_tick = *rb->current_tick + level_speed(level);
|
||||
}
|
||||
|
||||
if (gameover) {
|
||||
#if LCD_DEPTH >= 2
|
||||
rb->lcd_set_foreground (LCD_BLACK);
|
||||
#endif
|
||||
rb->splash (HZ * 2, true, "Game Over");
|
||||
init_rockblox ();
|
||||
new_block ();
|
||||
}
|
||||
|
||||
refresh_board ();
|
||||
}
|
||||
|
||||
return PLUGIN_OK;
|
||||
}
|
||||
|
||||
enum plugin_status plugin_start (struct plugin_api *api, void *parameter)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void) parameter;
|
||||
rb = api;
|
||||
|
||||
rb->srand (*rb->current_tick);
|
||||
|
||||
rb->lcd_setfont (FONT_SYSFIXED);
|
||||
/* Permanently enable the backlight (unless the user has turned it off) */
|
||||
if (rb->global_settings->backlight_timeout > 0)
|
||||
rb->backlight_set_timeout (1);
|
||||
|
||||
init_rockblox ();
|
||||
ret = rockblox_loop ();
|
||||
|
||||
/* Lets use the default font */
|
||||
rb->lcd_setfont (FONT_UI);
|
||||
/* Restore user's original backlight setting */
|
||||
rb->backlight_set_timeout (rb->global_settings->backlight_timeout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|