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