+ for (i = 0;i < search->numfilenames;i++)
+ {
+ if ((f = FS_LoadFile(search->filenames[i], tempmempool, false)))
+ {
+ text = f;
+ while (COM_ParseToken(&text, false))
+ {
+ strlcpy (shadername, com_token, sizeof (shadername));
+ flags = 0;
+ sky[0] = 0;
+ if (COM_ParseToken(&text, false) && !strcasecmp(com_token, "{"))
+ {
+ while (COM_ParseToken(&text, false))
+ {
+ if (!strcasecmp(com_token, "}"))
+ break;
+ else if (!strcasecmp(com_token, "{"))
+ {
+ while (COM_ParseToken(&text, false))
+ {
+ if (!strcasecmp(com_token, "}"))
+ break;
+ }
+ }
+ else if (!strcasecmp(com_token, "surfaceparm"))
+ {
+ if (COM_ParseToken(&text, true) && strcasecmp(com_token, "\n"))
+ {
+ if (!strcasecmp(com_token, "alphashadow"))
+ flags |= Q3SURFACEPARM_ALPHASHADOW;
+ else if (!strcasecmp(com_token, "areaportal"))
+ flags |= Q3SURFACEPARM_AREAPORTAL;
+ else if (!strcasecmp(com_token, "clusterportal"))
+ flags |= Q3SURFACEPARM_CLUSTERPORTAL;
+ else if (!strcasecmp(com_token, "detail"))
+ flags |= Q3SURFACEPARM_DETAIL;
+ else if (!strcasecmp(com_token, "donotenter"))
+ flags |= Q3SURFACEPARM_DONOTENTER;
+ else if (!strcasecmp(com_token, "fog"))
+ flags |= Q3SURFACEPARM_FOG;
+ else if (!strcasecmp(com_token, "lava"))
+ flags |= Q3SURFACEPARM_LAVA;
+ else if (!strcasecmp(com_token, "lightfilter"))
+ flags |= Q3SURFACEPARM_LIGHTFILTER;
+ else if (!strcasecmp(com_token, "metalsteps"))
+ flags |= Q3SURFACEPARM_METALSTEPS;
+ else if (!strcasecmp(com_token, "nodamage"))
+ flags |= Q3SURFACEPARM_NODAMAGE;
+ else if (!strcasecmp(com_token, "nodlight"))
+ flags |= Q3SURFACEPARM_NODLIGHT;
+ else if (!strcasecmp(com_token, "nodraw"))
+ flags |= Q3SURFACEPARM_NODRAW;
+ else if (!strcasecmp(com_token, "nodrop"))
+ flags |= Q3SURFACEPARM_NODROP;
+ else if (!strcasecmp(com_token, "noimpact"))
+ flags |= Q3SURFACEPARM_NOIMPACT;
+ else if (!strcasecmp(com_token, "nolightmap"))
+ flags |= Q3SURFACEPARM_NOLIGHTMAP;
+ else if (!strcasecmp(com_token, "nomarks"))
+ flags |= Q3SURFACEPARM_NOMARKS;
+ else if (!strcasecmp(com_token, "nomipmaps"))
+ flags |= Q3SURFACEPARM_NOMIPMAPS;
+ else if (!strcasecmp(com_token, "nonsolid"))
+ flags |= Q3SURFACEPARM_NONSOLID;
+ else if (!strcasecmp(com_token, "origin"))
+ flags |= Q3SURFACEPARM_ORIGIN;
+ else if (!strcasecmp(com_token, "playerclip"))
+ flags |= Q3SURFACEPARM_PLAYERCLIP;
+ else if (!strcasecmp(com_token, "sky"))
+ flags |= Q3SURFACEPARM_SKY;
+ else if (!strcasecmp(com_token, "slick"))
+ flags |= Q3SURFACEPARM_SLICK;
+ else if (!strcasecmp(com_token, "slime"))
+ flags |= Q3SURFACEPARM_SLIME;
+ else if (!strcasecmp(com_token, "structural"))
+ flags |= Q3SURFACEPARM_STRUCTURAL;
+ else if (!strcasecmp(com_token, "trans"))
+ flags |= Q3SURFACEPARM_TRANS;
+ else if (!strcasecmp(com_token, "water"))
+ flags |= Q3SURFACEPARM_WATER;
+ else
+ Con_Printf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[i], com_token);
+ if (!COM_ParseToken(&text, true) || strcasecmp(com_token, "\n"))
+ {
+ Con_Printf("%s parsing error: surfaceparm only takes one parameter.\n", search->filenames[i]);
+ goto parseerror;
+ }
+ }
+ else
+ {
+ Con_Printf("%s parsing error: surfaceparm expects a parameter.\n", search->filenames[i]);
+ goto parseerror;
+ }
+ }
+ else if (!strcasecmp(com_token, "sky"))
+ {
+ if (COM_ParseToken(&text, true) && strcasecmp(com_token, "\n"))
+ if (strlen(com_token) < sizeof(sky))
+ strcpy(sky, com_token);
+ }
+ else if (!strcasecmp(com_token, "skyparms"))
+ {
+ if (COM_ParseToken(&text, true) && strcasecmp(com_token, "\n"))
+ {
+ if (strlen(com_token) < sizeof(sky) && !atoi(com_token) && strcasecmp(com_token, "-"))
+ strcpy(sky, com_token);
+ if (COM_ParseToken(&text, true) && strcasecmp(com_token, "\n"))
+ COM_ParseToken(&text, true);
+ }
+ }
+ else
+ {
+ // look for linebreak or }
+ while(COM_ParseToken(&text, true) && strcasecmp(com_token, "\n") && strcasecmp(com_token, "}"));
+ // break out to top level if it was }
+ if (!strcasecmp(com_token, "}"))
+ break;
+ }
+ }
+ // add shader to list (shadername and flags)
+ // actually here we just poke into the texture settings
+ for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++)
+ {
+ if (!strcasecmp(out->name, shadername))
+ {
+ out->surfaceparms = flags;
+ if ((flags & Q3SURFACEPARM_SKY) && sky[0])
+ {
+ // quake3 seems to append a _ to the skybox name, so this must do so as well
+ snprintf(loadmodel->brush.skybox, sizeof(loadmodel->brush.skybox), "%s_", sky);
+ }
+ }
+ }
+ }
+ else
+ {
+ Con_Printf("%s parsing error - expected \"{\", found \"%s\"\n", search->filenames[i], com_token);
+ goto parseerror;
+ }
+ }
+parseerror:
+ Mem_Free(f);
+ }
+ }
+ }
+
+ c = 0;
+ for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++)
+ {
+ if (out->surfaceparms == -1)
+ {
+ c++;
+ Con_DPrintf("%s: No shader found for texture \"%s\"\n", loadmodel->name, out->name);
+ out->surfaceparms = 0;
+ // these are defaults
+ if (!strcmp(out->name, "caulk") || !strcmp(out->name, "common/caulk") || !strcmp(out->name, "textures/common/caulk")
+ || !strcmp(out->name, "nodraw") || !strcmp(out->name, "common/nodraw") || !strcmp(out->name, "textures/common/nodraw"))
+ out->surfaceparms |= Q3SURFACEPARM_NODRAW;
+ if (!strncmp(out->name, "textures/skies/", 15))
+ out->surfaceparms |= Q3SURFACEPARM_SKY;
+ if (R_TextureHasAlpha(out->skin.base))
+ out->surfaceparms |= Q3SURFACEPARM_TRANS;
+ }
+ }
+ Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c);
+}
+
+static void Mod_Q3BSP_LoadPlanes(lump_t *l)
+{
+ q3dplane_t *in;
+ mplane_t *out;
+ int i, count;
+
+ in = (void *)(mod_base + l->fileofs);
+ if (l->filelen % sizeof(*in))
+ Host_Error("Mod_Q3BSP_LoadPlanes: funny lump size in %s",loadmodel->name);
+ count = l->filelen / sizeof(*in);
+ out = Mem_Alloc(loadmodel->mempool, count * sizeof(*out));
+
+ loadmodel->brushq3.data_planes = out;
+ loadmodel->brushq3.num_planes = count;
+
+ for (i = 0;i < count;i++, in++, out++)
+ {
+ out->normal[0] = LittleLong(in->normal[0]);
+ out->normal[1] = LittleLong(in->normal[1]);
+ out->normal[2] = LittleLong(in->normal[2]);
+ out->dist = LittleLong(in->dist);
+ PlaneClassify(out);
+ }
+}
+
+static void Mod_Q3BSP_LoadBrushSides(lump_t *l)