From 8209aa1855024c5b8b96b39d37f3a2f80b9ae0fe Mon Sep 17 00:00:00 2001 From: Quinn Date: Sat, 1 Feb 2025 03:14:44 +0100 Subject: [PATCH] fix: rows are now being cleared properly and should no longer have any problems. --- src/game/game.c | 4 +++- src/game/tetromino/placing.c | 42 +++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/game/game.c b/src/game/game.c index 6b5bd55..9c9ef8c 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -23,8 +23,10 @@ void game_init(GameData* const game_data) { *game_data = (GameData){0}; // allocate size for each row - for (int8_t i = 0; i < ROWS; i++) + for (int8_t i = 0; i < ROWS; i++) { game_data->rows[i] = calloc(COLUMNS, sizeof(Colour)); + //game_data->rows[i][0] = (Colour){(uint8_t)((((i + 1) ^ ((i + 1) >> 3)) * 0x27) & 0xFF)}; // for debugging + } // set a random seed using the system clock srand(time(NULL)); diff --git a/src/game/tetromino/placing.c b/src/game/tetromino/placing.c index 21b1943..d86467a 100644 --- a/src/game/tetromino/placing.c +++ b/src/game/tetromino/placing.c @@ -1,7 +1,6 @@ #include "placing.h" #include -#include #include "../../window/colour.h" #include "../game.h" @@ -18,30 +17,39 @@ static bool is_filled(CRow row) { return true; } -static void clear_rows(Row* row) { - int8_t filled = 0; +static void clear_rows(Row* rows) { + Row cache[4] = {0}; // you can only clear four rows at a time + struct { + uint8_t filled : 3; // values will only ever be 0..4 (use extra bit for carry) + uint8_t checked : 3; // values will only ever be 0..4 (use extra bit for carry) + } dat = {0}; // loop through each row (excluding the empty rows at the top when clearing a line) - for (int8_t y = 0; y < (ROWS - filled); y++) { + for (int8_t y = 0; y < (ROWS - dat.filled); y++) { const int8_t i = (ROWS - 1) - y; // get the index starting from the bottom - Row row_cache = row[i]; // cache this row address in case the row is filled - row[i] = row[i - filled]; // set the row to the new or same address + rows[i] = rows[i - dat.filled]; // set the row to the new or same address - if (!is_filled(row[i])) continue; + // continue if the line isn't filled or the max amount has been reached + if (dat.checked >= 4 || !is_filled(rows[i])) { + if (dat.filled > 0 && dat.checked < 4) dat.checked++; + continue; // continue to the next line + } - // zero out the cache - for (int8_t x = 0; x < COLUMNS; x++) - row[i][x].packed = 0; - - // write the cached address to a row starting from the top - row[filled++] = row_cache; - row[i] = row[i - filled]; - y--; + cache[dat.filled] = rows[i]; // cache the current row address + dat.filled++; // increase filled, and keep the row in the cache + dat.checked++; // increase the checked count + y--; // decrease y to check this line again } - if (filled > 0) - printf("filled: %i\n", filled); + while (dat.filled > 0) { + dat.filled--; + rows[dat.filled] = cache[dat.filled]; + + // zero out the filled row + for (int8_t x = 0; x < COLUMNS; x++) + cache[dat.filled][x].packed = 0; + } } // sets a shape to the screen