Files
asteroids/input.c
2025-10-18 17:43:22 +01:00

136 lines
1.9 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 restart;
static input_callback_t quit;
static input_callback_t shoot;
static input_callback_t pause_;
static void key_press(int key)
{
switch (key) {
case KEY_UP:
++input.thrust;
break;
case KEY_LEFT:
++input.spin;
break;
case KEY_RIGHT:
--input.spin;
break;
case KEY_Q:
if (quit != nullptr)
quit();
break;
case KEY_R:
if (restart != nullptr)
restart();
break;
case KEY_SPACE:
if (shoot != nullptr)
shoot();
break;
case KEY_P:
if (pause_ != nullptr)
pause_();
}
}
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 = restart = quit = pause_ = 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_on_restart(input_callback_t cb)
{
restart = cb;
}
void input_on_quit(input_callback_t cb)
{
quit = cb;
}
void input_on_pause(input_callback_t cb)
{
pause_ = 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;
}
}
}