annotate libmlk-core/mlk/core/game.c @ 559:ba0cca39e4ca

util: fmemopen leftover
author David Demelier <markand@malikania.fr>
date Wed, 08 Mar 2023 20:01:00 +0100
parents c7664b679a95
children 5a4e5b852f8a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 *
445
773a082f0b91 misc: update copyright years
David Demelier <markand@malikania.fr>
parents: 431
diff changeset
4 * Copyright (c) 2020-2023 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>
57
9f6267843815 core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents: 45
diff changeset
20 #include <string.h>
44
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
21
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
22 #include "clock.h"
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
23 #include "err.h"
207
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"
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
27 #include "util.h"
248
37771eaf4245 core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents: 243
diff changeset
28 #include "window.h"
44
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
29
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
30 static struct mlk_state *states[8];
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
31
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
32 struct mlk_game mlk_game = {
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
33 .states = states,
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
34 .statesz = MLK_UTIL_SIZE(states)
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
35 };
44
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
36
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 void
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
38 mlk_game_init(void)
311
f10fd1293a7e core: fix states + tests
David Demelier <markand@malikania.fr>
parents: 300
diff changeset
39 {
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
40 for (size_t i = 0; i < mlk_game.statesz; ++i)
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
41 mlk_game.states[i] = NULL;
311
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
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
44 int
469
0d6206cee6b9 core: state -> mlk_state
David Demelier <markand@malikania.fr>
parents: 454
diff changeset
45 mlk_game_push(struct mlk_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 assert(state);
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
48
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
49 if (!mlk_game.state) {
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
50 mlk_game.state = &mlk_game.states[0];
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
51 mlk_state_start(*mlk_game.state = state);
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
52 return 0;
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
53 }
162
629f55f3961e core: rework states
David Demelier <markand@malikania.fr>
parents: 147
diff changeset
54
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
55 if (mlk_game.state == &mlk_game.states[mlk_game.statesz - 1])
547
c7664b679a95 misc: remove error codes for now
David Demelier <markand@malikania.fr>
parents: 529
diff changeset
56 return mlk_errf("no space in game states stack");
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
57
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
58 mlk_state_suspend(*mlk_game.state);
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
59 mlk_state_start(*(++mlk_game.state) = state);
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
60
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
61 return 0;
45
e10fd1b6323f core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents: 44
diff changeset
62 }
e10fd1b6323f core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents: 44
diff changeset
63
299
648f5f949afb core: implement stackable states
David Demelier <markand@malikania.fr>
parents: 298
diff changeset
64 void
452
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
65 mlk_game_pop(void)
260
60a214ec1ab4 adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents: 248
diff changeset
66 {
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
67 if (!mlk_game.state)
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
68 return;
260
60a214ec1ab4 adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents: 248
diff changeset
69
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
70 mlk_state_end(*mlk_game.state);
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
71 mlk_state_finish(*mlk_game.state);
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
72
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
73 if (mlk_game.state == mlk_game.states)
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
74 mlk_game.state = NULL;
389
ef4d4a51aeb7 core: game don't use fixed size states
David Demelier <markand@malikania.fr>
parents: 378
diff changeset
75 else
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
76 mlk_state_resume(*--mlk_game.state);
260
60a214ec1ab4 adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents: 248
diff changeset
77 }
60a214ec1ab4 adventure: change the way states are stored
David Demelier <markand@malikania.fr>
parents: 248
diff changeset
78
45
e10fd1b6323f core: implement splashscreen, closes #2458 @1h
David Demelier <markand@malikania.fr>
parents: 44
diff changeset
79 void
452
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
80 mlk_game_handle(const union mlk_event *ev)
44
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 {
162
629f55f3961e core: rework states
David Demelier <markand@malikania.fr>
parents: 147
diff changeset
82 assert(ev);
57
9f6267843815 core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents: 45
diff changeset
83
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
84 if (mlk_game.state && !(mlk_game.inhibit & MLK_GAME_INHIBIT_INPUT))
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
85 mlk_state_handle(*mlk_game.state, ev);
44
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
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 void
452
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
89 mlk_game_update(unsigned int ticks)
44
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 {
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
91 if (mlk_game.state && !(mlk_game.inhibit & MLK_GAME_INHIBIT_UPDATE))
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
92 mlk_state_update(*mlk_game.state, ticks);
44
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 }
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 void
452
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
96 mlk_game_draw(void)
44
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 {
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
98 if (mlk_game.state && !(mlk_game.inhibit & MLK_GAME_INHIBIT_DRAW))
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
99 mlk_state_draw(*mlk_game.state);
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
100 }
58
d7d88ac30611 core: forgot to implement action->draw
David Demelier <markand@malikania.fr>
parents: 57
diff changeset
101
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
102 void
452
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
103 mlk_game_loop(void)
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
104 {
421
3edda1ce314c core: remove mlk_ prefix for now
David Demelier <markand@malikania.fr>
parents: 400
diff changeset
105 struct mlk_clock clock = {0};
248
37771eaf4245 core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents: 243
diff changeset
106 unsigned int elapsed = 0;
37771eaf4245 core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents: 243
diff changeset
107 unsigned int frametime;
37771eaf4245 core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents: 243
diff changeset
108
485
3ff1fe64d0cd core: window -> mlk_window
David Demelier <markand@malikania.fr>
parents: 474
diff changeset
109 if (mlk_window.framerate > 0)
3ff1fe64d0cd core: window -> mlk_window
David Demelier <markand@malikania.fr>
parents: 474
diff changeset
110 frametime = 1000 / mlk_window.framerate;
248
37771eaf4245 core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents: 243
diff changeset
111 else
37771eaf4245 core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents: 243
diff changeset
112 /* Assuming 50.0 FPS. */
37771eaf4245 core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents: 243
diff changeset
113 frametime = 1000.0 / 50.0;
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
114
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
115 while (mlk_game.state) {
421
3edda1ce314c core: remove mlk_ prefix for now
David Demelier <markand@malikania.fr>
parents: 400
diff changeset
116 mlk_clock_start(&clock);
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
117
450
b26dd49f69ff core: event -> mlk_event (and friends)
David Demelier <markand@malikania.fr>
parents: 445
diff changeset
118 for (union mlk_event ev; mlk_event_poll(&ev); )
452
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
119 mlk_game_handle(&ev);
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
120
452
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
121 mlk_game_update(elapsed);
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
122 mlk_game_draw();
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
123
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
124 /*
248
37771eaf4245 core: use vsync and improve game loop
David Demelier <markand@malikania.fr>
parents: 243
diff changeset
125 * 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
126 * a little to save CPU cycles.
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
127 */
421
3edda1ce314c core: remove mlk_ prefix for now
David Demelier <markand@malikania.fr>
parents: 400
diff changeset
128 if ((elapsed = mlk_clock_elapsed(&clock)) < frametime)
474
ca30ff96bbe0 core: util -> mlk_util
David Demelier <markand@malikania.fr>
parents: 469
diff changeset
129 mlk_util_delay(frametime - elapsed);
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
130
421
3edda1ce314c core: remove mlk_ prefix for now
David Demelier <markand@malikania.fr>
parents: 400
diff changeset
131 elapsed = mlk_clock_elapsed(&clock);
207
133926e08d6e examples: use game_loop for all
David Demelier <markand@malikania.fr>
parents: 165
diff changeset
132 }
44
c97fe725fdeb core: implement basic states, closes #2457 @1h
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 }
57
9f6267843815 core: implement basic actions, closes #2463 @1h
David Demelier <markand@malikania.fr>
parents: 45
diff changeset
134
80
05ffbcdee585 adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents: 78
diff changeset
135 void
452
f89147faf8cf core: game -> mlk_game
David Demelier <markand@malikania.fr>
parents: 450
diff changeset
136 mlk_game_quit(void)
80
05ffbcdee585 adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents: 78
diff changeset
137 {
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
138 for (size_t i = 0; i < mlk_game.statesz; ++i) {
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
139 if (mlk_game.states[i])
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
140 mlk_state_finish(mlk_game.states[i]);
300
3638b39ef2bf examples: fix with new game_push function
David Demelier <markand@malikania.fr>
parents: 299
diff changeset
141
522
f45a023f6690 core: doxygenize game
David Demelier <markand@malikania.fr>
parents: 485
diff changeset
142 mlk_game.states[i] = NULL;
311
f10fd1293a7e core: fix states + tests
David Demelier <markand@malikania.fr>
parents: 300
diff changeset
143 }
529
7e835d43ef74 core: fix game crash
David Demelier <markand@malikania.fr>
parents: 522
diff changeset
144
7e835d43ef74 core: fix game crash
David Demelier <markand@malikania.fr>
parents: 522
diff changeset
145 mlk_game.state = NULL;
80
05ffbcdee585 adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents: 78
diff changeset
146 }