//process frame for movie, MUST be called after input updates void movie_frame() { if((nes->movie.mode & MOVIE_PLAY) && nes->movie.endframe == nes->ppu.frames) { log_printf("movie_frame: reached end of movie, stopping.\n"); movie_stop(); } else { nes->inputdev[0]->movie(nes->movie.mode); nes->inputdev[1]->movie(nes->movie.mode); nes->expdev->movie(nes->movie.mode); } }
int movie_save(char *filename) { memfile_t *file; u8 flags; if(filename) { if(nes->movie.filename) mem_free(nes->movie.filename); nes->movie.filename = mem_strdup(filename); } else if(nes->movie.filename == 0) { log_printf("movie_save: error! no filename given and movie doesnt have filename set\n"); return(0); } if(nes->movie.len == 0) { log_printf("movie_save: no movie data to save, just setting filename\n"); return(0); } if(nes->movie.mode & MOVIE_RECORD) { log_printf("movie_save: still recording, stopping...\n"); movie_stop(); } if((file = memfile_open(nes->movie.filename,"wb")) == 0) { log_printf("movie_save: error opening movie '%s'\n",filename); return(1); } memfile_seek(nes->movie.state,0,SEEK_SET); flags = (nes->movie.mode & MOVIE_TEST) ? 1 : 0; //header (just ident for now) memfile_write(movie_ident,1,4,file); memfile_write(&flags,1,sizeof(u8),file); //save input device configuration memfile_write(&nes->inputdev[0]->id,1,sizeof(int),file); memfile_write(&nes->inputdev[1]->id,1,sizeof(int),file); memfile_write(&nes->expdev->id,1,sizeof(int),file); //save movie data memfile_write(&nes->movie.startframe,1,sizeof(u32),file); memfile_write(&nes->movie.endframe,1,sizeof(u32),file); memfile_write(&nes->movie.crc32,1,sizeof(u32),file); memfile_write(&nes->movie.len,1,sizeof(u32),file); log_printf("movie_save: start, end = %d, %d :: len = %d bytes\n",nes->movie.startframe,nes->movie.endframe,nes->movie.len); memfile_write(nes->movie.data,1,nes->movie.len,file); //append savestate to end of movie memfile_copy(file,nes->movie.state,memfile_size(nes->movie.state)); memfile_close(file); return(0); }
int rzx_stop_recording( void ) { libspectrum_byte *buffer; size_t length; libspectrum_error libspec_error; int error; if( !rzx_recording ) return 0; /* Stop recording data */ rzx_recording = 0; if( settings_current.movie_stop_after_rzx ) movie_stop(); /* Embed final snapshot */ if( !rzx_competition_mode ) rzx_add_snap( rzx, 0 ); libspectrum_free( rzx_in_bytes ); rzx_in_bytes = NULL; rzx_in_allocated = 0; ui_menu_activate( UI_MENU_ITEM_RECORDING, 0 ); ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 0 ); libspectrum_creator_set_competition_code( fuse_creator, settings_current.competition_code ); length = 0; buffer = NULL; libspec_error = libspectrum_rzx_write( &buffer, &length, rzx, LIBSPECTRUM_ID_UNKNOWN, fuse_creator, settings_current.rzx_compression, rzx_competition_mode ? &rzx_key : NULL ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( rzx_filename ); libspectrum_rzx_free( rzx ); return libspec_error; } error = utils_write_file( rzx_filename, buffer, length ); libspectrum_free( rzx_filename ); if( error ) { libspectrum_free( buffer ); libspectrum_rzx_free( rzx ); return error; } libspectrum_free( buffer ); libspec_error = libspectrum_rzx_free( rzx ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) return libspec_error; return 0; }
virtual void set_edit_mode(i4_bool yes_no) { //show our views, set context //code is quite like g1_editor_class::set_edit_mode if (yes_no) { i4_unlink(i4gets("play_savename")); i4_user_message_event_class movie_stop(G1_STOP_MOVIE); // stop game movie if there was one i4_kernel.send_event(i4_current_app, &movie_stop); need_save=i4_T; g1_cwin_man_class::destroy_views(); // kill the normal game views maxtool_mode=i4_T; g1_change_key_context(G1_MAXTOOL_MODE); if (menu) { delete menu; } menu=0; menu=li_create_pull_menu("scheme/menu_maxtool.scm"); menu->show(parent, 0,0); create_views(); li_call("Pause"); i4_kernel.request_events(this, i4_device_class::FLAG_DISPLAY_CHANGE| i4_device_class::FLAG_USER_MESSAGE); } else { i4_kernel.unrequest_events(this, i4_device_class::FLAG_DISPLAY_CHANGE| i4_device_class::FLAG_USER_MESSAGE); if (menu) { menu->hide(); } delete menu; menu=0; //close_windows(); destroy_views(); maxtool_mode=i4_F; g1_cwin_man_class::create_views(); // create the normal game views li_call("Pause"); } }
int rzx_stop_playback( int add_interrupt ) { libspectrum_error libspec_error; rzx_playback = 0; if( settings_current.movie_stop_after_rzx ) movie_stop(); ui_menu_activate( UI_MENU_ITEM_RECORDING, 0 ); ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 0 ); event_remove_type( sentinel_event ); /* We've now finished with the RZX file, so add an end of frame event if we've been requested to do so; we don't if we just run out of frames, as this occurs just before a normal end of frame and everything works normally as rzx_playback is now zero again */ if( add_interrupt ) { event_add( machine_current->timings.tstates_per_frame, spectrum_frame_event ); /* We're no longer doing RZX playback, so tstates now be <= the normal frame count */ if( tstates > machine_current->timings.tstates_per_frame ) tstates = machine_current->timings.tstates_per_frame; } else { /* Ensure that tstates will be zero after it is reduced in spectrum_frame() */ tstates = machine_current->timings.tstates_per_frame; } libspec_error = libspectrum_rzx_free( rzx ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) return libspec_error; debugger_event( end_event ); return 0; }
//helpers for reading/writing movie data u8 movie_read_u8() { u8 ret; //make sure we are playing if((nes->movie.mode & MOVIE_PLAY) == 0) { log_printf("movie_read_u8: not playing, cannot read data\n"); return(0xFF); } //make sure we dont read past end of the data if(nes->movie.pos < nes->movie.len) ret = nes->movie.data[nes->movie.pos++]; else { log_printf("movie_read_u8: playing past end of movie, stopping\n"); movie_stop(); ret = 0xFF; } return(ret); }
int machine_select( libspectrum_machine type ) { int i; int error; /* We don't want to have to deal with screen size changes in the movie code and recording movies where we change machines seems pretty obscure */ movie_stop(); for( i=0; i < machine_count; i++ ) { if( machine_types[i]->machine == type ) { machine_location = i; error = machine_select_machine( machine_types[i] ); if( !error ) return 0; /* If we couldn't select the new machine type, try falling back to plain old 48K */ if( type != LIBSPECTRUM_MACHINE_48 ) error = machine_select( LIBSPECTRUM_MACHINE_48 ); /* If that still didn't work, give up */ if( error ) { ui_error( UI_ERROR_ERROR, "can't select 48K machine. Giving up." ); fuse_abort(); } else { ui_error( UI_ERROR_INFO, "selecting 48K machine" ); return 0; } return 0; } } ui_error( UI_ERROR_ERROR, "machine type %d unknown", type ); return 1; }