From 41011d365cc126998579069cd0408655d5673f69 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Mon, 18 Mar 2019 02:10:43 +0800 Subject: [PATCH] Input: Analog mapping, remove axes customization, support up to 32 gamepad buttons. --- input.cpp | 418 +++++++++++++++++++++++++--------------------------- menu.cpp | 49 ++++-- menu.h | 2 +- osd.h | 1 - user_io.cpp | 11 +- user_io.h | 2 +- 6 files changed, 241 insertions(+), 242 deletions(-) diff --git a/input.cpp b/input.cpp index b819021..83806e4 100644 --- a/input.cpp +++ b/input.cpp @@ -972,7 +972,7 @@ typedef struct { uint16_t vid, pid; uint8_t led; - uint8_t last_x, last_y; // last x & y axis bitmasks for each alternative directional control scheme (DPAD, Analog pad etc.) + uint8_t axis_state[256]; uint8_t num; uint8_t has_map; @@ -990,6 +990,8 @@ typedef struct static devInput input[NUMDEV] = {}; +#define BTN_NUM (sizeof(devInput::map) / sizeof(devInput::map[0])) + int mfd = -1; int mwd = -1; @@ -1003,8 +1005,7 @@ static int set_watch() return -1; } - mwd = inotify_add_watch(mfd, "/dev/input", - IN_MODIFY | IN_CREATE | IN_DELETE); + mwd = inotify_add_watch(mfd, "/dev/input", IN_MODIFY | IN_CREATE | IN_DELETE); if (mwd < 0) { @@ -1141,6 +1142,8 @@ static int mapping_type; static int mapping_count; static uint8_t mapping_key; +static uint32_t tmp_axis[4]; + void start_map_setting(int cnt) { mapping_button = 0; @@ -1148,6 +1151,9 @@ void start_map_setting(int cnt) mapping_dev = -1; mapping_type = (cnt<0) ? 3 : cnt ? 1 : 2; mapping_count = cnt; + + if (mapping_type <= 1 && is_menu_core()) mapping_button = -4; + memset(tmp_axis, 0, sizeof(tmp_axis)); } int get_map_button() @@ -1192,6 +1198,10 @@ void finish_map_setting(int dismiss) else { for (int i = 0; i < NUMDEV; i++) input[i].has_map = 0; + + if (mapping_button < 0) mapping_button = 0; + if (!is_menu_core()) for (uint i = mapping_button; i < BTN_NUM; i++) input[mapping_dev].map[i] = 0; + if (!dismiss) FileSaveConfig(get_map_name(mapping_dev, 0), &input[mapping_dev].map, sizeof(input[mapping_dev].map)); if (is_menu_core()) input[mapping_dev].has_mmap = 0; } @@ -1269,22 +1279,23 @@ static int keyrah_trans(int key, int press) return key; } -#define KEY_EMU_LEFT (KEY_MAX+1) -#define KEY_EMU_RIGHT (KEY_MAX+2) -#define KEY_EMU_UP (KEY_MAX+3) -#define KEY_EMU_DOWN (KEY_MAX+4) - -#define KEY_EMU_LT (KEY_EMU_LEFT+16) -#define KEY_EMU_RT (KEY_EMU_LEFT+17) -#define KEY_EMU_PS (KEY_EMU_LEFT+18) +#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; -static uint16_t joy[NUMPLAYERS] = {}, joy_prev[NUMPLAYERS] = {}; -static uint16_t autofire[NUMPLAYERS] = {}; -static uint16_t autofirecodes[NUMPLAYERS][16] = {}; +static uint32_t joy[NUMPLAYERS] = {}, joy_prev[NUMPLAYERS] = {}; +static uint32_t autofire[NUMPLAYERS] = {}; +static uint32_t autofirecodes[NUMPLAYERS][BTN_NUM] = {}; static int af_delay[NUMPLAYERS] = {}; static unsigned char mouse_btn = 0; @@ -1296,17 +1307,20 @@ static int mouse_emu_y = 0; static uint32_t mouse_timer = 0; -static void joy_digital(int jnum, uint16_t mask, uint16_t code, char press, int bnum) +#define BTN_TGL 100 +#define BTN_OSD 101 + +static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int bnum) { static char str[128]; - static uint16_t lastcode[NUMPLAYERS], lastmask[NUMPLAYERS]; + static uint32_t lastcode[NUMPLAYERS], lastmask[NUMPLAYERS]; int num = jnum - 1; if (num < NUMPLAYERS) { if (jnum) { - if (bnum != 17 && bnum != 16) + if (bnum != BTN_OSD && bnum != BTN_TGL) { if (!(mask & 0xF)) { @@ -1330,7 +1344,7 @@ static void joy_digital(int jnum, uint16_t mask, uint16_t code, char press, int { int found = 0; int zero = -1; - for (int i = 0; i < 16; i++) + for (uint i = 0; i < BTN_NUM; i++) { if (!autofirecodes[num][i]) zero = i; if (autofirecodes[num][i] == lastcode[num]) @@ -1388,13 +1402,13 @@ static void joy_digital(int jnum, uint16_t mask, uint16_t code, char press, int } } - if (bnum == 16) + if (bnum == BTN_TGL) { if(press) kbd_toggle = !kbd_toggle; return; } - if (!user_io_osd_is_visible() && (bnum == 17) && (mouse_emu & 1)) + if (!user_io_osd_is_visible() && (bnum == BTN_OSD) && (mouse_emu & 1)) { if (press) { @@ -1413,7 +1427,7 @@ static void joy_digital(int jnum, uint16_t mask, uint16_t code, char press, int return; } - if (user_io_osd_is_visible() || (bnum == 17)) + if (user_io_osd_is_visible() || (bnum == BTN_OSD)) { memset(joy, 0, sizeof(joy)); struct input_event ev; @@ -1450,7 +1464,7 @@ static void joy_digital(int jnum, uint16_t mask, uint16_t code, char press, int break; default: - ev.code = (bnum == 17) ? KEY_MENU : 0; + ev.code = (bnum == BTN_OSD) ? KEY_MENU : 0; } input_cb(&ev, 0, 0); @@ -1464,7 +1478,7 @@ static void joy_digital(int jnum, uint16_t mask, uint16_t code, char press, int if (code) { int found = 0; - for (int i = 0; i < 16; i++) if (autofirecodes[num][i] == code) found = 1; + for (uint i = 0; i < BTN_NUM; i++) if (autofirecodes[num][i] == code) found = 1; if (found) autofire[num] = press ? autofire[num] | mask : autofire[num] & ~mask; } } @@ -1489,7 +1503,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int if (ev->type == EV_KEY && mapping && mapping_type == 3 && ev->code == input[dev].mmap[17]) ev->code = KEY_ENTER; - int map_skip = (ev->type == EV_KEY && ev->code == KEY_SPACE && mapping_dev >= 0 && mapping_type==1); + 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; @@ -1547,15 +1561,8 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int memset(input[dev].map, 0, sizeof(input[dev].map)); } - //remove alt controls from default map - input[dev].map[8] = 0; - input[dev].map[9] = 0; - input[dev].map[10] = 0; - input[dev].map[11] = 0; - input[dev].map[12] = 0; - input[dev].map[13] = 0; - input[dev].map[14] = 0; - input[dev].map[15] = 0; + //remove system controls from default map + 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++; @@ -1573,7 +1580,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int //mapping if (mapping && (mapping_dev >=0 || ev->value) && !cancel && !enter) { - if (ev->type == EV_KEY) + if (ev->type == EV_KEY && mapping_button>=0) { if (mapping_type == 2) { @@ -1620,7 +1627,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int mapping_type = (ev->code >= 256) ? 1 : 0; } - if (mapping_dev == dev && mapping_button < mapping_count) + if (mapping_dev == dev && mapping_button < (is_menu_core() ? 17 : mapping_count)) { if (ev->value == 1) { @@ -1631,13 +1638,13 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int if (!found) { - input[dev].map[(mapping_button == (mapping_count - 1) && is_menu_core()) ? 16 + mapping_type : mapping_button] = ev->code; - key_mapped = 1; + input[dev].map[(mapping_button == 16 && is_menu_core()) ? 16 + mapping_type : mapping_button] = ev->code; + key_mapped = ev->code; } } - else if(ev->value == 0) + else if(ev->value == 0 && key_mapped == ev->code) { - if (key_mapped) mapping_button++; + mapping_button++; key_mapped = 0; } } @@ -1646,10 +1653,75 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int } } + int idx = 0; + if (is_menu_core()) + { + 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; + } + + if (mapping_dev == dev || (mapping_dev <0 && mapping_button<0)) + { + if (ev->type == EV_ABS && idx) + { + if (mapping_dev < 0) mapping_dev = dev; + + int threshold = (absinfo->maximum - absinfo->minimum) / 10; + int max = ev->value > (absinfo->maximum - threshold); + //int min = ev->value < (absinfo->minimum + threshold); + + if (idx && max) //(min || max)) + { + if (mapping_button < 0) + { + int found = 0; + for (int i = 0; i < idx-AXIS1_X; i++) if (ev->code == (tmp_axis[i]&0xFFFF)) found = 1; + if (!found) + { + tmp_axis[idx - AXIS1_X] = ev->code | 0x20000; + //if (min) tmp_axis[idx - AXIS1_X] |= 0x10000; + mapping_button++; + } + } + else + { + if (idx == AXIS_X || ev->code != (input[dev].map[idx - 1] & 0xFFFF)) + { + input[dev].map[idx] = ev->code | 0x20000; + //if (min) input[dev].map[idx] |= 0x10000; + mapping_button++; + } + } + } + } + } + } + if (mapping_type <= 1 && map_skip && mapping_button < mapping_count) { - if (ev->value == 1) mapping_button++; - return; + if (ev->value == 1) + { + if (idx) + { + if (mapping_button < 0) tmp_axis[idx - AXIS1_X] = 0; + else if (mapping_dev >= 0) input[mapping_dev].map[idx] = 0; + } + mapping_button++; + } + } + + 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)); } } else @@ -1682,6 +1754,12 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int } } + if (ev->code == input[dev].mmap[17]) + { + if (ev->value <= 1) joy_digital(input[dev].num, 0, 0, ev->value, BTN_OSD); + return; + } + if (user_io_osd_is_visible()) { if (ev->value <= 1) @@ -1699,7 +1777,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int if (ev->code == input[dev].mmap[17]) { - joy_digital(0, 0, 0, ev->value, 17); + joy_digital(0, 0, 0, ev->value, BTN_OSD); return; } } @@ -1708,7 +1786,9 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int { if (mouse_emu) { - for (int i = 8; i <= 14; i++) + int use_analog = (input[dev].mmap[AXIS_MX] || input[dev].mmap[AXIS_MY]); + + for (int i = (use_analog ? 12 : 8); i <= 14; i++) { if (ev->code == input[dev].mmap[i]) { @@ -1736,7 +1816,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int } } - for (int i = 0; i <= 15; i++) + for (uint i = 0; i < BTN_NUM; i++) { if (ev->code == input[dev].map[i]) { @@ -1747,12 +1827,12 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int } else if (input[dev].has_map == 2) { - if (ev->value == 1) joy_digital(0, 0, 0, 3, 17); + if (ev->value == 1) joy_digital(0, 0, 0, 3, BTN_OSD); return; } else { - for (int i = 0; i <= 15; i++) + for (uint i = 0; i < BTN_NUM; i++) { if (ev->code == input[dev].map[i]) { @@ -1773,12 +1853,6 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int } } - if (ev->code == input[dev].mmap[17]) - { - if (ev->value <= 1) joy_digital(input[dev].num, 0, 0, ev->value, 17); - return; - } - if (ev->code == input[dev].mmap[15] && (ev->value <= 1) && ((!(mouse_emu & 1)) ^ (!ev->value))) { mouse_emu = ev->value ? mouse_emu | 1 : mouse_emu & ~1; @@ -1834,7 +1908,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int { if (!kbd_toggle) { - for (int i = 0; i <= 15; i++) + for (uint i = 0; i < BTN_NUM; i++) { if (ev->code == input[dev].map[i]) { @@ -1847,7 +1921,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int if (ev->code == input[dev].mmap[16]) { - if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 1 : 2, 0, 0, ev->value, 16); + if (ev->value <= 1) joy_digital((user_io_get_kbdemu() == EMU_JOY0) ? 1 : 2, 0, 0, ev->value, BTN_TGL); return; } } @@ -1895,7 +1969,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int } } - if (ev->code == input[dev].map[16]) + if (ev->code == input[dev].mmap[16]) { if (ev->value == 1) { @@ -1921,59 +1995,49 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int case EV_ABS: if (!user_io_osd_is_visible()) { - if (ev->code <= 1) + // TODO: implement inversion + + //convert to 0..255 range + int value = ((ev->value - absinfo->minimum) * 256) / (absinfo->maximum - absinfo->minimum + 1); + value = (value < 127 || value>129) ? value - 128 : 0; + if (value < -127) value = -127; + //printf("ABS: axis %d = %d -> %d\n", ev->code, ev->value, value); + + else if (ev->code == (input[dev].mmap[AXIS_MX] & 0xFFFF) && mouse_emu) { - //convert to 0..255 range - int value = ((ev->value - absinfo->minimum) * 256) / (absinfo->maximum - absinfo->minimum + 1); - value = (value < 127 || value>129) ? value - 128 : 0; - if (value < -127) value = -127; - //printf("ABS: axis %d = %d -> %d\n", ev->code, ev->value, value); + 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) + { + 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)) + { + // skip if first joystick is not defined. + if (!input[dev].num) break; - if (mouse_emu) - { - if (ev->code == 0) // x - { - mouse_emu_x = 0; - if (value < -1 || value>1) mouse_emu_x = value; - mouse_emu_x /= 12; - return; - } + int offset = 0; + if (value < -1 || value>1) offset = value; + //printf("analog_x = %d\n", offset); + joy_analog(input[dev].num, 0, offset); + return; + } + else if (ev->code == (input[dev].mmap[AXIS_Y] & 0xFFFF)) + { + // skip if first joystick is not defined. + if (!input[dev].num) break; - if (ev->code == 1) // y - { - mouse_emu_y = 0; - if (value < -1 || value>1) mouse_emu_y = value; - mouse_emu_y /= 12; - return; - } - } - else - { - // skip if first joystick is not defined. - if (!input[dev].num) break; - - // TODO: - // 1) add analog axis mapping - // 2) enable invertion - - if (ev->code == 0) // x - { - int offset = 0; - if (value < -1 || value>1) offset = value; - //printf("analog_x = %d\n", offset); - joy_analog(input[dev].num, 0, offset); - return; - } - - if (ev->code == 1) // y - { - int offset = 0; - if (value < -1 || value>1) offset = value; - //printf("analog_y = %d\n", offset); - joy_analog(input[dev].num, 1, offset); - return; - } - } + int offset = 0; + if (value < -1 || value>1) offset = value; + //printf("analog_y = %d\n", offset); + joy_analog(input[dev].num, 1, offset); + return; } } break; @@ -2009,42 +2073,6 @@ static void getVidPid(int num, uint16_t* vid, uint16_t* pid) static struct pollfd pool[NUMDEV + 1]; -// Translate axis values to key events of specific codes. -// Only binary key press /release logic is supported, any value not 0 is considered -// a key press, value 0 is key release. -static void send_axis_key_event(int dev, int code1, int code2, int value1, int value2, int last1, int last2) { - struct input_event ev; - //note: key events do not require input_absinfo values - - ev.type = EV_KEY; - //send key releases first - // value1 unset but previously set - if (!value1 && last1) { - ev.code = code1; - ev.value = 0; - input_cb(&ev, 0, dev); - } - // value2 unset but previously set - if (!value2 && last2) { - ev.code = code2; - ev.value = 0; - input_cb(&ev, 0, dev); - } - //send key presses afterwards, but only if previously not set - if (value1 && !last1) - { - ev.code = code1; - ev.value = 1; - input_cb(&ev, 0, dev); - } else //either one or another, not both directions at the same time - if (value2 && !last2) - { - ev.code = code2; - ev.value = 1; - input_cb(&ev, 0, dev); - } -} - int input_test(int getchar) { static char cur_leds = 0; @@ -2180,98 +2208,46 @@ int input_test(int getchar) input_cb(&ev, &absinfo, i); //sumulate digital directions from analog - if (ev.type == EV_ABS && !(ev.code<=1 && mouse_emu && !user_io_osd_is_visible())) + if (ev.type == EV_ABS) { - // some pads use axis 16 for L/R PAD, axis 17 for U/D PAD - // emulate PAD on axis 0/1 - - // axis ranges vary per USB controller: some have 0-255, others -32768..+32767 etc. - int range = absinfo.maximum - absinfo.minimum + 1; - int center = absinfo.minimum + (range/2); - int treshold = range/4; - - char l, r, u, d; - l = r = u = d = 0; - uint16_t offset = 0; - char offset_mask1, offset_mask2; - - if (ev.code < 16) offset += 4; - if (ev.code < 2) offset += 4; - offset_mask1 = (1 << (offset >> 1)); // 01XX - offset_mask2 = (2 << (offset >> 1)); // 10XX - - uint16_t base_axis = !user_io_get_joy_transl() ? 0 : ~ev.code; - uint16_t extra_axis = 2; - if (input[i].vid == 0x045e && input[i].pid == 0x028e) extra_axis = 3; // 8BitDo Retro Receiver - if (input[i].vid == 0x046d && input[i].pid == 0xc21f) extra_axis = 3; // Logitech F710 - if (input[i].vid == 0x0079 && input[i].pid == 0x0006) extra_axis = 0; // AliExpress USB encoder PCB floods axis 2 - - if(ev.code == base_axis || ev.code == extra_axis || ev.code == 16) // x + uint8_t axis_state = 0; + if (absinfo.maximum == 1 && absinfo.minimum == -1) { - if ((ev.code < 16) ? ev.value < center - treshold : ev.value == -1) l = 1; - if ((ev.code < 16) ? ev.value > center + treshold : ev.value == 1) r = 1; + if (ev.value == -1) axis_state = 1; + if (ev.value == 1) axis_state = 2; + } + else + { + int range = absinfo.maximum - absinfo.minimum + 1; + int center = absinfo.minimum + (range / 2); + int treshold = range / 4; - // left or right pressed or now released but previously pressed (for specific controller offset) - if (l || r || (input[i].last_x & (offset_mask1 | offset_mask2))) { - send_axis_key_event(i, KEY_EMU_LEFT + offset, KEY_EMU_RIGHT + offset, l, r, input[i].last_x & offset_mask1, input[i].last_x & offset_mask2); - if (l) input[i].last_x |= offset_mask1; - else input[i].last_x &= ~offset_mask1; - if (r) input[i].last_x |= offset_mask2; - else input[i].last_x &= ~offset_mask2; - } + int only_max = 1; + for (int n = 0; n < 4; n++) if (input[i].mmap[AXIS1_X + n] && ((input[i].mmap[AXIS1_X + n] & 0xFFFF) == ev.code)) only_max = 0; + + if (ev.value < center - treshold && !only_max) axis_state = 1; + if (ev.value > center + treshold) axis_state = 2; } - base_axis = !user_io_get_joy_transl() ? 1 : ~ev.code; + uint8_t last_state = input[i].axis_state[ev.code & 255]; + input[i].axis_state[ev.code & 255] = axis_state; - extra_axis = 5; - if (input[i].vid == 0x045e && input[i].pid == 0x028e) extra_axis = 4; // 8BitDo Retro Receiver - if (input[i].vid == 0x046d && input[i].pid == 0xc21f) extra_axis = 4; // Logitech F710 - if (input[i].vid == 0x0079 && input[i].pid == 0x0006) extra_axis = 3; // AliExpress USB encoder PCB - - if (ev.code == base_axis || ev.code == extra_axis || ev.code == 17) // y - { - // override specific to x axis. Negative value as a center?? - if (input[i].vid == 0x046d && input[i].pid == 0xc21f) center = -129; // Logitech F710 - - if ((ev.code < 16) ? ev.value < center - treshold : ev.value == -1) u = 1; - if ((ev.code < 16) ? ev.value > center + treshold : ev.value == 1) d = 1; - - // up or down pressed or now released but previously pressed (for specific controller offset) - if (u || d || (input[i].last_y & (offset_mask1 | offset_mask2))) { - send_axis_key_event(i, KEY_EMU_UP + offset, KEY_EMU_DOWN + offset, u, d, input[i].last_y & offset_mask1, input[i].last_y & offset_mask2); - if (u) input[i].last_y |= offset_mask1; - else input[i].last_y &= ~offset_mask1; - if (d) input[i].last_y |= offset_mask2; - else input[i].last_y &= ~offset_mask2; - } - } - - if ((input[i].vid == 0x045e && input[i].pid == 0x028e) || // 8BitDo Retro Receiver - (input[i].vid == 0x046d && input[i].pid == 0xc21f)) // Logitech F710 + //printf("last_state=%d, axis_state=%d\n", last_state, axis_state); + if (last_state != axis_state) { ev.type = EV_KEY; - if (ev.code == 2) + if (last_state) { - ev.code = KEY_EMU_LT; - ev.value = (ev.value == 255) ? 1 : 0; - input_cb(&ev, &absinfo, i); + ev.value = 0; + ev.code = KEY_EMU + (ev.code * 2) + last_state - 1; + input_cb(&ev, 0, i); } - if (ev.code == 5) + if (axis_state) { - ev.code = KEY_EMU_RT; - ev.value = (ev.value == 255) ? 1 : 0; - input_cb(&ev, &absinfo, i); - } - } - - if (input[i].vid == 0x2dc8 && input[i].pid == 0x3100) // 8BitDo Retro Receiver (Select+Left) - { - ev.type = EV_KEY; - if (ev.code == 9) - { - ev.code = KEY_EMU_PS; - input_cb(&ev, &absinfo, i); + ev.value = 1; + ev.code = KEY_EMU + (ev.code * 2) + axis_state - 1; + input_cb(&ev, 0, i); } } } diff --git a/menu.cpp b/menu.cpp index 2dc6965..ccaedf5 100644 --- a/menu.cpp +++ b/menu.cpp @@ -168,12 +168,13 @@ const char *config_autofire_msg[] = { " AUTOFIRE OFF", " AUTOFIRE const char *config_cd32pad_msg[] = { "OFF", "ON" }; const char *config_button_turbo_msg[] = { "OFF", "FAST", "MEDIUM", "SLOW" }; const char *config_button_turbo_choice_msg[] = { "A only", "B only", "A & B" }; -const char *joy_button_map[] = { "RIGHT", "LEFT", "DOWN", "UP", "BUTTON 1", "BUTTON 2", "BUTTON 3", "BUTTON 4", "KBD TOGGLE", "BUTTON OSD" }; +const char *joy_button_map[] = { "RIGHT", "LEFT", "DOWN", "UP", "BUTTON 1", "BUTTON 2", "BUTTON 3", "BUTTON 4", "KBD TOGGLE", "BUTTON OSD", " Stick X: Tilt RIGHT", " Stick Y: Tilt DOWN", " Mouse emu X: Tilt RIGHT", " Mouse emu Y: Tilt DOWN" }; +const char *joy_ana_map[] = { " Stick 1: Tilt RIGHT", " Stick 1: Tilt DOWN", " Stick 2: Tilt RIGHT", " Stick 2: Tilt DOWN" }; const char *config_stereo_msg[] = { "0%", "25%", "50%", "100%" }; const char *config_uart_msg[] = { " None", " PPP", " Console", " MIDI" }; const char *config_scaler_msg[] = { "Internal","Custom" }; -char joy_bnames[12][32]; +char joy_bnames[32][32]; int joy_bcount = 0; #define script_line_length 1024 @@ -1134,7 +1135,7 @@ void HandleUI(void) if (p && (p[0] == 'J')) { // joystick button names. - for (int n = 0; n < 12; n++) + for (int n = 0; n < 28; n++) { substrcpy(joy_bnames[n], p, n + 1); //printf("joy_bname = %s\n", joy_bnames[n]); @@ -1724,31 +1725,51 @@ void HandleUI(void) case MENU_JOYDIGMAP1: { const char* p = 0; - if (get_map_button() < 4) + if (get_map_button() < 0) + { + strcpy(s, joy_ana_map[get_map_button() + 4]); + } + else if (get_map_button() < 4) { p = joy_button_map[get_map_button()]; } else if (joy_bcount) { - p = (is_menu_core() && get_map_button() == joy_bcount + 3) ? joy_button_map[8 + get_map_type()] : joy_bnames[get_map_button() - 4]; + p = joy_bnames[get_map_button() - 4]; + if (is_menu_core()) + { + if (get_map_type()) joy_bcount = 17; + if (get_map_button() == 16) p = joy_button_map[8 + get_map_type()]; + } } else { p = (get_map_button() < 8) ? joy_button_map[get_map_button()] : joy_button_map[8 + get_map_type()]; } - s[0] = 0; - int len = (30 - (strlen(p) + 7)) / 2; - while (len > 0) + if (get_map_button() >= 0) { - strcat(s, " "); - len--; + if (is_menu_core() && get_map_button() > 16) + { + strcpy(s, joy_button_map[10 + get_map_button() - 17]); + } + else + { + s[0] = 0; + int len = (30 - (strlen(p) + 7)) / 2; + while (len > 0) + { + strcat(s, " "); + len--; + } + + strcat(s, "Press: "); + strcat(s, p); + } } - strcat(s, "Press: "); - strcat(s, p); OsdWrite(3, s, 0, 0); - if (get_map_button()) + if (get_map_vid() || get_map_pid()) { if (get_map_type()) OsdWrite(OsdGetSize() - 1, " Enter \x16 Finish, Space \x16 Skip", menusub == 0, 0); else OsdWrite(OsdGetSize() - 1, "", 0, 0); @@ -3409,7 +3430,7 @@ void HandleUI(void) strcpy(joy_bnames[9], "Mouse Right Btn"); strcpy(joy_bnames[10], "Mouse Middle Btn"); strcpy(joy_bnames[11], "Mouse Emu/Sniper"); - start_map_setting(17); + start_map_setting(21); menustate = MENU_JOYDIGMAP; menusub = 0; break; diff --git a/menu.h b/menu.h index d625b83..fb7f0bc 100644 --- a/menu.h +++ b/menu.h @@ -24,7 +24,7 @@ void Info(const char *message, int timeout = 2000, int width = 0, int height = 0 uint32_t getStatus(char *opt, uint32_t status); void substrcpy(char *d, char *s, char idx); -extern char joy_bnames[12][32]; +extern char joy_bnames[32][32]; extern int joy_bcount; void open_joystick_setup(); diff --git a/osd.h b/osd.h index ef61620..d647a1e 100644 --- a/osd.h +++ b/osd.h @@ -74,7 +74,6 @@ void OsdClear(void); void OsdEnable(unsigned char mode); void InfoEnable(int x, int y, int width, int height); void OsdDisable(void); -void ConfigFilter(unsigned char lores, unsigned char hires); void ConfigVideo(unsigned char hires, unsigned char lores, unsigned char scanlines); void ConfigAudio(unsigned char audio); void ConfigMemory(unsigned char memory); diff --git a/user_io.cpp b/user_io.cpp index 2683b4a..5865cf6 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -311,7 +311,7 @@ static void parse_config() } joy_bcount = 0; - for (int n = 0; n < 12; n++) + for (int n = 0; n < 28; n++) { substrcpy(joy_bnames[n], p, n + 1); if (!joy_bnames[n][0]) break; @@ -340,7 +340,7 @@ static void parse_config() if (p[0] == 'V') { // get version string - char s[40]; + char s[128]; strcpy(s, OsdCoreName()); strcat(s, " "); substrcpy(s + strlen(s), p, 1); @@ -681,7 +681,7 @@ void user_io_analog_joystick(unsigned char joystick, char valueX, char valueY) } } -void user_io_digital_joystick(unsigned char joystick, uint16_t map, int newdir) +void user_io_digital_joystick(unsigned char joystick, uint32_t map, int newdir) { uint8_t joy = (joystick>1 || !joyswap) ? joystick : joystick ^ 1; @@ -693,7 +693,10 @@ void user_io_digital_joystick(unsigned char joystick, uint16_t map, int newdir) return; } - spi_uio_cmd16((joy < 2) ? (UIO_JOYSTICK0 + joy) : (UIO_JOYSTICK2 + joy - 2), map); + spi_uio_cmd_cont((joy < 2) ? (UIO_JOYSTICK0 + joy) : (UIO_JOYSTICK2 + joy - 2)); + spi_w(map); + if(joy_bcount>12) spi_w(map>>16); + DisableIO(); if (!is_minimig() && joy_transl == 1 && newdir) { diff --git a/user_io.h b/user_io.h index 1caa51c..b6b8505 100644 --- a/user_io.h +++ b/user_io.h @@ -213,7 +213,7 @@ void user_io_mouse(unsigned char b, int16_t x, int16_t y); void user_io_kbd(uint16_t key, int press); char* user_io_create_config_name(); int user_io_get_joy_transl(); -void user_io_digital_joystick(unsigned char, uint16_t, int); +void user_io_digital_joystick(unsigned char, uint32_t, int); void user_io_analog_joystick(unsigned char, char, char); void user_io_set_joyswap(int swap); int user_io_get_joyswap();