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();