w_wad.c (3999B)
1 #include <ctype.h> 2 #include <sys/types.h> 3 #include <string.h> 4 #include <stdarg.h> 5 #include <unistd.h> 6 #include <malloc.h> 7 #include <fcntl.h> 8 #include <sys/stat.h> 9 #include <alloca.h> 10 11 #include "doomdef.h" 12 #include "i_system.h" 13 #include "z_zone.h" 14 #include "w_wad.h" 15 16 #define O_BINARY 0 17 18 lumpinfo_t* lumpinfo_g; 19 void** lumpcache_g; 20 char* reloadname; 21 int numlumps_g; 22 int reloadlump; 23 int info[2500][10]; 24 int profilecount; 25 26 void 27 unpack(uchar** buf, char* fmt, ...) 28 { 29 va_list ap; 30 char* p, *q, *s; 31 ulong* l; 32 uchar* b; 33 uint i; 34 35 p = q = fmt; 36 b = *buf; 37 i = 0; 38 va_start(ap, fmt); 39 for (;*p;) { 40 switch (*p++) { 41 case 'l': 42 l = va_arg(ap, ulong*); 43 *l = *b++; 44 *l += *b++ << 8; 45 *l += *b++ << 16; 46 *l += *b++ << 24; 47 break; 48 case 's': 49 s = va_arg(ap, char*); 50 if (*p++ == ':') { 51 i = *p - 0x30; 52 53 for (;isdigit(*(++p));) { 54 i *= 10; 55 i += *p - 0x30; 56 } 57 while (i--) 58 *s++ = *b++; 59 } 60 } 61 } 62 *buf = b; 63 } 64 65 void 66 unpack_wadinfo(uchar** buf, wadinfo_t* p) 67 { 68 unpack(buf, "s:4ll", p->identification, &p->numlumps, &p->infotableofs); 69 } 70 71 void 72 unpack_filelump(uchar** buf, filelump_t* p) 73 { 74 unpack(buf, "lls:8", &p->filepos, &p->size, p->name); 75 } 76 77 void 78 W_AddFile(char* filename) 79 { 80 lumpinfo_t* lumpinfo_p; 81 filelump_t* filelump_p; 82 wadinfo_t header; 83 FILE* f; 84 uchar* file, *p; 85 ulong l; 86 unsigned i; 87 int startlump; 88 89 f = fopen(filename, "r"); 90 if (!f) { 91 printf(" couldn't open %s\n", filename); 92 return; 93 } 94 printf(" adding %s\n",filename); 95 fseek(f, 0, SEEK_END); 96 l = ftell(f); 97 p = file = malloc(l * sizeof(*file) + 1); 98 fseek(f, 0, SEEK_SET); 99 fread(file, l, 1, f); 100 fclose(f); 101 startlump = numlumps_g; 102 unpack_wadinfo(&p, &header); 103 numlumps_g += header.numlumps; 104 lumpinfo_g = realloc(lumpinfo_g, numlumps_g * sizeof(lumpinfo_t)); 105 if (!lumpinfo_g) 106 I_Error("Couldn't realloc lumpinfo_g"); 107 filelump_p = alloca(header.numlumps * sizeof(filelump_t)); 108 p = file + header.infotableofs; 109 for (i = 0; i < header.numlumps; ++i) 110 unpack_filelump(&p, filelump_p+i); 111 lumpinfo_p = lumpinfo_g + startlump; 112 for (i = startlump; i < numlumps_g; ++i) { 113 lumpinfo_p[i].cache = file; 114 lumpinfo_p[i].position = filelump_p[i].filepos; 115 lumpinfo_p[i].size = filelump_p[i].size; 116 strncpy(lumpinfo_p[i].name, filelump_p[i].name, 8); 117 } 118 } 119 120 void 121 W_InitMultipleFiles(char** filenames) 122 { 123 int size; 124 125 numlumps_g = 0; 126 lumpinfo_g = malloc(1); 127 for (;*filenames; ++filenames) 128 W_AddFile(*filenames); 129 if (!numlumps_g) 130 I_Error("W_InitFiles: no files found"); 131 size = numlumps_g * sizeof(*lumpcache_g); 132 lumpcache_g = malloc(size); 133 if (!lumpcache_g) 134 I_Error("Couldn't allocate lumpcache_g"); 135 memset(lumpcache_g, 0, size); 136 } 137 138 int 139 W_CheckNumForName(char* name) 140 { 141 lumpinfo_t* p; 142 char buf[8], *q; 143 144 strncpy(buf, name, 8); 145 for (q = buf; *q; ++q) 146 if (*q > 0x60) 147 *q -= 0x20; 148 for (p = lumpinfo_g + numlumps_g - 1; p >= lumpinfo_g; --p) 149 if (!memcmp(buf, p->name, 8)) 150 return p - lumpinfo_g; 151 return -1; 152 } 153 154 int 155 W_GetNumForName(char* name) 156 { 157 int i; 158 159 i = W_CheckNumForName(name); 160 if (i == -1) 161 I_Error("W_GetNumForName: %s not found!", name); 162 return i; 163 } 164 165 int 166 W_LumpLength(int lump) 167 { 168 if (lump >= numlumps_g) 169 I_Error("W_LumpLength: %i >= numlumps_g", lump); 170 return lumpinfo_g[lump].size; 171 } 172 173 void 174 W_ReadLump(int lump, void* dest) 175 { 176 lumpinfo_t* l; 177 uchar* src; 178 179 if (lump >= numlumps_g) 180 I_Error("W_ReadLump: %i >= numlumps_g",lump); 181 l = lumpinfo_g + lump; 182 src = l->cache + l->position; 183 memcpy(dest, src, l->size); 184 } 185 186 void* 187 W_CacheLumpNum(int lump, int tag) 188 { 189 if ((unsigned)lump >= numlumps_g) 190 I_Error("W_CacheLumpNum: %i >= numlumps_g",lump); 191 if (!lumpcache_g[lump]) { 192 Z_Malloc(W_LumpLength(lump), tag, &lumpcache_g[lump]); 193 W_ReadLump(lump, lumpcache_g[lump]); 194 } else 195 Z_ChangeTag(lumpcache_g[lump],tag); 196 return lumpcache_g[lump]; 197 } 198 199 void* 200 W_CacheLumpName(char* name, int tag) 201 { 202 return W_CacheLumpNum(W_GetNumForName(name), tag); 203 }