/* common/wadlib.c */ #include #include #include #include #include #include #include /* #include */ #include #ifdef NeXT #include #endif #include #include /* ============================================================================ * WAD READING * ============================================================================ */ lumpinfo_t *lumpinfo; /* location of each lump on disk */ int numlumps; wadinfo_t header; FILE *wadhandle; /* * ==================== * W_OpenWad * ==================== */ void W_OpenWad(char *filename) { lumpinfo_t *lump_p; unsigned i; int length; /* open the file and add to directory */ wadhandle = SafeOpenRead(filename); SafeRead(wadhandle, &header, sizeof(header)); if (strncmp(header.identification, "WAD2", 4)) Error("Wad file %s doesn't have WAD2 id\n", filename); header.numlumps = LittleLong(header.numlumps); header.infotableofs = LittleLong(header.infotableofs); numlumps = header.numlumps; length = numlumps * sizeof(lumpinfo_t); lumpinfo = malloc(length); lump_p = lumpinfo; fseek(wadhandle, header.infotableofs, SEEK_SET); SafeRead(wadhandle, lumpinfo, length); /* Fill in lumpinfo */ for (i = 0; i < numlumps; i++, lump_p++) { lump_p->filepos = LittleLong(lump_p->filepos); lump_p->size = LittleLong(lump_p->size); } } void CleanupName(char *in, char *out) { int i; for (i = 0; i < sizeof(((lumpinfo_t *) 0)->name); i++) { if (!in[i]) break; out[i] = toupper(in[i]); } for (; i < sizeof(((lumpinfo_t *) 0)->name); i++) out[i] = 0; } /* * ==================== * W_CheckNumForName * Returns -1 if name not found * ==================== */ int W_CheckNumForName(char *name) { char cleanname[16]; int v1, v2, v3, v4; int i; lumpinfo_t *lump_p; CleanupName(name, cleanname); /* make the name into four integers for easy compares */ v1 = *(int *)cleanname; v2 = *(int *)&cleanname[4]; v3 = *(int *)&cleanname[8]; v4 = *(int *)&cleanname[12]; /* find it */ lump_p = lumpinfo; for (i = 0; i < numlumps; i++, lump_p++) { if (*(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2 && *(int *)&lump_p->name[8] == v3 && *(int *)&lump_p->name[12] == v4) return i; } 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; Error("%s: %s not found!", __func__, name); return -1; } /* * ==================== * W_LumpLength * Returns the buffer size needed to load the given lump * ==================== */ int W_LumpLength(int lump) { if (lump >= numlumps) Error("%s: %i >= numlumps", __func__, lump); return lumpinfo[lump].size; } /* * ==================== * W_ReadLumpNum * Loads the lump into the given buffer, which must be >= W_LumpLength() * ==================== */ void W_ReadLumpNum(int lump, void *dest) { lumpinfo_t *l; if (lump >= numlumps) Error("%s: %i >= numlumps", __func__, lump); l = lumpinfo + lump; fseek(wadhandle, l->filepos, SEEK_SET); SafeRead(wadhandle, dest, l->size); } /* * ==================== * W_LoadLumpNum * ==================== */ void * W_LoadLumpNum(int lump) { void *buf; if ((unsigned)lump >= numlumps) Error("%s: %i >= numlumps", __func__, lump); buf = malloc(W_LumpLength(lump)); W_ReadLumpNum(lump, buf); return buf; } /* * ==================== * W_LoadLumpName * ==================== */ void * W_LoadLumpName(char *name) { return W_LoadLumpNum(W_GetNumForName(name)); } /* * ============================================================================ * WAD CREATION * ============================================================================ */ FILE *outwad; lumpinfo_t outinfo[4096]; int outlumps; short (*wadshort) (short l); int (*wadlong) (int l); /* * =============== * NewWad * =============== */ void NewWad(char *pathname, qboolean bigendien) { outwad = SafeOpenWrite(pathname); fseek(outwad, sizeof(wadinfo_t), SEEK_SET); memset(outinfo, 0, sizeof(outinfo)); if (bigendien) { wadshort = BigShort; wadlong = BigLong; } else { wadshort = LittleShort; wadlong = LittleLong; } outlumps = 0; } /* * =============== * AddLump * =============== */ void AddLump(char *name, void *buffer, int length, int type, int compress) { lumpinfo_t *info; int ofs; info = &outinfo[outlumps]; outlumps++; memset(info, 0, sizeof(info)); strcpy(info->name, name); Q_strupr(info->name); ofs = ftell(outwad); info->filepos = wadlong(ofs); info->size = info->disksize = wadlong(length); info->type = type; info->compression = compress; /* FIXME: do compression */ SafeWrite(outwad, buffer, length); } /* * =============== * WriteWad * =============== */ void WriteWad(void) { wadinfo_t header; int ofs; /* write the lumpingo */ ofs = ftell(outwad); SafeWrite(outwad, outinfo, outlumps * sizeof(lumpinfo_t)); /* write the header */ /* a program will be able to tell the ednieness of a wad by the id */ header.identification[0] = 'W'; header.identification[1] = 'A'; header.identification[2] = 'D'; header.identification[3] = '2'; header.numlumps = wadlong(outlumps); header.infotableofs = wadlong(ofs); fseek(outwad, 0, SEEK_SET); SafeWrite(outwad, &header, sizeof(header)); fclose(outwad); }