diff --git a/retroarch.c b/retroarch.c index 8b88303970..60e30e0e08 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1768,6 +1768,495 @@ void recording_driver_update_streaming_url(void) } } +/* BSV Movie */ +enum rarch_movie_type +{ + RARCH_MOVIE_PLAYBACK = 0, + RARCH_MOVIE_RECORD +}; + +struct bsv_state +{ + bool movie_start_recording; + bool movie_start_playback; + bool movie_playback; + bool eof_exit; + bool movie_end; + + /* Movie playback/recording support. */ + char movie_path[PATH_MAX_LENGTH]; + /* Immediate playback/recording. */ + char movie_start_path[PATH_MAX_LENGTH]; +}; + + +struct bsv_movie +{ + intfstream_t *file; + + /* A ring buffer keeping track of positions + * in the file for each frame. */ + size_t *frame_pos; + size_t frame_mask; + size_t frame_ptr; + + size_t min_file_pos; + + size_t state_size; + uint8_t *state; + + bool playback; + bool first_rewind; + bool did_rewind; +}; + +#define BSV_MAGIC 0x42535631 + +#define MAGIC_INDEX 0 +#define SERIALIZER_INDEX 1 +#define CRC_INDEX 2 +#define STATE_SIZE_INDEX 3 + +typedef struct bsv_movie bsv_movie_t; + +static bsv_movie_t *bsv_movie_state_handle = NULL; +static struct bsv_state bsv_movie_state; + +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); +#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 + + 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; + + handle->state = (uint8_t*)malloc(state_size); + if (!handle->state) + return false; + + 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 = bsv_movie_state_handle; + + if (!handle) + return; + + handle->did_rewind = true; + + if ( (handle->frame_ptr <= 1) + && (handle->frame_pos[0] == handle->min_file_pos)) + { + /* If we're at the beginning... */ + handle->frame_ptr = 0; + intfstream_seek(handle->file, (int)handle->min_file_pos, SEEK_SET); + } + else + { + /* First time rewind is performed, the old frame is simply replayed. + * However, playing back that frame caused us to read data, and push + * data to the ring buffer. + * + * Sucessively rewinding frames, we need to rewind past the read data, + * plus another. */ + handle->frame_ptr = (handle->frame_ptr - + (handle->first_rewind ? 1 : 2)) & handle->frame_mask; + intfstream_seek(handle->file, + (int)handle->frame_pos[handle->frame_ptr], SEEK_SET); + } + + if (intfstream_tell(handle->file) <= (long)handle->min_file_pos) + { + /* We rewound past the beginning. */ + + if (!handle->playback) + { + retro_ctx_serialize_info_t serial_info; + + /* If recording, we simply reset + * the starting point. Nice and easy. */ + + intfstream_seek(handle->file, 4 * sizeof(uint32_t), SEEK_SET); + + serial_info.data = handle->state; + serial_info.size = handle->state_size; + + core_serialize(&serial_info); + + intfstream_write(handle->file, handle->state, handle->state_size); + } + else + intfstream_seek(handle->file, (int)handle->min_file_pos, SEEK_SET); + } +} + +static bool bsv_movie_init_handle(const char *path, + enum rarch_movie_type type) +{ + bsv_movie_t *state = bsv_movie_init_internal(path, type); + if (!state) + return false; + + bsv_movie_state_handle = state; + return true; +} + +bool bsv_movie_init(void) +{ + bool set_granularity = false; + + if (bsv_movie_state.movie_start_playback) + { + if (!bsv_movie_init_handle(bsv_movie_state.movie_start_path, + RARCH_MOVIE_PLAYBACK)) + { + RARCH_ERR("%s: \"%s\".\n", + msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE), + bsv_movie_state.movie_start_path); + return false; + } + + 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)); + + set_granularity = true; + } + else if (bsv_movie_state.movie_start_recording) + { + if (!bsv_movie_init_handle(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; + } + + { + char msg[8192]; + snprintf(msg, sizeof(msg), + "%s \"%s\".", + msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), + 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), + bsv_movie_state.movie_start_path); + } + + set_granularity = true; + } + + if (set_granularity) + { + settings_t *settings = configuration_settings; + configuration_set_uint(settings, + settings->uints.rewind_granularity, 1); + } + + return true; +} + +#define bsv_movie_is_playback_on() (bsv_movie_state_handle && bsv_movie_state.movie_playback) +#define bsv_movie_is_playback_off() (bsv_movie_state_handle && !bsv_movie_state.movie_playback) + +static bool bsv_movie_get_input(int16_t *bsv_data) +{ + if (!bsv_movie_is_playback_on()) + return false; + if (intfstream_read(bsv_movie_state_handle->file, bsv_data, 1) != 1) + { + bsv_movie_state.movie_end = true; + return false; + } + + *bsv_data = swap_if_big16(*bsv_data); + + return true; +} + +void bsv_movie_set_path(const char *path) +{ + strlcpy(bsv_movie_state.movie_path, + path, sizeof(bsv_movie_state.movie_path)); +} + +void bsv_movie_deinit(void) +{ + if (!bsv_movie_state_handle) + return; + + bsv_movie_free(bsv_movie_state_handle); + bsv_movie_state_handle = NULL; +} + +static bool runloop_check_movie_init(void) +{ + char msg[16384], path[8192]; + settings_t *settings = configuration_settings; + + msg[0] = path[0] = '\0'; + + configuration_set_uint(settings, settings->uints.rewind_granularity, 1); + + if (settings->ints.state_slot > 0) + snprintf(path, sizeof(path), "%s%d", + bsv_movie_state.movie_path, + settings->ints.state_slot); + else + strlcpy(path, bsv_movie_state.movie_path, sizeof(path)); + + strlcat(path, + file_path_str(FILE_PATH_BSV_EXTENSION), + sizeof(path)); + + snprintf(msg, sizeof(msg), "%s \"%s\".", + msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), + path); + + bsv_movie_init_handle(path, RARCH_MOVIE_RECORD); + + if (!bsv_movie_state_handle) + { + 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(void) +{ + if (!bsv_movie_state_handle) + return runloop_check_movie_init(); + + if (bsv_movie_state.movie_playback) + { + /* Checks if movie is being played back. */ + if (!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)); + + command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); + + bsv_movie_state.movie_end = false; + bsv_movie_state.movie_playback = false; + + return true; + } + + /* Checks if movie is being recorded. */ + if (!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)); + + command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); + + return true; +} + + /* Input Remote */ #define DEFAULT_NETWORK_GAMEPAD_PORT 55400 @@ -2661,7 +3150,11 @@ static int16_t input_state_internal( } } - bsv_movie_set_input(&res); + if (bsv_movie_is_playback_off()) + { + res = swap_if_big16(res); + intfstream_write(bsv_movie_state_handle->file, &res, 1); + } return res; } @@ -11040,496 +11533,6 @@ struct string_list* video_driver_get_gpu_api_devices(enum gfx_ctx_api api) } -/* BSV Movie */ - -struct bsv_state -{ - bool movie_start_recording; - bool movie_start_playback; - bool movie_playback; - bool eof_exit; - bool movie_end; - - /* Movie playback/recording support. */ - char movie_path[PATH_MAX_LENGTH]; - /* Immediate playback/recording. */ - char movie_start_path[PATH_MAX_LENGTH]; -}; - - -struct bsv_movie -{ - intfstream_t *file; - - /* A ring buffer keeping track of positions - * in the file for each frame. */ - size_t *frame_pos; - size_t frame_mask; - size_t frame_ptr; - - size_t min_file_pos; - - size_t state_size; - uint8_t *state; - - bool playback; - bool first_rewind; - bool did_rewind; -}; - -#define BSV_MAGIC 0x42535631 - -#define MAGIC_INDEX 0 -#define SERIALIZER_INDEX 1 -#define CRC_INDEX 2 -#define STATE_SIZE_INDEX 3 - -typedef struct bsv_movie bsv_movie_t; - -static bsv_movie_t *bsv_movie_state_handle = NULL; -static struct bsv_state bsv_movie_state; - -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); -#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 - - 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; - - handle->state = (uint8_t*)malloc(state_size); - if (!handle->state) - return false; - - 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 = bsv_movie_state_handle; - - if (!handle) - return; - - handle->did_rewind = true; - - if ( (handle->frame_ptr <= 1) - && (handle->frame_pos[0] == handle->min_file_pos)) - { - /* If we're at the beginning... */ - handle->frame_ptr = 0; - intfstream_seek(handle->file, (int)handle->min_file_pos, SEEK_SET); - } - else - { - /* First time rewind is performed, the old frame is simply replayed. - * However, playing back that frame caused us to read data, and push - * data to the ring buffer. - * - * Sucessively rewinding frames, we need to rewind past the read data, - * plus another. */ - handle->frame_ptr = (handle->frame_ptr - - (handle->first_rewind ? 1 : 2)) & handle->frame_mask; - intfstream_seek(handle->file, - (int)handle->frame_pos[handle->frame_ptr], SEEK_SET); - } - - if (intfstream_tell(handle->file) <= (long)handle->min_file_pos) - { - /* We rewound past the beginning. */ - - if (!handle->playback) - { - retro_ctx_serialize_info_t serial_info; - - /* If recording, we simply reset - * the starting point. Nice and easy. */ - - intfstream_seek(handle->file, 4 * sizeof(uint32_t), SEEK_SET); - - serial_info.data = handle->state; - serial_info.size = handle->state_size; - - core_serialize(&serial_info); - - intfstream_write(handle->file, handle->state, handle->state_size); - } - else - intfstream_seek(handle->file, (int)handle->min_file_pos, SEEK_SET); - } -} - -static bool bsv_movie_init_handle(const char *path, - enum rarch_movie_type type) -{ - bsv_movie_t *state = bsv_movie_init_internal(path, type); - if (!state) - return false; - - bsv_movie_state_handle = state; - return true; -} - -bool bsv_movie_init(void) -{ - bool set_granularity = false; - - if (bsv_movie_state.movie_start_playback) - { - if (!bsv_movie_init_handle(bsv_movie_state.movie_start_path, - RARCH_MOVIE_PLAYBACK)) - { - RARCH_ERR("%s: \"%s\".\n", - msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE), - bsv_movie_state.movie_start_path); - return false; - } - - 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)); - - set_granularity = true; - } - else if (bsv_movie_state.movie_start_recording) - { - if (!bsv_movie_init_handle(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; - } - - { - char msg[8192]; - snprintf(msg, sizeof(msg), - "%s \"%s\".", - msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), - 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), - bsv_movie_state.movie_start_path); - } - - set_granularity = true; - } - - if (set_granularity) - { - settings_t *settings = configuration_settings; - configuration_set_uint(settings, - settings->uints.rewind_granularity, 1); - } - - return true; -} - -#define bsv_movie_is_playback_on() (bsv_movie_state_handle && bsv_movie_state.movie_playback) -#define bsv_movie_is_playback_off() (bsv_movie_state_handle && !bsv_movie_state.movie_playback) - -bool bsv_movie_get_input(int16_t *bsv_data) -{ - if (!bsv_movie_is_playback_on()) - return false; - if (intfstream_read(bsv_movie_state_handle->file, bsv_data, 1) != 1) - { - bsv_movie_state.movie_end = true; - return false; - } - - *bsv_data = swap_if_big16(*bsv_data); - - return true; -} - -void bsv_movie_set_input(int16_t *bsv_data) -{ - if (bsv_data && bsv_movie_is_playback_off()) - { - *bsv_data = swap_if_big16(*bsv_data); - intfstream_write(bsv_movie_state_handle->file, bsv_data, 1); - } -} - -void bsv_movie_set_path(const char *path) -{ - strlcpy(bsv_movie_state.movie_path, - path, sizeof(bsv_movie_state.movie_path)); -} - -void bsv_movie_deinit(void) -{ - if (!bsv_movie_state_handle) - return; - - bsv_movie_free(bsv_movie_state_handle); - bsv_movie_state_handle = NULL; -} - -static bool runloop_check_movie_init(void) -{ - char msg[16384], path[8192]; - settings_t *settings = configuration_settings; - - msg[0] = path[0] = '\0'; - - configuration_set_uint(settings, settings->uints.rewind_granularity, 1); - - if (settings->ints.state_slot > 0) - snprintf(path, sizeof(path), "%s%d", - bsv_movie_state.movie_path, - settings->ints.state_slot); - else - strlcpy(path, bsv_movie_state.movie_path, sizeof(path)); - - strlcat(path, - file_path_str(FILE_PATH_BSV_EXTENSION), - sizeof(path)); - - snprintf(msg, sizeof(msg), "%s \"%s\".", - msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), - path); - - bsv_movie_init_handle(path, RARCH_MOVIE_RECORD); - - if (!bsv_movie_state_handle) - { - 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(void) -{ - if (!bsv_movie_state_handle) - return runloop_check_movie_init(); - - if (bsv_movie_state.movie_playback) - { - /* Checks if movie is being played back. */ - if (!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)); - - command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); - - bsv_movie_state.movie_end = false; - bsv_movie_state.movie_playback = false; - - return true; - } - - /* Checks if movie is being recorded. */ - if (!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)); - - command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); - - return true; -} - /* Location */ static const location_driver_t *location_drivers[] = { diff --git a/retroarch.h b/retroarch.h index fff85ba8d3..012415ae87 100644 --- a/retroarch.h +++ b/retroarch.h @@ -2094,12 +2094,6 @@ extern const shader_backend_t gl_cg_backend; /* BSV Movie */ -enum rarch_movie_type -{ - RARCH_MOVIE_PLAYBACK = 0, - RARCH_MOVIE_RECORD -}; - void bsv_movie_deinit(void); bool bsv_movie_init(void); @@ -2108,10 +2102,6 @@ void bsv_movie_frame_rewind(void); void bsv_movie_set_path(const char *path); -bool bsv_movie_get_input(int16_t *bsv_data); - -void bsv_movie_set_input(int16_t *bsv_data); - bool bsv_movie_check(void); /* Location */