Add control / update logic
This commit is contained in:
89
main.c
89
main.c
@@ -3,19 +3,38 @@
|
|||||||
|
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define LIN_PWR 0.0001
|
||||||
|
#define ROT_PWR 0.001
|
||||||
|
|
||||||
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
#define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||||
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
|
||||||
|
static float aspect;
|
||||||
static bool quit = false;
|
static bool quit = false;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
int rot;
|
||||||
|
int fwd;
|
||||||
|
} input;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
vec2_t pos;
|
||||||
|
vec2_t vel;
|
||||||
|
mat2_t dir;
|
||||||
|
float omg;
|
||||||
|
} state;
|
||||||
|
|
||||||
static const vec2_t ship[] = {
|
static const vec2_t ship[] = {
|
||||||
{ 0.0, 0.1 },
|
{ 0.0, 0.08 },
|
||||||
{ 0.05, -0.1 },
|
{ 0.05, -0.1 },
|
||||||
{ 0.0, -0.05 },
|
{ 0.0, -0.07 },
|
||||||
{ -0.05, -0.1 },
|
{ -0.05, -0.1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const vec2_t thrust = { 0, LIN_PWR };
|
||||||
|
|
||||||
static void key_press_callback(int key)
|
static void key_press_callback(int key)
|
||||||
{
|
{
|
||||||
switch (key) {
|
switch (key) {
|
||||||
@@ -23,21 +42,82 @@ static void key_press_callback(int key)
|
|||||||
quit = true;
|
quit = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case KEY_UP:
|
||||||
|
++input.fwd;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_LEFT:
|
||||||
|
++input.rot;
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
--input.rot;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void key_release_callback(int key)
|
||||||
|
{
|
||||||
|
switch (key) {
|
||||||
|
case KEY_Q:
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_UP:
|
||||||
|
--input.fwd;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_LEFT:
|
||||||
|
--input.rot;
|
||||||
|
break;
|
||||||
|
case KEY_RIGHT:
|
||||||
|
++input.rot;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static mat3_t update()
|
||||||
|
{
|
||||||
|
state.omg += ROT_PWR * (float)input.rot;
|
||||||
|
state.dir = mat2_mul_mat2(mat2_rotation(state.omg), state.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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
return mat3_mul_mat3(
|
||||||
|
mat3_translation(state.pos), mat2_extend(state.dir));
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
const int input_fd = input_init();
|
const int input_fd = input_init();
|
||||||
input_on_press(key_press_callback);
|
input_on_press(key_press_callback);
|
||||||
|
input_on_release(key_release_callback);
|
||||||
|
|
||||||
const renderer_params_t renderer_params = renderer_init();
|
const renderer_params_t renderer_params = renderer_init();
|
||||||
|
aspect = renderer_params.aspect;
|
||||||
const int drm_fd = renderer_params.drm_fd;
|
const int drm_fd = renderer_params.drm_fd;
|
||||||
renderer_clear();
|
renderer_clear();
|
||||||
renderer_swap();
|
renderer_swap();
|
||||||
|
|
||||||
|
state.dir = (mat2_t) { { 1, 0 }, { 0, 1 } };
|
||||||
|
|
||||||
const int max_fd = MAX(input_fd, drm_fd);
|
const int max_fd = MAX(input_fd, drm_fd);
|
||||||
fd_set set;
|
fd_set set;
|
||||||
|
|
||||||
@@ -53,8 +133,11 @@ int main()
|
|||||||
|
|
||||||
if (FD_ISSET(drm_fd, &set)) {
|
if (FD_ISSET(drm_fd, &set)) {
|
||||||
renderer_handle();
|
renderer_handle();
|
||||||
|
|
||||||
|
const mat3_t m = update();
|
||||||
|
|
||||||
renderer_clear();
|
renderer_clear();
|
||||||
renderer_draw(ship, NELEMS(ship));
|
renderer_draw(ship, NELEMS(ship), m);
|
||||||
renderer_swap();
|
renderer_swap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
73
maths.c
73
maths.c
@@ -1,15 +1,82 @@
|
|||||||
#include "maths.h"
|
#include "maths.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
vec2_t vec2_add(vec2_t v1, vec2_t v2)
|
||||||
|
{
|
||||||
|
return (vec2_t) { v1.x + v2.x, v1.y + v2.y };
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2_t vec2_scale(vec2_t v, float s)
|
||||||
|
{
|
||||||
|
return (vec2_t) { s * v.x, s * v.y };
|
||||||
|
}
|
||||||
|
|
||||||
vec3_t vec2_extend(vec2_t v)
|
vec3_t vec2_extend(vec2_t v)
|
||||||
{
|
{
|
||||||
return (vec3_t) { v.x, v.y, 1 };
|
return (vec3_t) { v.x, v.y, 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat2_t mat2_rotation(float theta)
|
||||||
|
{
|
||||||
|
return (mat2_t) {
|
||||||
|
{ cosf(theta), sinf(theta) },
|
||||||
|
{ -sinf(theta), cosf(theta) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2_t mat2_mul_vec2(mat2_t m, vec2_t v)
|
||||||
|
{
|
||||||
|
return (vec2_t) {
|
||||||
|
m.x.x * v.x + m.y.x * v.y,
|
||||||
|
m.x.y * v.x + m.y.y * v.y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
mat2_t mat2_mul_mat2(mat2_t m1, mat2_t m2)
|
||||||
|
{
|
||||||
|
#define ELEM(i, j) m1.x.j *m2.i.x + m1.y.j *m2.i.y
|
||||||
|
return (mat2_t) {
|
||||||
|
{ ELEM(x, x), ELEM(x, y) },
|
||||||
|
{ ELEM(y, x), ELEM(y, y) },
|
||||||
|
};
|
||||||
|
#undef ELEM
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3_t mat2_extend(mat2_t m)
|
||||||
|
{
|
||||||
|
return (mat3_t) {
|
||||||
|
{ m.x.x, m.x.y, 0 },
|
||||||
|
{ m.y.x, m.y.y, 0 },
|
||||||
|
{ 0, 0, 1 },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3_t mat3_translation(vec2_t v)
|
||||||
|
{
|
||||||
|
return (mat3_t) {
|
||||||
|
{ 1, 0, 0 },
|
||||||
|
{ 0, 1, 0 },
|
||||||
|
{ v.x, v.y, 1 },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
vec3_t mat3_mul_vec3(mat3_t m, vec3_t v)
|
vec3_t mat3_mul_vec3(mat3_t m, vec3_t v)
|
||||||
{
|
{
|
||||||
return (vec3_t) {
|
return (vec3_t) {
|
||||||
.x = m.x.x * v.x + m.y.x * v.y + m.z.x * v.z,
|
m.x.x * v.x + m.y.x * v.y + m.z.x * v.z,
|
||||||
.y = m.x.y * v.x + m.y.y * v.y + m.z.y * v.z,
|
m.x.y * v.x + m.y.y * v.y + m.z.y * v.z,
|
||||||
.z = m.x.z * v.x + m.y.z * v.y + m.z.z * v.z,
|
m.x.z * v.x + m.y.z * v.y + m.z.z * v.z,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat3_t mat3_mul_mat3(mat3_t m1, mat3_t m2)
|
||||||
|
{
|
||||||
|
#define ELEM(i, j) m1.x.j *m2.i.x + m1.y.j *m2.i.y + m1.z.j *m2.i.z
|
||||||
|
return (mat3_t) {
|
||||||
|
{ ELEM(x, x), ELEM(x, y), ELEM(x, z) },
|
||||||
|
{ ELEM(y, x), ELEM(y, y), ELEM(y, z) },
|
||||||
|
{ ELEM(z, x), ELEM(z, y), ELEM(z, z) },
|
||||||
|
};
|
||||||
|
#undef ELEM
|
||||||
|
}
|
||||||
|
|||||||
27
maths.h
27
maths.h
@@ -1,24 +1,35 @@
|
|||||||
#ifndef MATHS_H
|
#ifndef MATHS_H
|
||||||
#define MATHS_H
|
#define MATHS_H
|
||||||
|
|
||||||
|
#define PI 3.14159265358979323846264
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float x;
|
float x, y;
|
||||||
float y;
|
|
||||||
} vec2_t;
|
} vec2_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float x;
|
vec2_t x, y;
|
||||||
float y;
|
} mat2_t;
|
||||||
float z;
|
|
||||||
|
typedef struct {
|
||||||
|
float x, y, z;
|
||||||
} vec3_t;
|
} vec3_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
vec3_t x;
|
vec3_t x, y, z;
|
||||||
vec3_t y;
|
|
||||||
vec3_t z;
|
|
||||||
} mat3_t;
|
} mat3_t;
|
||||||
|
|
||||||
|
vec2_t vec2_add(vec2_t v1, vec2_t v2);
|
||||||
|
vec2_t vec2_scale(vec2_t v, float s);
|
||||||
vec3_t vec2_extend(vec2_t v);
|
vec3_t vec2_extend(vec2_t v);
|
||||||
|
|
||||||
|
mat2_t mat2_rotation(float theta);
|
||||||
|
vec2_t mat2_mul_vec2(mat2_t m, vec2_t v);
|
||||||
|
mat2_t mat2_mul_mat2(mat2_t m1, mat2_t m2);
|
||||||
|
mat3_t mat2_extend(mat2_t m);
|
||||||
|
|
||||||
|
mat3_t mat3_translation(vec2_t v);
|
||||||
vec3_t mat3_mul_vec3(mat3_t m, vec3_t v);
|
vec3_t mat3_mul_vec3(mat3_t m, vec3_t v);
|
||||||
|
mat3_t mat3_mul_mat3(mat3_t m1, mat3_t m2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -143,11 +143,12 @@ void renderer_swap()
|
|||||||
back = (back + 1) & 1;
|
back = (back + 1) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer_draw(const vec2_t *vs, unsigned count)
|
void renderer_draw(const vec2_t *vs, unsigned count, mat3_t model)
|
||||||
{
|
{
|
||||||
|
mat3_t transform = mat3_mul_mat3(view, model);
|
||||||
assert(count < MAX_VERTS_PER_DRAW);
|
assert(count < MAX_VERTS_PER_DRAW);
|
||||||
for (unsigned i = 0; i < count; ++i)
|
for (unsigned i = 0; i < count; ++i)
|
||||||
vert_buf[i] = mat3_mul_vec3(view, vec2_extend(vs[i]));
|
vert_buf[i] = mat3_mul_vec3(transform, vec2_extend(vs[i]));
|
||||||
for (unsigned i = 1; i < count; ++i)
|
for (unsigned i = 1; i < count; ++i)
|
||||||
draw_line(vert_buf[i - 1], vert_buf[i]);
|
draw_line(vert_buf[i - 1], vert_buf[i]);
|
||||||
draw_line(vert_buf[count - 1], vert_buf[0]);
|
draw_line(vert_buf[count - 1], vert_buf[0]);
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ void renderer_handle();
|
|||||||
void renderer_clear();
|
void renderer_clear();
|
||||||
void renderer_swap();
|
void renderer_swap();
|
||||||
|
|
||||||
void renderer_draw(const vec2_t *vs, unsigned count);
|
void renderer_draw(const vec2_t *vs, unsigned count, mat3_t model);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user