From 7d876aaf2d9cc07595b56e41005516caac26411e Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Mon, 13 Oct 2025 21:04:50 +0100 Subject: [PATCH] Refactor to seperate shapes and physics --- main.c | 147 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 45 deletions(-) diff --git a/main.c b/main.c index c89aa13..974678c 100644 --- a/main.c +++ b/main.c @@ -5,12 +5,62 @@ #include #include +#define SHIP 0 +#define FIRE 1 + #define LIN_PWR 0.0001 -#define ROT_PWR 0.001 +#define ROT_PWR 0.002 + +#define MAX_SHAPES 8U +#define MAX_ENTITIES 8U #define MAX(a, b) ((a) < (b) ? (b) : (a)) #define NELEMS(arr) (sizeof(arr) / sizeof(arr[0])) +typedef struct { + bool visible; + int entity; + unsigned vert_count; + vec2_t verts[MAX_VERTS]; +} shape_t; + +typedef struct { + vec2_t pos; + vec2_t vel; + mat2_t dir; + float omg; +} entity_t; + +static shape_t shapes[MAX_SHAPES] = { + { + .visible = true, + .entity = SHIP, + .vert_count = 4, + .verts = { + { 0.0, 0.08 }, + { 0.05, -0.1 }, + { 0.0, -0.07 }, + { -0.05, -0.1 }, + }, + }, + { + .visible = false, + .entity = SHIP, + .vert_count = 3, + .verts = { + { 0.015, -0.1 }, + { -0.015, -0.1 }, + { 0.0, -0.15 }, + }, + }, +}; + +static entity_t entities[MAX_ENTITIES] = { + { .dir = { { 1, 0 }, { 0, 1 } } }, +}; + +static unsigned shape_count = 2; +static unsigned entity_count = 1; static float aspect; static bool quit = false; @@ -19,27 +69,6 @@ static struct { int fwd; } input; -static struct { - vec2_t pos; - vec2_t vel; - mat2_t dir; - float omg; -} state; - -static const vec2_t ship[] = { - { 0.0, 0.08 }, - { 0.05, -0.1 }, - { 0.0, -0.07 }, - { -0.05, -0.1 }, -}; -static const vec2_t fire[] = { - { 0.015, -0.1 }, - { -0.015, -0.1 }, - { 0.0, -0.15 }, -}; - -static const vec2_t thrust = { 0, LIN_PWR }; - static void key_press_callback(int key) { switch (key) { @@ -86,27 +115,58 @@ static void key_release_callback(int key) } } -static mat3_t update() +static mat3_t entity_transform(unsigned id) { - state.omg += ROT_PWR * (float)input.rot; - state.dir = mat2_mul_mat2(mat2_rotation(state.omg), state.dir); + const entity_t *e = entities + id; + return mat3_mul_mat3(mat3_translation(e->pos), mat2_extend(e->dir)); +} - const vec2_t acc - = mat2_mul_vec2(state.dir, vec2_scale(thrust, (float)input.fwd)); - state.vel = vec2_add(state.vel, acc); - state.pos = vec2_add(state.pos, state.vel); +static void ship_update() +{ + entity_t *ship = entities + SHIP; - if (state.pos.y > 1) - state.pos.y -= 2; - else if (state.pos.y < -1) - state.pos.y += 2; - if (state.pos.x > aspect) - state.pos.x -= 2 * aspect; - else if (state.pos.x < -aspect) - state.pos.x += 2 * aspect; + ship->omg += ROT_PWR * (float)input.rot; - return mat3_mul_mat3( - mat3_translation(state.pos), mat2_extend(state.dir)); + const vec2_t thrust = { 0, (float)input.fwd * LIN_PWR }; + const vec2_t acc = mat2_mul_vec2(ship->dir, thrust); + ship->vel = vec2_add(ship->vel, acc); + + shapes[FIRE].visible = input.fwd != 0; +} + +static void update() +{ + ship_update(); + + for (unsigned i = 0; i < entity_count; ++i) { + entity_t *e = entities + i; + + e->dir = mat2_mul_mat2(mat2_rotation(e->omg), e->dir); + e->pos = vec2_add(e->pos, e->vel); + + if (e->pos.y > 1) + e->pos.y -= 2; + else if (e->pos.y < -1) + e->pos.y += 2; + if (e->pos.x > aspect) + e->pos.x -= 2 * aspect; + else if (e->pos.x < -aspect) + e->pos.x += 2 * aspect; + } +} + +static void draw() +{ + static mat3_t transforms[MAX_ENTITIES]; + for (unsigned i = 0; i < entity_count; ++i) + transforms[i] = entity_transform(i); + + for (unsigned i = 0; i < shape_count; ++i) { + if (!shapes[i].visible) + continue; + const mat3_t transform = transforms[shapes[i].entity]; + renderer_draw(shapes[i].verts, shapes[i].vert_count, transform); + } } int main() @@ -121,8 +181,6 @@ int main() renderer_clear(); renderer_swap(); - state.dir = (mat2_t) { { 1, 0 }, { 0, 1 } }; - const int max_fd = MAX(input_fd, drm_fd); fd_set set; @@ -139,12 +197,11 @@ int main() if (FD_ISSET(drm_fd, &set)) { renderer_handle(); - const mat3_t m = update(); + update(); renderer_clear(); - renderer_draw(ship, NELEMS(ship), m); - if (input.fwd != 0) - renderer_draw(fire, NELEMS(fire), m); + draw(); + renderer_swap(); } }