8 // next doesn't need a binary flag in open call
30 char identification[4]; // should be IWAD
48 lumpinfo_t *lumpinfo; // location of each lump on disk
57 #define strcmpi strcasecmp
76 int filelength (int handle)
80 if (fstat (handle,&fileinfo) == -1)
81 I_Error ("Error fstating");
83 return fileinfo.st_size;
88 void ExtractFileBase (char *path, char *dest)
93 src = path + strlen(path) - 1;
96 // back up until a \ or the start
98 while (src != path && *(src-1) != '\\' && *(src-1) != '/')
102 // copy up to eight characters
106 while (*src && *src != '.')
109 I_Error ("Filename base of %s >8 chars",path);
110 *dest++ = toupper((int)*src++);
115 ============================================================================
119 ============================================================================
127 = All files are optional, but at least one file must be found
128 = Files with a .wad extension are wadlink files with multiple lumps
129 = Other files are single lumps with the base filename for the lump name
134 void W_AddFile (char *filename)
141 filelump_t *fileinfo, singleinfo;
144 // open the file and add to directory
146 if ( (handle = open (filename,O_RDONLY | O_BINARY)) == -1)
149 startlump = numlumps;
151 if (strcmpi (filename+strlen(filename)-3 , "wad" ) )
154 fileinfo = &singleinfo;
155 singleinfo.filepos = 0;
156 singleinfo.size = LONG(filelength(handle));
157 ExtractFileBase (filename, singleinfo.name);
163 read (handle, &header, sizeof(header));
164 if (strncmp(header.identification,"IWAD",4))
166 if (strncmp(header.identification,"PWAD",4))
167 I_Error ("Wad file %s doesn't have IWAD or PWAD id\n"
170 header.numlumps = LONG(header.numlumps);
171 header.infotableofs = LONG(header.infotableofs);
172 length = header.numlumps*sizeof(filelump_t);
173 fileinfo = alloca (length);
174 lseek (handle, header.infotableofs, SEEK_SET);
175 read (handle, fileinfo, length);
176 numlumps += header.numlumps;
182 lumpinfo = realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));
184 I_Error ("Couldn't realloc lumpinfo");
185 lump_p = &lumpinfo[startlump];
187 for (i=startlump ; i<numlumps ; i++,lump_p++, fileinfo++)
189 lump_p->handle = handle;
190 lump_p->position = LONG(fileinfo->filepos);
191 lump_p->size = LONG(fileinfo->size);
192 strncpy (lump_p->name, fileinfo->name, 8);
203 = W_InitMultipleFiles
205 = Pass a null terminated list of files to use.
207 = All files are optional, but at least one file must be found
209 = Files with a .wad extension are idlink files with multiple lumps
211 = Other files are single lumps with the base filename for the lump name
213 = Lump names can appear multiple times. The name searcher looks backwards,
214 = so a later file can override an earlier one.
219 void W_InitMultipleFiles (char **filenames)
224 // open all the files, load headers, and count lumps
227 lumpinfo = malloc(1); // will be realloced as lumps are added
229 for ( ; *filenames ; filenames++)
230 W_AddFile (*filenames);
233 I_Error ("W_InitFiles: no files found");
238 size = numlumps * sizeof(*lumpcache);
239 lumpcache = malloc (size);
241 I_Error ("Couldn't allocate lumpcache");
242 memset (lumpcache,0, size);
252 = Just initialize from a single file
257 void W_InitFile (char *filename)
263 W_InitMultipleFiles (names);
276 int W_NumLumps (void)
288 = Returns -1 if name not found
293 int W_CheckNumForName (char *name)
299 // make the name into two integers for easy compares
301 strncpy (name8,name,8);
302 name8[8] = 0; // in case the name was a fill 8 chars
303 strupr (name8); // case insensitive
306 v2 = *(int *)&name8[4];
309 // scan backwards so patch lump files take precedence
311 lump_p = lumpinfo + numlumps;
313 while (lump_p-- != lumpinfo)
315 if(*(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
317 return lump_p-lumpinfo;
329 = Calls W_CheckNumForName, but bombs out if not found
334 int W_GetNumForName (char *name)
338 i = W_CheckNumForName (name);
342 I_Error ("W_GetNumForName: %s not found!",name);
352 = Returns the buffer size needed to load the given lump
357 int W_LumpLength (int lump)
359 if (lump >= numlumps)
360 I_Error ("W_LumpLength: %i >= numlumps",lump);
361 return lumpinfo[lump].size;
370 = Loads the lump into the given buffer, which must be >= W_LumpLength()
375 void W_ReadLump (int lump, void *dest)
380 if (lump >= numlumps)
381 I_Error ("W_ReadLump: %i >= numlumps",lump);
385 lseek (l->handle, l->position, SEEK_SET);
386 c = read (l->handle, dest, l->size);
388 I_Error ("W_ReadLump: only read %i of %i on lump %i",c,l->size,lump);
401 void *W_CacheLumpNum (int lump, int tag)
405 if ((unsigned)lump >= numlumps)
406 I_Error ("W_CacheLumpNum: %i >= numlumps",lump);
408 if (!lumpcache[lump])
409 { // read the lump in
410 //printf ("cache miss on lump %i\n",lump);
411 ptr = Z_Malloc (W_LumpLength (lump), tag, &lumpcache[lump]);
412 W_ReadLump (lump, lumpcache[lump]);
416 //printf ("cache hit on lump %i\n",lump);
417 Z_ChangeTag (lumpcache[lump],tag);
420 return lumpcache[lump];
432 void *W_CacheLumpName (char *name, int tag)
434 return W_CacheLumpNum (W_GetNumForName(name), tag);
446 // Ripped out for Heretic
451 void W_Profile (void)
462 for (i=0 ; i<numlumps ; i++)
472 block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
473 if (block->tag < PU_PURGELEVEL)
478 info[i][profilecount] = ch;
482 f = fopen ("waddump.txt","w");
484 for (i=0 ; i<numlumps ; i++)
486 memcpy (name,lumpinfo[i].name,8);
487 for (j=0 ; j<8 ; j++)
492 fprintf (f,"%s ",name);
493 for (j=0 ; j<profilecount ; j++)
494 fprintf (f," %c",info[i][j]);
501 void W_Shutdown (void)