diff --git a/gfx/gfx_widgets.c b/gfx/gfx_widgets.c index 5029b9b6537b..d73d2ded83d7 100644 --- a/gfx/gfx_widgets.c +++ b/gfx/gfx_widgets.c @@ -188,6 +188,7 @@ void gfx_widgets_msg_queue_push( msg_widget->offset_y = 0; msg_widget->alpha = 1.0f; + msg_widget->alternative_look = (task && (task->flags & RETRO_TASK_FLG_ALTERNATIVE_LOOK)); msg_widget->width = 0; @@ -1168,7 +1169,7 @@ static void gfx_widgets_draw_task_msg( size_t task_percentage_offset = 0; char task_percentage[256] = ""; bool draw_msg_new = false; - bool msg_alternative = (task_get_flags(msg->task_ptr) & RETRO_TASK_FLG_ALTERNATIVE_LOOK); + bool msg_alternative = msg->alternative_look; if (msg->msg_new) draw_msg_new = !string_is_equal(msg->msg_new, msg->msg); diff --git a/gfx/gfx_widgets.h b/gfx/gfx_widgets.h index a62805d2d007..8fe215b6feb5 100644 --- a/gfx/gfx_widgets.h +++ b/gfx/gfx_widgets.h @@ -185,6 +185,7 @@ typedef struct disp_widget_msg int8_t task_progress; /* How many tasks have used this notification? */ uint8_t task_count; + bool alternative_look; } disp_widget_msg_t; typedef struct dispgfx_widget diff --git a/input/bsv/bsvmovie.c b/input/bsv/bsvmovie.c index 1cde9e47ba5e..48af5112dcba 100644 --- a/input/bsv/bsvmovie.c +++ b/input/bsv/bsvmovie.c @@ -60,6 +60,25 @@ bool bsv_movie_skip_to_next_checkpoint_impl(bsv_movie_t *movie); bool bsv_movie_skip_to_prev_checkpoint_impl(bsv_movie_t *movie); bool bsv_movie_seek_to_pos_impl(bsv_movie_t *movie, int64_t pos); +void bsv_movie_store_frame(bsv_movie_t *handle) +{ + retro_ctx_serialize_info_t serial_info; + serial_info.size = core_serialize_size(); + if (handle->cur_save_size < serial_info.size && handle->cur_save) + { + free(handle->cur_save); + handle->cur_save = NULL; + } + if (!handle->cur_save) + { + handle->cur_save_size = serial_info.size; + handle->cur_save = malloc(serial_info.size); + handle->cur_save_valid = false; + } + serial_info.data = handle->cur_save; + core_serialize(&serial_info); +} + bool bsv_movie_reset_playback(bsv_movie_t *handle) { uint32_t state_size = 0; @@ -153,6 +172,7 @@ bool bsv_movie_reset_recording(bsv_movie_t *handle) intfstream_write(handle->file, &compression, 1); intfstream_write(handle->file, &encoding, 1); handle->frame_counter = 0; + bsv_movie_store_frame(handle); state_size = 2 + bsv_movie_write_checkpoint(handle, compression, encoding); handle->min_file_pos = intfstream_tell(handle->file); /* Have to write initial state size header too */ @@ -479,6 +499,23 @@ bool bsv_movie_load_checkpoint(bsv_movie_t *handle, uint8_t compression, uint8_t return ret; } +void bsv_movie_start_frame(input_driver_state_t *input_st) { + unsigned checkpoint_interval = config_get_ptr()->uints.replay_checkpoint_interval; + bsv_movie_t *handle = input_st->bsv_movie_state_handle; + if (!handle || handle->playback) + return; + /* Is this a checkpoint recording frame? */ + if ((input_st->bsv_movie_state.flags & BSV_FLAG_MOVIE_FORCE_CHECKPOINT) || + ((checkpoint_interval != 0) + && (handle->frame_counter > 0) + && (handle->frame_counter % (checkpoint_interval*60) == 0))) + { + bsv_movie_store_frame(handle); + handle->make_checkpoint_frame = true; + input_st->bsv_movie_state.flags &= ~BSV_FLAG_MOVIE_FORCE_CHECKPOINT; + } +} + int64_t bsv_movie_write_checkpoint(bsv_movie_t *handle, uint8_t compression, uint8_t encoding) { int64_t ret = -1; @@ -487,33 +524,18 @@ int64_t bsv_movie_write_checkpoint(bsv_movie_t *handle, uint8_t compression, uin size_t size_swap; uint8_t *encoded_data = NULL, *compressed_encoded_data = NULL; bool owns_encoded = false, owns_compressed_encoded = false; - retro_ctx_serialize_info_t serial_info; - serial_info.size = core_serialize_size(); - if (handle->cur_save_size < serial_info.size) - { - free(handle->cur_save); - handle->cur_save = NULL; - } - if (!handle->cur_save) - { - handle->cur_save_size = serial_info.size; - handle->cur_save = malloc(serial_info.size); - handle->cur_save_valid = false; - } - serial_info.data = handle->cur_save; - core_serialize(&serial_info); switch (encoding) { case REPLAY_CHECKPOINT2_ENCODING_RAW: - encoded_size = serial_info.size; - encoded_data = serial_info.data; + encoded_size = handle->cur_save_size; + encoded_data = handle->cur_save; break; #ifdef HAVE_STATESTREAM case REPLAY_CHECKPOINT2_ENCODING_STATESTREAM: - encoded_size = serial_info.size + serial_info.size / 2; + encoded_size = handle->cur_save_size + handle->cur_save_size / 2; encoded_data = malloc(encoded_size); owns_encoded = true; - encoded_size = bsv_movie_write_deduped_state(handle, serial_info.data, serial_info.size, encoded_data, encoded_size); + encoded_size = bsv_movie_write_deduped_state(handle, handle->cur_save, handle->cur_save_size, encoded_data, encoded_size); break; #endif default: @@ -564,7 +586,7 @@ int64_t bsv_movie_write_checkpoint(bsv_movie_t *handle, uint8_t compression, uin goto exit; } /* uncompressed, unencoded size */ - size_ = swap_if_big32(serial_info.size); + size_ = swap_if_big32(handle->cur_save_size); if (intfstream_write(handle->file, &size_, sizeof(uint32_t)) < (int64_t)sizeof(uint32_t)) { ret = -1; @@ -757,6 +779,17 @@ void bsv_movie_scan_from_start(bsv_movie_t *movie, int32_t len) bsv_movie_scan_to(movie, len); } +void bsv_movie_dequeue_next(input_driver_state_t *input_st) +{ + if (input_st->bsv_movie_state_next_handle) + { + if (input_st->bsv_movie_state_handle) + bsv_movie_deinit(input_st); + input_st->bsv_movie_state_handle = input_st->bsv_movie_state_next_handle; + input_st->bsv_movie_state_next_handle = NULL; + } +} + void bsv_movie_next_frame(input_driver_state_t *input_st) { unsigned checkpoint_interval = config_get_ptr()->uints.replay_checkpoint_interval; @@ -765,14 +798,6 @@ void bsv_movie_next_frame(input_driver_state_t *input_st) bsv_movie_state_handle to bsv_movie_state_next_handle and clear next_handle */ bsv_movie_t *handle = input_st->bsv_movie_state_handle; - if (input_st->bsv_movie_state_next_handle) - { - if (handle) - bsv_movie_deinit(input_st); - handle = input_st->bsv_movie_state_next_handle; - input_st->bsv_movie_state_handle = handle; - input_st->bsv_movie_state_next_handle = NULL; - } if (!handle) return; @@ -805,10 +830,7 @@ void bsv_movie_next_frame(input_driver_state_t *input_st) handle->input_event_count = 0; /* Maybe record checkpoint */ - if ((input_st->bsv_movie_state.flags & BSV_FLAG_MOVIE_FORCE_CHECKPOINT) || - ((checkpoint_interval != 0) - && (handle->frame_counter > 0) - && (handle->frame_counter % (checkpoint_interval*60) == 0))) + if (handle->make_checkpoint_frame) { uint8_t frame_tok = REPLAY_TOKEN_CHECKPOINT2_FRAME; uint8_t compression = handle->checkpoint_compression; @@ -817,7 +839,7 @@ void bsv_movie_next_frame(input_driver_state_t *input_st) #else uint8_t encoding = REPLAY_CHECKPOINT2_ENCODING_RAW; #endif - input_st->bsv_movie_state.flags &= ~BSV_FLAG_MOVIE_FORCE_CHECKPOINT; + handle->make_checkpoint_frame = false; /* "next frame is a checkpoint" */ intfstream_write(handle->file, (uint8_t *)(&frame_tok), sizeof(uint8_t)); /* compression and encoding schemes */ @@ -1276,7 +1298,6 @@ int16_t bsv_movie_read_state(input_driver_state_t *input_st, #endif return bsv_result; } - input_st->bsv_movie_state.flags |= BSV_FLAG_MOVIE_END; return 0; } diff --git a/input/input_driver.h b/input/input_driver.h index b02046e258a9..105bb0a94b85 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -277,6 +277,7 @@ struct bsv_movie #endif uint8_t checkpoint_compression, checkpoint_encoding; + bool make_checkpoint_frame; uint8_t *last_save, *cur_save; size_t last_save_size, cur_save_size; @@ -1104,6 +1105,7 @@ void input_overlay_check_mouse_cursor(void); #ifdef HAVE_BSV_MOVIE void bsv_movie_frame_rewind(void); +void bsv_movie_start_frame(input_driver_state_t *input_st); void bsv_movie_next_frame(input_driver_state_t *input_st); bool bsv_movie_read_next_events(bsv_movie_t *handle, replay_checkpoint_behavior checkpoint_behavior, bool end_movie_on_eof); bool bsv_movie_reset_playback(bsv_movie_t *handle); @@ -1112,6 +1114,7 @@ void bsv_movie_finish_rewind(input_driver_state_t *input_st); void bsv_movie_deinit(input_driver_state_t *input_st); void bsv_movie_deinit_full(input_driver_state_t *input_st); void bsv_movie_enqueue(input_driver_state_t *input_st, bsv_movie_t *state, enum bsv_flags flags); +void bsv_movie_dequeue_next(input_driver_state_t *input_st); bool movie_commit_checkpoint(input_driver_state_t *input_st); bool movie_skip_to_prev_checkpoint(input_driver_state_t *input_st); diff --git a/runloop.c b/runloop.c index e8c2293a97d4..4a8f1dcaf296 100644 --- a/runloop.c +++ b/runloop.c @@ -7201,6 +7201,9 @@ int runloop_iterate(void) #endif } #endif +#ifdef HAVE_BSV_MOVIE + bsv_movie_dequeue_next(input_st); +#endif if (runloop_st->frame_time.callback) { @@ -7354,10 +7357,6 @@ int runloop_iterate(void) autosave_lock(); #endif -#ifdef HAVE_BSV_MOVIE - bsv_movie_next_frame(input_st); -#endif - if ( settings->bools.camera_allow && camera_st->cb.caps && camera_st->driver @@ -7370,6 +7369,10 @@ int runloop_iterate(void) /* Measure the time between core_run() and video_driver_frame() */ runloop_st->core_run_time = cpu_features_get_time_usec(); +#ifdef HAVE_BSV_MOVIE + bsv_movie_start_frame(input_st); +#endif + { #ifdef HAVE_RUNAHEAD bool run_ahead_enabled = settings->bools.run_ahead_enabled; @@ -7396,6 +7399,11 @@ int runloop_iterate(void) #endif core_run(); } +#ifdef HAVE_BSV_MOVIE + bsv_movie_finish_rewind(input_st); + bsv_movie_next_frame(input_st); +#endif + /* Increment runtime tick counter after each call to * core_run() or run_ahead() */ @@ -7413,12 +7421,6 @@ int runloop_iterate(void) presence_update(PRESENCE_GAME); #endif #ifdef HAVE_BSV_MOVIE - bsv_movie_finish_rewind(input_st); - if (input_st->bsv_movie_state.flags & BSV_FLAG_MOVIE_END) - { - movie_stop_playback(input_st); - command_event(CMD_EVENT_PAUSE, NULL); - } if (input_st->bsv_movie_state.flags & BSV_FLAG_MOVIE_END) { movie_stop_playback(input_st);