Files
asteroids/input.c

110 lines
1.5 KiB
C

#include "input.h"
#include <assert.h>
#include <fcntl.h>
#include <linux/input.h>
#include <string.h>
#include <unistd.h>
enum {
RELEASE = 0,
PRESS = 1,
REPEAT = 2,
};
input_state_t input;
static int input_fd;
static input_callback_t shoot;
static void key_press(int key)
{
switch (key) {
case KEY_Q:
input.quit = true;
break;
case KEY_UP:
++input.thrust;
break;
case KEY_LEFT:
++input.spin;
break;
case KEY_RIGHT:
--input.spin;
break;
case KEY_SPACE:
if (shoot != nullptr)
shoot();
break;
}
}
static void key_release(int key)
{
switch (key) {
case KEY_UP:
--input.thrust;
break;
case KEY_LEFT:
--input.spin;
break;
case KEY_RIGHT:
++input.spin;
break;
}
}
static void key_repeat(int key)
{
if (key == KEY_SPACE && shoot != nullptr)
shoot();
}
int input_init()
{
memset(&input, 0, sizeof(input));
shoot = nullptr;
input_fd = open("/dev/input/event0", O_RDONLY);
assert(input_fd != -1);
const int res = ioctl(input_fd, EVIOCGRAB, (void *)1);
assert(res != -1);
return input_fd;
}
void input_cleanup()
{
ioctl(input_fd, EVIOCGRAB, (void *)0);
close(input_fd);
}
void input_on_shoot(input_callback_t cb)
{
shoot = cb;
}
void input_handle()
{
struct input_event ev;
const int len = read(input_fd, &ev, sizeof(ev));
assert(len == sizeof(ev));
if (ev.type == EV_KEY) {
switch (ev.value) {
case PRESS:
key_press(ev.code);
break;
case RELEASE:
key_release(ev.code);
break;
case REPEAT:
key_repeat(ev.code);
break;
}
}
}