+ out->q2flags = MSG_ReadLittleLong(sb);
+ out->q2value = MSG_ReadLittleLong(sb);
+ MSG_ReadBytes(sb, 32, (unsigned char*)out->q2texture);
+ out->q2texture[31] = 0; // make absolutely sure it is terminated
+ out->q2nexttexinfo = MSG_ReadLittleLong(sb);
+
+ // find an existing match for the texture if possible
+ dpsnprintf(filename, sizeof(filename), "textures/%s.wal", out->q2texture);
+ for (j = 0;j < loadmodel->num_texturesperskin;j++)
+ if (!strcmp(filename, loadmodel->data_textures[j].name)
+ && out->q2flags == loadmodel->data_textures[j].q2flags
+ && out->q2value == loadmodel->data_textures[j].q2value)
+ break;
+ // if we don't find the texture, store the new texture
+ if (j == loadmodel->num_texturesperskin)
+ {
+ if (loadmodel->num_texturesperskin < maxtextures)
+ {
+ texture_t *tx = loadmodel->data_textures + j;
+ int q2flags = out->q2flags;
+ unsigned char *walfile = NULL;
+ fs_offset_t walfilesize = 0;
+ Mod_LoadTextureFromQ3Shader(tx, filename, true, true, TEXF_ALPHA | TEXF_MIPMAP | TEXF_ISWORLD | TEXF_PICMIP | TEXF_COMPRESS);
+ // now read the .wal file to get metadata (even if a .tga was overriding it, we still need the wal data)
+ walfile = FS_LoadFile(filename, tempmempool, true, &walfilesize);
+ if (walfile)
+ {
+ int w, h;
+ LoadWAL_GetMetadata(walfile, (int)walfilesize, &w, &h, NULL, NULL, &tx->q2contents, NULL);
+ tx->width = w;
+ tx->height = h;
+ Mem_Free(walfile);
+ }
+ else
+ {
+ tx->width = 16;
+ tx->height = 16;
+ }
+ tx->q2flags = out->q2flags;
+ tx->q2value = out->q2value;
+ // also modify the texture to have the correct contents and such based on flags
+ // note that we create multiple texture_t structures if q2flags differs
+ if (q2flags & Q2SURF_LIGHT)
+ {
+ // doesn't mean anything to us
+ }
+ if (q2flags & Q2SURF_SLICK)
+ {
+ // would be nice to support...
+ }
+ if (q2flags & Q2SURF_SKY)
+ {
+ // sky is a rather specific thing
+ q2flags &= ~Q2SURF_NODRAW; // quake2 had a slightly different meaning than we have in mind here...
+ tx->basematerialflags = MATERIALFLAG_SKY;
+ tx->supercontents = SUPERCONTENTS_SKY | SUPERCONTENTS_NODROP | SUPERCONTENTS_OPAQUE;
+ tx->surfaceflags = Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NOIMPACT | Q3SURFACEFLAG_NOMARKS | Q3SURFACEFLAG_NODLIGHT | Q3SURFACEFLAG_NOLIGHTMAP;
+ }
+ if (q2flags & Q2SURF_WARP)
+ {
+ // we use a scroll instead of a warp
+ tx->basematerialflags |= MATERIALFLAG_WATERSCROLL | MATERIALFLAG_FULLBRIGHT;
+ // if it's also transparent, we can enable the WATERSHADER
+ // but we do not set the WATERALPHA flag because we don't
+ // want to honor r_wateralpha in q2bsp
+ // (it would go against the artistic intent)
+ if (q2flags & (Q2SURF_TRANS33 | Q2SURF_TRANS66))
+ tx->basematerialflags |= MATERIALFLAG_WATERSHADER;
+ }
+ if (q2flags & Q2SURF_TRANS33)
+ {
+ tx->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED;
+ tx->basealpha = 1.0f / 3.0f;
+ tx->supercontents &= ~SUPERCONTENTS_OPAQUE;
+ if (tx->q2contents & Q2CONTENTS_SOLID)
+ tx->q2contents = (tx->q2contents & ~Q2CONTENTS_SOLID) | Q2CONTENTS_WINDOW;
+ }
+ if (q2flags & Q2SURF_TRANS66)
+ {
+ tx->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED;
+ tx->basealpha = 2.0f / 3.0f;
+ tx->supercontents &= ~SUPERCONTENTS_OPAQUE;
+ if (tx->q2contents & Q2CONTENTS_SOLID)
+ tx->q2contents = (tx->q2contents & ~Q2CONTENTS_SOLID) | Q2CONTENTS_WINDOW;
+ }
+ if ((q2flags & Q2SURF_FLOWING) && tx->materialshaderpass != NULL)
+ {
+ tx->materialshaderpass->tcmods[0].tcmod = Q3TCMOD_SCROLL;
+ if (q2flags & Q2SURF_WARP)
+ tx->materialshaderpass->tcmods[0].parms[0] = -0.5f;
+ else
+ tx->materialshaderpass->tcmods[0].parms[0] = -1.6f;
+ tx->materialshaderpass->tcmods[0].parms[1] = 0.0f;
+ }
+ if (q2flags & Q2SURF_ALPHATEST)
+ {
+ // KMQUAKE2 and other modded engines added this flag for lit alpha tested surfaces
+ tx->basematerialflags |= MATERIALFLAG_ALPHATEST | MATERIALFLAG_NOSHADOW;
+ }
+ else if (q2flags & (Q2SURF_TRANS33 | Q2SURF_TRANS66 | Q2SURF_WARP))
+ {
+ if (!mod_q2bsp_littransparentsurfaces.integer)
+ tx->basematerialflags |= MATERIALFLAG_FULLBRIGHT;
+ }
+ if (q2flags & Q2SURF_NODRAW)
+ {
+ tx->basematerialflags = MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
+ }
+ if (tx->q2contents & (Q2CONTENTS_TRANSLUCENT | Q2CONTENTS_MONSTERCLIP | Q2CONTENTS_PLAYERCLIP))
+ tx->q2contents |= Q2CONTENTS_DETAIL;
+ if (!(tx->q2contents & (Q2CONTENTS_SOLID | Q2CONTENTS_WINDOW | Q2CONTENTS_AUX | Q2CONTENTS_LAVA | Q2CONTENTS_SLIME | Q2CONTENTS_WATER | Q2CONTENTS_MIST | Q2CONTENTS_PLAYERCLIP | Q2CONTENTS_MONSTERCLIP | Q2CONTENTS_MIST)))
+ tx->q2contents |= Q2CONTENTS_SOLID;
+ if (tx->q2flags & (Q2SURF_HINT | Q2SURF_SKIP))
+ tx->q2contents = 0;
+ tx->supercontents = Mod_Q2BSP_SuperContentsFromNativeContents(loadmodel, tx->q2contents);
+ // set the current values to the base values
+ tx->currentframe = tx;
+ tx->currentskinframe = tx->materialshaderpass != NULL ? tx->materialshaderpass->skinframes[0] : NULL;
+ tx->currentmaterialflags = tx->basematerialflags;
+ loadmodel->num_texturesperskin++;
+ loadmodel->num_textures = loadmodel->num_texturesperskin;
+ }
+ else
+ {
+ Con_Printf("Mod_Q2BSP_LoadTexinfo: max textures reached (%i)\n", maxtextures);
+ j = 0; // use first texture and give up
+ }
+ }
+ // store the index we found for this texture
+ out->textureindex = j;
+ }
+
+ // realloc the textures array now that we know how many we actually need
+ loadmodel->data_textures = (texture_t*)Mem_Realloc(loadmodel->mempool, loadmodel->data_textures, loadmodel->num_texturesperskin * sizeof(texture_t));
+
+ // now assemble the texture chains
+ // if we encounter the textures out of order, the later ones won't mark the earlier ones in a sequence, so the earlier
+ for (i = 0, out = loadmodel->brushq1.texinfo;i < count;i++, out++)