diff --git a/src/game.c b/src/game.c index ca4c0c2..06ffba5 100644 --- a/src/game.c +++ b/src/game.c @@ -12,6 +12,8 @@ #define MAX_ROPE_GRAB_LEN 80000 #define MIN_PHYSICS_STEP 2.0 +#define TIMESTEP_LENGTH 2.0 + #define BREAKPOINT *(int *)0 = 1; GlobWorld world; @@ -30,6 +32,9 @@ int get_floor_ceiling(); struct sg_times_list save_times_lst; +struct timespec last_tick; +double time_remaining = 0; + /* array of all the things in the world and their kinds */ //world_thing *world; @@ -1216,41 +1221,13 @@ void advance_thing(Body * thing) { return; } + double time_delta = TIMESTEP_LENGTH; + Vect translation; Vect friction; translation.x = translation.y = 0; int numcols = 0; - // get time delta - struct timespec now = get_now(); - clock_gettime(CLOCK_MONOTONIC, &now); - if (now.tv_nsec >= 1000000000) { - now.tv_nsec -= 1000000000; - } - - double time_delta = now.tv_nsec - thing->last_advance_time.tv_nsec; - - if (now.tv_nsec < thing->last_advance_time.tv_nsec) { - time_delta = now.tv_nsec - (thing->last_advance_time.tv_nsec - 1000000000); - } - time_delta *= 0.000001; // convert to ms from ns - - - // cap the time delta: simulatino will slow down -// printf("delta: %f\n", time_delta); - if (time_delta > 19) { - printf("ERROR too slow: %f\n", time_delta); - time_delta = 19; - quality--; - } - - if (time_delta < MIN_PHYSICS_STEP) { - SDL_Delay(MIN_PHYSICS_STEP); - advance_thing(thing); - return; - } - thing->last_advance_time = now; - // collisions if ((numcols = process_collisions(thing, &translation))) { /*double check = vect_scalar_projection(translation, thing->vel);*/ @@ -1483,37 +1460,52 @@ void get_projectile(Projectile** proj) { void advance_things(void) { int numcols; Vect translation; - for (int i = 0; i < world.items.size; i++) { - switch (world.get(i).kind) { - case PLAYER_W : - advance_thing((world.get(i).player->physics)); - continue; - case STATIC_WALL_W: - advance_thing(world.get(i).wall->physics); - continue; - case FLOOR: - continue; - /*for (int k = 0; k < world.get(i).floor->numPolys; k++) {*/ - /*advance_thing(world.get(i).floor->polys[k].physics);*/ - /*}*/ - /*break;*/ - case CEILING: - continue; - /*for (int k = 0; k < world.get(i).floor->numPolys; k++) {*/ - /*advance_thing(world.get(i).floor->polys[k].physics);*/ - /*}*/ - /*break;*/ - case PROJECTILE: - if ((numcols = process_collisions(world.get(i).projectile->physics, - &translation))) { - world.get(i).projectile->on_collision(world.get(i).projectile); - } - world.get(i).projectile->on_step(world.get(i).projectile); - continue; - default: - continue; - } + + /* update the timer */ + struct timespec now = get_now(); + double time_delta = now.tv_nsec - last_tick.tv_nsec; + + if (now.tv_nsec < last_tick.tv_nsec) { + time_delta = now.tv_nsec - (last_tick.tv_nsec - 1000000000); } + time_delta *= 0.000001; // convert to ms from ns + time_remaining += time_delta; + last_tick = now; + + while (time_remaining > TIMESTEP_LENGTH) { + time_remaining -= TIMESTEP_LENGTH; + for (int i = 0; i < world.items.size; i++) { + switch (world.get(i).kind) { + case PLAYER_W : + advance_thing((world.get(i).player->physics)); + continue; + case STATIC_WALL_W: + advance_thing(world.get(i).wall->physics); + continue; + case FLOOR: + continue; + /*for (int k = 0; k < world.get(i).floor->numPolys; k++) {*/ + /*advance_thing(world.get(i).floor->polys[k].physics);*/ + /*}*/ + /*break;*/ + case CEILING: + continue; + /*for (int k = 0; k < world.get(i).floor->numPolys; k++) {*/ + /*advance_thing(world.get(i).floor->polys[k].physics);*/ + /*}*/ + /*break;*/ + case PROJECTILE: + if ((numcols = process_collisions(world.get(i).projectile->physics, + &translation))) { + world.get(i).projectile->on_collision(world.get(i).projectile); + } + world.get(i).projectile->on_step(world.get(i).projectile); + continue; + default: + continue; + } + } + } } bool unique_world_kind(enum world_thing_kind k) { @@ -1742,6 +1734,7 @@ int step(void) { game_paused = 1; } + if (player.physics->position.x > world.uniques_index[ROOM_W]->room ->floor.items[world.uniques_index[ROOM_W]->room->floor.numItems - 1]->position.x) { return 1; @@ -1756,6 +1749,8 @@ int step(void) { if (in_game) { advance_things(); } + } else { + last_tick = get_now(); } return 0; diff --git a/src/main.c b/src/main.c index ca232fe..ebdafb6 100644 --- a/src/main.c +++ b/src/main.c @@ -48,24 +48,29 @@ void redraw(struct SDL_Renderer * ren) { SDL_RenderPresent(ren); } + +void godophysics(void) { + if (step()) { + // display end level screen + in_game = false; + game_paused = true; + SDL_Delay(300); + SDL_SemWait(resume); + add_time(level_time); + + SDL_LockMutex(player.physics->lock); + next_level(); + in_game = true; + SDL_UnlockMutex(player.physics->lock); + SDL_Delay(1000); + game_paused = false; + } +} + int physics_loop(void *ptr) { game_paused = 1; while (1) { - if (step()) { - // display end level screen - in_game = false; - game_paused = true; - SDL_Delay(300); - SDL_SemWait(resume); - add_time(level_time); - - SDL_LockMutex(player.physics->lock); - next_level(); - in_game = true; - SDL_UnlockMutex(player.physics->lock); - SDL_Delay(1000); - game_paused = 0; - } + godophysics(); } } @@ -77,9 +82,9 @@ int game(void) { logwrite(INFO, "Starting\n"); SDL_Window * win = make_window(); - SDL_Renderer * ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); + SDL_Renderer * ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED + | SDL_RENDERER_PRESENTVSYNC); SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND); -// | SDL_RENDERER_PRESENTVSYNC); queue_for_cleanup(win, WINDOW); queue_for_cleanup(ren, RENDERER); @@ -130,8 +135,6 @@ int game(void) { handle_input_event (event); } } - /* Redraw Screen */ -// step(10); if (!in_game) { draw_end_screen(ren);