diff --git a/config.def.h b/config.def.h index d0067c618c..332baffebc 100644 --- a/config.def.h +++ b/config.def.h @@ -220,6 +220,7 @@ static const struct snes_keybind snes_keybinds_1[] = { { SSNES_REWIND, SDLK_r, NO_BTN, AXIS_NONE }, { SSNES_MOVIE_RECORD_TOGGLE, SDLK_o, NO_BTN, AXIS_NONE }, { SSNES_PAUSE_TOGGLE, SDLK_p, NO_BTN, AXIS_NONE }, + { SSNES_RESET, SDLK_h, NO_BTN, AXIS_NONE }, { -1 } }; diff --git a/driver.h b/driver.h index fc1b9b8c22..46e1ab4ee8 100644 --- a/driver.h +++ b/driver.h @@ -39,6 +39,7 @@ enum SSNES_REWIND, SSNES_MOVIE_RECORD_TOGGLE, SSNES_PAUSE_TOGGLE, + SSNES_RESET, }; diff --git a/dynamic.c b/dynamic.c index 872ed8f492..367a2fb1d5 100644 --- a/dynamic.c +++ b/dynamic.c @@ -54,6 +54,7 @@ void (*psnes_set_audio_sample)(snes_audio_sample_t); void (*psnes_set_input_poll)(snes_input_poll_t); void (*psnes_set_input_state)(snes_input_state_t); +void (*psnes_reset)(void); void (*psnes_run)(void); const char *(*psnes_library_id)(void) = NULL; @@ -110,6 +111,7 @@ static void load_dynamic(void) OPT_SYM(snes_library_id); SYM(snes_library_revision_minor); SYM(snes_library_revision_major); + SYM(snes_reset); SYM(snes_run); SYM(snes_get_region); SYM(snes_load_cartridge_normal); @@ -143,6 +145,7 @@ static void set_statics(void) SSYM(snes_set_input_state); SSYM(snes_library_revision_minor); SSYM(snes_library_revision_major); + SSYM(snes_reset); SSYM(snes_run); SSYM(snes_get_region); SSYM(snes_load_cartridge_normal); diff --git a/dynamic.h b/dynamic.h index 494c14bc8f..d8bfea86bc 100644 --- a/dynamic.h +++ b/dynamic.h @@ -64,6 +64,7 @@ extern unsigned (*psnes_serialize_size)(void); extern bool (*psnes_serialize)(uint8_t*, unsigned); extern bool (*psnes_unserialize)(const uint8_t*, unsigned); +extern void (*psnes_reset)(void); extern void (*psnes_run)(void); extern void (*psnes_set_cartridge_basename)(const char*); diff --git a/general.h b/general.h index b7e452f9fc..2a9c6abb36 100644 --- a/general.h +++ b/general.h @@ -42,7 +42,7 @@ #define MAX_PLAYERS 5 -#define MAX_BINDS 25 // Needs to be increased every time there are new binds added. +#define MAX_BINDS 26 // Needs to be increased every time there are new binds added. #define SSNES_NO_JOYPAD 0xFFFF enum ssnes_shader_type diff --git a/settings.c b/settings.c index 69f53166ff..a1a827b595 100644 --- a/settings.c +++ b/settings.c @@ -408,6 +408,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { DECLARE_BIND(rewind, SSNES_REWIND) DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) DECLARE_BIND(pause_toggle, SSNES_PAUSE_TOGGLE) + DECLARE_BIND(reset, SSNES_RESET) }, { DECLARE_BIND(player2_a, SNES_DEVICE_ID_JOYPAD_A) @@ -434,6 +435,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { DECLARE_BIND(rewind, SSNES_REWIND) DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) DECLARE_BIND(pause_toggle, SSNES_PAUSE_TOGGLE) + DECLARE_BIND(reset, SSNES_RESET) }, { DECLARE_BIND(player3_a, SNES_DEVICE_ID_JOYPAD_A) @@ -460,6 +462,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { DECLARE_BIND(rewind, SSNES_REWIND) DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) DECLARE_BIND(pause_toggle, SSNES_PAUSE_TOGGLE) + DECLARE_BIND(reset, SSNES_RESET) }, { DECLARE_BIND(player4_a, SNES_DEVICE_ID_JOYPAD_A) @@ -486,6 +489,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { DECLARE_BIND(rewind, SSNES_REWIND) DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) DECLARE_BIND(pause_toggle, SSNES_PAUSE_TOGGLE) + DECLARE_BIND(reset, SSNES_RESET) }, { DECLARE_BIND(player5_a, SNES_DEVICE_ID_JOYPAD_A) @@ -512,6 +516,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { DECLARE_BIND(rewind, SSNES_REWIND) DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) DECLARE_BIND(pause_toggle, SSNES_PAUSE_TOGGLE) + DECLARE_BIND(reset, SSNES_RESET) }, }; diff --git a/ssnes.c b/ssnes.c index eafd742540..09c7223dcc 100644 --- a/ssnes.c +++ b/ssnes.c @@ -1146,10 +1146,23 @@ static void check_pause(void) old_state = new_state; } +static void check_reset(void) +{ + if (driver.input->key_pressed(driver.input_data, SSNES_RESET)) + { + SSNES_LOG("Resetting game!\n"); + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, "Reset!", 1, 120); + psnes_reset(); + init_controllers(); // bSNES since v073r01 resets controllers to JOYPAD after a reset, so just enforce it here. + } +} + static void do_state_checks(void) { if (!g_extern.netplay) { + check_reset(); check_pause(); if (g_extern.is_paused) return; diff --git a/ssnes.cfg b/ssnes.cfg index e2d76c3042..ae096b1724 100644 --- a/ssnes.cfg +++ b/ssnes.cfg @@ -232,6 +232,9 @@ # Toggle between paused and non-paused state # input_pause_toggle = p +# Reset the emulated SNES. +# input_reset = h + # Pause gameplay when window focus is lost. # pause_nonactive = true @@ -241,3 +244,4 @@ # When being client over netplay, use keybinds for player 1. # netplay_client_swap_input = false + diff --git a/tools/ssnes-joyconfig.c b/tools/ssnes-joyconfig.c index a516e5e841..d32ed92b85 100644 --- a/tools/ssnes-joyconfig.c +++ b/tools/ssnes-joyconfig.c @@ -91,6 +91,7 @@ static struct bind binds[] = { MISC_BIND("Rewind", rewind) MISC_BIND("Movie recording toggle", movie_record_toggle) MISC_BIND("Pause", pause_toggle) + MISC_BIND("Reset", reset) }; static void get_binds(config_file_t *conf, int player, int joypad)