1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include <GLFW/glfw3.h>
#include <threads.h>
#include "voxel.h"
#include "window.h"
World world;
Camera camera;
_Atomic bool loaded;
void sleep(double seconds)
{
struct timespec req, rem;
req.tv_sec = seconds;
req.tv_nsec = 0;
if (seconds < 0)
return;
while (thrd_sleep(&req, &rem) == thrd_error)
req = rem;
}
/// handles rendering
VOXEL_RESULT render_main(void *)
{
Renderer renderer;
if (window_init_gl() != VOXEL_OK)
goto error;
if (renderer_init(&renderer) != VOXEL_OK)
goto error;
loaded = true;
while (!window_closed()) {
if (window.resize) {
glViewport(0, 0, window.width, window.height);
window.resize = false;
}
renderer_start(&renderer, &camera);
world_render(&world, &renderer);
renderer_stop(&renderer);
window_swap();
}
renderer_free(&renderer);
return VOXEL_OK;
error:
window_close();
loaded = true;
return VOXEL_ERROR;
}
#define TPS 20
/// handles game logic
VOXEL_RESULT logic_main(void *)
{
double last_tick, next_tick;
last_tick = 0;
next_tick = 0;
while (!loaded)
;
while (!window_closed()) {
world_update(&world, &camera);
next_tick = last_tick + (1.0 / TPS);
sleep(next_tick - last_tick);
last_tick = next_tick;
}
return VOXEL_OK;
}
/// handles user input
VOXEL_RESULT input_main(void *)
{
double last_tick, next_tick;
last_tick = 0;
next_tick = 0;
while (!loaded)
;
while (!window_closed()) {
window_update();
if (key_down(GLFW_KEY_ESCAPE))
window_close();
camera_update(&camera);
next_tick = last_tick + (1.0 / TPS);
sleep(next_tick - last_tick);
last_tick = next_tick;
}
return VOXEL_OK;
}
VOXEL_RESULT main(void)
{
thrd_t render_thread, logic_thread, input_thread;
loaded = false;
if (window_init() != VOXEL_OK)
return VOXEL_ERROR;
camera_init(&camera);
world_init(&world, 0);
thrd_create(&logic_thread, logic_main, NULL);
thrd_create(&input_thread, input_main, NULL);
thrd_create(&render_thread, render_main, NULL);
thrd_join(logic_thread, NULL);
thrd_join(input_thread, NULL);
thrd_join(render_thread, NULL);
world_free(&world);
window_free();
return VOXEL_OK;
}
|