Skip to content

Commit

Permalink
input: restore player gamepad after input devices re-enumeration.
Browse files Browse the repository at this point in the history
  • Loading branch information
sorgelig committed Jun 22, 2020
1 parent fed7cae commit 03d824a
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 83 deletions.
118 changes: 85 additions & 33 deletions input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,8 @@ typedef struct
} devInput;

static devInput input[NUMDEV] = {};
static devInput player_pad[NUMPLAYERS] = {};
static devInput player_pdsp[NUMPLAYERS] = {};

#define BTN_NUM (sizeof(devInput::map) / sizeof(devInput::map[0]))

Expand Down Expand Up @@ -1664,6 +1666,13 @@ static void joy_analog(int num, int axis, int offset)
}
}

void reset_players()
{
for (int i = 0; i < NUMDEV; i++) input[i].num = 0;
memset(player_pad, 0, sizeof(player_pad));
memset(player_pdsp, 0, sizeof(player_pdsp));
}

static int ds_mouse_emu = 0;

static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int dev)
Expand Down Expand Up @@ -1694,29 +1703,6 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
int enter = (ev->type == EV_KEY && ev->code == KEY_ENTER);
int origcode = ev->code;

if (!input[dev].num && ((ev->type == EV_KEY && ev->code >= 256) || (input[dev].quirk == QUIRK_PDSP && ev->type == EV_REL)))
{
for (uint8_t num = 1; num < NUMDEV + 1; num++)
{
int found = 0;
for (int i = 0; i < NUMDEV; i++)
{
// paddles/spinners overlay on top of other gamepad
if (!((input[dev].quirk == QUIRK_PDSP) ^ (input[i].quirk == QUIRK_PDSP)))
{
found = (input[i].num == num);
if (found) break;
}
}

if (!found)
{
input[dev].num = num;
break;
}
}
}

if (!input[dev].has_mmap)
{
if (input[dev].quirk != QUIRK_PDSP)
Expand All @@ -1737,12 +1723,6 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
{
memset(input[dev].map, 0, sizeof(input[dev].map));
input[dev].map[map_paddle_btn()] = 0x120;
if (cfg.controller_info)
{
char str[32];
sprintf(str, "P%d paddle/spinner", input[dev].num);
Info(str, cfg.controller_info * 1000);
}
}
else if (!load_map(get_map_name(dev, 0), &input[dev].map, sizeof(input[dev].map)))
{
Expand All @@ -1752,7 +1732,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
if (input[dev].has_mmap == 1)
{
// not defined try to guess the mapping
map_joystick(input[dev].map, input[dev].mmap, input[dev].num);
map_joystick(input[dev].map, input[dev].mmap);
}
else
{
Expand All @@ -1761,11 +1741,50 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
}
input[dev].has_map++;
}
else
input[dev].has_map++;
}

if (!input[dev].num && ((ev->type == EV_KEY && ev->code >= 256 && ev->value >= 1) || (input[dev].quirk == QUIRK_PDSP && ev->type == EV_REL)))
{
for (uint8_t num = 1; num < NUMDEV + 1; num++)
{
map_joystick_show(input[dev].map, input[dev].mmap, input[dev].num);
int found = 0;
for (int i = 0; i < NUMDEV; i++)
{
// paddles/spinners overlay on top of other gamepad
if (!((input[dev].quirk == QUIRK_PDSP) ^ (input[i].quirk == QUIRK_PDSP)))
{
found = (input[i].num == num);
if (found) break;
}
}

if (!found)
{
input[dev].num = num;
if (num < NUMPLAYERS)
{
if(input[dev].quirk == QUIRK_PDSP) memcpy(&player_pdsp[num], &input[dev], sizeof(player_pdsp[0]));
else memcpy(&player_pad[num], &input[dev], sizeof(player_pad[0]));
}
break;
}
}
input[dev].has_map++;

if (cfg.controller_info)
{
if (input[dev].quirk == QUIRK_PDSP)
{
char str[32];
sprintf(str, "P%d paddle/spinner", input[dev].num);
Info(str, cfg.controller_info * 1000);
}
else
{
map_joystick_show(input[dev].map, input[dev].mmap, input[dev].num);
}
}
printf("Device %d assigned to player %d\n", dev, input[dev].num);
}

int old_combo = input[dev].osd_combo;
Expand Down Expand Up @@ -2743,6 +2762,23 @@ int input_test(int getchar)
pool[i].events = 0;
}

// check assigned pads
// remove from list if pad is disappeared
for (int i = 0; i < NUMPLAYERS; i++)
{
if (strlen(player_pad[i].devname))
{
struct stat64 st = {};
if (stat64(player_pad[i].devname, &st) < 0) memset(&player_pad[i], 0, sizeof(player_pad[i]));
}

if (strlen(player_pdsp[i].devname))
{
struct stat64 st = {};
if (stat64(player_pdsp[i].devname, &st) < 0) memset(&player_pdsp[i], 0, sizeof(player_pdsp[i]));
}
}

int n = 0;
DIR *d = opendir("/dev/input");
if (d)
Expand Down Expand Up @@ -2911,6 +2947,22 @@ int input_test(int getchar)
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);

// restore players
devInput *player = (input[i].quirk == QUIRK_PDSP) ? player_pdsp : player_pad;
for (int k = 0; k < NUMPLAYERS; k++)
{
if (strlen(player[k].devname) && !strcmp(player[k].devname, input[i].devname))
{
printf("restore player %d\n", k);

int dev = i;
if (input[i].bind) dev = input[i].bind;
input[dev].num = k;
memcpy(input[dev].jkmap, player[k].jkmap, sizeof(input[dev].jkmap));
input[dev].lightgun = player[k].lightgun;
}
}
}
}
cur_leds |= 0x80;
Expand Down
1 change: 1 addition & 0 deletions input.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ uint16_t get_map_vid();
uint16_t get_map_pid();
int has_default_map();
void send_map_cmd(int key);
void reset_players();

uint32_t get_key_mod();
uint32_t get_ps2_code(uint16_t key);
Expand Down
51 changes: 13 additions & 38 deletions joymapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,8 @@ static int is_fire(char* name)
return 0;
}

void map_joystick(uint32_t *map, uint32_t *mmap, int num)
void map_joystick(uint32_t *map, uint32_t *mmap)
{
static char mapinfo[1024];
/*
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
Expand All @@ -125,8 +124,6 @@ void map_joystick(uint32_t *map, uint32_t *mmap, int num)
A, B, X, Y, L, R, Select, Start
*/
read_buttons();
sprintf(mapinfo, "P%d map:", num);
if (!num) sprintf(mapinfo, "Map:");

map[SYS_BTN_RIGHT] = mmap[SYS_BTN_RIGHT] & 0xFFFF;
map[SYS_BTN_LEFT] = mmap[SYS_BTN_LEFT] & 0xFFFF;
Expand Down Expand Up @@ -159,37 +156,31 @@ void map_joystick(uint32_t *map, uint32_t *mmap, int num)
char *p = strchr(btn_name, '|');
if (p) *p = 0;

int mapped = 1;

if(!strcasecmp(btn_name, "A")
|| !strcasecmp(btn_name, "Jump")
|| is_fire(btn_name) == 1)
{
map[idx] = mmap[SYS_BTN_A];
strcat(mapinfo, "\n[A]");
}

else if(!strcasecmp(btn_name, "B")
|| is_fire(btn_name) == 2)
{
map[idx] = mmap[SYS_BTN_B];
strcat(mapinfo, "\n[B]");
}

else if(!strcasecmp(btn_name, "X")
|| !strcasecmp(btn_name, "C")
|| is_fire(btn_name) == 3)
{
map[idx] = mmap[SYS_BTN_X];
strcat(mapinfo, "\n[X]");
}

else if(!strcasecmp(btn_name, "Y")
|| !strcasecmp(btn_name, "D")
|| is_fire(btn_name) == 4)
{
map[idx] = mmap[SYS_BTN_Y];
strcat(mapinfo, "\n[Y]");
}

// Genesis C and Z and TG16 V and VI
Expand All @@ -198,14 +189,12 @@ void map_joystick(uint32_t *map, uint32_t *mmap, int num)
|| !strcasecmp(btn_name, "Coin"))
{
map[idx] = mmap[SYS_BTN_R];
strcat(mapinfo, "\n[R]");
}

else if(!strcasecmp(btn_name, "L")
|| !strcasecmp(btn_name, "LT"))
{
map[idx] = mmap[SYS_BTN_L];
strcat(mapinfo, "\n[L]");
}

else if(!strcasecmp(btn_name, "Select")
Expand All @@ -214,7 +203,6 @@ void map_joystick(uint32_t *map, uint32_t *mmap, int num)
|| !strcasecmp(btn_name, "Start 2P"))
{
map[idx] = mmap[SYS_BTN_SELECT];
strcat(mapinfo, "\n[\x96]");
}

else if(!strcasecmp(btn_name, "Start")
Expand All @@ -223,24 +211,10 @@ void map_joystick(uint32_t *map, uint32_t *mmap, int num)
|| !strcasecmp(btn_name, "Start 1P"))
{
map[idx] = mmap[SYS_BTN_START];
strcat(mapinfo, "\n[\x16]");
}

else mapped = 0;

if (map[idx] && mapped)
{
strcat(mapinfo, ": ");
strcat(mapinfo, joy_names[i]);
}

n++;
}

if (cfg.controller_info)
{
Info(mapinfo, cfg.controller_info*1000);
}
}

int map_paddle_btn()
Expand All @@ -267,30 +241,31 @@ static const char* get_std_name(uint16_t code, uint32_t *mmap)
if (code == mmap[SYS_BTN_SELECT]) return "[\x96]";
if (code == mmap[SYS_BTN_START ]) return "[\x16]";

return "[ ]";
return code ? "[ ]" : NULL;
}

void map_joystick_show(uint32_t *map, uint32_t *mmap, int num)
{
static char mapinfo[1024];
read_buttons();

sprintf(mapinfo, "P%d, map:", num);
if(!num) sprintf(mapinfo, "Map:");
sprintf(mapinfo, "Map (P%d):", num);
if (!num) sprintf(mapinfo, " Map:");

// loop through core requested buttons and construct result map
for (int i = 0; i < joy_count; i++)
{
if (!strcmp(joy_names[i], "-")) continue;

strcat(mapinfo, "\n");
strcat(mapinfo, get_std_name((uint16_t)(map[i + DPAD_COUNT]), mmap));
strcat(mapinfo, ": ");
strcat(mapinfo, joy_names[i]);
const char *btn = get_std_name((uint16_t)(map[i + DPAD_COUNT]), mmap);
if (btn)
{
strcat(mapinfo, "\n");
strcat(mapinfo, btn);
strcat(mapinfo, ": ");
strcat(mapinfo, joy_names[i]);
}
}

if (cfg.controller_info)
{
Info(mapinfo, cfg.controller_info * 1000);
}
Info(mapinfo, (cfg.controller_info ? cfg.controller_info : 6) * 1000);
}
2 changes: 1 addition & 1 deletion joymapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#include <inttypes.h>

void map_joystick(uint32_t *map, uint32_t *mmap, int num);
void map_joystick(uint32_t *map, uint32_t *mmap);
void map_joystick_show(uint32_t *map, uint32_t *mmap, int num);
int map_paddle_btn();

Expand Down
Loading

0 comments on commit 03d824a

Please sign in to comment.