Annotation of doom/w_wad.c, revision 1.1.1.2

1.1.1.2 ! root        1: // W_wad.c
1.1       root        2: 
1.1.1.2 ! root        3: #ifdef NeXT
        !             4: #include <libc.h>
        !             5: #include <ctype.h>
1.1       root        6: 
1.1.1.2 ! root        7: // next doesn't need a binary flag in open call
        !             8: #define        O_BINARY        0
1.1       root        9: 
1.1.1.2 ! root       10: #else
        !            11: 
        !            12: #include <malloc.h>
        !            13: #include <io.h>
        !            14: #include <fcntl.h>
        !            15: #include <sys/stat.h>
        !            16: #endif
        !            17: 
        !            18: #include "DoomDef.h"
        !            19: 
        !            20: //===============
        !            21: //   TYPES
        !            22: //===============
1.1       root       23: 
                     24: 
                     25: typedef struct
                     26: {
1.1.1.2 ! root       27:        char            identification[4];              // should be IWAD
1.1       root       28:        int                     numlumps;
                     29:        int                     infotableofs;
                     30: } wadinfo_t;
                     31: 
                     32: 
1.1.1.2 ! root       33: typedef struct
        !            34: {
        !            35:        int                     filepos;
        !            36:        int                     size;
        !            37:        char            name[8];
        !            38: } filelump_t;
        !            39: 
1.1       root       40: 
1.1.1.2 ! root       41: //=============
        !            42: // GLOBALS
        !            43: //=============
1.1       root       44: 
1.1.1.2 ! root       45: lumpinfo_t     *lumpinfo;              // location of each lump on disk
1.1       root       46: int                    numlumps;
                     47: 
1.1.1.2 ! root       48: void           **lumpcache;
        !            49: 
        !            50: 
        !            51: //===================
        !            52: 
        !            53: #ifdef NeXT
        !            54: 
        !            55: #define strcmpi strcasecmp
1.1       root       56: 
                     57: void strupr (char *s)
                     58: {
1.1.1.2 ! root       59:     while (*s)
        !            60:        *s++ = toupper(*s);
1.1       root       61: }
                     62: 
1.1.1.2 ! root       63: /*
        !            64: ================
        !            65: =
        !            66: = filelength
        !            67: =
        !            68: ================
        !            69: */
1.1       root       70: 
1.1.1.2 ! root       71: int filelength (int handle)
        !            72: {
        !            73:     struct stat        fileinfo;
        !            74:     
        !            75:     if (fstat (handle,&fileinfo) == -1)
        !            76:        I_Error ("Error fstating");
1.1       root       77: 
1.1.1.2 ! root       78:     return fileinfo.st_size;
        !            79: }
1.1       root       80: 
1.1.1.2 ! root       81: #endif
1.1       root       82: 
                     83: 
1.1.1.2 ! root       84: void ExtractFileBase (char *path, char *dest)
1.1       root       85: {
1.1.1.2 ! root       86:        char    *src;
        !            87:        int             length;
1.1       root       88: 
1.1.1.2 ! root       89:        src = path + strlen(path) - 1;
1.1       root       90: 
1.1.1.2 ! root       91: //
        !            92: // back up until a \ or the start
        !            93: //
        !            94:        while (src != path && *(src-1) != '\\' && *(src-1) != '/')
        !            95:                src--;
        !            96: 
        !            97: //
        !            98: // copy up to eight characters
        !            99: //
        !           100:        memset (dest,0,8);
        !           101:        length = 0;
        !           102:        while (*src && *src != '.')
        !           103:        {
        !           104:                if (++length == 9)
        !           105:                        I_Error ("Filename base of %s >8 chars",path);
        !           106:                *dest++ = toupper((int)*src++);
        !           107:        }
1.1       root      108: }
                    109: 
                    110: /*
                    111: ============================================================================
                    112: 
                    113:                                                LUMP BASED ROUTINES
                    114: 
                    115: ============================================================================
                    116: */
                    117: 
                    118: /*
                    119: ====================
                    120: =
1.1.1.2 ! root      121: = W_AddFile
        !           122: =
        !           123: = All files are optional, but at least one file must be found
        !           124: = Files with a .wad extension are wadlink files with multiple lumps
        !           125: = Other files are single lumps with the base filename for the lump name
1.1       root      126: =
                    127: ====================
                    128: */
                    129: 
1.1.1.2 ! root      130: void W_AddFile (char *filename)
1.1       root      131: {
1.1.1.2 ! root      132:        wadinfo_t               header;
        !           133:        lumpinfo_t              *lump_p;
        !           134:        unsigned                i;
        !           135:        int                             handle, length;
        !           136:        int                             startlump;
        !           137:        filelump_t              *fileinfo, singleinfo;
        !           138:        
        !           139: //
        !           140: // open the file and add to directory
        !           141: //     
        !           142:        if ( (handle = open (filename,O_RDONLY | O_BINARY)) == -1)
        !           143:                return;
        !           144: 
        !           145:        startlump = numlumps;
1.1       root      146:        
1.1.1.2 ! root      147:        if (strcmpi (filename+strlen(filename)-3 , "wad" ) )
        !           148:        {
        !           149:        // single lump file
        !           150:                fileinfo = &singleinfo;
        !           151:                singleinfo.filepos = 0;
        !           152:                singleinfo.size = LONG(filelength(handle));
        !           153:                ExtractFileBase (filename, singleinfo.name);
        !           154:                numlumps++;
        !           155:        }
        !           156:        else 
        !           157:        {
        !           158:        // WAD file
        !           159:                read (handle, &header, sizeof(header));
        !           160:                if (strncmp(header.identification,"IWAD",4))
        !           161:                {
        !           162:                        if (strncmp(header.identification,"PWAD",4))
        !           163:                                I_Error ("Wad file %s doesn't have IWAD or PWAD id\n"
        !           164:                                ,filename);
        !           165:                }
        !           166:                header.numlumps = LONG(header.numlumps);
        !           167:                header.infotableofs = LONG(header.infotableofs);
        !           168:                length = header.numlumps*sizeof(filelump_t);
        !           169:                fileinfo = alloca (length);
        !           170:                lseek (handle, header.infotableofs, SEEK_SET);
        !           171:                read (handle, fileinfo, length);
        !           172:                numlumps += header.numlumps;
        !           173:        }
1.1       root      174: 
1.1.1.2 ! root      175: //
        !           176: // Fill in lumpinfo
        !           177: //
        !           178:        lumpinfo = realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));
        !           179:        if (!lumpinfo)
        !           180:                I_Error ("Couldn't realloc lumpinfo");
        !           181:        lump_p = &lumpinfo[startlump];
1.1       root      182:        
1.1.1.2 ! root      183:        for (i=startlump ; i<numlumps ; i++,lump_p++, fileinfo++)
        !           184:        {
        !           185:                lump_p->handle = handle;
        !           186:                lump_p->position = LONG(fileinfo->filepos);
        !           187:                lump_p->size = LONG(fileinfo->size);
        !           188:                strncpy (lump_p->name, fileinfo->name, 8);
        !           189:        }
        !           190: }
        !           191: 
        !           192: 
        !           193: 
        !           194: 
        !           195: 
        !           196: /*
        !           197: ====================
        !           198: =
        !           199: = W_InitMultipleFiles
        !           200: =
        !           201: = Pass a null terminated list of files to use.
        !           202: =
        !           203: = All files are optional, but at least one file must be found
        !           204: =
        !           205: = Files with a .wad extension are idlink files with multiple lumps
        !           206: =
        !           207: = Other files are single lumps with the base filename for the lump name
        !           208: =
        !           209: = Lump names can appear multiple times. The name searcher looks backwards,
        !           210: = so a later file can override an earlier one.
        !           211: =
        !           212: ====================
        !           213: */
        !           214: 
        !           215: void W_InitMultipleFiles (char **filenames)
        !           216: {      
        !           217:        int             size;
        !           218:        
        !           219: //
        !           220: // open all the files, load headers, and count lumps
        !           221: //
        !           222:        numlumps = 0;
        !           223:        lumpinfo = malloc(1);   // will be realloced as lumps are added
        !           224: 
        !           225:        for ( ; *filenames ; filenames++)
        !           226:                W_AddFile (*filenames);
        !           227: 
        !           228:        if (!numlumps)
        !           229:                I_Error ("W_InitFiles: no files found");
        !           230:                
        !           231: //
        !           232: // set up caching
        !           233: //
        !           234:        size = numlumps * sizeof(*lumpcache);
        !           235:        lumpcache = malloc (size);
        !           236:        if (!lumpcache)
        !           237:                I_Error ("Couldn't allocate lumpcache");
        !           238:        memset (lumpcache,0, size);
        !           239: }
        !           240: 
1.1       root      241: 
1.1.1.2 ! root      242: 
        !           243: /*
        !           244: ====================
        !           245: =
        !           246: = W_InitFile
        !           247: =
        !           248: = Just initialize from a single file
        !           249: =
        !           250: ====================
        !           251: */
        !           252: 
        !           253: void W_InitFile (char *filename)
        !           254: {
        !           255:        char    *names[2];
        !           256: 
        !           257:        names[0] = filename;
        !           258:        names[1] = NULL;
        !           259:        W_InitMultipleFiles (names);
1.1       root      260: }
                    261: 
                    262: 
1.1.1.2 ! root      263: 
        !           264: /*
        !           265: ====================
        !           266: =
        !           267: = W_NumLumps
        !           268: =
        !           269: ====================
        !           270: */
        !           271: 
        !           272: int    W_NumLumps (void)
        !           273: {
        !           274:        return numlumps;
        !           275: }
        !           276: 
        !           277: 
        !           278: 
1.1       root      279: /*
                    280: ====================
                    281: =
                    282: = W_CheckNumForName
                    283: =
                    284: = Returns -1 if name not found
                    285: =
                    286: ====================
                    287: */
                    288: 
                    289: int    W_CheckNumForName (char *name)
                    290: {
1.1.1.2 ! root      291:        char    name8[9];
1.1       root      292:        int             v1,v2;
                    293:        lumpinfo_t      *lump_p;
                    294: 
1.1.1.2 ! root      295: // make the name into two integers for easy compares
        !           296: 
        !           297:        strncpy (name8,name,8);
        !           298:        name8[8] = 0;                   // in case the name was a fill 8 chars
        !           299:        strupr (name8);                 // case insensitive
1.1       root      300: 
                    301:        v1 = *(int *)name8;
                    302:        v2 = *(int *)&name8[4];
                    303: 
                    304: 
1.1.1.2 ! root      305: // scan backwards so patch lump files take precedence
1.1       root      306: 
                    307:        lump_p = lumpinfo + numlumps;
                    308: 
                    309:        while (lump_p-- != lumpinfo)
1.1.1.2 ! root      310:                if ( *(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
1.1       root      311:                        return lump_p - lumpinfo;
                    312: 
                    313: 
                    314:        return -1;
                    315: }
                    316: 
                    317: 
                    318: /*
                    319: ====================
                    320: =
                    321: = W_GetNumForName
                    322: =
                    323: = Calls W_CheckNumForName, but bombs out if not found
                    324: =
                    325: ====================
                    326: */
                    327: 
                    328: int    W_GetNumForName (char *name)
                    329: {
                    330:        int     i;
                    331: 
                    332:        i = W_CheckNumForName (name);
                    333:        if (i != -1)
                    334:                return i;
                    335: 
                    336:        I_Error ("W_GetNumForName: %s not found!",name);
                    337:        return -1;
                    338: }
                    339: 
                    340: 
                    341: /*
                    342: ====================
                    343: =
                    344: = W_LumpLength
                    345: =
                    346: = Returns the buffer size needed to load the given lump
                    347: =
                    348: ====================
                    349: */
                    350: 
                    351: int W_LumpLength (int lump)
                    352: {
                    353:        if (lump >= numlumps)
                    354:                I_Error ("W_LumpLength: %i >= numlumps",lump);
1.1.1.2 ! root      355:        return lumpinfo[lump].size;
1.1       root      356: }
                    357: 
                    358: 
                    359: /*
                    360: ====================
                    361: =
                    362: = W_ReadLump
                    363: =
                    364: = Loads the lump into the given buffer, which must be >= W_LumpLength()
                    365: =
                    366: ====================
                    367: */
                    368: 
                    369: void W_ReadLump (int lump, void *dest)
                    370: {
1.1.1.2 ! root      371:        int                     c;
1.1       root      372:        lumpinfo_t      *l;
                    373:        
                    374:        if (lump >= numlumps)
                    375:                I_Error ("W_ReadLump: %i >= numlumps",lump);
                    376:        l = lumpinfo+lump;
1.1.1.2 ! root      377:        
        !           378:        I_BeginRead ();
        !           379:        
        !           380:        lseek (l->handle, l->position, SEEK_SET);
        !           381:        c = read (l->handle, dest, l->size);
        !           382:        if (c < l->size)
        !           383:                I_Error ("W_ReadLump: only read %i of %i on lump %i",c,l->size,lump);   
        !           384:        I_EndRead ();
1.1       root      385: }
                    386: 
                    387: 
                    388: 
                    389: /*
                    390: ====================
                    391: =
                    392: = W_CacheLumpNum
                    393: =
                    394: ====================
                    395: */
                    396: 
                    397: void   *W_CacheLumpNum (int lump, int tag)
                    398: {
1.1.1.2 ! root      399: byte *ptr;
        !           400: 
1.1       root      401:        if ((unsigned)lump >= numlumps)
                    402:                I_Error ("W_CacheLumpNum: %i >= numlumps",lump);
                    403:                
                    404:        if (!lumpcache[lump])
1.1.1.2 ! root      405:        {       // read the lump in
        !           406: //printf ("cache miss on lump %i\n",lump);
        !           407:                ptr = Z_Malloc (W_LumpLength (lump), tag, &lumpcache[lump]);
1.1       root      408:                W_ReadLump (lump, lumpcache[lump]);
                    409:        }
                    410:        else
1.1.1.2 ! root      411:        {
        !           412: //printf ("cache hit on lump %i\n",lump);
1.1       root      413:                Z_ChangeTag (lumpcache[lump],tag);
1.1.1.2 ! root      414:        }
1.1       root      415:        
                    416:        return lumpcache[lump];
                    417: }
                    418: 
                    419: 
                    420: /*
                    421: ====================
                    422: =
                    423: = W_CacheLumpName
                    424: =
                    425: ====================
                    426: */
                    427: 
                    428: void   *W_CacheLumpName (char *name, int tag)
                    429: {
                    430:        return W_CacheLumpNum (W_GetNumForName(name), tag);
                    431: }
                    432: 
1.1.1.2 ! root      433: 
        !           434: /*
        !           435: ====================
        !           436: =
        !           437: = W_Profile
        !           438: =
        !           439: ====================
        !           440: */
        !           441: 
        !           442: // Ripped out for Heretic
        !           443: /*
        !           444: int    info[2500][10];
        !           445: int    profilecount;
        !           446: 
        !           447: void W_Profile (void)
        !           448: {
        !           449:        int             i;
        !           450:        memblock_t      *block;
        !           451:        void    *ptr;
        !           452:        char    ch;
        !           453:        FILE    *f;
        !           454:        int             j;
        !           455:        char    name[9];
        !           456:        
        !           457:        
        !           458:        for (i=0 ; i<numlumps ; i++)
        !           459:        {       
        !           460:                ptr = lumpcache[i];
        !           461:                if (!ptr)
        !           462:                {
        !           463:                        ch = ' ';
        !           464:                        continue;
        !           465:                }
        !           466:                else
        !           467:                {
        !           468:                        block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
        !           469:                        if (block->tag < PU_PURGELEVEL)
        !           470:                                ch = 'S';
        !           471:                        else
        !           472:                                ch = 'P';
        !           473:                }
        !           474:                info[i][profilecount] = ch;
        !           475:        }
        !           476:        profilecount++;
        !           477:        
        !           478:        f = fopen ("waddump.txt","w");
        !           479:        name[8] = 0;
        !           480:        for (i=0 ; i<numlumps ; i++)
        !           481:        {
        !           482:                memcpy (name,lumpinfo[i].name,8);
        !           483:                for (j=0 ; j<8 ; j++)
        !           484:                        if (!name[j])
        !           485:                                break;
        !           486:                for ( ; j<8 ; j++)
        !           487:                        name[j] = ' ';
        !           488:                fprintf (f,"%s ",name);
        !           489:                for (j=0 ; j<profilecount ; j++)
        !           490:                        fprintf (f,"    %c",info[i][j]);
        !           491:                fprintf (f,"\n");
        !           492:        }
        !           493:        fclose (f);
        !           494: }
        !           495: */

unix.superglobalmegacorp.com

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