mirror of
https://github.com/thepigeongenerator/tetris_clone.git
synced 2025-12-17 05:55:46 +01:00
rework clear rows function to be more efficient, and shorter.
This commit is contained in:
@@ -12,47 +12,24 @@
|
||||
#include "shapes.h"
|
||||
|
||||
|
||||
/* count the empty columns in the row */
|
||||
__attribute_const__ static int count_empty(u8 const* restrict row) {
|
||||
int cnt = 0;
|
||||
#if defined(__clang__)
|
||||
#pragma unroll COLUMNS
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC unroll COLUMNS
|
||||
#endif
|
||||
for (int i = 0; i < COLUMNS; i++)
|
||||
cnt += !row[i];
|
||||
return cnt;
|
||||
}
|
||||
static int clear_rows(u8* restrict* restrict rows) {
|
||||
int count = 0;
|
||||
u8* cache[4]; /* the maximum amount of rows the user can clear at once is four */
|
||||
|
||||
/* checks for filled rows, clearing a max of 4 consecutive rows, if present.
|
||||
* all row pointers will be moved down to fill the gap, the filled rows will be inserted at the top, and zeroed-out */
|
||||
static void clear_rows(u8* restrict* restrict rows, u16* const score) {
|
||||
u8* cache[4] = {0}; // the I piece is 4 long, meaning only 4 rows can be cleared at a time
|
||||
uint fillc = 0;
|
||||
uint checkc = 0;
|
||||
|
||||
for (uint y = 0; y < (ROWS - fillc) && checkc <= 4; y++) {
|
||||
int i = (ROWS - 1) - y; // invert the index direction, so we start at the highest index
|
||||
rows[i] = rows[i - fillc]; // either assigns the current row to itself, or to the "next" row
|
||||
|
||||
if (count_empty(rows[i])) {
|
||||
checkc += (fillc > 0 && checkc < 4);
|
||||
continue;
|
||||
for (int y = ROWS - 1; y >= 0; y--) {
|
||||
int x = 0;
|
||||
while (x < COLUMNS && rows[y][x] && count < 4) x++;
|
||||
if (x >= COLUMNS) cache[count++] = rows[y];
|
||||
else rows[y + count] = rows[y];
|
||||
}
|
||||
|
||||
|
||||
cache[fillc] = rows[i]; // cache the current row address, since it's going to be overridden
|
||||
fillc++;
|
||||
checkc++;
|
||||
y--;
|
||||
}
|
||||
|
||||
*score += (8 << fillc) * !!fillc;
|
||||
for (uint i = 0; i < fillc; i++) {
|
||||
if (count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
memset(cache[i], 0, COLUMNS);
|
||||
rows[i] = cache[i];
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* writes a shape to the screen */
|
||||
@@ -99,7 +76,7 @@ int place_update(struct gamedata* gdat, int movdat) {
|
||||
if (tmp) {
|
||||
gdat->pdat.sel[VY]--;
|
||||
plcmnt_place(gdat->rows, id, gdat->pdat.sel);
|
||||
clear_rows(gdat->rows, &gdat->pnts); // clear the rows that have been completed
|
||||
gdat->pnts += clear_rows(gdat->rows) << 4; // clear the rows that have been completed
|
||||
next_shape();
|
||||
audio_play(AUDIO_ID_PLACE);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user