From 385c2201c9fe59a47ebe0e0768b88f203b19544f Mon Sep 17 00:00:00 2001 From: sorgelig Date: Fri, 31 Jan 2020 05:34:22 +0800 Subject: [PATCH] input: support buttons in MRA, show joystick map on first button press. --- input.cpp | 107 +++++++++++++++++++++++---- input.h | 4 ++ joymapping.cpp | 139 ++++++++++++++++++++++-------------- joymapping.h | 1 + menu.cpp | 19 ++--- support/arcade/romutils.cpp | 12 ++++ user_io.cpp | 15 ++-- 7 files changed, 205 insertions(+), 92 deletions(-) diff --git a/input.cpp b/input.cpp index 60abbc8..8b5ddbc 100644 --- a/input.cpp +++ b/input.cpp @@ -1795,6 +1795,10 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int } input[dev].has_map++; } + else + { + map_joystick_show(input[dev].map, input[dev].mmap); + } input[dev].has_map++; } @@ -1844,6 +1848,8 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int //mapping if (mapping && (mapping_dev >= 0 || ev->value) && !((mapping_type < 2 || !mapping_button) && (cancel || enter))) { + int idx = 0; + if (is_menu_core()) { spi_uio_cmd(UIO_KEYBOARD); //ping the Menu core to wakeup @@ -1997,15 +2003,12 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int { last_axis = 0; } - return; } } } - - //Define min-0-max analogs - int idx = 0; - if (is_menu_core()) + else if (is_menu_core()) { + //Define min-0-max analogs switch (mapping_button) { case 23: idx = SYS_AXIS_X; break; @@ -2109,22 +2112,29 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int } } - if (mapping_type <= 1 && map_skip && mapping_button < mapping_count) + while (mapping_type <= 1 && mapping_button < mapping_count) { - if (ev->value == 1) + if (map_skip) { - if (mapping_dev >= 0) + if (map_skip == 2 || ev->value == 1) { - if (idx) input[mapping_dev].map[idx] = 0; - else if (mapping_button > 0) + if (mapping_dev >= 0) { - if (!is_menu_core()) input[mapping_dev].map[mapping_button] &= mapping_set ? 0x0000FFFF : 0xFFFF0000; + if (idx) input[mapping_dev].map[idx] = 0; + else if (mapping_button > 0) + { + if (!is_menu_core()) input[mapping_dev].map[mapping_button] &= mapping_set ? 0x0000FFFF : 0xFFFF0000; + } } + last_axis = 0; + mapping_button++; + if (mapping_button < 0 && (mapping_button & 1)) mapping_button++; } - last_axis = 0; - mapping_button++; - if (mapping_button < 0 && (mapping_button&1)) mapping_button++; } + + map_skip = 0; + if (mapping_button >= 4 && !is_menu_core() && !strcmp(joy_bnames[mapping_button - 4], "-")) map_skip = 2; + if (!map_skip) break; } if (is_menu_core() && mapping_type <= 1 && mapping_dev >= 0) @@ -3373,3 +3383,72 @@ int input_state() { return grabbed; } + +static char ovr_buttons[1024] = {}; +static char ovr_nmap[1024] = {}; +static char ovr_pmap[1024] = {}; + +static char *get_btn(int type) +{ + int i = 2; + while (1) + { + char *p = user_io_get_confstr(i); + if (!p) break; + + if ((p[0] == 'J' && !type) || (p[0] == 'j' && ((p[1] == 'n' && type == 1) || (p[1] == 'p' && type == 2)))) + { + p = strchr(p, ','); + if (!p) break; + + p++; + if (!strlen(p)) break; + return p; + } + + i++; + } + return NULL; +} + +char *get_buttons(int type) +{ + if (type == 0 && ovr_buttons[0]) return ovr_buttons; + if (type == 1 && ovr_nmap[0]) return ovr_nmap; + if (type == 2 && ovr_pmap[0]) return ovr_pmap; + + return get_btn(type); +} + +void set_ovr_buttons(char *s, int type) +{ + switch (type) + { + case 0: + snprintf(ovr_buttons, sizeof(ovr_buttons), "%s", s); + break; + + case 1: + snprintf(ovr_nmap, sizeof(ovr_nmap), "%s", s); + break; + + case 2: + snprintf(ovr_pmap, sizeof(ovr_pmap), "%s", s); + break; + } +} + +void parse_buttons() +{ + joy_bcount = 0; + + char *str = get_buttons(); + if (!str) return; + + for (int n = 0; n < 28; n++) + { + substrcpy(joy_bnames[n], str, n); + if (!joy_bnames[n][0]) break; + joy_bcount++; + } +} diff --git a/input.h b/input.h index 7b3a583..151aee2 100644 --- a/input.h +++ b/input.h @@ -102,4 +102,8 @@ void input_uinp_destroy(); extern char joy_bnames[NUMBUTTONS][32]; extern int joy_bcount; +void parse_buttons(); +char *get_buttons(int type = 0); +void set_ovr_buttons(char *s, int type); + #endif diff --git a/joymapping.cpp b/joymapping.cpp index 33edecf..aaf0d0d 100644 --- a/joymapping.cpp +++ b/joymapping.cpp @@ -32,9 +32,8 @@ static char joy_nnames[NUMBUTTONS][32]; static char joy_pnames[NUMBUTTONS][32]; static int defaults = 0; -static void get_buttons() +static void read_buttons() { - int i = 2; char *p; memset(joy_bnames, 0, sizeof(joy_bnames)); @@ -44,64 +43,58 @@ static void get_buttons() defaults = 0; user_io_read_confstr(); - while(1) + + // this option used as default name map (unless jn/jp is supplied) + p = get_buttons(0); + if (p) { - p = user_io_get_confstr(i); - if (!p) break; - - // this option used as default name map (unless jn/jp is supplied) - if (p[0] == 'J') + for (int n = 0; n < NUMBUTTONS - DPAD_COUNT; n++) { - for (int n = 0; n < NUMBUTTONS - DPAD_COUNT; n++) - { - substrcpy(joy_bnames[n], p, n + 1); - if (!joy_bnames[n][0]) break; + substrcpy(joy_bnames[n], p, n); + if (!joy_bnames[n][0]) break; - printf("joy_bname[%d] = %s\n", n, joy_bnames[n]); + printf("joy_bname[%d] = %s\n", n, joy_bnames[n]); - memcpy(joy_nnames[n], joy_bnames[n], sizeof(joy_nnames[0])); - char *sstr = strchr(joy_nnames[n], '('); - if (sstr) *sstr = 0; - trim(joy_nnames[n]); + memcpy(joy_nnames[n], joy_bnames[n], sizeof(joy_nnames[0])); + char *sstr = strchr(joy_nnames[n], '('); + if (sstr) *sstr = 0; + trim(joy_nnames[n]); - if (!joy_nnames[n][0]) break; - joy_bcount++; - } - printf("\n"); + if (!joy_nnames[n][0]) break; + joy_bcount++; } + printf("\n"); + } - // - supports empty name to skip the button from default map - // - only base button names must be used (ABXYLR Start Select) - if (p[0] == 'j') + // - supports empty name to skip the button from default map + // - only base button names must be used (ABXYLR Start Select) + + // name default map + p = get_buttons(1); + if (p) + { + memset(joy_nnames, 0, sizeof(joy_nnames)); + for (int n = 0; n < joy_bcount; n++) { - // name default map - if (p[1] == 'n') - { - memset(joy_nnames, 0, sizeof(joy_nnames)); - for (int n = 0; n < joy_bcount; n++) - { - substrcpy(joy_nnames[n], p, n + 1); - trim(joy_nnames[n]); - if (joy_nnames[n][0]) printf("joy_nname[%d] = %s\n", n, joy_nnames[n]); - } - printf("\n"); - } - - // positional default map - if (p[1] == 'p') - { - defaults = cfg.gamepad_defaults; - for (int n = 0; n < joy_bcount; n++) - { - substrcpy(joy_pnames[n], p, n + 1); - trim(joy_pnames[n]); - if (joy_pnames[n][0]) printf("joy_pname[%d] = %s\n", n, joy_pnames[n]); - } - printf("\n"); - } + substrcpy(joy_nnames[n], p, n); + trim(joy_nnames[n]); + if (joy_nnames[n][0]) printf("joy_nname[%d] = %s\n", n, joy_nnames[n]); } + printf("\n"); + } - i++; + // positional default map + p = get_buttons(2); + if (p) + { + defaults = cfg.gamepad_defaults; + for (int n = 0; n < joy_bcount; n++) + { + substrcpy(joy_pnames[n], p, n); + trim(joy_pnames[n]); + if (joy_pnames[n][0]) printf("joy_pname[%d] = %s\n", n, joy_pnames[n]); + } + printf("\n"); } } @@ -137,7 +130,7 @@ void map_joystick(uint32_t *map, uint32_t *mmap) Input button order is "virtual SNES" i.e.: A, B, X, Y, L, R, Select, Start */ - get_buttons(); + read_buttons(); sprintf(mapinfo, "Default (%s) map:", defaults ? "pos" : "name"); map[SYS_BTN_RIGHT] = mmap[SYS_BTN_RIGHT] & 0xFFFF; @@ -160,10 +153,12 @@ void map_joystick(uint32_t *map, uint32_t *mmap) } // loop through core requested buttons and construct result map - for (int i=0; i void map_joystick(uint32_t *map, uint32_t *mmap); +void map_joystick_show(uint32_t *map, uint32_t *mmap); #endif // JOYMAPPING_H diff --git a/menu.cpp b/menu.cpp index c660ffb..09a6597 100644 --- a/menu.cpp +++ b/menu.cpp @@ -1291,7 +1291,6 @@ void HandleUI(void) adjvisible = 0; entry = 0; uint32_t selentry = 0; - joy_bcount = 0; menumask = 0; p = user_io_get_core_name(); if (!p[0]) OsdCoreNameSet("8BIT"); @@ -1465,20 +1464,6 @@ void HandleUI(void) substrcpy(s + strlen(s), p, 1); OsdCoreNameSet(s); } - - if (p[0] == 'J') - { - // joystick button names. - for (int n = 0; n < 28; n++) - { - substrcpy(joy_bnames[n], p, n + 1); - //printf("joy_bname = %s\n", joy_bnames[n]); - if (!joy_bnames[n][0]) break; - joy_bcount++; - } - - //printf("joy_bcount = %d\n", joy_bcount); - } } } while (p); @@ -1883,6 +1868,10 @@ void HandleUI(void) strcpy(joy_bnames[5], "LT"); strcpy(joy_bnames[6], "Pause"); } + else + { + parse_buttons(); + } start_map_setting(joy_bcount ? joy_bcount+4 : 8); menustate = MENU_JOYDIGMAP; menusub = 0; diff --git a/support/arcade/romutils.cpp b/support/arcade/romutils.cpp index c9d359b..73dc248 100644 --- a/support/arcade/romutils.cpp +++ b/support/arcade/romutils.cpp @@ -7,6 +7,7 @@ #include "../../sxmlc.h" #include "../../user_io.h" +#include "../../input.h" #include "../../file_io.h" #include "../../menu.h" #include "../../fpga_io.h" @@ -359,6 +360,17 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons { arc_info->romindex = atoi(node->attributes[i].value); } + + if (!strcasecmp(node->attributes[i].name, "names") && !strcasecmp(node->tag, "buttons")) + { + set_ovr_buttons(node->attributes[i].value, 0); + } + + if (!strcasecmp(node->attributes[i].name, "default") && !strcasecmp(node->tag, "buttons")) + { + set_ovr_buttons(node->attributes[i].value, 1); + } + /* these only exist if we are inside the rom tag, and in a part tag*/ if (arc_info->insiderom) { diff --git a/user_io.cpp b/user_io.cpp index f929e53..c0fd4ff 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -389,6 +389,7 @@ static void parse_config() char *p; joy_force = 0; + joy_bcount = 0; do { p = user_io_get_confstr(i); @@ -415,14 +416,6 @@ static void parse_config() joy_force = 1; set_emu_mode(EMU_JOY0); } - - joy_bcount = 0; - for (int n = 0; n < 28; n++) - { - substrcpy(joy_bnames[n], p, n + 1); - if (!joy_bnames[n][0]) break; - joy_bcount++; - } } if (p[0] == 'O' && p[1] == 'X') @@ -761,6 +754,7 @@ void user_io_init(const char *path, const char *xml) archie_init(); user_io_read_core_name(); parse_config(); + parse_buttons(); break; case CORE_TYPE_SHARPMZ: @@ -769,7 +763,8 @@ void user_io_init(const char *path, const char *xml) sharpmz_init(); user_io_read_core_name(); parse_config(); - break; + parse_buttons(); + break; case CORE_TYPE_8BIT: // try to load config @@ -901,6 +896,8 @@ void user_io_init(const char *path, const char *xml) } } } + + parse_buttons(); } send_rtc(3);