150 lines
2.4 KiB
C
150 lines
2.4 KiB
C
#include "input.h"
|
|
#include "renderer.h"
|
|
|
|
#include <linux/input-event-codes.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 NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
|
|
|
static float aspect;
|
|
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[] = {
|
|
{ 0.0, 0.08 },
|
|
{ 0.05, -0.1 },
|
|
{ 0.0, -0.07 },
|
|
{ -0.05, -0.1 },
|
|
};
|
|
|
|
static const vec2_t thrust = { 0, LIN_PWR };
|
|
|
|
static void key_press_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 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()
|
|
{
|
|
const int input_fd = input_init();
|
|
input_on_press(key_press_callback);
|
|
input_on_release(key_release_callback);
|
|
|
|
const renderer_params_t renderer_params = renderer_init();
|
|
aspect = renderer_params.aspect;
|
|
const int drm_fd = renderer_params.drm_fd;
|
|
renderer_clear();
|
|
renderer_swap();
|
|
|
|
state.dir = (mat2_t) { { 1, 0 }, { 0, 1 } };
|
|
|
|
const int max_fd = MAX(input_fd, drm_fd);
|
|
fd_set set;
|
|
|
|
while (!quit) {
|
|
FD_ZERO(&set);
|
|
FD_SET(input_fd, &set);
|
|
FD_SET(drm_fd, &set);
|
|
|
|
select(max_fd + 1, &set, nullptr, nullptr, nullptr);
|
|
|
|
if (FD_ISSET(input_fd, &set))
|
|
input_handle();
|
|
|
|
if (FD_ISSET(drm_fd, &set)) {
|
|
renderer_handle();
|
|
|
|
const mat3_t m = update();
|
|
|
|
renderer_clear();
|
|
renderer_draw(ship, NELEMS(ship), m);
|
|
renderer_swap();
|
|
}
|
|
}
|
|
|
|
renderer_cleanup();
|
|
input_cleanup();
|
|
|
|
return 0;
|
|
}
|