Mercurial > molko
annotate libmlk-core/core/game.c @ 300:3638b39ef2bf
examples: fix with new game_push function
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 11 Apr 2021 17:43:57 +0200 |
parents | 648f5f949afb |
children | f10fd1293a7e |
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 |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
31 struct game game = { |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
32 .state = &game.states[0], |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
33 }; |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
35 void |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
36 game_push(struct state *state) |
45
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
37 { |
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
38 assert(state); |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
39 assert(game.state != &game.states[GAME_STATE_MAX]); |
162 | 40 |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
41 if (*game.state) { |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
42 state_suspend(*game.state); |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
43 state_start(*(++game.state) = state); |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
44 } else |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
45 state_start((*game.state) = state); |
45
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
46 } |
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
47 |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
48 void |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
49 game_pop(void) |
260
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
50 { |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
51 if (!*game.state) |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
52 return; |
260
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
53 |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
54 state_end(*game.state); |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
55 state_finish(*game.state); |
260
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
56 |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
57 if (game.state != &game.states[0]) |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
58 state_resume(*--game.state); |
260
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
59 } |
60a214ec1ab4
adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents:
248
diff
changeset
|
60 |
45
e10fd1b6323f
core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents:
44
diff
changeset
|
61 void |
162 | 62 game_handle(const union event *ev) |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
63 { |
162 | 64 assert(ev); |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
65 |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
66 if (*game.state && !(game.inhibit & INHIBIT_STATE_INPUT)) |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
67 state_handle(*game.state, ev); |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
68 } |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 void |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 game_update(unsigned int ticks) |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 { |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
73 if (*game.state && !(game.inhibit & INHIBIT_STATE_UPDATE)) |
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
74 state_update(*game.state, ticks); |
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_draw(void) |
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 { |
300
3638b39ef2bf
examples: fix with new game_push function
David Demelier <markand@malikania.fr>
parents:
299
diff
changeset
|
80 if (*game.state && !(game.inhibit & INHIBIT_STATE_DRAW)) |
299
648f5f949afb
core: implement stackable states
David Demelier <markand@malikania.fr>
parents:
298
diff
changeset
|
81 state_draw(*game.state); |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
82 } |
58
d7d88ac30611
core: forgot to implement action->draw
David Demelier <markand@malikania.fr>
parents:
57
diff
changeset
|
83 |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
84 void |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
85 game_loop(void) |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
86 { |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
87 struct clock clock = {0}; |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
88 unsigned int elapsed = 0; |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
89 unsigned int frametime; |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
90 |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
91 if (window.framerate > 0) |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
92 frametime = 1000 / window.framerate; |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
93 else |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
94 /* Assuming 50.0 FPS. */ |
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
95 frametime = 1000.0 / 50.0; |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
96 |
300
3638b39ef2bf
examples: fix with new game_push function
David Demelier <markand@malikania.fr>
parents:
299
diff
changeset
|
97 while (*game.state) { |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
98 clock_start(&clock); |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
99 |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
100 for (union event ev; event_poll(&ev); ) |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
101 game_handle(&ev); |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
102 |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
103 game_update(elapsed); |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
104 game_draw(); |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
105 |
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
106 /* |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
107 * 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
|
108 * a little to save CPU cycles. |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
109 */ |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
110 if ((elapsed = clock_elapsed(&clock)) < frametime) |
261
bfde372bf152
core: prefix utilities with util_
David Demelier <markand@malikania.fr>
parents:
260
diff
changeset
|
111 util_delay(frametime - elapsed); |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
112 |
248
37771eaf4245
core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents:
243
diff
changeset
|
113 elapsed = clock_elapsed(&clock); |
207
133926e08d6e
examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents:
165
diff
changeset
|
114 } |
44
c97fe725fdeb
core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 } |
57
9f6267843815
core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents:
45
diff
changeset
|
116 |
80
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
117 void |
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
118 game_quit(void) |
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
119 { |
300
3638b39ef2bf
examples: fix with new game_push function
David Demelier <markand@malikania.fr>
parents:
299
diff
changeset
|
120 for (size_t i = 0; i < UTIL_SIZE(game.states); ++i) |
3638b39ef2bf
examples: fix with new game_push function
David Demelier <markand@malikania.fr>
parents:
299
diff
changeset
|
121 if (game.states[i]) |
3638b39ef2bf
examples: fix with new game_push function
David Demelier <markand@malikania.fr>
parents:
299
diff
changeset
|
122 state_finish(game.states[i]); |
3638b39ef2bf
examples: fix with new game_push function
David Demelier <markand@malikania.fr>
parents:
299
diff
changeset
|
123 |
3638b39ef2bf
examples: fix with new game_push function
David Demelier <markand@malikania.fr>
parents:
299
diff
changeset
|
124 *game.state = NULL; |
80
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
125 } |