Small block game in C
Commit 1f869eaffc8c
tarball3 files changed+115-58
@@ -34,6 +34,8 @@ void draw_color (tetromino current_square) {
3434
case Z_PIECE:3535
printf("%s", PURPLE);3636
break;37
+ default:38
+ break;3739
} 3840
}3941
@@ -32,63 +32,127 @@ int main () {
3232
printf("\033[?25l\033[?1049h");3333
3434
35
+ /* Polling */36
+37
+ struct pollfd polling[1];38
+39
+ polling[0].fd = 0;40
+ polling[0].events = POLLIN;41
+42
+3543
/* Init */3644
3745
init_field();3846
47
+ bool blink[FIELD_HEIGHT] = {};48
+3949
bool is_piece = false;4050
4151
piece current_piece = {};4252
4353
44
- uint16_t i;54
+ /* Game Loop */55
+56
+ struct timespec start, current;57
+ clock_gettime(CLOCK_MONOTONIC_RAW, &start);58
+59
+60
+ uint8_t i;61
+ bool is_tetris = false;4562
46
- for (i = 0;; i++) {63
+ while (true) {4764
4865
int8_t move = 0;4966
bool down = false;5067
bool draw = false;5168
bool rotate = false;5269
53
- int8_t j, k;70
+ clock_gettime(CLOCK_MONOTONIC_RAW, ¤t);5471
55
- if (!is_piece) {56
- current_piece = init_piece((rand() % Z_PIECE) + 1);57
- is_piece = true;58
- draw = true;59
- i = 0;60
- }72
+ uint64_t time_diff = (current.tv_sec - start.tv_sec) * 1000000000ULL + (current.tv_nsec - start.tv_nsec);6173
6274
6375
/* Take care of the input */6476
77
+ int is_poll = poll(polling, 1, 17);78
+79
+ if (is_poll > 0 && polling[0].revents & POLLIN) {80
+81
+ char buf[10] = {};6582
66
- char buf[10] = {};83
+ if (read(STDIN_FILENO, buf, sizeof(buf)) > 0) {84
+ if (buf[0] == 'q') {85
+ break;86
+ }6787
68
- if (read(STDIN_FILENO, buf, sizeof(buf)) > 0) {69
- if (buf[0] == 'q') {70
- break;88
+ if (buf[0] == '\033' && buf[1] == '[') {89
+ 90
+ switch (buf[2]) {91
+ case 'A':92
+ rotate = true;93
+ break;94
+ case 'B':95
+ down = true;96
+ break;97
+ case 'C':98
+ move = 1;99
+ break;100
+ case 'D':101
+ move = -1;102
+ break;103
+ default:104
+ break;105
+ }106
+ }71107
}108
+ }72109
73
- if (buf[0] == '\033' && buf[1] == '[') {74
- 75
- switch (buf[2]) {76
- case 'A':77
- rotate = true;78
- break;79
- case 'B':80
- down = true;81
- break;82
- case 'C':83
- move = 1;84
- break;85
- case 'D':86
- move = -1;87
- break;88
- default:89
- break;110
+111
+ if (is_tetris) {112
+113
+ if (time_diff >= FRAME * BLINK && i < 4) { 114
+115
+ time_diff -= time_diff % (FRAME * BLINK);116
+ start.tv_sec += time_diff / 1000000000ULL;117
+ start.tv_nsec += time_diff % 1000000000ULL;118
+ 119
+ draw_board(current_piece, (i % 2 == 0) ? NULL : blink, is_piece);120
+ i++;121
+ }122
+123
+ if (i == 4) {124
+ 125
+ int8_t j, k;126
+127
+ for (j = 0; j < FIELD_HEIGHT; j++) {128
+ if (blink[j]) {129
+130
+ for (k = j; k > 0; k--) {131
+ int8_t l;132
+ 133
+ for (l = 0; l < FIELD_WIDTH; l++) {134
+ playfield[k][l + BORDER_WIDTH] = playfield[k - 1][l + BORDER_WIDTH];135
+ }136
+ }137
+ }90138
}139
+140
+ i = 0;141
+ is_tetris = false;91142
}143
+144
+ continue;145
+ }146
+147
+148
+149
+ /* Creates new piece */150
+151
+ 152
+ if (!is_piece) {153
+ current_piece = init_piece((rand() % Z_PIECE) + 1);154
+ is_piece = true;155
+ draw = true;92156
}93157
94158
@@ -100,8 +164,6 @@ int main () {
100164
current_piece.x + move + current_piece.size <= FULL_WIDTH101165
) {102166
103
- bool is_valid = true;104
-105167
piece moved_piece = current_piece;106168
moved_piece.x += move;107169
@@ -125,14 +187,19 @@ int main () {
125187
current_piece = rotated;126188
draw = true;127189
}128
- }190
+ } 129191
130192
131193
/* Piece falls */132194
133
- if (i >= 100 || down) {195
+ if (time_diff >= (FRAME * FALL) || down) {134196
current_piece.y++;135
- i = 0;197
+ 198
+ time_diff -= time_diff % (FRAME * FALL);199
+ start.tv_sec += time_diff / 1000000000ULL;200
+ start.tv_nsec += time_diff % 1000000000ULL;201
+ 202
+136203
draw = true;137204
}138205
@@ -141,6 +208,8 @@ int main () {
141208
142209
if (!valid_position(current_piece)) {143210
211
+ int8_t j, k;212
+144213
for (j = 0; j < current_piece.size; j++) {145214
for (k = 0; k < current_piece.size; k++) {146215
@@ -159,8 +228,7 @@ int main () {
159228
160229
/* Looks if there is a tetris */161230
162
- bool blink[FIELD_HEIGHT] = {};163
- bool is_tetris = false;231
+ int8_t j, k;164232
165233
for (j = FIELD_HEIGHT - 1; j >= 0; j--) {166234
@@ -175,26 +243,8 @@ int main () {
175243
176244
blink[j] = true;177245
is_tetris = true; 178
- }179
- }180
-181
- if (is_tetris) {182
- for (j = 0; j < 4; j++) {183
- draw_board(current_piece, (j % 2 == 0) ? NULL : blink, is_piece);184
- usleep(200000);185
- }186
-187
- for (j = 0; j < FIELD_HEIGHT; j++) {188
- if (blink[j]) {189
-190
- for (k = j; k > 0; k--) {191
- int8_t l;192
- 193
- for (l = 0; l < FIELD_WIDTH; l++) {194
- playfield[k][l + BORDER_WIDTH] = playfield[k - 1][l + BORDER_WIDTH];195
- }196
- }197
- }246
+ } else {247
+ blink[j] = false;198248
}199249
}200250
@@ -215,7 +265,6 @@ int main () {
215265
216266
if (draw)217267
draw_board(current_piece, NULL, is_piece);218
- usleep(10000);219268
}220269
221270
end:@@ -13,6 +13,7 @@
1313
1414
#include <time.h>1515
#include <unistd.h>16
+#include <poll.h>1617
1718
#include <errno.h>1819
@@ -26,6 +27,11 @@
2627
#define FULL_WIDTH (FIELD_WIDTH + BORDER_WIDTH * 2)2728
#define FULL_HEIGHT (FIELD_HEIGHT + BORDER_WIDTH)2829
30
+#define FRAME 1700000031
+32
+#define FALL 5833
+#define BLINK 1234
+2935
typedef enum {3036
EMPTY, I_PIECE, J_PIECE, L_PIECE, O_PIECE, S_PIECE, T_PIECE, Z_PIECE, TETRIS3137
} tetromino;