Example #1
0
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
}
Example #6
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;
}  
Example #7
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;
  }

}