1 #ifndef __WAD_H
2 #define __WAD_H
3 
4 /*
5 	WAD.H
6 
7 	Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
8 	and the "Aleph One" developers.
9 
10 	This program is free software; you can redistribute it and/or modify
11 	it under the terms of the GNU General Public License as published by
12 	the Free Software Foundation; either version 3 of the License, or
13 	(at your option) any later version.
14 
15 	This program is distributed in the hope that it will be useful,
16 	but WITHOUT ANY WARRANTY; without even the implied warranty of
17 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 	GNU General Public License for more details.
19 
20 	This license is contained in the file "COPYING",
21 	which is included with this source code; it is available online at
22 	http://www.gnu.org/licenses/gpl.html
23 
24 	Thursday, June 30, 1994 10:55:20 PM
25 
26 	Sunday, July 3, 1994 5:51:47 PM
27 	I wonder if I should include an element size in the entry_header structure...
28 
29 	Tuesday, December 13, 1994 4:10:48 PM
30 	Included element size in the entry_header for the directory size.  The directory
31 	is application_specific_directory_data_size+sizeof(struct directory_entry).
32 
33 Feb 3, 2000 (Loren Petrich):
34 	Defined "WADFILE_HAS_INFINITY_STUFF" as 4
35 	Changed CURRENT_WADFILE_VERSION to WADFILE_HAS_INFINITY_STUFF
36 		to achieve Marathon Infinity compatibility
37 
38 Aug 12, 2000 (Loren Petrich):
39 	Using object-oriented file handler
40 */
41 
42 #include "tags.h"
43 
44 #define PRE_ENTRY_POINT_WADFILE_VERSION 0
45 #define WADFILE_HAS_DIRECTORY_ENTRY 1
46 #define WADFILE_SUPPORTS_OVERLAYS 2
47 #define WADFILE_HAS_INFINITY_STUFF 4
48 #define CURRENT_WADFILE_VERSION (WADFILE_HAS_INFINITY_STUFF)
49 
50 #define MAXIMUM_DIRECTORY_ENTRIES_PER_FILE 64
51 #define MAXIMUM_WADFILE_NAME_LENGTH 64
52 #define MAXIMUM_UNION_WADFILES 16
53 #define MAXIMUM_OPEN_WADFILES 3
54 
55 class FileSpecifier;
56 class OpenedFile;
57 
58 /* ------------- typedefs */
59 typedef uint32 WadDataType;
60 
61 /* ------------- file structures */
62 struct wad_header { /* 128 bytes */
63 	int16 version;									/* Used internally */
64 	int16 data_version;								/* Used by the data.. */
65 	char file_name[MAXIMUM_WADFILE_NAME_LENGTH];
66 	uint32 checksum;
67 	int32 directory_offset;
68 	int16 wad_count;
69 	int16 application_specific_directory_data_size;
70 	int16 entry_header_size;
71 	int16 directory_entry_base_size;
72 	uint32 parent_checksum;	/* If non-zero, this is the checksum of our parent, and we are simply modifications! */
73 	int16 unused[20];
74 };
75 const int SIZEOF_wad_header = 128;	// don't trust sizeof()
76 
77 struct old_directory_entry { /* 8 bytes */
78 	int32 offset_to_start; /* From start of file */
79 	int32 length; /* Of total level */
80 };
81 const int SIZEOF_old_directory_entry = 8;
82 
83 struct directory_entry { /* >=10 bytes */
84 	int32 offset_to_start; /* From start of file */
85 	int32 length; /* Of total level */
86 	int16 index; /* For inplace modification of the wadfile! */
87 };
88 const int SIZEOF_directory_entry = 10;
89 
90 struct old_entry_header { /* 12 bytes */
91 	WadDataType tag;
92 	int32 next_offset; /* From current file location-> ie directory_entry.offset_to_start+next_offset */
93 	int32 length; /* Of entry */
94 
95 	/* Element size? */
96 
97 	/* Data follows */
98 };
99 const int SIZEOF_old_entry_header = 12;
100 
101 struct entry_header { /* 16 bytes */
102 	WadDataType tag;
103 	int32 next_offset; /* From current file location-> ie directory_entry.offset_to_start+next_offset */
104 	int32 length; /* Of entry */
105 	int32 offset; /* Offset for inplace expansion of data */
106 
107 	/* Element size? */
108 
109 	/* Data follows */
110 };
111 const int SIZEOF_entry_header = 16;
112 
113 /* ---------- Memory Data structures ------------ */
114 struct tag_data {
115 	WadDataType tag;		/* What type of data is this? */
116 	byte *data; 			/* Offset into the wad.. */
117 	int32 length;			/* Length of the data */
118 	int32 offset;			/* Offset for patches */
119 };
120 
121 /* This is what a wad * actually is.. */
122 struct wad_data {
123 	short tag_count;			/* Tag count */
124 	short padding;
125 	byte *read_only_data;		/* If this is non NULL, we are read only.... */
126 	struct tag_data *tag_data;	/* Tag data array */
127 };
128 
129 /* ----- miscellaneous functions */
130 bool wad_file_has_checksum(FileSpecifier& File, uint32 checksum);
131 bool wad_file_has_parent_checksum(FileSpecifier& File, uint32 checksum);
132 
133 /* Find out how many wads there are in the map */
134 short number_of_wads_in_file(FileSpecifier& File); /* returns -1 on error */
135 
136 /* ----- Open/Close functions */
137 // Use one of the FileSpecifier enum types
138 bool create_wadfile(FileSpecifier& File, Typecode Type);
139 
140 bool open_wad_file_for_reading(FileSpecifier& File, OpenedFile& OFile);
141 bool open_wad_file_for_writing(FileSpecifier& File, OpenedFile& OFile);
142 
143 void close_wad_file(OpenedFile& OFile);
144 
145 /* ----- Read File functions */
146 
147 /* Read the header from the wad file */
148 bool read_wad_header(OpenedFile& OFile, struct wad_header *header);
149 
150 /* Read the indexed wad from the file */
151 struct wad_data *read_indexed_wad_from_file(OpenedFile& OFile,
152 	struct wad_header *header, short index, bool read_only);
153 
154 /* Properly deal with the memory.. */
155 void free_wad(struct wad_data *wad);
156 
157 int32 get_size_of_directory_data(struct wad_header *header);
158 
159 /* -----  Read Wad functions */
160 
161 /* Given a wad, extract the given tag from it */
162 void *extract_type_from_wad(struct wad_data *wad, WadDataType type,
163 	size_t *length);
164 
165 /* Calculate the length of the wad */
166 int32 calculate_wad_length(struct wad_header *file_header, struct wad_data *wad);
167 
168 /* Note wad_count and directory offset in the header! better be correct! */
169 void *get_indexed_directory_data(struct wad_header *header, short index,
170 	void *directories);
171 
172 void *read_directory_data(OpenedFile& OFile, struct wad_header *header);
173 
174 uint32 read_wad_file_checksum(FileSpecifier& File);
175 uint32 read_wad_file_parent_checksum(FileSpecifier& File);
176 
177 // Now intended to use the _typecode_stuff in tags.h (abstract filetypes)
178 
179 bool find_wad_file_that_has_checksum(FileSpecifier& File,
180 	Typecode file_type, short path_resource_id, uint32 checksum);
181 
182 /* Added in here for simplicity.  Really should be somewhere else.. */
183 bool find_file_with_modification_date(FileSpecifier& File,
184 	Typecode file_type, short path_resource_id, TimeType modification_date);
185 
186 /* ------------ Flat wad functions */
187 /* These functions are used for transferring data, and it completely encapsulates */
188 /*  a given wad from a given file... */
189 void *get_flat_data(FileSpecifier& File, bool use_union, short wad_index);
190 int32 get_flat_data_length(void *data);
191 
192 /* This is how you dispose of it-> you inflate it, then use free_wad() */
193 struct wad_data *inflate_flat_data(void *data, struct wad_header *header);
194 
195 /* ------------  Write File functions */
196 struct wad_data *create_empty_wad(void);
197 void fill_default_wad_header(FileSpecifier& File, short wadfile_version,
198 	short data_version, short wad_count, short application_directory_data_size,
199 	struct wad_header *header);
200 bool write_wad_header(OpenedFile& OFile, struct wad_header *header);
201 bool write_directorys(OpenedFile& OFile,  struct wad_header *header,
202 	void *entries);
203 void calculate_and_store_wadfile_checksum(OpenedFile& OFile);
204 bool write_wad(OpenedFile& OFile, struct wad_header *file_header,
205 	struct wad_data *wad, int32 offset);
206 
207 void set_indexed_directory_offset_and_length(struct wad_header *header,
208 	void *entries, short index, int32 offset, int32 length, short wad_index);
209 
210 /* ------ Write Wad Functions */
211 struct wad_data *append_data_to_wad(
212 	struct wad_data *wad,
213 	WadDataType type,
214 	const void *data,
215 	size_t size,
216 	size_t offset);
217 
218 void remove_tag_from_wad(struct wad_data *wad, WadDataType type);
219 
220 /* ------- debug function */
221 void dump_wad(struct wad_data *wad);
222 
223 // To tell the wad allocator that we are between levels (the default);
224 // if one wishes to load a model file with a WAD-based format, for example,
225 // one would shut off "between levels", so as not to interfere with other loaded stuff.
226 void SetBetweenlevels(bool _BetweenLevels);
227 bool IsBetweenLevels();
228 
229 
230 #endif
231 
232