Mercurial > molko
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 |
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 | 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 | 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 | 144 |
145 mlk_game.state = NULL; | |
80
05ffbcdee585
adventure: create main menu, closes #2482 @4h
David Demelier <markand@malikania.fr>
parents:
78
diff
changeset
|
146 } |