diff --git a/MiSTer.ini b/MiSTer.ini index bb111bb..2401c7a 100644 --- a/MiSTer.ini +++ b/MiSTer.ini @@ -138,6 +138,29 @@ jamma_pid=0xF3AD ;no_merge_vidpid=0x12345678 ;no_merge_vidpid=0x11112222 +; Permanently assign specific controller to specific player. +; Normally you don't need to use this option, but if you use arcade cabinet with integrated controllers then +; you may want to use it for specific player regardless which controller is used first. +; To assign it, you need to provide unique part of this controller ID. +; In USB debug log you may see list of input devices right after core has been loaded. +; For example: +; +; opened 0( 0): /dev/input/event8 (1915:0040) 0 "7c:10:c9:15:22:33/df:47:3a:12:44:55" "Flydigi APEX2" +; ... +; opened 7( 7): /dev/input/event3 (1997:2535) 0 "usb-ffb40000.usb-1.6/input0" " mini keyboard" +; opened 9( 9): /dev/input/event0 (046d:4024) 0 "usb-ffb40000.usb-1.2/input2:1/4024-19-a2-39-0a" "Logitech K400" +; +; following part is unique identifier in system ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +; So you need to provide part of this string identifying exactly this device. Don't include inputX part as it may change after reboot. +; Wireless devices usually have format MAC/MAC, wired devices use usb-... format. +; +; Example of such unique part of strings: +; +;player_1_controller=usb-1.2/ ;include / at the end so it won't match with something like usb-1.2.3 +;player_2_controller=7c:10:c9:15:22:33/df:47:3a:12:44:55 +;player_3_controller= +;player_4_controller= + ; Speeds in sniper/non-sniper modes of mouse emulation by joystick ; 0 - (default) - faster move in non-sniper mode, slower move in sniper mode. ; 1 - movement speeds are swapped. diff --git a/cfg.cpp b/cfg.cpp index 85bca96..c97e502 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -103,6 +103,10 @@ static const ini_var_t ini_vars[] = { "VRR_MAX_FRAMERATE", (void *)(&(cfg.vrr_max_framerate)), UINT8, 0, 255}, { "VRR_VESA_FRAMERATE", (void *)(&(cfg.vrr_vesa_framerate)), UINT8, 0, 255}, { "VIDEO_OFF", (void*)(&(cfg.video_off)), INT16, 0, 3600 }, + { "PLAYER_1_CONTROLLER", (void*)(&(cfg.player_controller[0])), STRING, 0, sizeof(cfg.player_controller[0]) - 1 }, + { "PLAYER_2_CONTROLLER", (void*)(&(cfg.player_controller[1])), STRING, 0, sizeof(cfg.player_controller[1]) - 1 }, + { "PLAYER_3_CONTROLLER", (void*)(&(cfg.player_controller[2])), STRING, 0, sizeof(cfg.player_controller[2]) - 1 }, + { "PLAYER_4_CONTROLLER", (void*)(&(cfg.player_controller[3])), STRING, 0, sizeof(cfg.player_controller[3]) - 1 }, }; static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t)); diff --git a/cfg.h b/cfg.h index ebc23e6..f16049b 100644 --- a/cfg.h +++ b/cfg.h @@ -69,6 +69,7 @@ typedef struct { char vfilter_vertical_default[1023]; char vfilter_scanlines_default[1023]; char shmask_default[1023]; + char player_controller[4][1024]; uint8_t rumble; uint8_t wheel_force; uint16_t wheel_range; diff --git a/input.cpp b/input.cpp index 16ab5ef..1dd9dd1 100644 --- a/input.cpp +++ b/input.cpp @@ -2235,6 +2235,14 @@ static uint16_t def_mmap[] = { 0x0000, 0x0002, 0x0001, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000 }; +static void assign_player(int dev, int num) +{ + input[dev].num = num; + if (JOYCON_COMBINED(dev)) input[input[dev].bind].num = num; + store_player(num, dev); + printf("Device %s assigned to player %d\n", input[dev].id, input[dev].num); +} + static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int dev) { if (ev->type != EV_KEY && ev->type != EV_ABS && ev->type != EV_REL) return; @@ -2295,7 +2303,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int //input[dev].has_mmap++; } } else { - gcdb_show_string_for_ctrl_map(input[sub_dev].bustype, input[sub_dev].vid, input[sub_dev].pid, input[sub_dev].version, pool[sub_dev].fd, input[sub_dev].name, input[dev].mmap); + gcdb_show_string_for_ctrl_map(input[sub_dev].bustype, input[sub_dev].vid, input[sub_dev].pid, input[sub_dev].version, pool[sub_dev].fd, input[sub_dev].name, input[dev].mmap); } 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]; @@ -2374,29 +2382,41 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int if (assign_btn) { - for (uint8_t num = 1; num < NUMDEV + 1; num++) + for (uint8_t i = 0; i < (sizeof(cfg.player_controller) / sizeof(cfg.player_controller[0])); i++) { - int found = 0; - for (int i = 0; i < NUMDEV; i++) + if (cfg.player_controller[i][0]) { - if (input[i].quirk != QUIRK_TOUCHGUN) + if (strcasestr(input[dev].id, cfg.player_controller[i])) { - // paddles/spinners overlay on top of other gamepad - if (!((input[dev].quirk == QUIRK_PDSP || input[dev].quirk == QUIRK_MSSP) ^ (input[i].quirk == QUIRK_PDSP || input[i].quirk == QUIRK_MSSP))) - { - found = (input[i].num == num); - if (found) break; - } + assign_player(dev, i + 1); + break; } } + } - if (!found) + if (!input[dev].num) + { + for (uint8_t num = 1; num < NUMDEV + 1; num++) { - input[dev].num = num; - if (JOYCON_COMBINED(dev)) input[input[dev].bind].num = num; - store_player(num, dev); - printf("Device %s assigned to player %d\n", input[dev].id, input[dev].num); - break; + int found = 0; + for (int i = 0; i < NUMDEV; i++) + { + if (input[i].quirk != QUIRK_TOUCHGUN) + { + // paddles/spinners overlay on top of other gamepad + if (!((input[dev].quirk == QUIRK_PDSP || input[dev].quirk == QUIRK_MSSP) ^ (input[i].quirk == QUIRK_PDSP || input[i].quirk == QUIRK_MSSP))) + { + found = (input[i].num == num); + if (found) break; + } + } + } + + if (!found) + { + assign_player(dev, num); + break; + } } } }