input: fixes and refactor.

This commit is contained in:
sorgelig
2019-10-22 08:39:53 +08:00
parent 22adac00dd
commit 6fee050765
8 changed files with 420 additions and 339 deletions

231
input.cpp
View File

@@ -26,9 +26,13 @@
#include "video.h"
#include "joymapping.h"
#define NUMDEV 30
#define NUMPLAYERS 6
#define UINPUT_NAME "MiSTer virtual input"
char joy_bnames[NUMBUTTONS][32] = {};
int joy_bcount = 0;
static int ev2amiga[] =
{
NONE, //0 KEY_RESERVED
@@ -988,6 +992,41 @@ enum QUIRK
QUIRK_DS4TOUCH,
};
typedef struct
{
uint16_t vid, pid;
uint8_t led;
uint8_t mouse;
uint8_t axis_edge[256];
int8_t axis_pos[256];
uint8_t num;
uint8_t has_map;
uint32_t map[NUMBUTTONS];
uint8_t osd_combo;
uint8_t has_mmap;
uint32_t mmap[NUMBUTTONS];
uint16_t jkmap[1024];
uint8_t has_kbdmap;
uint8_t kbdmap[256];
uint16_t guncal[4];
int accx, accy;
int quirk;
int lightgun_req;
int lightgun;
int bind;
char devname[32];
char uniq[32];
char name[128];
} devInput;
static devInput input[NUMDEV] = {};
#define BTN_NUM (sizeof(devInput::map) / sizeof(devInput::map[0]))
@@ -1181,8 +1220,8 @@ int get_map_clear()
static char *get_map_name(int dev, int def)
{
static char name[128];
if (def || is_menu_core()) sprintf(name, "input_%04x_%04x_v2.map", input[dev].vid, input[dev].pid);
else sprintf(name, "%s_input_%04x_%04x_v2.map", user_io_get_core_name_ex(), input[dev].vid, input[dev].pid);
if (def || is_menu_core()) sprintf(name, "input_%04x_%04x_v3.map", input[dev].vid, input[dev].pid);
else sprintf(name, "%s_input_%04x_%04x_v3.map", user_io_get_core_name_ex(), input[dev].vid, input[dev].pid);
return name;
}
@@ -1216,15 +1255,6 @@ void finish_map_setting(int dismiss)
}
}
int convert_from_menu_mapping(int dev) {
//attempts to map from Menu joystick config file
//returns: 0 if failed to map or 1 if success
if(!FileLoadConfig(get_map_name(dev, 1), &input[dev].map, sizeof(input[dev].map))) {
return 0;
}
return map_joystick (user_io_get_core_name_ex(), input, dev);
}
void input_lightgun_cal(uint16_t *cal)
{
FileSaveConfig("wiimote_cal.cfg", cal, 4 * sizeof(uint16_t));
@@ -1320,17 +1350,6 @@ static int keyrah_trans(int key, int press)
return key;
}
#define KEY_EMU (KEY_MAX+1)
#define AXIS1_X 24
#define AXIS1_Y 25
#define AXIS2_X 26
#define AXIS2_Y 27
#define AXIS_X 28
#define AXIS_Y 29
#define AXIS_MX 30
#define AXIS_MY 31
static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int dev);
static int kbd_toggle = 0;
@@ -1693,37 +1712,13 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
static int key_mapped = 0;
if (ev->type == EV_KEY && mapping && mapping_type == 3 && ev->code == input[dev].mmap[17]) ev->code = KEY_ENTER;
if (ev->type == EV_KEY && mapping && mapping_type == 3 && ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 1]) ev->code = KEY_ENTER;
int map_skip = (ev->type == EV_KEY && ev->code == KEY_SPACE && ((mapping_dev >= 0 && mapping_type==1) || mapping_button<0));
int cancel = (ev->type == EV_KEY && ev->code == KEY_ESC);
int enter = (ev->type == EV_KEY && ev->code == KEY_ENTER);
int origcode = ev->code;
if (!input[dev].has_map)
{
if (!FileLoadConfig(get_map_name(dev, 0), &input[dev].map, sizeof(input[dev].map)))
{
if(!convert_from_menu_mapping(dev)) {
if (is_menu_core() || !FileLoadConfig(get_map_name(dev, 1), &input[dev].map, sizeof(input[dev].map)))
{
// nothing found so blank out everything
memset(input[dev].map, 0, sizeof(input[dev].map));
input[dev].has_map++;
}
else
{
for (uint i = 8; i < sizeof(input[0].map) / sizeof(input[0].map[0]); i++)
{
input[dev].map[i] = 0;
}
}
}
input[dev].has_map++;
}
input[dev].has_map++;
}
if (!input[dev].has_mmap)
{
if (!FileLoadConfig(get_map_name(dev, 1), &input[dev].mmap, sizeof(input[dev].mmap)))
@@ -1732,18 +1727,40 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
input[dev].has_mmap++;
}
input[dev].has_mmap++;
if (!input[dev].mmap[18]) input[dev].mmap[18] = input[dev].mmap[17];
if (!input[dev].mmap[SYS_BTN_OSD_KTGL + 2]) input[dev].mmap[SYS_BTN_OSD_KTGL + 2] = input[dev].mmap[SYS_BTN_OSD_KTGL + 1];
}
if (!input[dev].has_map)
{
if (!FileLoadConfig(get_map_name(dev, 0), &input[dev].map, sizeof(input[dev].map)))
{
memset(input[dev].map, 0, sizeof(input[dev].map));
if (!is_menu_core())
{
if (input[dev].has_mmap == 1)
{
// not defined try to guess the mapping
map_joystick(input[dev].map, input[dev].mmap);
}
else
{
input[dev].has_map++;
}
}
input[dev].has_map++;
}
input[dev].has_map++;
}
int old_combo = input[dev].osd_combo;
if (ev->code == input[dev].mmap[18])
if (ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 2])
{
if (ev->value) input[dev].osd_combo |= 2;
else input[dev].osd_combo &= ~2;
}
if (ev->code == input[dev].mmap[17])
if (ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 1])
{
if (ev->value) input[dev].osd_combo |= 1;
else input[dev].osd_combo &= ~1;
@@ -1811,7 +1828,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
}
mapping_clear = 0;
if (mapping_dev >= 0 && (mapping_dev == dev || clear) && mapping_button < (is_menu_core() ? 17 : mapping_count))
if (mapping_dev >= 0 && (mapping_dev == dev || clear) && mapping_button < (is_menu_core() ? (SYS_BTN_OSD_KTGL+1) : mapping_count))
{
if (is_menu_core()) osd_event = 0;
if (osd_event) key_mapped = 0;
@@ -1828,22 +1845,22 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
int found = 0;
for (int i = (mapping_button >= BUTTON_DPAD_COUNT) ? BUTTON_DPAD_COUNT : 0; i < mapping_button; i++) if (input[dev].map[i] == ev->code) found = 1;
if (!found || (mapping_button == BUTTON_IDX_OSD && mapping_type))
if (!found || (mapping_button == SYS_BTN_OSD_KTGL && mapping_type))
{
input[dev].map[(mapping_button == BUTTON_IDX_OSD) ? BUTTON_IDX_OSD + mapping_type : mapping_button] = ev->code;
input[dev].map[BUTTON_IDX_OSD+2] = input[dev].map[BUTTON_IDX_OSD+1];
input[dev].map[(mapping_button == SYS_BTN_OSD_KTGL) ? SYS_BTN_OSD_KTGL + mapping_type : mapping_button] = ev->code;
input[dev].map[SYS_BTN_OSD_KTGL + 2] = input[dev].map[SYS_BTN_OSD_KTGL + 1];
key_mapped = ev->code;
//check if analog stick has been used for mouse
if (mapping_button == BUTTON_DPAD_COUNT+1 || mapping_button == BUTTON_DPAD_COUNT+3)
if (mapping_button == BUTTON_DPAD_COUNT + 1 || mapping_button == BUTTON_DPAD_COUNT + 3)
{
if (input[dev].map[mapping_button] >= KEY_EMU &&
input[dev].map[mapping_button - 1] >= KEY_EMU &&
(input[dev].map[mapping_button - 1] - input[dev].map[mapping_button] == 1) && // same axis
absinfo)
{
input[dev].map[AXIS_MX + (mapping_button - (BUTTON_DPAD_COUNT+1))/2] = ((input[dev].map[mapping_button] - KEY_EMU)/2) | 0x20000;
input[dev].map[SYS_AXIS_MX + (mapping_button - (BUTTON_DPAD_COUNT + 1)) / 2] = ((input[dev].map[mapping_button] - KEY_EMU) / 2) | 0x20000;
}
}
}
@@ -1884,10 +1901,10 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
}
}
//combo for osd button
if (ev->value == 1 && key_mapped && key_mapped != ev->code && is_menu_core() && mapping_button == BUTTON_IDX_OSD && mapping_type)
if (ev->value == 1 && key_mapped && key_mapped != ev->code && is_menu_core() && mapping_button == SYS_BTN_OSD_KTGL && mapping_type)
{
input[dev].map[BUTTON_IDX_OSD+2] = ev->code;
printf("Set combo: %x + %x\n", input[dev].map[BUTTON_IDX_OSD+1], input[dev].map[BUTTON_IDX_OSD+2]);
input[dev].map[SYS_BTN_OSD_KTGL + 2] = ev->code;
printf("Set combo: %x + %x\n", input[dev].map[SYS_BTN_OSD_KTGL + 1], input[dev].map[SYS_BTN_OSD_KTGL + 2]);
}
else if(mapping_dev == dev && ev->value == 0 && key_mapped == ev->code)
{
@@ -1910,14 +1927,14 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
{
switch (mapping_button)
{
case 17: idx = AXIS_X; break;
case 18: idx = AXIS_Y; break;
case 19: idx = AXIS_MX; break;
case 20: idx = AXIS_MY; break;
case -4: idx = AXIS1_X; break;
case -3: idx = AXIS1_Y; break;
case -2: idx = AXIS2_X; break;
case -1: idx = AXIS2_Y; break;
case 21: idx = SYS_AXIS_X; break;
case 22: idx = SYS_AXIS_Y; break;
case 23: idx = SYS_AXIS_MX; break;
case 24: idx = SYS_AXIS_MY; break;
case -4: idx = SYS_AXIS1_X; break;
case -3: idx = SYS_AXIS1_Y; break;
case -2: idx = SYS_AXIS2_X; break;
case -1: idx = SYS_AXIS2_Y; break;
}
if (mapping_dev == dev || (mapping_dev < 0 && mapping_button < 0))
@@ -2001,7 +2018,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
}
else
{
if (idx == AXIS_X || ev->code != (input[dev].map[idx - 1] & 0xFFFF))
if (idx == SYS_AXIS_X || ev->code != (input[dev].map[idx - 1] & 0xFFFF))
{
input[dev].map[idx] = ev->code | 0x20000;
//if (min) input[dev].map[idx] |= 0x10000;
@@ -2034,8 +2051,8 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (is_menu_core() && mapping_type <= 1 && mapping_dev >= 0)
{
memcpy(&input[mapping_dev].mmap[AXIS1_X], tmp_axis, sizeof(tmp_axis));
memcpy(&input[mapping_dev].map[AXIS1_X], tmp_axis, sizeof(tmp_axis));
memcpy(&input[mapping_dev].mmap[SYS_AXIS1_X], tmp_axis, sizeof(tmp_axis));
memcpy(&input[mapping_dev].map[SYS_AXIS1_X], tmp_axis, sizeof(tmp_axis));
}
}
else
@@ -2086,27 +2103,35 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
{
if (ev->value <= 1)
{
for (int i = 0; i <= 11; i++)
for (int i = 0; i <= SYS_BTN_Y; i++)
{
if (ev->code == input[dev].mmap[i])
{
int n = i;
if (n >= 8) n -= 8;
joy_digital(0, 1 << i, 0, ev->value, i);
return;
}
}
for (int i = SYS_MS_RIGHT; i <= SYS_MS_UP; i++)
{
if (ev->code == input[dev].mmap[i])
{
int n = i - SYS_MS_RIGHT;
joy_digital(0, 1 << n, 0, ev->value, n);
return;
}
}
if (input[dev].mmap[AXIS_X])
if (input[dev].mmap[SYS_AXIS_X])
{
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[AXIS_X]*2);
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[SYS_AXIS_X]*2);
if (ev->code == (key + 1)) joy_digital(0, 1 << 0, 0, ev->value, 0);
if (ev->code == key) joy_digital(0, 1 << 1, 0, ev->value, 1);
}
if (input[dev].mmap[AXIS_Y])
if (input[dev].mmap[SYS_AXIS_Y])
{
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[AXIS_Y]*2);
uint16_t key = KEY_EMU + ((uint16_t)input[dev].mmap[SYS_AXIS_Y]*2);
if (ev->code == (key + 1)) joy_digital(0, 1 << 2, 0, ev->value, 2);
if (ev->code == key) joy_digital(0, 1 << 3, 0, ev->value, 3);
}
@@ -2116,29 +2141,29 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
{
if (mouse_emu)
{
int use_analog = (input[dev].mmap[AXIS_MX] || input[dev].mmap[AXIS_MY]);
int use_analog = (input[dev].mmap[SYS_AXIS_MX] || input[dev].mmap[SYS_AXIS_MY]);
for (int i = (use_analog ? 12 : 8); i <= 14; i++)
for (int i = (use_analog ? SYS_MS_BTN_L : SYS_MS_RIGHT); i <= SYS_MS_BTN_M; i++)
{
if (ev->code == input[dev].mmap[i])
{
switch (i)
{
case 8:
case SYS_MS_RIGHT:
mouse_emu_x = ev->value ? 10 : 0;
break;
case 9:
case SYS_MS_LEFT:
mouse_emu_x = ev->value ? -10 : 0;
break;
case 10:
case SYS_MS_DOWN:
mouse_emu_y = ev->value ? 10 : 0;
break;
case 11:
case SYS_MS_UP:
mouse_emu_y = ev->value ? -10 : 0;
break;
default:
mouse_btn = ev->value ? mouse_btn | 1 << (i - 12) : mouse_btn & ~(1 << (i - 12));
mouse_btn = ev->value ? mouse_btn | 1 << (i - SYS_MS_BTN_L) : mouse_btn & ~(1 << (i - SYS_MS_BTN_L));
mouse_cb(mouse_btn | mice_btn);
break;
}
@@ -2149,7 +2174,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (input[dev].has_map >= 2)
{
Info((input[dev].has_map == 3) ? "This joystick is not defined" : "This joystick is not defined\n Using default map");
if (input[dev].has_map == 3) Info("This joystick is not defined");
input[dev].has_map = 1;
}
@@ -2158,13 +2183,13 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (ev->code == (input[dev].map[i] & 0xFFFF) || ev->code == (input[dev].map[i] >> 16))
{
if (i <= 3 && origcode == ev->code) origcode = 0; // prevent autofire for original dpad
if (ev->value <= 1) joy_digital(input[dev].num, 1 << i, origcode, ev->value, i, (ev->code == input[dev].mmap[17] || ev->code == input[dev].mmap[18]));
if (ev->value <= 1) joy_digital(input[dev].num, 1 << i, origcode, ev->value, i, (ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 1] || ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL + 2]));
// support 2 simultaneous functions for 1 button if defined in 2 sets. No return.
}
}
if (ev->code == input[dev].mmap[15] && (ev->value <= 1) && ((!(mouse_emu & 1)) ^ (!ev->value)))
if (ev->code == input[dev].mmap[SYS_MS_BTN_EMU] && (ev->value <= 1) && ((!(mouse_emu & 1)) ^ (!ev->value)))
{
mouse_emu = ev->value ? mouse_emu | 1 : mouse_emu & ~1;
if (input[sub_dev].quirk == QUIRK_DS4) ds_mouse_emu = mouse_emu & 1;
@@ -2231,7 +2256,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
}
}
if (ev->code == input[dev].mmap[16])
if (ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL])
{
if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 1 : 2, 0, 0, ev->value, BTN_TGL);
return;
@@ -2246,27 +2271,27 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
{
if (kbd_mouse_emu)
{
for (int i = 8; i <= 14; i++)
for (int i = SYS_MS_RIGHT; i <= SYS_MS_BTN_M; i++)
{
if (ev->code == input[dev].mmap[i])
{
switch (i)
{
case 8:
mouse_emu_x = ev->value ? 10 : 0;
case SYS_MS_RIGHT:
mouse_emu_x = ev->value ? 10 : 0;
break;
case 9:
case SYS_MS_LEFT:
mouse_emu_x = ev->value ? -10 : 0;
break;
case 10:
mouse_emu_y = ev->value ? 10 : 0;
case SYS_MS_DOWN:
mouse_emu_y = ev->value ? 10 : 0;
break;
case 11:
case SYS_MS_UP:
mouse_emu_y = ev->value ? -10 : 0;
break;
default:
mouse_btn = ev->value ? mouse_btn | 1 << (i - 12) : mouse_btn & ~(1 << (i - 12));
mouse_btn = ev->value ? mouse_btn | 1 << (i - SYS_MS_BTN_L) : mouse_btn & ~(1 << (i - SYS_MS_BTN_L));
mouse_cb(mouse_btn | mice_btn);
break;
}
@@ -2274,14 +2299,14 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
}
}
if (ev->code == input[dev].mmap[15])
if (ev->code == input[dev].mmap[SYS_MS_BTN_EMU])
{
if (ev->value <= 1) mouse_sniper = ev->value;
return;
}
}
if (ev->code == input[dev].mmap[16])
if (ev->code == input[dev].mmap[SYS_BTN_OSD_KTGL])
{
if (ev->value == 1)
{
@@ -2346,21 +2371,21 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (input[sub_dev].axis_pos[ev->code & 0xFF] == (int8_t)value) break;
input[sub_dev].axis_pos[ev->code & 0xFF] = (int8_t)value;
if (ev->code == (input[dev].mmap[AXIS_MX] & 0xFFFF) && mouse_emu)
if (ev->code == (input[dev].mmap[SYS_AXIS_MX] & 0xFFFF) && mouse_emu)
{
mouse_emu_x = 0;
if (value < -1 || value>1) mouse_emu_x = value;
mouse_emu_x /= 12;
return;
}
else if (ev->code == (input[dev].mmap[AXIS_MY] & 0xFFFF) && mouse_emu)
else if (ev->code == (input[dev].mmap[SYS_AXIS_MY] & 0xFFFF) && mouse_emu)
{
mouse_emu_y = 0;
if (value < -1 || value>1) mouse_emu_y = value;
mouse_emu_y /= 12;
return;
}
else if (ev->code == (input[dev].mmap[AXIS_X] & 0xFFFF) || (ev->code == 0 && input[dev].lightgun))
else if (ev->code == (input[dev].mmap[SYS_AXIS_X] & 0xFFFF) || (ev->code == 0 && input[dev].lightgun))
{
// skip if joystick is undefined.
if (!input[dev].num) break;
@@ -2371,7 +2396,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
joy_analog(input[dev].num, 0, offset);
return;
}
else if (ev->code == (input[dev].mmap[AXIS_Y] & 0xFFFF) || (ev->code == 1 && input[dev].lightgun))
else if (ev->code == (input[dev].mmap[SYS_AXIS_Y] & 0xFFFF) || (ev->code == 1 && input[dev].lightgun))
{
// skip if joystick is undefined.
if (!input[dev].num) break;
@@ -2918,7 +2943,7 @@ int input_test(int getchar)
int treshold = range / 4;
int only_max = 1;
for (int n = 0; n < 4; n++) if (input[dev].mmap[AXIS1_X + n] && ((input[dev].mmap[AXIS1_X + n] & 0xFFFF) == ev.code)) only_max = 0;
for (int n = 0; n < 4; n++) if (input[dev].mmap[SYS_AXIS1_X + n] && ((input[dev].mmap[SYS_AXIS1_X + n] & 0xFFFF) == ev.code)) only_max = 0;
if (ev.value < center - treshold && !only_max) axis_edge = 1;
if (ev.value > center + treshold) axis_edge = 2;