From 6fee050765a8573682a2e92dd0b3c09c69165935 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Tue, 22 Oct 2019 08:39:53 +0800 Subject: [PATCH] input: fixes and refactor. --- MiSTer.vcxproj | 2 + MiSTer.vcxproj.filters | 6 + input.cpp | 231 +++++++++++++++------------- input.h | 36 ++++- joymapping.cpp | 341 +++++++++++++++++++++++++---------------- joymapping.h | 77 ++-------- menu.cpp | 63 ++++---- menu.h | 3 - 8 files changed, 420 insertions(+), 339 deletions(-) diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj index ff503f1..e54964b 100644 --- a/MiSTer.vcxproj +++ b/MiSTer.vcxproj @@ -60,6 +60,7 @@ + @@ -107,6 +108,7 @@ + diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters index 26edffb..9c04bcb 100644 --- a/MiSTer.vcxproj.filters +++ b/MiSTer.vcxproj.filters @@ -145,6 +145,9 @@ Source Files + + Source Files + @@ -294,5 +297,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/input.cpp b/input.cpp index de773b4..e8c962d 100644 --- a/input.cpp +++ b/input.cpp @@ -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; diff --git a/input.h b/input.h index 126a6a7..47b71b9 100644 --- a/input.h +++ b/input.h @@ -29,9 +29,40 @@ #define UPSTROKE 0x400000 -#define BUTTON_IDX_OSD 16 +#define NUMBUTTONS 32 #define BUTTON_DPAD_COUNT 12 // dpad + 8 buttons +#define SYS_BTN_RIGHT 0 +#define SYS_BTN_LEFT 1 +#define SYS_BTN_DOWN 2 +#define SYS_BTN_UP 3 +#define SYS_BTN_A 4 +#define SYS_BTN_B 5 +#define SYS_BTN_X 6 +#define SYS_BTN_Y 7 +#define SYS_BTN_L 8 +#define SYS_BTN_R 9 +#define SYS_BTN_SELECT 10 +#define SYS_BTN_START 11 +#define SYS_MS_RIGHT 12 +#define SYS_MS_LEFT 13 +#define SYS_MS_DOWN 14 +#define SYS_MS_UP 15 +#define SYS_MS_BTN_L 16 +#define SYS_MS_BTN_R 17 +#define SYS_MS_BTN_M 18 +#define SYS_MS_BTN_EMU 19 +#define SYS_BTN_OSD_KTGL 20 // 20 for keyboard, 21+22 for gamepad +#define SYS_AXIS1_X 24 +#define SYS_AXIS1_Y 25 +#define SYS_AXIS2_X 26 +#define SYS_AXIS2_Y 27 +#define SYS_AXIS_X 28 +#define SYS_AXIS_Y 29 +#define SYS_AXIS_MX 30 +#define SYS_AXIS_MY 31 + +#define KEY_EMU (KEY_MAX+1) void set_kbdled(int mask, int state); int get_kbdled(int mask); @@ -63,4 +94,7 @@ void input_switch(int grab); int input_state(); void input_uinp_destroy(); +extern char joy_bnames[NUMBUTTONS][32]; +extern int joy_bcount; + #endif diff --git a/joymapping.cpp b/joymapping.cpp index c58b7f2..09b8671 100644 --- a/joymapping.cpp +++ b/joymapping.cpp @@ -1,134 +1,207 @@ -/* -This file contains lookup information on known controllers -*/ - -#include -#include -#include -#include -#include - -#include "joymapping.h" -#include "menu.h" -#include "input.h" -#include "user_io.h" - -#define DPAD_COUNT 4 - -/*****************************************************************************/ - -int swap_face_buttons(const char *core_name) { - //flags cores where B A should be swapped to A B and Y X to X Y (SNES vs. Genesis/NG) - return (!strcmp(core_name, "Genesis") - || !strcmp(core_name, "NEOGEO") - || !strcmp(core_name, "SMS")); -} - -int map_joystick(const char *core_name, devInput (&input)[NUMDEV], int dev) { - /* - attemps to centrally defined core joy mapping to the joystick declaredy by a core config string - we use the names declared by core with some special handling for specific edge cases - - Input button order is "virtual SNES" i.e.: - A, B, X, Y, L, R, Select, Start - */ - uint32_t new_map[NUMBUTTONS]; - // first copy directions (not really needed but helps keep things consistent) - for(int i=0; i +#include +#include +#include + +#include "joymapping.h" +#include "menu.h" +#include "input.h" +#include "user_io.h" + +#define DPAD_COUNT 4 + +/*****************************************************************************/ +static void trim(char * s) +{ + char *p = s; + int l = strlen(p); + if (!l) return; + + while (p[l - 1] == ' ') p[--l] = 0; + while (*p && (*p == ' ')) ++p, --l; + + memmove(s, p, l + 1); +} + +static void get_buttons() +{ + int i = 2; + char *p; + + memset(joy_bnames, 0, sizeof(joy_bnames)); + joy_bcount = 0; + + while(1) + { + p = user_io_8bit_get_string(i); + if (!p) break; + + if (p[0] == 'J') + { + for (int n = 0; n < 28; n++) + { + substrcpy(joy_bnames[n], p, n + 1); + if (!joy_bnames[n][0]) break; + + printf("joy_bname[%d] = %s\n", n, joy_bnames[n]); + + char *sstr = strchr(joy_bnames[n], '('); + if (sstr) *sstr = 0; + trim(joy_bnames[n]); + + if (!joy_bnames[n][0]) break; + joy_bcount++; + } + break; + } + i++; + } +} + +static int has_X_button() +{ + for (int i = 0; i < joy_bcount; i++) + { + if (!strcasecmp(joy_bnames[i], "X")) return 1; + } + return 0; +} + +static int is_fire(char* name) +{ + if (!strncasecmp(name, "fire", 4) || !strncasecmp(name, "button", 6)) + { + if (!strcasecmp(name, "fire") || strchr(name, '1')) return 1; + if (strchr(name, '2')) return 2; + if (strchr(name, '3')) return 3; + if (strchr(name, '4')) return 4; + } + + return 0; +} + +void map_joystick(uint32_t *map, uint32_t *mmap) +{ + static char mapinfo[1024]; + strcpy(mapinfo, "This joystick is not defined.\nDefault map:"); + /* + attemps to centrally defined core joy mapping to the joystick declaredy by a core config string + we use the names declared by core with some special handling for specific edge cases + + Input button order is "virtual SNES" i.e.: + A, B, X, Y, L, R, Select, Start + */ + get_buttons(); + + map[SYS_BTN_RIGHT] = mmap[SYS_BTN_RIGHT] & 0xFFFF; + map[SYS_BTN_LEFT] = mmap[SYS_BTN_LEFT] & 0xFFFF; + map[SYS_BTN_DOWN] = mmap[SYS_BTN_DOWN] & 0xFFFF; + map[SYS_BTN_UP] = mmap[SYS_BTN_UP] & 0xFFFF; + + if (mmap[SYS_AXIS_X]) + { + uint32_t key = KEY_EMU + (((uint16_t)mmap[SYS_AXIS_X]) << 1); + map[SYS_BTN_LEFT] = (key << 16) | map[SYS_BTN_LEFT]; + map[SYS_BTN_RIGHT] = ((key+1) << 16) | map[SYS_BTN_RIGHT]; + } + + if (mmap[SYS_AXIS_Y]) + { + uint32_t key = KEY_EMU + (((uint16_t)mmap[SYS_AXIS_Y]) << 1); + map[SYS_BTN_UP] = (key << 16) | map[SYS_BTN_UP]; + map[SYS_BTN_DOWN] = ((key + 1) << 16) | map[SYS_BTN_DOWN]; + } + + // loop through core requested buttons and construct result map + for (int i=0; i A"); + } + + else if(!strcasecmp(btn_name, "B") + || is_fire(btn_name) == 2 + || !strcasecmp(btn_name, "Button II")) + { + map[idx] = mmap[SYS_BTN_B]; + strcat(mapinfo, " -> B"); + } + + else if(!strcasecmp(btn_name, "X") + || (!strcasecmp(btn_name, "C") && !has_X_button()) + || is_fire(btn_name) == 3 + || !strcasecmp(btn_name, "Button III")) + { + map[idx] = mmap[SYS_BTN_X]; + strcat(mapinfo, " -> X"); + } + + else if(!strcasecmp(btn_name, "Y") + || !strcasecmp(btn_name, "D") + || is_fire(btn_name) == 4 + || !strcasecmp(btn_name, "Button IV")) + { + map[idx] = mmap[SYS_BTN_Y]; + strcat(mapinfo, " -> Y"); + } + + // Genesis C and Z and TG16 V and VI + else if(!strcasecmp(btn_name, "R") + || !strcasecmp(btn_name, "C") + || !strcasecmp(btn_name, "RT") + || !strcasecmp(btn_name, "Button V") + || !strcasecmp(btn_name, "Coin")) + { + map[idx] = mmap[SYS_BTN_R]; + strcat(mapinfo, " -> R"); + } + + else if(!strcasecmp(btn_name, "L") + || !strcasecmp(btn_name, "Z") + || !strcasecmp(btn_name, "LT") + || !strcasecmp(btn_name, "Button VI")) + { + map[idx] = mmap[SYS_BTN_L]; + strcat(mapinfo, " -> L"); + } + + else if(!strcasecmp(btn_name, "Select") + || !strcasecmp(btn_name, "Mode") + || !strcasecmp(btn_name, "Game Select") + || !strcasecmp(btn_name, "Start 2P")) + { + map[idx] = mmap[SYS_BTN_SELECT]; + strcat(mapinfo, " -> Select"); + } + + else if(!strcasecmp(btn_name, "Start") + || !strcasecmp(btn_name, "Run") + || !strcasecmp(btn_name, "Pause") + || !strcasecmp(btn_name, "Start 1P")) + { + map[idx] = mmap[SYS_BTN_START]; + strcat(mapinfo, " -> Start"); + } + else + { + strcat(mapinfo, " -> "); + } + } + + Info(mapinfo, 4000); +} diff --git a/joymapping.h b/joymapping.h index aca704f..07b9415 100644 --- a/joymapping.h +++ b/joymapping.h @@ -1,65 +1,12 @@ -/*****************************************************************************/ -// Handle mapping of various joystick controllers -/*****************************************************************************/ - -#ifndef JOYMAPPING_H -#define JOYMAPPING_H - -#include -#include - -#define NUMDEV 30 -#define NUMBUTTONS 32 - -//Defined as per main menu USB joypad mapping, see menu.cpp -#define MENU_JOY_A 4 -#define MENU_JOY_B 5 -#define MENU_JOY_X 6 -#define MENU_JOY_Y 7 -#define MENU_JOY_L 8 // menu.cpp skips 4 buttons for mouse directions -#define MENU_JOY_R 9 -#define MENU_JOY_SELECT 10 -#define MENU_JOY_START 11 - -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; - -/*****************************************************************************/ - -int map_joystick(const char *core_name, devInput (&input)[NUMDEV], int dev); - -/*****************************************************************************/ - -#endif // JOYMAPPING_H \ No newline at end of file +/*****************************************************************************/ +// Handle mapping of various joystick controllers +/*****************************************************************************/ + +#ifndef JOYMAPPING_H +#define JOYMAPPING_H + +#include + +void map_joystick(uint32_t *map, uint32_t *mmap); + +#endif // JOYMAPPING_H diff --git a/menu.cpp b/menu.cpp index 8ff0b94..a8e4bda 100644 --- a/menu.cpp +++ b/menu.cpp @@ -55,9 +55,10 @@ along with this program. If not, see . #include "bootcore.h" #include "cheats.h" #include "video.h" -#include "support.h" #include "joymapping.h" +#include "support.h" + /*menu states*/ enum MENU { @@ -201,10 +202,6 @@ const char *config_gamma_msg[] = { "Off","On" }; #define DPAD_NAMES 4 #define DPAD_BUTTON_NAMES 12 //DPAD_NAMES + 6 buttons + start/select - -char joy_bnames[32][32]; -int joy_bcount = 0; - #define script_line_length 1024 #define script_lines 50 static FILE *script_pipe; @@ -1783,12 +1780,12 @@ void HandleUI(void) if (is_minimig()) { joy_bcount = 7; - strcpy(joy_bnames[0], "Red/Fire"); - strcpy(joy_bnames[1], "Blue"); - strcpy(joy_bnames[2], "Yellow"); - strcpy(joy_bnames[3], "Green"); - strcpy(joy_bnames[4], "Right Trigger"); - strcpy(joy_bnames[5], "Left Trigger"); + strcpy(joy_bnames[0], "A(Red/Fire)"); + strcpy(joy_bnames[1], "B(Blue)"); + strcpy(joy_bnames[2], "C(Yellow)"); + strcpy(joy_bnames[3], "D(Green)"); + strcpy(joy_bnames[4], "RT"); + strcpy(joy_bnames[5], "LT"); strcpy(joy_bnames[6], "Pause"); } start_map_setting(joy_bcount ? joy_bcount+4 : 8); @@ -2163,8 +2160,8 @@ void HandleUI(void) p = joy_bnames[get_map_button() - DPAD_NAMES]; if (is_menu_core()) { - if (get_map_type()) joy_bcount = 15; - if (get_map_button() == 16) + if (get_map_type()) joy_bcount = 19; + if (get_map_button() == SYS_BTN_OSD_KTGL) { p = joy_button_map[DPAD_BUTTON_NAMES + get_map_type()]; if (get_map_type()) @@ -2182,9 +2179,9 @@ void HandleUI(void) if (get_map_button() >= 0) { - if (is_menu_core() && get_map_button() > 16) + if (is_menu_core() && get_map_button() > SYS_BTN_OSD_KTGL) { - strcpy(s, joy_button_map[14 + get_map_button() - 17]); + strcpy(s, joy_button_map[(get_map_button() - SYS_BTN_OSD_KTGL - 1) + DPAD_BUTTON_NAMES + 2]); } else { @@ -3993,24 +3990,24 @@ void HandleUI(void) menusub = 0; break; case 2: - joy_bcount = 16; - strcpy(joy_bnames[MENU_JOY_A - DPAD_NAMES], "Btn A (OK/Enter)"); - strcpy(joy_bnames[MENU_JOY_B - DPAD_NAMES], "Btn B (ESC/Back)"); - strcpy(joy_bnames[MENU_JOY_X - DPAD_NAMES], "Btn X (Backspace"); - strcpy(joy_bnames[MENU_JOY_Y - DPAD_NAMES], "Btn Y "); - strcpy(joy_bnames[MENU_JOY_L - DPAD_NAMES], "Btn L (Z)"); - strcpy(joy_bnames[MENU_JOY_R - DPAD_NAMES], "Btn R (C)"); - strcpy(joy_bnames[MENU_JOY_SELECT - DPAD_NAMES], "Btn Select"); - strcpy(joy_bnames[MENU_JOY_START - DPAD_NAMES], "Btn Start"); - strcpy(joy_bnames[8], "Mouse Move RIGHT"); - strcpy(joy_bnames[9], "Mouse Move LEFT"); - strcpy(joy_bnames[10], "Mouse Move DOWN"); - strcpy(joy_bnames[11], "Mouse Move UP"); - strcpy(joy_bnames[12], "Mouse Left Btn"); - strcpy(joy_bnames[13], "Mouse Right Btn"); - strcpy(joy_bnames[14], "Mouse Middle Btn"); - strcpy(joy_bnames[15], "Mouse Emu / Sniper"); - start_map_setting(joy_bcount + DPAD_NAMES); + strcpy(joy_bnames[SYS_BTN_A - DPAD_NAMES], "A (OK/Enter)"); + strcpy(joy_bnames[SYS_BTN_B - DPAD_NAMES], "B (ESC/Back)"); + strcpy(joy_bnames[SYS_BTN_X - DPAD_NAMES], "X (Backspace)"); + strcpy(joy_bnames[SYS_BTN_Y - DPAD_NAMES], "Y"); + strcpy(joy_bnames[SYS_BTN_L - DPAD_NAMES], "L"); + strcpy(joy_bnames[SYS_BTN_R - DPAD_NAMES], "R"); + strcpy(joy_bnames[SYS_BTN_SELECT - DPAD_NAMES], "Select"); + strcpy(joy_bnames[SYS_BTN_START - DPAD_NAMES], "Start"); + strcpy(joy_bnames[SYS_MS_RIGHT - DPAD_NAMES], "Mouse Move RIGHT"); + strcpy(joy_bnames[SYS_MS_LEFT - DPAD_NAMES], "Mouse Move LEFT"); + strcpy(joy_bnames[SYS_MS_DOWN - DPAD_NAMES], "Mouse Move DOWN"); + strcpy(joy_bnames[SYS_MS_UP - DPAD_NAMES], "Mouse Move UP"); + strcpy(joy_bnames[SYS_MS_BTN_L - DPAD_NAMES], "Mouse Btn Left"); + strcpy(joy_bnames[SYS_MS_BTN_R - DPAD_NAMES], "Mouse Btn Right"); + strcpy(joy_bnames[SYS_MS_BTN_M - DPAD_NAMES], "Mouse Btn Middle"); + strcpy(joy_bnames[SYS_MS_BTN_EMU - DPAD_NAMES], "Mouse Emu / Sniper"); + joy_bcount = 16+1; //buttons + OSD/KTGL button + start_map_setting(joy_bcount + 6); // + dpad + Analog X/Y menustate = MENU_JOYDIGMAP; menusub = 0; break; diff --git a/menu.h b/menu.h index bc63e18..a34deba 100644 --- a/menu.h +++ b/menu.h @@ -24,9 +24,6 @@ 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[32][32]; -extern int joy_bcount; - void open_joystick_setup(); int menu_lightgun_cb(uint16_t type, uint16_t code, int value);