Mercurial > molko
annotate libmlk-core/core/game.c @ 260:60a214ec1ab4
adventure: change the way states are stored
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 06 Dec 2020 22:50:48 +0100 |
parents | 37771eaf4245 |
children | bfde372bf152 |
rev | line source |
---|---|
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * game.c -- main game object |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr> |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
45
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
19 #include <assert.h> |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
20 #include <stddef.h> |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
21 #include <string.h> |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
23 #include "clock.h" |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
24 #include "event.h" |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 #include "game.h" |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 #include "state.h" |
61
8d34a12484db
core: game should present the window at the very end
David Demelier <markand@malikania.fr>
parents:
59
diff
changeset
|
27 #include "painter.h" |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
28 #include "util.h" |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
29 #include "window.h" |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
30 |
74
4991bf5f2343
core: implement inhibit system, closes #2468 @1h
David Demelier <markand@malikania.fr>
parents:
73
diff
changeset
|
31 struct game game; |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
32 |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
33 void |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
34 game_switch(struct state *state, bool quick) |
45
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
35 { |
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
36 assert(state); |
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
37 |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
38 if (quick) { |
165
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
39 if (game.state_next) { |
162 | 40 state_finish(game.state_next); |
165
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
41 game.state_next = NULL; |
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
42 } |
162 | 43 |
165
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
44 if (game.state) { |
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
45 state_end(game.state); |
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
46 state_finish(game.state); |
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
47 } |
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
48 |
eb3148c1e54d
core: add state functions
David Demelier <markand@malikania.fr>
parents:
162
diff
changeset
|
49 state_start(game.state = state); |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
50 } else |
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
51 game.state_next = state; |
45
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
52 } |
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
53 |
260
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
54 struct state * |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
55 game_replace(struct state *state) |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
56 { |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
57 assert(state); |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
58 |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
59 struct state *save = game.state; |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
60 |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
61 game.state = state; |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
62 |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
63 state_start(state); |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
64 |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
65 return save; |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
66 } |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
67 |
45
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
68 void |
162 | 69 game_handle(const union event *ev) |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 { |
162 | 71 assert(ev); |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
72 |
74
4991bf5f2343
core: implement inhibit system, closes #2468 @1h
David Demelier <markand@malikania.fr>
parents:
73
diff
changeset
|
73 if (game.state && !(game.inhibit & INHIBIT_STATE_INPUT)) |
162 | 74 state_handle(game.state, ev); |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 } |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
76 |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 void |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 game_update(unsigned int ticks) |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 { |
162 | 80 if (game.inhibit & INHIBIT_STATE_UPDATE) |
81 return; | |
82 | |
83 /* Change state if any. */ | |
84 if (game.state_next) { | |
85 struct state *previous; | |
86 | |
87 /* Inform the current state we're gonna leave it. */ | |
88 if ((previous = game.state)) | |
89 state_end(previous); | |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 |
162 | 91 /* Change the state and tell we're starting it. */ |
92 if ((game.state = game.state_next)) | |
93 state_start(game.state); | |
94 | |
95 game.state_next = NULL; | |
74
4991bf5f2343
core: implement inhibit system, closes #2468 @1h
David Demelier <markand@malikania.fr>
parents:
73
diff
changeset
|
96 |
162 | 97 /* |
98 * Only call finish at the end of the process because | |
99 * the user may still use resources from it during the | |
100 * transition. | |
101 */ | |
102 if (previous) | |
103 state_finish(previous); | |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
104 } |
162 | 105 |
106 if (game.state) | |
107 state_update(game.state, ticks); | |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 } |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
110 void |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 game_draw(void) |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 { |
74
4991bf5f2343
core: implement inhibit system, closes #2468 @1h
David Demelier <markand@malikania.fr>
parents:
73
diff
changeset
|
113 if (game.state && !(game.inhibit & INHIBIT_STATE_DRAW)) |
162 | 114 state_draw(game.state); |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
115 } |
58
d7d88ac30611
core: forgot to implement action->draw
David Demelier <markand@malikania.fr>
parents:
57
diff
changeset
|
116 |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
117 void |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
118 game_loop(void) |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
119 { |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
120 struct clock clock = {0}; |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
121 unsigned int elapsed = 0; |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
122 unsigned int frametime; |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
123 |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
124 if (window.framerate > 0) |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
125 frametime = 1000 / window.framerate; |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
126 else |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
127 /* Assuming 50.0 FPS. */ |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
128 frametime = 1000.0 / 50.0; |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
129 |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
130 while (game.state) { |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
131 clock_start(&clock); |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
132 |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
133 for (union event ev; event_poll(&ev); ) |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
134 game_handle(&ev); |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
135 |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
136 game_update(elapsed); |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
137 game_draw(); |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
138 |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
139 /* |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
140 * If vsync is enabled, it should have wait, otherwise sleep |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
141 * a little to save CPU cycles. |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
142 */ |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
143 if ((elapsed = clock_elapsed(&clock)) < frametime) |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
144 delay(frametime - elapsed); |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
145 |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
146 elapsed = clock_elapsed(&clock); |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
147 } |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
148 } |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
149 |
80
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
150 void |
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
151 game_quit(void) |
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
152 { |
162 | 153 /* Close the next state if any. */ |
154 if (game.state_next) { | |
155 state_finish(game.state_next); | |
156 game.state_next = NULL; | |
157 } | |
158 | |
159 if (game.state) { | |
160 state_end(game.state); | |
161 state_finish(game.state); | |
162 game.state = NULL; | |
163 } | |
80
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
164 } |