@@ -60,6 +60,25 @@ bool bsv_movie_skip_to_next_checkpoint_impl(bsv_movie_t *movie);
6060bool bsv_movie_skip_to_prev_checkpoint_impl (bsv_movie_t * movie );
6161bool bsv_movie_seek_to_pos_impl (bsv_movie_t * movie , int64_t pos );
6262
63+ void bsv_movie_store_frame (bsv_movie_t * handle )
64+ {
65+ retro_ctx_serialize_info_t serial_info ;
66+ serial_info .size = core_serialize_size ();
67+ if (handle -> cur_save_size < serial_info .size && handle -> cur_save )
68+ {
69+ free (handle -> cur_save );
70+ handle -> cur_save = NULL ;
71+ }
72+ if (!handle -> cur_save )
73+ {
74+ handle -> cur_save_size = serial_info .size ;
75+ handle -> cur_save = malloc (serial_info .size );
76+ handle -> cur_save_valid = false;
77+ }
78+ serial_info .data = handle -> cur_save ;
79+ core_serialize (& serial_info );
80+ }
81+
6382bool bsv_movie_reset_playback (bsv_movie_t * handle )
6483{
6584 uint32_t state_size = 0 ;
@@ -153,6 +172,7 @@ bool bsv_movie_reset_recording(bsv_movie_t *handle)
153172 intfstream_write (handle -> file , & compression , 1 );
154173 intfstream_write (handle -> file , & encoding , 1 );
155174 handle -> frame_counter = 0 ;
175+ bsv_movie_store_frame (handle );
156176 state_size = 2 + bsv_movie_write_checkpoint (handle , compression , encoding );
157177 handle -> min_file_pos = intfstream_tell (handle -> file );
158178 /* 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
479499 return ret ;
480500}
481501
502+ void bsv_movie_start_frame (input_driver_state_t * input_st ) {
503+ unsigned checkpoint_interval = config_get_ptr ()-> uints .replay_checkpoint_interval ;
504+ bsv_movie_t * handle = input_st -> bsv_movie_state_handle ;
505+ if (!handle || handle -> playback )
506+ return ;
507+ /* Is this a checkpoint recording frame? */
508+ if ((input_st -> bsv_movie_state .flags & BSV_FLAG_MOVIE_FORCE_CHECKPOINT ) ||
509+ ((checkpoint_interval != 0 )
510+ && (handle -> frame_counter > 0 )
511+ && (handle -> frame_counter % (checkpoint_interval * 60 ) == 0 )))
512+ {
513+ bsv_movie_store_frame (handle );
514+ handle -> make_checkpoint_frame = true;
515+ input_st -> bsv_movie_state .flags &= ~BSV_FLAG_MOVIE_FORCE_CHECKPOINT ;
516+ }
517+ }
518+
482519int64_t bsv_movie_write_checkpoint (bsv_movie_t * handle , uint8_t compression , uint8_t encoding )
483520{
484521 int64_t ret = -1 ;
@@ -487,33 +524,18 @@ int64_t bsv_movie_write_checkpoint(bsv_movie_t *handle, uint8_t compression, uin
487524 size_t size_swap ;
488525 uint8_t * encoded_data = NULL , * compressed_encoded_data = NULL ;
489526 bool owns_encoded = false, owns_compressed_encoded = false;
490- retro_ctx_serialize_info_t serial_info ;
491- serial_info .size = core_serialize_size ();
492- if (handle -> cur_save_size < serial_info .size )
493- {
494- free (handle -> cur_save );
495- handle -> cur_save = NULL ;
496- }
497- if (!handle -> cur_save )
498- {
499- handle -> cur_save_size = serial_info .size ;
500- handle -> cur_save = malloc (serial_info .size );
501- handle -> cur_save_valid = false;
502- }
503- serial_info .data = handle -> cur_save ;
504- core_serialize (& serial_info );
505527 switch (encoding )
506528 {
507529 case REPLAY_CHECKPOINT2_ENCODING_RAW :
508- encoded_size = serial_info . size ;
509- encoded_data = serial_info . data ;
530+ encoded_size = handle -> cur_save_size ;
531+ encoded_data = handle -> cur_save ;
510532 break ;
511533#ifdef HAVE_STATESTREAM
512534 case REPLAY_CHECKPOINT2_ENCODING_STATESTREAM :
513- encoded_size = serial_info . size + serial_info . size / 2 ;
535+ encoded_size = handle -> cur_save_size + handle -> cur_save_size / 2 ;
514536 encoded_data = malloc (encoded_size );
515537 owns_encoded = true;
516- encoded_size = bsv_movie_write_deduped_state (handle , serial_info . data , serial_info . size , encoded_data , encoded_size );
538+ encoded_size = bsv_movie_write_deduped_state (handle , handle -> cur_save , handle -> cur_save_size , encoded_data , encoded_size );
517539 break ;
518540#endif
519541 default :
@@ -564,7 +586,7 @@ int64_t bsv_movie_write_checkpoint(bsv_movie_t *handle, uint8_t compression, uin
564586 goto exit ;
565587 }
566588 /* uncompressed, unencoded size */
567- size_ = swap_if_big32 (serial_info . size );
589+ size_ = swap_if_big32 (handle -> cur_save_size );
568590 if (intfstream_write (handle -> file , & size_ , sizeof (uint32_t )) < (int64_t )sizeof (uint32_t ))
569591 {
570592 ret = -1 ;
@@ -757,6 +779,17 @@ void bsv_movie_scan_from_start(bsv_movie_t *movie, int32_t len)
757779 bsv_movie_scan_to (movie , len );
758780}
759781
782+ void bsv_movie_dequeue_next (input_driver_state_t * input_st )
783+ {
784+ if (input_st -> bsv_movie_state_next_handle )
785+ {
786+ if (input_st -> bsv_movie_state_handle )
787+ bsv_movie_deinit (input_st );
788+ input_st -> bsv_movie_state_handle = input_st -> bsv_movie_state_next_handle ;
789+ input_st -> bsv_movie_state_next_handle = NULL ;
790+ }
791+ }
792+
760793void bsv_movie_next_frame (input_driver_state_t * input_st )
761794{
762795 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)
765798 bsv_movie_state_handle to bsv_movie_state_next_handle and clear
766799 next_handle */
767800 bsv_movie_t * handle = input_st -> bsv_movie_state_handle ;
768- if (input_st -> bsv_movie_state_next_handle )
769- {
770- if (handle )
771- bsv_movie_deinit (input_st );
772- handle = input_st -> bsv_movie_state_next_handle ;
773- input_st -> bsv_movie_state_handle = handle ;
774- input_st -> bsv_movie_state_next_handle = NULL ;
775- }
776801
777802 if (!handle )
778803 return ;
@@ -805,10 +830,7 @@ void bsv_movie_next_frame(input_driver_state_t *input_st)
805830 handle -> input_event_count = 0 ;
806831
807832 /* Maybe record checkpoint */
808- if ((input_st -> bsv_movie_state .flags & BSV_FLAG_MOVIE_FORCE_CHECKPOINT ) ||
809- ((checkpoint_interval != 0 )
810- && (handle -> frame_counter > 0 )
811- && (handle -> frame_counter % (checkpoint_interval * 60 ) == 0 )))
833+ if (handle -> make_checkpoint_frame )
812834 {
813835 uint8_t frame_tok = REPLAY_TOKEN_CHECKPOINT2_FRAME ;
814836 uint8_t compression = handle -> checkpoint_compression ;
@@ -817,7 +839,7 @@ void bsv_movie_next_frame(input_driver_state_t *input_st)
817839#else
818840 uint8_t encoding = REPLAY_CHECKPOINT2_ENCODING_RAW ;
819841#endif
820- input_st -> bsv_movie_state . flags &= ~ BSV_FLAG_MOVIE_FORCE_CHECKPOINT ;
842+ handle -> make_checkpoint_frame = false ;
821843 /* "next frame is a checkpoint" */
822844 intfstream_write (handle -> file , (uint8_t * )(& frame_tok ), sizeof (uint8_t ));
823845 /* compression and encoding schemes */
@@ -1276,7 +1298,6 @@ int16_t bsv_movie_read_state(input_driver_state_t *input_st,
12761298#endif
12771299 return bsv_result ;
12781300 }
1279- input_st -> bsv_movie_state .flags |= BSV_FLAG_MOVIE_END ;
12801301 return 0 ;
12811302}
12821303
0 commit comments