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
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef GLK_BLORB_H
24 #define GLK_BLORB_H
25 
26 #include "glk/glk_types.h"
27 #include "glk/streams.h"
28 #include "common/archive.h"
29 #include "common/array.h"
30 
31 namespace Glk {
32 
33 /**
34  * Describes one chunk of the Blorb file.
35  */
36 struct ChunkEntry {
37 	uint _type;
38 	uint _number;
39 	uint _id;
40 	size_t _offset;
41 	size_t _size;
42 	Common::String _filename;
43 };
44 
45 enum {
46 	ID_FORM = MKTAG('F', 'O', 'R', 'M'),
47 	ID_IFRS = MKTAG('I', 'F', 'R', 'S'),
48 	ID_RIdx = MKTAG('R', 'I', 'd', 'x'),
49 	ID_APal = MKTAG('A', 'P', 'a', 'l'),
50 
51 	ID_Snd = MKTAG('S', 'n', 'd', ' '),
52 	ID_Exec = MKTAG('E', 'x', 'e', 'c'),
53 	ID_Pict = MKTAG('P', 'i', 'c', 't'),
54 	ID_Data = MKTAG('D', 'a', 't', 'a'),
55 
56 	ID_Copyright = MKTAG('(', 'c', ')', ' '),
57 	ID_AUTH = MKTAG('A', 'U', 'T', 'H'),
58 	ID_ANNO = MKTAG('A', 'N', 'N', 'O'),
59 
60 	ID_ZCOD = MKTAG('Z', 'C', 'O', 'D'),
61 	ID_GLUL = MKTAG('G', 'L', 'U', 'L'),
62 	ID_TAD2 = MKTAG('T', 'A', 'D', '2'),
63 	ID_TAD3 = MKTAG('T', 'A', 'D', '3'),
64 	ID_HUGO = MKTAG('H', 'U', 'G', 'O'),
65 	ID_SAAI = MKTAG('S', 'A', 'A', 'I'),
66 
67 	ID_JPEG = MKTAG('J', 'P', 'E', 'G'),
68 	ID_PNG  = MKTAG('P', 'N', 'G', ' '),
69 	ID_Rect = MKTAG('R', 'e', 'c', 't'),
70 
71 	ID_MIDI = MKTAG('M', 'I', 'D', 'I'),
72 	ID_MP3 = MKTAG('M', 'P', '3', ' '),
73 	ID_WAVE = MKTAG('W', 'A', 'V', 'E'),
74 	ID_AIFF = MKTAG('A', 'I', 'F', 'F'),
75 	ID_OGG = MKTAG('O', 'G', 'G', ' '),
76 	ID_MOD = MKTAG('M', 'O', 'D', ' ')
77 };
78 
79 /**
80  * Blorb file manager
81  */
82 class Blorb : public Common::Archive {
83 private:
84 	Common::String _filename;
85 	Common::FSNode _fileNode;
86 	InterpreterType _interpType;
87 	Common::Array<ChunkEntry> _chunks;	///< list of chunk descriptors
88 private:
89 	/**
90 	 * Parses the Blorb file index to load in a list of the chunks
91 	 */
92 	Common::ErrorCode load();
93 
94 	/**
95 	 * Add possible Blorb filenames for Infocom games
96 	 */
97 	static void getInfocomBlorbFilenames(Common::StringArray &filenames, const Common::String &gameId);
98 public:
99 	/**
100 	 * Constructor
101 	 */
102 	Blorb(const Common::String &filename, InterpreterType interpType);
103 
104 	/**
105 	 * Constructor
106 	 */
107 	Blorb(const Common::FSNode &fileNode, InterpreterType interpType);
108 
109 	/**
110 	 * Check if a member with the given name is present in the Archive.
111 	 * Patterns are not allowed, as this is meant to be a quick File::exists()
112 	 * replacement.
113 	 */
114 	virtual bool hasFile(const Common::String &name) const override;
115 
116 	/**
117 	 * Add all members of the Archive to list.
118 	 * Must only append to list, and not remove elements from it.
119 	 *
120 	 * @return the number of names added to list
121 	 */
122 	virtual int listMembers(Common::ArchiveMemberList &list) const override;
123 
124 	/**
125 	 * Returns a ArchiveMember representation of the given file.
126 	 */
127 	virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const override;
128 
129 	/**
130 	 * Create a stream bound to a member with the specified name in the
131 	 * archive. If no member with this name exists, 0 is returned.
132 	 * @return the newly created input stream
133 	 */
134 	virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
135 
136 	/**
137 	 * Read the RIdx section from the stream.
138 	 */
139 	static bool readRIdx(Common::SeekableReadStream &stream, Common::Array<ChunkEntry> &chunks);
140 
141 	/**
142 	 * Returns true if a given file is a Blorb file
143 	 */
144 	static bool isBlorb(Common::SeekableReadStream &stream, uint32 type = 0);
145 
146 	/**
147 	 * Returns true if a given filename specifies a Blorb file
148 	 */
149 	static bool isBlorb(const Common::String &filename, uint32 type = 0);
150 
151 	/**
152 	 * Returns true if a given filename has a Blorb file extension
153 	 */
154 	static bool hasBlorbExt(const Common::String &filename);
155 
156 	/**
157 	 * Return a list of possible filenames for blorb files
158 	 */
159 	static void getBlorbFilenames(const Common::String &srcFilename, Common::StringArray &filenames,
160 		InterpreterType interpType, const Common::String &gameId);
161 };
162 
163 } // End of namespace Glk
164 
165 #endif
166