From 50cd4a39b2f12000190b6c99fd1ad3185ea410bc Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Tue, 31 Dec 2019 00:26:31 -0500 Subject: optimize rendering --- frontends/gl/2 | 349 ++++++++++++++++++++++++++++++++++++++++++++++++ frontends/gl/drawable.h | 2 + frontends/gl/events.c | 7 +- frontends/gl/main.c | 2 +- frontends/gl/ui.c | 193 ++++++++++++++++++-------- frontends/gl/ui.h | 11 ++ lib/cetris.c | 8 +- lib/cetris.h | 12 +- 8 files changed, 525 insertions(+), 59 deletions(-) create mode 100644 frontends/gl/2 diff --git a/frontends/gl/2 b/frontends/gl/2 new file mode 100644 index 0000000..af23c35 --- /dev/null +++ b/frontends/gl/2 @@ -0,0 +1,349 @@ +#include +#include + +#include "ui.h" +#include "drawable.h" + +#define RES_SCALE 1.2 + +void reset_current(cetris_ui *ui) { + for (int i = 0; i < 4; i++) { + new_rectangle(&ui->board.current[i]); + new_rectangle(&ui->board.ghost[i]); + } +} + +void refresh_current(cetris_ui *ui) { + for (int i = 0; i < 4; i++) { + ui->board.current[i].visable = false; + ui->board.ghost[i].visable = false; + } +} + +void load_tetris_board(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat y, GLfloat w, GLfloat h) { + board->block_width = w / (GLfloat)board->game.config.board_x; + board->block_height = h / board->game.config.board_visible; + + board->x_offset = x; + board->y_offset = y; + board->block_offset = (board->game.config.board_y - board->game.config.board_visible); + + board->board_count = 0; + board->board = malloc(sizeof(drawable_t) * 100); + memset(board->board, 0, sizeof(drawable_t) * 100); + + board->update_current = false; + board->lock_current = false; + board->refresh_board_current = false; + + memset(&ui->board.current, 0, sizeof(drawable_t) * 4); + memset(&ui->board.ghost, 0, sizeof(drawable_t) * 4); + + refresh_current(ui); + reset_current(ui); + + update_rect(&board->skin.playboard, board->x_offset, board->y_offset - 10 * RES_SCALE, + board->game.config.board_x * board->block_width, + (board->game.config.board_visible * board->block_height) + 10 * RES_SCALE, + ui->window_width, ui->window_height); + + update_rect(&board->skin.border, board->x_offset - (110 * RES_SCALE), + board->y_offset - (45 * RES_SCALE), 380 * RES_SCALE, 600 * RES_SCALE, + ui->window_width, ui->window_height); +} + +void load_held_piece(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat y, GLfloat w, GLfloat h) { + board->held.block_width = w / 4.0f; + board->held.block_height = h / 4.0f; + + board->held.x_offset = x; + board->held.y_offset = y; +} + +void load_piece_queue(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat y, GLfloat w, GLfloat h) { + board->queue.block_width = w / 4.0f; + board->queue.block_height = w / 4.0f; + + board->queue.h = h; + board->queue.w = w; + + board->queue.x_offset = x; + board->queue.y_offset = y; +} + +// TODO: make this better +void update_current_drawable(cetris_ui *ui, drawable_t *current, drawable_t* ghost) { + refresh_current(ui); + int cur_piece = -1; + for (int s = 0; s < 4; s++) { + for (int j = 0; j < 4; j++) { + if ((ui->board.game.current.m[s]>>(3 - j))&1) { + cur_piece++; + + GLfloat block_x = + ui->board.x_offset + + (j + ui->board.game.current.pos.x) * ui->board.block_width; + + if (ghost) { + GLfloat ghost_y = + ui->board.y_offset + + (s + ui->board.game.current.ghost_y - ui->board.block_offset) + * ui->board.block_height; + + ghost[cur_piece].visable = true; + set_block_texture(&ghost[cur_piece], ui->board.game.current.t + 7); + update_rect(&ghost[cur_piece], block_x, ghost_y, + ui->board.block_width, ui->board.block_height, + ui->window_width, ui->window_height); + } + + if (s + ui->board.game.current.pos.y < ui->board.block_offset - 1) continue; + + GLfloat block_y = + ui->board.y_offset + + (s + ui->board.game.current.pos.y - ui->board.block_offset) + * ui->board.block_height; + + current[cur_piece].visable = true; + set_block_texture(¤t[cur_piece], ui->board.game.current.t); + update_rect(¤t[cur_piece], block_x, block_y, + ui->board.block_width, ui->board.block_height, + ui->window_width, ui->window_height); + + } + } + } +} + +void lock_current_drawable(cetris_ui *ui) { + for (int i = 0; i < 4; i++) { + new_rectangle(&ui->board.board[ui->board.board_count + i]); + } + + int current = 0; + for (int s = 0; s < 4; s++) { + for (int j = 0; j < 4; j++) { + if ((ui->board.game.lock_event.m[s]>>(3 - j))&1) { + GLfloat block_x = + ui->board.x_offset + + (j + ui->board.game.lock_event.pos.x) * ui->board.block_width; + + GLfloat block_y = + ui->board.y_offset + + (s + ui->board.game.lock_event.pos.y - ui->board.block_offset) + * ui->board.block_height; + + set_block_texture(&ui->board.board[ui->board.board_count + current], ui->board.game.lock_event.t); + update_rect(&ui->board.board[ui->board.board_count + current], block_x, block_y, + ui->board.block_width, ui->board.block_height, + ui->window_width, ui->window_height); + + // TODO: fix this + ui->board.board[ui->board.board_count + current].y = ui->board.game.lock_event.pos.y + s; + + ui->board.board_count++; + } + } + } + + ui->board.game.lock_event.processed = true; +} + +void refresh_board(cetris_ui *ui) { + ui->board.board_count = 0; + for (int s = 0; s < ui->board.game.config.board_x; s++) { + for (int j = 0; j < ui->board.game.config.board_y; j++) { + if (ui->board.game.board[s][y] & SLOT_OCCUPIED) { + GLfloat block_x = + ui->board.x_offset + + (j + ui->board.game.lock_event.pos.x) * ui->board.block_width; + + GLfloat block_y = + ui->board.y_offset + + (s + ui->board.game.lock_event.pos.y - ui->board.block_offset) + * ui->board.block_height; + + set_block_texture(&ui->board.board[ui->board.board_count], ui->board.game.lock_event.t); + update_rect(&ui->board.board[ui->board.board_count++], block_x, block_y, + ui->board.block_width, ui->board.block_height, + ui->window_width, ui->window_height); + } + } + } +} + +void draw_tetris_board(cetris_ui *ui) { + if (ui->board.update_current) { + update_current_drawable(ui, &ui->board.current[0], &ui->board.ghost[0]); + ui->board.update_current = false; + } + + if (ui->board.lock_current) { + lock_current_drawable(ui); + ui->board.lock_current = false; + } + + if (ui->board.refresh_board) { + refresh_board(ui); + ui->board.refresh_board = false; + } + + if (ui->board.game.line_event_count > 0) { + for (int i = 0; i < ui->board.board_count; i++) { + for (int j = 0; j < ui->board.game.line_event_count; j++) { + if (ui->board.board[i].y == ui->board.game.line_event[j].y) { + for (int s = i; s < ui->board.board_count; s++) { + ui->board.board[s] = ui->board.board[s + 1]; + } + } + } + } + ui->board.game.line_event_count = 0; + } + + glActiveTexture(GL_TEXTURE0); + + glBindTexture(GL_TEXTURE_2D, ui->board.skin.background.texture); + glBindVertexArray(ui->board.skin.background.vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + + glBindTexture(GL_TEXTURE_2D, 0); + + glBindTexture(GL_TEXTURE_2D, ui->board.skin.playboard.texture); + glBindVertexArray(ui->board.skin.playboard.vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + + glBindTexture(GL_TEXTURE_2D, 0); + + glBindTexture(GL_TEXTURE_2D, ui->board.skin.overlay.texture); + glBindVertexArray(ui->board.skin.overlay.vao); + + for (int y = 0; y < ui->board.game.config.board_visible + 1; y++) { + GLfloat height = ui->board.block_height; + GLfloat y_pos = (ui->board.y_offset - ui->board.block_height) + (y * ui->board.block_height); + if (y == 0) { + ui->board.skin.overlay.vertices[4] = ui->board.skin.overlay.vertices[9] = 0.6f; + height = 10 * RES_SCALE; + y_pos += 15 * RES_SCALE; + } + set_shine(&ui->board.skin.overlay, ui->board.skin.overlay_shine); + update_rect(&ui->board.skin.overlay, ui->board.x_offset, + y_pos, ui->board.block_width * ui->board.game.config.board_x, + height, ui->window_width, + ui->window_height); + if (ui->board.skin.overlay_shine > 0) + ui->board.skin.overlay_shine -= 0.00025f; + if (y == 0) + ui->board.skin.overlay.vertices[4] = ui->board.skin.overlay.vertices[9] = 0.0f; + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + + glBindTexture(GL_TEXTURE_2D, 0); + + glBindTexture(GL_TEXTURE_2D, ui->board.skin.block.texture); + for (int i = 0; i < ui->board.board_count; i++) { + glBindVertexArray(ui->board.board[i].vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + + for (int i = 0; i < 4; i++) { + if (ui->board.current[i].visable) { + glBindVertexArray(ui->board.current[i].vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + if (ui->board.ghost[i].visable) { + glBindVertexArray(ui->board.ghost[i].vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + } + + glBindTexture(GL_TEXTURE_2D, 0); + + glBindTexture(GL_TEXTURE_2D, ui->board.skin.border.texture); + glBindVertexArray(ui->board.skin.border.vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + + glBindTexture(GL_TEXTURE_2D, 0); +} + +void draw_held_piece(cetris_ui *ui) { + if (!ui->board.game.piece_held) return; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, ui->board.skin.block.texture); + glBindVertexArray(ui->board.skin.block.vao); + + for (int s = 0; s < 4; s++) { + for (int j = 0; j < 4; j++) { + if ((ui->board.game.held.m[s]>>(3 - j))&1) { + GLfloat block_x = + ui->board.held.x_offset + (j * ui->board.held.block_width); + GLfloat block_y = + ui->board.held.y_offset + (s * ui->board.held.block_height); + + if (ui->board.game.held.t == MINO_O) { + block_x -= ui->board.held.block_width / 1.5f; + } + if (ui->board.game.held.t == MINO_I) { + block_x -= ui->board.held.block_width / 1.5f; + } + + set_block_texture(&ui->board.skin.block, ui->board.game.held.t); + update_rect(&ui->board.skin.block, block_x, block_y, + ui->board.held.block_width, ui->board.held.block_height, + ui->window_width, ui->window_height); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + } + } + glBindTexture(GL_TEXTURE_2D, 0); +} + + +void draw_piece_queue(cetris_ui *ui) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, ui->board.skin.block.texture); + glBindVertexArray(ui->board.skin.block.vao); + + for (int i = 0; i < 5; i++) { + int index = (ui->board.game.current_index + i); + int mino; + + if (index <= 6) { + mino = ui->board.game.piece_queue[index]; + } else { + index = index % 7; + mino = ui->board.game.next_queue[index]; + } + + for (int s = 0; s < 4; s++) { + for (int j = 0; j < 4; j++) { + + if ((default_matrices[mino][s]>>(3 - j))&1) { + GLfloat block_x = + ui->board.queue.x_offset + (j * ui->board.queue.block_width); + GLfloat block_y = + ui->board.queue.y_offset + (ui->board.queue.h * (i / 5.0)) + (s * ui->board.queue.block_height); + + if (ui->board.game.held.t == MINO_O) { + block_x -= ui->board.queue.block_width / 1.5f; + } + if (ui->board.game.held.t == MINO_I) { + block_x -= ui->board.queue.block_width / 1.5f; + } + + set_block_texture(&ui->board.skin.block, mino); + update_rect(&ui->board.skin.block, block_x, block_y, + ui->board.queue.block_width, ui->board.queue.block_height, + ui->window_width, ui->window_height); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + } + } + } + glBindTexture(GL_TEXTURE_2D, 0); +} diff --git a/frontends/gl/drawable.h b/frontends/gl/drawable.h index 21ae453..3c3f6a5 100644 --- a/frontends/gl/drawable.h +++ b/frontends/gl/drawable.h @@ -12,6 +12,8 @@ typedef struct { GLfloat w; GLfloat h; + bool visable; + GLfloat *vertices; } drawable_t; diff --git a/frontends/gl/events.c b/frontends/gl/events.c index 4faee32..8d7fa32 100644 --- a/frontends/gl/events.c +++ b/frontends/gl/events.c @@ -20,15 +20,17 @@ void handle_game_event(cetris_ui *ui) { cetris_start_game(&ui->board.game); } - if (ui->board.game.lock_event > 0) { + if (!ui->board.game.lock_event.processed) { Mix_PlayChannel( 1, ui->board.skin.lock_sound, 0 ); - ui->board.game.lock_event--; + ui->board.game.lock_event.processed = true; + ui->board.lock_current = true; } if (ui->board.game.line_event > 0) { int index = ui->board.game.line_event - 1; ui->board.skin.overlay_shine = 0.25f; Mix_PlayChannel( 1, ui->board.skin.clear_sound[index], 0 ); + ui->board.refresh_board = true; ui->board.game.line_event = 0; } @@ -49,6 +51,7 @@ void handle_game_event(cetris_ui *ui) { if (ui->board.game.move_event > 0) { Mix_PlayChannel( 0, ui->board.skin.move_sound, 0); + ui->board.update_current = true; ui->board.game.move_event--; } } diff --git a/frontends/gl/main.c b/frontends/gl/main.c index f245932..89fffdd 100644 --- a/frontends/gl/main.c +++ b/frontends/gl/main.c @@ -147,7 +147,7 @@ int main(void) { printf("error\n"); } - Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 512); + Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 256); Mix_AllocateChannels(4); Mix_Volume(0, 20); Mix_Volume(1, 70); diff --git a/frontends/gl/ui.c b/frontends/gl/ui.c index d005ac8..470ad4a 100644 --- a/frontends/gl/ui.c +++ b/frontends/gl/ui.c @@ -6,6 +6,13 @@ #define RES_SCALE 1.2 +void refresh_current(cetris_ui *ui) { + for (int i = 0; i < 4; i++) { + ui->board.ghost[i].visable = false; + ui->board.current[i].visable = false; + } +} + void load_tetris_board(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat y, GLfloat w, GLfloat h) { board->block_width = w / (GLfloat)board->game.config.board_x; board->block_height = h / board->game.config.board_visible; @@ -13,6 +20,24 @@ void load_tetris_board(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat board->x_offset = x; board->y_offset = y; board->block_offset = (board->game.config.board_y - board->game.config.board_visible); + + board->board_count = 0; + board->board = malloc(sizeof(drawable_t) * 100); + memset(board->board, 0, sizeof(drawable_t) * 100); + + board->update_current = false; + board->lock_current = false; + board->refresh_board = false; + + memset(&ui->board.current, 0, sizeof(drawable_t) * 4); + memset(&ui->board.ghost, 0, sizeof(drawable_t) * 4); + + for (int i = 0; i < 4; i++) { + new_rectangle(&ui->board.current[i]); + new_rectangle(&ui->board.ghost[i]); + } + + refresh_current(ui); update_rect(&board->skin.playboard, board->x_offset, board->y_offset - 10 * RES_SCALE, board->game.config.board_x * board->block_width, @@ -43,8 +68,111 @@ void load_piece_queue(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat y board->queue.y_offset = y; } +// TODO: make this better +void update_current_drawable(cetris_ui *ui, drawable_t *current, drawable_t* ghost) { + refresh_current(ui); + int cur_piece = -1; + for (int s = 0; s < 4; s++) { + for (int j = 0; j < 4; j++) { + if ((ui->board.game.current.m[s]>>(3 - j))&1) { + cur_piece++; + + GLfloat block_x = + ui->board.x_offset + + (j + ui->board.game.current.pos.x) * ui->board.block_width; + + if (ghost) { + GLfloat ghost_y = + ui->board.y_offset + + (s + ui->board.game.current.ghost_y - ui->board.block_offset) + * ui->board.block_height; + + ghost[cur_piece].visable = true; + set_block_texture(&ghost[cur_piece], ui->board.game.current.t + 7); + update_rect(&ghost[cur_piece], block_x, ghost_y, + ui->board.block_width, ui->board.block_height, + ui->window_width, ui->window_height); + } + + if (s + ui->board.game.current.pos.y < ui->board.block_offset - 1) continue; + + GLfloat block_y = + ui->board.y_offset + + (s + ui->board.game.current.pos.y - ui->board.block_offset) + * ui->board.block_height; + + current[cur_piece].visable = true; + set_block_texture(¤t[cur_piece], ui->board.game.current.t); + update_rect(¤t[cur_piece], block_x, block_y, + ui->board.block_width, ui->board.block_height, + ui->window_width, ui->window_height); + + } + } + } +} + +void lock_current_drawable(cetris_ui *ui) { + for (int i = 0; i < 4; i++) { + new_rectangle(&ui->board.board[ui->board.board_count + i]); + } + + int current = 0; + for (int s = 0; s < 4; s++) { + for (int j = 0; j < 4; j++) { + if ((ui->board.game.lock_event.m[s]>>(3 - j))&1) { + GLfloat block_x = + ui->board.x_offset + + (j + ui->board.game.lock_event.pos.x) * ui->board.block_width; + + GLfloat block_y = + ui->board.y_offset + + (s + ui->board.game.lock_event.pos.y - ui->board.block_offset) + * ui->board.block_height; + + set_block_texture(&ui->board.board[ui->board.board_count + current], ui->board.game.lock_event.t); + update_rect(&ui->board.board[ui->board.board_count + current], block_x, block_y, + ui->board.block_width, ui->board.block_height, + ui->window_width, ui->window_height); + + ui->board.board_count++; + } + } + } +} + +void refresh_board(cetris_ui *ui) { + ui->board.board_count = 0; + for (int s = 0; s < ui->board.game.config.board_x; s++) { + for (int j = 0; j < ui->board.game.config.board_y; j++) { + if (ui->board.game.board[s][j] & SLOT_OCCUPIED) { + set_block_texture(&ui->board.board[ui->board.board_count], ui->board.game.board[s][j] >> 5); + update_rect(&ui->board.board[ui->board.board_count++], + ui->board.x_offset + (s * ui->board.block_width), + ui->board.y_offset + ((j - ui->board.block_offset) * ui->board.block_height), + ui->board.block_width, ui->board.block_height, + ui->window_width, ui->window_height); + } + } + } +} void draw_tetris_board(cetris_ui *ui) { + if (ui->board.update_current) { + update_current_drawable(ui, &ui->board.current[0], &ui->board.ghost[0]); + ui->board.update_current = false; + } + + if (ui->board.lock_current) { + lock_current_drawable(ui); + ui->board.lock_current = false; + } + + if (ui->board.refresh_board) { + refresh_board(ui); + ui->board.refresh_board = false; + } + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, ui->board.skin.background.texture); @@ -85,63 +213,22 @@ void draw_tetris_board(cetris_ui *ui) { glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, ui->board.skin.block.texture); - - glBindVertexArray(ui->board.skin.block.vao); - for (int x = 0; x < ui->board.game.config.board_x; x++) { - for (int y = ui->board.game.highest_line; y < ui->board.game.config.board_y; y++) { - if (ui->board.game.board[x][y] & SLOT_OCCUPIED) { - set_block_texture(&ui->board.skin.block, (ui->board.game.board[x][y] >> 5)); - - if (y < ui->board.block_offset - 1) continue; - - update_rect(&ui->board.skin.block, - ui->board.x_offset + (x * ui->board.block_width), - ui->board.y_offset + ((y - ui->board.block_offset) * ui->board.block_height), - ui->board.block_width, ui->board.block_height, - ui->window_width, ui->window_height); - - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - } - } + for (int i = 0; i < ui->board.board_count; i++) { + glBindVertexArray(ui->board.board[i].vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } - for (int s = 0; s < 4; s++) { - for (int j = 0; j < 4; j++) { - if ((ui->board.game.current.m[s]>>(3 - j))&1) { - GLfloat block_x = - ui->board.x_offset + - (j + ui->board.game.current.pos.x) * ui->board.block_width; - - GLfloat ghost_y = - ui->board.y_offset + - (s + ui->board.game.current.ghost_y - ui->board.block_offset) - * ui->board.block_height; - - set_block_texture(&ui->board.skin.block, ui->board.game.current.t + 7); - update_rect(&ui->board.skin.block, block_x, ghost_y, - ui->board.block_width, ui->board.block_height, - ui->window_width, ui->window_height); - - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - - if (s + ui->board.game.current.pos.y < ui->board.block_offset - 1) continue; - - GLfloat block_y = - ui->board.y_offset + - (s + ui->board.game.current.pos.y - ui->board.block_offset) - * ui->board.block_height; - - set_block_texture(&ui->board.skin.block, ui->board.game.current.t); - update_rect(&ui->board.skin.block, block_x, block_y, - ui->board.block_width, ui->board.block_height, - ui->window_width, ui->window_height); - - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - } + for (int i = 0; i < 4; i++) { + if (ui->board.current[i].visable) { + glBindVertexArray(ui->board.current[i].vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + } + if (ui->board.ghost[i].visable) { + glBindVertexArray(ui->board.ghost[i].vao); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } } + glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, ui->board.skin.border.texture); diff --git a/frontends/gl/ui.h b/frontends/gl/ui.h index 7b82a51..4606c4d 100644 --- a/frontends/gl/ui.h +++ b/frontends/gl/ui.h @@ -33,6 +33,16 @@ typedef struct { GLfloat y_offset; cetris_game game; + + drawable_t *board; + int board_count; + + bool lock_current; + bool update_current; + bool refresh_board; + + drawable_t current[4]; + drawable_t ghost[4]; held_piece_t held; piece_queue_t queue; @@ -68,6 +78,7 @@ void draw_tetris_board(cetris_ui *ui); void draw_held_piece(cetris_ui *ui); void draw_piece_queue(cetris_ui *ui); void draw_current(cetris_ui *ui); +void update_board_drawables(cetris_ui *ui); void load_tetris_board(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat y, GLfloat w, GLfloat h); void load_held_piece(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat y, GLfloat w, GLfloat h); void load_piece_queue(cetris_ui *ui, tetris_board_t *board, GLfloat x, GLfloat y, GLfloat w, GLfloat h); diff --git a/lib/cetris.c b/lib/cetris.c index 14c3a45..8be2b44 100644 --- a/lib/cetris.c +++ b/lib/cetris.c @@ -226,7 +226,11 @@ static void lock_current(cetris_game *g) { g->highest_line = g->current.pos.y; } - g->lock_event++; + g->lock_event.processed = false; + g->lock_event.pos = g->current.pos; + g->lock_event.t = g->current.t; + memcpy(&g->lock_event.m, &g->current.m, sizeof(piece_matrix)); + g->current.locked = true; update_board(g); } @@ -330,6 +334,8 @@ static void rotate_piece(cetris_game *g, bool clockwise) { } } + g->move_event++; + g->current.r = next; memcpy(g->current.m, &m, sizeof(piece_matrix)); update_board(g); diff --git a/lib/cetris.h b/lib/cetris.h index 3db7d37..b03f9fd 100644 --- a/lib/cetris.h +++ b/lib/cetris.h @@ -71,6 +71,13 @@ typedef struct { piece_matrix m; } tetrimino; +typedef struct { + vec2 pos; + uint8_t t; + piece_matrix m; + bool processed; +} lock_event_t; + typedef struct cetris_game cetris_game; typedef struct { @@ -146,10 +153,11 @@ struct cetris_game { // events uint8_t move_event; - uint8_t line_event; uint8_t combo_event; - uint8_t lock_event; uint8_t tetris_event; + uint8_t line_event; + + lock_event_t lock_event; // scoring flags bool tspin; -- cgit v1.2.3-101-g0448