1
1
Fork 0
Browse Source

deteministicish physics

master
alistair 3 years ago
parent
commit
e84be25cb3
  1. 115
      src/game.c
  2. 41
      src/main.c

115
src/game.c

@ -12,6 +12,8 @@ @@ -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(); @@ -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) { @@ -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) { @@ -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) { @@ -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) { @@ -1756,6 +1749,8 @@ int step(void) {
if (in_game) {
advance_things();
}
} else {
last_tick = get_now();
}
return 0;

41
src/main.c

@ -48,24 +48,29 @@ void redraw(struct SDL_Renderer * ren) { @@ -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) { @@ -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) { @@ -130,8 +135,6 @@ int game(void) {
handle_input_event (event);
}
}
/* Redraw Screen */
// step(10);
if (!in_game) {
draw_end_screen(ren);

Loading…
Cancel
Save