From 0ebf13753213508ce91034c120ca815f3c42ffaf Mon Sep 17 00:00:00 2001 From: Alexey Melnikov Date: Sun, 21 May 2023 02:14:27 +0800 Subject: [PATCH] input: Controller unique mapping (preliminary) Add ini option `unique_mapping` which makes controller mappings unique to the physical port the controller is connected to. Calculates a uint32_t unique_hash for each device during enumeration. Co-authored-by: Martin Donlon --- cfg.cpp | 1 + cfg.h | 1 + input.cpp | 22 +++++++++++++++++++--- str_util.cpp | 13 +++++++++++++ str_util.h | 2 ++ 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/cfg.cpp b/cfg.cpp index 9f0e37d..4644cf9 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -119,6 +119,7 @@ static const ini_var_t ini_vars[] = { "HDR_AVG_NITS", (void*)(&(cfg.hdr_avg_nits)), UINT16, 100, 10000}, { "VGA_MODE", (void*)(&(cfg.vga_mode)), STRING, 0, sizeof(cfg.vga_mode) - 1 }, { "NTSC_MODE", (void *)(&(cfg.ntsc_mode)), UINT8, 0, 2}, + { "UNIQUE_MAPPING", (void *)(&(cfg.unique_mapping)), UINT8, 0, 1}, }; static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t)); diff --git a/cfg.h b/cfg.h index 53a163e..a5cdeca 100644 --- a/cfg.h +++ b/cfg.h @@ -91,6 +91,7 @@ typedef struct { char vga_mode[16]; char vga_mode_int; char ntsc_mode; + uint8_t unique_mapping; } cfg_t; extern cfg_t cfg; diff --git a/input.cpp b/input.cpp index 8984c75..010d47a 100644 --- a/input.cpp +++ b/input.cpp @@ -30,6 +30,7 @@ #include "support.h" #include "profiling.h" #include "gamecontroller_db.h" +#include "str_util.h" #define NUMDEV 30 #define NUMPLAYERS 6 @@ -1189,6 +1190,7 @@ typedef struct char mac[64]; int bind; + uint32_t unique_hash; char devname[32]; char id[80]; char name[128]; @@ -1440,15 +1442,23 @@ int get_map_cancel() static char *get_map_name(int dev, int def) { static char name[128]; - if (def || is_menu()) sprintf(name, "input_%s%s_v3.map", input[dev].idstr, input[dev].mod ? "_m" : ""); - else sprintf(name, "%s_input_%s%s_v3.map", user_io_get_core_name(), input[dev].idstr, input[dev].mod ? "_m" : ""); + char id[32]; + + if (cfg.unique_mapping) sprintfz(id, "%08x", 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" : ""); return name; } static char *get_kbdmap_name(int dev) { static char name[128]; - sprintf(name, "kbd_%s.map", input[dev].idstr); + + if (cfg.unique_mapping) sprintfz(name, "kbd_%08x.map", input[dev].unique_hash); + else sprintfz(name, "kbd_%s.map", input[dev].idstr); + return name; } @@ -3385,6 +3395,12 @@ void mergedevs() strcpy(input[i].id, id); strcpy(input[i].sysfs, sysfs); strcpy(input[i].mac, uniq); + + int unique_hash = str_hash(input[i].id); + unique_hash = str_hash(input[i].mac, unique_hash); + unique_hash = str_hash(input[i].idstr, unique_hash); + input[i].unique_hash = unique_hash; + input[i].timeout = (strlen(uniq) && strstr(sysfs, "bluetooth")) ? (cfg.bt_auto_disconnect * 10) : 0; } } diff --git a/str_util.cpp b/str_util.cpp index 9a1a4ae..92a44e1 100644 --- a/str_util.cpp +++ b/str_util.cpp @@ -31,4 +31,17 @@ char *strncpyz(char *dest, size_t dest_size, const char *src, size_t num) char *strcpyz(char *dest, size_t dest_size, const char *src) { return strncpyz(dest, dest_size, src, dest_size - 1); +} + +unsigned int str_hash(const char *s, unsigned int initial) +{ + unsigned int hash = initial; + int c; + + while( c = *s++ ) + { + hash = ((hash << 5) + hash) + c; + } + + return hash; } \ No newline at end of file diff --git a/str_util.h b/str_util.h index ece59c9..f93506b 100644 --- a/str_util.h +++ b/str_util.h @@ -38,4 +38,6 @@ size_t sprintfz(char (&dest)[N], const char *fmt, ...) return r; } +unsigned int str_hash(const char *s, unsigned int initial = 5381); + #endif // STR_UTIL_H \ No newline at end of file