From 8d0df8b04ed1a12f234091adad65992f46664ad5 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 4 Sep 2019 14:46:12 -0400 Subject: cleanup core and do a bit on opengl --- core/cetris.c | 134 +++++-------------------------------------- core/cetris.h | 7 +-- core/matrix.c | 110 +++++++++++++++++++++++++++++++++++ core/matrix.h | 9 +++ core/meson.build | 2 +- core/types.h | 14 +++-- frontends/curses/curses_ui.c | 1 + frontends/gl/main.c | 30 ++++++++-- 8 files changed, 174 insertions(+), 133 deletions(-) create mode 100644 core/matrix.c create mode 100644 core/matrix.h diff --git a/core/cetris.c b/core/cetris.c index 5387ff1..0ae1517 100644 --- a/core/cetris.c +++ b/core/cetris.c @@ -5,6 +5,8 @@ #include #include "cetris.h" +#include "types.h" +#include "matrix.h" #ifdef BUILD_TESTS #include "test.h" @@ -17,15 +19,10 @@ static void update_board(cetris_game* g); static void lock_current(cetris_game* g); static void move_current(cetris_game* g, input_t move); static void hard_drop(cetris_game* g); -static void rotate_matrix(cetris_game* g, bool clockwise); -static void set_matrix(cetris_game* g, piece_matrix* m); -static i8 check_matrix(cetris_game* g, piece_matrix* m); +static void rotate_piece(cetris_game* g, bool clockwise); static void init_piece_queue(cetris_game* g); static void shuffle_queue(cetris_game* g); -static void next_piece(cetris_game* g); -static void lock_current(cetris_game* g); static void make_ghosts(cetris_game* g); -static void update_board(cetris_game* g); static void add_score(cetris_game* g, u8 lines); static void reset_tetrimino(tetrimino* t); @@ -54,59 +51,6 @@ static const vec2 srs_wall_kicks_i[8][5] = { { {0, 0}, {-1, 0}, {2, 0}, {-1,2}, {2,-1} } // 0->L }; -/* DEFAULT MATRIX FOR EACH POSSIBLE TETRIMINO */ - -static 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 } - } -}; - static const vec2 basic_movements[5] = { {0, 0}, {0, 1}, {0, 1}, {1, 0}, {-1, 0} // NONE, DOWN, USER_DOWN, RIGHT, LEFT }; @@ -267,7 +211,7 @@ void update_board(cetris_game* g) { } // 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 (s8 s = y - 1; s >= 0; s--) { for (u8 x = 0; x < CETRIS_BOARD_X; x++) { g->board[x][s + 1] = g->board[x][s]; } @@ -343,10 +287,10 @@ void move_piece(cetris_game* g, input_t move) { hard_drop(g); break; case ROTATE_CW: - rotate_matrix(g, 1); + rotate_piece(g, 1); break; case ROTATE_CCW: - rotate_matrix(g, 0); + rotate_piece(g, 0); break; } } @@ -378,65 +322,34 @@ void move_current(cetris_game* g, input_t move) { g->current.pos.y += basic_movements[move].y; g->current.pos.x += basic_movements[move].x; - i8 check = check_matrix(g, &g->current.m); + s8 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; } + } else { + if (move == USER_DOWN) g->score++; + if ((move == DOWN) | (move == USER_DOWN)) + g->current.lock_tick = 0; } 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) { + while (true) { g->current.pos.y++; drop_count++; if (check_matrix(g, &g->current.m) <= 0) { g->current.pos.y--; drop_count--; - drop = true; + break; } } @@ -446,7 +359,7 @@ void hard_drop(cetris_game* g) { lock_current(g); } -void rotate_matrix(cetris_game* g, bool clockwise) { +void rotate_piece(cetris_game* g, bool clockwise) { if (g->game_over || g->next_piece_tick) return; if (g->current.t == O) return; @@ -490,24 +403,7 @@ void rotate_matrix(cetris_game* g, bool clockwise) { 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; - } - } - } + rotate_matrix(g, &m, clockwise); vec2 kick; bool set_current = false; diff --git a/core/cetris.h b/core/cetris.h index 0232e4a..5c5a391 100644 --- a/core/cetris.h +++ b/core/cetris.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include "types.h" @@ -18,9 +17,7 @@ #define CETRIS_LOCK_DELAY 30 #define CETRIS_WAIT_ON_CLEAR 0 -#define CETRIS_STARTING_LEVEL 1 - -typedef u8 piece_matrix[4][4]; +#define CETRIS_STARTING_LEVEL 11 typedef enum { O, I, S, Z, L, J, T @@ -49,7 +46,7 @@ typedef struct { rstate r; color c; piece_matrix m; - i8 ghost_y; + s8 ghost_y; vec2 pos; u32 lock_tick; bool locked; diff --git a/core/matrix.c b/core/matrix.c new file mode 100644 index 0000000..ba32bfb --- /dev/null +++ b/core/matrix.c @@ -0,0 +1,110 @@ +#include + +#include "types.h" +#include "cetris.h" +#include "matrix.h" + +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 } + } +}; + +s8 check_matrix(cetris_game* g, piece_matrix* m) { + for (s8 y = 0; y < 4; y++) { + for (s8 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 (s8 y = 0; y < 4; y++) { + for (s8 x = 0; x < 4; x++) { + if ((*m)[y][x]) { + vec2 r = (vec2){x + g->current.pos.x, + y + g->current.pos.y}; + if (r.y >= 0) { + if (!g->board[r.x][r.y].occupied) { + 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 rotate_matrix(cetris_game* g, piece_matrix* m, bool clockwise) { + 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; + } + } + } +} diff --git a/core/matrix.h b/core/matrix.h new file mode 100644 index 0000000..6994b36 --- /dev/null +++ b/core/matrix.h @@ -0,0 +1,9 @@ +#pragma once + +#include "types.h" +#include "cetris.h" + +extern piece_matrix default_matrices[7]; +s8 check_matrix(cetris_game* g, piece_matrix* m); +void set_matrix(cetris_game* g, piece_matrix* m); +void rotate_matrix(cetris_game* g, piece_matrix* m, bool clockwise); diff --git a/core/meson.build b/core/meson.build index 92f20c5..ea8d15a 100644 --- a/core/meson.build +++ b/core/meson.build @@ -1,4 +1,4 @@ -src = ['cetris.c'] +src = ['cetris.c', 'matrix.c'] if get_option('debug') == true src += 'test.c' diff --git a/core/types.h b/core/types.h index cf36792..f123da3 100644 --- a/core/types.h +++ b/core/types.h @@ -1,10 +1,16 @@ +#pragma once + +#include + #define u8 uint8_t #define u32 uint32_t #define u64 uint64_t -#define i8 int8_t -#define i32 int32_t +#define s8 int8_t +#define s32 int32_t typedef struct { - i8 x; - i8 y; + s8 x; + s8 y; } vec2; + +typedef u8 piece_matrix[4][4]; diff --git a/frontends/curses/curses_ui.c b/frontends/curses/curses_ui.c index 8456438..5776af3 100644 --- a/frontends/curses/curses_ui.c +++ b/frontends/curses/curses_ui.c @@ -5,6 +5,7 @@ #include #include +#include #include #ifdef _WIN32 #include "win\curses.h" diff --git a/frontends/gl/main.c b/frontends/gl/main.c index 87cbd19..40a7b4a 100644 --- a/frontends/gl/main.c +++ b/frontends/gl/main.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -8,6 +9,8 @@ #include "cetris.h" +static cetris_game cetris; + const char *vertex_shader_source = "#version 450 core\n" "layout (location = 0) in vec3 aPos;\n" "layout (location = 1) in vec3 aColor;\n" @@ -75,9 +78,24 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } -void process_input(GLFWwindow *window) { - if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) +void input_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, 1); + + if (key == GLFW_KEY_D && action == GLFW_PRESS) + move_piece(&cetris, RIGHT); + + if (key == GLFW_KEY_S && action == GLFW_PRESS) + move_piece(&cetris, USER_DOWN); + + if (key == GLFW_KEY_A && action == GLFW_PRESS) + move_piece(&cetris, LEFT); + + if (key == GLFW_KEY_W && action == GLFW_PRESS) + move_piece(&cetris, ROTATE_CW); + + if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) + move_piece(&cetris, HARD_DROP); } void load_texture(char *file_name, GLuint texture) { @@ -153,6 +171,9 @@ void update_block(drawable *b, int x, int y, int color) { GLfloat block[32]; memcpy(block, default_rect, sizeof(GLfloat) * 32); + x = x - 6; + y = y - 20; + block[0] = block[8] = (x + 1.0f) / 10.0f; block[1] = block[25] = (((y) * -1.0f) + 1.0f) / 20.0f; block[9] = block[17] = block[1] - .05f; @@ -203,13 +224,14 @@ int main(void) { - cetris_game cetris; init_game(&cetris); double prev_time = glfwGetTime(); + glfwSetKeyCallback(window, input_callback); + while(!glfwWindowShouldClose(window)) { - process_input(window); + //process_input(window); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); -- cgit v1.2.3-101-g0448