summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2025-05-20 00:12:44 +0200
committerRichard Braun <rbraun@sceen.net>2025-05-20 00:12:44 +0200
commit06bce90b0fda8d7ff48d7ec5de2b34212f428e60 (patch)
tree16ee99438be099a76b9967706dbd24414de8bcb2
parentb3347b6be13139b10b87b97793f2f5ec9243b33a (diff)
Add swapping, but this needs to be improved
-rw-r--r--src/eetg.c4
-rw-r--r--src/et/et.c125
-rw-r--r--src/et/et.h1
3 files changed, 98 insertions, 32 deletions
diff --git a/src/eetg.c b/src/eetg.c
index 1b317fa..8a95ede 100644
--- a/src/eetg.c
+++ b/src/eetg.c
@@ -187,6 +187,10 @@ eetg_layer_remove(struct eetg_layer *layer, struct eetg_object *object)
assert(layer);
assert(object);
+ if (!layer->objects) {
+ return false;
+ }
+
if (layer->objects == object) {
layer->objects = object->next;
return true;
diff --git a/src/et/et.c b/src/et/et.c
index d628ac1..d58b684 100644
--- a/src/et/et.c
+++ b/src/et/et.c
@@ -43,10 +43,13 @@
#define ET_FRAME_WIDTH 10
#define ET_FRAME_HEIGHT 20
-#define ET_NEXT_QUEUE_HSPACE 10
+#define ET_NEXT_QUEUE_HSPACE ((ET_FRAME_WIDTH * 2) + 10)
#define ET_NEXT_QUEUE_VSPACE 5
#define ET_NEXT_QUEUE_PIECE_HEIGHT 3
+#define ET_HELD_PIECE_HSPACE (-20)
+#define ET_HELD_PIECE_VSPACE 5
+
#define ET_CURRENT_PIECE_SPEED 1
#define ET_LOCKDOWN_DELAY 2
@@ -754,7 +757,7 @@ et_game_prepare(struct et_game *game)
}
static struct et_piece *
-et_game_get_next_piece(struct et_game *game)
+et_game_get_piece_from_bag(struct et_game *game)
{
struct et_piece *piece;
@@ -790,7 +793,7 @@ et_game_end(struct et_game *game)
}
static void
-et_game_repaint_queue(struct et_game *game)
+et_game_repaint_next_queue(struct et_game *game)
{
assert(game);
@@ -800,8 +803,9 @@ et_game_repaint_queue(struct et_game *game)
int index, x, y;
index = (game->next_index + i) % ARRAY_SIZE(game->next_pieces);
- x = ET_FRAME_X + (ET_FRAME_WIDTH * 2) + ET_NEXT_QUEUE_HSPACE;
- y = ET_FRAME_Y + ET_NEXT_QUEUE_VSPACE + (i * ET_NEXT_QUEUE_PIECE_HEIGHT);
+ x = ET_FRAME_X + ET_NEXT_QUEUE_HSPACE;
+ y = ET_FRAME_Y + ET_NEXT_QUEUE_VSPACE
+ + (i * ET_NEXT_QUEUE_PIECE_HEIGHT);
object = et_piece_get_object(game->next_pieces[index]);
world = eetg_object_get_world(object);
@@ -809,13 +813,45 @@ et_game_repaint_queue(struct et_game *game)
if (world) {
eetg_object_move(object, x, y);
} else {
- eetg_world_add(&game->world, object, x, y, 1);
+ eetg_world_add(&game->world, object, x, y, 0);
}
}
}
+static struct et_piece *
+et_game_get_next_piece(struct et_game *game)
+{
+ struct et_piece *piece;
+
+ assert(game);
+
+ piece = game->next_pieces[game->next_index];
+ game->next_pieces[game->next_index] = et_game_get_piece_from_bag(game);
+ game->next_index = (game->next_index + 1) % ARRAY_SIZE(game->next_pieces);
+
+ eetg_world_remove(&game->world, et_piece_get_object(piece));
+ et_game_repaint_next_queue(game);
+
+ return piece;
+}
+
+static void
+et_game_repaint_held_piece(struct et_game *game)
+{
+ struct eetg_object *object;
+ int x, y;
+
+ assert(game);
+
+ x = ET_FRAME_X + ET_HELD_PIECE_HSPACE;
+ y = ET_FRAME_Y + ET_HELD_PIECE_VSPACE;
+
+ object = et_piece_get_object(game->held_piece);
+ eetg_world_add(&game->world, object, x, y, 0);
+}
+
static void
-et_game_switch_to_next_piece(struct et_game *game)
+et_game_set_current_piece(struct et_game *game, struct et_piece *piece)
{
struct eetg_object *object;
int width, x;
@@ -823,22 +859,18 @@ et_game_switch_to_next_piece(struct et_game *game)
assert(game);
- game->current_piece = game->next_pieces[game->next_index];
+ game->current_piece = piece;
+ game->current_piece_swapped = false;
+
object = et_piece_get_object(game->current_piece);
width = eetg_object_get_width(object) / 2;
x = ET_FRAME_X + (((ET_FRAME_WIDTH - width) / 2) * 2);
- hit = eetg_object_move(object, x, ET_FRAME_Y);
+ hit = eetg_world_add(&game->world, object, x, ET_FRAME_Y, 1);
if (hit) {
et_game_end(game);
- return;
}
-
- game->next_pieces[game->next_index] = et_game_get_next_piece(game);
- game->next_index = (game->next_index + 1) % ARRAY_SIZE(game->next_pieces);
-
- et_game_repaint_queue(game);
}
static bool
@@ -971,14 +1003,16 @@ et_game_start(struct et_game *game)
et_bag_init(&game->bag);
for (size_t i = 0; i < ARRAY_SIZE(game->next_pieces); i++) {
- game->next_pieces[i] = et_game_get_next_piece(game);
+ game->next_pieces[i] = et_game_get_piece_from_bag(game);
}
- et_game_repaint_queue(game);
+ et_game_repaint_next_queue(game);
game->held_piece = NULL;
game->current_piece = NULL;
+ et_game_set_current_piece(game, et_game_get_next_piece(game));
+
eetg_world_add(&game->world, &game->left_wall,
ET_FRAME_X - 2, ET_FRAME_Y, 0);
eetg_world_add(&game->world, &game->bg,
@@ -988,13 +1022,12 @@ et_game_start(struct et_game *game)
eetg_world_add(&game->world, &game->bottom_wall, ET_FRAME_X - 2,
ET_FRAME_Y + ET_FRAME_HEIGHT, 0);
- et_game_switch_to_next_piece(game);
-
game->gravity_counter_reload = ET_FPS / ET_CURRENT_PIECE_SPEED;
game->gravity_counter = game->gravity_counter_reload;
game->lockdown_counter_reload = ET_FPS / ET_LOCKDOWN_DELAY;
game->nr_lockdown_moves = -1;
game->next_index = 0;
+ game->current_piece_swapped = false;
game->state = ET_STATE_PLAYING;
}
@@ -1043,6 +1076,29 @@ et_game_process_intro_input(struct et_game *game, char c)
}
static void
+et_game_move_current_piece(struct et_game *game)
+{
+ bool hit;
+
+ assert(game);
+
+ assert(game->gravity_counter > 0);
+ game->gravity_counter--;
+
+ if (game->gravity_counter != 0) {
+ return;
+ }
+
+ game->gravity_counter = game->gravity_counter_reload;
+
+ hit = et_piece_move_down(game->current_piece);
+
+ if (hit) {
+ et_game_start_lockdown(game, false);
+ }
+}
+
+static void
et_game_drop_current_piece(struct et_game *game)
{
bool hit;
@@ -1057,26 +1113,29 @@ et_game_drop_current_piece(struct et_game *game)
}
static void
-et_game_move_current_piece(struct et_game *game)
+et_game_hold_current_piece(struct et_game *game)
{
- bool hit;
+ struct et_piece *current_piece;
assert(game);
- assert(game->gravity_counter > 0);
- game->gravity_counter--;
-
- if (game->gravity_counter != 0) {
+ if (game->current_piece_swapped) {
return;
}
- game->gravity_counter = game->gravity_counter_reload;
+ if (game->held_piece) {
+ eetg_world_remove(&game->world, et_piece_get_object(game->held_piece));
+ } else {
+ game->held_piece = et_game_get_next_piece(game);
+ }
- hit = et_piece_move_down(game->current_piece);
+ current_piece = game->current_piece;
+ eetg_world_remove(&game->world, et_piece_get_object(current_piece));
+ et_game_set_current_piece(game, game->held_piece);
+ game->held_piece = current_piece;
+ et_game_repaint_held_piece(game);
- if (hit) {
- et_game_start_lockdown(game, false);
- }
+ game->current_piece_swapped = true;
}
static bool
@@ -1088,7 +1147,9 @@ et_game_process_game_input(struct et_game *game, char c)
return true;
}
- if (game->nr_lockdown_moves != 0) {
+ if (c == 'h') {
+ et_game_hold_current_piece(game);
+ } else if (game->nr_lockdown_moves != 0) {
if (c == 's') {
et_piece_move_left(game->current_piece);
} else if (c == 'f') {
@@ -1121,7 +1182,7 @@ et_game_lock_current_piece(struct et_game *game)
et_game_scan_rows(game);
- et_game_switch_to_next_piece(game);
+ et_game_set_current_piece(game, et_game_get_next_piece(game));
}
static void
diff --git a/src/et/et.h b/src/et/et.h
index db9dd04..673d8b0 100644
--- a/src/et/et.h
+++ b/src/et/et.h
@@ -103,6 +103,7 @@ struct et_game {
int8_t level;
int8_t sync_counter_reload;
int8_t sync_counter;
+ bool current_piece_swapped;
char status_sprite[32];
};