mirror of
https://github.com/thepigeongenerator/tetris_clone.git
synced 2025-12-17 14:05:45 +01:00
function name changes for clairity
This commit is contained in:
@@ -12,17 +12,17 @@
|
|||||||
#include "shapes.h"
|
#include "shapes.h"
|
||||||
|
|
||||||
|
|
||||||
/* checks if `row` of `COLUMNS` wide contains anything with `0`.
|
/* count the empty columns in the row */
|
||||||
* returns `1` if it doesn't, otherwise returns `0` */
|
__attribute_const__ static int count_empty(u8 const* restrict row) {
|
||||||
__attribute_const__ static int is_filled(u8 const* restrict row) {
|
int cnt = 0;
|
||||||
int res = 0;
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma unroll COLUMNS
|
#pragma unroll COLUMNS
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#pragma GCC unroll COLUMNS
|
#pragma GCC unroll COLUMNS
|
||||||
#endif
|
#endif
|
||||||
for (int i = 0; i < COLUMNS; i++) res |= !row[i];
|
for (int i = 0; i < COLUMNS; i++)
|
||||||
return !res;
|
cnt += !row[i];
|
||||||
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* checks for filled rows, clearing a max of 4 consecutive rows, if present.
|
/* checks for filled rows, clearing a max of 4 consecutive rows, if present.
|
||||||
@@ -32,11 +32,11 @@ static void clear_rows(u8* restrict* restrict rows, u16* const score) {
|
|||||||
uint fillc = 0;
|
uint fillc = 0;
|
||||||
uint checkc = 0;
|
uint checkc = 0;
|
||||||
|
|
||||||
for (uint y = 0; y < (ROWS - fillc); y++) {
|
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
|
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
|
rows[i] = rows[i - fillc]; // either assigns the current row to itself, or to the "next" row
|
||||||
|
|
||||||
if (checkc >= 4 || !is_filled(rows[i])) {
|
if (count_empty(rows[i])) {
|
||||||
checkc += (fillc > 0 && checkc < 4);
|
checkc += (fillc > 0 && checkc < 4);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ static void clear_rows(u8* restrict* restrict rows, u16* const score) {
|
|||||||
|
|
||||||
// TODO: this is suboptimal, ditch the entire "representing shapes as binary-formatted data" and instead use a switch...case.
|
// TODO: this is suboptimal, ditch the entire "representing shapes as binary-formatted data" and instead use a switch...case.
|
||||||
/* writes a shape to the screen */
|
/* writes a shape to the screen */
|
||||||
static void set_shape(u8* restrict const* restrict row, u8 id, i8vec2 pos) {
|
static void plcmnt_place(u8* restrict const* restrict row, u8 id, i8vec2 pos) {
|
||||||
u8 colour = colour_from_id(id);
|
u8 colour = colour_from_id(id);
|
||||||
|
|
||||||
i8vec2 bpos[4];
|
i8vec2 bpos[4];
|
||||||
@@ -73,19 +73,19 @@ static void set_shape(u8* restrict const* restrict row, u8 id, i8vec2 pos) {
|
|||||||
row[bpos[3][VY]][bpos[3][VX]] = colour;
|
row[bpos[3][VY]][bpos[3][VX]] = colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int shape_is_valid_pos(u8* restrict const* restrict const rows, i8vec2 pos) {
|
static int plcmnt_valid(u8* restrict const* restrict const rows, i8vec2 pos) {
|
||||||
return pos[VX] >= 0 && pos[VX] < COLUMNS &&
|
return pos[VX] >= 0 && pos[VX] < COLUMNS &&
|
||||||
pos[VY] >= 0 && pos[VY] < ROWS &&
|
pos[VY] >= 0 && pos[VY] < ROWS &&
|
||||||
!rows[pos[VY]][pos[VX]];
|
!rows[pos[VY]][pos[VX]];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shape_intersects(u8* restrict const* restrict const rows, u8 const id, i8vec2 pos) {
|
static int plcmnt_intersect(u8* restrict const* restrict const rows, u8 const id, i8vec2 pos) {
|
||||||
i8vec2 bpos[4];
|
i8vec2 bpos[4];
|
||||||
shape_getblocks(id, bpos);
|
shape_getblocks(id, bpos);
|
||||||
return !(shape_is_valid_pos(rows, pos + bpos[0]) &&
|
return !(plcmnt_valid(rows, pos + bpos[0]) &&
|
||||||
shape_is_valid_pos(rows, pos + bpos[1]) &&
|
plcmnt_valid(rows, pos + bpos[1]) &&
|
||||||
shape_is_valid_pos(rows, pos + bpos[2]) &&
|
plcmnt_valid(rows, pos + bpos[2]) &&
|
||||||
shape_is_valid_pos(rows, pos + bpos[3]));
|
plcmnt_valid(rows, pos + bpos[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void place_update(struct gamedata* gdat, int movdat) {
|
void place_update(struct gamedata* gdat, int movdat) {
|
||||||
@@ -96,10 +96,10 @@ void place_update(struct gamedata* gdat, int movdat) {
|
|||||||
// update Y axis
|
// update Y axis
|
||||||
tmp = !!(movdat & MOVD);
|
tmp = !!(movdat & MOVD);
|
||||||
gdat->pdat.sel[VY] += tmp;
|
gdat->pdat.sel[VY] += tmp;
|
||||||
tmp = tmp && shape_intersects(gdat->rows, id, gdat->pdat.sel);
|
tmp = tmp && plcmnt_intersect(gdat->rows, id, gdat->pdat.sel);
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
gdat->pdat.sel[VY]--;
|
gdat->pdat.sel[VY]--;
|
||||||
set_shape(gdat->rows, id, gdat->pdat.sel);
|
plcmnt_place(gdat->rows, id, gdat->pdat.sel);
|
||||||
clear_rows(gdat->rows, &gdat->pnts); // clear the rows that have been completed
|
clear_rows(gdat->rows, &gdat->pnts); // clear the rows that have been completed
|
||||||
next_shape();
|
next_shape();
|
||||||
audio_play(AUDIO_ID_PLACE);
|
audio_play(AUDIO_ID_PLACE);
|
||||||
@@ -107,9 +107,9 @@ void place_update(struct gamedata* gdat, int movdat) {
|
|||||||
|
|
||||||
// update X axis
|
// update X axis
|
||||||
tmp = !!(movdat & MOVR) - !!(movdat & MOVL);
|
tmp = !!(movdat & MOVR) - !!(movdat & MOVL);
|
||||||
gdat->pdat.sel[VX] += (tmp && !shape_intersects(gdat->rows, id, (i8vec2){gdat->pdat.sel[VX] + tmp, gdat->pdat.sel[VY]})) * tmp;
|
gdat->pdat.sel[VX] += (tmp && !plcmnt_intersect(gdat->rows, id, (i8vec2){gdat->pdat.sel[VX] + tmp, gdat->pdat.sel[VY]})) * tmp;
|
||||||
|
|
||||||
// update roll
|
// update roll
|
||||||
tmp = id ^ (((!!(movdat & MOVRR) - !!(movdat & MOVRL)) * 8 + id) & 31);
|
tmp = id ^ (((!!(movdat & MOVRR) - !!(movdat & MOVRL)) * 8 + id) & 31);
|
||||||
gdat->pdat.cur ^= (tmp && !shape_intersects(gdat->rows, id ^ tmp, gdat->pdat.sel)) * tmp;
|
gdat->pdat.cur ^= (tmp && !plcmnt_intersect(gdat->rows, id ^ tmp, gdat->pdat.sel)) * tmp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ void render_init(SDL_Window* win, struct gamedata const* game_data) {
|
|||||||
gdat = game_data;
|
gdat = game_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t get_column_pos(uint column) {
|
static inline i32 colpos(uint column) {
|
||||||
return column * BLOCK_WIDTH + 1 + TET_PADDING;
|
return column * BLOCK_WIDTH + 1 + TET_PADDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,14 +62,14 @@ static void draw_score_text(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(score_surface && score_texture);
|
assert(score_surface && score_texture);
|
||||||
SDL_Rect text_rect = {get_column_pos(COLUMNS + 1), get_row_pos(0), score_surface->w, score_surface->h};
|
SDL_Rect text_rect = {colpos(COLUMNS + 1), rowpos(0), score_surface->w, score_surface->h};
|
||||||
SDL_RenderCopy(rend, score_texture, NULL, &text_rect);
|
SDL_RenderCopy(rend, score_texture, NULL, &text_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this is suboptimal, since each block will be 2 triangles, wasting perf. Consider using switch...case hard-coded drawing
|
// TODO: this is suboptimal, since each block will be 2 triangles, wasting perf. Consider using switch...case hard-coded drawing
|
||||||
// draws a block at the specified position
|
// draws a block at the specified position
|
||||||
static inline int draw_block(SDL_Renderer* const renderer, i8vec2 pos) {
|
static inline int draw_block(SDL_Renderer* const renderer, i8vec2 pos) {
|
||||||
SDL_Rect const block = {get_column_pos(pos[VX]), get_row_pos(pos[VY]), BLOCK_WIDTH - 1, BLOCK_HEIGHT - 1};
|
SDL_Rect const block = {colpos(pos[VX]), rowpos(pos[VY]), BLOCK_WIDTH - 1, BLOCK_HEIGHT - 1};
|
||||||
return SDL_RenderFillRect(renderer, &block);
|
return SDL_RenderFillRect(renderer, &block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user