Annotation of doom/w_wad.c, revision 1.1.1.5

1.1.1.4   root        1: // Emacs style mode select   -*- C++ -*- 
                      2: //-----------------------------------------------------------------------------
                      3: //
                      4: // $Id:$
                      5: //
                      6: // Copyright (C) 1993-1996 by id Software, Inc.
                      7: //
                      8: // This source is available for distribution and/or modification
                      9: // only under the terms of the DOOM Source Code License as
                     10: // published by id Software. All rights reserved.
                     11: //
                     12: // The source is distributed in the hope that it will be useful,
                     13: // but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
                     15: // for more details.
                     16: //
                     17: // $Log:$
                     18: //
                     19: // DESCRIPTION:
                     20: //     Handles WAD file header, directory, lump I/O.
                     21: //
                     22: //-----------------------------------------------------------------------------
                     23: 
1.1.1.3   root       24: 
1.1.1.4   root       25: static const char
                     26: rcsid[] = "$Id: w_wad.c,v 1.5 1997/02/03 16:47:57 b1 Exp $";
1.1.1.3   root       27: 
1.1       root       28: 
1.1.1.4   root       29: #ifdef NORMALUNIX
1.1.1.2   root       30: #include <ctype.h>
1.1.1.4   root       31: #include <sys/types.h>
                     32: #include <string.h>
                     33: #include <unistd.h>
1.1.1.2   root       34: #include <malloc.h>
                     35: #include <fcntl.h>
                     36: #include <sys/stat.h>
1.1.1.5 ! root       37: //#include <alloca.h>
        !            38: //#define O_BINARY             0
1.1.1.2   root       39: #endif
                     40: 
1.1.1.4   root       41: #include "doomtype.h"
                     42: #include "m_swap.h"
                     43: #include "i_system.h"
                     44: #include "z_zone.h"
1.1.1.2   root       45: 
1.1.1.4   root       46: #ifdef __GNUG__
                     47: #pragma implementation "w_wad.h"
1.1.1.3   root       48: #endif
1.1.1.4   root       49: #include "w_wad.h"
1.1       root       50: 
                     51: 
                     52: 
                     53: 
1.1.1.2   root       54: 
                     55: 
1.1.1.4   root       56: //
                     57: // GLOBALS
                     58: //
1.1.1.2   root       59: 
1.1.1.4   root       60: // Location of each lump on disk.
                     61: lumpinfo_t*            lumpinfo;               
                     62: int                    numlumps;
1.1.1.2   root       63: 
1.1.1.4   root       64: void**                 lumpcache;
1.1.1.3   root       65: 
1.1       root       66: 
1.1.1.4   root       67: #define strcmpi        strcasecmp
1.1.1.3   root       68: 
1.1.1.5 ! root       69: /*void strupr (char* s)
1.1       root       70: {
1.1.1.4   root       71:     while (*s) { *s = toupper(*s); s++; }
1.1.1.5 ! root       72: }*/
1.1       root       73: 
1.1.1.4   root       74: int filelength (int handle) 
                     75: { 
                     76:     struct stat        fileinfo;
                     77:     
                     78:     if (fstat (handle,&fileinfo) == -1)
                     79:        I_Error ("Error fstating");
1.1       root       80: 
1.1.1.2   root       81:     return fileinfo.st_size;
                     82: }
1.1       root       83: 
                     84: 
1.1.1.4   root       85: void
                     86: ExtractFileBase
                     87: ( char*                path,
                     88:   char*                dest )
1.1       root       89: {
1.1.1.4   root       90:     char*      src;
                     91:     int                length;
1.1       root       92: 
1.1.1.4   root       93:     src = path + strlen(path) - 1;
                     94:     
                     95:     // back up until a \ or the start
                     96:     while (src != path
                     97:           && *(src-1) != '\\'
                     98:           && *(src-1) != '/')
                     99:     {
                    100:        src--;
                    101:     }
                    102:     
                    103:     // copy up to eight characters
                    104:     memset (dest,0,8);
                    105:     length = 0;
                    106:     
                    107:     while (*src && *src != '.')
                    108:     {
                    109:        if (++length == 9)
                    110:            I_Error ("Filename base of %s >8 chars",path);
1.1.1.2   root      111: 
1.1.1.4   root      112:        *dest++ = toupper((int)*src++);
                    113:     }
                    114: }
1.1.1.2   root      115: 
                    116: 
                    117: 
                    118: 
                    119: 
                    120: //
1.1.1.4   root      121: // LUMP BASED ROUTINES.
1.1.1.2   root      122: //
                    123: 
1.1.1.3   root      124: //
1.1.1.4   root      125: // W_AddFile
                    126: // All files are optional, but at least one file must be
                    127: //  found (PWAD, if all required lumps are present).
                    128: // Files with a .wad extension are wadlink files
                    129: //  with multiple lumps.
                    130: // Other files are single lumps with the base filename
                    131: //  for the lump name.
                    132: //
                    133: // If filename starts with a tilde, the file is handled
                    134: //  specially to allow map reloads.
                    135: // But: the reload feature is a fragile hack...
                    136: 
                    137: int                    reloadlump;
                    138: char*                  reloadname;
                    139: 
                    140: 
                    141: void W_AddFile (char *filename)
                    142: {
                    143:     wadinfo_t          header;
                    144:     lumpinfo_t*                lump_p;
                    145:     unsigned           i;
                    146:     int                        handle;
                    147:     int                        length;
                    148:     int                        startlump;
                    149:     filelump_t*                fileinfo;
                    150:     filelump_t         singleinfo;
                    151:     int                        storehandle;
                    152:     
                    153:     // open the file and add to directory
                    154: 
                    155:     // handle reload indicator.
                    156:     if (filename[0] == '~')
                    157:     {
                    158:        filename++;
                    159:        reloadname = filename;
                    160:        reloadlump = numlumps;
                    161:     }
                    162:                
                    163:     if ( (handle = open (filename,O_RDONLY | O_BINARY)) == -1)
                    164:     {
                    165:        printf (" couldn't open %s\n",filename);
                    166:        return;
                    167:     }
1.1.1.2   root      168: 
1.1.1.4   root      169:     printf (" adding %s\n",filename);
                    170:     startlump = numlumps;
                    171:        
                    172:     if (strcmpi (filename+strlen(filename)-3 , "wad" ) )
                    173:     {
                    174:        // single lump file
                    175:        fileinfo = &singleinfo;
                    176:        singleinfo.filepos = 0;
                    177:        singleinfo.size = LONG(filelength(handle));
                    178:        ExtractFileBase (filename, singleinfo.name);
                    179:        numlumps++;
                    180:     }
                    181:     else 
                    182:     {
                    183:        // WAD file
                    184:        read (handle, &header, sizeof(header));
                    185:        if (strncmp(header.identification,"IWAD",4))
                    186:        {
                    187:            // Homebrew levels?
                    188:            if (strncmp(header.identification,"PWAD",4))
                    189:            {
                    190:                I_Error ("Wad file %s doesn't have IWAD "
                    191:                         "or PWAD id\n", filename);
                    192:            }
                    193:            
                    194:            // ???modifiedgame = true;          
1.1.1.3   root      195:        }
                    196:        header.numlumps = LONG(header.numlumps);
                    197:        header.infotableofs = LONG(header.infotableofs);
                    198:        length = header.numlumps*sizeof(filelump_t);
1.1.1.4   root      199:        fileinfo = alloca (length);
                    200:        lseek (handle, header.infotableofs, SEEK_SET);
                    201:        read (handle, fileinfo, length);
                    202:        numlumps += header.numlumps;
                    203:     }
                    204: 
                    205:     
                    206:     // Fill in lumpinfo
                    207:     lumpinfo = realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));
1.1.1.3   root      208: 
1.1.1.4   root      209:     if (!lumpinfo)
                    210:        I_Error ("Couldn't realloc lumpinfo");
1.1.1.3   root      211: 
1.1.1.4   root      212:     lump_p = &lumpinfo[startlump];
                    213:        
                    214:     storehandle = reloadname ? -1 : handle;
                    215:        
                    216:     for (i=startlump ; i<numlumps ; i++,lump_p++, fileinfo++)
                    217:     {
                    218:        lump_p->handle = storehandle;
                    219:        lump_p->position = LONG(fileinfo->filepos);
                    220:        lump_p->size = LONG(fileinfo->size);
                    221:        strncpy (lump_p->name, fileinfo->name, 8);
                    222:     }
                    223:        
                    224:     if (reloadname)
                    225:        close (handle);
1.1.1.3   root      226: }
1.1.1.2   root      227: 
1.1.1.3   root      228: 
1.1.1.2   root      229: 
1.1       root      230: 
1.1.1.3   root      231: //
1.1.1.4   root      232: // W_Reload
                    233: // Flushes any of the reloadable lumps in memory
                    234: //  and reloads the directory.
1.1.1.3   root      235: //
1.1.1.4   root      236: void W_Reload (void)
1.1.1.3   root      237: {
1.1.1.4   root      238:     wadinfo_t          header;
                    239:     int                        lumpcount;
                    240:     lumpinfo_t*                lump_p;
                    241:     unsigned           i;
                    242:     int                        handle;
                    243:     int                        length;
                    244:     filelump_t*                fileinfo;
                    245:        
                    246:     if (!reloadname)
                    247:        return;
                    248:                
                    249:     if ( (handle = open (reloadname,O_RDONLY | O_BINARY)) == -1)
                    250:        I_Error ("W_Reload: couldn't open %s",reloadname);
                    251: 
                    252:     read (handle, &header, sizeof(header));
                    253:     lumpcount = LONG(header.numlumps);
                    254:     header.infotableofs = LONG(header.infotableofs);
                    255:     length = lumpcount*sizeof(filelump_t);
                    256:     fileinfo = alloca (length);
                    257:     lseek (handle, header.infotableofs, SEEK_SET);
                    258:     read (handle, fileinfo, length);
                    259:     
                    260:     // Fill in lumpinfo
                    261:     lump_p = &lumpinfo[reloadlump];
                    262:        
                    263:     for (i=reloadlump ;
                    264:         i<reloadlump+lumpcount ;
                    265:         i++,lump_p++, fileinfo++)
                    266:     {
                    267:        if (lumpcache[i])
                    268:            Z_Free (lumpcache[i]);
                    269: 
                    270:        lump_p->position = LONG(fileinfo->filepos);
                    271:        lump_p->size = LONG(fileinfo->size);
                    272:     }
                    273:        
                    274:     close (handle);
1.1.1.3   root      275: }
1.1.1.2   root      276: 
1.1.1.4   root      277: 
                    278: 
1.1.1.3   root      279: //
1.1.1.4   root      280: // W_InitMultipleFiles
                    281: // Pass a null terminated list of files to use.
                    282: // All files are optional, but at least one file
                    283: //  must be found.
                    284: // Files with a .wad extension are idlink files
                    285: //  with multiple lumps.
                    286: // Other files are single lumps with the base filename
                    287: //  for the lump name.
                    288: // Lump names can appear multiple times.
                    289: // The name searcher looks backwards, so a later file
                    290: //  does override all earlier ones.
                    291: //
                    292: void W_InitMultipleFiles (char** filenames)
                    293: {      
                    294:     int                size;
                    295:     
                    296:     // open all the files, load headers, and count lumps
                    297:     numlumps = 0;
                    298: 
                    299:     // will be realloced as lumps are added
                    300:     lumpinfo = malloc(1);      
                    301: 
                    302:     for ( ; *filenames ; filenames++)
                    303:        W_AddFile (*filenames);
                    304: 
                    305:     if (!numlumps)
                    306:        I_Error ("W_InitFiles: no files found");
                    307:     
                    308:     // set up caching
                    309:     size = numlumps * sizeof(*lumpcache);
                    310:     lumpcache = malloc (size);
                    311:     
                    312:     if (!lumpcache)
                    313:        I_Error ("Couldn't allocate lumpcache");
1.1.1.2   root      314: 
1.1.1.4   root      315:     memset (lumpcache,0, size);
1.1.1.2   root      316: }
                    317: 
1.1.1.4   root      318: 
                    319: 
                    320: 
1.1.1.3   root      321: //
1.1.1.4   root      322: // W_InitFile
                    323: // Just initialize from a single file.
1.1.1.3   root      324: //
1.1.1.4   root      325: void W_InitFile (char* filename)
1.1.1.3   root      326: {
1.1.1.4   root      327:     char*      names[2];
                    328: 
                    329:     names[0] = filename;
                    330:     names[1] = NULL;
                    331:     W_InitMultipleFiles (names);
1.1.1.3   root      332: }
1.1.1.2   root      333: 
1.1.1.4   root      334: 
                    335: 
1.1.1.3   root      336: //
                    337: // W_NumLumps
                    338: //
1.1.1.4   root      339: int W_NumLumps (void)
1.1       root      340: {
1.1.1.4   root      341:     return numlumps;
1.1.1.3   root      342: }
1.1       root      343: 
1.1.1.4   root      344: 
                    345: 
1.1.1.3   root      346: //
                    347: // W_CheckNumForName
                    348: // Returns -1 if name not found.
                    349: //
1.1.1.2   root      350: 
1.1.1.4   root      351: int W_CheckNumForName (char* name)
1.1.1.3   root      352: {
1.1.1.4   root      353:     union {
                    354:        char    s[9];
                    355:        int     x[2];
                    356:        
                    357:     } name8;
                    358:     
                    359:     int                v1;
                    360:     int                v2;
                    361:     lumpinfo_t*        lump_p;
                    362: 
                    363:     // make the name into two integers for easy compares
                    364:     strncpy (name8.s,name,8);
                    365: 
                    366:     // in case the name was a fill 8 chars
                    367:     name8.s[8] = 0;
                    368: 
                    369:     // case insensitive
                    370:     strupr (name8.s);          
                    371: 
                    372:     v1 = name8.x[0];
                    373:     v2 = name8.x[1];
                    374: 
                    375: 
                    376:     // scan backwards so patch lump files take precedence
                    377:     lump_p = lumpinfo + numlumps;
                    378: 
                    379:     while (lump_p-- != lumpinfo)
                    380:     {
                    381:        if ( *(int *)lump_p->name == v1
                    382:             && *(int *)&lump_p->name[4] == v2)
1.1.1.3   root      383:        {
1.1.1.4   root      384:            return lump_p - lumpinfo;
1.1.1.3   root      385:        }
1.1.1.4   root      386:     }
                    387: 
                    388:     // TFB. Not found.
                    389:     return -1;
1.1       root      390: }
                    391: 
1.1.1.4   root      392: 
                    393: 
                    394: 
1.1.1.3   root      395: //
                    396: // W_GetNumForName
                    397: // Calls W_CheckNumForName, but bombs out if not found.
                    398: //
1.1.1.4   root      399: int W_GetNumForName (char* name)
1.1       root      400: {
1.1.1.4   root      401:     int        i;
1.1       root      402: 
1.1.1.4   root      403:     i = W_CheckNumForName (name);
                    404:     
                    405:     if (i == -1)
                    406:       I_Error ("W_GetNumForName: %s not found!", name);
                    407:       
                    408:     return i;
1.1       root      409: }
                    410: 
1.1.1.4   root      411: 
1.1.1.3   root      412: //
                    413: // W_LumpLength
                    414: // Returns the buffer size needed to load the given lump.
                    415: //
1.1.1.4   root      416: int W_LumpLength (int lump)
1.1       root      417: {
1.1.1.4   root      418:     if (lump >= numlumps)
                    419:        I_Error ("W_LumpLength: %i >= numlumps",lump);
                    420: 
                    421:     return lumpinfo[lump].size;
1.1       root      422: }
                    423: 
1.1.1.4   root      424: 
                    425: 
1.1.1.3   root      426: //
                    427: // W_ReadLump
1.1.1.4   root      428: // Loads the lump into the given buffer,
                    429: //  which must be >= W_LumpLength().
1.1.1.3   root      430: //
1.1.1.4   root      431: void
                    432: W_ReadLump
                    433: ( int          lump,
                    434:   void*                dest )
                    435: {
                    436:     int                c;
                    437:     lumpinfo_t*        l;
                    438:     int                handle;
                    439:        
                    440:     if (lump >= numlumps)
                    441:        I_Error ("W_ReadLump: %i >= numlumps",lump);
1.1.1.3   root      442: 
1.1.1.4   root      443:     l = lumpinfo+lump;
                    444:        
                    445:     // ??? I_BeginRead ();
                    446:        
                    447:     if (l->handle == -1)
                    448:     {
                    449:        // reloadable file, so use open / read / close
                    450:        if ( (handle = open (reloadname,O_RDONLY | O_BINARY)) == -1)
                    451:            I_Error ("W_ReadLump: couldn't open %s",reloadname);
                    452:     }
                    453:     else
                    454:        handle = l->handle;
                    455:                
                    456:     lseek (handle, l->position, SEEK_SET);
                    457:     c = read (handle, dest, l->size);
                    458: 
                    459:     if (c < l->size)
                    460:        I_Error ("W_ReadLump: only read %i of %i on lump %i",
                    461:                 c,l->size,lump);       
                    462: 
                    463:     if (l->handle == -1)
                    464:        close (handle);
                    465:                
                    466:     // ??? I_EndRead ();
1.1       root      467: }
                    468: 
1.1.1.4   root      469: 
                    470: 
                    471: 
1.1.1.3   root      472: //
                    473: // W_CacheLumpNum
                    474: //
1.1.1.4   root      475: void*
                    476: W_CacheLumpNum
                    477: ( int          lump,
                    478:   int          tag )
                    479: {
                    480:     byte*      ptr;
                    481: 
                    482:     if ((unsigned)lump >= numlumps)
                    483:        I_Error ("W_CacheLumpNum: %i >= numlumps",lump);
                    484:                
                    485:     if (!lumpcache[lump])
                    486:     {
                    487:        // read the lump in
                    488:        
                    489:        //printf ("cache miss on lump %i\n",lump);
                    490:        ptr = Z_Malloc (W_LumpLength (lump), tag, &lumpcache[lump]);
                    491:        W_ReadLump (lump, lumpcache[lump]);
                    492:     }
                    493:     else
                    494:     {
                    495:        //printf ("cache hit on lump %i\n",lump);
                    496:        Z_ChangeTag (lumpcache[lump],tag);
                    497:     }
                    498:        
                    499:     return lumpcache[lump];
                    500: }
1.1       root      501: 
1.1.1.2   root      502: 
1.1       root      503: 
1.1.1.3   root      504: //
                    505: // W_CacheLumpName
                    506: //
1.1.1.4   root      507: void*
                    508: W_CacheLumpName
                    509: ( char*                name,
                    510:   int          tag )
1.1       root      511: {
1.1.1.4   root      512:     return W_CacheLumpNum (W_GetNumForName(name), tag);
1.1       root      513: }
                    514: 
1.1.1.4   root      515: 
1.1.1.3   root      516: //
                    517: // W_Profile
                    518: //
1.1.1.4   root      519: int            info[2500][10];
                    520: int            profilecount;
1.1.1.2   root      521: 
                    522: void W_Profile (void)
                    523: {
1.1.1.4   root      524:     int                i;
                    525:     memblock_t*        block;
                    526:     void*      ptr;
                    527:     char       ch;
                    528:     FILE*      f;
                    529:     int                j;
                    530:     char       name[9];
1.1.1.2   root      531:        
1.1.1.4   root      532:        
                    533:     for (i=0 ; i<numlumps ; i++)
                    534:     {  
                    535:        ptr = lumpcache[i];
                    536:        if (!ptr)
1.1.1.2   root      537:        {
1.1.1.4   root      538:            ch = ' ';
                    539:            continue;
1.1.1.2   root      540:        }
1.1.1.4   root      541:        else
                    542:        {
                    543:            block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
                    544:            if (block->tag < PU_PURGELEVEL)
                    545:                ch = 'S';
                    546:            else
                    547:                ch = 'P';
                    548:        }
                    549:        info[i][profilecount] = ch;
                    550:     }
                    551:     profilecount++;
                    552:        
                    553:     f = fopen ("waddump.txt","w");
                    554:     name[8] = 0;
                    555: 
                    556:     for (i=0 ; i<numlumps ; i++)
                    557:     {
                    558:        memcpy (name,lumpinfo[i].name,8);
                    559: 
                    560:        for (j=0 ; j<8 ; j++)
                    561:            if (!name[j])
                    562:                break;
                    563: 
                    564:        for ( ; j<8 ; j++)
                    565:            name[j] = ' ';
                    566: 
                    567:        fprintf (f,"%s ",name);
                    568: 
                    569:        for (j=0 ; j<profilecount ; j++)
                    570:            fprintf (f,"    %c",info[i][j]);
                    571: 
                    572:        fprintf (f,"\n");
                    573:     }
                    574:     fclose (f);
1.1.1.2   root      575: }
1.1.1.4   root      576: 
                    577: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.