summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorturnipgod2025-03-03 19:56:31 -0500
committerturnipgod2025-03-03 19:56:31 -0500
commitdf24be9450f1221eea839b3c64982a0624627970 (patch)
treedd695633ea45e2acb7c31bb916f30f7cd52b7538 /src
parenta92899722ff9ef080fb9f6614020003ae9d918da (diff)
added lockdown timer, added super rotation systempiece_queue
Diffstat (limited to 'src')
-rw-r--r--src/main.c125
1 files changed, 98 insertions, 27 deletions
diff --git a/src/main.c b/src/main.c
index 82e9e90..9ef03f0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,6 +12,8 @@
#define BLOCK_SIZE 25
#define FALL_TICK 0.2
+#define SOFT_DROP_MULT 4
+#define LOCK_TICK 0.5
enum Phases {
GENERATION,
@@ -40,12 +42,32 @@ int current_bag = 0;
int current_piece_index = 0;
int hold = 7;
int held = 0;
+int hard_drop = 0;
+double phase_time = 0.0;
void draw_block(int x, int y, int width, int height, struct Color color)
{
DrawRectangle(x, -y + SCREEN_HEIGHT - height, width, height, color);
}
+int is_overlap(int x, int y)
+{
+ for (int i = 0; i < tetrominos[current_piece.type].size; i++) {
+ for (int j = 0; j < tetrominos[current_piece.type].size; j++) {
+ if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) {
+ if (current_piece.pos_x + i - 1 + x >= MATRIX_WIDTH
+ || current_piece.pos_x + i - 1 + x < 0
+ || current_piece.pos_y + j - 1 + y < 0
+ || (!ColorIsEqual(BLACK, matrix[current_piece.pos_x + i - 1 + x][current_piece.pos_y + j - 1 + y])
+ && !ColorIsEqual(WHITE, matrix[current_piece.pos_x + i - 1 + x][current_piece.pos_y + j - 1 + y]))) {
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
void render_matrix(void)
{
int matrix_origin_x = (SCREEN_WIDTH/2 - (MATRIX_WIDTH * BLOCK_SIZE))/2;
@@ -73,6 +95,33 @@ void render_matrix(void)
}
}
+ /* draw ghost piece */
+ int ghost_y = 0;
+ while(!is_overlap(0, ghost_y)) {
+ ghost_y--;
+ }
+
+ for (int i = 0; i < tetrominos[current_piece.type].size; i++) {
+ for (int j = 0; j < tetrominos[current_piece.type].size; j++) {
+ if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) {
+ draw_block(
+ (matrix_origin_x + ((current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 3
+ ,(matrix_origin_y + ((current_piece.pos_y + j + ghost_y) * BLOCK_SIZE)) + 3
+ ,BLOCK_SIZE - 6
+ ,BLOCK_SIZE - 6
+ ,tetrominos[current_piece.type].color
+ );
+ draw_block(
+ (matrix_origin_x + ((current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 4
+ ,(matrix_origin_y + ((current_piece.pos_y + j + ghost_y) * BLOCK_SIZE)) + 4
+ ,BLOCK_SIZE - 8
+ ,BLOCK_SIZE - 8
+ ,BLACK
+ );
+ }
+ }
+ }
+
/* draw current piece */
for (int i = 0; i < tetrominos[current_piece.type].size; i++) {
for (int j = 0; j < tetrominos[current_piece.type].size; j++) {
@@ -152,24 +201,6 @@ void shuffle_bag(int *bag)
}
}
-int is_overlap(int x, int y)
-{
- for (int i = 0; i < tetrominos[current_piece.type].size; i++) {
- for (int j = 0; j < tetrominos[current_piece.type].size; j++) {
- if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) {
- if (current_piece.pos_x + i - 1 + x >= MATRIX_WIDTH
- || current_piece.pos_x + i - 1 + x < 0
- || current_piece.pos_y + j - 1 + y < 0
- || (!ColorIsEqual(BLACK, matrix[current_piece.pos_x + i - 1 + x][current_piece.pos_y + j - 1 + y])
- && !ColorIsEqual(WHITE, matrix[current_piece.pos_x + i - 1 + x][current_piece.pos_y + j - 1 + y]))) {
- return 1;
- }
- }
- }
- }
- return 0;
-}
-
void generation_phase(void)
{
// bag generation
@@ -204,6 +235,7 @@ void handle_hold(void)
current_piece.type = hold;
hold = temp;
}
+ game_phase = FALL;
current_piece.rotation = NORTH;
current_piece.pos_x = 4;
current_piece.pos_y = 20;
@@ -219,10 +251,24 @@ void handle_rotate(void)
static int rotated_cw = 0;
static int rotated_ccw = 0;
if (game_phase == FALL || game_phase == LOCK) {
+ int *kick_table;
+ int can_rotate = 0;
+ int i;
if (IsKeyDown(KEY_L) && !rotated_cw) {
+ kick_table = tetrominos[current_piece.type].cw_kick_table[current_piece.rotation];
current_piece.rotation++;
current_piece.rotation = current_piece.rotation % 4;
- if (is_overlap(0, 0)) {
+ for (i = 0; i < 10 && !can_rotate; i += 2) {
+ if (!is_overlap(kick_table[i], kick_table[i+1])) {
+ current_piece.pos_x += kick_table[i];
+ current_piece.pos_y += kick_table[i+1];
+ can_rotate = 1;
+ if (game_phase == LOCK) {
+ phase_time = 0.0;
+ }
+ }
+ }
+ if (!can_rotate) {
current_piece.rotation--;
if (current_piece.rotation < 0) current_piece.rotation = 3;
}
@@ -232,9 +278,20 @@ void handle_rotate(void)
rotated_cw = 0;
}
if (IsKeyDown(KEY_J) && !rotated_ccw) {
+ kick_table = tetrominos[current_piece.type].ccw_kick_table[current_piece.rotation];
current_piece.rotation--;
if (current_piece.rotation < 0) current_piece.rotation = 3;
- if (is_overlap(0, 0)) {
+ for (i = 0; i < 10 && !can_rotate; i += 2) {
+ if (!is_overlap(kick_table[i], kick_table[i+1])) {
+ current_piece.pos_x += kick_table[i];
+ current_piece.pos_y += kick_table[i+1];
+ can_rotate = 1;
+ if (game_phase == LOCK) {
+ phase_time = 0.0;
+ }
+ }
+ }
+ if (!can_rotate) {
current_piece.rotation++;
current_piece.rotation = current_piece.rotation % 4;
}
@@ -251,6 +308,9 @@ void move_right(void)
if (is_overlap(1, 0)) {
return;
}
+ if (game_phase == LOCK) {
+ phase_time = 0.0;
+ }
current_piece.pos_x++;
}
@@ -259,6 +319,9 @@ void move_left(void)
if (is_overlap(-1, 0)) {
return;
}
+ if (game_phase == LOCK) {
+ phase_time = 0.0;
+ }
current_piece.pos_x--;
}
@@ -297,10 +360,9 @@ void move_piece_to_matrix(void)
void handle_fall(void)
{
- static double phase_time = 0.0;
+ phase_time += GetFrameTime();
if (game_phase == FALL) {
- phase_time += GetFrameTime();
- if ((!IsKeyDown(KEY_S) && phase_time < FALL_TICK) || phase_time < FALL_TICK * 0.5) {
+ if (!hard_drop && ((!IsKeyDown(KEY_S) && phase_time < FALL_TICK) || phase_time < FALL_TICK / SOFT_DROP_MULT)) {
return;
} else {
phase_time = 0.0;
@@ -308,21 +370,30 @@ void handle_fall(void)
}
if (is_overlap(0, -1)) {
+ game_phase = LOCK;
+ } else {
+ game_phase = FALL;
+ current_piece.pos_y--;
+ }
+
+ if (is_overlap(0, -1) && (phase_time >= LOCK_TICK || hard_drop)) {
move_piece_to_matrix();
generation_phase();
held = 0;
+ game_phase = FALL;
+ phase_time = 0.0;
+ hard_drop = 0;
return;
- }
-
- current_piece.pos_y--;
+ }
}
void handle_hard_drop(void)
{
static int dropped = 0;
- if (game_phase == FALL) {
+ if (game_phase == FALL || game_phase == LOCK) {
if (IsKeyDown(KEY_W) && !dropped) {
dropped = 1;
+ hard_drop = 1;
while(!is_overlap(0, -1)) {
current_piece.pos_y--;
}