From 6fa5bc504edfa4299b0b5d46d299cb5741654243 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 23 Oct 2019 19:53:39 -0400 Subject: optimize cpu usage --- frontends/curses/curses_ui.c | 42 +++++++++-------- lib/cetris.h | 104 +++++++++++++++++++------------------------ 2 files changed, 71 insertions(+), 75 deletions(-) diff --git a/frontends/curses/curses_ui.c b/frontends/curses/curses_ui.c index f3ebaa8..9b458dc 100644 --- a/frontends/curses/curses_ui.c +++ b/frontends/curses/curses_ui.c @@ -84,7 +84,7 @@ void curses_init() { curs_set(0); noecho(); keypad(stdscr, TRUE); - nodelay(stdscr, true); + timeout(16); #ifdef _WIN32 // only resize manually on windows resize_term(WIN_LINE, WIN_COL); @@ -122,15 +122,32 @@ void *game_loop(void) { void draw_board() { mvaddstr(0, 0, PLAY_FIELD_STR); - for (int x = 0; x < CETRIS_BOARD_X; x++) { - for (int y = CETRIS_BOARD_VISABLE; y < CETRIS_BOARD_Y; y++) { - int draw_y = y - CETRIS_BOARD_VISABLE + Y_OFFSET; - int draw_x = x * 2 + X_OFFSET; - if (game.board[x][y] & SLOT_GHOST) { - attron(A_DIM); + + for (int y = 0; y < 4; y++) { + for (int x = 0; x < 4; x++) { + if ((game.current.m[y]>>(3 - x))&1) { + int draw_x = X_OFFSET + ((x + game.current.pos.x) * 2); + int draw_y = Y_OFFSET + (y + game.current.pos.y) - CETRIS_BOARD_VISABLE; + int ghost_y = Y_OFFSET + (y + game.current.ghost_y) - CETRIS_BOARD_VISABLE; + attron(COLOR_PAIR(game.current.t) | A_BOLD); mvaddstr(draw_y, draw_x, BLOCK); + + if ((default_matrices[game.piece_queue[game.current_index]][y]>>(3 - x))&1) { + mvaddstr(6 + y, (x * 2) + 36, BLOCK); + } + + attroff(COLOR_PAIR(game.current.t) | A_BOLD); + attron(A_DIM); + mvaddstr(ghost_y, draw_x, BLOCK); attroff(A_DIM); } + } + } + + for (int x = 0; x < CETRIS_BOARD_X; x++) { + for (int y = game.highest_line; y < CETRIS_BOARD_Y; y++) { + int draw_y = y - CETRIS_BOARD_VISABLE + Y_OFFSET; + int draw_x = x * 2 + X_OFFSET; if (game.board[x][y] & SLOT_OCCUPIED) { attron(COLOR_PAIR(game.board[x][y] >> 5) | A_BOLD); if (game.line_remove_tick[y]) { @@ -144,17 +161,6 @@ void draw_board() { } } - int index = game.current_index; - attron(COLOR_PAIR(game.piece_queue[index])); - for (int x = 0; x < 4; x++) { - for (int y = 0; y < 4; y++) { - if ((default_matrices[game.piece_queue[index]][y]>>(3 - x))&1) { - mvaddstr(6 + y, (x * 2) + 36, BLOCK); - } - } - } - attroff(COLOR_PAIR(game.piece_queue[index])); - attron(A_BOLD); char score[50]; diff --git a/lib/cetris.h b/lib/cetris.h index 5a6081b..cc4659c 100644 --- a/lib/cetris.h +++ b/lib/cetris.h @@ -47,7 +47,6 @@ enum { enum { SLOT_OCCUPIED = 1, SLOT_GHOST = 1 << 1, - SLOT_CONSTANT = 1 << 2 }; enum { @@ -80,6 +79,7 @@ typedef enum { typedef struct { /* playfield represented by a 2d array */ uint8_t board[CETRIS_BOARD_X][CETRIS_BOARD_Y]; + int8_t highest_line; /* constant queue of all 7 possible tetrimino */ uint8_t piece_queue[7]; @@ -122,15 +122,15 @@ const piece_matrix default_matrices[7] = { /* SRS WALL KICK VALUES */ // https://tetris.wiki/SRS -static const vec2 srs_wall_kicks[8][4] = { - {{-1, 0}, {-1, 1}, {0, -2}, {-1, -2}}, // 0->R - {{1, 0}, {1, -1}, {0, 2}, {1, 2}}, // R->0 - {{1, 0}, {1, -1}, {0, 2}, {1, 2}}, // R->2 - {{-1, 0}, {-1, 1}, {0, -2}, {-1, -2}}, // 2->R - {{1, 0}, {1, 1}, {0, -2}, {1, -2}}, // 2->L - {{-1, 0}, {-1, -1}, {0, 2}, {-1, 2}}, // L->2 - {{-1, 0}, {-1, -1}, {0, 2}, {-1, 2}}, // L->0 - {{1, 0}, {1, 1}, {0, -2}, {1, -2}} // 0->L +static const vec2 srs_wall_kicks[8][5] = { + {{0, 0}, {-1, 0}, {-1, 1}, {0, -2}, {-1, -2}}, // 0->R + {{0, 0}, {1, 0}, {1, -1}, {0, 2}, {1, 2}}, // R->0 + {{0, 0}, {1, 0}, {1, -1}, {0, 2}, {1, 2}}, // R->2 + {{0, 0}, {-1, 0}, {-1, 1}, {0, -2}, {-1, -2}}, // 2->R + {{0, 0}, {1, 0}, {1, 1}, {0, -2}, {1, -2}}, // 2->L + {{0, 0}, {-1, 0}, {-1, -1}, {0, 2}, {-1, 2}}, // L->2 + {{0, 0}, {-1, 0}, {-1, -1}, {0, 2}, {-1, 2}}, // L->0 + {{0, 0}, {1, 0}, {1, 1}, {0, -2}, {1, -2}} // 0->L }; static const vec2 srs_wall_kicks_i[8][5] = { @@ -203,8 +203,7 @@ static int check_matrix(cetris_game *g, piece_matrix *m) { return 0; if (r.y >= CETRIS_BOARD_Y) return -1; - if ((g->board[r.x][r.y] & SLOT_OCCUPIED) - && (g->board[r.x][r.y] & SLOT_CONSTANT)) + if (g->board[r.x][r.y] & SLOT_OCCUPIED) return -1; } } @@ -281,7 +280,7 @@ static void add_score(cetris_game *g, int lines) { } static void make_ghosts(cetris_game *g) { - int orig_y = g->current.pos.y; + int8_t orig_y = g->current.pos.y; while (check_matrix(g, &g->current.m) > 0) { g->current.pos.y++; } @@ -289,13 +288,6 @@ static void make_ghosts(cetris_game *g) { g->current.pos.y = orig_y; } -static void reset_tetrimino(tetrimino *t) { - t->r = INIT; - t->pos.x = 3; - t->pos.y = (t->t == MINO_I) ? 17 : 16; - t->ghost_y = 0; -} - static void move_current(cetris_game *g, input_t move) { if (g->game_over || g->next_piece_tick) return; @@ -346,12 +338,19 @@ static void next_piece(cetris_game *g) { static void lock_current(cetris_game *g) { g->current.locked = true; - for (int x = 0; x < CETRIS_BOARD_X; x++) { - for (int y = 0; y < CETRIS_BOARD_Y; y++) { - if (g->board[x][y] & SLOT_OCCUPIED) - g->board[x][y] |= SLOT_CONSTANT; + for (int y = 0; y < 4; y++) { + for (int x = 0; x < 4; x++) { + if ((g->current.m[y]>>(3 - x))&1) { + g->board[g->current.pos.x + x][g->current.pos.y + y] |= SLOT_OCCUPIED; + g->board[g->current.pos.x + x][g->current.pos.y + y] |= g->current.t << 5; + } } } + + if (g->current.pos.y < g->highest_line) { + g->highest_line = g->current.pos.y; + } + update_board(g); } @@ -369,8 +368,8 @@ static void hard_drop(cetris_game *g) { g->score += 2 * drop_count; // 2 score for each hard-drop'd cell - update_board(g); lock_current(g); + update_board(g); } static void rotate_matrix(cetris_game *g, piece_matrix *m, bool clockwise) { @@ -411,33 +410,27 @@ static void rotate_piece(cetris_game *g, bool clockwise) { rotate_matrix(g, &m, clockwise); + vec2 kick; bool set_current = false; - if (check_matrix(g, &m) > 0) { - set_current = true; - } - bool did_kick = false; - if (!set_current) { - vec2 kick; - for (int i = 0; i < 4; i++) { - if (g->current.t == MINO_I) { - kick = srs_wall_kicks_i[wall_kick][i]; - } else { - kick = srs_wall_kicks[wall_kick][i]; - } + for (int i = 0; i < 4; i++) { + if (g->current.t == MINO_I) { + kick = srs_wall_kicks_i[wall_kick][i]; + } else { + kick = srs_wall_kicks[wall_kick][i]; + } - g->current.pos.x += kick.x; - g->current.pos.y += kick.y; + g->current.pos.x += kick.x; + g->current.pos.y += kick.y; - if (check_matrix(g, &m) > 0) { - set_current = true; - break; - } else { - g->current.pos.x -= kick.x; - g->current.pos.y -= kick.y; - } + if (check_matrix(g, &m) > 0) { + set_current = true; + if (i > 0) did_kick = true; + break; } - did_kick = true; + + g->current.pos.x -= kick.x; + g->current.pos.y -= kick.y; } if (set_current) { @@ -472,13 +465,9 @@ void update_board(cetris_game *g) { return; int lines_cleared = 0; - for (int y = 0; y < CETRIS_BOARD_Y; y++) { + for (int y = g->highest_line; y < CETRIS_BOARD_Y; y++) { bool clear_line = true; for (int x = 0; x < CETRIS_BOARD_X; x++) { - if (!(g->board[x][y] & SLOT_CONSTANT)) { - g->board[x][y] = 0; - } - if (!(g->board[x][y] & SLOT_OCCUPIED) || g->line_remove_tick[y] > 0) { clear_line = false; @@ -500,7 +489,7 @@ void update_board(cetris_game *g) { } make_ghosts(g); - set_matrix(g, &g->current.m); + //set_matrix(g, &g->current.m); assert(lines_cleared <= 4); @@ -528,8 +517,7 @@ CETRIS_EXPORT void hold_piece(cetris_game *g) { g->current = g->held; g->held = tmp; } else { - g->held = g->current; - reset_tetrimino(&g->held); + set_piece(g->current.t, &g->held); g->piece_held = true; next_piece(g); } @@ -570,6 +558,7 @@ CETRIS_EXPORT void init_game(cetris_game *g) { memset(g, 0, sizeof(cetris_game)); g->level = CETRIS_STARTING_LEVEL; + g->highest_line = CETRIS_BOARD_Y; init_queue(g); shuffle_queue(g); @@ -608,11 +597,12 @@ CETRIS_EXPORT void update_game_tick(cetris_game *g) { if (!g->next_piece_tick && g->current.lock_tick && g->current.lock_tick <= g->tick) { g->current.pos.y++; - if (check_matrix(g, &g->current.m) <= 0) { + int8_t res = check_matrix(g, &g->current.m); + g->current.pos.y--; + if (res <= 0) { lock_current(g); did_move = true; } - g->current.pos.y--; g->current.lock_tick = 0; } -- cgit v1.2.3-101-g0448