diff --git a/man/qbsp.1 b/man/qbsp.1 index 95f5fe48..f439122a 100644 --- a/man/qbsp.1 +++ b/man/qbsp.1 @@ -62,6 +62,9 @@ Space between leakfile points (default 2) Use different texture subdivision (default 240) .IP "\fB\-wadpath \fP" Search this directory for wad files (default is cwd) +.IP "\fB\-oldrottex\fP" +Use old method of texturing rotate_ brushes where the mapper aligns +textures for the object at (0 0 0). .SH "SPECIAL TEXTURE NAMES" .PP diff --git a/qbsp/brush.c b/qbsp/brush.c index f4dc71d3..afe839fb 100644 --- a/qbsp/brush.c +++ b/qbsp/brush.c @@ -423,6 +423,26 @@ CreateBrushFaces(hullbrush_t *hullbrush, const vec3_t rotate_offset, } } + // account for texture offset, from txqbsp-xt + if (options.fixRotateObjTexture) { + const texinfo_t *texinfo = pWorldEnt->lumps[LUMP_TEXINFO].data; + texinfo_t texInfoNew; + vec3_t vecs[2]; + int k, l; + + memcpy(&texInfoNew, &texinfo[ mapface->texinfo ], sizeof(texInfoNew)); + for (k=0; k<2; k++) { + for (l=0; l<3; l++) { + vecs[k][l] = texinfo[ mapface->texinfo ].vecs[k][l]; + } + } + + texInfoNew.vecs[0][3] += DotProduct( rotate_offset, vecs[0] ); + texInfoNew.vecs[1][3] += DotProduct( rotate_offset, vecs[1] ); + + mapface->texinfo = FindTexinfo( &texInfoNew ); + } + VectorCopy(mapface->plane.normal, plane.normal); VectorScale(mapface->plane.normal, mapface->plane.dist, point); VectorSubtract(point, rotate_offset, point); diff --git a/qbsp/map.c b/qbsp/map.c index 6bed4ee4..09fe4d76 100644 --- a/qbsp/map.c +++ b/qbsp/map.c @@ -146,7 +146,7 @@ FindTexinfo Returns a global texinfo number =============== */ -static int +int FindTexinfo(texinfo_t *texinfo) { int index, j; @@ -187,6 +187,9 @@ FindTexinfo(texinfo_t *texinfo) return index; } + if (index >= pWorldEnt->lumps[LUMP_TEXINFO].count) + Error("Internal error: didn't allocate enough texinfos?"); + /* Allocate a new texinfo at the end of the array */ *target = *texinfo; pWorldEnt->lumps[LUMP_TEXINFO].index++; @@ -691,9 +694,12 @@ PreParseFile(const char *buf) */ map.maxmiptex = map.maxfaces + 100; map.miptex = AllocMem(MIPTEX, map.maxmiptex, true); + + /* Fixing textures on rotate_object requires an extra texinfo per face */ + map.maxtexinfo = map.maxfaces * 2; texinfo = &pWorldEnt->lumps[LUMP_TEXINFO]; - texinfo->data = AllocMem(BSP_TEXINFO, map.maxfaces, true); - texinfo->count = map.maxfaces; + texinfo->data = AllocMem(BSP_TEXINFO, map.maxtexinfo, true); + texinfo->count = map.maxtexinfo; } /* @@ -720,7 +726,6 @@ LoadMapFile(void) parser_t parser; char *buf; int length; - void *pTemp; struct lumpdata *texinfo; mapentity_t *entity; @@ -757,15 +762,7 @@ LoadMapFile(void) // Message(msgWarning, warnNoPlayerCoop); texinfo = &pWorldEnt->lumps[LUMP_TEXINFO]; - if (texinfo->index > texinfo->count) - Error("Internal error: didn't allocate enough texinfos?"); - else if (texinfo->index < texinfo->count) { - pTemp = texinfo->data; - texinfo->data = AllocMem(BSP_TEXINFO, texinfo->index, true); - memcpy(texinfo->data, pTemp, texinfo->index * MemSize[BSP_TEXINFO]); - FreeMem(pTemp, BSP_TEXINFO, texinfo->count); - texinfo->count = texinfo->index; - } + map.maxplanes = MAX_MAP_PLANES; map.planes = AllocMem(PLANE, map.maxplanes, true); diff --git a/qbsp/qbsp.c b/qbsp/qbsp.c index a8169b95..613c4080 100644 --- a/qbsp/qbsp.c +++ b/qbsp/qbsp.c @@ -381,6 +381,7 @@ PrintOptions(void) " -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" + " -oldrottex Use old rotate_ brush texturing aligned at (0 0 0)\n" " sourcefile .MAP file to process\n" " destfile .BSP file to output\n"); @@ -450,6 +451,7 @@ ParseOptions(char *szOptions) /* Default to the original Quake BSP Version... */ options.BSPVersion = BSPVERSION; options.fTranswater = true; + options.fixRotateObjTexture = true; szEnd = szOptions + strlen(szOptions); szTok = GetTok(szOptions, szEnd); @@ -522,7 +524,9 @@ ParseOptions(char *szOptions) /* Remove trailing /, if any */ if (options.wadPath[strlen(options.wadPath) - 1] == '/') options.wadPath[strlen(options.wadPath) - 1] = 0; - } else if (!strcasecmp(szTok, "?") || !strcasecmp(szTok, "help")) + } else if (!strcasecmp(szTok, "oldrottex")) { + options.fixRotateObjTexture = false; + } else if (!strcasecmp(szTok, "?") || !strcasecmp(szTok, "help")) PrintOptions(); else Error("Unknown option '%s'", szTok); diff --git a/qbsp/qbsp.h b/qbsp/qbsp.h index 648ebf7a..7e145550 100644 --- a/qbsp/qbsp.h +++ b/qbsp/qbsp.h @@ -447,6 +447,7 @@ typedef struct options_s { bool fOldleak; bool fNopercent; bool forceGoodTree; + bool fixRotateObjTexture; int BSPVersion; int dxSubdivide; int dxLeakDist; @@ -502,6 +503,7 @@ typedef struct mapdata_s { int maxentities; int maxplanes; int maxmiptex; + int maxtexinfo; /* Number of items currently used */ int numfaces; @@ -531,6 +533,7 @@ extern mapentity_t *pWorldEnt; void LoadMapFile(void); int FindMiptex(const char *name); +int FindTexinfo(texinfo_t *texinfo); void PrintEntity(const mapentity_t *entity); const char *ValueForKey(const mapentity_t *entity, const char *key); diff --git a/qbsp/writebsp.c b/qbsp/writebsp.c index 0fbc9d7d..65bf78be 100644 --- a/qbsp/writebsp.c +++ b/qbsp/writebsp.c @@ -726,6 +726,19 @@ FinishBSPFile(void) planes->data = newdata; planes->count = map.cTotal[LUMP_PLANES]; + // Shrink texinfo lump + { + struct lumpdata *texinfo; + void *pTemp; + + texinfo = &pWorldEnt->lumps[LUMP_TEXINFO]; + pTemp = texinfo->data; + texinfo->data = AllocMem(BSP_TEXINFO, texinfo->index, true); + memcpy(texinfo->data, pTemp, texinfo->index * MemSize[BSP_TEXINFO]); + FreeMem(pTemp, BSP_TEXINFO, texinfo->count); + texinfo->count = texinfo->index; + } + PrintBSPFileSizes(); CleanBSPTexinfoFlags(); WriteBSPFile();