コード例 #1
0
ファイル: r_bsp.c プロジェクト: TehRealSalt/SRB2
//
// If player's view height is underneath fake floor, lower the
// drawn ceiling to be just under the floor height, and replace
// the drawn floor and ceiling textures, and light level, with
// the control sector's.
//
// Similar for ceiling, only reflected.
//
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
	INT32 *ceilinglightlevel, boolean back)
{
	INT32 mapnum = -1;

	if (floorlightlevel)
		*floorlightlevel = sec->floorlightsec == -1 ?
			sec->lightlevel : sectors[sec->floorlightsec].lightlevel;

	if (ceilinglightlevel)
		*ceilinglightlevel = sec->ceilinglightsec == -1 ?
			sec->lightlevel : sectors[sec->ceilinglightsec].lightlevel;

	// If the sector has a midmap, it's probably from 280 type
	if (sec->midmap != -1)
		mapnum = sec->midmap;
	else if (sec->heightsec != -1)
	{
		const sector_t *s = &sectors[sec->heightsec];
		mobj_t *viewmobj = viewplayer->mo;
		INT32 heightsec;
		boolean underwater;

		if (splitscreen && viewplayer == &players[secondarydisplayplayer] && camera2.chase)
			heightsec = R_PointInSubsector(camera2.x, camera2.y)->sector->heightsec;
		else if (camera.chase && viewplayer == &players[displayplayer])
			heightsec = R_PointInSubsector(camera.x, camera.y)->sector->heightsec;
		else if (viewmobj)
			heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec;
		else
			return sec;
		underwater = heightsec != -1 && viewz <= sectors[heightsec].floorheight;

		// Replace sector being drawn, with a copy to be hacked
		*tempsec = *sec;

		// Replace floor and ceiling height with other sector's heights.
		tempsec->floorheight = s->floorheight;
		tempsec->ceilingheight = s->ceilingheight;

		mapnum = s->midmap;

		if ((underwater && (tempsec->  floorheight = sec->floorheight,
			tempsec->ceilingheight = s->floorheight - 1, !back)) || viewz <= s->floorheight)
		{ // head-below-floor hack
			tempsec->floorpic = s->floorpic;
			tempsec->floor_xoffs = s->floor_xoffs;
			tempsec->floor_yoffs = s->floor_yoffs;
			tempsec->floorpic_angle = s->floorpic_angle;

			if (underwater)
			{
				if (s->ceilingpic == skyflatnum)
				{
					tempsec->floorheight = tempsec->ceilingheight+1;
					tempsec->ceilingpic = tempsec->floorpic;
					tempsec->ceiling_xoffs = tempsec->floor_xoffs;
					tempsec->ceiling_yoffs = tempsec->floor_yoffs;
					tempsec->ceilingpic_angle = tempsec->floorpic_angle;
				}
				else
				{
					tempsec->ceilingpic = s->ceilingpic;
					tempsec->ceiling_xoffs = s->ceiling_xoffs;
					tempsec->ceiling_yoffs = s->ceiling_yoffs;
					tempsec->ceilingpic_angle = s->ceilingpic_angle;
				}
				mapnum = s->bottommap;
			}

			tempsec->lightlevel = s->lightlevel;

			if (floorlightlevel)
				*floorlightlevel = s->floorlightsec == -1 ? s->lightlevel
					: sectors[s->floorlightsec].lightlevel;

			if (ceilinglightlevel)
				*ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel
					: sectors[s->ceilinglightsec].lightlevel;
		}
		else if (heightsec != -1 && viewz >= sectors[heightsec].ceilingheight
			&& sec->ceilingheight > s->ceilingheight)
		{ // Above-ceiling hack
			tempsec->ceilingheight = s->ceilingheight;
			tempsec->floorheight = s->ceilingheight + 1;

			tempsec->floorpic = tempsec->ceilingpic = s->ceilingpic;
			tempsec->floor_xoffs = tempsec->ceiling_xoffs = s->ceiling_xoffs;
			tempsec->floor_yoffs = tempsec->ceiling_yoffs = s->ceiling_yoffs;
			tempsec->floorpic_angle = tempsec->ceilingpic_angle = s->ceilingpic_angle;

			mapnum = s->topmap;

			if (s->floorpic == skyflatnum) // SKYFIX?
			{
				tempsec->ceilingheight = tempsec->floorheight-1;
				tempsec->floorpic = tempsec->ceilingpic;
				tempsec->floor_xoffs = tempsec->ceiling_xoffs;
				tempsec->floor_yoffs = tempsec->ceiling_yoffs;
				tempsec->floorpic_angle = tempsec->ceilingpic_angle;
			}
			else
			{
				tempsec->ceilingheight = sec->ceilingheight;
				tempsec->floorpic = s->floorpic;
				tempsec->floor_xoffs = s->floor_xoffs;
				tempsec->floor_yoffs = s->floor_yoffs;
				tempsec->floorpic_angle = s->floorpic_angle;
			}

			tempsec->lightlevel = s->lightlevel;

			if (floorlightlevel)
				*floorlightlevel = s->floorlightsec == -1 ? s->lightlevel :
			sectors[s->floorlightsec].lightlevel;

			if (ceilinglightlevel)
				*ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel :
			sectors[s->ceilinglightsec].lightlevel;
		}
		sec = tempsec;
	}

	if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
		sec->extra_colormap = &extra_colormaps[mapnum];
	else
		sec->extra_colormap = NULL;

	return sec;
}
コード例 #2
0
ファイル: p_mobj.c プロジェクト: ehershey/development
/*
 * Returns true if it the thing can be positioned in the coordinates.
 */
boolean P_CheckPosXYZ(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
{
    int     xl, xh;
    int     yl, yh;
    int     bx, by;
    subsector_t *newsubsec;
    checkpos_data_t data;
    boolean result = true;

    blockingMobj = NULL;
    thing->onmobj = NULL;
    thing->wallhit = false;

    // Prepare the data struct.
    data.thing = thing;
    data.flags = thing->ddflags;
    data.x = x;
    data.y = y;
    data.z = z;
    data.height = thing->height;
    data.box[BOXTOP] = y + thing->radius;
    data.box[BOXBOTTOM] = y - thing->radius;
    data.box[BOXRIGHT] = x + thing->radius;
    data.box[BOXLEFT] = x - thing->radius;

    newsubsec = R_PointInSubsector(x, y);

    // The base floor / ceiling is from the subsector
    // that contains the point.
    // Any contacted lines the step closer together
    // will adjust them.
    data.floorz = data.dropoffz = newsubsec->sector->floorheight;
    data.ceilingz = newsubsec->sector->ceilingheight;

    validcount++;

    // Check things first, possibly picking things up.
    // The bounding box is extended by MAXRADIUS
    // because mobj_ts are grouped into mapblocks
    // based on their origin point, and can overlap
    // into adjacent blocks by up to MAXRADIUS units.
    xl = (data.box[BOXLEFT] - bmaporgx - MAXRADIUS) >> MAPBLOCKSHIFT;
    xh = (data.box[BOXRIGHT] - bmaporgx + MAXRADIUS) >> MAPBLOCKSHIFT;
    yl = (data.box[BOXBOTTOM] - bmaporgy - MAXRADIUS) >> MAPBLOCKSHIFT;
    yh = (data.box[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;

    if(!dontHitMobjs)
    {
        for(bx = xl; bx <= xh; bx++)
            for(by = yl; by <= yh; by++)
                if(!P_BlockThingsIterator(bx, by, PIT_CheckThing, &data))
                {
                    result = false;
                    goto checkpos_done;
                }
    }

    // check lines
    xl = (data.box[BOXLEFT] - bmaporgx) >> MAPBLOCKSHIFT;
    xh = (data.box[BOXRIGHT] - bmaporgx) >> MAPBLOCKSHIFT;
    yl = (data.box[BOXBOTTOM] - bmaporgy) >> MAPBLOCKSHIFT;
    yh = (data.box[BOXTOP] - bmaporgy) >> MAPBLOCKSHIFT;

    for(bx = xl; bx <= xh; bx++)
        for(by = yl; by <= yh; by++)
            if(!P_BlockLinesIterator(bx, by, PIT_CheckLine, &data))
            {
                result = false;
                goto checkpos_done;
            }

checkpos_done:
    tmceilingz = data.ceilingz;
    tmfloorz = data.floorz;
    tmdropoffz = data.dropoffz;
    return result;
}
コード例 #3
0
ファイル: a_dynlight.cpp プロジェクト: AkumaKing/Xeu
void ADynamicLight::LinkLight()
{
	// mark the old light nodes
	FLightNode * node;
	
	node = touching_sides;
	while (node)
    {
		node->lightsource = NULL;
		node = node->nextTarget;
    }
	node = touching_subsectors;
	while (node)
    {
		node->lightsource = NULL;
		node = node->nextTarget;
    }
	node = touching_sector;
	while (node)
	{
		node->lightsource = NULL;
		node = node->nextTarget;
	}

	if (radius>0)
	{
		// passing in radius*radius allows us to do a distance check without any calls to sqrtf
		subsector_t * subSec = R_PointInSubsector(x, y);
		if (subSec)
		{
			float fradius = FIXED2FLOAT(radius);
			::validcount++;
			CollectWithinRadius(subSec, fradius*fradius);
		}
	}
		
	// Now delete any nodes that won't be used. These are the ones where
	// m_thing is still NULL.
	
	node = touching_sides;
	while (node)
	{
		if (node->lightsource == NULL)
		{
			node = DeleteLightNode(node);
		}
		else
			node = node->nextTarget;
	}

	node = touching_subsectors;
	while (node)
	{
		if (node->lightsource == NULL)
		{
			node = DeleteLightNode(node);
		}
		else
			node = node->nextTarget;
	}

	node = touching_sector;
	while (node)
	{
		if (node->lightsource == NULL)
		{
			node = DeleteLightNode(node);
		}
		else
			node = node->nextTarget;
	}
}
コード例 #4
0
ファイル: P_telept.c プロジェクト: amitahire/development
mobj_t *P_SpawnTeleFog(int x, int y)
{
	subsector_t *ss = R_PointInSubsector(x, y);

	return P_SpawnMobj(x, y, ss->sector->floorheight + TELEFOGHEIGHT, MT_TFOG);
}
コード例 #5
0
ファイル: rend_decor.c プロジェクト: amitahire/development
/*
 * A light decoration is created in the specified coordinates.
 * Does largely the same thing as DL_AddLuminous().
 */
void Rend_AddLightDecoration(float pos[3], ded_decorlight_t * def,
							 float brightness, boolean isWall,
							 DGLuint decorMap)
{
	decorsource_t *source;
	lumobj_t *lum;
	float   distance = Rend_PointDist3D(pos);
	float   fadeMul = 1, flareMul = 1;
	float   maxDist = (isWall ? decorWallMaxDist : decorPlaneMaxDist);
	int     i;

	// Is the point in range?
	if(distance > maxDist)
		return;

	// Close enough to the maximum distance, the lights fade out.
	if(distance > .67f * maxDist)
	{
		fadeMul = (maxDist - distance) / (.33f * maxDist);
	}

	// Apply the brightness factor (was calculated using sector lightlevel).
	fadeMul *= brightness * (isWall ? decorWallFactor : decorPlaneFactor);

	// Brightness drops as the angle gets too big.
	if(def->elevation < 2 && decorFadeAngle > 0)	// Close the surface?
	{
		float   vector[3] = { pos[VX] - vx, pos[VZ] - vy, pos[VY] - vz };
		float   dot;

		M_Normalize(vector);
		dot =
			-(surfaceNormal[VX] * vector[VX] + surfaceNormal[VY] * vector[VY] +
			  surfaceNormal[VZ] * vector[VZ]);
		if(dot < decorFadeAngle / 2)
		{
			flareMul = 0;
		}
		else if(dot < 3 * decorFadeAngle)
		{
			flareMul *= (dot - decorFadeAngle / 2) / (2.5f * decorFadeAngle);
		}
	}

	if(fadeMul <= 0)
		return;

	if(!(source = Rend_NewLightDecorationSource()))
		return;					// Out of sources!

	// Initialize the essentials in the dummy mobj.
	source->thing.x = pos[VX] * FRACUNIT;
	source->thing.y = pos[VY] * FRACUNIT;
	source->thing.z = pos[VZ] * FRACUNIT;
	source->thing.frame = FF_FULLBRIGHT;
	source->thing.halofactor = 0xff;	// Assumed visible.
	source->thing.subsector =
		R_PointInSubsector(source->thing.x, source->thing.y);

	// Fill in the data for a new luminous object.
	source->thing.light = DL_NewLuminous();
	lum = DL_GetLuminous(source->thing.light);
	lum->thing = &source->thing;
	lum->center = 0;
	lum->flags = LUMF_CLIPPED;
	lum->tex = def->sides.tex;
	lum->ceilTex = def->up.tex;
	lum->floorTex = def->down.tex;

	// These are the same rules as in DL_ThingRadius().
	lum->radius = def->radius * 40 * dlRadFactor;

	// Don't make a too small or too large light.
	if(lum->radius > dlMaxRad)
		lum->radius = dlMaxRad;

	if(def->halo_radius > 0)
	{
		lum->flareSize = def->halo_radius * 60 * (50 + haloSize) / 100.0f;
		if(lum->flareSize < 1)
			lum->flareSize = 1;
	}
	else
	{
		lum->flareSize = 0;
	}

	// This light source is associated with a decoration map, if one is 
	// available.
	lum->decorMap = decorMap;

	// Zero = Texture chosen automatically.
	lum->flareTex = def->flare_texture;
	lum->flareMul = flareMul;

	for(i = 0; i < 3; i++)
		lum->rgb[i] = (byte) (255 * def->color[i] * fadeMul);

	// Approximate the distance.
	lum->distance =
		P_ApproxDistance3(source->thing.x - viewx, source->thing.y - viewy,
						  source->thing.z - viewz);
}