diff --git a/config.def.h b/config.def.h index 1a6c72a2b2..fe33b5c847 100644 --- a/config.def.h +++ b/config.def.h @@ -195,6 +195,7 @@ static const struct snes_keybind snes_keybinds_1[] = { { SSNES_AUDIO_INPUT_RATE_PLUS, SDLK_KP_PLUS, NO_BTN, AXIS_NONE }, { 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 }, { -1 } }; diff --git a/driver.h b/driver.h index 7bc8a364a8..d825b28d56 100644 --- a/driver.h +++ b/driver.h @@ -37,6 +37,7 @@ enum SSNES_AUDIO_INPUT_RATE_PLUS, SSNES_AUDIO_INPUT_RATE_MINUS, SSNES_REWIND, + SSNES_MOVIE_RECORD_TOGGLE, }; struct snes_keybind diff --git a/general.h b/general.h index 74d8e8e1d3..a789abe294 100644 --- a/general.h +++ b/general.h @@ -37,7 +37,7 @@ #define MAX_PLAYERS 5 -#define MAX_BINDS 23 // Needs to be increased every time there are new binds added. +#define MAX_BINDS 24 // Needs to be increased every time there are new binds added. #define SSNES_NO_JOYPAD 0xFFFF struct settings { @@ -157,7 +157,7 @@ struct global bool frame_is_reverse; bsv_movie_t *bsv_movie; - char bsv_movie_path[256]; + char bsv_movie_path[512]; bool bsv_movie_end; bool bsv_movie_playback; diff --git a/movie.c b/movie.c index 43fe3ee843..60eaaa3f2a 100644 --- a/movie.c +++ b/movie.c @@ -135,7 +135,7 @@ static bool init_playback(bsv_movie_t *handle, const char *path) } uint32_t header[4] = {0}; - if (fread(header, 4, sizeof(uint32_t), handle->file) != 4) + if (fread(header, sizeof(uint32_t), 4, handle->file) != 4) { SSNES_ERR("Couldn't read movie header!\n"); return false; @@ -209,7 +209,7 @@ void bsv_movie_free(bsv_movie_t *handle) bool bsv_movie_get_input(bsv_movie_t *handle, int16_t *input) { - if (fread(input, 1, sizeof(int16_t), handle->file) != 1) + if (fread(input, sizeof(int16_t), 1, handle->file) != 1) return false; *input = swap_if_big16(*input); @@ -218,7 +218,7 @@ bool bsv_movie_get_input(bsv_movie_t *handle, int16_t *input) void bsv_movie_set_input(bsv_movie_t *handle, int16_t input) { - fwrite(&input, 1, sizeof(int16_t), handle->file); + fwrite(&input, sizeof(int16_t), 1, handle->file); } bsv_movie_t *bsv_movie_init(const char *path, enum ssnes_movie_type type) diff --git a/settings.c b/settings.c index f2b6b7f378..ce419c3916 100644 --- a/settings.c +++ b/settings.c @@ -357,6 +357,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { 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) + DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) }, { DECLARE_BIND(player2_a, SNES_DEVICE_ID_JOYPAD_A) @@ -381,6 +382,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { 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) + DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) }, { DECLARE_BIND(player3_a, SNES_DEVICE_ID_JOYPAD_A) @@ -405,6 +407,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { 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) + DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) }, { DECLARE_BIND(player4_a, SNES_DEVICE_ID_JOYPAD_A) @@ -429,6 +432,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { 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) + DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) }, { DECLARE_BIND(player5_a, SNES_DEVICE_ID_JOYPAD_A) @@ -453,6 +457,7 @@ static const struct bind_map bind_maps[MAX_PLAYERS][MAX_BINDS - 1] = { 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) + DECLARE_BIND(movie_record_toggle, SSNES_MOVIE_RECORD_TOGGLE) }, }; diff --git a/ssnes.c b/ssnes.c index 473402c261..abb43f4551 100644 --- a/ssnes.c +++ b/ssnes.c @@ -689,9 +689,18 @@ static void deinit_rewind(void) static void init_movie(void) { - if (strlen(g_extern.bsv_movie_path) > 0) - g_extern.bsv_movie = bsv_movie_init(g_extern.bsv_movie_path, - g_extern.bsv_movie_playback ? SSNES_MOVIE_PLAYBACK : SSNES_MOVIE_RECORD); + if (g_extern.bsv_movie_playback) + { + g_extern.bsv_movie = bsv_movie_init(g_extern.bsv_movie_path, SSNES_MOVIE_PLAYBACK); + if (!g_extern.bsv_movie) + { + SSNES_ERR("Failed to load movie file: \"%s\"!\n", g_extern.bsv_movie_path); + exit(1); + } + + msg_queue_push(g_extern.msg_queue, "Starting movie playback!", 2, 180); + SSNES_LOG("Starting movie playback!\n"); + } } static void deinit_movie(void) @@ -702,6 +711,9 @@ static void deinit_movie(void) static void fill_pathnames(void) { + if (!g_extern.bsv_movie_playback) + fill_pathname(g_extern.bsv_movie_path, g_extern.savefile_name_srm, ".bsv"); + switch (g_extern.game_type) { case SSNES_CART_BSX: @@ -877,6 +889,36 @@ static void check_rewind(void) } } +static void check_movie_record(void) +{ + static bool old_button = false; + bool new_button; + if ((new_button = driver.input->key_pressed(driver.input_data, SSNES_MOVIE_RECORD_TOGGLE)) && !old_button) + { + if (g_extern.bsv_movie) + { + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, "Stopping movie record!", 2, 180); + SSNES_LOG("Stopping movie record!\n"); + bsv_movie_free(g_extern.bsv_movie); + g_extern.bsv_movie = NULL; + } + else + { + g_extern.bsv_movie = bsv_movie_init(g_extern.bsv_movie_path, SSNES_MOVIE_RECORD); + msg_queue_clear(g_extern.msg_queue); + msg_queue_push(g_extern.msg_queue, g_extern.bsv_movie ? "Starting movie record!" : "Failed to start movie record!", 2, 180); + + if (g_extern.bsv_movie) + SSNES_LOG("Starting movie record!\n"); + else + SSNES_ERR("Failed to start movie record!\n"); + } + } + + old_button = new_button; +} + static void do_state_checks(void) { set_fast_forward_button(driver.input->key_pressed(driver.input_data, SSNES_FAST_FORWARD_KEY)); @@ -889,6 +931,9 @@ static void do_state_checks(void) } check_fullscreen(); check_input_rate(); + + if (!g_extern.bsv_movie_playback) + check_movie_record(); } @@ -916,6 +961,7 @@ int main(int argc, char *argv[]) psnes_set_input_poll(input_poll); psnes_set_input_state(input_state); + init_msg_queue(); init_controllers(); init_movie(); @@ -929,7 +975,6 @@ int main(int argc, char *argv[]) init_recording(); #endif - init_msg_queue(); // Main loop for(;;) @@ -946,7 +991,6 @@ int main(int argc, char *argv[]) psnes_run(); } - deinit_msg_queue(); #ifdef HAVE_FFMPEG deinit_recording(); #endif @@ -958,6 +1002,8 @@ int main(int argc, char *argv[]) } deinit_movie(); + deinit_msg_queue(); + psnes_unload_cartridge(); psnes_term(); uninit_drivers(); diff --git a/ssnes.cfg b/ssnes.cfg index 55548521e2..3e34e3a586 100644 --- a/ssnes.cfg +++ b/ssnes.cfg @@ -205,3 +205,5 @@ # Hold button down to rewind. Rewinding must be enabled. # input_rewind = r +# Toggle between recording and not. +# input_movie_record_toggle = o