if (t->trace->allsolid)
t->trace->startsolid = true;
#if COLLISIONPARANOID >= 3
- Con_Printf("S");
+ Con_Print("S");
#endif
return HULLCHECKSTATE_SOLID;
}
{
t->trace->allsolid = false;
#if COLLISIONPARANOID >= 3
- Con_Printf("E");
+ Con_Print("E");
#endif
return HULLCHECKSTATE_EMPTY;
}
if (t2 < 0)
{
#if COLLISIONPARANOID >= 3
- Con_Printf("<");
+ Con_Print("<");
#endif
num = node->children[1];
goto loc0;
if (t2 >= 0)
{
#if COLLISIONPARANOID >= 3
- Con_Printf(">");
+ Con_Print(">");
#endif
num = node->children[0];
goto loc0;
// the line intersects, find intersection point
// LordHavoc: this uses the original trace for maximum accuracy
#if COLLISIONPARANOID >= 3
- Con_Printf("M");
+ Con_Print("M");
#endif
if (plane->type < 3)
{
t->trace->fraction = bound(0, midf, 1);
#if COLLISIONPARANOID >= 3
- Con_Printf("D");
+ Con_Print("D");
#endif
return HULLCHECKSTATE_DONE;
}
#if COLLISIONPARANOID >= 2
Con_Printf("t(%f %f %f,%f %f %f,%i %f %f %f)", rhc.start[0], rhc.start[1], rhc.start[2], rhc.end[0], rhc.end[1], rhc.end[2], rhc.hull - model->brushq1.hulls, rhc.hull->clip_mins[0], rhc.hull->clip_mins[1], rhc.hull->clip_mins[2]);
Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
- Con_Printf("\n");
+ Con_Print("\n");
#else
if (DotProduct(rhc.dist, rhc.dist))
Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end);
surf = cl.worldmodel->brushq1.surfaces + node->firstsurface;
for (i = 0;i < node->numsurfaces;i++, surf++)
{
- if (!(surf->flags & SURF_LIGHTMAP))
+ if (!(surf->flags & SURF_LIGHTMAP) || !surf->samples)
continue; // no lightmaps
- ds = (int) (x * surf->texinfo->vecs[0][0] + y * surf->texinfo->vecs[0][1] + mid * surf->texinfo->vecs[0][2] + surf->texinfo->vecs[0][3])- surf->texturemins[0];
+ ds = (int) (x * surf->texinfo->vecs[0][0] + y * surf->texinfo->vecs[0][1] + mid * surf->texinfo->vecs[0][2] + surf->texinfo->vecs[0][3]) - surf->texturemins[0];
dt = (int) (x * surf->texinfo->vecs[1][0] + y * surf->texinfo->vecs[1][1] + mid * surf->texinfo->vecs[1][2] + surf->texinfo->vecs[1][3]) - surf->texturemins[1];
- ds = bound(0, ds, surf->extents[0]);
- dt = bound(0, dt, surf->extents[1]);
- if (surf->samples)
+ if (ds >= 0 && ds < surf->extents[0] && dt >= 0 && dt < surf->extents[1])
{
qbyte *lightmap;
int lmwidth, lmheight, maps, line3, size3, dsfrac = ds & 15, dtfrac = dt & 15, scale = 0, r00 = 0, g00 = 0, b00 = 0, r01 = 0, g01 = 0, b01 = 0, r10 = 0, g10 = 0, b10 = 0, r11 = 0, g11 = 0, b11 = 0;
ambientcolor[0] += (float) ((((((((r11-r10) * dsfrac) >> 4) + r10)-((((r01-r00) * dsfrac) >> 4) + r00)) * dtfrac) >> 4) + ((((r01-r00) * dsfrac) >> 4) + r00)) * (1.0f / 32768.0f);
ambientcolor[1] += (float) ((((((((g11-g10) * dsfrac) >> 4) + g10)-((((g01-g00) * dsfrac) >> 4) + g00)) * dtfrac) >> 4) + ((((g01-g00) * dsfrac) >> 4) + g00)) * (1.0f / 32768.0f);
ambientcolor[2] += (float) ((((((((b11-b10) * dsfrac) >> 4) + b10)-((((b01-b00) * dsfrac) >> 4) + b00)) * dtfrac) >> 4) + ((((b01-b00) * dsfrac) >> 4) + b00)) * (1.0f / 32768.0f);
+ return true; // success
}
- return true; // success
}
}
tx->width = 16;
tx->height = 16;
tx->skin.base = r_notexture;
- tx->shader = &Cshader_wall_lightmap;
- tx->flags = SURF_SOLIDCLIP;
if (i == loadmodel->brushq1.numtextures - 1)
- {
- tx->flags |= SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
- tx->shader = &Cshader_water;
- }
+ tx->flags = SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
+ else
+ tx->flags = SURF_LIGHTMAP | SURF_SOLIDCLIP;
tx->currentframe = tx;
}
}
if ((mtwidth & 15) || (mtheight & 15))
- Con_Printf("warning: texture \"%s\" in \"%s\" is not 16 aligned", dmiptex->name, loadmodel->name);
+ Con_Printf("warning: texture \"%s\" in \"%s\" is not 16 aligned\n", dmiptex->name, loadmodel->name);
// LordHavoc: force all names to lowercase
for (j = 0;name[j];j++)
if (tx->name[0] == '*')
{
// turb does not block movement
- tx->flags &= ~SURF_SOLIDCLIP;
- tx->flags |= SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
+ tx->flags = SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
// LordHavoc: some turbulent textures should be fullbright and solid
if (!strncmp(tx->name,"*lava",5)
|| !strncmp(tx->name,"*teleport",9)
tx->flags |= SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA;
else
tx->flags |= SURF_WATERALPHA;
- tx->shader = &Cshader_water;
}
else if (tx->name[0] == 's' && tx->name[1] == 'k' && tx->name[2] == 'y')
- {
- tx->flags |= SURF_DRAWSKY;
- tx->shader = &Cshader_sky;
- }
+ tx->flags = SURF_DRAWSKY | SURF_SOLIDCLIP;
else
- {
- tx->flags |= SURF_LIGHTMAP;
- if (!tx->skin.fog)
- tx->flags |= SURF_SHADOWCAST | SURF_SHADOWLIGHT;
- tx->shader = &Cshader_wall_lightmap;
- }
+ tx->flags = SURF_LIGHTMAP | SURF_SOLIDCLIP;
// start out with no animation
tx->currentframe = tx;
strlcpy (litfilename, loadmodel->name, sizeof (litfilename));
FS_StripExtension (litfilename, litfilename, sizeof (litfilename));
strlcat (litfilename, ".lit", sizeof (litfilename));
- data = (qbyte*) FS_LoadFile(litfilename, false);
+ data = (qbyte*) FS_LoadFile(litfilename, tempmempool, false);
if (data)
{
if (fs_filesize > 8 && data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
else
{
if (fs_filesize == 8)
- Con_Printf("Empty .lit file, ignoring\n");
+ Con_Print("Empty .lit file, ignoring\n");
else
- Con_Printf("Corrupt .lit file (old version?), ignoring\n");
+ Con_Print("Corrupt .lit file (old version?), ignoring\n");
Mem_Free(data);
}
}
strlcpy (lightsfilename, loadmodel->name, sizeof (lightsfilename));
FS_StripExtension (lightsfilename, lightsfilename, sizeof(lightsfilename));
strlcat (lightsfilename, ".lights", sizeof (lightsfilename));
- s = lightsstring = (char *) FS_LoadFile(lightsfilename, false);
+ s = lightsstring = (char *) FS_LoadFile(lightsfilename, tempmempool, false);
if (s)
{
numlights = 0;
{
// if texture chosen is NULL or the shader needs a lightmap,
// force to notexture water shader
- if (out->texture == NULL || out->texture->shader->flags & SHADERFLAGS_NEEDLIGHTMAP)
+ if (out->texture == NULL || out->texture->flags & SURF_LIGHTMAP)
out->texture = loadmodel->brushq1.textures + (loadmodel->brushq1.numtextures - 1);
}
else
{
if (subdivpolytriangles >= MAX_SUBDIVPOLYTRIANGLES)
{
- Con_Printf("SubdividePolygon: ran out of triangles in buffer, please increase your r_subdivide_size\n");
+ Con_Print("SubdividePolygon: ran out of triangles in buffer, please increase your r_subdivide_size\n");
return;
}
else // LordHavoc: white lighting (bsp version 29)
surf->samples = loadmodel->brushq1.lightdata + (i * 3);
- if (surf->texinfo->texture->shader == &Cshader_wall_lightmap)
+ if (surf->texinfo->texture->flags & SURF_LIGHTMAP)
{
if ((surf->extents[0] >> 4) + 1 > (256) || (surf->extents[1] >> 4) + 1 > (256))
Host_Error("Bad surface extents");
Mod_BuildTriangleNeighbors(mesh->data_neighbor3i, mesh->data_element3i, mesh->num_triangles);
Mod_BuildTextureVectorsAndNormals(mesh->num_vertices, mesh->num_triangles, mesh->data_vertex3f, mesh->data_texcoordtexture2f, mesh->data_element3i, mesh->data_svector3f, mesh->data_tvector3f, mesh->data_normal3f);
- if (surf->texinfo->texture->shader == &Cshader_wall_lightmap)
+ if (surf->texinfo->texture->flags & SURF_LIGHTMAP)
{
int i, iu, iv, smax, tmax;
float u, v, ubase, vbase, uscale, vscale;
smax = surf->extents[0] >> 4;
tmax = surf->extents[1] >> 4;
- surf->flags |= SURF_LIGHTMAP;
if (r_miplightmaps.integer)
{
surf->lightmaptexturestride = smax+1;
if (p >= 0 && out->clusterindex >= 0)
{
if (p >= loadmodel->brushq1.num_compressedpvs)
- Con_Printf("Mod_Q1BSP_LoadLeafs: invalid visofs\n");
+ Con_Print("Mod_Q1BSP_LoadLeafs: invalid visofs\n");
else
Mod_Q1BSP_DecompressVis(loadmodel->brushq1.data_compressedpvs + p, loadmodel->brushq1.data_compressedpvs + loadmodel->brushq1.num_compressedpvs, loadmodel->brush.data_pvsclusters + out->clusterindex * loadmodel->brush.num_pvsclusterbytes, loadmodel->brush.data_pvsclusters + (out->clusterindex + 1) * loadmodel->brush.num_pvsclusterbytes);
}
nodeportalwinding = Winding_Clip(nodeportalwinding, clipplane.normal[0], clipplane.normal[1], clipplane.normal[2], clipplane.dist, true);
if (!nodeportalwinding)
{
- Con_Printf("Mod_Q1BSP_RecursiveNodePortals: WARNING: new portal was clipped away\n");
+ Con_Print("Mod_Q1BSP_RecursiveNodePortals: WARNING: new portal was clipped away\n");
break;
}
}
extern void R_Model_Brush_DrawSky(entity_render_t *ent);
extern void R_Model_Brush_Draw(entity_render_t *ent);
-extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
+extern void R_Model_Brush_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer);
+extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist);
+extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, int numsurfaces, const int *surfacelist);
void Mod_Q1BSP_Load(model_t *mod, void *buffer)
{
int i, j, k;
mod->brushq1.firstmodelsurface = bm->firstface;
mod->brushq1.nummodelsurfaces = bm->numfaces;
+ // make the model surface list (used by shadowing/lighting)
+ mod->numsurfaces = mod->brushq1.nummodelsurfaces;
+ mod->surfacelist = Mem_Alloc(originalloadmodel->mempool, mod->numsurfaces * sizeof(*mod->surfacelist));
+ for (j = 0;j < mod->numsurfaces;j++)
+ mod->surfacelist[j] = mod->brushq1.firstmodelsurface + j;
+
// this gets altered below if sky is used
mod->DrawSky = NULL;
mod->Draw = R_Model_Brush_Draw;
+ mod->GetLightInfo = R_Model_Brush_GetLightInfo;
mod->DrawShadowVolume = R_Model_Brush_DrawShadowVolume;
mod->DrawLight = R_Model_Brush_DrawLight;
if (i != 0)
for (j = 0, surf = &mod->brushq1.surfaces[mod->brushq1.firstmodelsurface];j < mod->brushq1.nummodelsurfaces;j++, surf++)
{
// we only need to have a drawsky function if it is used(usually only on world model)
- if (surf->texinfo->texture->shader == &Cshader_sky)
+ if (surf->texinfo->texture->flags & SURF_DRAWSKY)
mod->DrawSky = R_Model_Brush_DrawSky;
// LordHavoc: submodels always clip, even if water
if (mod->brush.numsubmodels - 1)
const char *text;
int flags;
char shadername[Q3PATHLENGTH];
+ char sky[Q3PATHLENGTH];
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
for (i = 0;i < search->numfilenames;i++)
{
- if ((f = FS_LoadFile(search->filenames[i], false)))
+ if ((f = FS_LoadFile(search->filenames[i], tempmempool, false)))
{
text = f;
while (COM_ParseToken(&text, false))
{
- snprintf(shadername, sizeof(shadername), "%s", com_token);
+ strlcpy (shadername, com_token, sizeof (shadername));
flags = 0;
+ sky[0] = 0;
if (COM_ParseToken(&text, false) && !strcasecmp(com_token, "{"))
{
while (COM_ParseToken(&text, false))
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 }
// 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])
+ strcpy(loadmodel->brush.skybox, sky);
+ }
+ }
}
else
{
if (out->data_element3i[j] < 0 || out->data_element3i[j] >= out->num_vertices)
out->data_element3i[j] = 0;
}
- Con_Printf("\n");
+ Con_Print("\n");
}
// for shadow volumes
Mod_BuildTriangleNeighbors(out->data_neighbor3i, out->data_element3i, out->num_triangles);
int clusterindex, side, nodestackindex = 0;
q3mnode_t *node, *nodestack[1024];
node = model->brushq3.data_nodes;
- if (!loadmodel->brush.num_pvsclusters)
+ if (!model->brush.num_pvsclusters)
return true;
for (;;)
{
// leaf - check cluster bit
clusterindex = ((q3mleaf_t *)node)->clusterindex;
#if 0
- if (clusterindex >= loadmodel->brush.num_pvsclusters)
+ if (clusterindex >= model->brush.num_pvsclusters)
{
- Con_Printf("%i >= %i\n", clusterindex, loadmodel->brush.num_pvsclusters);
+ Con_Printf("%i >= %i\n", clusterindex, model->brush.num_pvsclusters);
return true;
}
#endif
{
int bytes = model->brush.num_pvsclusterbytes;
bytes = min(bytes, pvsbufferlength);
- if (r_novis.integer || !loadmodel->brush.num_pvsclusters || !Mod_Q3BSP_GetPVS(model, org))
+ if (r_novis.integer || !model->brush.num_pvsclusters || !Mod_Q3BSP_GetPVS(model, org))
{
memset(pvsbuffer, 0xFF, bytes);
return bytes;
extern void R_Q3BSP_DrawSky(struct entity_render_s *ent);
extern void R_Q3BSP_Draw(struct entity_render_s *ent);
-extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Q3BSP_DrawLight(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
+extern void R_Q3BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, vec3_t outmins, vec3_t outmaxs, int *outclusterlist, qbyte *outclusterpvs, int *outnumclusterspointer, int *outsurfacelist, qbyte *outsurfacepvs, int *outnumsurfacespointer);
+extern void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist);
+extern void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, int numsurfaces, const int *surfacelist);
void Mod_Q3BSP_Load(model_t *mod, void *buffer)
{
int i, j, numshadowmeshtriangles;
i = LittleLong(header->version);
if (i != Q3BSPVERSION)
Host_Error("Mod_Q3BSP_Load: %s has wrong version number (%i, should be %i)", mod->name, i, Q3BSPVERSION);
- if (loadmodel->isworldmodel)
+ if (mod->isworldmodel)
{
Cvar_SetValue("halflifebsp", false);
// until we get a texture for it...
mod->brush.FindNonSolidLocation = Mod_Q3BSP_FindNonSolidLocation;
//mod->DrawSky = R_Q3BSP_DrawSky;
mod->Draw = R_Q3BSP_Draw;
+ mod->GetLightInfo = R_Q3BSP_GetLightInfo;
mod->DrawShadowVolume = R_Q3BSP_DrawShadowVolume;
mod->DrawLight = R_Q3BSP_DrawLight;
mod->brushq3.data_thismodel = loadmodel->brushq3.data_models + i;
mod->brushq3.submodel = i;
+ // make the model surface list (used by shadowing/lighting)
+ mod->numsurfaces = mod->brushq3.data_thismodel->numfaces;
+ mod->surfacelist = Mem_Alloc(loadmodel->mempool, mod->numsurfaces * sizeof(*mod->surfacelist));
+ for (j = 0;j < mod->numsurfaces;j++)
+ mod->surfacelist[j] = (mod->brushq3.data_thismodel->firstface - mod->brushq3.data_faces) + j;
+
VectorCopy(mod->brushq3.data_thismodel->mins, mod->normalmins);
VectorCopy(mod->brushq3.data_thismodel->maxs, mod->normalmaxs);
corner[0] = max(fabs(mod->normalmins[0]), fabs(mod->normalmaxs[0]));