diff --git a/include/qbsp/brush.hh b/include/qbsp/brush.hh index 1ffffff2..756f038c 100644 --- a/include/qbsp/brush.hh +++ b/include/qbsp/brush.hh @@ -41,7 +41,7 @@ int Brush_ListCountWithCFlags(const brush_t *brush, int cflags); int Brush_ListCount(const brush_t *brush); int Brush_NumFaces(const brush_t *brush); -brush_t *LoadBrush(const mapbrush_t *mapbrush, const vec3_t rotate_offset, const int hullnum); +brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate_offset, const int hullnum); void FreeBrushes(mapentity_t *ent); int FindPlane(const vec3_t normal, const vec_t dist, int *side); diff --git a/include/qbsp/map.hh b/include/qbsp/map.hh index 036d7809..dcf7ccdd 100644 --- a/include/qbsp/map.hh +++ b/include/qbsp/map.hh @@ -71,6 +71,7 @@ public: int firstface; int numfaces; brushformat_t format; + int contents; mapbrush_t() : firstface(0), numfaces(0), format(brushformat_t::NORMAL) {} const mapface_t &face(int i) const; diff --git a/include/qbsp/qbsp.hh b/include/qbsp/qbsp.hh index 7109b18b..39a0b341 100644 --- a/include/qbsp/qbsp.hh +++ b/include/qbsp/qbsp.hh @@ -111,6 +111,8 @@ #define CONTENTS_DETAIL_ILLUSIONARY -11 /* compiler internal use only */ #define CONTENTS_DETAIL_FENCE -12 /* compiler internal use only */ #define CONTENTS_ILLUSIONARY_VISBLOCKER -13 +#define CONTENTS_FENCE -15 /* compiler internal use only */ +#define CONTENTS_LADDER -16 /* reserved for engine use */ // Special contents flags for the compiler only #define CFLAGS_STRUCTURAL_COVERED_BY_DETAIL (1U << 0) @@ -139,6 +141,7 @@ #define TEX_PHONG_ANGLE_CONCAVE_SHIFT 45 #define TEX_PHONG_ANGLE_CONCAVE_MASK (255ULL << TEX_PHONG_ANGLE_CONCAVE_SHIFT) /* 8 bit value. if non zero, overrides _phong_angle for concave joints. */ #define TEX_NOBOUNCE (1ULL << 53) /* light doesn't bounce off this face */ +#define TEX_NOEXPAND (1ULL << 54) /* don't expand this face for larger clip hulls */ /* * The quality of the bsp output is highly sensitive to these epsilon values. @@ -367,7 +370,11 @@ public: float midsplitSurfFraction; char szMapName[512]; char szBSPName[512]; - char wadPath[512]; + struct + { + char *path; + bool external; //wads from this path are not to be embedded into the bsp, but will instead require the engine to load them from elsewhere. strongly recommended for eg halflife.wad + } wadPaths[16]; vec_t on_epsilon; bool fObjExport; bool fOmitDetail; @@ -379,7 +386,15 @@ public: bool fLeakTest; bool fContentHack; vec_t worldExtent; - + + + ~options_t() { + for (int i = 0; i < sizeof(wadPaths)/sizeof(wadPaths[0]); i++) + { + free(wadPaths[i].path); + wadPaths[i].path = nullptr; + } + } options_t() { memset(this, 0, sizeof(options_t)); @@ -389,7 +404,6 @@ public: this->fVerbose = true; this->szMapName[0] = 0; this->szBSPName[0] = 0; - this->wadPath[0] = 0; /* Default to the original Quake BSP Version... */ this->BSPVersion = BSPVERSION; diff --git a/include/qbsp/wad.hh b/include/qbsp/wad.hh index cf28173e..0c848e7c 100644 --- a/include/qbsp/wad.hh +++ b/include/qbsp/wad.hh @@ -65,7 +65,7 @@ typedef struct wad_s { struct wad_s *next; } wad_t; -wad_t *WADList_AddWad(const char *fpath, wad_t *current_wadlist); +wad_t *WADList_AddWad(const char *fpath, bool external, wad_t *current_wadlist); wad_t *WADList_Init(const char *wadstring); void WADList_Process(const wad_t *wadlist); void WADList_Free(wad_t *wadlist); diff --git a/man/qbsp.1 b/man/qbsp.1 index 887d2572..6715e458 100644 --- a/man/qbsp.1 +++ b/man/qbsp.1 @@ -30,7 +30,8 @@ Print out more .map information .IP "\fB-noverbose\fP" Print out almost no information at all .IP "\fB-splitspecial\fP" -Doesn't combine sky and water faces into one large face +Doesn't combine sky and water faces into one large face. +This allows for statically lit water. .IP "\fB-transwater\fP" Computes portal information for transparent water (default) .IP "\fB-notranswater\fP" @@ -53,19 +54,27 @@ Create an old-style QBSP .PTS file (default is new) Makes it a compile error if a leak is detected. .IP "\fB-nopercent\fP" Prevents output of percent completion information +.IP "\fB-hexen2\fP" +Generate a hexen2 bsp. This can be used in addition to -bsp2 to avoid clipnode issues. .IP "\fB-bsp2\fP" Create the output BSP file in BSP2 format. Allows the creation of much larger and more complex maps than the original BSP 29 format). .IP "\fB-2psb\fP" Create the output BSP file in 2PSB format. This an earlier version of the BSP2 format, supported by the RMQ engine (and thus is also known as the -BSP2rmq or RMQe bsp format). original BSP 29 format). +BSP2rmq or RMQe bsp format). +.IP "\fB-hlbsp\fP" +Create the output BSP file in Half-Life's format. +Note that the hull size differences prevent this from being generally usable for the vanilla quake gamecode. +This cannot be used in combination with the -bsp2 argument. .IP "\fB-leakdist [n]\fP" Space between leakfile points (default 2) .IP "\fB-subdivide [n]\fP" -Use different texture subdivision (default 240) +Use different texture subdivision (default 240). Lower values will harm framerates. Higher values may not be supported. DP+FTEQW+QSS support up to 4080 (unless lightmap scaling is in use), but such values will cause other engines to crash-to-console. .IP "\fB-wadpath \fP" -Search this directory for wad files (default is cwd) +Search this directory for wad files (default is cwd). Multiple -wadpath args may be used. This argument is ignored for wads specified using an absolute path. +.IP "\fB-xwadpath \fP" +Like -wadpath, except textures found using the specified path will NOT be embedded into the bsp (equivelent to -notex, but for only textures from specific wads). You should use this for wads like halflife's standard wad files, but q1bsps require an engine extension and players are not nearly as likely to have the same wad version. .IP "\fB-oldrottex\fP" Use old method of texturing rotate_ brushes where the mapper aligns textures for the object at (0 0 0). @@ -74,14 +83,13 @@ Switch to the cheap spatial subdivion bsp heuristic when splitting nodes of this size (in any dimension). This gives much faster qbsp processing times on large maps and should generate better bsp trees as well. From txqbsp-xt, thanks rebb. (default 1024, 0 to disable) -.IP "\fB-hexen2\fP" -Generate a hexen2 bsp. .IP "\fB-wrbrushes\fP" (bspx) Includes a list of brushes for brush-based collision. +This allows for arbitrary collision sizes in engines that support it, currently only FTEQW. .IP "\fB-wrbrushesonly\fP" -"-wrbrushes" combined with "-noclip" argument. +"-wrbrushes" combined with "-noclip" argument. This is NOT backwards compatible. .IP "\fB-notex\fP" -Write only placeholder textures, to depend upon replacements. +Write only placeholder textures, to depend upon replacements. This avoids inclusion of third-party copyrighted images inside your maps, but is not backwards compatible but will work in FTEQW and QSS. .IP "\fB-omitdetail\fP" Detail brushes are omitted from the compile. .IP "\fB-convert \fP" diff --git a/qbsp/brush.cc b/qbsp/brush.cc index d0008574..82ba4bf5 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -33,6 +33,7 @@ typedef struct hullbrush_s { const mapbrush_t *srcbrush; + int contents; int numfaces; vec3_t mins; vec3_t maxs; @@ -382,11 +383,11 @@ CreateBrushFaces(hullbrush_t *hullbrush, const vec3_t rotate_offset, mapface = hullbrush->faces; for (i = 0; i < hullbrush->numfaces; i++, mapface++) { - if (!hullnum) { + if (!hullnum && hullbrush->contents == CONTENTS_HINT) { /* Don't generate hintskip faces */ const mtexinfo_t &texinfo = map.mtexinfos.at(mapface->texinfo); const char *texname = map.miptex.at(texinfo.miptex).c_str(); - if (!Q_strcasecmp(texname, "hintskip")) + if (Q_strcasecmp(texname, "hint")) continue; } @@ -764,6 +765,8 @@ ExpandBrush(hullbrush_t *hullbrush, vec3_t hull_size[2], face_t *facelist) // expand all of the planes mapface = hullbrush->faces; for (i = 0; i < hullbrush->numfaces; i++, mapface++) { + if (mapface->flags & TEX_NOEXPAND) + continue; VectorCopy(vec3_origin, corner); for (x = 0; x < 3; x++) { if (mapface->plane.normal[x] > 0) @@ -814,28 +817,33 @@ static int Brush_GetContents(const mapbrush_t *mapbrush) { const char *texname; - const mapface_t &mapface = mapbrush->face(0); - const mtexinfo_t &texinfo = map.mtexinfos.at(mapface.texinfo); - texname = map.miptex.at(texinfo.miptex).c_str(); - if (!Q_strcasecmp(texname, "origin")) - return CONTENTS_ORIGIN; - if (!Q_strcasecmp(texname, "hint") || !Q_strcasecmp(texname, "hintskip")) - return CONTENTS_HINT; - if (!Q_strcasecmp(texname, "clip")) - return CONTENTS_CLIP; + //check for strong content indicators + for (int i = 0; i < mapbrush->numfaces; i++) + { + const mapface_t &mapface = mapbrush->face(i); + const mtexinfo_t &texinfo = map.mtexinfos.at(mapface.texinfo); + texname = map.miptex.at(texinfo.miptex).c_str(); - if (texname[0] == '*') { - if (!Q_strncasecmp(texname + 1, "lava", 4)) - return CONTENTS_LAVA; - if (!Q_strncasecmp(texname + 1, "slime", 5)) - return CONTENTS_SLIME; - return CONTENTS_WATER; + if (!Q_strcasecmp(texname, "origin")) + return CONTENTS_ORIGIN; + if (!Q_strcasecmp(texname, "hint")) + return CONTENTS_HINT; + if (!Q_strcasecmp(texname, "clip")) + return CONTENTS_CLIP; + + if (texname[0] == '*') { + if (!Q_strncasecmp(texname + 1, "lava", 4)) + return CONTENTS_LAVA; + if (!Q_strncasecmp(texname + 1, "slime", 5)) + return CONTENTS_SLIME; + return CONTENTS_WATER; + } + + if (!Q_strncasecmp(texname, "sky", 3)) + return CONTENTS_SKY; } - - if (!Q_strncasecmp(texname, "sky", 3)) - return CONTENTS_SKY; - + //and anything else is assumed to be a regular solid. return CONTENTS_SOLID; } @@ -847,7 +855,7 @@ LoadBrush Converts a mapbrush to a bsp brush =============== */ -brush_t *LoadBrush(const mapbrush_t *mapbrush, const vec3_t rotate_offset, const int hullnum) +brush_t *LoadBrush(const mapbrush_t *mapbrush, int contents, const vec3_t rotate_offset, const int hullnum) { hullbrush_t hullbrush; brush_t *brush; @@ -858,6 +866,7 @@ brush_t *LoadBrush(const mapbrush_t *mapbrush, const vec3_t rotate_offset, const Error("brush->faces >= MAX_FACES (%d), source brush on line %d", MAX_FACES, mapbrush->face(0).linenum); + hullbrush.contents = contents; hullbrush.srcbrush = mapbrush; hullbrush.numfaces = mapbrush->numfaces; for (int i=0; inumfaces; i++) @@ -961,6 +970,7 @@ brush_t *LoadBrush(const mapbrush_t *mapbrush, const vec3_t rotate_offset, const // create the brush brush = (brush_t *)AllocMem(BRUSH, 1, true); + brush->contents = contents; brush->faces = facelist; VectorCopy(hullbrush.mins, brush->mins); VectorCopy(hullbrush.maxs, brush->maxs); @@ -1097,7 +1107,7 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum) continue; } - brush_t *brush = LoadBrush(mapbrush, vec3_origin, 0); + brush_t *brush = LoadBrush(mapbrush, contents, vec3_origin, 0); if (brush) { vec3_t origin; VectorAdd(brush->mins, brush->maxs, origin); @@ -1221,7 +1231,7 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum) */ if (contents == CONTENTS_CLIP) { if (hullnum <= 0) { - brush_t *brush = LoadBrush(mapbrush, rotate_offset, hullnum); + brush_t *brush = LoadBrush(mapbrush, contents, rotate_offset, hullnum); if (brush) { AddToBounds(dst, brush->mins); AddToBounds(dst, brush->maxs); @@ -1263,12 +1273,11 @@ Brush_LoadEntity(mapentity_t *dst, const mapentity_t *src, const int hullnum) if (hullnum && contents == CONTENTS_SKY) contents = CONTENTS_SOLID; - brush_t *brush = LoadBrush(mapbrush, rotate_offset, hullnum); + brush_t *brush = LoadBrush(mapbrush, contents, rotate_offset, hullnum); if (!brush) continue; dst->numbrushes++; - brush->contents = contents; brush->lmshift = lmshift; brush->cflags = cflags; diff --git a/qbsp/globals.cc b/qbsp/globals.cc index 6fbc216d..df88b997 100644 --- a/qbsp/globals.cc +++ b/qbsp/globals.cc @@ -132,7 +132,7 @@ const char *rgszWarnings[cWarnings] = { "Point (%.3f %.3f %.3f) off plane by %2.4f", "Couldn't create brush faces", - "Reached occupant at (%.0f %.0f %.0f), no filling performed.", + "Reached occupant \"%s\" at (%.0f %.0f %.0f), no filling performed.", "Portal siding direction is wrong", "New portal was clipped away in CutNodePortals_r near (%.3f %.3f %.3f)", "Winding outside node", diff --git a/qbsp/map.cc b/qbsp/map.cc index 03c5b557..860f0d91 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -204,6 +204,18 @@ IsSkipName(const char *name) return true; if (!Q_strcasecmp(name, "*lavaskip")) return true; + if (!Q_strcasecmp(name, "bevel")) //zhlt compat + return true; + if (!Q_strcasecmp(name, "null")) //zhlt compat + return true; + return false; +} + +static bool +IsNoExpandName(const char *name) +{ + if (!Q_strcasecmp(name, "bevel")) //zhlt compat + return true; return false; } @@ -292,6 +304,8 @@ FindTexinfoEnt(mtexinfo_t *texinfo, const mapentity_t *entity) flags |= TEX_HINT; if (IsSpecialName(texname)) flags |= TEX_SPECIAL; + if (IsNoExpandName(texname)) + flags |= TEX_NOEXPAND; if (atoi(ValueForKey(entity, "_dirt")) == -1) flags |= TEX_NODIRT; if (atoi(ValueForKey(entity, "_bounce")) == -1) @@ -2323,7 +2337,7 @@ TestExpandBrushes(const mapentity_t *src) for (int i = 0; i < src->nummapbrushes; i++) { const mapbrush_t *mapbrush = &src->mapbrush(i); - brush_t *hull1brush = LoadBrush(mapbrush, vec3_origin, 1); + brush_t *hull1brush = LoadBrush(mapbrush, CONTENTS_SOLID, vec3_origin, 1); if (hull1brush != nullptr) hull1brushes.push_back(hull1brush); diff --git a/qbsp/outside.cc b/qbsp/outside.cc index d55235e8..d2e54c39 100644 --- a/qbsp/outside.cc +++ b/qbsp/outside.cc @@ -436,7 +436,7 @@ FillOutside(node_t *node, const int hullnum) Q_assert(leakentity != nullptr); const vec_t *origin = leakentity->origin; - Message(msgWarning, warnMapLeak, origin[0], origin[1], origin[2]); + Message(msgWarning, warnMapLeak, ValueForKey(leakentity, "classname"), origin[0], origin[1], origin[2]); if (map.leakfile) return false; diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index ee8644c3..d2f9030a 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -682,15 +682,16 @@ PrintOptions(void) " -nooldaxis Uses alternate texture alignment which was default in tyrutils-ericw v0.15.1 and older\n" " -forcegoodtree Force use of expensive processing for SolidBSP stage\n" " -nopercent Prevents output of percent completion information\n" - " -hexen2 Generate a BSP compatible with hexen2 engines\n" " -wrbrushes (bspx) Includes a list of brushes for brush-based collision\n" " -wrbrushesonly -wrbrushes with -noclip\n" + " -hexen2 Generate a BSP compatible with hexen2 engines\n" " -hlbsp Request output in Half-Life bsp format\n" " -bsp2 Request output in bsp2 format\n" " -2psb Request output in 2psb format (RMQ compatible)\n" " -leakdist [n] Space between leakfile points (default 2)\n" " -subdivide [n] Use different texture subdivision (default 240)\n" - " -wadpath Search this directory for wad files\n" + " -wadpath Search this directory for wad files (mips will be embedded unless -notex)\n" + " -xwadpath Search this directory for wad files (mips will NOT be embedded, avoiding texture license issues)\n" " -oldrottex Use old rotate_ brush texturing aligned at (0 0 0)\n" " -maxnodesize [n]Triggers simpler BSP Splitting when node exceeds size (default 1024, 0 to disable)\n" " -epsilon [n] Customize ON_EPSILON (default 0.0001)\n" @@ -849,15 +850,25 @@ ParseOptions(char *szOptions) Error("Invalid argument to option %s", szTok); options.dxSubdivide = atoi(szTok2); szTok = szTok2; - } else if (!Q_strcasecmp(szTok, "wadpath")) { + } else if (!Q_strcasecmp(szTok, "wadpath") || !Q_strcasecmp(szTok, "xwadpath")) { szTok2 = GetTok(szTok + strlen(szTok) + 1, szEnd); if (!szTok2) Error("Invalid argument to option %s", szTok); - strcpy(options.wadPath, szTok2); + int i; + for (i = 0; i < sizeof(options.wadPaths)/sizeof(options.wadPaths[0]); i++) + { + if (options.wadPaths[i].path) + continue; + options.wadPaths[i].external = !!Q_strcasecmp(szTok, "wadpath"); + options.wadPaths[i].path = strdup(szTok2); + /* Remove trailing /, if any */ + if (options.wadPaths[i].path[strlen(options.wadPaths[i].path) - 1] == '/') + options.wadPaths[i].path[strlen(options.wadPaths[i].path) - 1] = 0; + break; + } + if (i == sizeof(options.wadPaths)/sizeof(options.wadPaths[0])) + Error("too many -wadpath args"); szTok = szTok2; - /* Remove trailing /, if any */ - if (options.wadPath[strlen(options.wadPath) - 1] == '/') - options.wadPath[strlen(options.wadPath) - 1] = 0; } else if (!Q_strcasecmp(szTok, "oldrottex")) { options.fixRotateObjTexture = false; } else if (!Q_strcasecmp(szTok, "maxnodesize")) { @@ -996,9 +1007,10 @@ InitQBSP(int argc, const char **argv) Message(msgFile, IntroString); /* If no wadpath given, default to the map directory */ - if (options.wadPath[0] == 0) { - strcpy(options.wadPath, options.szMapName); - StripFilename(options.wadPath); + if (!options.wadPaths[0].path) { + options.wadPaths[0].external = false; + options.wadPaths[0].path = strdup(options.szMapName); + StripFilename(options.wadPaths[0].path); } // Remove already existing files diff --git a/qbsp/wad.cc b/qbsp/wad.cc index a25179a6..b9eba8d6 100644 --- a/qbsp/wad.cc +++ b/qbsp/wad.cc @@ -42,13 +42,15 @@ byte thepalette[768] = // Quake palette }; static bool -WAD_LoadInfo(wad_t *wad) +WAD_LoadInfo(wad_t *wad, bool external) { wadinfo_t *hdr = &wad->header; - int i, len, lumpinfosize, disksize; + int i, len, lumpinfosize; dmiptex_t miptex; texture_t *tex; + external |= options.fNoTextures; + len = fread(hdr, 1, sizeof(wadinfo_t), wad->file); if (len != sizeof(wadinfo_t)) return false; @@ -80,6 +82,7 @@ WAD_LoadInfo(wad_t *wad) wad->lumps[i].size = sizeof(miptex) + (w>>0)*(h>>0) + (w>>1)*(h>>1) + (w>>2)*(h>>2) + (w>>3)*(h>>3); if (options.BSPVersion == BSPHLVERSION) wad->lumps[i].size += 2+3*256; //palette size+palette data + wad->lumps[i].size = (wad->lumps[i].size+3) & ~3; //keep things aligned if we can. tex = (texture_t *)AllocMem(OTHER, sizeof(texture_t), true); tex->next = textures; @@ -89,6 +92,10 @@ WAD_LoadInfo(wad_t *wad) tex->width = miptex.width; tex->height = miptex.height; + //if we're not going to embed it into the bsp, set its size now so we know how much to actually store. + if (external) + wad->lumps[i].size = wad->lumps[i].disksize = sizeof(dmiptex_t); + //printf("Created texture_t %s %d %d\n", tex->name, tex->width, tex->height); } else @@ -98,7 +105,7 @@ WAD_LoadInfo(wad_t *wad) return true; } -wad_t *WADList_AddWad(const char *fpath, wad_t *current_wadlist) +wad_t *WADList_AddWad(const char *fpath, bool external, wad_t *current_wadlist) { wad_t wad = {0}; @@ -106,12 +113,13 @@ wad_t *WADList_AddWad(const char *fpath, wad_t *current_wadlist) if (wad.file) { if (options.fVerbose) Message(msgLiteral, "Opened WAD: %s\n", fpath); - if (WAD_LoadInfo(&wad)) { + if (WAD_LoadInfo(&wad, external)) { wad_t *newwad = (wad_t *)AllocMem(OTHER, sizeof(wad), true); memcpy(newwad, &wad, sizeof(wad)); newwad->next = current_wadlist; // FIXME: leaves file open? + // (currently needed so that mips can be loaded later, as needed) return newwad; } else { @@ -143,18 +151,22 @@ WADList_Init(const char *wadstring) while (*pos && *pos != ';') pos++; - if (!options.wadPath[0] || IsAbsolutePath(fname)) { + if (!options.wadPaths[0].path || IsAbsolutePath(fname)) { fpath = (char *)AllocMem(OTHER, (pos - fname) + 1, false); q_snprintf(fpath, (pos - fname) + 1, "%s", fname); + wadlist = WADList_AddWad(fpath, false, wadlist); + FreeMem(fpath, OTHER, strlen(fpath) + 1); } else { - pathlen = strlen(options.wadPath) + 1 + (pos - fname); - fpath = (char *)AllocMem(OTHER, pathlen + 1, true); - q_snprintf(fpath, pathlen + 1, "%s/%s", options.wadPath, fname); + for (int i = 0; i < sizeof(options.wadPaths)/sizeof(options.wadPaths[0]) && options.wadPaths[i].path; i++) + { + pathlen = strlen(options.wadPaths[i].path) + 1 + (pos - fname); + fpath = (char *)AllocMem(OTHER, pathlen + 1, true); + q_snprintf(fpath, pathlen + 1, "%s/%s", options.wadPaths[i].path, fname); + wadlist = WADList_AddWad(fpath, options.wadPaths[i].external, wadlist); + FreeMem(fpath, OTHER, strlen(fpath) + 1); + } } - - wadlist = WADList_AddWad(fpath, wadlist); - FreeMem(fpath, OTHER, strlen(fpath) + 1); pos++; } @@ -206,10 +218,7 @@ WADList_Process(const wad_t *wadlist) for (i = 0; i < map.nummiptex(); i++) { texture = WADList_FindTexture(wadlist, map.miptex.at(i).c_str()); if (texture) { - if (options.fNoTextures) - texdata->count += sizeof(dmiptex_t); - else - texdata->count += texture->size; + texdata->count += texture->size; } } @@ -267,7 +276,7 @@ WAD_LoadLump(const wad_t *wad, const char *name, byte *dest) for (i = 0; i < wad->header.numlumps; i++) { if (!Q_strcasecmp(name, wad->lumps[i].name)) { fseek(wad->file, wad->lumps[i].filepos, SEEK_SET); - if (options.fNoTextures || wad->lumps[i].disksize == sizeof(dmiptex_t)) + if (wad->lumps[i].disksize == sizeof(dmiptex_t)) { size = fread(dest, 1, sizeof(dmiptex_t), wad->file); if (size != sizeof(dmiptex_t))