summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2025-07-07 23:20:36 +0200
committerRichard Braun <rbraun@sceen.net>2025-07-07 23:33:24 +0200
commitbad173c52be8ebfe75a4a46465b2d89669432246 (patch)
tree1757009d45d2fbbf97d5d63fc00809d2775aca1e
parentec598949b407d86d0d35548566c70c18fbce76aa (diff)
Update embedded invadersdev/et
-rw-r--r--src/eetg.c28
-rw-r--r--src/eetg.h4
-rw-r--r--src/ei/ei.c89
3 files changed, 72 insertions, 49 deletions
diff --git a/src/eetg.c b/src/eetg.c
index fe92ed3..b5f372b 100644
--- a/src/eetg.c
+++ b/src/eetg.c
@@ -130,6 +130,12 @@ eetg_object_check_collision(struct eetg_object *object1,
if (hit) {
return true;
}
+
+ if ((eetg_object_get_world(object1) == NULL)
+ || (eetg_object_get_world(object2) == NULL))
+ {
+ return false;
+ }
}
}
@@ -346,6 +352,8 @@ eetg_world_set_collision_fn(struct eetg_world *world,
static bool
eetg_world_scan_collisions(struct eetg_world *world, struct eetg_object *object)
{
+ bool hit = false;
+
assert(world);
assert(!world->handling_collision);
@@ -363,26 +371,28 @@ eetg_world_scan_collisions(struct eetg_world *world, struct eetg_object *object)
tmp = eetg_layer_get_objects(layer);
while (tmp) {
- if (tmp != object) {
- bool hit;
+ struct eetg_object *next;
+
+ next = tmp->next;
+ if (tmp != object) {
hit = eetg_object_check_collision(object, tmp,
world->handle_collision_fn,
world->handle_collision_fn_arg);
- if (hit) {
- world->handling_collision = false;
- return true;
+ if (hit || (eetg_object_get_world(object) == NULL)) {
+ goto out;
}
}
- tmp = tmp->next;
+ tmp = next;
}
}
+out:
world->handling_collision = false;
- return false;
+ return hit;
}
bool
@@ -402,7 +412,7 @@ eetg_world_add(struct eetg_world *world, struct eetg_object *object,
eetg_object_attach(object, world, x, y, layer_id);
hit = eetg_world_scan_collisions(world, object);
- if (hit) {
+ if (hit && (eetg_object_get_world(object) != NULL)) {
eetg_world_remove(world, object);
}
@@ -853,7 +863,7 @@ eetg_object_move(struct eetg_object *object, int x, int y)
if (object->world) {
hit = eetg_world_scan_collisions(object->world, object);
- if (hit) {
+ if (hit && object->world) {
object->x = prev_x;
object->y = prev_y;
}
diff --git a/src/eetg.h b/src/eetg.h
index 56856c8..f691894 100644
--- a/src/eetg.h
+++ b/src/eetg.h
@@ -51,6 +51,10 @@ typedef void (*eetg_write_fn)(const void *buffer, size_t size, void *arg);
*
* This function may not call any other function that could trigger
* another collision.
+ *
+ * If an object is removed from its world while handling a collision,
+ * it must persist in memory until the operation that triggered the
+ * collision is complete.
*/
typedef bool (*eetg_handle_collision_fn)(struct eetg_object *object1,
struct eetg_object *object2,
diff --git a/src/ei/ei.c b/src/ei/ei.c
index 665ebf0..4fb19c4 100644
--- a/src/ei/ei.c
+++ b/src/ei/ei.c
@@ -536,43 +536,63 @@ ei_game_update_status(struct ei_game *game)
snprintf(game->status_sprite, sizeof(game->status_sprite),
EI_STATUS_SPRITE_FORMAT, game->score, game->nr_lives);
+
+ eetg_object_update(&game->status);
}
static void
-ei_game_prepare(struct ei_game *game)
+ei_game_prepare(struct ei_game *game, bool score_reset)
{
assert(game);
eetg_world_clear(&game->world);
+ if (score_reset) {
+ game->score = 0;
+ }
+
game->state = EI_STATE_PREPARED;
}
static void
-ei_game_start(struct ei_game *game)
+ei_game_reset(struct ei_game *game)
{
assert(game);
eetg_world_clear(&game->world);
- eetg_world_add(&game->world, &game->player, 37, 23, 0);
-
- ei_game_add_bunkers(game);
- ei_game_add_aliens(game);
-
- eetg_world_add(&game->world, &game->status, 26, 0, 0);
-
+ game->sync_counter_reload = EI_FPS * 2;
+ game->sync_counter = 1;
+ game->nr_lives = EI_NR_LIVES;
game->player_missile_counter_reload = EI_FPS / EI_PLAYER_MISSILE_SPEED;
game->player_missile_counter = game->player_missile_counter_reload;
game->aliens_speed_counter_reload = EI_FPS / EI_ALIENS_SPEED;
game->aliens_speed_counter = game->aliens_speed_counter_reload;
game->first_alien_missile_counter = EI_FPS * EI_FIRST_ALIEN_MISSILE_DELAY;
game->alien_missile_counter_reload = EI_FPS / EI_ALIEN_MISSILE_SPEED;
+ game->alien_missile_counter = game->alien_missile_counter_reload;
game->ufo_counter_reload = EI_FPS / EI_UFO_SPEED;
+ game->ufo_counter = game->ufo_counter_reload;
game->nr_dead_aliens = 0;
-
+ game->state = EI_STATE_INTRO;
game->aliens_move_left = false;
game->aliens_move_down = false;
+ game->ufo_moves_left = false;
+
+ ei_game_update_status(game);
+}
+
+static void
+ei_game_start(struct ei_game *game)
+{
+ ei_game_reset(game);
+
+ eetg_world_add(&game->world, &game->player, 37, 23, 0);
+
+ ei_game_add_bunkers(game);
+ ei_game_add_aliens(game);
+
+ eetg_world_add(&game->world, &game->status, 26, 0, 0);
game->state = EI_STATE_PLAYING;
}
@@ -596,14 +616,12 @@ ei_game_kill_alien(struct ei_game *game, struct ei_alien *alien)
game->score += score;
- ei_game_update_status(game);
-
eetg_world_remove(&game->world, ei_alien_get_object(alien));
game->nr_dead_aliens++;
if (game->nr_dead_aliens == (EI_NR_ALIEN_GROUPS * EI_ALIEN_GROUP_SIZE)) {
- ei_game_prepare(game);
+ ei_game_prepare(game, false);
} else {
int aliens_speed;
@@ -633,7 +651,7 @@ ei_game_damage_bunker(struct ei_game *game, struct ei_bunker *bunker,
}
static void
-ei_game_terminate(struct ei_game *game)
+ei_game_end(struct ei_game *game)
{
assert(game);
@@ -654,11 +672,9 @@ ei_game_kill_player(struct ei_game *game, bool game_over)
game->nr_lives--;
- ei_game_update_status(game);
-
if (game_over || (game->nr_lives == 0))
{
- ei_game_terminate(game);
+ ei_game_end(game);
}
}
@@ -718,7 +734,7 @@ ei_game_handle_alien_missile_collision(struct ei_game *game,
}
}
-static void
+static bool
ei_game_handle_collision(struct eetg_object *object1,
struct eetg_object *object2,
int x, int y, void *arg)
@@ -745,17 +761,8 @@ ei_game_handle_collision(struct eetg_object *object1,
ei_game_handle_alien_missile_collision(arg, missile, other, x, y);
}
-}
-
-static void
-ei_game_reset_history(struct ei_game *game)
-{
- assert(game);
- game->score = 0;
- game->nr_lives = EI_NR_LIVES;
-
- ei_game_update_status(game);
+ return false;
}
static bool
@@ -771,8 +778,7 @@ ei_game_process_intro_input(struct ei_game *game, char c)
return false;
}
- ei_game_reset_history(game);
- ei_game_prepare(game);
+ ei_game_prepare(game, true);
return false;
}
@@ -962,7 +968,7 @@ ei_game_process_aliens(struct ei_game *game)
game_over = ei_alien_group_move_down(&game->aliens[i]);
if (game_over) {
- ei_game_terminate(game);
+ ei_game_end(game);
}
}
@@ -1095,13 +1101,6 @@ ei_game_init(struct ei_game *game, eetg_write_fn write_fn, void *arg)
{
assert(game);
- game->sync_counter_reload = EI_FPS * 2;
- game->sync_counter = 1;
-
- game->state = EI_STATE_INTRO;
-
- ei_game_reset_history(game);
-
eetg_world_init(&game->world, write_fn, arg);
eetg_world_set_collision_fn(&game->world, ei_game_handle_collision, game);
@@ -1129,12 +1128,15 @@ ei_game_init(struct ei_game *game, eetg_write_fn write_fn, void *arg)
eetg_object_init(&game->ufo, EI_TYPE_UFO, "<o~o>\n");
eetg_object_set_color(&game->ufo, EETG_COLOR_MAGENTA);
+ sprintf(game->status_sprite, "\n");
eetg_object_init(&game->status, EI_TYPE_STATUS, game->status_sprite);
eetg_object_set_color(&game->status, EETG_COLOR_RED);
eetg_object_init(&game->end_title, EI_TYPE_END_TITLE, EI_END_TITLE_SPRITE);
eetg_object_set_color(&game->end_title, EETG_COLOR_WHITE);
+ ei_game_reset(game);
+
eetg_world_add(&game->world, &game->title, 8, 1, 0);
eetg_world_add(&game->world, &game->help, 30, 16, 0);
eetg_world_add(&game->world, &game->start, 30, 20, 0);
@@ -1143,8 +1145,8 @@ ei_game_init(struct ei_game *game, eetg_write_fn write_fn, void *arg)
bool
ei_game_process(struct ei_game *game, int8_t c)
{
- bool sync = false;
- bool leave = false;
+ bool sync = false, leave = false;
+ int score = -1, nr_lives = -1;
game->sync_counter--;
@@ -1176,6 +1178,13 @@ ei_game_process(struct ei_game *game, int8_t c)
leave = ei_game_process_game_input(game, (char)c);
}
+ if ((score != game->score) || (nr_lives != game->nr_lives)) {
+ ei_game_update_status(game);
+
+ score = game->score;
+ nr_lives = game->nr_lives;
+ }
+
break;
}