diff --git a/input.cpp b/input.cpp index bdaf3ed..de773b4 100644 --- a/input.cpp +++ b/input.cpp @@ -24,8 +24,8 @@ #include "fpga_io.h" #include "osd.h" #include "video.h" +#include "joymapping.h" -#define NUMDEV 30 #define NUMPLAYERS 6 #define UINPUT_NAME "MiSTer virtual input" @@ -988,41 +988,6 @@ 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[32]; - - uint8_t osd_combo; - - uint8_t has_mmap; - uint32_t mmap[32]; - 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])) @@ -1251,6 +1216,15 @@ 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)); @@ -1730,16 +1704,19 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int { if (!FileLoadConfig(get_map_name(dev, 0), &input[dev].map, sizeof(input[dev].map))) { - if (is_menu_core() || !FileLoadConfig(get_map_name(dev, 1), &input[dev].map, sizeof(input[dev].map))) - { - 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++) + if(!convert_from_menu_mapping(dev)) { + if (is_menu_core() || !FileLoadConfig(get_map_name(dev, 1), &input[dev].map, sizeof(input[dev].map))) { - input[dev].map[i] = 0; + // 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++; @@ -1849,24 +1826,24 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int input[dev].osd_combo = 0; int found = 0; - for (int i = (mapping_button >= 8) ? 8 : 0; i < mapping_button; i++) if (input[dev].map[i] == ev->code) found = 1; + 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 == 16 && mapping_type)) + if (!found || (mapping_button == BUTTON_IDX_OSD && mapping_type)) { - input[dev].map[(mapping_button == 16) ? 16 + mapping_type : mapping_button] = ev->code; - input[dev].map[18] = input[dev].map[17]; + 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]; key_mapped = ev->code; //check if analog stick has been used for mouse - if (mapping_button == 9 || mapping_button == 11) + 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 - 9)/2] = ((input[dev].map[mapping_button] - KEY_EMU)/2) | 0x20000; + input[dev].map[AXIS_MX + (mapping_button - (BUTTON_DPAD_COUNT+1))/2] = ((input[dev].map[mapping_button] - KEY_EMU)/2) | 0x20000; } } } @@ -1907,10 +1884,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 == 16 && mapping_type) + if (ev->value == 1 && key_mapped && key_mapped != ev->code && is_menu_core() && mapping_button == BUTTON_IDX_OSD && mapping_type) { - input[dev].map[18] = ev->code; - printf("Set combo: %x + %x\n", input[dev].map[17], input[dev].map[18]); + 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]); } else if(mapping_dev == dev && ev->value == 0 && key_mapped == ev->code) { diff --git a/input.h b/input.h index df670c5..126a6a7 100644 --- a/input.h +++ b/input.h @@ -29,6 +29,10 @@ #define UPSTROKE 0x400000 +#define BUTTON_IDX_OSD 16 +#define BUTTON_DPAD_COUNT 12 // dpad + 8 buttons + + void set_kbdled(int mask, int state); int get_kbdled(int mask); int toggle_kbdled(int mask); diff --git a/joymapping.cpp b/joymapping.cpp new file mode 100644 index 0000000..c58b7f2 --- /dev/null +++ b/joymapping.cpp @@ -0,0 +1,134 @@ +/* +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 + +#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 diff --git a/menu.cpp b/menu.cpp index 35c08cd..8ff0b94 100644 --- a/menu.cpp +++ b/menu.cpp @@ -55,8 +55,8 @@ along with this program. If not, see . #include "bootcore.h" #include "cheats.h" #include "video.h" - #include "support.h" +#include "joymapping.h" /*menu states*/ enum MENU @@ -191,13 +191,17 @@ 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", "MENU", " Stick X: Tilt RIGHT", " Stick Y: Tilt DOWN", " Mouse emu X: Tilt RIGHT", " Mouse emu Y: Tilt DOWN" }; -const char *joy_ana_map[] = { " DPAD test: Press RIGHT", " DPAD test: Press DOWN", " Stick 1: Tilt RIGHT", " Stick 1: Tilt DOWN", " Stick 2: Tilt RIGHT", " Stick 2: Tilt DOWN" }; +const char *joy_button_map[] = { "RIGHT", "LEFT", "DOWN", "UP", "BUTTON A", "BUTTON B", "BUTTON X", "BUTTON Y", "BUTTON L", "BUTTON R", "SELECT", "START", "KBD TOGGLE", "MENU", " Stick X: Tilt RIGHT", " Stick Y: Tilt DOWN", " Mouse emu X: Tilt RIGHT", " Mouse emu Y: Tilt DOWN" }; +const char *joy_ana_map[] = { " DPAD test: Press RIGHT", " DPAD test: Press DOWN", " Stick 1 Test: Tilt RIGHT", " Stick 1 Test: Tilt DOWN", " Stick 2 Test: Tilt RIGHT", " Stick 2 Test: 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" }; 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; @@ -2150,22 +2154,22 @@ void HandleUI(void) { strcpy(s, joy_ana_map[get_map_button() + 6]); } - else if (get_map_button() < 4) + else if (get_map_button() < DPAD_NAMES) { p = joy_button_map[get_map_button()]; } else if (joy_bcount) { - p = joy_bnames[get_map_button() - 4]; + p = joy_bnames[get_map_button() - DPAD_NAMES]; if (is_menu_core()) { if (get_map_type()) joy_bcount = 15; if (get_map_button() == 16) { - p = joy_button_map[8 + get_map_type()]; + p = joy_button_map[DPAD_BUTTON_NAMES + get_map_type()]; if (get_map_type()) { - OsdWrite(12, " Allowed 2-buttons combo"); + OsdWrite(12, " (can use 2-button combo)"); line_info = 1; } } @@ -2173,14 +2177,14 @@ void HandleUI(void) } else { - p = (get_map_button() < 8) ? joy_button_map[get_map_button()] : joy_button_map[8 + get_map_type()]; + p = (get_map_button() < DPAD_BUTTON_NAMES) ? joy_button_map[get_map_button()] : joy_button_map[DPAD_BUTTON_NAMES + get_map_type()]; } if (get_map_button() >= 0) { if (is_menu_core() && get_map_button() > 16) { - strcpy(s, joy_button_map[10 + get_map_button() - 17]); + strcpy(s, joy_button_map[14 + get_map_button() - 17]); } else { @@ -3989,20 +3993,24 @@ void HandleUI(void) menusub = 0; break; case 2: - joy_bcount = 13; - strcpy(joy_bnames[0], "Btn 1 (OK/Enter)"); - strcpy(joy_bnames[1], "Btn 2 (ESC/Back)"); - strcpy(joy_bnames[2], "Btn 3 (Backspace)"); - strcpy(joy_bnames[3], "Btn 4"); - strcpy(joy_bnames[4], "Mouse Move RIGHT"); - strcpy(joy_bnames[5], "Mouse Move LEFT"); - strcpy(joy_bnames[6], "Mouse Move DOWN"); - strcpy(joy_bnames[7], "Mouse Move UP"); - strcpy(joy_bnames[8], "Mouse Left Btn"); - strcpy(joy_bnames[9], "Mouse Right Btn"); - strcpy(joy_bnames[10], "Mouse Middle Btn"); - strcpy(joy_bnames[11], "Mouse Emu/Sniper"); - start_map_setting(19); + 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); menustate = MENU_JOYDIGMAP; menusub = 0; break;