diff options
author | Richard Braun <rbraun@sceen.net> | 2025-07-07 23:20:36 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2025-07-07 23:33:24 +0200 |
commit | bad173c52be8ebfe75a4a46465b2d89669432246 (patch) | |
tree | 1757009d45d2fbbf97d5d63fc00809d2775aca1e | |
parent | ec598949b407d86d0d35548566c70c18fbce76aa (diff) |
Update embedded invadersdev/et
-rw-r--r-- | src/eetg.c | 28 | ||||
-rw-r--r-- | src/eetg.h | 4 | ||||
-rw-r--r-- | src/ei/ei.c | 89 |
3 files changed, 72 insertions, 49 deletions
@@ -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; } @@ -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; } |