summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJoel Stålnacke <joel@saker.fi>2025-07-26 21:09:26 +0300
committerJoel Stålnacke <joel@saker.fi>2025-07-26 21:09:26 +0300
commit63506e59366acddf4a9e017ad8aebeadcf58c164 (patch)
tree2fa106661b85497fc1d63b7743a78e523ab48fba /lib
parent53f68bb7b0dce309723675c4b97f726a469031c0 (diff)
Old changesHEADmaster
Diffstat (limited to 'lib')
-rwxr-xr-xlib/build.sh4
-rw-r--r--lib/common.h1
-rw-r--r--lib/constants.h12
-rw-r--r--lib/physics.c124
-rw-r--r--lib/physics.h17
-rw-r--r--lib/player.c36
-rw-r--r--lib/player.h5
-rw-r--r--lib/snapshot.c99
-rw-r--r--lib/snapshot.h39
-rw-r--r--lib/types.h9
-rw-r--r--lib/vec2.c7
-rw-r--r--lib/world.c105
-rw-r--r--lib/world.h31
13 files changed, 348 insertions, 141 deletions
diff --git a/lib/build.sh b/lib/build.sh
index f305939..3f8b5a6 100755
--- a/lib/build.sh
+++ b/lib/build.sh
@@ -6,9 +6,9 @@ fail() {
}
CC=cc
-CFLAGS="-std=c99 -Wall -Wextra -Wpedantic -D_POSIX_C_SOURCE=200809L"
+CFLAGS="-std=c99 -Wall -Wextra -Wpedantic -Og -g -D_POSIX_C_SOURCE=200809L"
LDFLAGS="-fPIC -lm"
-SOURCES="test.c vec2.c world.c log.c"
+SOURCES="test.c vec2.c snapshot.c log.c player.c physics.c"
output="build"
for arg ; do
diff --git a/lib/common.h b/lib/common.h
new file mode 100644
index 0000000..d6d8816
--- /dev/null
+++ b/lib/common.h
@@ -0,0 +1 @@
+#define LENGTH(x) (sizeof(x) / sizeof(x[0]))
diff --git a/lib/constants.h b/lib/constants.h
new file mode 100644
index 0000000..817fa43
--- /dev/null
+++ b/lib/constants.h
@@ -0,0 +1,12 @@
+#define WORLD_MAX_PLAYERS 5
+#define WORLD_MAX_BULLETS 5000
+
+#define PLAYER_ACCELERATION 150.0f
+#define PLAYER_DRAG 2.0f
+
+enum {
+ INPUT_UP = 1 << 0,
+ INPUT_DOWN = 1 << 1,
+ INPUT_LEFT = 1 << 2,
+ INPUT_RIGHT = 1 << 3
+};
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;
+}
diff --git a/lib/physics.h b/lib/physics.h
new file mode 100644
index 0000000..7aa2b31
--- /dev/null
+++ b/lib/physics.h
@@ -0,0 +1,17 @@
+#include "types.h"
+
+struct snapshot;
+
+/* A game world */
+struct context {
+ size_t snapshots_len;
+ struct snapshot *snapshots;
+};
+
+struct context *dp_physics_context_create(size_t snapshots);
+void dp_physics_context_free(struct context *);
+
+struct snapshot *dp_physics_context_get_snapshot(struct context *);
+void dp_physics_context_return_snapshot(struct context *, struct snapshot *);
+
+int dp_physics_tick(const struct snapshot *current, double delta, struct snapshot *next);
diff --git a/lib/player.c b/lib/player.c
new file mode 100644
index 0000000..35c3b80
--- /dev/null
+++ b/lib/player.c
@@ -0,0 +1,36 @@
+#include "snapshot.h"
+
+#include "player.h"
+
+vec2
+dp_player_calculate_acceleration(const struct player *p)
+{
+ vec2 acc, dec;
+ int x = 0, y = 0;
+
+ if (p->input & INPUT_UP)
+ {
+ y -= 1;
+ }
+ if (p->input & INPUT_DOWN)
+ {
+ y += 1;
+ }
+
+ if (p->input & INPUT_LEFT)
+ {
+ x -= 1;
+ }
+ if (p->input & INPUT_RIGHT)
+ {
+ x += 1;
+ }
+
+ acc = dp_vec2_new((float)x, (float)y);
+ acc = dp_vec2_normal(acc);
+ acc = dp_vec2_mul(acc, PLAYER_ACCELERATION);
+
+ dec = dp_vec2_mul(p->vel, -1.0f * PLAYER_DRAG);
+
+ return dp_vec2_add(acc, dec);
+}
diff --git a/lib/player.h b/lib/player.h
new file mode 100644
index 0000000..2f365bf
--- /dev/null
+++ b/lib/player.h
@@ -0,0 +1,5 @@
+#include "types.h"
+
+struct player;
+
+vec2 dp_player_calculate_acceleration(const struct player *);
diff --git a/lib/snapshot.c b/lib/snapshot.c
new file mode 100644
index 0000000..88c17a1
--- /dev/null
+++ b/lib/snapshot.c
@@ -0,0 +1,99 @@
+#include <string.h>
+
+#include "common.h"
+
+#include "snapshot.h"
+
+int dp_snapshot_put_player(struct snapshot *s, uint32_t id, const struct player *p)
+{
+ if (!s || !p)
+ return -1;
+ if (id >= LENGTH(s->players))
+ return -1;
+
+ s->players[id] = *p;
+ s->players[id].state = STATE_ACTIVE;
+ return 0;
+}
+
+struct player *dp_snapshot_get_player(struct snapshot *s, uint32_t id)
+{
+ struct player *p;
+
+ if (!s)
+ return NULL;
+ if (id >= LENGTH(s->players))
+ return NULL;
+
+ p = &s->players[id];
+ if (p->state == STATE_INACTIVE)
+ return NULL;
+ return p;
+}
+
+int dp_snapshot_remove_player(struct snapshot *s, uint32_t id)
+{
+ struct player *p;
+
+ if (!s)
+ return -1;
+ if (id >= LENGTH(s->players))
+ return -1;
+
+ p = dp_snapshot_get_player(s, id);
+ memset(p, 0, sizeof(*p));
+ p->state = STATE_REMOVED;
+ return 0;
+}
+
+int dp_snapshot_set_player_input(struct snapshot *s, uint32_t id, uint8_t input)
+{
+ struct player *p;
+
+ if (!(p = dp_snapshot_get_player(s, id)))
+ return -1;
+ p->input = input;
+ return 0;
+}
+
+int dp_snapshot_put_ball(struct snapshot *s, uint32_t id, const struct ball *b)
+{
+ if (!s || !b)
+ return -1;
+ if (id >= LENGTH(s->balls))
+ return -1;
+
+ s->balls[id] = *b;
+ s->balls[id].state = STATE_ACTIVE;
+ return 0;
+}
+
+struct ball *dp_snapshot_get_ball(struct snapshot *s, uint32_t id)
+{
+ struct ball *b;
+
+ if (!s)
+ return NULL;
+ if (id >= LENGTH(s->balls))
+ return NULL;
+
+ b = &s->balls[id];
+ if (b->state == STATE_INACTIVE)
+ return NULL;
+ return b;
+}
+
+int dp_snapshot_remove_ball(struct snapshot *s, uint32_t id)
+{
+ struct ball *b;
+
+ if (!s)
+ return -1;
+ if (id >= LENGTH(s->balls))
+ return -1;
+
+ b = dp_snapshot_get_ball(s, id);
+ memset(b, 0, sizeof(*b));
+ b->state = STATE_REMOVED;
+ return 0;
+}
diff --git a/lib/snapshot.h b/lib/snapshot.h
new file mode 100644
index 0000000..022d989
--- /dev/null
+++ b/lib/snapshot.h
@@ -0,0 +1,39 @@
+#include "types.h"
+#include "constants.h"
+
+enum {
+ STATE_INACTIVE = 0,
+ STATE_ACTIVE,
+ STATE_REMOVED,
+ STATE_DEAD
+};
+
+struct player {
+ uint8_t state;
+ uint8_t input;
+ char pad[2];
+ vec2 pos;
+ vec2 vel;
+};
+
+struct ball {
+ uint8_t state;
+ vec2 pos;
+ vec2 vel;
+};
+
+struct snapshot {
+ char active;
+ uint32_t tick;
+ struct player players[WORLD_MAX_PLAYERS];
+ struct ball balls[WORLD_MAX_BULLETS];
+};
+
+int dp_snapshot_put_player(struct snapshot *, uint32_t id, const struct player *);
+struct player *dp_snapshot_get_player(struct snapshot *, uint32_t id);
+int dp_snapshot_remove_player(struct snapshot *, uint32_t id);
+int dp_snapshot_set_player_input(struct snapshot *, uint32_t id, uint8_t input);
+
+int dp_snapshot_put_ball(struct snapshot *, uint32_t id, const struct ball *);
+struct ball *dp_snapshot_get_ball(struct snapshot *, uint32_t id);
+int dp_snapshot_remove_ball(struct snapshot *, uint32_t id);
diff --git a/lib/types.h b/lib/types.h
index 8618df9..bf42576 100644
--- a/lib/types.h
+++ b/lib/types.h
@@ -1,3 +1,10 @@
+#ifndef _TYPES_H
+#define _TYPES_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
typedef struct {
float x;
float y;
@@ -10,3 +17,5 @@ vec2 dp_vec2_mul(vec2, float scalar);
vec2 dp_vec2_dot(vec2, vec2);
float dp_vec2_length(vec2);
vec2 dp_vec2_normal(vec2);
+
+#endif
diff --git a/lib/vec2.c b/lib/vec2.c
index d795d50..55f5078 100644
--- a/lib/vec2.c
+++ b/lib/vec2.c
@@ -61,7 +61,8 @@ dp_vec2_length(vec2 v)
vec2
dp_vec2_normal(vec2 v)
{
- float a;
- a = 1.f / dp_vec2_length(v);
- return dp_vec2_mul(v, a);
+ float len = dp_vec2_length(v);
+ if (len == 0.0f)
+ return dp_vec2_new(0.0f, 0.0f);
+ return dp_vec2_mul(v, 1.0f / len);
}
diff --git a/lib/world.c b/lib/world.c
deleted file mode 100644
index 34d7489..0000000
--- a/lib/world.c
+++ /dev/null
@@ -1,105 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include "types.h"
-#include "world.h"
-#include "log.h"
-
-struct world {
- struct entity entities[WORLD_MAX_ENTITIES];
-};
-
-struct world *
-dp_world_create()
-{
- struct world *w;
-
- if (!(w = malloc(sizeof(*w))))
- return NULL;
- memset(w, 0, sizeof(*w));
-
- return w;
-}
-
-void
-dp_free_world(struct world *w)
-{
- if (w)
- free(w);
-}
-
-int
-dp_world_create_entity(struct world *w, int kind)
-{
- int i;
- struct entity *e;
-
- if (!w)
- return -1;
- if (kind == ENTITY_NONE)
- return -1;
-
- for (i = 0; i < WORLD_MAX_ENTITIES; i++) {
- e = &w->entities[i];
- if (e->kind != ENTITY_NONE)
- continue;
- e->kind = kind;
- return i;
- }
-
- return -1;
-}
-
-struct entity *
-dp_world_find_entity(struct world *w, int entity_id)
-{
- struct entity *e;
-
- if (!w || entity_id < 0)
- return NULL;
- if (entity_id >= WORLD_MAX_ENTITIES)
- return NULL;
-
- e = &w->entities[entity_id];
-
- if (e->kind == ENTITY_NONE)
- return NULL;
-
- return e;
-}
-
-int
-dp_world_remove_entity(struct world *w, int entity_id)
-{
- struct entity *e;
-
- if (!(e = dp_world_find_entity(w, entity_id)))
- return -1;
-
- memset(e, 0, sizeof(*e));
- e->kind = ENTITY_NONE;
- return 0;
-}
-
-int
-dp_world_tick(struct world *w, double delta)
-{
- int i;
- struct entity *e;
- struct entity_ball *ball;
-
- for (i = 0; i < WORLD_MAX_ENTITIES; i++)
- {
- e = &w->entities[i];
- switch (e->kind) {
- case ENTITY_BALL:
- ball = &e->e.ball;
- /*ball->pos = dp_vec2_new(500.0, 500.0);*/
- ball->pos = dp_vec2_add(ball->pos, dp_vec2_mul(ball->vel, delta));
- break;
- default:
- break;
- }
- }
- return 0;
-}
diff --git a/lib/world.h b/lib/world.h
deleted file mode 100644
index 40c3fef..0000000
--- a/lib/world.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#define WORLD_MAX_ENTITIES 5000
-
-enum {
- ENTITY_NONE,
- ENTITY_BALL
-};
-
-struct entity_ball {
- vec2 pos;
- vec2 vel;
-};
-
-union entity_union {
- struct entity_ball ball;
-};
-
-struct entity {
- int kind;
- union entity_union e;
-};
-
-struct world;
-
-struct world *dp_world_create();
-void dp_world_free(struct world *);
-
-int dp_world_create_entity(struct world *, int kind);
-struct entity *dp_world_find_entity(struct world *, int entity_id);
-int dp_world_remove_entity(struct world *, int entity_id);
-
-int dp_world_tick(struct world *, double delta);