summaryrefslogtreecommitdiff
path: root/lib/physics.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/physics.c')
-rw-r--r--lib/physics.c124
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;
+}