input: inject keys from gamepad to HPS.

This commit is contained in:
sorgelig
2019-05-28 00:57:35 +08:00
parent 92a76cf7b8
commit 15f8a5c7fa
3 changed files with 145 additions and 24 deletions

View File

@@ -633,6 +633,7 @@ void app_restart(const char *path)
fpga_core_reset(1);
input_switch(0);
input_uinp_destroy();
char *appname = getappname();
printf("restarting the %s\n", appname);

167
input.cpp
View File

@@ -9,6 +9,12 @@
#include <sys/sysinfo.h>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <sys/time.h>
#include <sys/types.h>
#include "input.h"
#include "user_io.h"
@@ -21,6 +27,7 @@
#define NUMDEV 30
#define NUMPLAYERS 6
#define UINPUT_NAME "MiSTer virtual input"
static int ev2amiga[] =
{
@@ -1369,6 +1376,69 @@ static uint32_t mouse_timer = 0;
#define BTN_TGL 100
#define BTN_OSD 101
static int uinp_fd = -1;
static int input_uinp_setup()
{
if (uinp_fd <= 0)
{
struct uinput_user_dev uinp;
if (!(uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY)))
{
printf("Unable to open /dev/uinput\n");
uinp_fd = -1;
return 0;
}
memset(&uinp, 0, sizeof(uinp));
strncpy(uinp.name, UINPUT_NAME, UINPUT_MAX_NAME_SIZE);
uinp.id.version = 4;
uinp.id.bustype = BUS_USB;
ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
for (int i = 0; i < 256; i++) ioctl(uinp_fd, UI_SET_KEYBIT, i);
write(uinp_fd, &uinp, sizeof(uinp));
if (ioctl(uinp_fd, UI_DEV_CREATE))
{
printf("Unable to create UINPUT device.");
close(uinp_fd);
uinp_fd = -1;
return 0;
}
}
return 1;
}
void input_uinp_destroy()
{
if (uinp_fd > 0)
{
ioctl(uinp_fd, UI_DEV_DESTROY);
close(uinp_fd);
uinp_fd = -1;
}
}
static void uinp_send_key(uint16_t key, int press)
{
if (uinp_fd > 0)
{
static struct input_event event;
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = key;
event.value = press ? 1 : 0;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
}
}
static void mouse_cb(unsigned char b, int16_t x = 0, int16_t y = 0, int16_t w = 0)
{
if (grabbed) user_io_mouse(b, x, y, w);
@@ -1533,6 +1603,43 @@ static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int
input_cb(&ev, 0, 0);
}
else if (video_fb_state())
{
switch (mask)
{
case JOY_RIGHT:
uinp_send_key(KEY_RIGHT, press);
break;
case JOY_LEFT:
uinp_send_key(KEY_LEFT, press);
break;
case JOY_UP:
uinp_send_key(KEY_UP, press);
break;
case JOY_DOWN:
uinp_send_key(KEY_DOWN, press);
break;
case JOY_BTN1:
uinp_send_key(KEY_ENTER, press);
break;
case JOY_BTN2:
uinp_send_key(KEY_ESC, press);
break;
case JOY_BTN3:
uinp_send_key(KEY_SPACE, press);
break;
case JOY_BTN4:
uinp_send_key(KEY_TAB, press);
break;
}
}
else if(jnum)
{
if (press) joy[num] |= mask;
@@ -2247,6 +2354,7 @@ int input_test(int getchar)
if (state == 0)
{
input_uinp_setup();
memset(pool, -1, sizeof(pool));
signal(SIGINT, INThandler);
@@ -2297,6 +2405,14 @@ int input_test(int getchar)
input[n].led = has_led(pool[n].fd);
}
//skip our virtual device
if (!strcmp(input[n].name, UINPUT_NAME))
{
close(pool[n].fd);
pool[n].fd = -1;
continue;
}
input[n].bind = -1;
// enable scroll wheel reading
@@ -2882,36 +2998,39 @@ int input_poll(int getchar)
if (!mouse_emu_x && !mouse_emu_y) mouse_timer = 0;
for (int i = 0; i < NUMPLAYERS; i++)
if (grabbed)
{
if (!af_delay[i]) af_delay[i] = 50;
if (!time[i]) time[i] = GetTimer(af_delay[i]);
int send = 0;
int newdir = ((joy[i] & 0xF) != (joy_prev[i] & 0xF));
if (joy[i] != joy_prev[i])
for (int i = 0; i < NUMPLAYERS; i++)
{
if ((joy[i] ^ joy_prev[i]) & autofire[i])
if (!af_delay[i]) af_delay[i] = 50;
if (!time[i]) time[i] = GetTimer(af_delay[i]);
int send = 0;
int newdir = ((joy[i] & 0xF) != (joy_prev[i] & 0xF));
if (joy[i] != joy_prev[i])
{
time[i] = GetTimer(af_delay[i]);
af[i] = 0;
if ((joy[i] ^ joy_prev[i]) & autofire[i])
{
time[i] = GetTimer(af_delay[i]);
af[i] = 0;
}
send = 1;
joy_prev[i] = joy[i];
}
send = 1;
joy_prev[i] = joy[i];
}
if (CheckTimer(time[i]))
{
time[i] = GetTimer(af_delay[i]);
af[i] = !af[i];
if (joy[i] & autofire[i]) send = 1;
}
if (CheckTimer(time[i]))
{
time[i] = GetTimer(af_delay[i]);
af[i] = !af[i];
if (joy[i] & autofire[i]) send = 1;
}
if (grabbed && send)
{
user_io_digital_joystick(i, af[i] ? joy[i] & ~autofire[i] : joy[i], newdir);
if (send)
{
user_io_digital_joystick(i, af[i] ? joy[i] & ~autofire[i] : joy[i], newdir);
}
}
}

View File

@@ -57,5 +57,6 @@ void input_lightgun_cal(uint16_t *cal);
void input_switch(int grab);
int input_state();
void input_uinp_destroy();
#endif