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