blargg_err_t load_( Data_Reader& in ) { int file_size = in.remain(); if ( file_size <= h.size ) return blargg_err_file_type; RETURN_ERR( in.read( &h, h.size ) ); if ( !h.valid_tag() ) return blargg_err_file_type; int gd3_offset = get_le32( h.gd3_offset ) - 0x2C; int remain = file_size - h.size - gd3_offset; byte gd3_h [gd3_header_size]; if ( gd3_offset > 0 && remain >= gd3_header_size ) { RETURN_ERR( in.skip( gd3_offset ) ); RETURN_ERR( in.read( gd3_h, sizeof gd3_h ) ); int gd3_size = check_gd3_header( gd3_h, remain ); if ( gd3_size ) { RETURN_ERR( gd3.resize( gd3_size ) ); RETURN_ERR( in.read( gd3.begin(), gd3.size() ) ); } } return blargg_ok; }
blargg_err_t load_( Data_Reader& in ) { long file_size = in.remain(); if ( file_size <= Vgm_Emu::header_size ) return gme_wrong_file_type; RETURN_ERR( in.read( &h, Vgm_Emu::header_size ) ); RETURN_ERR( check_vgm_header( h ) ); long gd3_offset = get_le32( h.gd3_offset ) - 0x2C; long remain = file_size - Vgm_Emu::header_size - gd3_offset; byte gd3_h [gd3_header_size]; if ( gd3_offset > 0 && remain >= gd3_header_size ) { RETURN_ERR( in.skip( gd3_offset ) ); RETURN_ERR( in.read( gd3_h, sizeof gd3_h ) ); long gd3_size = check_gd3_header( gd3_h, remain ); if ( gd3_size ) { RETURN_ERR( gd3.resize( gd3_size ) ); RETURN_ERR( in.read( gd3.begin(), gd3.size() ) ); } } return 0; }
static blargg_err_t apply_ips_patch( Data_Reader& patch, byte** file, long* file_size ) { byte signature [5]; BLARGG_RETURN_ERR( patch.read( signature, sizeof signature ) ); if ( memcmp( signature, "PATCH", sizeof signature ) ) return "Not an IPS patch file"; while ( patch.remain() ) { // read offset byte buf [6]; BLARGG_RETURN_ERR( patch.read( buf, 3 ) ); long offset = buf [0] * 0x10000 + buf [1] * 0x100 + buf [2]; if ( offset == 'EOF' ) break; // read size BLARGG_RETURN_ERR( patch.read( buf, 2 ) ); long size = buf [0] * 0x100 + buf [1]; // size = 0 signals a run of identical bytes int fill = -1; if ( size == 0 ) { BLARGG_RETURN_ERR( patch.read( buf, 3 ) ); size = buf [0] * 0x100 + buf [1]; fill = buf [2]; } // expand file if new data is at exact end of file if ( offset == *file_size ) { *file_size = offset + size; void* p = realloc( *file, *file_size ); BLARGG_CHECK_ALLOC( p ); *file = (byte*) p; } //dprintf( "Patch offset: 0x%04X, size: 0x%04X\n", (int) offset, (int) size ); if ( offset < 0 || *file_size < offset + size ) return "IPS tried to patch past end of file"; // read/fill data if ( fill < 0 ) BLARGG_RETURN_ERR( patch.read( *file + offset, size ) ); else memset( *file + offset, fill, size ); } return blargg_success; }
blargg_err_t Rom_Data_::load_rom_data_( Data_Reader& in, int header_size, void* header_out, int fill, long pad_size ) { long file_offset = pad_size - header_size; rom_addr = 0; mask = 0; size_ = 0; rom.clear(); file_size_ = in.remain(); if ( file_size_ <= header_size ) // <= because there must be data after header return gme_wrong_file_type; blargg_err_t err = rom.resize( file_offset + file_size_ + pad_size ); if ( !err ) err = in.read( rom.begin() + file_offset, file_size_ ); if ( err ) { rom.clear(); return err; } file_size_ -= header_size; memcpy( header_out, &rom [file_offset], header_size ); memset( rom.begin() , fill, pad_size ); memset( rom.end() - pad_size, fill, pad_size ); return 0; }
blargg_err_t load_( Data_Reader& in ) { assert( offsetof (header_t,fields) == Hes_Emu::header_size + 0x20 ); blargg_err_t err = in.read( &h, sizeof h ); if ( err ) return (err == in.eof_error ? gme_wrong_file_type : err); return check_hes_header( &h ); }
blargg_err_t load_( Data_Reader& in ) { long file_size = in.remain(); if ( file_size < Snes_Spc::spc_min_file_size ) return gme_wrong_file_type; RETURN_ERR( in.read( &header, Spc_Emu::header_size ) ); RETURN_ERR( check_spc_header( header.tag ) ); long const xid6_offset = 0x10200; long xid6_size = file_size - xid6_offset; if ( xid6_size > 0 ) { RETURN_ERR( xid6.resize( xid6_size ) ); RETURN_ERR( in.skip( xid6_offset - Spc_Emu::header_size ) ); RETURN_ERR( in.read( xid6.begin(), xid6.size() ) ); } return 0; }
// Reads file into array, placing file_offset bytes of padding before the beginning, and pad_size after the end blargg_err_t Rom_Data::load_( Data_Reader& in, int header_size, int file_offset ) { clear(); file_size_ = in.remain(); if ( file_size_ <= header_size ) // <= because there must be data after header return blargg_err_file_type; RETURN_ERR( rom.resize( file_offset + file_size_ + pad_size ) ); return in.read( rom.begin() + file_offset, file_size_ ); }
blargg_err_t load_( Data_Reader& in ) { blargg_err_t err = in.read( &h, Nsf_Emu::header_size ); if ( err ) return (err == in.eof_error ? gme_wrong_file_type : err); if ( h.chip_flags & ~(namco_flag | vrc6_flag | fme7_flag) ) set_warning( "Uses unsupported audio expansion hardware" ); set_track_count( h.track_count ); return check_nsf_header( &h ); }
blargg_err_t load_( Data_Reader& in ) { blargg_err_t err = in.read( &h, h.size ); if ( err ) return (blargg_is_err_type( err, blargg_err_file_eof ) ? blargg_err_file_type : err); set_track_count( h.track_count ); if ( !h.valid_tag() ) return blargg_err_file_type; return blargg_ok; }
blargg_err_t Nes_Snapshot::read_sta_file( Data_Reader& in ) { sram_size = 0x2000; BLARGG_RETURN_ERR( in.read( sram, sram_size ) ); ram_valid = true; BLARGG_RETURN_ERR( in.read( ram, 0x800 ) ); sta_regs_t r; BLARGG_RETURN_ERR( in.read( &r, sizeof r ) ); this->cpu.pc = r.pc [1] * 0x100 + r.pc [0]; this->cpu.a = r.a; this->cpu.status = r.p; this->cpu.x = r.x; this->cpu.y = r.y; this->cpu.sp = r.s; cpu_valid = true; BLARGG_RETURN_ERR( in.read( spr_ram, 0x100 ) ); spr_ram_valid = true; chr_size = 0x2000; BLARGG_RETURN_ERR( in.read( chr, chr_size ) ); nametable_size = 0x1000; BLARGG_RETURN_ERR( in.read( nametable, nametable_size ) ); return blargg_success; }
blargg_err_t load_( Data_Reader& in ) { int file_size = in.remain(); if ( file_size < Sfm_Emu::sfm_min_file_size ) return blargg_err_file_type; RETURN_ERR( data.resize( file_size ) ); RETURN_ERR( in.read( data.begin(), data.end() - data.begin() ) ); RETURN_ERR( check_sfm_header( data.begin() ) ); int metadata_size = get_le32( data.begin() + 4 ); byte temp = data[ 8 + metadata_size ]; data[ 8 + metadata_size ] = '\0'; metadata.parseDocument( (const char *)data.begin() + 8 ); data[ 8 + metadata_size ] = temp; return blargg_ok; }
blargg_err_t Nes_Rom::load_ines_rom( Data_Reader& in ) { ines_header_t h; BLARGG_RETURN_ERR( in.read( &h, sizeof h ) ); if ( 0 != memcmp( h.signature, "NES\x1A", 4 ) ) return "Not a iNES ROM file"; if ( h.zero [7] ) // handle header defaced by a f*****g idiot's handle h.flags2 = 0; set_mapper( h.flags, h.flags2 ); if ( h.flags & 0x04 ) // skip trainer BLARGG_RETURN_ERR( in.skip( 512 ) ); BLARGG_RETURN_ERR( resize_prg( h.prg_count * 16 * 1024L ) ); BLARGG_RETURN_ERR( resize_chr( h.chr_count * 8 * 1024L ) ); BLARGG_RETURN_ERR( in.read( prg(), prg_size() ) ); BLARGG_RETURN_ERR( in.read( chr(), chr_size() ) ); return blargg_success; }
blargg_err_t load_( Data_Reader& in ) { int file_size = in.remain(); if ( file_size <= h.size_min ) return blargg_err_file_type; RETURN_ERR( in.read( &h, h.size_min ) ); if ( !h.valid_tag() ) return blargg_err_file_type; if ( h.size() > h.size_min ) RETURN_ERR( in.read( &h.rf5c68_rate, h.size() - h.size_min ) ); h.cleanup(); int data_offset = get_le32( h.data_offset ) + offsetof( Vgm_Core::header_t, data_offset ); int data_size = file_size - offsetof( Vgm_Core::header_t, data_offset ) - data_offset; int gd3_offset = get_le32( h.gd3_offset ); if ( gd3_offset > 0 ) gd3_offset += offsetof( Vgm_Core::header_t, gd3_offset ); int amount_to_skip = gd3_offset - h.size(); if ( gd3_offset > 0 && gd3_offset > data_offset ) { data_size = gd3_offset - data_offset; amount_to_skip = 0; RETURN_ERR( data.resize( data_size ) ); RETURN_ERR( in.skip( data_offset - h.size() ) ); RETURN_ERR( in.read( data.begin(), data_size ) ); } int remain = file_size - gd3_offset; byte gd3_h [gd3_header_size]; if ( gd3_offset > 0 && remain >= gd3_header_size ) { RETURN_ERR( in.skip( amount_to_skip ) ); RETURN_ERR( in.read( gd3_h, sizeof gd3_h ) ); int gd3_size = check_gd3_header( gd3_h, remain ); if ( gd3_size ) { RETURN_ERR( gd3.resize( gd3_size ) ); RETURN_ERR( in.read( gd3.begin(), gd3.size() ) ); } if ( data_offset > gd3_offset ) { RETURN_ERR( data.resize( data_size ) ); RETURN_ERR( in.skip( data_offset - gd3_offset - sizeof gd3_h - gd3.size() ) ); RETURN_ERR( in.read( data.begin(), data.end() - data.begin() ) ); } } return (blargg_err_t)blargg_ok; }
// Read multiple strings and separate into individual strings static blargg_err_t read_strs( Data_Reader& in, int size, blargg_vector<char>& chars, blargg_vector<const char*>& strs ) { RETURN_ERR( chars.resize( size + 1 ) ); chars [size] = 0; // in case last string doesn't have terminator RETURN_ERR( in.read( &chars [0], size ) ); RETURN_ERR( strs.resize( 128 ) ); int count = 0; for ( int i = 0; i < size; i++ ) { if ( (int) strs.size() <= count ) RETURN_ERR( strs.resize( count * 2 ) ); strs [count++] = &chars [i]; while ( i < size && chars [i] ) i++; } return strs.resize( count ); }
blargg_err_t Nes_Rom::load_patched_ines_rom( Data_Reader& in, Data_Reader& patch ) { // read file into memory long size = in.remain(); byte* ines = (byte*) malloc( size ); BLARGG_CHECK_ALLOC( ines ); const char* err = in.read( ines, size ); // apply patch if ( !err ) err = apply_ips_patch( patch, &ines, &size ); // load patched file if ( !err ) { Mem_File_Reader patched( ines, size ); err = load_ines_rom( patched ); } free( ines ); return err; }
blargg_err_t Gme_Loader::load_( Data_Reader& in ) { RETURN_ERR( file_data.resize( in.remain() ) ); RETURN_ERR( in.read( file_data.begin(), file_data.size() ) ); return load_mem_wrapper( file_data.begin(), file_data.size() ); }
blargg_err_t M3u_Playlist::load( Data_Reader& in ) { RETURN_ERR( data.resize( in.remain() + 1 ) ); RETURN_ERR( in.read( data.begin(), data.size() - 1 ) ); return parse(); }
blargg_err_t Gme_File::load_( Data_Reader& in ) { RETURN_ERR( file_data.resize( in.remain() ) ); RETURN_ERR( in.read( file_data.begin(), (long)file_data.size() ) ); return load_mem_( file_data.begin(), (long)file_data.size() ); }