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); } } }
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; }
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)); }
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)); }
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); } }
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; } } }
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]); }