123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597 |
- //**************************************************************************
- //**
- //** w_wad.c : Heretic 2 : Raven Software, Corp.
- //**
- //** $RCSfile: w_wad.c,v $
- //** $Revision: 1.6 $
- //** $Date: 95/10/06 20:56:47 $
- //** $Author: cjr $
- //**
- //**************************************************************************
- // HEADER FILES ------------------------------------------------------------
- #ifdef NeXT
- #include <libc.h>
- #include <ctype.h>
- #else
- #include <malloc.h>
- #include <io.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #endif
- #include "h2def.h"
- // MACROS ------------------------------------------------------------------
- #ifdef NeXT
- // NeXT doesn't need a binary flag in open call
- #define O_BINARY 0
- #define strcmpi strcasecmp
- #endif
- // TYPES -------------------------------------------------------------------
- typedef struct
- {
- char identification[4];
- int numlumps;
- int infotableofs;
- } wadinfo_t;
- typedef struct
- {
- int filepos;
- int size;
- char name[8];
- } filelump_t;
- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
- // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
- // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
- // EXTERNAL DATA DECLARATIONS ----------------------------------------------
- // PUBLIC DATA DEFINITIONS -------------------------------------------------
- lumpinfo_t *lumpinfo;
- int numlumps;
- void **lumpcache;
- // PRIVATE DATA DEFINITIONS ------------------------------------------------
- static lumpinfo_t *PrimaryLumpInfo;
- static int PrimaryNumLumps;
- static void **PrimaryLumpCache;
- static lumpinfo_t *AuxiliaryLumpInfo;
- static int AuxiliaryNumLumps;
- static void **AuxiliaryLumpCache;
- static int AuxiliaryHandle = 0;
- boolean AuxiliaryOpened = false;
- // CODE --------------------------------------------------------------------
- #ifdef NeXT
- //==========================================================================
- //
- // strupr
- //
- //==========================================================================
- void strupr(char *s)
- {
- while(*s)
- *s++ = toupper(*s);
- }
- //==========================================================================
- //
- // filelength
- //
- //==========================================================================
- int filelength(int handle)
- {
- struct stat fileinfo;
- if(fstat(handle, &fileinfo) == -1)
- {
- I_Error("Error fstating");
- }
- return fileinfo.st_size;
- }
- #endif
- //==========================================================================
- //
- // W_AddFile
- //
- // Files with a .wad extension are wadlink files with multiple lumps,
- // other files are single lumps with the base filename for the lump name.
- //
- //==========================================================================
- void W_AddFile(char *filename)
- {
- wadinfo_t header;
- lumpinfo_t *lump_p;
- unsigned i;
- int handle, length;
- int startlump;
- filelump_t *fileinfo, singleinfo;
- filelump_t *freeFileInfo;
- if((handle = open(filename, O_RDONLY|O_BINARY)) == -1)
- { // Didn't find file
- return;
- }
- startlump = numlumps;
- if(strcmpi(filename+strlen(filename)-3, "wad"))
- { // Single lump file
- fileinfo = &singleinfo;
- freeFileInfo = NULL;
- singleinfo.filepos = 0;
- singleinfo.size = LONG(filelength(handle));
- M_ExtractFileBase(filename, singleinfo.name);
- numlumps++;
- }
- else
- { // WAD file
- read(handle, &header, sizeof(header));
- if(strncmp(header.identification, "IWAD", 4))
- {
- if(strncmp(header.identification, "PWAD", 4))
- { // Bad file id
- I_Error("Wad file %s doesn't have IWAD or PWAD id\n",
- filename);
- }
- }
- header.numlumps = LONG(header.numlumps);
- header.infotableofs = LONG(header.infotableofs);
- length = header.numlumps*sizeof(filelump_t);
- // fileinfo = alloca(length);
- if(!(fileinfo = malloc(length)))
- {
- I_Error("W_AddFile: fileinfo malloc failed\n");
- }
- freeFileInfo = fileinfo;
- lseek(handle, header.infotableofs, SEEK_SET);
- read(handle, fileinfo, length);
- numlumps += header.numlumps;
- }
- // Fill in lumpinfo
- lumpinfo = realloc(lumpinfo, numlumps*sizeof(lumpinfo_t));
- if(!lumpinfo)
- {
- I_Error("Couldn't realloc lumpinfo");
- }
- lump_p = &lumpinfo[startlump];
- for(i = startlump; i < numlumps; i++, lump_p++, fileinfo++)
- {
- lump_p->handle = handle;
- lump_p->position = LONG(fileinfo->filepos);
- lump_p->size = LONG(fileinfo->size);
- strncpy(lump_p->name, fileinfo->name, 8);
- }
- if(freeFileInfo)
- {
- free(freeFileInfo);
- }
- }
- //==========================================================================
- //
- // W_InitMultipleFiles
- //
- // Pass a null terminated list of files to use. All files are optional,
- // but at least one file must be found. Lump names can appear multiple
- // times. The name searcher looks backwards, so a later file can
- // override an earlier one.
- //
- //==========================================================================
- void W_InitMultipleFiles(char **filenames)
- {
- int size;
- // Open all the files, load headers, and count lumps
- numlumps = 0;
- lumpinfo = malloc(1); // Will be realloced as lumps are added
- for(; *filenames; filenames++)
- {
- W_AddFile(*filenames);
- }
- if(!numlumps)
- {
- I_Error("W_InitMultipleFiles: no files found");
- }
- // Set up caching
- size = numlumps*sizeof(*lumpcache);
- lumpcache = malloc(size);
- if(!lumpcache)
- {
- I_Error("Couldn't allocate lumpcache");
- }
- memset(lumpcache, 0, size);
- PrimaryLumpInfo = lumpinfo;
- PrimaryLumpCache = lumpcache;
- PrimaryNumLumps = numlumps;
- }
- //==========================================================================
- //
- // W_InitFile
- //
- // Initialize the primary from a single file.
- //
- //==========================================================================
- void W_InitFile(char *filename)
- {
- char *names[2];
- names[0] = filename;
- names[1] = NULL;
- W_InitMultipleFiles(names);
- }
- //==========================================================================
- //
- // W_OpenAuxiliary
- //
- //==========================================================================
- void W_OpenAuxiliary(char *filename)
- {
- int i;
- int size;
- wadinfo_t header;
- int handle;
- int length;
- filelump_t *fileinfo;
- filelump_t *sourceLump;
- lumpinfo_t *destLump;
- if(AuxiliaryOpened)
- {
- W_CloseAuxiliary();
- }
- if((handle = open(filename, O_RDONLY|O_BINARY)) == -1)
- {
- I_Error("W_OpenAuxiliary: %s not found.", filename);
- return;
- }
- AuxiliaryHandle = handle;
- read(handle, &header, sizeof(header));
- if(strncmp(header.identification, "IWAD", 4))
- {
- if(strncmp(header.identification, "PWAD", 4))
- { // Bad file id
- I_Error("Wad file %s doesn't have IWAD or PWAD id\n",
- filename);
- }
- }
- header.numlumps = LONG(header.numlumps);
- header.infotableofs = LONG(header.infotableofs);
- length = header.numlumps*sizeof(filelump_t);
- fileinfo = Z_Malloc(length, PU_STATIC, 0);
- lseek(handle, header.infotableofs, SEEK_SET);
- read(handle, fileinfo, length);
- numlumps = header.numlumps;
- // Init the auxiliary lumpinfo array
- lumpinfo = Z_Malloc(numlumps*sizeof(lumpinfo_t), PU_STATIC, 0);
- sourceLump = fileinfo;
- destLump = lumpinfo;
- for(i = 0; i < numlumps; i++, destLump++, sourceLump++)
- {
- destLump->handle = handle;
- destLump->position = LONG(sourceLump->filepos);
- destLump->size = LONG(sourceLump->size);
- strncpy(destLump->name, sourceLump->name, 8);
- }
- Z_Free(fileinfo);
- // Allocate the auxiliary lumpcache array
- size = numlumps*sizeof(*lumpcache);
- lumpcache = Z_Malloc(size, PU_STATIC, 0);
- memset(lumpcache, 0, size);
- AuxiliaryLumpInfo = lumpinfo;
- AuxiliaryLumpCache = lumpcache;
- AuxiliaryNumLumps = numlumps;
- AuxiliaryOpened = true;
- }
- //==========================================================================
- //
- // W_CloseAuxiliary
- //
- //==========================================================================
- void W_CloseAuxiliary(void)
- {
- int i;
- if(AuxiliaryOpened)
- {
- W_UseAuxiliary();
- for(i = 0; i < numlumps; i++)
- {
- if(lumpcache[i])
- {
- Z_Free(lumpcache[i]);
- }
- }
- Z_Free(AuxiliaryLumpInfo);
- Z_Free(AuxiliaryLumpCache);
- W_CloseAuxiliaryFile();
- AuxiliaryOpened = false;
- }
- W_UsePrimary();
- }
- //==========================================================================
- //
- // W_CloseAuxiliaryFile
- //
- // WARNING: W_CloseAuxiliary() must be called before any further
- // auxiliary lump processing.
- //
- //==========================================================================
- void W_CloseAuxiliaryFile(void)
- {
- if(AuxiliaryHandle)
- {
- close(AuxiliaryHandle);
- AuxiliaryHandle = 0;
- }
- }
- //==========================================================================
- //
- // W_UsePrimary
- //
- //==========================================================================
- void W_UsePrimary(void)
- {
- lumpinfo = PrimaryLumpInfo;
- numlumps = PrimaryNumLumps;
- lumpcache = PrimaryLumpCache;
- }
- //==========================================================================
- //
- // W_UseAuxiliary
- //
- //==========================================================================
- void W_UseAuxiliary(void)
- {
- if(AuxiliaryOpened == false)
- {
- I_Error("W_UseAuxiliary: WAD not opened.");
- }
- lumpinfo = AuxiliaryLumpInfo;
- numlumps = AuxiliaryNumLumps;
- lumpcache = AuxiliaryLumpCache;
- }
- //==========================================================================
- //
- // W_NumLumps
- //
- //==========================================================================
- int W_NumLumps(void)
- {
- return numlumps;
- }
- //==========================================================================
- //
- // W_CheckNumForName
- //
- // Returns -1 if name not found.
- //
- //==========================================================================
- int W_CheckNumForName(char *name)
- {
- char name8[9];
- int v1, v2;
- lumpinfo_t *lump_p;
- // Make the name into two integers for easy compares
- strncpy(name8, name, 8);
- name8[8] = 0; // in case the name was a full 8 chars
- strupr(name8); // case insensitive
- v1 = *(int *)name8;
- v2 = *(int *)&name8[4];
- // Scan backwards so patch lump files take precedence
- lump_p = lumpinfo+numlumps;
- while(lump_p-- != lumpinfo)
- {
- if(*(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
- {
- return lump_p-lumpinfo;
- }
- }
- return -1;
- }
- //==========================================================================
- //
- // W_GetNumForName
- //
- // Calls W_CheckNumForName, but bombs out if not found.
- //
- //==========================================================================
- int W_GetNumForName (char *name)
- {
- int i;
- i = W_CheckNumForName(name);
- if(i != -1)
- {
- return i;
- }
- I_Error("W_GetNumForName: %s not found!", name);
- return -1;
- }
- //==========================================================================
- //
- // W_LumpLength
- //
- // Returns the buffer size needed to load the given lump.
- //
- //==========================================================================
- int W_LumpLength(int lump)
- {
- if(lump >= numlumps)
- {
- I_Error("W_LumpLength: %i >= numlumps", lump);
- }
- return lumpinfo[lump].size;
- }
- //==========================================================================
- //
- // W_ReadLump
- //
- // Loads the lump into the given buffer, which must be >= W_LumpLength().
- //
- //==========================================================================
- void W_ReadLump(int lump, void *dest)
- {
- int c;
- lumpinfo_t *l;
- if(lump >= numlumps)
- {
- I_Error("W_ReadLump: %i >= numlumps", lump);
- }
- l = lumpinfo+lump;
- //I_BeginRead();
- lseek(l->handle, l->position, SEEK_SET);
- c = read(l->handle, dest, l->size);
- if(c < l->size)
- {
- I_Error("W_ReadLump: only read %i of %i on lump %i",
- c, l->size, lump);
- }
- //I_EndRead();
- }
- //==========================================================================
- //
- // W_CacheLumpNum
- //
- //==========================================================================
- void *W_CacheLumpNum(int lump, int tag)
- {
- byte *ptr;
- if((unsigned)lump >= numlumps)
- {
- I_Error("W_CacheLumpNum: %i >= numlumps", lump);
- }
- if(!lumpcache[lump])
- { // Need to read the lump in
- ptr = Z_Malloc(W_LumpLength(lump), tag, &lumpcache[lump]);
- W_ReadLump(lump, lumpcache[lump]);
- }
- else
- {
- Z_ChangeTag(lumpcache[lump], tag);
- }
- return lumpcache[lump];
- }
- //==========================================================================
- //
- // W_CacheLumpName
- //
- //==========================================================================
- void *W_CacheLumpName(char *name, int tag)
- {
- return W_CacheLumpNum(W_GetNumForName(name), tag);
- }
- //==========================================================================
- //
- // W_Profile
- //
- //==========================================================================
- // Ripped out for Heretic
- /*
- int info[2500][10];
- int profilecount;
- void W_Profile (void)
- {
- int i;
- memblock_t *block;
- void *ptr;
- char ch;
- FILE *f;
- int j;
- char name[9];
-
-
- for (i=0 ; i<numlumps ; i++)
- {
- ptr = lumpcache[i];
- if (!ptr)
- {
- ch = ' ';
- continue;
- }
- else
- {
- block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
- if (block->tag < PU_PURGELEVEL)
- ch = 'S';
- else
- ch = 'P';
- }
- info[i][profilecount] = ch;
- }
- profilecount++;
-
- f = fopen ("waddump.txt","w");
- name[8] = 0;
- for (i=0 ; i<numlumps ; i++)
- {
- memcpy (name,lumpinfo[i].name,8);
- for (j=0 ; j<8 ; j++)
- if (!name[j])
- break;
- for ( ; j<8 ; j++)
- name[j] = ' ';
- fprintf (f,"%s ",name);
- for (j=0 ; j<profilecount ; j++)
- fprintf (f," %c",info[i][j]);
- fprintf (f,"\n");
- }
- fclose (f);
- }
- */
|