mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-17 09:31:43 +00:00
- Polyobject sounds now play from their lines, similar to the way sector
sounds are handled. - Why do polyobjects have a 3D start spot? Flattened it to 2D. - Moved the sector sound origin calculation out of fmodsound.cpp and into s_sound.cpp so that the near sound limiting will use the correct sound location for deciding on neighbors. SVN r1061 (trunk)
This commit is contained in:
parent
2fccefa995
commit
7ed0311221
8 changed files with 185 additions and 151 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
July 1, 2008
|
||||||
|
- Polyobject sounds now play from their lines, similar to the way sector
|
||||||
|
sounds are handled.
|
||||||
|
- Why do polyobjects have a 3D start spot? Flattened it to 2D.
|
||||||
|
- Moved the sector sound origin calculation out of fmodsound.cpp and into
|
||||||
|
s_sound.cpp so that the near sound limiting will use the correct sound
|
||||||
|
location for deciding on neighbors.
|
||||||
|
|
||||||
June 30, 2008
|
June 30, 2008
|
||||||
- Removed the S_Sound() variant that allows for pointing the origin at an
|
- Removed the S_Sound() variant that allows for pointing the origin at an
|
||||||
arbitrary point. It has been replaced with a variant that takes a polyobject
|
arbitrary point. It has been replaced with a variant that takes a polyobject
|
||||||
|
|
|
@ -496,6 +496,7 @@ bool PO_MovePolyobj (int num, int x, int y, bool force=false);
|
||||||
bool PO_RotatePolyobj (int num, angle_t angle);
|
bool PO_RotatePolyobj (int num, angle_t angle);
|
||||||
void PO_Init ();
|
void PO_Init ();
|
||||||
bool PO_Busy (int polyobj);
|
bool PO_Busy (int polyobj);
|
||||||
|
void PO_ClosestPoint(const FPolyObj *poly, fixed_t ox, fixed_t oy, fixed_t &x, fixed_t &y, seg_t **seg);
|
||||||
|
|
||||||
//
|
//
|
||||||
// P_SPEC
|
// P_SPEC
|
||||||
|
|
|
@ -474,14 +474,14 @@ void P_SerializePolyobjs (FArchive &arc)
|
||||||
for(i = 0, po = polyobjs; i < po_NumPolyobjs; i++, po++)
|
for(i = 0, po = polyobjs; i < po_NumPolyobjs; i++, po++)
|
||||||
{
|
{
|
||||||
arc << po->tag << po->angle << po->startSpot[0] <<
|
arc << po->tag << po->angle << po->startSpot[0] <<
|
||||||
po->startSpot[1] << po->startSpot[2] << po->interpolation;
|
po->startSpot[1] << po->interpolation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int data;
|
int data;
|
||||||
angle_t angle;
|
angle_t angle;
|
||||||
fixed_t deltaX, deltaY, deltaZ;
|
fixed_t deltaX, deltaY;
|
||||||
|
|
||||||
arc << data;
|
arc << data;
|
||||||
if (data != ASEG_POLYOBJS)
|
if (data != ASEG_POLYOBJS)
|
||||||
|
@ -501,10 +501,9 @@ void P_SerializePolyobjs (FArchive &arc)
|
||||||
}
|
}
|
||||||
arc << angle;
|
arc << angle;
|
||||||
PO_RotatePolyobj (po->tag, angle);
|
PO_RotatePolyobj (po->tag, angle);
|
||||||
arc << deltaX << deltaY << deltaZ << po->interpolation;
|
arc << deltaX << deltaY << po->interpolation;
|
||||||
deltaX -= po->startSpot[0];
|
deltaX -= po->startSpot[0];
|
||||||
deltaY -= po->startSpot[1];
|
deltaY -= po->startSpot[1];
|
||||||
deltaZ -= po->startSpot[2];
|
|
||||||
PO_MovePolyobj (po->tag, deltaX, deltaY, true);
|
PO_MovePolyobj (po->tag, deltaX, deltaY, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1671,6 +1671,75 @@ bool PO_Busy (int polyobj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// PO_ClosestPoint
|
||||||
|
//
|
||||||
|
// Given a point (x,y), returns the point (ox,oy) on the polyobject's walls
|
||||||
|
// that is nearest to (x,y). Also returns the seg this point came from.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void PO_ClosestPoint(const FPolyObj *poly, fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy, seg_t **seg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
double x = fx, y = fy;
|
||||||
|
double bestdist = HUGE_VAL;
|
||||||
|
double bestx = 0, besty = 0;
|
||||||
|
seg_t *bestseg = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < poly->numsegs; ++i)
|
||||||
|
{
|
||||||
|
vertex_t *v1 = poly->segs[i]->v1;
|
||||||
|
vertex_t *v2 = poly->segs[i]->v2;
|
||||||
|
double a = v2->x - v1->x;
|
||||||
|
double b = v2->y - v1->y;
|
||||||
|
double den = a*a + b*b;
|
||||||
|
double ix, iy, dist;
|
||||||
|
|
||||||
|
if (den == 0)
|
||||||
|
{ // Line is actually a point!
|
||||||
|
ix = v1->x;
|
||||||
|
iy = v1->y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double num = (x - v1->x) * a + (y - v1->y) * b;
|
||||||
|
double u = num / den;
|
||||||
|
if (u <= 0)
|
||||||
|
{
|
||||||
|
ix = v1->x;
|
||||||
|
iy = v1->y;
|
||||||
|
}
|
||||||
|
else if (u >= 1)
|
||||||
|
{
|
||||||
|
ix = v2->x;
|
||||||
|
iy = v2->y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ix = v1->x + u * a;
|
||||||
|
iy = v1->y + u * b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a = (ix - x);
|
||||||
|
b = (iy - y);
|
||||||
|
dist = a*a + b*b;
|
||||||
|
if (dist < bestdist)
|
||||||
|
{
|
||||||
|
bestdist = dist;
|
||||||
|
bestx = ix;
|
||||||
|
besty = iy;
|
||||||
|
bestseg = poly->segs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ox = fixed_t(bestx);
|
||||||
|
oy = fixed_t(besty);
|
||||||
|
if (seg != NULL)
|
||||||
|
{
|
||||||
|
*seg = bestseg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FPolyObj::~FPolyObj()
|
FPolyObj::~FPolyObj()
|
||||||
{
|
{
|
||||||
|
|
|
@ -769,7 +769,7 @@ struct FPolyObj
|
||||||
line_t **lines;
|
line_t **lines;
|
||||||
int numvertices;
|
int numvertices;
|
||||||
vertex_t **vertices;
|
vertex_t **vertices;
|
||||||
fixed_t startSpot[3];
|
fixed_t startSpot[2];
|
||||||
vertex_t *originalPts; // used as the base for the rotations
|
vertex_t *originalPts; // used as the base for the rotations
|
||||||
vertex_t *prevPts; // use to restore the old point values
|
vertex_t *prevPts; // use to restore the old point values
|
||||||
angle_t angle;
|
angle_t angle;
|
||||||
|
|
201
src/s_sound.cpp
201
src/s_sound.cpp
|
@ -104,7 +104,9 @@ static bool S_CheckSoundLimit(sfxinfo_t *sfx, const FVector3 &pos, int near_limi
|
||||||
static void S_ActivatePlayList(bool goBack);
|
static void S_ActivatePlayList(bool goBack);
|
||||||
static void CalcPosVel(const FSoundChan *chan, FVector3 *pos, FVector3 *vel);
|
static void CalcPosVel(const FSoundChan *chan, FVector3 *pos, FVector3 *vel);
|
||||||
static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, const FPolyObj *poly,
|
static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, const FPolyObj *poly,
|
||||||
const FVector3 *pt, int constz, FVector3 *pos, FVector3 *vel);
|
const float pt[3], int channel, int chanflags, FVector3 *pos, FVector3 *vel);
|
||||||
|
static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z);
|
||||||
|
static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z);
|
||||||
static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly,
|
static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly,
|
||||||
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation);
|
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation);
|
||||||
static sfxinfo_t *S_LoadSound(sfxinfo_t *sfx);
|
static sfxinfo_t *S_LoadSound(sfxinfo_t *sfx);
|
||||||
|
@ -212,7 +214,6 @@ void S_NoiseDebug (void)
|
||||||
// Distance
|
// Distance
|
||||||
if (chan->DistanceScale > 0)
|
if (chan->DistanceScale > 0)
|
||||||
{
|
{
|
||||||
origin /= FRACUNIT;
|
|
||||||
sprintf (temp, "%.0f", (origin - listener).Length());
|
sprintf (temp, "%.0f", (origin - listener).Length());
|
||||||
screen->DrawText (color, 260, y, temp, TAG_DONE);
|
screen->DrawText (color, 260, y, temp, TAG_DONE);
|
||||||
}
|
}
|
||||||
|
@ -606,78 +607,10 @@ void S_LinkChannel(FSoundChan *chan, FSoundChan **head)
|
||||||
//
|
//
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
void CalcPosVel(const FSoundChan *chan, FVector3 *pos, FVector3 *vel)
|
static void CalcPosVel(const FSoundChan *chan, FVector3 *pos, FVector3 *vel)
|
||||||
{
|
{
|
||||||
if (pos != NULL)
|
CalcPosVel(chan->SourceType, chan->Actor, chan->Sector, chan->Poly, chan->Point,
|
||||||
{
|
chan->EntChannel, chan->ChanFlags, pos, vel);
|
||||||
fixed_t x, y, z;
|
|
||||||
|
|
||||||
switch (chan->SourceType)
|
|
||||||
{
|
|
||||||
case SOURCE_None:
|
|
||||||
default:
|
|
||||||
if (players[consoleplayer].camera != NULL)
|
|
||||||
{
|
|
||||||
x = players[consoleplayer].camera->x;
|
|
||||||
y = players[consoleplayer].camera->z;
|
|
||||||
z = players[consoleplayer].camera->y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
z = y = x = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOURCE_Actor:
|
|
||||||
x = chan->Actor->x;
|
|
||||||
y = chan->Actor->z;
|
|
||||||
z = chan->Actor->y;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOURCE_Sector:
|
|
||||||
x = chan->Sector->soundorg[0];
|
|
||||||
y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->z : 0;
|
|
||||||
z = chan->Sector->soundorg[1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOURCE_Polyobj:
|
|
||||||
x = chan->Poly->startSpot[0];
|
|
||||||
y = chan->Poly->startSpot[2];
|
|
||||||
z = chan->Poly->startSpot[1];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOURCE_Unattached:
|
|
||||||
pos->X = chan->Point[0];
|
|
||||||
pos->Y = !(chan->ChanFlags & CHAN_LISTENERZ) ? chan->Point[1]
|
|
||||||
: FIXED2FLOAT(players[consoleplayer].camera->z);
|
|
||||||
pos->Z = chan->Point[2];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (chan->SourceType != SOURCE_Unattached)
|
|
||||||
{
|
|
||||||
if (chan->ChanFlags & CHAN_LISTENERZ)
|
|
||||||
{
|
|
||||||
y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->z : 0;
|
|
||||||
}
|
|
||||||
pos->X = FIXED2FLOAT(x);
|
|
||||||
pos->Y = FIXED2FLOAT(y);
|
|
||||||
pos->Z = FIXED2FLOAT(z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (vel != NULL)
|
|
||||||
{
|
|
||||||
// Only actors maintain velocity information.
|
|
||||||
if (chan->SourceType == SOURCE_Actor)
|
|
||||||
{
|
|
||||||
vel->X = FIXED2FLOAT(chan->Actor->momx) * TICRATE;
|
|
||||||
vel->Y = FIXED2FLOAT(chan->Actor->momz) * TICRATE;
|
|
||||||
vel->Z = FIXED2FLOAT(chan->Actor->momy) * TICRATE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vel->Zero();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
@ -689,26 +622,27 @@ void CalcPosVel(const FSoundChan *chan, FVector3 *pos, FVector3 *vel)
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
|
static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
|
||||||
const FPolyObj *poly, const FVector3 *pt, int constz, FVector3 *pos, FVector3 *vel)
|
const FPolyObj *poly, const float pt[3], int channum, int chanflags, FVector3 *pos, FVector3 *vel)
|
||||||
{
|
{
|
||||||
if (pos != NULL)
|
if (pos != NULL)
|
||||||
{
|
{
|
||||||
fixed_t x, y, z;
|
fixed_t x, y, z;
|
||||||
|
|
||||||
|
if (players[consoleplayer].camera != NULL)
|
||||||
|
{
|
||||||
|
x = players[consoleplayer].camera->x;
|
||||||
|
y = players[consoleplayer].camera->z;
|
||||||
|
z = players[consoleplayer].camera->y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z = y = x = 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case SOURCE_None:
|
case SOURCE_None:
|
||||||
default:
|
default:
|
||||||
if (players[consoleplayer].camera != NULL)
|
|
||||||
{
|
|
||||||
x = players[consoleplayer].camera->x;
|
|
||||||
y = players[consoleplayer].camera->z;
|
|
||||||
z = players[consoleplayer].camera->y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
z = y = x = 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_Actor:
|
case SOURCE_Actor:
|
||||||
|
@ -718,26 +652,31 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_Sector:
|
case SOURCE_Sector:
|
||||||
x = sector->soundorg[0];
|
if (chanflags & CHAN_AREA)
|
||||||
y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->z : 0;
|
{
|
||||||
z = sector->soundorg[1];
|
CalcSectorSoundOrg(sector, channum, &x, &z, &y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x = sector->soundorg[0];
|
||||||
|
z = sector->soundorg[1];
|
||||||
|
chanflags |= CHAN_LISTENERZ;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_Polyobj:
|
case SOURCE_Polyobj:
|
||||||
x = poly->startSpot[0];
|
CalcPolyobjSoundOrg(poly, &x, &z, &y);
|
||||||
y = poly->startSpot[2];
|
|
||||||
z = poly->startSpot[1];
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_Unattached:
|
case SOURCE_Unattached:
|
||||||
pos->X = pt->X;
|
pos->X = pt[0];
|
||||||
pos->Y = !constz ? pt->Y : FIXED2FLOAT(players[consoleplayer].camera->z);
|
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : FIXED2FLOAT(players[consoleplayer].camera->z);
|
||||||
pos->Z = pt->Z;
|
pos->Z = pt[2];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (type != SOURCE_Unattached)
|
if (type != SOURCE_Unattached)
|
||||||
{
|
{
|
||||||
if (constz)
|
if (chanflags & CHAN_LISTENERZ)
|
||||||
{
|
{
|
||||||
y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->z : 0;
|
y = players[consoleplayer].camera != NULL ? players[consoleplayer].camera->z : 0;
|
||||||
}
|
}
|
||||||
|
@ -762,6 +701,67 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// CalcSectorSoundOrg
|
||||||
|
//
|
||||||
|
// Returns the perceived sound origin for a sector. If the listener is
|
||||||
|
// inside the sector, then the origin is their location. Otherwise, the
|
||||||
|
// origin is from the nearest wall on the sector.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z)
|
||||||
|
{
|
||||||
|
// Are we inside the sector? If yes, the closest point is the one we're on.
|
||||||
|
if (P_PointInSector(*x, *y) == sec)
|
||||||
|
{
|
||||||
|
*x = players[consoleplayer].camera->x;
|
||||||
|
*y = players[consoleplayer].camera->y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Find the closest point on the sector's boundary lines and use
|
||||||
|
// that as the perceived origin of the sound.
|
||||||
|
sec->ClosestPoint(*x, *y, *x, *y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sound vertical position based on channel.
|
||||||
|
if (channum == CHAN_FLOOR)
|
||||||
|
{
|
||||||
|
*z = MIN(sec->floorplane.ZatPoint(*x, *y), *z);
|
||||||
|
}
|
||||||
|
else if (channum == CHAN_CEILING)
|
||||||
|
{
|
||||||
|
*z = MAX(sec->ceilingplane.ZatPoint(*x, *y), *z);
|
||||||
|
}
|
||||||
|
else if (channum == CHAN_INTERIOR)
|
||||||
|
{
|
||||||
|
*z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// CalcPolySoundOrg
|
||||||
|
//
|
||||||
|
// Returns the perceived sound origin for a polyobject. This is similar to
|
||||||
|
// CalcSectorSoundOrg, except there is no special case for being "inside"
|
||||||
|
// a polyobject, so the sound literally comes from the polyobject's walls.
|
||||||
|
// Vertical position of the sound always comes from the visible wall.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z)
|
||||||
|
{
|
||||||
|
seg_t *seg;
|
||||||
|
sector_t *sec;
|
||||||
|
|
||||||
|
PO_ClosestPoint(poly, *x, *y, *x, *y, &seg);
|
||||||
|
sec = seg->frontsector;
|
||||||
|
*z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y));
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// S_StartSound
|
// S_StartSound
|
||||||
|
@ -811,23 +811,20 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
|
|
||||||
org_id = sound_id;
|
org_id = sound_id;
|
||||||
chanflags = channel & ~7;
|
chanflags = channel & ~7;
|
||||||
|
channel &= 7;
|
||||||
|
|
||||||
CalcPosVel(type, actor, sec, poly, pt, chanflags & CHAN_LISTENERZ, &pos, &vel);
|
CalcPosVel(type, actor, sec, poly, &pt->X, channel, chanflags, &pos, &vel);
|
||||||
|
|
||||||
if (i_compatflags & COMPATF_MAGICSILENCE)
|
if (i_compatflags & COMPATF_MAGICSILENCE)
|
||||||
{ // For people who just can't play without a silent BFG.
|
{ // For people who just can't play without a silent BFG.
|
||||||
channel = CHAN_WEAPON;
|
channel = CHAN_WEAPON;
|
||||||
}
|
}
|
||||||
else
|
else if ((chanflags & CHAN_MAYBE_LOCAL) && (i_compatflags & COMPATF_SILENTPICKUP))
|
||||||
{
|
{
|
||||||
if ((channel & CHAN_MAYBE_LOCAL) && (i_compatflags & COMPATF_SILENTPICKUP))
|
if (actor != NULL && actor != players[consoleplayer].camera)
|
||||||
{
|
{
|
||||||
if (actor != NULL && actor != players[consoleplayer].camera)
|
return NULL;
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
channel &= 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sfx = &S_sfx[sound_id];
|
sfx = &S_sfx[sound_id];
|
||||||
|
|
|
@ -1554,55 +1554,15 @@ FMOD_MODE FMODSoundRenderer::SetChanHeadSettings(FMOD::Channel *chan, sfxinfo_t
|
||||||
cpos.X = FIXED2FLOAT(players[consoleplayer].camera->x);
|
cpos.X = FIXED2FLOAT(players[consoleplayer].camera->x);
|
||||||
cpos.Y = FIXED2FLOAT(players[consoleplayer].camera->z);
|
cpos.Y = FIXED2FLOAT(players[consoleplayer].camera->z);
|
||||||
cpos.Z = FIXED2FLOAT(players[consoleplayer].camera->y);
|
cpos.Z = FIXED2FLOAT(players[consoleplayer].camera->y);
|
||||||
mpos = pos;
|
|
||||||
|
|
||||||
if ((chanflags & CHAN_AREA) && sec != NULL)
|
if (chanflags & CHAN_AREA)
|
||||||
{
|
{
|
||||||
fixed_t ox = fixed_t(pos[0] * 65536);
|
|
||||||
fixed_t oy = fixed_t(pos[1] * 65536);
|
|
||||||
fixed_t cx, cy, cz;
|
|
||||||
float level, old_level;
|
float level, old_level;
|
||||||
|
|
||||||
// Are we inside the sector? If yes, the closest point is the one we're on.
|
|
||||||
if (P_PointInSector(players[consoleplayer].camera->x, players[consoleplayer].camera->y) == sec)
|
|
||||||
{
|
|
||||||
mpos[0] = cpos[0];
|
|
||||||
mpos[2] = cpos[2];
|
|
||||||
cx = players[consoleplayer].camera->x;
|
|
||||||
cy = players[consoleplayer].camera->y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Find the closest point on the sector's boundary lines and use
|
|
||||||
// that as the perceived origin of the sound.
|
|
||||||
sec->ClosestPoint(players[consoleplayer].camera->x, players[consoleplayer].camera->y, cx, cy);
|
|
||||||
mpos[0] = FIXED2FLOAT(cx);
|
|
||||||
mpos[2] = FIXED2FLOAT(cy);
|
|
||||||
}
|
|
||||||
// Set sound height based on channel.
|
|
||||||
if (channum == CHAN_FLOOR)
|
|
||||||
{
|
|
||||||
cz = MIN(sec->floorplane.ZatPoint(cx, cy), players[consoleplayer].camera->z);
|
|
||||||
}
|
|
||||||
else if (channum == CHAN_CEILING)
|
|
||||||
{
|
|
||||||
cz = MAX(sec->ceilingplane.ZatPoint(cx, cy), players[consoleplayer].camera->z);
|
|
||||||
}
|
|
||||||
else if (channum == CHAN_INTERIOR)
|
|
||||||
{
|
|
||||||
cz = clamp(players[consoleplayer].camera->z, sec->floorplane.ZatPoint(cx, cy),
|
|
||||||
sec->ceilingplane.ZatPoint(cx, cy));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cz = players[consoleplayer].camera->z;
|
|
||||||
}
|
|
||||||
mpos[1] = FIXED2FLOAT(cz);
|
|
||||||
|
|
||||||
// How far are we from the perceived sound origin? Within a certain
|
// How far are we from the perceived sound origin? Within a certain
|
||||||
// short distance, we interpolate between 2D panning and full 3D panning.
|
// short distance, we interpolate between 2D panning and full 3D panning.
|
||||||
const double interp_range = 32.0;
|
const double interp_range = 32.0;
|
||||||
double dist_sqr = (cpos - mpos).LengthSquared();
|
double dist_sqr = (cpos - pos).LengthSquared();
|
||||||
|
|
||||||
if (dist_sqr == 0)
|
if (dist_sqr == 0)
|
||||||
{
|
{
|
||||||
|
@ -1628,7 +1588,7 @@ FMOD_MODE FMODSoundRenderer::SetChanHeadSettings(FMOD::Channel *chan, sfxinfo_t
|
||||||
}
|
}
|
||||||
return oldmode;
|
return oldmode;
|
||||||
}
|
}
|
||||||
else if (cpos == mpos)
|
else if (cpos == pos)
|
||||||
{ // Head relative
|
{ // Head relative
|
||||||
return (oldmode & ~FMOD_3D) | FMOD_2D;
|
return (oldmode & ~FMOD_3D) | FMOD_2D;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
// SAVESIG should match SAVEVER.
|
// SAVESIG should match SAVEVER.
|
||||||
|
|
||||||
// MINSAVEVER is the minimum level snapshot version that can be loaded.
|
// MINSAVEVER is the minimum level snapshot version that can be loaded.
|
||||||
#define MINSAVEVER 1059
|
#define MINSAVEVER 1061
|
||||||
|
|
||||||
#if SVN_REVISION_NUMBER < MINSAVEVER
|
#if SVN_REVISION_NUMBER < MINSAVEVER
|
||||||
// Never write a savegame with a version lower than what we need
|
// Never write a savegame with a version lower than what we need
|
||||||
|
|
Loading…
Reference in a new issue