#ifndef NES_FILE_H
#define NES_FILE_H
#include "blargg_common.h"
#include "abstract_file.h"
#include "nes_data.h"
class Nes_File_Writer : public Data_Writer {
public:
Nes_File_Writer();
~Nes_File_Writer();
blargg_err_t begin( Auto_File_Writer, nes_tag_t );
blargg_err_t begin_group( nes_tag_t );
blargg_err_t write_block( nes_tag_t, void const*, long size );
blargg_err_t write_block_header( nes_tag_t, long size );
error_t write( void const*, long );
blargg_err_t end_group();
blargg_err_t end();
private:
Auto_File_Writer out;
long write_remain;
int depth_;
blargg_err_t write_header( nes_tag_t tag, long size );
};
class Nes_File_Reader : public Data_Reader {
public:
Nes_File_Reader();
~Nes_File_Reader();
void enable_checksums( bool = true );
blargg_err_t begin( Auto_File_Reader );
blargg_err_t next_block();
enum block_type_t {
data_block,
group_begin,
group_end,
invalid
};
block_type_t block_type() const { return block_type_; }
nes_tag_t block_tag() const { return h.tag; }
blargg_err_t read_block_data( void*, long s );
virtual blargg_err_t read_v( void*, int n );
virtual blargg_err_t skip_v( int s );
blargg_err_t enter_group();
blargg_err_t exit_group();
int depth() const { return depth_; }
bool done() const { return depth() == 0 && block_type() == group_end; }
private:
Auto_File_Reader in;
nes_block_t h;
block_type_t block_type_;
int depth_;
blargg_err_t read_header();
};
template<class T>
inline blargg_err_t read_nes_state( Nes_File_Reader& in, T* out )
{
blargg_err_t err = in.read_block_data( out, sizeof *out );
out->swap();
return err;
}
template<class T>
inline blargg_err_t write_nes_state( Nes_File_Writer& out, T& in )
{
in.swap();
blargg_err_t err = out.write_block( in.tag, &in, sizeof in );
in.swap();
return err;
}
template<class T>
inline blargg_err_t write_nes_state( Nes_File_Writer& out, const T& in )
{
T copy = in;
copy.swap();
return out.write_block( copy.tag, ©, sizeof copy );
}
#endif