Mercurial > molko
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 } |