diff options
Diffstat (limited to 'src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c')
-rw-r--r-- | src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c new file mode 100644 index 0000000..b97b06a --- /dev/null +++ b/src/contrib/SDL-3.2.20/examples/demo/02-woodeneye-008/woodeneye-008.c | |||
@@ -0,0 +1,480 @@ | |||
1 | /* | ||
2 | * This code is public domain. Feel free to use it for any purpose! | ||
3 | */ | ||
4 | |||
5 | #define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */ | ||
6 | #include <SDL3/SDL.h> | ||
7 | #include <SDL3/SDL_main.h> | ||
8 | |||
9 | #define MAP_BOX_SCALE 16 | ||
10 | #define MAP_BOX_EDGES_LEN (12 + MAP_BOX_SCALE * 2) | ||
11 | #define MAX_PLAYER_COUNT 4 | ||
12 | #define CIRCLE_DRAW_SIDES 32 | ||
13 | #define CIRCLE_DRAW_SIDES_LEN (CIRCLE_DRAW_SIDES + 1) | ||
14 | |||
15 | typedef struct { | ||
16 | SDL_MouseID mouse; | ||
17 | SDL_KeyboardID keyboard; | ||
18 | double pos[3]; | ||
19 | double vel[3]; | ||
20 | unsigned int yaw; | ||
21 | int pitch; | ||
22 | float radius, height; | ||
23 | unsigned char color[3]; | ||
24 | unsigned char wasd; | ||
25 | } Player; | ||
26 | |||
27 | typedef struct { | ||
28 | SDL_Window *window; | ||
29 | SDL_Renderer *renderer; | ||
30 | int player_count; | ||
31 | Player players[MAX_PLAYER_COUNT]; | ||
32 | float edges[MAP_BOX_EDGES_LEN][6]; | ||
33 | } AppState; | ||
34 | |||
35 | static const struct { | ||
36 | const char *key; | ||
37 | const char *value; | ||
38 | } extended_metadata[] = { | ||
39 | { SDL_PROP_APP_METADATA_URL_STRING, "https://examples.libsdl.org/SDL3/demo/02-woodeneye-008/" }, | ||
40 | { SDL_PROP_APP_METADATA_CREATOR_STRING, "SDL team" }, | ||
41 | { SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Placed in the public domain" }, | ||
42 | { SDL_PROP_APP_METADATA_TYPE_STRING, "game" } | ||
43 | }; | ||
44 | |||
45 | static int whoseMouse(SDL_MouseID mouse, const Player players[], int players_len) | ||
46 | { | ||
47 | int i; | ||
48 | for (i = 0; i < players_len; i++) { | ||
49 | if (players[i].mouse == mouse) return i; | ||
50 | } | ||
51 | return -1; | ||
52 | } | ||
53 | |||
54 | static int whoseKeyboard(SDL_KeyboardID keyboard, const Player players[], int players_len) | ||
55 | { | ||
56 | int i; | ||
57 | for (i = 0; i < players_len; i++) { | ||
58 | if (players[i].keyboard == keyboard) return i; | ||
59 | } | ||
60 | return -1; | ||
61 | } | ||
62 | |||
63 | static void shoot(int shooter, Player players[], int players_len) | ||
64 | { | ||
65 | int i, j; | ||
66 | double x0 = players[shooter].pos[0]; | ||
67 | double y0 = players[shooter].pos[1]; | ||
68 | double z0 = players[shooter].pos[2]; | ||
69 | double bin_rad = SDL_PI_D / 2147483648.0; | ||
70 | double yaw_rad = bin_rad * players[shooter].yaw; | ||
71 | double pitch_rad = bin_rad * players[shooter].pitch; | ||
72 | double cos_yaw = SDL_cos( yaw_rad); | ||
73 | double sin_yaw = SDL_sin( yaw_rad); | ||
74 | double cos_pitch = SDL_cos(pitch_rad); | ||
75 | double sin_pitch = SDL_sin(pitch_rad); | ||
76 | double vx = -sin_yaw*cos_pitch; | ||
77 | double vy = sin_pitch; | ||
78 | double vz = -cos_yaw*cos_pitch; | ||
79 | for (i = 0; i < players_len; i++) { | ||
80 | if (i == shooter) continue; | ||
81 | Player *target = &(players[i]); | ||
82 | int hit = 0; | ||
83 | for (j = 0; j < 2; j++) { | ||
84 | double r = target->radius; | ||
85 | double h = target->height; | ||
86 | double dx = target->pos[0] - x0; | ||
87 | double dy = target->pos[1] - y0 + (j == 0 ? 0 : r - h); | ||
88 | double dz = target->pos[2] - z0; | ||
89 | double vd = vx*dx + vy*dy + vz*dz; | ||
90 | double dd = dx*dx + dy*dy + dz*dz; | ||
91 | double vv = vx*vx + vy*vy + vz*vz; | ||
92 | double rr = r * r; | ||
93 | if (vd < 0) continue; | ||
94 | if (vd * vd >= vv * (dd - rr)) hit += 1; | ||
95 | } | ||
96 | if (hit) { | ||
97 | target->pos[0] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256; | ||
98 | target->pos[1] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256; | ||
99 | target->pos[2] = (double)(MAP_BOX_SCALE * (SDL_rand(256) - 128)) / 256; | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static void update(Player *players, int players_len, Uint64 dt_ns) | ||
105 | { | ||
106 | int i; | ||
107 | for (i = 0; i < players_len; i++) { | ||
108 | Player *player = &players[i]; | ||
109 | double rate = 6.0; | ||
110 | double time = (double)dt_ns * 1e-9; | ||
111 | double drag = SDL_exp(-time * rate); | ||
112 | double diff = 1.0 - drag; | ||
113 | double mult = 60.0; | ||
114 | double grav = 25.0; | ||
115 | double yaw = (double)player->yaw; | ||
116 | double rad = yaw * SDL_PI_D / 2147483648.0; | ||
117 | double cos = SDL_cos(rad); | ||
118 | double sin = SDL_sin(rad); | ||
119 | unsigned char wasd = player->wasd; | ||
120 | double dirX = (wasd & 8 ? 1.0 : 0.0) - (wasd & 2 ? 1.0 : 0.0); | ||
121 | double dirZ = (wasd & 4 ? 1.0 : 0.0) - (wasd & 1 ? 1.0 : 0.0); | ||
122 | double norm = dirX * dirX + dirZ * dirZ; | ||
123 | double accX = mult * (norm == 0 ? 0 : ( cos*dirX + sin*dirZ) / SDL_sqrt(norm)); | ||
124 | double accZ = mult * (norm == 0 ? 0 : (-sin*dirX + cos*dirZ) / SDL_sqrt(norm)); | ||
125 | double velX = player->vel[0]; | ||
126 | double velY = player->vel[1]; | ||
127 | double velZ = player->vel[2]; | ||
128 | player->vel[0] -= velX * diff; | ||
129 | player->vel[1] -= grav * time; | ||
130 | player->vel[2] -= velZ * diff; | ||
131 | player->vel[0] += diff * accX / rate; | ||
132 | player->vel[2] += diff * accZ / rate; | ||
133 | player->pos[0] += (time - diff/rate) * accX / rate + diff * velX / rate; | ||
134 | player->pos[1] += -0.5 * grav * time * time + velY * time; | ||
135 | player->pos[2] += (time - diff/rate) * accZ / rate + diff * velZ / rate; | ||
136 | double scale = (double)MAP_BOX_SCALE; | ||
137 | double bound = scale - player->radius; | ||
138 | double posX = SDL_max(SDL_min(bound, player->pos[0]), -bound); | ||
139 | double posY = SDL_max(SDL_min(bound, player->pos[1]), player->height - scale); | ||
140 | double posZ = SDL_max(SDL_min(bound, player->pos[2]), -bound); | ||
141 | if (player->pos[0] != posX) player->vel[0] = 0; | ||
142 | if (player->pos[1] != posY) player->vel[1] = (wasd & 16) ? 8.4375 : 0; | ||
143 | if (player->pos[2] != posZ) player->vel[2] = 0; | ||
144 | player->pos[0] = posX; | ||
145 | player->pos[1] = posY; | ||
146 | player->pos[2] = posZ; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | static void drawCircle(SDL_Renderer *renderer, float r, float x, float y) | ||
151 | { | ||
152 | float ang; | ||
153 | SDL_FPoint points[CIRCLE_DRAW_SIDES_LEN]; | ||
154 | int i; | ||
155 | for (i = 0; i < CIRCLE_DRAW_SIDES_LEN; i++) { | ||
156 | ang = 2.0f * SDL_PI_F * (float)i / (float)CIRCLE_DRAW_SIDES; | ||
157 | points[i].x = x + r * SDL_cosf(ang); | ||
158 | points[i].y = y + r * SDL_sinf(ang); | ||
159 | } | ||
160 | SDL_RenderLines(renderer, (const SDL_FPoint*)&points, CIRCLE_DRAW_SIDES_LEN); | ||
161 | } | ||
162 | |||
163 | static void drawClippedSegment( | ||
164 | SDL_Renderer *renderer, | ||
165 | float ax, float ay, float az, | ||
166 | float bx, float by, float bz, | ||
167 | float x, float y, float z, float w) | ||
168 | { | ||
169 | if (az >= -w && bz >= -w) return; | ||
170 | float dx = ax - bx; | ||
171 | float dy = ay - by; | ||
172 | if (az > -w) { | ||
173 | float t = (-w - bz) / (az - bz); | ||
174 | ax = bx + dx * t; | ||
175 | ay = by + dy * t; | ||
176 | az = -w; | ||
177 | } else if (bz > -w) { | ||
178 | float t = (-w - az) / (bz - az); | ||
179 | bx = ax - dx * t; | ||
180 | by = ay - dy * t; | ||
181 | bz = -w; | ||
182 | } | ||
183 | ax = -z * ax / az; | ||
184 | ay = -z * ay / az; | ||
185 | bx = -z * bx / bz; | ||
186 | by = -z * by / bz; | ||
187 | SDL_RenderLine(renderer, x + ax, y - ay, x + bx, y - by); | ||
188 | } | ||
189 | |||
190 | static char debug_string[32]; | ||
191 | static void draw(SDL_Renderer *renderer, const float (*edges)[6], const Player players[], int players_len) | ||
192 | { | ||
193 | int w, h, i, j, k; | ||
194 | if (!SDL_GetRenderOutputSize(renderer, &w, &h)) { | ||
195 | return; | ||
196 | } | ||
197 | SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); | ||
198 | SDL_RenderClear(renderer); | ||
199 | if (players_len > 0) { | ||
200 | float wf = (float)w; | ||
201 | float hf = (float)h; | ||
202 | int part_hor = players_len > 2 ? 2 : 1; | ||
203 | int part_ver = players_len > 1 ? 2 : 1; | ||
204 | float size_hor = wf / ((float)part_hor); | ||
205 | float size_ver = hf / ((float)part_ver); | ||
206 | for (i = 0; i < players_len; i++) { | ||
207 | const Player *player = &players[i]; | ||
208 | float mod_x = (float)(i % part_hor); | ||
209 | float mod_y = (float)(i / part_hor); | ||
210 | float hor_origin = (mod_x + 0.5f) * size_hor; | ||
211 | float ver_origin = (mod_y + 0.5f) * size_ver; | ||
212 | float cam_origin = (float)(0.5 * SDL_sqrt(size_hor * size_hor + size_ver * size_ver)); | ||
213 | float hor_offset = mod_x * size_hor; | ||
214 | float ver_offset = mod_y * size_ver; | ||
215 | SDL_Rect rect; | ||
216 | rect.x = (int)hor_offset; | ||
217 | rect.y = (int)ver_offset; | ||
218 | rect.w = (int)size_hor; | ||
219 | rect.h = (int)size_ver; | ||
220 | SDL_SetRenderClipRect(renderer, &rect); | ||
221 | double x0 = player->pos[0]; | ||
222 | double y0 = player->pos[1]; | ||
223 | double z0 = player->pos[2]; | ||
224 | double bin_rad = SDL_PI_D / 2147483648.0; | ||
225 | double yaw_rad = bin_rad * player->yaw; | ||
226 | double pitch_rad = bin_rad * player->pitch; | ||
227 | double cos_yaw = SDL_cos( yaw_rad); | ||
228 | double sin_yaw = SDL_sin( yaw_rad); | ||
229 | double cos_pitch = SDL_cos(pitch_rad); | ||
230 | double sin_pitch = SDL_sin(pitch_rad); | ||
231 | double mat[9] = { | ||
232 | cos_yaw , 0, -sin_yaw , | ||
233 | sin_yaw*sin_pitch, cos_pitch, cos_yaw*sin_pitch, | ||
234 | sin_yaw*cos_pitch, -sin_pitch, cos_yaw*cos_pitch | ||
235 | }; | ||
236 | SDL_SetRenderDrawColor(renderer, 64, 64, 64, 255); | ||
237 | for (k = 0; k < MAP_BOX_EDGES_LEN; k++) { | ||
238 | const float *line = edges[k]; | ||
239 | float ax = (float)(mat[0] * (line[0] - x0) + mat[1] * (line[1] - y0) + mat[2] * (line[2] - z0)); | ||
240 | float ay = (float)(mat[3] * (line[0] - x0) + mat[4] * (line[1] - y0) + mat[5] * (line[2] - z0)); | ||
241 | float az = (float)(mat[6] * (line[0] - x0) + mat[7] * (line[1] - y0) + mat[8] * (line[2] - z0)); | ||
242 | float bx = (float)(mat[0] * (line[3] - x0) + mat[1] * (line[4] - y0) + mat[2] * (line[5] - z0)); | ||
243 | float by = (float)(mat[3] * (line[3] - x0) + mat[4] * (line[4] - y0) + mat[5] * (line[5] - z0)); | ||
244 | float bz = (float)(mat[6] * (line[3] - x0) + mat[7] * (line[4] - y0) + mat[8] * (line[5] - z0)); | ||
245 | drawClippedSegment(renderer, ax, ay, az, bx, by, bz, hor_origin, ver_origin, cam_origin, 1); | ||
246 | } | ||
247 | for (j = 0; j < players_len; j++) { | ||
248 | if (i == j) continue; | ||
249 | const Player *target = &players[j]; | ||
250 | SDL_SetRenderDrawColor(renderer, target->color[0], target->color[1], target->color[2], 255); | ||
251 | for (k = 0; k < 2; k++) { | ||
252 | double rx = target->pos[0] - player->pos[0]; | ||
253 | double ry = target->pos[1] - player->pos[1] + (target->radius - target->height) * (float)k; | ||
254 | double rz = target->pos[2] - player->pos[2]; | ||
255 | double dx = mat[0] * rx + mat[1] * ry + mat[2] * rz; | ||
256 | double dy = mat[3] * rx + mat[4] * ry + mat[5] * rz; | ||
257 | double dz = mat[6] * rx + mat[7] * ry + mat[8] * rz; | ||
258 | double r_eff = target->radius * cam_origin / dz; | ||
259 | if (!(dz < 0)) continue; | ||
260 | drawCircle(renderer, (float)(r_eff), (float)(hor_origin - cam_origin*dx/dz), (float)(ver_origin + cam_origin*dy/dz)); | ||
261 | } | ||
262 | } | ||
263 | SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); | ||
264 | SDL_RenderLine(renderer, hor_origin, ver_origin-10, hor_origin, ver_origin+10); | ||
265 | SDL_RenderLine(renderer, hor_origin-10, ver_origin, hor_origin+10, ver_origin); | ||
266 | } | ||
267 | } | ||
268 | SDL_SetRenderClipRect(renderer, 0); | ||
269 | SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); | ||
270 | SDL_RenderDebugText(renderer, 0, 0, debug_string); | ||
271 | SDL_RenderPresent(renderer); | ||
272 | } | ||
273 | |||
274 | static void initPlayers(Player *players, int len) | ||
275 | { | ||
276 | int i; | ||
277 | for (i = 0; i < len; i++) { | ||
278 | players[i].pos[0] = 8.0 * (i & 1 ? -1.0 : 1.0); | ||
279 | players[i].pos[1] = 0; | ||
280 | players[i].pos[2] = 8.0 * (i & 1 ? -1.0 : 1.0) * (i & 2 ? -1.0 : 1.0); | ||
281 | players[i].vel[0] = 0; | ||
282 | players[i].vel[1] = 0; | ||
283 | players[i].vel[2] = 0; | ||
284 | players[i].yaw = 0x20000000 + (i & 1 ? 0x80000000 : 0) + (i & 2 ? 0x40000000 : 0); | ||
285 | players[i].pitch = -0x08000000; | ||
286 | players[i].radius = 0.5f; | ||
287 | players[i].height = 1.5f; | ||
288 | players[i].wasd = 0; | ||
289 | players[i].mouse = 0; | ||
290 | players[i].keyboard = 0; | ||
291 | players[i].color[0] = (1 << (i / 2)) & 2 ? 0 : 0xff; | ||
292 | players[i].color[1] = (1 << (i / 2)) & 1 ? 0 : 0xff; | ||
293 | players[i].color[2] = (1 << (i / 2)) & 4 ? 0 : 0xff; | ||
294 | players[i].color[0] = (i & 1) ? players[i].color[0] : ~players[i].color[0]; | ||
295 | players[i].color[1] = (i & 1) ? players[i].color[1] : ~players[i].color[1]; | ||
296 | players[i].color[2] = (i & 1) ? players[i].color[2] : ~players[i].color[2]; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | static void initEdges(int scale, float (*edges)[6], int edges_len) | ||
301 | { | ||
302 | int i, j; | ||
303 | const float r = (float)scale; | ||
304 | const int map[24] = { | ||
305 | 0,1 , 1,3 , 3,2 , 2,0 , | ||
306 | 7,6 , 6,4 , 4,5 , 5,7 , | ||
307 | 6,2 , 3,7 , 0,4 , 5,1 | ||
308 | }; | ||
309 | for(i = 0; i < 12; i++) { | ||
310 | for (j = 0; j < 3; j++) { | ||
311 | edges[i][j+0] = (map[i*2+0] & (1 << j) ? r : -r); | ||
312 | edges[i][j+3] = (map[i*2+1] & (1 << j) ? r : -r); | ||
313 | } | ||
314 | } | ||
315 | for(i = 0; i < scale; i++) { | ||
316 | float d = (float)(i * 2); | ||
317 | for (j = 0; j < 2; j++) { | ||
318 | edges[i+12][3*j+0] = j ? r : -r; | ||
319 | edges[i+12][3*j+1] = -r; | ||
320 | edges[i+12][3*j+2] = d-r; | ||
321 | edges[i+12+scale][3*j+0] = d-r; | ||
322 | edges[i+12+scale][3*j+1] = -r; | ||
323 | edges[i+12+scale][3*j+2] = j ? r : -r; | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | |||
328 | SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) | ||
329 | { | ||
330 | if (!SDL_SetAppMetadata("Example splitscreen shooter game", "1.0", "com.example.woodeneye-008")) { | ||
331 | return SDL_APP_FAILURE; | ||
332 | } | ||
333 | int i; | ||
334 | for (i = 0; i < SDL_arraysize(extended_metadata); i++) { | ||
335 | if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) { | ||
336 | return SDL_APP_FAILURE; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | AppState *as = SDL_calloc(1, sizeof(AppState)); | ||
341 | if (!as) { | ||
342 | return SDL_APP_FAILURE; | ||
343 | } else { | ||
344 | *appstate = as; | ||
345 | } | ||
346 | |||
347 | if (!SDL_Init(SDL_INIT_VIDEO)) { | ||
348 | return SDL_APP_FAILURE; | ||
349 | } | ||
350 | if (!SDL_CreateWindowAndRenderer("examples/demo/woodeneye-008", 640, 480, 0, &as->window, &as->renderer)) { | ||
351 | return SDL_APP_FAILURE; | ||
352 | } | ||
353 | |||
354 | as->player_count = 1; | ||
355 | initPlayers(as->players, MAX_PLAYER_COUNT); | ||
356 | initEdges(MAP_BOX_SCALE, as->edges, MAP_BOX_EDGES_LEN); | ||
357 | debug_string[0] = 0; | ||
358 | |||
359 | SDL_SetRenderVSync(as->renderer, false); | ||
360 | SDL_SetWindowRelativeMouseMode(as->window, true); | ||
361 | SDL_SetHintWithPriority(SDL_HINT_WINDOWS_RAW_KEYBOARD, "1", SDL_HINT_OVERRIDE); | ||
362 | return SDL_APP_CONTINUE; | ||
363 | } | ||
364 | |||
365 | SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) | ||
366 | { | ||
367 | AppState *as = appstate; | ||
368 | Player *players = as->players; | ||
369 | int player_count = as->player_count; | ||
370 | int i; | ||
371 | switch (event->type) { | ||
372 | case SDL_EVENT_QUIT: | ||
373 | return SDL_APP_SUCCESS; | ||
374 | break; | ||
375 | case SDL_EVENT_MOUSE_REMOVED: | ||
376 | for (i = 0; i < player_count; i++) { | ||
377 | if (players[i].mouse == event->mdevice.which) { | ||
378 | players[i].mouse = 0; | ||
379 | } | ||
380 | } | ||
381 | break; | ||
382 | case SDL_EVENT_KEYBOARD_REMOVED: | ||
383 | for (i = 0; i < player_count; i++) { | ||
384 | if (players[i].keyboard == event->kdevice.which) { | ||
385 | players[i].keyboard = 0; | ||
386 | } | ||
387 | } | ||
388 | break; | ||
389 | case SDL_EVENT_MOUSE_MOTION: { | ||
390 | SDL_MouseID id = event->motion.which; | ||
391 | int index = whoseMouse(id, players, player_count); | ||
392 | if (index >= 0) { | ||
393 | players[index].yaw -= ((int)event->motion.xrel) * 0x00080000; | ||
394 | players[index].pitch = SDL_max(-0x40000000, SDL_min(0x40000000, players[index].pitch - ((int)event->motion.yrel) * 0x00080000)); | ||
395 | } else if (id) { | ||
396 | for (i = 0; i < MAX_PLAYER_COUNT; i++) { | ||
397 | if (players[i].mouse == 0) { | ||
398 | players[i].mouse = id; | ||
399 | as->player_count = SDL_max(as->player_count, i + 1); | ||
400 | break; | ||
401 | } | ||
402 | } | ||
403 | } | ||
404 | break; | ||
405 | } | ||
406 | case SDL_EVENT_MOUSE_BUTTON_DOWN: { | ||
407 | SDL_MouseID id = event->button.which; | ||
408 | int index = whoseMouse(id, players, player_count); | ||
409 | if (index >= 0) { | ||
410 | shoot(index, players, player_count); | ||
411 | } | ||
412 | break; | ||
413 | } | ||
414 | case SDL_EVENT_KEY_DOWN: { | ||
415 | SDL_Keycode sym = event->key.key; | ||
416 | SDL_KeyboardID id = event->key.which; | ||
417 | int index = whoseKeyboard(id, players, player_count); | ||
418 | if (index >= 0) { | ||
419 | if (sym == SDLK_W) players[index].wasd |= 1; | ||
420 | if (sym == SDLK_A) players[index].wasd |= 2; | ||
421 | if (sym == SDLK_S) players[index].wasd |= 4; | ||
422 | if (sym == SDLK_D) players[index].wasd |= 8; | ||
423 | if (sym == SDLK_SPACE) players[index].wasd |= 16; | ||
424 | } else if (id) { | ||
425 | for (i = 0; i < MAX_PLAYER_COUNT; i++) { | ||
426 | if (players[i].keyboard == 0) { | ||
427 | players[i].keyboard = id; | ||
428 | as->player_count = SDL_max(as->player_count, i + 1); | ||
429 | break; | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | break; | ||
434 | } | ||
435 | case SDL_EVENT_KEY_UP: { | ||
436 | SDL_Keycode sym = event->key.key; | ||
437 | SDL_KeyboardID id = event->key.which; | ||
438 | if (sym == SDLK_ESCAPE) return SDL_APP_SUCCESS; | ||
439 | int index = whoseKeyboard(id, players, player_count); | ||
440 | if (index >= 0) { | ||
441 | if (sym == SDLK_W) players[index].wasd &= 30; | ||
442 | if (sym == SDLK_A) players[index].wasd &= 29; | ||
443 | if (sym == SDLK_S) players[index].wasd &= 27; | ||
444 | if (sym == SDLK_D) players[index].wasd &= 23; | ||
445 | if (sym == SDLK_SPACE) players[index].wasd &= 15; | ||
446 | } | ||
447 | break; | ||
448 | } | ||
449 | } | ||
450 | return SDL_APP_CONTINUE; | ||
451 | } | ||
452 | |||
453 | SDL_AppResult SDL_AppIterate(void *appstate) | ||
454 | { | ||
455 | AppState *as = appstate; | ||
456 | static Uint64 accu = 0; | ||
457 | static Uint64 last = 0; | ||
458 | static Uint64 past = 0; | ||
459 | Uint64 now = SDL_GetTicksNS(); | ||
460 | Uint64 dt_ns = now - past; | ||
461 | update(as->players, as->player_count, dt_ns); | ||
462 | draw(as->renderer, (const float (*)[6])as->edges, as->players, as->player_count); | ||
463 | if (now - last > 999999999) { | ||
464 | last = now; | ||
465 | SDL_snprintf(debug_string, sizeof(debug_string), "%" SDL_PRIu64 " fps", accu); | ||
466 | accu = 0; | ||
467 | } | ||
468 | past = now; | ||
469 | accu += 1; | ||
470 | Uint64 elapsed = SDL_GetTicksNS() - now; | ||
471 | if (elapsed < 999999) { | ||
472 | SDL_DelayNS(999999 - elapsed); | ||
473 | } | ||
474 | return SDL_APP_CONTINUE; | ||
475 | } | ||
476 | |||
477 | void SDL_AppQuit(void *appstate, SDL_AppResult result) | ||
478 | { | ||
479 | SDL_free(appstate); // just free the memory, SDL will clean up the window/renderer for us. | ||
480 | } \ No newline at end of file | ||