input: inject keys from gamepad to HPS.
This commit is contained in:
@@ -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
167
input.cpp
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user