diff --git a/config.def.h b/config.def.h index ad46235515..1550fd3f47 100644 --- a/config.def.h +++ b/config.def.h @@ -183,5 +183,59 @@ static const struct snes_keybind snes_keybinds_2[] = { { -1 } }; +// Player 3 +static const struct snes_keybind snes_keybinds_3[] = { + // SNES button | keyboard key | js btn | js axis | + { SNES_DEVICE_ID_JOYPAD_A, SDLK_b, 1, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_B, SDLK_v, 0, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_X, SDLK_g, 3, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_Y, SDLK_f, 2, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_L, SDLK_r, 4, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_R, SDLK_t, 5, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_j, 11, AXIS_NEG(0) }, + { SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_l, 12, AXIS_POS(0) }, + { SNES_DEVICE_ID_JOYPAD_UP, SDLK_i, 13, AXIS_NEG(1) }, + { SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_k, 14, AXIS_POS(1) }, + { SNES_DEVICE_ID_JOYPAD_START, SDLK_p, 6, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_o, 7, AXIS_NONE }, + { -1 } +}; + +// Player 4 +static const struct snes_keybind snes_keybinds_4[] = { + // SNES button | keyboard key | js btn | js axis | + { SNES_DEVICE_ID_JOYPAD_A, SDLK_b, 1, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_B, SDLK_v, 0, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_X, SDLK_g, 3, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_Y, SDLK_f, 2, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_L, SDLK_r, 4, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_R, SDLK_t, 5, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_j, 11, AXIS_NEG(0) }, + { SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_l, 12, AXIS_POS(0) }, + { SNES_DEVICE_ID_JOYPAD_UP, SDLK_i, 13, AXIS_NEG(1) }, + { SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_k, 14, AXIS_POS(1) }, + { SNES_DEVICE_ID_JOYPAD_START, SDLK_p, 6, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_o, 7, AXIS_NONE }, + { -1 } +}; + +// Player 5 +static const struct snes_keybind snes_keybinds_5[] = { + // SNES button | keyboard key | js btn | js axis | + { SNES_DEVICE_ID_JOYPAD_A, SDLK_b, 1, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_B, SDLK_v, 0, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_X, SDLK_g, 3, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_Y, SDLK_f, 2, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_L, SDLK_r, 4, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_R, SDLK_t, 5, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_j, 11, AXIS_NEG(0) }, + { SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_l, 12, AXIS_POS(0) }, + { SNES_DEVICE_ID_JOYPAD_UP, SDLK_i, 13, AXIS_NEG(1) }, + { SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_k, 14, AXIS_POS(1) }, + { SNES_DEVICE_ID_JOYPAD_START, SDLK_p, 6, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_o, 7, AXIS_NONE }, + { -1 } +}; + #endif diff --git a/general.h b/general.h index 5bd362a09a..c95fb0f495 100644 --- a/general.h +++ b/general.h @@ -33,8 +33,9 @@ #endif -#define MAX_PLAYERS 2 // Should be 5 when multi-tap stuff is added ... +#define MAX_PLAYERS 5 #define MAX_BINDS 18 // Needs to be increased every time there are new binds added. +#define SSNES_NO_JOYPAD 0xFFFF struct settings { struct @@ -71,7 +72,7 @@ struct settings char driver[32]; struct snes_keybind binds[MAX_PLAYERS][MAX_BINDS]; float axis_threshold; - unsigned joypad_map[2]; + unsigned joypad_map[MAX_PLAYERS]; } input; char libsnes[256]; @@ -86,6 +87,9 @@ struct global bool has_mouse[2]; bool has_scope[2]; + bool has_justifier; + bool has_justifiers; + bool has_multitap; FILE *rom_file; char config_path[256]; diff --git a/input/sdl.c b/input/sdl.c index d4d67b78cd..5899fc46dd 100644 --- a/input/sdl.c +++ b/input/sdl.c @@ -37,8 +37,11 @@ static void* sdl_input_init(void) SDL_JoystickEventState(SDL_IGNORE); sdl->num_joysticks = SDL_NumJoysticks(); - for (unsigned i = 0; i < 2; i++) + for (unsigned i = 0; i < MAX_PLAYERS; i++) { + if (g_settings.input.joypad_map[i] == SSNES_NO_JOYPAD) + continue; + if (sdl->num_joysticks > g_settings.input.joypad_map[i]) { sdl->joysticks[i] = SDL_JoystickOpen(g_settings.input.joypad_map[i]); @@ -168,12 +171,10 @@ static bool sdl_bind_button_pressed(void *data, int key) } static int16_t sdl_joypad_device_state(sdl_input_t *sdl, const struct snes_keybind **binds, - bool port, unsigned device, unsigned index, unsigned id) + int port_num, unsigned device, unsigned index, unsigned id) { - const struct snes_keybind *snes_keybinds = binds[port == SNES_PORT_1 ? 0 : 1]; + const struct snes_keybind *snes_keybinds = binds[port_num]; - // Checks if button is pressed. - int port_num = port == SNES_PORT_1 ? 0 : 1; for (int i = 0; snes_keybinds[i].id != -1; i++) { if (snes_keybinds[i].id == (int)id) @@ -222,16 +223,44 @@ static int16_t sdl_scope_device_state(sdl_input_t *sdl, unsigned id) } } +// TODO: Support two players. +static int16_t sdl_justifier_device_state(sdl_input_t *sdl, unsigned index, unsigned id) +{ + if (index == 0) + { + switch (id) + { + case SNES_DEVICE_ID_JUSTIFIER_X: + return sdl->mouse_x; + case SNES_DEVICE_ID_JUSTIFIER_Y: + return sdl->mouse_y; + case SNES_DEVICE_ID_JUSTIFIER_TRIGGER: + return sdl->mouse_l; + case SNES_DEVICE_ID_JUSTIFIER_START: + return sdl->mouse_r; + default: + return 0; + } + } + else + return 0; +} + static int16_t sdl_input_state(void *data, const struct snes_keybind **binds, bool port, unsigned device, unsigned index, unsigned id) { switch (device) { case SNES_DEVICE_JOYPAD: - return sdl_joypad_device_state(data, binds, port, device, index, id); + return sdl_joypad_device_state(data, binds, port == SNES_PORT_1 ? 0 : 1, device, index, id); + case SNES_DEVICE_MULTITAP: + return sdl_joypad_device_state(data, binds, (port == SNES_PORT_2) ? 1 + index : 0, device, index, id); case SNES_DEVICE_MOUSE: return sdl_mouse_device_state(data, port, id); case SNES_DEVICE_SUPER_SCOPE: return sdl_scope_device_state(data, id); + case SNES_DEVICE_JUSTIFIER: + case SNES_DEVICE_JUSTIFIERS: + return sdl_justifier_device_state(data, index, id); default: return 0; @@ -247,7 +276,7 @@ static void sdl_input_free(void *data) while (SDL_PollEvent(&event)); sdl_input_t *sdl = data; - for (int i = 0; i < 2; i++) + for (int i = 0; i < MAX_PLAYERS; i++) { if (sdl->joysticks[i]) SDL_JoystickClose(sdl->joysticks[i]); diff --git a/input/ssnes_sdl_input.h b/input/ssnes_sdl_input.h index c87d6e3ca5..7e92749ceb 100644 --- a/input/ssnes_sdl_input.h +++ b/input/ssnes_sdl_input.h @@ -19,12 +19,13 @@ #define __SSNES_SDL_INPUT_H #include "SDL.h" +#include "general.h" typedef struct sdl_input { - SDL_Joystick *joysticks[2]; - unsigned num_axes[2]; - unsigned num_buttons[2]; - unsigned num_hats[2]; + SDL_Joystick *joysticks[MAX_PLAYERS]; + unsigned num_axes[MAX_PLAYERS]; + unsigned num_buttons[MAX_PLAYERS]; + unsigned num_hats[MAX_PLAYERS]; unsigned num_joysticks; // A video driver could pre-init with the SDL driver and have it handle resizing events... diff --git a/settings.c b/settings.c index baa8b9c6e3..e9a36e88be 100644 --- a/settings.c +++ b/settings.c @@ -108,12 +108,20 @@ static void set_defaults(void) assert(sizeof(g_settings.input.binds[0]) >= sizeof(snes_keybinds_1)); assert(sizeof(g_settings.input.binds[1]) >= sizeof(snes_keybinds_2)); + assert(sizeof(g_settings.input.binds[2]) >= sizeof(snes_keybinds_3)); + assert(sizeof(g_settings.input.binds[3]) >= sizeof(snes_keybinds_4)); + assert(sizeof(g_settings.input.binds[4]) >= sizeof(snes_keybinds_5)); memcpy(g_settings.input.binds[0], snes_keybinds_1, sizeof(snes_keybinds_1)); memcpy(g_settings.input.binds[1], snes_keybinds_2, sizeof(snes_keybinds_2)); + memcpy(g_settings.input.binds[2], snes_keybinds_3, sizeof(snes_keybinds_3)); + memcpy(g_settings.input.binds[3], snes_keybinds_4, sizeof(snes_keybinds_4)); + memcpy(g_settings.input.binds[4], snes_keybinds_5, sizeof(snes_keybinds_5)); g_settings.input.axis_threshold = AXIS_THRESHOLD; - g_settings.input.joypad_map[0] = 0; - g_settings.input.joypad_map[1] = 1; + for (int i = 0; i < 2; i++) + g_settings.input.joypad_map[i] = i; + for (int i = 2; i < MAX_PLAYERS; i++) + g_settings.input.joypad_map[i] = SSNES_NO_JOYPAD; } void parse_config(void) @@ -247,12 +255,22 @@ void parse_config(void) if (config_get_double(conf, "input_axis_threshold", &tmp_double)) g_settings.input.axis_threshold = tmp_double; + // Joypad mapping. if (config_get_int(conf, "input_player1_joypad_index", &tmp_int)) g_settings.input.joypad_map[0] = tmp_int; if (config_get_int(conf, "input_player2_joypad_index", &tmp_int)) g_settings.input.joypad_map[1] = tmp_int; + if (config_get_int(conf, "input_player3_joypad_index", &tmp_int)) + g_settings.input.joypad_map[2] = tmp_int; + + if (config_get_int(conf, "input_player4_joypad_index", &tmp_int)) + g_settings.input.joypad_map[3] = tmp_int; + + if (config_get_int(conf, "input_player5_joypad_index", &tmp_int)) + g_settings.input.joypad_map[4] = tmp_int; + // Audio settings. if (config_get_bool(conf, "audio_enable", &tmp_bool)) g_settings.audio.enable = tmp_bool; @@ -321,7 +339,7 @@ struct bind_map #define DECLARE_BIND(x, bind) { "input_" #x, "input_" #x "_btn", "input_" #x "_axis", bind }, // Big and nasty bind map... :) -static const struct bind_map bind_maps[2][MAX_BINDS - 1] = { +static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { { DECLARE_BIND(player1_a, SNES_DEVICE_ID_JOYPAD_A) DECLARE_BIND(player1_b, SNES_DEVICE_ID_JOYPAD_B) @@ -359,7 +377,64 @@ static const struct bind_map bind_maps[2][MAX_BINDS - 1] = { DECLARE_BIND(load_state, SSNES_LOAD_STATE_KEY) DECLARE_BIND(exit_emulator, SSNES_QUIT_KEY) DECLARE_BIND(toggle_fullscreen, SSNES_FULLSCREEN_TOGGLE_KEY) - } + }, + { + DECLARE_BIND(player3_a, SNES_DEVICE_ID_JOYPAD_A) + DECLARE_BIND(player3_b, SNES_DEVICE_ID_JOYPAD_B) + DECLARE_BIND(player3_y, SNES_DEVICE_ID_JOYPAD_Y) + DECLARE_BIND(player3_x, SNES_DEVICE_ID_JOYPAD_X) + DECLARE_BIND(player3_start, SNES_DEVICE_ID_JOYPAD_START) + DECLARE_BIND(player3_select, SNES_DEVICE_ID_JOYPAD_SELECT) + DECLARE_BIND(player3_l, SNES_DEVICE_ID_JOYPAD_L) + DECLARE_BIND(player3_r, SNES_DEVICE_ID_JOYPAD_R) + DECLARE_BIND(player3_left, SNES_DEVICE_ID_JOYPAD_LEFT) + DECLARE_BIND(player3_right, SNES_DEVICE_ID_JOYPAD_RIGHT) + DECLARE_BIND(player3_up, SNES_DEVICE_ID_JOYPAD_UP) + DECLARE_BIND(player3_down, SNES_DEVICE_ID_JOYPAD_DOWN) + DECLARE_BIND(toggle_fast_forward, SSNES_FAST_FORWARD_KEY) + DECLARE_BIND(save_state, SSNES_SAVE_STATE_KEY) + DECLARE_BIND(load_state, SSNES_LOAD_STATE_KEY) + DECLARE_BIND(exit_emulator, SSNES_QUIT_KEY) + DECLARE_BIND(toggle_fullscreen, SSNES_FULLSCREEN_TOGGLE_KEY) + }, + { + DECLARE_BIND(player4_a, SNES_DEVICE_ID_JOYPAD_A) + DECLARE_BIND(player4_b, SNES_DEVICE_ID_JOYPAD_B) + DECLARE_BIND(player4_y, SNES_DEVICE_ID_JOYPAD_Y) + DECLARE_BIND(player4_x, SNES_DEVICE_ID_JOYPAD_X) + DECLARE_BIND(player4_start, SNES_DEVICE_ID_JOYPAD_START) + DECLARE_BIND(player4_select, SNES_DEVICE_ID_JOYPAD_SELECT) + DECLARE_BIND(player4_l, SNES_DEVICE_ID_JOYPAD_L) + DECLARE_BIND(player4_r, SNES_DEVICE_ID_JOYPAD_R) + DECLARE_BIND(player4_left, SNES_DEVICE_ID_JOYPAD_LEFT) + DECLARE_BIND(player4_right, SNES_DEVICE_ID_JOYPAD_RIGHT) + DECLARE_BIND(player4_up, SNES_DEVICE_ID_JOYPAD_UP) + DECLARE_BIND(player4_down, SNES_DEVICE_ID_JOYPAD_DOWN) + DECLARE_BIND(toggle_fast_forward, SSNES_FAST_FORWARD_KEY) + DECLARE_BIND(save_state, SSNES_SAVE_STATE_KEY) + DECLARE_BIND(load_state, SSNES_LOAD_STATE_KEY) + DECLARE_BIND(exit_emulator, SSNES_QUIT_KEY) + DECLARE_BIND(toggle_fullscreen, SSNES_FULLSCREEN_TOGGLE_KEY) + }, + { + DECLARE_BIND(player5_a, SNES_DEVICE_ID_JOYPAD_A) + DECLARE_BIND(player5_b, SNES_DEVICE_ID_JOYPAD_B) + DECLARE_BIND(player5_y, SNES_DEVICE_ID_JOYPAD_Y) + DECLARE_BIND(player5_x, SNES_DEVICE_ID_JOYPAD_X) + DECLARE_BIND(player5_start, SNES_DEVICE_ID_JOYPAD_START) + DECLARE_BIND(player5_select, SNES_DEVICE_ID_JOYPAD_SELECT) + DECLARE_BIND(player5_l, SNES_DEVICE_ID_JOYPAD_L) + DECLARE_BIND(player5_r, SNES_DEVICE_ID_JOYPAD_R) + DECLARE_BIND(player5_left, SNES_DEVICE_ID_JOYPAD_LEFT) + DECLARE_BIND(player5_right, SNES_DEVICE_ID_JOYPAD_RIGHT) + DECLARE_BIND(player5_up, SNES_DEVICE_ID_JOYPAD_UP) + DECLARE_BIND(player5_down, SNES_DEVICE_ID_JOYPAD_DOWN) + DECLARE_BIND(toggle_fast_forward, SSNES_FAST_FORWARD_KEY) + DECLARE_BIND(save_state, SSNES_SAVE_STATE_KEY) + DECLARE_BIND(load_state, SSNES_LOAD_STATE_KEY) + DECLARE_BIND(exit_emulator, SSNES_QUIT_KEY) + DECLARE_BIND(toggle_fullscreen, SSNES_FULLSCREEN_TOGGLE_KEY) + }, }; struct key_map @@ -436,9 +511,9 @@ static void read_keybinds(config_file_t *conf) char *tmp_btn = NULL; char *tmp_axis = NULL; - for (int j = 0; j < 1; j++) + for (int j = 0; j < MAX_PLAYERS; j++) { - for (int i = 0; i < sizeof(bind_maps[j])/sizeof(struct bind_map); i++) + for (int i = 0; i < sizeof(bind_maps[0])/sizeof(struct bind_map); i++) { struct snes_keybind *bind = find_snes_bind(j, bind_maps[j][i].snes_key); if (!bind) diff --git a/ssnes.c b/ssnes.c index cb322e68d2..17c4ceb42b 100644 --- a/ssnes.c +++ b/ssnes.c @@ -201,7 +201,10 @@ static void input_poll(void) static int16_t input_state(bool port, unsigned device, unsigned index, unsigned id) { - const struct snes_keybind *binds[] = { g_settings.input.binds[0], g_settings.input.binds[1] }; + const struct snes_keybind *binds[MAX_PLAYERS]; + for (int i = 0; i < MAX_PLAYERS; i++) + binds[i] = g_settings.input.binds[i]; + return driver.input->input_state(driver.input_data, binds, port, device, index, id); } @@ -242,6 +245,9 @@ static void print_help(void) puts("\t-m/--mouse: Connect a virtual mouse into designated port of the SNES (1 or 2)."); puts("\tThis argument can be specified several times to connect more mice."); puts("\t-p/--scope: Connect a virtual SuperScope into port 2 of the SNES."); + puts("\t-j/--justifier: Connect a virtual Konami Justifier into port 2 of the SNES."); + puts("\t-k/--justifiers: Daisy chain two virtual Konami Justifiers into port 2 of the SNES."); + puts("\t-4/--multitap: Connect a multitap to port 2 of the SNES."); #ifdef HAVE_FFMPEG puts("\t-r/--record: Path to record video file. Settings for video/audio codecs are found in config file."); @@ -268,6 +274,9 @@ static void parse_input(int argc, char *argv[]) { "mouse", 1, NULL, 'm' }, { "scope", 0, NULL, 'p' }, { "savestate", 1, NULL, 't' }, + { "justifier", 0, NULL, 'j' }, + { "justifiers", 0, NULL, 'k' }, + { "multitap", 0, NULL, '4' }, { NULL, 0, NULL, 0 } }; @@ -279,7 +288,7 @@ static void parse_input(int argc, char *argv[]) #define FFMPEG_RECORD_ARG #endif - char optstring[] = "hs:vc:t:m:p" FFMPEG_RECORD_ARG; + char optstring[] = "hs:vc:t:m:p4jk" FFMPEG_RECORD_ARG; for(;;) { int c = getopt_long(argc, argv, optstring, opts, &option_index); @@ -294,6 +303,18 @@ static void parse_input(int argc, char *argv[]) print_help(); exit(0); + case '4': + g_extern.has_multitap = true; + break; + + case 'j': + g_extern.has_justifier = true; + break; + + case 'k': + g_extern.has_justifiers = true; + break; + case 's': strncpy(g_extern.savefile_name_srm, optarg, sizeof(g_extern.savefile_name_srm) - 1); break; @@ -389,17 +410,35 @@ static void parse_input(int argc, char *argv[]) // TODO: Add rest of the controllers. static void init_controllers(void) { - for (int i = 0; i < 2; i++) + if (g_extern.has_justifier) { - if (g_extern.has_mouse[i]) + SSNES_LOG("Connecting Justifier to port 2.\n"); + psnes_set_controller_port_device(SNES_PORT_2, SNES_DEVICE_JUSTIFIER); + } + else if (g_extern.has_justifiers) + { + SSNES_LOG("Connecting Justifiers to port 2.\n"); + psnes_set_controller_port_device(SNES_PORT_2, SNES_DEVICE_JUSTIFIERS); + } + else if (g_extern.has_multitap) + { + SSNES_LOG("Connecting multitap to port 2.\n"); + psnes_set_controller_port_device(SNES_PORT_2, SNES_DEVICE_MULTITAP); + } + else + { + for (int i = 0; i < 2; i++) { - SSNES_LOG("Connecting mouse to port %d\n", i + 1); - psnes_set_controller_port_device(i, SNES_DEVICE_MOUSE); - } - else if (g_extern.has_scope[i]) - { - SSNES_LOG("Connecting scope to port %d\n", i + 1); - psnes_set_controller_port_device(i, SNES_DEVICE_SUPER_SCOPE); + if (g_extern.has_mouse[i]) + { + SSNES_LOG("Connecting mouse to port %d\n", i + 1); + psnes_set_controller_port_device(i, SNES_DEVICE_MOUSE); + } + else if (g_extern.has_scope[i]) + { + SSNES_LOG("Connecting scope to port %d\n", i + 1); + psnes_set_controller_port_device(i, SNES_DEVICE_SUPER_SCOPE); + } } } } diff --git a/tools/ssnes-joyconfig.c b/tools/ssnes-joyconfig.c index 613e8991e0..b5c0ee8c23 100644 --- a/tools/ssnes-joyconfig.c +++ b/tools/ssnes-joyconfig.c @@ -27,6 +27,7 @@ #include #include #include +#include "general.h" static int g_player = 1; @@ -52,11 +53,11 @@ static void print_help(void) struct bind { char *keystr; - char *confbtn[2]; - char *confaxis[2]; + char *confbtn[MAX_PLAYERS]; + char *confaxis[MAX_PLAYERS]; }; -#define BIND(x, k) { x, { "input_player1_" #k "_btn", "input_player2_" #k "_btn" }, {"input_player1_" #k "_axis", "input_player2_" #k "_axis"}}, +#define BIND(x, k) { x, { "input_player1_" #k "_btn", "input_player2_" #k "_btn", "input_player3_" #k "_btn", "input_player4_" #k "_btn", "input_player5_" #k "_btn" }, {"input_player1_" #k "_axis", "input_player2_" #k "_axis", "input_player3_" #k "_axis", "input_player4_" #k "_axis", "input_player5_" #k "_axis"}}, static struct bind binds[] = { BIND("A button (right)", a) BIND("B button (down)", b) @@ -226,9 +227,9 @@ static void parse_input(int argc, char *argv[]) fprintf(stderr, "Player number must be at least 1!\n"); exit(1); } - else if (g_player > 2) + else if (g_player > MAX_PLAYERS) { - fprintf(stderr, "Player number must be 1 or 2.\n"); + fprintf(stderr, "Player number must be from 1 to %d.\n", MAX_PLAYERS); exit(1); } break; @@ -262,8 +263,15 @@ int main(int argc, char *argv[]) return 1; } - config_set_int(conf, g_player == 1 ? "input_player1_joypad_index" : "input_player2_joypad_index", - g_joypad - 1); + const char *index_list[] = { + "input_player1_joypad_index", + "input_player2_joypad_index", + "input_player3_joypad_index", + "input_player4_joypad_index", + "input_player5_joypad_index" + }; + + config_set_int(conf, index_list[g_player - 1], g_joypad - 1); get_binds(conf, g_player - 1, g_joypad - 1); config_file_write(conf, g_out_path);