comparison 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
comparison
equal deleted inserted replaced
319:b843eef4cc35 320:8f9937403749
1 /*
2 * game.c -- main game object
3 *
4 * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <assert.h>
20 #include <stddef.h>
21 #include <string.h>
22
23 #include "clock.h"
24 #include "event.h"
25 #include "game.h"
26 #include "state.h"
27 #include "painter.h"
28 #include "util.h"
29 #include "window.h"
30
31 struct game game = {
32 .state = &game.states[0],
33 };
34
35 void
36 game_init(void)
37 {
38 memset(&game, 0, sizeof (game));
39
40 game.state = &game.states[0];
41 }
42
43 void
44 game_push(struct state *state)
45 {
46 assert(state);
47 assert(game.state != &game.states[GAME_STATE_MAX]);
48
49 if (*game.state) {
50 state_suspend(*game.state);
51 state_start(*(++game.state) = state);
52 } else
53 state_start((*game.state) = state);
54 }
55
56 void
57 game_pop(void)
58 {
59 if (!*game.state)
60 return;
61
62 state_end(*game.state);
63 state_finish(*game.state);
64
65 *game.state = NULL;
66
67 if (game.state != &game.states[0])
68 state_resume(*--game.state);
69 }
70
71 void
72 game_handle(const union event *ev)
73 {
74 assert(ev);
75
76 if (*game.state && !(game.inhibit & INHIBIT_STATE_INPUT))
77 state_handle(*game.state, ev);
78 }
79
80 void
81 game_update(unsigned int ticks)
82 {
83 if (*game.state && !(game.inhibit & INHIBIT_STATE_UPDATE))
84 state_update(*game.state, ticks);
85 }
86
87 void
88 game_draw(void)
89 {
90 if (*game.state && !(game.inhibit & INHIBIT_STATE_DRAW))
91 state_draw(*game.state);
92 }
93
94 void
95 game_loop(void)
96 {
97 struct clock clock = {0};
98 unsigned int elapsed = 0;
99 unsigned int frametime;
100
101 if (window.framerate > 0)
102 frametime = 1000 / window.framerate;
103 else
104 /* Assuming 50.0 FPS. */
105 frametime = 1000.0 / 50.0;
106
107 while (*game.state) {
108 clock_start(&clock);
109
110 for (union event ev; event_poll(&ev); )
111 game_handle(&ev);
112
113 game_update(elapsed);
114 game_draw();
115
116 /*
117 * If vsync is enabled, it should have wait, otherwise sleep
118 * a little to save CPU cycles.
119 */
120 if ((elapsed = clock_elapsed(&clock)) < frametime)
121 util_delay(frametime - elapsed);
122
123 elapsed = clock_elapsed(&clock);
124 }
125 }
126
127 void
128 game_quit(void)
129 {
130 for (size_t i = 0; i < UTIL_SIZE(game.states); ++i) {
131 if (game.states[i])
132 state_finish(game.states[i]);
133
134 game.states[i] = NULL;
135 }
136 }