diff options
Diffstat (limited to 'lib/physics.c')
| -rw-r--r-- | lib/physics.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/lib/physics.c b/lib/physics.c new file mode 100644 index 0000000..adcf433 --- /dev/null +++ b/lib/physics.c @@ -0,0 +1,124 @@ +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "common.h" +#include "player.h" +#include "snapshot.h" +#include "types.h" + +#include "physics.h" + +struct context * +dp_physics_context_create(size_t snapshots) +{ + struct context *ctx = NULL; + + if (!(ctx = malloc(sizeof(*ctx)))) + return NULL; + memset(ctx, 0, sizeof(*ctx)); + + ctx->snapshots_len = snapshots; + if (!(ctx->snapshots = malloc(sizeof(*ctx->snapshots) * snapshots))) + { + free(ctx); + return NULL; + } + memset(ctx->snapshots, 0, sizeof(*ctx->snapshots) * snapshots); + + return ctx; +} + +void +dp_physics_context_free(struct context *ctx) +{ + if (!ctx) + return; + if (ctx->snapshots) + free(ctx->snapshots); + free(ctx); +} + +struct snapshot *dp_physics_context_get_snapshot(struct context *ctx) +{ + size_t i; + struct snapshot *s; + + for (i = 0; i < ctx->snapshots_len; i++) + { + s = &ctx->snapshots[i]; + if (!s->active) + { + s->active = true; + return s; + } + } + return NULL; +} + +void dp_physics_context_return_snapshot(struct context *ctx, struct snapshot *s) +{ + size_t i; + + assert(s->active); + + for (i = 0; i < ctx->snapshots_len; i++) + { + if (s == &ctx->snapshots[i]) + { + s->active = false; + } + } + + assert(!s->active); +} + +static void +dp_physics_tick_player(const struct player *cur, double delta, struct player *next) +{ + vec2 acc; + + next->state = cur->state; + if (next->state == STATE_REMOVED) + next->state = STATE_INACTIVE; + if (next->state == STATE_INACTIVE) + return; + + acc = dp_player_calculate_acceleration(cur); + next->vel = dp_vec2_add(cur->vel, dp_vec2_mul(acc, delta)); + next->pos = dp_vec2_add(cur->pos, dp_vec2_mul(next->vel, delta)); +} + +static void +dp_physics_tick_ball(const struct ball *cur, double delta, struct ball *next) +{ + next->state = cur->state; + if (next->state == STATE_REMOVED) + next->state = STATE_INACTIVE; + if (next->state == STATE_INACTIVE) + return; + + next->pos = dp_vec2_add(cur->pos, dp_vec2_mul(cur->vel, delta)); +} + +int +dp_physics_tick(const struct snapshot *cur, double delta, struct snapshot *next) +{ + size_t i; + + assert(cur->active); + assert(next->active); + + for (i = 0; i < LENGTH(cur->players); i++) + { + dp_physics_tick_player(&cur->players[i], delta, &next->players[i]); + } + + for (i = 0; i < LENGTH(cur->balls); i++) + { + dp_physics_tick_ball(&cur->balls[i], delta, &next->balls[i]); + } + + next->tick = cur->tick + 1; + return 0; +} |
