예제 #1
0
static int gl_SetSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec, 
                              int lightlevel, int rellight, FColormap * cm, float alpha, 
							  PalEntry ThingColor, bool weapon)
{
	float r,g,b;
	float result[4]; // Korshun.

	gl_GetLightColor(lightlevel, rellight, cm, &r, &g, &b, weapon);
	bool res = gl_GetSpriteLight(self, x, y, z, subsec, cm? cm->colormap : 0, result);
	if (!res || glset.lightmode == 8)
	{
		r *= ThingColor.r/255.f;
		g *= ThingColor.g/255.f;
		b *= ThingColor.b/255.f;
		glColor4f(r, g, b, alpha);
		if (glset.lightmode == 8) 
		{
			glVertexAttrib1f(VATTR_LIGHTLEVEL, gl_CalcLightLevel(lightlevel, rellight, weapon) / 255.0f); // Korshun.
			gl_RenderState.SetDynLight(result[0], result[1], result[2]);
		}
		return lightlevel;
	}
	else
	{
		// Note: Due to subtractive lights the values can easily become negative so we have to clamp both
		// at the low and top end of the range!
		r = clamp<float>(result[0]+r, 0, 1.0f);
		g = clamp<float>(result[1]+g, 0, 1.0f);
		b = clamp<float>(result[2]+b, 0, 1.0f);

		float dlightlevel = r*77 + g*143 + b*35;

		r *= ThingColor.r/255.f;
		g *= ThingColor.g/255.f;
		b *= ThingColor.b/255.f;

		glColor4f(r, g, b, alpha);		

		if (dlightlevel == 0) return 0;

		if (glset.lightmode&2 && dlightlevel<192.f) 
		{
			return xs_CRoundToInt(192.f - (192.f - dlightlevel) / 1.95f);
		}
		else
		{
			return xs_CRoundToInt(dlightlevel);
		}
	}
}
예제 #2
0
size_t SndFileDecoder::read(char *buffer, size_t bytes)
{
    short *out = (short*)buffer;
    size_t frames = bytes / SndInfo.channels / 2;
    size_t total = 0;

    // It seems libsndfile has a bug with converting float samples from Vorbis
    // to the 16-bit shorts we use, which causes some PCM samples to overflow
    // and wrap, creating static. So instead, read the samples as floats and
    // convert to short ourselves.
    // Use a loop to convert a handful of samples at a time, avoiding a heap
    // allocation for temporary storage. 64 at a time works, though maybe it
    // could be more.
    while(total < frames)
    {
        size_t todo = MIN<size_t>(frames-total, 64/SndInfo.channels);
        float tmp[64];

        size_t got = (size_t)sf_readf_float(SndFile, tmp, todo);
        if(got < todo) frames = total + got;

        for(size_t i = 0;i < got*SndInfo.channels;i++)
            *out++ = (short)xs_CRoundToInt(clamp(tmp[i] * 32767.f, -32768.f, 32767.f));
        total += got;
    }
    return total * SndInfo.channels * 2;
}
예제 #3
0
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal)
{
	TArray<FCoverageVertex> shape;
	double centerx=0, centery=0;

	shape.Resize(subsector->numlines);
	for(unsigned i=0; i<subsector->numlines; i++)
	{
		centerx += (shape[i].x = subsector->firstline[i].v1->x + portal->xDisplacement);
		centery += (shape[i].y = subsector->firstline[i].v1->y + portal->yDisplacement);
	}

	FCoverageBuilder build(subsector, portal);
	build.center.x = xs_CRoundToInt(centerx / subsector->numlines);
	build.center.y = xs_CRoundToInt(centery / subsector->numlines);

	build.CollectNode(nodes + numnodes - 1, shape);
	coverage->subsectors = new DWORD[build.collect.Size()]; 
	coverage->sscount = build.collect.Size();
	memcpy(coverage->subsectors, &build.collect[0], build.collect.Size() * sizeof(DWORD));
}
예제 #4
0
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement)
{
	TArray<FCoverageVertex> shape;
	double centerx=0, centery=0;

	shape.Resize(subsector->numlines);
	for(unsigned i=0; i<subsector->numlines; i++)
	{
		centerx += (shape[i].x = FLOAT2FIXED(subsector->firstline[i].v1->fX() + displacement.X));
		centery += (shape[i].y = FLOAT2FIXED(subsector->firstline[i].v1->fY() + displacement.Y));
	}

	FCoverageBuilder build(subsector);
	build.center.x = xs_CRoundToInt(centerx / subsector->numlines);
	build.center.y = xs_CRoundToInt(centery / subsector->numlines);

	build.CollectNode(level.HeadNode(), shape);
	coverage->subsectors = new uint32_t[build.collect.Size()]; 
	coverage->sscount = build.collect.Size();
	memcpy(coverage->subsectors, &build.collect[0], build.collect.Size() * sizeof(uint32_t));
}
예제 #5
0
bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
				 bool useFog, bool sourceFog, bool keepOrientation, bool bHaltVelocity, bool keepHeight)
{
	bool predicting = (thing->player && (thing->player->cheats & CF_PREDICTING));

	fixed_t oldx;
	fixed_t oldy;
	fixed_t oldz;
	fixed_t aboveFloor;
	player_t *player;
	angle_t an;
	sector_t *destsect;
	bool resetpitch = false;
	fixed_t floorheight, ceilingheight;
	fixed_t missilespeed;

	oldx = thing->x;
	oldy = thing->y;
	oldz = thing->z;
	aboveFloor = thing->z - thing->floorz;
	destsect = P_PointInSector (x, y);
	// killough 5/12/98: exclude voodoo dolls:
	player = thing->player;
	if (player && player->mo != thing)
		player = NULL;
	floorheight = destsect->floorplane.ZatPoint (x, y);
	ceilingheight = destsect->ceilingplane.ZatPoint (x, y);
	if (thing->flags & MF_MISSILE)
	{ // We don't measure z velocity, because it doesn't change.
		missilespeed = xs_CRoundToInt(TVector2<double>(thing->velx, thing->vely).Length());
	}
	if (keepHeight)
	{
		z = floorheight + aboveFloor;
	}
	else if (z == ONFLOORZ)
	{
		if (player)
		{
			if (thing->flags & MF_NOGRAVITY && aboveFloor)
			{
				z = floorheight + aboveFloor;
				if (z + thing->height > ceilingheight)
				{
					z = ceilingheight - thing->height;
				}
			}
			else
			{
				z = floorheight;
				if (!keepOrientation)
				{
					resetpitch = false;
				}
			}
		}
		else if (thing->flags & MF_MISSILE)
		{
			z = floorheight + aboveFloor;
			if (z + thing->height > ceilingheight)
			{
				z = ceilingheight - thing->height;
			}
		}
		else
		{
			z = floorheight;
		}
	}
	if (!P_TeleportMove (thing, x, y, z, false))
	{
		return false;
	}
	if (player)
	{
		player->viewz = thing->z + player->viewheight;
		if (resetpitch)
		{
			player->mo->pitch = 0;
		}
	}
	if (!keepOrientation)
	{
		thing->angle = angle;
	}
	else
	{
		angle = thing->angle;
	}
	// Spawn teleport fog at source and destination
	if (sourceFog && !predicting)
	{
		fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
		P_SpawnTeleportFog(thing, oldx, oldy, oldz, true, true); //Passes the actor through which then pulls the TeleFog metadate types based on properties.
	}
	if (useFog)
	{
		if (!predicting)
		{
			fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
			an = angle >> ANGLETOFINESHIFT;
			P_SpawnTeleportFog(thing, x + 20 * finecosine[an], y + 20 * finesine[an], thing->z + fogDelta, false, true);

		}
		if (thing->player)
		{
			// [RH] Zoom player's field of vision
			// [BC] && bHaltVelocity.
			if (telezoom && thing->player->mo == thing && bHaltVelocity)
				thing->player->FOV = MIN (175.f, thing->player->DesiredFOV + 45.f);
		}
	}
예제 #6
0
void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, unsigned char *dst_data)
{

    // This function implements a simple pre-blur/box averaging method for
    // downsampling that gives reasonably smooth results To scale the image
    // down we will need to gather a grid of pixels of the size of the scale
    // factor in each direction and then do an averaging of the pixels.

    TArray<BoxPrecalc> vPrecalcs(height);
    TArray<BoxPrecalc> hPrecalcs(width);

    ResampleBoxPrecalc(vPrecalcs, texheight);
    ResampleBoxPrecalc(hPrecalcs, texwidth);

    int averaged_pixels, averaged_alpha, src_pixel_index;
    double sum_r, sum_g, sum_b, sum_a;

    for (int y = 0; y < height; y++)         // Destination image - Y direction
    {
        // Source pixel in the Y direction
        const BoxPrecalc& vPrecalc = vPrecalcs[y];

        for (int x = 0; x < width; x++)      // Destination image - X direction
        {
            // Source pixel in the X direction
            const BoxPrecalc& hPrecalc = hPrecalcs[x];

            // Box of pixels to average
            averaged_pixels = 0;
            averaged_alpha = 0;
            sum_r = sum_g = sum_b = sum_a = 0.0;

            for (int j = vPrecalc.boxStart; j <= vPrecalc.boxEnd; ++j)
            {
                for (int i = hPrecalc.boxStart; i <= hPrecalc.boxEnd; ++i)
                {
                    // Calculate the actual index in our source pixels
                    src_pixel_index = j * texwidth + i;

                    int a = src_data[src_pixel_index * 4 + 3];
                    if (a > 0)	// do not use color from fully transparent pixels
                    {
                        sum_r += src_data[src_pixel_index * 4 + 0];
                        sum_g += src_data[src_pixel_index * 4 + 1];
                        sum_b += src_data[src_pixel_index * 4 + 2];
                        sum_a += a;
                        averaged_pixels++;
                    }
                    averaged_alpha++;

                }
            }

            // Calculate the average from the sum and number of averaged pixels
            dst_data[0] = (unsigned char)xs_CRoundToInt(sum_r / averaged_pixels);
            dst_data[1] = (unsigned char)xs_CRoundToInt(sum_g / averaged_pixels);
            dst_data[2] = (unsigned char)xs_CRoundToInt(sum_b / averaged_pixels);
            dst_data[3] = (unsigned char)xs_CRoundToInt(sum_a / averaged_alpha);
            dst_data += 4;
        }
    }
}
예제 #7
0
bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
				 bool useFog, bool sourceFog, bool keepOrientation, bool bHaltVelocity, bool keepHeight)
{
	fixed_t oldx;
	fixed_t oldy;
	fixed_t oldz;
	fixed_t aboveFloor;
	player_t *player;
	angle_t an;
	sector_t *destsect;
	bool resetpitch = false;
	fixed_t floorheight, ceilingheight;
	fixed_t missilespeed;

	oldx = thing->x;
	oldy = thing->y;
	oldz = thing->z;
	aboveFloor = thing->z - thing->floorz;
	destsect = P_PointInSector (x, y);
	// killough 5/12/98: exclude voodoo dolls:
	player = thing->player;
	if (player && player->mo != thing)
		player = NULL;
	floorheight = destsect->floorplane.ZatPoint (x, y);
	ceilingheight = destsect->ceilingplane.ZatPoint (x, y);
	if (thing->flags & MF_MISSILE)
	{ // We don't measure z velocity, because it doesn't change.
		missilespeed = xs_CRoundToInt(TVector2<double>(thing->velx, thing->vely).Length());
	}
	if (keepHeight)
	{
		z = floorheight + aboveFloor;
	}
	else if (z == ONFLOORZ)
	{
		if (player)
		{
			if (thing->flags & MF_NOGRAVITY && aboveFloor)
			{
				z = floorheight + aboveFloor;
				if (z + thing->height > ceilingheight)
				{
					z = ceilingheight - thing->height;
				}
			}
			else
			{
				z = floorheight;
				if (!keepOrientation)
				{
					resetpitch = false;
				}
			}
		}
		else if (thing->flags & MF_MISSILE)
		{
			z = floorheight + aboveFloor;
			if (z + thing->height > ceilingheight)
			{
				z = ceilingheight - thing->height;
			}
		}
		else
		{
			z = floorheight;
		}
	}
	if (!P_TeleportMove (thing, x, y, z, false))
	{
		return false;
	}
	if (player)
	{
		player->viewz = thing->z + player->viewheight;
		if (resetpitch)
		{
			player->mo->pitch = 0;
		}
	}
	if (!keepOrientation)
	{
		thing->angle = angle;
	}
	else
	{
		angle = thing->angle;
	}
	// Spawn teleport fog at source and destination
	if (sourceFog)
	{
		fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
		AActor *fog = Spawn<ATeleportFog> (oldx, oldy, oldz + fogDelta, ALLOW_REPLACE);
		fog->target = thing;
	}
	if (useFog)
	{
		fixed_t fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
		an = angle >> ANGLETOFINESHIFT;
		AActor *fog = Spawn<ATeleportFog> (x + 20*finecosine[an],
			y + 20*finesine[an], thing->z + fogDelta, ALLOW_REPLACE);
		fog->target = thing;
		if (thing->player)
		{
			// [RH] Zoom player's field of vision
			// [BC] && bHaltVelocity.
			if (telezoom && thing->player->mo == thing && bHaltVelocity)
				thing->player->FOV = MIN (175.f, thing->player->DesiredFOV + 45.f);
		}
	}
	// [BC] && bHaltVelocity.
	if (thing->player && (useFog || !keepOrientation) && bHaltVelocity)
	{
		// Freeze player for about .5 sec
		if (thing->Inventory == NULL || thing->Inventory->GetSpeedFactor() <= FRACUNIT)
			thing->reactiontime = 18;
	}
	if (thing->flags & MF_MISSILE)
	{
		angle >>= ANGLETOFINESHIFT;
		thing->velx = FixedMul (missilespeed, finecosine[angle]);
		thing->vely = FixedMul (missilespeed, finesine[angle]);
	}