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