321 lines
7.2 KiB
C
321 lines
7.2 KiB
C
#include "ctris.h"
|
|
#include "game.h"
|
|
#include "brick.h"
|
|
#include "screen.h"
|
|
#include "highscore.h"
|
|
|
|
void init_board(char board[BOARD_HEIGHT][BOARD_WIDTH])
|
|
{
|
|
unsigned char i, n;
|
|
for(i = 0; i < BOARD_HEIGHT; i++)
|
|
{
|
|
for(n = 0; n < BOARD_WIDTH; n++)
|
|
{
|
|
board[i][n] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// NEW CODE
|
|
#define PATH_MODULE "/dev/mylab1_joystick"
|
|
int fd;
|
|
int buffer[5] = {1,1,1,1,1};
|
|
int read_err;
|
|
int init_mylab(){
|
|
fd = open(PATH_MODULE,O_RDONLY,S_IRUSR);
|
|
if(fd < 0){
|
|
printf("Could not retrieve mylab driver\n");
|
|
return fd;
|
|
}
|
|
}
|
|
//
|
|
|
|
void remove_this_row(WINDOW *win, char board[BOARD_HEIGHT][BOARD_WIDTH], unsigned char y)
|
|
{
|
|
unsigned char x;
|
|
show_remove_row(win, board, y);
|
|
for(; y > 0; y--)
|
|
{
|
|
for(x = 0; x < BOARD_WIDTH; x++)
|
|
{
|
|
board[y][x] = board[y - 1][x];
|
|
}
|
|
}
|
|
}
|
|
|
|
void remove_rows(WINDOW *win, char board[BOARD_HEIGHT][BOARD_WIDTH], unsigned int *score, const char level)
|
|
{
|
|
char removed_rows = 0;
|
|
unsigned char x, y;
|
|
unsigned int sub_score = 0;
|
|
for(y = 0; y < BOARD_HEIGHT; y++)
|
|
{
|
|
for(x = 0; x < BOARD_WIDTH; x++)
|
|
{
|
|
if(board[y][x] == 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if(x >= BOARD_WIDTH)
|
|
{
|
|
remove_this_row(win, board, y);
|
|
removed_rows++;
|
|
sub_score += BONUS_CONST * level * removed_rows;
|
|
}
|
|
}
|
|
*score += sub_score;
|
|
if(removed_rows > 0)
|
|
{
|
|
refresh_win(win);
|
|
usleep(REMOVE_SPLASH_TIME);
|
|
}
|
|
}
|
|
|
|
void calc_level(const unsigned int score, char *level)
|
|
{
|
|
while(SPEED_CONST_2 - (*level + 1) * SPEED_CONST_1 >= 0 && score / (LEVEL_CONST * (unsigned int)pow((double)*level, 2)) > 0)
|
|
{
|
|
*level += 1;
|
|
}
|
|
}
|
|
|
|
void pause_game()
|
|
{
|
|
game_engine(true);
|
|
}
|
|
|
|
unsigned int start_game()
|
|
{
|
|
return game_engine(false);
|
|
}
|
|
|
|
unsigned int game_engine(bool resize)
|
|
{
|
|
static char brick_type, next_brick_type, name[40], cur_brick[4][4], board[BOARD_HEIGHT][BOARD_WIDTH], level = 1;
|
|
char run;
|
|
unsigned int score = 0;
|
|
static unsigned long time = 0L;
|
|
unsigned int tick = 0;
|
|
static unsigned char x, y;
|
|
static WINDOW *board_win, *preview_win, *score_win;
|
|
static bool engine_stop = false;
|
|
|
|
show_headline();
|
|
|
|
// NEW CODE
|
|
|
|
init_mylab();
|
|
|
|
//
|
|
|
|
if (resize) {
|
|
if (game_state != PAUSED_STATE) {
|
|
// if the game engine is in the RUNING_STATE then
|
|
// the resize call below will switch the engine to PAUSED_STATE
|
|
|
|
// if the game is in the QUIT_STATE then
|
|
// the call below will simulate a key being pressed
|
|
// and that will force the highscore screen or play_again dialog to be refreshed
|
|
put_key('p');
|
|
}
|
|
|
|
if (game_state == QUIT_STATE)
|
|
{
|
|
// if the game is in the highscore screen then refresh it upon resize
|
|
if (!engine_stop) {
|
|
show_highscore(name);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// here we will only have RUNNING_STATE, PAUSED_STATE or GAME_OVER_STATE
|
|
// both states coresponds to the main screen so
|
|
// the main screen will be refreshed upon resize
|
|
show_score(score_win, score, level, time);
|
|
show_brick_preview(preview_win, next_brick_type);
|
|
show_board_win(board_win, board, cur_brick, brick_type, x, y);
|
|
if (game_state == PAUSED_STATE) {
|
|
show_pause(board_win);
|
|
}
|
|
else if (game_state == GAME_OVER_STATE) {
|
|
show_game_over(board_win);
|
|
}
|
|
}
|
|
return score;
|
|
}
|
|
|
|
engine_stop = false;
|
|
board_win = (WINDOW *)create_board_win();
|
|
preview_win = (WINDOW *)create_preview_win();
|
|
score_win = (WINDOW *)create_score_win();
|
|
init_board(board);
|
|
show_score(score_win, score, level, time);
|
|
next_brick_type = get_rand(7) + 1;
|
|
game_state = PAUSED_STATE;
|
|
wait_for_start(board_win);
|
|
game_state = RUNNING_STATE;
|
|
while(game_state == RUNNING_STATE)
|
|
{
|
|
brick_type = next_brick_type;
|
|
next_brick_type = get_rand(7) + 1;
|
|
show_brick_preview(preview_win, next_brick_type);
|
|
memcpy(cur_brick, brick_digit[brick_type - 1], sizeof(char) * 4 * 4);
|
|
x = BOARD_WIDTH / 2;
|
|
y = 0;
|
|
run = 1;
|
|
while(game_state == RUNNING_STATE)
|
|
{
|
|
show_board_win(board_win, board, cur_brick, brick_type, x, y);
|
|
|
|
int keyValue = get_key(board_win);
|
|
|
|
// NEW CODE
|
|
// Update KEY_STATE
|
|
read_err = read(fd,buffer,5 * sizeof(int));
|
|
if(read_err < 0)
|
|
printf("Could not read module\n");
|
|
|
|
if(!buffer[0])
|
|
keyValue = KEY_UP;
|
|
if(!buffer[1])
|
|
keyValue = KEY_DOWN;
|
|
if(!buffer[2])
|
|
keyValue = KEY_LEFT;
|
|
if(!buffer[3])
|
|
keyValue = KEY_RIGHT;
|
|
if(!buffer[4])
|
|
keyValue = 'p';
|
|
//
|
|
|
|
switch(keyValue)
|
|
{
|
|
case 's':
|
|
case KEY_DOWN:
|
|
if(old_style_keys != 0)
|
|
{
|
|
if(counterclockwise_rotation == 1)
|
|
{
|
|
change_direction(board, cur_brick, x, y, -1);
|
|
}
|
|
else
|
|
{
|
|
change_direction(board, cur_brick, x, y, 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(check_brick(board, cur_brick, x, y + 1) == 0)
|
|
{
|
|
y++;
|
|
}
|
|
}
|
|
break;
|
|
case 'w':
|
|
case 'k':
|
|
case KEY_UP:
|
|
if(counterclockwise_rotation == 1)
|
|
{
|
|
change_direction(board, cur_brick, x, y, 1);
|
|
}
|
|
else
|
|
{
|
|
change_direction(board, cur_brick, x, y, -1);
|
|
}
|
|
break;
|
|
case 'd':
|
|
case 'l':
|
|
case KEY_RIGHT:
|
|
if(check_brick(board, cur_brick, x + 1, y) == 0)
|
|
{
|
|
x++;
|
|
}
|
|
break;
|
|
case 'a':
|
|
case 'j':
|
|
case KEY_LEFT:
|
|
if(x > 0 && check_brick(board, cur_brick, x - 1, y) == 0)
|
|
{
|
|
x--;
|
|
}
|
|
break;
|
|
case ' ':
|
|
if(old_style_keys != 0)
|
|
{
|
|
if(check_brick(board, cur_brick, x, y + 1) == 0)
|
|
{
|
|
y++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while(check_brick(board, cur_brick, x, y + 1) == 0)
|
|
{
|
|
y++;
|
|
}
|
|
}
|
|
break;
|
|
case 'p':
|
|
game_state = PAUSED_STATE;
|
|
show_pause(board_win);
|
|
while(old_get_key(board_win) != 'p');
|
|
game_state = RUNNING_STATE;
|
|
break;
|
|
case 'q':
|
|
game_state = QUIT_STATE;
|
|
break;
|
|
}
|
|
tick = SPEED_CONST_2 - level * SPEED_CONST_1;
|
|
time += tick;
|
|
show_score(score_win, score, level, time);
|
|
usleep(tick);
|
|
if(run > 15)
|
|
{
|
|
if(check_brick(board, cur_brick, x, y + 1) == 0)
|
|
{
|
|
y++;
|
|
run = 0;
|
|
}
|
|
else
|
|
{
|
|
if(y <= 1)
|
|
{
|
|
game_state = GAME_OVER_STATE;
|
|
show_game_over(board_win);
|
|
while(old_get_key(board_win) != ' ');
|
|
game_state = QUIT_STATE;
|
|
}
|
|
draw_to_board(board, cur_brick, brick_type, x, y);
|
|
show_board_win(board_win, board, cur_brick, brick_type, x, y);
|
|
remove_rows(board_win, board, &score, level);
|
|
#ifdef EXTRA_BONUS
|
|
score += level;
|
|
#endif
|
|
calc_level(score, &level);
|
|
show_score(score_win, score, level, time);
|
|
break;
|
|
}
|
|
}
|
|
run++;
|
|
}
|
|
|
|
}
|
|
destroy_score_win(score_win);
|
|
destroy_preview_win(preview_win);
|
|
destroy_board_win(board_win);
|
|
if(game_state == QUIT_STATE)
|
|
{
|
|
if(in_highscore(score) == 0)
|
|
{
|
|
add_user_to_highscore(name, score);
|
|
}
|
|
else
|
|
{
|
|
strncpy(name, "-no-name-", 40);
|
|
}
|
|
show_highscore(name);
|
|
getch();
|
|
}
|
|
engine_stop = true;
|
|
return score;
|
|
} |