/* moves down the figure and returns true if gameover */ static void move_down (void) { int l, i, rx, ry; if (!canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co)) { /* save figure to board */ for (i = 0; i < 4; i++) { rx = getRelativeX (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cx; ry = getRelativeY (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cy; rockblox_status.board[ry][rx] = rockblox_status.cf; } /* check if formed some lines */ l = check_lines (); if (l) { /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */ rockblox_status.score += scoring[l - 1] * rockblox_status.level; rockblox_status.lines += l; rockblox_status.level = (int) rockblox_status.lines / 10 + 1; } /* show details */ show_details (); /* generate a new figure */ new_block (); } else move_block (0, 1, rockblox_status.co); }
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; }
void Animation::nextFrame(bool force) { // If there are no frames or if the animation is not playing, return if (getFrameCount() == 0 || !_playing) return; const Drawable *frame = getConstCurrentFrame(); Surface *surface = _vm->_screen->getSurface(); if (force || (_tick + frame->getDelay() <= _vm->_system->getMillis()) || (_canBeQuick && _vm->_game->getEnableQuickHero() && _vm->_game->getWantQuickHero())) { // If we are at the last frame and not looping, stop the animation // The animation is also restarted to frame zero if ((_currentFrame == getFrameCount() - 1) && !_looping) { // When the animation reaches its end, call the preset callback (this->*_callback)(); } else { // Mark old frame dirty so it gets deleted markDirtyRect(surface); _shift.x += _relativeShifts[_currentFrame].x; _shift.y += _relativeShifts[_currentFrame].y; _currentFrame = nextFrameNum(); _tick = _vm->_system->getMillis(); // Fetch new frame and mark it dirty markDirtyRect(surface); // If the animation is paused, then nextFrameNum() // returns the same frame number even though the time // has elapsed to switch to another frame. We must not // flip _hasChangedFrame to true, otherwise the sample // assigned to this frame will be re-started over and // over until all sound handles are exhausted (happens, // e.g., when switching to the inventory which pauses // all animations). _hasChangedFrame = !_paused; } } debugC(6, kDraciAnimationDebugLevel, "anim=%d tick=%d delay=%d tick+delay=%d currenttime=%d frame=%d framenum=%d x=%d y=%d z=%d", _id, _tick, frame->getDelay(), _tick + frame->getDelay(), _vm->_system->getMillis(), _currentFrame, _frames.size(), frame->getX() + getRelativeX(), frame->getY() + getRelativeY(), _z); }
/* 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 mylcd_set_drawmode (DRMODE_SOLID | DRMODE_INVERSEVID); #endif /* 4x4 */ mylcd_fillrect (PREVIEW_X, PREVIEW_Y, BLOCK_WIDTH * 4, BLOCK_HEIGHT * 4); #if LCD_DEPTH == 1 mylcd_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 (rockblox_status.nf, i, 0) + 2; ry = getRelativeY (rockblox_status.nf, i, 0) + 2; #ifdef HAVE_LCD_BITMAP #if LCD_DEPTH >= 2 rb->lcd_set_foreground (figures[rockblox_status.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[rockblox_status.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[rockblox_status.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); #else /* HAVE_LCD_CHARCELLS */ pgfx_drawpixel (PREVIEW_X + rx, PREVIEW_Y + ry); #endif } }
/* 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 mylcd_set_drawmode (DRMODE_SOLID | DRMODE_INVERSEVID); #endif mylcd_fillrect (BOARD_X, BOARD_Y, BOARD_WIDTH * BLOCK_WIDTH, BOARD_HEIGHT * BLOCK_HEIGHT); #if LCD_DEPTH == 1 mylcd_set_drawmode (DRMODE_SOLID); #endif for (i = 0; i < BOARD_WIDTH; i++) for (j = 0; j < BOARD_HEIGHT; j++) { block = rockblox_status.board[j][i]; if (block != EMPTY_BLOCK) { #ifdef HAVE_LCD_BITMAP #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); #else /* HAVE_LCD_CHARCELLS */ pgfx_drawpixel (BOARD_X + i, BOARD_Y + j); #endif } } 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) + rockblox_status.cy; #ifdef HAVE_LCD_BITMAP #if LCD_DEPTH >= 2 /* middle drawing */ rb->lcd_set_foreground (figures[rockblox_status.cf].color[1]); #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 (figures[rockblox_status.cf].color[0]); #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 (figures[rockblox_status.cf].color[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 } mylcd_update (); }