comparison 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
comparison
equal deleted inserted replaced
56:43d1102a367e 57:9f6267843815
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19 #include <assert.h> 19 #include <assert.h>
20 #include <stddef.h> 20 #include <stddef.h>
21 #include <string.h>
21 22
22 #include "game.h" 23 #include "game.h"
23 #include "state.h" 24 #include "state.h"
24 25
25 struct game game = { 26 struct game game = {
26 .state = NULL, 27 .state = NULL,
27 .state_next = NULL 28 .state_next = NULL
28 }; 29 };
29 30
31 static struct action *
32 find_empty_action(void)
33 {
34 static struct action null;
35
36 for (size_t i = 0; i < GAME_ACTIONS_MAX; ++i)
37 if (memcmp(&game.actions[i], &null, sizeof (struct action)) == 0)
38 return &game.actions[i];
39
40 return NULL;
41 }
42
43 static void
44 clear_actions(void)
45 {
46 for (size_t i = 0; i < GAME_ACTIONS_MAX; ++i) {
47 struct action *a = &game.actions[i];
48
49 /* These actions are removed on state change. */
50 if (a->flags & ACTION_AUTO_LEAVE) {
51 if (a->finish)
52 a->finish(a);
53
54 memset(a, 0, sizeof (struct action));
55 }
56 }
57 }
58
59 static void
60 handle_actions(const union event *event)
61 {
62 for (size_t i = 0; i < GAME_ACTIONS_MAX; ++i)
63 if (game.actions[i].handle)
64 game.actions[i].handle(&game.actions[i], event);
65 }
66
67 static void
68 update_actions(unsigned int ticks)
69 {
70 for (size_t i = 0; i < GAME_ACTIONS_MAX; ++i) {
71 struct action *a = &game.actions[i];
72
73 if (!a->update)
74 continue;
75
76 if (a->update(a, ticks)) {
77 if (a->finish)
78 a->finish(a);
79
80 memset(&game.actions[i], 0, sizeof (struct action));
81 }
82 }
83 }
84
30 void 85 void
31 game_switch(struct state *state) 86 game_switch(struct state *state, bool quick)
32 { 87 {
33 assert(state); 88 assert(state);
34 89
35 game.state_next = state; 90 if (quick) {
91 game.state = state;
92 game.state->enter();
93 } else
94 game.state_next = state;
36 } 95 }
37 96
38 void 97 void
39 game_handle(const union event *event) 98 game_handle(const union event *event)
40 { 99 {
100 assert(event);
101
41 if (game.state) 102 if (game.state)
42 game.state->handle(event); 103 game.state->handle(event);
104
105 handle_actions(event);
43 } 106 }
44 107
45 void 108 void
46 game_update(unsigned int ticks) 109 game_update(unsigned int ticks)
47 { 110 {
52 game.state->leave(); 115 game.state->leave();
53 116
54 game.state = game.state_next; 117 game.state = game.state_next;
55 game.state->enter(); 118 game.state->enter();
56 game.state_next = NULL; 119 game.state_next = NULL;
120
121 /* Remove any actions that must be deleted. */
122 clear_actions();
57 } 123 }
58 124
59 if (game.state) 125 if (game.state)
60 game.state->update(ticks); 126 game.state->update(ticks);
127
128 update_actions(ticks);
61 } 129 }
62 130
63 void 131 void
64 game_draw(void) 132 game_draw(void)
65 { 133 {
66 if (game.state) 134 if (game.state)
67 game.state->draw(); 135 game.state->draw();
68 } 136 }
137
138 void
139 game_add_action(const struct action *action)
140 {
141 assert(action);
142
143 struct action *pos;
144
145 if ((pos = find_empty_action()))
146 memcpy(pos, action, sizeof (struct action));
147 }