input: support for multiple input devices mapping per player.
This commit is contained in:
@@ -184,13 +184,15 @@ jamma_pid=0xF3AD
|
||||
; 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.
|
||||
; UPDATE: you may define up to 8 devices to the same player. Use player_1_controller in several lines to assign multiple devices to player 1.
|
||||
;
|
||||
; 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=
|
||||
;player_3_controller=1915_0040_55c4dd0c ; VID_PID_HASH - VID, PID and unique HASH
|
||||
;player_4_controller=1915_0040 ; VID_PID - warning, it will assign all input devices with these VID:PID to same player!
|
||||
|
||||
|
||||
; Speeds in sniper/non-sniper modes of mouse emulation by joystick
|
||||
; 0 - (default) - faster move in non-sniper mode, slower move in sniper mode.
|
||||
|
||||
42
cfg.cpp
42
cfg.cpp
@@ -19,7 +19,7 @@ cfg_t cfg;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UINT8 = 0, INT8, UINT16, INT16, UINT32, INT32, HEX8, HEX16, HEX32, FLOAT, STRING, UINT32ARR, HEX32ARR
|
||||
UINT8 = 0, INT8, UINT16, INT16, UINT32, INT32, HEX8, HEX16, HEX32, FLOAT, STRING, UINT32ARR, HEX32ARR, STRINGARR
|
||||
} ini_vartypes_t;
|
||||
|
||||
typedef struct
|
||||
@@ -104,10 +104,12 @@ 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 },
|
||||
{ "PLAYER_1_CONTROLLER", (void*)(&(cfg.player_controller[0])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_2_CONTROLLER", (void*)(&(cfg.player_controller[1])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_3_CONTROLLER", (void*)(&(cfg.player_controller[2])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_4_CONTROLLER", (void*)(&(cfg.player_controller[3])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_5_CONTROLLER", (void*)(&(cfg.player_controller[4])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_6_CONTROLLER", (void*)(&(cfg.player_controller[5])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "DISABLE_AUTOFIRE", (void *)(&(cfg.disable_autofire)), UINT8, 0, 1},
|
||||
{ "VIDEO_BRIGHTNESS", (void *)(&(cfg.video_brightness)), UINT8, 0, 100},
|
||||
{ "VIDEO_CONTRAST", (void *)(&(cfg.video_contrast)), UINT8, 0, 100},
|
||||
@@ -354,7 +356,22 @@ static void ini_parse_var(char* buf)
|
||||
{
|
||||
case STRING:
|
||||
memset(var->var, 0, var->max);
|
||||
strncpy((char*)(var->var), &(buf[i]), var->max);
|
||||
snprintf((char*)(var->var), var->max, "%s", buf+i);
|
||||
break;
|
||||
|
||||
case STRINGARR:
|
||||
{
|
||||
int item_sz = var->max;
|
||||
for (int n = 0; n < var->min; n++)
|
||||
{
|
||||
char *str = ((char*)var->var) + (n * item_sz);
|
||||
if (!strlen(str))
|
||||
{
|
||||
snprintf(str, item_sz, "%s", buf + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HEX32ARR:
|
||||
@@ -592,7 +609,7 @@ void cfg_print()
|
||||
if (*(uint32_t*)ini_vars[i].var)
|
||||
{
|
||||
uint32_t* arr = (uint32_t*)ini_vars[i].var;
|
||||
for (uint32_t n = 0; n < arr[0]; n++) printf("%s=%u\n", ini_vars[i].name, arr[n + 1]);
|
||||
for (uint32_t n = 0; n < arr[0]; n++) printf(" %s=%u\n", ini_vars[i].name, arr[n + 1]);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -612,7 +629,7 @@ void cfg_print()
|
||||
if (*(uint32_t*)ini_vars[i].var)
|
||||
{
|
||||
uint32_t* arr = (uint32_t*)ini_vars[i].var;
|
||||
for (uint32_t n = 0; n < arr[0]; n++) printf("%s=0x%08X\n", ini_vars[i].name, arr[n + 1]);
|
||||
for (uint32_t n = 0; n < arr[0]; n++) printf(" %s=0x%08X\n", ini_vars[i].name, arr[n + 1]);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -635,6 +652,15 @@ void cfg_print()
|
||||
case STRING:
|
||||
if (*(uint32_t*)ini_vars[i].var) printf(" %s=%s\n", ini_vars[i].name, (char*)ini_vars[i].var);
|
||||
break;
|
||||
|
||||
case STRINGARR:
|
||||
for (int n = 0; n < ini_vars[i].min; n++)
|
||||
{
|
||||
char *str = ((char*)ini_vars[i].var) + (n*ini_vars[i].max);
|
||||
if (!strlen(str)) break;
|
||||
printf(" %s=%s\n", ini_vars[i].name, str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("--------------\n");
|
||||
|
||||
2
cfg.h
2
cfg.h
@@ -69,7 +69,7 @@ typedef struct {
|
||||
char vfilter_scanlines_default[1023];
|
||||
char shmask_default[1023];
|
||||
char preset_default[1023];
|
||||
char player_controller[4][1024];
|
||||
char player_controller[6][8][256];
|
||||
uint8_t rumble;
|
||||
uint8_t wheel_force;
|
||||
uint16_t wheel_range;
|
||||
|
||||
60
input.cpp
60
input.cpp
@@ -1439,36 +1439,41 @@ int get_map_cancel()
|
||||
return (mapping && !is_menu() && osd_timer && CheckTimer(osd_timer));
|
||||
}
|
||||
|
||||
static int has_unique_mapping(uint32_t vidpid)
|
||||
static char *get_unique_mapping(int dev, int force_unique = 0)
|
||||
{
|
||||
uint32_t vidpid = (input[dev].vid << 16) | input[dev].pid;
|
||||
static char str[128];
|
||||
|
||||
for (uint i = 0; i < cfg.controller_unique_mapping[0]; i++)
|
||||
{
|
||||
if (!cfg.controller_unique_mapping[i + 1]) break;
|
||||
if (cfg.controller_unique_mapping[i + 1] == 1 || cfg.controller_unique_mapping[i + 1] == vidpid) return 1;
|
||||
if (force_unique || cfg.controller_unique_mapping[i + 1] == 1 || cfg.controller_unique_mapping[i + 1] == vidpid)
|
||||
{
|
||||
sprintfz(str, "%s_%08x", input[dev].idstr, input[dev].unique_hash);
|
||||
return str;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
sprintfz(str, "%s", input[dev].idstr);
|
||||
return str;
|
||||
}
|
||||
|
||||
static char *get_map_name(int dev, int def)
|
||||
{
|
||||
static char name[128];
|
||||
char id[32];
|
||||
static char name[1024];
|
||||
char *id = get_unique_mapping(dev);
|
||||
|
||||
if (has_unique_mapping((input[dev].vid << 16) | input[dev].pid)) sprintfz(id, "%s_%08x", input[dev].idstr, input[dev].unique_hash);
|
||||
else strcpyz(id, input[dev].idstr);
|
||||
|
||||
if (def || is_menu()) sprintf(name, "input_%s%s_v3.map", id, input[dev].mod ? "_m" : "");
|
||||
else sprintf(name, "%s_input_%s%s_v3.map", user_io_get_core_name(), id, input[dev].mod ? "_m" : "");
|
||||
if (def || is_menu()) sprintfz(name, "input_%s%s_v3.map", id, input[dev].mod ? "_m" : "");
|
||||
else sprintfz(name, "%s_input_%s%s_v3.map", user_io_get_core_name(), id, input[dev].mod ? "_m" : "");
|
||||
return name;
|
||||
}
|
||||
|
||||
static char *get_kbdmap_name(int dev)
|
||||
{
|
||||
static char name[128];
|
||||
char *id = get_unique_mapping(dev);
|
||||
|
||||
if (has_unique_mapping((input[dev].vid << 16) | input[dev].pid)) sprintfz(name, "kbd_%s_%08x.map", input[dev].idstr, input[dev].unique_hash);
|
||||
else sprintfz(name, "kbd_%s.map", input[dev].idstr);
|
||||
|
||||
sprintfz(name, "kbd_%s.map", id);
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -2269,12 +2274,12 @@ static uint16_t def_mmap[] = {
|
||||
0x0000, 0x0002, 0x0001, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
static void assign_player(int dev, int num)
|
||||
static void assign_player(int dev, int num, int force = 0)
|
||||
{
|
||||
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);
|
||||
printf("Device %s %sassigned to player %d\n", input[dev].id, force ? "forcebly " : "", input[dev].num);
|
||||
}
|
||||
|
||||
static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int dev)
|
||||
@@ -2411,24 +2416,35 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
int assign_btn = ((input[dev].quirk == QUIRK_PDSP || input[dev].quirk == QUIRK_MSSP) && (ev->type == EV_REL || ev->type == EV_KEY));
|
||||
if (!assign_btn && ev->type == EV_KEY && ev->value >= 1 && ev->code >= 256)
|
||||
{
|
||||
for (int i = SYS_BTN_RIGHT; i <= SYS_BTN_START; i++) if (ev->code == input[dev].mmap[i]) assign_btn = 1;
|
||||
for (int i = SYS_BTN_RIGHT; i <= SYS_BTN_START; i++)
|
||||
{
|
||||
if (ev->code == input[dev].mmap[i]) assign_btn = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (assign_btn)
|
||||
{
|
||||
for (uint8_t i = 0; i < (sizeof(cfg.player_controller) / sizeof(cfg.player_controller[0])); i++)
|
||||
{
|
||||
if (cfg.player_controller[i][0])
|
||||
for (int n = 0; n < 8; n++)
|
||||
{
|
||||
if (strcasestr(input[dev].id, cfg.player_controller[i]))
|
||||
if (!cfg.player_controller[i][n][0]) break;
|
||||
|
||||
if (strcasestr(input[dev].id, cfg.player_controller[i][n]))
|
||||
{
|
||||
assign_player(dev, i + 1);
|
||||
assign_player(dev, i + 1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcasestr(input[dev].sysfs, cfg.player_controller[i]))
|
||||
if (strcasestr(input[dev].sysfs, cfg.player_controller[i][n]))
|
||||
{
|
||||
assign_player(dev, i + 1);
|
||||
assign_player(dev, i + 1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcasestr(get_unique_mapping(dev, 1), cfg.player_controller[i][n]))
|
||||
{
|
||||
assign_player(dev, i + 1, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -4573,7 +4589,7 @@ int input_test(int getchar)
|
||||
setup_wheels();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
printf("opened %d(%2d): %s (%04x:%04x) %d \"%s\" \"%s\"\n", i, input[i].bind, input[i].devname, input[i].vid, input[i].pid, input[i].quirk, input[i].id, input[i].name);
|
||||
printf("opened %d(%2d): %s (%04x:%04x:%08x) %d \"%s\" \"%s\"\n", i, input[i].bind, input[i].devname, input[i].vid, input[i].pid, input[i].unique_hash, input[i].quirk, input[i].id, input[i].name);
|
||||
restore_player(i);
|
||||
}
|
||||
unflag_players();
|
||||
|
||||
Reference in New Issue
Block a user