diff --git a/config.def.h b/config.def.h index 1a0e8881b0..fed2f9895e 100644 --- a/config.def.h +++ b/config.def.h @@ -142,28 +142,34 @@ static const bool audio_sync = true; #define AXIS_NEG(x) ((uint32_t)(x << 16) | 0xFFFF) #define AXIS_POS(x) ((uint32_t)(x) | 0xFFFF0000U) #define AXIS_NONE ((uint32_t)0xFFFFFFFFU) +#define NO_BTN 0xFFFF // I hope no joypad will ever have this many buttons ... ;) // To figure out which joypad buttons to use, check jstest or similar. // Axes are configured using the axis number for the positive (up, right) // direction and the number's two's-complement (~) for negative directions. // To use the axis, set the button to -1. +// SDL sometimes reverses the axes for some odd reason, but hey. :D // Player 1 static const struct snes_keybind snes_keybinds_1[] = { // SNES button | keyboard key | js btn | js axis | - { SNES_DEVICE_ID_JOYPAD_A, SDLK_x, 1, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_B, SDLK_z, 0, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_X, SDLK_s, 3, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_Y, SDLK_a, 2, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_L, SDLK_q, 4, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_R, SDLK_w, 5, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_LEFT, 11, AXIS_NEG(0) }, - { SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_RIGHT, 12, AXIS_POS(0) }, - { SNES_DEVICE_ID_JOYPAD_UP, SDLK_UP, 13, AXIS_POS(1) }, - { SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_DOWN, 14, AXIS_NEG(1) }, - { SNES_DEVICE_ID_JOYPAD_START, SDLK_RETURN, 7, AXIS_NONE }, - { SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_RSHIFT, 6, AXIS_NONE }, - { SSNES_FAST_FORWARD_KEY, SDLK_SPACE, 10, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_A, SDLK_x, 1, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_B, SDLK_z, 0, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_X, SDLK_s, 3, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_Y, SDLK_a, 2, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_L, SDLK_q, 4, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_R, SDLK_w, 5, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_LEFT, SDLK_LEFT, 11, AXIS_NEG(0) }, + { SNES_DEVICE_ID_JOYPAD_RIGHT, SDLK_RIGHT, 12, AXIS_POS(0) }, + { SNES_DEVICE_ID_JOYPAD_UP, SDLK_UP, 13, AXIS_NEG(1) }, + { SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_DOWN, 14, AXIS_POS(1) }, + { SNES_DEVICE_ID_JOYPAD_START, SDLK_RETURN, 7, AXIS_NONE }, + { SNES_DEVICE_ID_JOYPAD_SELECT, SDLK_RSHIFT, 6, AXIS_NONE }, + { SSNES_FAST_FORWARD_KEY, SDLK_SPACE, 10, AXIS_NONE }, + { SSNES_SAVE_STATE_KEY, SDLK_F2, NO_BTN, AXIS_NONE }, + { SSNES_LOAD_STATE_KEY, SDLK_F4, NO_BTN, AXIS_NONE }, + { SSNES_FULLSCREEN_TOGGLE_KEY, SDLK_f, NO_BTN, AXIS_NONE }, + { SSNES_QUIT_KEY, SDLK_ESCAPE, NO_BTN, AXIS_NONE }, { -1 } }; @@ -178,21 +184,12 @@ static const struct snes_keybind snes_keybinds_2[] = { { 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_POS(1) }, - { SNES_DEVICE_ID_JOYPAD_DOWN, SDLK_k, 14, AXIS_NEG(1) }, + { 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 } }; -///// Save state -#define SAVE_STATE_KEY SDLK_F2 -///// Load state -#define LOAD_STATE_KEY SDLK_F4 - -//// Toggles between fullscreen and windowed mode. -#define TOGGLE_FULLSCREEN SDLK_f - - #endif diff --git a/driver.h b/driver.h index ec5f3dcca8..778bce9172 100644 --- a/driver.h +++ b/driver.h @@ -25,8 +25,14 @@ #include #include -#define SSNES_FAST_FORWARD_KEY 0x666 // Hurr, durr -void set_fast_forward_button(bool state); +enum +{ + SSNES_FAST_FORWARD_KEY = 0x666, // Hurr, durr + SSNES_LOAD_STATE_KEY, + SSNES_SAVE_STATE_KEY, + SSNES_FULLSCREEN_TOGGLE_KEY, + SSNES_QUIT_KEY, +}; struct snes_keybind { diff --git a/general.h b/general.h index ef1bfffbb3..1fcda776e2 100644 --- a/general.h +++ b/general.h @@ -33,8 +33,8 @@ #endif -#define MAX_PLAYERS 2 -#define MAX_BINDS 14 +#define MAX_PLAYERS 2 // Should be 5 when multi-tap stuff is added ... +#define MAX_BINDS 18 // Needs to be increased every time there are new binds added. struct settings { struct @@ -70,10 +70,6 @@ struct settings { char driver[32]; struct snes_keybind binds[MAX_PLAYERS][MAX_BINDS]; - int save_state_key; - int load_state_key; - int toggle_fullscreen_key; - int exit_emulator_key; float axis_threshold; } input; diff --git a/input/sdl.c b/input/sdl.c index a2260ebe2e..aca92a9ae7 100644 --- a/input/sdl.c +++ b/input/sdl.c @@ -56,6 +56,7 @@ static void* sdl_input_init(void) return sdl; } + static bool sdl_key_pressed(void *data, int key) { int num_keys; @@ -97,6 +98,17 @@ static bool sdl_is_pressed(sdl_input_t *sdl, int port_num, const struct snes_key return false; } +static bool sdl_bind_button_pressed(void *data, int key) +{ + const struct snes_keybind *binds = g_settings.input.binds[0]; + for (int i = 0; binds[i].id != -1; i++) + { + if (binds[i].id == key) + return sdl_is_pressed(data, 0, &binds[i]); + } + return false; +} + static int16_t sdl_input_state(void *data, const struct snes_keybind **binds, bool port, unsigned device, unsigned index, unsigned id) { sdl_input_t *sdl = data; @@ -105,18 +117,15 @@ static int16_t sdl_input_state(void *data, const struct snes_keybind **binds, bo const struct snes_keybind *snes_keybinds = binds[port == SNES_PORT_1 ? 0 : 1]; - // Checks if button is pressed, and sets fast-forwarding state - bool pressed = false; + // 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 == SSNES_FAST_FORWARD_KEY) - set_fast_forward_button(sdl_is_pressed(sdl, port_num, &snes_keybinds[i])); - else if (!pressed && snes_keybinds[i].id == (int)id) - pressed = sdl_is_pressed(sdl, port_num, &snes_keybinds[i]); + if (snes_keybinds[i].id == (int)id) + return sdl_is_pressed(sdl, port_num, &snes_keybinds[i]); } - return pressed; + return false; } static void sdl_input_free(void *data) @@ -170,7 +179,7 @@ const input_driver_t input_sdl = { .init = sdl_input_init, .poll = sdl_input_poll, .input_state = sdl_input_state, - .key_pressed = sdl_key_pressed, + .key_pressed = sdl_bind_button_pressed, .free = sdl_input_free, .ident = "sdl" }; diff --git a/settings.c b/settings.c index 5337f042c7..8e352cea4b 100644 --- a/settings.c +++ b/settings.c @@ -111,11 +111,7 @@ static void set_defaults(void) 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)); - g_settings.input.save_state_key = SAVE_STATE_KEY; - g_settings.input.load_state_key = LOAD_STATE_KEY; - g_settings.input.toggle_fullscreen_key = TOGGLE_FULLSCREEN; g_settings.input.axis_threshold = AXIS_THRESHOLD; - g_settings.input.exit_emulator_key = SDLK_ESCAPE; } void parse_config(void) @@ -311,37 +307,47 @@ struct bind_map int snes_key; }; + +#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][13] = { +static const struct bind_map bind_maps[2][MAX_BINDS - 1] = { { - { "input_player1_a", "input_player1_a_btn", NULL, SNES_DEVICE_ID_JOYPAD_A }, - { "input_player1_b", "input_player1_b_btn", NULL, SNES_DEVICE_ID_JOYPAD_B }, - { "input_player1_y", "input_player1_y_btn", NULL, SNES_DEVICE_ID_JOYPAD_Y }, - { "input_player1_x", "input_player1_x_btn", NULL, SNES_DEVICE_ID_JOYPAD_X }, - { "input_player1_start", "input_player1_start_btn", NULL, SNES_DEVICE_ID_JOYPAD_START }, - { "input_player1_select", "input_player1_select_btn", NULL, SNES_DEVICE_ID_JOYPAD_SELECT }, - { "input_player1_l", "input_player1_l_btn", NULL, SNES_DEVICE_ID_JOYPAD_L }, - { "input_player1_r", "input_player1_r_btn", NULL, SNES_DEVICE_ID_JOYPAD_R }, - { "input_player1_left", "input_player1_left_btn", "input_player1_left_axis", SNES_DEVICE_ID_JOYPAD_LEFT }, - { "input_player1_right", "input_player1_right_btn", "input_player1_right_axis", SNES_DEVICE_ID_JOYPAD_RIGHT }, - { "input_player1_up", "input_player1_up_btn", "input_player1_up_axis", SNES_DEVICE_ID_JOYPAD_UP }, - { "input_player1_down", "input_player1_down_btn", "input_player1_down_axis", SNES_DEVICE_ID_JOYPAD_DOWN }, - { "input_toggle_fast_forward", "input_toggle_fast_forward_btn", NULL, SSNES_FAST_FORWARD_KEY } - }, + 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_up, SNES_DEVICE_ID_JOYPAD_UP) + DECLARE_BIND(player1_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) + }, { - { "input_player2_a", "input_player2_a_btn", NULL, SNES_DEVICE_ID_JOYPAD_A }, - { "input_player2_b", "input_player2_b_btn", NULL, SNES_DEVICE_ID_JOYPAD_B }, - { "input_player2_y", "input_player2_y_btn", NULL, SNES_DEVICE_ID_JOYPAD_Y }, - { "input_player2_x", "input_player2_x_btn", NULL, SNES_DEVICE_ID_JOYPAD_X }, - { "input_player2_start", "input_player2_start_btn", NULL, SNES_DEVICE_ID_JOYPAD_START }, - { "input_player2_select", "input_player2_select_btn", NULL, SNES_DEVICE_ID_JOYPAD_SELECT }, - { "input_player2_l", "input_player2_l_btn", NULL, SNES_DEVICE_ID_JOYPAD_L }, - { "input_player2_r", "input_player2_r_btn", NULL, SNES_DEVICE_ID_JOYPAD_R }, - { "input_player2_left", "input_player2_left_btn", "input_player2_left_axis", SNES_DEVICE_ID_JOYPAD_LEFT }, - { "input_player2_right", "input_player2_right_btn", "input_player2_right_axis", SNES_DEVICE_ID_JOYPAD_RIGHT }, - { "input_player2_up", "input_player2_up_btn", "input_player2_up_axis", SNES_DEVICE_ID_JOYPAD_UP }, - { "input_player2_down", "input_player2_down_btn", "input_player2_down_axis", SNES_DEVICE_ID_JOYPAD_DOWN }, - { "input_toggle_fast_forward", "input_toggle_fast_forward_btn", NULL, SSNES_FAST_FORWARD_KEY } + DECLARE_BIND(player2_a, SNES_DEVICE_ID_JOYPAD_A) + DECLARE_BIND(player2_b, SNES_DEVICE_ID_JOYPAD_B) + DECLARE_BIND(player2_y, SNES_DEVICE_ID_JOYPAD_Y) + DECLARE_BIND(player2_x, SNES_DEVICE_ID_JOYPAD_X) + DECLARE_BIND(player2_start, SNES_DEVICE_ID_JOYPAD_START) + DECLARE_BIND(player2_select, SNES_DEVICE_ID_JOYPAD_SELECT) + DECLARE_BIND(player2_l, SNES_DEVICE_ID_JOYPAD_L) + DECLARE_BIND(player2_r, SNES_DEVICE_ID_JOYPAD_R) + DECLARE_BIND(player2_left, SNES_DEVICE_ID_JOYPAD_LEFT) + DECLARE_BIND(player2_right, SNES_DEVICE_ID_JOYPAD_RIGHT) + DECLARE_BIND(player2_up, SNES_DEVICE_ID_JOYPAD_UP) + DECLARE_BIND(player2_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) } }; @@ -352,6 +358,7 @@ struct key_map }; // Edit: Not portable to different input systems atm. Might move this map into the driver itself or something. +// However, this should map nicely over to other systems aswell since the definition are mostly the same anyways. static const struct key_map sdlk_map[] = { { "left", SDLK_LEFT }, { "right", SDLK_RIGHT }, @@ -459,38 +466,5 @@ static void read_keybinds(config_file_t *conf) } } } - - char *tmp_str; - if (config_get_string(conf, "input_toggle_fullscreen", &tmp_str)) - { - int key = find_sdlk_key(tmp_str); - if (key >= 0) - g_settings.input.toggle_fullscreen_key = key; - free(tmp_str); - } - if (config_get_string(conf, "input_save_state", &tmp_str)) - { - int key = find_sdlk_key(tmp_str); - if (key >= 0) - g_settings.input.save_state_key = key; - free(tmp_str); - } - if (config_get_string(conf, "input_load_state", &tmp_str)) - { - int key = find_sdlk_key(tmp_str); - if (key >= 0) - g_settings.input.load_state_key = key; - free(tmp_str); - } - if (config_get_string(conf, "input_exit_emulator", &tmp_str)) - { - int key = find_sdlk_key(tmp_str); - if (key >= 0) - g_settings.input.exit_emulator_key = key; - free(tmp_str); - } } - - - diff --git a/ssnes.c b/ssnes.c index eab1ff97ad..4d3090607f 100644 --- a/ssnes.c +++ b/ssnes.c @@ -43,7 +43,7 @@ struct global g_extern = { #define AUDIO_CHUNK_SIZE_BLOCKING 64 #define AUDIO_CHUNK_SIZE_NONBLOCKING 2048 // So we don't get complete line-noise when fast-forwarding audio. static size_t audio_chunk_size = AUDIO_CHUNK_SIZE_BLOCKING; -void set_fast_forward_button(bool new_button_state) +static void set_fast_forward_button(bool new_button_state) { static bool old_button_state = false; static bool syncing_state = false; @@ -426,21 +426,24 @@ int main(int argc, char *argv[]) } #endif + // Main loop for(;;) { - if (driver.input->key_pressed(driver.input_data, g_settings.input.exit_emulator_key) || + if (driver.input->key_pressed(driver.input_data, SSNES_QUIT_KEY) || !driver.video->alive(driver.video_data)) break; - if (driver.input->key_pressed(driver.input_data, g_settings.input.save_state_key)) + set_fast_forward_button(driver.input->key_pressed(driver.input_data, SSNES_FAST_FORWARD_KEY)); + + if (driver.input->key_pressed(driver.input_data, SSNES_SAVE_STATE_KEY)) { write_file(statefile_name, serial_data, serial_size); } - else if (driver.input->key_pressed(driver.input_data, g_settings.input.load_state_key)) + else if (driver.input->key_pressed(driver.input_data, SSNES_LOAD_STATE_KEY)) load_state(statefile_name, serial_data, serial_size); - else if (driver.input->key_pressed(driver.input_data, g_settings.input.toggle_fullscreen_key)) + else if (driver.input->key_pressed(driver.input_data, SSNES_FULLSCREEN_TOGGLE_KEY)) { g_settings.video.fullscreen = !g_settings.video.fullscreen; uninit_drivers(); diff --git a/ssnes.cfg b/ssnes.cfg index 7f52b5961f..499b3cee7b 100644 --- a/ssnes.cfg +++ b/ssnes.cfg @@ -102,7 +102,9 @@ # input_player1_up_btn = 13 # input_player1_down_btn = 14 -# Axis for DPAD. Needs to be either '+' or '-' in the first character signaling either positive or negative direction of the axis, then the axis number. +# Axis for DPAD. +# Needs to be either '+' or '-' in the first character signaling either positive or negative direction of the axis, then the axis number. +# Do note that every other input option has the corresponding _btn and _axis binds as well; they are omitted here for clarity. # input_player1_left_axis = -0 # input_player1_right_axis = +0 # input_player1_up_axis = +1 @@ -138,8 +140,8 @@ # input_player2_left_axis = -0 # input_player2_right_axis = +0 -# input_player2_up_axis = +1 -# input_player2_down_axis = -1 +# input_player2_up_axis = -1 +# input_player2_down_axis = +1 # Toggles fullscreen. # input_toggle_fullscreen = f @@ -150,8 +152,7 @@ # Toggles between fast-forwarding and normal speed. # input_toggle_fast_forward = space -# Same, just mapping to a joypad button. -# input_toggle_fast_forward_btn = 10 -# Key to exit emulator cleanly. +# Key to exit emulator cleanly. +# Killing it in any hard way (SIGTERM, SIGKILL, etc, will terminate emulator without saving RAM, etc.) # input_exit_emulator = escape