int rzx_start_playback_from_buffer( const unsigned char *buffer, size_t length ) { int error; libspectrum_snap* snap; if( rzx_recording ) return 0; rzx = libspectrum_rzx_alloc(); error = libspectrum_rzx_read( rzx, buffer, length ); if( error ) return error; snap = rzx_get_initial_snapshot(); if( !snap ) { error = utils_open_snap(); if( error ) { libspectrum_rzx_free( rzx ); return error; } } error = start_playback( rzx ); if( error ) { libspectrum_rzx_free( rzx ); return error; } return 0; }
int rzx_finalise_recording( const char *filename ) { libspectrum_byte *buffer; size_t length; libspectrum_error libspec_error; int error; utils_file file; if( rzx_recording || rzx_playback ) return 1; error = utils_read_file( filename, &file ); if( error ) return error; rzx = libspectrum_rzx_alloc(); libspec_error = libspectrum_rzx_read( rzx, file.buffer, file.length ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { utils_close_file( &file ); libspectrum_rzx_free( rzx ); return libspec_error; } utils_close_file( &file ); libspec_error = libspectrum_rzx_finalise( rzx ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_rzx_free( rzx ); return libspec_error; } /* Write the file */ 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_rzx_free( rzx ); return libspec_error; } error = utils_write_file( filename, buffer, length ); if( error ) { libspectrum_free( buffer ); libspectrum_rzx_free( rzx ); return error; } libspectrum_free( buffer ); libspectrum_rzx_free( rzx ); 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; }
int rzx_start_recording( const char *filename, int embed_snapshot ) { int error; if( rzx_playback ) return 1; rzx = libspectrum_rzx_alloc(); /* Store the filename */ rzx_filename = utils_safe_strdup( filename ); /* If we're embedding a snapshot, create it now */ if( embed_snapshot ) { error = rzx_add_snap( rzx, 0 ); if( error ) { libspectrum_free( rzx_filename ); libspectrum_rzx_free( rzx ); return error; } } start_recording( rzx, settings_current.competition_mode ); return 0; }
int rzx_continue_recording( const char *filename ) { utils_file file; libspectrum_error libspec_error; int error; libspectrum_snap* snap = NULL; libspectrum_rzx_iterator last_it = NULL; if( rzx_recording || rzx_playback ) return 1; /* Store the filename */ rzx_filename = utils_safe_strdup( filename ); error = utils_read_file( filename, &file ); if( error ) return error; rzx = libspectrum_rzx_alloc(); libspec_error = libspectrum_rzx_read( rzx, file.buffer, file.length ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { utils_close_file( &file ); return libspec_error; } utils_close_file( &file ); /* Get final snapshot */ last_it = libspectrum_rzx_iterator_last( rzx ); if( last_it ) snap = libspectrum_rzx_iterator_get_snap( last_it ); if( snap ) { error = snapshot_copy_from( snap ); if( error ) return error; } else { ui_error( UI_ERROR_WARNING, "RZX file cannot be continued" ); libspectrum_free( rzx_filename ); libspectrum_rzx_free( rzx ); return 1; } start_recording( rzx, 0 ); return 0; }
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; }
int rzx_start_playback( const char *filename, int check_snapshot ) { utils_file file; libspectrum_error libspec_error; int error; libspectrum_snap* snap; if( rzx_recording ) return 1; rzx = libspectrum_rzx_alloc(); error = utils_read_file( filename, &file ); if( error ) return error; libspec_error = libspectrum_rzx_read( rzx, file.buffer, file.length ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { utils_close_file( &file ); return libspec_error; } utils_close_file( &file ); snap = rzx_get_initial_snapshot(); if( !snap && check_snapshot ) { /* We need to load an external snapshot. Could be skipped if the snapshot is preloaded from command line */ error = utils_open_snap(); if( error ) return error; } error = start_playback( rzx ); if( error ) { libspectrum_rzx_free( rzx ); return error; } return 0; }
int main( int argc, char **argv ) { unsigned char *buffer; size_t length; const char *rzxfile; libspectrum_rzx *rzx; libspectrum_error error; libspectrum_dword keyid = 0; libspectrum_signature signature; struct rzx_key *key; int c; int bad_option = 0; struct option long_options[] = { { "version", 0, NULL, 'V' }, { "help", 0, NULL, 'h' }, { 0, 0, 0, 0 } }; progname = argv[0]; while( ( c = getopt_long( argc, argv, "Vh", long_options, NULL ) ) != -1 ) { switch( c ) { case 'V': show_version(); exit( 0 ); case 'h': show_help(); exit( 0 ); case '?': /* getopt prints an error message to stderr */ bad_option = 1; break; default: bad_option = 1; fprintf( stderr, "%s: unknown option `%c'\n", progname, (char) c ); break; } } argc -= optind; argv += optind; if( bad_option ) { fprintf( stderr, "Try `%s --help' for more information.\n", progname ); return bad_option; } if( argc < 1 ) { fprintf( stderr, "%s: usage: %s <rzxfile>\n", progname, progname ); fprintf( stderr, "Try `%s --help' for more information.\n", progname ); return 2; } if( init_libspectrum() ) return 16; rzxfile = argv[0]; rzx = libspectrum_rzx_alloc(); if( read_file( rzxfile, &buffer, &length ) ) return 16; if( libspectrum_rzx_read( rzx, buffer, length ) ) { free( buffer ); return 16; } keyid = libspectrum_rzx_get_keyid( rzx ); if( !keyid ) { printf( "%s: no key ID found in '%s'\n", progname, rzxfile ); libspectrum_rzx_free( rzx ); free( buffer ); return 16; } for( key = known_keys; key->id; key++ ) if( keyid == key->id ) break; if( !key->id ) { printf( "%s: don't know anything about key ID %08x\n", progname, keyid ); libspectrum_rzx_free( rzx ); free( buffer ); return 16; } error = libspectrum_rzx_get_signature( rzx, &signature ); if( error ) { libspectrum_rzx_free( rzx ); free( buffer ); return 16; } error = libspectrum_verify_signature( &signature, &( key->key ) ); if( error && error != LIBSPECTRUM_ERROR_SIGNATURE ) { libspectrum_signature_free( &signature ); libspectrum_rzx_free( rzx ); free( buffer ); return 16; } free( buffer ); libspectrum_rzx_free( rzx ); free( rzx ); libspectrum_signature_free( &signature ); if( error == LIBSPECTRUM_ERROR_SIGNATURE ) { printf( "%s: BAD signature with key %08x (%s) in '%s'\n", progname, key->id, key->description, rzxfile ); return 1; } else { printf( "%s: good signature with key %08x (%s) in '%s'\n", progname, key->id, key->description, rzxfile ); return 0; } }