From d64514659c38c672e65ffccd6f44a64143a4dbfd Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Mon, 19 Aug 2019 15:53:22 -0400 Subject: remove das code and simplify some other stuff --- core/src/cetris.c | 300 ------------------------------------------------------ core/src/input.c | 51 ---------- core/src/matrix.c | 278 -------------------------------------------------- core/src/test.c | 72 ------------- 4 files changed, 701 deletions(-) delete mode 100644 core/src/cetris.c delete mode 100644 core/src/input.c delete mode 100644 core/src/matrix.c delete mode 100644 core/src/test.c (limited to 'core/src') diff --git a/core/src/cetris.c b/core/src/cetris.c deleted file mode 100644 index d8eda2f..0000000 --- a/core/src/cetris.c +++ /dev/null @@ -1,300 +0,0 @@ -#include -#include -#include -#include -#include - -#include "cetris.h" -#include "types.h" -#include "matrix.h" -#include "input.h" - -#ifdef BUILD_TESTS -#include "test.h" -#endif - -/* FUNCTION PROTOTYPES */ - -static void init_piece_queue(cetris_game* g); -static void shuffle_queue(cetris_game* g); -static void add_score(cetris_game* g, u8 lines); - -/* LEVEL DROP SPEED VALUES */ - -// https://tetris.fandom.com/wiki/Tetris_Worlds -// TODO: Make this more accurate -static const u32 level_drop_delay[20] = { - 60, 48, 37, 28, 21, 16, 11, 8, 6, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1 -}; - -/* GAME FUNCTIONS */ - -void init_game(cetris_game* g) { - - /* check for config errors */ - assert(CETRIS_NEXT_PIECE_DELAY >= CETRIS_LINE_CLEAR_DELAY); - - srand(time(NULL)); - -#ifdef BUILD_TESTS - apply_test_board(g, TSPIN_NO_LINES); -#endif - - memset(g, 0, sizeof(cetris_game)); - - g->level = CETRIS_STARTING_LEVEL; - - init_piece_queue(g); - shuffle_queue(g); - - next_piece(g); -} - -void init_piece_queue(cetris_game* g) { - for (u8 i = 0; i < 7; i++) { - g->piece_queue[i].t = i; - g->piece_queue[i].c = i + 1; - memcpy(g->piece_queue[i].m, default_matrices[i], sizeof(piece_matrix)); - g->piece_queue[i].r = INIT; - g->piece_queue[i].lock_tick = 0; - g->piece_queue[i].locked = false; - g->piece_queue[i].ghost_y = 0; - - /* Pieces should spawn so that on the first down - * tick the bottom row will show. Values here are adjusted - * for the default 4x4 matricies for each piece */ - g->piece_queue[i].pos.x = 3; - g->piece_queue[i].pos.y = (i == I) ? 17 : 16; - } -} - -void shuffle_queue(cetris_game* g) { - for (u8 i = 0; i < 7; i++) { - tetrimino t = g->piece_queue[i]; - u8 rand_index = rand() % 7; - g->piece_queue[i] = g->piece_queue[rand_index]; - g->piece_queue[rand_index] = t; - } -} - -void update_game_tick(cetris_game* g) { - if (g->game_over) return; - - g->tick++; - - if (g->next_piece_tick && g->tick >= g->next_piece_tick) { - next_piece(g); - } - - if (g->next_piece_tick) return; - - bool did_move = false; - if (g->tick >= g->next_drop_tick || !g->next_drop_tick) { - if (g->next_drop_tick) { - move_current(g, DOWN); - did_move = true; - } - - if (g->level <= 20) { - g->next_drop_tick = g->tick + level_drop_delay[g->level - 1]; - } else { - g->next_drop_tick = g->tick + level_drop_delay[19]; - } - } - - /* lock piece if it was hovering for CETRIS_LOCK_DELAY */ - 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) { - lock_current(g); - did_move = true; - } - g->current.pos.y--; - g->current.lock_tick = 0; - } - - if (handle_inputs(g)) { - did_move = true; - } - - if (did_move) update_board(g); -} - -void next_piece(cetris_game* g) { - g->next_drop_tick = 0; - g->next_piece_tick = 0; - - g->current = g->piece_queue[g->current_index]; - if (check_matrix(g, &g->current.m) <= 0) { - g->game_over = true; - } - g->current_index++; - - if (!g->game_over) { - move_current(g, DOWN); - } - - if (g->current_index >= 7) { - g->current_index = 0; - shuffle_queue(g); - } - - update_board(g); -} - -void lock_current(cetris_game* g) { - g->current.locked = true; - for (u8 x = 0; x < CETRIS_BOARD_X; x++) { - for (u8 y = 0; y < CETRIS_BOARD_Y; y++) { - if (g->board[x][y].occupied) g->board[x][y].constant = 1; - } - } - update_board(g); -} - -void make_ghosts(cetris_game* g) { - u8 orig_y = g->current.pos.y; - while (true) { - g->current.pos.y++; - if (check_matrix(g, &g->current.m) <= 0) { - g->current.ghost_y = g->current.pos.y - 1; - g->current.pos.y = orig_y; - break; - } - } -} - -void update_board(cetris_game* g) { - if (g->game_over) return; - - u8 lines_cleared = 0; - for (u8 y = 0; y < CETRIS_BOARD_Y; y++) { - bool clear_line = true; - for (u8 x = 0; x < CETRIS_BOARD_X; x++) { - if (!g->board[x][y].constant) { - memset(&g->board[x][y], 0, sizeof(slot)); - } - - if (!g->board[x][y].occupied || g->board[0][y].remove_tick > 0) { - clear_line = false; - } - } - // remove tick only tracked on first block of line - if (g->board[0][y].remove_tick && g->board[0][y].remove_tick <= g->tick) { - for (i8 s = y - 1; s >= 0; s--) { - for (u8 x = 0; x < CETRIS_BOARD_X; x++) { - g->board[x][s + 1] = g->board[x][s]; - } - } - } - if (clear_line) { - g->board[0][y].remove_tick = g->tick + CETRIS_LINE_CLEAR_DELAY; - lines_cleared++; - } - } - - make_ghosts(g); - set_matrix(g, &g->current.m); - - assert(lines_cleared <= 4); - - if (g->current.locked && !g->next_piece_tick) { - if (lines_cleared > 0) { - g->next_piece_tick = g->tick + CETRIS_NEXT_PIECE_DELAY; - } else { - next_piece(g); - } - } - - if (lines_cleared > 0 || g->tspin || g->mini_tspin) { - add_score(g, lines_cleared); - if (lines_cleared > 0) { - g->lines += lines_cleared; - if (g->lines >= (g->level * 10)) g->level++; - } - } -} - -/* SCORE FUNCTIONS */ - -void add_score(cetris_game* g, u8 lines) { - if (!g->tspin && !g->mini_tspin) { - switch (lines) { - case 1: g->score += 100 * g->level; break; - case 2: g->score += 300 * g->level; break; - case 3: g->score += 500 * g->level; break; - case 4: g->score += 800 * g->level; break; - } - } else if (g->tspin) { - switch (lines) { - case 0: g->score += 400 * g->level; break; - case 1: g->score += 800 * g->level; break; - case 2: g->score += 1200 * g->level; break; - case 3: g->score += 1600 * g->level; break; - } - g->tspin = false; - } else if (g->mini_tspin) { - switch (lines) { - case 0: g->score += 100 * g->level; break; - case 1: g->score += 200 * g->level; break; - case 2: g->score += 400 * g->level; break; - } - g->mini_tspin = false; - } -} - -/* MOVEMENT FUNCTIONS */ - -void move_piece(cetris_game* g, input_t move, bool hold) { - if (!g->held_moves[move]) { - switch (move) { - case LEFT: - case RIGHT: - case DOWN: - case USER_DOWN: - move_current(g, move); - break; - case HARD_DROP: - hard_drop(g); - break; - case ROTATE_CW: - rotate_matrix(g, 1); - break; - case ROTATE_CCW: - rotate_matrix(g, 0); - break; - } - } - if (hold) g->held_moves[move] = true; -} - -void stop_holding(cetris_game* g, input_t move) { - g->held_moves[move] = false; - if (move == RIGHT || move == LEFT) { - g->das_move_tick = 0; - g->das_repeat = 0; - } else if (move == USER_DOWN) g->down_move_tick = 0; -} - -void reset_tetrimino(tetrimino* t) { - t->r = INIT; - t->pos.x = 3; - t->pos.y = (t->t == I) ? 17 : 16; - t->ghost_y = 0; -} - -void hold_piece(cetris_game* g) { - if (g->piece_held) { - tetrimino tmp = g->current; - g->current = g->held; - g->held = tmp; - } else { - g->held = g->current; - reset_tetrimino(&g->held); - g->piece_held = true; - next_piece(g); - } - update_board(g); -} - - diff --git a/core/src/input.c b/core/src/input.c deleted file mode 100644 index 65dead1..0000000 --- a/core/src/input.c +++ /dev/null @@ -1,51 +0,0 @@ -#include - -#include "input.h" - -#include "types.h" -#include "matrix.h" -#include "cetris.h" - -bool handle_inputs(cetris_game* g) { - if ((g->held_moves[RIGHT] || g->held_moves[LEFT]) && !g->das_move_tick) { - if (g->das_repeat == 0) { - g->das_move_tick = g->tick + CETRIS_DAS_DELAY; - } else if (g->das_repeat > 0) { - g->das_move_tick = g->tick + CETRIS_DAS_PERIOD; - } - } - - if (g->held_moves[USER_DOWN] && !g->down_move_tick) { - g->down_move_tick = g->tick + CETRIS_DROP_PERIOD; - } - - bool did_move = false; - if (g->das_move_tick && g->tick >= g->das_move_tick) { - if (g->held_moves[RIGHT]) { - if (g->prev_das_move == RIGHT || g->das_repeat == 0) g->das_repeat++; - else g->das_repeat = 0; - move_current(g, RIGHT); - g->prev_das_move = RIGHT; - } - - if (g->held_moves[LEFT]) { - if (g->prev_das_move == LEFT || g->das_repeat == 0) g->das_repeat++; - else g->das_repeat = 0; - move_current(g, LEFT); - g->prev_das_move = LEFT; - } - - g->das_move_tick = 0; - did_move = true; - } - - if (g->down_move_tick && g->tick >= g->down_move_tick) { - if (g->held_moves[USER_DOWN]) { - move_current(g, USER_DOWN); - did_move = true; - } - - g->down_move_tick = 0; - } - return did_move; -} diff --git a/core/src/matrix.c b/core/src/matrix.c deleted file mode 100644 index d4597a7..0000000 --- a/core/src/matrix.c +++ /dev/null @@ -1,278 +0,0 @@ -#include - -#include "matrix.h" -#include "types.h" -#include "cetris.h" - -/* SRS WALL KICK VALUES */ - -// https://tetris.wiki/SRS -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] = { - { {0, 0}, {-2, 0}, {1, 0}, {-2,-1}, {1,2} }, // 0->R - { {0, 0}, {2, 0}, {-1, 0}, {2,1}, {-1,-2} }, // R->0 - { {0, 0}, {-1, 0}, {2, 0}, {-1,2}, {2,-1} }, // R->2 - { {0, 0}, {1, 0}, {-2, 0}, {1,-2}, {-2,1} }, // 2->R - { {0, 0}, {2, 0}, {-1, 0}, {2,1}, {-1,-2} }, // 2->L - { {0, 0}, {-2, 0}, {1, 0}, {-2,-1}, {1,2} }, // L->2 - { {0, 0}, {1, 0}, {-2, 0}, {1,-2}, {-2,1} }, // L->0 - { {0, 0}, {-1, 0}, {2, 0}, {-1,2}, {2,-1} } // 0->L -}; - -/* DEFAULT MATRIX FOR EACH POSSIBLE TETRIMINO */ - -const piece_matrix default_matrices[7] = { - { - { 0, 0, 0, 0 }, - { 0, 1, 1, 0 }, - { 0, 1, 1, 0 }, - { 0, 0, 0, 0 } - }, - - { - { 0, 0, 0, 0 }, - { 1, 1, 1, 1 }, - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 } - }, - - { - { 0, 0, 0, 0 }, - { 0, 1, 1, 0 }, - { 1, 1, 0, 0 }, - { 0, 0, 0, 0 } - }, - - { - { 0, 0, 0, 0 }, - { 1, 1, 0, 0 }, - { 0, 1, 1, 0 }, - { 0, 0, 0, 0 } - }, - - { - { 0, 0, 0, 0 }, - { 0, 0, 1, 0 }, - { 1, 1, 1, 0 }, - { 0, 0, 0, 0 } - }, - - { - { 0, 0, 0, 0 }, - { 1, 0, 0, 0 }, - { 1, 1, 1, 0 }, - { 0, 0, 0, 0 } - }, - - { - { 0, 0, 0, 0 }, - { 0, 1, 0, 0 }, - { 1, 1, 1, 0 }, - { 0, 0, 0, 0 } - } -}; - -/* MATRIX MODIFICATION */ - -const vec2 basic_movements[5] = { - {0, 0}, {0, 1}, {0, 1}, {1, 0}, {-1, 0} // NONE, DOWN, USER_DOWN, RIGHT, LEFT -}; - -void move_current(cetris_game* g, input_t move) { - if (g->game_over || g->next_piece_tick) return; - - g->current.pos.y += basic_movements[move].y; - g->current.pos.x += basic_movements[move].x; - - i8 check = check_matrix(g, &g->current.m); - if (check <= 0) { - g->current.pos.y -= basic_movements[move].y; - g->current.pos.x -= basic_movements[move].x; - - if (move == USER_DOWN) g->score++; - if (move == DOWN && check == -1 && !g->current.lock_tick) { - g->current.lock_tick = g->tick + CETRIS_LOCK_DELAY; - } - } - - update_board(g); -} - -i8 check_matrix(cetris_game* g, piece_matrix* m) { - for (i8 y = 0; y < 4; y++) { - for (i8 x = 0; x < 4; x++) { - vec2 r = (vec2){x + g->current.pos.x, y + g->current.pos.y}; - if (r.y < 0) continue; - if ((*m)[y][x]) { - if (r.x >= CETRIS_BOARD_X || r.x < 0) return 0; - if (r.y >= CETRIS_BOARD_Y) return -1; - if (g->board[r.x][r.y].occupied && - g->board[r.x][r.y].constant) return -1; - } - } - } - return 1; -} - -void set_matrix(cetris_game* g, piece_matrix* m) { - for (i8 y = 0; y < 4; y++) { - for (i8 x = 0; x < 4; x++) { - vec2 r = (vec2){x + g->current.pos.x, y + g->current.pos.y}; - if ((*m)[y][x]) { - if (r.y >= 0) { - g->board[r.x][r.y].occupied = true; - g->board[r.x][r.y].c = g->current.c; - } - if (g->current.ghost_y + y >= 0) { - if (r.y != (g->current.ghost_y + y)) { - g->board[r.x][g->current.ghost_y + y].ghost = true; - } - } - } - } - } -} - -void hard_drop(cetris_game* g) { - if (g->game_over || g->next_piece_tick) return; - - bool drop = false; - u8 drop_count = 0; - while (!drop) { - g->current.pos.y++; - drop_count++; - if (check_matrix(g, &g->current.m) <= 0) { - g->current.pos.y--; - drop_count--; - drop = true; - } - } - - g->score += 2 * drop_count; // 2 score for each hard-drop'd cell - - update_board(g); - lock_current(g); -} - -void rotate_matrix(cetris_game* g, bool clockwise) { - if (g->game_over || g->next_piece_tick) return; - if (g->current.t == O) return; - - rstate next = 0; - u8 wall_kick = 0; - switch (g->current.r) { - case INIT: - if (clockwise) { - next = ONCE_RIGHT; - wall_kick = 0; - } else { - next = ONCE_LEFT; - wall_kick = 7; - } break; - case ONCE_RIGHT: - if (clockwise) { - next = TWICE; - wall_kick = 2; - } else { - next = INIT; - wall_kick = 1; - } break; - case ONCE_LEFT: - if (clockwise) { - next = INIT; - wall_kick = 6; - } else { - next = TWICE; - wall_kick = 5; - } break; - case TWICE: - if (clockwise) { - next = ONCE_LEFT; - wall_kick = 4; - } else { - next = ONCE_RIGHT; - wall_kick = 3; - } break; - } - - piece_matrix m; - memset(m, 0, sizeof(piece_matrix)); - - for (u8 x = 0; x < 4; x++) { - for (u8 y = 0; y < 4; y++) { - if (g->current.m[y][x]) { - u8 new_x = (clockwise) ? 1 - (y - 2) : 1 + (y - 2); - u8 new_y = (clockwise) ? 2 + (x - 1) : 2 - (x - 1); - - if (g->current.t == I) { - if (clockwise) { - new_y--; - } else { - new_x++; - } - } - - m[new_y][new_x] = 1; - } - } - } - - vec2 kick; - bool set_current = false; - bool did_kick = false; - for (u8 i = 0; i < 5; i++) { - if (g->current.t == 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; - - if (check_matrix(g, &m) > 0) { - set_current = true; - if (i > 0) did_kick = true; - break; - } else { - g->current.pos.x -= kick.x; - g->current.pos.y -= kick.y; - } - } - - if (set_current) { - - /* check for tspin */ - if (g->current.t == T) { - bool did_tspin = true; - for (u8 i = 1; i < 5; i++) { - g->current.pos.x += basic_movements[i].x; - g->current.pos.y += basic_movements[i].y; - - if (check_matrix(g, &m) == 1) did_tspin = false; - - g->current.pos.x -= basic_movements[i].x; - g->current.pos.y -= basic_movements[i].y; - } - - if (did_tspin) { - if (did_kick) g->mini_tspin = true; - else g->tspin = true; - } - } - - g->current.r = next; - memcpy(g->current.m, m, sizeof(piece_matrix)); - update_board(g); - } -} diff --git a/core/src/test.c b/core/src/test.c deleted file mode 100644 index bad50d8..0000000 --- a/core/src/test.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "test.h" -#include "cetris.h" - -u8 tspin_board[20][10] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 }, - { 1, 1, 1, 0, 0, 0, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 }, - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } -}; - -u8 tspin_no_lines_board[20][10] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 1, 0, 0, 1, 1, 1, 0 }, - { 1, 1, 1, 0, 0, 0, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 }, - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 } -}; - -void apply_test_board(cetris_game* g, test t) { - u8 (*board)[20][10]; - switch (t) { - case TSPIN: - board = &tspin_board; - break; - case TSPIN_NO_LINES: - board = &tspin_no_lines_board; - break; - default: - return; - } - for (u8 y = 0; y < CETRIS_BOARD_Y; y++) { - for (u8 x = 0; x < 10; x++) { - if ((*board)[y][x]) { - g->board[x][y].occupied = 1; - g->board[x][y].constant = 1; - g->board[x][y].c = COLOR_I; - } - } - } -} - -- cgit v1.2.3-101-g0448