Mercurial > molko
diff src/game.c @ 57:9f6267843815
core: implement basic actions, closes #2463 @1h
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 21 Jan 2020 12:28:26 +0100 |
parents | e10fd1b6323f |
children | d7d88ac30611 |
line wrap: on
line diff
--- a/src/game.c Tue Jan 21 12:26:49 2020 +0100 +++ b/src/game.c Tue Jan 21 12:28:26 2020 +0100 @@ -18,6 +18,7 @@ #include <assert.h> #include <stddef.h> +#include <string.h> #include "game.h" #include "state.h" @@ -27,19 +28,81 @@ .state_next = NULL }; +static struct action * +find_empty_action(void) +{ + static struct action null; + + for (size_t i = 0; i < GAME_ACTIONS_MAX; ++i) + if (memcmp(&game.actions[i], &null, sizeof (struct action)) == 0) + return &game.actions[i]; + + return NULL; +} + +static void +clear_actions(void) +{ + for (size_t i = 0; i < GAME_ACTIONS_MAX; ++i) { + struct action *a = &game.actions[i]; + + /* These actions are removed on state change. */ + if (a->flags & ACTION_AUTO_LEAVE) { + if (a->finish) + a->finish(a); + + memset(a, 0, sizeof (struct action)); + } + } +} + +static void +handle_actions(const union event *event) +{ + for (size_t i = 0; i < GAME_ACTIONS_MAX; ++i) + if (game.actions[i].handle) + game.actions[i].handle(&game.actions[i], event); +} + +static void +update_actions(unsigned int ticks) +{ + for (size_t i = 0; i < GAME_ACTIONS_MAX; ++i) { + struct action *a = &game.actions[i]; + + if (!a->update) + continue; + + if (a->update(a, ticks)) { + if (a->finish) + a->finish(a); + + memset(&game.actions[i], 0, sizeof (struct action)); + } + } +} + void -game_switch(struct state *state) +game_switch(struct state *state, bool quick) { assert(state); - game.state_next = state; + if (quick) { + game.state = state; + game.state->enter(); + } else + game.state_next = state; } void game_handle(const union event *event) { + assert(event); + if (game.state) game.state->handle(event); + + handle_actions(event); } void @@ -54,10 +117,15 @@ game.state = game.state_next; game.state->enter(); game.state_next = NULL; + + /* Remove any actions that must be deleted. */ + clear_actions(); } if (game.state) game.state->update(ticks); + + update_actions(ticks); } void @@ -66,3 +134,14 @@ if (game.state) game.state->draw(); } + +void +game_add_action(const struct action *action) +{ + assert(action); + + struct action *pos; + + if ((pos = find_empty_action())) + memcpy(pos, action, sizeof (struct action)); +}