Files
asteroids/scene.c

106 lines
2.0 KiB
C

#include "scene.h"
#include "entity.h"
#include "physics.h"
#include "renderer.h"
#include <assert.h>
#include <string.h>
#define MAX_SHAPES 256U
typedef struct {
unsigned entity_id;
unsigned component_id;
unsigned vert_count;
vec2_t verts[MAX_VERTS];
scene_anim_cb_t anim_cb;
bool hidden;
bool connect;
} shape_t;
static unsigned count;
static shape_t shapes[MAX_SHAPES];
static void update(unsigned new_entity_id, void *ref)
{
shape_t *s = (shape_t *)ref;
s->entity_id = new_entity_id;
}
static void remove(void *ref)
{
shape_t *s = (shape_t *)ref;
const shape_t *last = shapes + (count - 1);
if (s < last) {
memcpy(s, last, sizeof(shape_t));
entity_update_component(s->entity_id, s->component_id, s);
}
--count;
}
static mat3_t get_transform(unsigned entity_id)
{
const physics_t *phys = physics_get(entity_id);
return mat3_mul_mat3(
mat3_translation(phys->pos), mat2_extend(phys->dir));
}
void scene_clear()
{
count = 0;
}
void scene_update()
{
for (unsigned i = 0; i < count; ++i) {
if (shapes[i].anim_cb != nullptr)
shapes[i].anim_cb(shapes[i].verts);
}
}
void scene_draw()
{
for (unsigned i = 0; i < count; ++i) {
const shape_t *s = shapes + i;
if (!s->hidden) {
const mat3_t m = get_transform(s->entity_id);
renderer_draw(s->verts, s->vert_count, m, s->connect);
}
}
}
unsigned scene_add(
unsigned entity, const vec2_t *verts, unsigned vert_count, bool connect)
{
assert(count < MAX_SHAPES);
const unsigned id = count++;
shape_t *s = shapes + id;
*s = (shape_t) {
.entity_id = entity,
.vert_count = vert_count,
.connect = connect,
};
memcpy(s->verts, verts, vert_count * sizeof(vec2_t));
s->component_id = entity_add_component(entity, update, remove, s);
return id;
}
void scene_hide(unsigned id)
{
assert(id < count);
shapes[id].hidden = true;
}
void scene_show(unsigned id)
{
assert(id < count);
shapes[id].hidden = false;
}
void scene_animate(unsigned id, scene_anim_cb_t cb)
{
assert(id < count);
shapes[id].anim_cb = cb;
}