Mercurial > molko
changeset 74:4991bf5f2343
core: implement inhibit system, closes #2468 @1h
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 31 Jan 2020 13:47:49 +0100 |
parents | b49d8475a611 |
children | ac97053d8e2e |
files | Makefile src/adventure/main.c src/core/game.c src/core/game.h src/core/inhibit.c src/core/inhibit.h src/core/painter.h |
diffstat | 7 files changed, 162 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Fri Jan 31 08:09:05 2020 +0100 +++ b/Makefile Fri Jan 31 13:47:49 2020 +0100 @@ -32,6 +32,7 @@ src/core/font.c \ src/core/game.c \ src/core/image.c \ + src/core/inhibit.c \ src/core/map.c \ src/core/map_state.c \ src/core/message.c \
--- a/src/adventure/main.c Fri Jan 31 08:09:05 2020 +0100 +++ b/src/adventure/main.c Fri Jan 31 13:47:49 2020 +0100 @@ -26,6 +26,7 @@ #include "font.h" #include "game.h" #include "image.h" +#include "inhibit.h" #include "map.h" #include "map_state.h" #include "message.h" @@ -99,11 +100,19 @@ wait_action(&w, &ac); script_append(&sc, &ac); + /* Inhibit input. */ + inhibit_action(INHIBIT_STATE_INPUT, &ac); + script_append(&sc, &ac); + message_start(&msg); message_action(&msg, &ac); ac.end = myresult; + script_append(&sc, &ac); + /* Put it back. */ + inhibit_action(INHIBIT_NONE, &ac); script_append(&sc, &ac); + script_start(&sc); script_action(&sc, &ac);
--- a/src/core/game.c Fri Jan 31 08:09:05 2020 +0100 +++ b/src/core/game.c Fri Jan 31 13:47:49 2020 +0100 @@ -24,10 +24,7 @@ #include "state.h" #include "painter.h" -struct game game = { - .state = NULL, - .state_next = NULL -}; +struct game game; static struct action * find_empty_action(void) @@ -73,6 +70,7 @@ continue; if (a->update(a, ticks)) { + puts("HERE ACTION HAS FINISHED"); if (a->end) a->end(a); if (a->finish) @@ -109,7 +107,7 @@ { assert(event); - if (game.state) + if (game.state && !(game.inhibit & INHIBIT_STATE_INPUT)) game.state->handle(event); handle_actions(event); @@ -118,30 +116,32 @@ void game_update(unsigned int ticks) { - /* Change state if any. */ - if (game.state_next) { - /* Inform the current state we're gonna leave it. */ - if (game.state) - game.state->leave(); + if (!(game.inhibit & INHIBIT_STATE_UPDATE)) { + /* Change state if any. */ + if (game.state_next) { + /* Inform the current state we're gonna leave it. */ + if (game.state) + game.state->leave(); - game.state = game.state_next; - game.state->enter(); - game.state_next = NULL; + game.state = game.state_next; + game.state->enter(); + game.state_next = NULL; - /* Remove any actions that must be deleted. */ - clear_actions(); + /* Remove any actions that must be deleted. */ + clear_actions(); + } + + if (game.state) + game.state->update(ticks); } - if (game.state) - game.state->update(ticks); - update_actions(ticks); } void game_draw(void) { - if (game.state) + if (game.state && !(game.inhibit & INHIBIT_STATE_DRAW)) game.state->draw(); draw_actions();
--- a/src/core/game.h Fri Jan 31 08:09:05 2020 +0100 +++ b/src/core/game.h Fri Jan 31 13:47:49 2020 +0100 @@ -27,11 +27,12 @@ #include <stdbool.h> #include "action.h" +#include "inhibit.h" /** * \brief Max number of actions allowed at the same time. */ -#define GAME_ACTIONS_MAX 32 +#define GAME_ACTIONS_MAX 128 struct state; @@ -41,6 +42,9 @@ * \brief Main game object. */ struct game { + /* Inhibition */ + enum inhibit inhibit; /*!< (RW) What to disable. */ + /* Game states. */ struct state *state; /*!< (RO) Current state */ struct state *state_next; /*!< (RO) Next state */ @@ -57,9 +61,8 @@ /** * Request to change state. * - * This function will only update state after the next \a game_update call. - * - * If quick is true, change state immediately. + * This function will only update state after the next \ref game_update call + * unless quick is set to true. * * \pre state != NULL * \param state the new state @@ -98,6 +101,7 @@ * * \pre action != NULL * \param action the action to copy + * \note The core API **never** add actions by itself. */ void game_add_action(const struct action *action);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/inhibit.c Fri Jan 31 13:47:49 2020 +0100 @@ -0,0 +1,53 @@ +/* + * inhibit.c -- disable specific game behavior + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "action.h" +#include "inhibit.h" +#include "game.h" +#include "util.h" + +static bool +update(struct action *a, unsigned int ticks) +{ + (void)ticks; + + game.inhibit = *((enum inhibit *)a->data); + + return true; +} + +static void +finish(struct action *a) +{ + free(a->data); +} + +void +inhibit_action(enum inhibit mode, struct action *a) +{ + assert(a); + + memset(a, 0, sizeof (struct action)); + a->data = ememdup(&mode, sizeof (enum inhibit)); + a->update = update; + a->finish = finish; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/inhibit.h Fri Jan 31 13:47:49 2020 +0100 @@ -0,0 +1,68 @@ +/* + * inhibit.h -- disable specific game behavior + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_INHIBIT_H +#define MOLKO_INHIBIT_H + +/** + * \file inhibit.h + * \brief Disable specific game behavior. + */ + +struct action; + +/** + * \brief Game inhibition. + * + * This enum is used to alter the game behavior. + */ +enum inhibit { + /** + * Nothing. + */ + INHIBIT_NONE, + + /** + * Disable input handling in current state. + */ + INHIBIT_STATE_INPUT = (1 << 0), + + /** + * Disable current state updates. + */ + INHIBIT_STATE_UPDATE = (1 << 1), + + /** + * Disable current state rendering. + */ + INHIBIT_STATE_DRAW = (1 << 2) +}; + +/** + * Create an action to inhibit the system. + * + * The mode will replace the actual inhibit modes rather than adding new flags. + * + * \pre a != NULL + * \param mode the new mode + * \param a the action to fill + */ +void +inhibit_action(enum inhibit mode, struct action *a); + +#endif /* !MOLKO_INHIBIT_H */
--- a/src/core/painter.h Fri Jan 31 08:09:05 2020 +0100 +++ b/src/core/painter.h Fri Jan 31 13:47:49 2020 +0100 @@ -48,8 +48,8 @@ * If texture is NULL, use default context aka the window. * * \param tex the texture - * \see PAINTER_BEGIN - * \see PAINTER_END + * \see \ref PAINTER_BEGIN + * \see \ref PAINTER_END */ void painter_set_target(struct texture *tex); @@ -120,7 +120,7 @@ * * \pre tex != NULL * \param tex the texture to use - * \see PAINTER_END + * \see \ref PAINTER_END */ #define PAINTER_BEGIN(tex ) \ do { \ @@ -132,7 +132,7 @@ /** * Use this macro at the end of rendering into a given texture. * - * \see PAINTER_BEGIN + * \see \ref PAINTER_BEGIN */ #define PAINTER_END() \ painter_set_target(__current_texture__); \