#include #include #include #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; }