diff --git a/retroarch.c b/retroarch.c index 5d36ff5d2a..4a1e04a8f6 100644 --- a/retroarch.c +++ b/retroarch.c @@ -20071,193 +20071,6 @@ void recording_driver_update_streaming_url(void) } #ifdef HAVE_BSV_MOVIE -/* BSV MOVIE */ -static bool bsv_movie_init_playback( - bsv_movie_t *handle, const char *path) -{ - uint32_t state_size = 0; - uint32_t content_crc = 0; - uint32_t header[4] = {0}; - intfstream_t *file = intfstream_open_file(path, - RETRO_VFS_FILE_ACCESS_READ, - RETRO_VFS_FILE_ACCESS_HINT_NONE); - - if (!file) - { - RARCH_ERR("Could not open BSV file for playback, path : \"%s\".\n", path); - return false; - } - - handle->file = file; - handle->playback = true; - - intfstream_read(handle->file, header, sizeof(uint32_t) * 4); - /* Compatibility with old implementation that - * used incorrect documentation. */ - if (swap_if_little32(header[MAGIC_INDEX]) != BSV_MAGIC - && swap_if_big32(header[MAGIC_INDEX]) != BSV_MAGIC) - { - RARCH_ERR("%s\n", msg_hash_to_str(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE)); - return false; - } - - content_crc = content_get_crc(); - - if (content_crc != 0) - if (swap_if_big32(header[CRC_INDEX]) != content_crc) - RARCH_WARN("%s.\n", msg_hash_to_str(MSG_CRC32_CHECKSUM_MISMATCH)); - - state_size = swap_if_big32(header[STATE_SIZE_INDEX]); - -#if 0 - RARCH_ERR("----- debug %u -----\n", header[0]); - RARCH_ERR("----- debug %u -----\n", header[1]); - RARCH_ERR("----- debug %u -----\n", header[2]); - RARCH_ERR("----- debug %u -----\n", header[3]); -#endif - - if (state_size) - { - retro_ctx_size_info_t info; - retro_ctx_serialize_info_t serial_info; - uint8_t *buf = (uint8_t*)malloc(state_size); - - if (!buf) - return false; - - handle->state = buf; - handle->state_size = state_size; - if (intfstream_read(handle->file, - handle->state, state_size) != state_size) - { - RARCH_ERR("%s\n", msg_hash_to_str(MSG_COULD_NOT_READ_STATE_FROM_MOVIE)); - return false; - } - - core_serialize_size( &info); - - if (info.size == state_size) - { - serial_info.data_const = handle->state; - serial_info.size = state_size; - core_unserialize(&serial_info); - } - else - RARCH_WARN("%s\n", - msg_hash_to_str(MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION)); - } - - handle->min_file_pos = sizeof(header) + state_size; - - return true; -} - -static bool bsv_movie_init_record( - bsv_movie_t *handle, const char *path) -{ - retro_ctx_size_info_t info; - uint32_t state_size = 0; - uint32_t content_crc = 0; - uint32_t header[4] = {0}; - intfstream_t *file = intfstream_open_file(path, - RETRO_VFS_FILE_ACCESS_WRITE, - RETRO_VFS_FILE_ACCESS_HINT_NONE); - - if (!file) - { - RARCH_ERR("Could not open BSV file for recording, path : \"%s\".\n", path); - return false; - } - - handle->file = file; - - content_crc = content_get_crc(); - - /* This value is supposed to show up as - * BSV1 in a HEX editor, big-endian. */ - header[MAGIC_INDEX] = swap_if_little32(BSV_MAGIC); - header[CRC_INDEX] = swap_if_big32(content_crc); - - core_serialize_size(&info); - - state_size = (unsigned)info.size; - - header[STATE_SIZE_INDEX] = swap_if_big32(state_size); - - intfstream_write(handle->file, header, 4 * sizeof(uint32_t)); - - handle->min_file_pos = sizeof(header) + state_size; - handle->state_size = state_size; - - if (state_size) - { - retro_ctx_serialize_info_t serial_info; - uint8_t *st = (uint8_t*)malloc(state_size); - - if (!st) - return false; - - handle->state = st; - - serial_info.data = handle->state; - serial_info.size = state_size; - - core_serialize(&serial_info); - - intfstream_write(handle->file, - handle->state, state_size); - } - - return true; -} - -static void bsv_movie_free(bsv_movie_t *handle) -{ - if (!handle) - return; - - intfstream_close(handle->file); - free(handle->file); - - free(handle->state); - free(handle->frame_pos); - free(handle); -} - -static bsv_movie_t *bsv_movie_init_internal(const char *path, - enum rarch_movie_type type) -{ - size_t *frame_pos = NULL; - bsv_movie_t *handle = (bsv_movie_t*)calloc(1, sizeof(*handle)); - - if (!handle) - return NULL; - - if (type == RARCH_MOVIE_PLAYBACK) - { - if (!bsv_movie_init_playback(handle, path)) - goto error; - } - else if (!bsv_movie_init_record(handle, path)) - goto error; - - /* Just pick something really large - * ~1 million frames rewind should do the trick. */ - if (!(frame_pos = (size_t*)calloc((1 << 20), sizeof(size_t)))) - goto error; - - handle->frame_pos = frame_pos; - - handle->frame_pos[0] = handle->min_file_pos; - handle->frame_mask = (1 << 20) - 1; - - return handle; - -error: - bsv_movie_free(handle); - return NULL; -} - void bsv_movie_frame_rewind(void) { bsv_movie_t *handle = runloop_state.bsv_movie_state_handle; @@ -20312,147 +20125,6 @@ void bsv_movie_frame_rewind(void) intfstream_seek(handle->file, (int)handle->min_file_pos, SEEK_SET); } } - -static bool bsv_movie_init(runloop_state_t *p_runloop) -{ - if (p_runloop->bsv_movie_state.movie_start_playback) - { - if (!(p_runloop->bsv_movie_state_handle = bsv_movie_init_internal( - p_runloop->bsv_movie_state.movie_start_path, - RARCH_MOVIE_PLAYBACK))) - { - RARCH_ERR("%s: \"%s\".\n", - msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE), - p_runloop->bsv_movie_state.movie_start_path); - return false; - } - - p_runloop->bsv_movie_state.movie_playback = true; - runloop_msg_queue_push(msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK), - 2, 180, false, - NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - RARCH_LOG("%s.\n", msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK)); - - return true; - } - else if (p_runloop->bsv_movie_state.movie_start_recording) - { - char msg[8192]; - - if (!(p_runloop->bsv_movie_state_handle = bsv_movie_init_internal( - p_runloop->bsv_movie_state.movie_start_path, - RARCH_MOVIE_RECORD))) - { - runloop_msg_queue_push( - msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD), - 1, 180, true, - NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - RARCH_ERR("%s.\n", - msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); - return false; - } - - snprintf(msg, sizeof(msg), - "%s \"%s\".", - msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), - p_runloop->bsv_movie_state.movie_start_path); - - runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - RARCH_LOG("%s \"%s\".\n", - msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), - p_runloop->bsv_movie_state.movie_start_path); - - return true; - } - - return false; -} - -static void bsv_movie_deinit(runloop_state_t *p_runloop) -{ - if (p_runloop->bsv_movie_state_handle) - bsv_movie_free(p_runloop->bsv_movie_state_handle); - p_runloop->bsv_movie_state_handle = NULL; -} - -static bool runloop_check_movie_init(runloop_state_t *p_runloop, - settings_t *settings) -{ - char msg[16384], path[8192]; - int state_slot = settings->ints.state_slot; - - msg[0] = path[0] = '\0'; - - configuration_set_uint(settings, settings->uints.rewind_granularity, 1); - - if (state_slot > 0) - snprintf(path, sizeof(path), "%s%d.bsv", - p_runloop->bsv_movie_state.movie_path, - state_slot); - else - snprintf(path, sizeof(path), "%s.bsv", - p_runloop->bsv_movie_state.movie_path); - - snprintf(msg, sizeof(msg), "%s \"%s\".", - msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), - path); - - if (!(p_runloop->bsv_movie_state_handle = bsv_movie_init_internal( - path, RARCH_MOVIE_RECORD))) - { - runloop_msg_queue_push( - msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD), - 2, 180, true, - NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - RARCH_ERR("%s\n", - msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); - return false; - } - - runloop_msg_queue_push(msg, 2, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - RARCH_LOG("%s \"%s\".\n", - msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), - path); - - return true; -} - -static bool bsv_movie_check( - runloop_state_t *p_runloop, - settings_t *settings) -{ - if (!p_runloop->bsv_movie_state_handle) - return runloop_check_movie_init(p_runloop, settings); - - if (p_runloop->bsv_movie_state.movie_playback) - { - /* Checks if movie is being played back. */ - if (!p_runloop->bsv_movie_state.movie_end) - return false; - runloop_msg_queue_push( - msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED), 2, 180, false, - NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED)); - - p_runloop->bsv_movie_state.movie_end = false; - p_runloop->bsv_movie_state.movie_playback = false; - - goto end; - } - - /* Checks if movie is being recorded. */ - if (!p_runloop->bsv_movie_state_handle) - return false; - - runloop_msg_queue_push( - msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED), 2, 180, true, - NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); - RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED)); - -end: - bsv_movie_deinit(p_runloop); - return true; -} #endif /* INPUT OVERLAY */ diff --git a/retroarch.h b/retroarch.h index 9284c098f4..f054def661 100644 --- a/retroarch.h +++ b/retroarch.h @@ -47,6 +47,7 @@ #include "audio/audio_defines.h" #include "gfx/video_shader_parse.h" +#include "configuration.h" #include "core_type.h" #include "core.h" #include "core_option_manager.h" @@ -89,6 +90,11 @@ RETRO_BEGIN_DECLS #define MEASURE_FRAME_TIME_SAMPLES_COUNT (2 * 1024) #define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024) +#define MAGIC_INDEX 0 +#define SERIALIZER_INDEX 1 +#define CRC_INDEX 2 +#define STATE_SIZE_INDEX 3 + #ifdef HAVE_BSV_MOVIE #define BSV_MAGIC 0x42535631 @@ -221,6 +227,12 @@ enum runloop_action }; #ifdef HAVE_BSV_MOVIE +enum rarch_movie_type +{ + RARCH_MOVIE_PLAYBACK = 0, + RARCH_MOVIE_RECORD +}; + struct bsv_state { /* Movie playback/recording support. */ @@ -2372,6 +2384,14 @@ void core_option_manager_flush( config_file_t *conf, core_option_manager_t *opt); +#ifdef HAVE_BSV_MOVIE +bool bsv_movie_check( + runloop_state_t *p_runloop, + settings_t *settings); +void bsv_movie_deinit(runloop_state_t *p_runloop); +bool bsv_movie_init(runloop_state_t *p_runloop); +#endif + RETRO_END_DECLS #endif diff --git a/retroarch_data.h b/retroarch_data.h index 4dee08eda7..c3b076df9a 100644 --- a/retroarch_data.h +++ b/retroarch_data.h @@ -62,12 +62,6 @@ #define DEBUG_INFO_FILENAME "debug_info.txt" -#define MAGIC_INDEX 0 -#define SERIALIZER_INDEX 1 -#define CRC_INDEX 2 -#define STATE_SIZE_INDEX 3 - - #define TIME_TO_FPS(last_time, new_time, frames) ((1000000.0f * (frames)) / ((new_time) - (last_time))) #define MENU_SOUND_FORMATS "ogg|mod|xm|s3m|mp3|flac|wav" @@ -1249,12 +1243,6 @@ enum runloop_state RUNLOOP_STATE_QUIT }; -enum rarch_movie_type -{ - RARCH_MOVIE_PLAYBACK = 0, - RARCH_MOVIE_RECORD -}; - enum poll_type_override_t { POLL_TYPE_OVERRIDE_DONTCARE = 0, diff --git a/retroarch_fwd_decls.h b/retroarch_fwd_decls.h index d952492537..9b9b916cc5 100644 --- a/retroarch_fwd_decls.h +++ b/retroarch_fwd_decls.h @@ -130,13 +130,6 @@ static bool video_driver_find_driver( settings_t *settings, const char *prefix, bool verbosity_enabled); -#ifdef HAVE_BSV_MOVIE -static void bsv_movie_deinit(runloop_state_t *p_runloop); -static bool bsv_movie_init(runloop_state_t *p_runloop); -static bool bsv_movie_check(runloop_state_t *p_runloop, - settings_t *settings); -#endif - static void driver_uninit(struct rarch_state *p_rarch, int flags); static void drivers_init(struct rarch_state *p_rarch, settings_t *settings, diff --git a/runloop.c b/runloop.c index 11205c8371..4823db94a6 100755 --- a/runloop.c +++ b/runloop.c @@ -22,6 +22,7 @@ #endif #include "configuration.h" +#include "content.h" #include "file_path_special.h" #include "paths.h" #include "retroarch.h" @@ -516,6 +517,337 @@ error: return NULL; } +#ifdef HAVE_BSV_MOVIE +/* BSV MOVIE */ +static bool bsv_movie_init_playback( + bsv_movie_t *handle, const char *path) +{ + uint32_t state_size = 0; + uint32_t content_crc = 0; + uint32_t header[4] = {0}; + intfstream_t *file = intfstream_open_file(path, + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); + + if (!file) + { + RARCH_ERR("Could not open BSV file for playback, path : \"%s\".\n", path); + return false; + } + + handle->file = file; + handle->playback = true; + + intfstream_read(handle->file, header, sizeof(uint32_t) * 4); + /* Compatibility with old implementation that + * used incorrect documentation. */ + if (swap_if_little32(header[MAGIC_INDEX]) != BSV_MAGIC + && swap_if_big32(header[MAGIC_INDEX]) != BSV_MAGIC) + { + RARCH_ERR("%s\n", msg_hash_to_str(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE)); + return false; + } + + content_crc = content_get_crc(); + + if (content_crc != 0) + if (swap_if_big32(header[CRC_INDEX]) != content_crc) + RARCH_WARN("%s.\n", msg_hash_to_str(MSG_CRC32_CHECKSUM_MISMATCH)); + + state_size = swap_if_big32(header[STATE_SIZE_INDEX]); + +#if 0 + RARCH_ERR("----- debug %u -----\n", header[0]); + RARCH_ERR("----- debug %u -----\n", header[1]); + RARCH_ERR("----- debug %u -----\n", header[2]); + RARCH_ERR("----- debug %u -----\n", header[3]); +#endif + + if (state_size) + { + retro_ctx_size_info_t info; + retro_ctx_serialize_info_t serial_info; + uint8_t *buf = (uint8_t*)malloc(state_size); + + if (!buf) + return false; + + handle->state = buf; + handle->state_size = state_size; + if (intfstream_read(handle->file, + handle->state, state_size) != state_size) + { + RARCH_ERR("%s\n", msg_hash_to_str(MSG_COULD_NOT_READ_STATE_FROM_MOVIE)); + return false; + } + + core_serialize_size( &info); + + if (info.size == state_size) + { + serial_info.data_const = handle->state; + serial_info.size = state_size; + core_unserialize(&serial_info); + } + else + RARCH_WARN("%s\n", + msg_hash_to_str(MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION)); + } + + handle->min_file_pos = sizeof(header) + state_size; + + return true; +} + +static bool bsv_movie_init_record( + bsv_movie_t *handle, const char *path) +{ + retro_ctx_size_info_t info; + uint32_t state_size = 0; + uint32_t content_crc = 0; + uint32_t header[4] = {0}; + intfstream_t *file = intfstream_open_file(path, + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); + + if (!file) + { + RARCH_ERR("Could not open BSV file for recording, path : \"%s\".\n", path); + return false; + } + + handle->file = file; + + content_crc = content_get_crc(); + + /* This value is supposed to show up as + * BSV1 in a HEX editor, big-endian. */ + header[MAGIC_INDEX] = swap_if_little32(BSV_MAGIC); + header[CRC_INDEX] = swap_if_big32(content_crc); + + core_serialize_size(&info); + + state_size = (unsigned)info.size; + + header[STATE_SIZE_INDEX] = swap_if_big32(state_size); + + intfstream_write(handle->file, header, 4 * sizeof(uint32_t)); + + handle->min_file_pos = sizeof(header) + state_size; + handle->state_size = state_size; + + if (state_size) + { + retro_ctx_serialize_info_t serial_info; + uint8_t *st = (uint8_t*)malloc(state_size); + + if (!st) + return false; + + handle->state = st; + + serial_info.data = handle->state; + serial_info.size = state_size; + + core_serialize(&serial_info); + + intfstream_write(handle->file, + handle->state, state_size); + } + + return true; +} + +static void bsv_movie_free(bsv_movie_t *handle) +{ + if (!handle) + return; + + intfstream_close(handle->file); + free(handle->file); + + free(handle->state); + free(handle->frame_pos); + free(handle); +} + +static bsv_movie_t *bsv_movie_init_internal(const char *path, + enum rarch_movie_type type) +{ + size_t *frame_pos = NULL; + bsv_movie_t *handle = (bsv_movie_t*)calloc(1, sizeof(*handle)); + + if (!handle) + return NULL; + + if (type == RARCH_MOVIE_PLAYBACK) + { + if (!bsv_movie_init_playback(handle, path)) + goto error; + } + else if (!bsv_movie_init_record(handle, path)) + goto error; + + /* Just pick something really large + * ~1 million frames rewind should do the trick. */ + if (!(frame_pos = (size_t*)calloc((1 << 20), sizeof(size_t)))) + goto error; + + handle->frame_pos = frame_pos; + + handle->frame_pos[0] = handle->min_file_pos; + handle->frame_mask = (1 << 20) - 1; + + return handle; + +error: + bsv_movie_free(handle); + return NULL; +} + +bool bsv_movie_init(runloop_state_t *p_runloop) +{ + if (p_runloop->bsv_movie_state.movie_start_playback) + { + if (!(p_runloop->bsv_movie_state_handle = bsv_movie_init_internal( + p_runloop->bsv_movie_state.movie_start_path, + RARCH_MOVIE_PLAYBACK))) + { + RARCH_ERR("%s: \"%s\".\n", + msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE), + p_runloop->bsv_movie_state.movie_start_path); + return false; + } + + p_runloop->bsv_movie_state.movie_playback = true; + runloop_msg_queue_push(msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK), + 2, 180, false, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + RARCH_LOG("%s.\n", msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK)); + + return true; + } + else if (p_runloop->bsv_movie_state.movie_start_recording) + { + char msg[8192]; + + if (!(p_runloop->bsv_movie_state_handle = bsv_movie_init_internal( + p_runloop->bsv_movie_state.movie_start_path, + RARCH_MOVIE_RECORD))) + { + runloop_msg_queue_push( + msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD), + 1, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + RARCH_ERR("%s.\n", + msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); + return false; + } + + snprintf(msg, sizeof(msg), + "%s \"%s\".", + msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), + p_runloop->bsv_movie_state.movie_start_path); + + runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + RARCH_LOG("%s \"%s\".\n", + msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), + p_runloop->bsv_movie_state.movie_start_path); + + return true; + } + + return false; +} + +void bsv_movie_deinit(runloop_state_t *p_runloop) +{ + if (p_runloop->bsv_movie_state_handle) + bsv_movie_free(p_runloop->bsv_movie_state_handle); + p_runloop->bsv_movie_state_handle = NULL; +} + +static bool runloop_check_movie_init(runloop_state_t *p_runloop, + settings_t *settings) +{ + char msg[16384], path[8192]; + int state_slot = settings->ints.state_slot; + + msg[0] = path[0] = '\0'; + + configuration_set_uint(settings, settings->uints.rewind_granularity, 1); + + if (state_slot > 0) + snprintf(path, sizeof(path), "%s%d.bsv", + p_runloop->bsv_movie_state.movie_path, + state_slot); + else + snprintf(path, sizeof(path), "%s.bsv", + p_runloop->bsv_movie_state.movie_path); + + snprintf(msg, sizeof(msg), "%s \"%s\".", + msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), + path); + + if (!(p_runloop->bsv_movie_state_handle = bsv_movie_init_internal( + path, RARCH_MOVIE_RECORD))) + { + runloop_msg_queue_push( + msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD), + 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + RARCH_ERR("%s\n", + msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); + return false; + } + + runloop_msg_queue_push(msg, 2, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + RARCH_LOG("%s \"%s\".\n", + msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), + path); + + return true; +} + +bool bsv_movie_check( + runloop_state_t *p_runloop, + settings_t *settings) +{ + if (!p_runloop->bsv_movie_state_handle) + return runloop_check_movie_init(p_runloop, settings); + + if (p_runloop->bsv_movie_state.movie_playback) + { + /* Checks if movie is being played back. */ + if (!p_runloop->bsv_movie_state.movie_end) + return false; + runloop_msg_queue_push( + msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED), 2, 180, false, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED)); + + p_runloop->bsv_movie_state.movie_end = false; + p_runloop->bsv_movie_state.movie_playback = false; + + goto end; + } + + /* Checks if movie is being recorded. */ + if (!p_runloop->bsv_movie_state_handle) + return false; + + runloop_msg_queue_push( + msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED), 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED)); + +end: + bsv_movie_deinit(p_runloop); + return true; +} +#endif + + /* Fetches core options path for current core/content * - path: path from which options should be read * from/saved to