Skip to content

Commit

Permalink
Server: Investigating non identifiable sound emitters
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Apr 28, 2013
1 parent 1ab7eff commit beccc5e
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 26 deletions.
6 changes: 6 additions & 0 deletions doomsday/client/include/map/gamemap.h
Expand Up @@ -217,6 +217,12 @@ class GameMap
*/
Surface *surfaceBySoundEmitter(ddmobj_base_t const &soundEmitter) const;

//#ifdef __SERVER__
/// @return @c true iff @a emitter is an identifiable map element.
bool identifySoundEmitter(ddmobj_base_t const &emitter, Sector **sector,
Polyobj **poly, Plane **plane, Surface **surface) const;
//#endif

/**
* Provides access to the list of polyobjs for efficient traversal.
*/
Expand Down
8 changes: 8 additions & 0 deletions doomsday/client/include/map/polyobj.h
Expand Up @@ -55,6 +55,14 @@ typedef struct polyobj_s
/// @note: Does nothing about the user data section.
~polyobj_s();

/**
* Returns the sound emitter for the polyobj.
*/
ddmobj_base_t &soundEmitter();

/// @copydoc soundEmitter()
ddmobj_base_t const &soundEmitter() const;

/**
* Provides access to the list of Lines for the polyobj.
*/
Expand Down
33 changes: 33 additions & 0 deletions doomsday/client/src/map/gamemap.cpp
Expand Up @@ -759,6 +759,39 @@ Surface *GameMap::surfaceBySoundEmitter(ddmobj_base_t const &soundEmitter) const
return 0; // Not found.
}

//#ifdef __SERVER__
bool GameMap::identifySoundEmitter(ddmobj_base_t const &emitter, Sector **sector,
Polyobj **poly, Plane **plane, Surface **surface) const
{
*sector = 0;
*poly = 0;
*plane = 0;
*surface = 0;

/// @todo Optimize: All sound emitters in a sector are linked together forming
/// a chain. Make use of the chains instead.

*poly = polyobjByBase(emitter);
if(!*poly)
{
// Not a polyobj. Try the sectors next.
*sector = sectorBySoundEmitter(emitter);
if(!*sector)
{
// Not a sector. Try the planes next.
*plane = planeBySoundEmitter(emitter);
if(!*plane)
{
// Not a plane. Try the surfaces next.
*surface = surfaceBySoundEmitter(emitter);
}
}
}

return (!*sector || !*poly || !*plane || !*surface);
}
//#endif // __SERVER__

Polyobj *GameMap::polyobjByTag(int tag) const
{
foreach(Polyobj *polyobj, _polyobjs)
Expand Down
10 changes: 10 additions & 0 deletions doomsday/client/src/map/polyobj.cpp
Expand Up @@ -109,6 +109,16 @@ void Polyobj::setCollisionCallback(void (*func) (mobj_t *mobj, void *line, void
collisionCallback = func;
}

ddmobj_base_t &Polyobj::soundEmitter()
{
return *reinterpret_cast<ddmobj_base_t *>(this);
}

ddmobj_base_t const &Polyobj::soundEmitter() const
{
return const_cast<ddmobj_base_t const &>(const_cast<Polyobj &>(*this).soundEmitter());
}

Polyobj::Lines const &Polyobj::lines() const
{
return *static_cast<Lines *>(_lines);
Expand Down
40 changes: 40 additions & 0 deletions doomsday/client/src/map/r_world.cpp
Expand Up @@ -735,6 +735,41 @@ static void updateAllMapSectors(GameMap &map)
}
}

#if /*defined(__SERVER__) &&*/ defined(DENG_DEBUG)
static void verifyAllSoundEmitters()
{
DENG_ASSERT(theMap != 0);

Sector *emSec;
Plane *emPln;
Polyobj *emPoly;
Surface *emSuf;
foreach(Sector *sector, theMap->sectors())
{
DENG_ASSERT(theMap->identifySoundEmitter(sector->soundEmitter(), &emSec, &emPoly, &emPln, &emSuf));

foreach(Plane *plane, sector->planes())
{
DENG_ASSERT(theMap->identifySoundEmitter(plane->soundEmitter(), &emSec, &emPoly, &emPln, &emSuf));
}
}
foreach(Polyobj *polyobj, theMap->polyobjs())
{
DENG_ASSERT(theMap->identifySoundEmitter(polyobj->soundEmitter(), &emSec, &emPoly, &emPln, &emSuf));
}
foreach(Line *line, theMap->lines())
for(int i = 0; i < 2; ++i)
{
Line::Side &side = line->side(i);
if(!side.hasSections()) continue;

DENG_ASSERT(theMap->identifySoundEmitter(side.middleSoundEmitter(), &emSec, &emPoly, &emPln, &emSuf));
DENG_ASSERT(theMap->identifySoundEmitter(side.bottomSoundEmitter(), &emSec, &emPoly, &emPln, &emSuf));
DENG_ASSERT(theMap->identifySoundEmitter(side.topSoundEmitter(), &emSec, &emPoly, &emPln, &emSuf));
}
}
#endif // defined(__SERVER__) && defined(DENG_DEBUG)

#undef R_SetupMap
DENG_EXTERN_C void R_SetupMap(int mode, int flags)
{
Expand Down Expand Up @@ -808,6 +843,11 @@ DENG_EXTERN_C void R_SetupMap(int mode, int flags)

// Map setup has been completed.

#if /*defined(__SERVER__) &&*/ defined(DENG_DEBUG)
// Ensure all sound emitters are identifiable.
verifyAllSoundEmitters();
#endif

// Run any commands specified in Map Info.
de::Uri mapUri = theMap->uri();
ded_mapinfo_t *mapInfo = Def_GetMapInfo(reinterpret_cast<uri_s *>(&mapUri));
Expand Down
34 changes: 8 additions & 26 deletions doomsday/server/src/server/sv_sound.cpp
Expand Up @@ -35,7 +35,7 @@ static inline boolean isRealMobj(const mobj_t* base)
/**
* Find the map object to whom @a base belongs.
*/
static void Sv_IdentifySoundBase(mobj_t **base, Sector **sector, Polyobj **poly,
static void identifySoundEmitter(mobj_t **base, Sector **sector, Polyobj **poly,
Plane **plane, Surface **surface)
{
*sector = 0;
Expand All @@ -45,31 +45,13 @@ static void Sv_IdentifySoundBase(mobj_t **base, Sector **sector, Polyobj **poly,

if(!*base || isRealMobj(*base)) return;

/// @todo Optimize: All sound emitters in a sector are linked together forming
/// a chain. Make use of the chains instead.
theMap->identifySoundEmitter(*reinterpret_cast<ddmobj_base_t*>(*base),
sector, poly, plane, surface);

// No mobj ID => it's not a real mobj.
*poly = theMap->polyobjByBase(*reinterpret_cast<ddmobj_base_t *>(base));
if(!*poly)
{
// Not a polyobj. Try the sectors next.
*sector = theMap->sectorBySoundEmitter(*reinterpret_cast<ddmobj_base_t *>(base));
if(!*sector)
{
// Not a sector. Try the planes next.
*plane = theMap->planeBySoundEmitter(*reinterpret_cast<ddmobj_base_t *>(base));
if(!*plane)
{
// Not a plane. Try the surfaces next.
*surface = theMap->surfaceBySoundEmitter(*reinterpret_cast<ddmobj_base_t *>(base));
}
}
}

#ifdef _DEBUG
#ifdef DENG_DEBUG
if(!*sector && !*poly && !*plane && !*surface)
{
Con_Error("Sv_IdentifySoundBase: Bad sound base.\n");
throw de::Error("Sv_IdentifySoundBase", "Bad sound base.");
}
#endif

Expand All @@ -81,7 +63,7 @@ void Sv_Sound(int soundId, mobj_t* origin, int toPlr)
Sv_SoundAtVolume(soundId, origin, 1, toPlr);
}

void Sv_SoundAtVolume(int soundIDAndFlags, mobj_t* origin, float volume, int toPlr)
void Sv_SoundAtVolume(int soundIDAndFlags, mobj_t *origin, float volume, int toPlr)
{
if(isClient) return;

Expand All @@ -92,7 +74,7 @@ void Sv_SoundAtVolume(int soundIDAndFlags, mobj_t* origin, float volume, int toP
Polyobj *poly;
Plane *plane;
Surface *surface;
Sv_IdentifySoundBase(&origin, &sector, &poly, &plane, &surface);
identifySoundEmitter(&origin, &sector, &poly, &plane, &surface);

int targetPlayers = 0;
if(toPlr & SVSF_TO_ALL)
Expand Down Expand Up @@ -128,7 +110,7 @@ void Sv_StopSound(int soundId, mobj_t *origin)
Polyobj *poly;
Plane *plane;
Surface *surface;
Sv_IdentifySoundBase(&origin, &sector, &poly, &plane, &surface);
identifySoundEmitter(&origin, &sector, &poly, &plane, &surface);

LOG_TRACE("Sv_StopSound: id: #%i origin: %i(%p) sec: %p poly: %p plane: %p surface: %p")
<< soundId << (origin? origin->thinker.id : 0)
Expand Down

0 comments on commit beccc5e

Please sign in to comment.