/* Start a new game */ static void startGame(StcGame *game) { int i; /* Initialize game data */ game->errorCode = GAME_ERROR_NONE; game->systemTime = platformGetSystemTime(); game->lastFallTime = game->systemTime; game->isOver = 0; game->isPaused = 0; game->showPreview = 1; game->events = EVENT_NONE; game->delay = INI_DELAY_FALL; /* Initialize game statistics */ game->stats.score = 0; game->stats.lines = 0; game->stats.totalPieces = 0; game->stats.level = 0; for (i = 0; i < 7; ++i) { game->stats.pieces[i] = 0; } /* Initialize rand generator */ srand(game->systemTime); /* Initialize game tile map */ setMatrixCells(&game->map[0][0], BOARD_WIDTH, BOARD_HEIGHT, EMPTY_CELL); /* Initialize falling tetromino */ setTetramino(rand() % 7, &game->fallingBlock); game->fallingBlock.x = (BOARD_WIDTH - game->fallingBlock.size) / 2; game->fallingBlock.y = 0; /* Initialize preview tetromino */ setTetramino(rand() % 7, &game->nextBlock); }
/* Start a new game */ static void startGame(StcGame *game) { int i; /* Initialize game data */ game->errorCode = ERROR_NONE; game->data->systemTime = platformGetSystemTime(); game->data->lastFallTime = game->data->systemTime; game->data->isOver = 0; game->isPaused = 0; game->showPreview = 1; game->data->events = EVENT_NONE; game->data->fallingDelay = STC_INIT_DELAY_FALL; #ifdef STC_SHOW_GHOST_PIECE game->showShadow = 1; #endif /* Initialize game statistics */ game->stats.score = 0; game->stats.lines = 0; game->stats.totalPieces = 0; game->stats.level = 0; for (i = 0; i < TETROMINO_TYPES; ++i) { game->stats.pieces[i] = 0; } /* Initialize game tile map */ setMatrixCells(&game->map[0][0], BOARD_TILEMAP_WIDTH, BOARD_TILEMAP_HEIGHT, EMPTY_CELL); /* Initialize falling tetromino */ setTetromino(platformRandom() % TETROMINO_TYPES, &game->fallingBlock); game->fallingBlock.x = (BOARD_TILEMAP_WIDTH - game->fallingBlock.size) / 2; game->fallingBlock.y = 0; /* Initialize preview tetromino */ setTetromino(platformRandom() % TETROMINO_TYPES, &game->nextBlock); /* Initialize events */ onTetrominoMoved(game); /* Initialize delayed autoshift */ game->data->delayLeft = -1; game->data->delayRight = -1; game->data->delayDown = -1; #ifdef STC_AUTO_ROTATION game->data->delayRotation = -1; #endif }
/* * Main function game called every frame */ void gameUpdate(StcGame *game) { long currentTime; int timeDelta; /* Read user input */ platformProcessEvents(game); /* Update game state */ if (game->data->isOver != 0) { if ((game->data->events & EVENT_RESTART) != 0) { game->data->isOver = 0; startGame(game); } } else { currentTime = platformGetSystemTime(); /* Process delayed autoshift */ timeDelta = (int)(currentTime - game->data->systemTime); if (game->data->delayDown > 0) { game->data->delayDown -= timeDelta; if (game->data->delayDown <= 0) { game->data->delayDown = DAS_MOVE_TIMER; game->data->events |= EVENT_MOVE_DOWN; } } if (game->data->delayLeft > 0) { game->data->delayLeft -= timeDelta; if (game->data->delayLeft <= 0) { game->data->delayLeft = DAS_MOVE_TIMER; game->data->events |= EVENT_MOVE_LEFT; } } else if (game->data->delayRight > 0) { game->data->delayRight -= timeDelta; if (game->data->delayRight <= 0) { game->data->delayRight = DAS_MOVE_TIMER; game->data->events |= EVENT_MOVE_RIGHT; } } #ifdef STC_AUTO_ROTATION if (game->data->delayRotation > 0) { game->data->delayRotation -= timeDelta; if (game->data->delayRotation <= 0) { game->data->delayRotation = ROTATION_AUTOREPEAT_TIMER; game->data->events |= EVENT_ROTATE_CW; } } #endif /* STC_AUTO_ROTATION */ /* Always handle pause event */ if ((game->data->events & EVENT_PAUSE) != 0) { game->isPaused = !game->isPaused; game->data->events = EVENT_NONE; } /* Check if the game is paused */ if (game->isPaused != 0) { /* We achieve the effect of pausing the game * adding the last frame duration to lastFallTime */ game->data->lastFallTime += (currentTime - game->data->systemTime); } else { if ((game->data->events != EVENT_NONE) != 0) { if (game->data->events & EVENT_SHOW_NEXT) { game->showPreview = !game->showPreview; game->stateChanged = 1; } #ifdef STC_SHOW_GHOST_PIECE if ((game->data->events & EVENT_SHOW_SHADOW) != 0) { game->showShadow = !game->showShadow; game->stateChanged = 1; } #endif if ((game->data->events & EVENT_DROP) != 0) { dropTetromino(game); } if ((game->data->events & EVENT_ROTATE_CW) != 0) { rotateTetromino(game, 1); } if ((game->data->events & EVENT_MOVE_RIGHT) != 0) { moveTetromino(game, 1, 0); } else if ((game->data->events & EVENT_MOVE_LEFT) != 0) { moveTetromino(game, -1, 0); } if ((game->data->events & EVENT_MOVE_DOWN) != 0) { /* Update score if the user accelerates downfall */ game->stats.score += (long)(SCORE_2_FILLED_ROW * (game->stats.level + 1) / SCORE_MOVE_DOWN_DIVISOR); moveTetromino(game, 0, 1); } game->data->events = EVENT_NONE; } /* Check if it's time to move downwards the falling tetromino */ if (currentTime - game->data->lastFallTime >= game->data->fallingDelay) { moveTetromino(game, 0, 1); game->data->lastFallTime = currentTime; } } /* Save current time for next game update */ game->data->systemTime = currentTime; } /* Draw game state */ platformRenderGame(game); }
/* * Main function game called every frame */ void gameUpdate(StcGame *game) { long sysTime; /* Read user input */ platformReadInput(game); /* Update game state */ if (game->isOver) { if (game->stats.score > game->stats.high) { game->stats.high = game->stats.score; FILE * f; long buf; buf = game->stats.score; mkdir_if_not_exist("A/CHDK/GAMES"); f = fopen ( "A/CHDK/GAMES/TETRIS.SCO" , "wb" ); fwrite (&buf , 1 , sizeof(buf) , f ); fclose (f); } //if (game->events & EVENT_RESTART) { if (game->events & EVENT_PAUSE) { //TurnOnBackLight(); game->isOver = 0; startGame(game); } } else { sysTime = platformGetSystemTime(); /* Always handle pause event */ if (game->events & EVENT_PAUSE) { game->isPaused = !game->isPaused; game->events = EVENT_NONE; } /* Check if the game is paused */ if (game->isPaused) { /* We achieve the effect of pausing the game * adding the last frame duration to lastFallTime */ game->lastFallTime += (sysTime - game->systemTime); } else { if (game->events != EVENT_NONE) { if (game->events & EVENT_SHOW_NEXT) { game->showPreview = !game->showPreview; } if (game->events & EVENT_DROP) { dropTetramino(game); } if (game->events & EVENT_ROTATE_CW) { rotateTetramino(game, 1); } if (game->events & EVENT_MOVE_RIGHT) { moveTetramino(game, 1, 0); } else if (game->events & EVENT_MOVE_LEFT) { moveTetramino(game, -1, 0); } if (game->events & EVENT_MOVE_DOWN) { moveTetramino(game, 0, 1); } game->events = EVENT_NONE; } /* Check if it's time to move downwards the falling tetromino */ if (sysTime - game->lastFallTime >= game->delay) { moveTetramino(game, 0, 1); game->lastFallTime = sysTime; } } game->systemTime = sysTime; } /* Draw game state */ platformRenderGame(game); }