Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/quicknes/nes_emu/Nes_File.h
2 views
1
2
// NES block-oriented file access
3
4
// Nes_Emu 0.7.0
5
6
#ifndef NES_FILE_H
7
#define NES_FILE_H
8
9
#include "blargg_common.h"
10
#include "abstract_file.h"
11
#include "nes_data.h"
12
13
// Writes a structured file
14
class Nes_File_Writer : public Data_Writer {
15
public:
16
Nes_File_Writer();
17
~Nes_File_Writer();
18
19
// Begin writing file with specified signature tag
20
blargg_err_t begin( Auto_File_Writer, nes_tag_t );
21
22
// Begin tagged group
23
blargg_err_t begin_group( nes_tag_t );
24
25
// Write tagged block
26
blargg_err_t write_block( nes_tag_t, void const*, long size );
27
28
// Write tagged block header. 'Size' bytes must be written before next block.
29
blargg_err_t write_block_header( nes_tag_t, long size );
30
31
// Write data to current block
32
error_t write( void const*, long );
33
34
// End tagged group
35
blargg_err_t end_group();
36
37
// End file
38
blargg_err_t end();
39
40
private:
41
Auto_File_Writer out;
42
long write_remain;
43
int depth_;
44
blargg_err_t write_header( nes_tag_t tag, long size );
45
};
46
47
// Reads a structured file
48
class Nes_File_Reader : public Data_Reader {
49
public:
50
Nes_File_Reader();
51
~Nes_File_Reader();
52
53
// If true, verify checksums of any blocks that have them
54
void enable_checksums( bool = true );
55
56
// Begin reading file. Until next_block() is called, block_tag() yields tag for file.
57
blargg_err_t begin( Auto_File_Reader );
58
59
// Read header of next block in current group
60
blargg_err_t next_block();
61
62
// Type of current block
63
enum block_type_t {
64
data_block,
65
group_begin,
66
group_end,
67
invalid
68
};
69
block_type_t block_type() const { return block_type_; }
70
71
// Tag of current block
72
nes_tag_t block_tag() const { return h.tag; }
73
74
// Read at most s bytes from block and skip any remaining bytes
75
blargg_err_t read_block_data( void*, long s );
76
77
// Read at most 's' bytes from current block and return number of bytes actually read
78
virtual blargg_err_t read_v( void*, int n );
79
80
// Skip 's' bytes in current block
81
virtual blargg_err_t skip_v( int s );
82
83
// Read first sub-block of current group block
84
blargg_err_t enter_group();
85
86
// Skip past current group
87
blargg_err_t exit_group();
88
89
// Current depth, where 0 is top-level in file and higher is deeper
90
int depth() const { return depth_; }
91
92
// True if all data has been read
93
bool done() const { return depth() == 0 && block_type() == group_end; }
94
private:
95
Auto_File_Reader in;
96
nes_block_t h;
97
block_type_t block_type_;
98
int depth_;
99
blargg_err_t read_header();
100
};
101
102
template<class T>
103
inline blargg_err_t read_nes_state( Nes_File_Reader& in, T* out )
104
{
105
blargg_err_t err = in.read_block_data( out, sizeof *out );
106
out->swap();
107
return err;
108
}
109
110
template<class T>
111
inline blargg_err_t write_nes_state( Nes_File_Writer& out, T& in )
112
{
113
in.swap();
114
blargg_err_t err = out.write_block( in.tag, &in, sizeof in );
115
in.swap();
116
return err;
117
}
118
119
template<class T>
120
inline blargg_err_t write_nes_state( Nes_File_Writer& out, const T& in )
121
{
122
T copy = in;
123
copy.swap();
124
return out.write_block( copy.tag, &copy, sizeof copy );
125
}
126
127
#endif
128
129
130