diff --git a/config.def.h b/config.def.h index 875b891789..16ddb097d6 100644 --- a/config.def.h +++ b/config.def.h @@ -272,61 +272,60 @@ static const float axis_threshold = 0.5; // Player 1 static const struct snes_keybind snes_keybinds_1[] = { - // SNES button | keyboard key | js btn | js axis | - { SNES_DEVICE_ID_JOYPAD_A, SK_x, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_B, SK_z, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_X, SK_s, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_Y, SK_a, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_L, SK_q, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_R, SK_w, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_LEFT, SK_LEFT, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_RIGHT, SK_RIGHT, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_UP, SK_UP, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_DOWN, SK_DOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_START, SK_RETURN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_SELECT, SK_RSHIFT, NO_BTN, AXIS_NONE }, - { SSNES_FAST_FORWARD_KEY, SK_SPACE, NO_BTN, AXIS_NONE }, - { SSNES_FAST_FORWARD_HOLD_KEY, SK_l, NO_BTN, AXIS_NONE }, - { SSNES_SAVE_STATE_KEY, SK_F2, NO_BTN, AXIS_NONE }, - { SSNES_LOAD_STATE_KEY, SK_F4, NO_BTN, AXIS_NONE }, - { SSNES_FULLSCREEN_TOGGLE_KEY, SK_f, NO_BTN, AXIS_NONE }, - { SSNES_QUIT_KEY, SK_ESCAPE, NO_BTN, AXIS_NONE }, - { SSNES_STATE_SLOT_MINUS, SK_F6, NO_BTN, AXIS_NONE }, - { SSNES_STATE_SLOT_PLUS, SK_F7, NO_BTN, AXIS_NONE }, - { SSNES_AUDIO_INPUT_RATE_PLUS, SK_KP_PLUS, NO_BTN, AXIS_NONE }, - { SSNES_AUDIO_INPUT_RATE_MINUS, SK_KP_MINUS, NO_BTN, AXIS_NONE }, - { SSNES_REWIND, SK_r, NO_BTN, AXIS_NONE }, - { SSNES_MOVIE_RECORD_TOGGLE, SK_o, NO_BTN, AXIS_NONE }, - { SSNES_PAUSE_TOGGLE, SK_p, NO_BTN, AXIS_NONE }, - { SSNES_FRAMEADVANCE, SK_k, NO_BTN, AXIS_NONE }, - { SSNES_RESET, SK_h, NO_BTN, AXIS_NONE }, - { SSNES_SHADER_NEXT, SK_m, NO_BTN, AXIS_NONE }, - { SSNES_SHADER_PREV, SK_n, NO_BTN, AXIS_NONE }, - { SSNES_CHEAT_INDEX_PLUS, SK_y, NO_BTN, AXIS_NONE }, - { SSNES_CHEAT_INDEX_MINUS, SK_t, NO_BTN, AXIS_NONE }, - { SSNES_CHEAT_TOGGLE, SK_u, NO_BTN, AXIS_NONE }, - { SSNES_SCREENSHOT, SK_PRINT, NO_BTN, AXIS_NONE }, - { SSNES_DSP_CONFIG, SK_c, NO_BTN, AXIS_NONE }, - { SSNES_MUTE, SK_F9, NO_BTN, AXIS_NONE }, - { SSNES_NETPLAY_FLIP, SK_i, NO_BTN, AXIS_NONE }, - { -1 } + // SNES button | keyboard key | js btn | js axis | + { true, SNES_DEVICE_ID_JOYPAD_B, SK_z, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_Y, SK_a, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_SELECT, SK_RSHIFT, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_START, SK_RETURN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_UP, SK_UP, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_DOWN, SK_DOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_LEFT, SK_LEFT, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_RIGHT, SK_RIGHT, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_A, SK_x, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_X, SK_s, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_L, SK_q, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_R, SK_w, NO_BTN, AXIS_NONE }, + + { true, SSNES_FAST_FORWARD_KEY, SK_SPACE, NO_BTN, AXIS_NONE }, + { true, SSNES_FAST_FORWARD_HOLD_KEY, SK_l, NO_BTN, AXIS_NONE }, + { true, SSNES_LOAD_STATE_KEY, SK_F4, NO_BTN, AXIS_NONE }, + { true, SSNES_SAVE_STATE_KEY, SK_F2, NO_BTN, AXIS_NONE }, + { true, SSNES_FULLSCREEN_TOGGLE_KEY, SK_f, NO_BTN, AXIS_NONE }, + { true, SSNES_QUIT_KEY, SK_ESCAPE, NO_BTN, AXIS_NONE }, + { true, SSNES_STATE_SLOT_PLUS, SK_F7, NO_BTN, AXIS_NONE }, + { true, SSNES_STATE_SLOT_MINUS, SK_F6, NO_BTN, AXIS_NONE }, + { true, SSNES_AUDIO_INPUT_RATE_PLUS, SK_KP_PLUS, NO_BTN, AXIS_NONE }, + { true, SSNES_AUDIO_INPUT_RATE_MINUS, SK_KP_MINUS, NO_BTN, AXIS_NONE }, + { true, SSNES_REWIND, SK_r, NO_BTN, AXIS_NONE }, + { true, SSNES_MOVIE_RECORD_TOGGLE, SK_o, NO_BTN, AXIS_NONE }, + { true, SSNES_PAUSE_TOGGLE, SK_p, NO_BTN, AXIS_NONE }, + { true, SSNES_FRAMEADVANCE, SK_k, NO_BTN, AXIS_NONE }, + { true, SSNES_RESET, SK_h, NO_BTN, AXIS_NONE }, + { true, SSNES_SHADER_NEXT, SK_m, NO_BTN, AXIS_NONE }, + { true, SSNES_SHADER_PREV, SK_n, NO_BTN, AXIS_NONE }, + { true, SSNES_CHEAT_INDEX_PLUS, SK_y, NO_BTN, AXIS_NONE }, + { true, SSNES_CHEAT_INDEX_MINUS, SK_t, NO_BTN, AXIS_NONE }, + { true, SSNES_CHEAT_TOGGLE, SK_u, NO_BTN, AXIS_NONE }, + { true, SSNES_SCREENSHOT, SK_PRINT, NO_BTN, AXIS_NONE }, + { true, SSNES_DSP_CONFIG, SK_c, NO_BTN, AXIS_NONE }, + { true, SSNES_MUTE, SK_F9, NO_BTN, AXIS_NONE }, + { true, SSNES_NETPLAY_FLIP, SK_i, NO_BTN, AXIS_NONE }, }; // Player 2-5 static const struct snes_keybind snes_keybinds_rest[] = { - { SNES_DEVICE_ID_JOYPAD_A, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_B, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_X, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_Y, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_L, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_R, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_LEFT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_RIGHT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_UP, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_DOWN, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_START, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_SELECT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, - { -1 } + { true, SNES_DEVICE_ID_JOYPAD_B, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_Y, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_SELECT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_START, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_UP, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_DOWN, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_LEFT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_RIGHT, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_A, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_X, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_L, SK_UNKNOWN, NO_BTN, AXIS_NONE }, + { true, SNES_DEVICE_ID_JOYPAD_R, SK_UNKNOWN, NO_BTN, AXIS_NONE }, }; #endif diff --git a/driver.h b/driver.h index fe21c3bdd0..50bf6779e0 100644 --- a/driver.h +++ b/driver.h @@ -69,6 +69,7 @@ enum struct snes_keybind { + bool valid; int id; enum ssnes_key key; uint16_t joykey; diff --git a/general.h b/general.h index 61d24d8c29..046fbe4bc8 100644 --- a/general.h +++ b/general.h @@ -68,8 +68,6 @@ #endif #define MAX_PLAYERS 5 -#define MAX_BINDS (SSNES_BIND_LIST_END + 1) -#define SSNES_NO_JOYPAD 0xFFFF enum ssnes_shader_type { @@ -145,9 +143,9 @@ struct settings struct { char driver[32]; - struct snes_keybind binds[MAX_PLAYERS][MAX_BINDS]; + struct snes_keybind binds[MAX_PLAYERS][SSNES_BIND_LIST_END]; float axis_threshold; - unsigned joypad_map[MAX_PLAYERS]; + int joypad_map[MAX_PLAYERS]; bool netplay_client_swap_input; } input; diff --git a/gfx/ext_gfx.c b/gfx/ext_gfx.c index d6fcb4640b..dab26c5395 100644 --- a/gfx/ext_gfx.c +++ b/gfx/ext_gfx.c @@ -205,7 +205,7 @@ static void *setup_input(ext_t *ext, const ssnes_input_driver_t *driver) { int joypad_index[5]; for (unsigned i = 0; i < 5; i++) - joypad_index[i] = g_settings.input.joypad_map[i] == SSNES_NO_JOYPAD ? -1 : g_settings.input.joypad_map[i]; + joypad_index[i] = g_settings.input.joypad_map[i] < 0 ? -1 : g_settings.input.joypad_map[i]; void *handle = driver->init(joypad_index, g_settings.input.axis_threshold); if (!handle) diff --git a/input/sdl_input.c b/input/sdl_input.c index 49a6a18d75..c043a44535 100644 --- a/input/sdl_input.c +++ b/input/sdl_input.c @@ -147,7 +147,7 @@ static void *sdl_input_init(void) for (unsigned i = 0; i < MAX_PLAYERS; i++) { - if (g_settings.input.joypad_map[i] == SSNES_NO_JOYPAD) + if (g_settings.input.joypad_map[i] < 0) continue; if (sdl->num_joysticks > g_settings.input.joypad_map[i]) diff --git a/settings.c b/settings.c index d9542b77fc..756072acb2 100644 --- a/settings.c +++ b/settings.c @@ -487,54 +487,54 @@ bool config_load_file(const char *path) struct bind_map { + bool valid; const char *key; const char *btn; const char *axis; int snes_key; }; -#define DECLARE_BIND(x, bind) { "input_" #x, "input_" #x "_btn", "input_" #x "_axis", bind } -#define DECLARE_BIND_END() { NULL, NULL, NULL, SSNES_BIND_LIST_END } +#define DECLARE_BIND(x, bind) { true, "input_" #x, "input_" #x "_btn", "input_" #x "_axis", bind } #define DECL_PLAYER(P) \ { \ - DECLARE_BIND(player##P##_a, SNES_DEVICE_ID_JOYPAD_A), \ DECLARE_BIND(player##P##_b, SNES_DEVICE_ID_JOYPAD_B), \ DECLARE_BIND(player##P##_y, SNES_DEVICE_ID_JOYPAD_Y), \ - DECLARE_BIND(player##P##_x, SNES_DEVICE_ID_JOYPAD_X), \ - DECLARE_BIND(player##P##_start, SNES_DEVICE_ID_JOYPAD_START), \ DECLARE_BIND(player##P##_select, SNES_DEVICE_ID_JOYPAD_SELECT), \ - DECLARE_BIND(player##P##_l, SNES_DEVICE_ID_JOYPAD_L), \ - DECLARE_BIND(player##P##_r, SNES_DEVICE_ID_JOYPAD_R), \ - DECLARE_BIND(player##P##_left, SNES_DEVICE_ID_JOYPAD_LEFT), \ - DECLARE_BIND(player##P##_right, SNES_DEVICE_ID_JOYPAD_RIGHT), \ + DECLARE_BIND(player##P##_start, SNES_DEVICE_ID_JOYPAD_START), \ DECLARE_BIND(player##P##_up, SNES_DEVICE_ID_JOYPAD_UP), \ DECLARE_BIND(player##P##_down, SNES_DEVICE_ID_JOYPAD_DOWN), \ - DECLARE_BIND_END(), \ + DECLARE_BIND(player##P##_left, SNES_DEVICE_ID_JOYPAD_LEFT), \ + DECLARE_BIND(player##P##_right, SNES_DEVICE_ID_JOYPAD_RIGHT), \ + DECLARE_BIND(player##P##_a, SNES_DEVICE_ID_JOYPAD_A), \ + DECLARE_BIND(player##P##_x, SNES_DEVICE_ID_JOYPAD_X), \ + DECLARE_BIND(player##P##_l, SNES_DEVICE_ID_JOYPAD_L), \ + DECLARE_BIND(player##P##_r, SNES_DEVICE_ID_JOYPAD_R), \ } // Big and nasty bind map... :) -static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS] = { +static const struct bind_map bind_maps[MAX_PLAYERS][SSNES_BIND_LIST_END] = { { - DECLARE_BIND(player1_a, SNES_DEVICE_ID_JOYPAD_A), DECLARE_BIND(player1_b, SNES_DEVICE_ID_JOYPAD_B), DECLARE_BIND(player1_y, SNES_DEVICE_ID_JOYPAD_Y), - DECLARE_BIND(player1_x, SNES_DEVICE_ID_JOYPAD_X), - DECLARE_BIND(player1_start, SNES_DEVICE_ID_JOYPAD_START), DECLARE_BIND(player1_select, SNES_DEVICE_ID_JOYPAD_SELECT), - DECLARE_BIND(player1_l, SNES_DEVICE_ID_JOYPAD_L), - DECLARE_BIND(player1_r, SNES_DEVICE_ID_JOYPAD_R), - DECLARE_BIND(player1_left, SNES_DEVICE_ID_JOYPAD_LEFT), - DECLARE_BIND(player1_right, SNES_DEVICE_ID_JOYPAD_RIGHT), + DECLARE_BIND(player1_start, SNES_DEVICE_ID_JOYPAD_START), DECLARE_BIND(player1_up, SNES_DEVICE_ID_JOYPAD_UP), DECLARE_BIND(player1_down, SNES_DEVICE_ID_JOYPAD_DOWN), + DECLARE_BIND(player1_left, SNES_DEVICE_ID_JOYPAD_LEFT), + DECLARE_BIND(player1_right, SNES_DEVICE_ID_JOYPAD_RIGHT), + DECLARE_BIND(player1_a, SNES_DEVICE_ID_JOYPAD_A), + DECLARE_BIND(player1_x, SNES_DEVICE_ID_JOYPAD_X), + DECLARE_BIND(player1_l, SNES_DEVICE_ID_JOYPAD_L), + DECLARE_BIND(player1_r, SNES_DEVICE_ID_JOYPAD_R), + DECLARE_BIND(toggle_fast_forward, SSNES_FAST_FORWARD_KEY), DECLARE_BIND(hold_fast_forward, SSNES_FAST_FORWARD_HOLD_KEY), - DECLARE_BIND(save_state, SSNES_SAVE_STATE_KEY), DECLARE_BIND(load_state, SSNES_LOAD_STATE_KEY), + DECLARE_BIND(save_state, SSNES_SAVE_STATE_KEY), + DECLARE_BIND(toggle_fullscreen, SSNES_FULLSCREEN_TOGGLE_KEY), + DECLARE_BIND(exit_emulator, SSNES_QUIT_KEY), DECLARE_BIND(state_slot_increase, SSNES_STATE_SLOT_PLUS), DECLARE_BIND(state_slot_decrease, SSNES_STATE_SLOT_MINUS), - DECLARE_BIND(exit_emulator, SSNES_QUIT_KEY), - DECLARE_BIND(toggle_fullscreen, SSNES_FULLSCREEN_TOGGLE_KEY), DECLARE_BIND(rate_step_up, SSNES_AUDIO_INPUT_RATE_PLUS), DECLARE_BIND(rate_step_down, SSNES_AUDIO_INPUT_RATE_MINUS), DECLARE_BIND(rewind, SSNES_REWIND), @@ -551,7 +551,6 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS] = { DECLARE_BIND(dsp_config, SSNES_DSP_CONFIG), DECLARE_BIND(audio_mute, SSNES_MUTE), DECLARE_BIND(netplay_flip_players, SSNES_NETPLAY_FLIP), - DECLARE_BIND_END(), }, DECL_PLAYER(2), @@ -641,13 +640,7 @@ static const struct key_map sk_map[] = { static struct snes_keybind *find_snes_bind(unsigned port, int id) { struct snes_keybind *binds = g_settings.input.binds[port]; - - for (int i = 0; binds[i].id != -1; i++) - { - if (id == binds[i].id) - return &binds[i]; - } - return NULL; + return binds[id].valid ? &binds[id] : NULL; } static int find_sk_bind(const char *str) @@ -657,105 +650,114 @@ static int find_sk_bind(const char *str) if (strcasecmp(sk_map[i].str, str) == 0) return sk_map[i].key; } + return -1; } static int find_sk_key(const char *str) { - // If the bind is a normal key-press ... if (strlen(str) == 1 && isalpha(*str)) return (int)SK_a + (tolower(*str) - (int)'a'); - else // Check if we have a special mapping for it. + else return find_sk_bind(str); } -// Yes, this function needs a good refactor :) -static void read_keybinds(config_file_t *conf) +static void read_keybinds_keyboard(config_file_t *conf, unsigned player, unsigned index, struct snes_keybind *bind) { - char *tmp_key = NULL; - char *tmp_btn = NULL; - char *tmp_axis = NULL; + char tmp[64]; - for (int j = 0; j < MAX_PLAYERS; j++) + if (bind_maps[player][index].key && + config_get_array(conf, bind_maps[player][index].key, tmp, sizeof(tmp))) { - for (int i = 0; bind_maps[j][i].snes_key != SSNES_BIND_LIST_END; i++) + int key = find_sk_key(tmp); + + if (key >= 0) + bind->key = (enum ssnes_key)key; + } +} + +static void parse_hat(struct snes_keybind *bind, const char *str) +{ + if (isdigit(*str)) + { + char *dir = NULL; + int hat = strtol(str, &dir, 0); + int hat_dir = 0; + + if (dir) { - struct snes_keybind *bind = find_snes_bind(j, bind_maps[j][i].snes_key); - if (!bind) - continue; + if (strcasecmp(str, "up") == 0) + hat_dir = HAT_UP_MASK; + else if (strcasecmp(str, "down") == 0) + hat_dir = HAT_DOWN_MASK; + else if (strcasecmp(str, "left") == 0) + hat_dir = HAT_LEFT_MASK; + else if (strcasecmp(str, "right") == 0) + hat_dir = HAT_RIGHT_MASK; - // Check keybind - if (bind_maps[j][i].key && config_get_string(conf, bind_maps[j][i].key, &tmp_key)) - { - int key = find_sk_key(tmp_key); - - if (key >= 0) - bind->key = (enum ssnes_key)key; - - free(tmp_key); - tmp_key = NULL; - } - - // Check joybutton bind (hats too) - if (bind_maps[j][i].btn && config_get_string(conf, bind_maps[j][i].btn, &tmp_btn)) - { - const char *btn = tmp_btn; - if (strcmp(tmp_btn, "nul") == 0) - { - bind->joykey = NO_BTN; - } - else - { - if (*btn++ == 'h') - { - if (isdigit(*btn)) - { - char *dir = NULL; - int hat = strtol(btn, &dir, 0); - int hat_dir = 0; - if (dir) - { - if (strcasecmp(dir, "up") == 0) - hat_dir = HAT_UP_MASK; - else if (strcasecmp(dir, "down") == 0) - hat_dir = HAT_DOWN_MASK; - else if (strcasecmp(dir, "left") == 0) - hat_dir = HAT_LEFT_MASK; - else if (strcasecmp(dir, "right") == 0) - hat_dir = HAT_RIGHT_MASK; - - if (hat_dir) - bind->joykey = HAT_MAP(hat, hat_dir); - } - } - } - else - bind->joykey = strtol(tmp_btn, NULL, 0); - } - free(tmp_btn); - } - - // Check joyaxis binds. - if (bind_maps[j][i].axis && config_get_string(conf, bind_maps[j][i].axis, &tmp_axis)) - { - if (strcmp(tmp_axis, "nul") == 0) - { - bind->joyaxis = AXIS_NONE; - } - else if (strlen(tmp_axis) >= 2 && (*tmp_axis == '+' || *tmp_axis == '-')) - { - int axis = strtol(tmp_axis + 1, NULL, 0); - if (*tmp_axis == '+') - bind->joyaxis = AXIS_POS(axis); - else - bind->joyaxis = AXIS_NEG(axis); - - } - free(tmp_axis); - tmp_axis = NULL; - } + if (hat_dir) + bind->joykey = HAT_MAP(hat, hat_dir); } } } + +static void read_keybinds_button(config_file_t *conf, unsigned player, unsigned index, struct snes_keybind *bind) +{ + char tmp[64]; + if (bind_maps[player][index].btn && + config_get_array(conf, bind_maps[player][index].btn, tmp, sizeof(tmp))) + { + const char *btn = tmp; + if (strcmp(btn, "nul") == 0) + bind->joykey = NO_BTN; + else + { + if (*btn == 'h') + parse_hat(bind, btn + 1); + else + bind->joykey = strtol(tmp, NULL, 0); + } + } +} + +static void read_keybinds_axis(config_file_t *conf, unsigned player, unsigned index, struct snes_keybind *bind) +{ + char tmp[64]; + if (bind_maps[player][index].axis && + config_get_array(conf, bind_maps[player][index].axis, tmp, sizeof(tmp))) + { + if (strcmp(tmp, "nul") == 0) + bind->joyaxis = AXIS_NONE; + else if (strlen(tmp) >= 2 && (*tmp == '+' || *tmp == '-')) + { + int axis = strtol(tmp + 1, NULL, 0); + if (*tmp == '+') + bind->joyaxis = AXIS_POS(axis); + else + bind->joyaxis = AXIS_NEG(axis); + + } + } +} + +static void read_keybinds_player(config_file_t *conf, unsigned player) +{ + for (unsigned i = 0; bind_maps[player][i].valid; i++) + { + struct snes_keybind *bind = find_snes_bind(player, bind_maps[player][i].snes_key); + ssnes_assert(bind); + + read_keybinds_keyboard(conf, player, i, bind); + read_keybinds_button(conf, player, i, bind); + read_keybinds_axis(conf, player, i, bind); + } +} + +static void read_keybinds(config_file_t *conf) +{ + for (unsigned i = 0; i < MAX_PLAYERS; i++) + read_keybinds_player(conf, i); +} + #endif