Annotation of doom/w_wad.c, revision 1.1.1.3

1.1.1.3 ! root        1: 
        !             2: //**************************************************************************
        !             3: //**
        !             4: //** w_wad.c : Heretic 2 : Raven Software, Corp.
        !             5: //**
        !             6: //** $RCSfile: w_wad.c,v $
        !             7: //** $Revision: 1.6 $
        !             8: //** $Date: 95/10/06 20:56:47 $
        !             9: //** $Author: cjr $
        !            10: //**
        !            11: //**************************************************************************
        !            12: 
        !            13: // HEADER FILES ------------------------------------------------------------
1.1       root       14: 
1.1.1.2   root       15: #ifdef NeXT
                     16: #include <libc.h>
                     17: #include <ctype.h>
                     18: #else
                     19: #include <malloc.h>
                     20: #include <io.h>
                     21: #include <fcntl.h>
                     22: #include <sys/stat.h>
                     23: #endif
1.1.1.3 ! root       24: #include "h2def.h"
1.1.1.2   root       25: 
1.1.1.3 ! root       26: // MACROS ------------------------------------------------------------------
1.1.1.2   root       27: 
1.1.1.3 ! root       28: #ifdef NeXT
        !            29: // NeXT doesn't need a binary flag in open call
        !            30: #define O_BINARY 0
        !            31: #define strcmpi strcasecmp
        !            32: #endif
1.1       root       33: 
1.1.1.3 ! root       34: // TYPES -------------------------------------------------------------------
1.1       root       35: 
                     36: typedef struct
                     37: {
1.1.1.3 ! root       38:        char identification[4];
        !            39:        int numlumps;
        !            40:        int infotableofs;
1.1       root       41: } wadinfo_t;
                     42: 
1.1.1.2   root       43: typedef struct
                     44: {
1.1.1.3 ! root       45:        int filepos;
        !            46:        int size;
        !            47:        char name[8];
1.1.1.2   root       48: } filelump_t;
                     49: 
1.1.1.3 ! root       50: // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
1.1       root       51: 
1.1.1.3 ! root       52: // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
1.1       root       53: 
1.1.1.3 ! root       54: // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
1.1       root       55: 
1.1.1.3 ! root       56: // EXTERNAL DATA DECLARATIONS ----------------------------------------------
1.1.1.2   root       57: 
1.1.1.3 ! root       58: // PUBLIC DATA DEFINITIONS -------------------------------------------------
1.1.1.2   root       59: 
1.1.1.3 ! root       60: lumpinfo_t *lumpinfo;
        !            61: int numlumps;
        !            62: void **lumpcache;
1.1.1.2   root       63: 
1.1.1.3 ! root       64: // PRIVATE DATA DEFINITIONS ------------------------------------------------
1.1.1.2   root       65: 
1.1.1.3 ! root       66: static lumpinfo_t *PrimaryLumpInfo;
        !            67: static int PrimaryNumLumps;
        !            68: static void **PrimaryLumpCache;
        !            69: static lumpinfo_t *AuxiliaryLumpInfo;
        !            70: static int AuxiliaryNumLumps;
        !            71: static void **AuxiliaryLumpCache;
        !            72: static int AuxiliaryHandle = 0;
        !            73: boolean AuxiliaryOpened = false;
        !            74: 
        !            75: // CODE --------------------------------------------------------------------
1.1       root       76: 
1.1.1.3 ! root       77: #ifdef NeXT
        !            78: //==========================================================================
        !            79: //
        !            80: // strupr
        !            81: //
        !            82: //==========================================================================
        !            83: 
        !            84: void strupr(char *s)
1.1       root       85: {
1.1.1.3 ! root       86:     while(*s)
1.1.1.2   root       87:        *s++ = toupper(*s);
1.1       root       88: }
                     89: 
1.1.1.3 ! root       90: //==========================================================================
        !            91: //
        !            92: // filelength
        !            93: //
        !            94: //==========================================================================
1.1       root       95: 
1.1.1.3 ! root       96: int filelength(int handle)
1.1.1.2   root       97: {
1.1.1.3 ! root       98:     struct stat fileinfo;
1.1       root       99: 
1.1.1.3 ! root      100:     if(fstat(handle, &fileinfo) == -1)
        !           101:        {
        !           102:                I_Error("Error fstating");
        !           103:        }
1.1.1.2   root      104:     return fileinfo.st_size;
                    105: }
                    106: #endif
1.1       root      107: 
1.1.1.3 ! root      108: //==========================================================================
1.1.1.2   root      109: //
1.1.1.3 ! root      110: // W_AddFile
1.1.1.2   root      111: //
1.1.1.3 ! root      112: // Files with a .wad extension are wadlink files with multiple lumps,
        !           113: // other files are single lumps with the base filename for the lump name.
1.1.1.2   root      114: //
1.1.1.3 ! root      115: //==========================================================================
1.1       root      116: 
1.1.1.3 ! root      117: void W_AddFile(char *filename)
1.1       root      118: {
1.1.1.3 ! root      119:        wadinfo_t header;
        !           120:        lumpinfo_t *lump_p;
        !           121:        unsigned i;
        !           122:        int handle, length;
        !           123:        int startlump;
        !           124:        filelump_t *fileinfo, singleinfo;
        !           125:        filelump_t *freeFileInfo;
1.1.1.2   root      126: 
1.1.1.3 ! root      127:        if((handle = open(filename, O_RDONLY|O_BINARY)) == -1)
        !           128:        { // Didn't find file
        !           129:                return;
        !           130:        }
1.1.1.2   root      131:        startlump = numlumps;
1.1.1.3 ! root      132:        if(strcmpi(filename+strlen(filename)-3, "wad"))
        !           133:        { // Single lump file
1.1.1.2   root      134:                fileinfo = &singleinfo;
1.1.1.3 ! root      135:                freeFileInfo = NULL;
1.1.1.2   root      136:                singleinfo.filepos = 0;
                    137:                singleinfo.size = LONG(filelength(handle));
1.1.1.3 ! root      138:                M_ExtractFileBase(filename, singleinfo.name);
1.1.1.2   root      139:                numlumps++;
                    140:        }
1.1.1.3 ! root      141:        else
        !           142:        { // WAD file
        !           143:                read(handle, &header, sizeof(header));
        !           144:                if(strncmp(header.identification, "IWAD", 4))
1.1.1.2   root      145:                {
1.1.1.3 ! root      146:                        if(strncmp(header.identification, "PWAD", 4))
        !           147:                        { // Bad file id
        !           148:                                I_Error("Wad file %s doesn't have IWAD or PWAD id\n",
        !           149:                                        filename);
        !           150:                        }
1.1.1.2   root      151:                }
                    152:                header.numlumps = LONG(header.numlumps);
                    153:                header.infotableofs = LONG(header.infotableofs);
                    154:                length = header.numlumps*sizeof(filelump_t);
1.1.1.3 ! root      155: //             fileinfo = alloca(length);
        !           156:                if(!(fileinfo = malloc(length)))
        !           157:                {
        !           158:                        I_Error("W_AddFile:  fileinfo malloc failed\n");
        !           159:                }
        !           160:                freeFileInfo = fileinfo;
        !           161:                lseek(handle, header.infotableofs, SEEK_SET);
        !           162:                read(handle, fileinfo, length);
1.1.1.2   root      163:                numlumps += header.numlumps;
                    164:        }
1.1       root      165: 
1.1.1.3 ! root      166:        // Fill in lumpinfo
        !           167:        lumpinfo = realloc(lumpinfo, numlumps*sizeof(lumpinfo_t));
        !           168:        if(!lumpinfo)
        !           169:        {
        !           170:                I_Error("Couldn't realloc lumpinfo");
        !           171:        }
1.1.1.2   root      172:        lump_p = &lumpinfo[startlump];
1.1.1.3 ! root      173:        for(i = startlump; i < numlumps; i++, lump_p++, fileinfo++)
1.1.1.2   root      174:        {
                    175:                lump_p->handle = handle;
                    176:                lump_p->position = LONG(fileinfo->filepos);
                    177:                lump_p->size = LONG(fileinfo->size);
1.1.1.3 ! root      178:                strncpy(lump_p->name, fileinfo->name, 8);
        !           179:        }
        !           180:        if(freeFileInfo)
        !           181:        {
        !           182:                free(freeFileInfo);
1.1.1.2   root      183:        }
                    184: }
                    185: 
1.1.1.3 ! root      186: //==========================================================================
        !           187: //
        !           188: // W_InitMultipleFiles
        !           189: //
        !           190: // Pass a null terminated list of files to use.  All files are optional,
        !           191: // but at least one file must be found.  Lump names can appear multiple
        !           192: // times.  The name searcher looks backwards, so a later file can
        !           193: // override an earlier one.
        !           194: //
        !           195: //==========================================================================
1.1.1.2   root      196: 
1.1.1.3 ! root      197: void W_InitMultipleFiles(char **filenames)
        !           198: {
        !           199:        int size;
1.1.1.2   root      200: 
1.1.1.3 ! root      201:        // Open all the files, load headers, and count lumps
        !           202:        numlumps = 0;
        !           203:        lumpinfo = malloc(1); // Will be realloced as lumps are added
1.1.1.2   root      204: 
1.1.1.3 ! root      205:        for(; *filenames; filenames++)
        !           206:        {
        !           207:                W_AddFile(*filenames);
        !           208:        }
        !           209:        if(!numlumps)
        !           210:        {
        !           211:                I_Error("W_InitMultipleFiles: no files found");
        !           212:        }
1.1.1.2   root      213: 
1.1.1.3 ! root      214:        // Set up caching
        !           215:        size = numlumps*sizeof(*lumpcache);
        !           216:        lumpcache = malloc(size);
        !           217:        if(!lumpcache)
        !           218:        {
        !           219:                I_Error("Couldn't allocate lumpcache");
        !           220:        }
        !           221:        memset(lumpcache, 0, size);
1.1.1.2   root      222: 
1.1.1.3 ! root      223:        PrimaryLumpInfo = lumpinfo;
        !           224:        PrimaryLumpCache = lumpcache;
        !           225:        PrimaryNumLumps = numlumps;
        !           226: }
        !           227: 
        !           228: //==========================================================================
1.1.1.2   root      229: //
1.1.1.3 ! root      230: // W_InitFile
1.1.1.2   root      231: //
1.1.1.3 ! root      232: // Initialize the primary from a single file.
        !           233: //
        !           234: //==========================================================================
1.1.1.2   root      235: 
1.1.1.3 ! root      236: void W_InitFile(char *filename)
        !           237: {
        !           238:        char *names[2];
1.1.1.2   root      239: 
1.1.1.3 ! root      240:        names[0] = filename;
        !           241:        names[1] = NULL;
        !           242:        W_InitMultipleFiles(names);
1.1.1.2   root      243: }
                    244: 
1.1.1.3 ! root      245: //==========================================================================
        !           246: //
        !           247: // W_OpenAuxiliary
        !           248: //
        !           249: //==========================================================================
1.1       root      250: 
1.1.1.3 ! root      251: void W_OpenAuxiliary(char *filename)
        !           252: {
        !           253:        int i;
        !           254:        int size;
        !           255:        wadinfo_t header;
        !           256:        int handle;
        !           257:        int length;
        !           258:        filelump_t *fileinfo;
        !           259:        filelump_t *sourceLump;
        !           260:        lumpinfo_t *destLump;
1.1.1.2   root      261: 
1.1.1.3 ! root      262:        if(AuxiliaryOpened)
        !           263:        {
        !           264:                W_CloseAuxiliary();
        !           265:        }
        !           266:        if((handle = open(filename, O_RDONLY|O_BINARY)) == -1)
        !           267:        {
        !           268:                I_Error("W_OpenAuxiliary: %s not found.", filename);
        !           269:                return;
        !           270:        }
        !           271:        AuxiliaryHandle = handle;
        !           272:        read(handle, &header, sizeof(header));
        !           273:        if(strncmp(header.identification, "IWAD", 4))
        !           274:        {
        !           275:                if(strncmp(header.identification, "PWAD", 4))
        !           276:                { // Bad file id
        !           277:                        I_Error("Wad file %s doesn't have IWAD or PWAD id\n",
        !           278:                                filename);
        !           279:                }
        !           280:        }
        !           281:        header.numlumps = LONG(header.numlumps);
        !           282:        header.infotableofs = LONG(header.infotableofs);
        !           283:        length = header.numlumps*sizeof(filelump_t);
        !           284:        fileinfo = Z_Malloc(length, PU_STATIC, 0);
        !           285:        lseek(handle, header.infotableofs, SEEK_SET);
        !           286:        read(handle, fileinfo, length);
        !           287:        numlumps = header.numlumps;
        !           288: 
        !           289:        // Init the auxiliary lumpinfo array
        !           290:        lumpinfo = Z_Malloc(numlumps*sizeof(lumpinfo_t), PU_STATIC, 0);
        !           291:        sourceLump = fileinfo;
        !           292:        destLump = lumpinfo;
        !           293:        for(i = 0; i < numlumps; i++, destLump++, sourceLump++)
        !           294:        {
        !           295:                destLump->handle = handle;
        !           296:                destLump->position = LONG(sourceLump->filepos);
        !           297:                destLump->size = LONG(sourceLump->size);
        !           298:                strncpy(destLump->name, sourceLump->name, 8);
        !           299:        }
        !           300:        Z_Free(fileinfo);
        !           301: 
        !           302:        // Allocate the auxiliary lumpcache array
        !           303:        size = numlumps*sizeof(*lumpcache);
        !           304:        lumpcache = Z_Malloc(size, PU_STATIC, 0);
        !           305:        memset(lumpcache, 0, size);
        !           306: 
        !           307:        AuxiliaryLumpInfo = lumpinfo;
        !           308:        AuxiliaryLumpCache = lumpcache;
        !           309:        AuxiliaryNumLumps = numlumps;
        !           310:        AuxiliaryOpened = true;
        !           311: }
1.1.1.2   root      312: 
1.1.1.3 ! root      313: //==========================================================================
        !           314: //
        !           315: // W_CloseAuxiliary
        !           316: //
        !           317: //==========================================================================
        !           318: 
        !           319: void W_CloseAuxiliary(void)
1.1.1.2   root      320: {
1.1.1.3 ! root      321:        int i;
1.1.1.2   root      322: 
1.1.1.3 ! root      323:        if(AuxiliaryOpened)
        !           324:        {
        !           325:                W_UseAuxiliary();
        !           326:                for(i = 0; i < numlumps; i++)
        !           327:                {
        !           328:                        if(lumpcache[i])
        !           329:                        {
        !           330:                                Z_Free(lumpcache[i]);
        !           331:                        }
        !           332:                }
        !           333:                Z_Free(AuxiliaryLumpInfo);
        !           334:                Z_Free(AuxiliaryLumpCache);
        !           335:                W_CloseAuxiliaryFile();
        !           336:                AuxiliaryOpened = false;
        !           337:        }
        !           338:        W_UsePrimary();
1.1       root      339: }
                    340: 
1.1.1.3 ! root      341: //==========================================================================
        !           342: //
        !           343: // W_CloseAuxiliaryFile
        !           344: //
        !           345: // WARNING: W_CloseAuxiliary() must be called before any further
        !           346: // auxiliary lump processing.
        !           347: //
        !           348: //==========================================================================
1.1       root      349: 
1.1.1.3 ! root      350: void W_CloseAuxiliaryFile(void)
        !           351: {
        !           352:        if(AuxiliaryHandle)
        !           353:        {
        !           354:                close(AuxiliaryHandle);
        !           355:                AuxiliaryHandle = 0;
        !           356:        }
        !           357: }
1.1.1.2   root      358: 
1.1.1.3 ! root      359: //==========================================================================
        !           360: //
        !           361: // W_UsePrimary
        !           362: //
        !           363: //==========================================================================
1.1.1.2   root      364: 
1.1.1.3 ! root      365: void W_UsePrimary(void)
1.1.1.2   root      366: {
1.1.1.3 ! root      367:        lumpinfo = PrimaryLumpInfo;
        !           368:        numlumps = PrimaryNumLumps;
        !           369:        lumpcache = PrimaryLumpCache;
1.1.1.2   root      370: }
                    371: 
1.1.1.3 ! root      372: //==========================================================================
        !           373: //
        !           374: // W_UseAuxiliary
        !           375: //
        !           376: //==========================================================================
1.1.1.2   root      377: 
1.1.1.3 ! root      378: void W_UseAuxiliary(void)
        !           379: {
        !           380:        if(AuxiliaryOpened == false)
        !           381:        {
        !           382:                I_Error("W_UseAuxiliary: WAD not opened.");
        !           383:        }
        !           384:        lumpinfo = AuxiliaryLumpInfo;
        !           385:        numlumps = AuxiliaryNumLumps;
        !           386:        lumpcache = AuxiliaryLumpCache;
        !           387: }
1.1.1.2   root      388: 
1.1.1.3 ! root      389: //==========================================================================
        !           390: //
        !           391: // W_NumLumps
        !           392: //
        !           393: //==========================================================================
1.1       root      394: 
1.1.1.3 ! root      395: int    W_NumLumps(void)
1.1       root      396: {
1.1.1.3 ! root      397:        return numlumps;
        !           398: }
1.1       root      399: 
1.1.1.3 ! root      400: //==========================================================================
        !           401: //
        !           402: // W_CheckNumForName
        !           403: //
        !           404: // Returns -1 if name not found.
        !           405: //
        !           406: //==========================================================================
1.1.1.2   root      407: 
1.1.1.3 ! root      408: int W_CheckNumForName(char *name)
        !           409: {
        !           410:        char name8[9];
        !           411:        int v1, v2;
        !           412:        lumpinfo_t *lump_p;
1.1       root      413: 
1.1.1.3 ! root      414:        // Make the name into two integers for easy compares
        !           415:        strncpy(name8, name, 8);
        !           416:        name8[8] = 0; // in case the name was a full 8 chars
        !           417:        strupr(name8); // case insensitive
1.1       root      418:        v1 = *(int *)name8;
                    419:        v2 = *(int *)&name8[4];
                    420: 
1.1.1.3 ! root      421:        // Scan backwards so patch lump files take precedence
        !           422:        lump_p = lumpinfo+numlumps;
        !           423:        while(lump_p-- != lumpinfo)
        !           424:        {
        !           425:                if(*(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
        !           426:                {
        !           427:                        return lump_p-lumpinfo;
        !           428:                }
        !           429:        }
1.1       root      430:        return -1;
                    431: }
                    432: 
1.1.1.3 ! root      433: //==========================================================================
        !           434: //
        !           435: // W_GetNumForName
        !           436: //
        !           437: // Calls W_CheckNumForName, but bombs out if not found.
        !           438: //
        !           439: //==========================================================================
1.1       root      440: 
                    441: int    W_GetNumForName (char *name)
                    442: {
                    443:        int     i;
                    444: 
1.1.1.3 ! root      445:        i = W_CheckNumForName(name);
        !           446:        if(i != -1)
        !           447:        {
1.1       root      448:                return i;
1.1.1.3 ! root      449:        }
        !           450:        I_Error("W_GetNumForName: %s not found!", name);
1.1       root      451:        return -1;
                    452: }
                    453: 
1.1.1.3 ! root      454: //==========================================================================
        !           455: //
        !           456: // W_LumpLength
        !           457: //
        !           458: // Returns the buffer size needed to load the given lump.
        !           459: //
        !           460: //==========================================================================
1.1       root      461: 
1.1.1.3 ! root      462: int W_LumpLength(int lump)
1.1       root      463: {
1.1.1.3 ! root      464:        if(lump >= numlumps)
        !           465:        {
        !           466:                I_Error("W_LumpLength: %i >= numlumps", lump);
        !           467:        }
1.1.1.2   root      468:        return lumpinfo[lump].size;
1.1       root      469: }
                    470: 
1.1.1.3 ! root      471: //==========================================================================
        !           472: //
        !           473: // W_ReadLump
        !           474: //
        !           475: // Loads the lump into the given buffer, which must be >= W_LumpLength().
        !           476: //
        !           477: //==========================================================================
1.1       root      478: 
1.1.1.3 ! root      479: void W_ReadLump(int lump, void *dest)
1.1       root      480: {
1.1.1.3 ! root      481:        int c;
        !           482:        lumpinfo_t *l;
        !           483: 
        !           484:        if(lump >= numlumps)
        !           485:        {
        !           486:                I_Error("W_ReadLump: %i >= numlumps", lump);
        !           487:        }
1.1       root      488:        l = lumpinfo+lump;
1.1.1.3 ! root      489:        //I_BeginRead();
        !           490:        lseek(l->handle, l->position, SEEK_SET);
        !           491:        c = read(l->handle, dest, l->size);
        !           492:        if(c < l->size)
        !           493:        {
        !           494:                I_Error("W_ReadLump: only read %i of %i on lump %i",
        !           495:                        c, l->size, lump);
        !           496:        }
        !           497:        //I_EndRead();
1.1       root      498: }
                    499: 
1.1.1.3 ! root      500: //==========================================================================
        !           501: //
        !           502: // W_CacheLumpNum
        !           503: //
        !           504: //==========================================================================
1.1       root      505: 
1.1.1.3 ! root      506: void *W_CacheLumpNum(int lump, int tag)
1.1       root      507: {
1.1.1.3 ! root      508:        byte *ptr;
1.1.1.2   root      509: 
1.1.1.3 ! root      510:        if((unsigned)lump >= numlumps)
        !           511:        {
        !           512:                I_Error("W_CacheLumpNum: %i >= numlumps", lump);
        !           513:        }
        !           514:        if(!lumpcache[lump])
        !           515:        { // Need to read the lump in
        !           516:                ptr = Z_Malloc(W_LumpLength(lump), tag, &lumpcache[lump]);
        !           517:                W_ReadLump(lump, lumpcache[lump]);
1.1       root      518:        }
                    519:        else
1.1.1.2   root      520:        {
1.1.1.3 ! root      521:                Z_ChangeTag(lumpcache[lump], tag);
1.1.1.2   root      522:        }
1.1       root      523:        return lumpcache[lump];
                    524: }
                    525: 
1.1.1.3 ! root      526: //==========================================================================
        !           527: //
        !           528: // W_CacheLumpName
        !           529: //
        !           530: //==========================================================================
1.1       root      531: 
1.1.1.3 ! root      532: void *W_CacheLumpName(char *name, int tag)
1.1       root      533: {
1.1.1.3 ! root      534:        return W_CacheLumpNum(W_GetNumForName(name), tag);
1.1       root      535: }
                    536: 
1.1.1.3 ! root      537: //==========================================================================
        !           538: //
        !           539: // W_Profile
        !           540: //
        !           541: //==========================================================================
1.1.1.2   root      542: 
                    543: // Ripped out for Heretic
                    544: /*
                    545: int    info[2500][10];
                    546: int    profilecount;
                    547: 
                    548: void W_Profile (void)
                    549: {
                    550:        int             i;
                    551:        memblock_t      *block;
                    552:        void    *ptr;
                    553:        char    ch;
                    554:        FILE    *f;
                    555:        int             j;
                    556:        char    name[9];
                    557:        
                    558:        
                    559:        for (i=0 ; i<numlumps ; i++)
                    560:        {       
                    561:                ptr = lumpcache[i];
                    562:                if (!ptr)
                    563:                {
                    564:                        ch = ' ';
                    565:                        continue;
                    566:                }
                    567:                else
                    568:                {
                    569:                        block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
                    570:                        if (block->tag < PU_PURGELEVEL)
                    571:                                ch = 'S';
                    572:                        else
                    573:                                ch = 'P';
                    574:                }
                    575:                info[i][profilecount] = ch;
                    576:        }
                    577:        profilecount++;
                    578:        
                    579:        f = fopen ("waddump.txt","w");
                    580:        name[8] = 0;
                    581:        for (i=0 ; i<numlumps ; i++)
                    582:        {
                    583:                memcpy (name,lumpinfo[i].name,8);
                    584:                for (j=0 ; j<8 ; j++)
                    585:                        if (!name[j])
                    586:                                break;
                    587:                for ( ; j<8 ; j++)
                    588:                        name[j] = ' ';
                    589:                fprintf (f,"%s ",name);
                    590:                for (j=0 ; j<profilecount ; j++)
                    591:                        fprintf (f,"    %c",info[i][j]);
                    592:                fprintf (f,"\n");
                    593:        }
                    594:        fclose (f);
                    595: }
                    596: */

unix.superglobalmegacorp.com

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