ScummVM API documentation
datafile.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#ifndef MEDIASTATION_DATAFILE_H
23#define MEDIASTATION_DATAFILE_H
24
25#include "common/file.h"
26#include "common/stream.h"
27#include "common/path.h"
28#include "common/rect.h"
29#include "common/str.h"
30
31namespace MediaStation {
32
33// The version number of this engine,
34// in the form 4.0r8 (major . minor r revision).
36 uint16 major = 0;
37 uint16 minor = 0;
38 uint16 patch = 0;
39};
40
41// A Media Station datafile consists of one or more RIFF-style "subfiles". Aside
42// from some oddness at the start of the subfile, each subfile is basically
43// standard sequence of chunks inside a LIST chunk, like you'd see in any RIFF
44// file. These chunks have special IDs:
45// - igod: Indicates a chunk that contains metadata about actor(s) in metadata sections.
46// - a000, where 000 is a string that represents a 3-digit hexadecimal number.
47// Indicates a chunk that contains actor data (sounds and bitmaps).
48
49enum DatumType {
50 kDatumTypeEmpty = 0x00,
51 kDatumTypeUint8 = 0x02,
52 kDatumTypeUint16 = 0x03,
53 kDatumTypeUint32 = 0x04,
54 kDatumTypeInt8 = 0x05,
55 kDatumTypeInt16 = 0x06,
56 kDatumTypeInt32 = 0x07,
57 kDatumTypeFloat = 0x08,
58 kDatumTypeDouble = 0x09,
59 kDatumTypeFilename = 0x0a,
60 kDatumTypeRect = 0x0d,
61 kDatumTypePoint = 0x0e,
62 kDatumTypeGraphicSize = 0x0f,
63 kDatumTypeGraphicUnit = 0x10,
64 kDatumTypeTime = 0x11,
65 kDatumTypeString = 0x12,
66 kDatumTypeVersion = 0x13,
67 kDatumTypeChannelIdent = 0x1b,
68 kDatumTypePolygon = 0x1d,
69};
70
72public:
73 // Data files are internally little-endian, even on game versions targeting
74 // big-endian systems. The original engine has code for swapping byte order
75 // at runtime when needed. All of these internally assume the data files are
76 // stored little-endian on disk.
77 byte readTypedByte();
78 uint16 readTypedUint16();
79 uint32 readTypedUint32();
80 int8 readTypedSByte();
81 int16 readTypedSint16();
82 int32 readTypedSint32();
83 float readTypedFloat();
84 double readTypedDouble();
85 Common::String readTypedFilename();
86 Common::Rect readTypedRect();
87 Common::Point readTypedPoint();
88 Common::Point readTypedGraphicSize();
89 int16 readTypedGraphicUnit();
90 double readTypedTime();
91 Common::String readTypedString();
92 VersionInfo readTypedVersion();
93 uint32 readTypedChannelIdent();
94
95private:
96 void readAndVerifyType(DatumType type);
97};
98
99class Chunk : public ParameterReadStream {
100public:
101 Chunk() = default;
103
104 uint32 bytesRemaining();
105 uint32 startPos() const { return _dataStartOffset; }
106
107 uint32 _id = 0;
108 uint32 _length = 0;
109
110 // ReadStream implementation
111 virtual bool eos() const { return _parentStream->eos(); };
112 virtual bool err() const { return _parentStream->err(); };
113 virtual void clearErr() { _parentStream->clearErr(); };
114 virtual uint32 read(void *dataPtr, uint32 dataSize);
115 virtual int64 pos() const { return _parentStream->pos(); };
116 virtual int64 size() const { return _parentStream->size(); };
117 virtual bool skip(uint32 offset) { return seek(offset, SEEK_CUR); };
118 virtual bool seek(int64 offset, int whence = SEEK_SET);
119
120private:
121 Common::SeekableReadStream *_parentStream = nullptr;
122 uint32 _dataStartOffset = 0;
123 uint32 _dataEndOffset = 0;
124};
125
126class Subfile {
127public:
128 Subfile() = default;
130
131 Chunk nextChunk();
132 bool atEnd();
133
134 Chunk _currentChunk;
135 uint32 _rate;
136
137private:
138 Common::SeekableReadStream *_stream = nullptr;
139 Chunk _rootChunk;
140};
141
142// The stream loading class hierarchy presented below is a bit complex for reading directly
143// from streams, like we can do on modern computers, without needing to worry about
144// buffering from CD-ROM. But we are staying close to the original logic and class
145// hierarchy where possible, so some of that original architecture is reflected here.
146typedef uint32 ChannelIdent;
147
148class CdRomStream : public Common::File {
149public:
150 CdRomStream() {};
151 void openStream(uint streamId);
152 void closeStream() { close(); }
153
154 Subfile getNextSubfile();
155
156private:
157 uint _fileId = 0;
158};
159
161public:
162 virtual ~ChannelClient() {};
163
164 void setChannelIdent(ChannelIdent channelIdent) { _channelIdent = channelIdent; }
165 ChannelIdent channelIdent() const { return _channelIdent; }
166
167 virtual void readChunk(Chunk &chunk) {};
168
169 void registerWithStreamManager();
170 void unregisterWithStreamManager();
171
172protected:
173 ChannelIdent _channelIdent = 0;
174};
175
177public:
178 StreamFeed(uint streamId) : _id(streamId) {};
179 virtual ~StreamFeed() {};
180
181 virtual void openFeed(uint streamId, uint startOffset) = 0;
182
183 // The original also has forceCloseFeed, which doesn't do some other cleanup
184 // that the regular closeFeed does. However, since we are not doing caching and
185 // some other functionality in the original, we don't need this.
186 virtual void closeFeed() = 0;
187 virtual void stopFeed() = 0;
188 virtual void readData() = 0;
189
190 uint _id = 0;
191
192protected:
193 CdRomStream *_stream = nullptr;
194};
195
196class ImtStreamFeed : public StreamFeed {
197public:
198 ImtStreamFeed(uint streamId);
200
201 virtual void openFeed(uint streamId, uint startOffset) override;
202 virtual void closeFeed() override;
203 // This implementation is currently empty because all this has to do with read timing.
204 virtual void stopFeed() override {};
205 virtual void readData() override;
206};
207
209public:
211
212 void registerChannelClient(ChannelClient *client);
213 void unregisterChannelClient(ChannelClient *client);
214 ChannelClient *channelClientForChannel(uint clientId) { return _channelClients.getValOrDefault(clientId); }
215
216 ImtStreamFeed *openStreamFeed(uint streamId, uint offsetInStream = 0, uint maxBytesToRead = 0);
217 void closeStreamFeed(StreamFeed *streamFeed);
218
219private:
222};
223
224} // End of namespace MediaStation
225
226#endif
Definition: file.h:47
virtual void close()
Definition: hashmap.h:85
virtual bool eos() const =0
Definition: stream.h:745
virtual int64 pos() const =0
virtual int64 size() const =0
virtual void clearErr()
Definition: stream.h:71
virtual bool err() const
Definition: stream.h:61
Definition: str.h:59
Definition: datafile.h:148
Definition: datafile.h:160
Definition: datafile.h:99
virtual bool seek(int64 offset, int whence=SEEK_SET)
virtual bool eos() const
Definition: datafile.h:111
virtual uint32 read(void *dataPtr, uint32 dataSize)
virtual int64 size() const
Definition: datafile.h:116
virtual int64 pos() const
Definition: datafile.h:115
virtual void clearErr()
Definition: datafile.h:113
virtual bool skip(uint32 offset)
Definition: datafile.h:117
virtual bool err() const
Definition: datafile.h:112
Definition: datafile.h:196
Definition: datafile.h:71
Definition: datafile.h:176
Definition: datafile.h:208
Definition: datafile.h:126
Definition: rect.h:144
Definition: rect.h:536
Definition: datafile.h:35