8 // next doesn't need a binary flag in open call
29 char identification[4]; // should be IWAD
47 lumpinfo_t *lumpinfo; // location of each lump on disk
56 #define strcmpi strcasecmp
75 int filelength (int handle)
79 if (fstat (handle,&fileinfo) == -1)
80 I_Error ("Error fstating");
82 return fileinfo.st_size;
87 void ExtractFileBase (char *path, char *dest)
92 src = path + strlen(path) - 1;
95 // back up until a \ or the start
97 while (src != path && *(src-1) != '\\' && *(src-1) != '/')
101 // copy up to eight characters
105 while (*src && *src != '.')
108 I_Error ("Filename base of %s >8 chars",path);
109 *dest++ = toupper((int)*src++);
114 ============================================================================
118 ============================================================================
126 = All files are optional, but at least one file must be found
127 = Files with a .wad extension are wadlink files with multiple lumps
128 = Other files are single lumps with the base filename for the lump name
133 void W_AddFile (char *filename)
140 filelump_t *fileinfo, singleinfo;
143 // open the file and add to directory
145 if ( (handle = open (filename,O_RDONLY | O_BINARY)) == -1)
148 startlump = numlumps;
150 if (strcmpi (filename+strlen(filename)-3 , "wad" ) )
153 fileinfo = &singleinfo;
154 singleinfo.filepos = 0;
155 singleinfo.size = LONG(filelength(handle));
156 ExtractFileBase (filename, singleinfo.name);
162 read (handle, &header, sizeof(header));
163 if (strncmp(header.identification,"IWAD",4))
165 if (strncmp(header.identification,"PWAD",4))
166 I_Error ("Wad file %s doesn't have IWAD or PWAD id\n"
169 header.numlumps = LONG(header.numlumps);
170 header.infotableofs = LONG(header.infotableofs);
171 length = header.numlumps*sizeof(filelump_t);
172 fileinfo = alloca (length);
173 lseek (handle, header.infotableofs, SEEK_SET);
174 read (handle, fileinfo, length);
175 numlumps += header.numlumps;
181 lumpinfo = realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));
183 I_Error ("Couldn't realloc lumpinfo");
184 lump_p = &lumpinfo[startlump];
186 for (i=startlump ; i<numlumps ; i++,lump_p++, fileinfo++)
188 lump_p->handle = handle;
189 lump_p->position = LONG(fileinfo->filepos);
190 lump_p->size = LONG(fileinfo->size);
191 strncpy (lump_p->name, fileinfo->name, 8);
202 = W_InitMultipleFiles
204 = Pass a null terminated list of files to use.
206 = All files are optional, but at least one file must be found
208 = Files with a .wad extension are idlink files with multiple lumps
210 = Other files are single lumps with the base filename for the lump name
212 = Lump names can appear multiple times. The name searcher looks backwards,
213 = so a later file can override an earlier one.
218 void W_InitMultipleFiles (char **filenames)
223 // open all the files, load headers, and count lumps
226 lumpinfo = malloc(1); // will be realloced as lumps are added
228 for ( ; *filenames ; filenames++)
229 W_AddFile (*filenames);
232 I_Error ("W_InitFiles: no files found");
237 size = numlumps * sizeof(*lumpcache);
238 lumpcache = malloc (size);
240 I_Error ("Couldn't allocate lumpcache");
241 memset (lumpcache,0, size);
251 = Just initialize from a single file
256 void W_InitFile (char *filename)
262 W_InitMultipleFiles (names);
275 int W_NumLumps (void)
287 = Returns -1 if name not found
292 int W_CheckNumForName (char *name)
298 // make the name into two integers for easy compares
300 strncpy (name8,name,8);
301 name8[8] = 0; // in case the name was a fill 8 chars
302 strupr (name8); // case insensitive
305 v2 = *(int *)&name8[4];
308 // scan backwards so patch lump files take precedence
310 lump_p = lumpinfo + numlumps;
312 while (lump_p-- != lumpinfo)
314 if(*(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
316 return lump_p-lumpinfo;
328 = Calls W_CheckNumForName, but bombs out if not found
333 int W_GetNumForName (char *name)
337 i = W_CheckNumForName (name);
341 I_Error ("W_GetNumForName: %s not found!",name);
351 = Returns the buffer size needed to load the given lump
356 int W_LumpLength (int lump)
358 if (lump >= numlumps)
359 I_Error ("W_LumpLength: %i >= numlumps",lump);
360 return lumpinfo[lump].size;
369 = Loads the lump into the given buffer, which must be >= W_LumpLength()
374 void W_ReadLump (int lump, void *dest)
379 if (lump >= numlumps)
380 I_Error ("W_ReadLump: %i >= numlumps",lump);
384 lseek (l->handle, l->position, SEEK_SET);
385 c = read (l->handle, dest, l->size);
387 I_Error ("W_ReadLump: only read %i of %i on lump %i",c,l->size,lump);
400 void *W_CacheLumpNum (int lump, int tag)
404 if ((unsigned)lump >= numlumps)
405 I_Error ("W_CacheLumpNum: %i >= numlumps",lump);
407 if (!lumpcache[lump])
408 { // read the lump in
409 //printf ("cache miss on lump %i\n",lump);
410 ptr = Z_Malloc (W_LumpLength (lump), tag, &lumpcache[lump]);
411 W_ReadLump (lump, lumpcache[lump]);
415 //printf ("cache hit on lump %i\n",lump);
416 Z_ChangeTag (lumpcache[lump],tag);
419 return lumpcache[lump];
431 void *W_CacheLumpName (char *name, int tag)
433 return W_CacheLumpNum (W_GetNumForName(name), tag);
445 // Ripped out for Heretic
450 void W_Profile (void)
461 for (i=0 ; i<numlumps ; i++)
471 block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
472 if (block->tag < PU_PURGELEVEL)
477 info[i][profilecount] = ch;
481 f = fopen ("waddump.txt","w");
483 for (i=0 ; i<numlumps ; i++)
485 memcpy (name,lumpinfo[i].name,8);
486 for (j=0 ; j<8 ; j++)
491 fprintf (f,"%s ",name);
492 for (j=0 ; j<profilecount ; j++)
493 fprintf (f," %c",info[i][j]);
500 void W_Shutdown (void)