diff options
| author | 2019-04-14 20:10:23 -0400 | |
|---|---|---|
| committer | 2019-04-14 20:10:23 -0400 | |
| commit | 4477c1db42b579a441bf0a62bed2f627176f1c76 (patch) | |
| tree | e6960d29717ddecd45c88fa7ec510e644eecfda8 /core | |
| parent | 2e59a5b0a8e8b70f30d44de7d14e53c800e19914 (diff) | |
| download | cetris-4477c1db42b579a441bf0a62bed2f627176f1c76.tar.gz cetris-4477c1db42b579a441bf0a62bed2f627176f1c76.tar.bz2 cetris-4477c1db42b579a441bf0a62bed2f627176f1c76.zip | |
add next piece delay for when a line is cleared + cleanup
Diffstat (limited to 'core')
| -rw-r--r-- | core/include/cetris.h | 35 | ||||
| -rw-r--r-- | core/include/input.h | 6 | ||||
| -rw-r--r-- | core/include/matrix.h | 10 | ||||
| -rw-r--r-- | core/include/test.h | 8 | ||||
| -rw-r--r-- | core/src/cetris.c | 105 | ||||
| -rw-r--r-- | core/src/input.c | 2 | ||||
| -rw-r--r-- | core/src/matrix.c | 31 | ||||
| -rw-r--r-- | core/src/test.c | 2 |
8 files changed, 111 insertions, 88 deletions
diff --git a/core/include/cetris.h b/core/include/cetris.h index 9e3cf83..1606f2a 100644 --- a/core/include/cetris.h +++ b/core/include/cetris.h @@ -10,16 +10,18 @@ #define CETRIS_INITIAL_X 3
#define CETRIS_INITIAL_Y 0
#define CETRIS_INITIAL_Y_OFFSET 2
-//#define CETRIS_BOARD_VISABLE 21
#define CETRIS_HZ 60
#define CETRIS_DAS_DELAY 11
#define CETRIS_DAS_PERIOD 3
#define CETRIS_DROP_PERIOD 2
+#define CETRIS_NEXT_PIECE_DELAY 40
#define CETRIS_LINE_CLEAR_DELAY 40
#define CETRIS_LOCK_DELAY 40
#define CETRIS_WAIT_ON_CLEAR 0
+#define CETRIS_STARTING_LEVEL 1
+
typedef enum {
O, I, S, Z, L, J, T
} type;
@@ -42,15 +44,16 @@ typedef enum { TWICE
} rstate;
-struct tetrimino {
+typedef struct {
type t;
rstate r;
color c;
piece_matrix m;
- u8 ghost_y;
+ i8 ghost_y;
vec2 pos;
u32 lock_tick;
-};
+ bool locked;
+} tetrimino;
typedef struct {
bool occupied;
@@ -60,15 +63,15 @@ typedef struct { color c;
} slot;
-struct cetris_game {
+typedef struct {
/* playfield represented by a 2d array */
slot board[CETRIS_BOARD_X][CETRIS_BOARD_Y];
/* constant queue of all 7 possible tetrimino */
- struct tetrimino piece_queue[7];
+ tetrimino piece_queue[7];
/* current tetrimino */
- struct tetrimino current;
+ tetrimino current;
u8 current_index;
/* input_manager */
@@ -81,6 +84,7 @@ struct cetris_game { /* internal game tick */
u32 tick;
u32 next_drop_tick;
+ u32 next_piece_tick;
/* progress trackers */
u32 lines;
@@ -92,15 +96,16 @@ struct cetris_game { bool mini_tspin;
/* score counter */
- u64 score;
-};
+ u32 score;
+} cetris_game;
-void next_piece(struct cetris_game* g);
-void update_board(struct cetris_game* g);
+void next_piece(cetris_game* g);
+void update_board(cetris_game* g);
+void lock_current(cetris_game* g);
/* API PROTOTYPES FUNCTIONS */
-void init_game(struct cetris_game* g);
-void update_game_tick(struct cetris_game* g);
-void move_piece(struct cetris_game* g, input_t move);
-void stop_holding(struct cetris_game* g, input_t move);
+void init_game(cetris_game* g);
+void update_game_tick(cetris_game* g);
+void move_piece(cetris_game* g, input_t move);
+void stop_holding(cetris_game* g, input_t move);
diff --git a/core/include/input.h b/core/include/input.h index 3cfa947..95cb2aa 100644 --- a/core/include/input.h +++ b/core/include/input.h @@ -3,7 +3,7 @@ #include <stdint.h>
#include <stdbool.h>
-struct cetris_game;
+#include "cetris.h"
-bool handle_inputs(struct cetris_game* g);
-void clear_held_key(struct cetris_game* g);
+bool handle_inputs(cetris_game *g);
+void clear_held_key(cetris_game *g);
diff --git a/core/include/matrix.h b/core/include/matrix.h index 050a32e..eb9e272 100644 --- a/core/include/matrix.h +++ b/core/include/matrix.h @@ -7,8 +7,8 @@ extern const piece_matrix default_matrices[7];
-void move_current(struct cetris_game* g, input_t move);
-void hard_drop(struct cetris_game* g);
-void rotate_matrix(struct cetris_game* g, bool clockwise);
-void set_matrix(struct cetris_game* g, piece_matrix *m);
-i8 check_matrix(struct cetris_game* g, piece_matrix *m);
+void move_current(cetris_game* g, input_t move);
+void hard_drop(cetris_game* g);
+void rotate_matrix(cetris_game* g, bool clockwise);
+void set_matrix(cetris_game* g, piece_matrix* m);
+i8 check_matrix(cetris_game* g, piece_matrix* m);
diff --git a/core/include/test.h b/core/include/test.h index d700627..4b8622e 100644 --- a/core/include/test.h +++ b/core/include/test.h @@ -1,8 +1,8 @@ -struct cetris_game;
+#include "cetris.h"
-enum tests {
+typedef enum {
TSPIN,
TSPIN_NO_LINES
-};
+} test;
-void apply_test_board(struct cetris_game* g, enum tests t);
+void apply_test_board( cetris_game* g, test t);
diff --git a/core/src/cetris.c b/core/src/cetris.c index a3f2ded..4e404d6 100644 --- a/core/src/cetris.c +++ b/core/src/cetris.c @@ -1,4 +1,3 @@ -#include <locale.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
@@ -16,10 +15,9 @@ /* FUNCTION PROTOTYPES */
-static void init_piece_queue(struct cetris_game* g);
-static void shuffle_queue(struct cetris_game* g);
-static void set_constants(struct cetris_game* g);
-static void add_score(struct cetris_game* g, u8 lines);
+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 */
@@ -29,34 +27,20 @@ static const u32 level_drop_delay[20] = { /* GAME FUNCTIONS */
-void init_game(struct cetris_game* g) {
- srand(time(NULL));
+void init_game(cetris_game* g) {
+
+ /* check for config errors */
+ assert(CETRIS_NEXT_PIECE_DELAY >= CETRIS_LINE_CLEAR_DELAY);
- memset(g->board, 0, sizeof(slot) * CETRIS_BOARD_X * CETRIS_BOARD_Y);
+ srand(time(NULL));
#ifdef BUILD_TESTS
apply_test_board(g, TSPIN_NO_LINES);
#endif
- g->tick = 0;
- g->next_drop_tick = level_drop_delay[0];
-
- g->current_index = 0;
+ memset(g, 0, sizeof(cetris_game));
- memset(g->held_moves, 0, sizeof(bool) * 7);
- g->das_repeat = 0;
- g->prev_das_move = 0;
- g->das_move_tick = 0;
- g->down_move_tick = 0;
-
- g->lines = 0;
- g->level = 1;
- g->game_over = false;
-
- g->tspin = false;
- g->mini_tspin = false;
-
- g->score = 0;
+ g->level = CETRIS_STARTING_LEVEL;
init_piece_queue(g);
shuffle_queue(g);
@@ -64,34 +48,46 @@ void init_game(struct cetris_game* g) { next_piece(g);
}
-void init_piece_queue(struct cetris_game* 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].pos = (vec2){CETRIS_INITIAL_X, CETRIS_INITIAL_Y - CETRIS_INITIAL_Y_OFFSET};
+ g->piece_queue[i].locked = false;
g->piece_queue[i].ghost_y = 0;
+ g->piece_queue[i].pos = (vec2){CETRIS_INITIAL_X, CETRIS_INITIAL_Y - CETRIS_INITIAL_Y_OFFSET};
}
}
-void shuffle_queue(struct cetris_game* g) {
+void shuffle_queue(cetris_game* g) {
for (u8 i = 0; i < 7; i++) {
- struct tetrimino t = g->piece_queue[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(struct cetris_game* g) {
+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->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 {
@@ -100,10 +96,11 @@ void update_game_tick(struct cetris_game* g) { }
/* lock piece if it was hovering for CETRIS_LOCK_DELAY */
- if (g->current.lock_tick && g->current.lock_tick <= g->tick) {
+ 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) {
- next_piece(g);
+ lock_current(g);
+ did_move = true;
}
g->current.pos.y--;
g->current.lock_tick = 0;
@@ -114,14 +111,11 @@ void update_game_tick(struct cetris_game* g) { }
if (did_move) update_board(g);
-
- g->tick++;
}
-void next_piece(struct cetris_game* g) {
- set_constants(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) {
@@ -133,17 +127,21 @@ void next_piece(struct cetris_game* g) { g->current_index = 0;
shuffle_queue(g);
}
+
+ update_board(g);
}
-void set_constants(struct cetris_game* 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(struct cetris_game* g) {
+void make_ghosts(cetris_game* g) {
u8 orig_y = g->current.pos.y;
while (true) {
g->current.pos.y++;
@@ -155,7 +153,9 @@ void make_ghosts(struct cetris_game* g) { }
}
-void update_board(struct cetris_game* g) {
+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;
@@ -175,15 +175,26 @@ void update_board(struct cetris_game* g) { 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++;
}
- if (clear_line) g->board[0][y].remove_tick = g->tick + CETRIS_LINE_CLEAR_DELAY;
}
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) {
@@ -195,7 +206,7 @@ void update_board(struct cetris_game* g) { /* SCORE FUNCTIONS */
-void add_score(struct cetris_game* g, u8 lines) {
+void add_score(cetris_game* g, u8 lines) {
if (!g->tspin && !g->mini_tspin) {
switch (lines) {
case 1: g->score += 100 * g->level; break;
@@ -223,7 +234,7 @@ void add_score(struct cetris_game* g, u8 lines) { /* MOVEMENT FUNCTIONS */
-void move_piece(struct cetris_game* g, input_t move) {
+void move_piece(cetris_game* g, input_t move) {
if (!g->held_moves[move]) {
switch (move) {
case LEFT:
@@ -246,7 +257,7 @@ void move_piece(struct cetris_game* g, input_t move) { g->held_moves[move] = true;
}
-void stop_holding(struct cetris_game* g, input_t move) {
+void stop_holding(cetris_game* g, input_t move) {
g->held_moves[move] = false;
if (move == RIGHT || move == LEFT) {
g->das_move_tick = 0;
diff --git a/core/src/input.c b/core/src/input.c index 2904158..65dead1 100644 --- a/core/src/input.c +++ b/core/src/input.c @@ -6,7 +6,7 @@ #include "matrix.h"
#include "cetris.h"
-bool handle_inputs(struct cetris_game* g) {
+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;
diff --git a/core/src/matrix.c b/core/src/matrix.c index 86e9ad2..caae107 100644 --- a/core/src/matrix.c +++ b/core/src/matrix.c @@ -88,8 +88,8 @@ const vec2 basic_movements[5] = { {0, 0}, {0, 1}, {0, 1}, {1, 0}, {-1, 0} // NONE, DOWN, USER_DOWN, RIGHT, LEFT
};
-void move_current(struct cetris_game* g, input_t move) {
- if (g->game_over) return;
+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;
@@ -108,7 +108,7 @@ void move_current(struct cetris_game* g, input_t move) { update_board(g);
}
-i8 check_matrix(struct cetris_game* g, piece_matrix *m) {
+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};
@@ -124,7 +124,7 @@ i8 check_matrix(struct cetris_game* g, piece_matrix *m) { return 1;
}
-void set_matrix(struct cetris_game *g, piece_matrix *m) {
+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};
@@ -134,15 +134,17 @@ void set_matrix(struct cetris_game *g, piece_matrix *m) { g->board[r.x][r.y].c = g->current.c;
}
if (g->current.ghost_y + y >= 0) {
- g->board[r.x][g->current.ghost_y + y].ghost = true;
+ if (r.y != (g->current.ghost_y + y)) {
+ g->board[r.x][g->current.ghost_y + y].ghost = true;
+ }
}
}
}
}
}
-void hard_drop(struct cetris_game* g) {
- if (g->game_over) return;
+void hard_drop(cetris_game* g) {
+ if (g->game_over || g->next_piece_tick) return;
bool drop = false;
u8 drop_count = 0;
@@ -159,11 +161,11 @@ void hard_drop(struct cetris_game* g) { g->score += 2 * drop_count; // 2 score for each hard-drop'd cell
update_board(g);
- next_piece(g);
+ lock_current(g);
}
-void rotate_matrix(struct cetris_game* g, bool clockwise) {
- if (g->game_over) return;
+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;
@@ -213,8 +215,11 @@ void rotate_matrix(struct cetris_game* g, bool clockwise) { u8 new_y = (clockwise) ? 2 + (x - 1) : 2 - (x - 1);
if (g->current.t == I) {
- if (clockwise) new_y--;
- else new_x++;
+ if (clockwise) {
+ new_y--;
+ } else {
+ new_x++;
+ }
}
m[new_y][new_x] = 1;
@@ -231,8 +236,10 @@ void rotate_matrix(struct cetris_game* g, bool clockwise) { } 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;
diff --git a/core/src/test.c b/core/src/test.c index 7db2fe5..bad50d8 100644 --- a/core/src/test.c +++ b/core/src/test.c @@ -47,7 +47,7 @@ u8 tspin_no_lines_board[20][10] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }
};
-void apply_test_board(struct cetris_game* g, enum tests t) {
+void apply_test_board(cetris_game* g, test t) {
u8 (*board)[20][10];
switch (t) {
case TSPIN:
|