|
|
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: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.