fix board read/write indexing

This commit is contained in:
nino-porcino 2021-12-21 15:26:50 +01:00
parent 473de5f026
commit 07906ea3c1
3 changed files with 74 additions and 13 deletions

View File

@ -9,15 +9,16 @@
#define BCOLS 10 // number of board columns
#define BROWS 20 // number of board rows
#define EMPTY NUMPIECES // the empty character is the character after all tetrominoes
#define MARKED 255 // mark position on the board while moving (to reduce flickering)
// TODO KickC doesn't allow double arrays[][]
//byte board[32 /*BROWS*/ ][16 /*BCOLS*/]; // the board
byte board[16*BROWS];
#define BOARD_INDEX(x,y) (((int)(y))*16+((int)(x)))
#define WRITE_BOARD(x,y,c) board[BOARD_INDEX(x,y)]=(c)
#define READ_BOARD(x,y) board[BOARD_INDEX(x,y)]
#define BOARD_INDEX(y,x) (((int)(y))*16+((int)(x)))
#define WRITE_BOARD(y,x,c) board[BOARD_INDEX(y,x)]=(c)
#define READ_BOARD(y,x) board[BOARD_INDEX(y,x)]
// prototypes
void ck_init();
@ -45,7 +46,7 @@ void ck_drawpiece(sprite *pl) {
int x = pl->x + d->offset_x;
int y = pl->y + d->offset_y;
*/
WRITE_BOARD(x,y,pl->piece);
WRITE_BOARD(y,x,pl->piece);
data++;
}
}
@ -60,7 +61,22 @@ void ck_erasepiece(sprite *pl) {
int x = pl->x + (int) data->offset_x;
int y = pl->y + (int) data->offset_y;
*/
WRITE_BOARD(x,y,EMPTY);
WRITE_BOARD(y,x,EMPTY);
data++;
}
}
// draw a piece on the check board, marking it with high bit set
void ck_markpiece(sprite *pl) {
tile_offset *data = get_piece_offsets(pl->piece, pl->angle);
for(byte t=0; t<4; t++) {
int x = pl->x; byte x1 = data->offset_x; x+= (int) x1;
int y = pl->y; byte y1 = data->offset_y; y+= (int) y1;
/*
int x = pl->x + (int) data->offset_x;
int y = pl->y + (int) data->offset_y;
*/
WRITE_BOARD(y,x,MARKED);
data++;
}
}
@ -77,7 +93,7 @@ int collides(sprite *pl) {
if(x<0) return 1; // does it collide with left border?
if(x>=BCOLS) return 1; // does it collide with right border?
if(y>=BROWS) return 1; // does it collide with bottom?
if(READ_BOARD(x,y) != EMPTY) return 1; // does it collide with something?
if(READ_BOARD(y,x) != EMPTY) return 1; // does it collide with something?
data++;
}
return 0;
@ -86,7 +102,7 @@ int collides(sprite *pl) {
// returns 1 if the line is all filled
byte is_line_filled(byte line) {
for(byte t=0;t<BCOLS;t++) {
if(READ_BOARD(t,line)==EMPTY) return 0;
if(READ_BOARD(line,t)==EMPTY) return 0;
}
return 1;
}
@ -94,7 +110,7 @@ byte is_line_filled(byte line) {
// fills the specified line with an empty character
void ck_erase_line(byte line) {
for(byte t=0; t<BCOLS; t++) {
WRITE_BOARD(t,line,EMPTY);
WRITE_BOARD(line,t,EMPTY);
}
}
@ -102,7 +118,7 @@ void ck_erase_line(byte line) {
void ck_scroll_down(byte endline) {
for(byte line=endline;line>0;line--) {
for(byte x=0;x<BCOLS;x++) {
WRITE_BOARD(x,line,READ_BOARD(x,line-1));
WRITE_BOARD(line,x,READ_BOARD(line-1,x));
}
}
// clears the top line

View File

@ -195,6 +195,33 @@ void gr_erasepiece(sprite *p) {
}
}
// erase piece from the screen
void gr_erasepiece_unmarked(sprite *p) {
tile_offset *data = get_piece_offsets(p->piece, p->angle);
int px = p->x;
int py = p->y;
int zx = px;
int zy = py;
px += STARTBOARD_X;
py += STARTBOARD_Y;
for(byte t=0; t<4; t++) {
int x = px + data->offset_x;
int y = py + data->offset_y;
int cx = zx + data->offset_x;
int cy = zy + data->offset_y;
data++;
if(READ_BOARD(cy,cx) != MARKED) {
draw_tile((byte)x,(byte)y,EMPTY_GR_CHAR,EMPTY_GR_COLOR);
}
}
}
// draw a piece on the screen
void gr_drawpiece(sprite *p) {
tile_offset *data = get_piece_offsets(p->piece, p->angle);
@ -237,7 +264,7 @@ void gr_update_board() {
byte tile,ch,col;
for(byte line=0;line<BROWS;line++) {
for(byte column=0;column<BCOLS;column++) {
tile = READ_BOARD(column,line);
tile = READ_BOARD(line,column);
ch = piece_chars[tile];
col = piece_colors[tile];
draw_tile(STARTBOARD_X+column, STARTBOARD_Y+line, ch, col);

View File

@ -153,7 +153,13 @@ void handle_player_input() {
break;
}
gr_erasepiece(&player);
gr_drawpiece(&new_pos);
gr_drawpiece(&new_pos);
// flicker-free version
// ck_markpiece(&new_pos);
// gr_erasepiece_unmarked(&player);
// gr_drawpiece(&new_pos);
ck_drawpiece(&new_pos);
sprite_copy(&player,&new_pos);
}
@ -164,6 +170,12 @@ void handle_player_input() {
if(allowed == 1) {
gr_erasepiece(&player);
gr_drawpiece(&new_pos);
// flicker-free version
// ck_markpiece(&new_pos);
// gr_erasepiece_unmarked(&player);
// gr_drawpiece(&new_pos);
sprite_copy(&player, &new_pos);
}
ck_drawpiece(&player);
@ -197,8 +209,14 @@ void gameLoop() {
// automatic drop does not collide, simply draw it
gr_erasepiece(&player); // erase and draw are as close as possible
gr_drawpiece(&new_pos);
ck_drawpiece(&new_pos);
sprite_copy(&player, &new_pos); // make player new pos
// flicker-free version
// ck_markpiece(&new_pos);
// gr_erasepiece_unmarked(&player);
// gr_drawpiece(&new_pos);
sprite_copy(&player, &new_pos);
ck_drawpiece(&player);
}
}
else {