ScummVM API documentation
disk_image.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#include "common/bitarray.h"
23#include "common/ptr.h"
24#include "common/file.h"
25#include "common/debug.h"
26
27#ifndef COMMON_FORMATS_DISK_IMAGE_H
28#define COMMON_FORMATS_DISK_IMAGE_H
29
30namespace Common {
31
32// Disk image parsers / decoders
33//
34// These classes handle floppy disk image files. Multiple formats are supported.
35// An image's file name extension determines its format. DiskImage::open selects
36// the format and expected disk size. Data can be read by track/sector/offset
37// or by the calculated stream position. Several file systems can also be read.
38//
39// Supported image formats:
40// .do Apple II disk sectors. 35 tracks, 16 sectors, no encoding.
41// .dsk Same as .do. Note that alternative sector orders are not handled.
42// Currently, if clients want to support images with a different sector
43// order, then they will have to detect and handle it themselves.
44// .d13 Apple II disk sectors. 35 tracks, 13 sectors, no encoding.
45// .nib Apple II disk nibbles. 35 tracks, 13 or 16 sectors, nibble-encoded.
46// .woz Apple II comprehensive disk bitstream. 35 tracks, 13 or 16 sectors.
47// This encoding format takes a noticeable amount of time to decode.
48// .img PC disk sectors. 40 tracks, 8 sectors, no encoding.
49// .xfd Atari disk sectors. 40 tracks, 18 sectors, no encoding.
50//
51// For encoded formats, the default behavior is to decode every track when
52// opening an image. Lazy decoding can also be enabled, causing tracks to be
53// decoded when they are first accessed. This can significantly speed up access
54// if the format is expensive to decode but only a little data is needed.
55//
56// This code was originally part of the ADL engine.
57
58class SeekableReadStream;
59class String;
60
65 DiskImageEncodingNone,
66 DiskImageEncodingNib,
67 DiskImageEncodingWoz
68};
69
70// Used for disk image detection
71int32 computeMD5(const Common::FSNode &node, Common::String &md5, uint32 md5Bytes);
72
73class DataBlock {
74public:
75 virtual ~DataBlock() { }
76
77 virtual Common::SeekableReadStream *createReadStream() const = 0;
78};
79
82
83class Files {
84public:
85 virtual ~Files() { }
86
87 virtual const DataBlockPtr getDataBlock(const Common::Path &filename, uint offset = 0) const = 0;
88 virtual Common::SeekableReadStream *createReadStream(const Common::Path &filename, uint offset = 0) const = 0;
89 virtual bool exists(const Common::Path &filename) const = 0;
90
91protected:
93 public:
94 DataBlock(const Files *files, const Common::Path &filename, uint offset) :
95 _files(files),
96 _filename(filename),
97 _offset(offset) { }
98
99 Common::SeekableReadStream *createReadStream() const override {
100 return _files->createReadStream(_filename, _offset);
101 }
102
103 private:
104 const Common::Path _filename;
105 uint _offset;
106 const Files *_files;
107 };
108};
109
111public:
112 DiskImage() :
113 _inputStream(nullptr),
114 _decodeStream(nullptr),
115 _decodeBuffer(nullptr),
116 _encoding(DiskImageEncodingNone),
117 _lazyDecoding(false),
118 _tracks(0),
119 _sectorsPerTrack(0),
120 _bytesPerSector(0),
121 _sectorLimit(0),
122 _firstSector(0) { }
123
124 ~DiskImage() {
125 delete _inputStream;
126 delete _decodeStream; // frees _decodeBuffer
127 }
128
129 bool open(const Common::Path &filename);
130 bool open(const Common::FSNode &node);
131 const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
132 Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0, uint sectorsUsed = 0) const;
133 Common::SeekableReadStream *releaseStream();
134 Common::SeekableReadStream *getDiskStream() const { return _decodeBuffer ? _decodeStream : _inputStream; }
135 uint32 read(void *dataPtr, uint32 diskPosition, uint32 dataSize);
136 void setLazyDecoding(bool lazyDecoding) { _lazyDecoding = lazyDecoding; }
137 void setSectorLimit(uint sectorLimit) { _sectorLimit = sectorLimit; } // Maximum number of sectors to read per track before stepping
138 uint getBytesPerSector() const { return _bytesPerSector; }
139 uint getSectorsPerTrack() const { return _sectorsPerTrack; }
140 uint getTracks() const { return _tracks; }
141
142protected:
144 public:
145 DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size, uint sectorLimit) :
146 _track(track),
147 _sector(sector),
148 _offset(offset),
149 _size(size),
150 _sectorLimit(sectorLimit),
151 _disk(disk) { }
152
153 Common::SeekableReadStream *createReadStream() const override {
154 return _disk->createReadStream(_track, _sector, _offset, _size, _sectorLimit);
155 }
156
157 private:
158 uint _track, _sector, _offset, _size;
159 uint _sectorLimit;
160 const DiskImage *_disk;
161 };
162
163 Common::String _name;
164 Common::SeekableReadStream *_inputStream;
165 Common::SeekableReadStream *_decodeStream;
166 byte *_decodeBuffer;
167 Common::BitArray _decodedTracks;
168 DiskImageEncoding _encoding;
169 bool _lazyDecoding;
170
171 uint _tracks, _sectorsPerTrack, _bytesPerSector, _firstSector;
172 uint _sectorLimit;
173
174private:
175 bool open(const Common::String &name, Common::File *f);
176 void decodeTrack(uint track);
177};
178
179// Data in plain files
180class Files_Plain : public Files {
181public:
182 const DataBlockPtr getDataBlock(const Common::Path &filename, uint offset = 0) const override;
183 Common::SeekableReadStream *createReadStream(const Common::Path &filename, uint offset = 0) const override;
184 bool exists(const Common::Path &filename) const override { return Common::File::exists(filename); }
185};
186
187// Data in files contained in Apple DOS 3.3 disk image
188class Files_AppleDOS : public Files {
189public:
191 ~Files_AppleDOS() override;
192
193 bool open(const Common::Path &filename);
194 const DataBlockPtr getDataBlock(const Common::Path &filename, uint offset = 0) const override;
195 Common::SeekableReadStream *createReadStream(const Common::Path &filename, uint offset = 0) const override;
196 bool exists(const Common::Path &filename) const override { return _toc.contains(filename); }
197
198private:
199 enum FileType {
200 kFileTypeText = 0,
201 kFileTypeAppleSoft = 2,
202 kFileTypeBinary = 4
203 };
204
205 enum {
206 kSectorSize = 256,
207 kFilenameLen = 30
208 };
209
210 struct TrackSector {
211 byte track;
212 byte sector;
213 };
214
215 struct TOCEntry {
216 byte type;
217 uint16 totalSectors;
219 };
220
221 void readVTOC();
222 void readSectorList(TrackSector start, Common::Array<TrackSector> &list);
223 Common::SeekableReadStream *createReadStreamText(const TOCEntry &entry) const;
224 Common::SeekableReadStream *createReadStreamBinary(const TOCEntry &entry) const;
225
226 DiskImage *_disk;
228};
229
230} // End of namespace Common
231
232#endif
Definition: bitarray.h:29
Definition: disk_image.h:73
Definition: disk_image.h:143
Definition: disk_image.h:110
Definition: fs.h:69
Definition: file.h:47
static bool exists(const Path &filename)
Definition: disk_image.h:92
Definition: disk_image.h:188
Definition: disk_image.h:180
Definition: disk_image.h:83
Definition: path.h:52
Definition: stream.h:745
Definition: str.h:59
bool contains(const Key &key) const
Definition: hashmap.h:598
Definition: algorithm.h:29
DiskImageEncoding
Definition: disk_image.h:64