Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Experimento con emscripten y SDL

1178 views
1
#include "engine.h"
2
#include <SDL2/SDL.h>
3
#include <SDL2/SDL_image.h>
4
5
void setup_textures();
6
void setup_decals();
7
void setup_actors();
8
void loop_handler();
9
bool should_continue_logic_loops();
10
void setup_bindings();
11
12
engine *engine_init(
13
unsigned int w,
14
unsigned int h)
15
{
16
eng.fps = 80;
17
eng.current_frame = 0;
18
eng.score = 0;
19
20
eng.start_time = 0;
21
eng.should_start_logic_loop = true;
22
eng.whole_frames_to_do = 0;
23
24
SDL_Init(SDL_INIT_VIDEO);
25
TTF_Init();
26
27
SDL_CreateWindowAndRenderer(w, h, 0, &eng.window, &eng.renderer);
28
eng.w = w;
29
eng.h = h;
30
31
if(eng.window == NULL) {
32
fprintf(
33
stderr,
34
"Window could not be created: %s\n", SDL_GetError());
35
return NULL;
36
}
37
38
setup_textures();
39
setup_decals();
40
41
eng.grid_width = w / TILE_DIMENSION;
42
eng.grid_height = (h / TILE_DIMENSION) - STATUS_BAR_HEIGHT;
43
eng.occupied_gridpoints = malloc(eng.grid_width * eng.grid_height * sizeof(*eng.occupied_gridpoints));
44
memset(eng.occupied_gridpoints, 0, eng.grid_width * eng.grid_height * sizeof(*eng.occupied_gridpoints));
45
46
SDL_StartTextInput();
47
setup_bindings();
48
49
eng.render_list = NULL;
50
eng.logic_list = NULL;
51
52
setup_actors();
53
54
return &eng;
55
}
56
57
void engine_destroy()
58
{
59
SDL_Quit();
60
}
61
62
void engine_start()
63
{
64
eng.start_time = SDL_GetTicks();
65
66
emscripten_set_main_loop(loop_handler, -1, 0);
67
}
68
69
void engine_reset()
70
{
71
snake_actor_init(&eng.snake_actor);
72
memset(eng.occupied_gridpoints, 0, eng.grid_width * eng.grid_height * sizeof(*eng.occupied_gridpoints));
73
apple_actor_init(&eng.apple_actor);
74
eng.score = 0;
75
background_actor_update_scoreboard(&eng.background_actor);
76
}
77
78
void setup_textures()
79
{
80
char * filenames[] = {
81
"assets/sand.png",
82
"assets/sprites.png",
83
"assets/status_bar.png"
84
};
85
int i;
86
87
for (i = 0; i < sizeof(filenames) / sizeof(filenames[0]); i++) {
88
char * fname = filenames[i];
89
SDL_Surface *img = IMG_Load(fname);
90
91
if(!img){
92
fprintf(stdout, "Error! Could not load %s\n", fname);
93
exit(1);
94
}
95
96
eng.textures[i] = SDL_CreateTextureFromSurface(eng.renderer, img);
97
98
SDL_FreeSurface(img);
99
}
100
}
101
102
void setup_decals()
103
{
104
int i;
105
106
int imgw, imgh;
107
SDL_QueryTexture(eng.textures[SPRITES_TEXTURE],
108
NULL, NULL, &imgw, &imgh);
109
110
for (i = 0; i < NUM_SPRITES_DECALS; i++) {
111
double w = 1/8. * imgw;
112
double h = 1/2. * imgh;
113
double x = (double)(i % 8) * w;
114
double y = (double)(i / 8) * h;
115
116
decal_init(
117
&eng.sprites_decals[i],
118
eng.textures[SPRITES_TEXTURE],
119
x,
120
y,
121
w,
122
h);
123
}
124
125
SDL_QueryTexture(eng.textures[SAND_TEXTURE],
126
NULL, NULL, &imgw, &imgh);
127
128
decal_init(
129
&(eng.sand_decal),
130
eng.textures[SAND_TEXTURE],
131
0,
132
0,
133
imgw,
134
imgh);
135
}
136
137
void setup_actors()
138
{
139
snake_actor_init(&eng.snake_actor);
140
eng.render_list = actor_list_add(eng.render_list, (actor *)(&eng.snake_actor));
141
eng.logic_list = actor_list_add(eng.logic_list, (actor *)(&eng.snake_actor));
142
143
apple_actor_init(&eng.apple_actor);
144
eng.render_list = actor_list_add(eng.render_list, (actor *)(&eng.apple_actor));
145
146
background_actor_init(&eng.background_actor);
147
eng.render_list = actor_list_add(eng.render_list, (actor *)(&eng.background_actor));
148
}
149
150
bool should_continue_logic_loops()
151
{
152
if (eng.should_start_logic_loop) {
153
unsigned int logic_loop_start_time = SDL_GetTicks();
154
double elapsed_frames = (double)(logic_loop_start_time \
155
- eng.start_time) / 1000.0f * eng.fps;
156
157
eng.whole_frames_to_do = (unsigned int)elapsed_frames - eng.current_frame;
158
}
159
160
if (!eng.whole_frames_to_do) {
161
eng.should_start_logic_loop = true;
162
return false;
163
}
164
165
eng.whole_frames_to_do -= 1;
166
eng.current_frame += 1;
167
eng.should_start_logic_loop = false;
168
return true;
169
}
170
171
void loop_handler()
172
{
173
process_input();
174
175
// if (is_state_active(GS_QUIT)) {
176
// return;
177
// }
178
179
SDL_RenderClear(eng.renderer);
180
181
actor_list *al;
182
for (al = eng.render_list; al != NULL; al = al->next) {
183
al->a->render_handler(al->a);
184
}
185
186
while (should_continue_logic_loops()) {
187
for (al = eng.logic_list; al != NULL; al = al->next) {
188
al->a->logic_handler(al->a);
189
}
190
}
191
192
SDL_RenderPresent(eng.renderer);
193
}
194
195
void setup_bindings()
196
{
197
input_processor_init();
198
key_state_binding binding;
199
200
binding.k = SDLK_UP;
201
binding.s = GS_N;
202
binding.t = BINDING_ONE_TIME;
203
add_binding(&binding);
204
205
binding.k = SDLK_RIGHT;
206
binding.s = GS_E;
207
add_binding(&binding);
208
209
binding.k = SDLK_DOWN;
210
binding.s = GS_S;
211
add_binding(&binding);
212
213
binding.k = SDLK_LEFT;
214
binding.s = GS_W;
215
add_binding(&binding);
216
}
217
218
void engine_get_grid_coord(const int *pixel_coord, int *grid_coord)
219
{
220
grid_coord[0] = pixel_coord[0] / TILE_DIMENSION;
221
grid_coord[1] = pixel_coord[1] / TILE_DIMENSION - STATUS_BAR_HEIGHT;
222
}
223
224
void engine_get_pixel_coord(const int *grid_coord, int *pixel_coord)
225
{
226
pixel_coord[0] = grid_coord[0] * TILE_DIMENSION;
227
pixel_coord[1] = (grid_coord[1] + STATUS_BAR_HEIGHT) * TILE_DIMENSION;
228
}
229
230
void engine_apply_boundary_conditions(int *grid_coords)
231
{
232
grid_coords[0] = ((grid_coords[0] % eng.grid_width) + eng.grid_width) % eng.grid_width;
233
grid_coords[1] = ((grid_coords[1] % eng.grid_height) + eng.grid_height) % eng.grid_height;
234
}
235
236