diff --git a/config.def.h b/config.def.h index fe33b5c847..fd350ad07e 100644 --- a/config.def.h +++ b/config.def.h @@ -196,6 +196,7 @@ static const struct snes_keybind snes_keybinds_1[] = { { SSNES_AUDIO_INPUT_RATE_MINUS, SDLK_KP_MINUS, NO_BTN, AXIS_NONE }, { 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 }, { -1 } }; diff --git a/driver.h b/driver.h index 3f39b46b12..35247020a9 100644 --- a/driver.h +++ b/driver.h @@ -38,6 +38,7 @@ enum SSNES_AUDIO_INPUT_RATE_MINUS, SSNES_REWIND, SSNES_MOVIE_RECORD_TOGGLE, + SSNES_PAUSE_TOGGLE, }; struct snes_keybind diff --git a/general.h b/general.h index ada828157b..b763b98e24 100644 --- a/general.h +++ b/general.h @@ -37,7 +37,7 @@ #define MAX_PLAYERS 5 -#define MAX_BINDS 24 // Needs to be increased every time there are new binds added. +#define MAX_BINDS 25 // Needs to be increased every time there are new binds added. #define SSNES_NO_JOYPAD 0xFFFF struct settings { @@ -161,6 +161,8 @@ struct global bool bsv_movie_end; bool bsv_movie_playback; + bool is_paused; + #ifdef HAVE_FFMPEG ffemu_t *rec; char record_path[256]; diff --git a/ssnes.c b/ssnes.c index 628e2f026f..ed507edb97 100644 --- a/ssnes.c +++ b/ssnes.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "driver.h" #include "file.h" #include "hqflt/filters.h" @@ -35,6 +36,12 @@ #include #endif +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + + #ifdef __APPLE__ #include "SDL.h" // OSX seems to really need -lSDLmain, @@ -932,8 +939,37 @@ static void check_movie_record(void) old_button = new_button; } +static void check_pause(void) +{ + static bool old_state = false; + bool new_state = driver.input->key_pressed(driver.input_data, SSNES_PAUSE_TOGGLE); + if (new_state && !old_state) + { + g_extern.is_paused = !g_extern.is_paused; + + if (g_extern.is_paused) + { + SSNES_LOG("Paused!\n"); + if (driver.audio_data) + driver.audio->stop(driver.audio_data); + } + else + { + SSNES_LOG("Unpaused!\n"); + if (driver.audio_data) + driver.audio->start(driver.audio_data); + } + } + + old_state = new_state; +} + static void do_state_checks(void) { + check_pause(); + if (g_extern.is_paused) + return; + set_fast_forward_button(driver.input->key_pressed(driver.input_data, SSNES_FAST_FORWARD_KEY)); if (!g_extern.bsv_movie) @@ -1001,7 +1037,21 @@ int main(int argc, char *argv[]) do_state_checks(); // Run libsnes for one frame. - psnes_run(); + if (!g_extern.is_paused) + psnes_run(); + else + { + input_poll(); +#ifdef _WIN32 + Sleep(10); +#else + struct timespec tv = { + .tv_sec = 0, + .tv_nsec = 10000000 + }; + nanosleep(&tv, NULL); +#endif + } } #ifdef HAVE_FFMPEG diff --git a/ssnes.cfg b/ssnes.cfg index 45d2c5d63e..47f4ccabc9 100644 --- a/ssnes.cfg +++ b/ssnes.cfg @@ -208,3 +208,7 @@ # Toggle between recording and not. # input_movie_record_toggle = o + +# Toggle between paused and non-paused state +# input_pause_toggle = p + diff --git a/tools/ssnes-joyconfig.c b/tools/ssnes-joyconfig.c index 3f79fd56be..f009baf6b3 100644 --- a/tools/ssnes-joyconfig.c +++ b/tools/ssnes-joyconfig.c @@ -90,6 +90,7 @@ static struct bind binds[] = { MISC_BIND("Audio input rate step down", rate_step_down) MISC_BIND("Rewind", rewind) MISC_BIND("Movie recording toggle", movie_record_toggle) + MISC_BIND("Pause", pause_toggle) }; void get_binds(config_file_t *conf, int player, int joypad)