Exemplo n.º 1
0
Arquivo: elight.c Projeto: btb/d2x
// -----------------------------------------------------------------------------
//	Recursively apply light to segments.
//	If current side is a wall, apply light there.
//	If not a wall, apply light to child through that wall.
//	Notes:
//		It is possible to enter a segment twice by taking different paths.  It is easy
//		to prevent this by maintaining a list of visited segments, but it is important
//		to reach segments with the greatest light intensity.  This can be done by doing
//		a breadth-first-search, or by storing the applied intensity with a visited segment,
//		and if the current intensity is brighter, then apply the difference between it and
//		the previous intensity.
//		Note that it is also possible to visit the original light-casting segment, for example
//		going from segment 0 to 2, then from 2 to 0.  This is peculiar and probably not
//		desired, but not entirely invalid.  2 reflects some light back to 0.
void apply_light_intensity(segment *segp, int sidenum, fix intensity, int depth)
{
	int	wid_result;

	if (intensity == 0)
		return;

	wid_result = WALL_IS_DOORWAY(segp, sidenum);
	if ((wid_result != WID_FLY_FLAG) && (wid_result != WID_NO_WALL)) {
		int	v;
		for (v=0; v<4; v++)							// add light to this wall
			add_light_intensity(segp, sidenum, v, intensity);
		return;										// we return because there is a wall here, and light does not shine through walls
	}

	//	No wall here, so apply light recursively
	if (depth < 3) {
		int	s;
		for (s=0; s<MAX_SIDES_PER_SEGMENT; s++)
			apply_light_intensity(&Segments[segp->children[sidenum]], s, intensity/3, depth+1);
	}

}
Exemplo n.º 2
0
// -----------------------------------------------------------------------------
//	Top level recursive function for applying light.
//	Calls apply_light_intensity.
//	Uses light value on segp:sidenum (tmap_num2 defines light value) and applies
//	the associated intensity to segp.  It calls apply_light_intensity to apply intensity/3
//	to all neighbors.  apply_light_intensity recursively calls itself to apply light to
//	subsequent neighbors (and forming loops, see above).
static void propagate_light_intensity(const vmsegptr_t segp, int sidenum) 
{
	fix		intensity;
	short		texmap;

	intensity = 0;
	auto &us = segp->unique_segment::sides[sidenum];
	auto &TmapInfo = LevelUniqueTmapInfoState.TmapInfo;
	texmap = us.tmap_num;
	intensity += TmapInfo[texmap].lighting;
	texmap = us.tmap_num2 & 0x3fff;
	intensity += TmapInfo[texmap].lighting;

	if (intensity > 0) {
		add_light_intensity_all_verts(us, intensity);
	
		//	Now, for all sides which are not the same as sidenum (the side casting the light),
		//	add a light value to them (if they have no children, ie, they have a wall there).
		for (int s=0; s<MAX_SIDES_PER_SEGMENT; s++)
			if (s != sidenum)
				apply_light_intensity(segp, s, intensity/2, 1);
	}

}
Exemplo n.º 3
0
Arquivo: elight.c Projeto: btb/d2x
// -----------------------------------------------------------------------------
//	Top level recursive function for applying light.
//	Calls apply_light_intensity.
//	Uses light value on segp:sidenum (tmap_num2 defines light value) and applies
//	the associated intensity to segp.  It calls apply_light_intensity to apply intensity/3
//	to all neighbors.  apply_light_intensity recursively calls itself to apply light to
//	subsequent neighbors (and forming loops, see above).
void propagate_light_intensity(segment *segp, int sidenum) 
{
	int		v,s;
	fix		intensity;
	short		texmap;

	intensity = 0;
	texmap = segp->sides[sidenum].tmap_num;
	intensity += TmapInfo[texmap].lighting;
	texmap = (segp->sides[sidenum].tmap_num2) & 0x3fff;
	intensity += TmapInfo[texmap].lighting;

	if (intensity > 0) {
		for (v=0; v<4; v++)
			add_light_intensity(segp, sidenum, v, intensity);
	
		//	Now, for all sides which are not the same as sidenum (the side casting the light),
		//	add a light value to them (if they have no children, ie, they have a wall there).
		for (s=0; s<MAX_SIDES_PER_SEGMENT; s++)
			if (s != sidenum)
				apply_light_intensity(segp, s, intensity/2, 1);
	}

}
Exemplo n.º 4
0
// -----------------------------------------------------------------------------
//	Recursively apply light to segments.
//	If current side is a wall, apply light there.
//	If not a wall, apply light to child through that wall.
//	Notes:
//		It is possible to enter a segment twice by taking different paths.  It is easy
//		to prevent this by maintaining a list of visited segments, but it is important
//		to reach segments with the greatest light intensity.  This can be done by doing
//		a breadth-first-search, or by storing the applied intensity with a visited segment,
//		and if the current intensity is brighter, then apply the difference between it and
//		the previous intensity.
//		Note that it is also possible to visit the original light-casting segment, for example
//		going from segment 0 to 2, then from 2 to 0.  This is peculiar and probably not
//		desired, but not entirely invalid.  2 reflects some light back to 0.
static void apply_light_intensity(const vmsegptr_t segp, const unsigned sidenum, fix intensity, const unsigned depth)
{
	if (intensity == 0)
		return;

	auto &Walls = LevelUniqueWallSubsystemState.Walls;
	auto &vcwallptr = Walls.vcptr;
	const auto wid_result = WALL_IS_DOORWAY(GameBitmaps, Textures, vcwallptr, segp, segp, sidenum);
	if (!(wid_result & WID_RENDPAST_FLAG)) {
		add_light_intensity_all_verts(segp->unique_segment::sides[sidenum], intensity);
		return;										// we return because there is a wall here, and light does not shine through walls
	}

	//	No wall here, so apply light recursively
	if (depth < 3) {
		intensity /= 3;
		if (!intensity)
			return;
		const auto &&csegp = vmsegptr(segp->children[sidenum]);
		for (int s=0; s<MAX_SIDES_PER_SEGMENT; s++)
			apply_light_intensity(csegp, s, intensity, depth+1);
	}

}