New Rockblox features

- Add "Ghost piece" feature
   - on 1-bit displays, it's too hard to distinguish from "real" pieces, should it be disabled?
 - Show what your score is when you get a high score
 - Indent

Change-Id: Ibefe748bca3a84736cf1884cc0872d9c36daa613
Reviewed-on: http://gerrit.rockbox.org/990
Tested: Franklin Wei <frankhwei536@gmail.com>
Reviewed-by: Michael Giacomelli <giac2000@hotmail.com>
This commit is contained in:
Franklin Wei 2014-09-27 19:53:16 -04:00 committed by Michael Giacomelli
parent f014a76866
commit 4991544037

View file

@ -779,7 +779,7 @@ extern const fb_data rockblox_background[];
% % %%%
%% % %% % - T has 4 orientations
% %%% %
*/
*/
/* c=current f=figure o=orientation n=next */
static struct _rockblox_status
@ -788,11 +788,12 @@ static struct _rockblox_status
int lines;
int level;
int score;
int cx;
int cy;
int cf;
int co;
int nf;
int cx; /* current piece, x-coord */
int cy; /* current piece, y-coord */
int cf; /* current figure number, index in figures[] */
int co; /* orientation of figure */
int nf; /* next figure */
int hf; /* hold figure */
bool dropped;
short board[BOARD_HEIGHT][BOARD_WIDTH]; /* 20 rows of 10 blocks */
} rockblox_status;
@ -824,7 +825,7 @@ struct figure
}
/* array of figures */
figures[BLOCKS_NUM] = {
figures[BLOCKS_NUM] = {
/* O */
{
#if LCD_DEPTH >= 16
@ -909,7 +910,11 @@ figures[BLOCKS_NUM] = {
{-1, 0, 1, 0},
{0, 0, 0, 1}
}
};
};
#if LCD_DEPTH >=2
unsigned int ghost_colors[BLOCKS_NUM][3]; /* same format as figure.colors[] */
#endif
bool resume = false;
bool resume_file = false;
@ -982,7 +987,7 @@ static void load_game(void)
if (rb->read(fd, &rockblox_status, sizeof(struct _rockblox_status))
< (ssize_t)sizeof(struct _rockblox_status))
{
rb->splash(HZ/2, "Loading Rockblox resume info failed");
rb->splash(HZ/2, "Loading failed");
} else {
resume = true;
}
@ -1010,7 +1015,7 @@ static void dump_resume(void)
return;
fail:
rb->splash(HZ/2, "Writing Rockblox resume info failed");
rb->splash(HZ/2, "Saving failed");
return;
}
@ -1094,6 +1099,20 @@ static int getRelativeY (int figure, int square, int orientation)
}
}
static bool canMoveTo (int x, int y, int newOrientation)
{
int i, rx, ry;
for (i = 0; i < 4; i++) {
ry = getRelativeY (rockblox_status.cf, i, newOrientation) + y;
rx = getRelativeX (rockblox_status.cf, i, newOrientation) + x;
if ((rx < 0 || rx >= BOARD_WIDTH) ||
(ry < 0 || ry >= BOARD_HEIGHT) ||
(rockblox_status.board[ry][rx] != EMPTY_BLOCK))
return false;
}
return true;
}
/* redraw the while board on the screen */
static void refresh_board (void)
{
@ -1112,6 +1131,8 @@ static void refresh_board (void)
mylcd_set_drawmode (DRMODE_SOLID);
#endif
/* draw board (not including current piece) */
for (i = 0; i < BOARD_WIDTH; i++)
for (j = 0; j < BOARD_HEIGHT; j++) {
block = rockblox_status.board[j][i];
@ -1150,6 +1171,53 @@ static void refresh_board (void)
}
}
/* draw ghost piece first so that it appears underneath the "real" piece */
int ghost_y=rockblox_status.cy;
/* find the position to draw it in */
while(canMoveTo(rockblox_status.cx, ghost_y+1, rockblox_status.co))
ghost_y++;
for (i = 0; i < 4; i++) {
x = getRelativeX (rockblox_status.cf, i, rockblox_status.co)
+ rockblox_status.cx;
y = getRelativeY (rockblox_status.cf, i, rockblox_status.co)
+ ghost_y;
#ifdef HAVE_LCD_BITMAP
#if LCD_DEPTH >= 2
/* middle drawing */
rb->lcd_set_foreground (ghost_colors[rockblox_status.cf][0]);
#endif
rb->lcd_fillrect (BOARD_X + x * BLOCK_WIDTH,
BOARD_Y + y * BLOCK_HEIGHT,
BLOCK_WIDTH, BLOCK_HEIGHT);
#if LCD_DEPTH >= 2
/* light drawing */
rb->lcd_set_foreground (ghost_colors[rockblox_status.cf][1]);
#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
/* shadow drawing */
rb->lcd_set_foreground (ghost_colors[rockblox_status.cf][2]);
#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);
#else /* HAVE_LCD_CHARCELLS */
pgfx_drawpixel (BOARD_X + x, BOARD_Y + y);
#endif
}
/* draw current piece */
for (i = 0; i < 4; i++) {
x = getRelativeX (rockblox_status.cf, i, rockblox_status.co)
+ rockblox_status.cx;
@ -1186,21 +1254,8 @@ static void refresh_board (void)
pgfx_drawpixel (BOARD_X + x, BOARD_Y + y);
#endif
}
mylcd_update ();
}
static bool canMoveTo (int x, int y, int newOrientation)
{
int i, rx, ry;
for (i = 0; i < 4; i++) {
ry = getRelativeY (rockblox_status.cf, i, newOrientation) + y;
rx = getRelativeX (rockblox_status.cf, i, newOrientation) + x;
if ((rx < 0 || rx >= BOARD_WIDTH) ||
(ry < 0 || ry >= BOARD_HEIGHT) ||
(rockblox_status.board[ry][rx] != EMPTY_BLOCK))
return false;
}
return true;
mylcd_update ();
}
/* draws the preview of next block in the preview window */
@ -1429,8 +1484,9 @@ static int rockblox_menu(void)
return 1;
case 6:
if (resume) {
rb->splash(HZ*1, "Saving game ...");
rb->splash(0, "Saving...");
dump_resume();
rb->lcd_update();
}
return 1;
case MENU_ATTACHED_USB:
@ -1645,10 +1701,41 @@ enum plugin_status plugin_start (const void *parameter)
return PLUGIN_OK;
}
#endif
/* Turn off backlight timeout */
backlight_ignore_timeout();
load_game();
resume_file = resume;
#if LCD_DEPTH >= 2
/* precalculate ghost piece colors */
#ifdef HAVE_LCD_COLOR
for(int p=0;p<BLOCKS_NUM;++p)
{
for(int i=0;i<3;++i)
{
/* find red average */
int red=0;
red+=RGB_UNPACK_RED(figures[p].color[i])/4;
/* green */
int green=0;
green+=RGB_UNPACK_GREEN(figures[p].color[i])/4;
/* blue */
int blue=0;
blue+=RGB_UNPACK_BLUE(figures[p].color[i])/4;
ghost_colors[p][i]=LCD_RGBPACK(red,green,blue);
}
}
#else /* greyscale or monochrome */
for(int p=0;p<BLOCKS_NUM;++p)
{
for(int i=0;i<3;++i)
ghost_colors[p][i]=figures[p].color[i]/2;
}
#endif
#endif /* LCD_DEPTH >= 2 */
while(!rockblox_loop()) {
if(!resume) {
int position = highscore_update(rockblox_status.score,
@ -1656,7 +1743,7 @@ enum plugin_status plugin_start (const void *parameter)
highscores, NUM_SCORES);
if (position != -1) {
if (position == 0)
rb->splash(HZ*2, "New High Score");
rb->splashf(HZ*2, "New High Score: %d", rockblox_status.score);
highscore_show(position, highscores, NUM_SCORES, true);
}
}